ForceFunctionAttrs.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. #include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
  9. #include "llvm/IR/Function.h"
  10. #include "llvm/IR/Module.h"
  11. #include "llvm/InitializePasses.h"
  12. #include "llvm/Pass.h"
  13. #include "llvm/Support/CommandLine.h"
  14. #include "llvm/Support/Debug.h"
  15. #include "llvm/Support/raw_ostream.h"
  16. using namespace llvm;
  17. #define DEBUG_TYPE "forceattrs"
  18. static cl::list<std::string>
  19. ForceAttributes("force-attribute", cl::Hidden,
  20. cl::desc("Add an attribute to a function. This should be a "
  21. "pair of 'function-name:attribute-name', for "
  22. "example -force-attribute=foo:noinline. This "
  23. "option can be specified multiple times."));
  24. static cl::list<std::string> ForceRemoveAttributes(
  25. "force-remove-attribute", cl::Hidden,
  26. cl::desc("Remove an attribute from a function. This should be a "
  27. "pair of 'function-name:attribute-name', for "
  28. "example -force-remove-attribute=foo:noinline. This "
  29. "option can be specified multiple times."));
  30. /// If F has any forced attributes given on the command line, add them.
  31. /// If F has any forced remove attributes given on the command line, remove
  32. /// them. When both force and force-remove are given to a function, the latter
  33. /// takes precedence.
  34. static void forceAttributes(Function &F) {
  35. auto ParseFunctionAndAttr = [&](StringRef S) {
  36. auto Kind = Attribute::None;
  37. auto KV = StringRef(S).split(':');
  38. if (KV.first != F.getName())
  39. return Kind;
  40. Kind = Attribute::getAttrKindFromName(KV.second);
  41. if (Kind == Attribute::None || !Attribute::canUseAsFnAttr(Kind)) {
  42. LLVM_DEBUG(dbgs() << "ForcedAttribute: " << KV.second
  43. << " unknown or not a function attribute!\n");
  44. }
  45. return Kind;
  46. };
  47. for (const auto &S : ForceAttributes) {
  48. auto Kind = ParseFunctionAndAttr(S);
  49. if (Kind == Attribute::None || F.hasFnAttribute(Kind))
  50. continue;
  51. F.addFnAttr(Kind);
  52. }
  53. for (const auto &S : ForceRemoveAttributes) {
  54. auto Kind = ParseFunctionAndAttr(S);
  55. if (Kind == Attribute::None || !F.hasFnAttribute(Kind))
  56. continue;
  57. F.removeFnAttr(Kind);
  58. }
  59. }
  60. static bool hasForceAttributes() {
  61. return !ForceAttributes.empty() || !ForceRemoveAttributes.empty();
  62. }
  63. PreservedAnalyses ForceFunctionAttrsPass::run(Module &M,
  64. ModuleAnalysisManager &) {
  65. if (!hasForceAttributes())
  66. return PreservedAnalyses::all();
  67. for (Function &F : M.functions())
  68. forceAttributes(F);
  69. // Just conservatively invalidate analyses, this isn't likely to be important.
  70. return PreservedAnalyses::none();
  71. }
  72. namespace {
  73. struct ForceFunctionAttrsLegacyPass : public ModulePass {
  74. static char ID; // Pass identification, replacement for typeid
  75. ForceFunctionAttrsLegacyPass() : ModulePass(ID) {
  76. initializeForceFunctionAttrsLegacyPassPass(
  77. *PassRegistry::getPassRegistry());
  78. }
  79. bool runOnModule(Module &M) override {
  80. if (!hasForceAttributes())
  81. return false;
  82. for (Function &F : M.functions())
  83. forceAttributes(F);
  84. // Conservatively assume we changed something.
  85. return true;
  86. }
  87. };
  88. }
  89. char ForceFunctionAttrsLegacyPass::ID = 0;
  90. INITIALIZE_PASS(ForceFunctionAttrsLegacyPass, "forceattrs",
  91. "Force set function attributes", false, false)
  92. Pass *llvm::createForceFunctionAttrsLegacyPass() {
  93. return new ForceFunctionAttrsLegacyPass();
  94. }