46#define DEBUG_TYPE "select-optimize"
49 "Number of select groups considered for conversion to branch");
51 "Number of select groups converted due to expensive cold operand");
53 "Number of select groups converted due to high-predictability");
55 "Number of select groups not converted due to unpredictability");
57 "Number of select groups not converted due to cold basic block");
59 "Number of select groups converted due to loop-level analysis");
60STATISTIC(NumSelectsConverted,
"Number of selects converted");
63 "cold-operand-threshold",
64 cl::desc(
"Maximum frequency of path for an operand to be considered cold."),
68 "cold-operand-max-cost-multiplier",
69 cl::desc(
"Maximum cost multiplier of TCC_expensive for the dependence "
70 "slice of a cold operand to be considered inexpensive."),
75 cl::desc(
"Gradient gain threshold (%)."),
80 cl::desc(
"Minimum gain per loop (in cycles) threshold."),
84 "select-opti-loop-relative-gain-threshold",
86 "Minimum relative gain per loop threshold (1/X). Defaults to 12.5%"),
91 cl::desc(
"Default mispredict rate (initialized to 25%)."));
96 cl::desc(
"Disable loop-level heuristics."));
107 std::unique_ptr<BlockFrequencyInfo> BFI;
108 std::unique_ptr<BranchProbabilityInfo> BPI;
154 void optimizeSelectsBase(
Function &
F, SelectGroups &ProfSIGroups);
155 void optimizeSelectsInnerLoops(
Function &
F, SelectGroups &ProfSIGroups);
159 void convertProfitableSIGroups(SelectGroups &ProfSIGroups);
162 void collectSelectGroups(
BasicBlock &BB, SelectGroups &SIGroups);
166 void findProfitableSIGroupsBase(SelectGroups &SIGroups,
167 SelectGroups &ProfSIGroups);
168 void findProfitableSIGroupsInnerLoops(
const Loop *L, SelectGroups &SIGroups,
169 SelectGroups &ProfSIGroups);
183 void getExclBackwardsSlice(
Instruction *
I, std::stack<Instruction *> &Slice,
187 bool isSelectHighlyPredictable(
const SelectInst *SI);
191 bool checkLoopHeuristics(
const Loop *L,
const CostInfo LoopDepth[2]);
195 bool computeLoopCosts(
const Loop *L,
const SelectGroups &SIGroups,
203 std::optional<uint64_t> computeInstCost(
const Instruction *
I);
217char SelectOptimize::ID = 0;
232bool SelectOptimize::runOnFunction(
Function &
F) {
234 TSI =
TM->getSubtargetImpl(
F);
235 TLI = TSI->getTargetLowering();
240 if (!TLI->isSelectSupported(TargetLowering::ScalarValSelect) &&
241 !TLI->isSelectSupported(TargetLowering::ScalarCondVectorVal) &&
242 !TLI->isSelectSupported(TargetLowering::VectorMaskSelect))
245 TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
250 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
251 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
254 PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
255 ORE = &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
256 TSchedModel.init(TSI);
262 return optimizeSelects(
F);
265bool SelectOptimize::optimizeSelects(
Function &
F) {
267 SelectGroups ProfSIGroups;
269 optimizeSelectsBase(
F, ProfSIGroups);
271 optimizeSelectsInnerLoops(
F, ProfSIGroups);
275 convertProfitableSIGroups(ProfSIGroups);
278 return !ProfSIGroups.empty();
281void SelectOptimize::optimizeSelectsBase(
Function &
F,
282 SelectGroups &ProfSIGroups) {
284 SelectGroups SIGroups;
287 Loop *
L = LI->getLoopFor(&BB);
288 if (L &&
L->isInnermost())
290 collectSelectGroups(BB, SIGroups);
294 findProfitableSIGroupsBase(SIGroups, ProfSIGroups);
297void SelectOptimize::optimizeSelectsInnerLoops(
Function &
F,
298 SelectGroups &ProfSIGroups) {
301 for (
unsigned long i = 0; i <
Loops.size(); ++i)
302 for (
Loop *ChildL :
Loops[i]->getSubLoops())
303 Loops.push_back(ChildL);
306 if (!
L->isInnermost())
309 SelectGroups SIGroups;
311 collectSelectGroups(*BB, SIGroups);
313 findProfitableSIGroupsInnerLoops(L, SIGroups, ProfSIGroups);
326 DefSI = dyn_cast<SelectInst>(V)) {
327 assert(DefSI->getCondition() ==
SI->getCondition() &&
328 "The condition of DefSI does not match with SI");
329 V = (isTrue ? DefSI->getTrueValue() : DefSI->getFalseValue());
331 assert(V &&
"Failed to get select true/false value");
335void SelectOptimize::convertProfitableSIGroups(SelectGroups &ProfSIGroups) {
336 for (SelectGroup &ASI : ProfSIGroups) {
376 typedef std::stack<Instruction *>::size_type StackSizeType;
377 StackSizeType maxTrueSliceLen = 0, maxFalseSliceLen = 0;
381 if (
auto *TI = dyn_cast<Instruction>(
SI->getTrueValue())) {
382 std::stack<Instruction *> TrueSlice;
383 getExclBackwardsSlice(TI, TrueSlice, SI,
true);
384 maxTrueSliceLen = std::max(maxTrueSliceLen, TrueSlice.size());
387 if (
auto *FI = dyn_cast<Instruction>(
SI->getFalseValue())) {
388 std::stack<Instruction *> FalseSlice;
389 getExclBackwardsSlice(FI, FalseSlice, SI,
true);
390 maxFalseSliceLen = std::max(maxFalseSliceLen, FalseSlice.size());
405 for (StackSizeType IS = 0; IS < maxTrueSliceLen; ++IS) {
406 for (
auto &S : TrueSlices) {
408 TrueSlicesInterleaved.
push_back(S.top());
413 for (StackSizeType IS = 0; IS < maxFalseSliceLen; ++IS) {
414 for (
auto &S : FalseSlices) {
416 FalseSlicesInterleaved.
push_back(S.top());
428 BFI->setBlockFreq(EndBlock,
BFI->getBlockFreq(StartBlock).getFrequency());
435 auto DIt =
SI->getIterator();
436 while (&*DIt != LastSI) {
437 if (DIt->isDebugOrPseudoInst())
441 for (
auto *DI : DebugPseudoINS) {
447 BasicBlock *TrueBlock =
nullptr, *FalseBlock =
nullptr;
448 BranchInst *TrueBranch =
nullptr, *FalseBranch =
nullptr;
449 if (!TrueSlicesInterleaved.
empty()) {
454 for (
Instruction *TrueInst : TrueSlicesInterleaved)
455 TrueInst->moveBefore(TrueBranch);
457 if (!FalseSlicesInterleaved.
empty()) {
462 for (
Instruction *FalseInst : FalseSlicesInterleaved)
463 FalseInst->moveBefore(FalseBranch);
467 if (TrueBlock == FalseBlock) {
468 assert(TrueBlock ==
nullptr &&
469 "Unexpected basic block transform while optimizing select");
474 FalseBranch->setDebugLoc(
SI->getDebugLoc());
483 if (TrueBlock ==
nullptr) {
486 TrueBlock = StartBlock;
487 }
else if (FalseBlock ==
nullptr) {
490 FalseBlock = StartBlock;
497 IB.CreateFreeze(
SI->getCondition(),
SI->getName() +
".frozen");
498 IB.CreateCondBr(CondFr, TT, FT, SI);
501 INS.
insert(ASI.begin(), ASI.end());
505 for (
auto It = ASI.rbegin(); It != ASI.rend(); ++It) {
514 SI->replaceAllUsesWith(PN);
515 SI->eraseFromParent();
517 ++NumSelectsConverted;
534void SelectOptimize::collectSelectGroups(
BasicBlock &BB,
535 SelectGroups &SIGroups) {
537 while (BBIt != BB.
end()) {
544 SIGroup.push_back(SI);
545 while (BBIt != BB.
end()) {
549 SIGroup.push_back(NSI);
560 if (!isSelectKindSupported(SI))
563 SIGroups.push_back(SIGroup);
568void SelectOptimize::findProfitableSIGroupsBase(SelectGroups &SIGroups,
569 SelectGroups &ProfSIGroups) {
570 for (SelectGroup &ASI : SIGroups) {
571 ++NumSelectOptAnalyzed;
572 if (isConvertToBranchProfitableBase(ASI))
573 ProfSIGroups.push_back(ASI);
583void SelectOptimize::findProfitableSIGroupsInnerLoops(
584 const Loop *L, SelectGroups &SIGroups, SelectGroups &ProfSIGroups) {
585 NumSelectOptAnalyzed += SIGroups.size();
599 if (!computeLoopCosts(L, SIGroups, InstCostMap, LoopCost) ||
600 !checkLoopHeuristics(L, LoopCost)) {
604 for (SelectGroup &ASI : SIGroups) {
609 SelectCost = std::max(SelectCost, InstCostMap[SI].PredCost);
610 BranchCost = std::max(BranchCost, InstCostMap[SI].NonPredCost);
612 if (BranchCost < SelectCost) {
614 OR <<
"Profitable to convert to branch (loop analysis). BranchCost="
615 << BranchCost.toString() <<
", SelectCost=" << SelectCost.
toString()
618 ++NumSelectConvertedLoop;
619 ProfSIGroups.push_back(ASI);
622 ORmiss <<
"Select is more profitable (loop analysis). BranchCost="
623 << BranchCost.toString()
624 <<
", SelectCost=" << SelectCost.
toString() <<
". ";
630bool SelectOptimize::isConvertToBranchProfitableBase(
633 LLVM_DEBUG(
dbgs() <<
"Analyzing select group containing " << *SI <<
"\n");
638 if (PSI->isColdBlock(
SI->getParent(),
BFI.get())) {
640 ORmiss <<
"Not converted to branch because of cold basic block. ";
646 if (
SI->getMetadata(LLVMContext::MD_unpredictable)) {
648 ORmiss <<
"Not converted to branch because of unpredictable branch. ";
655 if (isSelectHighlyPredictable(SI) && TLI->isPredictableSelectExpensive()) {
656 ++NumSelectConvertedHighPred;
657 OR <<
"Converted to branch because of highly predictable branch. ";
664 if (hasExpensiveColdOperand(ASI)) {
665 ++NumSelectConvertedExpColdOperand;
666 OR <<
"Converted to branch because of expensive cold operand.";
671 ORmiss <<
"Not profitable to convert to branch (base heuristic).";
678 return (Numerator + (Denominator / 2)) / Denominator;
681bool SelectOptimize::hasExpensiveColdOperand(
683 bool ColdOperand =
false;
684 uint64_t TrueWeight, FalseWeight, TotalWeight;
686 uint64_t MinWeight = std::min(TrueWeight, FalseWeight);
687 TotalWeight = TrueWeight + FalseWeight;
690 }
else if (PSI->hasProfileSummary()) {
692 ORmiss <<
"Profile data available but missing branch-weights metadata for "
693 "select instruction. ";
703 if (TrueWeight < FalseWeight) {
704 ColdI = dyn_cast<Instruction>(
SI->getTrueValue());
705 HotWeight = FalseWeight;
707 ColdI = dyn_cast<Instruction>(
SI->getFalseValue());
708 HotWeight = TrueWeight;
711 std::stack<Instruction *> ColdSlice;
712 getExclBackwardsSlice(ColdI, ColdSlice, SI);
714 while (!ColdSlice.empty()) {
742 if (It->mayWriteToMemory())
755void SelectOptimize::getExclBackwardsSlice(
Instruction *
I,
756 std::stack<Instruction *> &Slice,
759 std::queue<Instruction *> Worklist;
761 while (!Worklist.empty()) {
766 if (!Visited.
insert(II).second)
776 isa<SelectInst>(II) || isa<PHINode>(II)))
796 if (
auto *OpI = dyn_cast<Instruction>(II->
getOperand(k)))
801bool SelectOptimize::isSelectHighlyPredictable(
const SelectInst *SI) {
805 uint64_t Sum = TrueWeight + FalseWeight;
815bool SelectOptimize::checkLoopHeuristics(
const Loop *L,
816 const CostInfo LoopCost[2]) {
824 L->getHeader()->getFirstNonPHI());
826 if (LoopCost[0].NonPredCost > LoopCost[0].PredCost ||
827 LoopCost[1].NonPredCost >= LoopCost[1].PredCost) {
828 ORmissL <<
"No select conversion in the loop due to no reduction of loop's "
834 Scaled64 Gain[2] = {LoopCost[0].PredCost - LoopCost[0].NonPredCost,
835 LoopCost[1].PredCost - LoopCost[1].NonPredCost};
843 ORmissL <<
"No select conversion in the loop due to small reduction of "
844 "loop's critical path. Gain="
846 <<
", RelativeGain=" << RelativeGain.
toString() <<
"%. ";
856 if (Gain[1] > Gain[0]) {
858 (LoopCost[1].PredCost - LoopCost[0].PredCost);
860 ORmissL <<
"No select conversion in the loop due to small gradient gain. "
862 << GradientGain.
toString() <<
"%. ";
868 else if (Gain[1] < Gain[0]) {
870 <<
"No select conversion in the loop due to negative gradient gain. ";
884bool SelectOptimize::computeLoopCosts(
885 const Loop *L,
const SelectGroups &SIGroups,
887 LLVM_DEBUG(
dbgs() <<
"Calculating Latency / IPredCost / INonPredCost of loop "
888 <<
L->getHeader()->getName() <<
"\n");
889 const auto &SIset = getSIset(SIGroups);
892 const unsigned Iterations = 2;
893 for (
unsigned Iter = 0; Iter < Iterations; ++Iter) {
895 CostInfo &MaxCost = LoopCost[Iter];
898 if (
I.isDebugOrPseudoInst())
907 for (
const Use &U :
I.operands()) {
908 auto UI = dyn_cast<Instruction>(
U.get());
911 if (InstCostMap.
count(UI)) {
912 IPredCost = std::max(IPredCost, InstCostMap[UI].PredCost);
913 INonPredCost = std::max(INonPredCost, InstCostMap[UI].NonPredCost);
916 auto ILatency = computeInstCost(&
I);
919 ORmissL <<
"Invalid instruction cost preventing analysis and "
920 "optimization of the inner-most loop containing this "
934 if (SIset.contains(&
I)) {
935 auto SI = cast<SelectInst>(&
I);
939 if (
auto *TI = dyn_cast<Instruction>(
SI->getTrueValue()))
940 if (InstCostMap.
count(TI))
941 TrueOpCost = InstCostMap[TI].NonPredCost;
942 if (
auto *FI = dyn_cast<Instruction>(
SI->getFalseValue()))
943 if (InstCostMap.
count(FI))
944 FalseOpCost = InstCostMap[FI].NonPredCost;
946 getPredictedPathCost(TrueOpCost, FalseOpCost, SI);
949 if (
auto *CI = dyn_cast<Instruction>(
SI->getCondition()))
950 if (InstCostMap.
count(CI))
951 CondCost = InstCostMap[CI].NonPredCost;
952 Scaled64 MispredictCost = getMispredictionCost(SI, CondCost);
954 INonPredCost = PredictedPathCost + MispredictCost;
957 << INonPredCost <<
" for " <<
I <<
"\n");
959 InstCostMap[&
I] = {IPredCost, INonPredCost};
960 MaxCost.PredCost = std::max(MaxCost.PredCost, IPredCost);
961 MaxCost.NonPredCost = std::max(MaxCost.NonPredCost, INonPredCost);
965 <<
" MaxCost = " << MaxCost.PredCost <<
" "
966 << MaxCost.NonPredCost <<
"\n");
972SelectOptimize::getSIset(
const SelectGroups &SIGroups) {
974 for (
const SelectGroup &ASI : SIGroups)
980std::optional<uint64_t> SelectOptimize::computeInstCost(
const Instruction *
I) {
984 return std::optional<uint64_t>(*OC);
989SelectOptimize::getMispredictionCost(
const SelectInst *SI,
991 uint64_t MispredictPenalty = TSchedModel.getMCSchedModel()->MispredictPenalty;
998 if (isSelectHighlyPredictable(SI))
1009 return MispredictCost;
1020 uint64_t SumWeight = TrueWeight + FalseWeight;
1021 if (SumWeight != 0) {
1025 return PredPathCost;
1030 PredPathCost = std::max(TrueCost *
Scaled64::get(3) + FalseCost,
1033 return PredPathCost;
1036bool SelectOptimize::isSelectKindSupported(
SelectInst *SI) {
1037 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
1041 if (
SI->getType()->isVectorTy())
1042 SelectKind = TargetLowering::ScalarCondVectorVal;
1044 SelectKind = TargetLowering::ScalarValSelect;
1045 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 &)