From 516286ff698dd0781ba39e3f3144dfbcc241e5db Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Thu, 2 Jul 2015 22:13:27 +0000 Subject: [PATCH] Use function attribute "trap-func-name" and remove TargetOptions::TrapFuncName. This commit changes normal isel and fast isel to read the user-defined trap function name from function attribute "trap-func-name" attached to llvm.trap or llvm.debugtrap instead of from TargetOptions::TrapFuncName. This is needed to use clang's command line option "-ftrap-function" for LTO and enable changing the trap function name on a per-call-site basis. Out-of-tree projects currently using TargetOptions::TrapFuncName to specify the trap function name should attach attribute "trap-func-name" to the call sites of llvm.trap and llvm.debugtrap instead. rdar://problem/21225723 Differential Revision: http://reviews.llvm.org/D10832 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241305 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/CommandFlags.h | 13 +++++- include/llvm/Target/TargetOptions.h | 9 +---- lib/CodeGen/SelectionDAG/FastISel.cpp | 2 +- .../SelectionDAG/SelectionDAGBuilder.cpp | 5 ++- lib/CodeGen/TargetOptionsImpl.cpp | 7 ---- test/CodeGen/ARM/fnattr-trap.ll | 40 +++++++++++++++++++ 6 files changed, 58 insertions(+), 18 deletions(-) create mode 100644 test/CodeGen/ARM/fnattr-trap.ll diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h index 3c3f770f92b..554511d6f4a 100644 --- a/include/llvm/CodeGen/CommandFlags.h +++ b/include/llvm/CodeGen/CommandFlags.h @@ -17,6 +17,8 @@ #define LLVM_CODEGEN_COMMANDFLAGS_H #include "llvm/ADT/StringExtras.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" #include "llvm/MC/MCTargetOptionsCommandFlags.h" #include "llvm//MC/SubtargetFeature.h" @@ -249,7 +251,6 @@ static inline TargetOptions InitTargetOptionsFromCodeGenFlags() { Options.NoZerosInBSS = DontPlaceZerosInBSS; Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt; Options.StackAlignmentOverride = OverrideStackAlignment; - Options.TrapFuncName = TrapFuncName; Options.PositionIndependentExecutable = EnablePIE; Options.UseInitArray = !UseCtors; Options.DataSections = DataSections; @@ -320,6 +321,16 @@ static inline void setFunctionAttributes(StringRef CPU, StringRef Features, "disable-tail-calls", toStringRef(DisableTailCalls)); + if (TrapFuncName.getNumOccurrences() > 0) + for (auto &B : F) + for (auto &I : B) + if (auto *Call = dyn_cast(&I)) + if (const auto *F = Call->getCalledFunction()) + if (F->getIntrinsicID() == Intrinsic::debugtrap || + F->getIntrinsicID() == Intrinsic::trap) + Call->addAttribute(llvm::AttributeSet::FunctionIndex, + "trap-func-name", TrapFuncName); + // Let NewAttrs override Attrs. NewAttrs = Attrs.addAttributes(Ctx, AttributeSet::FunctionIndex, NewAttrs); F.setAttributes(NewAttrs); diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index a4e0954129d..d52cb60cf10 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -72,7 +72,7 @@ namespace llvm { UseInitArray(false), DisableIntegratedAS(false), CompressDebugSections(false), FunctionSections(false), DataSections(false), UniqueSectionNames(true), TrapUnreachable(false), - TrapFuncName(), FloatABIType(FloatABI::Default), + FloatABIType(FloatABI::Default), AllowFPOpFusion(FPOpFusion::Standard), Reciprocals(TargetRecip()), JTType(JumpTable::Single), ThreadModel(ThreadModel::POSIX) {} @@ -172,12 +172,6 @@ namespace llvm { /// Emit target-specific trap instruction for 'unreachable' IR instructions. unsigned TrapUnreachable : 1; - /// getTrapFunctionName - If this returns a non-empty string, this means - /// isel should lower Intrinsic::trap to a call to the specified function - /// name instead of an ISD::TRAP node. - std::string TrapFuncName; - StringRef getTrapFunctionName() const; - /// FloatABIType - This setting is set by -float-abi=xxx option is specfied /// on the command line. This setting may either be Default, Soft, or Hard. /// Default selects the target's default behavior. Soft selects the ABI for @@ -237,7 +231,6 @@ inline bool operator==(const TargetOptions &LHS, ARE_EQUAL(PositionIndependentExecutable) && ARE_EQUAL(UseInitArray) && ARE_EQUAL(TrapUnreachable) && - ARE_EQUAL(TrapFuncName) && ARE_EQUAL(FloatABIType) && ARE_EQUAL(AllowFPOpFusion) && ARE_EQUAL(Reciprocals) && diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp index 350db6a94ee..5452b1721bb 100644 --- a/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1350,7 +1350,7 @@ bool FastISel::selectInstruction(const Instruction *I) { // Don't handle Intrinsic::trap if a trap funciton is specified. if (F && F->getIntrinsicID() == Intrinsic::trap && - !TM.Options.getTrapFunctionName().empty()) + Call->hasFnAttr("trap-func-name")) return false; } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 85b2d5f62ff..a50c4394527 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -4780,7 +4780,10 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { case Intrinsic::debugtrap: case Intrinsic::trap: { - StringRef TrapFuncName = TM.Options.getTrapFunctionName(); + StringRef TrapFuncName = + I.getAttributes() + .getAttribute(AttributeSet::FunctionIndex, "trap-func-name") + .getValueAsString(); if (TrapFuncName.empty()) { ISD::NodeType Op = (Intrinsic == Intrinsic::trap) ? ISD::TRAP : ISD::DEBUGTRAP; diff --git a/lib/CodeGen/TargetOptionsImpl.cpp b/lib/CodeGen/TargetOptionsImpl.cpp index f4926cbc624..8d2048fa047 100644 --- a/lib/CodeGen/TargetOptionsImpl.cpp +++ b/lib/CodeGen/TargetOptionsImpl.cpp @@ -47,10 +47,3 @@ bool TargetOptions::LessPreciseFPMAD() const { bool TargetOptions::HonorSignDependentRoundingFPMath() const { return !UnsafeFPMath && HonorSignDependentRoundingFPMathOption; } - -/// getTrapFunctionName - If this returns a non-empty string, this means isel -/// should lower Intrinsic::trap to a call to the specified function name -/// instead of an ISD::TRAP node. -StringRef TargetOptions::getTrapFunctionName() const { - return TrapFuncName; -} diff --git a/test/CodeGen/ARM/fnattr-trap.ll b/test/CodeGen/ARM/fnattr-trap.ll new file mode 100644 index 00000000000..c7948609c41 --- /dev/null +++ b/test/CodeGen/ARM/fnattr-trap.ll @@ -0,0 +1,40 @@ +; RUN: llc < %s -march arm | FileCheck %s -check-prefix=NOOPTION +; RUN: llc < %s -march arm -trap-func=trap_llc | FileCheck %s -check-prefix=TRAP + +; NOOPTION-LABEL: {{\_?}}foo0: +; NOOPTION: trap{{$}} + +; TRAP-LABEL: {{\_?}}foo0: +; TRAP: bl {{\_?}}trap_llc + +define void @foo0() { + call void @llvm.trap() + unreachable +} + +; NOOPTION-LABEL: {{\_?}}foo1: +; NOOPTION: bl {{\_?}}trap_func_attr0 + +; TRAP-LABEL: {{\_?}}foo1: +; TRAP: bl {{\_?}}trap_llc + +define void @foo1() { + call void @llvm.trap() #0 + unreachable +} + +; NOOPTION-LABEL: {{\_?}}foo2: +; NOOPTION: bl {{\_?}}trap_func_attr1 + +; TRAP-LABEL: {{\_?}}foo2: +; TRAP: bl {{\_?}}trap_llc + +define void @foo2() { + call void @llvm.trap() #1 + unreachable +} + +declare void @llvm.trap() nounwind + +attributes #0 = { "trap-func-name"="trap_func_attr0" } +attributes #1 = { "trap-func-name"="trap_func_attr1" }