1 //===-- JumpInstrTables.cpp: Jump-Instruction Tables ----------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
9 /// \brief An implementation of jump-instruction tables.
11 //===----------------------------------------------------------------------===//
13 #define DEBUG_TYPE "jt"
15 #include "llvm/CodeGen/JumpInstrTables.h"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/Analysis/JumpInstrTableInfo.h"
19 #include "llvm/CodeGen/Passes.h"
20 #include "llvm/IR/Attributes.h"
21 #include "llvm/IR/CallSite.h"
22 #include "llvm/IR/Constants.h"
23 #include "llvm/IR/DerivedTypes.h"
24 #include "llvm/IR/Function.h"
25 #include "llvm/IR/LLVMContext.h"
26 #include "llvm/IR/Module.h"
27 #include "llvm/IR/Operator.h"
28 #include "llvm/IR/Type.h"
29 #include "llvm/IR/Verifier.h"
30 #include "llvm/Support/CommandLine.h"
31 #include "llvm/Support/Debug.h"
32 #include "llvm/Support/raw_ostream.h"
38 char JumpInstrTables::ID = 0;
40 INITIALIZE_PASS_BEGIN(JumpInstrTables, "jump-instr-tables",
41 "Jump-Instruction Tables", true, true)
42 INITIALIZE_PASS_DEPENDENCY(JumpInstrTableInfo);
43 INITIALIZE_PASS_END(JumpInstrTables, "jump-instr-tables",
44 "Jump-Instruction Tables", true, true)
46 STATISTIC(NumJumpTables, "Number of indirect call tables generated");
47 STATISTIC(NumFuncsInJumpTables, "Number of functions in the jump tables");
49 ModulePass *llvm::createJumpInstrTablesPass() {
50 // The default implementation uses a single table for all functions.
51 return new JumpInstrTables(JumpTable::Single);
54 ModulePass *llvm::createJumpInstrTablesPass(JumpTable::JumpTableType JTT) {
55 return new JumpInstrTables(JTT);
59 static const char jump_func_prefix[] = "__llvm_jump_instr_table_";
60 static const char jump_section_prefix[] = ".jump.instr.table.text.";
62 // Checks to see if a given CallSite is making an indirect call, including
63 // cases where the indirect call is made through a bitcast.
64 bool isIndirectCall(CallSite &CS) {
65 if (CS.getCalledFunction())
68 // Check the value to see if it is merely a bitcast of a function. In
69 // this case, it will translate to a direct function call in the resulting
70 // assembly, so we won't treat it as an indirect call here.
71 const Value *V = CS.getCalledValue();
72 if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
73 return !(CE->isCast() && isa<Function>(CE->getOperand(0)));
76 // Otherwise, since we know it's a call, it must be an indirect call
80 // Replaces Functions and GlobalAliases with a different Value.
81 bool replaceGlobalValueIndirectUse(GlobalValue *GV, Value *V, Use *U) {
82 User *Us = U->getUser();
85 if (Instruction *I = dyn_cast<Instruction>(Us)) {
88 // Don't do the replacement if this use is a direct call to this function.
89 // If the use is not the called value, then replace it.
90 if (CS && (isIndirectCall(CS) || CS.isCallee(U))) {
95 } else if (Constant *C = dyn_cast<Constant>(Us)) {
96 // Don't replace calls to bitcasts of function symbols, since they get
97 // translated to direct calls.
98 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Us)) {
99 if (CE->getOpcode() == Instruction::BitCast) {
100 // This bitcast must have exactly one user.
101 if (CE->user_begin() != CE->user_end()) {
102 User *ParentUs = *CE->user_begin();
103 if (CallInst *CI = dyn_cast<CallInst>(ParentUs)) {
105 Use &CEU = *CE->use_begin();
106 if (CS.isCallee(&CEU)) {
114 // GlobalAlias doesn't support replaceUsesOfWithOnConstant. And the verifier
115 // requires alias to point to a defined function. So, GlobalAlias is handled
116 // as a separate case in runOnModule.
117 if (!isa<GlobalAlias>(C))
118 C->replaceUsesOfWithOnConstant(GV, V, U);
120 assert(false && "The Use of a Function symbol is neither an instruction nor"
127 // Replaces all replaceable address-taken uses of GV with a pointer to a
128 // jump-instruction table entry.
129 void replaceValueWithFunction(GlobalValue *GV, Function *F) {
130 // Go through all uses of this function and replace the uses of GV with the
131 // jump-table version of the function. Get the uses as a vector before
132 // replacing them, since replacing them changes the use list and invalidates
133 // the iterator otherwise.
134 for (Value::use_iterator I = GV->use_begin(), E = GV->use_end(); I != E;) {
137 // Replacement of constants replaces all instances in the constant. So, some
138 // uses might have already been handled by the time we reach them here.
140 replaceGlobalValueIndirectUse(GV, F, &U);
145 } // end anonymous namespace
147 JumpInstrTables::JumpInstrTables()
148 : ModulePass(ID), Metadata(), JITI(nullptr), TableCount(0),
149 JTType(JumpTable::Single) {
150 initializeJumpInstrTablesPass(*PassRegistry::getPassRegistry());
153 JumpInstrTables::JumpInstrTables(JumpTable::JumpTableType JTT)
154 : ModulePass(ID), Metadata(), JITI(nullptr), TableCount(0), JTType(JTT) {
155 initializeJumpInstrTablesPass(*PassRegistry::getPassRegistry());
158 JumpInstrTables::~JumpInstrTables() {}
160 void JumpInstrTables::getAnalysisUsage(AnalysisUsage &AU) const {
161 AU.addRequired<JumpInstrTableInfo>();
164 Function *JumpInstrTables::insertEntry(Module &M, Function *Target) {
165 FunctionType *OrigFunTy = Target->getFunctionType();
166 FunctionType *FunTy = transformType(JTType, OrigFunTy);
168 JumpMap::iterator it = Metadata.find(FunTy);
169 if (Metadata.end() == it) {
170 struct TableMeta Meta;
171 Meta.TableNum = TableCount;
173 Metadata[FunTy] = Meta;
174 it = Metadata.find(FunTy);
181 std::string NewName(jump_func_prefix);
182 NewName += (Twine(it->second.TableNum) + "_" + Twine(it->second.Count)).str();
184 Function::Create(OrigFunTy, GlobalValue::ExternalLinkage, NewName, &M);
185 // The section for this table
186 JumpFun->setSection((jump_section_prefix + Twine(it->second.TableNum)).str());
187 JITI->insertEntry(FunTy, Target, JumpFun);
189 ++NumFuncsInJumpTables;
193 bool JumpInstrTables::hasTable(FunctionType *FunTy) {
194 FunctionType *TransTy = transformType(JTType, FunTy);
195 return Metadata.end() != Metadata.find(TransTy);
198 FunctionType *JumpInstrTables::transformType(JumpTable::JumpTableType JTT,
199 FunctionType *FunTy) {
200 // Returning nullptr forces all types into the same table, since all types map
202 Type *VoidPtrTy = Type::getInt8PtrTy(FunTy->getContext());
204 // Ignore the return type.
205 Type *RetTy = VoidPtrTy;
206 bool IsVarArg = FunTy->isVarArg();
207 std::vector<Type *> ParamTys(FunTy->getNumParams());
208 FunctionType::param_iterator PI, PE;
211 std::vector<Type *> EmptyParams;
212 Type *Int32Ty = Type::getInt32Ty(FunTy->getContext());
213 FunctionType *VoidFnTy = FunctionType::get(
214 Type::getVoidTy(FunTy->getContext()), EmptyParams, false);
216 case JumpTable::Single:
218 return FunctionType::get(RetTy, EmptyParams, false);
219 case JumpTable::Arity:
220 // Transform all types to void* so that all functions with the same arity
221 // end up in the same table.
222 for (PI = FunTy->param_begin(), PE = FunTy->param_end(); PI != PE;
224 ParamTys[i] = VoidPtrTy;
227 return FunctionType::get(RetTy, ParamTys, IsVarArg);
228 case JumpTable::Simplified:
229 // Project all parameters types to one of 3 types: composite, integer, and
230 // function, matching the three subclasses of Type.
231 for (PI = FunTy->param_begin(), PE = FunTy->param_end(); PI != PE;
233 assert((isa<IntegerType>(*PI) || isa<FunctionType>(*PI) ||
234 isa<CompositeType>(*PI)) &&
235 "This type is not an Integer or a Composite or a Function");
236 if (isa<CompositeType>(*PI)) {
237 ParamTys[i] = VoidPtrTy;
238 } else if (isa<FunctionType>(*PI)) {
239 ParamTys[i] = VoidFnTy;
240 } else if (isa<IntegerType>(*PI)) {
241 ParamTys[i] = Int32Ty;
245 return FunctionType::get(RetTy, ParamTys, IsVarArg);
246 case JumpTable::Full:
247 // Don't transform this type at all.
254 bool JumpInstrTables::runOnModule(Module &M) {
255 JITI = &getAnalysis<JumpInstrTableInfo>();
257 // Get the set of jumptable-annotated functions that have their address taken.
258 DenseMap<Function *, Function *> Functions;
259 for (Function &F : M) {
260 if (F.hasFnAttribute(Attribute::JumpTable) && F.hasAddressTaken()) {
261 assert(F.hasUnnamedAddr() &&
262 "Attribute 'jumptable' requires 'unnamed_addr'");
263 Functions[&F] = nullptr;
267 // Create the jump-table functions.
268 for (auto &KV : Functions) {
269 Function *F = KV.first;
270 KV.second = insertEntry(M, F);
273 // GlobalAlias is a special case, because the target of an alias statement
274 // must be a defined function. So, instead of replacing a given function in
275 // the alias, we replace all uses of aliases that target jumptable functions.
276 // Note that there's no need to create these functions, since only aliases
277 // that target known jumptable functions are replaced, and there's no way to
278 // put the jumptable annotation on a global alias.
279 DenseMap<GlobalAlias *, Function *> Aliases;
280 for (GlobalAlias &GA : M.aliases()) {
281 Constant *Aliasee = GA.getAliasee();
282 if (Function *F = dyn_cast<Function>(Aliasee)) {
283 auto it = Functions.find(F);
284 if (it != Functions.end()) {
285 Aliases[&GA] = it->second;
290 // Replace each address taken function with its jump-instruction table entry.
291 for (auto &KV : Functions)
292 replaceValueWithFunction(KV.first, KV.second);
294 for (auto &KV : Aliases)
295 replaceValueWithFunction(KV.first, KV.second);
297 return !Functions.empty();