LLVM  12.0.0git
ForceFunctionAttrs.cpp
Go to the documentation of this file.
1 //===- ForceFunctionAttrs.cpp - Force function attrs for debugging --------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
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/InitializePasses.h"
16 #include "llvm/Support/Debug.h"
18 using namespace llvm;
19 
20 #define DEBUG_TYPE "forceattrs"
21 
23  ForceAttributes("force-attribute", cl::Hidden,
24  cl::desc("Add an attribute to a function. This should be a "
25  "pair of 'function-name:attribute-name', for "
26  "example -force-attribute=foo:noinline. This "
27  "option can be specified multiple times."));
28 
30  "force-remove-attribute", cl::Hidden,
31  cl::desc("Remove an attribute from a function. This should be a "
32  "pair of 'function-name:attribute-name', for "
33  "example -force-remove-attribute=foo:noinline. This "
34  "option can be specified multiple times."));
35 
38  .Case("alwaysinline", Attribute::AlwaysInline)
39  .Case("builtin", Attribute::Builtin)
40  .Case("cold", Attribute::Cold)
41  .Case("convergent", Attribute::Convergent)
42  .Case("inlinehint", Attribute::InlineHint)
43  .Case("jumptable", Attribute::JumpTable)
44  .Case("minsize", Attribute::MinSize)
45  .Case("naked", Attribute::Naked)
46  .Case("nobuiltin", Attribute::NoBuiltin)
47  .Case("noduplicate", Attribute::NoDuplicate)
48  .Case("noimplicitfloat", Attribute::NoImplicitFloat)
49  .Case("noinline", Attribute::NoInline)
50  .Case("nonlazybind", Attribute::NonLazyBind)
51  .Case("noredzone", Attribute::NoRedZone)
52  .Case("noreturn", Attribute::NoReturn)
53  .Case("nocf_check", Attribute::NoCfCheck)
54  .Case("norecurse", Attribute::NoRecurse)
55  .Case("nounwind", Attribute::NoUnwind)
56  .Case("optforfuzzing", Attribute::OptForFuzzing)
57  .Case("optnone", Attribute::OptimizeNone)
58  .Case("optsize", Attribute::OptimizeForSize)
59  .Case("readnone", Attribute::ReadNone)
60  .Case("readonly", Attribute::ReadOnly)
61  .Case("argmemonly", Attribute::ArgMemOnly)
62  .Case("returns_twice", Attribute::ReturnsTwice)
63  .Case("safestack", Attribute::SafeStack)
64  .Case("shadowcallstack", Attribute::ShadowCallStack)
65  .Case("sanitize_address", Attribute::SanitizeAddress)
66  .Case("sanitize_hwaddress", Attribute::SanitizeHWAddress)
67  .Case("sanitize_memory", Attribute::SanitizeMemory)
68  .Case("sanitize_thread", Attribute::SanitizeThread)
69  .Case("sanitize_memtag", Attribute::SanitizeMemTag)
70  .Case("speculative_load_hardening", Attribute::SpeculativeLoadHardening)
71  .Case("ssp", Attribute::StackProtect)
72  .Case("sspreq", Attribute::StackProtectReq)
73  .Case("sspstrong", Attribute::StackProtectStrong)
74  .Case("strictfp", Attribute::StrictFP)
75  .Case("uwtable", Attribute::UWTable)
77 }
78 
79 /// If F has any forced attributes given on the command line, add them.
80 /// If F has any forced remove attributes given on the command line, remove
81 /// them. When both force and force-remove are given to a function, the latter
82 /// takes precedence.
83 static void forceAttributes(Function &F) {
84  auto ParseFunctionAndAttr = [&](StringRef S) {
85  auto Kind = Attribute::None;
86  auto KV = StringRef(S).split(':');
87  if (KV.first != F.getName())
88  return Kind;
89  Kind = parseAttrKind(KV.second);
90  if (Kind == Attribute::None) {
91  LLVM_DEBUG(dbgs() << "ForcedAttribute: " << KV.second
92  << " unknown or not handled!\n");
93  }
94  return Kind;
95  };
96 
97  for (auto &S : ForceAttributes) {
98  auto Kind = ParseFunctionAndAttr(S);
99  if (Kind == Attribute::None || F.hasFnAttribute(Kind))
100  continue;
101  F.addFnAttr(Kind);
102  }
103 
104  for (auto &S : ForceRemoveAttributes) {
105  auto Kind = ParseFunctionAndAttr(S);
106  if (Kind == Attribute::None || !F.hasFnAttribute(Kind))
107  continue;
108  F.removeFnAttr(Kind);
109  }
110 }
111 
112 static bool hasForceAttributes() {
113  return !ForceAttributes.empty() || !ForceRemoveAttributes.empty();
114 }
115 
118  if (!hasForceAttributes())
119  return PreservedAnalyses::all();
120 
121  for (Function &F : M.functions())
123 
124  // Just conservatively invalidate analyses, this isn't likely to be important.
125  return PreservedAnalyses::none();
126 }
127 
128 namespace {
129 struct ForceFunctionAttrsLegacyPass : public ModulePass {
130  static char ID; // Pass identification, replacement for typeid
131  ForceFunctionAttrsLegacyPass() : ModulePass(ID) {
134  }
135 
136  bool runOnModule(Module &M) override {
137  if (!hasForceAttributes())
138  return false;
139 
140  for (Function &F : M.functions())
142 
143  // Conservatively assume we changed something.
144  return true;
145  }
146 };
147 }
148 
150 INITIALIZE_PASS(ForceFunctionAttrsLegacyPass, "forceattrs",
151  "Force set function attributes", false, false)
152 
154  return new ForceFunctionAttrsLegacyPass();
155 }
Super simple passes to force specific function attrs from the commandline into the IR for debugging p...
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents lattice values for constants.
Definition: AllocatorList.h:23
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
F(f)
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:67
LLVM_NODISCARD R Default(T Value)
Definition: StringSwitch.h:181
No attributes have been set.
Definition: Attributes.h:72
static bool hasForceAttributes()
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:158
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:155
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:161
static Attribute::AttrKind parseAttrKind(StringRef Kind)
static cl::list< std::string > ForceAttributes("force-attribute", cl::Hidden, cl::desc("Add an attribute to a function. This should be a " "pair of 'function-name:attribute-name', for " "example -force-attribute=foo:noinline. This " "option can be specified multiple times."))
Module.h This file contains the declarations for the Module class.
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:730
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
static void forceAttributes(Function &F)
If F has any forced attributes given on the command line, add them.
static cl::list< std::string > ForceRemoveAttributes("force-remove-attribute", cl::Hidden, cl::desc("Remove an attribute from a function. This should be a " "pair of 'function-name:attribute-name', for " "example -force-remove-attribute=foo:noinline. This " "option can be specified multiple times."))
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
INITIALIZE_PASS(ForceFunctionAttrsLegacyPass, "forceattrs", "Force set function attributes", false, false) Pass *llvm
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:238
void initializeForceFunctionAttrsLegacyPassPass(PassRegistry &)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
A container for analyses that lazily runs them and caches their results.
#define LLVM_DEBUG(X)
Definition: Debug.h:122
Pass * createForceFunctionAttrsLegacyPass()
Create a legacy pass manager instance of a pass to force function attrs.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition: Attributes.h:70