xref: /llvm-project/llvm/lib/Analysis/CostModel.cpp (revision 236fda550d36d35a00785938c3e38b0f402aeda6)
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/TargetTransformInfo.h"
21 #include "llvm/IR/Function.h"
22 #include "llvm/IR/IntrinsicInst.h"
23 #include "llvm/IR/PassManager.h"
24 #include "llvm/Pass.h"
25 #include "llvm/Support/CommandLine.h"
26 #include "llvm/Support/raw_ostream.h"
27 using namespace llvm;
28 
29 static 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"),
38                clEnumValN(TargetTransformInfo::TCK_SizeAndLatency,
39                           "size-latency", "Code size and latency")));
40 
41 static cl::opt<bool> TypeBasedIntrinsicCost("type-based-intrinsic-cost",
42     cl::desc("Calculate intrinsics cost based only on argument types"),
43     cl::init(false));
44 
45 #define CM_NAME "cost-model"
46 #define DEBUG_TYPE CM_NAME
47 
48 PreservedAnalyses CostModelPrinterPass::run(Function &F,
49                                             FunctionAnalysisManager &AM) {
50   auto &TTI = AM.getResult<TargetIRAnalysis>(F);
51   OS << "Printing analysis 'Cost Model Analysis' for function '" << F.getName() << "':\n";
52   for (BasicBlock &B : F) {
53     for (Instruction &Inst : B) {
54       // TODO: Use a pass parameter instead of cl::opt CostKind to determine
55       // which cost kind to print.
56       InstructionCost Cost;
57       auto *II = dyn_cast<IntrinsicInst>(&Inst);
58       if (II && TypeBasedIntrinsicCost) {
59         IntrinsicCostAttributes ICA(II->getIntrinsicID(), *II,
60                                     InstructionCost::getInvalid(), true);
61         Cost = TTI.getIntrinsicInstrCost(ICA, CostKind);
62       }
63       else {
64         Cost = TTI.getInstructionCost(&Inst, CostKind);
65       }
66 
67       if (auto CostVal = Cost.getValue())
68         OS << "Cost Model: Found an estimated cost of " << *CostVal;
69       else
70         OS << "Cost Model: Invalid cost";
71 
72       OS << " for instruction: " << Inst << "\n";
73     }
74   }
75   return PreservedAnalyses::all();
76 }
77