Home | History | Annotate | Download | only in Analysis
      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/Pass.h"
     25 #include "llvm/Support/CommandLine.h"
     26 #include "llvm/Support/Debug.h"
     27 #include "llvm/Support/raw_ostream.h"
     28 using namespace llvm;
     29 
     30 static cl::opt<TargetTransformInfo::TargetCostKind> CostKind(
     31     "cost-kind", cl::desc("Target cost kind"),
     32     cl::init(TargetTransformInfo::TCK_RecipThroughput),
     33     cl::values(clEnumValN(TargetTransformInfo::TCK_RecipThroughput,
     34                           "throughput", "Reciprocal throughput"),
     35                clEnumValN(TargetTransformInfo::TCK_Latency,
     36                           "latency", "Instruction latency"),
     37                clEnumValN(TargetTransformInfo::TCK_CodeSize,
     38                           "code-size", "Code size")));
     39 
     40 #define CM_NAME "cost-model"
     41 #define DEBUG_TYPE CM_NAME
     42 
     43 namespace {
     44   class CostModelAnalysis : public FunctionPass {
     45 
     46   public:
     47     static char ID; // Class identification, replacement for typeinfo
     48     CostModelAnalysis() : FunctionPass(ID), F(nullptr), TTI(nullptr) {
     49       initializeCostModelAnalysisPass(
     50         *PassRegistry::getPassRegistry());
     51     }
     52 
     53     /// Returns the expected cost of the instruction.
     54     /// Returns -1 if the cost is unknown.
     55     /// Note, this method does not cache the cost calculation and it
     56     /// can be expensive in some cases.
     57     unsigned getInstructionCost(const Instruction *I) const {
     58       return TTI->getInstructionCost(I, TargetTransformInfo::TCK_RecipThroughput);
     59     }
     60 
     61   private:
     62     void getAnalysisUsage(AnalysisUsage &AU) const override;
     63     bool runOnFunction(Function &F) override;
     64     void print(raw_ostream &OS, const Module*) const override;
     65 
     66     /// The function that we analyze.
     67     Function *F;
     68     /// Target information.
     69     const TargetTransformInfo *TTI;
     70   };
     71 }  // End of anonymous namespace
     72 
     73 // Register this pass.
     74 char CostModelAnalysis::ID = 0;
     75 static const char cm_name[] = "Cost Model Analysis";
     76 INITIALIZE_PASS_BEGIN(CostModelAnalysis, CM_NAME, cm_name, false, true)
     77 INITIALIZE_PASS_END  (CostModelAnalysis, CM_NAME, cm_name, false, true)
     78 
     79 FunctionPass *llvm::createCostModelAnalysisPass() {
     80   return new CostModelAnalysis();
     81 }
     82 
     83 void
     84 CostModelAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
     85   AU.setPreservesAll();
     86 }
     87 
     88 bool
     89 CostModelAnalysis::runOnFunction(Function &F) {
     90  this->F = &F;
     91  auto *TTIWP = getAnalysisIfAvailable<TargetTransformInfoWrapperPass>();
     92  TTI = TTIWP ? &TTIWP->getTTI(F) : nullptr;
     93 
     94  return false;
     95 }
     96 
     97 void CostModelAnalysis::print(raw_ostream &OS, const Module*) const {
     98   if (!F)
     99     return;
    100 
    101   for (BasicBlock &B : *F) {
    102     for (Instruction &Inst : B) {
    103       unsigned Cost = TTI->getInstructionCost(&Inst, CostKind);
    104       if (Cost != (unsigned)-1)
    105         OS << "Cost Model: Found an estimated cost of " << Cost;
    106       else
    107         OS << "Cost Model: Unknown cost";
    108 
    109       OS << " for instruction: " << Inst << "\n";
    110     }
    111   }
    112 }
    113