LLVM API Documentation

VectorUtils.h
Go to the documentation of this file.
00001 //===- llvm/Transforms/Utils/VectorUtils.h - Vector utilities -*- C++ -*-=====//
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 defines some vectorizer utilities.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_TRANSFORMS_UTILS_VECTORUTILS_H
00015 #define LLVM_TRANSFORMS_UTILS_VECTORUTILS_H
00016 
00017 #include "llvm/IR/Intrinsics.h"
00018 #include "llvm/IR/IntrinsicInst.h"
00019 #include "llvm/Target/TargetLibraryInfo.h"
00020 
00021 namespace llvm {
00022 
00023 /// \brief Identify if the intrinsic is trivially vectorizable.
00024 ///
00025 /// This method returns true if the intrinsic's argument types are all
00026 /// scalars for the scalar form of the intrinsic and all vectors for
00027 /// the vector form of the intrinsic.
00028 static inline bool isTriviallyVectorizable(Intrinsic::ID ID) {
00029   switch (ID) {
00030   case Intrinsic::sqrt:
00031   case Intrinsic::sin:
00032   case Intrinsic::cos:
00033   case Intrinsic::exp:
00034   case Intrinsic::exp2:
00035   case Intrinsic::log:
00036   case Intrinsic::log10:
00037   case Intrinsic::log2:
00038   case Intrinsic::fabs:
00039   case Intrinsic::copysign:
00040   case Intrinsic::floor:
00041   case Intrinsic::ceil:
00042   case Intrinsic::trunc:
00043   case Intrinsic::rint:
00044   case Intrinsic::nearbyint:
00045   case Intrinsic::round:
00046   case Intrinsic::bswap:
00047   case Intrinsic::ctpop:
00048   case Intrinsic::pow:
00049   case Intrinsic::fma:
00050   case Intrinsic::fmuladd:
00051   case Intrinsic::ctlz:
00052   case Intrinsic::cttz:
00053   case Intrinsic::powi:
00054     return true;
00055   default:
00056     return false;
00057   }
00058 }
00059 
00060 static bool hasVectorInstrinsicScalarOpd(Intrinsic::ID ID,
00061                                          unsigned ScalarOpdIdx) {
00062   switch (ID) {
00063     case Intrinsic::ctlz:
00064     case Intrinsic::cttz:
00065     case Intrinsic::powi:
00066       return (ScalarOpdIdx == 1);
00067     default:
00068       return false;
00069   }
00070 }
00071 
00072 static Intrinsic::ID checkUnaryFloatSignature(const CallInst &I,
00073                                               Intrinsic::ID ValidIntrinsicID) {
00074   if (I.getNumArgOperands() != 1 ||
00075       !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
00076       I.getType() != I.getArgOperand(0)->getType() ||
00077       !I.onlyReadsMemory())
00078     return Intrinsic::not_intrinsic;
00079 
00080   return ValidIntrinsicID;
00081 }
00082 
00083 static Intrinsic::ID checkBinaryFloatSignature(const CallInst &I,
00084                                                Intrinsic::ID ValidIntrinsicID) {
00085   if (I.getNumArgOperands() != 2 ||
00086       !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
00087       !I.getArgOperand(1)->getType()->isFloatingPointTy() ||
00088       I.getType() != I.getArgOperand(0)->getType() ||
00089       I.getType() != I.getArgOperand(1)->getType() ||
00090       !I.onlyReadsMemory())
00091     return Intrinsic::not_intrinsic;
00092 
00093   return ValidIntrinsicID;
00094 }
00095 
00096 static Intrinsic::ID
00097 getIntrinsicIDForCall(CallInst *CI, const TargetLibraryInfo *TLI) {
00098   // If we have an intrinsic call, check if it is trivially vectorizable.
00099   if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) {
00100     Intrinsic::ID ID = II->getIntrinsicID();
00101     if (isTriviallyVectorizable(ID) || ID == Intrinsic::lifetime_start ||
00102         ID == Intrinsic::lifetime_end)
00103       return ID;
00104     else
00105       return Intrinsic::not_intrinsic;
00106   }
00107 
00108   if (!TLI)
00109     return Intrinsic::not_intrinsic;
00110 
00111   LibFunc::Func Func;
00112   Function *F = CI->getCalledFunction();
00113   // We're going to make assumptions on the semantics of the functions, check
00114   // that the target knows that it's available in this environment and it does
00115   // not have local linkage.
00116   if (!F || F->hasLocalLinkage() || !TLI->getLibFunc(F->getName(), Func))
00117     return Intrinsic::not_intrinsic;
00118 
00119   // Otherwise check if we have a call to a function that can be turned into a
00120   // vector intrinsic.
00121   switch (Func) {
00122   default:
00123     break;
00124   case LibFunc::sin:
00125   case LibFunc::sinf:
00126   case LibFunc::sinl:
00127     return checkUnaryFloatSignature(*CI, Intrinsic::sin);
00128   case LibFunc::cos:
00129   case LibFunc::cosf:
00130   case LibFunc::cosl:
00131     return checkUnaryFloatSignature(*CI, Intrinsic::cos);
00132   case LibFunc::exp:
00133   case LibFunc::expf:
00134   case LibFunc::expl:
00135     return checkUnaryFloatSignature(*CI, Intrinsic::exp);
00136   case LibFunc::exp2:
00137   case LibFunc::exp2f:
00138   case LibFunc::exp2l:
00139     return checkUnaryFloatSignature(*CI, Intrinsic::exp2);
00140   case LibFunc::log:
00141   case LibFunc::logf:
00142   case LibFunc::logl:
00143     return checkUnaryFloatSignature(*CI, Intrinsic::log);
00144   case LibFunc::log10:
00145   case LibFunc::log10f:
00146   case LibFunc::log10l:
00147     return checkUnaryFloatSignature(*CI, Intrinsic::log10);
00148   case LibFunc::log2:
00149   case LibFunc::log2f:
00150   case LibFunc::log2l:
00151     return checkUnaryFloatSignature(*CI, Intrinsic::log2);
00152   case LibFunc::fabs:
00153   case LibFunc::fabsf:
00154   case LibFunc::fabsl:
00155     return checkUnaryFloatSignature(*CI, Intrinsic::fabs);
00156   case LibFunc::copysign:
00157   case LibFunc::copysignf:
00158   case LibFunc::copysignl:
00159     return checkBinaryFloatSignature(*CI, Intrinsic::copysign);
00160   case LibFunc::floor:
00161   case LibFunc::floorf:
00162   case LibFunc::floorl:
00163     return checkUnaryFloatSignature(*CI, Intrinsic::floor);
00164   case LibFunc::ceil:
00165   case LibFunc::ceilf:
00166   case LibFunc::ceill:
00167     return checkUnaryFloatSignature(*CI, Intrinsic::ceil);
00168   case LibFunc::trunc:
00169   case LibFunc::truncf:
00170   case LibFunc::truncl:
00171     return checkUnaryFloatSignature(*CI, Intrinsic::trunc);
00172   case LibFunc::rint:
00173   case LibFunc::rintf:
00174   case LibFunc::rintl:
00175     return checkUnaryFloatSignature(*CI, Intrinsic::rint);
00176   case LibFunc::nearbyint:
00177   case LibFunc::nearbyintf:
00178   case LibFunc::nearbyintl:
00179     return checkUnaryFloatSignature(*CI, Intrinsic::nearbyint);
00180   case LibFunc::round:
00181   case LibFunc::roundf:
00182   case LibFunc::roundl:
00183     return checkUnaryFloatSignature(*CI, Intrinsic::round);
00184   case LibFunc::pow:
00185   case LibFunc::powf:
00186   case LibFunc::powl:
00187     return checkBinaryFloatSignature(*CI, Intrinsic::pow);
00188   }
00189 
00190   return Intrinsic::not_intrinsic;
00191 }
00192 
00193 } // llvm namespace
00194 
00195 #endif