Tail merging can convert an undef use into a normal one when creating a common tail. Doing so can make the register live out from a block which previously contained the undef use. To keep the liveness up-to-date, insert IMPLICIT_DEFs in such blocks when necessary.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
lib/CodeGen/BranchFolding.cpp | ||
---|---|---|
385–398 | I'm confused: Don't you need to compare the live-outs of Pred with the live-ins of NewDest? Adding the liveouts of Pred and stepping backwards over the instructions gives you the live-ins of Pred, but I don't see what they are good for. I would have expected this to look like this: PredLiveOuts.init(*TRI); PrevLiveOuts.addLiveOutsNoPristines(*Pred); // Add implicit defs for NewDest live-in values not available at end of Pred. for (const MachineBasicBlock::RegisterMaskPair &LI : NewDest->liveins()) { // computeLiveIn() currently doesn't add partial live-ins so we are fine with an assert. assert(LI.LaneMask == LaneBitmask::getAll() && "found partial live-in"); if (PredLiveOuts.available(*MRI, LI.PhysReg)) { BuildMI ... } } |
lib/CodeGen/BranchFolding.cpp | ||
---|---|---|
385–398 | You're right, this won't work. Still, we need to traverse the block, and it will have to use stepForward. Consider this case: MBB: liveins: R0 R0<def,dead> = ... R0<kill> ; stays in MBB ... = R0<undef> ; goes into common tail, but no longer <undef> We need to add R0<def> = IMPLICIT_DEF here. We can't rely on addLiveOuts from LivePhysRegs, because NewDest->liveins() will (by definition) be a subset of Pred->addLiveOuts. |
Changed how the liveness inconsistencies are detected. Added comments with explanations.
lib/CodeGen/BranchFolding.cpp | ||
---|---|---|
385–398 |
Fair point. This is trickier than it seemed at first. I'm still convinced though that it can be done, and I really want to avoid stepForward(). I'll have a shot at implementing it. |
This should fix the problem without using stepForward: https://reviews.llvm.org/D37034
I'm confused: Don't you need to compare the live-outs of Pred with the live-ins of NewDest? Adding the liveouts of Pred and stepping backwards over the instructions gives you the live-ins of Pred, but I don't see what they are good for.
I would have expected this to look like this: