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