Go to the documentation of this file.
33 cl::desc(
"Verify Call Frame Information instructions"),
59 if (
unsigned ErrorNum =
verify(MF))
61 " in/out CFI information errors.");
63 bool insertedCFI = insertCFIInstrs(MF);
72 int IncomingCFAOffset = -1;
74 int OutgoingCFAOffset = -1;
76 unsigned IncomingCFARegister = 0;
78 unsigned OutgoingCFARegister = 0;
85 bool Processed =
false;
88 #define INVALID_REG UINT_MAX
89 #define INVALID_OFFSET INT_MAX
91 struct CSRSavedLocation {
93 :
Reg(R), Offset(
O) {}
111 void calculateOutgoingCFAInfo(MBBCFAInfo &MBBInfo);
114 void updateSuccCFAInfo(MBBCFAInfo &MBBInfo);
128 void reportCFAError(
const MBBCFAInfo &Pred,
const MBBCFAInfo &Succ);
129 void reportCSRError(
const MBBCFAInfo &Pred,
const MBBCFAInfo &Succ);
140 "Check CFA info and insert CFI instructions if needed",
false,
151 unsigned InitialRegister =
160 MBBInfo.IncomingCFAOffset = InitialOffset;
161 MBBInfo.OutgoingCFAOffset = InitialOffset;
162 MBBInfo.IncomingCFARegister = InitialRegister;
163 MBBInfo.OutgoingCFARegister = InitialRegister;
164 MBBInfo.IncomingCSRSaved.resize(NumRegs);
165 MBBInfo.OutgoingCSRSaved.resize(NumRegs);
173 updateSuccCFAInfo(
MBBVector[MF.front().getNumber()]);
176 void CFIInstrInserter::calculateOutgoingCFAInfo(MBBCFAInfo &MBBInfo) {
178 int SetOffset = MBBInfo.IncomingCFAOffset;
180 unsigned SetRegister = MBBInfo.IncomingCFARegister;
185 BitVector CSRSaved(NumRegs), CSRRestored(NumRegs);
189 if (
MI.isCFIInstruction()) {
192 unsigned CFIIndex =
MI.getOperand(0).getCFIIndex();
224 "Support for cfi_llvm_def_aspace_cfa not implemented! Value of CFA "
225 "may be incorrect!\n");
232 "Support for cfi_remember_state not implemented! Value of CFA "
233 "may be incorrect!\n");
240 "Support for cfi_restore_state not implemented! Value of CFA may "
253 if (CSRReg || CSROffset) {
255 if (It == CSRLocMap.end()) {
257 {CFI.
getRegister(), CSRSavedLocation(CSRReg, CSROffset)});
258 }
else if (It->second.Reg != CSRReg || It->second.Offset != CSROffset) {
266 MBBInfo.Processed =
true;
269 MBBInfo.OutgoingCFAOffset = SetOffset;
270 MBBInfo.OutgoingCFARegister = SetRegister;
274 MBBInfo.OutgoingCSRSaved, MBBInfo.IncomingCSRSaved, CSRSaved,
278 void CFIInstrInserter::updateSuccCFAInfo(MBBCFAInfo &MBBInfo) {
280 Stack.push_back(MBBInfo.MBB);
285 calculateOutgoingCFAInfo(CurrentInfo);
286 for (
auto *Succ : CurrentInfo.MBB->successors()) {
287 MBBCFAInfo &SuccInfo =
MBBVector[Succ->getNumber()];
288 if (!SuccInfo.Processed) {
289 SuccInfo.IncomingCFAOffset = CurrentInfo.OutgoingCFAOffset;
290 SuccInfo.IncomingCFARegister = CurrentInfo.OutgoingCFARegister;
291 SuccInfo.IncomingCSRSaved = CurrentInfo.OutgoingCSRSaved;
292 Stack.push_back(Succ);
295 }
while (!
Stack.empty());
301 bool InsertedCFIInstr =
false;
306 if (
MBB.
getNumber() == MF.front().getNumber())
continue;
309 auto MBBI = MBBInfo.MBB->begin();
316 if ((PrevMBBInfo->OutgoingCFAOffset != MBBInfo.IncomingCFAOffset &&
317 PrevMBBInfo->OutgoingCFARegister != MBBInfo.IncomingCFARegister) ||
324 nullptr, MBBInfo.IncomingCFARegister, getCorrectCFAOffset(&
MBB)));
327 InsertedCFIInstr =
true;
328 }
else if (PrevMBBInfo->OutgoingCFAOffset != MBBInfo.IncomingCFAOffset) {
333 nullptr, getCorrectCFAOffset(&
MBB)));
336 InsertedCFIInstr =
true;
337 }
else if (PrevMBBInfo->OutgoingCFARegister !=
338 MBBInfo.IncomingCFARegister) {
341 nullptr, MBBInfo.IncomingCFARegister));
344 InsertedCFIInstr =
true;
348 MF.getSubtarget().getFrameLowering()->emitCalleeSavedFrameMovesFullCFA(
350 InsertedCFIInstr =
true;
351 PrevMBBInfo = &MBBInfo;
356 PrevMBBInfo->OutgoingCSRSaved, MBBInfo.IncomingCSRSaved);
362 InsertedCFIInstr =
true;
366 MBBInfo.IncomingCSRSaved, PrevMBBInfo->OutgoingCSRSaved);
368 auto it = CSRLocMap.find(
Reg);
369 assert(
it != CSRLocMap.end() &&
"Reg should have an entry in CSRLocMap");
371 CSRSavedLocation RO =
it->second;
372 if (!RO.Reg && RO.Offset) {
373 CFIIndex = MF.addFrameInst(
375 }
else if (RO.Reg && !RO.Offset) {
376 CFIIndex = MF.addFrameInst(
383 InsertedCFIInstr =
true;
386 PrevMBBInfo = &MBBInfo;
388 return InsertedCFIInstr;
391 void CFIInstrInserter::reportCFAError(
const MBBCFAInfo &Pred,
392 const MBBCFAInfo &Succ) {
393 errs() <<
"*** Inconsistent CFA register and/or offset between pred and succ "
395 errs() <<
"Pred: " << Pred.MBB->getName() <<
" #" << Pred.MBB->getNumber()
396 <<
" in " << Pred.MBB->getParent()->getName()
397 <<
" outgoing CFA Reg:" << Pred.OutgoingCFARegister <<
"\n";
398 errs() <<
"Pred: " << Pred.MBB->getName() <<
" #" << Pred.MBB->getNumber()
399 <<
" in " << Pred.MBB->getParent()->getName()
400 <<
" outgoing CFA Offset:" << Pred.OutgoingCFAOffset <<
"\n";
401 errs() <<
"Succ: " << Succ.MBB->getName() <<
" #" << Succ.MBB->getNumber()
402 <<
" incoming CFA Reg:" << Succ.IncomingCFARegister <<
"\n";
403 errs() <<
"Succ: " << Succ.MBB->getName() <<
" #" << Succ.MBB->getNumber()
404 <<
" incoming CFA Offset:" << Succ.IncomingCFAOffset <<
"\n";
407 void CFIInstrInserter::reportCSRError(
const MBBCFAInfo &Pred,
408 const MBBCFAInfo &Succ) {
409 errs() <<
"*** Inconsistent CSR Saved between pred and succ in function "
410 << Pred.MBB->getParent()->getName() <<
" ***\n";
411 errs() <<
"Pred: " << Pred.MBB->getName() <<
" #" << Pred.MBB->getNumber()
412 <<
" outgoing CSR Saved: ";
413 for (
int Reg : Pred.OutgoingCSRSaved.set_bits())
416 errs() <<
"Succ: " << Succ.MBB->getName() <<
" #" << Succ.MBB->getNumber()
417 <<
" incoming CSR Saved: ";
418 for (
int Reg : Succ.IncomingCSRSaved.set_bits())
424 unsigned ErrorNum = 0;
426 const MBBCFAInfo &CurrMBBInfo =
MBBVector[CurrMBB->getNumber()];
428 const MBBCFAInfo &SuccMBBInfo =
MBBVector[Succ->getNumber()];
431 if (SuccMBBInfo.IncomingCFAOffset != CurrMBBInfo.OutgoingCFAOffset ||
432 SuccMBBInfo.IncomingCFARegister != CurrMBBInfo.OutgoingCFARegister) {
435 if (SuccMBBInfo.MBB->succ_empty() && !SuccMBBInfo.MBB->isReturnBlock())
437 reportCFAError(CurrMBBInfo, SuccMBBInfo);
442 if (SuccMBBInfo.IncomingCSRSaved != CurrMBBInfo.OutgoingCSRSaved) {
443 reportCSRError(CurrMBBInfo, SuccMBBInfo);
This is an optimization pass for GlobalISel generic memory operations.
into xmm2 addss xmm2 xmm1 xmm3 addss xmm3 movaps xmm0 unpcklps xmm0 ret seems silly when it could just be one addps Expand libm rounding functions main should enable SSE DAZ mode and other fast SSE modes Think about doing i64 math in SSE regs on x86 This testcase should have no SSE instructions in it
virtual const TargetInstrInfo * getInstrInfo() const
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
static cl::opt< bool > VerifyCFI("verify-cfiinstrs", cl::desc("Verify Call Frame Information instructions"), cl::init(false), cl::Hidden)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
virtual Register getInitialCFARegister(const MachineFunction &MF) const
Return initial CFA register value i.e.
Reg
All possible values of the reg field in the ModR/M byte.
iterator_range< const_set_bits_iterator > set_bits() const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
unsigned const TargetRegisterInfo * TRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
const std::vector< MCCFIInstruction > & getFrameInstructions() const
Returns a reference to a list of cfi instructions in the function's prologue.
bool isBeginSection() const
Returns true if this block begins any section.
const MachineBasicBlock & front() const
TargetInstrInfo - Interface to description of machine instruction set.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Represent the analysis usage information of a pass.
const HexagonInstrInfo * TII
FunctionPass * createCFIInstrInserter()
Creates CFI Instruction Inserter pass.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
OpType getOperation() const
unsigned getRegister() const
void initializeCFIInstrInserterPass(PassRegistry &)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register)
.cfi_def_cfa_register modifies a rule for computing CFA.
SmallVector< MachineBasicBlock *, 4 > MBBVector
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Representation of each machine instruction.
initializer< Ty > init(const Ty &Val)
unsigned getRegister2() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int Offset)
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
INITIALIZE_PASS(CFIInstrInserter, "cfi-instr-inserter", "Check CFA info and insert CFI instructions if needed", false, false) FunctionPass *llvm
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
iterator_range< succ_iterator > successors()
MachineBasicBlock MachineBasicBlock::iterator MBBI
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
iterator_range< df_iterator< T > > depth_first(const T &G)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
virtual const TargetFrameLowering * getFrameLowering() const
bool needsFrameMoves() const
True if this function needs frame moves for debug or exceptions.
void setPreservesAll()
Set by analyses that do not transform their input at all.
into llvm powi allowing the code generator to produce balanced multiplication trees the intrinsic needs to be extended to support and second the code generator needs to be enhanced to lower these to multiplication trees Interesting testcase for add shift mul int y
static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1, unsigned Register2)
.cfi_register Previous value of Register1 is saved in register Register2.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
FunctionPass class - This class is used to implement most global optimizations.
virtual int getInitialCFAOffset(const MachineFunction &MF) const
Return initial CFA offset value i.e.
static BitVector & apply(F &&f, BitVector &Out, BitVector const &Arg, ArgTys const &...Args)
static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register)
.cfi_restore says that the rule for Register is now the same as it was at the beginning of the functi...