llvm.org GIT mirror llvm / f7fc15e
[X86] Always generate precise CFA adjustments. This removes the code path that generate "synchronous" (only correct at call site) CFA. We will probably want to re-introduce it once we are capable of emitting different .eh_frame and .debug_frame sections. Differential Revision: http://reviews.llvm.org/D14948 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254874 91177308-0d34-0410-b5e6-96231b3b80d8 Michael Kuperstein 4 years ago
7 changed file(s) with 76 addition(s) and 36 deletion(s). Raw diff Collapse all Expand all
160160 bool CallsUnwindInit;
161161 bool HasEHFunclets;
162162
163 // TODO: Ideally, what we'd like is to have a switch that allows emitting
164 // synchronous (precise at call-sites only) CFA into .eh_frame. However,
165 // even under this switch, we'd like .debug_frame to be precise when using.
166 // -g. At this moment, there's no way to specify that some CFI directives
167 // go into .eh_frame only, while others go into .debug_frame only.
168
163169 /// DbgInfoAvailable - True if debugging information is available
164170 /// in this module.
165171 bool DbgInfoAvailable;
234240 bool hasDebugInfo() const { return DbgInfoAvailable; }
235241 void setDebugInfoAvailability(bool avail) { DbgInfoAvailable = avail; }
236242
237 // Returns true if we need to generate precise CFI. Currently
238 // this is equivalent to hasDebugInfo(), but if we ever implement
239 // async EH, it will require precise CFI as well.
240 bool usePreciseUnwindInfo() const { return hasDebugInfo(); }
241
242243 bool callsEHReturn() const { return CallsEHReturn; }
243244 void setCallsEHReturn(bool b) { CallsEHReturn = b; }
244245
499499
500500 // For debugging, when using SP-based CFA, we need to adjust the CFA
501501 // offset after each push.
502 if (!TFL->hasFP(MF) && MF.getMMI().usePreciseUnwindInfo())
502 // TODO: This is needed only if we require precise CFA.
503 if (!TFL->hasFP(MF))
503504 TFL->BuildCFI(MBB, std::next(Push), DL,
504505 MCCFIInstruction::createAdjustCfaOffset(nullptr, 4));
505506
25232523 // (Pushes of argument for frame setup, callee pops for frame destroy)
25242524 Amount -= InternalAmt;
25252525
2526 // If this is a callee-pop calling convention, and we're emitting precise
2527 // SP-based CFI, emit a CFA adjust for the amount the callee popped.
2528 if (isDestroy && InternalAmt && DwarfCFI && !hasFP(MF) &&
2529 MMI.usePreciseUnwindInfo())
2526 // TODO: This is needed only if we require precise CFA.
2527 // If this is a callee-pop calling convention, emit a CFA adjust for
2528 // the amount the callee popped.
2529 if (isDestroy && InternalAmt && DwarfCFI && !hasFP(MF))
25302530 BuildCFI(MBB, I, DL,
25312531 MCCFIInstruction::createAdjustCfaOffset(nullptr, -InternalAmt));
25322532
25472547 // offset to be correct at each call site, while for debugging we want
25482548 // it to be more precise.
25492549 int CFAOffset = Amount;
2550 if (!MMI.usePreciseUnwindInfo())
2551 CFAOffset += InternalAmt;
2552 CFAOffset = isDestroy ? -CFAOffset : CFAOffset;
2553 BuildCFI(MBB, I, DL,
2554 MCCFIInstruction::createAdjustCfaOffset(nullptr, CFAOffset));
2550 // TODO: When not using precise CFA, we also need to adjust for the
2551 // InternalAmt here.
2552
2553 if (CFAOffset) {
2554 CFAOffset = isDestroy ? -CFAOffset : CFAOffset;
2555 BuildCFI(MBB, I, DL,
2556 MCCFIInstruction::createAdjustCfaOffset(nullptr, CFAOffset));
2557 }
25552558 }
25562559
25572560 return;
11421142 const X86FrameLowering* FrameLowering =
11431143 MF->getSubtarget().getFrameLowering();
11441144 bool hasFP = FrameLowering->hasFP(*MF);
1145
1146 bool NeedsDwarfCFI = MMI->usePreciseUnwindInfo();
1145
1146 // TODO: This is needed only if we require precise CFA.
1147 bool NeedsDwarfCFI =
1148 (MMI->hasDebugInfo() || MF->getFunction()->needsUnwindTableEntry());
11471149 int stackGrowth = -RI->getSlotSize();
11481150
11491151 if (NeedsDwarfCFI && !hasFP) {
55 declare void @large(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f)
66 declare void @empty()
77
8 ; When we use an invoke, and have FP, we expect a .cfi_escape GNU_ARGS_SIZE
9 ; with size 16 before the invocation. Without FP, we expect.cfi_adjust_cfa_offset
10 ; before and after.
11 ; Darwin should not generate pushes in neither circumstance.
8 ; When we use an invoke, we expect a .cfi_escape GNU_ARGS_SIZE
9 ; with size 16 before the invocation. Without FP, we also expect
10 ; .cfi_adjust_cfa_offset after each push.
11 ; Darwin should not generate pushes in either circumstance.
1212 ; CHECK-LABEL: test1_nofp:
1313 ; LINUX: .cfi_escape 0x2e, 0x10
14 ; LINUX: .cfi_adjust_cfa_offset 16
15 ; LINUX-NEXT: pushl $4
16 ; LINUX-NEXT: pushl $3
17 ; LINUX-NEXT: pushl $2
18 ; LINUX-NEXT: pushl $1
14 ; LINUX-NEXT: pushl $4
15 ; LINUX-NEXT: Ltmp{{[0-9]+}}:
16 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
17 ; LINUX-NEXT: pushl $3
18 ; LINUX-NEXT: Ltmp{{[0-9]+}}:
19 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
20 ; LINUX-NEXT: pushl $2
21 ; LINUX-NEXT: Ltmp{{[0-9]+}}:
22 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
23 ; LINUX-NEXT: pushl $1
24 ; LINUX-NEXT: Ltmp{{[0-9]+}}:
25 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
1926 ; LINUX-NEXT: call
2027 ; LINUX-NEXT: addl $16, %esp
2128 ; LINUX: .cfi_adjust_cfa_offset -16
6168 ; so darwin should not generate pushes.
6269 ; CHECK-LABEL: test2_nofp:
6370 ; LINUX-NOT: .cfi_escape
64 ; LINUX: .cfi_adjust_cfa_offset 16
65 ; LINUX-NEXT: pushl $4
66 ; LINUX-NEXT: pushl $3
67 ; LINUX-NEXT: pushl $2
68 ; LINUX-NEXT: pushl $1
71 ; LINUX: pushl $4
72 ; LINUX-NEXT: Ltmp{{[0-9]+}}:
73 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
74 ; LINUX-NEXT: pushl $3
75 ; LINUX-NEXT: Ltmp{{[0-9]+}}:
76 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
77 ; LINUX-NEXT: pushl $2
78 ; LINUX-NEXT: Ltmp{{[0-9]+}}:
79 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
80 ; LINUX-NEXT: pushl $1
81 ; LINUX-NEXT: Ltmp{{[0-9]+}}:
82 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
6983 ; LINUX-NEXT: call
7084 ; LINUX-NEXT: addl $16, %esp
7185 ; LINUX: .cfi_adjust_cfa_offset -16
169183 ; without parameters, but don't need to adjust the cfa offset
170184 ; CHECK-LABEL: test5_nofp:
171185 ; LINUX: .cfi_escape 0x2e, 0x10
172 ; LINUX: .cfi_adjust_cfa_offset 16
173 ; LINUX-NEXT: pushl $4
174 ; LINUX-NEXT: pushl $3
175 ; LINUX-NEXT: pushl $2
176 ; LINUX-NEXT: pushl $1
186 ; LINUX-NEXT: pushl $4
187 ; LINUX-NEXT: Ltmp{{[0-9]+}}:
188 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
189 ; LINUX-NEXT: pushl $3
190 ; LINUX-NEXT: Ltmp{{[0-9]+}}:
191 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
192 ; LINUX-NEXT: pushl $2
193 ; LINUX-NEXT: Ltmp{{[0-9]+}}:
194 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
195 ; LINUX-NEXT: pushl $1
196 ; LINUX-NEXT: Ltmp{{[0-9]+}}:
197 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
177198 ; LINUX-NEXT: call
178199 ; LINUX-NEXT: addl $16, %esp
179200 ; LINUX: .cfi_adjust_cfa_offset -16
3535 define i32 @f3() {
3636 ; X32-LABEL: f3:
3737 ; X32: calll .L{{[0-9]+}}$pb
38 ; X32-NEXT: .Ltmp{{[0-9]+}}:
39 ; X32-NEXT: .cfi_adjust_cfa_offset 4
3840 ; X32-NEXT: .L{{[0-9]+}}$pb:
3941 ; X32-NEXT: popl %eax
42 ; X32-NEXT: .Ltmp{{[0-9]+}}:
43 ; X32-NEXT: .cfi_adjust_cfa_offset -4
4044 ; X32-NEXT: .Ltmp{{[0-9]+}}:
4145 ; X32-NEXT: addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp{{[0-9]+}}-.L{{[0-9]+}}$pb), %eax
4246 ; X32-NEXT: movl i2@GOTNTPOFF(%eax), %eax
5559 define i32* @f4() {
5660 ; X32-LABEL: f4:
5761 ; X32: calll .L{{[0-9]+}}$pb
62 ; X32-NEXT: .Ltmp{{[0-9]+}}:
63 ; X32-NEXT: .cfi_adjust_cfa_offset 4
5864 ; X32-NEXT: .L{{[0-9]+}}$pb:
5965 ; X32-NEXT: popl %ecx
66 ; X32-NEXT: .Ltmp{{[0-9]+}}:
67 ; X32-NEXT: .cfi_adjust_cfa_offset -4
6068 ; X32-NEXT: .Ltmp{{[0-9]+}}:
6169 ; X32-NEXT: addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp{{[0-9]+}}-.L{{[0-9]+}}$pb), %ecx
6270 ; X32-NEXT: movl %gs:0, %eax
0 ; RUN: llc < %s -relocation-model=pic | FileCheck %s
11
22 ; CHECK: calll L0$pb
3 ; CHECK-NEXT: Ltmp{{[0-9]+}}:
4 ; CHECK-NEXT: .cfi_adjust_cfa_offset 4
35 ; CHECK-NEXT: L0$pb:
46 ; CHECK-NEXT: popl %eax
7 ; CHECK-NEXT: Ltmp{{[0-9]+}}:
8 ; CHECK-NEXT: .cfi_adjust_cfa_offset -4
59 ; CHECK-NEXT: addl LJTI0_0(,%ecx,4), %eax
610 ; CHECK-NEXT: jmpl *%eax
711