xref: /freebsd-src/contrib/llvm-project/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- ConstantHoisting.cpp - Prepare code for expensive constants --------===//
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 pass identifies expensive constants to hoist and coalesces them to
100b57cec5SDimitry Andric // better prepare it for SelectionDAG-based code generation. This works around
110b57cec5SDimitry Andric // the limitations of the basic-block-at-a-time approach.
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric // First it scans all instructions for integer constants and calculates its
140b57cec5SDimitry Andric // cost. If the constant can be folded into the instruction (the cost is
150b57cec5SDimitry Andric // TCC_Free) or the cost is just a simple operation (TCC_BASIC), then we don't
160b57cec5SDimitry Andric // consider it expensive and leave it alone. This is the default behavior and
17480093f4SDimitry Andric // the default implementation of getIntImmCostInst will always return TCC_Free.
180b57cec5SDimitry Andric //
190b57cec5SDimitry Andric // If the cost is more than TCC_BASIC, then the integer constant can't be folded
200b57cec5SDimitry Andric // into the instruction and it might be beneficial to hoist the constant.
210b57cec5SDimitry Andric // Similar constants are coalesced to reduce register pressure and
220b57cec5SDimitry Andric // materialization code.
230b57cec5SDimitry Andric //
240b57cec5SDimitry Andric // When a constant is hoisted, it is also hidden behind a bitcast to force it to
250b57cec5SDimitry Andric // be live-out of the basic block. Otherwise the constant would be just
260b57cec5SDimitry Andric // duplicated and each basic block would have its own copy in the SelectionDAG.
270b57cec5SDimitry Andric // The SelectionDAG recognizes such constants as opaque and doesn't perform
280b57cec5SDimitry Andric // certain transformations on them, which would create a new expensive constant.
290b57cec5SDimitry Andric //
300b57cec5SDimitry Andric // This optimization is only applied to integer constants in instructions and
310b57cec5SDimitry Andric // simple (this means not nested) constant cast expressions. For example:
320b57cec5SDimitry Andric // %0 = load i64* inttoptr (i64 big_constant to i64*)
330b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric #include "llvm/Transforms/Scalar/ConstantHoisting.h"
360b57cec5SDimitry Andric #include "llvm/ADT/APInt.h"
370b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
380b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
390b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
400b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
410b57cec5SDimitry Andric #include "llvm/Analysis/BlockFrequencyInfo.h"
420b57cec5SDimitry Andric #include "llvm/Analysis/ProfileSummaryInfo.h"
430b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
440b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h"
450b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
46*0fca6ea1SDimitry Andric #include "llvm/IR/DataLayout.h"
470b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
480b57cec5SDimitry Andric #include "llvm/IR/Dominators.h"
490b57cec5SDimitry Andric #include "llvm/IR/Function.h"
500b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h"
510b57cec5SDimitry Andric #include "llvm/IR/Instruction.h"
520b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
530b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
5481ad6265SDimitry Andric #include "llvm/IR/Operator.h"
550b57cec5SDimitry Andric #include "llvm/IR/Value.h"
56480093f4SDimitry Andric #include "llvm/InitializePasses.h"
570b57cec5SDimitry Andric #include "llvm/Pass.h"
580b57cec5SDimitry Andric #include "llvm/Support/BlockFrequency.h"
590b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
600b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
610b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
620b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
630b57cec5SDimitry Andric #include "llvm/Transforms/Scalar.h"
64480093f4SDimitry Andric #include "llvm/Transforms/Utils/Local.h"
650b57cec5SDimitry Andric #include "llvm/Transforms/Utils/SizeOpts.h"
660b57cec5SDimitry Andric #include <algorithm>
670b57cec5SDimitry Andric #include <cassert>
680b57cec5SDimitry Andric #include <cstdint>
690b57cec5SDimitry Andric #include <iterator>
700b57cec5SDimitry Andric #include <tuple>
710b57cec5SDimitry Andric #include <utility>
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric using namespace llvm;
740b57cec5SDimitry Andric using namespace consthoist;
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric #define DEBUG_TYPE "consthoist"
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric STATISTIC(NumConstantsHoisted, "Number of constants hoisted");
790b57cec5SDimitry Andric STATISTIC(NumConstantsRebased, "Number of constants rebased");
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric static cl::opt<bool> ConstHoistWithBlockFrequency(
820b57cec5SDimitry Andric     "consthoist-with-block-frequency", cl::init(true), cl::Hidden,
830b57cec5SDimitry Andric     cl::desc("Enable the use of the block frequency analysis to reduce the "
840b57cec5SDimitry Andric              "chance to execute const materialization more frequently than "
850b57cec5SDimitry Andric              "without hoisting."));
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric static cl::opt<bool> ConstHoistGEP(
880b57cec5SDimitry Andric     "consthoist-gep", cl::init(false), cl::Hidden,
890b57cec5SDimitry Andric     cl::desc("Try hoisting constant gep expressions"));
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric static cl::opt<unsigned>
920b57cec5SDimitry Andric MinNumOfDependentToRebase("consthoist-min-num-to-rebase",
930b57cec5SDimitry Andric     cl::desc("Do not rebase if number of dependent constants of a Base is less "
940b57cec5SDimitry Andric              "than this number."),
950b57cec5SDimitry Andric     cl::init(0), cl::Hidden);
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric namespace {
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric /// The constant hoisting pass.
1000b57cec5SDimitry Andric class ConstantHoistingLegacyPass : public FunctionPass {
1010b57cec5SDimitry Andric public:
1020b57cec5SDimitry Andric   static char ID; // Pass identification, replacement for typeid
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric   ConstantHoistingLegacyPass() : FunctionPass(ID) {
1050b57cec5SDimitry Andric     initializeConstantHoistingLegacyPassPass(*PassRegistry::getPassRegistry());
1060b57cec5SDimitry Andric   }
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric   bool runOnFunction(Function &Fn) override;
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   StringRef getPassName() const override { return "Constant Hoisting"; }
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override {
1130b57cec5SDimitry Andric     AU.setPreservesCFG();
1140b57cec5SDimitry Andric     if (ConstHoistWithBlockFrequency)
1150b57cec5SDimitry Andric       AU.addRequired<BlockFrequencyInfoWrapperPass>();
1160b57cec5SDimitry Andric     AU.addRequired<DominatorTreeWrapperPass>();
1170b57cec5SDimitry Andric     AU.addRequired<ProfileSummaryInfoWrapperPass>();
1180b57cec5SDimitry Andric     AU.addRequired<TargetTransformInfoWrapperPass>();
1190b57cec5SDimitry Andric   }
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric private:
1220b57cec5SDimitry Andric   ConstantHoistingPass Impl;
1230b57cec5SDimitry Andric };
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric } // end anonymous namespace
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric char ConstantHoistingLegacyPass::ID = 0;
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(ConstantHoistingLegacyPass, "consthoist",
1300b57cec5SDimitry Andric                       "Constant Hoisting", false, false)
1310b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
1320b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
1330b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
1340b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
1350b57cec5SDimitry Andric INITIALIZE_PASS_END(ConstantHoistingLegacyPass, "consthoist",
1360b57cec5SDimitry Andric                     "Constant Hoisting", false, false)
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric FunctionPass *llvm::createConstantHoistingPass() {
1390b57cec5SDimitry Andric   return new ConstantHoistingLegacyPass();
1400b57cec5SDimitry Andric }
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric /// Perform the constant hoisting optimization for the given function.
1430b57cec5SDimitry Andric bool ConstantHoistingLegacyPass::runOnFunction(Function &Fn) {
1440b57cec5SDimitry Andric   if (skipFunction(Fn))
1450b57cec5SDimitry Andric     return false;
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "********** Begin Constant Hoisting **********\n");
1480b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "********** Function: " << Fn.getName() << '\n');
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric   bool MadeChange =
1510b57cec5SDimitry Andric       Impl.runImpl(Fn, getAnalysis<TargetTransformInfoWrapperPass>().getTTI(Fn),
1520b57cec5SDimitry Andric                    getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
1530b57cec5SDimitry Andric                    ConstHoistWithBlockFrequency
1540b57cec5SDimitry Andric                        ? &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI()
1550b57cec5SDimitry Andric                        : nullptr,
1560b57cec5SDimitry Andric                    Fn.getEntryBlock(),
1570b57cec5SDimitry Andric                    &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI());
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "********** End Constant Hoisting **********\n");
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric   return MadeChange;
1620b57cec5SDimitry Andric }
1630b57cec5SDimitry Andric 
16406c3fb27SDimitry Andric void ConstantHoistingPass::collectMatInsertPts(
16506c3fb27SDimitry Andric     const RebasedConstantListType &RebasedConstants,
166*0fca6ea1SDimitry Andric     SmallVectorImpl<BasicBlock::iterator> &MatInsertPts) const {
16706c3fb27SDimitry Andric   for (const RebasedConstantInfo &RCI : RebasedConstants)
16806c3fb27SDimitry Andric     for (const ConstantUser &U : RCI.Uses)
16906c3fb27SDimitry Andric       MatInsertPts.emplace_back(findMatInsertPt(U.Inst, U.OpndIdx));
17006c3fb27SDimitry Andric }
17106c3fb27SDimitry Andric 
1720b57cec5SDimitry Andric /// Find the constant materialization insertion point.
173*0fca6ea1SDimitry Andric BasicBlock::iterator ConstantHoistingPass::findMatInsertPt(Instruction *Inst,
1740b57cec5SDimitry Andric                                                            unsigned Idx) const {
1750b57cec5SDimitry Andric   // If the operand is a cast instruction, then we have to materialize the
1760b57cec5SDimitry Andric   // constant before the cast instruction.
1770b57cec5SDimitry Andric   if (Idx != ~0U) {
1780b57cec5SDimitry Andric     Value *Opnd = Inst->getOperand(Idx);
1790b57cec5SDimitry Andric     if (auto CastInst = dyn_cast<Instruction>(Opnd))
1800b57cec5SDimitry Andric       if (CastInst->isCast())
181*0fca6ea1SDimitry Andric         return CastInst->getIterator();
1820b57cec5SDimitry Andric   }
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric   // The simple and common case. This also includes constant expressions.
1850b57cec5SDimitry Andric   if (!isa<PHINode>(Inst) && !Inst->isEHPad())
186*0fca6ea1SDimitry Andric     return Inst->getIterator();
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric   // We can't insert directly before a phi node or an eh pad. Insert before
1890b57cec5SDimitry Andric   // the terminator of the incoming or dominating block.
1900b57cec5SDimitry Andric   assert(Entry != Inst->getParent() && "PHI or landing pad in entry block!");
191fe6060f1SDimitry Andric   BasicBlock *InsertionBlock = nullptr;
192fe6060f1SDimitry Andric   if (Idx != ~0U && isa<PHINode>(Inst)) {
193fe6060f1SDimitry Andric     InsertionBlock = cast<PHINode>(Inst)->getIncomingBlock(Idx);
194fe6060f1SDimitry Andric     if (!InsertionBlock->isEHPad()) {
195*0fca6ea1SDimitry Andric       return InsertionBlock->getTerminator()->getIterator();
196fe6060f1SDimitry Andric     }
197fe6060f1SDimitry Andric   } else {
198fe6060f1SDimitry Andric     InsertionBlock = Inst->getParent();
199fe6060f1SDimitry Andric   }
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   // This must be an EH pad. Iterate over immediate dominators until we find a
2020b57cec5SDimitry Andric   // non-EH pad. We need to skip over catchswitch blocks, which are both EH pads
2030b57cec5SDimitry Andric   // and terminators.
204fe6060f1SDimitry Andric   auto *IDom = DT->getNode(InsertionBlock)->getIDom();
2050b57cec5SDimitry Andric   while (IDom->getBlock()->isEHPad()) {
2060b57cec5SDimitry Andric     assert(Entry != IDom->getBlock() && "eh pad in entry block");
2070b57cec5SDimitry Andric     IDom = IDom->getIDom();
2080b57cec5SDimitry Andric   }
2090b57cec5SDimitry Andric 
210*0fca6ea1SDimitry Andric   return IDom->getBlock()->getTerminator()->getIterator();
2110b57cec5SDimitry Andric }
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric /// Given \p BBs as input, find another set of BBs which collectively
2140b57cec5SDimitry Andric /// dominates \p BBs and have the minimal sum of frequencies. Return the BB
2150b57cec5SDimitry Andric /// set found in \p BBs.
2160b57cec5SDimitry Andric static void findBestInsertionSet(DominatorTree &DT, BlockFrequencyInfo &BFI,
2170b57cec5SDimitry Andric                                  BasicBlock *Entry,
2188bcb0991SDimitry Andric                                  SetVector<BasicBlock *> &BBs) {
2190b57cec5SDimitry Andric   assert(!BBs.count(Entry) && "Assume Entry is not in BBs");
2200b57cec5SDimitry Andric   // Nodes on the current path to the root.
2210b57cec5SDimitry Andric   SmallPtrSet<BasicBlock *, 8> Path;
2220b57cec5SDimitry Andric   // Candidates includes any block 'BB' in set 'BBs' that is not strictly
2230b57cec5SDimitry Andric   // dominated by any other blocks in set 'BBs', and all nodes in the path
2240b57cec5SDimitry Andric   // in the dominator tree from Entry to 'BB'.
2250b57cec5SDimitry Andric   SmallPtrSet<BasicBlock *, 16> Candidates;
226bdd1243dSDimitry Andric   for (auto *BB : BBs) {
2270b57cec5SDimitry Andric     // Ignore unreachable basic blocks.
2280b57cec5SDimitry Andric     if (!DT.isReachableFromEntry(BB))
2290b57cec5SDimitry Andric       continue;
2300b57cec5SDimitry Andric     Path.clear();
2310b57cec5SDimitry Andric     // Walk up the dominator tree until Entry or another BB in BBs
2320b57cec5SDimitry Andric     // is reached. Insert the nodes on the way to the Path.
2330b57cec5SDimitry Andric     BasicBlock *Node = BB;
2340b57cec5SDimitry Andric     // The "Path" is a candidate path to be added into Candidates set.
2350b57cec5SDimitry Andric     bool isCandidate = false;
2360b57cec5SDimitry Andric     do {
2370b57cec5SDimitry Andric       Path.insert(Node);
2380b57cec5SDimitry Andric       if (Node == Entry || Candidates.count(Node)) {
2390b57cec5SDimitry Andric         isCandidate = true;
2400b57cec5SDimitry Andric         break;
2410b57cec5SDimitry Andric       }
2420b57cec5SDimitry Andric       assert(DT.getNode(Node)->getIDom() &&
2430b57cec5SDimitry Andric              "Entry doens't dominate current Node");
2440b57cec5SDimitry Andric       Node = DT.getNode(Node)->getIDom()->getBlock();
2450b57cec5SDimitry Andric     } while (!BBs.count(Node));
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric     // If isCandidate is false, Node is another Block in BBs dominating
2480b57cec5SDimitry Andric     // current 'BB'. Drop the nodes on the Path.
2490b57cec5SDimitry Andric     if (!isCandidate)
2500b57cec5SDimitry Andric       continue;
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric     // Add nodes on the Path into Candidates.
2530b57cec5SDimitry Andric     Candidates.insert(Path.begin(), Path.end());
2540b57cec5SDimitry Andric   }
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric   // Sort the nodes in Candidates in top-down order and save the nodes
2570b57cec5SDimitry Andric   // in Orders.
2580b57cec5SDimitry Andric   unsigned Idx = 0;
2590b57cec5SDimitry Andric   SmallVector<BasicBlock *, 16> Orders;
2600b57cec5SDimitry Andric   Orders.push_back(Entry);
2610b57cec5SDimitry Andric   while (Idx != Orders.size()) {
2620b57cec5SDimitry Andric     BasicBlock *Node = Orders[Idx++];
263bdd1243dSDimitry Andric     for (auto *ChildDomNode : DT.getNode(Node)->children()) {
2640b57cec5SDimitry Andric       if (Candidates.count(ChildDomNode->getBlock()))
2650b57cec5SDimitry Andric         Orders.push_back(ChildDomNode->getBlock());
2660b57cec5SDimitry Andric     }
2670b57cec5SDimitry Andric   }
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric   // Visit Orders in bottom-up order.
2700b57cec5SDimitry Andric   using InsertPtsCostPair =
2718bcb0991SDimitry Andric       std::pair<SetVector<BasicBlock *>, BlockFrequency>;
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric   // InsertPtsMap is a map from a BB to the best insertion points for the
2740b57cec5SDimitry Andric   // subtree of BB (subtree not including the BB itself).
2750b57cec5SDimitry Andric   DenseMap<BasicBlock *, InsertPtsCostPair> InsertPtsMap;
2760b57cec5SDimitry Andric   InsertPtsMap.reserve(Orders.size() + 1);
2770eae32dcSDimitry Andric   for (BasicBlock *Node : llvm::reverse(Orders)) {
2780b57cec5SDimitry Andric     bool NodeInBBs = BBs.count(Node);
2798bcb0991SDimitry Andric     auto &InsertPts = InsertPtsMap[Node].first;
2800b57cec5SDimitry Andric     BlockFrequency &InsertPtsFreq = InsertPtsMap[Node].second;
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric     // Return the optimal insert points in BBs.
2830b57cec5SDimitry Andric     if (Node == Entry) {
2840b57cec5SDimitry Andric       BBs.clear();
2850b57cec5SDimitry Andric       if (InsertPtsFreq > BFI.getBlockFreq(Node) ||
2860b57cec5SDimitry Andric           (InsertPtsFreq == BFI.getBlockFreq(Node) && InsertPts.size() > 1))
2870b57cec5SDimitry Andric         BBs.insert(Entry);
2880b57cec5SDimitry Andric       else
2890b57cec5SDimitry Andric         BBs.insert(InsertPts.begin(), InsertPts.end());
2900b57cec5SDimitry Andric       break;
2910b57cec5SDimitry Andric     }
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric     BasicBlock *Parent = DT.getNode(Node)->getIDom()->getBlock();
2940b57cec5SDimitry Andric     // Initially, ParentInsertPts is empty and ParentPtsFreq is 0. Every child
2950b57cec5SDimitry Andric     // will update its parent's ParentInsertPts and ParentPtsFreq.
2968bcb0991SDimitry Andric     auto &ParentInsertPts = InsertPtsMap[Parent].first;
2970b57cec5SDimitry Andric     BlockFrequency &ParentPtsFreq = InsertPtsMap[Parent].second;
2980b57cec5SDimitry Andric     // Choose to insert in Node or in subtree of Node.
2990b57cec5SDimitry Andric     // Don't hoist to EHPad because we may not find a proper place to insert
3000b57cec5SDimitry Andric     // in EHPad.
3010b57cec5SDimitry Andric     // If the total frequency of InsertPts is the same as the frequency of the
3020b57cec5SDimitry Andric     // target Node, and InsertPts contains more than one nodes, choose hoisting
3030b57cec5SDimitry Andric     // to reduce code size.
3040b57cec5SDimitry Andric     if (NodeInBBs ||
3050b57cec5SDimitry Andric         (!Node->isEHPad() &&
3060b57cec5SDimitry Andric          (InsertPtsFreq > BFI.getBlockFreq(Node) ||
3070b57cec5SDimitry Andric           (InsertPtsFreq == BFI.getBlockFreq(Node) && InsertPts.size() > 1)))) {
3080b57cec5SDimitry Andric       ParentInsertPts.insert(Node);
3090b57cec5SDimitry Andric       ParentPtsFreq += BFI.getBlockFreq(Node);
3100b57cec5SDimitry Andric     } else {
3110b57cec5SDimitry Andric       ParentInsertPts.insert(InsertPts.begin(), InsertPts.end());
3120b57cec5SDimitry Andric       ParentPtsFreq += InsertPtsFreq;
3130b57cec5SDimitry Andric     }
3140b57cec5SDimitry Andric   }
3150b57cec5SDimitry Andric }
3160b57cec5SDimitry Andric 
3170b57cec5SDimitry Andric /// Find an insertion point that dominates all uses.
318*0fca6ea1SDimitry Andric SetVector<BasicBlock::iterator>
319*0fca6ea1SDimitry Andric ConstantHoistingPass::findConstantInsertionPoint(
32006c3fb27SDimitry Andric     const ConstantInfo &ConstInfo,
321*0fca6ea1SDimitry Andric     const ArrayRef<BasicBlock::iterator> MatInsertPts) const {
3220b57cec5SDimitry Andric   assert(!ConstInfo.RebasedConstants.empty() && "Invalid constant info entry.");
3230b57cec5SDimitry Andric   // Collect all basic blocks.
3248bcb0991SDimitry Andric   SetVector<BasicBlock *> BBs;
325*0fca6ea1SDimitry Andric   SetVector<BasicBlock::iterator> InsertPts;
32606c3fb27SDimitry Andric 
327*0fca6ea1SDimitry Andric   for (BasicBlock::iterator MatInsertPt : MatInsertPts)
32806c3fb27SDimitry Andric     BBs.insert(MatInsertPt->getParent());
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric   if (BBs.count(Entry)) {
331*0fca6ea1SDimitry Andric     InsertPts.insert(Entry->begin());
3320b57cec5SDimitry Andric     return InsertPts;
3330b57cec5SDimitry Andric   }
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric   if (BFI) {
3360b57cec5SDimitry Andric     findBestInsertionSet(*DT, *BFI, Entry, BBs);
33706c3fb27SDimitry Andric     for (BasicBlock *BB : BBs)
338*0fca6ea1SDimitry Andric       InsertPts.insert(BB->getFirstInsertionPt());
3390b57cec5SDimitry Andric     return InsertPts;
3400b57cec5SDimitry Andric   }
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric   while (BBs.size() >= 2) {
3430b57cec5SDimitry Andric     BasicBlock *BB, *BB1, *BB2;
3448bcb0991SDimitry Andric     BB1 = BBs.pop_back_val();
3458bcb0991SDimitry Andric     BB2 = BBs.pop_back_val();
3460b57cec5SDimitry Andric     BB = DT->findNearestCommonDominator(BB1, BB2);
3470b57cec5SDimitry Andric     if (BB == Entry) {
348*0fca6ea1SDimitry Andric       InsertPts.insert(Entry->begin());
3490b57cec5SDimitry Andric       return InsertPts;
3500b57cec5SDimitry Andric     }
3510b57cec5SDimitry Andric     BBs.insert(BB);
3520b57cec5SDimitry Andric   }
3530b57cec5SDimitry Andric   assert((BBs.size() == 1) && "Expected only one element.");
3540b57cec5SDimitry Andric   Instruction &FirstInst = (*BBs.begin())->front();
3550b57cec5SDimitry Andric   InsertPts.insert(findMatInsertPt(&FirstInst));
3560b57cec5SDimitry Andric   return InsertPts;
3570b57cec5SDimitry Andric }
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric /// Record constant integer ConstInt for instruction Inst at operand
3600b57cec5SDimitry Andric /// index Idx.
3610b57cec5SDimitry Andric ///
3620b57cec5SDimitry Andric /// The operand at index Idx is not necessarily the constant integer itself. It
3630b57cec5SDimitry Andric /// could also be a cast instruction or a constant expression that uses the
3640b57cec5SDimitry Andric /// constant integer.
3650b57cec5SDimitry Andric void ConstantHoistingPass::collectConstantCandidates(
3660b57cec5SDimitry Andric     ConstCandMapType &ConstCandMap, Instruction *Inst, unsigned Idx,
3670b57cec5SDimitry Andric     ConstantInt *ConstInt) {
368*0fca6ea1SDimitry Andric   if (ConstInt->getType()->isVectorTy())
369*0fca6ea1SDimitry Andric     return;
370*0fca6ea1SDimitry Andric 
371fe6060f1SDimitry Andric   InstructionCost Cost;
3720b57cec5SDimitry Andric   // Ask the target about the cost of materializing the constant for the given
3730b57cec5SDimitry Andric   // instruction and operand index.
3740b57cec5SDimitry Andric   if (auto IntrInst = dyn_cast<IntrinsicInst>(Inst))
375480093f4SDimitry Andric     Cost = TTI->getIntImmCostIntrin(IntrInst->getIntrinsicID(), Idx,
3765ffd83dbSDimitry Andric                                     ConstInt->getValue(), ConstInt->getType(),
3775ffd83dbSDimitry Andric                                     TargetTransformInfo::TCK_SizeAndLatency);
3780b57cec5SDimitry Andric   else
379e8d8bef9SDimitry Andric     Cost = TTI->getIntImmCostInst(
380e8d8bef9SDimitry Andric         Inst->getOpcode(), Idx, ConstInt->getValue(), ConstInt->getType(),
381e8d8bef9SDimitry Andric         TargetTransformInfo::TCK_SizeAndLatency, Inst);
3820b57cec5SDimitry Andric 
3830b57cec5SDimitry Andric   // Ignore cheap integer constants.
3840b57cec5SDimitry Andric   if (Cost > TargetTransformInfo::TCC_Basic) {
3850b57cec5SDimitry Andric     ConstCandMapType::iterator Itr;
3860b57cec5SDimitry Andric     bool Inserted;
3870b57cec5SDimitry Andric     ConstPtrUnionType Cand = ConstInt;
3880b57cec5SDimitry Andric     std::tie(Itr, Inserted) = ConstCandMap.insert(std::make_pair(Cand, 0));
3890b57cec5SDimitry Andric     if (Inserted) {
3900b57cec5SDimitry Andric       ConstIntCandVec.push_back(ConstantCandidate(ConstInt));
3910b57cec5SDimitry Andric       Itr->second = ConstIntCandVec.size() - 1;
3920b57cec5SDimitry Andric     }
393fe6060f1SDimitry Andric     ConstIntCandVec[Itr->second].addUser(Inst, Idx, *Cost.getValue());
3940b57cec5SDimitry Andric     LLVM_DEBUG(if (isa<ConstantInt>(Inst->getOperand(Idx))) dbgs()
3950b57cec5SDimitry Andric                    << "Collect constant " << *ConstInt << " from " << *Inst
3960b57cec5SDimitry Andric                    << " with cost " << Cost << '\n';
3970b57cec5SDimitry Andric                else dbgs() << "Collect constant " << *ConstInt
3980b57cec5SDimitry Andric                            << " indirectly from " << *Inst << " via "
3990b57cec5SDimitry Andric                            << *Inst->getOperand(Idx) << " with cost " << Cost
4000b57cec5SDimitry Andric                            << '\n';);
4010b57cec5SDimitry Andric   }
4020b57cec5SDimitry Andric }
4030b57cec5SDimitry Andric 
4040b57cec5SDimitry Andric /// Record constant GEP expression for instruction Inst at operand index Idx.
4050b57cec5SDimitry Andric void ConstantHoistingPass::collectConstantCandidates(
4060b57cec5SDimitry Andric     ConstCandMapType &ConstCandMap, Instruction *Inst, unsigned Idx,
4070b57cec5SDimitry Andric     ConstantExpr *ConstExpr) {
4080b57cec5SDimitry Andric   // TODO: Handle vector GEPs
4090b57cec5SDimitry Andric   if (ConstExpr->getType()->isVectorTy())
4100b57cec5SDimitry Andric     return;
4110b57cec5SDimitry Andric 
4120b57cec5SDimitry Andric   GlobalVariable *BaseGV = dyn_cast<GlobalVariable>(ConstExpr->getOperand(0));
4130b57cec5SDimitry Andric   if (!BaseGV)
4140b57cec5SDimitry Andric     return;
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   // Get offset from the base GV.
4178bcb0991SDimitry Andric   PointerType *GVPtrTy = cast<PointerType>(BaseGV->getType());
41806c3fb27SDimitry Andric   IntegerType *OffsetTy = DL->getIndexType(*Ctx, GVPtrTy->getAddressSpace());
41906c3fb27SDimitry Andric   APInt Offset(DL->getTypeSizeInBits(OffsetTy), /*val*/ 0, /*isSigned*/ true);
4200b57cec5SDimitry Andric   auto *GEPO = cast<GEPOperator>(ConstExpr);
42104eeddc0SDimitry Andric 
42204eeddc0SDimitry Andric   // TODO: If we have a mix of inbounds and non-inbounds GEPs, then basing a
42304eeddc0SDimitry Andric   // non-inbounds GEP on an inbounds GEP is potentially incorrect. Restrict to
42404eeddc0SDimitry Andric   // inbounds GEP for now -- alternatively, we could drop inbounds from the
42504eeddc0SDimitry Andric   // constant expression,
42604eeddc0SDimitry Andric   if (!GEPO->isInBounds())
42704eeddc0SDimitry Andric     return;
42804eeddc0SDimitry Andric 
4290b57cec5SDimitry Andric   if (!GEPO->accumulateConstantOffset(*DL, Offset))
4300b57cec5SDimitry Andric     return;
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric   if (!Offset.isIntN(32))
4330b57cec5SDimitry Andric     return;
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric   // A constant GEP expression that has a GlobalVariable as base pointer is
4360b57cec5SDimitry Andric   // usually lowered to a load from constant pool. Such operation is unlikely
4370b57cec5SDimitry Andric   // to be cheaper than compute it by <Base + Offset>, which can be lowered to
4380b57cec5SDimitry Andric   // an ADD instruction or folded into Load/Store instruction.
439fe6060f1SDimitry Andric   InstructionCost Cost =
44006c3fb27SDimitry Andric       TTI->getIntImmCostInst(Instruction::Add, 1, Offset, OffsetTy,
441e8d8bef9SDimitry Andric                              TargetTransformInfo::TCK_SizeAndLatency, Inst);
4420b57cec5SDimitry Andric   ConstCandVecType &ExprCandVec = ConstGEPCandMap[BaseGV];
4430b57cec5SDimitry Andric   ConstCandMapType::iterator Itr;
4440b57cec5SDimitry Andric   bool Inserted;
4450b57cec5SDimitry Andric   ConstPtrUnionType Cand = ConstExpr;
4460b57cec5SDimitry Andric   std::tie(Itr, Inserted) = ConstCandMap.insert(std::make_pair(Cand, 0));
4470b57cec5SDimitry Andric   if (Inserted) {
4480b57cec5SDimitry Andric     ExprCandVec.push_back(ConstantCandidate(
4490b57cec5SDimitry Andric         ConstantInt::get(Type::getInt32Ty(*Ctx), Offset.getLimitedValue()),
4500b57cec5SDimitry Andric         ConstExpr));
4510b57cec5SDimitry Andric     Itr->second = ExprCandVec.size() - 1;
4520b57cec5SDimitry Andric   }
453fe6060f1SDimitry Andric   ExprCandVec[Itr->second].addUser(Inst, Idx, *Cost.getValue());
4540b57cec5SDimitry Andric }
4550b57cec5SDimitry Andric 
4560b57cec5SDimitry Andric /// Check the operand for instruction Inst at index Idx.
4570b57cec5SDimitry Andric void ConstantHoistingPass::collectConstantCandidates(
4580b57cec5SDimitry Andric     ConstCandMapType &ConstCandMap, Instruction *Inst, unsigned Idx) {
4590b57cec5SDimitry Andric   Value *Opnd = Inst->getOperand(Idx);
4600b57cec5SDimitry Andric 
4610b57cec5SDimitry Andric   // Visit constant integers.
4620b57cec5SDimitry Andric   if (auto ConstInt = dyn_cast<ConstantInt>(Opnd)) {
4630b57cec5SDimitry Andric     collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt);
4640b57cec5SDimitry Andric     return;
4650b57cec5SDimitry Andric   }
4660b57cec5SDimitry Andric 
4670b57cec5SDimitry Andric   // Visit cast instructions that have constant integers.
4680b57cec5SDimitry Andric   if (auto CastInst = dyn_cast<Instruction>(Opnd)) {
4690b57cec5SDimitry Andric     // Only visit cast instructions, which have been skipped. All other
4700b57cec5SDimitry Andric     // instructions should have already been visited.
4710b57cec5SDimitry Andric     if (!CastInst->isCast())
4720b57cec5SDimitry Andric       return;
4730b57cec5SDimitry Andric 
4740b57cec5SDimitry Andric     if (auto *ConstInt = dyn_cast<ConstantInt>(CastInst->getOperand(0))) {
4750b57cec5SDimitry Andric       // Pretend the constant is directly used by the instruction and ignore
4760b57cec5SDimitry Andric       // the cast instruction.
4770b57cec5SDimitry Andric       collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt);
4780b57cec5SDimitry Andric       return;
4790b57cec5SDimitry Andric     }
4800b57cec5SDimitry Andric   }
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric   // Visit constant expressions that have constant integers.
4830b57cec5SDimitry Andric   if (auto ConstExpr = dyn_cast<ConstantExpr>(Opnd)) {
4840b57cec5SDimitry Andric     // Handle constant gep expressions.
48504eeddc0SDimitry Andric     if (ConstHoistGEP && isa<GEPOperator>(ConstExpr))
4860b57cec5SDimitry Andric       collectConstantCandidates(ConstCandMap, Inst, Idx, ConstExpr);
4870b57cec5SDimitry Andric 
4880b57cec5SDimitry Andric     // Only visit constant cast expressions.
4890b57cec5SDimitry Andric     if (!ConstExpr->isCast())
4900b57cec5SDimitry Andric       return;
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric     if (auto ConstInt = dyn_cast<ConstantInt>(ConstExpr->getOperand(0))) {
4930b57cec5SDimitry Andric       // Pretend the constant is directly used by the instruction and ignore
4940b57cec5SDimitry Andric       // the constant expression.
4950b57cec5SDimitry Andric       collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt);
4960b57cec5SDimitry Andric       return;
4970b57cec5SDimitry Andric     }
4980b57cec5SDimitry Andric   }
4990b57cec5SDimitry Andric }
5000b57cec5SDimitry Andric 
5010b57cec5SDimitry Andric /// Scan the instruction for expensive integer constants and record them
5020b57cec5SDimitry Andric /// in the constant candidate vector.
5030b57cec5SDimitry Andric void ConstantHoistingPass::collectConstantCandidates(
5040b57cec5SDimitry Andric     ConstCandMapType &ConstCandMap, Instruction *Inst) {
5050b57cec5SDimitry Andric   // Skip all cast instructions. They are visited indirectly later on.
5060b57cec5SDimitry Andric   if (Inst->isCast())
5070b57cec5SDimitry Andric     return;
5080b57cec5SDimitry Andric 
5090b57cec5SDimitry Andric   // Scan all operands.
5100b57cec5SDimitry Andric   for (unsigned Idx = 0, E = Inst->getNumOperands(); Idx != E; ++Idx) {
5110b57cec5SDimitry Andric     // The cost of materializing the constants (defined in
512480093f4SDimitry Andric     // `TargetTransformInfo::getIntImmCostInst`) for instructions which only
513480093f4SDimitry Andric     // take constant variables is lower than `TargetTransformInfo::TCC_Basic`.
514480093f4SDimitry Andric     // So it's safe for us to collect constant candidates from all
515480093f4SDimitry Andric     // IntrinsicInsts.
5165ffd83dbSDimitry Andric     if (canReplaceOperandWithVariable(Inst, Idx)) {
5170b57cec5SDimitry Andric       collectConstantCandidates(ConstCandMap, Inst, Idx);
5180b57cec5SDimitry Andric     }
5190b57cec5SDimitry Andric   } // end of for all operands
5200b57cec5SDimitry Andric }
5210b57cec5SDimitry Andric 
5220b57cec5SDimitry Andric /// Collect all integer constants in the function that cannot be folded
5230b57cec5SDimitry Andric /// into an instruction itself.
5240b57cec5SDimitry Andric void ConstantHoistingPass::collectConstantCandidates(Function &Fn) {
5250b57cec5SDimitry Andric   ConstCandMapType ConstCandMap;
526480093f4SDimitry Andric   for (BasicBlock &BB : Fn) {
527480093f4SDimitry Andric     // Ignore unreachable basic blocks.
528480093f4SDimitry Andric     if (!DT->isReachableFromEntry(&BB))
529480093f4SDimitry Andric       continue;
5300b57cec5SDimitry Andric     for (Instruction &Inst : BB)
5315f757f3fSDimitry Andric       if (!TTI->preferToKeepConstantsAttached(Inst, Fn))
5320b57cec5SDimitry Andric         collectConstantCandidates(ConstCandMap, &Inst);
5330b57cec5SDimitry Andric   }
534480093f4SDimitry Andric }
5350b57cec5SDimitry Andric 
5360b57cec5SDimitry Andric // This helper function is necessary to deal with values that have different
5370b57cec5SDimitry Andric // bit widths (APInt Operator- does not like that). If the value cannot be
5380b57cec5SDimitry Andric // represented in uint64 we return an "empty" APInt. This is then interpreted
5390b57cec5SDimitry Andric // as the value is not in range.
540bdd1243dSDimitry Andric static std::optional<APInt> calculateOffsetDiff(const APInt &V1,
541bdd1243dSDimitry Andric                                                 const APInt &V2) {
542bdd1243dSDimitry Andric   std::optional<APInt> Res;
5430b57cec5SDimitry Andric   unsigned BW = V1.getBitWidth() > V2.getBitWidth() ?
5440b57cec5SDimitry Andric                 V1.getBitWidth() : V2.getBitWidth();
5450b57cec5SDimitry Andric   uint64_t LimVal1 = V1.getLimitedValue();
5460b57cec5SDimitry Andric   uint64_t LimVal2 = V2.getLimitedValue();
5470b57cec5SDimitry Andric 
5480b57cec5SDimitry Andric   if (LimVal1 == ~0ULL || LimVal2 == ~0ULL)
5490b57cec5SDimitry Andric     return Res;
5500b57cec5SDimitry Andric 
5510b57cec5SDimitry Andric   uint64_t Diff = LimVal1 - LimVal2;
5520b57cec5SDimitry Andric   return APInt(BW, Diff, true);
5530b57cec5SDimitry Andric }
5540b57cec5SDimitry Andric 
5550b57cec5SDimitry Andric // From a list of constants, one needs to picked as the base and the other
5560b57cec5SDimitry Andric // constants will be transformed into an offset from that base constant. The
5570b57cec5SDimitry Andric // question is which we can pick best? For example, consider these constants
5580b57cec5SDimitry Andric // and their number of uses:
5590b57cec5SDimitry Andric //
5600b57cec5SDimitry Andric //  Constants| 2 | 4 | 12 | 42 |
5610b57cec5SDimitry Andric //  NumUses  | 3 | 2 |  8 |  7 |
5620b57cec5SDimitry Andric //
5630b57cec5SDimitry Andric // Selecting constant 12 because it has the most uses will generate negative
5640b57cec5SDimitry Andric // offsets for constants 2 and 4 (i.e. -10 and -8 respectively). If negative
5650b57cec5SDimitry Andric // offsets lead to less optimal code generation, then there might be better
5660b57cec5SDimitry Andric // solutions. Suppose immediates in the range of 0..35 are most optimally
5670b57cec5SDimitry Andric // supported by the architecture, then selecting constant 2 is most optimal
5680b57cec5SDimitry Andric // because this will generate offsets: 0, 2, 10, 40. Offsets 0, 2 and 10 are in
5690b57cec5SDimitry Andric // range 0..35, and thus 3 + 2 + 8 = 13 uses are in range. Selecting 12 would
5700b57cec5SDimitry Andric // have only 8 uses in range, so choosing 2 as a base is more optimal. Thus, in
5710b57cec5SDimitry Andric // selecting the base constant the range of the offsets is a very important
5720b57cec5SDimitry Andric // factor too that we take into account here. This algorithm calculates a total
5730b57cec5SDimitry Andric // costs for selecting a constant as the base and substract the costs if
5740b57cec5SDimitry Andric // immediates are out of range. It has quadratic complexity, so we call this
5750b57cec5SDimitry Andric // function only when we're optimising for size and there are less than 100
5760b57cec5SDimitry Andric // constants, we fall back to the straightforward algorithm otherwise
5770b57cec5SDimitry Andric // which does not do all the offset calculations.
5780b57cec5SDimitry Andric unsigned
5790b57cec5SDimitry Andric ConstantHoistingPass::maximizeConstantsInRange(ConstCandVecType::iterator S,
5800b57cec5SDimitry Andric                                            ConstCandVecType::iterator E,
5810b57cec5SDimitry Andric                                            ConstCandVecType::iterator &MaxCostItr) {
5820b57cec5SDimitry Andric   unsigned NumUses = 0;
5830b57cec5SDimitry Andric 
5840b57cec5SDimitry Andric   if (!OptForSize || std::distance(S,E) > 100) {
5850b57cec5SDimitry Andric     for (auto ConstCand = S; ConstCand != E; ++ConstCand) {
5860b57cec5SDimitry Andric       NumUses += ConstCand->Uses.size();
5870b57cec5SDimitry Andric       if (ConstCand->CumulativeCost > MaxCostItr->CumulativeCost)
5880b57cec5SDimitry Andric         MaxCostItr = ConstCand;
5890b57cec5SDimitry Andric     }
5900b57cec5SDimitry Andric     return NumUses;
5910b57cec5SDimitry Andric   }
5920b57cec5SDimitry Andric 
5930b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "== Maximize constants in range ==\n");
594fe6060f1SDimitry Andric   InstructionCost MaxCost = -1;
5950b57cec5SDimitry Andric   for (auto ConstCand = S; ConstCand != E; ++ConstCand) {
5960b57cec5SDimitry Andric     auto Value = ConstCand->ConstInt->getValue();
5970b57cec5SDimitry Andric     Type *Ty = ConstCand->ConstInt->getType();
598fe6060f1SDimitry Andric     InstructionCost Cost = 0;
5990b57cec5SDimitry Andric     NumUses += ConstCand->Uses.size();
6000b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "= Constant: " << ConstCand->ConstInt->getValue()
6010b57cec5SDimitry Andric                       << "\n");
6020b57cec5SDimitry Andric 
6030b57cec5SDimitry Andric     for (auto User : ConstCand->Uses) {
6040b57cec5SDimitry Andric       unsigned Opcode = User.Inst->getOpcode();
6050b57cec5SDimitry Andric       unsigned OpndIdx = User.OpndIdx;
6065ffd83dbSDimitry Andric       Cost += TTI->getIntImmCostInst(Opcode, OpndIdx, Value, Ty,
6075ffd83dbSDimitry Andric                                      TargetTransformInfo::TCK_SizeAndLatency);
6080b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "Cost: " << Cost << "\n");
6090b57cec5SDimitry Andric 
6100b57cec5SDimitry Andric       for (auto C2 = S; C2 != E; ++C2) {
611bdd1243dSDimitry Andric         std::optional<APInt> Diff = calculateOffsetDiff(
612bdd1243dSDimitry Andric             C2->ConstInt->getValue(), ConstCand->ConstInt->getValue());
6130b57cec5SDimitry Andric         if (Diff) {
614fe6060f1SDimitry Andric           const InstructionCost ImmCosts =
615bdd1243dSDimitry Andric               TTI->getIntImmCodeSizeCost(Opcode, OpndIdx, *Diff, Ty);
6160b57cec5SDimitry Andric           Cost -= ImmCosts;
617bdd1243dSDimitry Andric           LLVM_DEBUG(dbgs() << "Offset " << *Diff << " "
6180b57cec5SDimitry Andric                             << "has penalty: " << ImmCosts << "\n"
6190b57cec5SDimitry Andric                             << "Adjusted cost: " << Cost << "\n");
6200b57cec5SDimitry Andric         }
6210b57cec5SDimitry Andric       }
6220b57cec5SDimitry Andric     }
6230b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Cumulative cost: " << Cost << "\n");
6240b57cec5SDimitry Andric     if (Cost > MaxCost) {
6250b57cec5SDimitry Andric       MaxCost = Cost;
6260b57cec5SDimitry Andric       MaxCostItr = ConstCand;
6270b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "New candidate: " << MaxCostItr->ConstInt->getValue()
6280b57cec5SDimitry Andric                         << "\n");
6290b57cec5SDimitry Andric     }
6300b57cec5SDimitry Andric   }
6310b57cec5SDimitry Andric   return NumUses;
6320b57cec5SDimitry Andric }
6330b57cec5SDimitry Andric 
6340b57cec5SDimitry Andric /// Find the base constant within the given range and rebase all other
6350b57cec5SDimitry Andric /// constants with respect to the base constant.
6360b57cec5SDimitry Andric void ConstantHoistingPass::findAndMakeBaseConstant(
6370b57cec5SDimitry Andric     ConstCandVecType::iterator S, ConstCandVecType::iterator E,
6380b57cec5SDimitry Andric     SmallVectorImpl<consthoist::ConstantInfo> &ConstInfoVec) {
6390b57cec5SDimitry Andric   auto MaxCostItr = S;
6400b57cec5SDimitry Andric   unsigned NumUses = maximizeConstantsInRange(S, E, MaxCostItr);
6410b57cec5SDimitry Andric 
6420b57cec5SDimitry Andric   // Don't hoist constants that have only one use.
6430b57cec5SDimitry Andric   if (NumUses <= 1)
6440b57cec5SDimitry Andric     return;
6450b57cec5SDimitry Andric 
6460b57cec5SDimitry Andric   ConstantInt *ConstInt = MaxCostItr->ConstInt;
6470b57cec5SDimitry Andric   ConstantExpr *ConstExpr = MaxCostItr->ConstExpr;
6480b57cec5SDimitry Andric   ConstantInfo ConstInfo;
6490b57cec5SDimitry Andric   ConstInfo.BaseInt = ConstInt;
6500b57cec5SDimitry Andric   ConstInfo.BaseExpr = ConstExpr;
6510b57cec5SDimitry Andric   Type *Ty = ConstInt->getType();
6520b57cec5SDimitry Andric 
6530b57cec5SDimitry Andric   // Rebase the constants with respect to the base constant.
6540b57cec5SDimitry Andric   for (auto ConstCand = S; ConstCand != E; ++ConstCand) {
6550b57cec5SDimitry Andric     APInt Diff = ConstCand->ConstInt->getValue() - ConstInt->getValue();
6560b57cec5SDimitry Andric     Constant *Offset = Diff == 0 ? nullptr : ConstantInt::get(Ty, Diff);
6570b57cec5SDimitry Andric     Type *ConstTy =
6580b57cec5SDimitry Andric         ConstCand->ConstExpr ? ConstCand->ConstExpr->getType() : nullptr;
6590b57cec5SDimitry Andric     ConstInfo.RebasedConstants.push_back(
6600b57cec5SDimitry Andric       RebasedConstantInfo(std::move(ConstCand->Uses), Offset, ConstTy));
6610b57cec5SDimitry Andric   }
6620b57cec5SDimitry Andric   ConstInfoVec.push_back(std::move(ConstInfo));
6630b57cec5SDimitry Andric }
6640b57cec5SDimitry Andric 
6650b57cec5SDimitry Andric /// Finds and combines constant candidates that can be easily
6660b57cec5SDimitry Andric /// rematerialized with an add from a common base constant.
6670b57cec5SDimitry Andric void ConstantHoistingPass::findBaseConstants(GlobalVariable *BaseGV) {
6680b57cec5SDimitry Andric   // If BaseGV is nullptr, find base among candidate constant integers;
6690b57cec5SDimitry Andric   // Otherwise find base among constant GEPs that share the same BaseGV.
6700b57cec5SDimitry Andric   ConstCandVecType &ConstCandVec = BaseGV ?
6710b57cec5SDimitry Andric       ConstGEPCandMap[BaseGV] : ConstIntCandVec;
6720b57cec5SDimitry Andric   ConstInfoVecType &ConstInfoVec = BaseGV ?
6730b57cec5SDimitry Andric       ConstGEPInfoMap[BaseGV] : ConstIntInfoVec;
6740b57cec5SDimitry Andric 
6750b57cec5SDimitry Andric   // Sort the constants by value and type. This invalidates the mapping!
6760b57cec5SDimitry Andric   llvm::stable_sort(ConstCandVec, [](const ConstantCandidate &LHS,
6770b57cec5SDimitry Andric                                      const ConstantCandidate &RHS) {
6780b57cec5SDimitry Andric     if (LHS.ConstInt->getType() != RHS.ConstInt->getType())
679cb14a3feSDimitry Andric       return LHS.ConstInt->getBitWidth() < RHS.ConstInt->getBitWidth();
6800b57cec5SDimitry Andric     return LHS.ConstInt->getValue().ult(RHS.ConstInt->getValue());
6810b57cec5SDimitry Andric   });
6820b57cec5SDimitry Andric 
6830b57cec5SDimitry Andric   // Simple linear scan through the sorted constant candidate vector for viable
6840b57cec5SDimitry Andric   // merge candidates.
6850b57cec5SDimitry Andric   auto MinValItr = ConstCandVec.begin();
6860b57cec5SDimitry Andric   for (auto CC = std::next(ConstCandVec.begin()), E = ConstCandVec.end();
6870b57cec5SDimitry Andric        CC != E; ++CC) {
6880b57cec5SDimitry Andric     if (MinValItr->ConstInt->getType() == CC->ConstInt->getType()) {
6890b57cec5SDimitry Andric       Type *MemUseValTy = nullptr;
6900b57cec5SDimitry Andric       for (auto &U : CC->Uses) {
6910b57cec5SDimitry Andric         auto *UI = U.Inst;
6920b57cec5SDimitry Andric         if (LoadInst *LI = dyn_cast<LoadInst>(UI)) {
6930b57cec5SDimitry Andric           MemUseValTy = LI->getType();
6940b57cec5SDimitry Andric           break;
6950b57cec5SDimitry Andric         } else if (StoreInst *SI = dyn_cast<StoreInst>(UI)) {
6960b57cec5SDimitry Andric           // Make sure the constant is used as pointer operand of the StoreInst.
6970b57cec5SDimitry Andric           if (SI->getPointerOperand() == SI->getOperand(U.OpndIdx)) {
6980b57cec5SDimitry Andric             MemUseValTy = SI->getValueOperand()->getType();
6990b57cec5SDimitry Andric             break;
7000b57cec5SDimitry Andric           }
7010b57cec5SDimitry Andric         }
7020b57cec5SDimitry Andric       }
7030b57cec5SDimitry Andric 
7040b57cec5SDimitry Andric       // Check if the constant is in range of an add with immediate.
7050b57cec5SDimitry Andric       APInt Diff = CC->ConstInt->getValue() - MinValItr->ConstInt->getValue();
7060b57cec5SDimitry Andric       if ((Diff.getBitWidth() <= 64) &&
7070b57cec5SDimitry Andric           TTI->isLegalAddImmediate(Diff.getSExtValue()) &&
7080b57cec5SDimitry Andric           // Check if Diff can be used as offset in addressing mode of the user
7090b57cec5SDimitry Andric           // memory instruction.
7100b57cec5SDimitry Andric           (!MemUseValTy || TTI->isLegalAddressingMode(MemUseValTy,
7110b57cec5SDimitry Andric            /*BaseGV*/nullptr, /*BaseOffset*/Diff.getSExtValue(),
7120b57cec5SDimitry Andric            /*HasBaseReg*/true, /*Scale*/0)))
7130b57cec5SDimitry Andric         continue;
7140b57cec5SDimitry Andric     }
7150b57cec5SDimitry Andric     // We either have now a different constant type or the constant is not in
7160b57cec5SDimitry Andric     // range of an add with immediate anymore.
7170b57cec5SDimitry Andric     findAndMakeBaseConstant(MinValItr, CC, ConstInfoVec);
7180b57cec5SDimitry Andric     // Start a new base constant search.
7190b57cec5SDimitry Andric     MinValItr = CC;
7200b57cec5SDimitry Andric   }
7210b57cec5SDimitry Andric   // Finalize the last base constant search.
7220b57cec5SDimitry Andric   findAndMakeBaseConstant(MinValItr, ConstCandVec.end(), ConstInfoVec);
7230b57cec5SDimitry Andric }
7240b57cec5SDimitry Andric 
7250b57cec5SDimitry Andric /// Updates the operand at Idx in instruction Inst with the result of
7260b57cec5SDimitry Andric ///        instruction Mat. If the instruction is a PHI node then special
727bdd1243dSDimitry Andric ///        handling for duplicate values from the same incoming basic block is
7280b57cec5SDimitry Andric ///        required.
7290b57cec5SDimitry Andric /// \return The update will always succeed, but the return value indicated if
7300b57cec5SDimitry Andric ///         Mat was used for the update or not.
7310b57cec5SDimitry Andric static bool updateOperand(Instruction *Inst, unsigned Idx, Instruction *Mat) {
7320b57cec5SDimitry Andric   if (auto PHI = dyn_cast<PHINode>(Inst)) {
7330b57cec5SDimitry Andric     // Check if any previous operand of the PHI node has the same incoming basic
7340b57cec5SDimitry Andric     // block. This is a very odd case that happens when the incoming basic block
7350b57cec5SDimitry Andric     // has a switch statement. In this case use the same value as the previous
7360b57cec5SDimitry Andric     // operand(s), otherwise we will fail verification due to different values.
7370b57cec5SDimitry Andric     // The values are actually the same, but the variable names are different
7380b57cec5SDimitry Andric     // and the verifier doesn't like that.
7390b57cec5SDimitry Andric     BasicBlock *IncomingBB = PHI->getIncomingBlock(Idx);
7400b57cec5SDimitry Andric     for (unsigned i = 0; i < Idx; ++i) {
7410b57cec5SDimitry Andric       if (PHI->getIncomingBlock(i) == IncomingBB) {
7420b57cec5SDimitry Andric         Value *IncomingVal = PHI->getIncomingValue(i);
7430b57cec5SDimitry Andric         Inst->setOperand(Idx, IncomingVal);
7440b57cec5SDimitry Andric         return false;
7450b57cec5SDimitry Andric       }
7460b57cec5SDimitry Andric     }
7470b57cec5SDimitry Andric   }
7480b57cec5SDimitry Andric 
7490b57cec5SDimitry Andric   Inst->setOperand(Idx, Mat);
7500b57cec5SDimitry Andric   return true;
7510b57cec5SDimitry Andric }
7520b57cec5SDimitry Andric 
7530b57cec5SDimitry Andric /// Emit materialization code for all rebased constants and update their
7540b57cec5SDimitry Andric /// users.
7550b57cec5SDimitry Andric void ConstantHoistingPass::emitBaseConstants(Instruction *Base,
75606c3fb27SDimitry Andric                                              UserAdjustment *Adj) {
7570b57cec5SDimitry Andric   Instruction *Mat = Base;
7580b57cec5SDimitry Andric 
7590b57cec5SDimitry Andric   // The same offset can be dereferenced to different types in nested struct.
76006c3fb27SDimitry Andric   if (!Adj->Offset && Adj->Ty && Adj->Ty != Base->getType())
76106c3fb27SDimitry Andric     Adj->Offset = ConstantInt::get(Type::getInt32Ty(*Ctx), 0);
7620b57cec5SDimitry Andric 
76306c3fb27SDimitry Andric   if (Adj->Offset) {
76406c3fb27SDimitry Andric     if (Adj->Ty) {
7650b57cec5SDimitry Andric       // Constant being rebased is a ConstantExpr.
76606c3fb27SDimitry Andric       Mat = GetElementPtrInst::Create(Type::getInt8Ty(*Ctx), Base, Adj->Offset,
76706c3fb27SDimitry Andric                                       "mat_gep", Adj->MatInsertPt);
7685f757f3fSDimitry Andric       // Hide it behind a bitcast.
769*0fca6ea1SDimitry Andric       Mat = new BitCastInst(Mat, Adj->Ty, "mat_bitcast",
770*0fca6ea1SDimitry Andric                             Adj->MatInsertPt->getIterator());
7710b57cec5SDimitry Andric     } else
7720b57cec5SDimitry Andric       // Constant being rebased is a ConstantInt.
773*0fca6ea1SDimitry Andric       Mat =
774*0fca6ea1SDimitry Andric           BinaryOperator::Create(Instruction::Add, Base, Adj->Offset,
775*0fca6ea1SDimitry Andric                                  "const_mat", Adj->MatInsertPt->getIterator());
7760b57cec5SDimitry Andric 
7770b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Materialize constant (" << *Base->getOperand(0)
77806c3fb27SDimitry Andric                       << " + " << *Adj->Offset << ") in BB "
7790b57cec5SDimitry Andric                       << Mat->getParent()->getName() << '\n'
7800b57cec5SDimitry Andric                       << *Mat << '\n');
78106c3fb27SDimitry Andric     Mat->setDebugLoc(Adj->User.Inst->getDebugLoc());
7820b57cec5SDimitry Andric   }
78306c3fb27SDimitry Andric   Value *Opnd = Adj->User.Inst->getOperand(Adj->User.OpndIdx);
7840b57cec5SDimitry Andric 
7850b57cec5SDimitry Andric   // Visit constant integer.
7860b57cec5SDimitry Andric   if (isa<ConstantInt>(Opnd)) {
78706c3fb27SDimitry Andric     LLVM_DEBUG(dbgs() << "Update: " << *Adj->User.Inst << '\n');
78806c3fb27SDimitry Andric     if (!updateOperand(Adj->User.Inst, Adj->User.OpndIdx, Mat) && Adj->Offset)
7890b57cec5SDimitry Andric       Mat->eraseFromParent();
79006c3fb27SDimitry Andric     LLVM_DEBUG(dbgs() << "To    : " << *Adj->User.Inst << '\n');
7910b57cec5SDimitry Andric     return;
7920b57cec5SDimitry Andric   }
7930b57cec5SDimitry Andric 
7940b57cec5SDimitry Andric   // Visit cast instruction.
7950b57cec5SDimitry Andric   if (auto CastInst = dyn_cast<Instruction>(Opnd)) {
7960b57cec5SDimitry Andric     assert(CastInst->isCast() && "Expected an cast instruction!");
7970b57cec5SDimitry Andric     // Check if we already have visited this cast instruction before to avoid
7980b57cec5SDimitry Andric     // unnecessary cloning.
7990b57cec5SDimitry Andric     Instruction *&ClonedCastInst = ClonedCastMap[CastInst];
8000b57cec5SDimitry Andric     if (!ClonedCastInst) {
8010b57cec5SDimitry Andric       ClonedCastInst = CastInst->clone();
8020b57cec5SDimitry Andric       ClonedCastInst->setOperand(0, Mat);
8030b57cec5SDimitry Andric       ClonedCastInst->insertAfter(CastInst);
8040b57cec5SDimitry Andric       // Use the same debug location as the original cast instruction.
8050b57cec5SDimitry Andric       ClonedCastInst->setDebugLoc(CastInst->getDebugLoc());
8060b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "Clone instruction: " << *CastInst << '\n'
8070b57cec5SDimitry Andric                         << "To               : " << *ClonedCastInst << '\n');
8080b57cec5SDimitry Andric     }
8090b57cec5SDimitry Andric 
81006c3fb27SDimitry Andric     LLVM_DEBUG(dbgs() << "Update: " << *Adj->User.Inst << '\n');
81106c3fb27SDimitry Andric     updateOperand(Adj->User.Inst, Adj->User.OpndIdx, ClonedCastInst);
81206c3fb27SDimitry Andric     LLVM_DEBUG(dbgs() << "To    : " << *Adj->User.Inst << '\n');
8130b57cec5SDimitry Andric     return;
8140b57cec5SDimitry Andric   }
8150b57cec5SDimitry Andric 
8160b57cec5SDimitry Andric   // Visit constant expression.
8170b57cec5SDimitry Andric   if (auto ConstExpr = dyn_cast<ConstantExpr>(Opnd)) {
81804eeddc0SDimitry Andric     if (isa<GEPOperator>(ConstExpr)) {
8190b57cec5SDimitry Andric       // Operand is a ConstantGEP, replace it.
82006c3fb27SDimitry Andric       updateOperand(Adj->User.Inst, Adj->User.OpndIdx, Mat);
8210b57cec5SDimitry Andric       return;
8220b57cec5SDimitry Andric     }
8230b57cec5SDimitry Andric 
8240b57cec5SDimitry Andric     // Aside from constant GEPs, only constant cast expressions are collected.
8250b57cec5SDimitry Andric     assert(ConstExpr->isCast() && "ConstExpr should be a cast");
826*0fca6ea1SDimitry Andric     Instruction *ConstExprInst = ConstExpr->getAsInstruction();
827*0fca6ea1SDimitry Andric     ConstExprInst->insertBefore(Adj->MatInsertPt);
8280b57cec5SDimitry Andric     ConstExprInst->setOperand(0, Mat);
8290b57cec5SDimitry Andric 
8300b57cec5SDimitry Andric     // Use the same debug location as the instruction we are about to update.
83106c3fb27SDimitry Andric     ConstExprInst->setDebugLoc(Adj->User.Inst->getDebugLoc());
8320b57cec5SDimitry Andric 
8330b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Create instruction: " << *ConstExprInst << '\n'
8340b57cec5SDimitry Andric                       << "From              : " << *ConstExpr << '\n');
83506c3fb27SDimitry Andric     LLVM_DEBUG(dbgs() << "Update: " << *Adj->User.Inst << '\n');
83606c3fb27SDimitry Andric     if (!updateOperand(Adj->User.Inst, Adj->User.OpndIdx, ConstExprInst)) {
8370b57cec5SDimitry Andric       ConstExprInst->eraseFromParent();
83806c3fb27SDimitry Andric       if (Adj->Offset)
8390b57cec5SDimitry Andric         Mat->eraseFromParent();
8400b57cec5SDimitry Andric     }
84106c3fb27SDimitry Andric     LLVM_DEBUG(dbgs() << "To    : " << *Adj->User.Inst << '\n');
8420b57cec5SDimitry Andric     return;
8430b57cec5SDimitry Andric   }
8440b57cec5SDimitry Andric }
8450b57cec5SDimitry Andric 
8460b57cec5SDimitry Andric /// Hoist and hide the base constant behind a bitcast and emit
8470b57cec5SDimitry Andric /// materialization code for derived constants.
8480b57cec5SDimitry Andric bool ConstantHoistingPass::emitBaseConstants(GlobalVariable *BaseGV) {
8490b57cec5SDimitry Andric   bool MadeChange = false;
8500b57cec5SDimitry Andric   SmallVectorImpl<consthoist::ConstantInfo> &ConstInfoVec =
8510b57cec5SDimitry Andric       BaseGV ? ConstGEPInfoMap[BaseGV] : ConstIntInfoVec;
85206c3fb27SDimitry Andric   for (const consthoist::ConstantInfo &ConstInfo : ConstInfoVec) {
853*0fca6ea1SDimitry Andric     SmallVector<BasicBlock::iterator, 4> MatInsertPts;
85406c3fb27SDimitry Andric     collectMatInsertPts(ConstInfo.RebasedConstants, MatInsertPts);
855*0fca6ea1SDimitry Andric     SetVector<BasicBlock::iterator> IPSet =
85606c3fb27SDimitry Andric         findConstantInsertionPoint(ConstInfo, MatInsertPts);
8570b57cec5SDimitry Andric     // We can have an empty set if the function contains unreachable blocks.
8580b57cec5SDimitry Andric     if (IPSet.empty())
8590b57cec5SDimitry Andric       continue;
8600b57cec5SDimitry Andric 
8610b57cec5SDimitry Andric     unsigned UsesNum = 0;
8620b57cec5SDimitry Andric     unsigned ReBasesNum = 0;
8630b57cec5SDimitry Andric     unsigned NotRebasedNum = 0;
864*0fca6ea1SDimitry Andric     for (const BasicBlock::iterator &IP : IPSet) {
8650b57cec5SDimitry Andric       // First, collect constants depending on this IP of the base.
86606c3fb27SDimitry Andric       UsesNum = 0;
86706c3fb27SDimitry Andric       SmallVector<UserAdjustment, 4> ToBeRebased;
86806c3fb27SDimitry Andric       unsigned MatCtr = 0;
8690b57cec5SDimitry Andric       for (auto const &RCI : ConstInfo.RebasedConstants) {
87006c3fb27SDimitry Andric         UsesNum += RCI.Uses.size();
8710b57cec5SDimitry Andric         for (auto const &U : RCI.Uses) {
872*0fca6ea1SDimitry Andric           const BasicBlock::iterator &MatInsertPt = MatInsertPts[MatCtr++];
87306c3fb27SDimitry Andric           BasicBlock *OrigMatInsertBB = MatInsertPt->getParent();
8740b57cec5SDimitry Andric           // If Base constant is to be inserted in multiple places,
8750b57cec5SDimitry Andric           // generate rebase for U using the Base dominating U.
8760b57cec5SDimitry Andric           if (IPSet.size() == 1 ||
8770b57cec5SDimitry Andric               DT->dominates(IP->getParent(), OrigMatInsertBB))
87806c3fb27SDimitry Andric             ToBeRebased.emplace_back(RCI.Offset, RCI.Ty, MatInsertPt, U);
8790b57cec5SDimitry Andric         }
8800b57cec5SDimitry Andric       }
8810b57cec5SDimitry Andric 
8820b57cec5SDimitry Andric       // If only few constants depend on this IP of base, skip rebasing,
8830b57cec5SDimitry Andric       // assuming the base and the rebased have the same materialization cost.
8840b57cec5SDimitry Andric       if (ToBeRebased.size() < MinNumOfDependentToRebase) {
8850b57cec5SDimitry Andric         NotRebasedNum += ToBeRebased.size();
8860b57cec5SDimitry Andric         continue;
8870b57cec5SDimitry Andric       }
8880b57cec5SDimitry Andric 
8890b57cec5SDimitry Andric       // Emit an instance of the base at this IP.
8900b57cec5SDimitry Andric       Instruction *Base = nullptr;
8910b57cec5SDimitry Andric       // Hoist and hide the base constant behind a bitcast.
8920b57cec5SDimitry Andric       if (ConstInfo.BaseExpr) {
8930b57cec5SDimitry Andric         assert(BaseGV && "A base constant expression must have an base GV");
8940b57cec5SDimitry Andric         Type *Ty = ConstInfo.BaseExpr->getType();
8950b57cec5SDimitry Andric         Base = new BitCastInst(ConstInfo.BaseExpr, Ty, "const", IP);
8960b57cec5SDimitry Andric       } else {
897cb14a3feSDimitry Andric         IntegerType *Ty = ConstInfo.BaseInt->getIntegerType();
8980b57cec5SDimitry Andric         Base = new BitCastInst(ConstInfo.BaseInt, Ty, "const", IP);
8990b57cec5SDimitry Andric       }
9000b57cec5SDimitry Andric 
9010b57cec5SDimitry Andric       Base->setDebugLoc(IP->getDebugLoc());
9020b57cec5SDimitry Andric 
9030b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "Hoist constant (" << *ConstInfo.BaseInt
9040b57cec5SDimitry Andric                         << ") to BB " << IP->getParent()->getName() << '\n'
9050b57cec5SDimitry Andric                         << *Base << '\n');
9060b57cec5SDimitry Andric 
9070b57cec5SDimitry Andric       // Emit materialization code for rebased constants depending on this IP.
90806c3fb27SDimitry Andric       for (UserAdjustment &R : ToBeRebased) {
90906c3fb27SDimitry Andric         emitBaseConstants(Base, &R);
9100b57cec5SDimitry Andric         ReBasesNum++;
9110b57cec5SDimitry Andric         // Use the same debug location as the last user of the constant.
9120b57cec5SDimitry Andric         Base->setDebugLoc(DILocation::getMergedLocation(
91306c3fb27SDimitry Andric             Base->getDebugLoc(), R.User.Inst->getDebugLoc()));
9140b57cec5SDimitry Andric       }
9150b57cec5SDimitry Andric       assert(!Base->use_empty() && "The use list is empty!?");
9160b57cec5SDimitry Andric       assert(isa<Instruction>(Base->user_back()) &&
9170b57cec5SDimitry Andric              "All uses should be instructions.");
9180b57cec5SDimitry Andric     }
9190b57cec5SDimitry Andric     (void)UsesNum;
9200b57cec5SDimitry Andric     (void)ReBasesNum;
9210b57cec5SDimitry Andric     (void)NotRebasedNum;
9220b57cec5SDimitry Andric     // Expect all uses are rebased after rebase is done.
9230b57cec5SDimitry Andric     assert(UsesNum == (ReBasesNum + NotRebasedNum) &&
9240b57cec5SDimitry Andric            "Not all uses are rebased");
9250b57cec5SDimitry Andric 
9260b57cec5SDimitry Andric     NumConstantsHoisted++;
9270b57cec5SDimitry Andric 
9280b57cec5SDimitry Andric     // Base constant is also included in ConstInfo.RebasedConstants, so
9290b57cec5SDimitry Andric     // deduct 1 from ConstInfo.RebasedConstants.size().
9300b57cec5SDimitry Andric     NumConstantsRebased += ConstInfo.RebasedConstants.size() - 1;
9310b57cec5SDimitry Andric 
9320b57cec5SDimitry Andric     MadeChange = true;
9330b57cec5SDimitry Andric   }
9340b57cec5SDimitry Andric   return MadeChange;
9350b57cec5SDimitry Andric }
9360b57cec5SDimitry Andric 
9370b57cec5SDimitry Andric /// Check all cast instructions we made a copy of and remove them if they
9380b57cec5SDimitry Andric /// have no more users.
9390b57cec5SDimitry Andric void ConstantHoistingPass::deleteDeadCastInst() const {
9400b57cec5SDimitry Andric   for (auto const &I : ClonedCastMap)
9410b57cec5SDimitry Andric     if (I.first->use_empty())
9420b57cec5SDimitry Andric       I.first->eraseFromParent();
9430b57cec5SDimitry Andric }
9440b57cec5SDimitry Andric 
9450b57cec5SDimitry Andric /// Optimize expensive integer constants in the given function.
9460b57cec5SDimitry Andric bool ConstantHoistingPass::runImpl(Function &Fn, TargetTransformInfo &TTI,
9470b57cec5SDimitry Andric                                    DominatorTree &DT, BlockFrequencyInfo *BFI,
9480b57cec5SDimitry Andric                                    BasicBlock &Entry, ProfileSummaryInfo *PSI) {
9490b57cec5SDimitry Andric   this->TTI = &TTI;
9500b57cec5SDimitry Andric   this->DT = &DT;
9510b57cec5SDimitry Andric   this->BFI = BFI;
952*0fca6ea1SDimitry Andric   this->DL = &Fn.getDataLayout();
9530b57cec5SDimitry Andric   this->Ctx = &Fn.getContext();
9540b57cec5SDimitry Andric   this->Entry = &Entry;
9550b57cec5SDimitry Andric   this->PSI = PSI;
9567a6dacacSDimitry Andric   this->OptForSize = Entry.getParent()->hasOptSize() ||
9577a6dacacSDimitry Andric                      llvm::shouldOptimizeForSize(Entry.getParent(), PSI, BFI,
9587a6dacacSDimitry Andric                                                  PGSOQueryType::IRPass);
9597a6dacacSDimitry Andric 
9600b57cec5SDimitry Andric   // Collect all constant candidates.
9610b57cec5SDimitry Andric   collectConstantCandidates(Fn);
9620b57cec5SDimitry Andric 
9630b57cec5SDimitry Andric   // Combine constants that can be easily materialized with an add from a common
9640b57cec5SDimitry Andric   // base constant.
9650b57cec5SDimitry Andric   if (!ConstIntCandVec.empty())
9660b57cec5SDimitry Andric     findBaseConstants(nullptr);
967e8d8bef9SDimitry Andric   for (const auto &MapEntry : ConstGEPCandMap)
9680b57cec5SDimitry Andric     if (!MapEntry.second.empty())
9690b57cec5SDimitry Andric       findBaseConstants(MapEntry.first);
9700b57cec5SDimitry Andric 
9710b57cec5SDimitry Andric   // Finally hoist the base constant and emit materialization code for dependent
9720b57cec5SDimitry Andric   // constants.
9730b57cec5SDimitry Andric   bool MadeChange = false;
9740b57cec5SDimitry Andric   if (!ConstIntInfoVec.empty())
9750b57cec5SDimitry Andric     MadeChange = emitBaseConstants(nullptr);
976e8d8bef9SDimitry Andric   for (const auto &MapEntry : ConstGEPInfoMap)
9770b57cec5SDimitry Andric     if (!MapEntry.second.empty())
9780b57cec5SDimitry Andric       MadeChange |= emitBaseConstants(MapEntry.first);
9790b57cec5SDimitry Andric 
9800b57cec5SDimitry Andric 
9810b57cec5SDimitry Andric   // Cleanup dead instructions.
9820b57cec5SDimitry Andric   deleteDeadCastInst();
9830b57cec5SDimitry Andric 
9840b57cec5SDimitry Andric   cleanup();
9850b57cec5SDimitry Andric 
9860b57cec5SDimitry Andric   return MadeChange;
9870b57cec5SDimitry Andric }
9880b57cec5SDimitry Andric 
9890b57cec5SDimitry Andric PreservedAnalyses ConstantHoistingPass::run(Function &F,
9900b57cec5SDimitry Andric                                             FunctionAnalysisManager &AM) {
9910b57cec5SDimitry Andric   auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
9920b57cec5SDimitry Andric   auto &TTI = AM.getResult<TargetIRAnalysis>(F);
9930b57cec5SDimitry Andric   auto BFI = ConstHoistWithBlockFrequency
9940b57cec5SDimitry Andric                  ? &AM.getResult<BlockFrequencyAnalysis>(F)
9950b57cec5SDimitry Andric                  : nullptr;
9965ffd83dbSDimitry Andric   auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
9975ffd83dbSDimitry Andric   auto *PSI = MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
9980b57cec5SDimitry Andric   if (!runImpl(F, TTI, DT, BFI, F.getEntryBlock(), PSI))
9990b57cec5SDimitry Andric     return PreservedAnalyses::all();
10000b57cec5SDimitry Andric 
10010b57cec5SDimitry Andric   PreservedAnalyses PA;
10020b57cec5SDimitry Andric   PA.preserveSet<CFGAnalyses>();
10030b57cec5SDimitry Andric   return PA;
10040b57cec5SDimitry Andric }
1005