Skip to content

Commit f2faee9

Browse files
Correct dwarf unwind information in function epilogue for X86
This patch aims to provide correct dwarf unwind information in function epilogue for X86. It consists of two parts. The first part inserts CFI instructions that set appropriate cfa offset and cfa register in emitEpilogue() in X86FrameLowering. This part is X86 specific. The second part is platform independent and ensures that: - CFI instructions do not affect code generation - Unwind information remains correct when a function is modified by different passes. This is done in a late pass by analyzing information about cfa offset and cfa register in BBs and inserting additional CFI directives where necessary. Changed CFI instructions so that they: - are duplicable - are not counted as instructions when tail duplicating or tail merging - can be compared as equal Added CFIInstrInserter pass: - analyzes each basic block to determine cfa offset and register valid at its entry and exit - verifies that outgoing cfa offset and register of predecessor blocks match incoming values of their successors - inserts additional CFI directives at basic block beginning to correct the rule for calculating CFA Having CFI instructions in function epilogue can cause incorrect CFA calculation rule for some basic blocks. This can happen if, due to basic block reordering, or the existence of multiple epilogue blocks, some of the blocks have wrong cfa offset and register values set by the epilogue block above them. CFIInstrInserter is currently run only on X86, but can be used by any target that implements support for adding CFI instructions in epilogue. Patch by Violeta Vukobrat. Differential Revision: https://reviews.llvm.org/D35844 llvm-svn: 317100
1 parent e0d5184 commit f2faee9

File tree

99 files changed

+1689
-32
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+1689
-32
lines changed

llvm/include/llvm/CodeGen/Passes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,9 @@ namespace llvm {
417417
/// shuffles.
418418
FunctionPass *createExpandReductionsPass();
419419

420+
/// Creates CFI Instruction Inserter pass. \see CFIInstrInserter.cpp
421+
FunctionPass *createCFIInstrInserter();
422+
420423
} // End llvm namespace
421424

422425
#endif

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ void initializeCFGOnlyViewerLegacyPassPass(PassRegistry&);
8585
void initializeCFGPrinterLegacyPassPass(PassRegistry&);
8686
void initializeCFGSimplifyPassPass(PassRegistry&);
8787
void initializeCFGViewerLegacyPassPass(PassRegistry&);
88+
void initializeCFIInstrInserterPass(PassRegistry&);
8889
void initializeCFLAndersAAWrapperPassPass(PassRegistry&);
8990
void initializeCFLSteensAAWrapperPassPass(PassRegistry&);
9091
void initializeCallGraphDOTPrinterPass(PassRegistry&);

llvm/include/llvm/Target/Target.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,7 @@ def CFI_INSTRUCTION : Instruction {
902902
let InOperandList = (ins i32imm:$id);
903903
let AsmString = "";
904904
let hasCtrlDep = 1;
905-
let isNotDuplicable = 1;
905+
let isNotDuplicable = 0;
906906
}
907907
def EH_LABEL : Instruction {
908908
let OutOperandList = (outs);

llvm/include/llvm/Target/TargetFrameLowering.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,14 @@ class TargetFrameLowering {
341341
return false;
342342
return true;
343343
}
344+
345+
/// Return initial CFA offset value i.e. the one valid at the beginning of the
346+
/// function (before any stack operations).
347+
virtual int getInitialCFAOffset(const MachineFunction &MF) const;
348+
349+
/// Return initial CFA register value i.e. the one valid at the beginning of
350+
/// the function (before any stack operations).
351+
virtual unsigned getInitialCFARegister(const MachineFunction &MF) const;
344352
};
345353

346354
} // End llvm namespace

llvm/lib/CodeGen/BranchFolding.cpp

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,11 @@ static unsigned HashEndOfMBB(const MachineBasicBlock &MBB) {
296296
return HashMachineInstr(*I);
297297
}
298298

299+
// Whether MI should be counted as an instruction when calculating common tail.
300+
static bool countsAsInstruction(const MachineInstr &MI) {
301+
return !(MI.isDebugValue() || MI.isCFIInstruction());
302+
}
303+
299304
/// ComputeCommonTailLength - Given two machine basic blocks, compute the number
300305
/// of instructions they actually have in common together at their end. Return
301306
/// iterators for the first shared instruction in each block.
@@ -310,9 +315,9 @@ static unsigned ComputeCommonTailLength(MachineBasicBlock *MBB1,
310315
while (I1 != MBB1->begin() && I2 != MBB2->begin()) {
311316
--I1; --I2;
312317
// Skip debugging pseudos; necessary to avoid changing the code.
313-
while (I1->isDebugValue()) {
318+
while (!countsAsInstruction(*I1)) {
314319
if (I1==MBB1->begin()) {
315-
while (I2->isDebugValue()) {
320+
while (!countsAsInstruction(*I2)) {
316321
if (I2==MBB2->begin())
317322
// I1==DBG at begin; I2==DBG at begin
318323
return TailLen;
@@ -325,7 +330,7 @@ static unsigned ComputeCommonTailLength(MachineBasicBlock *MBB1,
325330
--I1;
326331
}
327332
// I1==first (untested) non-DBG preceding known match
328-
while (I2->isDebugValue()) {
333+
while (!countsAsInstruction(*I2)) {
329334
if (I2==MBB2->begin()) {
330335
++I1;
331336
// I1==non-DBG, or first of DBGs not at begin; I2==DBG at begin
@@ -368,6 +373,35 @@ static unsigned ComputeCommonTailLength(MachineBasicBlock *MBB1,
368373
}
369374
++I1;
370375
}
376+
377+
// Ensure that I1 and I2 do not point to a CFI_INSTRUCTION. This can happen if
378+
// I1 and I2 are non-identical when compared and then one or both of them ends
379+
// up pointing to a CFI instruction after being incremented. For example:
380+
/*
381+
BB1:
382+
...
383+
INSTRUCTION_A
384+
ADD32ri8 <- last common instruction
385+
...
386+
BB2:
387+
...
388+
INSTRUCTION_B
389+
CFI_INSTRUCTION
390+
ADD32ri8 <- last common instruction
391+
...
392+
*/
393+
// When INSTRUCTION_A and INSTRUCTION_B are compared as not equal, after
394+
// incrementing the iterators, I1 will point to ADD, however I2 will point to
395+
// the CFI instruction. Later on, this leads to BB2 being 'hacked off' at the
396+
// wrong place (in ReplaceTailWithBranchTo()) which results in losing this CFI
397+
// instruction.
398+
while (I1 != MBB1->end() && I1->isCFIInstruction()) {
399+
++I1;
400+
}
401+
402+
while (I2 != MBB2->end() && I2->isCFIInstruction()) {
403+
++I2;
404+
}
371405
return TailLen;
372406
}
373407

@@ -454,7 +488,7 @@ static unsigned EstimateRuntime(MachineBasicBlock::iterator I,
454488
MachineBasicBlock::iterator E) {
455489
unsigned Time = 0;
456490
for (; I != E; ++I) {
457-
if (I->isDebugValue())
491+
if (!countsAsInstruction(*I))
458492
continue;
459493
if (I->isCall())
460494
Time += 10;
@@ -814,12 +848,12 @@ mergeOperations(MachineBasicBlock::iterator MBBIStartPos,
814848
assert(MBBI != MBBIE && "Reached BB end within common tail length!");
815849
(void)MBBIE;
816850

817-
if (MBBI->isDebugValue()) {
851+
if (!countsAsInstruction(*MBBI)) {
818852
++MBBI;
819853
continue;
820854
}
821855

822-
while ((MBBICommon != MBBIECommon) && MBBICommon->isDebugValue())
856+
while ((MBBICommon != MBBIECommon) && !countsAsInstruction(*MBBICommon))
823857
++MBBICommon;
824858

825859
assert(MBBICommon != MBBIECommon &&
@@ -859,7 +893,7 @@ void BranchFolder::mergeCommonTails(unsigned commonTailIndex) {
859893
}
860894

861895
for (auto &MI : *MBB) {
862-
if (MI.isDebugValue())
896+
if (!countsAsInstruction(MI))
863897
continue;
864898
DebugLoc DL = MI.getDebugLoc();
865899
for (unsigned int i = 0 ; i < NextCommonInsts.size() ; i++) {
@@ -869,7 +903,7 @@ void BranchFolder::mergeCommonTails(unsigned commonTailIndex) {
869903
auto &Pos = NextCommonInsts[i];
870904
assert(Pos != SameTails[i].getBlock()->end() &&
871905
"Reached BB end within common tail");
872-
while (Pos->isDebugValue()) {
906+
while (!countsAsInstruction(*Pos)) {
873907
++Pos;
874908
assert(Pos != SameTails[i].getBlock()->end() &&
875909
"Reached BB end within common tail");

0 commit comments

Comments
 (0)