diff --git a/llvm/lib/Transforms/Utils/MetaRenamer.cpp b/llvm/lib/Transforms/Utils/MetaRenamer.cpp --- a/llvm/lib/Transforms/Utils/MetaRenamer.cpp +++ b/llvm/lib/Transforms/Utils/MetaRenamer.cpp @@ -15,6 +15,7 @@ #include "llvm/Transforms/Utils/MetaRenamer.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/Analysis/TargetLibraryInfo.h" @@ -31,10 +32,36 @@ #include "llvm/IR/TypeFinder.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Transforms/Utils.h" 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 const char *const metaNames[] = { // See http://en.wikipedia.org/wiki/Metasyntactic_variable "foo", "bar", "baz", "quux", "barney", "snork", "zot", "blam", "hoge", @@ -66,6 +93,18 @@ 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 MetaRename(Function &F) { for (Argument &Arg : F.args()) if (!Arg.getType()->isVoidTy()) @@ -91,10 +130,26 @@ 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) { + return any_of(ExcludedPrefixes, + [&Name](auto &Prefix) { return Name.startswith(Prefix); }); + }; + // Rename all aliases for (GlobalAlias &GA : M.aliases()) { StringRef Name = GA.getName(); - if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1)) + if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) || + IsNameExcluded(Name, ExcludedAliasesPrefixes)) continue; GA.setName("alias"); @@ -103,7 +158,8 @@ // Rename all global variables for (GlobalVariable &GV : M.globals()) { StringRef Name = GV.getName(); - if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1)) + if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) || + IsNameExcluded(Name, ExcludedGlobalsPrefixes)) continue; GV.setName("global"); @@ -113,7 +169,9 @@ TypeFinder StructTypes; StructTypes.run(M, true); for (StructType *STy : StructTypes) { - if (STy->isLiteral() || STy->getName().empty()) + StringRef Name = STy->getName(); + if (STy->isLiteral() || Name.empty() || + IsNameExcluded(Name, ExcludedStructsPrefixes)) continue; SmallString<128> NameStorage; @@ -128,7 +186,8 @@ // Leave library functions alone because their presence or absence could // affect the behavior of other passes. if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) || - GetTLI(F).getLibFunc(F, Tmp)) + GetTLI(F).getLibFunc(F, Tmp) || + IsNameExcluded(Name, ExcludedFuncPrefixes)) continue; // Leave @main alone. The output of -metarenamer might be passed to diff --git a/llvm/test/Transforms/MetaRenamer/exclude-names.ll b/llvm/test/Transforms/MetaRenamer/exclude-names.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/MetaRenamer/exclude-names.ll @@ -0,0 +1,58 @@ +; 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 + +; Check that excluded names don't get renamed while all the other ones do + +; CHECK: %my_struct1 = type { i8*, i32 } +; CHECK: %my_struct2 = type { i8*, i32 } +; CHECK-NOT: %other_struct = type { i8*, i32 } +; CHECK: @my_global1 = global i32 42 +; CHECK: @my_global2 = global i32 24 +; CHECK-NOT: @other_global = global i32 24 +; CHECK: @my_alias1 = alias i32, i32* @my_global1 +; CHECK: @my_alias2 = alias i32, i32* @my_global2 +; CHECK-NOT: @other_alias = alias i32, i32* @other_global +; CHECK: declare void @my_func1 +; CHECK: declare void @my_func2 +; CHECK-NOT: declare void @other_func + +; CHECK: call void @my_func1 +; CHECK: call void @my_func2 +; CHECK-NOT: call void @other_func +; CHECK: load i32, i32* @my_global1 +; CHECK: load i32, i32* @my_global2 +; CHECK-NOT: load i32, i32* @other_global +; CHECK: load i32, i32* @my_alias1 +; CHECK: load i32, i32* @my_alias2 +; CHECK-NOT: load i32, i32* @other_alias +; CHECK: alloca %my_struct1 +; CHECK: alloca %my_struct2 +; CHECK-NOT: alloca %other_struct + +%my_struct1 = type { i8*, i32 } +%my_struct2 = type { i8*, i32 } +%other_struct = type { i8*, i32 } +@my_global1 = global i32 42 +@my_global2 = global i32 24 +@other_global = global i32 24 +@my_alias1 = alias i32, i32* @my_global1 +@my_alias2 = alias i32, i32* @my_global2 +@other_alias = alias i32, i32* @other_global +declare void @my_func1() +declare void @my_func2() +declare void @other_func() + +define void @some_func() { + call void @my_func1() + call void @my_func2() + call void @other_func() + %a = load i32, i32* @my_global1 + %b = load i32, i32* @my_global2 + %c = load i32, i32* @other_global + %d = load i32, i32* @my_alias1 + %e = load i32, i32* @my_alias2 + %f = load i32, i32* @other_alias + %g = alloca %my_struct1 + %h = alloca %my_struct2 + %i = alloca %other_struct + ret void +}