74#define DEBUG_TYPE "consthoist"
76STATISTIC(NumConstantsHoisted,
"Number of constants hoisted");
77STATISTIC(NumConstantsRebased,
"Number of constants rebased");
92 StringRef getPassName()
const override {
return "Constant Hoisting"; }
94 void getAnalysisUsage(AnalysisUsage &AU)
const override {
103 ConstantHoistingPass Impl;
108char ConstantHoistingLegacyPass::ID = 0;
111 "Constant Hoisting",
false,
false)
120 return new ConstantHoistingLegacyPass();
124bool ConstantHoistingLegacyPass::runOnFunction(
Function &Fn) {
125 if (skipFunction(Fn))
128 LLVM_DEBUG(
dbgs() <<
"********** Begin Constant Hoisting **********\n");
132 auto GetBFI = [&]() {
133 return Opts.consthoist_with_block_frequency
134 ? &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI()
138 Impl.
runImpl(Fn, getAnalysis<TargetTransformInfoWrapperPass>().getTTI(Fn),
139 getAnalysis<DominatorTreeWrapperPass>().
getDomTree(), GetBFI,
141 &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI());
143 LLVM_DEBUG(
dbgs() <<
"********** End Constant Hoisting **********\n");
148void ConstantHoistingPass::collectMatInsertPts(
150 SmallVectorImpl<BasicBlock::iterator> &MatInsertPts)
const {
151 for (
const RebasedConstantInfo &RCI : RebasedConstants)
152 for (
const ConstantUser &U : RCI.Uses)
158 unsigned Idx)
const {
164 if (CastInst->isCast())
165 return CastInst->getIterator();
174 assert(Entry != Inst->
getParent() &&
"PHI or landing pad in entry block!");
178 if (!InsertionBlock->
isEHPad()) {
188 auto *IDom = DT->getNode(InsertionBlock)->getIDom();
189 while (IDom->getBlock()->isEHPad()) {
190 assert(Entry != IDom->getBlock() &&
"eh pad in entry block");
191 IDom = IDom->getIDom();
194 return IDom->getBlock()->getTerminator()->getIterator();
203 assert(!BBs.
count(Entry) &&
"Assume Entry is not in BBs");
210 for (
auto *BB : BBs) {
227 "Entry doens't dominate current Node");
245 while (Idx != Orders.
size()) {
248 if (Candidates.
count(ChildDomNode->getBlock()))
249 Orders.
push_back(ChildDomNode->getBlock());
254 using InsertPtsCostPair =
265 auto &[InsertPts, InsertPtsFreq] = InsertPtsMap.
find(
Node)->second;
281 auto &[ParentInsertPts, ParentPtsFreq] = InsertPtsMap.
find(Parent)->second;
292 ParentInsertPts.insert(
Node);
295 ParentInsertPts.insert_range(InsertPts);
296 ParentPtsFreq += InsertPtsFreq;
302SetVector<BasicBlock::iterator>
303ConstantHoistingPass::findConstantInsertionPoint(
304 const ConstantInfo &ConstInfo,
308 SetVector<BasicBlock *> BBs;
309 SetVector<BasicBlock::iterator> InsertPts;
312 BBs.
insert(MatInsertPt->getParent());
314 if (BBs.
count(Entry)) {
321 for (BasicBlock *BB : BBs)
322 InsertPts.
insert(BB->getFirstInsertionPt());
326 while (BBs.size() >= 2) {
328 BB1 = BBs.pop_back_val();
329 BB2 = BBs.pop_back_val();
330 BB = DT->findNearestCommonDominator(BB1, BB2);
337 assert((BBs.size() == 1) &&
"Expected only one element.");
339 InsertPts.
insert(findMatInsertPt(&FirstInst));
349void ConstantHoistingPass::collectConstantCandidates(
350 ConstCandMapType &ConstCandMap, Instruction *Inst,
unsigned Idx,
351 ConstantInt *ConstInt) {
369 ConstCandMapType::iterator Itr;
371 ConstPtrUnionType Cand = ConstInt;
372 std::tie(Itr, Inserted) = ConstCandMap.try_emplace(Cand);
374 ConstIntCandVec.push_back(ConstantCandidate(ConstInt));
375 Itr->second = ConstIntCandVec.size() - 1;
377 ConstIntCandVec[Itr->second].addUser(Inst, Idx,
Cost.
getValue());
379 <<
"Collect constant " << *ConstInt <<
" from " << *Inst
380 <<
" with cost " <<
Cost <<
'\n';
381 else dbgs() <<
"Collect constant " << *ConstInt
382 <<
" indirectly from " << *Inst <<
" via "
389void ConstantHoistingPass::collectConstantCandidates(
390 ConstCandMapType &ConstCandMap, Instruction *Inst,
unsigned Idx,
391 ConstantExpr *ConstExpr) {
402 IntegerType *OffsetTy =
DL->getIndexType(*Ctx, GVPtrTy->getAddressSpace());
403 APInt
Offset(
DL->getTypeSizeInBits(OffsetTy), 0,
true);
410 if (!GEPO->isInBounds())
413 if (!GEPO->accumulateConstantOffset(*
DL,
Offset))
426 ConstCandVecType &ExprCandVec = ConstGEPCandMap[BaseGV];
427 ConstCandMapType::iterator Itr;
429 ConstPtrUnionType Cand = ConstExpr;
430 std::tie(Itr, Inserted) = ConstCandMap.try_emplace(Cand);
432 ExprCandVec.push_back(ConstantCandidate(
433 ConstantInt::get(Type::getInt32Ty(*Ctx),
Offset.getLimitedValue()),
435 Itr->second = ExprCandVec.size() - 1;
437 ExprCandVec[Itr->second].addUser(Inst, Idx,
Cost.
getValue());
441void ConstantHoistingPass::collectConstantCandidates(
442 ConstCandMapType &ConstCandMap, Instruction *Inst,
unsigned Idx) {
447 collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt);
455 if (!CastInst->isCast())
461 collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt);
470 collectConstantCandidates(ConstCandMap, Inst, Idx, ConstExpr);
479 collectConstantCandidates(ConstCandMap, Inst, Idx, ConstInt);
487void ConstantHoistingPass::collectConstantCandidates(
488 ConstCandMapType &ConstCandMap, Instruction *Inst) {
498 if (!DT->isReachableFromEntry(IncomingBB))
507 collectConstantCandidates(ConstCandMap, Inst, Idx);
514void ConstantHoistingPass::collectConstantCandidates(
Function &Fn) {
515 ConstCandMapType ConstCandMap;
516 for (BasicBlock &BB : Fn) {
518 if (!DT->isReachableFromEntry(&BB))
520 for (Instruction &Inst : BB)
522 collectConstantCandidates(ConstCandMap, &Inst);
550ConstantHoistingPass::maximizeConstantsInRange(ConstCandVecType::iterator S,
551 ConstCandVecType::iterator
E,
552 ConstCandVecType::iterator &MaxCostItr) {
553 unsigned NumUses = 0;
555 if (!OptForSize || std::distance(S,
E) > 100) {
556 for (
auto ConstCand = S; ConstCand !=
E; ++ConstCand) {
557 NumUses += ConstCand->Uses.size();
558 if (ConstCand->CumulativeCost > MaxCostItr->CumulativeCost)
559 MaxCostItr = ConstCand;
566 for (
auto ConstCand = S; ConstCand !=
E; ++ConstCand) {
567 auto Value = ConstCand->ConstInt->getValue();
568 Type *Ty = ConstCand->ConstInt->getType();
570 NumUses += ConstCand->Uses.size();
571 LLVM_DEBUG(
dbgs() <<
"= Constant: " << ConstCand->ConstInt->getValue()
574 for (
auto User : ConstCand->Uses) {
575 unsigned Opcode =
User.Inst->getOpcode();
576 unsigned OpndIdx =
User.OpndIdx;
581 for (
auto C2 = S; C2 !=
E; ++C2) {
582 APInt Diff = C2->ConstInt->getValue() - ConstCand->ConstInt->getValue();
587 <<
"has penalty: " << ImmCosts <<
"\n"
588 <<
"Adjusted cost: " <<
Cost <<
"\n");
592 if (
Cost > MaxCost) {
594 MaxCostItr = ConstCand;
595 LLVM_DEBUG(
dbgs() <<
"New candidate: " << MaxCostItr->ConstInt->getValue()
604void ConstantHoistingPass::findAndMakeBaseConstant(
605 ConstCandVecType::iterator S, ConstCandVecType::iterator
E,
606 SmallVectorImpl<consthoist::ConstantInfo> &ConstInfoVec) {
608 unsigned NumUses = maximizeConstantsInRange(S,
E, MaxCostItr);
614 ConstantInt *ConstInt = MaxCostItr->ConstInt;
615 ConstantExpr *ConstExpr = MaxCostItr->ConstExpr;
616 ConstantInfo ConstInfo;
622 for (
auto ConstCand = S; ConstCand !=
E; ++ConstCand) {
623 APInt Diff = ConstCand->ConstInt->getValue() - ConstInt->
getValue();
624 Constant *
Offset = Diff == 0 ? nullptr : ConstantInt::get(Ty, Diff);
626 ConstCand->ConstExpr ? ConstCand->ConstExpr->getType() :
nullptr;
628 RebasedConstantInfo(std::move(ConstCand->Uses),
Offset, ConstTy));
630 ConstInfoVec.
push_back(std::move(ConstInfo));
635void ConstantHoistingPass::findBaseConstants(GlobalVariable *BaseGV) {
638 ConstCandVecType &ConstCandVec = BaseGV ?
639 ConstGEPCandMap[BaseGV] : ConstIntCandVec;
640 ConstInfoVecType &ConstInfoVec = BaseGV ?
641 ConstGEPInfoMap[BaseGV] : ConstIntInfoVec;
645 const ConstantCandidate &
RHS) {
647 return LHS.ConstInt->getBitWidth() <
RHS.ConstInt->getBitWidth();
648 return LHS.ConstInt->getValue().ult(
RHS.ConstInt->getValue());
653 auto MinValItr = ConstCandVec.begin();
654 for (
auto CC = std::next(ConstCandVec.begin()),
E = ConstCandVec.end();
656 if (MinValItr->ConstInt->getType() ==
CC->ConstInt->getType()) {
657 Type *MemUseValTy =
nullptr;
658 for (
auto &U :
CC->Uses) {
661 MemUseValTy = LI->getType();
665 if (
SI->getPointerOperand() ==
SI->getOperand(
U.OpndIdx)) {
666 MemUseValTy =
SI->getValueOperand()->getType();
673 APInt Diff =
CC->ConstInt->getValue() - MinValItr->ConstInt->getValue();
685 findAndMakeBaseConstant(MinValItr,
CC, ConstInfoVec);
690 findAndMakeBaseConstant(MinValItr, ConstCandVec.end(), ConstInfoVec);
708 for (
unsigned i = 0; i < Idx; ++i) {
709 if (
PHI->getIncomingBlock(i) == IncomingBB) {
710 Value *IncomingVal =
PHI->getIncomingValue(i);
723void ConstantHoistingPass::emitBaseConstants(Instruction *
Base,
724 UserAdjustment *Adj) {
728 if (!Adj->Offset && Adj->Ty && Adj->Ty !=
Base->getType())
729 Adj->Offset = ConstantInt::get(Type::getInt32Ty(*Ctx), 0);
735 "mat_gep", Adj->MatInsertPt);
737 Mat =
new BitCastInst(Mat, Adj->Ty,
"mat_bitcast",
738 Adj->MatInsertPt->getIterator());
743 "const_mat", Adj->MatInsertPt->getIterator());
746 <<
" + " << *Adj->Offset <<
") in BB "
751 Value *Opnd = Adj->User.Inst->getOperand(Adj->User.OpndIdx);
756 if (!
updateOperand(Adj->User.Inst, Adj->User.OpndIdx, Mat) && Adj->Offset)
764 assert(CastInst->isCast() &&
"Expected an cast instruction!");
767 Instruction *&ClonedCastInst = ClonedCastMap[CastInst];
768 if (!ClonedCastInst) {
769 ClonedCastInst = CastInst->
clone();
771 ClonedCastInst->
insertAfter(CastInst->getIterator());
773 ClonedCastInst->
setDebugLoc(CastInst->getDebugLoc());
775 <<
"To : " << *ClonedCastInst <<
'\n');
779 updateOperand(Adj->User.Inst, Adj->User.OpndIdx, ClonedCastInst);
793 assert(ConstExpr->
isCast() &&
"ConstExpr should be a cast");
799 ConstExprInst->
setDebugLoc(Adj->User.Inst->getDebugLoc());
801 LLVM_DEBUG(
dbgs() <<
"Create instruction: " << *ConstExprInst <<
'\n'
802 <<
"From : " << *ConstExpr <<
'\n');
804 if (!
updateOperand(Adj->User.Inst, Adj->User.OpndIdx, ConstExprInst)) {
816bool ConstantHoistingPass::emitBaseConstants(GlobalVariable *BaseGV) {
817 bool MadeChange =
false;
818 SmallVectorImpl<consthoist::ConstantInfo> &ConstInfoVec =
819 BaseGV ? ConstGEPInfoMap[BaseGV] : ConstIntInfoVec;
820 for (
const consthoist::ConstantInfo &ConstInfo : ConstInfoVec) {
823 SetVector<BasicBlock::iterator> IPSet =
824 findConstantInsertionPoint(ConstInfo, MatInsertPts);
829 unsigned UsesNum = 0;
830 unsigned ReBasesNum = 0;
831 unsigned NotRebasedNum = 0;
838 UsesNum += RCI.Uses.size();
839 for (
auto const &U : RCI.Uses) {
841 BasicBlock *OrigMatInsertBB = MatInsertPt->getParent();
844 if (IPSet.size() == 1 ||
845 DT->dominates(IP->getParent(), OrigMatInsertBB))
846 ToBeRebased.
emplace_back(RCI.Offset, RCI.Ty, MatInsertPt, U);
852 if (ToBeRebased.
size() < Opts->consthoist_min_num_to_rebase) {
853 NotRebasedNum += ToBeRebased.
size();
861 assert(BaseGV &&
"A base constant expression must have an base GV");
863 Base =
new BitCastInst(ConstInfo.
BaseExpr, Ty,
"const", IP);
866 Base =
new BitCastInst(ConstInfo.
BaseInt, Ty,
"const", IP);
869 Base->setDebugLoc(IP->getDebugLoc());
872 <<
") to BB " << IP->getParent()->
getName() <<
'\n'
876 for (UserAdjustment &R : ToBeRebased) {
877 emitBaseConstants(
Base, &R);
881 Base->getDebugLoc(),
R.User.Inst->getDebugLoc()));
883 assert(!
Base->use_empty() &&
"The use list is empty!?");
885 "All uses should be instructions.");
891 assert(UsesNum == (ReBasesNum + NotRebasedNum) &&
892 "Not all uses are rebased");
894 NumConstantsHoisted++;
907void ConstantHoistingPass::deleteDeadCastInst()
const {
908 for (
auto const &
I : ClonedCastMap)
909 if (
I.first->use_empty())
910 I.first->eraseFromParent();
924 this->Entry = &Entry;
927 Entry.getParent(), PSI,
928 PSI && PSI->hasProfileSummary() ? GetBFI() :
nullptr,
932 collectConstantCandidates(Fn);
936 if (!ConstIntCandVec.empty())
937 findBaseConstants(
nullptr);
938 for (
const auto &MapEntry : ConstGEPCandMap)
939 if (!MapEntry.second.empty())
940 findBaseConstants(MapEntry.first);
944 bool MadeChange =
false;
945 if (!ConstIntInfoVec.empty()) {
946 BFI = BFI ? BFI : GetBFI();
947 MadeChange = emitBaseConstants(
nullptr);
949 for (
const auto &MapEntry : ConstGEPInfoMap)
950 if (!MapEntry.second.empty()) {
951 BFI = BFI ? BFI : GetBFI();
952 MadeChange |= emitBaseConstants(MapEntry.first);
956 deleteDeadCastInst();
968 auto GetBFI = [&]() {
969 return CLOpts.consthoist_with_block_frequency
975 if (!
runImpl(
F, TTI, DT, GetBFI,
F.getEntryBlock(), PSI))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void cleanup(BlockFrequencyInfoImplBase &BFI)
Clear all memory not needed downstream.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool runImpl(MachineFunction &MF)
static bool updateOperand(Instruction *Inst, unsigned Idx, Instruction *Mat)
Updates the operand at Idx in instruction Inst with the result of instruction Mat.
static void findBestInsertionSet(DominatorTree &DT, BlockFrequencyInfo &BFI, BasicBlock *Entry, SetVector< BasicBlock * > &BBs)
Given BBs as input, find another set of BBs which collectively dominates BBs and have the minimal sum...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
static bool isCandidate(const MachineInstr *MI, Register &DefedReg, Register FrameReg)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static DominatorTree getDomTree(Function &F)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
unsigned getBitWidth() const
Return the number of bits in the APInt.
int64_t getSExtValue() const
Get sign extended value.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
LLVM Basic Block Representation.
InstListType::iterator iterator
Instruction iterators...
bool isEHPad() const
Return true if this basic block is an exception handling block.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
Represents analyses that only rely on functions' control flow.
LLVM_ABI bool isCast() const
Return true if this is a convert constant expression.
LLVM_ABI Instruction * getAsInstruction() const
Returns an Instruction which implements the same operation as this ConstantExpr.
LLVM_ABI bool runImpl(Function &F, TargetTransformInfo &TTI, DominatorTree &DT, function_ref< BlockFrequencyInfo *()> GetBFI, BasicBlock &Entry, ProfileSummaryInfo *PSI)
Optimize expensive integer constants in the given function.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
IntegerType * getIntegerType() const
Variant of the getType() method to always return an IntegerType, which reduces the amount of casting ...
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI DebugLoc getMergedLocation(DebugLoc LocA, DebugLoc LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
iterator_range< iterator > children()
DomTreeNodeBase * getIDom() const
Analysis pass which computes a DominatorTree.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
FunctionPass class - This class is used to implement most global optimizations.
const BasicBlock & getEntryBlock() const
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
PointerType * getType() const
Global values are always pointers.
CostType getValue() const
This function is intended to be used as sparingly as possible, since the class provides the full rang...
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction.
This is an alternative analysis pass to BlockFrequencyInfoWrapperPass.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
A vector that has set insertion semantics.
void insert_range(Range &&R)
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
void clear()
Completely clear the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
void insert_range(Range &&R)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Analysis pass providing the TargetTransformInfo.
bool isVectorTy() const
True if this is an instance of VectorType.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
@ BasicBlock
Various leaf nodes.
A private "module" namespace for types and utilities used by ConstantHoisting.
SmallVector< RebasedConstantInfo, 4 > RebasedConstantListType
@ User
could "use" a pointer
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
LLVM_ABI FunctionPass * createConstantHoistingPass()
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI, const MachineBlockFrequencyInfo *BFI, PGSOQueryType QueryType=PGSOQueryType::Other)
Returns true if machine function MF is suggested to be size-optimized based on the profile.
const ScalarOptions & getScalarOptions(const LLVMContext &C)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI void initializeConstantHoistingLegacyPassPass(PassRegistry &)
LLVM_ABI bool canReplaceOperandWithVariable(const Instruction *I, unsigned OpIdx)
Given an instruction, is it legal to set operand OpIdx to a non-constant value?
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
RebasedConstantListType RebasedConstants