Chandler Carruth | f49f1a87 | 2015-12-27 08:13:45 +0000 | [diff] [blame] | 1 | //===- ForceFunctionAttrs.cpp - Force function attrs for debugging --------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | |
| 10 | #include "llvm/Transforms/IPO/ForceFunctionAttrs.h" |
| 11 | #include "llvm/ADT/StringSwitch.h" |
| 12 | #include "llvm/IR/Function.h" |
| 13 | #include "llvm/IR/LLVMContext.h" |
| 14 | #include "llvm/IR/Module.h" |
| 15 | #include "llvm/Support/Debug.h" |
| 16 | #include "llvm/Support/raw_ostream.h" |
| 17 | using namespace llvm; |
| 18 | |
| 19 | #define DEBUG_TYPE "forceattrs" |
| 20 | |
| 21 | static cl::list<std::string> |
| 22 | ForceAttributes("force-attribute", cl::Hidden, |
| 23 | cl::desc("Add an attribute to a function. This should be a " |
| 24 | "pair of 'function-name:attribute-name', for " |
Weiming Zhao | c7c18d6 | 2016-01-06 18:18:16 +0000 | [diff] [blame] | 25 | "example -force-attribute=foo:noinline. This " |
Chandler Carruth | f49f1a87 | 2015-12-27 08:13:45 +0000 | [diff] [blame] | 26 | "option can be specified multiple times.")); |
| 27 | |
| 28 | static Attribute::AttrKind parseAttrKind(StringRef Kind) { |
| 29 | return StringSwitch<Attribute::AttrKind>(Kind) |
| 30 | .Case("alwaysinline", Attribute::AlwaysInline) |
| 31 | .Case("builtin", Attribute::Builtin) |
| 32 | .Case("cold", Attribute::Cold) |
| 33 | .Case("convergent", Attribute::Convergent) |
| 34 | .Case("inlinehint", Attribute::InlineHint) |
| 35 | .Case("jumptable", Attribute::JumpTable) |
| 36 | .Case("minsize", Attribute::MinSize) |
| 37 | .Case("naked", Attribute::Naked) |
| 38 | .Case("nobuiltin", Attribute::NoBuiltin) |
| 39 | .Case("noduplicate", Attribute::NoDuplicate) |
| 40 | .Case("noimplicitfloat", Attribute::NoImplicitFloat) |
| 41 | .Case("noinline", Attribute::NoInline) |
| 42 | .Case("nonlazybind", Attribute::NonLazyBind) |
| 43 | .Case("noredzone", Attribute::NoRedZone) |
| 44 | .Case("noreturn", Attribute::NoReturn) |
Oren Ben Simhon | fdd72fd | 2018-03-17 13:29:46 +0000 | [diff] [blame] | 45 | .Case("nocf_check", Attribute::NoCfCheck) |
Chandler Carruth | f49f1a87 | 2015-12-27 08:13:45 +0000 | [diff] [blame] | 46 | .Case("norecurse", Attribute::NoRecurse) |
| 47 | .Case("nounwind", Attribute::NoUnwind) |
Matt Morehouse | 236cdaf | 2018-03-22 17:07:51 +0000 | [diff] [blame] | 48 | .Case("optforfuzzing", Attribute::OptForFuzzing) |
Chandler Carruth | f49f1a87 | 2015-12-27 08:13:45 +0000 | [diff] [blame] | 49 | .Case("optnone", Attribute::OptimizeNone) |
| 50 | .Case("optsize", Attribute::OptimizeForSize) |
| 51 | .Case("readnone", Attribute::ReadNone) |
| 52 | .Case("readonly", Attribute::ReadOnly) |
| 53 | .Case("argmemonly", Attribute::ArgMemOnly) |
| 54 | .Case("returns_twice", Attribute::ReturnsTwice) |
| 55 | .Case("safestack", Attribute::SafeStack) |
Vlad Tsyrklevich | 07cf78c | 2018-04-03 21:40:27 +0000 | [diff] [blame] | 56 | .Case("shadowcallstack", Attribute::ShadowCallStack) |
Chandler Carruth | f49f1a87 | 2015-12-27 08:13:45 +0000 | [diff] [blame] | 57 | .Case("sanitize_address", Attribute::SanitizeAddress) |
Evgeniy Stepanov | c667c1f | 2017-12-09 00:21:41 +0000 | [diff] [blame] | 58 | .Case("sanitize_hwaddress", Attribute::SanitizeHWAddress) |
Chandler Carruth | f49f1a87 | 2015-12-27 08:13:45 +0000 | [diff] [blame] | 59 | .Case("sanitize_memory", Attribute::SanitizeMemory) |
| 60 | .Case("sanitize_thread", Attribute::SanitizeThread) |
Chandler Carruth | 664aa86 | 2018-09-04 12:38:00 +0000 | [diff] [blame^] | 61 | .Case("speculative_load_hardening", Attribute::SpeculativeLoadHardening) |
Chandler Carruth | f49f1a87 | 2015-12-27 08:13:45 +0000 | [diff] [blame] | 62 | .Case("ssp", Attribute::StackProtect) |
| 63 | .Case("sspreq", Attribute::StackProtectReq) |
| 64 | .Case("sspstrong", Attribute::StackProtectStrong) |
Andrew Kaylor | 53a5fbb | 2017-08-14 21:15:13 +0000 | [diff] [blame] | 65 | .Case("strictfp", Attribute::StrictFP) |
Chandler Carruth | f49f1a87 | 2015-12-27 08:13:45 +0000 | [diff] [blame] | 66 | .Case("uwtable", Attribute::UWTable) |
| 67 | .Default(Attribute::None); |
| 68 | } |
| 69 | |
| 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()) |
| 75 | continue; |
| 76 | |
| 77 | auto Kind = parseAttrKind(KV.second); |
| 78 | if (Kind == Attribute::None) { |
Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 79 | LLVM_DEBUG(dbgs() << "ForcedAttribute: " << KV.second |
| 80 | << " unknown or not handled!\n"); |
Chandler Carruth | f49f1a87 | 2015-12-27 08:13:45 +0000 | [diff] [blame] | 81 | continue; |
| 82 | } |
| 83 | if (F.hasFnAttribute(Kind)) |
| 84 | continue; |
| 85 | F.addFnAttr(Kind); |
| 86 | } |
| 87 | } |
| 88 | |
Chandler Carruth | 164a2aa6 | 2016-06-17 00:11:01 +0000 | [diff] [blame] | 89 | PreservedAnalyses ForceFunctionAttrsPass::run(Module &M, |
| 90 | ModuleAnalysisManager &) { |
Chandler Carruth | f49f1a87 | 2015-12-27 08:13:45 +0000 | [diff] [blame] | 91 | if (ForceAttributes.empty()) |
| 92 | return PreservedAnalyses::all(); |
| 93 | |
| 94 | for (Function &F : M.functions()) |
| 95 | addForcedAttributes(F); |
| 96 | |
| 97 | // Just conservatively invalidate analyses, this isn't likely to be important. |
| 98 | return PreservedAnalyses::none(); |
| 99 | } |
| 100 | |
| 101 | namespace { |
| 102 | struct ForceFunctionAttrsLegacyPass : public ModulePass { |
| 103 | static char ID; // Pass identification, replacement for typeid |
| 104 | ForceFunctionAttrsLegacyPass() : ModulePass(ID) { |
| 105 | initializeForceFunctionAttrsLegacyPassPass( |
| 106 | *PassRegistry::getPassRegistry()); |
| 107 | } |
| 108 | |
| 109 | bool runOnModule(Module &M) override { |
| 110 | if (ForceAttributes.empty()) |
| 111 | return false; |
| 112 | |
| 113 | for (Function &F : M.functions()) |
| 114 | addForcedAttributes(F); |
| 115 | |
| 116 | // Conservatively assume we changed something. |
| 117 | return true; |
| 118 | } |
| 119 | }; |
| 120 | } |
| 121 | |
| 122 | char ForceFunctionAttrsLegacyPass::ID = 0; |
| 123 | INITIALIZE_PASS(ForceFunctionAttrsLegacyPass, "forceattrs", |
| 124 | "Force set function attributes", false, false) |
| 125 | |
| 126 | Pass *llvm::createForceFunctionAttrsLegacyPass() { |
| 127 | return new ForceFunctionAttrsLegacyPass(); |
| 128 | } |