OSDN Git Service

867fa587bd950129a5df6154c54896a93e0b3849
[android-x86/external-llvm.git] / lib / Analysis / CostModel.cpp
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 }