diff options
Diffstat (limited to 'contrib/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp')
| -rw-r--r-- | contrib/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp | 121 | 
1 files changed, 121 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp b/contrib/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp new file mode 100644 index 000000000000..816291dac9e8 --- /dev/null +++ b/contrib/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp @@ -0,0 +1,121 @@ +//===- ForceFunctionAttrs.cpp - Force function attrs for debugging --------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/IPO/ForceFunctionAttrs.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +#define DEBUG_TYPE "forceattrs" + +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-add-attribute=foo:noinline. This " +                             "option can be specified multiple times.")); + +static Attribute::AttrKind parseAttrKind(StringRef Kind) { +  return StringSwitch<Attribute::AttrKind>(Kind) +      .Case("alwaysinline", Attribute::AlwaysInline) +      .Case("builtin", Attribute::Builtin) +      .Case("cold", Attribute::Cold) +      .Case("convergent", Attribute::Convergent) +      .Case("inlinehint", Attribute::InlineHint) +      .Case("jumptable", Attribute::JumpTable) +      .Case("minsize", Attribute::MinSize) +      .Case("naked", Attribute::Naked) +      .Case("nobuiltin", Attribute::NoBuiltin) +      .Case("noduplicate", Attribute::NoDuplicate) +      .Case("noimplicitfloat", Attribute::NoImplicitFloat) +      .Case("noinline", Attribute::NoInline) +      .Case("nonlazybind", Attribute::NonLazyBind) +      .Case("noredzone", Attribute::NoRedZone) +      .Case("noreturn", Attribute::NoReturn) +      .Case("norecurse", Attribute::NoRecurse) +      .Case("nounwind", Attribute::NoUnwind) +      .Case("optnone", Attribute::OptimizeNone) +      .Case("optsize", Attribute::OptimizeForSize) +      .Case("readnone", Attribute::ReadNone) +      .Case("readonly", Attribute::ReadOnly) +      .Case("argmemonly", Attribute::ArgMemOnly) +      .Case("returns_twice", Attribute::ReturnsTwice) +      .Case("safestack", Attribute::SafeStack) +      .Case("sanitize_address", Attribute::SanitizeAddress) +      .Case("sanitize_memory", Attribute::SanitizeMemory) +      .Case("sanitize_thread", Attribute::SanitizeThread) +      .Case("ssp", Attribute::StackProtect) +      .Case("sspreq", Attribute::StackProtectReq) +      .Case("sspstrong", Attribute::StackProtectStrong) +      .Case("uwtable", Attribute::UWTable) +      .Default(Attribute::None); +} + +/// If F has any forced attributes given on the command line, add them. +static void addForcedAttributes(Function &F) { +  for (auto &S : ForceAttributes) { +    auto KV = StringRef(S).split(':'); +    if (KV.first != F.getName()) +      continue; + +    auto Kind = parseAttrKind(KV.second); +    if (Kind == Attribute::None) { +      DEBUG(dbgs() << "ForcedAttribute: " << KV.second +                   << " unknown or not handled!\n"); +      continue; +    } +    if (F.hasFnAttribute(Kind)) +      continue; +    F.addFnAttr(Kind); +  } +} + +PreservedAnalyses ForceFunctionAttrsPass::run(Module &M) { +  if (ForceAttributes.empty()) +    return PreservedAnalyses::all(); + +  for (Function &F : M.functions()) +    addForcedAttributes(F); + +  // Just conservatively invalidate analyses, this isn't likely to be important. +  return PreservedAnalyses::none(); +} + +namespace { +struct ForceFunctionAttrsLegacyPass : public ModulePass { +  static char ID; // Pass identification, replacement for typeid +  ForceFunctionAttrsLegacyPass() : ModulePass(ID) { +    initializeForceFunctionAttrsLegacyPassPass( +        *PassRegistry::getPassRegistry()); +  } + +  bool runOnModule(Module &M) override { +    if (ForceAttributes.empty()) +      return false; + +    for (Function &F : M.functions()) +      addForcedAttributes(F); + +    // Conservatively assume we changed something. +    return true; +  } +}; +} + +char ForceFunctionAttrsLegacyPass::ID = 0; +INITIALIZE_PASS(ForceFunctionAttrsLegacyPass, "forceattrs", +                "Force set function attributes", false, false) + +Pass *llvm::createForceFunctionAttrsLegacyPass() { +  return new ForceFunctionAttrsLegacyPass(); +}  | 
