1 //===-- AutoUpgrade.cpp - Implement auto-upgrade helper functions ---------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the auto-upgrade helper functions
12 //===----------------------------------------------------------------------===//
14 #include "llvm/AutoUpgrade.h"
15 #include "llvm/Constants.h"
16 #include "llvm/Function.h"
17 #include "llvm/Instruction.h"
18 #include "llvm/LLVMContext.h"
19 #include "llvm/Module.h"
20 #include "llvm/IntrinsicInst.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/ADT/SmallPtrSet.h"
23 #include "llvm/ADT/SmallVector.h"
24 #include "llvm/Support/CallSite.h"
25 #include "llvm/Support/CFG.h"
26 #include "llvm/Support/ErrorHandling.h"
27 #include "llvm/Support/IRBuilder.h"
32 static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
33 assert(F && "Illegal to upgrade a non-existent Function.");
35 // Quickly eliminate it, if it's not a candidate.
36 StringRef Name = F->getName();
37 if (Name.size() <= 8 || !Name.startswith("llvm."))
39 Name = Name.substr(5); // Strip off "llvm."
41 FunctionType *FTy = F->getFunctionType();
42 Module *M = F->getParent();
47 if (Name.startswith("atomic.cmp.swap") ||
48 Name.startswith("atomic.swap") ||
49 Name.startswith("atomic.load.add") ||
50 Name.startswith("atomic.load.sub") ||
51 Name.startswith("atomic.load.and") ||
52 Name.startswith("atomic.load.nand") ||
53 Name.startswith("atomic.load.or") ||
54 Name.startswith("atomic.load.xor") ||
55 Name.startswith("atomic.load.max") ||
56 Name.startswith("atomic.load.min") ||
57 Name.startswith("atomic.load.umax") ||
58 Name.startswith("atomic.load.umin"))
61 // This upgrades the old llvm.init.trampoline to the new
62 // llvm.init.trampoline and llvm.adjust.trampoline pair.
63 if (Name == "init.trampoline") {
64 // The new llvm.init.trampoline returns nothing.
65 if (FTy->getReturnType()->isVoidTy())
68 assert(FTy->getNumParams() == 3 && "old init.trampoline takes 3 args!");
70 // Change the name of the old intrinsic so that we can play with its type.
71 std::string NameTmp = F->getName();
73 NewFn = cast<Function>(M->getOrInsertFunction(
75 Type::getVoidTy(M->getContext()),
76 FTy->getParamType(0), FTy->getParamType(1),
77 FTy->getParamType(2), (Type *)0));
81 if (Name == "memory.barrier")
84 // This upgrades the llvm.prefetch intrinsic to accept one more parameter,
85 // which is a instruction / data cache identifier. The old version only
86 // implicitly accepted the data version.
87 if (Name == "prefetch") {
88 // Don't do anything if it has the correct number of arguments already
89 if (FTy->getNumParams() == 4)
92 assert(FTy->getNumParams() == 3 && "old prefetch takes 3 args!");
93 // We first need to change the name of the old (bad) intrinsic, because
94 // its type is incorrect, but we cannot overload that name. We
95 // arbitrarily unique it here allowing us to construct a correctly named
96 // and typed function below.
97 std::string NameTmp = F->getName();
99 NewFn = cast<Function>(M->getOrInsertFunction(NameTmp,
100 FTy->getReturnType(),
101 FTy->getParamType(0),
102 FTy->getParamType(1),
103 FTy->getParamType(2),
104 FTy->getParamType(2),
112 // This may not belong here. This function is effectively being overloaded
113 // to both detect an intrinsic which needs upgrading, and to provide the
114 // upgraded form of the intrinsic. We should perhaps have two separate
115 // functions for this.
119 bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) {
121 bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn);
123 // Upgrade intrinsic attributes. This does not change the function.
126 if (unsigned id = F->getIntrinsicID())
127 F->setAttributes(Intrinsic::getAttributes((Intrinsic::ID)id));
131 bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
132 // Nothing to do yet.
136 // UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the
137 // upgraded intrinsic. All argument and return casting must be provided in
138 // order to seamlessly integrate with existing context.
139 void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
140 Function *F = CI->getCalledFunction();
141 LLVMContext &C = CI->getContext();
142 ImmutableCallSite CS(CI);
144 assert(F && "CallInst has no function associated with it.");
147 if (F->getName().startswith("llvm.atomic.cmp.swap")) {
148 IRBuilder<> Builder(C);
149 Builder.SetInsertPoint(CI->getParent(), CI);
150 Value *Val = Builder.CreateAtomicCmpXchg(CI->getArgOperand(0),
151 CI->getArgOperand(1),
152 CI->getArgOperand(2),
155 // Replace intrinsic.
157 if (!CI->use_empty())
158 CI->replaceAllUsesWith(Val);
159 CI->eraseFromParent();
160 } else if (F->getName().startswith("llvm.atomic")) {
161 IRBuilder<> Builder(C);
162 Builder.SetInsertPoint(CI->getParent(), CI);
164 AtomicRMWInst::BinOp Op;
165 if (F->getName().startswith("llvm.atomic.swap"))
166 Op = AtomicRMWInst::Xchg;
167 else if (F->getName().startswith("llvm.atomic.load.add"))
168 Op = AtomicRMWInst::Add;
169 else if (F->getName().startswith("llvm.atomic.load.sub"))
170 Op = AtomicRMWInst::Sub;
171 else if (F->getName().startswith("llvm.atomic.load.and"))
172 Op = AtomicRMWInst::And;
173 else if (F->getName().startswith("llvm.atomic.load.nand"))
174 Op = AtomicRMWInst::Nand;
175 else if (F->getName().startswith("llvm.atomic.load.or"))
176 Op = AtomicRMWInst::Or;
177 else if (F->getName().startswith("llvm.atomic.load.xor"))
178 Op = AtomicRMWInst::Xor;
179 else if (F->getName().startswith("llvm.atomic.load.max"))
180 Op = AtomicRMWInst::Max;
181 else if (F->getName().startswith("llvm.atomic.load.min"))
182 Op = AtomicRMWInst::Min;
183 else if (F->getName().startswith("llvm.atomic.load.umax"))
184 Op = AtomicRMWInst::UMax;
185 else if (F->getName().startswith("llvm.atomic.load.umin"))
186 Op = AtomicRMWInst::UMin;
188 llvm_unreachable("Unknown atomic");
190 Value *Val = Builder.CreateAtomicRMW(Op, CI->getArgOperand(0),
191 CI->getArgOperand(1),
194 // Replace intrinsic.
196 if (!CI->use_empty())
197 CI->replaceAllUsesWith(Val);
198 CI->eraseFromParent();
199 } else if (F->getName() == "llvm.memory.barrier") {
200 IRBuilder<> Builder(C);
201 Builder.SetInsertPoint(CI->getParent(), CI);
203 // Note that this conversion ignores the "device" bit; it was not really
204 // well-defined, and got abused because nobody paid enough attention to
205 // get it right. In practice, this probably doesn't matter; application
206 // code generally doesn't need anything stronger than
207 // SequentiallyConsistent (and realistically, SequentiallyConsistent
208 // is lowered to a strong enough barrier for almost anything).
210 if (cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue())
211 Builder.CreateFence(SequentiallyConsistent);
212 else if (!cast<ConstantInt>(CI->getArgOperand(0))->getZExtValue())
213 Builder.CreateFence(Release);
214 else if (!cast<ConstantInt>(CI->getArgOperand(3))->getZExtValue())
215 Builder.CreateFence(Acquire);
217 Builder.CreateFence(AcquireRelease);
220 CI->eraseFromParent();
222 llvm_unreachable("Unknown function for CallInst upgrade.");
227 switch (NewFn->getIntrinsicID()) {
228 case Intrinsic::prefetch: {
229 IRBuilder<> Builder(C);
230 Builder.SetInsertPoint(CI->getParent(), CI);
231 llvm::Type *I32Ty = llvm::Type::getInt32Ty(CI->getContext());
233 // Add the extra "data cache" argument
234 Value *Operands[4] = { CI->getArgOperand(0), CI->getArgOperand(1),
235 CI->getArgOperand(2),
236 llvm::ConstantInt::get(I32Ty, 1) };
237 CallInst *NewCI = CallInst::Create(NewFn, Operands,
239 NewCI->setTailCall(CI->isTailCall());
240 NewCI->setCallingConv(CI->getCallingConv());
241 // Handle any uses of the old CallInst.
242 if (!CI->use_empty())
243 // Replace all uses of the old call with the new cast which has the
245 CI->replaceAllUsesWith(NewCI);
247 // Clean up the old call now that it has been completely upgraded.
248 CI->eraseFromParent();
251 case Intrinsic::init_trampoline: {
254 // %tramp = call i8* llvm.init.trampoline (i8* x, i8* y, i8* z)
256 // call void llvm.init.trampoline (i8* %x, i8* %y, i8* %z)
257 // %tramp = call i8* llvm.adjust.trampoline (i8* %x)
259 Function *AdjustTrampolineFn =
260 cast<Function>(Intrinsic::getDeclaration(F->getParent(),
261 Intrinsic::adjust_trampoline));
263 IRBuilder<> Builder(C);
264 Builder.SetInsertPoint(CI);
266 Builder.CreateCall3(NewFn, CI->getArgOperand(0), CI->getArgOperand(1),
267 CI->getArgOperand(2));
269 CallInst *AdjustCall = Builder.CreateCall(AdjustTrampolineFn,
270 CI->getArgOperand(0),
272 if (!CI->use_empty())
273 CI->replaceAllUsesWith(AdjustCall);
274 CI->eraseFromParent();
280 // This tests each Function to determine if it needs upgrading. When we find
281 // one we are interested in, we then upgrade all calls to reflect the new
283 void llvm::UpgradeCallsToIntrinsic(Function* F) {
284 assert(F && "Illegal attempt to upgrade a non-existent intrinsic.");
286 // Upgrade the function and check if it is a totaly new function.
288 if (UpgradeIntrinsicFunction(F, NewFn)) {
290 // Replace all uses to the old function with the new one if necessary.
291 for (Value::use_iterator UI = F->use_begin(), UE = F->use_end();
293 if (CallInst *CI = dyn_cast<CallInst>(*UI++))
294 UpgradeIntrinsicCall(CI, NewFn);
296 // Remove old function, no longer used, from the module.
297 F->eraseFromParent();