LLVM  16.0.0git
CostModel.cpp
Go to the documentation of this file.
1 //===- CostModel.cpp ------ Cost Model Analysis ---------------------------===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the cost model analysis. It provides a very basic cost
10 // 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.
16 //
17 //===----------------------------------------------------------------------===//
18 
20 #include "llvm/Analysis/Passes.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/IR/PassManager.h"
24 #include "llvm/InitializePasses.h"
25 #include "llvm/Pass.h"
28 #include "llvm/IR/IntrinsicInst.h"
29 using namespace llvm;
30 
32  "cost-kind", cl::desc("Target cost kind"),
35  "throughput", "Reciprocal throughput"),
37  "latency", "Instruction latency"),
39  "code-size", "Code size"),
41  "size-latency", "Code size and latency")));
42 
43 static cl::opt<bool> TypeBasedIntrinsicCost("type-based-intrinsic-cost",
44  cl::desc("Calculate intrinsics cost based only on argument types"),
45  cl::init(false));
46 
47 #define CM_NAME "cost-model"
48 #define DEBUG_TYPE CM_NAME
49 
50 namespace {
51  class CostModelAnalysis : public FunctionPass {
52 
53  public:
54  static char ID; // Class identification, replacement for typeinfo
55  CostModelAnalysis() : FunctionPass(ID) {
58  }
59 
60  private:
61  void getAnalysisUsage(AnalysisUsage &AU) const override;
62  bool runOnFunction(Function &F) override;
63  void print(raw_ostream &OS, const Module*) const override;
64 
65  /// The function that we analyze.
66  Function *F = nullptr;
67  /// Target information.
68  const TargetTransformInfo *TTI = nullptr;
69  };
70 } // End of anonymous namespace
71 
72 // Register this pass.
73 char CostModelAnalysis::ID = 0;
74 static const char cm_name[] = "Cost Model Analysis";
75 INITIALIZE_PASS_BEGIN(CostModelAnalysis, CM_NAME, cm_name, false, true)
76 INITIALIZE_PASS_END (CostModelAnalysis, CM_NAME, cm_name, false, true)
77 
79  return new CostModelAnalysis();
80 }
81 
82 void
83 CostModelAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
84  AU.setPreservesAll();
85 }
86 
87 bool
89  this->F = &F;
90  auto *TTIWP = getAnalysisIfAvailable<TargetTransformInfoWrapperPass>();
91  TTI = TTIWP ? &TTIWP->getTTI(F) : nullptr;
92 
93  return false;
94 }
95 
96 void CostModelAnalysis::print(raw_ostream &OS, const Module*) const {
97  if (!F)
98  return;
99 
100  for (BasicBlock &B : *F) {
101  for (Instruction &Inst : B) {
103  if (TypeBasedIntrinsicCost && isa<IntrinsicInst>(&Inst)) {
104  auto *II = dyn_cast<IntrinsicInst>(&Inst);
105  IntrinsicCostAttributes ICA(II->getIntrinsicID(), *II,
108  }
109  else {
110  Cost = TTI->getInstructionCost(&Inst, CostKind);
111  }
112  if (auto CostVal = Cost.getValue())
113  OS << "Cost Model: Found an estimated cost of " << *CostVal;
114  else
115  OS << "Cost Model: Invalid cost";
116 
117  OS << " for instruction: " << Inst << "\n";
118  }
119  }
120 }
121 
124  auto &TTI = AM.getResult<TargetIRAnalysis>(F);
125  OS << "Printing analysis 'Cost Model Analysis' for function '" << F.getName() << "':\n";
126  for (BasicBlock &B : F) {
127  for (Instruction &Inst : B) {
128  // TODO: Use a pass parameter instead of cl::opt CostKind to determine
129  // which cost kind to print.
131  if (TypeBasedIntrinsicCost && isa<IntrinsicInst>(&Inst)) {
132  auto *II = dyn_cast<IntrinsicInst>(&Inst);
133  IntrinsicCostAttributes ICA(II->getIntrinsicID(), *II,
136  }
137  else {
139  }
140  if (auto CostVal = Cost.getValue())
141  OS << "Cost Model: Found an estimated cost of " << *CostVal;
142  else
143  OS << "Cost Model: Invalid cost";
144 
145  OS << " for instruction: " << Inst << "\n";
146  }
147  }
148  return PreservedAnalyses::all();
149 }
llvm::InstructionCost
Definition: InstructionCost.h:29
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
llvm::TargetIRAnalysis
Analysis pass providing the TargetTransformInfo.
Definition: TargetTransformInfo.h:2546
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::TargetTransformInfo::TCK_Latency
@ TCK_Latency
The latency of instruction.
Definition: TargetTransformInfo.h:217
print
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Definition: ArchiveWriter.cpp:189
TypeBasedIntrinsicCost
static cl::opt< bool > TypeBasedIntrinsicCost("type-based-intrinsic-cost", cl::desc("Calculate intrinsics cost based only on argument types"), cl::init(false))
IntrinsicInst.h
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:778
llvm::Function
Definition: Function.h:60
Pass.h
llvm::TargetTransformInfo
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Definition: TargetTransformInfo.h:172
llvm::TargetTransformInfo::getIntrinsicInstrCost
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const
Definition: TargetTransformInfo.cpp:941
llvm::TargetTransformInfo::TCK_CodeSize
@ TCK_CodeSize
Instruction code size.
Definition: TargetTransformInfo.h:218
true
basic Basic Alias true
Definition: BasicAliasAnalysis.cpp:1875
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
CommandLine.h
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:24
llvm::CostModelPrinterPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: CostModel.cpp:122
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
false
Definition: StackSlotColoring.cpp:141
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::Instruction
Definition: Instruction.h:42
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
llvm::createCostModelAnalysisPass
FunctionPass * createCostModelAnalysisPass()
Definition: CostModel.cpp:78
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::IntrinsicCostAttributes
Definition: TargetTransformInfo.h:119
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
llvm::cl::opt
Definition: CommandLine.h:1399
llvm::cl::values
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
Definition: CommandLine.h:692
cm_name
static const char cm_name[]
Definition: CostModel.cpp:74
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:439
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::TargetTransformInfo::TCK_SizeAndLatency
@ TCK_SizeAndLatency
The weighted sum of size and latency.
Definition: TargetTransformInfo.h:219
CostKind
static cl::opt< TargetTransformInfo::TargetCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(TargetTransformInfo::TCK_RecipThroughput), cl::values(clEnumValN(TargetTransformInfo::TCK_RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(TargetTransformInfo::TCK_Latency, "latency", "Instruction latency"), clEnumValN(TargetTransformInfo::TCK_CodeSize, "code-size", "Code size"), clEnumValN(TargetTransformInfo::TCK_SizeAndLatency, "size-latency", "Code size and latency")))
clEnumValN
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Definition: CommandLine.h:667
CostModel.h
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:69
llvm::InlinePriorityMode::Cost
@ Cost
llvm::AnalysisUsage::setPreservesAll
void setPreservesAll()
Set by analyses that do not transform their input at all.
Definition: PassAnalysisSupport.h:130
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:158
Function.h
PassManager.h
llvm::TargetTransformInfo::getInstructionCost
InstructionCost getInstructionCost(const Instruction *I, enum TargetCostKind kind) const
Query the cost of a specified instruction.
Definition: TargetTransformInfo.h:229
llvm::InstructionCost::getInvalid
static InstructionCost getInvalid(CostType Val=0)
Definition: InstructionCost.h:73
INITIALIZE_PASS_BEGIN
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:51
TargetTransformInfo.h
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:42
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
llvm::cl::desc
Definition: CommandLine.h:412
raw_ostream.h
llvm::initializeCostModelAnalysisPass
void initializeCostModelAnalysisPass(PassRegistry &)
CM_NAME
#define CM_NAME
Definition: CostModel.cpp:47
InitializePasses.h
llvm::TargetTransformInfo::TCK_RecipThroughput
@ TCK_RecipThroughput
Reciprocal throughput.
Definition: TargetTransformInfo.h:216
Passes.h
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38