1 //===-- AutoUpgrade.cpp - Implement auto-upgrade helper functions ---------===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
10 // This file implements the auto-upgrade helper functions
12 //===----------------------------------------------------------------------===//
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"
24 static Function *getUpgradedUnaryFn(Function *F) {
25 const std::string &Name = F->getName();
26 Module *M = F->getParent();
27 switch (F->getReturnType()->getTypeID()) {
31 return M->getOrInsertFunction(Name+".i8",
32 Type::UByteTy, Type::UByteTy, NULL);
33 case Type::UShortTyID:
35 return M->getOrInsertFunction(Name+".i16",
36 Type::UShortTy, Type::UShortTy, NULL);
39 return M->getOrInsertFunction(Name+".i32",
40 Type::UIntTy, Type::UIntTy, NULL);
43 return M->getOrInsertFunction(Name+".i64",
44 Type::ULongTy, Type::ULongTy, NULL);
46 return M->getOrInsertFunction(Name+".f32",
47 Type::FloatTy, Type::FloatTy, NULL);
48 case Type::DoubleTyID:
49 return M->getOrInsertFunction(Name+".f64",
50 Type::DoubleTy, Type::DoubleTy, NULL);
54 static Function *getUpgradedIntrinsic(Function *F) {
55 // If there's no function, we can't get the argument type.
58 // Get the Function's name.
59 const std::string& Name = F->getName();
61 // Quickly eliminate it, if it's not a candidate.
62 if (Name.length() <= 8 || Name[0] != 'l' || Name[1] != 'l' ||
63 Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.')
66 Module *M = F->getParent();
70 if (Name == "llvm.bswap") return getUpgradedUnaryFn(F);
73 if (Name == "llvm.ctpop" || Name == "llvm.ctlz" || Name == "llvm.cttz")
74 return getUpgradedUnaryFn(F);
77 if (Name == "llvm.isunordered" && F->arg_begin() != F->arg_end()) {
78 if (F->arg_begin()->getType() == Type::FloatTy)
79 return M->getOrInsertFunction(Name+".f32", F->getFunctionType());
80 if (F->arg_begin()->getType() == Type::DoubleTy)
81 return M->getOrInsertFunction(Name+".f64", F->getFunctionType());
85 if (Name == "llvm.memcpy" || Name == "llvm.memset" ||
86 Name == "llvm.memmove") {
87 if (F->getFunctionType()->getParamType(2) == Type::UIntTy ||
88 F->getFunctionType()->getParamType(2) == Type::IntTy)
89 return M->getOrInsertFunction(Name+".i32", Type::VoidTy,
90 PointerType::get(Type::SByteTy),
91 F->getFunctionType()->getParamType(1),
92 Type::UIntTy, Type::UIntTy, NULL);
93 if (F->getFunctionType()->getParamType(2) == Type::ULongTy ||
94 F->getFunctionType()->getParamType(2) == Type::LongTy)
95 return M->getOrInsertFunction(Name+".i64", Type::VoidTy,
96 PointerType::get(Type::SByteTy),
97 F->getFunctionType()->getParamType(1),
98 Type::ULongTy, Type::UIntTy, NULL);
102 if (Name == "llvm.sqrt")
103 return getUpgradedUnaryFn(F);
109 // UpgradeIntrinsicFunction - Convert overloaded intrinsic function names to
110 // their non-overloaded variants by appending the appropriate suffix based on
111 // the argument types.
112 Function *llvm::UpgradeIntrinsicFunction(Function* F) {
113 // See if its one of the name's we're interested in.
114 if (Function *R = getUpgradedIntrinsic(F)) {
115 std::cerr << "WARNING: change " << F->getName() << " to "
116 << R->getName() << "\n";
123 Instruction* llvm::MakeUpgradedCall(Function *F,
124 const std::vector<Value*> &Params,
125 BasicBlock *BB, bool isTailCall,
126 unsigned CallingConv) {
127 assert(F && "Need a Function to make a CallInst");
128 assert(BB && "Need a BasicBlock to make a CallInst");
130 // Convert the params
131 bool signedArg = false;
132 std::vector<Value*> Oprnds;
133 for (std::vector<Value*>::const_iterator PI = Params.begin(),
134 PE = Params.end(); PI != PE; ++PI) {
135 const Type* opTy = (*PI)->getType();
136 if (opTy->isSigned()) {
139 new CastInst(*PI,opTy->getUnsignedVersion(), "autoupgrade_cast");
140 BB->getInstList().push_back(cast);
141 Oprnds.push_back(cast);
144 Oprnds.push_back(*PI);
147 Instruction *result = new CallInst(F, Oprnds);
148 if (result->getType() != Type::VoidTy) result->setName("autoupgrade_call");
149 if (isTailCall) cast<CallInst>(result)->setTailCall();
150 if (CallingConv) cast<CallInst>(result)->setCallingConv(CallingConv);
152 const Type* newTy = F->getReturnType()->getUnsignedVersion();
153 CastInst* final = new CastInst(result, newTy, "autoupgrade_uncast");
154 BB->getInstList().push_back(result);
160 // UpgradeIntrinsicCall - In the BC reader, change a call to some intrinsic to
161 // be a called to the specified intrinsic. We expect the callees to have the
162 // same number of arguments, but their types may be different.
163 void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
164 Function *F = CI->getCalledFunction();
166 const FunctionType *NewFnTy = NewFn->getFunctionType();
167 std::vector<Value*> Oprnds;
168 for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) {
169 Value *V = CI->getOperand(i);
170 if (V->getType() != NewFnTy->getParamType(i-1))
171 V = new CastInst(V, NewFnTy->getParamType(i-1), V->getName(), CI);
174 CallInst *NewCI = new CallInst(NewFn, Oprnds, CI->getName(), CI);
175 NewCI->setTailCall(CI->isTailCall());
176 NewCI->setCallingConv(CI->getCallingConv());
178 if (!CI->use_empty()) {
179 Instruction *RetVal = NewCI;
180 if (F->getReturnType() != NewFn->getReturnType()) {
181 RetVal = new CastInst(NewCI, NewFn->getReturnType(),
182 NewCI->getName(), CI);
183 NewCI->moveBefore(RetVal);
185 CI->replaceAllUsesWith(RetVal);
187 CI->eraseFromParent();
190 bool llvm::UpgradeCallsToIntrinsic(Function* F) {
191 if (Function* newF = UpgradeIntrinsicFunction(F)) {
192 for (Value::use_iterator UI = F->use_begin(), UE = F->use_end();
194 if (CallInst* CI = dyn_cast<CallInst>(*UI++)) {
195 std::vector<Value*> Oprnds;
196 User::op_iterator OI = CI->op_begin();
198 for (User::op_iterator OE = CI->op_end(); OI != OE; ++OI) {
199 const Type* opTy = OI->get()->getType();
200 if (opTy->isSigned()) {
202 new CastInst(OI->get(),opTy->getUnsignedVersion(),
203 "autoupgrade_cast",CI));
205 Oprnds.push_back(*OI);
208 CallInst* newCI = new CallInst(newF, Oprnds,
209 CI->hasName() ? "autoupcall" : "", CI);
210 newCI->setTailCall(CI->isTailCall());
211 newCI->setCallingConv(CI->getCallingConv());
212 if (CI->use_empty()) {
214 } else if (CI->getType() != newCI->getType()) {
215 CastInst *final = new CastInst(newCI, CI->getType(),
216 "autoupgrade_uncast", newCI);
217 newCI->moveBefore(final);
218 CI->replaceAllUsesWith(final);
220 CI->replaceAllUsesWith(newCI);
222 CI->eraseFromParent();
226 F->eraseFromParent();