LLVM API Documentation

IntrinsicLowering.cpp

Go to the documentation of this file.
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 }