summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/MachineOutliner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/MachineOutliner.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineOutliner.cpp38
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.
OpenPOWER on IntegriCloud