LLVM API Documentation

AutoUpgrade.cpp
Go to the documentation of this file.
00001 //===-- AutoUpgrade.cpp - Implement auto-upgrade helper functions ---------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the auto-upgrade helper functions 
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "llvm/AutoUpgrade.h"
00015 #include "llvm/IR/Constants.h"
00016 #include "llvm/IR/Function.h"
00017 #include "llvm/IR/IRBuilder.h"
00018 #include "llvm/IR/Instruction.h"
00019 #include "llvm/IR/IntrinsicInst.h"
00020 #include "llvm/IR/LLVMContext.h"
00021 #include "llvm/IR/Module.h"
00022 #include "llvm/Support/CFG.h"
00023 #include "llvm/Support/CallSite.h"
00024 #include "llvm/Support/ErrorHandling.h"
00025 #include <cstring>
00026 using namespace llvm;
00027 
00028 // Upgrade the declarations of the SSE4.1 functions whose arguments have
00029 // changed their type from v4f32 to v2i64.
00030 static bool UpgradeSSE41Function(Function* F, Intrinsic::ID IID,
00031                                  Function *&NewFn) {
00032   // Check whether this is an old version of the function, which received
00033   // v4f32 arguments.
00034   Type *Arg0Type = F->getFunctionType()->getParamType(0);
00035   if (Arg0Type != VectorType::get(Type::getFloatTy(F->getContext()), 4))
00036     return false;
00037 
00038   // Yes, it's old, replace it with new version.
00039   F->setName(F->getName() + ".old");
00040   NewFn = Intrinsic::getDeclaration(F->getParent(), IID);
00041   return true;
00042 }
00043 
00044 static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
00045   assert(F && "Illegal to upgrade a non-existent Function.");
00046 
00047   // Quickly eliminate it, if it's not a candidate.
00048   StringRef Name = F->getName();
00049   if (Name.size() <= 8 || !Name.startswith("llvm."))
00050     return false;
00051   Name = Name.substr(5); // Strip off "llvm."
00052 
00053   switch (Name[0]) {
00054   default: break;
00055   case 'a': {
00056     if (Name.startswith("arm.neon.vclz")) {
00057       Type* args[2] = {
00058         F->arg_begin()->getType(), 
00059         Type::getInt1Ty(F->getContext())
00060       };
00061       // Can't use Intrinsic::getDeclaration here as it adds a ".i1" to
00062       // the end of the name. Change name from llvm.arm.neon.vclz.* to
00063       //  llvm.ctlz.*
00064       FunctionType* fType = FunctionType::get(F->getReturnType(), args, false);
00065       NewFn = Function::Create(fType, F->getLinkage(), 
00066                                "llvm.ctlz." + Name.substr(14), F->getParent());
00067       return true;
00068     }
00069     if (Name.startswith("arm.neon.vcnt")) {
00070       NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctpop,
00071                                         F->arg_begin()->getType());
00072       return true;
00073     }
00074     break;
00075   }
00076   case 'c': {
00077     if (Name.startswith("ctlz.") && F->arg_size() == 1) {
00078       F->setName(Name + ".old");
00079       NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz,
00080                                         F->arg_begin()->getType());
00081       return true;
00082     }
00083     if (Name.startswith("cttz.") && F->arg_size() == 1) {
00084       F->setName(Name + ".old");
00085       NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::cttz,
00086                                         F->arg_begin()->getType());
00087       return true;
00088     }
00089     break;
00090   }
00091   case 'x': {
00092     if (Name.startswith("x86.sse2.pcmpeq.") ||
00093         Name.startswith("x86.sse2.pcmpgt.") ||
00094         Name.startswith("x86.avx2.pcmpeq.") ||
00095         Name.startswith("x86.avx2.pcmpgt.") ||
00096         Name.startswith("x86.avx.vpermil.") ||
00097         Name == "x86.avx.movnt.dq.256" ||
00098         Name == "x86.avx.movnt.pd.256" ||
00099         Name == "x86.avx.movnt.ps.256" ||
00100         (Name.startswith("x86.xop.vpcom") && F->arg_size() == 2)) {
00101       NewFn = 0;
00102       return true;
00103     }
00104     // SSE4.1 ptest functions may have an old signature.
00105     if (Name.startswith("x86.sse41.ptest")) {
00106       if (Name == "x86.sse41.ptestc")
00107         return UpgradeSSE41Function(F, Intrinsic::x86_sse41_ptestc, NewFn);
00108       if (Name == "x86.sse41.ptestz")
00109         return UpgradeSSE41Function(F, Intrinsic::x86_sse41_ptestz, NewFn);
00110       if (Name == "x86.sse41.ptestnzc")
00111         return UpgradeSSE41Function(F, Intrinsic::x86_sse41_ptestnzc, NewFn);
00112     }
00113     // frcz.ss/sd may need to have an argument dropped
00114     if (Name.startswith("x86.xop.vfrcz.ss") && F->arg_size() == 2) {
00115       F->setName(Name + ".old");
00116       NewFn = Intrinsic::getDeclaration(F->getParent(),
00117                                         Intrinsic::x86_xop_vfrcz_ss);
00118       return true;
00119     }
00120     if (Name.startswith("x86.xop.vfrcz.sd") && F->arg_size() == 2) {
00121       F->setName(Name + ".old");
00122       NewFn = Intrinsic::getDeclaration(F->getParent(),
00123                                         Intrinsic::x86_xop_vfrcz_sd);
00124       return true;
00125     }
00126     // Fix the FMA4 intrinsics to remove the 4
00127     if (Name.startswith("x86.fma4.")) {
00128       F->setName("llvm.x86.fma" + Name.substr(8));
00129       NewFn = F;
00130       return true;
00131     }
00132     break;
00133   }
00134   }
00135 
00136   //  This may not belong here. This function is effectively being overloaded
00137   //  to both detect an intrinsic which needs upgrading, and to provide the
00138   //  upgraded form of the intrinsic. We should perhaps have two separate
00139   //  functions for this.
00140   return false;
00141 }
00142 
00143 bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) {
00144   NewFn = 0;
00145   bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn);
00146 
00147   // Upgrade intrinsic attributes.  This does not change the function.
00148   if (NewFn)
00149     F = NewFn;
00150   if (unsigned id = F->getIntrinsicID())
00151     F->setAttributes(Intrinsic::getAttributes(F->getContext(),
00152                                               (Intrinsic::ID)id));
00153   return Upgraded;
00154 }
00155 
00156 bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
00157   // Nothing to do yet.
00158   return false;
00159 }
00160 
00161 // UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the
00162 // upgraded intrinsic. All argument and return casting must be provided in
00163 // order to seamlessly integrate with existing context.
00164 void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
00165   Function *F = CI->getCalledFunction();
00166   LLVMContext &C = CI->getContext();
00167   IRBuilder<> Builder(C);
00168   Builder.SetInsertPoint(CI->getParent(), CI);
00169 
00170   assert(F && "Intrinsic call is not direct?");
00171 
00172   if (!NewFn) {
00173     // Get the Function's name.
00174     StringRef Name = F->getName();
00175 
00176     Value *Rep;
00177     // Upgrade packed integer vector compares intrinsics to compare instructions
00178     if (Name.startswith("llvm.x86.sse2.pcmpeq.") ||
00179         Name.startswith("llvm.x86.avx2.pcmpeq.")) {
00180       Rep = Builder.CreateICmpEQ(CI->getArgOperand(0), CI->getArgOperand(1),
00181                                  "pcmpeq");
00182       // need to sign extend since icmp returns vector of i1
00183       Rep = Builder.CreateSExt(Rep, CI->getType(), "");
00184     } else if (Name.startswith("llvm.x86.sse2.pcmpgt.") ||
00185                Name.startswith("llvm.x86.avx2.pcmpgt.")) {
00186       Rep = Builder.CreateICmpSGT(CI->getArgOperand(0), CI->getArgOperand(1),
00187                                   "pcmpgt");
00188       // need to sign extend since icmp returns vector of i1
00189       Rep = Builder.CreateSExt(Rep, CI->getType(), "");
00190     } else if (Name == "llvm.x86.avx.movnt.dq.256" ||
00191                Name == "llvm.x86.avx.movnt.ps.256" ||
00192                Name == "llvm.x86.avx.movnt.pd.256") {
00193       IRBuilder<> Builder(C);
00194       Builder.SetInsertPoint(CI->getParent(), CI);
00195 
00196       Module *M = F->getParent();
00197       SmallVector<Value *, 1> Elts;
00198       Elts.push_back(ConstantInt::get(Type::getInt32Ty(C), 1));
00199       MDNode *Node = MDNode::get(C, Elts);
00200 
00201       Value *Arg0 = CI->getArgOperand(0);
00202       Value *Arg1 = CI->getArgOperand(1);
00203 
00204       // Convert the type of the pointer to a pointer to the stored type.
00205       Value *BC = Builder.CreateBitCast(Arg0,
00206                                         PointerType::getUnqual(Arg1->getType()),
00207                                         "cast");
00208       StoreInst *SI = Builder.CreateStore(Arg1, BC);
00209       SI->setMetadata(M->getMDKindID("nontemporal"), Node);
00210       SI->setAlignment(16);
00211 
00212       // Remove intrinsic.
00213       CI->eraseFromParent();
00214       return;
00215     } else if (Name.startswith("llvm.x86.xop.vpcom")) {
00216       Intrinsic::ID intID;
00217       if (Name.endswith("ub"))
00218         intID = Intrinsic::x86_xop_vpcomub;
00219       else if (Name.endswith("uw"))
00220         intID = Intrinsic::x86_xop_vpcomuw;
00221       else if (Name.endswith("ud"))
00222         intID = Intrinsic::x86_xop_vpcomud;
00223       else if (Name.endswith("uq"))
00224         intID = Intrinsic::x86_xop_vpcomuq;
00225       else if (Name.endswith("b"))
00226         intID = Intrinsic::x86_xop_vpcomb;
00227       else if (Name.endswith("w"))
00228         intID = Intrinsic::x86_xop_vpcomw;
00229       else if (Name.endswith("d"))
00230         intID = Intrinsic::x86_xop_vpcomd;
00231       else if (Name.endswith("q"))
00232         intID = Intrinsic::x86_xop_vpcomq;
00233       else
00234         llvm_unreachable("Unknown suffix");
00235 
00236       Name = Name.substr(18); // strip off "llvm.x86.xop.vpcom"
00237       unsigned Imm;
00238       if (Name.startswith("lt"))
00239         Imm = 0;
00240       else if (Name.startswith("le"))
00241         Imm = 1;
00242       else if (Name.startswith("gt"))
00243         Imm = 2;
00244       else if (Name.startswith("ge"))
00245         Imm = 3;
00246       else if (Name.startswith("eq"))
00247         Imm = 4;
00248       else if (Name.startswith("ne"))
00249         Imm = 5;
00250       else if (Name.startswith("true"))
00251         Imm = 6;
00252       else if (Name.startswith("false"))
00253         Imm = 7;
00254       else
00255         llvm_unreachable("Unknown condition");
00256 
00257       Function *VPCOM = Intrinsic::getDeclaration(F->getParent(), intID);
00258       Rep = Builder.CreateCall3(VPCOM, CI->getArgOperand(0),
00259                                 CI->getArgOperand(1), Builder.getInt8(Imm));
00260     } else {
00261       bool PD128 = false, PD256 = false, PS128 = false, PS256 = false;
00262       if (Name == "llvm.x86.avx.vpermil.pd.256")
00263         PD256 = true;
00264       else if (Name == "llvm.x86.avx.vpermil.pd")
00265         PD128 = true;
00266       else if (Name == "llvm.x86.avx.vpermil.ps.256")
00267         PS256 = true;
00268       else if (Name == "llvm.x86.avx.vpermil.ps")
00269         PS128 = true;
00270 
00271       if (PD256 || PD128 || PS256 || PS128) {
00272         Value *Op0 = CI->getArgOperand(0);
00273         unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
00274         SmallVector<Constant*, 8> Idxs;
00275 
00276         if (PD128)
00277           for (unsigned i = 0; i != 2; ++i)
00278             Idxs.push_back(Builder.getInt32((Imm >> i) & 0x1));
00279         else if (PD256)
00280           for (unsigned l = 0; l != 4; l+=2)
00281             for (unsigned i = 0; i != 2; ++i)
00282               Idxs.push_back(Builder.getInt32(((Imm >> (l+i)) & 0x1) + l));
00283         else if (PS128)
00284           for (unsigned i = 0; i != 4; ++i)
00285             Idxs.push_back(Builder.getInt32((Imm >> (2 * i)) & 0x3));
00286         else if (PS256)
00287           for (unsigned l = 0; l != 8; l+=4)
00288             for (unsigned i = 0; i != 4; ++i)
00289               Idxs.push_back(Builder.getInt32(((Imm >> (2 * i)) & 0x3) + l));
00290         else
00291           llvm_unreachable("Unexpected function");
00292 
00293         Rep = Builder.CreateShuffleVector(Op0, Op0, ConstantVector::get(Idxs));
00294       } else {
00295         llvm_unreachable("Unknown function for CallInst upgrade.");
00296       }
00297     }
00298 
00299     CI->replaceAllUsesWith(Rep);
00300     CI->eraseFromParent();
00301     return;
00302   }
00303 
00304   std::string Name = CI->getName().str();
00305   CI->setName(Name + ".old");
00306 
00307   switch (NewFn->getIntrinsicID()) {
00308   default:
00309     llvm_unreachable("Unknown function for CallInst upgrade.");
00310 
00311   case Intrinsic::ctlz:
00312   case Intrinsic::cttz:
00313     assert(CI->getNumArgOperands() == 1 &&
00314            "Mismatch between function args and call args");
00315     CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, CI->getArgOperand(0),
00316                                                Builder.getFalse(), Name));
00317     CI->eraseFromParent();
00318     return;
00319 
00320   case Intrinsic::arm_neon_vclz: {
00321     // Change name from llvm.arm.neon.vclz.* to llvm.ctlz.*
00322     CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, CI->getArgOperand(0),
00323                                                Builder.getFalse(),
00324                                                "llvm.ctlz." + Name.substr(14)));
00325     CI->eraseFromParent();
00326     return;
00327   }
00328   case Intrinsic::ctpop: {
00329     CI->replaceAllUsesWith(Builder.CreateCall(NewFn, CI->getArgOperand(0)));
00330     CI->eraseFromParent();
00331     return;
00332   }
00333 
00334   case Intrinsic::x86_xop_vfrcz_ss:
00335   case Intrinsic::x86_xop_vfrcz_sd:
00336     CI->replaceAllUsesWith(Builder.CreateCall(NewFn, CI->getArgOperand(1),
00337                                               Name));
00338     CI->eraseFromParent();
00339     return;
00340 
00341   case Intrinsic::x86_sse41_ptestc:
00342   case Intrinsic::x86_sse41_ptestz:
00343   case Intrinsic::x86_sse41_ptestnzc: {
00344     // The arguments for these intrinsics used to be v4f32, and changed
00345     // to v2i64. This is purely a nop, since those are bitwise intrinsics.
00346     // So, the only thing required is a bitcast for both arguments.
00347     // First, check the arguments have the old type.
00348     Value *Arg0 = CI->getArgOperand(0);
00349     if (Arg0->getType() != VectorType::get(Type::getFloatTy(C), 4))
00350       return;
00351 
00352     // Old intrinsic, add bitcasts
00353     Value *Arg1 = CI->getArgOperand(1);
00354 
00355     Value *BC0 =
00356       Builder.CreateBitCast(Arg0,
00357                             VectorType::get(Type::getInt64Ty(C), 2),
00358                             "cast");
00359     Value *BC1 =
00360       Builder.CreateBitCast(Arg1,
00361                             VectorType::get(Type::getInt64Ty(C), 2),
00362                             "cast");
00363 
00364     CallInst* NewCall = Builder.CreateCall2(NewFn, BC0, BC1, Name);
00365     CI->replaceAllUsesWith(NewCall);
00366     CI->eraseFromParent();
00367     return;
00368   }
00369   }
00370 }
00371 
00372 // This tests each Function to determine if it needs upgrading. When we find 
00373 // one we are interested in, we then upgrade all calls to reflect the new 
00374 // function.
00375 void llvm::UpgradeCallsToIntrinsic(Function* F) {
00376   assert(F && "Illegal attempt to upgrade a non-existent intrinsic.");
00377 
00378   // Upgrade the function and check if it is a totaly new function.
00379   Function *NewFn;
00380   if (UpgradeIntrinsicFunction(F, NewFn)) {
00381     if (NewFn != F) {
00382       // Replace all uses to the old function with the new one if necessary.
00383       for (Value::use_iterator UI = F->use_begin(), UE = F->use_end();
00384            UI != UE; ) {
00385         if (CallInst *CI = dyn_cast<CallInst>(*UI++))
00386           UpgradeIntrinsicCall(CI, NewFn);
00387       }
00388       // Remove old function, no longer used, from the module.
00389       F->eraseFromParent();
00390     }
00391   }
00392 }
00393