[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
This commit is contained in:
Ties Stuij 2024-12-06 14:05:30 +00:00 committed by GitHub
parent 37797d3e80
commit 2f4eac6287
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 80 additions and 23 deletions

View File

@ -52,6 +52,26 @@ bool arm::isARMAProfile(const llvm::Triple &Triple) {
return llvm::ARM::parseArchProfile(Arch) == llvm::ARM::ProfileKind::A;
}
/// Is the triple {arm,armeb,thumb,thumbeb}-none-none-{eabi,eabihf} ?
bool arm::isARMEABIBareMetal(const llvm::Triple &Triple) {
auto arch = Triple.getArch();
if (arch != llvm::Triple::arm && arch != llvm::Triple::thumb &&
arch != llvm::Triple::armeb && arch != llvm::Triple::thumbeb)
return false;
if (Triple.getVendor() != llvm::Triple::UnknownVendor)
return false;
if (Triple.getOS() != llvm::Triple::UnknownOS)
return false;
if (Triple.getEnvironment() != llvm::Triple::EABI &&
Triple.getEnvironment() != llvm::Triple::EABIHF)
return false;
return true;
}
// Get Arch/CPU from args.
void arm::getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch,
llvm::StringRef &CPU, bool FromAs) {

View File

@ -75,6 +75,7 @@ int getARMSubArchVersionNumber(const llvm::Triple &Triple);
bool isARMMProfile(const llvm::Triple &Triple);
bool isARMAProfile(const llvm::Triple &Triple);
bool isARMBigEndian(const llvm::Triple &Triple, const llvm::opt::ArgList &Args);
bool isARMEABIBareMetal(const llvm::Triple &Triple);
} // end namespace arm
} // end namespace tools

View File

@ -128,27 +128,6 @@ BareMetal::BareMetal(const Driver &D, const llvm::Triple &Triple,
}
}
/// Is the triple {arm,armeb,thumb,thumbeb}-none-none-{eabi,eabihf} ?
static bool isARMBareMetal(const llvm::Triple &Triple) {
if (Triple.getArch() != llvm::Triple::arm &&
Triple.getArch() != llvm::Triple::thumb &&
Triple.getArch() != llvm::Triple::armeb &&
Triple.getArch() != llvm::Triple::thumbeb)
return false;
if (Triple.getVendor() != llvm::Triple::UnknownVendor)
return false;
if (Triple.getOS() != llvm::Triple::UnknownOS)
return false;
if (Triple.getEnvironment() != llvm::Triple::EABI &&
Triple.getEnvironment() != llvm::Triple::EABIHF)
return false;
return true;
}
/// Is the triple {aarch64.aarch64_be}-none-elf?
static bool isAArch64BareMetal(const llvm::Triple &Triple) {
if (Triple.getArch() != llvm::Triple::aarch64 &&
@ -267,7 +246,7 @@ void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple,
}
bool BareMetal::handlesTarget(const llvm::Triple &Triple) {
return isARMBareMetal(Triple) || isAArch64BareMetal(Triple) ||
return arm::isARMEABIBareMetal(Triple) || isAArch64BareMetal(Triple) ||
isRISCVBareMetal(Triple) || isPPCBareMetal(Triple);
}
@ -561,7 +540,7 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// The R_ARM_TARGET2 relocation must be treated as R_ARM_REL32 on arm*-*-elf
// and arm*-*-eabi (the default is R_ARM_GOT_PREL, used on arm*-*-linux and
// arm*-*-*bsd).
if (isARMBareMetal(TC.getTriple()))
if (arm::isARMEABIBareMetal(TC.getTriple()))
CmdArgs.push_back("--target2=rel");
CmdArgs.push_back("-o");

View File

@ -19,6 +19,7 @@
#include "Arch/SystemZ.h"
#include "Arch/VE.h"
#include "Arch/X86.h"
#include "BareMetal.h"
#include "HIPAMD.h"
#include "Hexagon.h"
#include "MSP430.h"
@ -151,6 +152,9 @@ static bool useFramePointerForTargetByDefault(const llvm::opt::ArgList &Args,
}
}
if (arm::isARMEABIBareMetal(Triple))
return false;
return true;
}

View File

@ -162,5 +162,58 @@
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: not %clang -### --target=riscv64-linux-android -mbig-endian -O1 -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// On ARM backend bare metal targets, frame pointer is omitted
// RUN: %clang -### --target=arm-arm-none-eabi -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NONE %s
// RUN: %clang -### --target=arm-arm-none-eabihf -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NONE %s
// RUN: %clang -### --target=arm-arm-none-eabi -S -fno-omit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-ALL %s
// RUN: %clang -### --target=arm-arm-none-eabihf -S -fno-omit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-ALL %s
// RUN: %clang -### --target=arm-arm-none-eabi -S -O1 %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NONE %s
// RUN: %clang -### --target=arm-arm-none-eabihf -S -O1 %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NONE %s
// RUN: %clang -### --target=arm-arm-none-eabi -S -O1 -fno-omit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-ALL %s
// RUN: %clang -### --target=arm-arm-none-eabihf -S -O1 -fno-omit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-ALL %s
// RUN: %clang -### --target=armeb-arm-none-eabi -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NONE %s
// RUN: %clang -### --target=thumb-arm-none-eabi -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NONE %s
// RUN: %clang -### --target=thumbeb-arm-none-eabi -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NONE %s
// Check that for Apple bare metal targets, we're keeping frame pointers by default
// RUN: %clang -### --target=thumbv6m-apple-none-macho -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-ALL %s
// RUN: %clang -### --target=thumbv6m-apple-none-macho -S -fno-omit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-ALL %s
// RUN: %clang -### --target=arm-apple-none-macho -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-ALL %s
// RUN: %clang -### --target=arm-apple-none-macho -S -fno-omit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-ALL %s
// RUN: %clang -### --target=thumbv6m-apple-none-macho -S -O1 %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-ALL %s
// RUN: %clang -### --target=thumbv6m-apple-none-macho -S -O1 -fno-omit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-ALL %s
// RUN: %clang -### --target=arm-apple-none-macho -S -O1 %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-ALL %s
// RUN: %clang -### --target=arm-apple-none-macho -S -O1 -fno-omit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-ALL %s
// AArch64 bare metal targets behave like hosted targets
// RUN: %clang -### --target=aarch64-none-elf -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: %clang -### --target=aarch64-none-elf -S -O1 %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: %clang -### --target=aarch64-none-elf -S -fno-omit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: %clang -### --target=aarch64-none-elf -S -O1 -fno-omit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
void f0() {}
void f1() { f0(); }