From fad998fc360e9d7140354e14ef71de8426446ead Mon Sep 17 00:00:00 2001 From: Artyom Skrobov Date: Mon, 7 Dec 2015 14:22:39 +0000 Subject: [PATCH] [ARM] Generate ABI_optimization_goals build attribute, as described in the ARM ARM. Summary: This reverts r254234, and adds a simple fix for the annoying case of use-after-free. Reviewers: rengolin Subscribers: aemerson, llvm-commits, rengolin Differential Revision: http://reviews.llvm.org/D15236 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254912 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMAsmPrinter.cpp | 45 +++++++++++++++++-- lib/Target/ARM/ARMAsmPrinter.h | 5 +++ .../ARM/MCTargetDesc/ARMELFStreamer.cpp | 6 +-- .../build-attributes-optimization-minsize.ll | 18 ++++++++ .../build-attributes-optimization-mixed.ll | 23 ++++++++++ .../build-attributes-optimization-optnone.ll | 18 ++++++++ .../build-attributes-optimization-optsize.ll | 18 ++++++++ .../ARM/build-attributes-optimization.ll | 23 ++++++++++ test/MC/ARM/data-in-code.ll | 16 +++---- 9 files changed, 157 insertions(+), 15 deletions(-) create mode 100644 test/CodeGen/ARM/build-attributes-optimization-minsize.ll create mode 100644 test/CodeGen/ARM/build-attributes-optimization-mixed.ll create mode 100644 test/CodeGen/ARM/build-attributes-optimization-optnone.ll create mode 100644 test/CodeGen/ARM/build-attributes-optimization-optsize.ll create mode 100644 test/CodeGen/ARM/build-attributes-optimization.ll diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 67ebfa2b581..61141c0031d 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -60,7 +60,7 @@ using namespace llvm; ARMAsmPrinter::ARMAsmPrinter(TargetMachine &TM, std::unique_ptr Streamer) : AsmPrinter(TM, std::move(Streamer)), AFI(nullptr), MCP(nullptr), - InConstantPool(false) {} + InConstantPool(false), OptimizationGoals(-1) {} void ARMAsmPrinter::EmitFunctionBodyEnd() { // Make sure to terminate any constant pools that were at the end @@ -106,9 +106,38 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { Subtarget = &MF.getSubtarget(); SetupMachineFunction(MF); + const Function* F = MF.getFunction(); + const TargetMachine& TM = MF.getTarget(); + + // Calculate this function's optimization goal. + unsigned OptimizationGoal; + if (F->hasFnAttribute(Attribute::OptimizeNone)) + // For best debugging illusion, speed and small size sacrificed + OptimizationGoal = 6; + else if (F->optForMinSize()) + // Aggressively for small size, speed and debug illusion sacrificed + OptimizationGoal = 4; + else if (F->optForSize()) + // For small size, but speed and debugging illusion preserved + OptimizationGoal = 3; + else if (TM.getOptLevel() == CodeGenOpt::Aggressive) + // Aggressively for speed, small size and debug illusion sacrificed + OptimizationGoal = 2; + else if (TM.getOptLevel() > CodeGenOpt::None) + // For speed, but small size and good debug illusion preserved + OptimizationGoal = 1; + else // TM.getOptLevel() == CodeGenOpt::None + // For good debugging, but speed and small size preserved + OptimizationGoal = 5; + + // Combine a new optimization goal with existing ones. + if (OptimizationGoals == -1) // uninitialized goals + OptimizationGoals = OptimizationGoal; + else if (OptimizationGoals != (int)OptimizationGoal) // conflicting goals + OptimizationGoals = 0; if (Subtarget->isTargetCOFF()) { - bool Internal = MF.getFunction()->hasInternalLinkage(); + bool Internal = F->hasInternalLinkage(); COFF::SymbolStorageClass Scl = Internal ? COFF::IMAGE_SYM_CLASS_STATIC : COFF::IMAGE_SYM_CLASS_EXTERNAL; int Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT; @@ -506,6 +535,16 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { // generates code that does this, it is always safe to set. OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); } + + // The last attribute to be emitted is ABI_optimization_goals + MCTargetStreamer &TS = *OutStreamer->getTargetStreamer(); + ARMTargetStreamer &ATS = static_cast(TS); + + if (OptimizationGoals > 0) + ATS.emitAttribute(ARMBuildAttrs::ABI_optimization_goals, OptimizationGoals); + OptimizationGoals = -1; + + ATS.finishAttributeSection(); } //===----------------------------------------------------------------------===// @@ -798,8 +837,6 @@ void ARMAsmPrinter::emitAttributes() { else if (STI.hasVirtualization()) ATS.emitAttribute(ARMBuildAttrs::Virtualization_use, ARMBuildAttrs::AllowVirtualization); - - ATS.finishAttributeSection(); } //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/ARMAsmPrinter.h b/lib/Target/ARM/ARMAsmPrinter.h index fb925f162f7..ed7be2de51c 100644 --- a/lib/Target/ARM/ARMAsmPrinter.h +++ b/lib/Target/ARM/ARMAsmPrinter.h @@ -51,6 +51,11 @@ class LLVM_LIBRARY_VISIBILITY ARMAsmPrinter : public AsmPrinter { /// labels used for ARMv4t thumb code to make register indirect calls. SmallVector, 4> ThumbIndirectPads; + /// OptimizationGoals - Maintain a combined optimization goal for all + /// functions in a module: one of Tag_ABI_optimization_goals values, + /// -1 if uninitialized, 0 if conflicting goals + int OptimizationGoals; + public: explicit ARMAsmPrinter(TargetMachine &TM, std::unique_ptr Streamer); diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index f316ad17576..6084f22c847 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -79,7 +79,7 @@ class ARMTargetAsmStreamer : public ARMTargetStreamer { void emitAttribute(unsigned Attribute, unsigned Value) override; void emitTextAttribute(unsigned Attribute, StringRef String) override; void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, - StringRef StrinValue) override; + StringRef StringValue) override; void emitArch(unsigned Arch) override; void emitArchExtension(unsigned ArchExt) override; void emitObjectArch(unsigned Arch) override; @@ -243,7 +243,7 @@ void ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset, class ARMTargetELFStreamer : public ARMTargetStreamer { private: // This structure holds all attributes, accounting for - // their string/numeric value, so we can later emmit them + // their string/numeric value, so we can later emit them // in declaration order, keeping all in the same vector struct AttributeItem { enum { @@ -254,7 +254,7 @@ private: } Type; unsigned Tag; unsigned IntValue; - StringRef StringValue; + std::string StringValue; static bool LessTag(const AttributeItem &LHS, const AttributeItem &RHS) { // The conformance tag must be emitted first when serialised diff --git a/test/CodeGen/ARM/build-attributes-optimization-minsize.ll b/test/CodeGen/ARM/build-attributes-optimization-minsize.ll new file mode 100644 index 00000000000..4cfb6012f43 --- /dev/null +++ b/test/CodeGen/ARM/build-attributes-optimization-minsize.ll @@ -0,0 +1,18 @@ +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O0 | FileCheck %s +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O1 | FileCheck %s +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O3 | FileCheck %s + +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O0 -filetype obj -o - | llvm-readobj -arm-attributes - | FileCheck %s --check-prefix=CHECK-OBJ +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O1 -filetype obj -o - | llvm-readobj -arm-attributes - | FileCheck %s --check-prefix=CHECK-OBJ +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O3 -filetype obj -o - | llvm-readobj -arm-attributes - | FileCheck %s --check-prefix=CHECK-OBJ + +; CHECK: .eabi_attribute 30, 4 @ Tag_ABI_optimization_goals +; CHECK-OBJ: TagName: ABI_optimization_goals +; CHECK-OBJ-NEXT: Description: Aggressive Size + +define i32 @f(i64 %z) #0 { + ret i32 0 +} + +attributes #0 = { minsize optsize } + diff --git a/test/CodeGen/ARM/build-attributes-optimization-mixed.ll b/test/CodeGen/ARM/build-attributes-optimization-mixed.ll new file mode 100644 index 00000000000..8009fc6e28f --- /dev/null +++ b/test/CodeGen/ARM/build-attributes-optimization-mixed.ll @@ -0,0 +1,23 @@ +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O0 | FileCheck %s +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O1 | FileCheck %s +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O3 | FileCheck %s + +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O0 -filetype obj -o - | llvm-readobj -arm-attributes - | FileCheck %s +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O1 -filetype obj -o - | llvm-readobj -arm-attributes - | FileCheck %s +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O3 -filetype obj -o - | llvm-readobj -arm-attributes - | FileCheck %s + +; CHECK-NOT: .eabi_attribute 30 +; CHECK-NOT: Tag_ABI_optimization_goals + +define i32 @f(i64 %z) #0 { + ret i32 0 +} + +define i32 @g(i64 %z) #1 { + ret i32 1 +} + +attributes #0 = { noinline optnone } + +attributes #1 = { minsize optsize } + diff --git a/test/CodeGen/ARM/build-attributes-optimization-optnone.ll b/test/CodeGen/ARM/build-attributes-optimization-optnone.ll new file mode 100644 index 00000000000..cbdb915045c --- /dev/null +++ b/test/CodeGen/ARM/build-attributes-optimization-optnone.ll @@ -0,0 +1,18 @@ +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O0 | FileCheck %s +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O1 | FileCheck %s +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O3 | FileCheck %s + +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O0 -filetype obj -o - | llvm-readobj -arm-attributes - | FileCheck %s --check-prefix=CHECK-OBJ +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O1 -filetype obj -o - | llvm-readobj -arm-attributes - | FileCheck %s --check-prefix=CHECK-OBJ +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O3 -filetype obj -o - | llvm-readobj -arm-attributes - | FileCheck %s --check-prefix=CHECK-OBJ + +; CHECK: .eabi_attribute 30, 6 @ Tag_ABI_optimization_goals +; CHECK-OBJ: TagName: ABI_optimization_goals +; CHECK-OBJ-NEXT: Description: Best Debugging + +define i32 @f(i64 %z) #0 { + ret i32 0 +} + +attributes #0 = { noinline optnone } + diff --git a/test/CodeGen/ARM/build-attributes-optimization-optsize.ll b/test/CodeGen/ARM/build-attributes-optimization-optsize.ll new file mode 100644 index 00000000000..bab210aa8d0 --- /dev/null +++ b/test/CodeGen/ARM/build-attributes-optimization-optsize.ll @@ -0,0 +1,18 @@ +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O0 | FileCheck %s +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O1 | FileCheck %s +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O3 | FileCheck %s + +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O0 -filetype obj -o - | llvm-readobj -arm-attributes - | FileCheck %s --check-prefix=CHECK-OBJ +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O1 -filetype obj -o - | llvm-readobj -arm-attributes - | FileCheck %s --check-prefix=CHECK-OBJ +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O3 -filetype obj -o - | llvm-readobj -arm-attributes - | FileCheck %s --check-prefix=CHECK-OBJ + +; CHECK: .eabi_attribute 30, 3 @ Tag_ABI_optimization_goals +; CHECK-OBJ: TagName: ABI_optimization_goals +; CHECK-OBJ-NEXT: Description: Size + +define i32 @f(i64 %z) #0 { + ret i32 0 +} + +attributes #0 = { optsize } + diff --git a/test/CodeGen/ARM/build-attributes-optimization.ll b/test/CodeGen/ARM/build-attributes-optimization.ll new file mode 100644 index 00000000000..21b7b3c3ab0 --- /dev/null +++ b/test/CodeGen/ARM/build-attributes-optimization.ll @@ -0,0 +1,23 @@ +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O0 | FileCheck %s --check-prefix=NONE +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O1 | FileCheck %s --check-prefix=SPEED +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O3 | FileCheck %s --check-prefix=MAXSPEED + +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O0 -filetype obj -o - | llvm-readobj -arm-attributes - | FileCheck %s --check-prefix=NONE-OBJ +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O1 -filetype obj -o - | llvm-readobj -arm-attributes - | FileCheck %s --check-prefix=SPEED-OBJ +; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-a7 -O3 -filetype obj -o - | llvm-readobj -arm-attributes - | FileCheck %s --check-prefix=MAXSPEED-OBJ + +; NONE: .eabi_attribute 30, 5 @ Tag_ABI_optimization_goals +; SPEED: .eabi_attribute 30, 1 @ Tag_ABI_optimization_goals +; MAXSPEED: .eabi_attribute 30, 2 @ Tag_ABI_optimization_goals + +; NONE-OBJ: TagName: ABI_optimization_goals +; NONE-OBJ-NEXT: Description: Debugging +; SPEED-OBJ: TagName: ABI_optimization_goals +; SPEED-OBJ-NEXT: Description: Speed +; MAXSPEED-OBJ: TagName: ABI_optimization_goals +; MAXSPEED-OBJ-NEXT: Description: Aggressive Speed + +define i32 @f(i64 %z) { + ret i32 0 +} + diff --git a/test/MC/ARM/data-in-code.ll b/test/MC/ARM/data-in-code.ll index c4910ff20e6..10657a3fed3 100644 --- a/test/MC/ARM/data-in-code.ll +++ b/test/MC/ARM/data-in-code.ll @@ -51,13 +51,6 @@ exit: ;; ARM-NEXT: Other: ;; ARM-NEXT: Section: [[MIXED_SECT]] -;; ARM: Symbol { -;; ARM: Name: $d -;; ARM-NEXT: Value: 0 -;; ARM-NEXT: Size: 0 -;; ARM-NEXT: Binding: Local -;; ARM-NEXT: Type: None - ;; ARM: Symbol { ;; ARM: Name: $d ;; ARM-NEXT: Value: 0x{{[0-9A-F]+}} @@ -77,10 +70,17 @@ exit: ;; ARM-NEXT: Section: .ARM.exidx ;; ARM-NEXT: } +;; ARM: Symbol { +;; ARM: Name: $d +;; ARM-NEXT: Value: 0 +;; ARM-NEXT: Size: 0 +;; ARM-NEXT: Binding: Local +;; ARM-NEXT: Type: None + ;; ARM-NOT: ${{[atd]}} ;; TMB: Symbol { -;; TMB: Name: $d.2 +;; TMB: Name: $d.1 ;; TMB-NEXT: Value: 0x{{[0-9A-F]+}} ;; TMB-NEXT: Size: 0 ;; TMB-NEXT: Binding: Local -- 2.34.1