Home | History | Annotate | Download | only in VMCore
      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