Skip to content

Commit 0a652c5

Browse files
committed
[codegen] Add StackFrameLayoutAnalysisPass
Issue #58168 describes the difficulty diagnosing stack size issues identified by -Wframe-larger-than. For simple code, its easy to understand the stack layout and where space is being allocated, but in more complex programs, where code may be heavily inlined, unrolled, and have duplicated code paths, it is no longer easy to manually inspect the source program and understand where stack space can be attributed. This patch implements a machine function pass that emits remarks with a textual representation of stack slots, and also outputs any available debug information to map source variables to those slots. The new behavior can be used by adding `-Rpass-analysis=stack-frame-layout` to the compiler invocation. Like other remarks the diagnostic information can be saved to a file in a machine readable format by adding -fsave-optimzation-record. Fixes: #58168 Reviewed By: nickdesaulniers, thegameg Differential Revision: https://reviews.llvm.org/D135488
1 parent e0f3a95 commit 0a652c5

23 files changed

+1302
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,11 @@ New Compiler Flags
540540
int b[0]; // NOT a flexible array member.
541541
};
542542
543+
- Added ``-Rpass-analysis=stack-frame-layout`` which will emit new diagnostic
544+
information about the layout of stack frames through the remarks
545+
infrastructure. Since it uses remarks the diagnostic information is available
546+
both on the CLI, and in a machine readable format.
547+
543548
Deprecated Compiler Flags
544549
-------------------------
545550
- ``-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang``

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1268,7 +1268,25 @@ def OpenMP : DiagGroup<"openmp", [
12681268
// Backend warnings.
12691269
def BackendInlineAsm : DiagGroup<"inline-asm">;
12701270
def BackendSourceMgr : DiagGroup<"source-mgr">;
1271-
def BackendFrameLargerThan : DiagGroup<"frame-larger-than">;
1271+
def BackendFrameLargerThan : DiagGroup<"frame-larger-than">{
1272+
code Documentation = [{
1273+
More fine grained information about the stack layout is available by adding the
1274+
`-Rpass-analysis=stack-frame-layout` command-line flag to the compiler
1275+
invocation.
1276+
1277+
The diagnostic information can be saved to a file in a machine readable format,
1278+
like YAML by adding the `-foptimization-record-file=<file>` command-line flag.
1279+
1280+
Results can be filtered by function name by passing
1281+
`-mllvm -filter-print-funcs=foo`, where `foo` is the target function's name.
1282+
1283+
.. code-block: console
1284+
clang -c a.cpp -Rpass-analysis=stack-frame-layout -mllvm -filter-print-funcs=foo
1285+
1286+
.. code-block: console
1287+
clang -c a.cpp -Rpass-analysis=stack-frame-layout -foptimization-record-file=<file>
1288+
}];
1289+
}
12721290
// Compatibility flag name from old versions of Clang.
12731291
def : DiagGroup<"frame-larger-than=", [BackendFrameLargerThan]>;
12741292
def BackendPlugin : DiagGroup<"backend-plugin">;
Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
// Check that backend stack layout diagnostics are working correctly with and
2+
// without debug information, and when optimizations are enabled
3+
//
4+
// REQUIRES: x86-registered-target
5+
//
6+
// RUN: rm -rf %t
7+
// RUN: mkdir -p %t
8+
// RUN: %clang_cc1 %s -emit-codegen-only -triple x86_64-unknown-linux-gnu -target-cpu corei7 -Rpass-analysis=stack-frame-layout -o /dev/null -O0 2>&1 | FileCheck %s --check-prefix=O0-NODEBUG
9+
// RUN: %clang_cc1 %s -emit-codegen-only -triple x86_64-unknown-linux-gnu -target-cpu corei7 -Rpass-analysis=stack-frame-layout -o /dev/null -O0 -debug-info-kind=constructor -dwarf-version=5 -debugger-tuning=gdb 2>&1 | FileCheck %s --check-prefix=O0-DEBUG
10+
// RUN: %clang_cc1 %s -emit-codegen-only -triple x86_64-unknown-linux-gnu -target-cpu corei7 -funwind-tables=2 -O3 -Rpass-analysis=stack-frame-layout -debug-info-kind=constructor -dwarf-version=5 -debugger-tuning=gdb -opt-record-file %t/stack-layout-remark.c.yml -opt-record-passes stack-frame-layout 2>&1 | FileCheck %s --check-prefix=O3-DEBUG
11+
// RUN: cat %t/stack-layout-remark.c.yml | FileCheck %s --check-prefix=YAML
12+
13+
#define NULL (void*)0
14+
15+
extern void* allocate(unsigned size);
16+
extern void deallocate(void* ptr);
17+
extern int work(char *ary, int size);
18+
extern int rand(void);
19+
20+
// Test YAML Ouput
21+
// YAML: --- !Analysis
22+
// YAML: Pass: stack-frame-layout
23+
// YAML: Name: StackLayout
24+
// YAML: DebugLoc: { File: '{{.*}}stack-layout-remark.c', Line: [[# @LINE + 24]],
25+
// YAML: Function: foo
26+
// YAML: Args:
27+
// YAML: - Offset: '-40'
28+
// YAML: - Type: Variable
29+
// YAML: - Align: '16'
30+
// YAML: - Size: '32'
31+
// YAML: - DataLoc: 'a @ {{.*}}stack-layout-remark.c:[[# @LINE + 19]]'
32+
// YAML: - DataLoc: 'f @ {{.*}}stack-layout-remark.c:[[# @LINE + 21]]'
33+
34+
// O0-NODEBUG: Function: foo
35+
// O0-NODEBUG-NEXT: Offset: [SP-40], Type: Variable, Align: 16, Size: 32
36+
// O0-NODEBUG-NEXT: Offset: [SP-72], Type: Variable, Align: 16, Size: 32
37+
//
38+
// O0-DEBUG: Function: foo
39+
// O0-DEBUG-NEXT: Offset: [SP-40], Type: Variable, Align: 16, Size: 32
40+
// O0-DEBUG-NEXT: a @ {{.*}}stack-layout-remark.c:[[# @LINE + 10]]
41+
// O0-DEBUG-NEXT: Offset: [SP-72], Type: Variable, Align: 16, Size: 32
42+
// O0-DEBUG-NEXT: f @ {{.*}}stack-layout-remark.c:[[# @LINE + 11]]
43+
44+
// O3-DEBUG: Function: foo
45+
// O3-DEBUG-NEXT: Offset: [SP-40], Type: Variable, Align: 16, Size: 32
46+
// O3-DEBUG-NEXT: a @ {{.*}}stack-layout-remark.c:[[# @LINE + 4]]
47+
// O3-DEBUG-NEXT: f @ {{.*}}stack-layout-remark.c:[[# @LINE + 6]]
48+
void foo() {
49+
{
50+
char a[32] = {0};
51+
work(a, sizeof(a));
52+
}
53+
char f[32] = {0};
54+
work(f, sizeof(f));
55+
}
56+
// O0-NODEBUG: Function: bar
57+
// O0-NODEBUG-NEXT: Offset: [SP-40], Type: Variable, Align: 16, Size: 32
58+
// O0-NODEBUG-NEXT: Offset: [SP-72], Type: Variable, Align: 16, Size: 32
59+
60+
// O0-DEBUG: Function: bar
61+
// O0-DEBUG-NEXT: Offset: [SP-40], Type: Variable, Align: 16, Size: 32
62+
// O0-DEBUG-NEXT: f @ {{.*}}stack-layout-remark.c:[[# @LINE + 10]]
63+
// O0-DEBUG-NEXT: Offset: [SP-72], Type: Variable, Align: 16, Size: 32
64+
// O0-DEBUG-NEXT: a @ {{.*}}stack-layout-remark.c:[[# @LINE + 10]]
65+
66+
// O3-DEBUG: Function: bar
67+
// O3-DEBUG-NEXT: Offset: [SP-40], Type: Variable, Align: 16, Size: 32
68+
// O3-DEBUG-NEXT: f @ {{.*}}stack-layout-remark.c:[[# @LINE + 4]]
69+
// O3-DEBUG-NEXT: Offset: [SP-72], Type: Variable, Align: 16, Size: 32
70+
// O3-DEBUG-NEXT: a @ {{.*}}stack-layout-remark.c:[[# @LINE + 4]]
71+
void bar() {
72+
char f[32] = {0};
73+
{
74+
char a[32] = {0};
75+
work(a, sizeof(a));
76+
}
77+
work(f, sizeof(f));
78+
}
79+
80+
struct Array {
81+
int *data;
82+
int size;
83+
};
84+
85+
struct Result {
86+
struct Array *data;
87+
int sum;
88+
};
89+
90+
// O0-NODEBUG: Function: cleanup_array
91+
// O0-NODEBUG-NEXT: Offset: [SP-8], Type: Variable, Align: 8, Size: 8
92+
93+
// O0-DEBUG: Function: cleanup_array
94+
// O0-DEBUG-NEXT: Offset: [SP-8], Type: Variable, Align: 8, Size: 8
95+
// O0-DEBUG-NEXT: a @ {{.*}}stack-layout-remark.c:[[# @LINE + 5]]
96+
97+
// O3-DEBUG: Function: cleanup_array
98+
// O3-DEBUG: Function: cleanup_result
99+
// O3-DEBUG-NEXT: Offset: [SP-8], Type: Spill, Align: 16, Size: 8
100+
void cleanup_array(struct Array *a) {
101+
if (!a)
102+
return;
103+
if (!a->data)
104+
return;
105+
deallocate(a->data);
106+
}
107+
108+
// O0-NODEBUG: Function: cleanup_result
109+
// O0-NODEBUG-NEXT: Offset: [SP-8], Type: Variable, Align: 8, Size: 8
110+
111+
// O0-DEBUG: Function: cleanup_result
112+
// O0-DEBUG-NEXT: Offset: [SP-8], Type: Variable, Align: 8, Size: 8
113+
// O0-DEBUG-NEXT: res @ {{.*}}stack-layout-remark.c:[[# @LINE + 1]]
114+
void cleanup_result(struct Result *res) {
115+
if (!res)
116+
return;
117+
if (!res->data)
118+
return;
119+
cleanup_array(res->data);
120+
deallocate(res->data);
121+
}
122+
123+
extern void use_dot_vector(struct Array *data);
124+
125+
// O0-NODEBUG: Function: do_work
126+
// O0-NODEBUG-NEXT: Offset: [SP-4], Type: Variable, Align: 4, Size: 4
127+
// O0-NODEBUG-NEXT: Offset: [SP-16], Type: Variable, Align: 8, Size: 8
128+
// O0-NODEBUG-NEXT: Offset: [SP-24], Type: Variable, Align: 8, Size: 8
129+
// O0-NODEBUG-NEXT: Offset: [SP-32], Type: Variable, Align: 8, Size: 8
130+
// O0-NODEBUG-NEXT: Offset: [SP-36], Type: Variable, Align: 4, Size: 4
131+
// O0-NODEBUG-NEXT: Offset: [SP-48], Type: Variable, Align: 8, Size: 8
132+
// O0-NODEBUG-NEXT: Offset: [SP-52], Type: Variable, Align: 4, Size: 4
133+
// O0-NODEBUG-NEXT: Offset: [SP-56], Type: Variable, Align: 4, Size: 4
134+
135+
// O0-DEBUG: Function: do_work
136+
// O0-DEBUG-NEXT: Offset: [SP-4], Type: Variable, Align: 4, Size: 4
137+
// O0-DEBUG-NEXT: Offset: [SP-16], Type: Variable, Align: 8, Size: 8
138+
// O0-DEBUG-NEXT: A @ {{.*}}stack-layout-remark.c:[[# @LINE + 20]]
139+
// O0-DEBUG-NEXT: Offset: [SP-24], Type: Variable, Align: 8, Size: 8
140+
// O0-DEBUG-NEXT: B @ {{.*}}stack-layout-remark.c:[[# @LINE + 18]]
141+
// O0-DEBUG-NEXT: Offset: [SP-32], Type: Variable, Align: 8, Size: 8
142+
// O0-DEBUG-NEXT: out @ {{.*}}stack-layout-remark.c:[[# @LINE + 16]]
143+
// O0-DEBUG-NEXT: Offset: [SP-36], Type: Variable, Align: 4, Size: 4
144+
// O0-DEBUG-NEXT: len @ {{.*}}stack-layout-remark.c:[[# @LINE + 19]]
145+
// O0-DEBUG-NEXT: Offset: [SP-48], Type: Variable, Align: 8, Size: 8
146+
// O0-DEBUG-NEXT: AB @ {{.*}}stack-layout-remark.c:[[# @LINE + 18]]
147+
// O0-DEBUG-NEXT: Offset: [SP-52], Type: Variable, Align: 4, Size: 4
148+
// O0-DEBUG-NEXT: sum @ {{.*}}stack-layout-remark.c:[[# @LINE + 32]]
149+
// O0-DEBUG-NEXT: Offset: [SP-56], Type: Variable, Align: 4, Size: 4
150+
// O0-DEBUG-NEXT: i @ {{.*}}stack-layout-remark.c:[[# @LINE + 31]]
151+
152+
// O3-DEBUG: Function: do_work
153+
// O3-DEBUG-NEXT: Offset: [SP-8], Type: Spill, Align: 16, Size: 8
154+
// O3-DEBUG-NEXT: Offset: [SP-16], Type: Spill, Align: 8, Size: 8
155+
// O3-DEBUG-NEXT: Offset: [SP-24], Type: Spill, Align: 16, Size: 8
156+
// O3-DEBUG-NEXT: Offset: [SP-32], Type: Spill, Align: 8, Size: 8
157+
// O3-DEBUG-NEXT: Offset: [SP-40], Type: Spill, Align: 16, Size: 8
158+
int do_work(struct Array *A, struct Array *B, struct Result *out) {
159+
if (!A || !B)
160+
return -1;
161+
if (A->size != B->size)
162+
return -1;
163+
const int len = A->size;
164+
struct Array *AB;
165+
if (out->data == NULL) {
166+
AB = (struct Array *)allocate(sizeof(struct Array));
167+
AB->data = NULL;
168+
AB->size = 0;
169+
out->data = AB;
170+
} else {
171+
AB = out->data;
172+
}
173+
174+
if (AB->data)
175+
deallocate(AB->data);
176+
177+
AB->data = (int *)allocate(len * sizeof(int));
178+
AB->size = len;
179+
180+
int sum = 0;
181+
for (int i = 0; i < len; ++i) {
182+
AB->data[i] = A->data[i] * B->data[i];
183+
sum += AB->data[i];
184+
}
185+
return sum;
186+
}
187+
188+
// O0-NODEBUG: Function: gen_array
189+
// O0-NODEBUG-NEXT: Offset: [SP-8], Type: Variable, Align: 8, Size: 8
190+
// O0-NODEBUG-NEXT: Offset: [SP-12], Type: Variable, Align: 4, Size: 4
191+
// O0-NODEBUG-NEXT: Offset: [SP-24], Type: Variable, Align: 8, Size: 8
192+
// O0-NODEBUG-NEXT: Offset: [SP-28], Type: Variable, Align: 4, Size: 4
193+
194+
// O0-DEBUG: Function: gen_array
195+
// O0-DEBUG-NEXT: Offset: [SP-8], Type: Variable, Align: 8, Size: 8
196+
// O0-DEBUG-NEXT: Offset: [SP-12], Type: Variable, Align: 4, Size: 4
197+
// O0-DEBUG-NEXT: size @ {{.*}}stack-layout-remark.c:[[# @LINE + 10]]
198+
// O0-DEBUG-NEXT: Offset: [SP-24], Type: Variable, Align: 8, Size: 8
199+
// O0-DEBUG-NEXT: res @ {{.*}}stack-layout-remark.c:[[# @LINE + 11]]
200+
// O0-DEBUG-NEXT: Offset: [SP-28], Type: Variable, Align: 4, Size: 4
201+
// O0-DEBUG-NEXT: i @ {{.*}}stack-layout-remark.c:[[# @LINE + 13]]
202+
203+
// O3-DEBUG: Function: gen_array
204+
// O3-DEBUG-NEXT: Offset: [SP-8], Type: Spill, Align: 16, Size: 8
205+
// O3-DEBUG-NEXT: Offset: [SP-16], Type: Spill, Align: 8, Size: 8
206+
// O3-DEBUG-NEXT: Offset: [SP-24], Type: Spill, Align: 16, Size: 8
207+
struct Array *gen_array(int size) {
208+
if (size < 0)
209+
return NULL;
210+
struct Array *res = (struct Array *)allocate(sizeof(struct Array));
211+
res->size = size;
212+
res->data = (int *)allocate(size * sizeof(int));
213+
214+
for (int i = 0; i < size; ++i) {
215+
res->data[i] = rand();
216+
}
217+
218+
return res;
219+
}
220+
221+
// YAML: --- !Analysis
222+
// YAML: Pass: stack-frame-layout
223+
// YAML: Name: StackLayout
224+
// YAML: DebugLoc: { File: '{{.*}}stack-layout-remark.c', Line: [[# @LINE + 59]]
225+
// YAML: Function: caller
226+
// YAML: Args:
227+
// YAML: - Offset: '-8'
228+
// YAML: - Type: Spill
229+
// YAML: - Align: '16'
230+
// YAML: - Size: '8'
231+
// YAML: - Offset: '-16'
232+
// YAML: - Type: Spill
233+
// YAML: - Align: '8'
234+
// YAML: - Size: '8'
235+
// YAML: - Offset: '-24'
236+
// YAML: - Type: Spill
237+
// YAML: - Align: '16'
238+
// YAML: - Size: '8'
239+
// YAML: - Offset: '-32'
240+
// YAML: - Type: Spill
241+
// YAML: - Align: '8'
242+
// YAML: - Size: '8'
243+
// YAML: - Offset: '-40'
244+
// YAML: - Type: Spill
245+
// YAML: - Align: '16'
246+
// YAML: - Size: '8'
247+
// YAML: - Offset: '-48'
248+
// YAML: - Type: Spill
249+
// YAML: - Align: '8'
250+
// YAML: - Size: '8'
251+
252+
// O0-NODEBUG: Function: caller
253+
// O0-NODEBUG-NEXT: Offset: [SP-4], Type: Variable, Align: 4, Size: 4
254+
// O0-NODEBUG-NEXT: Offset: [SP-8], Type: Variable, Align: 4, Size: 4
255+
// O0-NODEBUG-NEXT: Offset: [SP-16], Type: Variable, Align: 8, Size: 8
256+
// O0-NODEBUG-NEXT: Offset: [SP-24], Type: Variable, Align: 8, Size: 8
257+
// O0-NODEBUG-NEXT: Offset: [SP-32], Type: Variable, Align: 8, Size: 8
258+
// O0-NODEBUG-NEXT: Offset: [SP-36], Type: Variable, Align: 4, Size: 4
259+
// O0-NODEBUG-NEXT: Offset: [SP-40], Type: Variable, Align: 4, Size: 4
260+
261+
// O0-DEBUG: Function: caller
262+
// O0-DEBUG-NEXT: Offset: [SP-4], Type: Variable, Align: 4, Size: 4
263+
// O0-DEBUG-NEXT: Offset: [SP-8], Type: Variable, Align: 4, Size: 4
264+
// O0-DEBUG-NEXT: size @ {{.*}}stack-layout-remark.c:[[# @LINE + 20]]
265+
// O0-DEBUG-NEXT: Offset: [SP-16], Type: Variable, Align: 8, Size: 8
266+
// O0-DEBUG-NEXT: A @ {{.*}}stack-layout-remark.c:[[# @LINE + 19]]
267+
// O0-DEBUG-NEXT: Offset: [SP-24], Type: Variable, Align: 8, Size: 8
268+
// O0-DEBUG-NEXT: B @ {{.*}}stack-layout-remark.c:[[# @LINE + 18]]
269+
// O0-DEBUG-NEXT: Offset: [SP-32], Type: Variable, Align: 8, Size: 8
270+
// O0-DEBUG-NEXT: res @ {{.*}}stack-layout-remark.c:[[# @LINE + 17]]
271+
// O0-DEBUG-NEXT: Offset: [SP-36], Type: Variable, Align: 4, Size: 4
272+
// O0-DEBUG-NEXT: ret @ {{.*}}stack-layout-remark.c:[[# @LINE + 16]]
273+
// O0-DEBUG-NEXT: Offset: [SP-40], Type: Variable, Align: 4, Size: 4
274+
// O0-DEBUG-NEXT: err @ {{.*}}stack-layout-remark.c:[[# @LINE + 16]]
275+
276+
// O3-DEBUG: Function: caller
277+
// O3-DEBUG-NEXT: Offset: [SP-8], Type: Spill, Align: 16, Size: 8
278+
// O3-DEBUG-NEXT: Offset: [SP-16], Type: Spill, Align: 8, Size: 8
279+
// O3-DEBUG-NEXT: Offset: [SP-24], Type: Spill, Align: 16, Size: 8
280+
// O3-DEBUG-NEXT: Offset: [SP-32], Type: Spill, Align: 8, Size: 8
281+
// O3-DEBUG-NEXT: Offset: [SP-40], Type: Spill, Align: 16, Size: 8
282+
// O3-DEBUG-NEXT: Offset: [SP-48], Type: Spill, Align: 8, Size: 8
283+
int caller() {
284+
const int size = 100;
285+
struct Array *A = gen_array(size);
286+
struct Array *B = gen_array(size);
287+
struct Result *res = (struct Result *)allocate(sizeof(struct Result));
288+
int ret = -1;
289+
290+
int err = do_work(A, B, res);
291+
if (err == -1) {
292+
goto cleanup;
293+
}
294+
295+
ret = res->sum;
296+
if (ret == -1)
297+
return caller();
298+
299+
use_dot_vector(res->data);
300+
301+
cleanup:
302+
cleanup_array(A);
303+
cleanup_array(B);
304+
cleanup_result(res);
305+
306+
return ret;
307+
}
308+

llvm/include/llvm/CodeGen/Passes.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ namespace llvm {
6363
createMachineFunctionPrinterPass(raw_ostream &OS,
6464
const std::string &Banner ="");
6565

66+
/// StackFramePrinter pass - This pass prints out the machine function's
67+
/// stack frame to the given stream as a debugging tool.
68+
MachineFunctionPass *createStackFrameLayoutAnalysisPass();
69+
6670
/// MIRPrinting pass - this pass prints out the LLVM IR into the given stream
6771
/// using the MIR serialization format.
6872
MachineFunctionPass *createPrintMIRPass(raw_ostream &OS);
@@ -264,6 +268,10 @@ namespace llvm {
264268
/// It merges disjoint allocas to reduce the stack size.
265269
extern char &StackColoringID;
266270

271+
/// StackFramePrinter - This pass prints the stack frame layout and variable
272+
/// mappings.
273+
extern char &StackFrameLayoutAnalysisPassID;
274+
267275
/// IfConverter - This pass performs machine code if conversion.
268276
extern char &IfConverterID;
269277

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ void initializeSlotIndexesPass(PassRegistry&);
378378
void initializeSpeculativeExecutionLegacyPassPass(PassRegistry&);
379379
void initializeSpillPlacementPass(PassRegistry&);
380380
void initializeStackColoringPass(PassRegistry&);
381+
void initializeStackFrameLayoutAnalysisPassPass(PassRegistry &);
381382
void initializeStackMapLivenessPass(PassRegistry&);
382383
void initializeStackProtectorPass(PassRegistry&);
383384
void initializeStackSafetyGlobalInfoWrapperPassPass(PassRegistry &);

llvm/lib/CodeGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ add_llvm_component_library(LLVMCodeGen
213213
SpillPlacement.cpp
214214
SplitKit.cpp
215215
StackColoring.cpp
216+
StackFrameLayoutAnalysisPass.cpp
216217
StackMapLivenessAnalysis.cpp
217218
StackMaps.cpp
218219
StackProtector.cpp

llvm/lib/CodeGen/CodeGen.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
122122
initializeSjLjEHPreparePass(Registry);
123123
initializeSlotIndexesPass(Registry);
124124
initializeStackColoringPass(Registry);
125+
initializeStackFrameLayoutAnalysisPassPass(Registry);
125126
initializeStackMapLivenessPass(Registry);
126127
initializeStackProtectorPass(Registry);
127128
initializeStackSlotColoringPass(Registry);

0 commit comments

Comments
 (0)