blob: 378df839ad4a1bd07a00833cb51fc1b51124a60e [file] [log] [blame]
Chandler Carruth7132e002007-08-04 01:51:18 +00001//===-- AutoUpgrade.cpp - Implement auto-upgrade helper functions ---------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattnerf3ebc3f2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chandler Carruth7132e002007-08-04 01:51:18 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the auto-upgrade helper functions
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/AutoUpgrade.h"
Anders Carlssonf924f342007-12-14 06:38:54 +000015#include "llvm/Constants.h"
Chandler Carruth7132e002007-08-04 01:51:18 +000016#include "llvm/Function.h"
Owen Anderson155dccd82009-07-07 23:43:39 +000017#include "llvm/LLVMContext.h"
Chandler Carruth7132e002007-08-04 01:51:18 +000018#include "llvm/Module.h"
19#include "llvm/Instructions.h"
Chandler Carruth7132e002007-08-04 01:51:18 +000020#include "llvm/Intrinsics.h"
Chris Lattner8a923e72008-03-12 17:45:29 +000021#include "llvm/ADT/SmallVector.h"
Anton Korobeynikov579f0712008-02-20 11:08:44 +000022#include <cstring>
Chandler Carruth7132e002007-08-04 01:51:18 +000023using namespace llvm;
24
25
Evan Cheng0e179d02007-12-17 22:33:23 +000026static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
Chandler Carruth7132e002007-08-04 01:51:18 +000027 assert(F && "Illegal to upgrade a non-existent Function.");
28
Owen Anderson155dccd82009-07-07 23:43:39 +000029 LLVMContext* Context = F->getContext();
30
Chandler Carruth7132e002007-08-04 01:51:18 +000031 // Get the Function's name.
32 const std::string& Name = F->getName();
33
34 // Convenience
35 const FunctionType *FTy = F->getFunctionType();
36
37 // Quickly eliminate it, if it's not a candidate.
38 if (Name.length() <= 8 || Name[0] != 'l' || Name[1] != 'l' ||
39 Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.')
Evan Cheng0e179d02007-12-17 22:33:23 +000040 return false;
Chandler Carruth7132e002007-08-04 01:51:18 +000041
42 Module *M = F->getParent();
43 switch (Name[5]) {
44 default: break;
Mon P Wang6a490372008-06-25 08:15:39 +000045 case 'a':
Mon P Wang2c839d42008-07-30 04:36:53 +000046 // This upgrades the llvm.atomic.lcs, llvm.atomic.las, llvm.atomic.lss,
47 // and atomics with default address spaces to their new names to their new
48 // function name (e.g. llvm.atomic.add.i32 => llvm.atomic.add.i32.p0i32)
49 if (Name.compare(5,7,"atomic.",7) == 0) {
Mon P Wang6a490372008-06-25 08:15:39 +000050 if (Name.compare(12,3,"lcs",3) == 0) {
51 std::string::size_type delim = Name.find('.',12);
Mon P Wang2c839d42008-07-30 04:36:53 +000052 F->setName("llvm.atomic.cmp.swap" + Name.substr(delim) +
53 ".p0" + Name.substr(delim+1));
Mon P Wang6a490372008-06-25 08:15:39 +000054 NewFn = F;
55 return true;
56 }
57 else if (Name.compare(12,3,"las",3) == 0) {
58 std::string::size_type delim = Name.find('.',12);
Mon P Wang2c839d42008-07-30 04:36:53 +000059 F->setName("llvm.atomic.load.add"+Name.substr(delim)
60 + ".p0" + Name.substr(delim+1));
Mon P Wang6a490372008-06-25 08:15:39 +000061 NewFn = F;
62 return true;
63 }
64 else if (Name.compare(12,3,"lss",3) == 0) {
65 std::string::size_type delim = Name.find('.',12);
Mon P Wang2c839d42008-07-30 04:36:53 +000066 F->setName("llvm.atomic.load.sub"+Name.substr(delim)
67 + ".p0" + Name.substr(delim+1));
68 NewFn = F;
69 return true;
70 }
71 else if (Name.rfind(".p") == std::string::npos) {
72 // We don't have an address space qualifier so this has be upgraded
73 // to the new name. Copy the type name at the end of the intrinsic
74 // and add to it
75 std::string::size_type delim = Name.find_last_of('.');
76 assert(delim != std::string::npos && "can not find type");
77 F->setName(Name + ".p0" + Name.substr(delim+1));
Mon P Wang6a490372008-06-25 08:15:39 +000078 NewFn = F;
79 return true;
80 }
81 }
82 break;
Chandler Carruth7132e002007-08-04 01:51:18 +000083 case 'b':
84 // This upgrades the name of the llvm.bswap intrinsic function to only use
85 // a single type name for overloading. We only care about the old format
86 // 'llvm.bswap.i*.i*', so check for 'bswap.' and then for there being
87 // a '.' after 'bswap.'
88 if (Name.compare(5,6,"bswap.",6) == 0) {
89 std::string::size_type delim = Name.find('.',11);
90
91 if (delim != std::string::npos) {
92 // Construct the new name as 'llvm.bswap' + '.i*'
93 F->setName(Name.substr(0,10)+Name.substr(delim));
Evan Cheng0e179d02007-12-17 22:33:23 +000094 NewFn = F;
95 return true;
Chandler Carruth7132e002007-08-04 01:51:18 +000096 }
97 }
98 break;
99
100 case 'c':
101 // We only want to fix the 'llvm.ct*' intrinsics which do not have the
102 // correct return type, so we check for the name, and then check if the
103 // return type does not match the parameter type.
104 if ( (Name.compare(5,5,"ctpop",5) == 0 ||
105 Name.compare(5,4,"ctlz",4) == 0 ||
106 Name.compare(5,4,"cttz",4) == 0) &&
107 FTy->getReturnType() != FTy->getParamType(0)) {
108 // We first need to change the name of the old (bad) intrinsic, because
109 // its type is incorrect, but we cannot overload that name. We
110 // arbitrarily unique it here allowing us to construct a correctly named
111 // and typed function below.
112 F->setName("");
113
114 // Now construct the new intrinsic with the correct name and type. We
115 // leave the old function around in order to query its type, whatever it
116 // may be, and correctly convert up to the new type.
Evan Cheng0e179d02007-12-17 22:33:23 +0000117 NewFn = cast<Function>(M->getOrInsertFunction(Name,
118 FTy->getParamType(0),
119 FTy->getParamType(0),
120 (Type *)0));
121 return true;
Chandler Carruth7132e002007-08-04 01:51:18 +0000122 }
123 break;
124
125 case 'p':
126 // This upgrades the llvm.part.select overloaded intrinsic names to only
127 // use one type specifier in the name. We only care about the old format
128 // 'llvm.part.select.i*.i*', and solve as above with bswap.
129 if (Name.compare(5,12,"part.select.",12) == 0) {
130 std::string::size_type delim = Name.find('.',17);
131
132 if (delim != std::string::npos) {
133 // Construct a new name as 'llvm.part.select' + '.i*'
134 F->setName(Name.substr(0,16)+Name.substr(delim));
Evan Cheng0e179d02007-12-17 22:33:23 +0000135 NewFn = F;
136 return true;
Chandler Carruth7132e002007-08-04 01:51:18 +0000137 }
138 break;
139 }
140
141 // This upgrades the llvm.part.set intrinsics similarly as above, however
142 // we care about 'llvm.part.set.i*.i*.i*', but only the first two types
143 // must match. There is an additional type specifier after these two
144 // matching types that we must retain when upgrading. Thus, we require
145 // finding 2 periods, not just one, after the intrinsic name.
146 if (Name.compare(5,9,"part.set.",9) == 0) {
147 std::string::size_type delim = Name.find('.',14);
148
149 if (delim != std::string::npos &&
150 Name.find('.',delim+1) != std::string::npos) {
151 // Construct a new name as 'llvm.part.select' + '.i*.i*'
152 F->setName(Name.substr(0,13)+Name.substr(delim));
Evan Cheng0e179d02007-12-17 22:33:23 +0000153 NewFn = F;
154 return true;
Chandler Carruth7132e002007-08-04 01:51:18 +0000155 }
156 break;
157 }
158
159 break;
Anders Carlssonf924f342007-12-14 06:38:54 +0000160 case 'x':
161 // This fixes all MMX shift intrinsic instructions to take a
162 // v1i64 instead of a v2i32 as the second parameter.
163 if (Name.compare(5,10,"x86.mmx.ps",10) == 0 &&
164 (Name.compare(13,4,"psll", 4) == 0 ||
165 Name.compare(13,4,"psra", 4) == 0 ||
Evan Chengcdf22f22008-05-03 00:52:09 +0000166 Name.compare(13,4,"psrl", 4) == 0) && Name[17] != 'i') {
Anders Carlssonf924f342007-12-14 06:38:54 +0000167
Owen Anderson155dccd82009-07-07 23:43:39 +0000168 const llvm::Type *VT =
169 Context->getVectorType(Context->getIntegerType(64), 1);
Anders Carlssonf924f342007-12-14 06:38:54 +0000170
171 // We don't have to do anything if the parameter already has
172 // the correct type.
173 if (FTy->getParamType(1) == VT)
174 break;
175
176 // We first need to change the name of the old (bad) intrinsic, because
177 // its type is incorrect, but we cannot overload that name. We
178 // arbitrarily unique it here allowing us to construct a correctly named
179 // and typed function below.
180 F->setName("");
181
182 assert(FTy->getNumParams() == 2 && "MMX shift intrinsics take 2 args!");
183
184 // Now construct the new intrinsic with the correct name and type. We
185 // leave the old function around in order to query its type, whatever it
186 // may be, and correctly convert up to the new type.
Evan Cheng0e179d02007-12-17 22:33:23 +0000187 NewFn = cast<Function>(M->getOrInsertFunction(Name,
188 FTy->getReturnType(),
189 FTy->getParamType(0),
190 VT,
191 (Type *)0));
192 return true;
Evan Cheng50659322008-05-24 00:08:39 +0000193 } else if (Name.compare(5,17,"x86.sse2.loadh.pd",17) == 0 ||
194 Name.compare(5,17,"x86.sse2.loadl.pd",17) == 0 ||
Evan Cheng2146270c2008-05-24 02:14:05 +0000195 Name.compare(5,16,"x86.sse2.movl.dq",16) == 0 ||
196 Name.compare(5,15,"x86.sse2.movs.d",15) == 0 ||
197 Name.compare(5,16,"x86.sse2.shuf.pd",16) == 0 ||
198 Name.compare(5,18,"x86.sse2.unpckh.pd",18) == 0 ||
Evan Cheng91a2e562008-05-24 02:56:30 +0000199 Name.compare(5,18,"x86.sse2.unpckl.pd",18) == 0 ||
200 Name.compare(5,20,"x86.sse2.punpckh.qdq",20) == 0 ||
201 Name.compare(5,20,"x86.sse2.punpckl.qdq",20) == 0) {
Evan Cheng50659322008-05-24 00:08:39 +0000202 // Calls to these intrinsics are transformed into ShuffleVector's.
Evan Cheng0e179d02007-12-17 22:33:23 +0000203 NewFn = 0;
204 return true;
Anders Carlssonf924f342007-12-14 06:38:54 +0000205 }
Evan Cheng0e179d02007-12-17 22:33:23 +0000206
Anders Carlssonf924f342007-12-14 06:38:54 +0000207 break;
Chandler Carruth7132e002007-08-04 01:51:18 +0000208 }
209
210 // This may not belong here. This function is effectively being overloaded
211 // to both detect an intrinsic which needs upgrading, and to provide the
212 // upgraded form of the intrinsic. We should perhaps have two separate
213 // functions for this.
Evan Cheng0e179d02007-12-17 22:33:23 +0000214 return false;
Chandler Carruth7132e002007-08-04 01:51:18 +0000215}
216
Evan Cheng0e179d02007-12-17 22:33:23 +0000217bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) {
218 NewFn = 0;
219 bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn);
Duncan Sands38ef3a82007-12-03 20:06:50 +0000220
221 // Upgrade intrinsic attributes. This does not change the function.
Evan Cheng0e179d02007-12-17 22:33:23 +0000222 if (NewFn)
223 F = NewFn;
Dale Johannesenb842d522009-02-05 01:49:45 +0000224 if (unsigned id = F->getIntrinsicID())
Devang Patel4c758ea2008-09-25 21:00:45 +0000225 F->setAttributes(Intrinsic::getAttributes((Intrinsic::ID)id));
Duncan Sands38ef3a82007-12-03 20:06:50 +0000226 return Upgraded;
227}
228
Chandler Carruth7132e002007-08-04 01:51:18 +0000229// UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the
230// upgraded intrinsic. All argument and return casting must be provided in
231// order to seamlessly integrate with existing context.
232void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Chandler Carruth7132e002007-08-04 01:51:18 +0000233 Function *F = CI->getCalledFunction();
Owen Anderson155dccd82009-07-07 23:43:39 +0000234 LLVMContext* Context = F->getContext();
235
Chandler Carruth7132e002007-08-04 01:51:18 +0000236 assert(F && "CallInst has no function associated with it.");
Evan Cheng0e179d02007-12-17 22:33:23 +0000237
238 if (!NewFn) {
Evan Cheng50659322008-05-24 00:08:39 +0000239 bool isLoadH = false, isLoadL = false, isMovL = false;
Evan Cheng2146270c2008-05-24 02:14:05 +0000240 bool isMovSD = false, isShufPD = false;
241 bool isUnpckhPD = false, isUnpcklPD = false;
Evan Cheng91a2e562008-05-24 02:56:30 +0000242 bool isPunpckhQPD = false, isPunpcklQPD = false;
Evan Cheng50659322008-05-24 00:08:39 +0000243 if (strcmp(F->getNameStart(), "llvm.x86.sse2.loadh.pd") == 0)
244 isLoadH = true;
245 else if (strcmp(F->getNameStart(), "llvm.x86.sse2.loadl.pd") == 0)
246 isLoadL = true;
247 else if (strcmp(F->getNameStart(), "llvm.x86.sse2.movl.dq") == 0)
248 isMovL = true;
Evan Cheng2146270c2008-05-24 02:14:05 +0000249 else if (strcmp(F->getNameStart(), "llvm.x86.sse2.movs.d") == 0)
250 isMovSD = true;
251 else if (strcmp(F->getNameStart(), "llvm.x86.sse2.shuf.pd") == 0)
252 isShufPD = true;
253 else if (strcmp(F->getNameStart(), "llvm.x86.sse2.unpckh.pd") == 0)
254 isUnpckhPD = true;
255 else if (strcmp(F->getNameStart(), "llvm.x86.sse2.unpckl.pd") == 0)
256 isUnpcklPD = true;
Evan Cheng91a2e562008-05-24 02:56:30 +0000257 else if (strcmp(F->getNameStart(), "llvm.x86.sse2.punpckh.qdq") == 0)
258 isPunpckhQPD = true;
259 else if (strcmp(F->getNameStart(), "llvm.x86.sse2.punpckl.qdq") == 0)
260 isPunpcklQPD = true;
Evan Cheng0e179d02007-12-17 22:33:23 +0000261
Evan Cheng2146270c2008-05-24 02:14:05 +0000262 if (isLoadH || isLoadL || isMovL || isMovSD || isShufPD ||
Evan Cheng91a2e562008-05-24 02:56:30 +0000263 isUnpckhPD || isUnpcklPD || isPunpckhQPD || isPunpcklQPD) {
Evan Cheng50659322008-05-24 00:08:39 +0000264 std::vector<Constant*> Idxs;
265 Value *Op0 = CI->getOperand(1);
Evan Cheng2146270c2008-05-24 02:14:05 +0000266 ShuffleVectorInst *SI = NULL;
Evan Cheng50659322008-05-24 00:08:39 +0000267 if (isLoadH || isLoadL) {
Owen Anderson155dccd82009-07-07 23:43:39 +0000268 Value *Op1 = Context->getUndef(Op0->getType());
Evan Cheng50659322008-05-24 00:08:39 +0000269 Value *Addr = new BitCastInst(CI->getOperand(2),
Owen Anderson155dccd82009-07-07 23:43:39 +0000270 Context->getPointerTypeUnqual(Type::DoubleTy),
Evan Cheng50659322008-05-24 00:08:39 +0000271 "upgraded.", CI);
272 Value *Load = new LoadInst(Addr, "upgraded.", false, 8, CI);
Owen Anderson155dccd82009-07-07 23:43:39 +0000273 Value *Idx = Context->getConstantInt(Type::Int32Ty, 0);
Evan Cheng50659322008-05-24 00:08:39 +0000274 Op1 = InsertElementInst::Create(Op1, Load, Idx, "upgraded.", CI);
275
276 if (isLoadH) {
Owen Anderson155dccd82009-07-07 23:43:39 +0000277 Idxs.push_back(Context->getConstantInt(Type::Int32Ty, 0));
278 Idxs.push_back(Context->getConstantInt(Type::Int32Ty, 2));
Evan Cheng50659322008-05-24 00:08:39 +0000279 } else {
Owen Anderson155dccd82009-07-07 23:43:39 +0000280 Idxs.push_back(Context->getConstantInt(Type::Int32Ty, 2));
281 Idxs.push_back(Context->getConstantInt(Type::Int32Ty, 1));
Evan Cheng50659322008-05-24 00:08:39 +0000282 }
Owen Anderson155dccd82009-07-07 23:43:39 +0000283 Value *Mask = Context->getConstantVector(Idxs);
Evan Cheng50659322008-05-24 00:08:39 +0000284 SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI);
Evan Cheng2146270c2008-05-24 02:14:05 +0000285 } else if (isMovL) {
Owen Anderson155dccd82009-07-07 23:43:39 +0000286 Constant *Zero = Context->getConstantInt(Type::Int32Ty, 0);
Evan Cheng50659322008-05-24 00:08:39 +0000287 Idxs.push_back(Zero);
288 Idxs.push_back(Zero);
289 Idxs.push_back(Zero);
290 Idxs.push_back(Zero);
Owen Anderson155dccd82009-07-07 23:43:39 +0000291 Value *ZeroV = Context->getConstantVector(Idxs);
Evan Cheng50659322008-05-24 00:08:39 +0000292
293 Idxs.clear();
Owen Anderson155dccd82009-07-07 23:43:39 +0000294 Idxs.push_back(Context->getConstantInt(Type::Int32Ty, 4));
295 Idxs.push_back(Context->getConstantInt(Type::Int32Ty, 5));
296 Idxs.push_back(Context->getConstantInt(Type::Int32Ty, 2));
297 Idxs.push_back(Context->getConstantInt(Type::Int32Ty, 3));
298 Value *Mask = Context->getConstantVector(Idxs);
Evan Cheng50659322008-05-24 00:08:39 +0000299 SI = new ShuffleVectorInst(ZeroV, Op0, Mask, "upgraded.", CI);
Evan Cheng91a2e562008-05-24 02:56:30 +0000300 } else if (isMovSD ||
301 isUnpckhPD || isUnpcklPD || isPunpckhQPD || isPunpcklQPD) {
Evan Cheng2146270c2008-05-24 02:14:05 +0000302 Value *Op1 = CI->getOperand(2);
303 if (isMovSD) {
Owen Anderson155dccd82009-07-07 23:43:39 +0000304 Idxs.push_back(Context->getConstantInt(Type::Int32Ty, 2));
305 Idxs.push_back(Context->getConstantInt(Type::Int32Ty, 1));
Evan Cheng91a2e562008-05-24 02:56:30 +0000306 } else if (isUnpckhPD || isPunpckhQPD) {
Owen Anderson155dccd82009-07-07 23:43:39 +0000307 Idxs.push_back(Context->getConstantInt(Type::Int32Ty, 1));
308 Idxs.push_back(Context->getConstantInt(Type::Int32Ty, 3));
Evan Cheng2146270c2008-05-24 02:14:05 +0000309 } else {
Owen Anderson155dccd82009-07-07 23:43:39 +0000310 Idxs.push_back(Context->getConstantInt(Type::Int32Ty, 0));
311 Idxs.push_back(Context->getConstantInt(Type::Int32Ty, 2));
Evan Cheng2146270c2008-05-24 02:14:05 +0000312 }
Owen Anderson155dccd82009-07-07 23:43:39 +0000313 Value *Mask = Context->getConstantVector(Idxs);
Evan Cheng2146270c2008-05-24 02:14:05 +0000314 SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI);
315 } else if (isShufPD) {
316 Value *Op1 = CI->getOperand(2);
317 unsigned MaskVal = cast<ConstantInt>(CI->getOperand(3))->getZExtValue();
Owen Anderson155dccd82009-07-07 23:43:39 +0000318 Idxs.push_back(Context->getConstantInt(Type::Int32Ty, MaskVal & 1));
319 Idxs.push_back(Context->getConstantInt(Type::Int32Ty,
320 ((MaskVal >> 1) & 1)+2));
321 Value *Mask = Context->getConstantVector(Idxs);
Evan Cheng2146270c2008-05-24 02:14:05 +0000322 SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI);
Evan Cheng50659322008-05-24 00:08:39 +0000323 }
Evan Cheng0e179d02007-12-17 22:33:23 +0000324
Evan Cheng2146270c2008-05-24 02:14:05 +0000325 assert(SI && "Unexpected!");
326
Evan Cheng0e179d02007-12-17 22:33:23 +0000327 // Handle any uses of the old CallInst.
328 if (!CI->use_empty())
329 // Replace all uses of the old call with the new cast which has the
330 // correct type.
331 CI->replaceAllUsesWith(SI);
332
333 // Clean up the old call now that it has been completely upgraded.
334 CI->eraseFromParent();
Evan Chenga8288f42007-12-18 01:04:25 +0000335 } else {
336 assert(0 && "Unknown function for CallInst upgrade.");
Evan Cheng0e179d02007-12-17 22:33:23 +0000337 }
338 return;
339 }
340
Gabor Greife9ecc682008-04-06 20:25:17 +0000341 switch (NewFn->getIntrinsicID()) {
Chandler Carruth7132e002007-08-04 01:51:18 +0000342 default: assert(0 && "Unknown function for CallInst upgrade.");
Anders Carlssonf924f342007-12-14 06:38:54 +0000343 case Intrinsic::x86_mmx_psll_d:
344 case Intrinsic::x86_mmx_psll_q:
345 case Intrinsic::x86_mmx_psll_w:
346 case Intrinsic::x86_mmx_psra_d:
347 case Intrinsic::x86_mmx_psra_w:
348 case Intrinsic::x86_mmx_psrl_d:
349 case Intrinsic::x86_mmx_psrl_q:
350 case Intrinsic::x86_mmx_psrl_w: {
Chris Lattner8a923e72008-03-12 17:45:29 +0000351 Value *Operands[2];
Anders Carlssonf924f342007-12-14 06:38:54 +0000352
Chris Lattner8a923e72008-03-12 17:45:29 +0000353 Operands[0] = CI->getOperand(1);
Anders Carlssonf924f342007-12-14 06:38:54 +0000354
355 // Cast the second parameter to the correct type.
356 BitCastInst *BC = new BitCastInst(CI->getOperand(2),
357 NewFn->getFunctionType()->getParamType(1),
Evan Cheng50659322008-05-24 00:08:39 +0000358 "upgraded.", CI);
Chris Lattner8a923e72008-03-12 17:45:29 +0000359 Operands[1] = BC;
Anders Carlssonf924f342007-12-14 06:38:54 +0000360
361 // Construct a new CallInst
Gabor Greife9ecc682008-04-06 20:25:17 +0000362 CallInst *NewCI = CallInst::Create(NewFn, Operands, Operands+2,
363 "upgraded."+CI->getName(), CI);
Anders Carlssonf924f342007-12-14 06:38:54 +0000364 NewCI->setTailCall(CI->isTailCall());
365 NewCI->setCallingConv(CI->getCallingConv());
366
367 // Handle any uses of the old CallInst.
368 if (!CI->use_empty())
369 // Replace all uses of the old call with the new cast which has the
370 // correct type.
371 CI->replaceAllUsesWith(NewCI);
372
373 // Clean up the old call now that it has been completely upgraded.
374 CI->eraseFromParent();
375 break;
376 }
Chandler Carruth7132e002007-08-04 01:51:18 +0000377 case Intrinsic::ctlz:
378 case Intrinsic::ctpop:
Gabor Greife9ecc682008-04-06 20:25:17 +0000379 case Intrinsic::cttz: {
Chandler Carruth7132e002007-08-04 01:51:18 +0000380 // Build a small vector of the 1..(N-1) operands, which are the
381 // parameters.
Chris Lattner8a923e72008-03-12 17:45:29 +0000382 SmallVector<Value*, 8> Operands(CI->op_begin()+1, CI->op_end());
Chandler Carruth7132e002007-08-04 01:51:18 +0000383
384 // Construct a new CallInst
Gabor Greife9ecc682008-04-06 20:25:17 +0000385 CallInst *NewCI = CallInst::Create(NewFn, Operands.begin(), Operands.end(),
386 "upgraded."+CI->getName(), CI);
Chandler Carruth7132e002007-08-04 01:51:18 +0000387 NewCI->setTailCall(CI->isTailCall());
388 NewCI->setCallingConv(CI->getCallingConv());
389
390 // Handle any uses of the old CallInst.
391 if (!CI->use_empty()) {
392 // Check for sign extend parameter attributes on the return values.
Devang Patel4c758ea2008-09-25 21:00:45 +0000393 bool SrcSExt = NewFn->getAttributes().paramHasAttr(0, Attribute::SExt);
394 bool DestSExt = F->getAttributes().paramHasAttr(0, Attribute::SExt);
Chandler Carruth7132e002007-08-04 01:51:18 +0000395
396 // Construct an appropriate cast from the new return type to the old.
Gabor Greife1f6e4b2008-05-16 19:29:10 +0000397 CastInst *RetCast = CastInst::Create(
Chandler Carruth7132e002007-08-04 01:51:18 +0000398 CastInst::getCastOpcode(NewCI, SrcSExt,
399 F->getReturnType(),
400 DestSExt),
401 NewCI, F->getReturnType(),
402 NewCI->getName(), CI);
403 NewCI->moveBefore(RetCast);
404
405 // Replace all uses of the old call with the new cast which has the
406 // correct type.
407 CI->replaceAllUsesWith(RetCast);
408 }
409
410 // Clean up the old call now that it has been completely upgraded.
411 CI->eraseFromParent();
Gabor Greife9ecc682008-04-06 20:25:17 +0000412 }
413 break;
Chandler Carruth7132e002007-08-04 01:51:18 +0000414 }
415}
416
417// This tests each Function to determine if it needs upgrading. When we find
418// one we are interested in, we then upgrade all calls to reflect the new
419// function.
420void llvm::UpgradeCallsToIntrinsic(Function* F) {
421 assert(F && "Illegal attempt to upgrade a non-existent intrinsic.");
422
423 // Upgrade the function and check if it is a totaly new function.
Evan Cheng0e179d02007-12-17 22:33:23 +0000424 Function* NewFn;
425 if (UpgradeIntrinsicFunction(F, NewFn)) {
Chandler Carruth7132e002007-08-04 01:51:18 +0000426 if (NewFn != F) {
427 // Replace all uses to the old function with the new one if necessary.
428 for (Value::use_iterator UI = F->use_begin(), UE = F->use_end();
429 UI != UE; ) {
430 if (CallInst* CI = dyn_cast<CallInst>(*UI++))
431 UpgradeIntrinsicCall(CI, NewFn);
432 }
433 // Remove old function, no longer used, from the module.
434 F->eraseFromParent();
435 }
436 }
437}