1 //===- ForceFunctionAttrs.cpp - Force function attrs for debugging --------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
10 #include "llvm/ADT/StringSwitch.h"
11 #include "llvm/IR/Function.h"
12 #include "llvm/IR/LLVMContext.h"
13 #include "llvm/IR/Module.h"
14 #include "llvm/Support/Debug.h"
15 #include "llvm/Support/raw_ostream.h"
18 #define DEBUG_TYPE "forceattrs"
20 static cl::list
<std::string
>
21 ForceAttributes("force-attribute", cl::Hidden
,
22 cl::desc("Add an attribute to a function. This should be a "
23 "pair of 'function-name:attribute-name', for "
24 "example -force-attribute=foo:noinline. This "
25 "option can be specified multiple times."));
27 static Attribute::AttrKind
parseAttrKind(StringRef Kind
) {
28 return StringSwitch
<Attribute::AttrKind
>(Kind
)
29 .Case("alwaysinline", Attribute::AlwaysInline
)
30 .Case("builtin", Attribute::Builtin
)
31 .Case("cold", Attribute::Cold
)
32 .Case("convergent", Attribute::Convergent
)
33 .Case("inlinehint", Attribute::InlineHint
)
34 .Case("jumptable", Attribute::JumpTable
)
35 .Case("minsize", Attribute::MinSize
)
36 .Case("naked", Attribute::Naked
)
37 .Case("nobuiltin", Attribute::NoBuiltin
)
38 .Case("noduplicate", Attribute::NoDuplicate
)
39 .Case("noimplicitfloat", Attribute::NoImplicitFloat
)
40 .Case("noinline", Attribute::NoInline
)
41 .Case("nonlazybind", Attribute::NonLazyBind
)
42 .Case("noredzone", Attribute::NoRedZone
)
43 .Case("noreturn", Attribute::NoReturn
)
44 .Case("nocf_check", Attribute::NoCfCheck
)
45 .Case("norecurse", Attribute::NoRecurse
)
46 .Case("nounwind", Attribute::NoUnwind
)
47 .Case("optforfuzzing", Attribute::OptForFuzzing
)
48 .Case("optnone", Attribute::OptimizeNone
)
49 .Case("optsize", Attribute::OptimizeForSize
)
50 .Case("readnone", Attribute::ReadNone
)
51 .Case("readonly", Attribute::ReadOnly
)
52 .Case("argmemonly", Attribute::ArgMemOnly
)
53 .Case("returns_twice", Attribute::ReturnsTwice
)
54 .Case("safestack", Attribute::SafeStack
)
55 .Case("shadowcallstack", Attribute::ShadowCallStack
)
56 .Case("sanitize_address", Attribute::SanitizeAddress
)
57 .Case("sanitize_hwaddress", Attribute::SanitizeHWAddress
)
58 .Case("sanitize_memory", Attribute::SanitizeMemory
)
59 .Case("sanitize_thread", Attribute::SanitizeThread
)
60 .Case("sanitize_memtag", Attribute::SanitizeMemTag
)
61 .Case("speculative_load_hardening", Attribute::SpeculativeLoadHardening
)
62 .Case("ssp", Attribute::StackProtect
)
63 .Case("sspreq", Attribute::StackProtectReq
)
64 .Case("sspstrong", Attribute::StackProtectStrong
)
65 .Case("strictfp", Attribute::StrictFP
)
66 .Case("uwtable", Attribute::UWTable
)
67 .Default(Attribute::None
);
70 /// If F has any forced attributes given on the command line, add them.
71 static void addForcedAttributes(Function
&F
) {
72 for (auto &S
: ForceAttributes
) {
73 auto KV
= StringRef(S
).split(':');
74 if (KV
.first
!= F
.getName())
77 auto Kind
= parseAttrKind(KV
.second
);
78 if (Kind
== Attribute::None
) {
79 LLVM_DEBUG(dbgs() << "ForcedAttribute: " << KV
.second
80 << " unknown or not handled!\n");
83 if (F
.hasFnAttribute(Kind
))
89 PreservedAnalyses
ForceFunctionAttrsPass::run(Module
&M
,
90 ModuleAnalysisManager
&) {
91 if (ForceAttributes
.empty())
92 return PreservedAnalyses::all();
94 for (Function
&F
: M
.functions())
95 addForcedAttributes(F
);
97 // Just conservatively invalidate analyses, this isn't likely to be important.
98 return PreservedAnalyses::none();
102 struct ForceFunctionAttrsLegacyPass
: public ModulePass
{
103 static char ID
; // Pass identification, replacement for typeid
104 ForceFunctionAttrsLegacyPass() : ModulePass(ID
) {
105 initializeForceFunctionAttrsLegacyPassPass(
106 *PassRegistry::getPassRegistry());
109 bool runOnModule(Module
&M
) override
{
110 if (ForceAttributes
.empty())
113 for (Function
&F
: M
.functions())
114 addForcedAttributes(F
);
116 // Conservatively assume we changed something.
122 char ForceFunctionAttrsLegacyPass::ID
= 0;
123 INITIALIZE_PASS(ForceFunctionAttrsLegacyPass
, "forceattrs",
124 "Force set function attributes", false, false)
126 Pass
*llvm::createForceFunctionAttrsLegacyPass() {
127 return new ForceFunctionAttrsLegacyPass();