LLVM API Documentation

CostModel.cpp
Go to the documentation of this file.
00001 //===- CostModel.cpp ------ Cost Model Analysis ---------------------------===//
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 the cost model analysis. It provides a very basic cost
00011 // estimation for LLVM-IR. This analysis uses the services of the codegen
00012 // to approximate the cost of any IR instruction when lowered to machine
00013 // instructions. The cost results are unit-less and the cost number represents
00014 // the throughput of the machine assuming that all loads hit the cache, all
00015 // branches are predicted, etc. The cost numbers can be added in order to
00016 // compare two or more transformation alternatives.
00017 //
00018 //===----------------------------------------------------------------------===//
00019 
00020 #include "llvm/ADT/STLExtras.h"
00021 #include "llvm/Analysis/Passes.h"
00022 #include "llvm/Analysis/TargetTransformInfo.h"
00023 #include "llvm/IR/Function.h"
00024 #include "llvm/IR/Instructions.h"
00025 #include "llvm/IR/IntrinsicInst.h"
00026 #include "llvm/IR/Value.h"
00027 #include "llvm/Pass.h"
00028 #include "llvm/Support/CommandLine.h"
00029 #include "llvm/Support/Debug.h"
00030 #include "llvm/Support/raw_ostream.h"
00031 using namespace llvm;
00032 
00033 #define CM_NAME "cost-model"
00034 #define DEBUG_TYPE CM_NAME
00035 
00036 static cl::opt<bool> EnableReduxCost("costmodel-reduxcost", cl::init(false),
00037                                      cl::Hidden,
00038                                      cl::desc("Recognize reduction patterns."));
00039 
00040 namespace {
00041   class CostModelAnalysis : public FunctionPass {
00042 
00043   public:
00044     static char ID; // Class identification, replacement for typeinfo
00045     CostModelAnalysis() : FunctionPass(ID), F(nullptr), TTI(nullptr) {
00046       initializeCostModelAnalysisPass(
00047         *PassRegistry::getPassRegistry());
00048     }
00049 
00050     /// Returns the expected cost of the instruction.
00051     /// Returns -1 if the cost is unknown.
00052     /// Note, this method does not cache the cost calculation and it
00053     /// can be expensive in some cases.
00054     unsigned getInstructionCost(const Instruction *I) const;
00055 
00056   private:
00057     void getAnalysisUsage(AnalysisUsage &AU) const override;
00058     bool runOnFunction(Function &F) override;
00059     void print(raw_ostream &OS, const Module*) const override;
00060 
00061     /// The function that we analyze.
00062     Function *F;
00063     /// Target information.
00064     const TargetTransformInfo *TTI;
00065   };
00066 }  // End of anonymous namespace
00067 
00068 // Register this pass.
00069 char CostModelAnalysis::ID = 0;
00070 static const char cm_name[] = "Cost Model Analysis";
00071 INITIALIZE_PASS_BEGIN(CostModelAnalysis, CM_NAME, cm_name, false, true)
00072 INITIALIZE_PASS_END  (CostModelAnalysis, CM_NAME, cm_name, false, true)
00073 
00074 FunctionPass *llvm::createCostModelAnalysisPass() {
00075   return new CostModelAnalysis();
00076 }
00077 
00078 void
00079 CostModelAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
00080   AU.setPreservesAll();
00081 }
00082 
00083 bool
00084 CostModelAnalysis::runOnFunction(Function &F) {
00085  this->F = &F;
00086  TTI = getAnalysisIfAvailable<TargetTransformInfo>();
00087 
00088  return false;
00089 }
00090 
00091 static bool isReverseVectorMask(SmallVectorImpl<int> &Mask) {
00092   for (unsigned i = 0, MaskSize = Mask.size(); i < MaskSize; ++i)
00093     if (Mask[i] > 0 && Mask[i] != (int)(MaskSize - 1 - i))
00094       return false;
00095   return true;
00096 }
00097 
00098 static bool isAlternateVectorMask(SmallVectorImpl<int> &Mask) {
00099   bool isAlternate = true;
00100   unsigned MaskSize = Mask.size();
00101 
00102   // Example: shufflevector A, B, <0,5,2,7>
00103   for (unsigned i = 0; i < MaskSize && isAlternate; ++i) {
00104     if (Mask[i] < 0)
00105       continue;
00106     isAlternate = Mask[i] == (int)((i & 1) ? MaskSize + i : i);
00107   }
00108 
00109   if (isAlternate)
00110     return true;
00111 
00112   isAlternate = true;
00113   // Example: shufflevector A, B, <4,1,6,3>
00114   for (unsigned i = 0; i < MaskSize && isAlternate; ++i) {
00115     if (Mask[i] < 0)
00116       continue;
00117     isAlternate = Mask[i] == (int)((i & 1) ? i : MaskSize + i);
00118   }
00119 
00120   return isAlternate;
00121 }
00122 
00123 static TargetTransformInfo::OperandValueKind getOperandInfo(Value *V) {
00124   TargetTransformInfo::OperandValueKind OpInfo =
00125     TargetTransformInfo::OK_AnyValue;
00126 
00127   // Check for a splat of a constant or for a non uniform vector of constants.
00128   if (isa<ConstantVector>(V) || isa<ConstantDataVector>(V)) {
00129     OpInfo = TargetTransformInfo::OK_NonUniformConstantValue;
00130     if (cast<Constant>(V)->getSplatValue() != nullptr)
00131       OpInfo = TargetTransformInfo::OK_UniformConstantValue;
00132   }
00133 
00134   return OpInfo;
00135 }
00136 
00137 static bool matchPairwiseShuffleMask(ShuffleVectorInst *SI, bool IsLeft,
00138                                      unsigned Level) {
00139   // We don't need a shuffle if we just want to have element 0 in position 0 of
00140   // the vector.
00141   if (!SI && Level == 0 && IsLeft)
00142     return true;
00143   else if (!SI)
00144     return false;
00145 
00146   SmallVector<int, 32> Mask(SI->getType()->getVectorNumElements(), -1);
00147 
00148   // Build a mask of 0, 2, ... (left) or 1, 3, ... (right) depending on whether
00149   // we look at the left or right side.
00150   for (unsigned i = 0, e = (1 << Level), val = !IsLeft; i != e; ++i, val += 2)
00151     Mask[i] = val;
00152 
00153   SmallVector<int, 16> ActualMask = SI->getShuffleMask();
00154   if (Mask != ActualMask)
00155     return false;
00156 
00157   return true;
00158 }
00159 
00160 static bool matchPairwiseReductionAtLevel(const BinaryOperator *BinOp,
00161                                           unsigned Level, unsigned NumLevels) {
00162   // Match one level of pairwise operations.
00163   // %rdx.shuf.0.0 = shufflevector <4 x float> %rdx, <4 x float> undef,
00164   //       <4 x i32> <i32 0, i32 2 , i32 undef, i32 undef>
00165   // %rdx.shuf.0.1 = shufflevector <4 x float> %rdx, <4 x float> undef,
00166   //       <4 x i32> <i32 1, i32 3, i32 undef, i32 undef>
00167   // %bin.rdx.0 = fadd <4 x float> %rdx.shuf.0.0, %rdx.shuf.0.1
00168   if (BinOp == nullptr)
00169     return false;
00170 
00171   assert(BinOp->getType()->isVectorTy() && "Expecting a vector type");
00172 
00173   unsigned Opcode = BinOp->getOpcode();
00174   Value *L = BinOp->getOperand(0);
00175   Value *R = BinOp->getOperand(1);
00176 
00177   ShuffleVectorInst *LS = dyn_cast<ShuffleVectorInst>(L);
00178   if (!LS && Level)
00179     return false;
00180   ShuffleVectorInst *RS = dyn_cast<ShuffleVectorInst>(R);
00181   if (!RS && Level)
00182     return false;
00183 
00184   // On level 0 we can omit one shufflevector instruction.
00185   if (!Level && !RS && !LS)
00186     return false;
00187 
00188   // Shuffle inputs must match.
00189   Value *NextLevelOpL = LS ? LS->getOperand(0) : nullptr;
00190   Value *NextLevelOpR = RS ? RS->getOperand(0) : nullptr;
00191   Value *NextLevelOp = nullptr;
00192   if (NextLevelOpR && NextLevelOpL) {
00193     // If we have two shuffles their operands must match.
00194     if (NextLevelOpL != NextLevelOpR)
00195       return false;
00196 
00197     NextLevelOp = NextLevelOpL;
00198   } else if (Level == 0 && (NextLevelOpR || NextLevelOpL)) {
00199     // On the first level we can omit the shufflevector <0, undef,...>. So the
00200     // input to the other shufflevector <1, undef> must match with one of the
00201     // inputs to the current binary operation.
00202     // Example:
00203     //  %NextLevelOpL = shufflevector %R, <1, undef ...>
00204     //  %BinOp        = fadd          %NextLevelOpL, %R
00205     if (NextLevelOpL && NextLevelOpL != R)
00206       return false;
00207     else if (NextLevelOpR && NextLevelOpR != L)
00208       return false;
00209 
00210     NextLevelOp = NextLevelOpL ? R : L;
00211   } else
00212     return false;
00213 
00214   // Check that the next levels binary operation exists and matches with the
00215   // current one.
00216   BinaryOperator *NextLevelBinOp = nullptr;
00217   if (Level + 1 != NumLevels) {
00218     if (!(NextLevelBinOp = dyn_cast<BinaryOperator>(NextLevelOp)))
00219       return false;
00220     else if (NextLevelBinOp->getOpcode() != Opcode)
00221       return false;
00222   }
00223 
00224   // Shuffle mask for pairwise operation must match.
00225   if (matchPairwiseShuffleMask(LS, true, Level)) {
00226     if (!matchPairwiseShuffleMask(RS, false, Level))
00227       return false;
00228   } else if (matchPairwiseShuffleMask(RS, true, Level)) {
00229     if (!matchPairwiseShuffleMask(LS, false, Level))
00230       return false;
00231   } else
00232     return false;
00233 
00234   if (++Level == NumLevels)
00235     return true;
00236 
00237   // Match next level.
00238   return matchPairwiseReductionAtLevel(NextLevelBinOp, Level, NumLevels);
00239 }
00240 
00241 static bool matchPairwiseReduction(const ExtractElementInst *ReduxRoot,
00242                                    unsigned &Opcode, Type *&Ty) {
00243   if (!EnableReduxCost)
00244     return false;
00245 
00246   // Need to extract the first element.
00247   ConstantInt *CI = dyn_cast<ConstantInt>(ReduxRoot->getOperand(1));
00248   unsigned Idx = ~0u;
00249   if (CI)
00250     Idx = CI->getZExtValue();
00251   if (Idx != 0)
00252     return false;
00253 
00254   BinaryOperator *RdxStart = dyn_cast<BinaryOperator>(ReduxRoot->getOperand(0));
00255   if (!RdxStart)
00256     return false;
00257 
00258   Type *VecTy = ReduxRoot->getOperand(0)->getType();
00259   unsigned NumVecElems = VecTy->getVectorNumElements();
00260   if (!isPowerOf2_32(NumVecElems))
00261     return false;
00262 
00263   // We look for a sequence of shuffle,shuffle,add triples like the following
00264   // that builds a pairwise reduction tree.
00265   //
00266   //  (X0, X1, X2, X3)
00267   //   (X0 + X1, X2 + X3, undef, undef)
00268   //    ((X0 + X1) + (X2 + X3), undef, undef, undef)
00269   //
00270   // %rdx.shuf.0.0 = shufflevector <4 x float> %rdx, <4 x float> undef,
00271   //       <4 x i32> <i32 0, i32 2 , i32 undef, i32 undef>
00272   // %rdx.shuf.0.1 = shufflevector <4 x float> %rdx, <4 x float> undef,
00273   //       <4 x i32> <i32 1, i32 3, i32 undef, i32 undef>
00274   // %bin.rdx.0 = fadd <4 x float> %rdx.shuf.0.0, %rdx.shuf.0.1
00275   // %rdx.shuf.1.0 = shufflevector <4 x float> %bin.rdx.0, <4 x float> undef,
00276   //       <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
00277   // %rdx.shuf.1.1 = shufflevector <4 x float> %bin.rdx.0, <4 x float> undef,
00278   //       <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
00279   // %bin.rdx8 = fadd <4 x float> %rdx.shuf.1.0, %rdx.shuf.1.1
00280   // %r = extractelement <4 x float> %bin.rdx8, i32 0
00281   if (!matchPairwiseReductionAtLevel(RdxStart, 0,  Log2_32(NumVecElems)))
00282     return false;
00283 
00284   Opcode = RdxStart->getOpcode();
00285   Ty = VecTy;
00286 
00287   return true;
00288 }
00289 
00290 static std::pair<Value *, ShuffleVectorInst *>
00291 getShuffleAndOtherOprd(BinaryOperator *B) {
00292 
00293   Value *L = B->getOperand(0);
00294   Value *R = B->getOperand(1);
00295   ShuffleVectorInst *S = nullptr;
00296 
00297   if ((S = dyn_cast<ShuffleVectorInst>(L)))
00298     return std::make_pair(R, S);
00299 
00300   S = dyn_cast<ShuffleVectorInst>(R);
00301   return std::make_pair(L, S);
00302 }
00303 
00304 static bool matchVectorSplittingReduction(const ExtractElementInst *ReduxRoot,
00305                                           unsigned &Opcode, Type *&Ty) {
00306   if (!EnableReduxCost)
00307     return false;
00308 
00309   // Need to extract the first element.
00310   ConstantInt *CI = dyn_cast<ConstantInt>(ReduxRoot->getOperand(1));
00311   unsigned Idx = ~0u;
00312   if (CI)
00313     Idx = CI->getZExtValue();
00314   if (Idx != 0)
00315     return false;
00316 
00317   BinaryOperator *RdxStart = dyn_cast<BinaryOperator>(ReduxRoot->getOperand(0));
00318   if (!RdxStart)
00319     return false;
00320   unsigned RdxOpcode = RdxStart->getOpcode();
00321 
00322   Type *VecTy = ReduxRoot->getOperand(0)->getType();
00323   unsigned NumVecElems = VecTy->getVectorNumElements();
00324   if (!isPowerOf2_32(NumVecElems))
00325     return false;
00326 
00327   // We look for a sequence of shuffles and adds like the following matching one
00328   // fadd, shuffle vector pair at a time.
00329   //
00330   // %rdx.shuf = shufflevector <4 x float> %rdx, <4 x float> undef,
00331   //                           <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
00332   // %bin.rdx = fadd <4 x float> %rdx, %rdx.shuf
00333   // %rdx.shuf7 = shufflevector <4 x float> %bin.rdx, <4 x float> undef,
00334   //                          <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
00335   // %bin.rdx8 = fadd <4 x float> %bin.rdx, %rdx.shuf7
00336   // %r = extractelement <4 x float> %bin.rdx8, i32 0
00337 
00338   unsigned MaskStart = 1;
00339   Value *RdxOp = RdxStart;
00340   SmallVector<int, 32> ShuffleMask(NumVecElems, 0);
00341   unsigned NumVecElemsRemain = NumVecElems;
00342   while (NumVecElemsRemain - 1) {
00343     // Check for the right reduction operation.
00344     BinaryOperator *BinOp;
00345     if (!(BinOp = dyn_cast<BinaryOperator>(RdxOp)))
00346       return false;
00347     if (BinOp->getOpcode() != RdxOpcode)
00348       return false;
00349 
00350     Value *NextRdxOp;
00351     ShuffleVectorInst *Shuffle;
00352     std::tie(NextRdxOp, Shuffle) = getShuffleAndOtherOprd(BinOp);
00353 
00354     // Check the current reduction operation and the shuffle use the same value.
00355     if (Shuffle == nullptr)
00356       return false;
00357     if (Shuffle->getOperand(0) != NextRdxOp)
00358       return false;
00359 
00360     // Check that shuffle masks matches.
00361     for (unsigned j = 0; j != MaskStart; ++j)
00362       ShuffleMask[j] = MaskStart + j;
00363     // Fill the rest of the mask with -1 for undef.
00364     std::fill(&ShuffleMask[MaskStart], ShuffleMask.end(), -1);
00365 
00366     SmallVector<int, 16> Mask = Shuffle->getShuffleMask();
00367     if (ShuffleMask != Mask)
00368       return false;
00369 
00370     RdxOp = NextRdxOp;
00371     NumVecElemsRemain /= 2;
00372     MaskStart *= 2;
00373   }
00374 
00375   Opcode = RdxOpcode;
00376   Ty = VecTy;
00377   return true;
00378 }
00379 
00380 unsigned CostModelAnalysis::getInstructionCost(const Instruction *I) const {
00381   if (!TTI)
00382     return -1;
00383 
00384   switch (I->getOpcode()) {
00385   case Instruction::GetElementPtr:{
00386     Type *ValTy = I->getOperand(0)->getType()->getPointerElementType();
00387     return TTI->getAddressComputationCost(ValTy);
00388   }
00389 
00390   case Instruction::Ret:
00391   case Instruction::PHI:
00392   case Instruction::Br: {
00393     return TTI->getCFInstrCost(I->getOpcode());
00394   }
00395   case Instruction::Add:
00396   case Instruction::FAdd:
00397   case Instruction::Sub:
00398   case Instruction::FSub:
00399   case Instruction::Mul:
00400   case Instruction::FMul:
00401   case Instruction::UDiv:
00402   case Instruction::SDiv:
00403   case Instruction::FDiv:
00404   case Instruction::URem:
00405   case Instruction::SRem:
00406   case Instruction::FRem:
00407   case Instruction::Shl:
00408   case Instruction::LShr:
00409   case Instruction::AShr:
00410   case Instruction::And:
00411   case Instruction::Or:
00412   case Instruction::Xor: {
00413     TargetTransformInfo::OperandValueKind Op1VK =
00414       getOperandInfo(I->getOperand(0));
00415     TargetTransformInfo::OperandValueKind Op2VK =
00416       getOperandInfo(I->getOperand(1));
00417     return TTI->getArithmeticInstrCost(I->getOpcode(), I->getType(), Op1VK,
00418                                        Op2VK);
00419   }
00420   case Instruction::Select: {
00421     const SelectInst *SI = cast<SelectInst>(I);
00422     Type *CondTy = SI->getCondition()->getType();
00423     return TTI->getCmpSelInstrCost(I->getOpcode(), I->getType(), CondTy);
00424   }
00425   case Instruction::ICmp:
00426   case Instruction::FCmp: {
00427     Type *ValTy = I->getOperand(0)->getType();
00428     return TTI->getCmpSelInstrCost(I->getOpcode(), ValTy);
00429   }
00430   case Instruction::Store: {
00431     const StoreInst *SI = cast<StoreInst>(I);
00432     Type *ValTy = SI->getValueOperand()->getType();
00433     return TTI->getMemoryOpCost(I->getOpcode(), ValTy,
00434                                  SI->getAlignment(),
00435                                  SI->getPointerAddressSpace());
00436   }
00437   case Instruction::Load: {
00438     const LoadInst *LI = cast<LoadInst>(I);
00439     return TTI->getMemoryOpCost(I->getOpcode(), I->getType(),
00440                                  LI->getAlignment(),
00441                                  LI->getPointerAddressSpace());
00442   }
00443   case Instruction::ZExt:
00444   case Instruction::SExt:
00445   case Instruction::FPToUI:
00446   case Instruction::FPToSI:
00447   case Instruction::FPExt:
00448   case Instruction::PtrToInt:
00449   case Instruction::IntToPtr:
00450   case Instruction::SIToFP:
00451   case Instruction::UIToFP:
00452   case Instruction::Trunc:
00453   case Instruction::FPTrunc:
00454   case Instruction::BitCast:
00455   case Instruction::AddrSpaceCast: {
00456     Type *SrcTy = I->getOperand(0)->getType();
00457     return TTI->getCastInstrCost(I->getOpcode(), I->getType(), SrcTy);
00458   }
00459   case Instruction::ExtractElement: {
00460     const ExtractElementInst * EEI = cast<ExtractElementInst>(I);
00461     ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1));
00462     unsigned Idx = -1;
00463     if (CI)
00464       Idx = CI->getZExtValue();
00465 
00466     // Try to match a reduction sequence (series of shufflevector and vector
00467     // adds followed by a extractelement).
00468     unsigned ReduxOpCode;
00469     Type *ReduxType;
00470 
00471     if (matchVectorSplittingReduction(EEI, ReduxOpCode, ReduxType))
00472       return TTI->getReductionCost(ReduxOpCode, ReduxType, false);
00473     else if (matchPairwiseReduction(EEI, ReduxOpCode, ReduxType))
00474       return TTI->getReductionCost(ReduxOpCode, ReduxType, true);
00475 
00476     return TTI->getVectorInstrCost(I->getOpcode(),
00477                                    EEI->getOperand(0)->getType(), Idx);
00478   }
00479   case Instruction::InsertElement: {
00480     const InsertElementInst * IE = cast<InsertElementInst>(I);
00481     ConstantInt *CI = dyn_cast<ConstantInt>(IE->getOperand(2));
00482     unsigned Idx = -1;
00483     if (CI)
00484       Idx = CI->getZExtValue();
00485     return TTI->getVectorInstrCost(I->getOpcode(),
00486                                    IE->getType(), Idx);
00487   }
00488   case Instruction::ShuffleVector: {
00489     const ShuffleVectorInst *Shuffle = cast<ShuffleVectorInst>(I);
00490     Type *VecTypOp0 = Shuffle->getOperand(0)->getType();
00491     unsigned NumVecElems = VecTypOp0->getVectorNumElements();
00492     SmallVector<int, 16> Mask = Shuffle->getShuffleMask();
00493 
00494     if (NumVecElems == Mask.size()) {
00495       if (isReverseVectorMask(Mask))
00496         return TTI->getShuffleCost(TargetTransformInfo::SK_Reverse, VecTypOp0,
00497                                    0, nullptr);
00498       if (isAlternateVectorMask(Mask))
00499         return TTI->getShuffleCost(TargetTransformInfo::SK_Alternate,
00500                                    VecTypOp0, 0, nullptr);
00501     }
00502 
00503     return -1;
00504   }
00505   case Instruction::Call:
00506     if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
00507       SmallVector<Type*, 4> Tys;
00508       for (unsigned J = 0, JE = II->getNumArgOperands(); J != JE; ++J)
00509         Tys.push_back(II->getArgOperand(J)->getType());
00510 
00511       return TTI->getIntrinsicInstrCost(II->getIntrinsicID(), II->getType(),
00512                                         Tys);
00513     }
00514     return -1;
00515   default:
00516     // We don't have any information on this instruction.
00517     return -1;
00518   }
00519 }
00520 
00521 void CostModelAnalysis::print(raw_ostream &OS, const Module*) const {
00522   if (!F)
00523     return;
00524 
00525   for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
00526     for (BasicBlock::iterator it = B->begin(), e = B->end(); it != e; ++it) {
00527       Instruction *Inst = it;
00528       unsigned Cost = getInstructionCost(Inst);
00529       if (Cost != (unsigned)-1)
00530         OS << "Cost Model: Found an estimated cost of " << Cost;
00531       else
00532         OS << "Cost Model: Unknown cost";
00533 
00534       OS << " for instruction: "<< *Inst << "\n";
00535     }
00536   }
00537 }