LLVM API Documentation
00001 //===-- AutoUpgrade.cpp - Implement auto-upgrade helper functions ---------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by Reid Spencer and is distributed under the 00006 // University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the auto-upgrade helper functions 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/Assembly/AutoUpgrade.h" 00015 #include "llvm/Constants.h" 00016 #include "llvm/DerivedTypes.h" 00017 #include "llvm/Function.h" 00018 #include "llvm/Module.h" 00019 #include "llvm/Instructions.h" 00020 #include "llvm/Intrinsics.h" 00021 #include "llvm/SymbolTable.h" 00022 #include <iostream> 00023 using namespace llvm; 00024 00025 static Function *getUpgradedUnaryFn(Function *F) { 00026 const std::string &Name = F->getName(); 00027 Module *M = F->getParent(); 00028 switch (F->getReturnType()->getTypeID()) { 00029 default: return 0; 00030 case Type::UByteTyID: 00031 case Type::SByteTyID: 00032 return M->getOrInsertFunction(Name+".i8", 00033 Type::UByteTy, Type::UByteTy, NULL); 00034 case Type::UShortTyID: 00035 case Type::ShortTyID: 00036 return M->getOrInsertFunction(Name+".i16", 00037 Type::UShortTy, Type::UShortTy, NULL); 00038 case Type::UIntTyID: 00039 case Type::IntTyID: 00040 return M->getOrInsertFunction(Name+".i32", 00041 Type::UIntTy, Type::UIntTy, NULL); 00042 case Type::ULongTyID: 00043 case Type::LongTyID: 00044 return M->getOrInsertFunction(Name+".i64", 00045 Type::ULongTy, Type::ULongTy, NULL); 00046 case Type::FloatTyID: 00047 return M->getOrInsertFunction(Name+".f32", 00048 Type::FloatTy, Type::FloatTy, NULL); 00049 case Type::DoubleTyID: 00050 return M->getOrInsertFunction(Name+".f64", 00051 Type::DoubleTy, Type::DoubleTy, NULL); 00052 } 00053 } 00054 00055 static Function *getUpgradedIntrinsic(Function *F) { 00056 // If there's no function, we can't get the argument type. 00057 if (!F) return 0; 00058 00059 // Get the Function's name. 00060 const std::string& Name = F->getName(); 00061 00062 // Quickly eliminate it, if it's not a candidate. 00063 if (Name.length() <= 8 || Name[0] != 'l' || Name[1] != 'l' || 00064 Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.') 00065 return 0; 00066 00067 Module *M = F->getParent(); 00068 switch (Name[5]) { 00069 default: break; 00070 case 'b': 00071 if (Name == "llvm.bswap") return getUpgradedUnaryFn(F); 00072 break; 00073 case 'c': 00074 if (Name == "llvm.ctpop" || Name == "llvm.ctlz" || Name == "llvm.cttz") 00075 return getUpgradedUnaryFn(F); 00076 break; 00077 case 'd': 00078 if (Name == "llvm.dbg.stoppoint") { 00079 PointerType *ESP = 00080 PointerType::get(StructType::get(std::vector<const Type*>())); 00081 if (F->getReturnType() != Type::VoidTy || 00082 F->getFunctionType()->getParamType(2) != ESP) { 00083 return M->getOrInsertFunction(Name, Type::VoidTy, 00084 Type::UIntTy, Type::UIntTy, ESP, NULL); 00085 } 00086 } else if (Name == "llvm.dbg.func.start") { 00087 PointerType *ESP = 00088 PointerType::get(StructType::get(std::vector<const Type*>())); 00089 if (F->getReturnType() != Type::VoidTy || 00090 F->getFunctionType()->getParamType(0) != ESP) { 00091 return M->getOrInsertFunction(Name, Type::VoidTy, ESP, NULL); 00092 } 00093 } else if (Name == "llvm.dbg.region.start") { 00094 PointerType *ESP = 00095 PointerType::get(StructType::get(std::vector<const Type*>())); 00096 if (F->getReturnType() != Type::VoidTy || 00097 F->getFunctionType()->getParamType(0) != ESP) { 00098 return M->getOrInsertFunction(Name, Type::VoidTy, ESP, NULL); 00099 } 00100 } else if (Name == "llvm.dbg.region.end") { 00101 PointerType *ESP = 00102 PointerType::get(StructType::get(std::vector<const Type*>())); 00103 if (F->getReturnType() != Type::VoidTy || 00104 F->getFunctionType()->getParamType(0) != ESP) { 00105 return M->getOrInsertFunction(Name, Type::VoidTy, ESP, NULL); 00106 } 00107 } else if (Name == "llvm.dbg.declare") { 00108 PointerType *ESP = 00109 PointerType::get(StructType::get(std::vector<const Type*>())); 00110 if (F->getReturnType() != Type::VoidTy || 00111 F->getFunctionType()->getParamType(0) != ESP || 00112 F->getFunctionType()->getParamType(1) != ESP) { 00113 return M->getOrInsertFunction(Name, Type::VoidTy, ESP, ESP, NULL); 00114 } 00115 } 00116 break; 00117 case 'i': 00118 if (Name == "llvm.isunordered" && F->arg_begin() != F->arg_end()) { 00119 if (F->arg_begin()->getType() == Type::FloatTy) 00120 return M->getOrInsertFunction(Name+".f32", F->getFunctionType()); 00121 if (F->arg_begin()->getType() == Type::DoubleTy) 00122 return M->getOrInsertFunction(Name+".f64", F->getFunctionType()); 00123 } 00124 break; 00125 case 'm': 00126 if (Name == "llvm.memcpy" || Name == "llvm.memset" || 00127 Name == "llvm.memmove") { 00128 if (F->getFunctionType()->getParamType(2) == Type::UIntTy || 00129 F->getFunctionType()->getParamType(2) == Type::IntTy) 00130 return M->getOrInsertFunction(Name+".i32", Type::VoidTy, 00131 PointerType::get(Type::SByteTy), 00132 F->getFunctionType()->getParamType(1), 00133 Type::UIntTy, Type::UIntTy, NULL); 00134 if (F->getFunctionType()->getParamType(2) == Type::ULongTy || 00135 F->getFunctionType()->getParamType(2) == Type::LongTy) 00136 return M->getOrInsertFunction(Name+".i64", Type::VoidTy, 00137 PointerType::get(Type::SByteTy), 00138 F->getFunctionType()->getParamType(1), 00139 Type::ULongTy, Type::UIntTy, NULL); 00140 } 00141 break; 00142 case 's': 00143 if (Name == "llvm.sqrt") 00144 return getUpgradedUnaryFn(F); 00145 break; 00146 } 00147 return 0; 00148 } 00149 00150 // Occasionally upgraded function call site arguments need to be permutated to 00151 // some new order. The result of getArgumentPermutation is an array of size 00152 // F->getFunctionType()getNumParams() indicating the new operand order. A value 00153 // of zero in the array indicates replacing with UndefValue for the arg type. 00154 // NULL is returned if there is no permutation. It's assumed that the function 00155 // name is in the form "llvm.?????" 00156 static unsigned *getArgumentPermutation(Function* Fn, Function* NewFn) { 00157 const std::string& Name = Fn->getName(); 00158 unsigned N = Fn->getFunctionType()->getNumParams(); 00159 unsigned M = NewFn->getFunctionType()->getNumParams(); 00160 00161 switch (Name[5]) { 00162 case 'd': 00163 if (Name == "llvm.dbg.stoppoint") { 00164 static unsigned Permutation[] = { 2, 3, 4 }; 00165 assert(M == (sizeof(Permutation) / sizeof(unsigned)) && 00166 "Permutation is wrong length"); 00167 if (N == 4) return Permutation; 00168 } else if (Name == "llvm.dbg.region.start") { 00169 static unsigned Permutation[] = { 0 }; 00170 assert(M == (sizeof(Permutation) / sizeof(unsigned)) && 00171 "Permutation is wrong length"); 00172 if (N == 0) return Permutation; 00173 } else if (Name == "llvm.dbg.region.end") { 00174 static unsigned Permutation[] = { 0 }; 00175 assert(M == (sizeof(Permutation) / sizeof(unsigned)) && 00176 "Permutation is wrong length"); 00177 if (N == 0) return Permutation; 00178 } else if (Name == "llvm.dbg.declare") { 00179 static unsigned Permutation[] = { 0, 0 }; 00180 assert(M == (sizeof(Permutation) / sizeof(unsigned)) && 00181 "Permutation is wrong length"); 00182 if (N == 0) return Permutation; 00183 } 00184 break; 00185 } 00186 return NULL; 00187 } 00188 00189 // UpgradeIntrinsicFunction - Convert overloaded intrinsic function names to 00190 // their non-overloaded variants by appending the appropriate suffix based on 00191 // the argument types. 00192 Function *llvm::UpgradeIntrinsicFunction(Function* F) { 00193 // See if its one of the name's we're interested in. 00194 if (Function *R = getUpgradedIntrinsic(F)) { 00195 if (R->getName() != F->getName()) 00196 std::cerr << "WARNING: change " << F->getName() << " to " 00197 << R->getName() << "\n"; 00198 return R; 00199 } 00200 return 0; 00201 } 00202 00203 // CastArg - Perform the appropriate cast of an upgraded argument. 00204 // 00205 static Value *CastArg(Value *Arg, const Type *Ty, Instruction *InsertBefore) { 00206 if (Constant *C = dyn_cast<Constant>(Arg)) { 00207 return ConstantExpr::getCast(C, Ty); 00208 } else { 00209 Value *Cast = new CastInst(Arg, Ty, "autoupgrade_cast", InsertBefore); 00210 return Cast; 00211 } 00212 } 00213 00214 // UpgradeIntrinsicCall - In the BC reader, change a call to an intrinsic to be 00215 // a call to an upgraded intrinsic. We may have to permute the order or promote 00216 // some arguments with a cast. 00217 void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { 00218 Function *F = CI->getCalledFunction(); 00219 00220 const FunctionType *NewFnTy = NewFn->getFunctionType(); 00221 std::vector<Value*> Oprnds; 00222 00223 unsigned *Permutation = getArgumentPermutation(F, NewFn); 00224 unsigned N = NewFnTy->getNumParams(); 00225 00226 if (Permutation) { 00227 for (unsigned i = 0; i != N; ++i) { 00228 unsigned p = Permutation[i]; 00229 00230 if (p) { 00231 Value *V = CI->getOperand(p); 00232 if (V->getType() != NewFnTy->getParamType(i)) 00233 V = CastArg(V, NewFnTy->getParamType(i), CI); 00234 Oprnds.push_back(V); 00235 } else 00236 Oprnds.push_back(UndefValue::get(NewFnTy->getParamType(i))); 00237 } 00238 } else if (N) { 00239 assert(N == (CI->getNumOperands() - 1) && 00240 "Upgraded function needs permutation"); 00241 for (unsigned i = 0; i != N; ++i) { 00242 Value *V = CI->getOperand(i + 1); 00243 if (V->getType() != NewFnTy->getParamType(i)) 00244 V = CastArg(V, NewFnTy->getParamType(i), CI); 00245 Oprnds.push_back(V); 00246 } 00247 } 00248 00249 bool NewIsVoid = NewFn->getReturnType() == Type::VoidTy; 00250 00251 CallInst *NewCI = new CallInst(NewFn, Oprnds, 00252 NewIsVoid ? "" : CI->getName(), 00253 CI); 00254 NewCI->setTailCall(CI->isTailCall()); 00255 NewCI->setCallingConv(CI->getCallingConv()); 00256 00257 if (!CI->use_empty()) { 00258 if (NewIsVoid) { 00259 CI->replaceAllUsesWith(UndefValue::get(CI->getType())); 00260 } else { 00261 Instruction *RetVal = NewCI; 00262 00263 if (F->getReturnType() != NewFn->getReturnType()) { 00264 RetVal = new CastInst(NewCI, F->getReturnType(), 00265 NewCI->getName(), CI); 00266 NewCI->moveBefore(RetVal); 00267 } 00268 00269 CI->replaceAllUsesWith(RetVal); 00270 } 00271 } 00272 CI->eraseFromParent(); 00273 } 00274 00275 bool llvm::UpgradeCallsToIntrinsic(Function* F) { 00276 if (Function* NewFn = UpgradeIntrinsicFunction(F)) { 00277 for (Value::use_iterator UI = F->use_begin(), UE = F->use_end(); 00278 UI != UE; ) { 00279 if (CallInst* CI = dyn_cast<CallInst>(*UI++)) 00280 UpgradeIntrinsicCall(CI, NewFn); 00281 } 00282 if (NewFn != F) 00283 F->eraseFromParent(); 00284 return true; 00285 } 00286 return false; 00287 }