1 //===- MetaRenamer.cpp - Rename everything with metasyntatic names --------===//
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
7 //===----------------------------------------------------------------------===//
9 // This pass renames everything with metasyntatic names. The intent is to use
10 // this pass after bugpoint reduction to conceal the nature of the original
13 //===----------------------------------------------------------------------===//
15 #include "llvm/Transforms/Utils/MetaRenamer.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/Analysis/TargetLibraryInfo.h"
22 #include "llvm/IR/Argument.h"
23 #include "llvm/IR/BasicBlock.h"
24 #include "llvm/IR/DerivedTypes.h"
25 #include "llvm/IR/Function.h"
26 #include "llvm/IR/GlobalAlias.h"
27 #include "llvm/IR/GlobalVariable.h"
28 #include "llvm/IR/Instruction.h"
29 #include "llvm/IR/InstIterator.h"
30 #include "llvm/IR/Module.h"
31 #include "llvm/IR/PassManager.h"
32 #include "llvm/IR/Type.h"
33 #include "llvm/IR/TypeFinder.h"
34 #include "llvm/Support/CommandLine.h"
38 static cl::opt
<std::string
> RenameExcludeFunctionPrefixes(
39 "rename-exclude-function-prefixes",
40 cl::desc("Prefixes for functions that don't need to be renamed, separated "
44 static cl::opt
<std::string
> RenameExcludeAliasPrefixes(
45 "rename-exclude-alias-prefixes",
46 cl::desc("Prefixes for aliases that don't need to be renamed, separated "
50 static cl::opt
<std::string
> RenameExcludeGlobalPrefixes(
51 "rename-exclude-global-prefixes",
53 "Prefixes for global values that don't need to be renamed, separated "
57 static cl::opt
<std::string
> RenameExcludeStructPrefixes(
58 "rename-exclude-struct-prefixes",
59 cl::desc("Prefixes for structs that don't need to be renamed, separated "
64 RenameOnlyInst("rename-only-inst", cl::init(false),
65 cl::desc("only rename the instructions in the function"),
68 static const char *const metaNames
[] = {
69 // See http://en.wikipedia.org/wiki/Metasyntactic_variable
70 "foo", "bar", "baz", "quux", "barney", "snork", "zot", "blam", "hoge",
71 "wibble", "wobble", "widget", "wombat", "ham", "eggs", "pluto", "spam"
75 // This PRNG is from the ISO C spec. It is intentionally simple and
76 // unsuitable for cryptographic use. We're just looking for enough
77 // variety to surprise and delight users.
81 void srand(unsigned int seed
) { next
= seed
; }
84 next
= next
* 1103515245 + 12345;
85 return (unsigned int)(next
/ 65536) % 32768;
90 Renamer(unsigned int seed
) { prng
.srand(seed
); }
92 const char *newName() {
93 return metaNames
[prng
.rand() % std::size(metaNames
)];
100 parseExcludedPrefixes(StringRef PrefixesStr
,
101 SmallVectorImpl
<StringRef
> &ExcludedPrefixes
) {
103 auto PrefixesSplit
= PrefixesStr
.split(',');
104 if (PrefixesSplit
.first
.empty())
106 ExcludedPrefixes
.push_back(PrefixesSplit
.first
);
107 PrefixesStr
= PrefixesSplit
.second
;
111 void MetaRenameOnlyInstructions(Function
&F
) {
112 for (auto &I
: instructions(F
))
113 if (!I
.getType()->isVoidTy() && I
.getName().empty())
114 I
.setName(I
.getOpcodeName());
117 void MetaRename(Function
&F
) {
118 for (Argument
&Arg
: F
.args())
119 if (!Arg
.getType()->isVoidTy())
126 if (!I
.getType()->isVoidTy())
127 I
.setName(I
.getOpcodeName());
131 void MetaRename(Module
&M
,
132 function_ref
<TargetLibraryInfo
&(Function
&)> GetTLI
) {
133 // Seed our PRNG with simple additive sum of ModuleID. We're looking to
134 // simply avoid always having the same function names, and we need to
135 // remain deterministic.
136 unsigned int randSeed
= 0;
137 for (auto C
: M
.getModuleIdentifier())
140 Renamer
renamer(randSeed
);
142 SmallVector
<StringRef
, 8> ExcludedAliasesPrefixes
;
143 SmallVector
<StringRef
, 8> ExcludedGlobalsPrefixes
;
144 SmallVector
<StringRef
, 8> ExcludedStructsPrefixes
;
145 SmallVector
<StringRef
, 8> ExcludedFuncPrefixes
;
146 parseExcludedPrefixes(RenameExcludeAliasPrefixes
, ExcludedAliasesPrefixes
);
147 parseExcludedPrefixes(RenameExcludeGlobalPrefixes
, ExcludedGlobalsPrefixes
);
148 parseExcludedPrefixes(RenameExcludeStructPrefixes
, ExcludedStructsPrefixes
);
149 parseExcludedPrefixes(RenameExcludeFunctionPrefixes
, ExcludedFuncPrefixes
);
151 auto IsNameExcluded
= [](StringRef
&Name
,
152 SmallVectorImpl
<StringRef
> &ExcludedPrefixes
) {
153 return any_of(ExcludedPrefixes
,
154 [&Name
](auto &Prefix
) { return Name
.starts_with(Prefix
); });
157 // Leave library functions alone because their presence or absence could
158 // affect the behavior of other passes.
159 auto ExcludeLibFuncs
= [&](Function
&F
) {
161 StringRef Name
= F
.getName();
162 return Name
.starts_with("llvm.") || (!Name
.empty() && Name
[0] == 1) ||
163 GetTLI(F
).getLibFunc(F
, Tmp
) ||
164 IsNameExcluded(Name
, ExcludedFuncPrefixes
);
167 if (RenameOnlyInst
) {
168 // Rename all functions
170 if (ExcludeLibFuncs(F
))
172 MetaRenameOnlyInstructions(F
);
177 // Rename all aliases
178 for (GlobalAlias
&GA
: M
.aliases()) {
179 StringRef Name
= GA
.getName();
180 if (Name
.starts_with("llvm.") || (!Name
.empty() && Name
[0] == 1) ||
181 IsNameExcluded(Name
, ExcludedAliasesPrefixes
))
187 // Rename all global variables
188 for (GlobalVariable
&GV
: M
.globals()) {
189 StringRef Name
= GV
.getName();
190 if (Name
.starts_with("llvm.") || (!Name
.empty() && Name
[0] == 1) ||
191 IsNameExcluded(Name
, ExcludedGlobalsPrefixes
))
194 GV
.setName("global");
197 // Rename all struct types
198 TypeFinder StructTypes
;
199 StructTypes
.run(M
, true);
200 for (StructType
*STy
: StructTypes
) {
201 StringRef Name
= STy
->getName();
202 if (STy
->isLiteral() || Name
.empty() ||
203 IsNameExcluded(Name
, ExcludedStructsPrefixes
))
206 SmallString
<128> NameStorage
;
208 (Twine("struct.") + renamer
.newName()).toStringRef(NameStorage
));
211 // Rename all functions
213 if (ExcludeLibFuncs(F
))
216 // Leave @main alone. The output of -metarenamer might be passed to
217 // lli for execution and the latter needs a main entry point.
218 if (F
.getName() != "main")
219 F
.setName(renamer
.newName());
225 } // end anonymous namespace
227 PreservedAnalyses
MetaRenamerPass::run(Module
&M
, ModuleAnalysisManager
&AM
) {
228 FunctionAnalysisManager
&FAM
=
229 AM
.getResult
<FunctionAnalysisManagerModuleProxy
>(M
).getManager();
230 auto GetTLI
= [&FAM
](Function
&F
) -> TargetLibraryInfo
& {
231 return FAM
.getResult
<TargetLibraryAnalysis
>(F
);
233 MetaRename(M
, GetTLI
);
235 return PreservedAnalyses::all();