From 0b6724917a694692049325cb582da668c4e28528 Mon Sep 17 00:00:00 2001 From: Jessica Paquette Date: Fri, 27 Apr 2018 23:36:35 +0000 Subject: [MachineOutliner] Add defs to calls + don't track liveness on outlined functions This commit makes it so that if you outline a def of some register, then the call instruction created by the outliner actually reflects that the register is defined by the call. It also makes it so that outlined functions don't have the TracksLiveness property. Outlined calls shouldn't break liveness assumptions that someone might make. This also un-XFAILs the noredzone test, and updates the calls test. llvm-svn: 331095 --- llvm/lib/CodeGen/MachineOutliner.cpp | 38 ++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'llvm/lib/CodeGen/MachineOutliner.cpp') 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. -- cgit v1.2.3