diff options
author | Zhaoshi Zheng <zhaoshiz@coduaurora.org> | 2018-09-25 17:45:37 +0000 |
---|---|---|
committer | Zhaoshi Zheng <zhaoshiz@coduaurora.org> | 2018-09-25 17:45:37 +0000 |
commit | 2c1a09188f12208313b77799d96af619ffc6020b (patch) | |
tree | 44d8e3247768fcd5f15c95bed1fadc73ac849de4 /llvm/lib/Transforms/Scalar/ConstantHoisting.cpp | |
parent | ef2ae740c6d82e3d310064a17e884dec024c55a8 (diff) | |
download | bcm5719-llvm-2c1a09188f12208313b77799d96af619ffc6020b.tar.gz bcm5719-llvm-2c1a09188f12208313b77799d96af619ffc6020b.zip |
[ConstHoist] Do not rebase single (or few) dependent constant
If an instance (InsertionPoint or IP) of Base constant A has only one or few
rebased constants depending on it, do NOT rebase. One extra ADD instruction is
required to materialize each rebased constant, assuming A and the rebased have
the same materialization cost.
Differential Revision: https://reviews.llvm.org/D52243
llvm-svn: 342994
Diffstat (limited to 'llvm/lib/Transforms/Scalar/ConstantHoisting.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/ConstantHoisting.cpp | 68 |
1 files changed, 46 insertions, 22 deletions
diff --git a/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp b/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp index 7acc85c3dd3..434fae94703 100644 --- a/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp +++ b/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp @@ -86,6 +86,12 @@ static cl::opt<bool> ConstHoistGEP( "consthoist-gep", cl::init(false), cl::Hidden, cl::desc("Try hoisting constant gep expressions")); +static cl::opt<unsigned> +MinNumOfDependentToRebase("consthoist-min-num-to-rebase", + cl::desc("Do not rebase if number of dependent constants of a Base is less " + "than this number."), + cl::init(2), cl::Hidden); + namespace { /// The constant hoisting pass. @@ -822,7 +828,34 @@ bool ConstantHoistingPass::emitBaseConstants(GlobalVariable *BaseGV) { unsigned UsesNum = 0; unsigned ReBasesNum = 0; + unsigned NotRebasedNum = 0; for (Instruction *IP : IPSet) { + // First, collect constants depending on this IP of the base. + unsigned Uses = 0; + using RebasedUse = std::tuple<Constant *, Type *, ConstantUser>; + SmallVector<RebasedUse, 4> ToBeRebased; + for (auto const &RCI : ConstInfo.RebasedConstants) { + for (auto const &U : RCI.Uses) { + Uses++; + BasicBlock *OrigMatInsertBB = + findMatInsertPt(U.Inst, U.OpndIdx)->getParent(); + // If Base constant is to be inserted in multiple places, + // generate rebase for U using the Base dominating U. + if (IPSet.size() == 1 || + DT->dominates(IP->getParent(), OrigMatInsertBB)) + ToBeRebased.push_back(RebasedUse(RCI.Offset, RCI.Ty, U)); + } + } + UsesNum = Uses; + + // If only few constants depend on this IP of base, skip rebasing, + // assuming the base and the rebased have the same materialization cost. + if (ToBeRebased.size() < MinNumOfDependentToRebase) { + NotRebasedNum += ToBeRebased.size(); + continue; + } + + // Emit an instance of the base at this IP. Instruction *Base = nullptr; // Hoist and hide the base constant behind a bitcast. if (ConstInfo.BaseExpr) { @@ -840,36 +873,27 @@ bool ConstantHoistingPass::emitBaseConstants(GlobalVariable *BaseGV) { << ") to BB " << IP->getParent()->getName() << '\n' << *Base << '\n'); - // Emit materialization code for all rebased constants. - unsigned Uses = 0; - for (auto const &RCI : ConstInfo.RebasedConstants) { - for (auto const &U : RCI.Uses) { - Uses++; - BasicBlock *OrigMatInsertBB = - findMatInsertPt(U.Inst, U.OpndIdx)->getParent(); - // If Base constant is to be inserted in multiple places, - // generate rebase for U using the Base dominating U. - if (IPSet.size() == 1 || - DT->dominates(Base->getParent(), OrigMatInsertBB)) { - emitBaseConstants(Base, RCI.Offset, RCI.Ty, U); - ReBasesNum++; - } - - Base->setDebugLoc(DILocation::getMergedLocation( - Base->getDebugLoc(), U.Inst->getDebugLoc())); - } + // Emit materialization code for rebased constants depending on this IP. + for (auto const &R : ToBeRebased) { + Constant *Off = std::get<0>(R); + Type *Ty = std::get<1>(R); + ConstantUser U = std::get<2>(R); + emitBaseConstants(Base, Off, Ty, U); + ReBasesNum++; + // Use the same debug location as the last user of the constant. + Base->setDebugLoc(DILocation::getMergedLocation( + Base->getDebugLoc(), U.Inst->getDebugLoc())); } - UsesNum = Uses; - - // Use the same debug location as the last user of the constant. assert(!Base->use_empty() && "The use list is empty!?"); assert(isa<Instruction>(Base->user_back()) && "All uses should be instructions."); } (void)UsesNum; (void)ReBasesNum; + (void)NotRebasedNum; // Expect all uses are rebased after rebase is done. - assert(UsesNum == ReBasesNum && "Not all uses are rebased"); + assert(UsesNum == (ReBasesNum + NotRebasedNum) && + "Not all uses are rebased"); NumConstantsHoisted++; |