llvm.org GIT mirror llvm / 6bed58e
Add a cost model analysis that allows us to estimate the cost of IR-level instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167324 91177308-0d34-0410-b5e6-96231b3b80d8 Nadav Rotem 8 years ago
11 changed file(s) with 295 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
186186
187187 //===--------------------------------------------------------------------===//
188188 //
189 // createCostModelAnalysisPass - This creates an instance of the
190 // CostModelAnalysis pass.
191 //
192 FunctionPass *createCostModelAnalysisPass();
193
194 //===--------------------------------------------------------------------===//
195 //
189196 // Minor pass prototypes, allowing us to expose them through bugpoint and
190197 // analyze.
191198 FunctionPass *createInstCountPass();
8787 void initializeConstantMergePass(PassRegistry&);
8888 void initializeConstantPropagationPass(PassRegistry&);
8989 void initializeMachineCopyPropagationPass(PassRegistry&);
90 void initializeCostModelAnalysisPass(PassRegistry&);
9091 void initializeCorrelatedValuePropagationPass(PassRegistry&);
9192 void initializeDAEPass(PassRegistry&);
9293 void initializeDAHPass(PassRegistry&);
5959 (void) llvm::createCFGSimplificationPass();
6060 (void) llvm::createConstantMergePass();
6161 (void) llvm::createConstantPropagationPass();
62 (void) llvm::createCostModelAnalysisPass();
6263 (void) llvm::createDeadArgEliminationPass();
6364 (void) llvm::createDeadCodeEliminationPass();
6465 (void) llvm::createDeadInstEliminationPass();
2525 initializeBasicAliasAnalysisPass(Registry);
2626 initializeBlockFrequencyInfoPass(Registry);
2727 initializeBranchProbabilityInfoPass(Registry);
28 initializeCostModelAnalysisPass(Registry);
2829 initializeCFGViewerPass(Registry);
2930 initializeCFGPrinterPass(Registry);
3031 initializeCFGOnlyViewerPass(Registry);
99 BranchProbabilityInfo.cpp
1010 CFGPrinter.cpp
1111 CaptureTracking.cpp
12 CostModel.cpp
1213 CodeMetrics.cpp
1314 ConstantFolding.cpp
1415 DbgInfoPrinter.cpp
0 //===- CostModel.cpp ------ Cost Model Analysis ---------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the cost model analysis. It provides a very basic cost
10 // estimation for LLVM-IR. The cost result can be thought of as cycles, but it
11 // is really unit-less. The estimated cost is ment to be used for comparing
12 // alternatives.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #define CM_NAME "cost-model"
17 #define DEBUG_TYPE CM_NAME
18 #include "llvm/Analysis/Passes.h"
19 #include "llvm/Function.h"
20 #include "llvm/Instructions.h"
21 #include "llvm/Pass.h"
22 #include "llvm/TargetTransformInfo.h"
23 #include "llvm/Value.h"
24 #include "llvm/Support/Debug.h"
25 #include "llvm/Support/raw_ostream.h"
26 using namespace llvm;
27
28 namespace {
29 class CostModelAnalysis : public FunctionPass {
30
31 public:
32 static char ID; // Class identification, replacement for typeinfo
33 CostModelAnalysis() : FunctionPass(ID), F(0), VTTI(0) {
34 initializeCostModelAnalysisPass(
35 *PassRegistry::getPassRegistry());
36 }
37
38 /// Returns the expected cost of the instruction.
39 /// Returns -1 if the cost is unknown.
40 /// Note, this method does not cache the cost calculation and it
41 /// can be expensive in some cases.
42 unsigned getInstructionCost(Instruction *I) const;
43
44 private:
45 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
46 virtual bool runOnFunction(Function &F);
47 virtual void print(raw_ostream &OS, const Module*) const;
48
49 /// The function that we analyze.
50 Function *F;
51 /// Vector target information.
52 const VectorTargetTransformInfo *VTTI;
53 };
54 } // End of anonymous namespace
55
56 // Register this pass.
57 char CostModelAnalysis::ID = 0;
58 static const char cm_name[] = "Cost Model Analysis";
59 INITIALIZE_PASS_BEGIN(CostModelAnalysis, CM_NAME, cm_name, false, true)
60 INITIALIZE_PASS_END (CostModelAnalysis, CM_NAME, cm_name, false, true)
61
62 FunctionPass *llvm::createCostModelAnalysisPass() {
63 return new CostModelAnalysis();
64 }
65
66 void
67 CostModelAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
68 AU.setPreservesAll();
69 }
70
71 bool
72 CostModelAnalysis::runOnFunction(Function &F) {
73 this->F = &F;
74
75 // Target information.
76 TargetTransformInfo *TTI;
77 TTI = getAnalysisIfAvailable();
78 if (TTI)
79 VTTI = TTI->getVectorTargetTransformInfo();
80
81 return false;
82 }
83
84 unsigned CostModelAnalysis::getInstructionCost(Instruction *I) const {
85 if (!VTTI)
86 return -1;
87
88 switch (I->getOpcode()) {
89 case Instruction::Ret:
90 case Instruction::PHI:
91 case Instruction::Br: {
92 return VTTI->getCFInstrCost(I->getOpcode());
93 }
94 case Instruction::Add:
95 case Instruction::FAdd:
96 case Instruction::Sub:
97 case Instruction::FSub:
98 case Instruction::Mul:
99 case Instruction::FMul:
100 case Instruction::UDiv:
101 case Instruction::SDiv:
102 case Instruction::FDiv:
103 case Instruction::URem:
104 case Instruction::SRem:
105 case Instruction::FRem:
106 case Instruction::Shl:
107 case Instruction::LShr:
108 case Instruction::AShr:
109 case Instruction::And:
110 case Instruction::Or:
111 case Instruction::Xor: {
112 return VTTI->getArithmeticInstrCost(I->getOpcode(), I->getType());
113 }
114 case Instruction::Select: {
115 SelectInst *SI = cast(I);
116 Type *CondTy = SI->getCondition()->getType();
117 return VTTI->getCmpSelInstrCost(I->getOpcode(), I->getType(), CondTy);
118 }
119 case Instruction::ICmp:
120 case Instruction::FCmp: {
121 Type *ValTy = I->getOperand(0)->getType();
122 return VTTI->getCmpSelInstrCost(I->getOpcode(), ValTy);
123 }
124 case Instruction::Store: {
125 StoreInst *SI = cast(I);
126 Type *ValTy = SI->getValueOperand()->getType();
127 return VTTI->getMemoryOpCost(I->getOpcode(), ValTy,
128 SI->getAlignment(),
129 SI->getPointerAddressSpace());
130 }
131 case Instruction::Load: {
132 LoadInst *LI = cast(I);
133 return VTTI->getMemoryOpCost(I->getOpcode(), I->getType(),
134 LI->getAlignment(),
135 LI->getPointerAddressSpace());
136 }
137 case Instruction::ZExt:
138 case Instruction::SExt:
139 case Instruction::FPToUI:
140 case Instruction::FPToSI:
141 case Instruction::FPExt:
142 case Instruction::PtrToInt:
143 case Instruction::IntToPtr:
144 case Instruction::SIToFP:
145 case Instruction::UIToFP:
146 case Instruction::Trunc:
147 case Instruction::FPTrunc:
148 case Instruction::BitCast: {
149 Type *SrcTy = I->getOperand(0)->getType();
150 return VTTI->getCastInstrCost(I->getOpcode(), I->getType(), SrcTy);
151 }
152 default:
153 // We don't have any information on this instruction.
154 return -1;
155 }
156 }
157
158 void CostModelAnalysis::print(raw_ostream &OS, const Module*) const {
159 if (!F)
160 return;
161
162 for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
163 for (BasicBlock::iterator it = B->begin(), e = B->end(); it != e; ++it) {
164 Instruction *Inst = it;
165 unsigned Cost = getInstructionCost(Inst);
166 if (Cost != (unsigned)-1)
167 OS << "Cost Model: Found an estimated cost of " << Cost;
168 else
169 OS << "Cost Model: Unknown cost";
170
171 OS << " for instruction: "<< *Inst << "\n";
172 }
173 }
174 }
0 config.suffixes = ['.ll', '.c', '.cpp']
1
2 targets = set(config.root.targets_to_build.split())
3 if not 'X86' in targets:
4 config.unsupported = True
5
0 ; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7-avx | FileCheck %s
1
2 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
3 target triple = "x86_64-apple-macosx10.8.0"
4
5 ;CHECK: cost of 1 {{.*}} add
6 ;CHECK: cost of 1 {{.*}} ret
7 define i32 @no_info(i32 %arg) {
8 %e = add i32 %arg, %arg
9 ret i32 %e
10 }
0 ; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7-avx | FileCheck %s
1
2 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
3 target triple = "x86_64-apple-macosx10.8.0"
4
5 define i32 @foo(i32* noalias nocapture %A, i32* noalias nocapture %B, i32 %start, i32 %end) nounwind uwtable ssp {
6 entry:
7 ;CHECK: cost of 1 {{.*}} icmp
8 %cmp7 = icmp slt i32 %start, %end
9 br i1 %cmp7, label %for.body.lr.ph, label %for.end
10
11 for.body.lr.ph: ; preds = %entry
12 ;CHECK: cost of 1 {{.*}} sext
13 %0 = sext i32 %start to i64
14 %1 = sub i32 %end, %start
15 %2 = zext i32 %1 to i64
16 %end.idx = add i64 %2, %0
17 ;CHECK: cost of 1 {{.*}} add
18 %n.vec = and i64 %2, 4294967288
19 %end.idx.rnd.down = add i64 %n.vec, %0
20 ;CHECK: cost of 1 {{.*}} icmp
21 %cmp.zero = icmp eq i64 %n.vec, 0
22 br i1 %cmp.zero, label %middle.block, label %vector.body
23
24 vector.body: ; preds = %for.body.lr.ph, %vector.body
25 %index = phi i64 [ %index.next, %vector.body ], [ %0, %for.body.lr.ph ]
26 %3 = add i64 %index, 2
27 %4 = getelementptr inbounds i32* %B, i64 %3
28 ;CHECK: cost of 0 {{.*}} bitcast
29 %5 = bitcast i32* %4 to <8 x i32>*
30 ;CHECK: cost of 1 {{.*}} load
31 %6 = load <8 x i32>* %5, align 4
32 %7 = mul nsw <8 x i32> %6,
33 %8 = getelementptr inbounds i32* %A, i64 %index
34 %9 = bitcast i32* %8 to <8 x i32>*
35 %10 = load <8 x i32>* %9, align 4
36 %11 = add nsw <8 x i32> %10, %7
37 ;CHECK: cost of 1 {{.*}} store
38 store <8 x i32> %11, <8 x i32>* %9, align 4
39 %index.next = add i64 %index, 8
40 %12 = icmp eq i64 %index.next, %end.idx.rnd.down
41 ;CHECK: cost of 1 {{.*}} br
42 br i1 %12, label %middle.block, label %vector.body
43
44 middle.block: ; preds = %vector.body, %for.body.lr.ph
45 %cmp.n = icmp eq i64 %end.idx, %end.idx.rnd.down
46 br i1 %cmp.n, label %for.end, label %for.body
47
48 for.body: ; preds = %middle.block, %for.body
49 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %end.idx.rnd.down, %middle.block ]
50 %13 = add nsw i64 %indvars.iv, 2
51 %arrayidx = getelementptr inbounds i32* %B, i64 %13
52 ;CHECK: cost of 1 {{.*}} load
53 %14 = load i32* %arrayidx, align 4, !tbaa !0
54 ;CHECK: cost of 1 {{.*}} mul
55 %mul = mul nsw i32 %14, 5
56 %arrayidx2 = getelementptr inbounds i32* %A, i64 %indvars.iv
57 ;CHECK: cost of 1 {{.*}} load
58 %15 = load i32* %arrayidx2, align 4, !tbaa !0
59 %add3 = add nsw i32 %15, %mul
60 store i32 %add3, i32* %arrayidx2, align 4, !tbaa !0
61 %indvars.iv.next = add i64 %indvars.iv, 1
62 ;CHECK: cost of 0 {{.*}} trunc
63 %16 = trunc i64 %indvars.iv.next to i32
64 %cmp = icmp slt i32 %16, %end
65 ;CHECK: cost of 1 {{.*}} br
66 br i1 %cmp, label %for.body, label %for.end
67
68 for.end: ; preds = %middle.block, %for.body, %entry
69 ;CHECK: cost of 1 {{.*}} ret
70 ret i32 undef
71 }
72
73 !0 = metadata !{metadata !"int", metadata !1}
74 !1 = metadata !{metadata !"omnipotent char", metadata !2}
75 !2 = metadata !{metadata !"Simple C/C++ TBAA"}
0 config.suffixes = ['.ll', '.c', '.cpp']
0 ; RUN: opt < %s -cost-model -analyze | FileCheck %s
1
2 ; The cost model does not have any target information so it can't make a decision.
3 ; Notice that OPT does not read the triple information from the module itself, only through the command line.
4
5 ; This info ignored:
6 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
7 target triple = "x86_64-apple-macosx10.8.0"
8
9 ;CHECK: Unknown cost {{.*}} add
10 ;CHECK: Unknown cost {{.*}} ret
11 define i32 @no_info(i32 %arg) {
12 %e = add i32 %arg, %arg
13 ret i32 %e
14 }