LLVM API Documentation
00001 //===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the default intrinsic lowering implementation. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/CodeGen/IntrinsicLowering.h" 00015 #include "llvm/Constants.h" 00016 #include "llvm/DerivedTypes.h" 00017 #include "llvm/Module.h" 00018 #include "llvm/Instructions.h" 00019 #include "llvm/Type.h" 00020 #include <iostream> 00021 00022 using namespace llvm; 00023 00024 template <class ArgIt> 00025 static Function *EnsureFunctionExists(Module &M, const char *Name, 00026 ArgIt ArgBegin, ArgIt ArgEnd, 00027 const Type *RetTy) { 00028 if (Function *F = M.getNamedFunction(Name)) return F; 00029 // It doesn't already exist in the program, insert a new definition now. 00030 std::vector<const Type *> ParamTys; 00031 for (ArgIt I = ArgBegin; I != ArgEnd; ++I) 00032 ParamTys.push_back(I->getType()); 00033 return M.getOrInsertFunction(Name, FunctionType::get(RetTy, ParamTys, false)); 00034 } 00035 00036 /// ReplaceCallWith - This function is used when we want to lower an intrinsic 00037 /// call to a call of an external function. This handles hard cases such as 00038 /// when there was already a prototype for the external function, and if that 00039 /// prototype doesn't match the arguments we expect to pass in. 00040 template <class ArgIt> 00041 static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI, 00042 ArgIt ArgBegin, ArgIt ArgEnd, 00043 const Type *RetTy, Function *&FCache) { 00044 if (!FCache) { 00045 // If we haven't already looked up this function, check to see if the 00046 // program already contains a function with this name. 00047 Module *M = CI->getParent()->getParent()->getParent(); 00048 FCache = M->getNamedFunction(NewFn); 00049 if (!FCache) { 00050 // It doesn't already exist in the program, insert a new definition now. 00051 std::vector<const Type *> ParamTys; 00052 for (ArgIt I = ArgBegin; I != ArgEnd; ++I) 00053 ParamTys.push_back((*I)->getType()); 00054 FCache = M->getOrInsertFunction(NewFn, 00055 FunctionType::get(RetTy, ParamTys, false)); 00056 } 00057 } 00058 00059 const FunctionType *FT = FCache->getFunctionType(); 00060 std::vector<Value*> Operands; 00061 unsigned ArgNo = 0; 00062 for (ArgIt I = ArgBegin; I != ArgEnd && ArgNo != FT->getNumParams(); 00063 ++I, ++ArgNo) { 00064 Value *Arg = *I; 00065 if (Arg->getType() != FT->getParamType(ArgNo)) 00066 Arg = new CastInst(Arg, FT->getParamType(ArgNo), Arg->getName(), CI); 00067 Operands.push_back(Arg); 00068 } 00069 // Pass nulls into any additional arguments... 00070 for (; ArgNo != FT->getNumParams(); ++ArgNo) 00071 Operands.push_back(Constant::getNullValue(FT->getParamType(ArgNo))); 00072 00073 std::string Name = CI->getName(); CI->setName(""); 00074 if (FT->getReturnType() == Type::VoidTy) Name.clear(); 00075 CallInst *NewCI = new CallInst(FCache, Operands, Name, CI); 00076 if (!CI->use_empty()) { 00077 Value *V = NewCI; 00078 if (CI->getType() != NewCI->getType()) 00079 V = new CastInst(NewCI, CI->getType(), Name, CI); 00080 CI->replaceAllUsesWith(V); 00081 } 00082 return NewCI; 00083 } 00084 00085 void DefaultIntrinsicLowering::AddPrototypes(Module &M) { 00086 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 00087 if (I->isExternal() && !I->use_empty()) 00088 switch (I->getIntrinsicID()) { 00089 default: break; 00090 case Intrinsic::setjmp: 00091 EnsureFunctionExists(M, "setjmp", I->arg_begin(), I->arg_end(), 00092 Type::IntTy); 00093 break; 00094 case Intrinsic::longjmp: 00095 EnsureFunctionExists(M, "longjmp", I->arg_begin(), I->arg_end(), 00096 Type::VoidTy); 00097 break; 00098 case Intrinsic::siglongjmp: 00099 EnsureFunctionExists(M, "abort", I->arg_end(), I->arg_end(), 00100 Type::VoidTy); 00101 break; 00102 case Intrinsic::memcpy_i32: 00103 case Intrinsic::memcpy_i64: 00104 EnsureFunctionExists(M, "memcpy", I->arg_begin(), --I->arg_end(), 00105 I->arg_begin()->getType()); 00106 break; 00107 case Intrinsic::memmove_i32: 00108 case Intrinsic::memmove_i64: 00109 EnsureFunctionExists(M, "memmove", I->arg_begin(), --I->arg_end(), 00110 I->arg_begin()->getType()); 00111 break; 00112 case Intrinsic::memset_i32: 00113 case Intrinsic::memset_i64: 00114 M.getOrInsertFunction("memset", PointerType::get(Type::SByteTy), 00115 PointerType::get(Type::SByteTy), 00116 Type::IntTy, (--(--I->arg_end()))->getType(), 00117 (Type *)0); 00118 break; 00119 case Intrinsic::isunordered_f32: 00120 case Intrinsic::isunordered_f64: 00121 EnsureFunctionExists(M, "isunordered", I->arg_begin(), I->arg_end(), 00122 Type::BoolTy); 00123 break; 00124 case Intrinsic::sqrt_f32: 00125 case Intrinsic::sqrt_f64: 00126 if(I->arg_begin()->getType() == Type::FloatTy) 00127 EnsureFunctionExists(M, "sqrtf", I->arg_begin(), I->arg_end(), 00128 Type::FloatTy); 00129 else 00130 EnsureFunctionExists(M, "sqrt", I->arg_begin(), I->arg_end(), 00131 Type::DoubleTy); 00132 break; 00133 } 00134 } 00135 00136 /// LowerBSWAP - Emit the code to lower bswap of V before the specified 00137 /// instruction IP. 00138 static Value *LowerBSWAP(Value *V, Instruction *IP) { 00139 assert(V->getType()->isInteger() && "Can't bswap a non-integer type!"); 00140 00141 const Type *DestTy = V->getType(); 00142 00143 // Force to unsigned so that the shift rights are logical. 00144 if (DestTy->isSigned()) 00145 V = new CastInst(V, DestTy->getUnsignedVersion(), V->getName(), IP); 00146 00147 unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); 00148 00149 switch(BitSize) { 00150 default: assert(0 && "Unhandled type size of value to byteswap!"); 00151 case 16: { 00152 Value *Tmp1 = new ShiftInst(Instruction::Shl, V, 00153 ConstantInt::get(Type::UByteTy,8),"bswap.2",IP); 00154 Value *Tmp2 = new ShiftInst(Instruction::Shr, V, 00155 ConstantInt::get(Type::UByteTy,8),"bswap.1",IP); 00156 V = BinaryOperator::createOr(Tmp1, Tmp2, "bswap.i16", IP); 00157 break; 00158 } 00159 case 32: { 00160 Value *Tmp4 = new ShiftInst(Instruction::Shl, V, 00161 ConstantInt::get(Type::UByteTy,24),"bswap.4", IP); 00162 Value *Tmp3 = new ShiftInst(Instruction::Shl, V, 00163 ConstantInt::get(Type::UByteTy,8),"bswap.3",IP); 00164 Value *Tmp2 = new ShiftInst(Instruction::Shr, V, 00165 ConstantInt::get(Type::UByteTy,8),"bswap.2",IP); 00166 Value *Tmp1 = new ShiftInst(Instruction::Shr, V, 00167 ConstantInt::get(Type::UByteTy,24),"bswap.1", IP); 00168 Tmp3 = BinaryOperator::createAnd(Tmp3, 00169 ConstantUInt::get(Type::UIntTy, 0xFF0000), 00170 "bswap.and3", IP); 00171 Tmp2 = BinaryOperator::createAnd(Tmp2, 00172 ConstantUInt::get(Type::UIntTy, 0xFF00), 00173 "bswap.and2", IP); 00174 Tmp4 = BinaryOperator::createOr(Tmp4, Tmp3, "bswap.or1", IP); 00175 Tmp2 = BinaryOperator::createOr(Tmp2, Tmp1, "bswap.or2", IP); 00176 V = BinaryOperator::createOr(Tmp4, Tmp3, "bswap.i32", IP); 00177 break; 00178 } 00179 case 64: { 00180 Value *Tmp8 = new ShiftInst(Instruction::Shl, V, 00181 ConstantInt::get(Type::UByteTy,56),"bswap.8", IP); 00182 Value *Tmp7 = new ShiftInst(Instruction::Shl, V, 00183 ConstantInt::get(Type::UByteTy,40),"bswap.7", IP); 00184 Value *Tmp6 = new ShiftInst(Instruction::Shl, V, 00185 ConstantInt::get(Type::UByteTy,24),"bswap.6", IP); 00186 Value *Tmp5 = new ShiftInst(Instruction::Shl, V, 00187 ConstantInt::get(Type::UByteTy,8),"bswap.5",IP); 00188 Value *Tmp4 = new ShiftInst(Instruction::Shr, V, 00189 ConstantInt::get(Type::UByteTy,8),"bswap.4",IP); 00190 Value *Tmp3 = new ShiftInst(Instruction::Shr, V, 00191 ConstantInt::get(Type::UByteTy,24),"bswap.3", IP); 00192 Value *Tmp2 = new ShiftInst(Instruction::Shr, V, 00193 ConstantInt::get(Type::UByteTy,40),"bswap.2", IP); 00194 Value *Tmp1 = new ShiftInst(Instruction::Shr, V, 00195 ConstantInt::get(Type::UByteTy,56),"bswap.1", IP); 00196 Tmp7 = BinaryOperator::createAnd(Tmp7, 00197 ConstantUInt::get(Type::ULongTy, 0xFF000000000000ULL), 00198 "bswap.and7", IP); 00199 Tmp6 = BinaryOperator::createAnd(Tmp6, 00200 ConstantUInt::get(Type::ULongTy, 0xFF0000000000ULL), 00201 "bswap.and6", IP); 00202 Tmp5 = BinaryOperator::createAnd(Tmp5, 00203 ConstantUInt::get(Type::ULongTy, 0xFF00000000ULL), 00204 "bswap.and5", IP); 00205 Tmp4 = BinaryOperator::createAnd(Tmp4, 00206 ConstantUInt::get(Type::ULongTy, 0xFF000000ULL), 00207 "bswap.and4", IP); 00208 Tmp3 = BinaryOperator::createAnd(Tmp3, 00209 ConstantUInt::get(Type::ULongTy, 0xFF0000ULL), 00210 "bswap.and3", IP); 00211 Tmp2 = BinaryOperator::createAnd(Tmp2, 00212 ConstantUInt::get(Type::ULongTy, 0xFF00ULL), 00213 "bswap.and2", IP); 00214 Tmp8 = BinaryOperator::createOr(Tmp8, Tmp7, "bswap.or1", IP); 00215 Tmp6 = BinaryOperator::createOr(Tmp6, Tmp5, "bswap.or2", IP); 00216 Tmp4 = BinaryOperator::createOr(Tmp4, Tmp3, "bswap.or3", IP); 00217 Tmp2 = BinaryOperator::createOr(Tmp2, Tmp1, "bswap.or4", IP); 00218 Tmp8 = BinaryOperator::createOr(Tmp8, Tmp6, "bswap.or5", IP); 00219 Tmp4 = BinaryOperator::createOr(Tmp4, Tmp2, "bswap.or6", IP); 00220 V = BinaryOperator::createOr(Tmp8, Tmp4, "bswap.i64", IP); 00221 break; 00222 } 00223 } 00224 00225 if (V->getType() != DestTy) 00226 V = new CastInst(V, DestTy, V->getName(), IP); 00227 return V; 00228 } 00229 00230 /// LowerCTPOP - Emit the code to lower ctpop of V before the specified 00231 /// instruction IP. 00232 static Value *LowerCTPOP(Value *V, Instruction *IP) { 00233 assert(V->getType()->isInteger() && "Can't ctpop a non-integer type!"); 00234 00235 static const uint64_t MaskValues[6] = { 00236 0x5555555555555555ULL, 0x3333333333333333ULL, 00237 0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL, 00238 0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL 00239 }; 00240 00241 const Type *DestTy = V->getType(); 00242 00243 // Force to unsigned so that the shift rights are logical. 00244 if (DestTy->isSigned()) 00245 V = new CastInst(V, DestTy->getUnsignedVersion(), V->getName(), IP); 00246 00247 unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); 00248 for (unsigned i = 1, ct = 0; i != BitSize; i <<= 1, ++ct) { 00249 Value *MaskCst = 00250 ConstantExpr::getCast(ConstantUInt::get(Type::ULongTy, 00251 MaskValues[ct]), V->getType()); 00252 Value *LHS = BinaryOperator::createAnd(V, MaskCst, "cppop.and1", IP); 00253 Value *VShift = new ShiftInst(Instruction::Shr, V, 00254 ConstantInt::get(Type::UByteTy, i), "ctpop.sh", IP); 00255 Value *RHS = BinaryOperator::createAnd(VShift, MaskCst, "cppop.and2", IP); 00256 V = BinaryOperator::createAdd(LHS, RHS, "ctpop.step", IP); 00257 } 00258 00259 if (V->getType() != DestTy) 00260 V = new CastInst(V, DestTy, V->getName(), IP); 00261 return V; 00262 } 00263 00264 /// LowerCTLZ - Emit the code to lower ctlz of V before the specified 00265 /// instruction IP. 00266 static Value *LowerCTLZ(Value *V, Instruction *IP) { 00267 const Type *DestTy = V->getType(); 00268 00269 // Force to unsigned so that the shift rights are logical. 00270 if (DestTy->isSigned()) 00271 V = new CastInst(V, DestTy->getUnsignedVersion(), V->getName(), IP); 00272 00273 unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); 00274 for (unsigned i = 1; i != BitSize; i <<= 1) { 00275 Value *ShVal = ConstantInt::get(Type::UByteTy, i); 00276 ShVal = new ShiftInst(Instruction::Shr, V, ShVal, "ctlz.sh", IP); 00277 V = BinaryOperator::createOr(V, ShVal, "ctlz.step", IP); 00278 } 00279 00280 if (V->getType() != DestTy) 00281 V = new CastInst(V, DestTy, V->getName(), IP); 00282 00283 V = BinaryOperator::createNot(V, "", IP); 00284 return LowerCTPOP(V, IP); 00285 } 00286 00287 00288 00289 void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { 00290 Function *Callee = CI->getCalledFunction(); 00291 assert(Callee && "Cannot lower an indirect call!"); 00292 00293 switch (Callee->getIntrinsicID()) { 00294 case Intrinsic::not_intrinsic: 00295 std::cerr << "Cannot lower a call to a non-intrinsic function '" 00296 << Callee->getName() << "'!\n"; 00297 abort(); 00298 default: 00299 std::cerr << "Error: Code generator does not support intrinsic function '" 00300 << Callee->getName() << "'!\n"; 00301 abort(); 00302 00303 // The setjmp/longjmp intrinsics should only exist in the code if it was 00304 // never optimized (ie, right out of the CFE), or if it has been hacked on 00305 // by the lowerinvoke pass. In both cases, the right thing to do is to 00306 // convert the call to an explicit setjmp or longjmp call. 00307 case Intrinsic::setjmp: { 00308 static Function *SetjmpFCache = 0; 00309 Value *V = ReplaceCallWith("setjmp", CI, CI->op_begin()+1, CI->op_end(), 00310 Type::IntTy, SetjmpFCache); 00311 if (CI->getType() != Type::VoidTy) 00312 CI->replaceAllUsesWith(V); 00313 break; 00314 } 00315 case Intrinsic::sigsetjmp: 00316 if (CI->getType() != Type::VoidTy) 00317 CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 00318 break; 00319 00320 case Intrinsic::longjmp: { 00321 static Function *LongjmpFCache = 0; 00322 ReplaceCallWith("longjmp", CI, CI->op_begin()+1, CI->op_end(), 00323 Type::VoidTy, LongjmpFCache); 00324 break; 00325 } 00326 00327 case Intrinsic::siglongjmp: { 00328 // Insert the call to abort 00329 static Function *AbortFCache = 0; 00330 ReplaceCallWith("abort", CI, CI->op_end(), CI->op_end(), Type::VoidTy, 00331 AbortFCache); 00332 break; 00333 } 00334 case Intrinsic::ctpop_i8: 00335 case Intrinsic::ctpop_i16: 00336 case Intrinsic::ctpop_i32: 00337 case Intrinsic::ctpop_i64: 00338 CI->replaceAllUsesWith(LowerCTPOP(CI->getOperand(1), CI)); 00339 break; 00340 00341 case Intrinsic::bswap_i16: 00342 case Intrinsic::bswap_i32: 00343 case Intrinsic::bswap_i64: 00344 CI->replaceAllUsesWith(LowerBSWAP(CI->getOperand(1), CI)); 00345 break; 00346 00347 case Intrinsic::ctlz_i8: 00348 case Intrinsic::ctlz_i16: 00349 case Intrinsic::ctlz_i32: 00350 case Intrinsic::ctlz_i64: 00351 CI->replaceAllUsesWith(LowerCTLZ(CI->getOperand(1), CI)); 00352 break; 00353 00354 case Intrinsic::cttz_i8: 00355 case Intrinsic::cttz_i16: 00356 case Intrinsic::cttz_i32: 00357 case Intrinsic::cttz_i64: { 00358 // cttz(x) -> ctpop(~X & (X-1)) 00359 Value *Src = CI->getOperand(1); 00360 Value *NotSrc = BinaryOperator::createNot(Src, Src->getName()+".not", CI); 00361 Value *SrcM1 = ConstantInt::get(Src->getType(), 1); 00362 SrcM1 = BinaryOperator::createSub(Src, SrcM1, "", CI); 00363 Src = LowerCTPOP(BinaryOperator::createAnd(NotSrc, SrcM1, "", CI), CI); 00364 CI->replaceAllUsesWith(Src); 00365 break; 00366 } 00367 00368 case Intrinsic::stacksave: 00369 case Intrinsic::stackrestore: { 00370 static bool Warned = false; 00371 if (!Warned) 00372 std::cerr << "WARNING: this target does not support the llvm.stack" 00373 << (Callee->getIntrinsicID() == Intrinsic::stacksave ? 00374 "save" : "restore") << " intrinsic.\n"; 00375 Warned = true; 00376 if (Callee->getIntrinsicID() == Intrinsic::stacksave) 00377 CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 00378 break; 00379 } 00380 00381 case Intrinsic::returnaddress: 00382 case Intrinsic::frameaddress: 00383 std::cerr << "WARNING: this target does not support the llvm." 00384 << (Callee->getIntrinsicID() == Intrinsic::returnaddress ? 00385 "return" : "frame") << "address intrinsic.\n"; 00386 CI->replaceAllUsesWith(ConstantPointerNull::get( 00387 cast<PointerType>(CI->getType()))); 00388 break; 00389 00390 case Intrinsic::prefetch: 00391 break; // Simply strip out prefetches on unsupported architectures 00392 00393 case Intrinsic::pcmarker: 00394 break; // Simply strip out pcmarker on unsupported architectures 00395 case Intrinsic::readcyclecounter: { 00396 std::cerr << "WARNING: this target does not support the llvm.readcyclecoun" 00397 << "ter intrinsic. It is being lowered to a constant 0\n"; 00398 CI->replaceAllUsesWith(ConstantUInt::get(Type::ULongTy, 0)); 00399 break; 00400 } 00401 00402 case Intrinsic::dbg_stoppoint: 00403 case Intrinsic::dbg_region_start: 00404 case Intrinsic::dbg_region_end: 00405 case Intrinsic::dbg_func_start: 00406 case Intrinsic::dbg_declare: 00407 break; // Simply strip out debugging intrinsics 00408 00409 case Intrinsic::memcpy_i32: 00410 case Intrinsic::memcpy_i64: { 00411 // The memcpy intrinsic take an extra alignment argument that the memcpy 00412 // libc function does not. 00413 static Function *MemcpyFCache = 0; 00414 ReplaceCallWith("memcpy", CI, CI->op_begin()+1, CI->op_end()-1, 00415 (*(CI->op_begin()+1))->getType(), MemcpyFCache); 00416 break; 00417 } 00418 case Intrinsic::memmove_i32: 00419 case Intrinsic::memmove_i64: { 00420 // The memmove intrinsic take an extra alignment argument that the memmove 00421 // libc function does not. 00422 static Function *MemmoveFCache = 0; 00423 ReplaceCallWith("memmove", CI, CI->op_begin()+1, CI->op_end()-1, 00424 (*(CI->op_begin()+1))->getType(), MemmoveFCache); 00425 break; 00426 } 00427 case Intrinsic::memset_i32: 00428 case Intrinsic::memset_i64: { 00429 // The memset intrinsic take an extra alignment argument that the memset 00430 // libc function does not. 00431 static Function *MemsetFCache = 0; 00432 ReplaceCallWith("memset", CI, CI->op_begin()+1, CI->op_end()-1, 00433 (*(CI->op_begin()+1))->getType(), MemsetFCache); 00434 break; 00435 } 00436 case Intrinsic::isunordered_f32: 00437 case Intrinsic::isunordered_f64: { 00438 Value *L = CI->getOperand(1); 00439 Value *R = CI->getOperand(2); 00440 00441 Value *LIsNan = new SetCondInst(Instruction::SetNE, L, L, "LIsNan", CI); 00442 Value *RIsNan = new SetCondInst(Instruction::SetNE, R, R, "RIsNan", CI); 00443 CI->replaceAllUsesWith( 00444 BinaryOperator::create(Instruction::Or, LIsNan, RIsNan, 00445 "isunordered", CI)); 00446 break; 00447 } 00448 case Intrinsic::sqrt_f32: 00449 case Intrinsic::sqrt_f64: { 00450 static Function *sqrtFCache = 0; 00451 static Function *sqrtfFCache = 0; 00452 if(CI->getType() == Type::FloatTy) 00453 ReplaceCallWith("sqrtf", CI, CI->op_begin()+1, CI->op_end(), 00454 Type::FloatTy, sqrtfFCache); 00455 else 00456 ReplaceCallWith("sqrt", CI, CI->op_begin()+1, CI->op_end(), 00457 Type::DoubleTy, sqrtFCache); 00458 break; 00459 } 00460 } 00461 00462 assert(CI->use_empty() && 00463 "Lowering should have eliminated any uses of the intrinsic call!"); 00464 CI->eraseFromParent(); 00465 }