Line data Source code
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 405 : CostModelAnalysis() : FunctionPass(ID), F(nullptr), TTI(nullptr) {
49 405 : initializeCostModelAnalysisPass(
50 405 : *PassRegistry::getPassRegistry());
51 405 : }
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 10756 : INITIALIZE_PASS_BEGIN(CostModelAnalysis, CM_NAME, cm_name, false, true)
77 21917 : INITIALIZE_PASS_END (CostModelAnalysis, CM_NAME, cm_name, false, true)
78 :
79 0 : FunctionPass *llvm::createCostModelAnalysisPass() {
80 0 : return new CostModelAnalysis();
81 : }
82 :
83 : void
84 405 : CostModelAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
85 : AU.setPreservesAll();
86 405 : }
87 :
88 : bool
89 6773 : CostModelAnalysis::runOnFunction(Function &F) {
90 6773 : this->F = &F;
91 6773 : auto *TTIWP = getAnalysisIfAvailable<TargetTransformInfoWrapperPass>();
92 6773 : TTI = TTIWP ? &TTIWP->getTTI(F) : nullptr;
93 :
94 6773 : return false;
95 : }
96 :
97 6773 : void CostModelAnalysis::print(raw_ostream &OS, const Module*) const {
98 6773 : if (!F)
99 : return;
100 :
101 13571 : for (BasicBlock &B : *F) {
102 34568 : for (Instruction &Inst : B) {
103 55540 : unsigned Cost = TTI->getInstructionCost(&Inst, CostKind);
104 27770 : if (Cost != (unsigned)-1)
105 27769 : OS << "Cost Model: Found an estimated cost of " << Cost;
106 : else
107 1 : OS << "Cost Model: Unknown cost";
108 :
109 27770 : OS << " for instruction: " << Inst << "\n";
110 : }
111 : }
112 : }
|