Skip to content

Commit cada2a8

Browse files
committed
Fix NoOp move handling and drop glue setup
1 parent 1c30859 commit cada2a8

1 file changed

Lines changed: 39 additions & 35 deletions

File tree

  • kmir/src/kmir/kdist/mir-semantics

kmir/src/kmir/kdist/mir-semantics/kmir.md

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,10 @@ NB that a stack height of `0` cannot occur here, because the compiler prevents l
219219
If the local `_0` does not have a value (i.e., it remained uninitialised), the function returns unit and writing the value is skipped.
220220

221221
```k
222-
// `place(local(-1), .ProjectionElems)` is a sentinel destination meaning that the caller
223-
// ignores the callee's return value. Skip the normal writeback path in that case, because
224-
// `#setLocalValue` only accepts real local indices and would get stuck on `local(-1)`.
222+
// `place(local(-1), .ProjectionElems)` is the sentinel destination for calls whose
223+
// return should not be written back. Without this rule, the return path would fall
224+
// through to `#setLocalValue`, which only accepts real local indices and would get
225+
// stuck on `local(-1)`.
225226
rule [termReturnIgnored]: <k> #execTerminator(terminator(terminatorKindReturn, _SPAN)) ~> _
226227
=>
227228
#execBlockIdx(TARGET)
@@ -390,21 +391,18 @@ where the returned result should go.
390391
391392
rule <k> #consumeNoOpArg(operandConstant(_)) => .K ... </k>
392393
393-
rule <k> #consumeNoOpArg(operandValue(_)) => .K ... </k>
394-
395394
rule <k> #consumeNoOpArg(operandCopy(place(local(I), .ProjectionElems))) => .K ... </k>
396-
<stack> ListItem(StackFrame(_, _, _, _, CALLERLOCALS)) _:List </stack>
395+
<locals> LOCALS </locals>
397396
requires 0 <=Int I
398-
andBool I <Int size(CALLERLOCALS)
399-
andBool isTypedValue(CALLERLOCALS[I])
397+
andBool I <Int size(LOCALS)
398+
andBool isTypedValue(LOCALS[I])
400399
[preserves-definedness]
401400
402401
rule <k> #consumeNoOpArg(operandMove(place(local(I), _))) => .K ... </k>
403-
<stack> (ListItem(StackFrame(_, _, _, _, CALLERLOCALS) #as CALLERFRAME => #updateStackLocal(CALLERFRAME, I, Moved))) _:List
404-
</stack>
402+
<locals> LOCALS => LOCALS[I <- typedValue(Moved, tyOfLocal(getLocal(LOCALS, I)), mutabilityMut)] </locals>
405403
requires 0 <=Int I
406-
andBool I <Int size(CALLERLOCALS)
407-
andBool isTypedValue(CALLERLOCALS[I])
404+
andBool I <Int size(LOCALS)
405+
andBool isTypedValue(LOCALS[I])
408406
[preserves-definedness]
409407
410408
// Regular function call - full state switching and stack setup
@@ -502,6 +500,7 @@ An operand may be a `Reference` (the only way a function could access another fu
502500

503501
```k
504502
syntax KItem ::= #setUpCalleeData(MonoItemKind, Operands, Span)
503+
| #setUpDropGlueData(MonoItemKind, Value, Span)
505504
506505
// reserve space for local variables and copy/move arguments from old locals into their place
507506
rule [setupCalleeData]: <k> #setUpCalleeData(
@@ -526,6 +525,21 @@ An operand may be a `Reference` (the only way a function could access another fu
526525
</currentFrame>
527526
// TODO: Haven't handled "noBody" case
528527
528+
rule [setupDropGlueData]: <k> #setUpDropGlueData(
529+
monoItemFn(_, _, someBody(body((FIRST:BasicBlock _) #as BLOCKS, NEWLOCALS, _, _, _, _))),
530+
PTR,
531+
_SPAN
532+
)
533+
=>
534+
#setLocalValue(place(local(1), .ProjectionElems), #incrementRef(PTR)) ~> #execBlock(FIRST)
535+
...
536+
</k>
537+
<currentFrame>
538+
<currentBody> _ => toKList(BLOCKS) </currentBody>
539+
<locals> _ => #reserveFor(NEWLOCALS) </locals>
540+
...
541+
</currentFrame>
542+
529543
syntax List ::= #reserveFor( LocalDecls ) [function, total]
530544
531545
rule #reserveFor(.LocalDecls) => .List
@@ -534,11 +548,6 @@ An operand may be a `Reference` (the only way a function could access another fu
534548
=>
535549
ListItem(newLocal(TY, MUT)) #reserveFor(REST)
536550
537-
syntax Operand ::= operandValue ( Value )
538-
539-
// Internal helper operand for already-evaluated runtime values.
540-
rule <k> operandValue(VAL) => VAL ... </k>
541-
542551
syntax KItem ::= #setArgsFromStack ( Int, Operands)
543552
| #setArgFromStack ( Int, Operand)
544553
| #execIntrinsic ( MonoItemKind, Operands, Place, Span )
@@ -558,12 +567,6 @@ An operand may be a `Reference` (the only way a function could access another fu
558567
...
559568
</k>
560569
561-
rule <k> #setArgFromStack(IDX, operandValue(VAL))
562-
=>
563-
#setLocalValue(place(local(IDX), .ProjectionElems), #incrementRef(VAL))
564-
...
565-
</k>
566-
567570
rule <k> #setArgFromStack(IDX, operandCopy(place(local(I), .ProjectionElems)))
568571
=>
569572
#setLocalValue(place(local(IDX), .ProjectionElems), #incrementRef(getValue(CALLERLOCALS, I)))
@@ -772,19 +775,20 @@ Drops are elaborated to Noops but still define the continuing control flow. Unre
772775
...
773776
</k>
774777
775-
rule <k> PTR:Value ~> #callDropGlue(FTY, TARGET, UNWIND, SPAN)
776-
=>
777-
#execTerminatorCall(
778-
FTY,
779-
lookupFunction(FTY),
780-
operandValue(PTR) .Operands,
781-
place(local(-1), .ProjectionElems),
782-
someBasicBlockIdx(TARGET),
783-
UNWIND,
784-
SPAN
785-
)
786-
...
778+
rule [termCallDropGlue]:
779+
<k> PTR:Value ~> #callDropGlue(FTY, TARGET, UNWIND, SPAN) ~> _
780+
=> #setUpDropGlueData(lookupFunction(FTY), PTR, SPAN)
787781
</k>
782+
<currentFunc> CALLER => FTY </currentFunc>
783+
<currentFrame>
784+
<currentBody> _ </currentBody>
785+
<caller> OLDCALLER => CALLER </caller>
786+
<dest> OLDDEST => place(local(-1), .ProjectionElems) </dest>
787+
<target> OLDTARGET => someBasicBlockIdx(TARGET) </target>
788+
<unwind> OLDUNWIND => UNWIND </unwind>
789+
<locals> LOCALS </locals>
790+
</currentFrame>
791+
<stack> STACK => ListItem(StackFrame(OLDCALLER, OLDDEST, OLDTARGET, OLDUNWIND, LOCALS)) STACK </stack>
788792
789793
syntax MIRError ::= "ReachedUnreachable"
790794

0 commit comments

Comments
 (0)