LLVM API Documentation
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