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 | |
19 | #include "llvm/Analysis/CostModel.h" |
20 | #include "llvm/Analysis/Passes.h" |
21 | #include "llvm/Analysis/TargetTransformInfo.h" |
22 | #include "llvm/IR/Function.h" |
23 | #include "llvm/IR/PassManager.h" |
24 | #include "llvm/InitializePasses.h" |
25 | #include "llvm/Pass.h" |
26 | #include "llvm/Support/CommandLine.h" |
27 | #include "llvm/Support/raw_ostream.h" |
28 | #include "llvm/IR/IntrinsicInst.h" |
29 | using namespace llvm; |
30 | |
31 | static cl::opt<TargetTransformInfo::TargetCostKind> CostKind( |
32 | "cost-kind" , cl::desc("Target cost kind" ), |
33 | cl::init(Val: 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 | clEnumValN(TargetTransformInfo::TCK_SizeAndLatency, |
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(Val: false)); |
46 | |
47 | #define CM_NAME "cost-model" |
48 | #define DEBUG_TYPE CM_NAME |
49 | |
50 | PreservedAnalyses CostModelPrinterPass::run(Function &F, |
51 | FunctionAnalysisManager &AM) { |
52 | auto &TTI = AM.getResult<TargetIRAnalysis>(IR&: F); |
53 | OS << "Printing analysis 'Cost Model Analysis' for function '" << F.getName() << "':\n" ; |
54 | for (BasicBlock &B : F) { |
55 | for (Instruction &Inst : B) { |
56 | // TODO: Use a pass parameter instead of cl::opt CostKind to determine |
57 | // which cost kind to print. |
58 | InstructionCost Cost; |
59 | auto *II = dyn_cast<IntrinsicInst>(Val: &Inst); |
60 | if (II && TypeBasedIntrinsicCost) { |
61 | IntrinsicCostAttributes ICA(II->getIntrinsicID(), *II, |
62 | InstructionCost::getInvalid(), true); |
63 | Cost = TTI.getIntrinsicInstrCost(ICA, CostKind); |
64 | } |
65 | else { |
66 | Cost = TTI.getInstructionCost(U: &Inst, CostKind); |
67 | } |
68 | |
69 | if (auto CostVal = Cost.getValue()) |
70 | OS << "Cost Model: Found an estimated cost of " << *CostVal; |
71 | else |
72 | OS << "Cost Model: Invalid cost" ; |
73 | |
74 | OS << " for instruction: " << Inst << "\n" ; |
75 | } |
76 | } |
77 | return PreservedAnalyses::all(); |
78 | } |
79 | |