IntrinsicLowering.cpp revision f9b1cbc80d89b9a03d73b8b3c1703b344e1d9b70
1//===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the IntrinsicLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Constants.h"
15#include "llvm/DerivedTypes.h"
16#include "llvm/Module.h"
17#include "llvm/Instructions.h"
18#include "llvm/Type.h"
19#include "llvm/CodeGen/IntrinsicLowering.h"
20#include "llvm/Support/Streams.h"
21#include "llvm/Target/TargetData.h"
22#include "llvm/ADT/SmallVector.h"
23using namespace llvm;
24
25template <class ArgIt>
26static void EnsureFunctionExists(Module &M, const char *Name,
27                                 ArgIt ArgBegin, ArgIt ArgEnd,
28                                 const Type *RetTy) {
29  // Insert a correctly-typed definition now.
30  std::vector<const Type *> ParamTys;
31  for (ArgIt I = ArgBegin; I != ArgEnd; ++I)
32    ParamTys.push_back(I->getType());
33  M.getOrInsertFunction(Name, FunctionType::get(RetTy, ParamTys, false));
34}
35
36/// ReplaceCallWith - This function is used when we want to lower an intrinsic
37/// call to a call of an external function.  This handles hard cases such as
38/// when there was already a prototype for the external function, and if that
39/// prototype doesn't match the arguments we expect to pass in.
40template <class ArgIt>
41static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI,
42                                 ArgIt ArgBegin, ArgIt ArgEnd,
43                                 const Type *RetTy, Constant *&FCache) {
44  if (!FCache) {
45    // If we haven't already looked up this function, check to see if the
46    // program already contains a function with this name.
47    Module *M = CI->getParent()->getParent()->getParent();
48    // Get or insert the definition now.
49    std::vector<const Type *> ParamTys;
50    for (ArgIt I = ArgBegin; I != ArgEnd; ++I)
51      ParamTys.push_back((*I)->getType());
52    FCache = M->getOrInsertFunction(NewFn,
53                                    FunctionType::get(RetTy, ParamTys, false));
54  }
55
56  SmallVector<Value*, 8> Operands(ArgBegin, ArgEnd);
57  CallInst *NewCI = new CallInst(FCache, &Operands[0], Operands.size(),
58                                 CI->getName(), CI);
59  if (!CI->use_empty())
60    CI->replaceAllUsesWith(NewCI);
61  return NewCI;
62}
63
64void IntrinsicLowering::AddPrototypes(Module &M) {
65  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
66    if (I->isDeclaration() && !I->use_empty())
67      switch (I->getIntrinsicID()) {
68      default: break;
69      case Intrinsic::setjmp:
70        EnsureFunctionExists(M, "setjmp", I->arg_begin(), I->arg_end(),
71                             Type::Int32Ty);
72        break;
73      case Intrinsic::longjmp:
74        EnsureFunctionExists(M, "longjmp", I->arg_begin(), I->arg_end(),
75                             Type::VoidTy);
76        break;
77      case Intrinsic::siglongjmp:
78        EnsureFunctionExists(M, "abort", I->arg_end(), I->arg_end(),
79                             Type::VoidTy);
80        break;
81      case Intrinsic::memcpy_i32:
82      case Intrinsic::memcpy_i64:
83        M.getOrInsertFunction("memcpy", PointerType::get(Type::Int8Ty),
84                              PointerType::get(Type::Int8Ty),
85                              PointerType::get(Type::Int8Ty),
86                              TD.getIntPtrType(), (Type *)0);
87        break;
88      case Intrinsic::memmove_i32:
89      case Intrinsic::memmove_i64:
90        M.getOrInsertFunction("memmove", PointerType::get(Type::Int8Ty),
91                              PointerType::get(Type::Int8Ty),
92                              PointerType::get(Type::Int8Ty),
93                              TD.getIntPtrType(), (Type *)0);
94        break;
95      case Intrinsic::memset_i32:
96      case Intrinsic::memset_i64:
97        M.getOrInsertFunction("memset", PointerType::get(Type::Int8Ty),
98                              PointerType::get(Type::Int8Ty), Type::Int32Ty,
99                              TD.getIntPtrType(), (Type *)0);
100        break;
101      case Intrinsic::sqrt_f32:
102      case Intrinsic::sqrt_f64:
103        if(I->arg_begin()->getType() == Type::FloatTy)
104          EnsureFunctionExists(M, "sqrtf", I->arg_begin(), I->arg_end(),
105                               Type::FloatTy);
106        else
107          EnsureFunctionExists(M, "sqrt", I->arg_begin(), I->arg_end(),
108                               Type::DoubleTy);
109        break;
110      }
111}
112
113/// LowerBSWAP - Emit the code to lower bswap of V before the specified
114/// instruction IP.
115static Value *LowerBSWAP(Value *V, Instruction *IP) {
116  assert(V->getType()->isInteger() && "Can't bswap a non-integer type!");
117
118  unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
119
120  switch(BitSize) {
121  default: assert(0 && "Unhandled type size of value to byteswap!");
122  case 16: {
123    Value *Tmp1 = BinaryOperator::createShl(V,
124                                ConstantInt::get(V->getType(),8),"bswap.2",IP);
125    Value *Tmp2 = BinaryOperator::createLShr(V,
126                                ConstantInt::get(V->getType(),8),"bswap.1",IP);
127    V = BinaryOperator::createOr(Tmp1, Tmp2, "bswap.i16", IP);
128    break;
129  }
130  case 32: {
131    Value *Tmp4 = BinaryOperator::createShl(V,
132                              ConstantInt::get(V->getType(),24),"bswap.4", IP);
133    Value *Tmp3 = BinaryOperator::createShl(V,
134                              ConstantInt::get(V->getType(),8),"bswap.3",IP);
135    Value *Tmp2 = BinaryOperator::createLShr(V,
136                              ConstantInt::get(V->getType(),8),"bswap.2",IP);
137    Value *Tmp1 = BinaryOperator::createLShr(V,
138                              ConstantInt::get(V->getType(),24),"bswap.1", IP);
139    Tmp3 = BinaryOperator::createAnd(Tmp3,
140                                     ConstantInt::get(Type::Int32Ty, 0xFF0000),
141                                     "bswap.and3", IP);
142    Tmp2 = BinaryOperator::createAnd(Tmp2,
143                                     ConstantInt::get(Type::Int32Ty, 0xFF00),
144                                     "bswap.and2", IP);
145    Tmp4 = BinaryOperator::createOr(Tmp4, Tmp3, "bswap.or1", IP);
146    Tmp2 = BinaryOperator::createOr(Tmp2, Tmp1, "bswap.or2", IP);
147    V = BinaryOperator::createOr(Tmp4, Tmp3, "bswap.i32", IP);
148    break;
149  }
150  case 64: {
151    Value *Tmp8 = BinaryOperator::createShl(V,
152                              ConstantInt::get(V->getType(),56),"bswap.8", IP);
153    Value *Tmp7 = BinaryOperator::createShl(V,
154                              ConstantInt::get(V->getType(),40),"bswap.7", IP);
155    Value *Tmp6 = BinaryOperator::createShl(V,
156                              ConstantInt::get(V->getType(),24),"bswap.6", IP);
157    Value *Tmp5 = BinaryOperator::createShl(V,
158                              ConstantInt::get(V->getType(),8),"bswap.5", IP);
159    Value* Tmp4 = BinaryOperator::createLShr(V,
160                              ConstantInt::get(V->getType(),8),"bswap.4", IP);
161    Value* Tmp3 = BinaryOperator::createLShr(V,
162                              ConstantInt::get(V->getType(),24),"bswap.3", IP);
163    Value* Tmp2 = BinaryOperator::createLShr(V,
164                              ConstantInt::get(V->getType(),40),"bswap.2", IP);
165    Value* Tmp1 = BinaryOperator::createLShr(V,
166                              ConstantInt::get(V->getType(),56),"bswap.1", IP);
167    Tmp7 = BinaryOperator::createAnd(Tmp7,
168                             ConstantInt::get(Type::Int64Ty,
169                               0xFF000000000000ULL),
170                             "bswap.and7", IP);
171    Tmp6 = BinaryOperator::createAnd(Tmp6,
172                             ConstantInt::get(Type::Int64Ty, 0xFF0000000000ULL),
173                             "bswap.and6", IP);
174    Tmp5 = BinaryOperator::createAnd(Tmp5,
175                             ConstantInt::get(Type::Int64Ty, 0xFF00000000ULL),
176                             "bswap.and5", IP);
177    Tmp4 = BinaryOperator::createAnd(Tmp4,
178                             ConstantInt::get(Type::Int64Ty, 0xFF000000ULL),
179                             "bswap.and4", IP);
180    Tmp3 = BinaryOperator::createAnd(Tmp3,
181                             ConstantInt::get(Type::Int64Ty, 0xFF0000ULL),
182                             "bswap.and3", IP);
183    Tmp2 = BinaryOperator::createAnd(Tmp2,
184                             ConstantInt::get(Type::Int64Ty, 0xFF00ULL),
185                             "bswap.and2", IP);
186    Tmp8 = BinaryOperator::createOr(Tmp8, Tmp7, "bswap.or1", IP);
187    Tmp6 = BinaryOperator::createOr(Tmp6, Tmp5, "bswap.or2", IP);
188    Tmp4 = BinaryOperator::createOr(Tmp4, Tmp3, "bswap.or3", IP);
189    Tmp2 = BinaryOperator::createOr(Tmp2, Tmp1, "bswap.or4", IP);
190    Tmp8 = BinaryOperator::createOr(Tmp8, Tmp6, "bswap.or5", IP);
191    Tmp4 = BinaryOperator::createOr(Tmp4, Tmp2, "bswap.or6", IP);
192    V = BinaryOperator::createOr(Tmp8, Tmp4, "bswap.i64", IP);
193    break;
194  }
195  }
196  return V;
197}
198
199/// LowerCTPOP - Emit the code to lower ctpop of V before the specified
200/// instruction IP.
201static Value *LowerCTPOP(Value *V, Instruction *IP) {
202  assert(V->getType()->isInteger() && "Can't ctpop a non-integer type!");
203
204  static const uint64_t MaskValues[6] = {
205    0x5555555555555555ULL, 0x3333333333333333ULL,
206    0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL,
207    0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL
208  };
209
210  unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
211
212  for (unsigned i = 1, ct = 0; i != BitSize; i <<= 1, ++ct) {
213    Value *MaskCst = ConstantInt::get(V->getType(), MaskValues[ct]);
214    Value *LHS = BinaryOperator::createAnd(V, MaskCst, "cppop.and1", IP);
215    Value *VShift = BinaryOperator::createLShr(V,
216                      ConstantInt::get(V->getType(), i), "ctpop.sh", IP);
217    Value *RHS = BinaryOperator::createAnd(VShift, MaskCst, "cppop.and2", IP);
218    V = BinaryOperator::createAdd(LHS, RHS, "ctpop.step", IP);
219  }
220
221  return V;
222}
223
224/// LowerCTLZ - Emit the code to lower ctlz of V before the specified
225/// instruction IP.
226static Value *LowerCTLZ(Value *V, Instruction *IP) {
227
228  unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
229  for (unsigned i = 1; i != BitSize; i <<= 1) {
230    Value *ShVal = ConstantInt::get(V->getType(), i);
231    ShVal = BinaryOperator::createLShr(V, ShVal, "ctlz.sh", IP);
232    V = BinaryOperator::createOr(V, ShVal, "ctlz.step", IP);
233  }
234
235  V = BinaryOperator::createNot(V, "", IP);
236  return LowerCTPOP(V, IP);
237}
238
239
240
241void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
242  Function *Callee = CI->getCalledFunction();
243  assert(Callee && "Cannot lower an indirect call!");
244
245  switch (Callee->getIntrinsicID()) {
246  case Intrinsic::not_intrinsic:
247    cerr << "Cannot lower a call to a non-intrinsic function '"
248         << Callee->getName() << "'!\n";
249    abort();
250  default:
251    cerr << "Error: Code generator does not support intrinsic function '"
252         << Callee->getName() << "'!\n";
253    abort();
254
255    // The setjmp/longjmp intrinsics should only exist in the code if it was
256    // never optimized (ie, right out of the CFE), or if it has been hacked on
257    // by the lowerinvoke pass.  In both cases, the right thing to do is to
258    // convert the call to an explicit setjmp or longjmp call.
259  case Intrinsic::setjmp: {
260    static Constant *SetjmpFCache = 0;
261    Value *V = ReplaceCallWith("setjmp", CI, CI->op_begin()+1, CI->op_end(),
262                               Type::Int32Ty, SetjmpFCache);
263    if (CI->getType() != Type::VoidTy)
264      CI->replaceAllUsesWith(V);
265    break;
266  }
267  case Intrinsic::sigsetjmp:
268     if (CI->getType() != Type::VoidTy)
269       CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
270     break;
271
272  case Intrinsic::longjmp: {
273    static Constant *LongjmpFCache = 0;
274    ReplaceCallWith("longjmp", CI, CI->op_begin()+1, CI->op_end(),
275                    Type::VoidTy, LongjmpFCache);
276    break;
277  }
278
279  case Intrinsic::siglongjmp: {
280    // Insert the call to abort
281    static Constant *AbortFCache = 0;
282    ReplaceCallWith("abort", CI, CI->op_end(), CI->op_end(),
283                    Type::VoidTy, AbortFCache);
284    break;
285  }
286  case Intrinsic::ctpop_i8:
287  case Intrinsic::ctpop_i16:
288  case Intrinsic::ctpop_i32:
289  case Intrinsic::ctpop_i64:
290    CI->replaceAllUsesWith(LowerCTPOP(CI->getOperand(1), CI));
291    break;
292
293  case Intrinsic::bswap_i16:
294  case Intrinsic::bswap_i32:
295  case Intrinsic::bswap_i64:
296    CI->replaceAllUsesWith(LowerBSWAP(CI->getOperand(1), CI));
297    break;
298
299  case Intrinsic::ctlz_i8:
300  case Intrinsic::ctlz_i16:
301  case Intrinsic::ctlz_i32:
302  case Intrinsic::ctlz_i64:
303    CI->replaceAllUsesWith(LowerCTLZ(CI->getOperand(1), CI));
304    break;
305
306  case Intrinsic::cttz_i8:
307  case Intrinsic::cttz_i16:
308  case Intrinsic::cttz_i32:
309  case Intrinsic::cttz_i64: {
310    // cttz(x) -> ctpop(~X & (X-1))
311    Value *Src = CI->getOperand(1);
312    Value *NotSrc = BinaryOperator::createNot(Src, Src->getName()+".not", CI);
313    Value *SrcM1  = ConstantInt::get(Src->getType(), 1);
314    SrcM1 = BinaryOperator::createSub(Src, SrcM1, "", CI);
315    Src = LowerCTPOP(BinaryOperator::createAnd(NotSrc, SrcM1, "", CI), CI);
316    CI->replaceAllUsesWith(Src);
317    break;
318  }
319
320  case Intrinsic::stacksave:
321  case Intrinsic::stackrestore: {
322    static bool Warned = false;
323    if (!Warned)
324      cerr << "WARNING: this target does not support the llvm.stack"
325           << (Callee->getIntrinsicID() == Intrinsic::stacksave ?
326               "save" : "restore") << " intrinsic.\n";
327    Warned = true;
328    if (Callee->getIntrinsicID() == Intrinsic::stacksave)
329      CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
330    break;
331  }
332
333  case Intrinsic::returnaddress:
334  case Intrinsic::frameaddress:
335    cerr << "WARNING: this target does not support the llvm."
336         << (Callee->getIntrinsicID() == Intrinsic::returnaddress ?
337             "return" : "frame") << "address intrinsic.\n";
338    CI->replaceAllUsesWith(ConstantPointerNull::get(
339                                            cast<PointerType>(CI->getType())));
340    break;
341
342  case Intrinsic::prefetch:
343    break;    // Simply strip out prefetches on unsupported architectures
344
345  case Intrinsic::pcmarker:
346    break;    // Simply strip out pcmarker on unsupported architectures
347  case Intrinsic::readcyclecounter: {
348    cerr << "WARNING: this target does not support the llvm.readcyclecoun"
349         << "ter intrinsic.  It is being lowered to a constant 0\n";
350    CI->replaceAllUsesWith(ConstantInt::get(Type::Int64Ty, 0));
351    break;
352  }
353
354  case Intrinsic::dbg_stoppoint:
355  case Intrinsic::dbg_region_start:
356  case Intrinsic::dbg_region_end:
357  case Intrinsic::dbg_func_start:
358  case Intrinsic::dbg_declare:
359  case Intrinsic::eh_exception:
360  case Intrinsic::eh_handlers:
361    break;    // Simply strip out debugging intrinsics
362
363  case Intrinsic::memcpy_i32:
364  case Intrinsic::memcpy_i64: {
365    static Constant *MemcpyFCache = 0;
366    Value *Size = CI->getOperand(3);
367    const Type *IntPtr = TD.getIntPtrType();
368    if (Size->getType()->getPrimitiveSizeInBits() <
369        IntPtr->getPrimitiveSizeInBits())
370      Size = new ZExtInst(Size, IntPtr, "", CI);
371    else if (Size->getType()->getPrimitiveSizeInBits() >
372             IntPtr->getPrimitiveSizeInBits())
373      Size = new TruncInst(Size, IntPtr, "", CI);
374    Value *Ops[3];
375    Ops[0] = CI->getOperand(1);
376    Ops[1] = CI->getOperand(2);
377    Ops[2] = Size;
378    ReplaceCallWith("memcpy", CI, Ops, Ops+3, CI->getOperand(1)->getType(),
379                    MemcpyFCache);
380    break;
381  }
382  case Intrinsic::memmove_i32:
383  case Intrinsic::memmove_i64: {
384    static Constant *MemmoveFCache = 0;
385    Value *Size = CI->getOperand(3);
386    const Type *IntPtr = TD.getIntPtrType();
387    if (Size->getType()->getPrimitiveSizeInBits() <
388        IntPtr->getPrimitiveSizeInBits())
389      Size = new ZExtInst(Size, IntPtr, "", CI);
390    else if (Size->getType()->getPrimitiveSizeInBits() >
391             IntPtr->getPrimitiveSizeInBits())
392      Size = new TruncInst(Size, IntPtr, "", CI);
393    Value *Ops[3];
394    Ops[0] = CI->getOperand(1);
395    Ops[1] = CI->getOperand(2);
396    Ops[2] = Size;
397    ReplaceCallWith("memmove", CI, Ops, Ops+3, CI->getOperand(1)->getType(),
398                    MemmoveFCache);
399    break;
400  }
401  case Intrinsic::memset_i32:
402  case Intrinsic::memset_i64: {
403    static Constant *MemsetFCache = 0;
404    Value *Size = CI->getOperand(3);
405    const Type *IntPtr = TD.getIntPtrType();
406    if (Size->getType()->getPrimitiveSizeInBits() <
407        IntPtr->getPrimitiveSizeInBits())
408      Size = new ZExtInst(Size, IntPtr, "", CI);
409    else if (Size->getType()->getPrimitiveSizeInBits() >
410             IntPtr->getPrimitiveSizeInBits())
411      Size = new TruncInst(Size, IntPtr, "", CI);
412    Value *Ops[3];
413    Ops[0] = CI->getOperand(1);
414    // Extend the amount to i32.
415    Ops[1] = new ZExtInst(CI->getOperand(2), Type::Int32Ty, "", CI);
416    Ops[2] = Size;
417    ReplaceCallWith("memset", CI, Ops, Ops+3, CI->getOperand(1)->getType(),
418                    MemsetFCache);
419    break;
420  }
421  case Intrinsic::sqrt_f32: {
422    static Constant *sqrtfFCache = 0;
423    ReplaceCallWith("sqrtf", CI, CI->op_begin()+1, CI->op_end(),
424                    Type::FloatTy, sqrtfFCache);
425    break;
426  }
427  case Intrinsic::sqrt_f64: {
428    static Constant *sqrtFCache = 0;
429    ReplaceCallWith("sqrt", CI, CI->op_begin()+1, CI->op_end(),
430                    Type::DoubleTy, sqrtFCache);
431    break;
432  }
433  }
434
435  assert(CI->use_empty() &&
436         "Lowering should have eliminated any uses of the intrinsic call!");
437  CI->eraseFromParent();
438}
439