31#define GET_GICOMBINER_DEPS
32#include "AMDGPUGenPreLegalizeGICombiner.inc"
33#undef GET_GICOMBINER_DEPS
35#define DEBUG_TYPE "amdgpu-regbank-combiner"
41#define GET_GICOMBINER_TYPES
42#include "AMDGPUGenRegBankGICombiner.inc"
43#undef GET_GICOMBINER_TYPES
45class AMDGPURegBankCombinerImpl :
public Combiner {
47 const AMDGPURegBankCombinerImplRuleConfig &RuleConfig;
55 AMDGPURegBankCombinerImpl(
58 const AMDGPURegBankCombinerImplRuleConfig &RuleConfig,
62 static const char *
getName() {
return "AMDGPURegBankCombinerImpl"; }
70 unsigned Min, Max, Med;
73 struct Med3MatchInfo {
78 struct MinMaxToMinMax3MatchInfo {
83 MinMaxMedOpc getMinMaxPair(
unsigned Opc)
const;
85 template <
class m_Cst,
typename CstTy>
87 Register &Val, CstTy &K0, CstTy &K1)
const;
89 bool matchIntMinMaxToMed3(
MachineInstr &
MI, Med3MatchInfo &MatchInfo)
const;
90 bool matchFPMinMaxToMed3(
MachineInstr &
MI, Med3MatchInfo &MatchInfo)
const;
104 MinMaxToMinMax3MatchInfo &MatchInfo)
const;
106 MinMaxToMinMax3MatchInfo &MatchInfo)
const;
110 bool getIEEE()
const;
111 bool getDX10Clamp()
const;
118#define GET_GICOMBINER_CLASS_MEMBERS
119#define AMDGPUSubtarget GCNSubtarget
120#include "AMDGPUGenRegBankGICombiner.inc"
121#undef GET_GICOMBINER_CLASS_MEMBERS
122#undef AMDGPUSubtarget
125#define GET_GICOMBINER_IMPL
126#define AMDGPUSubtarget GCNSubtarget
127#include "AMDGPUGenRegBankGICombiner.inc"
128#undef AMDGPUSubtarget
129#undef GET_GICOMBINER_IMPL
131AMDGPURegBankCombinerImpl::AMDGPURegBankCombinerImpl(
134 const AMDGPURegBankCombinerImplRuleConfig &RuleConfig,
136 :
Combiner(MF, CInfo, &VT, CSEInfo), RuleConfig(RuleConfig), STI(STI),
137 RBI(*STI.getRegBankInfo()),
TRI(*STI.getRegisterInfo()),
138 TII(*STI.getInstrInfo()),
139 Helper(Observer,
B,
false, &VT, MDT, LI),
141#include
"AMDGPUGenRegBankGICombiner.inc"
146bool AMDGPURegBankCombinerImpl::isVgprRegBank(
Register Reg)
const {
151 if (isVgprRegBank(
Reg))
157 if (
Use.getOpcode() == AMDGPU::COPY && isVgprRegBank(Def))
167AMDGPURegBankCombinerImpl::MinMaxMedOpc
168AMDGPURegBankCombinerImpl::getMinMaxPair(
unsigned Opc)
const {
174 return {AMDGPU::G_SMIN, AMDGPU::G_SMAX, AMDGPU::G_AMDGPU_SMED3};
177 return {AMDGPU::G_UMIN, AMDGPU::G_UMAX, AMDGPU::G_AMDGPU_UMED3};
178 case AMDGPU::G_FMAXNUM:
179 case AMDGPU::G_FMINNUM:
180 return {AMDGPU::G_FMINNUM, AMDGPU::G_FMAXNUM, AMDGPU::G_AMDGPU_FMED3};
181 case AMDGPU::G_FMAXNUM_IEEE:
182 case AMDGPU::G_FMINNUM_IEEE:
183 return {AMDGPU::G_FMINNUM_IEEE, AMDGPU::G_FMAXNUM_IEEE,
184 AMDGPU::G_AMDGPU_FMED3};
188template <
class m_Cst,
typename CstTy>
189bool AMDGPURegBankCombinerImpl::matchMed(MachineInstr &
MI,
190 MachineRegisterInfo &
MRI,
192 CstTy &K0, CstTy &K1)
const {
210bool AMDGPURegBankCombinerImpl::matchIntMinMaxToMed3(
211 MachineInstr &
MI, Med3MatchInfo &MatchInfo)
const {
213 if (!isVgprRegBank(Dst))
221 MinMaxMedOpc OpcodeTriple = getMinMaxPair(
MI.getOpcode());
223 std::optional<ValueAndVReg> K0, K1;
225 if (!matchMed<GCstAndRegMatch>(
MI,
MRI, OpcodeTriple, Val, K0, K1))
228 if (OpcodeTriple.Med == AMDGPU::G_AMDGPU_SMED3 && K0->Value.sgt(K1->Value))
230 if (OpcodeTriple.Med == AMDGPU::G_AMDGPU_UMED3 && K0->Value.ugt(K1->Value))
233 MatchInfo = {OpcodeTriple.Med, Val, K0->VReg, K1->VReg};
255bool AMDGPURegBankCombinerImpl::matchFPMinMaxToMed3(
256 MachineInstr &
MI, Med3MatchInfo &MatchInfo)
const {
259 if (!isVgprRegBank(Dst))
268 auto OpcodeTriple = getMinMaxPair(
MI.getOpcode());
271 std::optional<FPValueAndVReg> K0, K1;
273 if (!matchMed<GFCstAndRegMatch>(
MI,
MRI, OpcodeTriple, Val, K0, K1))
276 if (K0->Value > K1->Value)
286 if ((getIEEE() && isFminnumLike(
MI)) || VT->isKnownNeverNaN(Dst)) {
290 MatchInfo = {OpcodeTriple.Med, Val, K0->VReg, K1->VReg};
298bool AMDGPURegBankCombinerImpl::matchFPMinMaxToClamp(MachineInstr &
MI,
301 if (!isVgprRegBank(
MI.getOperand(0).getReg()))
305 auto OpcodeTriple = getMinMaxPair(
MI.getOpcode());
307 std::optional<FPValueAndVReg> K0, K1;
309 if (!matchMed<GFCstOrSplatGFCstMatch>(
MI,
MRI, OpcodeTriple, Val, K0, K1))
312 if (!K0->Value.isPosZero() || !K1->Value.isOne())
319 if ((getIEEE() && getDX10Clamp() && isFminnumLike(
MI) &&
320 VT->isKnownNeverSNaN(Val)) ||
321 VT->isKnownNeverNaN(
MI.getOperand(0).getReg())) {
338bool AMDGPURegBankCombinerImpl::matchFPMed3ToClamp(MachineInstr &
MI,
341 if (!isVgprRegBank(
MI.getOperand(0).getReg()))
350 if (isFCst(Src0) && !isFCst(Src1))
352 if (isFCst(Src1) && !isFCst(Src2))
354 if (isFCst(Src0) && !isFCst(Src1))
361 auto isOp3Zero = [&]() {
363 if (Op3->
getOpcode() == TargetOpcode::G_FCONSTANT)
371 if (VT->isKnownNeverNaN(
MI.getOperand(0).getReg()) ||
372 (getIEEE() && getDX10Clamp() &&
373 (VT->isKnownNeverSNaN(Val) || isOp3Zero()))) {
381void AMDGPURegBankCombinerImpl::applyClamp(MachineInstr &
MI,
383 B.buildInstr(AMDGPU::G_AMDGPU_CLAMP, {
MI.getOperand(0)}, {
Reg},
385 MI.eraseFromParent();
388void AMDGPURegBankCombinerImpl::applyMed3(MachineInstr &
MI,
389 Med3MatchInfo &MatchInfo)
const {
390 B.buildInstr(MatchInfo.Opc, {MI.getOperand(0)},
391 {getAsVgpr(MatchInfo.Val0), getAsVgpr(MatchInfo.Val1),
392 getAsVgpr(MatchInfo.Val2)},
394 MI.eraseFromParent();
397void AMDGPURegBankCombinerImpl::applyCanonicalizeZextShiftAmt(
398 MachineInstr &
MI, MachineInstr &Ext)
const {
399 unsigned ShOpc =
MI.getOpcode();
400 assert(ShOpc == AMDGPU::G_SHL || ShOpc == AMDGPU::G_LSHR ||
401 ShOpc == AMDGPU::G_ASHR);
413 auto NewExt =
B.buildAnyExt(ExtAmtTy, AmtReg);
414 auto Mask =
B.buildConstant(
416 auto And =
B.buildAnd(ExtAmtTy, NewExt, Mask);
417 B.buildInstr(ShOpc, {ShDst}, {ShSrc,
And});
422 MI.eraseFromParent();
425bool AMDGPURegBankCombinerImpl::combineD16Load(MachineInstr &
MI)
const {
430 const MachineMemOperand *MMO;
431 const int64_t CleanLo16 = 0xFFFFFFFFFFFF0000;
432 const int64_t CleanHi16 = 0x000000000000FFFF;
434 auto TryApplyD16Load = [&](
unsigned D16Opc, GAnyLoad *SmallLoad) {
436 MachineInstr *InsertPt = SmallLoad;
437 if (SmallLoad->isSimple() && isObviouslySafeToFold(*SmallLoad,
MI))
439 else if (!Helper.
dominates(*DstDef, *SmallLoad))
442 applyD16Load(D16Opc,
MI, SmallLoad, Dst, *InsertPt);
454 return TryApplyD16Load(AMDGPU::G_AMDGPU_LOAD_D16_LO_U8, ZextLoad);
456 return TryApplyD16Load(AMDGPU::G_AMDGPU_LOAD_D16_LO, ZextLoad);
470 SextLoad,
m_MMO(MMO)))))))) {
473 return TryApplyD16Load(AMDGPU::G_AMDGPU_LOAD_D16_LO_I8, SextLoad);
481 MI.getOperand(1).getReg(),
MRI,
489 return TryApplyD16Load(AMDGPU::G_AMDGPU_LOAD_D16_HI_U8, ZextLoad);
491 return TryApplyD16Load(AMDGPU::G_AMDGPU_LOAD_D16_HI, ZextLoad);
505 SextLoad,
m_MMO(MMO)))))))) {
508 return TryApplyD16Load(AMDGPU::G_AMDGPU_LOAD_D16_HI_I8, SextLoad);
517void AMDGPURegBankCombinerImpl::applyMinMaxToMinMax3(
518 MachineInstr &
MI, MinMaxToMinMax3MatchInfo &MatchInfo)
const {
519 B.buildInstr(MatchInfo.Opc, {MI.getOperand(0)},
520 {MatchInfo.Val0, MatchInfo.Val1, MatchInfo.Val2},
MI.getFlags());
521 MI.eraseFromParent();
527bool AMDGPURegBankCombinerImpl::matchMinMaxToMinMax3(
528 MachineInstr &
MI, MinMaxToMinMax3MatchInfo &MatchInfo)
const {
533 if (!(isVgprRegBank(Dst) && isVgprRegBank(Src1) && isVgprRegBank(Src2))) {
538 unsigned Opc =
MI.getOpcode();
551 unsigned AMDGPUOpc = 0;
554 AMDGPUOpc = AMDGPU::G_AMDGPU_SMAX3;
557 AMDGPUOpc = AMDGPU::G_AMDGPU_SMIN3;
560 AMDGPUOpc = AMDGPU::G_AMDGPU_UMAX3;
563 AMDGPUOpc = AMDGPU::G_AMDGPU_UMIN3;
565 case AMDGPU::G_FMAXNUM:
566 case AMDGPU::G_FMAXNUM_IEEE:
567 AMDGPUOpc = AMDGPU::G_AMDGPU_FMAX3;
569 case AMDGPU::G_FMINNUM:
570 case AMDGPU::G_FMINNUM_IEEE:
571 AMDGPUOpc = AMDGPU::G_AMDGPU_FMIN3;
573 case AMDGPU::G_FMAXIMUM:
574 case AMDGPU::G_FMAXIMUMNUM:
575 AMDGPUOpc = AMDGPU::G_AMDGPU_FMAXIMUM3;
577 case AMDGPU::G_FMINIMUM:
578 case AMDGPU::G_FMINIMUMNUM:
579 AMDGPUOpc = AMDGPU::G_AMDGPU_FMINIMUM3;
585 MatchInfo = {AMDGPUOpc, R0, R1,
R2};
589void AMDGPURegBankCombinerImpl::applyD16Load(
unsigned D16Opc,
591 MachineInstr *SmallLoad,
593 MachineInstr &InsertPt)
const {
595 LLT SrcTy =
MRI.
getType(SrcReg32ToOverwriteD16);
603 B.setInstrAndDebugLoc(InsertPt);
605 B.buildInstr(D16Opc, {D16Dst},
609 if (D16Dst != DstReg)
610 B.buildBitcast(DstReg, D16Dst);
620SIModeRegisterDefaults AMDGPURegBankCombinerImpl::getMode()
const {
621 return MF.getInfo<SIMachineFunctionInfo>()->getMode();
624bool AMDGPURegBankCombinerImpl::getIEEE()
const {
return getMode().IEEE; }
626bool AMDGPURegBankCombinerImpl::getDX10Clamp()
const {
627 return getMode().DX10Clamp;
630bool AMDGPURegBankCombinerImpl::isFminnumIeee(
const MachineInstr &
MI)
const {
631 return MI.getOpcode() == AMDGPU::G_FMINNUM_IEEE;
634bool AMDGPURegBankCombinerImpl::isFminnum(
const MachineInstr &
MI)
const {
635 return MI.getOpcode() == AMDGPU::G_FMINNUM;
638bool AMDGPURegBankCombinerImpl::isFminnumLike(
const MachineInstr &
MI)
const {
639 return isFminnumIeee(
MI) || isFminnum(
MI);
642bool AMDGPURegBankCombinerImpl::isFCst(MachineInstr *
MI)
const {
643 return MI->getOpcode() == AMDGPU::G_FCONSTANT;
646bool AMDGPURegBankCombinerImpl::isClampZeroToOne(MachineInstr *K0,
647 MachineInstr *K1)
const {
648 if (isFCst(K0) && isFCst(K1)) {
658 function_ref<GISelValueTracking *()> GetVT,
659 function_ref<MachineDominatorTree *()> GetMDT,
661 AMDGPURegBankCombinerImplRuleConfig RuleConfig;
662 if (!RuleConfig.parseCommandLineOption())
670 const auto *LI =
ST.getLegalizerInfo();
672 CombinerInfo CInfo(
false,
true,
673 LI, EnableOpt,
F.hasOptSize(),
F.hasMinSize());
675 CInfo.MaxIterations = 1;
676 CInfo.ObserverLvl = CombinerInfo::ObserverLevel::SinglePass;
679 CInfo.EnableFullDCE =
false;
681 GISelValueTracking *VT = GetVT();
682 MachineDominatorTree *MDT = GetMDT();
683 AMDGPURegBankCombinerImpl Impl(MF, CInfo, *VT,
nullptr,
684 RuleConfig, ST, MDT, LI);
685 return Impl.combineMachineInstrs();
691class AMDGPURegBankCombinerLegacy :
public MachineFunctionPass {
695 AMDGPURegBankCombinerLegacy(
bool IsOptLevelNone =
false)
696 : MachineFunctionPass(
ID), IsOptLevelNone(IsOptLevelNone) {}
698 StringRef getPassName()
const override {
return "AMDGPURegBankCombiner"; }
702 void getAnalysisUsage(AnalysisUsage &AU)
const override;
709void AMDGPURegBankCombinerLegacy::getAnalysisUsage(AnalysisUsage &AU)
const {
712 AU.
addRequired<GISelValueTrackingAnalysisLegacy>();
714 if (!IsOptLevelNone) {
720bool AMDGPURegBankCombinerLegacy::runOnMachineFunction(
MachineFunction &MF) {
728 return &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
730 [&]() -> MachineDominatorTree * {
731 return IsOptLevelNone ? nullptr
732 : &getAnalysis<MachineDominatorTreeWrapperPass>()
738char AMDGPURegBankCombinerLegacy::ID = 0;
740 "Combine AMDGPU machine instrs after regbankselect",
744 "Combine AMDGPU machine instrs after regbankselect",
false,
748 return new AMDGPURegBankCombinerLegacy(IsOptLevelNone);
752 : IsOptLevelNone(IsOptLevelNone) {}
764 return IsOptLevelNone
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define GET_GICOMBINER_CONSTRUCTOR_INITS
This file declares the targeting of the Machinelegalizer class for AMDGPU.
This file declares the targeting of the RegisterBankInfo class for AMDGPU.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This contains common combine transformations that may be used in a combine pass,or by the target else...
Option class for Targets to specify which operations are combined how and when.
This contains the base class for all Combiners generated by TableGen.
AMD GCN specific subclass of TargetSubtarget.
Provides analysis for querying information about KnownBits during GISel passes.
const HexagonInstrInfo * TII
Contains matchers for matching SSA Machine Instructions.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static StringRef getName(Value *V)
MachineRegisterInfo & MRI
static bool isClampZeroToOne(SDValue A, SDValue B)
Target-Independent Code Generator Pass Configuration Options pass.
AMDGPURegBankCombinerPass(bool IsOptLevelNone=false)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
LLVM_ABI bool dominates(const MachineInstr &DefMI, const MachineInstr &UseMI) const
Returns true if DefMI dominates UseMI.
bool isPosZero() const
Return true if the value is positive zero.
bool isOne() const
Returns true if this value is exactly +1.0.
FunctionPass class - This class is used to implement most global optimizations.
bool hasMin3Max3_16() const
To use KnownBitsInfo analysis in a pass, KnownBitsInfo &Info = getAnalysis<GISelValueTrackingInfoAnal...
constexpr unsigned getScalarSizeInBits() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
TypeSize getValue() const
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
ArrayRef< MachineMemOperand * > memoperands() const
Access to memory operands of the instruction.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
LocationSize getSizeInBits() const
Return the size in bits of the memory reference.
Register getReg() const
getReg - Returns the register number.
const ConstantFP * getFPImm() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
const RegisterBank * getRegBank(Register Reg) const
Return the register bank of Reg.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
LLVM_ABI void setRegBank(Register Reg, const RegisterBank &RegBank)
Set the register bank to RegBank for Reg.
iterator_range< use_instr_iterator > use_instructions(Register Reg) const
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.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Holds all the information related to register banks.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
operand_type_match m_Reg()
SpecificConstantMatch m_SpecificICst(const APInt &RequestedValue)
Matches a constant equal to RequestedValue.
UnaryOp_match< SrcTy, TargetOpcode::COPY > m_Copy(SrcTy &&Src)
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
LoadOp_match< GZExtLoad, operand_type_match > m_GZExtLoad(GZExtLoad *&Inst)
LoadOp_match< GSExtLoad, operand_type_match > m_GSExtLoad(GSExtLoad *&Inst)
BinaryOp_match< LHS, RHS, TargetOpcode::G_OR, true > m_GOr(const LHS &L, const RHS &R)
OneNonDBGUse_match< SubPat > m_OneNonDBGUse(const SubPat &SP)
CheckType m_SpecificType(LLT Ty)
BinaryOpc_match< LHS, RHS, true > m_CommutativeBinOp(unsigned Opcode, const LHS &L, const RHS &R)
MMORef m_MMO(const MachineMemOperand *&MMO)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SHL, false > m_GShl(const LHS &L, const RHS &R)
Or< Preds... > m_any_of(Preds &&... preds)
BinaryOp_match< LHS, RHS, TargetOpcode::G_AND, true > m_GAnd(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_BITCAST > m_GBitcast(const SrcTy &Src)
bind_ty< MachineInstr * > m_MInstr(MachineInstr *&MI)
And< Preds... > m_all_of(Preds &&... preds)
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
NodeAddr< DefNode * > Def
NodeAddr< UseNode * > Use
This is an optimization pass for GlobalISel generic memory operations.
@ Load
The value being inserted comes from a load (InsertElement only).
FunctionPass * createAMDGPURegBankCombinerLegacy(bool IsOptLevelNone)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
@ And
Bitwise or logical AND of integers.
LLVM_ABI void eraseInstr(MachineInstr &MI, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool shouldSkipOptimizationForOptBisect(IRUnitRef IR)