diff options
Diffstat (limited to 'llvm/lib/CodeGen/MachineOutliner.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineOutliner.cpp | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp index d56f113aa7f..d0f6f56b3d7 100644 --- a/llvm/lib/CodeGen/MachineOutliner.cpp +++ b/llvm/lib/CodeGen/MachineOutliner.cpp @@ -1323,6 +1323,8 @@ MachineOutliner::createOutlinedFunction(Module &M, const OutlinedFunction &OF, DB.finalize(); } + // Outlined functions shouldn't preserve liveness. + MF.getProperties().reset(MachineFunctionProperties::Property::TracksLiveness); MF.getRegInfo().freezeReservedRegs(MF); return &MF; } @@ -1357,8 +1359,6 @@ bool MachineOutliner::outline( MachineBasicBlock::iterator EndIt = Mapper.InstrList[EndIdx]; assert(EndIt != MBB->end() && "EndIt out of bounds!"); - EndIt++; // Erase needs one past the end index. - // Does this candidate have a function yet? if (!OF.MF) { OF.MF = createOutlinedFunction(M, OF, Mapper); @@ -1401,10 +1401,40 @@ bool MachineOutliner::outline( const TargetInstrInfo &TII = *STI.getInstrInfo(); // Insert a call to the new function and erase the old sequence. - TII.insertOutlinedCall(M, *MBB, StartIt, *MF, C.MInfo); + auto CallInst = TII.insertOutlinedCall(M, *MBB, StartIt, *MF, C.MInfo); StartIt = Mapper.InstrList[C.getStartIdx()]; - MBB->erase(StartIt, EndIt); + // If the caller tracks liveness, then we need to make sure that anything + // we outline doesn't break liveness assumptions. + // The outlined functions themselves currently don't track liveness, but + // we should make sure that the ranges we yank things out of aren't + // wrong. + if (MBB->getParent()->getProperties().hasProperty( + MachineFunctionProperties::Property::TracksLiveness)) { + // Helper lambda for adding implicit def operands to the call instruction. + auto CopyDefs = [&CallInst](MachineInstr &MI) { + for (MachineOperand &MOP : MI.operands()) { + // Skip over anything that isn't a register. + if (!MOP.isReg()) + continue; + + // If it's a def, add it to the call instruction. + if (MOP.isDef()) + CallInst->addOperand( + MachineOperand::CreateReg(MOP.getReg(), true, /* isDef = true */ + true /* isImp = true */)); + } + }; + + // Copy over the defs in the outlined range. + // First inst in outlined range <-- Anything that's defined in this + // ... .. range has to be added as an implicit + // Last inst in outlined range <-- def to the call instruction. + std::for_each(CallInst, EndIt, CopyDefs); + } + + EndIt++; // Erase needs one past the end index. + MBB->erase(StartIt, EndIt); OutlinedSomething = true; // Statistics. |