diff --git a/llvm/include/llvm/Transforms/Utils/MetaRenamer.h b/llvm/include/llvm/Transforms/Utils/MetaRenamer.h index fff3dff75837e..165940428b158 100644 --- a/llvm/include/llvm/Transforms/Utils/MetaRenamer.h +++ b/llvm/include/llvm/Transforms/Utils/MetaRenamer.h @@ -18,7 +18,32 @@ #include "llvm/IR/PassManager.h" namespace llvm { + +struct MetaRenamerOptions { + /// Prefixes for functions that don't need to be renamed + SmallVector ExcludedFunctionsPrefixes; + + /// Prefixes for aliases that don't need to be renamed + SmallVector ExcludedAliasesPrefixes; + + /// Prefixes for global values that don't need to be renamed + SmallVector ExcludedGlobalsPrefixes; + + /// Prefixes for structs that don't need to be renamed + SmallVector ExcludedStructsPrefixes; + + /// Only rename the instructions in the function + bool RenameOnlyInst = false; +}; + struct MetaRenamerPass : PassInfoMixin { +private: + const MetaRenamerOptions Options; + +public: + MetaRenamerPass(MetaRenamerOptions Options = MetaRenamerOptions()) + : Options(Options) {} + PreservedAnalyses run(Module &, ModuleAnalysisManager &); }; } // namespace llvm diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 5cda1517e127d..ffa91f1f766ad 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -176,6 +176,7 @@ #include "llvm/Passes/OptimizationLevel.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Regex.h" @@ -947,6 +948,35 @@ parseLowerAllowCheckPassOptions(StringRef Params) { return Result; } +Expected parseMetaRenamerPassOptions(StringRef Params) { + MetaRenamerOptions Result; + + while (!Params.empty()) { + StringRef ParamName; + std::tie(ParamName, Params) = Params.split(';'); + bool Enable = !ParamName.consume_front("no-"); + + if (ParamName == "rename-only-inst") { + Result.RenameOnlyInst = Enable; + } else if (ParamName.consume_front("rename-exclude-struct-prefixes=")) { + Result.ExcludedStructsPrefixes.push_back(ParamName); + } else if (ParamName.consume_front("rename-exclude-global-prefixes=")) { + Result.ExcludedGlobalsPrefixes.push_back(ParamName); + } else if (ParamName.consume_front("rename-exclude-alias-prefixes=")) { + Result.ExcludedAliasesPrefixes.push_back(ParamName); + } else if (ParamName.consume_front("rename-exclude-function-prefixes=")) { + Result.ExcludedFunctionsPrefixes.push_back(ParamName); + } else { + return make_error( + formatv("invalid metarenamer pass parameter '{0}' ", ParamName) + .str(), + inconvertibleErrorCode()); + } + } + + return Result; +} + Expected parseMSanPassOptions(StringRef Params) { MemorySanitizerOptions Result; while (!Params.empty()) { diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 510a505995304..7d5be4a6af2a5 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -103,7 +103,6 @@ MODULE_PASS("pgo-force-function-attrs", PGOForceFunctionAttrsPass(PGOOpt ? PGOOp MODULE_PASS("memprof-context-disambiguation", MemProfContextDisambiguation()) MODULE_PASS("memprof-module", ModuleMemProfilerPass()) MODULE_PASS("mergefunc", MergeFunctionsPass()) -MODULE_PASS("metarenamer", MetaRenamerPass()) MODULE_PASS("module-inline", ModuleInlinerPass()) MODULE_PASS("name-anon-globals", NameAnonGlobalPass()) MODULE_PASS("no-op-module", NoOpModulePass()) @@ -233,7 +232,13 @@ MODULE_PASS_WITH_PARAMS( return StructuralHashPrinterPass(errs(), Options); }, parseStructuralHashPrinterPassOptions, "detailed;call-target-ignored") - +MODULE_PASS_WITH_PARAMS( + "metarenamer", "MetaRenamerPass", + [](MetaRenamerOptions Options) { return MetaRenamerPass(Options); }, + parseMetaRenamerPassOptions, + "rename-exclude-function-prefixes=S;rename-exclude-alias-prefixes=S;rename-" + "exclude-global-prefixes=S;rename-exclude-struct-prefixes=S;no-rename-only-" + "inst;rename-only-inst") #undef MODULE_PASS_WITH_PARAMS #ifndef CGSCC_ANALYSIS diff --git a/llvm/lib/Transforms/Utils/MetaRenamer.cpp b/llvm/lib/Transforms/Utils/MetaRenamer.cpp index fd0112ae529cc..6f694c4467031 100644 --- a/llvm/lib/Transforms/Utils/MetaRenamer.cpp +++ b/llvm/lib/Transforms/Utils/MetaRenamer.cpp @@ -35,36 +35,6 @@ using namespace llvm; -static cl::opt RenameExcludeFunctionPrefixes( - "rename-exclude-function-prefixes", - cl::desc("Prefixes for functions that don't need to be renamed, separated " - "by a comma"), - cl::Hidden); - -static cl::opt RenameExcludeAliasPrefixes( - "rename-exclude-alias-prefixes", - cl::desc("Prefixes for aliases that don't need to be renamed, separated " - "by a comma"), - cl::Hidden); - -static cl::opt RenameExcludeGlobalPrefixes( - "rename-exclude-global-prefixes", - cl::desc( - "Prefixes for global values that don't need to be renamed, separated " - "by a comma"), - cl::Hidden); - -static cl::opt RenameExcludeStructPrefixes( - "rename-exclude-struct-prefixes", - cl::desc("Prefixes for structs that don't need to be renamed, separated " - "by a comma"), - cl::Hidden); - -static cl::opt - RenameOnlyInst("rename-only-inst", cl::init(false), - cl::desc("only rename the instructions in the function"), - cl::Hidden); - static const char *const metaNames[] = { // See http://en.wikipedia.org/wiki/Metasyntactic_variable "foo", "bar", "baz", "quux", "barney", "snork", "zot", "blam", "hoge", @@ -96,18 +66,6 @@ struct Renamer { PRNG prng; }; -static void -parseExcludedPrefixes(StringRef PrefixesStr, - SmallVectorImpl &ExcludedPrefixes) { - for (;;) { - auto PrefixesSplit = PrefixesStr.split(','); - if (PrefixesSplit.first.empty()) - break; - ExcludedPrefixes.push_back(PrefixesSplit.first); - PrefixesStr = PrefixesSplit.second; - } -} - void MetaRenameOnlyInstructions(Function &F) { for (auto &I : instructions(F)) if (!I.getType()->isVoidTy() && I.getName().empty()) @@ -129,7 +87,8 @@ void MetaRename(Function &F) { } void MetaRename(Module &M, - function_ref GetTLI) { + function_ref GetTLI, + const MetaRenamerOptions &Options) { // Seed our PRNG with simple additive sum of ModuleID. We're looking to // simply avoid always having the same function names, and we need to // remain deterministic. @@ -139,17 +98,8 @@ void MetaRename(Module &M, Renamer renamer(randSeed); - SmallVector ExcludedAliasesPrefixes; - SmallVector ExcludedGlobalsPrefixes; - SmallVector ExcludedStructsPrefixes; - SmallVector ExcludedFuncPrefixes; - parseExcludedPrefixes(RenameExcludeAliasPrefixes, ExcludedAliasesPrefixes); - parseExcludedPrefixes(RenameExcludeGlobalPrefixes, ExcludedGlobalsPrefixes); - parseExcludedPrefixes(RenameExcludeStructPrefixes, ExcludedStructsPrefixes); - parseExcludedPrefixes(RenameExcludeFunctionPrefixes, ExcludedFuncPrefixes); - auto IsNameExcluded = [](StringRef &Name, - SmallVectorImpl &ExcludedPrefixes) { + const SmallVectorImpl &ExcludedPrefixes) { return any_of(ExcludedPrefixes, [&Name](auto &Prefix) { return Name.starts_with(Prefix); }); }; @@ -161,10 +111,10 @@ void MetaRename(Module &M, StringRef Name = F.getName(); return Name.starts_with("llvm.") || (!Name.empty() && Name[0] == 1) || GetTLI(F).getLibFunc(F, Tmp) || - IsNameExcluded(Name, ExcludedFuncPrefixes); + IsNameExcluded(Name, Options.ExcludedFunctionsPrefixes); }; - if (RenameOnlyInst) { + if (Options.RenameOnlyInst) { // Rename all functions for (auto &F : M) { if (ExcludeLibFuncs(F)) @@ -178,7 +128,7 @@ void MetaRename(Module &M, for (GlobalAlias &GA : M.aliases()) { StringRef Name = GA.getName(); if (Name.starts_with("llvm.") || (!Name.empty() && Name[0] == 1) || - IsNameExcluded(Name, ExcludedAliasesPrefixes)) + IsNameExcluded(Name, Options.ExcludedAliasesPrefixes)) continue; GA.setName("alias"); @@ -188,7 +138,7 @@ void MetaRename(Module &M, for (GlobalVariable &GV : M.globals()) { StringRef Name = GV.getName(); if (Name.starts_with("llvm.") || (!Name.empty() && Name[0] == 1) || - IsNameExcluded(Name, ExcludedGlobalsPrefixes)) + IsNameExcluded(Name, Options.ExcludedGlobalsPrefixes)) continue; GV.setName("global"); @@ -200,7 +150,7 @@ void MetaRename(Module &M, for (StructType *STy : StructTypes) { StringRef Name = STy->getName(); if (STy->isLiteral() || Name.empty() || - IsNameExcluded(Name, ExcludedStructsPrefixes)) + IsNameExcluded(Name, Options.ExcludedStructsPrefixes)) continue; SmallString<128> NameStorage; @@ -230,7 +180,7 @@ PreservedAnalyses MetaRenamerPass::run(Module &M, ModuleAnalysisManager &AM) { auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & { return FAM.getResult(F); }; - MetaRename(M, GetTLI); + MetaRename(M, GetTLI, Options); return PreservedAnalyses::all(); } diff --git a/llvm/test/Transforms/MetaRenamer/exclude-names.ll b/llvm/test/Transforms/MetaRenamer/exclude-names.ll index 6e088ef7f4190..d53a0f96a51fe 100644 --- a/llvm/test/Transforms/MetaRenamer/exclude-names.ll +++ b/llvm/test/Transforms/MetaRenamer/exclude-names.ll @@ -1,4 +1,4 @@ -; RUN: opt -passes=metarenamer -rename-exclude-function-prefixes=my_func -rename-exclude-global-prefixes=my_global -rename-exclude-struct-prefixes=my_struct -rename-exclude-alias-prefixes=my_alias -S %s | FileCheck %s +; RUN: opt -passes='metarenamer' -S %s | FileCheck %s ; Check that excluded names don't get renamed while all the other ones do diff --git a/llvm/test/Transforms/MetaRenamer/invalid-pass-parameter.ll b/llvm/test/Transforms/MetaRenamer/invalid-pass-parameter.ll new file mode 100644 index 0000000000000..2e672f9409b12 --- /dev/null +++ b/llvm/test/Transforms/MetaRenamer/invalid-pass-parameter.ll @@ -0,0 +1,9 @@ +; RUN: not opt -S -passes='metarenamer' %s 2>&1 | FileCheck -check-prefix=ERR %s + +; ERR: invalid metarenamer pass parameter 'invalid' + +define i32 @0(i32, i32) { + %3 = add i32 %0, %1 + ret i32 %3 +} + diff --git a/llvm/test/Transforms/MetaRenamer/only-inst.ll b/llvm/test/Transforms/MetaRenamer/only-inst.ll index f13371519682f..c423bab08e301 100644 --- a/llvm/test/Transforms/MetaRenamer/only-inst.ll +++ b/llvm/test/Transforms/MetaRenamer/only-inst.ll @@ -1,4 +1,4 @@ -; RUN: opt -passes=metarenamer -rename-only-inst=1 -S < %s | FileCheck %s +; RUN: opt -passes='metarenamer' -S < %s | FileCheck %s target triple = "x86_64-pc-linux-gnu" ; CHECK: %struct.foo_xxx = type { i32, float, %struct.bar_xxx } diff --git a/llvm/test/Transforms/MetaRenamer/semicolon-substr.ll b/llvm/test/Transforms/MetaRenamer/semicolon-substr.ll new file mode 100644 index 0000000000000..131a03cebefca --- /dev/null +++ b/llvm/test/Transforms/MetaRenamer/semicolon-substr.ll @@ -0,0 +1,14 @@ +; RUN: opt -passes='metarenamer' -S %s | FileCheck %s + +; CHECK: define i32 @my_func( +define i32 @my_func(i32, i32) { + %3 = add i32 %0, %1 + ret i32 %3 +} + +; CHECK: define i32 @some_func( +define i32 @some_func(i32, i32) { + %3 = add i32 %0, %1 + ret i32 %3 +} +