10b57cec5SDimitry Andric //===- CostModel.cpp ------ Cost Model Analysis ---------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines the cost model analysis. It provides a very basic cost 100b57cec5SDimitry Andric // estimation for LLVM-IR. This analysis uses the services of the codegen 110b57cec5SDimitry Andric // to approximate the cost of any IR instruction when lowered to machine 120b57cec5SDimitry Andric // instructions. The cost results are unit-less and the cost number represents 130b57cec5SDimitry Andric // the throughput of the machine assuming that all loads hit the cache, all 140b57cec5SDimitry Andric // branches are predicted, etc. The cost numbers can be added in order to 150b57cec5SDimitry Andric // compare two or more transformation alternatives. 160b57cec5SDimitry Andric // 170b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 180b57cec5SDimitry Andric 19349cc55cSDimitry Andric #include "llvm/Analysis/CostModel.h" 200b57cec5SDimitry Andric #include "llvm/Analysis/Passes.h" 210b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h" 220b57cec5SDimitry Andric #include "llvm/IR/Function.h" 23349cc55cSDimitry Andric #include "llvm/IR/PassManager.h" 24480093f4SDimitry Andric #include "llvm/InitializePasses.h" 250b57cec5SDimitry Andric #include "llvm/Pass.h" 260b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 270b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 28fcaf7f86SDimitry Andric #include "llvm/IR/IntrinsicInst.h" 290b57cec5SDimitry Andric using namespace llvm; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric static cl::opt<TargetTransformInfo::TargetCostKind> CostKind( 320b57cec5SDimitry Andric "cost-kind", cl::desc("Target cost kind"), 330b57cec5SDimitry Andric cl::init(TargetTransformInfo::TCK_RecipThroughput), 340b57cec5SDimitry Andric cl::values(clEnumValN(TargetTransformInfo::TCK_RecipThroughput, 350b57cec5SDimitry Andric "throughput", "Reciprocal throughput"), 360b57cec5SDimitry Andric clEnumValN(TargetTransformInfo::TCK_Latency, 370b57cec5SDimitry Andric "latency", "Instruction latency"), 380b57cec5SDimitry Andric clEnumValN(TargetTransformInfo::TCK_CodeSize, 39e8d8bef9SDimitry Andric "code-size", "Code size"), 40e8d8bef9SDimitry Andric clEnumValN(TargetTransformInfo::TCK_SizeAndLatency, 41e8d8bef9SDimitry Andric "size-latency", "Code size and latency"))); 42e8d8bef9SDimitry Andric 43fcaf7f86SDimitry Andric static cl::opt<bool> TypeBasedIntrinsicCost("type-based-intrinsic-cost", 44fcaf7f86SDimitry Andric cl::desc("Calculate intrinsics cost based only on argument types"), 45fcaf7f86SDimitry Andric cl::init(false)); 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric #define CM_NAME "cost-model" 480b57cec5SDimitry Andric #define DEBUG_TYPE CM_NAME 490b57cec5SDimitry Andric 50349cc55cSDimitry Andric PreservedAnalyses CostModelPrinterPass::run(Function &F, 51349cc55cSDimitry Andric FunctionAnalysisManager &AM) { 52349cc55cSDimitry Andric auto &TTI = AM.getResult<TargetIRAnalysis>(F); 5381ad6265SDimitry Andric OS << "Printing analysis 'Cost Model Analysis' for function '" << F.getName() << "':\n"; 54349cc55cSDimitry Andric for (BasicBlock &B : F) { 55349cc55cSDimitry Andric for (Instruction &Inst : B) { 56349cc55cSDimitry Andric // TODO: Use a pass parameter instead of cl::opt CostKind to determine 57349cc55cSDimitry Andric // which cost kind to print. 58fcaf7f86SDimitry Andric InstructionCost Cost; 59fcaf7f86SDimitry Andric auto *II = dyn_cast<IntrinsicInst>(&Inst); 60*bdd1243dSDimitry Andric if (II && TypeBasedIntrinsicCost) { 61fcaf7f86SDimitry Andric IntrinsicCostAttributes ICA(II->getIntrinsicID(), *II, 62fcaf7f86SDimitry Andric InstructionCost::getInvalid(), true); 63fcaf7f86SDimitry Andric Cost = TTI.getIntrinsicInstrCost(ICA, CostKind); 64fcaf7f86SDimitry Andric } 65fcaf7f86SDimitry Andric else { 66fcaf7f86SDimitry Andric Cost = TTI.getInstructionCost(&Inst, CostKind); 67fcaf7f86SDimitry Andric } 68*bdd1243dSDimitry Andric 69349cc55cSDimitry Andric if (auto CostVal = Cost.getValue()) 70349cc55cSDimitry Andric OS << "Cost Model: Found an estimated cost of " << *CostVal; 71349cc55cSDimitry Andric else 72349cc55cSDimitry Andric OS << "Cost Model: Invalid cost"; 73349cc55cSDimitry Andric 74349cc55cSDimitry Andric OS << " for instruction: " << Inst << "\n"; 75349cc55cSDimitry Andric } 76349cc55cSDimitry Andric } 77349cc55cSDimitry Andric return PreservedAnalyses::all(); 78349cc55cSDimitry Andric } 79