brintos

brintos / llvm-project-archived public Read only

0
0
Text · 38.2 KiB · db594e0 Raw
977 lines · cpp
1//===- ConstantHoisting.cpp - Prepare code for expensive constants --------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This pass identifies expensive constants to hoist and coalesces them to10// better prepare it for SelectionDAG-based code generation. This works around11// the limitations of the basic-block-at-a-time approach.12//13// First it scans all instructions for integer constants and calculates its14// cost. If the constant can be folded into the instruction (the cost is15// TCC_Free) or the cost is just a simple operation (TCC_BASIC), then we don't16// consider it expensive and leave it alone. This is the default behavior and17// the default implementation of getIntImmCostInst will always return TCC_Free.18//19// If the cost is more than TCC_BASIC, then the integer constant can't be folded20// into the instruction and it might be beneficial to hoist the constant.21// Similar constants are coalesced to reduce register pressure and22// materialization code.23//24// When a constant is hoisted, it is also hidden behind a bitcast to force it to25// be live-out of the basic block. Otherwise the constant would be just26// duplicated and each basic block would have its own copy in the SelectionDAG.27// The SelectionDAG recognizes such constants as opaque and doesn't perform28// certain transformations on them, which would create a new expensive constant.29//30// This optimization is only applied to integer constants in instructions and31// simple (this means not nested) constant cast expressions. For example:32// %0 = load i64* inttoptr (i64 big_constant to i64*)33//===----------------------------------------------------------------------===//34 35#include "llvm/Transforms/Scalar/ConstantHoisting.h"36#include "llvm/ADT/APInt.h"37#include "llvm/ADT/DenseMap.h"38#include "llvm/ADT/SmallPtrSet.h"39#include "llvm/ADT/SmallVector.h"40#include "llvm/ADT/Statistic.h"41#include "llvm/Analysis/BlockFrequencyInfo.h"42#include "llvm/Analysis/ProfileSummaryInfo.h"43#include "llvm/Analysis/TargetTransformInfo.h"44#include "llvm/IR/BasicBlock.h"45#include "llvm/IR/Constants.h"46#include "llvm/IR/DataLayout.h"47#include "llvm/IR/Dominators.h"48#include "llvm/IR/Function.h"49#include "llvm/IR/InstrTypes.h"50#include "llvm/IR/Instruction.h"51#include "llvm/IR/Instructions.h"52#include "llvm/IR/IntrinsicInst.h"53#include "llvm/IR/Operator.h"54#include "llvm/IR/Value.h"55#include "llvm/InitializePasses.h"56#include "llvm/Pass.h"57#include "llvm/Support/BlockFrequency.h"58#include "llvm/Support/Casting.h"59#include "llvm/Support/CommandLine.h"60#include "llvm/Support/Debug.h"61#include "llvm/Support/raw_ostream.h"62#include "llvm/Transforms/Scalar.h"63#include "llvm/Transforms/Utils/Local.h"64#include "llvm/Transforms/Utils/SizeOpts.h"65#include <cassert>66#include <iterator>67#include <tuple>68#include <utility>69 70using namespace llvm;71using namespace consthoist;72 73#define DEBUG_TYPE "consthoist"74 75STATISTIC(NumConstantsHoisted, "Number of constants hoisted");76STATISTIC(NumConstantsRebased, "Number of constants rebased");77 78static cl::opt<bool> ConstHoistWithBlockFrequency(79    "consthoist-with-block-frequency", cl::init(true), cl::Hidden,80    cl::desc("Enable the use of the block frequency analysis to reduce the "81             "chance to execute const materialization more frequently than "82             "without hoisting."));83 84static cl::opt<bool> ConstHoistGEP(85    "consthoist-gep", cl::init(false), cl::Hidden,86    cl::desc("Try hoisting constant gep expressions"));87 88static cl::opt<unsigned>89MinNumOfDependentToRebase("consthoist-min-num-to-rebase",90    cl::desc("Do not rebase if number of dependent constants of a Base is less "91             "than this number."),92    cl::init(0), cl::Hidden);93 94namespace {95 96/// The constant hoisting pass.97class ConstantHoistingLegacyPass : public FunctionPass {98public:99  static char ID; // Pass identification, replacement for typeid100 101  ConstantHoistingLegacyPass() : FunctionPass(ID) {102    initializeConstantHoistingLegacyPassPass(*PassRegistry::getPassRegistry());103  }104 105  bool runOnFunction(Function &Fn) override;106 107  StringRef getPassName() const override { return "Constant Hoisting"; }108 109  void getAnalysisUsage(AnalysisUsage &AU) const override {110    AU.setPreservesCFG();111    if (ConstHoistWithBlockFrequency)112      AU.addRequired<BlockFrequencyInfoWrapperPass>();113    AU.addRequired<DominatorTreeWrapperPass>();114    AU.addRequired<ProfileSummaryInfoWrapperPass>();115    AU.addRequired<TargetTransformInfoWrapperPass>();116  }117 118private:119  ConstantHoistingPass Impl;120};121 122} // end anonymous namespace123 124char ConstantHoistingLegacyPass::ID = 0;125 126INITIALIZE_PASS_BEGIN(ConstantHoistingLegacyPass, "consthoist",127                      "Constant Hoisting", false, false)128INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)129INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)130INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)131INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)132INITIALIZE_PASS_END(ConstantHoistingLegacyPass, "consthoist",133                    "Constant Hoisting", false, false)134 135FunctionPass *llvm::createConstantHoistingPass() {136  return new ConstantHoistingLegacyPass();137}138 139/// Perform the constant hoisting optimization for the given function.140bool ConstantHoistingLegacyPass::runOnFunction(Function &Fn) {141  if (skipFunction(Fn))142    return false;143 144  LLVM_DEBUG(dbgs() << "********** Begin Constant Hoisting **********\n");145  LLVM_DEBUG(dbgs() << "********** Function: " << Fn.getName() << '\n');146 147  bool MadeChange =148      Impl.runImpl(Fn, getAnalysis<TargetTransformInfoWrapperPass>().getTTI(Fn),149                   getAnalysis<DominatorTreeWrapperPass>().getDomTree(),150                   ConstHoistWithBlockFrequency151                       ? &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI()152                       : nullptr,153                   Fn.getEntryBlock(),154                   &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI());155 156  LLVM_DEBUG(dbgs() << "********** End Constant Hoisting **********\n");157 158  return MadeChange;159}160 161void ConstantHoistingPass::collectMatInsertPts(162    const RebasedConstantListType &RebasedConstants,163    SmallVectorImpl<BasicBlock::iterator> &MatInsertPts) const {164  for (const RebasedConstantInfo &RCI : RebasedConstants)165    for (const ConstantUser &U : RCI.Uses)166      MatInsertPts.emplace_back(findMatInsertPt(U.Inst, U.OpndIdx));167}168 169/// Find the constant materialization insertion point.170BasicBlock::iterator ConstantHoistingPass::findMatInsertPt(Instruction *Inst,171                                                           unsigned Idx) const {172  // If the operand is a cast instruction, then we have to materialize the173  // constant before the cast instruction.174  if (Idx != ~0U) {175    Value *Opnd = Inst->getOperand(Idx);176    if (auto CastInst = dyn_cast<Instruction>(Opnd))177      if (CastInst->isCast())178        return CastInst->getIterator();179  }180 181  // The simple and common case. This also includes constant expressions.182  if (!isa<PHINode>(Inst) && !Inst->isEHPad())183    return Inst->getIterator();184 185  // We can't insert directly before a phi node or an eh pad. Insert before186  // the terminator of the incoming or dominating block.187  assert(Entry != Inst->getParent() && "PHI or landing pad in entry block!");188  BasicBlock *InsertionBlock = nullptr;189  if (Idx != ~0U && isa<PHINode>(Inst)) {190    InsertionBlock = cast<PHINode>(Inst)->getIncomingBlock(Idx);191    if (!InsertionBlock->isEHPad()) {192      return InsertionBlock->getTerminator()->getIterator();193    }194  } else {195    InsertionBlock = Inst->getParent();196  }197 198  // This must be an EH pad. Iterate over immediate dominators until we find a199  // non-EH pad. We need to skip over catchswitch blocks, which are both EH pads200  // and terminators.201  auto *IDom = DT->getNode(InsertionBlock)->getIDom();202  while (IDom->getBlock()->isEHPad()) {203    assert(Entry != IDom->getBlock() && "eh pad in entry block");204    IDom = IDom->getIDom();205  }206 207  return IDom->getBlock()->getTerminator()->getIterator();208}209 210/// Given \p BBs as input, find another set of BBs which collectively211/// dominates \p BBs and have the minimal sum of frequencies. Return the BB212/// set found in \p BBs.213static void findBestInsertionSet(DominatorTree &DT, BlockFrequencyInfo &BFI,214                                 BasicBlock *Entry,215                                 SetVector<BasicBlock *> &BBs) {216  assert(!BBs.count(Entry) && "Assume Entry is not in BBs");217  // Nodes on the current path to the root.218  SmallPtrSet<BasicBlock *, 8> Path;219  // Candidates includes any block 'BB' in set 'BBs' that is not strictly220  // dominated by any other blocks in set 'BBs', and all nodes in the path221  // in the dominator tree from Entry to 'BB'.222  SmallPtrSet<BasicBlock *, 16> Candidates;223  for (auto *BB : BBs) {224    // Ignore unreachable basic blocks.225    if (!DT.isReachableFromEntry(BB))226      continue;227    Path.clear();228    // Walk up the dominator tree until Entry or another BB in BBs229    // is reached. Insert the nodes on the way to the Path.230    BasicBlock *Node = BB;231    // The "Path" is a candidate path to be added into Candidates set.232    bool isCandidate = false;233    do {234      Path.insert(Node);235      if (Node == Entry || Candidates.count(Node)) {236        isCandidate = true;237        break;238      }239      assert(DT.getNode(Node)->getIDom() &&240             "Entry doens't dominate current Node");241      Node = DT.getNode(Node)->getIDom()->getBlock();242    } while (!BBs.count(Node));243 244    // If isCandidate is false, Node is another Block in BBs dominating245    // current 'BB'. Drop the nodes on the Path.246    if (!isCandidate)247      continue;248 249    // Add nodes on the Path into Candidates.250    Candidates.insert_range(Path);251  }252 253  // Sort the nodes in Candidates in top-down order and save the nodes254  // in Orders.255  unsigned Idx = 0;256  SmallVector<BasicBlock *, 16> Orders;257  Orders.push_back(Entry);258  while (Idx != Orders.size()) {259    BasicBlock *Node = Orders[Idx++];260    for (auto *ChildDomNode : DT.getNode(Node)->children()) {261      if (Candidates.count(ChildDomNode->getBlock()))262        Orders.push_back(ChildDomNode->getBlock());263    }264  }265 266  // Visit Orders in bottom-up order.267  using InsertPtsCostPair =268      std::pair<SetVector<BasicBlock *>, BlockFrequency>;269 270  // InsertPtsMap is a map from a BB to the best insertion points for the271  // subtree of BB (subtree not including the BB itself).272  DenseMap<BasicBlock *, InsertPtsCostPair> InsertPtsMap;273  InsertPtsMap.reserve(Orders.size() + 1);274  for (BasicBlock *Node : llvm::reverse(Orders)) {275    bool NodeInBBs = BBs.count(Node);276    auto &[InsertPts, InsertPtsFreq] = InsertPtsMap[Node];277 278    // Return the optimal insert points in BBs.279    if (Node == Entry) {280      BBs.clear();281      if (InsertPtsFreq > BFI.getBlockFreq(Node) ||282          (InsertPtsFreq == BFI.getBlockFreq(Node) && InsertPts.size() > 1))283        BBs.insert(Entry);284      else285        BBs.insert_range(InsertPts);286      break;287    }288 289    BasicBlock *Parent = DT.getNode(Node)->getIDom()->getBlock();290    // Initially, ParentInsertPts is empty and ParentPtsFreq is 0. Every child291    // will update its parent's ParentInsertPts and ParentPtsFreq.292    auto &[ParentInsertPts, ParentPtsFreq] = InsertPtsMap[Parent];293    // Choose to insert in Node or in subtree of Node.294    // Don't hoist to EHPad because we may not find a proper place to insert295    // in EHPad.296    // If the total frequency of InsertPts is the same as the frequency of the297    // target Node, and InsertPts contains more than one nodes, choose hoisting298    // to reduce code size.299    if (NodeInBBs ||300        (!Node->isEHPad() &&301         (InsertPtsFreq > BFI.getBlockFreq(Node) ||302          (InsertPtsFreq == BFI.getBlockFreq(Node) && InsertPts.size() > 1)))) {303      ParentInsertPts.insert(Node);304      ParentPtsFreq += BFI.getBlockFreq(Node);305    } else {306      ParentInsertPts.insert_range(InsertPts);307      ParentPtsFreq += InsertPtsFreq;308    }309  }310}311 312/// Find an insertion point that dominates all uses.313SetVector<BasicBlock::iterator>314ConstantHoistingPass::findConstantInsertionPoint(315    const ConstantInfo &ConstInfo,316    const ArrayRef<BasicBlock::iterator> MatInsertPts) const {317  assert(!ConstInfo.RebasedConstants.empty() && "Invalid constant info entry.");318  // Collect all basic blocks.319  SetVector<BasicBlock *> BBs;320  SetVector<BasicBlock::iterator> InsertPts;321 322  for (BasicBlock::iterator MatInsertPt : MatInsertPts)323    BBs.insert(MatInsertPt->getParent());324 325  if (BBs.count(Entry)) {326    InsertPts.insert(Entry->begin());327    return InsertPts;328  }329 330  if (BFI) {331    findBestInsertionSet(*DT, *BFI, Entry, BBs);332    for (BasicBlock *BB : BBs)333      InsertPts.insert(BB->getFirstInsertionPt());334    return InsertPts;335  }336 337  while (BBs.size() >= 2) {338    BasicBlock *BB, *BB1, *BB2;339    BB1 = BBs.pop_back_val();340    BB2 = BBs.pop_back_val();341    BB = DT->findNearestCommonDominator(BB1, BB2);342    if (BB == Entry) {343      InsertPts.insert(Entry->begin());344      return InsertPts;345    }346    BBs.insert(BB);347  }348  assert((BBs.size() == 1) && "Expected only one element.");349  Instruction &FirstInst = (*BBs.begin())->front();350  InsertPts.insert(findMatInsertPt(&FirstInst));351  return InsertPts;352}353 354/// Record constant integer ConstInt for instruction Inst at operand355/// index Idx.356///357/// The operand at index Idx is not necessarily the constant integer itself. It358/// could also be a cast instruction or a constant expression that uses the359/// constant integer.360void ConstantHoistingPass::collectConstantCandidates(361    ConstCandMapType &ConstCandMap, Instruction *Inst, unsigned Idx,362    ConstantInt *ConstInt) {363  if (ConstInt->getType()->isVectorTy())364    return;365 366  InstructionCost Cost;367  // Ask the target about the cost of materializing the constant for the given368  // instruction and operand index.369  if (auto IntrInst = dyn_cast<IntrinsicInst>(Inst))370    Cost = TTI->getIntImmCostIntrin(IntrInst->getIntrinsicID(), Idx,371                                    ConstInt->getValue(), ConstInt->getType(),372                                    TargetTransformInfo::TCK_SizeAndLatency);373  else374    Cost = TTI->getIntImmCostInst(375        Inst->getOpcode(), Idx, ConstInt->getValue(), ConstInt->getType(),376        TargetTransformInfo::TCK_SizeAndLatency, Inst);377 378  // Ignore cheap integer constants.379  if (Cost > TargetTransformInfo::TCC_Basic) {380    ConstCandMapType::iterator Itr;381    bool Inserted;382    ConstPtrUnionType Cand = ConstInt;383    std::tie(Itr, Inserted) = ConstCandMap.try_emplace(Cand);384    if (Inserted) {385      ConstIntCandVec.push_back(ConstantCandidate(ConstInt));386      Itr->second = ConstIntCandVec.size() - 1;387    }388    ConstIntCandVec[Itr->second].addUser(Inst, Idx, Cost.getValue());389    LLVM_DEBUG(if (isa<ConstantInt>(Inst->getOperand(Idx))) dbgs()390                   << "Collect constant " << *ConstInt << " from " << *Inst391                   << " with cost " << Cost << '\n';392               else dbgs() << "Collect constant " << *ConstInt393                           << " indirectly from " << *Inst << " via "394                           << *Inst->getOperand(Idx) << " with cost " << Cost395                           << '\n';);396  }397}398 399/// Record constant GEP expression for instruction Inst at operand index Idx.400void ConstantHoistingPass::collectConstantCandidates(401    ConstCandMapType &ConstCandMap, Instruction *Inst, unsigned Idx,402    ConstantExpr *ConstExpr) {403  // TODO: Handle vector GEPs404  if (ConstExpr->getType()->isVectorTy())405    return;406 407  GlobalVariable *BaseGV = dyn_cast<GlobalVariable>(ConstExpr->getOperand(0));408  if (!BaseGV)409    return;410 411  // Get offset from the base GV.412  PointerType *GVPtrTy = cast<PointerType>(BaseGV->getType());413  IntegerType *OffsetTy = DL->getIndexType(*Ctx, GVPtrTy->getAddressSpace());414  APInt Offset(DL->getTypeSizeInBits(OffsetTy), /*val*/ 0, /*isSigned*/ true);415  auto *GEPO = cast<GEPOperator>(ConstExpr);416 417  // TODO: If we have a mix of inbounds and non-inbounds GEPs, then basing a418  // non-inbounds GEP on an inbounds GEP is potentially incorrect. Restrict to419  // inbounds GEP for now -- alternatively, we could drop inbounds from the420  // constant expression,421  if (!GEPO->isInBounds())422    return;423 424  if (!GEPO->accumulateConstantOffset(*DL, Offset))425    return;426 427  if (!Offset.isIntN(32))428    return;429 430  // A constant GEP expression that has a GlobalVariable as base pointer is431  // usually lowered to a load from constant pool. Such operation is unlikely432  // to be cheaper than compute it by <Base + Offset>, which can be lowered to433  // an ADD instruction or folded into Load/Store instruction.434  InstructionCost Cost =435      TTI->getIntImmCostInst(Instruction::Add, 1, Offset, OffsetTy,436                             TargetTransformInfo::TCK_SizeAndLatency, Inst);437  ConstCandVecType &ExprCandVec = ConstGEPCandMap[BaseGV];438  ConstCandMapType::iterator Itr;439  bool Inserted;440  ConstPtrUnionType Cand = ConstExpr;441  std::tie(Itr, Inserted) = ConstCandMap.try_emplace(Cand);442  if (Inserted) {443    ExprCandVec.push_back(ConstantCandidate(444        ConstantInt::get(Type::getInt32Ty(*Ctx), Offset.getLimitedValue()),445        ConstExpr));446    Itr->second = ExprCandVec.size() - 1;447  }448  ExprCandVec[Itr->second].addUser(Inst, Idx, Cost.getValue());449}450 451/// Check the operand for instruction Inst at index Idx.452void ConstantHoistingPass::collectConstantCandidates(453    ConstCandMapType &ConstCandMap, Instruction *Inst, unsigned Idx) {454  Value *Opnd = Inst->getOperand(Idx);455 456  // Visit constant integers.457  if (auto ConstInt = dyn_cast<ConstantInt>(Opnd)) {458    collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt);459    return;460  }461 462  // Visit cast instructions that have constant integers.463  if (auto CastInst = dyn_cast<Instruction>(Opnd)) {464    // Only visit cast instructions, which have been skipped. All other465    // instructions should have already been visited.466    if (!CastInst->isCast())467      return;468 469    if (auto *ConstInt = dyn_cast<ConstantInt>(CastInst->getOperand(0))) {470      // Pretend the constant is directly used by the instruction and ignore471      // the cast instruction.472      collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt);473      return;474    }475  }476 477  // Visit constant expressions that have constant integers.478  if (auto ConstExpr = dyn_cast<ConstantExpr>(Opnd)) {479    // Handle constant gep expressions.480    if (ConstHoistGEP && isa<GEPOperator>(ConstExpr))481      collectConstantCandidates(ConstCandMap, Inst, Idx, ConstExpr);482 483    // Only visit constant cast expressions.484    if (!ConstExpr->isCast())485      return;486 487    if (auto ConstInt = dyn_cast<ConstantInt>(ConstExpr->getOperand(0))) {488      // Pretend the constant is directly used by the instruction and ignore489      // the constant expression.490      collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt);491      return;492    }493  }494}495 496/// Scan the instruction for expensive integer constants and record them497/// in the constant candidate vector.498void ConstantHoistingPass::collectConstantCandidates(499    ConstCandMapType &ConstCandMap, Instruction *Inst) {500  // Skip all cast instructions. They are visited indirectly later on.501  if (Inst->isCast())502    return;503 504  // Scan all operands.505  for (unsigned Idx = 0, E = Inst->getNumOperands(); Idx != E; ++Idx) {506    // The cost of materializing the constants (defined in507    // `TargetTransformInfo::getIntImmCostInst`) for instructions which only508    // take constant variables is lower than `TargetTransformInfo::TCC_Basic`.509    // So it's safe for us to collect constant candidates from all510    // IntrinsicInsts.511    if (canReplaceOperandWithVariable(Inst, Idx)) {512      collectConstantCandidates(ConstCandMap, Inst, Idx);513    }514  } // end of for all operands515}516 517/// Collect all integer constants in the function that cannot be folded518/// into an instruction itself.519void ConstantHoistingPass::collectConstantCandidates(Function &Fn) {520  ConstCandMapType ConstCandMap;521  for (BasicBlock &BB : Fn) {522    // Ignore unreachable basic blocks.523    if (!DT->isReachableFromEntry(&BB))524      continue;525    for (Instruction &Inst : BB)526      if (!TTI->preferToKeepConstantsAttached(Inst, Fn))527        collectConstantCandidates(ConstCandMap, &Inst);528  }529}530 531// From a list of constants, one needs to picked as the base and the other532// constants will be transformed into an offset from that base constant. The533// question is which we can pick best? For example, consider these constants534// and their number of uses:535//536//  Constants| 2 | 4 | 12 | 42 |537//  NumUses  | 3 | 2 |  8 |  7 |538//539// Selecting constant 12 because it has the most uses will generate negative540// offsets for constants 2 and 4 (i.e. -10 and -8 respectively). If negative541// offsets lead to less optimal code generation, then there might be better542// solutions. Suppose immediates in the range of 0..35 are most optimally543// supported by the architecture, then selecting constant 2 is most optimal544// because this will generate offsets: 0, 2, 10, 40. Offsets 0, 2 and 10 are in545// range 0..35, and thus 3 + 2 + 8 = 13 uses are in range. Selecting 12 would546// have only 8 uses in range, so choosing 2 as a base is more optimal. Thus, in547// selecting the base constant the range of the offsets is a very important548// factor too that we take into account here. This algorithm calculates a total549// costs for selecting a constant as the base and substract the costs if550// immediates are out of range. It has quadratic complexity, so we call this551// function only when we're optimising for size and there are less than 100552// constants, we fall back to the straightforward algorithm otherwise553// which does not do all the offset calculations.554unsigned555ConstantHoistingPass::maximizeConstantsInRange(ConstCandVecType::iterator S,556                                           ConstCandVecType::iterator E,557                                           ConstCandVecType::iterator &MaxCostItr) {558  unsigned NumUses = 0;559 560  if (!OptForSize || std::distance(S,E) > 100) {561    for (auto ConstCand = S; ConstCand != E; ++ConstCand) {562      NumUses += ConstCand->Uses.size();563      if (ConstCand->CumulativeCost > MaxCostItr->CumulativeCost)564        MaxCostItr = ConstCand;565    }566    return NumUses;567  }568 569  LLVM_DEBUG(dbgs() << "== Maximize constants in range ==\n");570  InstructionCost MaxCost = -1;571  for (auto ConstCand = S; ConstCand != E; ++ConstCand) {572    auto Value = ConstCand->ConstInt->getValue();573    Type *Ty = ConstCand->ConstInt->getType();574    InstructionCost Cost = 0;575    NumUses += ConstCand->Uses.size();576    LLVM_DEBUG(dbgs() << "= Constant: " << ConstCand->ConstInt->getValue()577                      << "\n");578 579    for (auto User : ConstCand->Uses) {580      unsigned Opcode = User.Inst->getOpcode();581      unsigned OpndIdx = User.OpndIdx;582      Cost += TTI->getIntImmCostInst(Opcode, OpndIdx, Value, Ty,583                                     TargetTransformInfo::TCK_SizeAndLatency);584      LLVM_DEBUG(dbgs() << "Cost: " << Cost << "\n");585 586      for (auto C2 = S; C2 != E; ++C2) {587        APInt Diff = C2->ConstInt->getValue() - ConstCand->ConstInt->getValue();588        const InstructionCost ImmCosts =589            TTI->getIntImmCodeSizeCost(Opcode, OpndIdx, Diff, Ty);590        Cost -= ImmCosts;591        LLVM_DEBUG(dbgs() << "Offset " << Diff << " "592                          << "has penalty: " << ImmCosts << "\n"593                          << "Adjusted cost: " << Cost << "\n");594      }595    }596    LLVM_DEBUG(dbgs() << "Cumulative cost: " << Cost << "\n");597    if (Cost > MaxCost) {598      MaxCost = Cost;599      MaxCostItr = ConstCand;600      LLVM_DEBUG(dbgs() << "New candidate: " << MaxCostItr->ConstInt->getValue()601                        << "\n");602    }603  }604  return NumUses;605}606 607/// Find the base constant within the given range and rebase all other608/// constants with respect to the base constant.609void ConstantHoistingPass::findAndMakeBaseConstant(610    ConstCandVecType::iterator S, ConstCandVecType::iterator E,611    SmallVectorImpl<consthoist::ConstantInfo> &ConstInfoVec) {612  auto MaxCostItr = S;613  unsigned NumUses = maximizeConstantsInRange(S, E, MaxCostItr);614 615  // Don't hoist constants that have only one use.616  if (NumUses <= 1)617    return;618 619  ConstantInt *ConstInt = MaxCostItr->ConstInt;620  ConstantExpr *ConstExpr = MaxCostItr->ConstExpr;621  ConstantInfo ConstInfo;622  ConstInfo.BaseInt = ConstInt;623  ConstInfo.BaseExpr = ConstExpr;624  Type *Ty = ConstInt->getType();625 626  // Rebase the constants with respect to the base constant.627  for (auto ConstCand = S; ConstCand != E; ++ConstCand) {628    APInt Diff = ConstCand->ConstInt->getValue() - ConstInt->getValue();629    Constant *Offset = Diff == 0 ? nullptr : ConstantInt::get(Ty, Diff);630    Type *ConstTy =631        ConstCand->ConstExpr ? ConstCand->ConstExpr->getType() : nullptr;632    ConstInfo.RebasedConstants.push_back(633      RebasedConstantInfo(std::move(ConstCand->Uses), Offset, ConstTy));634  }635  ConstInfoVec.push_back(std::move(ConstInfo));636}637 638/// Finds and combines constant candidates that can be easily639/// rematerialized with an add from a common base constant.640void ConstantHoistingPass::findBaseConstants(GlobalVariable *BaseGV) {641  // If BaseGV is nullptr, find base among candidate constant integers;642  // Otherwise find base among constant GEPs that share the same BaseGV.643  ConstCandVecType &ConstCandVec = BaseGV ?644      ConstGEPCandMap[BaseGV] : ConstIntCandVec;645  ConstInfoVecType &ConstInfoVec = BaseGV ?646      ConstGEPInfoMap[BaseGV] : ConstIntInfoVec;647 648  // Sort the constants by value and type. This invalidates the mapping!649  llvm::stable_sort(ConstCandVec, [](const ConstantCandidate &LHS,650                                     const ConstantCandidate &RHS) {651    if (LHS.ConstInt->getType() != RHS.ConstInt->getType())652      return LHS.ConstInt->getBitWidth() < RHS.ConstInt->getBitWidth();653    return LHS.ConstInt->getValue().ult(RHS.ConstInt->getValue());654  });655 656  // Simple linear scan through the sorted constant candidate vector for viable657  // merge candidates.658  auto MinValItr = ConstCandVec.begin();659  for (auto CC = std::next(ConstCandVec.begin()), E = ConstCandVec.end();660       CC != E; ++CC) {661    if (MinValItr->ConstInt->getType() == CC->ConstInt->getType()) {662      Type *MemUseValTy = nullptr;663      for (auto &U : CC->Uses) {664        auto *UI = U.Inst;665        if (LoadInst *LI = dyn_cast<LoadInst>(UI)) {666          MemUseValTy = LI->getType();667          break;668        } else if (StoreInst *SI = dyn_cast<StoreInst>(UI)) {669          // Make sure the constant is used as pointer operand of the StoreInst.670          if (SI->getPointerOperand() == SI->getOperand(U.OpndIdx)) {671            MemUseValTy = SI->getValueOperand()->getType();672            break;673          }674        }675      }676 677      // Check if the constant is in range of an add with immediate.678      APInt Diff = CC->ConstInt->getValue() - MinValItr->ConstInt->getValue();679      if ((Diff.getBitWidth() <= 64) &&680          TTI->isLegalAddImmediate(Diff.getSExtValue()) &&681          // Check if Diff can be used as offset in addressing mode of the user682          // memory instruction.683          (!MemUseValTy || TTI->isLegalAddressingMode(MemUseValTy,684           /*BaseGV*/nullptr, /*BaseOffset*/Diff.getSExtValue(),685           /*HasBaseReg*/true, /*Scale*/0)))686        continue;687    }688    // We either have now a different constant type or the constant is not in689    // range of an add with immediate anymore.690    findAndMakeBaseConstant(MinValItr, CC, ConstInfoVec);691    // Start a new base constant search.692    MinValItr = CC;693  }694  // Finalize the last base constant search.695  findAndMakeBaseConstant(MinValItr, ConstCandVec.end(), ConstInfoVec);696}697 698/// Updates the operand at Idx in instruction Inst with the result of699///        instruction Mat. If the instruction is a PHI node then special700///        handling for duplicate values from the same incoming basic block is701///        required.702/// \return The update will always succeed, but the return value indicated if703///         Mat was used for the update or not.704static bool updateOperand(Instruction *Inst, unsigned Idx, Instruction *Mat) {705  if (auto PHI = dyn_cast<PHINode>(Inst)) {706    // Check if any previous operand of the PHI node has the same incoming basic707    // block. This is a very odd case that happens when the incoming basic block708    // has a switch statement. In this case use the same value as the previous709    // operand(s), otherwise we will fail verification due to different values.710    // The values are actually the same, but the variable names are different711    // and the verifier doesn't like that.712    BasicBlock *IncomingBB = PHI->getIncomingBlock(Idx);713    for (unsigned i = 0; i < Idx; ++i) {714      if (PHI->getIncomingBlock(i) == IncomingBB) {715        Value *IncomingVal = PHI->getIncomingValue(i);716        Inst->setOperand(Idx, IncomingVal);717        return false;718      }719    }720  }721 722  Inst->setOperand(Idx, Mat);723  return true;724}725 726/// Emit materialization code for all rebased constants and update their727/// users.728void ConstantHoistingPass::emitBaseConstants(Instruction *Base,729                                             UserAdjustment *Adj) {730  Instruction *Mat = Base;731 732  // The same offset can be dereferenced to different types in nested struct.733  if (!Adj->Offset && Adj->Ty && Adj->Ty != Base->getType())734    Adj->Offset = ConstantInt::get(Type::getInt32Ty(*Ctx), 0);735 736  if (Adj->Offset) {737    if (Adj->Ty) {738      // Constant being rebased is a ConstantExpr.739      Mat = GetElementPtrInst::Create(Type::getInt8Ty(*Ctx), Base, Adj->Offset,740                                      "mat_gep", Adj->MatInsertPt);741      // Hide it behind a bitcast.742      Mat = new BitCastInst(Mat, Adj->Ty, "mat_bitcast",743                            Adj->MatInsertPt->getIterator());744    } else745      // Constant being rebased is a ConstantInt.746      Mat =747          BinaryOperator::Create(Instruction::Add, Base, Adj->Offset,748                                 "const_mat", Adj->MatInsertPt->getIterator());749 750    LLVM_DEBUG(dbgs() << "Materialize constant (" << *Base->getOperand(0)751                      << " + " << *Adj->Offset << ") in BB "752                      << Mat->getParent()->getName() << '\n'753                      << *Mat << '\n');754    Mat->setDebugLoc(Adj->User.Inst->getDebugLoc());755  }756  Value *Opnd = Adj->User.Inst->getOperand(Adj->User.OpndIdx);757 758  // Visit constant integer.759  if (isa<ConstantInt>(Opnd)) {760    LLVM_DEBUG(dbgs() << "Update: " << *Adj->User.Inst << '\n');761    if (!updateOperand(Adj->User.Inst, Adj->User.OpndIdx, Mat) && Adj->Offset)762      Mat->eraseFromParent();763    LLVM_DEBUG(dbgs() << "To    : " << *Adj->User.Inst << '\n');764    return;765  }766 767  // Visit cast instruction.768  if (auto CastInst = dyn_cast<Instruction>(Opnd)) {769    assert(CastInst->isCast() && "Expected an cast instruction!");770    // Check if we already have visited this cast instruction before to avoid771    // unnecessary cloning.772    Instruction *&ClonedCastInst = ClonedCastMap[CastInst];773    if (!ClonedCastInst) {774      ClonedCastInst = CastInst->clone();775      ClonedCastInst->setOperand(0, Mat);776      ClonedCastInst->insertAfter(CastInst->getIterator());777      // Use the same debug location as the original cast instruction.778      ClonedCastInst->setDebugLoc(CastInst->getDebugLoc());779      LLVM_DEBUG(dbgs() << "Clone instruction: " << *CastInst << '\n'780                        << "To               : " << *ClonedCastInst << '\n');781    }782 783    LLVM_DEBUG(dbgs() << "Update: " << *Adj->User.Inst << '\n');784    updateOperand(Adj->User.Inst, Adj->User.OpndIdx, ClonedCastInst);785    LLVM_DEBUG(dbgs() << "To    : " << *Adj->User.Inst << '\n');786    return;787  }788 789  // Visit constant expression.790  if (auto ConstExpr = dyn_cast<ConstantExpr>(Opnd)) {791    if (isa<GEPOperator>(ConstExpr)) {792      // Operand is a ConstantGEP, replace it.793      updateOperand(Adj->User.Inst, Adj->User.OpndIdx, Mat);794      return;795    }796 797    // Aside from constant GEPs, only constant cast expressions are collected.798    assert(ConstExpr->isCast() && "ConstExpr should be a cast");799    Instruction *ConstExprInst = ConstExpr->getAsInstruction();800    ConstExprInst->insertBefore(Adj->MatInsertPt);801    ConstExprInst->setOperand(0, Mat);802 803    // Use the same debug location as the instruction we are about to update.804    ConstExprInst->setDebugLoc(Adj->User.Inst->getDebugLoc());805 806    LLVM_DEBUG(dbgs() << "Create instruction: " << *ConstExprInst << '\n'807                      << "From              : " << *ConstExpr << '\n');808    LLVM_DEBUG(dbgs() << "Update: " << *Adj->User.Inst << '\n');809    if (!updateOperand(Adj->User.Inst, Adj->User.OpndIdx, ConstExprInst)) {810      ConstExprInst->eraseFromParent();811      if (Adj->Offset)812        Mat->eraseFromParent();813    }814    LLVM_DEBUG(dbgs() << "To    : " << *Adj->User.Inst << '\n');815    return;816  }817}818 819/// Hoist and hide the base constant behind a bitcast and emit820/// materialization code for derived constants.821bool ConstantHoistingPass::emitBaseConstants(GlobalVariable *BaseGV) {822  bool MadeChange = false;823  SmallVectorImpl<consthoist::ConstantInfo> &ConstInfoVec =824      BaseGV ? ConstGEPInfoMap[BaseGV] : ConstIntInfoVec;825  for (const consthoist::ConstantInfo &ConstInfo : ConstInfoVec) {826    SmallVector<BasicBlock::iterator, 4> MatInsertPts;827    collectMatInsertPts(ConstInfo.RebasedConstants, MatInsertPts);828    SetVector<BasicBlock::iterator> IPSet =829        findConstantInsertionPoint(ConstInfo, MatInsertPts);830    // We can have an empty set if the function contains unreachable blocks.831    if (IPSet.empty())832      continue;833 834    unsigned UsesNum = 0;835    unsigned ReBasesNum = 0;836    unsigned NotRebasedNum = 0;837    for (const BasicBlock::iterator &IP : IPSet) {838      // First, collect constants depending on this IP of the base.839      UsesNum = 0;840      SmallVector<UserAdjustment, 4> ToBeRebased;841      unsigned MatCtr = 0;842      for (auto const &RCI : ConstInfo.RebasedConstants) {843        UsesNum += RCI.Uses.size();844        for (auto const &U : RCI.Uses) {845          const BasicBlock::iterator &MatInsertPt = MatInsertPts[MatCtr++];846          BasicBlock *OrigMatInsertBB = MatInsertPt->getParent();847          // If Base constant is to be inserted in multiple places,848          // generate rebase for U using the Base dominating U.849          if (IPSet.size() == 1 ||850              DT->dominates(IP->getParent(), OrigMatInsertBB))851            ToBeRebased.emplace_back(RCI.Offset, RCI.Ty, MatInsertPt, U);852        }853      }854 855      // If only few constants depend on this IP of base, skip rebasing,856      // assuming the base and the rebased have the same materialization cost.857      if (ToBeRebased.size() < MinNumOfDependentToRebase) {858        NotRebasedNum += ToBeRebased.size();859        continue;860      }861 862      // Emit an instance of the base at this IP.863      Instruction *Base = nullptr;864      // Hoist and hide the base constant behind a bitcast.865      if (ConstInfo.BaseExpr) {866        assert(BaseGV && "A base constant expression must have an base GV");867        Type *Ty = ConstInfo.BaseExpr->getType();868        Base = new BitCastInst(ConstInfo.BaseExpr, Ty, "const", IP);869      } else {870        IntegerType *Ty = ConstInfo.BaseInt->getIntegerType();871        Base = new BitCastInst(ConstInfo.BaseInt, Ty, "const", IP);872      }873 874      Base->setDebugLoc(IP->getDebugLoc());875 876      LLVM_DEBUG(dbgs() << "Hoist constant (" << *ConstInfo.BaseInt877                        << ") to BB " << IP->getParent()->getName() << '\n'878                        << *Base << '\n');879 880      // Emit materialization code for rebased constants depending on this IP.881      for (UserAdjustment &R : ToBeRebased) {882        emitBaseConstants(Base, &R);883        ReBasesNum++;884        // Use the same debug location as the last user of the constant.885        Base->setDebugLoc(DebugLoc::getMergedLocation(886            Base->getDebugLoc(), R.User.Inst->getDebugLoc()));887      }888      assert(!Base->use_empty() && "The use list is empty!?");889      assert(isa<Instruction>(Base->user_back()) &&890             "All uses should be instructions.");891    }892    (void)UsesNum;893    (void)ReBasesNum;894    (void)NotRebasedNum;895    // Expect all uses are rebased after rebase is done.896    assert(UsesNum == (ReBasesNum + NotRebasedNum) &&897           "Not all uses are rebased");898 899    NumConstantsHoisted++;900 901    // Base constant is also included in ConstInfo.RebasedConstants, so902    // deduct 1 from ConstInfo.RebasedConstants.size().903    NumConstantsRebased += ConstInfo.RebasedConstants.size() - 1;904 905    MadeChange = true;906  }907  return MadeChange;908}909 910/// Check all cast instructions we made a copy of and remove them if they911/// have no more users.912void ConstantHoistingPass::deleteDeadCastInst() const {913  for (auto const &I : ClonedCastMap)914    if (I.first->use_empty())915      I.first->eraseFromParent();916}917 918/// Optimize expensive integer constants in the given function.919bool ConstantHoistingPass::runImpl(Function &Fn, TargetTransformInfo &TTI,920                                   DominatorTree &DT, BlockFrequencyInfo *BFI,921                                   BasicBlock &Entry, ProfileSummaryInfo *PSI) {922  this->TTI = &TTI;923  this->DT = &DT;924  this->BFI = BFI;925  this->DL = &Fn.getDataLayout();926  this->Ctx = &Fn.getContext();927  this->Entry = &Entry;928  this->PSI = PSI;929  this->OptForSize = llvm::shouldOptimizeForSize(Entry.getParent(), PSI, BFI,930                                                 PGSOQueryType::IRPass);931 932  // Collect all constant candidates.933  collectConstantCandidates(Fn);934 935  // Combine constants that can be easily materialized with an add from a common936  // base constant.937  if (!ConstIntCandVec.empty())938    findBaseConstants(nullptr);939  for (const auto &MapEntry : ConstGEPCandMap)940    if (!MapEntry.second.empty())941      findBaseConstants(MapEntry.first);942 943  // Finally hoist the base constant and emit materialization code for dependent944  // constants.945  bool MadeChange = false;946  if (!ConstIntInfoVec.empty())947    MadeChange = emitBaseConstants(nullptr);948  for (const auto &MapEntry : ConstGEPInfoMap)949    if (!MapEntry.second.empty())950      MadeChange |= emitBaseConstants(MapEntry.first);951 952 953  // Cleanup dead instructions.954  deleteDeadCastInst();955 956  cleanup();957 958  return MadeChange;959}960 961PreservedAnalyses ConstantHoistingPass::run(Function &F,962                                            FunctionAnalysisManager &AM) {963  auto &DT = AM.getResult<DominatorTreeAnalysis>(F);964  auto &TTI = AM.getResult<TargetIRAnalysis>(F);965  auto BFI = ConstHoistWithBlockFrequency966                 ? &AM.getResult<BlockFrequencyAnalysis>(F)967                 : nullptr;968  auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);969  auto *PSI = MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());970  if (!runImpl(F, TTI, DT, BFI, F.getEntryBlock(), PSI))971    return PreservedAnalyses::all();972 973  PreservedAnalyses PA;974  PA.preserveSet<CFGAnalyses>();975  return PA;976}977