llvm.org GIT mirror llvm / 3fae04d
[PM] Port ConstantHoisting to the new Pass Manager Differential Revision: http://reviews.llvm.org/D21945 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@274411 91177308-0d34-0410-b5e6-96231b3b80d8 Michael Kuperstein 4 years ago
7 changed file(s) with 204 addition(s) and 136 deletion(s). Raw diff Collapse all Expand all
8787 void initializeCallGraphViewerPass(PassRegistry&);
8888 void initializeCallGraphWrapperPassPass(PassRegistry &);
8989 void initializeCodeGenPreparePass(PassRegistry&);
90 void initializeConstantHoistingPass(PassRegistry&);
90 void initializeConstantHoistingLegacyPassPass(PassRegistry&);
9191 void initializeConstantMergeLegacyPassPass(PassRegistry &);
9292 void initializeConstantPropagationPass(PassRegistry&);
9393 void initializeCorrelatedValuePropagationPass(PassRegistry&);
0 //===-- ConstantHoisting.h - Prepare code for expensive constants ---------===//
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 pass identifies expensive constants to hoist and coalesces them to
10 // better prepare it for SelectionDAG-based code generation. This works around
11 // the limitations of the basic-block-at-a-time approach.
12 //
13 // First it scans all instructions for integer constants and calculates its
14 // cost. If the constant can be folded into the instruction (the cost is
15 // TCC_Free) or the cost is just a simple operation (TCC_BASIC), then we don't
16 // consider it expensive and leave it alone. This is the default behavior and
17 // the default implementation of getIntImmCost will always return TCC_Free.
18 //
19 // If the cost is more than TCC_BASIC, then the integer constant can't be folded
20 // into the instruction and it might be beneficial to hoist the constant.
21 // Similar constants are coalesced to reduce register pressure and
22 // materialization code.
23 //
24 // When a constant is hoisted, it is also hidden behind a bitcast to force it to
25 // be live-out of the basic block. Otherwise the constant would be just
26 // duplicated and each basic block would have its own copy in the SelectionDAG.
27 // The SelectionDAG recognizes such constants as opaque and doesn't perform
28 // certain transformations on them, which would create a new expensive constant.
29 //
30 // This optimization is only applied to integer constants in instructions and
31 // simple (this means not nested) constant cast expressions. For example:
32 // %0 = load i64* inttoptr (i64 big_constant to i64*)
33 //===----------------------------------------------------------------------===//
34
35 #ifndef LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H
36 #define LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H
37
38 #include "llvm/Analysis/TargetTransformInfo.h"
39 #include "llvm/IR/Dominators.h"
40 #include "llvm/IR/PassManager.h"
41
42 namespace llvm {
43
44 /// A private "module" namespace for types and utilities used by
45 /// ConstantHoisting. These are implementation details and should not be used by
46 /// clients.
47 namespace consthoist {
48 /// \brief Keeps track of the user of a constant and the operand index where the
49 /// constant is used.
50 struct ConstantUser {
51 Instruction *Inst;
52 unsigned OpndIdx;
53
54 ConstantUser(Instruction *Inst, unsigned Idx) : Inst(Inst), OpndIdx(Idx) { }
55 };
56
57 typedef SmallVector ConstantUseListType;
58
59 /// \brief Keeps track of a constant candidate and its uses.
60 struct ConstantCandidate {
61 ConstantUseListType Uses;
62 ConstantInt *ConstInt;
63 unsigned CumulativeCost;
64
65 ConstantCandidate(ConstantInt *ConstInt)
66 : ConstInt(ConstInt), CumulativeCost(0) { }
67
68 /// \brief Add the user to the use list and update the cost.
69 void addUser(Instruction *Inst, unsigned Idx, unsigned Cost) {
70 CumulativeCost += Cost;
71 Uses.push_back(ConstantUser(Inst, Idx));
72 }
73 };
74
75 /// \brief This represents a constant that has been rebased with respect to a
76 /// base constant. The difference to the base constant is recorded in Offset.
77 struct RebasedConstantInfo {
78 ConstantUseListType Uses;
79 Constant *Offset;
80
81 RebasedConstantInfo(ConstantUseListType &&Uses, Constant *Offset)
82 : Uses(std::move(Uses)), Offset(Offset) { }
83 };
84
85 typedef SmallVector RebasedConstantListType;
86
87 /// \brief A base constant and all its rebased constants.
88 struct ConstantInfo {
89 ConstantInt *BaseConstant;
90 RebasedConstantListType RebasedConstants;
91 };
92 }
93
94 class ConstantHoistingPass : public PassInfoMixin {
95 public:
96 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
97
98 // Glue for old PM.
99 bool runImpl(Function &F, TargetTransformInfo &TTI, DominatorTree &DT,
100 BasicBlock &Entry);
101
102 void releaseMemory() {
103 ConstantVec.clear();
104 ClonedCastMap.clear();
105 ConstCandVec.clear();
106 }
107
108 private:
109 typedef DenseMap ConstCandMapType;
110 typedef std::vector ConstCandVecType;
111
112 const TargetTransformInfo *TTI;
113 DominatorTree *DT;
114 BasicBlock *Entry;
115
116 /// Keeps track of constant candidates found in the function.
117 ConstCandVecType ConstCandVec;
118
119 /// Keep track of cast instructions we already cloned.
120 SmallDenseMap ClonedCastMap;
121
122 /// These are the final constants we decided to hoist.
123 SmallVector ConstantVec;
124
125 Instruction *findMatInsertPt(Instruction *Inst, unsigned Idx = ~0U) const;
126 Instruction *findConstantInsertionPoint(
127 const consthoist::ConstantInfo &ConstInfo) const;
128 void collectConstantCandidates(ConstCandMapType &ConstCandMap,
129 Instruction *Inst, unsigned Idx,
130 ConstantInt *ConstInt);
131 void collectConstantCandidates(ConstCandMapType &ConstCandMap,
132 Instruction *Inst);
133 void collectConstantCandidates(Function &Fn);
134 void findAndMakeBaseConstant(ConstCandVecType::iterator S,
135 ConstCandVecType::iterator E);
136 void findBaseConstants();
137 void emitBaseConstants(Instruction *Base, Constant *Offset,
138 const consthoist::ConstantUser &ConstUser);
139 bool emitBaseConstants();
140 void deleteDeadCastInst() const;
141 bool optimizeConstants(Function &Fn);
142 };
143 }
144
145 #endif // LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H
7373 #include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h"
7474 #include "llvm/Transforms/Scalar/BDCE.h"
7575 #include "llvm/Transforms/Scalar/DCE.h"
76 #include "llvm/Transforms/Scalar/ConstantHoisting.h"
7677 #include "llvm/Transforms/Scalar/DeadStoreElimination.h"
7778 #include "llvm/Transforms/Scalar/EarlyCSE.h"
7879 #include "llvm/Transforms/Scalar/Float2Int.h"
124124 FUNCTION_PASS("add-discriminators", AddDiscriminatorsPass())
125125 FUNCTION_PASS("alignment-from-assumptions", AlignmentFromAssumptionsPass())
126126 FUNCTION_PASS("bdce", BDCEPass())
127 FUNCTION_PASS("consthoist", ConstantHoistingPass())
127128 FUNCTION_PASS("dce", DCEPass())
128129 FUNCTION_PASS("dse", DSEPass())
129130 FUNCTION_PASS("early-cse", EarlyCSEPass())
3232 // %0 = load i64* inttoptr (i64 big_constant to i64*)
3333 //===----------------------------------------------------------------------===//
3434
35 #include "llvm/Transforms/Scalar.h"
35 #include "llvm/Transforms/Scalar/ConstantHoisting.h"
3636 #include "llvm/ADT/SmallSet.h"
3737 #include "llvm/ADT/SmallVector.h"
3838 #include "llvm/ADT/Statistic.h"
39 #include "llvm/Analysis/TargetTransformInfo.h"
4039 #include "llvm/IR/Constants.h"
41 #include "llvm/IR/Dominators.h"
4240 #include "llvm/IR/IntrinsicInst.h"
4341 #include "llvm/Pass.h"
4442 #include "llvm/Support/Debug.h"
4543 #include "llvm/Support/raw_ostream.h"
44 #include "llvm/Transforms/Scalar.h"
4645 #include
4746
4847 using namespace llvm;
48 using namespace consthoist;
4949
5050 #define DEBUG_TYPE "consthoist"
5151
5353 STATISTIC(NumConstantsRebased, "Number of constants rebased");
5454
5555 namespace {
56 struct ConstantUser;
57 struct RebasedConstantInfo;
58
59 typedef SmallVector ConstantUseListType;
60 typedef SmallVector RebasedConstantListType;
61
62 /// \brief Keeps track of the user of a constant and the operand index where the
63 /// constant is used.
64 struct ConstantUser {
65 Instruction *Inst;
66 unsigned OpndIdx;
67
68 ConstantUser(Instruction *Inst, unsigned Idx) : Inst(Inst), OpndIdx(Idx) { }
69 };
70
71 /// \brief Keeps track of a constant candidate and its uses.
72 struct ConstantCandidate {
73 ConstantUseListType Uses;
74 ConstantInt *ConstInt;
75 unsigned CumulativeCost;
76
77 ConstantCandidate(ConstantInt *ConstInt)
78 : ConstInt(ConstInt), CumulativeCost(0) { }
79
80 /// \brief Add the user to the use list and update the cost.
81 void addUser(Instruction *Inst, unsigned Idx, unsigned Cost) {
82 CumulativeCost += Cost;
83 Uses.push_back(ConstantUser(Inst, Idx));
84 }
85 };
86
87 /// \brief This represents a constant that has been rebased with respect to a
88 /// base constant. The difference to the base constant is recorded in Offset.
89 struct RebasedConstantInfo {
90 ConstantUseListType Uses;
91 Constant *Offset;
92
93 RebasedConstantInfo(ConstantUseListType &&Uses, Constant *Offset)
94 : Uses(std::move(Uses)), Offset(Offset) { }
95 };
96
97 /// \brief A base constant and all its rebased constants.
98 struct ConstantInfo {
99 ConstantInt *BaseConstant;
100 RebasedConstantListType RebasedConstants;
101 };
102
10356 /// \brief The constant hoisting pass.
104 class ConstantHoisting : public FunctionPass {
105 typedef DenseMap ConstCandMapType;
106 typedef std::vector ConstCandVecType;
107
108 const TargetTransformInfo *TTI;
109 DominatorTree *DT;
110 BasicBlock *Entry;
111
112 /// Keeps track of constant candidates found in the function.
113 ConstCandVecType ConstCandVec;
114
115 /// Keep track of cast instructions we already cloned.
116 SmallDenseMap ClonedCastMap;
117
118 /// These are the final constants we decided to hoist.
119 SmallVector ConstantVec;
57 class ConstantHoistingLegacyPass : public FunctionPass {
12058 public:
12159 static char ID; // Pass identification, replacement for typeid
122 ConstantHoisting() : FunctionPass(ID), TTI(nullptr), DT(nullptr),
123 Entry(nullptr) {
124 initializeConstantHoistingPass(*PassRegistry::getPassRegistry());
60 ConstantHoistingLegacyPass() : FunctionPass(ID) {
61 initializeConstantHoistingLegacyPassPass(*PassRegistry::getPassRegistry());
12562 }
12663
12764 bool runOnFunction(Function &Fn) override;
13471 AU.addRequired();
13572 }
13673
74 void releaseMemory() override { Impl.releaseMemory(); }
75
13776 private:
138 /// \brief Initialize the pass.
139 void setup(Function &Fn) {
140 DT = &getAnalysis().getDomTree();
141 TTI = &getAnalysis().getTTI(Fn);
142 Entry = &Fn.getEntryBlock();
143 }
144
145 /// \brief Cleanup.
146 void cleanup() {
147 ConstantVec.clear();
148 ClonedCastMap.clear();
149 ConstCandVec.clear();
150
151 TTI = nullptr;
152 DT = nullptr;
153 Entry = nullptr;
154 }
155
156 Instruction *findMatInsertPt(Instruction *Inst, unsigned Idx = ~0U) const;
157 Instruction *findConstantInsertionPoint(const ConstantInfo &ConstInfo) const;
158 void collectConstantCandidates(ConstCandMapType &ConstCandMap,
159 Instruction *Inst, unsigned Idx,
160 ConstantInt *ConstInt);
161 void collectConstantCandidates(ConstCandMapType &ConstCandMap,
162 Instruction *Inst);
163 void collectConstantCandidates(Function &Fn);
164 void findAndMakeBaseConstant(ConstCandVecType::iterator S,
165 ConstCandVecType::iterator E);
166 void findBaseConstants();
167 void emitBaseConstants(Instruction *Base, Constant *Offset,
168 const ConstantUser &ConstUser);
169 bool emitBaseConstants();
170 void deleteDeadCastInst() const;
171 bool optimizeConstants(Function &Fn);
77 ConstantHoistingPass Impl;
17278 };
17379 }
17480
175 char ConstantHoisting::ID = 0;
176 INITIALIZE_PASS_BEGIN(ConstantHoisting, "consthoist", "Constant Hoisting",
177 false, false)
81 char ConstantHoistingLegacyPass::ID = 0;
82 INITIALIZE_PASS_BEGIN(ConstantHoistingLegacyPass, "consthoist",
83 "Constant Hoisting", false, false)
17884 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
17985 INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
180 INITIALIZE_PASS_END(ConstantHoisting, "consthoist", "Constant Hoisting",
181 false, false)
86 INITIALIZE_PASS_END(ConstantHoistingLegacyPass, "consthoist",
87 "Constant Hoisting", false, false)
18288
18389 FunctionPass *llvm::createConstantHoistingPass() {
184 return new ConstantHoisting();
90 return new ConstantHoistingLegacyPass();
18591 }
18692
18793 /// \brief Perform the constant hoisting optimization for the given function.
188 bool ConstantHoisting::runOnFunction(Function &Fn) {
94 bool ConstantHoistingLegacyPass::runOnFunction(Function &Fn) {
18995 if (skipFunction(Fn))
19096 return false;
19197
19298 DEBUG(dbgs() << "********** Begin Constant Hoisting **********\n");
19399 DEBUG(dbgs() << "********** Function: " << Fn.getName() << '\n');
194100
195 setup(Fn);
196
197 bool MadeChange = optimizeConstants(Fn);
101 bool MadeChange = Impl.runImpl(
102 Fn, getAnalysis().getTTI(Fn),
103 getAnalysis().getDomTree(), Fn.getEntryBlock());
198104
199105 if (MadeChange) {
200106 DEBUG(dbgs() << "********** Function after Constant Hoisting: "
203109 }
204110 DEBUG(dbgs() << "********** End Constant Hoisting **********\n");
205111
206 cleanup();
207
208112 return MadeChange;
209113 }
210114
211115
212116 /// \brief Find the constant materialization insertion point.
213 Instruction *ConstantHoisting::findMatInsertPt(Instruction *Inst,
214 unsigned Idx) const {
117 Instruction *ConstantHoistingPass::findMatInsertPt(Instruction *Inst,
118 unsigned Idx) const {
215119 // If the operand is a cast instruction, then we have to materialize the
216120 // constant before the cast instruction.
217121 if (Idx != ~0U) {
236140 }
237141
238142 /// \brief Find an insertion point that dominates all uses.
239 Instruction *ConstantHoisting::
240 findConstantInsertionPoint(const ConstantInfo &ConstInfo) const {
143 Instruction *ConstantHoistingPass::findConstantInsertionPoint(
144 const ConstantInfo &ConstInfo) const {
241145 assert(!ConstInfo.RebasedConstants.empty() && "Invalid constant info entry.");
242146 // Collect all basic blocks.
243147 SmallPtrSet BBs;
271175 /// The operand at index Idx is not necessarily the constant integer itself. It
272176 /// could also be a cast instruction or a constant expression that uses the
273177 // constant integer.
274 void ConstantHoisting::collectConstantCandidates(ConstCandMapType &ConstCandMap,
275 Instruction *Inst,
276 unsigned Idx,
277 ConstantInt *ConstInt) {
178 void ConstantHoistingPass::collectConstantCandidates(
179 ConstCandMapType &ConstCandMap, Instruction *Inst, unsigned Idx,
180 ConstantInt *ConstInt) {
278181 unsigned Cost;
279182 // Ask the target about the cost of materializing the constant for the given
280183 // instruction and operand index.
308211
309212 /// \brief Scan the instruction for expensive integer constants and record them
310213 /// in the constant candidate vector.
311 void ConstantHoisting::collectConstantCandidates(ConstCandMapType &ConstCandMap,
312 Instruction *Inst) {
214 void ConstantHoistingPass::collectConstantCandidates(
215 ConstCandMapType &ConstCandMap, Instruction *Inst) {
313216 // Skip all cast instructions. They are visited indirectly later on.
314217 if (Inst->isCast())
315218 return;
374277
375278 /// \brief Collect all integer constants in the function that cannot be folded
376279 /// into an instruction itself.
377 void ConstantHoisting::collectConstantCandidates(Function &Fn) {
280 void ConstantHoistingPass::collectConstantCandidates(Function &Fn) {
378281 ConstCandMapType ConstCandMap;
379282 for (BasicBlock &BB : Fn)
380283 for (Instruction &Inst : BB)
383286
384287 /// \brief Find the base constant within the given range and rebase all other
385288 /// constants with respect to the base constant.
386 void ConstantHoisting::findAndMakeBaseConstant(ConstCandVecType::iterator S,
387 ConstCandVecType::iterator E) {
289 void ConstantHoistingPass::findAndMakeBaseConstant(
290 ConstCandVecType::iterator S, ConstCandVecType::iterator E) {
388291 auto MaxCostItr = S;
389292 unsigned NumUses = 0;
390293 // Use the constant that has the maximum cost as base constant.
415318
416319 /// \brief Finds and combines constant candidates that can be easily
417320 /// rematerialized with an add from a common base constant.
418 void ConstantHoisting::findBaseConstants() {
321 void ConstantHoistingPass::findBaseConstants() {
419322 // Sort the constants by value and type. This invalidates the mapping!
420323 std::sort(ConstCandVec.begin(), ConstCandVec.end(),
421324 [](const ConstantCandidate &LHS, const ConstantCandidate &RHS) {
477380
478381 /// \brief Emit materialization code for all rebased constants and update their
479382 /// users.
480 void ConstantHoisting::emitBaseConstants(Instruction *Base, Constant *Offset,
481 const ConstantUser &ConstUser) {
383 void ConstantHoistingPass::emitBaseConstants(Instruction *Base,
384 Constant *Offset,
385 const ConstantUser &ConstUser) {
482386 Instruction *Mat = Base;
483387 if (Offset) {
484388 Instruction *InsertionPt = findMatInsertPt(ConstUser.Inst,
549453
550454 /// \brief Hoist and hide the base constant behind a bitcast and emit
551455 /// materialization code for derived constants.
552 bool ConstantHoisting::emitBaseConstants() {
456 bool ConstantHoistingPass::emitBaseConstants() {
553457 bool MadeChange = false;
554458 for (auto const &ConstInfo : ConstantVec) {
555459 // Hoist and hide the base constant behind a bitcast.
583487
584488 /// \brief Check all cast instructions we made a copy of and remove them if they
585489 /// have no more users.
586 void ConstantHoisting::deleteDeadCastInst() const {
490 void ConstantHoistingPass::deleteDeadCastInst() const {
587491 for (auto const &I : ClonedCastMap)
588492 if (I.first->use_empty())
589493 I.first->eraseFromParent();
590494 }
591495
592496 /// \brief Optimize expensive integer constants in the given function.
593 bool ConstantHoisting::optimizeConstants(Function &Fn) {
497 bool ConstantHoistingPass::runImpl(Function &Fn, TargetTransformInfo &TTI,
498 DominatorTree &DT, BasicBlock &Entry) {
499 this->TTI = &TTI;
500 this->DT = &DT;
501 this->Entry = &Entry;
594502 // Collect all constant candidates.
595503 collectConstantCandidates(Fn);
596504
615523
616524 return MadeChange;
617525 }
526
527 PreservedAnalyses ConstantHoistingPass::run(Function &F,
528 FunctionAnalysisManager &AM) {
529 auto &DT = AM.getResult(F);
530 auto &TTI = AM.getResult(F);
531 if (!runImpl(F, TTI, DT, F.getEntryBlock()))
532 return PreservedAnalyses::all();
533
534 // FIXME: This should also 'preserve the CFG'.
535 return PreservedAnalyses::none();
536 }
3333 initializeADCELegacyPassPass(Registry);
3434 initializeBDCELegacyPassPass(Registry);
3535 initializeAlignmentFromAssumptionsPass(Registry);
36 initializeConstantHoistingPass(Registry);
36 initializeConstantHoistingLegacyPassPass(Registry);
3737 initializeConstantPropagationPass(Registry);
3838 initializeCorrelatedValuePropagationPass(Registry);
3939 initializeDCELegacyPassPass(Registry);
0 ; RUN: opt -S -consthoist < %s | FileCheck %s
1 ; RUN: opt -S -passes='consthoist' < %s | FileCheck %s
12
23 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
34 target triple = "x86_64-apple-macosx10.9.0"