1 //===- CostModel.cpp ------ Cost Model Analysis ---------------------------===// 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 defines the cost model analysis. It provides a very basic cost 11 // estimation for LLVM-IR. This analysis uses the services of the codegen 12 // to approximate the cost of any IR instruction when lowered to machine 13 // instructions. The cost results are unit-less and the cost number represents 14 // the throughput of the machine assuming that all loads hit the cache, all 15 // branches are predicted, etc. The cost numbers can be added in order to 16 // compare two or more transformation alternatives. 17 // 18 //===----------------------------------------------------------------------===// 19 20 #include "llvm/ADT/STLExtras.h" 21 #include "llvm/Analysis/Passes.h" 22 #include "llvm/Analysis/TargetTransformInfo.h" 23 #include "llvm/IR/Function.h" 24 #include "llvm/IR/Instructions.h" 25 #include "llvm/Pass.h" 26 #include "llvm/Support/CommandLine.h" 27 #include "llvm/Support/Debug.h" 28 #include "llvm/Support/raw_ostream.h" 29 using namespace llvm; 30 31 static cl::opt<TargetTransformInfo::TargetCostKind> CostKind( 32 "cost-kind", cl::desc("Target cost kind"), 33 cl::init(TargetTransformInfo::TCK_RecipThroughput), 34 cl::values(clEnumValN(TargetTransformInfo::TCK_RecipThroughput, 35 "throughput", "Reciprocal throughput"), 36 clEnumValN(TargetTransformInfo::TCK_Latency, 37 "latency", "Instruction latency"), 38 clEnumValN(TargetTransformInfo::TCK_CodeSize, 39 "code-size", "Code size"))); 40 41 #define CM_NAME "cost-model" 42 #define DEBUG_TYPE CM_NAME 43 44 namespace { 45 class CostModelAnalysis : public FunctionPass { 46 47 public: 48 static char ID; // Class identification, replacement for typeinfo 49 CostModelAnalysis() : FunctionPass(ID), F(nullptr), TTI(nullptr) { 50 initializeCostModelAnalysisPass( 51 *PassRegistry::getPassRegistry()); 52 } 53 54 /// Returns the expected cost of the instruction. 55 /// Returns -1 if the cost is unknown. 56 /// Note, this method does not cache the cost calculation and it 57 /// can be expensive in some cases. 58 unsigned getInstructionCost(const Instruction *I) const { 59 return TTI->getInstructionCost(I, TargetTransformInfo::TCK_RecipThroughput); 60 } 61 62 private: 63 void getAnalysisUsage(AnalysisUsage &AU) const override; 64 bool runOnFunction(Function &F) override; 65 void print(raw_ostream &OS, const Module*) const override; 66 67 /// The function that we analyze. 68 Function *F; 69 /// Target information. 70 const TargetTransformInfo *TTI; 71 }; 72 } // End of anonymous namespace 73 74 // Register this pass. 75 char CostModelAnalysis::ID = 0; 76 static const char cm_name[] = "Cost Model Analysis"; 77 INITIALIZE_PASS_BEGIN(CostModelAnalysis, CM_NAME, cm_name, false, true) 78 INITIALIZE_PASS_END (CostModelAnalysis, CM_NAME, cm_name, false, true) 79 80 FunctionPass *llvm::createCostModelAnalysisPass() { 81 return new CostModelAnalysis(); 82 } 83 84 void 85 CostModelAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { 86 AU.setPreservesAll(); 87 } 88 89 bool 90 CostModelAnalysis::runOnFunction(Function &F) { 91 this->F = &F; 92 auto *TTIWP = getAnalysisIfAvailable<TargetTransformInfoWrapperPass>(); 93 TTI = TTIWP ? &TTIWP->getTTI(F) : nullptr; 94 95 return false; 96 } 97 98 void CostModelAnalysis::print(raw_ostream &OS, const Module*) const { 99 if (!F) 100 return; 101 102 for (BasicBlock &B : *F) { 103 for (Instruction &Inst : B) { 104 unsigned Cost = TTI->getInstructionCost(&Inst, CostKind); 105 if (Cost != (unsigned)-1) 106 OS << "Cost Model: Found an estimated cost of " << Cost; 107 else 108 OS << "Cost Model: Unknown cost"; 109 110 OS << " for instruction: " << Inst << "\n"; 111 } 112 } 113 } 114