45#define DEBUG_TYPE "select-optimize"
48 "Number of select groups considered for conversion to branch");
50 "Number of select groups converted due to expensive cold operand");
52 "Number of select groups converted due to high-predictability");
54 "Number of select groups not converted due to unpredictability");
56 "Number of select groups not converted due to cold basic block");
58 "Number of select groups converted due to loop-level analysis");
59STATISTIC(NumSelectsConverted,
"Number of selects converted");
62 "cold-operand-threshold",
63 cl::desc(
"Maximum frequency of path for an operand to be considered cold."),
67 "cold-operand-max-cost-multiplier",
68 cl::desc(
"Maximum cost multiplier of TCC_expensive for the dependence "
69 "slice of a cold operand to be considered inexpensive."),
74 cl::desc(
"Gradient gain threshold (%)."),
79 cl::desc(
"Minimum gain per loop (in cycles) threshold."),
83 "select-opti-loop-relative-gain-threshold",
85 "Minimum relative gain per loop threshold (1/X). Defaults to 12.5%"),
90 cl::desc(
"Default mispredict rate (initialized to 25%)."));
95 cl::desc(
"Disable loop-level heuristics."));
106 std::unique_ptr<BlockFrequencyInfo> BFI;
107 std::unique_ptr<BranchProbabilityInfo> BPI;
153 void optimizeSelectsBase(
Function &
F, SelectGroups &ProfSIGroups);
154 void optimizeSelectsInnerLoops(
Function &
F, SelectGroups &ProfSIGroups);
158 void convertProfitableSIGroups(SelectGroups &ProfSIGroups);
161 void collectSelectGroups(
BasicBlock &BB, SelectGroups &SIGroups);
165 void findProfitableSIGroupsBase(SelectGroups &SIGroups,
166 SelectGroups &ProfSIGroups);
167 void findProfitableSIGroupsInnerLoops(
const Loop *L, SelectGroups &SIGroups,
168 SelectGroups &ProfSIGroups);
182 void getExclBackwardsSlice(
Instruction *
I, std::stack<Instruction *> &Slice,
186 bool isSelectHighlyPredictable(
const SelectInst *SI);
190 bool checkLoopHeuristics(
const Loop *L,
const CostInfo LoopDepth[2]);
194 bool computeLoopCosts(
const Loop *L,
const SelectGroups &SIGroups,
202 std::optional<uint64_t> computeInstCost(
const Instruction *
I);
216char SelectOptimize::ID = 0;
231bool SelectOptimize::runOnFunction(
Function &
F) {
233 TSI =
TM->getSubtargetImpl(
F);
234 TLI = TSI->getTargetLowering();
239 if (!TLI->isSelectSupported(TargetLowering::ScalarValSelect) &&
240 !TLI->isSelectSupported(TargetLowering::ScalarCondVectorVal) &&
241 !TLI->isSelectSupported(TargetLowering::VectorMaskSelect))
244 TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
249 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
250 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
253 PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
254 ORE = &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
255 TSchedModel.init(TSI);
261 return optimizeSelects(
F);
264bool SelectOptimize::optimizeSelects(
Function &
F) {
266 SelectGroups ProfSIGroups;
268 optimizeSelectsBase(
F, ProfSIGroups);
270 optimizeSelectsInnerLoops(
F, ProfSIGroups);
274 convertProfitableSIGroups(ProfSIGroups);
277 return !ProfSIGroups.empty();
280void SelectOptimize::optimizeSelectsBase(
Function &
F,
281 SelectGroups &ProfSIGroups) {
283 SelectGroups SIGroups;
286 Loop *
L = LI->getLoopFor(&BB);
287 if (L &&
L->isInnermost())
289 collectSelectGroups(BB, SIGroups);
293 findProfitableSIGroupsBase(SIGroups, ProfSIGroups);
296void SelectOptimize::optimizeSelectsInnerLoops(
Function &
F,
297 SelectGroups &ProfSIGroups) {
300 for (
unsigned long i = 0; i <
Loops.size(); ++i)
301 for (
Loop *ChildL :
Loops[i]->getSubLoops())
302 Loops.push_back(ChildL);
305 if (!
L->isInnermost())
308 SelectGroups SIGroups;
310 collectSelectGroups(*BB, SIGroups);
312 findProfitableSIGroupsInnerLoops(L, SIGroups, ProfSIGroups);
325 DefSI = dyn_cast<SelectInst>(V)) {
326 assert(DefSI->getCondition() ==
SI->getCondition() &&
327 "The condition of DefSI does not match with SI");
328 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
330 assert(V &&
"Failed to get select true/false value");
334void SelectOptimize::convertProfitableSIGroups(SelectGroups &ProfSIGroups) {
335 for (SelectGroup &ASI : ProfSIGroups) {
375 typedef std::stack<Instruction *>::size_type StackSizeType;
376 StackSizeType maxTrueSliceLen = 0, maxFalseSliceLen = 0;
380 if (
auto *TI = dyn_cast<Instruction>(
SI->getTrueValue())) {
381 std::stack<Instruction *> TrueSlice;
382 getExclBackwardsSlice(TI, TrueSlice, SI,
true);
383 maxTrueSliceLen = std::max(maxTrueSliceLen, TrueSlice.size());
386 if (
auto *FI = dyn_cast<Instruction>(
SI->getFalseValue())) {
387 std::stack<Instruction *> FalseSlice;
388 getExclBackwardsSlice(FI, FalseSlice, SI,
true);
389 maxFalseSliceLen = std::max(maxFalseSliceLen, FalseSlice.size());
404 for (StackSizeType IS = 0; IS < maxTrueSliceLen; ++IS) {
405 for (
auto &S : TrueSlices) {
407 TrueSlicesInterleaved.
push_back(S.top());
412 for (StackSizeType IS = 0; IS < maxFalseSliceLen; ++IS) {
413 for (
auto &S : FalseSlices) {
415 FalseSlicesInterleaved.
push_back(S.top());
427 BFI->setBlockFreq(EndBlock,
BFI->getBlockFreq(StartBlock).getFrequency());
434 auto DIt =
SI->getIterator();
435 while (&*DIt != LastSI) {
436 if (DIt->isDebugOrPseudoInst())
440 for (
auto *DI : DebugPseudoINS) {
446 BasicBlock *TrueBlock =
nullptr, *FalseBlock =
nullptr;
447 BranchInst *TrueBranch =
nullptr, *FalseBranch =
nullptr;
448 if (!TrueSlicesInterleaved.
empty()) {
453 for (
Instruction *TrueInst : TrueSlicesInterleaved)
454 TrueInst->moveBefore(TrueBranch);
456 if (!FalseSlicesInterleaved.
empty()) {
461 for (
Instruction *FalseInst : FalseSlicesInterleaved)
462 FalseInst->moveBefore(FalseBranch);
466 if (TrueBlock == FalseBlock) {
467 assert(TrueBlock ==
nullptr &&
468 "Unexpected basic block transform while optimizing select");
473 FalseBranch->setDebugLoc(
SI->getDebugLoc());
482 if (TrueBlock ==
nullptr) {
485 TrueBlock = StartBlock;
486 }
else if (FalseBlock ==
nullptr) {
489 FalseBlock = StartBlock;
496 IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
497 IB.CreateCondBr(CondFr, TT, FT, SI);
500 INS.
insert(ASI.begin(), ASI.end());
504 for (
auto It = ASI.rbegin(); It != ASI.rend(); ++It) {
513 SI->replaceAllUsesWith(PN);
514 SI->eraseFromParent();
516 ++NumSelectsConverted;
533void SelectOptimize::collectSelectGroups(
BasicBlock &BB,
534 SelectGroups &SIGroups) {
536 while (BBIt != BB.
end()) {
543 SIGroup.push_back(SI);
544 while (BBIt != BB.
end()) {
548 SIGroup.push_back(NSI);
559 if (!isSelectKindSupported(SI))
562 SIGroups.push_back(SIGroup);
567void SelectOptimize::findProfitableSIGroupsBase(SelectGroups &SIGroups,
568 SelectGroups &ProfSIGroups) {
569 for (SelectGroup &ASI : SIGroups) {
570 ++NumSelectOptAnalyzed;
571 if (isConvertToBranchProfitableBase(ASI))
572 ProfSIGroups.push_back(ASI);
582void SelectOptimize::findProfitableSIGroupsInnerLoops(
583 const Loop *L, SelectGroups &SIGroups, SelectGroups &ProfSIGroups) {
584 NumSelectOptAnalyzed += SIGroups.size();
598 if (!computeLoopCosts(L, SIGroups, InstCostMap, LoopCost) ||
599 !checkLoopHeuristics(L, LoopCost)) {
603 for (SelectGroup &ASI : SIGroups) {
608 SelectCost = std::max(SelectCost, InstCostMap[SI].PredCost);
609 BranchCost = std::max(BranchCost, InstCostMap[SI].NonPredCost);
611 if (BranchCost < SelectCost) {
613 OR <<
"Profitable to convert to branch (loop analysis). BranchCost="
614 << BranchCost.toString() <<
", SelectCost=" << SelectCost.
toString()
617 ++NumSelectConvertedLoop;
618 ProfSIGroups.push_back(ASI);
621 ORmiss <<
"Select is more profitable (loop analysis). BranchCost="
622 << BranchCost.toString()
623 <<
", SelectCost=" << SelectCost.
toString() <<
". ";
629bool SelectOptimize::isConvertToBranchProfitableBase(
632 LLVM_DEBUG(
dbgs() <<
"Analyzing select group containing " << *SI <<
"\n");
637 if (PSI->isColdBlock(
SI->getParent(),
BFI.get())) {
639 ORmiss <<
"Not converted to branch because of cold basic block. ";
645 if (
SI->getMetadata(LLVMContext::MD_unpredictable)) {
647 ORmiss <<
"Not converted to branch because of unpredictable branch. ";
654 if (isSelectHighlyPredictable(SI) && TLI->isPredictableSelectExpensive()) {
655 ++NumSelectConvertedHighPred;
656 OR <<
"Converted to branch because of highly predictable branch. ";
663 if (hasExpensiveColdOperand(ASI)) {
664 ++NumSelectConvertedExpColdOperand;
665 OR <<
"Converted to branch because of expensive cold operand.";
670 ORmiss <<
"Not profitable to convert to branch (base heuristic).";
677 return (Numerator + (Denominator / 2)) / Denominator;
680bool SelectOptimize::hasExpensiveColdOperand(
682 bool ColdOperand =
false;
683 uint64_t TrueWeight, FalseWeight, TotalWeight;
685 uint64_t MinWeight = std::min(TrueWeight, FalseWeight);
686 TotalWeight = TrueWeight + FalseWeight;
689 }
else if (PSI->hasProfileSummary()) {
691 ORmiss <<
"Profile data available but missing branch-weights metadata for "
692 "select instruction. ";
702 if (TrueWeight < FalseWeight) {
703 ColdI = dyn_cast<Instruction>(
SI->getTrueValue());
704 HotWeight = FalseWeight;
706 ColdI = dyn_cast<Instruction>(
SI->getFalseValue());
707 HotWeight = TrueWeight;
710 std::stack<Instruction *> ColdSlice;
711 getExclBackwardsSlice(ColdI, ColdSlice, SI);
713 while (!ColdSlice.empty()) {
741 if (It->mayWriteToMemory())
754void SelectOptimize::getExclBackwardsSlice(
Instruction *
I,
755 std::stack<Instruction *> &Slice,
758 std::queue<Instruction *> Worklist;
760 while (!Worklist.empty()) {
765 if (!Visited.
insert(II).second)
775 isa<SelectInst>(II) || isa<PHINode>(II)))
795 if (
auto *OpI = dyn_cast<Instruction>(II->
getOperand(k)))
800bool SelectOptimize::isSelectHighlyPredictable(
const SelectInst *SI) {
804 uint64_t Sum = TrueWeight + FalseWeight;
814bool SelectOptimize::checkLoopHeuristics(
const Loop *L,
815 const CostInfo LoopCost[2]) {
823 L->getHeader()->getFirstNonPHI());
825 if (LoopCost[0].NonPredCost > LoopCost[0].PredCost ||
826 LoopCost[1].NonPredCost >= LoopCost[1].PredCost) {
827 ORmissL <<
"No select conversion in the loop due to no reduction of loop's "
833 Scaled64 Gain[2] = {LoopCost[0].PredCost - LoopCost[0].NonPredCost,
834 LoopCost[1].PredCost - LoopCost[1].NonPredCost};
842 ORmissL <<
"No select conversion in the loop due to small reduction of "
843 "loop's critical path. Gain="
845 <<
", RelativeGain=" << RelativeGain.
toString() <<
"%. ";
855 if (Gain[1] > Gain[0]) {
857 (LoopCost[1].PredCost - LoopCost[0].PredCost);
859 ORmissL <<
"No select conversion in the loop due to small gradient gain. "
861 << GradientGain.
toString() <<
"%. ";
867 else if (Gain[1] < Gain[0]) {
869 <<
"No select conversion in the loop due to negative gradient gain. ";
883bool SelectOptimize::computeLoopCosts(
884 const Loop *L,
const SelectGroups &SIGroups,
886 LLVM_DEBUG(
dbgs() <<
"Calculating Latency / IPredCost / INonPredCost of loop "
887 <<
L->getHeader()->getName() <<
"\n");
888 const auto &SIset = getSIset(SIGroups);
891 const unsigned Iterations = 2;
892 for (
unsigned Iter = 0; Iter < Iterations; ++Iter) {
894 CostInfo &MaxCost = LoopCost[Iter];
897 if (
I.isDebugOrPseudoInst())
906 for (
const Use &U :
I.operands()) {
907 auto UI = dyn_cast<Instruction>(
U.get());
910 if (InstCostMap.
count(UI)) {
911 IPredCost = std::max(IPredCost, InstCostMap[UI].PredCost);
912 INonPredCost = std::max(INonPredCost, InstCostMap[UI].NonPredCost);
915 auto ILatency = computeInstCost(&
I);
918 ORmissL <<
"Invalid instruction cost preventing analysis and "
919 "optimization of the inner-most loop containing this "
933 if (SIset.contains(&
I)) {
934 auto SI = cast<SelectInst>(&
I);
938 if (
auto *TI = dyn_cast<Instruction>(
SI->getTrueValue()))
939 if (InstCostMap.
count(TI))
940 TrueOpCost = InstCostMap[TI].NonPredCost;
941 if (
auto *FI = dyn_cast<Instruction>(
SI->getFalseValue()))
942 if (InstCostMap.
count(FI))
943 FalseOpCost = InstCostMap[FI].NonPredCost;
945 getPredictedPathCost(TrueOpCost, FalseOpCost, SI);
948 if (
auto *CI = dyn_cast<Instruction>(
SI->getCondition()))
949 if (InstCostMap.
count(CI))
950 CondCost = InstCostMap[CI].NonPredCost;
951 Scaled64 MispredictCost = getMispredictionCost(SI, CondCost);
953 INonPredCost = PredictedPathCost + MispredictCost;
956 << INonPredCost <<
" for " <<
I <<
"\n");
958 InstCostMap[&
I] = {IPredCost, INonPredCost};
959 MaxCost.PredCost = std::max(MaxCost.PredCost, IPredCost);
960 MaxCost.NonPredCost = std::max(MaxCost.NonPredCost, INonPredCost);
964 <<
" MaxCost = " << MaxCost.PredCost <<
" "
965 << MaxCost.NonPredCost <<
"\n");
971SelectOptimize::getSIset(
const SelectGroups &SIGroups) {
973 for (
const SelectGroup &ASI : SIGroups)
979std::optional<uint64_t> SelectOptimize::computeInstCost(
const Instruction *
I) {
983 return std::optional<uint64_t>(*OC);
988SelectOptimize::getMispredictionCost(
const SelectInst *SI,
990 uint64_t MispredictPenalty = TSchedModel.getMCSchedModel()->MispredictPenalty;
997 if (isSelectHighlyPredictable(SI))
1008 return MispredictCost;
1019 uint64_t SumWeight = TrueWeight + FalseWeight;
1020 if (SumWeight != 0) {
1024 return PredPathCost;
1029 PredPathCost = std::max(TrueCost *
Scaled64::get(3) + FalseCost,
1032 return PredPathCost;
1035bool SelectOptimize::isSelectKindSupported(
SelectInst *SI) {
1036 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
1040 if (
SI->getType()->isVectorTy())
1041 SelectKind = TargetLowering::ScalarCondVectorVal;
1043 SelectKind = TargetLowering::ScalarValSelect;
1044 return TLI->isSelectSupported(SelectKind);
const char LLVMTargetMachineRef TM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file contains the declarations for profiling metadata utility functions.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isSafeToSinkLoad(Instruction *LoadI, Instruction *SI)
static InstructionCost divideNearest(InstructionCost Numerator, uint64_t Denominator)
static Value * getTrueOrFalseValue(SelectInst *SI, bool isTrue, const SmallPtrSet< const Instruction *, 2 > &Selects)
If isTrue is true, return the true value of SI, otherwise return false value of SI.
static cl::opt< unsigned > ColdOperandMaxCostMultiplier("cold-operand-max-cost-multiplier", cl::desc("Maximum cost multiplier of TCC_expensive for the dependence " "slice of a cold operand to be considered inexpensive."), cl::init(1), cl::Hidden)
static cl::opt< unsigned > ColdOperandThreshold("cold-operand-threshold", cl::desc("Maximum frequency of path for an operand to be considered cold."), cl::init(20), cl::Hidden)
static cl::opt< bool > DisableLoopLevelHeuristics("disable-loop-level-heuristics", cl::Hidden, cl::init(false), cl::desc("Disable loop-level heuristics."))
static bool isSpecialSelect(SelectInst *SI)
static cl::opt< unsigned > GainCycleThreshold("select-opti-loop-cycle-gain-threshold", cl::desc("Minimum gain per loop (in cycles) threshold."), cl::init(4), cl::Hidden)
static cl::opt< unsigned > MispredictDefaultRate("mispredict-default-rate", cl::Hidden, cl::init(25), cl::desc("Default mispredict rate (initialized to 25%)."))
static void EmitAndPrintRemark(OptimizationRemarkEmitter *ORE, DiagnosticInfoOptimizationBase &Rem)
static cl::opt< unsigned > GainGradientThreshold("select-opti-loop-gradient-gain-threshold", cl::desc("Gradient gain threshold (%)."), cl::init(25), cl::Hidden)
static cl::opt< unsigned > GainRelativeThreshold("select-opti-loop-relative-gain-threshold", cl::desc("Minimum relative gain per loop threshold (1/X). Defaults to 12.5%"), cl::init(8), cl::Hidden)
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)
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Instruction & front() const
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="", bool Before=false)
Split the basic block into two basic blocks at the specified instruction.
const Function * getParent() const
Return the enclosing method, or null if none.
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Conditional or Unconditional Branch instruction.
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
Analysis providing branch probability information.
static BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Common features for diagnostics dealing with optimization remarks that are used by both IR and MIR pa...
std::string getMsg() const
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
std::optional< CostType > getValue() const
This function is intended to be used as sparingly as possible, since the class provides the full rang...
bool isDebugOrPseudoInst() const LLVM_READONLY
Return true if the instruction is a DbgInfoIntrinsic or PseudoProbeInst.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
const BasicBlock * getParent() const
bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
bool isTerminator() const
bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
The legacy pass manager's analysis pass to compute loop information.
Represents a single loop in the control flow graph.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
std::string toString(unsigned Precision=DefaultPrecision)
Convert to a decimal representation in a string.
static ScaledNumber get(uint64_t N)
static ScaledNumber getZero()
This class represents the LLVM 'select' instruction.
const Value * getCondition() const
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
SelectSupportKind
Enum that describes what type of support for selects the target has.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
Target-Independent Code Generator Pass Configuration Options.
Provide an instruction scheduling machine model to CodeGen passes.
TargetSubtargetInfo - Generic base class for all target subtargets.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVMContext & getContext() const
All values hold a context through their type.
void takeName(Value *V)
Transfer the name from V to this value.
self_iterator getIterator()
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
bool match(Val *V, const Pattern &P)
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createSelectOptimizePass()
This pass converts conditional moves to conditional jumps when profitable.
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
void initializeSelectOptimizePass(PassRegistry &)