ConstantHoisting.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
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 3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define DEBUG_TYPE "consthoist" 3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Transforms/Scalar.h" 3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/SmallSet.h" 3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/SmallVector.h" 4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/Statistic.h" 4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Analysis/TargetTransformInfo.h" 4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Constants.h" 4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Dominators.h" 4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/IntrinsicInst.h" 4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Pass.h" 4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/Debug.h" 4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesusing namespace llvm; 4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesSTATISTIC(NumConstantsHoisted, "Number of constants hoisted"); 5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesSTATISTIC(NumConstantsRebased, "Number of constants rebased"); 5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace { 5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstruct ConstantUser; 5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstruct RebasedConstantInfo; 5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestypedef SmallVector<ConstantUser, 8> ConstantUseListType; 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestypedef SmallVector<RebasedConstantInfo, 4> RebasedConstantListType; 5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Keeps track of the user of a constant and the operand index where the 6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// constant is used. 6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstruct ConstantUser { 6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *Inst; 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned OpndIdx; 6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstantUser(Instruction *Inst, unsigned Idx) : Inst(Inst), OpndIdx(Idx) { } 6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Keeps track of a constant candidate and its uses. 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstruct ConstantCandidate { 7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstantUseListType Uses; 7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstantInt *ConstInt; 7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned CumulativeCost; 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstantCandidate(ConstantInt *ConstInt) 7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : ConstInt(ConstInt), CumulativeCost(0) { } 7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// \brief Add the user to the use list and update the cost. 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addUser(Instruction *Inst, unsigned Idx, unsigned Cost) { 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CumulativeCost += Cost; 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Uses.push_back(ConstantUser(Inst, Idx)); 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief This represents a constant that has been rebased with respect to a 8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// base constant. The difference to the base constant is recorded in Offset. 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstruct RebasedConstantInfo { 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstantUseListType Uses; 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Constant *Offset; 9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RebasedConstantInfo(ConstantUseListType &&Uses, Constant *Offset) 9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : Uses(Uses), Offset(Offset) { } 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief A base constant and all its rebased constants. 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstruct ConstantInfo { 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstantInt *BaseConstant; 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RebasedConstantListType RebasedConstants; 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief The constant hoisting pass. 10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass ConstantHoisting : public FunctionPass { 10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typedef DenseMap<ConstantInt *, unsigned> ConstCandMapType; 10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typedef std::vector<ConstantCandidate> ConstCandVecType; 10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const TargetTransformInfo *TTI; 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DominatorTree *DT; 10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BasicBlock *Entry; 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Keeps track of constant candidates found in the function. 11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstCandVecType ConstCandVec; 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Keep track of cast instructions we already cloned. 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallDenseMap<Instruction *, Instruction *> ClonedCastMap; 11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// These are the final constants we decided to hoist. 11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<ConstantInfo, 8> ConstantVec; 11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic: 11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines static char ID; // Pass identification, replacement for typeid 12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstantHoisting() : FunctionPass(ID), TTI(0), DT(0), Entry(0) { 12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines initializeConstantHoistingPass(*PassRegistry::getPassRegistry()); 12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnFunction(Function &Fn) override; 12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *getPassName() const override { return "Constant Hoisting"; } 12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AU.setPreservesCFG(); 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AU.addRequired<DominatorTreeWrapperPass>(); 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AU.addRequired<TargetTransformInfo>(); 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesprivate: 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// \brief Initialize the pass. 13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void setup(Function &Fn) { 13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TTI = &getAnalysis<TargetTransformInfo>(); 13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Entry = &Fn.getEntryBlock(); 14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// \brief Cleanup. 14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void cleanup() { 14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstantVec.clear(); 14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ClonedCastMap.clear(); 14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstCandVec.clear(); 14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TTI = nullptr; 14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DT = nullptr; 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Entry = nullptr; 15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *findMatInsertPt(Instruction *Inst, unsigned Idx = ~0U) const; 15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *findConstantInsertionPoint(const ConstantInfo &ConstInfo) const; 15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void collectConstantCandidates(ConstCandMapType &ConstCandMap, 15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *Inst, unsigned Idx, 15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstantInt *ConstInt); 15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void collectConstantCandidates(ConstCandMapType &ConstCandMap, 15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *Inst); 16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void collectConstantCandidates(Function &Fn); 16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void findAndMakeBaseConstant(ConstCandVecType::iterator S, 16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstCandVecType::iterator E); 16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void findBaseConstants(); 16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void emitBaseConstants(Instruction *Base, Constant *Offset, 16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const ConstantUser &ConstUser); 16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool emitBaseConstants(); 16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void deleteDeadCastInst() const; 16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool optimizeConstants(Function &Fn); 16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hineschar ConstantHoisting::ID = 0; 17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesINITIALIZE_PASS_BEGIN(ConstantHoisting, "consthoist", "Constant Hoisting", 17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines false, false) 17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesINITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesINITIALIZE_AG_DEPENDENCY(TargetTransformInfo) 17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesINITIALIZE_PASS_END(ConstantHoisting, "consthoist", "Constant Hoisting", 17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines false, false) 17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesFunctionPass *llvm::createConstantHoistingPass() { 18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return new ConstantHoisting(); 18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Perform the constant hoisting optimization for the given function. 18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool ConstantHoisting::runOnFunction(Function &Fn) { 18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "********** Begin Constant Hoisting **********\n"); 18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "********** Function: " << Fn.getName() << '\n'); 18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines setup(Fn); 19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool MadeChange = optimizeConstants(Fn); 19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MadeChange) { 19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "********** Function after Constant Hoisting: " 19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << Fn.getName() << '\n'); 19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << Fn); 19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "********** End Constant Hoisting **********\n"); 19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cleanup(); 20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MadeChange; 20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Find the constant materialization insertion point. 20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesInstruction *ConstantHoisting::findMatInsertPt(Instruction *Inst, 20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Idx) const { 20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The simple and common case. 21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!isa<PHINode>(Inst) && !isa<LandingPadInst>(Inst)) 21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Inst; 21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We can't insert directly before a phi node or landing pad. Insert before 21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // the terminator of the incoming or dominating block. 21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Entry != Inst->getParent() && "PHI or landing pad in entry block!"); 21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Idx != ~0U && isa<PHINode>(Inst)) 21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return cast<PHINode>(Inst)->getIncomingBlock(Idx)->getTerminator(); 21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BasicBlock *IDom = DT->getNode(Inst->getParent())->getIDom()->getBlock(); 22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return IDom->getTerminator(); 22136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Find an insertion point that dominates all uses. 22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesInstruction *ConstantHoisting:: 22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesfindConstantInsertionPoint(const ConstantInfo &ConstInfo) const { 22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(!ConstInfo.RebasedConstants.empty() && "Invalid constant info entry."); 22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Collect all basic blocks. 22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallPtrSet<BasicBlock *, 8> BBs; 22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto const &RCI : ConstInfo.RebasedConstants) 23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto const &U : RCI.Uses) 23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BBs.insert(U.Inst->getParent()); 23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (BBs.count(Entry)) 23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return &Entry->front(); 23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines while (BBs.size() >= 2) { 23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BasicBlock *BB, *BB1, *BB2; 23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BB1 = *BBs.begin(); 23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BB2 = *std::next(BBs.begin()); 24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BB = DT->findNearestCommonDominator(BB1, BB2); 24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (BB == Entry) 24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return &Entry->front(); 24336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BBs.erase(BB1); 24436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BBs.erase(BB2); 24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BBs.insert(BB); 24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert((BBs.size() == 1) && "Expected only one element."); 24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction &FirstInst = (*BBs.begin())->front(); 24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return findMatInsertPt(&FirstInst); 25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Record constant integer ConstInt for instruction Inst at operand 25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// index Idx. 25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// 25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// The operand at index Idx is not necessarily the constant integer itself. It 25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// could also be a cast instruction or a constant expression that uses the 25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// constant integer. 25936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ConstantHoisting::collectConstantCandidates(ConstCandMapType &ConstCandMap, 26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *Inst, 26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Idx, 26236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstantInt *ConstInt) { 26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Cost; 26436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Ask the target about the cost of materializing the constant for the given 26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // instruction and operand index. 26636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto IntrInst = dyn_cast<IntrinsicInst>(Inst)) 26736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Cost = TTI->getIntImmCost(IntrInst->getIntrinsicID(), Idx, 26836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstInt->getValue(), ConstInt->getType()); 26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 27036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Cost = TTI->getIntImmCost(Inst->getOpcode(), Idx, ConstInt->getValue(), 27136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstInt->getType()); 27236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 27336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Ignore cheap integer constants. 27436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Cost > TargetTransformInfo::TCC_Basic) { 27536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstCandMapType::iterator Itr; 27636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool Inserted; 27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::tie(Itr, Inserted) = ConstCandMap.insert(std::make_pair(ConstInt, 0)); 27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Inserted) { 27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstCandVec.push_back(ConstantCandidate(ConstInt)); 28036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Itr->second = ConstCandVec.size() - 1; 28136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstCandVec[Itr->second].addUser(Inst, Idx, Cost); 28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(if (isa<ConstantInt>(Inst->getOperand(Idx))) 28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines dbgs() << "Collect constant " << *ConstInt << " from " << *Inst 28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " with cost " << Cost << '\n'; 28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 28736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines dbgs() << "Collect constant " << *ConstInt << " indirectly from " 28836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << *Inst << " via " << *Inst->getOperand(Idx) << " with cost " 28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << Cost << '\n'; 29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ); 29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Scan the instruction for expensive integer constants and record them 29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// in the constant candidate vector. 29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ConstantHoisting::collectConstantCandidates(ConstCandMapType &ConstCandMap, 29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *Inst) { 29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Skip all cast instructions. They are visited indirectly later on. 29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Inst->isCast()) 30036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 30136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 30236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Can't handle inline asm. Skip it. 30336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto Call = dyn_cast<CallInst>(Inst)) 30436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isa<InlineAsm>(Call->getCalledValue())) 30536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 30736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Scan all operands. 30836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned Idx = 0, E = Inst->getNumOperands(); Idx != E; ++Idx) { 30936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Opnd = Inst->getOperand(Idx); 31036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 31136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Visit constant integers. 31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto ConstInt = dyn_cast<ConstantInt>(Opnd)) { 31336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt); 31436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Visit cast instructions that have constant integers. 31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto CastInst = dyn_cast<Instruction>(Opnd)) { 31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Only visit cast instructions, which have been skipped. All other 32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // instructions should have already been visited. 32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!CastInst->isCast()) 32236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto *ConstInt = dyn_cast<ConstantInt>(CastInst->getOperand(0))) { 32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Pretend the constant is directly used by the instruction and ignore 32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // the cast instruction. 32736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt); 32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Visit constant expressions that have constant integers. 33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto ConstExpr = dyn_cast<ConstantExpr>(Opnd)) { 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Only visit constant cast expressions. 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!ConstExpr->isCast()) 33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 33736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto ConstInt = dyn_cast<ConstantInt>(ConstExpr->getOperand(0))) { 33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Pretend the constant is directly used by the instruction and ignore 34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // the constant expression. 34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt); 34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } // end of for all operands 34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Collect all integer constants in the function that cannot be folded 34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// into an instruction itself. 35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ConstantHoisting::collectConstantCandidates(Function &Fn) { 35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstCandMapType ConstCandMap; 35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (Function::iterator BB : Fn) 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (BasicBlock::iterator Inst : *BB) 35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines collectConstantCandidates(ConstCandMap, Inst); 35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 35636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Find the base constant within the given range and rebase all other 35836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// constants with respect to the base constant. 35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ConstantHoisting::findAndMakeBaseConstant(ConstCandVecType::iterator S, 36036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstCandVecType::iterator E) { 36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto MaxCostItr = S; 36236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned NumUses = 0; 36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Use the constant that has the maximum cost as base constant. 36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto ConstCand = S; ConstCand != E; ++ConstCand) { 36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NumUses += ConstCand->Uses.size(); 36636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ConstCand->CumulativeCost > MaxCostItr->CumulativeCost) 36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MaxCostItr = ConstCand; 36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 36936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Don't hoist constants that have only one use. 37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (NumUses <= 1) 37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstantInfo ConstInfo; 37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstInfo.BaseConstant = MaxCostItr->ConstInt; 37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Type *Ty = ConstInfo.BaseConstant->getType(); 37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Rebase the constants with respect to the base constant. 37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto ConstCand = S; ConstCand != E; ++ConstCand) { 38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines APInt Diff = ConstCand->ConstInt->getValue() - 38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstInfo.BaseConstant->getValue(); 38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Constant *Offset = Diff == 0 ? nullptr : ConstantInt::get(Ty, Diff); 38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstInfo.RebasedConstants.push_back( 38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RebasedConstantInfo(std::move(ConstCand->Uses), Offset)); 38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstantVec.push_back(ConstInfo); 38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Finds and combines constant candidates that can be easily 39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// rematerialized with an add from a common base constant. 39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ConstantHoisting::findBaseConstants() { 39236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Sort the constants by value and type. This invalidates the mapping! 39336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::sort(ConstCandVec.begin(), ConstCandVec.end(), 39436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines [](const ConstantCandidate &LHS, const ConstantCandidate &RHS) { 39536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (LHS.ConstInt->getType() != RHS.ConstInt->getType()) 39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return LHS.ConstInt->getType()->getBitWidth() < 39736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RHS.ConstInt->getType()->getBitWidth(); 39836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return LHS.ConstInt->getValue().ult(RHS.ConstInt->getValue()); 39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines }); 40036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 40136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Simple linear scan through the sorted constant candidate vector for viable 40236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // merge candidates. 40336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto MinValItr = ConstCandVec.begin(); 40436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto CC = std::next(ConstCandVec.begin()), E = ConstCandVec.end(); 40536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CC != E; ++CC) { 40636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MinValItr->ConstInt->getType() == CC->ConstInt->getType()) { 40736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Check if the constant is in range of an add with immediate. 40836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines APInt Diff = CC->ConstInt->getValue() - MinValItr->ConstInt->getValue(); 40936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((Diff.getBitWidth() <= 64) && 41036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TTI->isLegalAddImmediate(Diff.getSExtValue())) 41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 41236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 41336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We either have now a different constant type or the constant is not in 41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // range of an add with immediate anymore. 41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines findAndMakeBaseConstant(MinValItr, CC); 41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Start a new base constant search. 41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MinValItr = CC; 41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Finalize the last base constant search. 42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines findAndMakeBaseConstant(MinValItr, ConstCandVec.end()); 42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 42236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 42336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Updates the operand at Idx in instruction Inst with the result of 42436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// instruction Mat. If the instruction is a PHI node then special 42536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// handling for duplicate values form the same incomming basic block is 42636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// required. 42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \return The update will always succeed, but the return value indicated if 42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// Mat was used for the update or not. 42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool updateOperand(Instruction *Inst, unsigned Idx, Instruction *Mat) { 43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto PHI = dyn_cast<PHINode>(Inst)) { 43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Check if any previous operand of the PHI node has the same incoming basic 43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // block. This is a very odd case that happens when the incoming basic block 43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // has a switch statement. In this case use the same value as the previous 43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // operand(s), otherwise we will fail verification due to different values. 43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The values are actually the same, but the variable names are different 43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // and the verifier doesn't like that. 43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BasicBlock *IncomingBB = PHI->getIncomingBlock(Idx); 43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned i = 0; i < Idx; ++i) { 43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (PHI->getIncomingBlock(i) == IncomingBB) { 44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *IncomingVal = PHI->getIncomingValue(i); 44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst->setOperand(Idx, IncomingVal); 44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 44436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst->setOperand(Idx, Mat); 44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 44936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 45036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Emit materialization code for all rebased constants and update their 45236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// users. 45336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ConstantHoisting::emitBaseConstants(Instruction *Base, Constant *Offset, 45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const ConstantUser &ConstUser) { 45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *Mat = Base; 45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Offset) { 45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *InsertionPt = findMatInsertPt(ConstUser.Inst, 45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstUser.OpndIdx); 45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mat = BinaryOperator::Create(Instruction::Add, Base, Offset, 46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "const_mat", InsertionPt); 46136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 46236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Materialize constant (" << *Base->getOperand(0) 46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " + " << *Offset << ") in BB " 46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << Mat->getParent()->getName() << '\n' << *Mat << '\n'); 46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mat->setDebugLoc(ConstUser.Inst->getDebugLoc()); 46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Opnd = ConstUser.Inst->getOperand(ConstUser.OpndIdx); 46836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 46936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Visit constant integer. 47036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isa<ConstantInt>(Opnd)) { 47136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Update: " << *ConstUser.Inst << '\n'); 47236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!updateOperand(ConstUser.Inst, ConstUser.OpndIdx, Mat) && Offset) 47336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mat->eraseFromParent(); 47436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "To : " << *ConstUser.Inst << '\n'); 47536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 47636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 47736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Visit cast instruction. 47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto CastInst = dyn_cast<Instruction>(Opnd)) { 48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(CastInst->isCast() && "Expected an cast instruction!"); 48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Check if we already have visited this cast instruction before to avoid 48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // unnecessary cloning. 48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *&ClonedCastInst = ClonedCastMap[CastInst]; 48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!ClonedCastInst) { 48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ClonedCastInst = CastInst->clone(); 48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ClonedCastInst->setOperand(0, Mat); 48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ClonedCastInst->insertAfter(CastInst); 48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Use the same debug location as the original cast instruction. 48936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ClonedCastInst->setDebugLoc(CastInst->getDebugLoc()); 49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Clone instruction: " << *ClonedCastInst << '\n' 49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << "To : " << *CastInst << '\n'); 49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Update: " << *ConstUser.Inst << '\n'); 49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines updateOperand(ConstUser.Inst, ConstUser.OpndIdx, ClonedCastInst); 49636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "To : " << *ConstUser.Inst << '\n'); 49736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 49936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 50036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Visit constant expression. 50136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto ConstExpr = dyn_cast<ConstantExpr>(Opnd)) { 50236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *ConstExprInst = ConstExpr->getAsInstruction(); 50336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstExprInst->setOperand(0, Mat); 50436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstExprInst->insertBefore(findMatInsertPt(ConstUser.Inst, 50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstUser.OpndIdx)); 50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Use the same debug location as the instruction we are about to update. 50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstExprInst->setDebugLoc(ConstUser.Inst->getDebugLoc()); 50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Create instruction: " << *ConstExprInst << '\n' 51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << "From : " << *ConstExpr << '\n'); 51236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Update: " << *ConstUser.Inst << '\n'); 51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!updateOperand(ConstUser.Inst, ConstUser.OpndIdx, ConstExprInst)) { 51436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstExprInst->eraseFromParent(); 51536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Offset) 51636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mat->eraseFromParent(); 51736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "To : " << *ConstUser.Inst << '\n'); 51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 52036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 52136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 52236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 52336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Hoist and hide the base constant behind a bitcast and emit 52436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// materialization code for derived constants. 52536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool ConstantHoisting::emitBaseConstants() { 52636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool MadeChange = false; 52736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto const &ConstInfo : ConstantVec) { 52836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Hoist and hide the base constant behind a bitcast. 52936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *IP = findConstantInsertionPoint(ConstInfo); 53036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IntegerType *Ty = ConstInfo.BaseConstant->getType(); 53136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *Base = 53236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines new BitCastInst(ConstInfo.BaseConstant, Ty, "const", IP); 53336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Hoist constant (" << *ConstInfo.BaseConstant << ") to BB " 53436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << IP->getParent()->getName() << '\n' << *Base << '\n'); 53536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NumConstantsHoisted++; 53636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 53736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Emit materialization code for all rebased constants. 53836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto const &RCI : ConstInfo.RebasedConstants) { 53936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NumConstantsRebased++; 54036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto const &U : RCI.Uses) 54136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines emitBaseConstants(Base, RCI.Offset, U); 54236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 54336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 54436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Use the same debug location as the last user of the constant. 54536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(!Base->use_empty() && "The use list is empty!?"); 54636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isa<Instruction>(Base->user_back()) && 54736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "All uses should be instructions."); 54836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Base->setDebugLoc(cast<Instruction>(Base->user_back())->getDebugLoc()); 54936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 55036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Correct for base constant, which we counted above too. 55136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NumConstantsRebased--; 55236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MadeChange = true; 55336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 55436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MadeChange; 55536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 55636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Check all cast instructions we made a copy of and remove them if they 55836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// have no more users. 55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ConstantHoisting::deleteDeadCastInst() const { 56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto const &I : ClonedCastMap) 56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (I.first->use_empty()) 56236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I.first->eraseFromParent(); 56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief Optimize expensive integer constants in the given function. 56636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool ConstantHoisting::optimizeConstants(Function &Fn) { 56736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Collect all constant candidates. 56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines collectConstantCandidates(Fn); 56936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 57036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // There are no constant candidates to worry about. 57136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ConstCandVec.empty()) 57236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 57336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 57436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Combine constants that can be easily materialized with an add from a common 57536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // base constant. 57636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines findBaseConstants(); 57736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // There are no constants to emit. 57936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ConstantVec.empty()) 58036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 58136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 58236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Finally hoist the base constant and emit materialization code for dependent 58336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // constants. 58436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool MadeChange = emitBaseConstants(); 58536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 58636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Cleanup dead instructions. 58736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines deleteDeadCastInst(); 58836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 58936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MadeChange; 59036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 591