diff options
author | Jin Lin <jinl@uber.com> | 2020-03-05 13:54:58 -0800 |
---|---|---|
committer | Jin Lin <jinl@uber.com> | 2020-03-06 09:13:20 -0800 |
commit | fc6fda90f708ec0a8dc26ef7e936ea70df0b879b (patch) | |
tree | 470a0172f61e86d52a7c38997ac1b7e9c6ae2d1c /llvm/lib/CodeGen/MachineOutliner.cpp | |
parent | 5dadf577d59b53110f2a0084dc9ef9f974116955 (diff) | |
download | llvm-fc6fda90f708ec0a8dc26ef7e936ea70df0b879b.zip llvm-fc6fda90f708ec0a8dc26ef7e936ea70df0b879b.tar.gz llvm-fc6fda90f708ec0a8dc26ef7e936ea70df0b879b.tar.bz2 |
Fix incorrect logic in maintaining the side-effect of compiler generated outliner functions
Summary: Fix incorrect logic in maintaining the side-effect of compiler generated outliner functions by adding the up-exposed uses.
Reviewers: paquette, tellenbach
Reviewed By: paquette
Subscribers: aemerson, lebedev.ri, hiraditya, llvm-commits, jinlin
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D71217
Diffstat (limited to 'llvm/lib/CodeGen/MachineOutliner.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineOutliner.cpp | 59 |
1 files changed, 41 insertions, 18 deletions
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp index 7081950..19bcb09 100644 --- a/llvm/lib/CodeGen/MachineOutliner.cpp +++ b/llvm/lib/CodeGen/MachineOutliner.cpp @@ -56,6 +56,7 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/MachineOutliner.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/Twine.h" #include "llvm/CodeGen/MachineFunction.h" @@ -1245,31 +1246,53 @@ bool MachineOutliner::outline(Module &M, // 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 + // The following code is to add implicit def operands to the call // instruction. It also updates call site information for moved // code. - auto CopyDefsAndUpdateCalls = [&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 */)); - } - if (MI.shouldUpdateCallSiteInfo()) - MI.getMF()->eraseCallSiteInfo(&MI); - }; + SmallSet<Register, 2> UseRegs, DefRegs; // 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. Also remove call site information for outlined block - // of code. - std::for_each(CallInst, std::next(EndIt), CopyDefsAndUpdateCalls); + // of code. The exposed uses need to be copied in the outlined range. + for (MachineBasicBlock::reverse_iterator Iter = EndIt.getReverse(), + Last = std::next(CallInst.getReverse()); + Iter != Last; Iter++) { + MachineInstr *MI = &*Iter; + for (MachineOperand &MOP : MI->operands()) { + // Skip over anything that isn't a register. + if (!MOP.isReg()) + continue; + + if (MOP.isDef()) { + // Introduce DefRegs set to skip the redundant register. + DefRegs.insert(MOP.getReg()); + if (UseRegs.count(MOP.getReg())) + // Since the regiester is modeled as defined, + // it is not necessary to be put in use register set. + UseRegs.erase(MOP.getReg()); + } else if (!MOP.isUndef()) { + // Any register which is not undefined should + // be put in the use register set. + UseRegs.insert(MOP.getReg()); + } + } + if (MI->isCandidateForCallSiteEntry()) + MI->getMF()->eraseCallSiteInfo(MI); + } + + for (const Register &I : DefRegs) + // If it's a def, add it to the call instruction. + CallInst->addOperand(MachineOperand::CreateReg( + I, true, /* isDef = true */ + true /* isImp = true */)); + + for (const Register &I : UseRegs) + // If it's a exposed use, add it to the call instruction. + CallInst->addOperand( + MachineOperand::CreateReg(I, false, /* isDef = false */ + true /* isImp = true */)); } // Erase from the point after where the call was inserted up to, and |