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/Support/CallSite.h" 22 #include "llvm/Support/CFG.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include "llvm/Support/IRBuilder.h" 25 #include <cstring> 26 using namespace llvm; 27 28 29 static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { 30 assert(F && "Illegal to upgrade a non-existent Function."); 31 32 // Quickly eliminate it, if it's not a candidate. 33 StringRef Name = F->getName(); 34 if (Name.size() <= 8 || !Name.startswith("llvm.")) 35 return false; 36 Name = Name.substr(5); // Strip off "llvm." 37 38 switch (Name[0]) { 39 default: break; 40 case 'c': { 41 if (Name.startswith("ctlz.") && F->arg_size() == 1) { 42 F->setName(Name + ".old"); 43 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz, 44 F->arg_begin()->getType()); 45 return true; 46 } 47 if (Name.startswith("cttz.") && F->arg_size() == 1) { 48 F->setName(Name + ".old"); 49 NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::cttz, 50 F->arg_begin()->getType()); 51 return true; 52 } 53 break; 54 } 55 case 'x': { 56 if (Name.startswith("x86.sse2.pcmpeq.") || 57 Name.startswith("x86.sse2.pcmpgt.") || 58 Name.startswith("x86.avx2.pcmpeq.") || 59 Name.startswith("x86.avx2.pcmpgt.") || 60 Name.startswith("x86.avx.vpermil.")) { 61 NewFn = 0; 62 return true; 63 } 64 break; 65 } 66 } 67 68 // This may not belong here. This function is effectively being overloaded 69 // to both detect an intrinsic which needs upgrading, and to provide the 70 // upgraded form of the intrinsic. We should perhaps have two separate 71 // functions for this. 72 return false; 73 } 74 75 bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) { 76 NewFn = 0; 77 bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn); 78 79 // Upgrade intrinsic attributes. This does not change the function. 80 if (NewFn) 81 F = NewFn; 82 if (unsigned id = F->getIntrinsicID()) 83 F->setAttributes(Intrinsic::getAttributes((Intrinsic::ID)id)); 84 return Upgraded; 85 } 86 87 bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) { 88 // Nothing to do yet. 89 return false; 90 } 91 92 // UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the 93 // upgraded intrinsic. All argument and return casting must be provided in 94 // order to seamlessly integrate with existing context. 95 void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { 96 Function *F = CI->getCalledFunction(); 97 LLVMContext &C = CI->getContext(); 98 IRBuilder<> Builder(C); 99 Builder.SetInsertPoint(CI->getParent(), CI); 100 101 assert(F && "Intrinsic call is not direct?"); 102 103 if (!NewFn) { 104 // Get the Function's name. 105 StringRef Name = F->getName(); 106 107 Value *Rep; 108 // Upgrade packed integer vector compares intrinsics to compare instructions 109 if (Name.startswith("llvm.x86.sse2.pcmpeq.") || 110 Name.startswith("llvm.x86.avx2.pcmpeq.")) { 111 Rep = Builder.CreateICmpEQ(CI->getArgOperand(0), CI->getArgOperand(1), 112 "pcmpeq"); 113 // need to sign extend since icmp returns vector of i1 114 Rep = Builder.CreateSExt(Rep, CI->getType(), ""); 115 } else if (Name.startswith("llvm.x86.sse2.pcmpgt.") || 116 Name.startswith("llvm.x86.avx2.pcmpgt.")) { 117 Rep = Builder.CreateICmpSGT(CI->getArgOperand(0), CI->getArgOperand(1), 118 "pcmpgt"); 119 // need to sign extend since icmp returns vector of i1 120 Rep = Builder.CreateSExt(Rep, CI->getType(), ""); 121 } else { 122 bool PD128 = false, PD256 = false, PS128 = false, PS256 = false; 123 if (Name.startswith("llvm.x86.avx.vpermil.pd.256")) 124 PD256 = true; 125 else if (Name.startswith("llvm.x86.avx.vpermil.pd")) 126 PD128 = true; 127 else if (Name.startswith("llvm.x86.avx.vpermil.ps.256")) 128 PS256 = true; 129 else if (Name.startswith("llvm.x86.avx.vpermil.ps")) 130 PS128 = true; 131 132 if (PD256 || PD128 || PS256 || PS128) { 133 Value *Op0 = CI->getArgOperand(0); 134 unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue(); 135 SmallVector<Constant*, 8> Idxs; 136 137 if (PD128) 138 for (unsigned i = 0; i != 2; ++i) 139 Idxs.push_back(Builder.getInt32((Imm >> i) & 0x1)); 140 else if (PD256) 141 for (unsigned l = 0; l != 4; l+=2) 142 for (unsigned i = 0; i != 2; ++i) 143 Idxs.push_back(Builder.getInt32(((Imm >> (l+i)) & 0x1) + l)); 144 else if (PS128) 145 for (unsigned i = 0; i != 4; ++i) 146 Idxs.push_back(Builder.getInt32((Imm >> (2 * i)) & 0x3)); 147 else if (PS256) 148 for (unsigned l = 0; l != 8; l+=4) 149 for (unsigned i = 0; i != 4; ++i) 150 Idxs.push_back(Builder.getInt32(((Imm >> (2 * i)) & 0x3) + l)); 151 else 152 llvm_unreachable("Unexpected function"); 153 154 Rep = Builder.CreateShuffleVector(Op0, Op0, ConstantVector::get(Idxs)); 155 } else { 156 llvm_unreachable("Unknown function for CallInst upgrade."); 157 } 158 } 159 160 CI->replaceAllUsesWith(Rep); 161 CI->eraseFromParent(); 162 return; 163 } 164 165 switch (NewFn->getIntrinsicID()) { 166 default: 167 llvm_unreachable("Unknown function for CallInst upgrade."); 168 169 case Intrinsic::ctlz: 170 case Intrinsic::cttz: 171 assert(CI->getNumArgOperands() == 1 && 172 "Mismatch between function args and call args"); 173 StringRef Name = CI->getName(); 174 CI->setName(Name + ".old"); 175 CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, CI->getArgOperand(0), 176 Builder.getFalse(), Name)); 177 CI->eraseFromParent(); 178 return; 179 } 180 } 181 182 // This tests each Function to determine if it needs upgrading. When we find 183 // one we are interested in, we then upgrade all calls to reflect the new 184 // function. 185 void llvm::UpgradeCallsToIntrinsic(Function* F) { 186 assert(F && "Illegal attempt to upgrade a non-existent intrinsic."); 187 188 // Upgrade the function and check if it is a totaly new function. 189 Function *NewFn; 190 if (UpgradeIntrinsicFunction(F, NewFn)) { 191 if (NewFn != F) { 192 // Replace all uses to the old function with the new one if necessary. 193 for (Value::use_iterator UI = F->use_begin(), UE = F->use_end(); 194 UI != UE; ) { 195 if (CallInst *CI = dyn_cast<CallInst>(*UI++)) 196 UpgradeIntrinsicCall(CI, NewFn); 197 } 198 // Remove old function, no longer used, from the module. 199 F->eraseFromParent(); 200 } 201 } 202 } 203 204