blob: bf0cdbfd0c8b5a545fbfbb34c0eab303512bd0ee [file] [log] [blame]
Nadav Rotema6b91ac2012-11-02 21:48:17 +00001//===- CostModel.cpp ------ Cost Model Analysis ---------------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Nadav Rotema6b91ac2012-11-02 21:48:17 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the cost model analysis. It provides a very basic cost
Nadav Rotem99868e42012-12-24 05:51:12 +000010// estimation for LLVM-IR. This analysis uses the services of the codegen
11// to approximate the cost of any IR instruction when lowered to machine
12// instructions. The cost results are unit-less and the cost number represents
13// the throughput of the machine assuming that all loads hit the cache, all
14// branches are predicted, etc. The cost numbers can be added in order to
15// compare two or more transformation alternatives.
Nadav Rotema6b91ac2012-11-02 21:48:17 +000016//
17//===----------------------------------------------------------------------===//
18
Arnold Schwaighofercae87352013-09-17 18:06:50 +000019#include "llvm/ADT/STLExtras.h"
Nadav Rotema6b91ac2012-11-02 21:48:17 +000020#include "llvm/Analysis/Passes.h"
Chandler Carruthd3e73552013-01-07 03:08:10 +000021#include "llvm/Analysis/TargetTransformInfo.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000022#include "llvm/IR/Function.h"
Nadav Rotema6b91ac2012-11-02 21:48:17 +000023#include "llvm/Pass.h"
Arnold Schwaighofercae87352013-09-17 18:06:50 +000024#include "llvm/Support/CommandLine.h"
Nadav Rotema6b91ac2012-11-02 21:48:17 +000025#include "llvm/Support/Debug.h"
26#include "llvm/Support/raw_ostream.h"
27using namespace llvm;
Guozhi Wei62d64142017-09-08 22:29:17 +000028
29static cl::opt<TargetTransformInfo::TargetCostKind> CostKind(
30 "cost-kind", cl::desc("Target cost kind"),
31 cl::init(TargetTransformInfo::TCK_RecipThroughput),
32 cl::values(clEnumValN(TargetTransformInfo::TCK_RecipThroughput,
33 "throughput", "Reciprocal throughput"),
34 clEnumValN(TargetTransformInfo::TCK_Latency,
35 "latency", "Instruction latency"),
36 clEnumValN(TargetTransformInfo::TCK_CodeSize,
37 "code-size", "Code size")));
Nadav Rotema6b91ac2012-11-02 21:48:17 +000038
Chandler Carruthf1221bd2014-04-22 02:48:03 +000039#define CM_NAME "cost-model"
40#define DEBUG_TYPE CM_NAME
41
Nadav Rotema6b91ac2012-11-02 21:48:17 +000042namespace {
43 class CostModelAnalysis : public FunctionPass {
44
45 public:
46 static char ID; // Class identification, replacement for typeinfo
Craig Topper9f008862014-04-15 04:59:12 +000047 CostModelAnalysis() : FunctionPass(ID), F(nullptr), TTI(nullptr) {
Nadav Rotema6b91ac2012-11-02 21:48:17 +000048 initializeCostModelAnalysisPass(
49 *PassRegistry::getPassRegistry());
50 }
51
52 /// Returns the expected cost of the instruction.
53 /// Returns -1 if the cost is unknown.
54 /// Note, this method does not cache the cost calculation and it
55 /// can be expensive in some cases.
Guozhi Wei62d64142017-09-08 22:29:17 +000056 unsigned getInstructionCost(const Instruction *I) const {
57 return TTI->getInstructionCost(I, TargetTransformInfo::TCK_RecipThroughput);
58 }
Nadav Rotema6b91ac2012-11-02 21:48:17 +000059
60 private:
Craig Toppere9ba7592014-03-05 07:30:04 +000061 void getAnalysisUsage(AnalysisUsage &AU) const override;
62 bool runOnFunction(Function &F) override;
63 void print(raw_ostream &OS, const Module*) const override;
Nadav Rotema6b91ac2012-11-02 21:48:17 +000064
65 /// The function that we analyze.
66 Function *F;
Chandler Carruthcf569a82013-01-05 10:09:33 +000067 /// Target information.
68 const TargetTransformInfo *TTI;
Nadav Rotema6b91ac2012-11-02 21:48:17 +000069 };
70} // End of anonymous namespace
71
72// Register this pass.
73char CostModelAnalysis::ID = 0;
74static const char cm_name[] = "Cost Model Analysis";
75INITIALIZE_PASS_BEGIN(CostModelAnalysis, CM_NAME, cm_name, false, true)
76INITIALIZE_PASS_END (CostModelAnalysis, CM_NAME, cm_name, false, true)
77
78FunctionPass *llvm::createCostModelAnalysisPass() {
79 return new CostModelAnalysis();
80}
81
82void
83CostModelAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
84 AU.setPreservesAll();
85}
86
87bool
88CostModelAnalysis::runOnFunction(Function &F) {
89 this->F = &F;
Chandler Carruth705b1852015-01-31 03:43:40 +000090 auto *TTIWP = getAnalysisIfAvailable<TargetTransformInfoWrapperPass>();
Chandler Carruthfdb9c572015-02-01 12:01:35 +000091 TTI = TTIWP ? &TTIWP->getTTI(F) : nullptr;
Nadav Rotema6b91ac2012-11-02 21:48:17 +000092
93 return false;
94}
95
Nadav Rotema6b91ac2012-11-02 21:48:17 +000096void CostModelAnalysis::print(raw_ostream &OS, const Module*) const {
97 if (!F)
98 return;
99
Benjamin Krameraa209152016-06-26 17:27:42 +0000100 for (BasicBlock &B : *F) {
101 for (Instruction &Inst : B) {
Guozhi Wei62d64142017-09-08 22:29:17 +0000102 unsigned Cost = TTI->getInstructionCost(&Inst, CostKind);
Nadav Rotema6b91ac2012-11-02 21:48:17 +0000103 if (Cost != (unsigned)-1)
104 OS << "Cost Model: Found an estimated cost of " << Cost;
105 else
106 OS << "Cost Model: Unknown cost";
107
Benjamin Krameraa209152016-06-26 17:27:42 +0000108 OS << " for instruction: " << Inst << "\n";
Nadav Rotema6b91ac2012-11-02 21:48:17 +0000109 }
110 }
111}