LLVM  15.0.0git
MetaRenamer.cpp
Go to the documentation of this file.
1 //===- MetaRenamer.cpp - Rename everything with metasyntatic names --------===//
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 //
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
11 // program.
12 //
13 //===----------------------------------------------------------------------===//
14 
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"
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/Module.h"
30 #include "llvm/IR/PassManager.h"
31 #include "llvm/IR/Type.h"
32 #include "llvm/IR/TypeFinder.h"
33 #include "llvm/InitializePasses.h"
34 #include "llvm/Pass.h"
36 #include "llvm/Transforms/Utils.h"
37 
38 using namespace llvm;
39 
41  "rename-exclude-function-prefixes",
42  cl::desc("Prefixes for functions that don't need to be renamed, separated "
43  "by a comma"),
44  cl::Hidden);
45 
47  "rename-exclude-alias-prefixes",
48  cl::desc("Prefixes for aliases that don't need to be renamed, separated "
49  "by a comma"),
50  cl::Hidden);
51 
53  "rename-exclude-global-prefixes",
54  cl::desc(
55  "Prefixes for global values that don't need to be renamed, separated "
56  "by a comma"),
57  cl::Hidden);
58 
60  "rename-exclude-struct-prefixes",
61  cl::desc("Prefixes for structs that don't need to be renamed, separated "
62  "by a comma"),
63  cl::Hidden);
64 
65 static const char *const metaNames[] = {
66  // See http://en.wikipedia.org/wiki/Metasyntactic_variable
67  "foo", "bar", "baz", "quux", "barney", "snork", "zot", "blam", "hoge",
68  "wibble", "wobble", "widget", "wombat", "ham", "eggs", "pluto", "spam"
69 };
70 
71 namespace {
72 // This PRNG is from the ISO C spec. It is intentionally simple and
73 // unsuitable for cryptographic use. We're just looking for enough
74 // variety to surprise and delight users.
75 struct PRNG {
76  unsigned long next;
77 
78  void srand(unsigned int seed) { next = seed; }
79 
80  int rand() {
81  next = next * 1103515245 + 12345;
82  return (unsigned int)(next / 65536) % 32768;
83  }
84 };
85 
86 struct Renamer {
87  Renamer(unsigned int seed) { prng.srand(seed); }
88 
89  const char *newName() {
90  return metaNames[prng.rand() % array_lengthof(metaNames)];
91  }
92 
93  PRNG prng;
94 };
95 
96 static void
97 parseExcludedPrefixes(StringRef PrefixesStr,
98  SmallVectorImpl<StringRef> &ExcludedPrefixes) {
99  for (;;) {
100  auto PrefixesSplit = PrefixesStr.split(',');
101  if (PrefixesSplit.first.empty())
102  break;
103  ExcludedPrefixes.push_back(PrefixesSplit.first);
104  PrefixesStr = PrefixesSplit.second;
105  }
106 }
107 
108 void MetaRename(Function &F) {
109  for (Argument &Arg : F.args())
110  if (!Arg.getType()->isVoidTy())
111  Arg.setName("arg");
112 
113  for (auto &BB : F) {
114  BB.setName("bb");
115 
116  for (auto &I : BB)
117  if (!I.getType()->isVoidTy())
118  I.setName("tmp");
119  }
120 }
121 
122 void MetaRename(Module &M,
123  function_ref<TargetLibraryInfo &(Function &)> GetTLI) {
124  // Seed our PRNG with simple additive sum of ModuleID. We're looking to
125  // simply avoid always having the same function names, and we need to
126  // remain deterministic.
127  unsigned int randSeed = 0;
128  for (auto C : M.getModuleIdentifier())
129  randSeed += C;
130 
131  Renamer renamer(randSeed);
132 
133  SmallVector<StringRef, 8> ExcludedAliasesPrefixes;
134  SmallVector<StringRef, 8> ExcludedGlobalsPrefixes;
135  SmallVector<StringRef, 8> ExcludedStructsPrefixes;
136  SmallVector<StringRef, 8> ExcludedFuncPrefixes;
137  parseExcludedPrefixes(RenameExcludeAliasPrefixes, ExcludedAliasesPrefixes);
138  parseExcludedPrefixes(RenameExcludeGlobalPrefixes, ExcludedGlobalsPrefixes);
139  parseExcludedPrefixes(RenameExcludeStructPrefixes, ExcludedStructsPrefixes);
140  parseExcludedPrefixes(RenameExcludeFunctionPrefixes, ExcludedFuncPrefixes);
141 
142  auto IsNameExcluded = [](StringRef &Name,
143  SmallVectorImpl<StringRef> &ExcludedPrefixes) {
144  return any_of(ExcludedPrefixes,
145  [&Name](auto &Prefix) { return Name.startswith(Prefix); });
146  };
147 
148  // Rename all aliases
149  for (GlobalAlias &GA : M.aliases()) {
150  StringRef Name = GA.getName();
151  if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) ||
152  IsNameExcluded(Name, ExcludedAliasesPrefixes))
153  continue;
154 
155  GA.setName("alias");
156  }
157 
158  // Rename all global variables
159  for (GlobalVariable &GV : M.globals()) {
160  StringRef Name = GV.getName();
161  if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) ||
162  IsNameExcluded(Name, ExcludedGlobalsPrefixes))
163  continue;
164 
165  GV.setName("global");
166  }
167 
168  // Rename all struct types
169  TypeFinder StructTypes;
170  StructTypes.run(M, true);
171  for (StructType *STy : StructTypes) {
172  StringRef Name = STy->getName();
173  if (STy->isLiteral() || Name.empty() ||
174  IsNameExcluded(Name, ExcludedStructsPrefixes))
175  continue;
176 
177  SmallString<128> NameStorage;
178  STy->setName(
179  (Twine("struct.") + renamer.newName()).toStringRef(NameStorage));
180  }
181 
182  // Rename all functions
183  for (auto &F : M) {
184  StringRef Name = F.getName();
185  LibFunc Tmp;
186  // Leave library functions alone because their presence or absence could
187  // affect the behavior of other passes.
188  if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) ||
189  GetTLI(F).getLibFunc(F, Tmp) ||
190  IsNameExcluded(Name, ExcludedFuncPrefixes))
191  continue;
192 
193  // Leave @main alone. The output of -metarenamer might be passed to
194  // lli for execution and the latter needs a main entry point.
195  if (Name != "main")
196  F.setName(renamer.newName());
197 
198  MetaRename(F);
199  }
200 }
201 
202 struct MetaRenamer : public ModulePass {
203  // Pass identification, replacement for typeid
204  static char ID;
205 
206  MetaRenamer() : ModulePass(ID) {
208  }
209 
210  void getAnalysisUsage(AnalysisUsage &AU) const override {
212  AU.setPreservesAll();
213  }
214 
215  bool runOnModule(Module &M) override {
216  auto GetTLI = [this](Function &F) -> TargetLibraryInfo & {
217  return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
218  };
219  MetaRename(M, GetTLI);
220  return true;
221  }
222 };
223 
224 } // end anonymous namespace
225 
226 char MetaRenamer::ID = 0;
227 
228 INITIALIZE_PASS_BEGIN(MetaRenamer, "metarenamer",
229  "Assign new names to everything", false, false)
232  "Assign new names to everything", false, false)
233 
234 //===----------------------------------------------------------------------===//
235 //
236 // MetaRenamer - Rename everything with metasyntactic names.
237 //
239  return new MetaRenamer();
240 }
241 
245  auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
247  };
248  MetaRename(M, GetTLI);
249 
250  return PreservedAnalyses::all();
251 }
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
llvm::Argument
This class represents an incoming formal argument to a Function.
Definition: Argument.h:28
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:248
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:780
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:160
llvm::Function
Definition: Function.h:60
StringRef.h
Pass.h
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
llvm::GlobalVariable
Definition: GlobalVariable.h:39
llvm::GlobalAlias
Definition: GlobalAlias.h:28
FAM
FunctionAnalysisManager FAM
Definition: PassBuilderBindings.cpp:59
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:139
to
Should compile to
Definition: README.txt:449
Module.h
MetaRenamer.h
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(MetaRenamer, "metarenamer", "Assign new names to everything", false, false) INITIALIZE_PASS_END(MetaRenamer
STLExtras.h
everything
Assign new names to everything
Definition: MetaRenamer.cpp:232
new
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM ID Predecessors according to mbb< bb27, 0x8b0a7c0 > Note ADDri is not a two address instruction its result reg1037 is an operand of the PHI node in bb76 and its operand reg1039 is the result of the PHI node We should treat it as a two address code and make sure the ADDri is scheduled after any node that reads reg1039 Use info(i.e. register scavenger) to assign it a free register to allow reuse the collector could move the objects and invalidate the derived pointer This is bad enough in the first but safe points can crop up unpredictably **array_addr i32 n y store obj * new
Definition: README.txt:125
F
#define F(x, y, z)
Definition: MD5.cpp:55
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:186
Instruction.h
CommandLine.h
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
SmallString.h
llvm::StringRef::split
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:753
llvm::LibFunc
LibFunc
Definition: TargetLibraryInfo.h:35
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
Twine.h
TypeFinder.h
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::initializeMetaRenamerPass
void initializeMetaRenamerPass(PassRegistry &)
TargetLibraryInfo.h
false
Definition: StackSlotColoring.cpp:141
RenameExcludeGlobalPrefixes
static cl::opt< std::string > RenameExcludeGlobalPrefixes("rename-exclude-global-prefixes", cl::desc("Prefixes for global values that don't need to be renamed, separated " "by a comma"), cl::Hidden)
RenameExcludeStructPrefixes
static cl::opt< std::string > RenameExcludeStructPrefixes("rename-exclude-struct-prefixes", cl::desc("Prefixes for structs that don't need to be renamed, separated " "by a comma"), cl::Hidden)
llvm::MetaRenamerPass::run
PreservedAnalyses run(Module &, ModuleAnalysisManager &)
Definition: MetaRenamer.cpp:242
Utils.h
llvm::array_lengthof
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLArrayExtras.h:29
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
Type.h
llvm::SmallString< 128 >
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLFunctionalExtras.h:36
BasicBlock.h
llvm::cl::opt
Definition: CommandLine.h:1392
RenameExcludeAliasPrefixes
static cl::opt< std::string > RenameExcludeAliasPrefixes("rename-exclude-alias-prefixes", cl::desc("Prefixes for aliases that don't need to be renamed, separated " "by a comma"), cl::Hidden)
llvm::TargetLibraryInfoWrapperPass
Definition: TargetLibraryInfo.h:468
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
RenameExcludeFunctionPrefixes
static cl::opt< std::string > RenameExcludeFunctionPrefixes("rename-exclude-function-prefixes", cl::desc("Prefixes for functions that don't need to be renamed, separated " "by a comma"), cl::Hidden)
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::createMetaRenamerPass
ModulePass * createMetaRenamerPass()
Definition: MetaRenamer.cpp:238
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::any_of
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1624
llvm::StructType
Class to represent struct types.
Definition: DerivedTypes.h:213
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::TypeFinder::run
void run(const Module &M, bool onlyNamed)
Definition: TypeFinder.cpp:34
llvm::TypeFinder
TypeFinder - Walk over a module, identifying all of the types that are used by the module.
Definition: TypeFinder.h:31
metaNames
static const char *const metaNames[]
Definition: MetaRenamer.cpp:65
Argument.h
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::AnalysisUsage::setPreservesAll
void setPreservesAll()
Set by analyses that do not transform their input at all.
Definition: PassAnalysisSupport.h:130
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:158
GlobalVariable.h
Function.h
PassManager.h
llvm::TargetLibraryInfo
Provides information about what library functions are available for the current target.
Definition: TargetLibraryInfo.h:222
GlobalAlias.h
SmallVector.h
llvm::SmallVectorImpl< StringRef >
DerivedTypes.h
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:42
llvm::InnerAnalysisManagerProxy
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:937
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
llvm::cl::desc
Definition: CommandLine.h:405
InitializePasses.h
llvm::TargetLibraryAnalysis
Analysis pass providing the TargetLibraryInfo.
Definition: TargetLibraryInfo.h:443
metarenamer
metarenamer
Definition: MetaRenamer.cpp:231
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38