[Backend] Keep call site info valid through the backend

Handle call instruction replacements and deletions in order to preserve
valid state of the call site info of the MachineFunction.

NOTE: If the call site info is enabled for a new target, the assertion from
the MachineFunction::DeleteMachineInstr() should help to locate places
where the updateCallSiteInfo() should be called in order to preserve valid
state of the call site info.

([10/13] Introduce the debug entry values.)

Co-authored-by: Ananth Sowda <asowda@cisco.com>
Co-authored-by: Nikola Prica <nikola.prica@rt-rk.com>
Co-authored-by: Ivan Baev <ibaev@cisco.com>

Differential Revision: https://reviews.llvm.org/D61062

llvm-svn: 364536
This commit is contained in:
Djordje Todorovic 2019-06-27 13:10:29 +00:00
parent 79dc930c13
commit 71d3869f60
9 changed files with 54 additions and 6 deletions

View File

@ -976,6 +976,12 @@ public:
return CallSitesInfo;
}
/// Update call sites info by deleting entry for \p Old call instruction.
/// If \p New is present then transfer \p Old call info to it. This function
/// should be called before removing call instruction or before replacing
/// call instruction with new one.
void updateCallSiteInfo(const MachineInstr *Old,
const MachineInstr *New = nullptr);
};
//===--------------------------------------------------------------------===//

View File

@ -868,6 +868,8 @@ foldMemoryOperand(ArrayRef<std::pair<MachineInstr *, unsigned>> Ops,
HSpiller.rmFromMergeableSpills(*MI, FI))
--NumSpills;
LIS.ReplaceMachineInstrInMaps(*MI, *FoldMI);
if (MI->isCall())
MI->getMF()->updateCallSiteInfo(MI, FoldMI);
MI->eraseFromParent();
// Insert any new instructions other than FoldMI into the LIS maps.

View File

@ -232,6 +232,8 @@ bool LiveRangeEdit::foldAsLoad(LiveInterval *LI,
LLVM_DEBUG(dbgs() << " folded: " << *FoldMI);
LIS.ReplaceMachineInstrInMaps(*UseMI, *FoldMI);
UseMI->eraseFromParent();
if (UseMI->isCall())
UseMI->getMF()->updateCallSiteInfo(UseMI, FoldMI);
DefMI->addRegisterDead(LI->reg, nullptr);
Dead.push_back(DefMI);
++NumDCEFoldedLoads;

View File

@ -363,6 +363,13 @@ MachineInstr &MachineFunction::CloneMachineInstrBundle(MachineBasicBlock &MBB,
/// ~MachineInstr() destructor must be empty.
void
MachineFunction::DeleteMachineInstr(MachineInstr *MI) {
// Verify that a call site info is at valid state. This assertion should
// be triggered during the implementation of support for the
// call site info of a new architecture. If the assertion is triggered,
// back trace will tell where to insert a call to updateCallSiteInfo().
assert((!MI->isCall(MachineInstr::IgnoreBundle) ||
CallSitesInfo.find(MI) == CallSitesInfo.end()) &&
"Call site info was not updated!");
// Strip it for parts. The operand array and the MI object itself are
// independently recyclable.
if (MI->Operands)
@ -826,6 +833,22 @@ void MachineFunction::addCodeViewHeapAllocSite(MachineInstr *I, MDNode *MD) {
CodeViewHeapAllocSites.push_back(std::make_tuple(BeginLabel, EndLabel, DI));
}
void MachineFunction::updateCallSiteInfo(const MachineInstr *Old,
const MachineInstr *New) {
if (!Target.Options.EnableDebugEntryValues || Old == New)
return;
assert(Old->isCall() && (!New || New->isCall()) &&
"Call site info referes only to call instructions!");
CallSiteInfoMap::iterator CSIt = CallSitesInfo.find(Old);
if (CSIt == CallSitesInfo.end())
return;
CallSiteInfo CSInfo = std::move(CSIt->second);
CallSitesInfo.erase(CSIt);
if (New)
CallSitesInfo[New] = CSInfo;
}
/// \}
//===----------------------------------------------------------------------===//

View File

@ -1245,8 +1245,9 @@ bool MachineOutliner::outline(Module &M,
if (MBB.getParent()->getProperties().hasProperty(
MachineFunctionProperties::Property::TracksLiveness)) {
// Helper lambda for adding implicit def operands to the call
// instruction.
auto CopyDefs = [&CallInst](MachineInstr &MI) {
// 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())
@ -1258,13 +1259,16 @@ bool MachineOutliner::outline(Module &M,
MOP.getReg(), true, /* isDef = true */
true /* isImp = true */));
}
if (MI.isCall())
MI.getMF()->updateCallSiteInfo(&MI);
};
// 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, std::next(EndIt), CopyDefs);
// instruction. Also remove call site information for outlined block
// of code.
std::for_each(CallInst, std::next(EndIt), CopyDefsAndUpdateCalls);
}
// Erase from the point after where the call was inserted up to, and

View File

@ -1777,6 +1777,8 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
LocalMIs.erase(MI);
LocalMIs.erase(DefMI);
LocalMIs.insert(FoldMI);
if (MI->isCall())
MI->getMF()->updateCallSiteInfo(MI, FoldMI);
MI->eraseFromParent();
DefMI->eraseFromParent();
MRI->markUsesInDebugValueAsUndef(FoldedReg);

View File

@ -137,8 +137,14 @@ TargetInstrInfo::ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
// Save off the debug loc before erasing the instruction.
DebugLoc DL = Tail->getDebugLoc();
// Remove all the dead instructions from the end of MBB.
MBB->erase(Tail, MBB->end());
// Update call site info and remove all the dead instructions
// from the end of MBB.
while (Tail != MBB->end()) {
auto MI = Tail++;
if (MI->isCall())
MBB->getParent()->updateCallSiteInfo(&*MI);
MBB->erase(MI);
}
// If MBB isn't immediately before MBB, insert a branch to it.
if (++MachineFunction::iterator(MBB) != MachineFunction::iterator(NewDest))

View File

@ -110,6 +110,8 @@ void XRayInstrumentation::replaceRetWithPatchableRet(
for (auto &MO : T.operands())
MIB.add(MO);
Terminators.push_back(&T);
if (T.isCall())
MF.updateCallSiteInfo(&T);
}
}
}

View File

@ -270,6 +270,7 @@ bool X86ExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
MachineInstr &NewMI = *std::prev(MBBI);
NewMI.copyImplicitOps(*MBBI->getParent()->getParent(), *MBBI);
MBB.getParent()->updateCallSiteInfo(&*MBBI, &NewMI);
// Delete the pseudo instruction TCRETURN.
MBB.erase(MBBI);