Skip to content

Commit 4c1baeb

Browse files
committed
Include PHINode operands in liveness analysis.
Until now we've ignored PHINode operands inside our liveness analysis, since the algorithm we are using did not consider SSA. With the recent change in yk which uses stackmap calls to collect live values for deoptimisation, we no longer get away with this. The difficulty with PHINodes, is that marking their operands live means the backwards running liveness algorithm will consider values live in blocks where they can never appear. For example, let's consider a branch in a block A splitting to block B and C, which then both diverge into block D. The PHINode at the beginning of block D might look like this: `%10 = phi [B, %5], [C, %7]` The backwards running pass would now consider `%5` and `%7` live in both block B and C, even though only one of the values was defined in each. This is incorrect and leads to non-existing values inside some stackmap calls. The fix is relatively simple. At the end of each block we mark each value that wasn't defined inside this block as if it was. For example, at the end of block B we mark `%7` as defined, and do the same for block C and value `%5`. This means the backwards pass immediately kills those values when entering the block, which means the non-existing values are no longer live at that point and won't be inserted into any earlier stackmap calls.
1 parent 22e35b8 commit 4c1baeb

File tree

1 file changed

+26
-4
lines changed

1 file changed

+26
-4
lines changed

llvm/lib/Transforms/Yk/LivenessAnalysis.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,36 @@ LivenessAnalysis::LivenessAnalysis(Function *Func) {
7777

7878
// Record what this instruction uses.
7979
//
80-
// Note that Phi nodes are special and must be skipped. If we consider
81-
// their operands as uses, then Phi nodes in loops may use variables
82-
// before they are defined, and this messes with the algorithm.
80+
// In order to track the operands of PHI nodes we need to be a bit crafty
81+
// as otherwise we end up with live values in blocks where they actually
82+
// don't exist. To avoid this, we need to mark as live any PHI operand
83+
// from one block at the end of all other blocks. This leads to those
84+
// values being killed immediately after entering the block in the
85+
// backwards pass and thus the value never being live there.
8386
//
8487
// The book doesn't cover this quirk, as it explains liveness for
8588
// non-SSA form, and thus doesn't need to worry about Phi nodes.
86-
if (isa<PHINode>(I))
89+
if (isa<PHINode>(I)) {
90+
PHINode *P = cast<PHINode>(&I);
91+
for (unsigned IVC = 0; IVC < P->getNumIncomingValues(); IVC++) {
92+
BasicBlock *IBB = P->getIncomingBlock(IVC);
93+
Value *IV = P->getIncomingValue(IVC);
94+
if (isa<Constant>(IV)) {
95+
continue;
96+
}
97+
// For each block that isn't the incoming block create a Def for this
98+
// value. This means when we do the backwards liveness pass this
99+
// value is immediately killed in the block.
100+
for (auto *BBB = P->block_begin(); BBB != P->block_end(); BBB++) {
101+
if (*BBB != IBB) {
102+
Instruction *Last = &((*BBB)->back());
103+
Defs[Last].insert(IV);
104+
}
105+
}
106+
Uses[&I].insert(IV);
107+
}
87108
continue;
109+
}
88110

89111
for (auto *U = I.op_begin(); U < I.op_end(); U++)
90112
if ((!isa<Constant>(U)) && (!isa<BasicBlock>(U)) &&

0 commit comments

Comments
 (0)