Skip to content

Commit bca9e6b

Browse files
Jake Hughesjacob-hughes
Jake Hughes
authored andcommitted
Serialise stack-maps on demand
Instead of serialising stack-maps as separate instructions with their own opcode, we fold them up into the instruction that they act as a safepoint for (i.e. `call` or `condbr` instrs).
1 parent 336d00a commit bca9e6b

File tree

1 file changed

+27
-15
lines changed

1 file changed

+27
-15
lines changed

llvm/lib/YkIR/YkIRWriter.cpp

+27-15
Original file line numberDiff line numberDiff line change
@@ -395,24 +395,17 @@ class YkIRWriter {
395395
InstIdx++;
396396
}
397397

398-
void serialiseDeoptSafepointInst(CallInst *I, ValueLoweringMap &VLMap,
399-
unsigned BBIdx, unsigned &InstIdx) {
400-
serialiseOpcode(OpCodeDeoptSafepoint);
398+
void serialiseStackmapCall(CallInst *I, ValueLoweringMap &VLMap) {
401399
// stackmap ID:
402400
serialiseOperand(I, VLMap, I->getOperand(0));
403401

404-
// num_shadow_bytes:
405-
serialiseOperand(I, VLMap, I->getOperand(1));
406-
407402
// num_lives:
408403
OutStreamer.emitInt32(I->arg_size() - 2);
409404

410405
// lives:
411406
for (unsigned OI = 2; OI < I->arg_size(); OI++) {
412407
serialiseOperand(I, VLMap, I->getOperand(OI));
413408
}
414-
InstIdx++;
415-
return;
416409
}
417410

418411
void serialiseCallInst(CallInst *I, ValueLoweringMap &VLMap, unsigned BBIdx,
@@ -430,6 +423,13 @@ class YkIRWriter {
430423
return;
431424
}
432425

426+
// Stackmap calls are serialised on-demand by folding them into the `call`
427+
// or `condbr` instruction which they belong to.
428+
if (I->getCalledFunction()->isIntrinsic() &&
429+
I->getIntrinsicID() == Intrinsic::experimental_stackmap) {
430+
return;
431+
}
432+
433433
// FIXME: indirect calls.
434434
//
435435
// Note that this assertion can also fail if you do a direct call without
@@ -448,13 +448,6 @@ class YkIRWriter {
448448
// call i32 (i32, ...) @f(1i32, 2i32);
449449
assert(I->getCalledFunction());
450450

451-
// special case for llvm.experimental.stackmap intrinsic.
452-
if (I->getCalledFunction()->isIntrinsic() &&
453-
I->getIntrinsicID() == Intrinsic::experimental_stackmap) {
454-
serialiseDeoptSafepointInst(I, VLMap, BBIdx, InstIdx);
455-
return;
456-
}
457-
458451
serialiseOpcode(OpCodeCall);
459452
// callee:
460453
OutStreamer.emitSizeT(functionIndex(I->getCalledFunction()));
@@ -465,6 +458,19 @@ class YkIRWriter {
465458
for (unsigned OI = 0; OI < I->arg_size(); OI++) {
466459
serialiseOperand(I, VLMap, I->getOperand(OI));
467460
}
461+
if (!I->getCalledFunction()->isDeclaration()) {
462+
// The next instruction will be the stackmap entry
463+
CallInst *SMI = dyn_cast<CallInst>(I->getNextNonDebugInstruction());
464+
assert(SMI);
465+
assert(SMI->getCalledFunction()->isIntrinsic());
466+
assert(SMI->getIntrinsicID() == Intrinsic::experimental_stackmap);
467+
// has_safepoint = 1:
468+
OutStreamer.emitInt8(1);
469+
serialiseStackmapCall(SMI, VLMap);
470+
} else {
471+
// has_safepoint = 0:
472+
OutStreamer.emitInt8(0);
473+
}
468474

469475
// If the return type is non-void, then this defines a local.
470476
if (!I->getType()->isVoidTy()) {
@@ -497,6 +503,12 @@ class YkIRWriter {
497503
serialiseBlockLabel(I->getSuccessor(0));
498504
// false_bb:
499505
serialiseBlockLabel(I->getSuccessor(1));
506+
507+
CallInst *SMI = dyn_cast<CallInst>(I->getPrevNonDebugInstruction());
508+
assert(SMI);
509+
assert(SMI->getCalledFunction()->isIntrinsic());
510+
assert(SMI->getIntrinsicID() == Intrinsic::experimental_stackmap);
511+
serialiseStackmapCall(SMI, VLMap);
500512
}
501513
InstIdx++;
502514
}

0 commit comments

Comments
 (0)