136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===- ConstantHoisting.cpp - Prepare code for expensive constants --------===// 236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// The LLVM Compiler Infrastructure 436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file is distributed under the University of Illinois Open Source 636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// License. See LICENSE.TXT for details. 736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===// 936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This pass identifies expensive constants to hoist and coalesces them to 1136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// better prepare it for SelectionDAG-based code generation. This works around 1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// the limitations of the basic-block-at-a-time approach. 1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// First it scans all instructions for integer constants and calculates its 1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// cost. If the constant can be folded into the instruction (the cost is 1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// TCC_Free) or the cost is just a simple operation (TCC_BASIC), then we don't 1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// consider it expensive and leave it alone. This is the default behavior and 1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// the default implementation of getIntImmCost will always return TCC_Free. 1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// If the cost is more than TCC_BASIC, then the integer constant can't be folded 2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// into the instruction and it might be beneficial to hoist the constant. 2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Similar constants are coalesced to reduce register pressure and 2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// materialization code. 2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// When a constant is hoisted, it is also hidden behind a bitcast to force it to 2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// be live-out of the basic block. Otherwise the constant would be just 2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// duplicated and each basic block would have its own copy in the SelectionDAG. 2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// The SelectionDAG recognizes such constants as opaque and doesn't perform 2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// certain transformations on them, which would create a new expensive constant. 3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This optimization is only applied to integer constants in instructions and 3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// simple (this means not nested) constant cast expressions. For example: 3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// %0 = load i64* inttoptr (i64 big_constant to i64*) 3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===// 3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 36de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Transforms/Scalar/ConstantHoisting.h" 3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/SmallSet.h" 3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/SmallVector.h" 3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/Statistic.h" 4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Constants.h" 4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/IntrinsicInst.h" 4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Pass.h" 4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/Debug.h" 444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Support/raw_ostream.h" 45de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Transforms/Scalar.h" 46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include <tuple> 4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesusing namespace llvm; 49de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarusing namespace consthoist; 5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "consthoist" 52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesSTATISTIC(NumConstantsHoisted, "Number of constants hoisted"); 5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesSTATISTIC(NumConstantsRebased, "Number of constants rebased"); 5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace { 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief The constant hoisting pass. 58de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarclass ConstantHoistingLegacyPass : public FunctionPass { 5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic: 6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines static char ID; // Pass identification, replacement for typeid 61de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstantHoistingLegacyPass() : FunctionPass(ID) { 62de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar initializeConstantHoistingLegacyPassPass(*PassRegistry::getPassRegistry()); 6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnFunction(Function &Fn) override; 6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *getPassName() const override { return "Constant Hoisting"; } 6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AU.setPreservesCFG(); 7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AU.addRequired<DominatorTreeWrapperPass>(); 72ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AU.addRequired<TargetTransformInfoWrapperPass>(); 7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 75de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void releaseMemory() override { Impl.releaseMemory(); } 7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 77de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarprivate: 78de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstantHoistingPass Impl; 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 82de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarchar ConstantHoistingLegacyPass::ID = 0; 83de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarINITIALIZE_PASS_BEGIN(ConstantHoistingLegacyPass, "consthoist", 84de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "Constant Hoisting", false, false) 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesINITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 86ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) 87de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarINITIALIZE_PASS_END(ConstantHoistingLegacyPass, "consthoist", 88de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "Constant Hoisting", false, false) 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesFunctionPass *llvm::createConstantHoistingPass() { 91de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return new ConstantHoistingLegacyPass(); 9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Perform the constant hoisting optimization for the given function. 95de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool ConstantHoistingLegacyPass::runOnFunction(Function &Fn) { 96de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (skipFunction(Fn)) 97ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 98ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "********** Begin Constant Hoisting **********\n"); 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "********** Function: " << Fn.getName() << '\n'); 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 102de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool MadeChange = Impl.runImpl( 103de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Fn, getAnalysis<TargetTransformInfoWrapperPass>().getTTI(Fn), 104de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar getAnalysis<DominatorTreeWrapperPass>().getDomTree(), Fn.getEntryBlock()); 10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MadeChange) { 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "********** Function after Constant Hoisting: " 10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << Fn.getName() << '\n'); 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << Fn); 11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "********** End Constant Hoisting **********\n"); 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MadeChange; 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Find the constant materialization insertion point. 118de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarInstruction *ConstantHoistingPass::findMatInsertPt(Instruction *Inst, 119de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned Idx) const { 120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // If the operand is a cast instruction, then we have to materialize the 121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // constant before the cast instruction. 122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Idx != ~0U) { 123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value *Opnd = Inst->getOperand(Idx); 124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (auto CastInst = dyn_cast<Instruction>(Opnd)) 125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (CastInst->isCast()) 126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return CastInst; 127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // The simple and common case. This also includes constant expressions. 130f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!isa<PHINode>(Inst) && !Inst->isEHPad()) 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Inst; 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 133f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // We can't insert directly before a phi node or an eh pad. Insert before 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // the terminator of the incoming or dominating block. 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Entry != Inst->getParent() && "PHI or landing pad in entry block!"); 13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Idx != ~0U && isa<PHINode>(Inst)) 13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return cast<PHINode>(Inst)->getIncomingBlock(Idx)->getTerminator(); 13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BasicBlock *IDom = DT->getNode(Inst->getParent())->getIDom()->getBlock(); 14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return IDom->getTerminator(); 14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Find an insertion point that dominates all uses. 144de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarInstruction *ConstantHoistingPass::findConstantInsertionPoint( 145de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const ConstantInfo &ConstInfo) const { 14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(!ConstInfo.RebasedConstants.empty() && "Invalid constant info entry."); 14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Collect all basic blocks. 14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallPtrSet<BasicBlock *, 8> BBs; 14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto const &RCI : ConstInfo.RebasedConstants) 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto const &U : RCI.Uses) 151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines BBs.insert(findMatInsertPt(U.Inst, U.OpndIdx)->getParent()); 15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (BBs.count(Entry)) 15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return &Entry->front(); 15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines while (BBs.size() >= 2) { 15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BasicBlock *BB, *BB1, *BB2; 15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BB1 = *BBs.begin(); 15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BB2 = *std::next(BBs.begin()); 16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BB = DT->findNearestCommonDominator(BB1, BB2); 16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (BB == Entry) 16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return &Entry->front(); 16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BBs.erase(BB1); 16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BBs.erase(BB2); 16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BBs.insert(BB); 16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert((BBs.size() == 1) && "Expected only one element."); 16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction &FirstInst = (*BBs.begin())->front(); 16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return findMatInsertPt(&FirstInst); 17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Record constant integer ConstInt for instruction Inst at operand 17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// index Idx. 17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// 17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// The operand at index Idx is not necessarily the constant integer itself. It 17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// could also be a cast instruction or a constant expression that uses the 17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// constant integer. 179de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid ConstantHoistingPass::collectConstantCandidates( 180de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstCandMapType &ConstCandMap, Instruction *Inst, unsigned Idx, 181de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstantInt *ConstInt) { 18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Cost; 18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Ask the target about the cost of materializing the constant for the given 18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // instruction and operand index. 18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto IntrInst = dyn_cast<IntrinsicInst>(Inst)) 18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Cost = TTI->getIntImmCost(IntrInst->getIntrinsicID(), Idx, 18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstInt->getValue(), ConstInt->getType()); 18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Cost = TTI->getIntImmCost(Inst->getOpcode(), Idx, ConstInt->getValue(), 19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstInt->getType()); 19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Ignore cheap integer constants. 19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Cost > TargetTransformInfo::TCC_Basic) { 19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstCandMapType::iterator Itr; 19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool Inserted; 19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::tie(Itr, Inserted) = ConstCandMap.insert(std::make_pair(ConstInt, 0)); 19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Inserted) { 19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstCandVec.push_back(ConstantCandidate(ConstInt)); 19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Itr->second = ConstCandVec.size() - 1; 20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstCandVec[Itr->second].addUser(Inst, Idx, Cost); 20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(if (isa<ConstantInt>(Inst->getOperand(Idx))) 20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines dbgs() << "Collect constant " << *ConstInt << " from " << *Inst 20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " with cost " << Cost << '\n'; 20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines dbgs() << "Collect constant " << *ConstInt << " indirectly from " 20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << *Inst << " via " << *Inst->getOperand(Idx) << " with cost " 20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << Cost << '\n'; 20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ); 21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Scan the instruction for expensive integer constants and record them 21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// in the constant candidate vector. 215de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid ConstantHoistingPass::collectConstantCandidates( 216de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstCandMapType &ConstCandMap, Instruction *Inst) { 21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Skip all cast instructions. They are visited indirectly later on. 21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Inst->isCast()) 21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 22136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Can't handle inline asm. Skip it. 22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto Call = dyn_cast<CallInst>(Inst)) 22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isa<InlineAsm>(Call->getCalledValue())) 22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 226de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Switch cases must remain constant, and if the value being tested is 227de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // constant the entire thing should disappear. 228de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (isa<SwitchInst>(Inst)) 229de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return; 230de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 231de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Static allocas (constant size in the entry block) are handled by 232de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // prologue/epilogue insertion so they're free anyway. We definitely don't 233de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // want to make them non-constant. 234de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto AI = dyn_cast<AllocaInst>(Inst); 235de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (AI && AI->isStaticAlloca()) 236de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return; 237de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Scan all operands. 23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned Idx = 0, E = Inst->getNumOperands(); Idx != E; ++Idx) { 24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Opnd = Inst->getOperand(Idx); 24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Visit constant integers. 24336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto ConstInt = dyn_cast<ConstantInt>(Opnd)) { 24436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt); 24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Visit cast instructions that have constant integers. 24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto CastInst = dyn_cast<Instruction>(Opnd)) { 25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Only visit cast instructions, which have been skipped. All other 25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // instructions should have already been visited. 25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!CastInst->isCast()) 25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto *ConstInt = dyn_cast<ConstantInt>(CastInst->getOperand(0))) { 25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Pretend the constant is directly used by the instruction and ignore 25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // the cast instruction. 25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt); 25936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 26236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Visit constant expressions that have constant integers. 26436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto ConstExpr = dyn_cast<ConstantExpr>(Opnd)) { 26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Only visit constant cast expressions. 26636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!ConstExpr->isCast()) 26736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 26836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto ConstInt = dyn_cast<ConstantInt>(ConstExpr->getOperand(0))) { 27036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Pretend the constant is directly used by the instruction and ignore 27136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // the constant expression. 27236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt); 27336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 27436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 27536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 27636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } // end of for all operands 27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Collect all integer constants in the function that cannot be folded 28036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// into an instruction itself. 281de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid ConstantHoistingPass::collectConstantCandidates(Function &Fn) { 28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstCandMapType ConstCandMap; 283f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (BasicBlock &BB : Fn) 284f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (Instruction &Inst : BB) 285f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar collectConstantCandidates(ConstCandMap, &Inst); 28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 28736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 288de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// This helper function is necessary to deal with values that have different 289de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// bit widths (APInt Operator- does not like that). If the value cannot be 290de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// represented in uint64 we return an "empty" APInt. This is then interpreted 291de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// as the value is not in range. 292de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic llvm::Optional<APInt> calculateOffsetDiff(APInt V1, APInt V2) 293de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar{ 294de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar llvm::Optional<APInt> Res = None; 295de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned BW = V1.getBitWidth() > V2.getBitWidth() ? 296de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar V1.getBitWidth() : V2.getBitWidth(); 297de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar uint64_t LimVal1 = V1.getLimitedValue(); 298de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar uint64_t LimVal2 = V2.getLimitedValue(); 299de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 300de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (LimVal1 == ~0ULL || LimVal2 == ~0ULL) 301de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Res; 302de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 303de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar uint64_t Diff = LimVal1 - LimVal2; 304de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return APInt(BW, Diff, true); 305de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 306de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 307de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// From a list of constants, one needs to picked as the base and the other 308de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// constants will be transformed into an offset from that base constant. The 309de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// question is which we can pick best? For example, consider these constants 310de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// and their number of uses: 311de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// 312de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// Constants| 2 | 4 | 12 | 42 | 313de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// NumUses | 3 | 2 | 8 | 7 | 314de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// 315de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// Selecting constant 12 because it has the most uses will generate negative 316de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// offsets for constants 2 and 4 (i.e. -10 and -8 respectively). If negative 317de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// offsets lead to less optimal code generation, then there might be better 318de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// solutions. Suppose immediates in the range of 0..35 are most optimally 319de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// supported by the architecture, then selecting constant 2 is most optimal 320de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// because this will generate offsets: 0, 2, 10, 40. Offsets 0, 2 and 10 are in 321de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// range 0..35, and thus 3 + 2 + 8 = 13 uses are in range. Selecting 12 would 322de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// have only 8 uses in range, so choosing 2 as a base is more optimal. Thus, in 323de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// selecting the base constant the range of the offsets is a very important 324de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// factor too that we take into account here. This algorithm calculates a total 325de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// costs for selecting a constant as the base and substract the costs if 326de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// immediates are out of range. It has quadratic complexity, so we call this 327de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// function only when we're optimising for size and there are less than 100 328de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// constants, we fall back to the straightforward algorithm otherwise 329de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// which does not do all the offset calculations. 330de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarunsigned 331de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarConstantHoistingPass::maximizeConstantsInRange(ConstCandVecType::iterator S, 332de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstCandVecType::iterator E, 333de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstCandVecType::iterator &MaxCostItr) { 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned NumUses = 0; 335de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 336de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if(!Entry->getParent()->optForSize() || std::distance(S,E) > 100) { 337de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto ConstCand = S; ConstCand != E; ++ConstCand) { 338de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar NumUses += ConstCand->Uses.size(); 339de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (ConstCand->CumulativeCost > MaxCostItr->CumulativeCost) 340de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MaxCostItr = ConstCand; 341de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 342de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return NumUses; 343de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 344de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 345de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DEBUG(dbgs() << "== Maximize constants in range ==\n"); 346de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int MaxCost = -1; 34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto ConstCand = S; ConstCand != E; ++ConstCand) { 348de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto Value = ConstCand->ConstInt->getValue(); 349de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Type *Ty = ConstCand->ConstInt->getType(); 350de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int Cost = 0; 35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NumUses += ConstCand->Uses.size(); 352de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DEBUG(dbgs() << "= Constant: " << ConstCand->ConstInt->getValue() << "\n"); 353de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 354de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto User : ConstCand->Uses) { 355de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned Opcode = User.Inst->getOpcode(); 356de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned OpndIdx = User.OpndIdx; 357de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Cost += TTI->getIntImmCost(Opcode, OpndIdx, Value, Ty); 358de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DEBUG(dbgs() << "Cost: " << Cost << "\n"); 359de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 360de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto C2 = S; C2 != E; ++C2) { 361de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar llvm::Optional<APInt> Diff = calculateOffsetDiff( 362de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar C2->ConstInt->getValue(), 363de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstCand->ConstInt->getValue()); 364de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Diff) { 365de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const int ImmCosts = 366de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar TTI->getIntImmCodeSizeCost(Opcode, OpndIdx, Diff.getValue(), Ty); 367de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Cost -= ImmCosts; 368de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DEBUG(dbgs() << "Offset " << Diff.getValue() << " " 369de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar << "has penalty: " << ImmCosts << "\n" 370de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar << "Adjusted cost: " << Cost << "\n"); 371de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 372de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 373de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 374de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DEBUG(dbgs() << "Cumulative cost: " << Cost << "\n"); 375de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Cost > MaxCost) { 376de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MaxCost = Cost; 37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MaxCostItr = ConstCand; 378de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DEBUG(dbgs() << "New candidate: " << MaxCostItr->ConstInt->getValue() 379de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar << "\n"); 380de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 382de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return NumUses; 383de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 384de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 385de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar/// \brief Find the base constant within the given range and rebase all other 386de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar/// constants with respect to the base constant. 387de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid ConstantHoistingPass::findAndMakeBaseConstant( 388de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstCandVecType::iterator S, ConstCandVecType::iterator E) { 389de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto MaxCostItr = S; 390de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned NumUses = maximizeConstantsInRange(S, E, MaxCostItr); 39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 39236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Don't hoist constants that have only one use. 39336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (NumUses <= 1) 39436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 39536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstantInfo ConstInfo; 39736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstInfo.BaseConstant = MaxCostItr->ConstInt; 39836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Type *Ty = ConstInfo.BaseConstant->getType(); 39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 40036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Rebase the constants with respect to the base constant. 40136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto ConstCand = S; ConstCand != E; ++ConstCand) { 40236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines APInt Diff = ConstCand->ConstInt->getValue() - 40336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstInfo.BaseConstant->getValue(); 40436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Constant *Offset = Diff == 0 ? nullptr : ConstantInt::get(Ty, Diff); 40536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstInfo.RebasedConstants.push_back( 40636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RebasedConstantInfo(std::move(ConstCand->Uses), Offset)); 40736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 40837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ConstantVec.push_back(std::move(ConstInfo)); 40936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 41036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Finds and combines constant candidates that can be easily 41236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// rematerialized with an add from a common base constant. 413de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid ConstantHoistingPass::findBaseConstants() { 41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Sort the constants by value and type. This invalidates the mapping! 41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::sort(ConstCandVec.begin(), ConstCandVec.end(), 41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines [](const ConstantCandidate &LHS, const ConstantCandidate &RHS) { 41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (LHS.ConstInt->getType() != RHS.ConstInt->getType()) 41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return LHS.ConstInt->getType()->getBitWidth() < 41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RHS.ConstInt->getType()->getBitWidth(); 42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return LHS.ConstInt->getValue().ult(RHS.ConstInt->getValue()); 42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines }); 42236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 42336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Simple linear scan through the sorted constant candidate vector for viable 42436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // merge candidates. 42536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto MinValItr = ConstCandVec.begin(); 42636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto CC = std::next(ConstCandVec.begin()), E = ConstCandVec.end(); 42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CC != E; ++CC) { 42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MinValItr->ConstInt->getType() == CC->ConstInt->getType()) { 42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Check if the constant is in range of an add with immediate. 43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines APInt Diff = CC->ConstInt->getValue() - MinValItr->ConstInt->getValue(); 43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((Diff.getBitWidth() <= 64) && 43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TTI->isLegalAddImmediate(Diff.getSExtValue())) 43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We either have now a different constant type or the constant is not in 43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // range of an add with immediate anymore. 43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines findAndMakeBaseConstant(MinValItr, CC); 43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Start a new base constant search. 43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MinValItr = CC; 44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Finalize the last base constant search. 44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines findAndMakeBaseConstant(MinValItr, ConstCandVec.end()); 44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 44436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Updates the operand at Idx in instruction Inst with the result of 44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// instruction Mat. If the instruction is a PHI node then special 44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// handling for duplicate values form the same incomming basic block is 44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// required. 44936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \return The update will always succeed, but the return value indicated if 45036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// Mat was used for the update or not. 45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool updateOperand(Instruction *Inst, unsigned Idx, Instruction *Mat) { 45236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto PHI = dyn_cast<PHINode>(Inst)) { 45336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Check if any previous operand of the PHI node has the same incoming basic 45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // block. This is a very odd case that happens when the incoming basic block 45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // has a switch statement. In this case use the same value as the previous 45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // operand(s), otherwise we will fail verification due to different values. 45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The values are actually the same, but the variable names are different 45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // and the verifier doesn't like that. 45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BasicBlock *IncomingBB = PHI->getIncomingBlock(Idx); 46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned i = 0; i < Idx; ++i) { 46136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (PHI->getIncomingBlock(i) == IncomingBB) { 46236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *IncomingVal = PHI->getIncomingValue(i); 46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst->setOperand(Idx, IncomingVal); 46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 46836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 46936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst->setOperand(Idx, Mat); 47036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 47136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 47236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 47336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Emit materialization code for all rebased constants and update their 47436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// users. 475de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid ConstantHoistingPass::emitBaseConstants(Instruction *Base, 476de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Constant *Offset, 477de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const ConstantUser &ConstUser) { 47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *Mat = Base; 47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Offset) { 48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *InsertionPt = findMatInsertPt(ConstUser.Inst, 48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstUser.OpndIdx); 48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mat = BinaryOperator::Create(Instruction::Add, Base, Offset, 48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "const_mat", InsertionPt); 48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Materialize constant (" << *Base->getOperand(0) 48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " + " << *Offset << ") in BB " 48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << Mat->getParent()->getName() << '\n' << *Mat << '\n'); 48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mat->setDebugLoc(ConstUser.Inst->getDebugLoc()); 48936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Opnd = ConstUser.Inst->getOperand(ConstUser.OpndIdx); 49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Visit constant integer. 49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isa<ConstantInt>(Opnd)) { 49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Update: " << *ConstUser.Inst << '\n'); 49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!updateOperand(ConstUser.Inst, ConstUser.OpndIdx, Mat) && Offset) 49636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mat->eraseFromParent(); 49736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "To : " << *ConstUser.Inst << '\n'); 49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 49936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 50036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 50136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Visit cast instruction. 50236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto CastInst = dyn_cast<Instruction>(Opnd)) { 50336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(CastInst->isCast() && "Expected an cast instruction!"); 50436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Check if we already have visited this cast instruction before to avoid 50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // unnecessary cloning. 50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *&ClonedCastInst = ClonedCastMap[CastInst]; 50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!ClonedCastInst) { 50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ClonedCastInst = CastInst->clone(); 50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ClonedCastInst->setOperand(0, Mat); 51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ClonedCastInst->insertAfter(CastInst); 51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Use the same debug location as the original cast instruction. 51236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ClonedCastInst->setDebugLoc(CastInst->getDebugLoc()); 513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << "Clone instruction: " << *CastInst << '\n' 514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << "To : " << *ClonedCastInst << '\n'); 51536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 51636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 51736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Update: " << *ConstUser.Inst << '\n'); 51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines updateOperand(ConstUser.Inst, ConstUser.OpndIdx, ClonedCastInst); 51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "To : " << *ConstUser.Inst << '\n'); 52036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 52136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 52236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 52336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Visit constant expression. 52436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto ConstExpr = dyn_cast<ConstantExpr>(Opnd)) { 52536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *ConstExprInst = ConstExpr->getAsInstruction(); 52636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstExprInst->setOperand(0, Mat); 52736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstExprInst->insertBefore(findMatInsertPt(ConstUser.Inst, 52836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstUser.OpndIdx)); 52936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 53036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Use the same debug location as the instruction we are about to update. 53136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstExprInst->setDebugLoc(ConstUser.Inst->getDebugLoc()); 53236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 53336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Create instruction: " << *ConstExprInst << '\n' 53436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << "From : " << *ConstExpr << '\n'); 53536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Update: " << *ConstUser.Inst << '\n'); 53636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!updateOperand(ConstUser.Inst, ConstUser.OpndIdx, ConstExprInst)) { 53736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstExprInst->eraseFromParent(); 53836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Offset) 53936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mat->eraseFromParent(); 54036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 54136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "To : " << *ConstUser.Inst << '\n'); 54236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 54336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 54436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 54536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 54636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Hoist and hide the base constant behind a bitcast and emit 54736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// materialization code for derived constants. 548de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool ConstantHoistingPass::emitBaseConstants() { 54936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool MadeChange = false; 55036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto const &ConstInfo : ConstantVec) { 55136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Hoist and hide the base constant behind a bitcast. 55236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *IP = findConstantInsertionPoint(ConstInfo); 55336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IntegerType *Ty = ConstInfo.BaseConstant->getType(); 55436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *Base = 55536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines new BitCastInst(ConstInfo.BaseConstant, Ty, "const", IP); 55636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Hoist constant (" << *ConstInfo.BaseConstant << ") to BB " 55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << IP->getParent()->getName() << '\n' << *Base << '\n'); 55836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NumConstantsHoisted++; 55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Emit materialization code for all rebased constants. 56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto const &RCI : ConstInfo.RebasedConstants) { 56236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NumConstantsRebased++; 56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto const &U : RCI.Uses) 56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines emitBaseConstants(Base, RCI.Offset, U); 56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 56636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 56736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Use the same debug location as the last user of the constant. 56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(!Base->use_empty() && "The use list is empty!?"); 56936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isa<Instruction>(Base->user_back()) && 57036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "All uses should be instructions."); 57136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Base->setDebugLoc(cast<Instruction>(Base->user_back())->getDebugLoc()); 57236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 57336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Correct for base constant, which we counted above too. 57436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NumConstantsRebased--; 57536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MadeChange = true; 57636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 57736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MadeChange; 57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 57936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 58036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Check all cast instructions we made a copy of and remove them if they 58136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// have no more users. 582de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid ConstantHoistingPass::deleteDeadCastInst() const { 58336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto const &I : ClonedCastMap) 58436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (I.first->use_empty()) 58536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I.first->eraseFromParent(); 58636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 58736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 58836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Optimize expensive integer constants in the given function. 589de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool ConstantHoistingPass::runImpl(Function &Fn, TargetTransformInfo &TTI, 590de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DominatorTree &DT, BasicBlock &Entry) { 591de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar this->TTI = &TTI; 592de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar this->DT = &DT; 593de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar this->Entry = &Entry; 59436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Collect all constant candidates. 59536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines collectConstantCandidates(Fn); 59636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 59736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // There are no constant candidates to worry about. 59836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ConstCandVec.empty()) 59936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 60036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 60136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Combine constants that can be easily materialized with an add from a common 60236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // base constant. 60336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines findBaseConstants(); 60436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 60536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // There are no constants to emit. 60636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ConstantVec.empty()) 60736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 60836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 60936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Finally hoist the base constant and emit materialization code for dependent 61036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // constants. 61136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool MadeChange = emitBaseConstants(); 61236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 61336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Cleanup dead instructions. 61436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines deleteDeadCastInst(); 61536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 61636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MadeChange; 61736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 618de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 619de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarPreservedAnalyses ConstantHoistingPass::run(Function &F, 620de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar FunctionAnalysisManager &AM) { 621de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &DT = AM.getResult<DominatorTreeAnalysis>(F); 622de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &TTI = AM.getResult<TargetIRAnalysis>(F); 623de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!runImpl(F, TTI, DT, F.getEntryBlock())) 624de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return PreservedAnalyses::all(); 625de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 626de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // FIXME: This should also 'preserve the CFG'. 627de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return PreservedAnalyses::none(); 628de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 629