Add a new interface function to AutoUpgrade for simultaneously upgrading
[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/DerivedTypes.h"
16 #include "llvm/Function.h"
17 #include "llvm/Module.h"
18 #include "llvm/Instructions.h"
19 #include "llvm/Intrinsics.h"
20 #include "llvm/SymbolTable.h"
21 #include <iostream>
22
23 using namespace llvm;
24
25 // Utility function for getting the correct suffix given a type
26 static inline const char* get_suffix(const Type* Ty) {
27   if (Ty == Type::UIntTy)
28     return ".i32";
29   if (Ty == Type::UShortTy)
30     return ".i16";
31   if (Ty == Type::UByteTy)
32     return ".i8";
33   if (Ty == Type::ULongTy)
34     return ".i64";
35   if (Ty == Type::FloatTy)
36     return ".f32";
37   if (Ty == Type::DoubleTy)
38     return ".f64";
39   return 0;
40 }
41
42 static inline const Type* get_type(Function* F) {
43   // If there's no function, we can't get the argument type.
44   if (!F)
45     return 0;
46
47   // Get the Function's name.
48   const std::string& Name = F->getName();
49
50   // Quickly eliminate it, if it's not a candidate.
51   if (Name.length() <= 5 || Name[0] != 'l' || Name[1] != 'l' || Name[2] !=
52     'v' || Name[3] != 'm' || Name[4] != '.')
53     return 0;
54
55   switch (Name[5]) {
56     case 'b':
57       if (Name == "llvm.bswap")
58         return F->getReturnType();
59       break;
60     case 'c':
61       if (Name == "llvm.ctpop" || Name == "llvm.ctlz" || Name == "llvm.cttz")
62         return F->getReturnType();
63       break;
64     case 'i':
65       if (Name == "llvm.isunordered") {
66         Function::const_arg_iterator ArgIt = F->arg_begin();
67         if (ArgIt != F->arg_end()) 
68           return ArgIt->getType();
69       }
70       break;
71     case 's':
72       if (Name == "llvm.sqrt")
73         return F->getReturnType();
74       break;
75     default:
76       break;
77   }
78   return 0;
79 }
80
81 bool llvm::IsUpgradeableIntrinsicName(const std::string& Name) {
82   // Quickly eliminate it, if it's not a candidate.
83   if (Name.length() <= 5 || Name[0] != 'l' || Name[1] != 'l' || Name[2] !=
84     'v' || Name[3] != 'm' || Name[4] != '.')
85     return false;
86
87   switch (Name[5]) {
88     case 'b':
89       if (Name == "llvm.bswap")
90         return true;
91       break;
92     case 'c':
93       if (Name == "llvm.ctpop" || Name == "llvm.ctlz" || Name == "llvm.cttz")
94         return true;
95       break;
96     case 'i':
97       if (Name == "llvm.isunordered")
98         return true;
99       break;
100     case 's':
101       if (Name == "llvm.sqrt")
102         return true;
103       break;
104     default:
105       break;
106   }
107   return false;
108 }
109
110 // UpgradeIntrinsicFunction - Convert overloaded intrinsic function names to
111 // their non-overloaded variants by appending the appropriate suffix based on
112 // the argument types.
113 Function* llvm::UpgradeIntrinsicFunction(Function* F) {
114   // See if its one of the name's we're interested in.
115   if (const Type* Ty = get_type(F)) {
116     const char* suffix = get_suffix(Ty);
117     if (Ty->isSigned())
118       suffix = get_suffix(Ty->getUnsignedVersion());
119     assert(suffix && "Intrinsic parameter type not recognized");
120     const std::string& Name = F->getName();
121     std::string new_name = Name + suffix;
122     std::cerr << "WARNING: change " << Name << " to " << new_name << "\n";
123     SymbolTable& SymTab = F->getParent()->getSymbolTable();
124     if (Value* V = SymTab.lookup(F->getType(),new_name))
125       if (Function* OtherF = dyn_cast<Function>(V))
126         return OtherF;
127     
128     // There wasn't an existing function for the intrinsic, so now make sure the
129     // signedness of the arguments is correct.
130     if (Ty->isSigned()) {
131       const Type* newTy = Ty->getUnsignedVersion();
132       std::vector<const Type*> Params;
133       Params.push_back(newTy);
134       FunctionType* FT = FunctionType::get(newTy, Params,false);
135       return new Function(FT, GlobalValue::ExternalLinkage, new_name, 
136                           F->getParent());
137     }
138
139     // The argument was the correct type (unsigned or floating), so just
140     // rename the function to its correct name and return it.
141     F->setName(new_name);
142     return F;
143   }
144   return 0;
145 }
146
147 CallInst* llvm::UpgradeIntrinsicCall(CallInst *CI) {
148   Function *F = CI->getCalledFunction();
149   if (const Type* Ty = get_type(F)) {
150     Function* newF = UpgradeIntrinsicFunction(F);
151     std::vector<Value*> Oprnds;
152     for (User::op_iterator OI = CI->op_begin(), OE = CI->op_end(); 
153          OI != OE; ++OI)
154       Oprnds.push_back(CI);
155     CallInst* newCI = new CallInst(newF,Oprnds,"autoupgrade_call",CI);
156     if (Ty->isSigned()) {
157       const Type* newTy = Ty->getUnsignedVersion();
158       newCI->setOperand(1,new CastInst(newCI->getOperand(1), newTy, 
159                      "autoupgrade_cast", newCI));
160     }
161     return newCI;
162   }
163   return 0;
164 }
165
166 bool llvm::UpgradeCallsToIntrinsic(Function* F) {
167   if (Function* newF = UpgradeIntrinsicFunction(F)) {
168     for (Value::use_iterator UI = F->use_begin(), UE = F->use_end();
169          UI != UE; ++UI) {
170       if (CallInst* CI = dyn_cast<CallInst>(*UI)) {
171         std::vector<Value*> Oprnds;
172         User::op_iterator OI = CI->op_begin();
173         ++OI;
174         for (User::op_iterator OE = CI->op_end(); OI != OE; ++OI)
175           Oprnds.push_back(*OI);
176         CallInst* newCI = new CallInst(newF,Oprnds,"autoupgrade_call",CI);
177         const Type* Ty = Oprnds[0]->getType();
178         if (Ty->isSigned()) {
179           const Type* newTy = Ty->getUnsignedVersion();
180           newCI->setOperand(1,new CastInst(newCI->getOperand(1), newTy, 
181                          "autoupgrade_cast", newCI));
182           CastInst* final = new CastInst(newCI, Ty, "autoupgrade_uncast",newCI);
183           newCI->moveBefore(final);
184           CI->replaceAllUsesWith(final);
185         } else {
186           CI->replaceAllUsesWith(newCI);
187         }
188         CI->eraseFromParent();
189       }
190     }
191     if (newF != F)
192       F->eraseFromParent();
193     return true;
194   }
195   return false;
196 }