89#define DEBUG_TYPE "cfi-fixup"
94 "Insert CFI remember/restore state instructions",
false,
false)
98 return MI.getOpcode() == TargetOpcode::CFI_INSTRUCTION &&
104 return MI.getOpcode() == TargetOpcode::CFI_INSTRUCTION &&
119 PrologueEnd = std::next(
MI.getIterator());
148 BlockInfo[0].Reachable =
true;
149 BlockInfo[0].StrongNoFrameOnEntry =
true;
158 bool HasPrologue =
MBB == PrologueBlock;
159 bool HasEpilogue =
false;
161 if (
Info.HasFrameOnEntry || HasPrologue)
167 Info.HasFrameOnExit = (
Info.HasFrameOnEntry || HasPrologue) && !HasEpilogue;
171 BlockFlags &SuccInfo = BlockInfo[Succ->getNumber()];
174 Info.StrongNoFrameOnEntry && !HasPrologue;
204 TII.get(TargetOpcode::CFI_INSTRUCTION))
210 return {RestoreInsertPt.
MBB,
212 DebugLoc(),
TII.get(TargetOpcode::CFI_INSTRUCTION))
258 BlockInfo[std::prev(CurrBB.
getIterator())->getNumber()];
260 bool NeedsFrame =
Info.HasFrameOnEntry && !
Info.StrongNoFrameOnEntry;
263 if (!
Info.StrongNoFrameOnEntry) {
265 const BlockFlags &PredInfo = BlockInfo[Pred->getNumber()];
268 "Inconsistent call frame state");
273 if (HasFrame == NeedsFrame)
284 if (InsertPt.
MBB ==
nullptr) {
310 if (PrologueBlock ==
nullptr)
324 InsertionPts[PrologueBlock->
getSectionID()] = {PrologueBlock, PrologueEnd};
327 "Inconsistent notion of \"prologue block\"");
335 fixupBlock(
MBB, BlockInfo, InsertionPts, {PrologueBlock, PrologueEnd});
static InsertionPoint insertRememberRestorePair(const InsertionPoint &RememberInsertPt, const InsertionPoint &RestoreInsertPt)
static bool fixupBlock(MachineBasicBlock &CurrBB, const BlockFlagsVector &BlockInfo, SmallDenseMap< MBBSectionID, InsertionPoint > &InsertionPts, const InsertionPoint &Prologue)
static InsertionPoint cloneCfiPrologue(const InsertionPoint &PrologueEnd, const InsertionPoint &DstInsertPt)
static bool isPrologueCFIInstruction(const MachineInstr &MI)
static BlockFlagsVector computeBlockInfo(const MachineFunction &MF, const MachineBasicBlock *PrologueBlock)
static MachineBasicBlock * findPrologueEnd(MachineFunction &MF, MachineBasicBlock::iterator &PrologueEnd)
static bool containsEpilogue(const MachineBasicBlock &MBB)
Contains definition of the base CFIFixup pass.
Analysis containing CSE Info
This file defines the DenseMap class.
const HexagonInstrInfo * TII
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
FunctionPass class - This class is used to implement most global optimizations.
static MCCFIInstruction createRememberState(MCSymbol *L, SMLoc Loc={})
.cfi_remember_state Save all current rules for all registers.
static MCCFIInstruction createRestoreState(MCSymbol *L, SMLoc Loc={})
.cfi_restore_state Restore the previously saved state.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
MBBSectionID getSectionID() const
Returns the section ID of this basic block.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
bool isBeginSection() const
Returns true if this block begins any section.
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
Create a new MachineInstr which is a copy of Orig, identical in all ways except the instruction has n...
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
Representation of each machine instruction.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Information about stack frame layout on the target.
virtual void resetCFIToInitialState(MachineBasicBlock &MBB) const
Emit CFI instructions that recreate the state of the unwind information upon fucntion entry.
virtual bool enableCFIFixup(MachineFunction &MF) const
Returns true if we may need to fix the unwind information for the function.
TargetInstrInfo - Interface to description of machine instruction set.
virtual const TargetFrameLowering * getFrameLowering() const
virtual const TargetInstrInfo * getInstrInfo() const
self_iterator getIterator()
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
auto map_range(ContainerTy &&C, FuncTy F)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
FunctionPass * createCFIFixup()
Creates CFI Fixup pass.
bool StrongNoFrameOnEntry
MachineBasicBlock::iterator Iterator