mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-23 16:06:24 +00:00
[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:
parent
79dc930c13
commit
71d3869f60
@ -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);
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/// \}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user