Skip to content

Commit 2f4eac6

Browse files
authored
[clang][ARM] disable frame pointers by default for bare metal ARM targets (#117140)
because: - This brings Clang in line with GCC for which this is the default for ARM - It frees up a register, so performance increase, especially on Thumb/6-M - It will decrease code size
1 parent 37797d3 commit 2f4eac6

File tree

5 files changed

+80
-23
lines changed

5 files changed

+80
-23
lines changed

clang/lib/Driver/ToolChains/Arch/ARM.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,26 @@ bool arm::isARMAProfile(const llvm::Triple &Triple) {
5252
return llvm::ARM::parseArchProfile(Arch) == llvm::ARM::ProfileKind::A;
5353
}
5454

55+
/// Is the triple {arm,armeb,thumb,thumbeb}-none-none-{eabi,eabihf} ?
56+
bool arm::isARMEABIBareMetal(const llvm::Triple &Triple) {
57+
auto arch = Triple.getArch();
58+
if (arch != llvm::Triple::arm && arch != llvm::Triple::thumb &&
59+
arch != llvm::Triple::armeb && arch != llvm::Triple::thumbeb)
60+
return false;
61+
62+
if (Triple.getVendor() != llvm::Triple::UnknownVendor)
63+
return false;
64+
65+
if (Triple.getOS() != llvm::Triple::UnknownOS)
66+
return false;
67+
68+
if (Triple.getEnvironment() != llvm::Triple::EABI &&
69+
Triple.getEnvironment() != llvm::Triple::EABIHF)
70+
return false;
71+
72+
return true;
73+
}
74+
5575
// Get Arch/CPU from args.
5676
void arm::getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch,
5777
llvm::StringRef &CPU, bool FromAs) {

clang/lib/Driver/ToolChains/Arch/ARM.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ int getARMSubArchVersionNumber(const llvm::Triple &Triple);
7575
bool isARMMProfile(const llvm::Triple &Triple);
7676
bool isARMAProfile(const llvm::Triple &Triple);
7777
bool isARMBigEndian(const llvm::Triple &Triple, const llvm::opt::ArgList &Args);
78+
bool isARMEABIBareMetal(const llvm::Triple &Triple);
7879

7980
} // end namespace arm
8081
} // end namespace tools

clang/lib/Driver/ToolChains/BareMetal.cpp

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -128,27 +128,6 @@ BareMetal::BareMetal(const Driver &D, const llvm::Triple &Triple,
128128
}
129129
}
130130

131-
/// Is the triple {arm,armeb,thumb,thumbeb}-none-none-{eabi,eabihf} ?
132-
static bool isARMBareMetal(const llvm::Triple &Triple) {
133-
if (Triple.getArch() != llvm::Triple::arm &&
134-
Triple.getArch() != llvm::Triple::thumb &&
135-
Triple.getArch() != llvm::Triple::armeb &&
136-
Triple.getArch() != llvm::Triple::thumbeb)
137-
return false;
138-
139-
if (Triple.getVendor() != llvm::Triple::UnknownVendor)
140-
return false;
141-
142-
if (Triple.getOS() != llvm::Triple::UnknownOS)
143-
return false;
144-
145-
if (Triple.getEnvironment() != llvm::Triple::EABI &&
146-
Triple.getEnvironment() != llvm::Triple::EABIHF)
147-
return false;
148-
149-
return true;
150-
}
151-
152131
/// Is the triple {aarch64.aarch64_be}-none-elf?
153132
static bool isAArch64BareMetal(const llvm::Triple &Triple) {
154133
if (Triple.getArch() != llvm::Triple::aarch64 &&
@@ -267,7 +246,7 @@ void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple,
267246
}
268247

269248
bool BareMetal::handlesTarget(const llvm::Triple &Triple) {
270-
return isARMBareMetal(Triple) || isAArch64BareMetal(Triple) ||
249+
return arm::isARMEABIBareMetal(Triple) || isAArch64BareMetal(Triple) ||
271250
isRISCVBareMetal(Triple) || isPPCBareMetal(Triple);
272251
}
273252

@@ -561,7 +540,7 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
561540
// The R_ARM_TARGET2 relocation must be treated as R_ARM_REL32 on arm*-*-elf
562541
// and arm*-*-eabi (the default is R_ARM_GOT_PREL, used on arm*-*-linux and
563542
// arm*-*-*bsd).
564-
if (isARMBareMetal(TC.getTriple()))
543+
if (arm::isARMEABIBareMetal(TC.getTriple()))
565544
CmdArgs.push_back("--target2=rel");
566545

567546
CmdArgs.push_back("-o");

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "Arch/SystemZ.h"
2020
#include "Arch/VE.h"
2121
#include "Arch/X86.h"
22+
#include "BareMetal.h"
2223
#include "HIPAMD.h"
2324
#include "Hexagon.h"
2425
#include "MSP430.h"
@@ -151,6 +152,9 @@ static bool useFramePointerForTargetByDefault(const llvm::opt::ArgList &Args,
151152
}
152153
}
153154

155+
if (arm::isARMEABIBareMetal(Triple))
156+
return false;
157+
154158
return true;
155159
}
156160

clang/test/Driver/frame-pointer-elim.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,5 +162,58 @@
162162
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
163163
// RUN: not %clang -### --target=riscv64-linux-android -mbig-endian -O1 -S %s 2>&1 | \
164164
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
165+
166+
// On ARM backend bare metal targets, frame pointer is omitted
167+
// RUN: %clang -### --target=arm-arm-none-eabi -S %s 2>&1 | \
168+
// RUN: FileCheck --check-prefix=KEEP-NONE %s
169+
// RUN: %clang -### --target=arm-arm-none-eabihf -S %s 2>&1 | \
170+
// RUN: FileCheck --check-prefix=KEEP-NONE %s
171+
// RUN: %clang -### --target=arm-arm-none-eabi -S -fno-omit-frame-pointer %s 2>&1 | \
172+
// RUN: FileCheck --check-prefix=KEEP-ALL %s
173+
// RUN: %clang -### --target=arm-arm-none-eabihf -S -fno-omit-frame-pointer %s 2>&1 | \
174+
// RUN: FileCheck --check-prefix=KEEP-ALL %s
175+
// RUN: %clang -### --target=arm-arm-none-eabi -S -O1 %s 2>&1 | \
176+
// RUN: FileCheck --check-prefix=KEEP-NONE %s
177+
// RUN: %clang -### --target=arm-arm-none-eabihf -S -O1 %s 2>&1 | \
178+
// RUN: FileCheck --check-prefix=KEEP-NONE %s
179+
// RUN: %clang -### --target=arm-arm-none-eabi -S -O1 -fno-omit-frame-pointer %s 2>&1 | \
180+
// RUN: FileCheck --check-prefix=KEEP-ALL %s
181+
// RUN: %clang -### --target=arm-arm-none-eabihf -S -O1 -fno-omit-frame-pointer %s 2>&1 | \
182+
// RUN: FileCheck --check-prefix=KEEP-ALL %s
183+
// RUN: %clang -### --target=armeb-arm-none-eabi -S %s 2>&1 | \
184+
// RUN: FileCheck --check-prefix=KEEP-NONE %s
185+
// RUN: %clang -### --target=thumb-arm-none-eabi -S %s 2>&1 | \
186+
// RUN: FileCheck --check-prefix=KEEP-NONE %s
187+
// RUN: %clang -### --target=thumbeb-arm-none-eabi -S %s 2>&1 | \
188+
// RUN: FileCheck --check-prefix=KEEP-NONE %s
189+
190+
// Check that for Apple bare metal targets, we're keeping frame pointers by default
191+
// RUN: %clang -### --target=thumbv6m-apple-none-macho -S %s 2>&1 | \
192+
// RUN: FileCheck --check-prefix=KEEP-ALL %s
193+
// RUN: %clang -### --target=thumbv6m-apple-none-macho -S -fno-omit-frame-pointer %s 2>&1 | \
194+
// RUN: FileCheck --check-prefix=KEEP-ALL %s
195+
// RUN: %clang -### --target=arm-apple-none-macho -S %s 2>&1 | \
196+
// RUN: FileCheck --check-prefix=KEEP-ALL %s
197+
// RUN: %clang -### --target=arm-apple-none-macho -S -fno-omit-frame-pointer %s 2>&1 | \
198+
// RUN: FileCheck --check-prefix=KEEP-ALL %s
199+
// RUN: %clang -### --target=thumbv6m-apple-none-macho -S -O1 %s 2>&1 | \
200+
// RUN: FileCheck --check-prefix=KEEP-ALL %s
201+
// RUN: %clang -### --target=thumbv6m-apple-none-macho -S -O1 -fno-omit-frame-pointer %s 2>&1 | \
202+
// RUN: FileCheck --check-prefix=KEEP-ALL %s
203+
// RUN: %clang -### --target=arm-apple-none-macho -S -O1 %s 2>&1 | \
204+
// RUN: FileCheck --check-prefix=KEEP-ALL %s
205+
// RUN: %clang -### --target=arm-apple-none-macho -S -O1 -fno-omit-frame-pointer %s 2>&1 | \
206+
// RUN: FileCheck --check-prefix=KEEP-ALL %s
207+
208+
// AArch64 bare metal targets behave like hosted targets
209+
// RUN: %clang -### --target=aarch64-none-elf -S %s 2>&1 | \
210+
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
211+
// RUN: %clang -### --target=aarch64-none-elf -S -O1 %s 2>&1 | \
212+
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
213+
// RUN: %clang -### --target=aarch64-none-elf -S -fno-omit-frame-pointer %s 2>&1 | \
214+
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
215+
// RUN: %clang -### --target=aarch64-none-elf -S -O1 -fno-omit-frame-pointer %s 2>&1 | \
216+
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
217+
165218
void f0() {}
166219
void f1() { f0(); }

0 commit comments

Comments
 (0)