0b6344c1eb487ea1eaef7a97f8d0387f1f11c8ee
[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 is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the auto-upgrade helper functions 
11 //
12 //===----------------------------------------------------------------------===//
13
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"
28 #include <cstring>
29 using namespace llvm;
30
31
32 static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
33   assert(F && "Illegal to upgrade a non-existent Function.");
34
35   // Quickly eliminate it, if it's not a candidate.
36   StringRef Name = F->getName();
37   if (Name.size() <= 8 || !Name.startswith("llvm."))
38     return false;
39   Name = Name.substr(5); // Strip off "llvm."
40   
41   switch (Name[0]) {
42   default: break;
43   case 'a':
44     if (Name.startswith("atomic.cmp.swap") ||
45         Name.startswith("atomic.swap") ||
46         Name.startswith("atomic.load.add") ||
47         Name.startswith("atomic.load.sub") ||
48         Name.startswith("atomic.load.and") ||
49         Name.startswith("atomic.load.nand") ||
50         Name.startswith("atomic.load.or") ||
51         Name.startswith("atomic.load.xor") ||
52         Name.startswith("atomic.load.max") ||
53         Name.startswith("atomic.load.min") ||
54         Name.startswith("atomic.load.umax") ||
55         Name.startswith("atomic.load.umin"))
56       return true;
57     break;
58   case 'm':
59     if (Name == "memory.barrier")
60       return true;
61     break;
62   }
63
64   //  This may not belong here. This function is effectively being overloaded 
65   //  to both detect an intrinsic which needs upgrading, and to provide the 
66   //  upgraded form of the intrinsic. We should perhaps have two separate 
67   //  functions for this.
68   return false;
69 }
70
71 bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) {
72   NewFn = 0;
73   bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn);
74
75   // Upgrade intrinsic attributes.  This does not change the function.
76   if (NewFn)
77     F = NewFn;
78   if (unsigned id = F->getIntrinsicID())
79     F->setAttributes(Intrinsic::getAttributes((Intrinsic::ID)id));
80   return Upgraded;
81 }
82
83 bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
84   // Nothing to do yet.
85   return false;
86 }
87
88 // UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the 
89 // upgraded intrinsic. All argument and return casting must be provided in 
90 // order to seamlessly integrate with existing context.
91 void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
92   Function *F = CI->getCalledFunction();
93   LLVMContext &C = CI->getContext();
94   ImmutableCallSite CS(CI);
95
96   assert(F && "CallInst has no function associated with it.");
97
98   if (!NewFn) {
99     if (F->getName().startswith("llvm.atomic.cmp.swap")) {
100       IRBuilder<> Builder(C);
101       Builder.SetInsertPoint(CI->getParent(), CI);
102       Value *Val = Builder.CreateAtomicCmpXchg(CI->getArgOperand(0),
103                                                CI->getArgOperand(1),
104                                                CI->getArgOperand(2),
105                                                Monotonic);
106
107       // Replace intrinsic.
108       Val->takeName(CI);
109       if (!CI->use_empty())
110         CI->replaceAllUsesWith(Val);
111       CI->eraseFromParent();
112     } else if (F->getName().startswith("llvm.atomic")) {
113       IRBuilder<> Builder(C);
114       Builder.SetInsertPoint(CI->getParent(), CI);
115
116       AtomicRMWInst::BinOp Op;
117       if (F->getName().startswith("llvm.atomic.swap"))
118         Op = AtomicRMWInst::Xchg;
119       else if (F->getName().startswith("llvm.atomic.load.add"))
120         Op = AtomicRMWInst::Add;
121       else if (F->getName().startswith("llvm.atomic.load.sub"))
122         Op = AtomicRMWInst::Sub;
123       else if (F->getName().startswith("llvm.atomic.load.and"))
124         Op = AtomicRMWInst::And;
125       else if (F->getName().startswith("llvm.atomic.load.nand"))
126         Op = AtomicRMWInst::Nand;
127       else if (F->getName().startswith("llvm.atomic.load.or"))
128         Op = AtomicRMWInst::Or;
129       else if (F->getName().startswith("llvm.atomic.load.xor"))
130         Op = AtomicRMWInst::Xor;
131       else if (F->getName().startswith("llvm.atomic.load.max"))
132         Op = AtomicRMWInst::Max;
133       else if (F->getName().startswith("llvm.atomic.load.min"))
134         Op = AtomicRMWInst::Min;
135       else if (F->getName().startswith("llvm.atomic.load.umax"))
136         Op = AtomicRMWInst::UMax;
137       else if (F->getName().startswith("llvm.atomic.load.umin"))
138         Op = AtomicRMWInst::UMin;
139       else
140         llvm_unreachable("Unknown atomic");
141
142       Value *Val = Builder.CreateAtomicRMW(Op, CI->getArgOperand(0),
143                                            CI->getArgOperand(1),
144                                            Monotonic);
145
146       // Replace intrinsic.
147       Val->takeName(CI);
148       if (!CI->use_empty())
149         CI->replaceAllUsesWith(Val);
150       CI->eraseFromParent();
151     } else if (F->getName() == "llvm.memory.barrier") {
152       IRBuilder<> Builder(C);
153       Builder.SetInsertPoint(CI->getParent(), CI);
154
155       // Note that this conversion ignores the "device" bit; it was not really
156       // well-defined, and got abused because nobody paid enough attention to
157       // get it right. In practice, this probably doesn't matter; application
158       // code generally doesn't need anything stronger than
159       // SequentiallyConsistent (and realistically, SequentiallyConsistent
160       // is lowered to a strong enough barrier for almost anything).
161
162       if (cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue())
163         Builder.CreateFence(SequentiallyConsistent);
164       else if (!cast<ConstantInt>(CI->getArgOperand(0))->getZExtValue())
165         Builder.CreateFence(Release);
166       else if (!cast<ConstantInt>(CI->getArgOperand(3))->getZExtValue())
167         Builder.CreateFence(Acquire);
168       else
169         Builder.CreateFence(AcquireRelease);
170
171       // Remove intrinsic.
172       CI->eraseFromParent();
173     } else {
174       llvm_unreachable("Unknown function for CallInst upgrade.");
175     }
176     return;
177   }
178 }
179
180 // This tests each Function to determine if it needs upgrading. When we find 
181 // one we are interested in, we then upgrade all calls to reflect the new 
182 // function.
183 void llvm::UpgradeCallsToIntrinsic(Function* F) {
184   assert(F && "Illegal attempt to upgrade a non-existent intrinsic.");
185
186   // Upgrade the function and check if it is a totaly new function.
187   Function *NewFn;
188   if (UpgradeIntrinsicFunction(F, NewFn)) {
189     if (NewFn != F) {
190       // Replace all uses to the old function with the new one if necessary.
191       for (Value::use_iterator UI = F->use_begin(), UE = F->use_end();
192            UI != UE; ) {
193         if (CallInst *CI = dyn_cast<CallInst>(*UI++))
194           UpgradeIntrinsicCall(CI, NewFn);
195       }
196       // Remove old function, no longer used, from the module.
197       F->eraseFromParent();
198     }
199   }
200 }
201