Change the argument types of llvm.dbg intrinsics.
[oota-llvm.git] / lib / VMCore / AutoUpgrade.cpp
1 //===-- AutoUpgrade.cpp - Implement auto-upgrade helper functions ---------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Reid Spencer and is distributed under the 
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the auto-upgrade helper functions 
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Assembly/AutoUpgrade.h"
15 #include "llvm/Constants.h"
16 #include "llvm/DerivedTypes.h"
17 #include "llvm/Function.h"
18 #include "llvm/Module.h"
19 #include "llvm/Instructions.h"
20 #include "llvm/Intrinsics.h"
21 #include "llvm/SymbolTable.h"
22 #include <iostream>
23 using namespace llvm;
24
25 static Function *getUpgradedUnaryFn(Function *F) {
26   const std::string &Name = F->getName();
27   Module *M = F->getParent();
28   switch (F->getReturnType()->getTypeID()) {
29   default: return 0;
30   case Type::UByteTyID:
31   case Type::SByteTyID:
32     return M->getOrInsertFunction(Name+".i8", 
33                                   Type::UByteTy, Type::UByteTy, NULL);
34   case Type::UShortTyID:
35   case Type::ShortTyID:
36     return M->getOrInsertFunction(Name+".i16", 
37                                   Type::UShortTy, Type::UShortTy, NULL);
38   case Type::UIntTyID:
39   case Type::IntTyID:
40     return M->getOrInsertFunction(Name+".i32", 
41                                   Type::UIntTy, Type::UIntTy, NULL);
42   case Type::ULongTyID:
43   case Type::LongTyID:
44     return M->getOrInsertFunction(Name+".i64",
45                                   Type::ULongTy, Type::ULongTy, NULL);
46   case Type::FloatTyID:
47     return M->getOrInsertFunction(Name+".f32",
48                                   Type::FloatTy, Type::FloatTy, NULL);
49   case Type::DoubleTyID:
50     return M->getOrInsertFunction(Name+".f64",
51                                   Type::DoubleTy, Type::DoubleTy, NULL);
52   }
53 }
54
55 static Function *getUpgradedIntrinsic(Function *F) {
56   // If there's no function, we can't get the argument type.
57   if (!F) return 0;
58
59   // Get the Function's name.
60   const std::string& Name = F->getName();
61
62   // Quickly eliminate it, if it's not a candidate.
63   if (Name.length() <= 8 || Name[0] != 'l' || Name[1] != 'l' || 
64       Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.')
65     return 0;
66
67   Module *M = F->getParent();
68   switch (Name[5]) {
69   default: break;
70   case 'b':
71     if (Name == "llvm.bswap") return getUpgradedUnaryFn(F);
72     break;
73   case 'c':
74     if (Name == "llvm.ctpop" || Name == "llvm.ctlz" || Name == "llvm.cttz")
75       return getUpgradedUnaryFn(F);
76     break;
77   case 'd':
78     if (Name == "llvm.dbg.stoppoint") {
79       PointerType *ESP =
80                   PointerType::get(StructType::get(std::vector<const Type*>()));
81       if (F->getReturnType() != Type::VoidTy ||
82           F->getFunctionType()->getParamType(2) != ESP) {
83         return M->getOrInsertFunction(Name, Type::VoidTy,
84                                       Type::UIntTy, Type::UIntTy, ESP, NULL);
85       }
86     } else if (Name == "llvm.dbg.func.start") {
87       PointerType *ESP =
88                   PointerType::get(StructType::get(std::vector<const Type*>()));
89       if (F->getReturnType()  != Type::VoidTy ||
90           F->getFunctionType()->getParamType(0) != ESP) {
91         return M->getOrInsertFunction(Name, Type::VoidTy, ESP, NULL);
92       }
93     } else if (Name == "llvm.dbg.region.start") {
94       PointerType *ESP =
95                   PointerType::get(StructType::get(std::vector<const Type*>()));
96       if (F->getReturnType() != Type::VoidTy ||
97           F->getFunctionType()->getParamType(0) != ESP) {
98         return M->getOrInsertFunction(Name, Type::VoidTy,  ESP, NULL);
99       }
100     } else if (Name == "llvm.dbg.region.end") {
101       PointerType *ESP =
102                   PointerType::get(StructType::get(std::vector<const Type*>()));
103       if (F->getReturnType() != Type::VoidTy ||
104           F->getFunctionType()->getParamType(0) != ESP) {
105          return M->getOrInsertFunction(Name, Type::VoidTy,  ESP, NULL);
106       }
107     } else if (Name == "llvm.dbg.declare") {
108       PointerType *ESP =
109                   PointerType::get(StructType::get(std::vector<const Type*>()));
110       if (F->getReturnType() != Type::VoidTy ||
111           F->getFunctionType()->getParamType(0) != ESP ||
112           F->getFunctionType()->getParamType(1) != ESP) {
113         return M->getOrInsertFunction(Name, Type::VoidTy, ESP, ESP, NULL);
114       }
115     }
116     break;
117   case 'i':
118     if (Name == "llvm.isunordered" && F->arg_begin() != F->arg_end()) {
119       if (F->arg_begin()->getType() == Type::FloatTy)
120         return M->getOrInsertFunction(Name+".f32", F->getFunctionType());
121       if (F->arg_begin()->getType() == Type::DoubleTy)
122         return M->getOrInsertFunction(Name+".f64", F->getFunctionType());
123     }
124     break;
125   case 'm':
126     if (Name == "llvm.memcpy" || Name == "llvm.memset" || 
127         Name == "llvm.memmove") {
128       if (F->getFunctionType()->getParamType(2) == Type::UIntTy ||
129           F->getFunctionType()->getParamType(2) == Type::IntTy)
130         return M->getOrInsertFunction(Name+".i32", Type::VoidTy,
131                                       PointerType::get(Type::SByteTy),
132                                       F->getFunctionType()->getParamType(1),
133                                       Type::UIntTy, Type::UIntTy, NULL);
134       if (F->getFunctionType()->getParamType(2) == Type::ULongTy ||
135           F->getFunctionType()->getParamType(2) == Type::LongTy)
136         return M->getOrInsertFunction(Name+".i64", Type::VoidTy,
137                                       PointerType::get(Type::SByteTy),
138                                       F->getFunctionType()->getParamType(1),
139                                       Type::ULongTy, Type::UIntTy, NULL);
140     }
141     break;
142   case 's':
143     if (Name == "llvm.sqrt")
144       return getUpgradedUnaryFn(F);
145     break;
146   }
147   return 0;
148 }
149
150 // Occasionally upgraded function call site arguments need to be permutated to
151 // some new order.  The result of getArgumentPermutation is an array of size 
152 // F->getFunctionType()getNumParams() indicating the new operand order.  A value
153 // of zero in the array indicates replacing with UndefValue for the arg type.
154 // NULL is returned if there is no permutation.  It's assumed that the function
155 // name is in the form "llvm.?????"
156 static unsigned *getArgumentPermutation(Function* F) {
157   const std::string& Name = F->getName();
158   const FunctionType *FTy = F->getFunctionType();
159   unsigned N = FTy->getNumParams();
160   
161   switch (Name[5]) {
162   case 'd':
163     if (Name == "llvm.dbg.stoppoint") {
164       static unsigned Permutation[] = { 2, 3, 4 };
165       assert(F->getFunctionType()->getNumParams() ==
166              (sizeof(Permutation) / sizeof(unsigned)) &&
167              "Permutation is wrong length");
168       if (N == 4) return Permutation;
169     } else if (Name == "llvm.dbg.region.start") {
170       static unsigned Permutation[] = { 0 };
171       assert(F->getFunctionType()->getNumParams() ==
172              (sizeof(Permutation) / sizeof(unsigned)) &&
173              "Permutation is wrong length");
174       if (N == 0) return Permutation;
175     } else if (Name == "llvm.dbg.region.end") {
176       static unsigned Permutation[] = { 0 };
177       assert(F->getFunctionType()->getNumParams() ==
178              (sizeof(Permutation) / sizeof(unsigned)) &&
179              "Permutation is wrong length");
180       if (N == 0) return Permutation;
181     } else if (Name == "llvm.dbg.declare") {
182       static unsigned Permutation[] = { 0, 0 };
183       assert(F->getFunctionType()->getNumParams() ==
184              (sizeof(Permutation) / sizeof(unsigned)) &&
185              "Permutation is wrong length");
186       if (N == 0) return Permutation;
187     }
188     break;
189   }
190   return NULL;
191 }
192
193 // UpgradeIntrinsicFunction - Convert overloaded intrinsic function names to
194 // their non-overloaded variants by appending the appropriate suffix based on
195 // the argument types.
196 Function *llvm::UpgradeIntrinsicFunction(Function* F) {
197   // See if its one of the name's we're interested in.
198   if (Function *R = getUpgradedIntrinsic(F)) {
199     std::cerr << "WARNING: change " << F->getName() << " to "
200               << R->getName() << "\n";
201     return R;
202   }
203   return 0;
204 }
205
206 // CastArg - Perform the appropriate cast of an upgraded argument.
207 //
208 static Value *CastArg(Value *Arg, const Type *Ty) {
209   if (Constant *C = dyn_cast<Constant>(Arg)) {
210     return ConstantExpr::getCast(C, Ty);
211   } else {
212     return new CastInst(Arg, Ty, "autoupgrade_cast");
213   }
214 }
215
216 Instruction* llvm::MakeUpgradedCall(Function *F, 
217                                     const std::vector<Value*> &Params,
218                                     BasicBlock *BB, bool isTailCall,
219                                     unsigned CallingConv) {
220   assert(F && "Need a Function to make a CallInst");
221   assert(BB && "Need a BasicBlock to make a CallInst");
222
223   // Convert the params
224   bool signedArg = false;
225   std::vector<Value*> Oprnds;
226   for (std::vector<Value*>::const_iterator PI = Params.begin(), 
227        PE = Params.end(); PI != PE; ++PI) {
228     const Type* opTy = (*PI)->getType();
229     if (opTy->isSigned()) {
230       signedArg = true;
231       Value *cast = CastArg(*PI, opTy->getUnsignedVersion());
232       if (Instruction *I = dyn_cast<Instruction>(cast))
233         BB->getInstList().push_back(I);
234       Oprnds.push_back(cast);
235     }
236     else
237       Oprnds.push_back(*PI);
238   }
239
240   Instruction *result = new CallInst(F, Oprnds);
241   if (result->getType() != Type::VoidTy) result->setName("autoupgrade_call");
242   if (isTailCall) cast<CallInst>(result)->setTailCall();
243   if (CallingConv) cast<CallInst>(result)->setCallingConv(CallingConv);
244   if (signedArg) {
245     const Type* newTy = F->getReturnType()->getUnsignedVersion();
246     CastInst* final = new CastInst(result, newTy, "autoupgrade_uncast");
247     BB->getInstList().push_back(result);
248     result = final;
249   }
250   return result;
251 }
252
253 // UpgradeIntrinsicCall - In the BC reader, change a call to an intrinsic to be
254 // a call to an upgraded intrinsic.  We may have to permute the order or promote
255 // some arguments with a cast.
256 void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
257   Function *F = CI->getCalledFunction();
258
259   const FunctionType *NewFnTy = NewFn->getFunctionType();
260   std::vector<Value*> Oprnds;
261   
262   unsigned *Permutation = getArgumentPermutation(F);
263   unsigned N = NewFnTy->getNumParams();
264
265   if (Permutation) {
266     for (unsigned i = 0; i != N; ++i) {
267       unsigned p = Permutation[i];
268       
269       if (p) {
270         Value *V = CI->getOperand(p);
271         if (V->getType() != NewFnTy->getParamType(i))
272           V = CastArg(V, NewFnTy->getParamType(i));
273         Oprnds.push_back(V);
274       } else
275         Oprnds.push_back(UndefValue::get(NewFnTy->getParamType(i)));
276     }
277   } else if (N) {
278     assert(N == (CI->getNumOperands() - 1) &&
279            "Upgraded function needs permutation");
280     for (unsigned i = 0; i != N; ++i) {
281       Value *V = CI->getOperand(i + 1);
282       if (V->getType() != NewFnTy->getParamType(i))
283         V = CastArg(V, NewFnTy->getParamType(i));
284       Oprnds.push_back(V);
285     }
286   }
287   
288   bool NewIsVoid = NewFn->getReturnType() == Type::VoidTy;
289   
290   CallInst *NewCI = new CallInst(NewFn, Oprnds,
291                                  NewIsVoid ? "" : CI->getName(),
292                                  CI);
293   NewCI->setTailCall(CI->isTailCall());
294   NewCI->setCallingConv(CI->getCallingConv());
295   
296   if (!CI->use_empty()) {
297     if (NewIsVoid) {
298       CI->replaceAllUsesWith(UndefValue::get(CI->getType()));
299     } else {
300       Instruction *RetVal = NewCI;
301       
302       if (F->getReturnType() != NewFn->getReturnType()) {
303         RetVal = new CastInst(NewCI, F->getReturnType(), 
304                               NewCI->getName(), CI);
305         NewCI->moveBefore(RetVal);
306       }
307       
308       CI->replaceAllUsesWith(RetVal);
309     }
310   }
311   CI->eraseFromParent();
312 }
313
314 bool llvm::UpgradeCallsToIntrinsic(Function* F) {
315   if (Function* NewFn = UpgradeIntrinsicFunction(F)) {
316     for (Value::use_iterator UI = F->use_begin(), UE = F->use_end();
317          UI != UE; ) {
318       if (CallInst* CI = dyn_cast<CallInst>(*UI++)) 
319         UpgradeIntrinsicCall(CI, NewFn);
320     }
321     if (NewFn != F)
322       F->eraseFromParent();
323     return true;
324   }
325   return false;
326 }