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) {
515 SI->replaceAllUsesWith(PN);
516 SI->eraseFromParent();
518 ++NumSelectsConverted;
535void SelectOptimize::collectSelectGroups(
BasicBlock &BB,
536 SelectGroups &SIGroups) {
538 while (BBIt != BB.
end()) {
545 SIGroup.push_back(SI);
546 while (BBIt != BB.
end()) {
550 SIGroup.push_back(NSI);
561 if (!isSelectKindSupported(SI))
564 SIGroups.push_back(SIGroup);
569void SelectOptimize::findProfitableSIGroupsBase(SelectGroups &SIGroups,
570 SelectGroups &ProfSIGroups) {
571 for (SelectGroup &ASI : SIGroups) {
572 ++NumSelectOptAnalyzed;
573 if (isConvertToBranchProfitableBase(ASI))
574 ProfSIGroups.push_back(ASI);
584void SelectOptimize::findProfitableSIGroupsInnerLoops(
585 const Loop *L, SelectGroups &SIGroups, SelectGroups &ProfSIGroups) {
586 NumSelectOptAnalyzed += SIGroups.size();
600 if (!computeLoopCosts(L, SIGroups, InstCostMap, LoopCost) ||
601 !checkLoopHeuristics(L, LoopCost)) {
605 for (SelectGroup &ASI : SIGroups) {
610 SelectCost = std::max(SelectCost, InstCostMap[SI].PredCost);
611 BranchCost = std::max(BranchCost, InstCostMap[SI].NonPredCost);
613 if (BranchCost < SelectCost) {
615 OR <<
"Profitable to convert to branch (loop analysis). BranchCost="
616 << BranchCost.toString() <<
", SelectCost=" << SelectCost.
toString()
619 ++NumSelectConvertedLoop;
620 ProfSIGroups.push_back(ASI);
623 ORmiss <<
"Select is more profitable (loop analysis). BranchCost="
624 << BranchCost.toString()
625 <<
", SelectCost=" << SelectCost.
toString() <<
". ";
631bool SelectOptimize::isConvertToBranchProfitableBase(
634 LLVM_DEBUG(
dbgs() <<
"Analyzing select group containing " << *SI <<
"\n");
639 if (PSI->isColdBlock(
SI->getParent(),
BFI.get())) {
641 ORmiss <<
"Not converted to branch because of cold basic block. ";
647 if (
SI->getMetadata(LLVMContext::MD_unpredictable)) {
649 ORmiss <<
"Not converted to branch because of unpredictable branch. ";
656 if (isSelectHighlyPredictable(SI) && TLI->isPredictableSelectExpensive()) {
657 ++NumSelectConvertedHighPred;
658 OR <<
"Converted to branch because of highly predictable branch. ";
665 if (hasExpensiveColdOperand(ASI)) {
666 ++NumSelectConvertedExpColdOperand;
667 OR <<
"Converted to branch because of expensive cold operand.";
672 ORmiss <<
"Not profitable to convert to branch (base heuristic).";
679 return (Numerator + (Denominator / 2)) / Denominator;
682bool SelectOptimize::hasExpensiveColdOperand(
684 bool ColdOperand =
false;
685 uint64_t TrueWeight, FalseWeight, TotalWeight;
687 uint64_t MinWeight = std::min(TrueWeight, FalseWeight);
688 TotalWeight = TrueWeight + FalseWeight;
691 }
else if (PSI->hasProfileSummary()) {
693 ORmiss <<
"Profile data available but missing branch-weights metadata for "
694 "select instruction. ";
704 if (TrueWeight < FalseWeight) {
705 ColdI = dyn_cast<Instruction>(
SI->getTrueValue());
706 HotWeight = FalseWeight;
708 ColdI = dyn_cast<Instruction>(
SI->getFalseValue());
709 HotWeight = TrueWeight;
712 std::stack<Instruction *> ColdSlice;
713 getExclBackwardsSlice(ColdI, ColdSlice, SI);
715 while (!ColdSlice.empty()) {
739 if (LoadI->
getParent() != SI->getParent())
743 if (It->mayWriteToMemory())
756void SelectOptimize::getExclBackwardsSlice(
Instruction *
I,
757 std::stack<Instruction *> &Slice,
760 std::queue<Instruction *> Worklist;
762 while (!Worklist.empty()) {
767 if (!Visited.
insert(II).second)
777 isa<SelectInst>(II) || isa<PHINode>(II)))
797 if (
auto *OpI = dyn_cast<Instruction>(II->
getOperand(k)))
802bool SelectOptimize::isSelectHighlyPredictable(
const SelectInst *SI) {
806 uint64_t Sum = TrueWeight + FalseWeight;
816bool SelectOptimize::checkLoopHeuristics(
const Loop *L,
817 const CostInfo LoopCost[2]) {
825 L->getHeader()->getFirstNonPHI());
827 if (LoopCost[0].NonPredCost > LoopCost[0].PredCost ||
828 LoopCost[1].NonPredCost >= LoopCost[1].PredCost) {
829 ORmissL <<
"No select conversion in the loop due to no reduction of loop's "
835 Scaled64 Gain[2] = {LoopCost[0].PredCost - LoopCost[0].NonPredCost,
836 LoopCost[1].PredCost - LoopCost[1].NonPredCost};
844 ORmissL <<
"No select conversion in the loop due to small reduction of "
845 "loop's critical path. Gain="
847 <<
", RelativeGain=" << RelativeGain.
toString() <<
"%. ";
857 if (Gain[1] > Gain[0]) {
859 (LoopCost[1].PredCost - LoopCost[0].PredCost);
861 ORmissL <<
"No select conversion in the loop due to small gradient gain. "
863 << GradientGain.
toString() <<
"%. ";
869 else if (Gain[1] < Gain[0]) {
871 <<
"No select conversion in the loop due to negative gradient gain. ";
885bool SelectOptimize::computeLoopCosts(
886 const Loop *L,
const SelectGroups &SIGroups,
888 LLVM_DEBUG(
dbgs() <<
"Calculating Latency / IPredCost / INonPredCost of loop "
889 <<
L->getHeader()->getName() <<
"\n");
890 const auto &SIset = getSIset(SIGroups);
893 const unsigned Iterations = 2;
894 for (
unsigned Iter = 0; Iter < Iterations; ++Iter) {
896 CostInfo &MaxCost = LoopCost[Iter];
899 if (
I.isDebugOrPseudoInst())
908 for (
const Use &U :
I.operands()) {
909 auto UI = dyn_cast<Instruction>(
U.get());
912 if (InstCostMap.
count(UI)) {
913 IPredCost = std::max(IPredCost, InstCostMap[UI].PredCost);
914 INonPredCost = std::max(INonPredCost, InstCostMap[UI].NonPredCost);
917 auto ILatency = computeInstCost(&
I);
920 ORmissL <<
"Invalid instruction cost preventing analysis and "
921 "optimization of the inner-most loop containing this "
935 if (SIset.contains(&
I)) {
936 auto SI = cast<SelectInst>(&
I);
940 if (
auto *TI = dyn_cast<Instruction>(
SI->getTrueValue()))
941 if (InstCostMap.
count(TI))
942 TrueOpCost = InstCostMap[TI].NonPredCost;
943 if (
auto *FI = dyn_cast<Instruction>(
SI->getFalseValue()))
944 if (InstCostMap.
count(FI))
945 FalseOpCost = InstCostMap[FI].NonPredCost;
947 getPredictedPathCost(TrueOpCost, FalseOpCost, SI);
950 if (
auto *CI = dyn_cast<Instruction>(
SI->getCondition()))
951 if (InstCostMap.
count(CI))
952 CondCost = InstCostMap[CI].NonPredCost;
953 Scaled64 MispredictCost = getMispredictionCost(SI, CondCost);
955 INonPredCost = PredictedPathCost + MispredictCost;
958 << INonPredCost <<
" for " <<
I <<
"\n");
960 InstCostMap[&
I] = {IPredCost, INonPredCost};
961 MaxCost.PredCost = std::max(MaxCost.PredCost, IPredCost);
962 MaxCost.NonPredCost = std::max(MaxCost.NonPredCost, INonPredCost);
966 <<
" MaxCost = " << MaxCost.PredCost <<
" "
967 << MaxCost.NonPredCost <<
"\n");
973SelectOptimize::getSIset(
const SelectGroups &SIGroups) {
975 for (
const SelectGroup &ASI : SIGroups)
981std::optional<uint64_t> SelectOptimize::computeInstCost(
const Instruction *
I) {
985 return std::optional<uint64_t>(*OC);
990SelectOptimize::getMispredictionCost(
const SelectInst *SI,
992 uint64_t MispredictPenalty = TSchedModel.getMCSchedModel()->MispredictPenalty;
999 if (isSelectHighlyPredictable(SI))
1010 return MispredictCost;
1021 uint64_t SumWeight = TrueWeight + FalseWeight;
1022 if (SumWeight != 0) {
1026 return PredPathCost;
1031 PredPathCost = std::max(TrueCost *
Scaled64::get(3) + FalseCost,
1034 return PredPathCost;
1037bool SelectOptimize::isSelectKindSupported(
SelectInst *SI) {
1038 bool VectorCond = !
SI->getCondition()->getType()->isIntegerTy(1);
1042 if (
SI->getType()->isVectorTy())
1043 SelectKind = TargetLowering::ScalarCondVectorVal;
1045 SelectKind = TargetLowering::ScalarValSelect;
1046 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...
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.
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
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 &)