33 #include "llvm/Config/llvm-config.h" 50 #define DEBUG_TYPE "regbankselect" 57 "Run the Fast mode (default mapping)"),
58 clEnumValN(RegBankSelect::Mode::Greedy,
"regbankselect-greedy",
59 "Use the Greedy mode (best local mapping)")));
64 "Assign register bank of generic virtual registers",
70 "Assign register bank of generic virtual registers",
false,
73 RegBankSelect::RegBankSelect(
Mode RunningMode)
79 LLVM_DEBUG(
dbgs() <<
"RegBankSelect mode overrided by command line\n");
85 assert(RBI &&
"Cannot work without RegisterBankInfo");
88 TPC = &getAnalysis<TargetPassConfig>();
90 MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
91 MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
97 MORE = llvm::make_unique<MachineOptimizationRemarkEmitter>(MF, MBFI);
112 bool RegBankSelect::assignmentMatch(
114 bool &OnlyAssign)
const {
126 OnlyAssign = CurRegBank ==
nullptr;
128 if (CurRegBank)
dbgs() << *CurRegBank;
else dbgs() <<
"none";
129 dbgs() <<
" against ";
130 assert(DesiredRegBrank &&
"The mapping must be valid");
131 dbgs() << *DesiredRegBrank <<
'\n';);
132 return CurRegBank == DesiredRegBrank;
135 bool RegBankSelect::repairReg(
143 assert(!
empty(NewVRegs) &&
"We should not have to repair");
147 unsigned Src = MO.
getReg();
148 unsigned Dst = *NewVRegs.begin();
157 "We are about to create several defs for Dst");
169 std::unique_ptr<MachineInstr *[]> NewInstrs(
173 for (
const std::unique_ptr<InsertPoint> &InsertPt : RepairPt) {
179 InsertPt->insert(*CurMI);
180 NewInstrs[Idx++] = CurMI;
188 uint64_t RegBankSelect::getRepairCost(
191 assert(MO.
isReg() &&
"We should only repair register operand");
198 assert((!IsSameNumOfValues || CurRegBank) &&
"We should not have to repair");
209 if (IsSameNumOfValues) {
226 unsigned Cost = RBI->
copyCost(*DesiredRegBrank, *CurRegBank,
227 RBI->getSizeInBits(MO.
getReg(), *MRI, *TRI));
240 "Do not know how to map this instruction");
243 MappingCost Cost = MappingCost::ImpossibleCost();
247 MappingCost CurCost =
248 computeMapping(MI, *CurMapping, LocalRepairPts, &Cost);
249 if (CurCost < Cost) {
252 BestMapping = CurMapping;
262 BestMapping = *PossibleMappings.begin();
266 assert(BestMapping &&
"No suitable mapping for instruction");
270 void RegBankSelect::tryAvoidingSplit(
274 assert(RepairPt.
hasSplit() &&
"We should not have to adjust for split");
280 "Repairing placement does not match operand");
292 "Need to split for the first terminator?!");
299 RepairPt.
switchTo(RepairingPlacement::RepairingKind::Reassign);
314 "This code is for the def of a terminator");
348 unsigned Reg = MO.
getReg();
362 "Do not know which outgoing edges are relevant");
365 "Do not know where each terminator ends up");
379 assert(
false &&
"Repairing cost may not be accurate");
384 RepairPt.
switchTo(RepairingPlacement::RepairingKind::Impossible);
389 RegBankSelect::MappingCost RegBankSelect::computeMapping(
392 const RegBankSelect::MappingCost *BestCost) {
393 assert((MBFI || !BestCost) &&
"Costs comparison require MBFI");
396 return MappingCost::ImpossibleCost();
400 bool Saturated = Cost.addLocalCost(InstrMapping.
getCost());
401 assert(!Saturated &&
"Possible mapping saturated the cost");
405 if (BestCost && Cost > *BestCost) {
406 LLVM_DEBUG(
dbgs() <<
"Mapping is too expensive from the start\n");
414 for (
unsigned OpIdx = 0, EndOpIdx = InstrMapping.
getNumOperands();
415 OpIdx != EndOpIdx; ++OpIdx) {
419 unsigned Reg = MO.
getReg();
424 InstrMapping.getOperandMapping(OpIdx);
427 if (assignmentMatch(Reg, ValMapping, Assign)) {
447 tryAvoidingSplit(RepairPt, MO, ValMapping);
452 return MappingCost::ImpossibleCost();
457 if (!BestCost || Saturated)
462 assert(MBFI && MBPI &&
"Cost computation requires MBFI and MBPI");
474 uint64_t RepairCost = getRepairCost(MO, ValMapping);
478 return MappingCost::ImpossibleCost();
481 const uint64_t PercentageForBias = 5;
482 uint64_t Bias = (RepairCost * PercentageForBias + 99) / 100;
487 assert(((RepairCost < RepairCost * PercentageForBias) &&
488 (RepairCost * PercentageForBias <
489 RepairCost * PercentageForBias + 99)) &&
490 "Repairing involves more than a billion of instructions?!");
491 for (
const std::unique_ptr<InsertPoint> &InsertPt : RepairPt) {
492 assert(InsertPt->canMaterialize() &&
"We should not have made it here");
494 if (!InsertPt->isSplit())
495 Saturated = Cost.addLocalCost(RepairCost);
497 uint64_t CostForInsertPt = RepairCost;
500 assert(CostForInsertPt + Bias > CostForInsertPt &&
501 "Repairing + split bias overflows");
502 CostForInsertPt += Bias;
503 uint64_t PtCost = InsertPt->frequency(*
this) * CostForInsertPt;
505 if ((Saturated = PtCost < CostForInsertPt))
508 Saturated = Cost.addNonLocalCost(PtCost);
513 if (BestCost && Cost > *BestCost) {
514 LLVM_DEBUG(
dbgs() <<
"Mapping is too expensive, stop processing\n");
528 bool RegBankSelect::applyMapping(
540 "This should not make its way in the list");
541 unsigned OpIdx = RepairPt.
getOpIdx();
544 InstrMapping.getOperandMapping(OpIdx);
545 unsigned Reg = MO.
getReg();
550 "Reassignment should only be for simple mapping");
555 if (!repairReg(MO, ValMapping, RepairPt, OpdMapper.
getVRegs(OpIdx)))
564 LLVM_DEBUG(
dbgs() <<
"Actual mapping of the operands: " << OpdMapper <<
'\n');
565 RBI->applyMapping(OpdMapper);
578 MappingCost DefaultCost = computeMapping(MI, *BestMapping, RepairPts);
580 if (DefaultCost == MappingCost::ImpossibleCost())
584 RBI->getInstrPossibleMappings(MI);
585 if (PossibleMappings.
empty())
587 BestMapping = &findBestMapping(MI, PossibleMappings, RepairPts);
590 assert(BestMapping->
verify(MI) &&
"Invalid instruction mapping");
596 return applyMapping(MI, *BestMapping, RepairPts);
607 Mode SaveOptMode = OptMode;
619 "instruction is not legal", *MI);
642 if (!assignInstr(MI)) {
644 "unable to map instruction", MI);
649 OptMode = SaveOptMode;
660 : Kind(Kind), OpIdx(OpIdx),
663 assert(MO.
isReg() &&
"Trying to repair a non-reg operand");
665 if (Kind != RepairingKind::Insert)
669 bool Before = !MO.
isDef();
695 unsigned Reg = MO.
getReg();
697 for (
auto Begin = Pred.
begin(); It != Begin && It->isTerminator(); --It)
698 if (It->modifiesRegister(Reg, &TRI)) {
709 if (It == Pred.
end())
722 for (; It != REnd && It->isTerminator(); ++It) {
724 "copy insertion in middle of terminators not handled");
742 "Do not know where to split");
778 "Splitting before phis requires more points");
780 "Splitting between phis does not make sense");
783 void RegBankSelect::InstrInsertPoint::materialize() {
832 void RegBankSelect::EdgeInsertPoint::materialize() {
837 assert(Src.isSuccessor(DstOrSplit) && DstOrSplit->isPredecessor(&Src) &&
838 "This point has already been split");
840 assert(NewBB &&
"Invalid call to materialize");
866 assert(Src.succ_size() > 1 && DstOrSplit->pred_size() > 1 &&
867 "Edge is not critical");
868 return Src.canSplitCriticalEdge(DstOrSplit);
871 RegBankSelect::MappingCost::MappingCost(
const BlockFrequency &LocalFreq)
874 bool RegBankSelect::MappingCost::addLocalCost(uint64_t Cost) {
876 if (LocalCost + Cost < LocalCost) {
881 return isSaturated();
884 bool RegBankSelect::MappingCost::addNonLocalCost(uint64_t Cost) {
886 if (NonLocalCost + Cost < NonLocalCost) {
890 NonLocalCost += Cost;
891 return isSaturated();
894 bool RegBankSelect::MappingCost::isSaturated()
const {
899 void RegBankSelect::MappingCost::saturate() {
900 *
this = ImpossibleCost();
904 RegBankSelect::MappingCost RegBankSelect::MappingCost::ImpossibleCost() {
914 if ((*
this == ImpossibleCost()) || (Cost == ImpossibleCost()))
915 return (*
this == ImpossibleCost()) < (Cost == ImpossibleCost());
918 if (isSaturated() || Cost.isSaturated())
919 return isSaturated() < Cost.isSaturated();
926 uint64_t ThisLocalAdjust;
927 uint64_t OtherLocalAdjust;
932 if (NonLocalCost == Cost.NonLocalCost)
935 return LocalCost < Cost.LocalCost;
940 OtherLocalAdjust = 0;
941 if (LocalCost < Cost.LocalCost)
942 OtherLocalAdjust = Cost.LocalCost - LocalCost;
944 ThisLocalAdjust = LocalCost - Cost.LocalCost;
946 ThisLocalAdjust = LocalCost;
947 OtherLocalAdjust = Cost.LocalCost;
951 uint64_t ThisNonLocalAdjust = 0;
952 uint64_t OtherNonLocalAdjust = 0;
953 if (NonLocalCost < Cost.NonLocalCost)
954 OtherNonLocalAdjust = Cost.NonLocalCost - NonLocalCost;
956 ThisNonLocalAdjust = NonLocalCost - Cost.NonLocalCost;
958 uint64_t ThisScaledCost = ThisLocalAdjust * LocalFreq;
960 bool ThisOverflows = ThisLocalAdjust && (ThisScaledCost < ThisLocalAdjust ||
961 ThisScaledCost < LocalFreq);
962 uint64_t OtherScaledCost = OtherLocalAdjust * Cost.LocalFreq;
964 bool OtherOverflows =
966 (OtherScaledCost < OtherLocalAdjust || OtherScaledCost < Cost.LocalFreq);
968 ThisOverflows |= ThisNonLocalAdjust &&
969 ThisScaledCost + ThisNonLocalAdjust < ThisNonLocalAdjust;
970 ThisScaledCost += ThisNonLocalAdjust;
971 OtherOverflows |= OtherNonLocalAdjust &&
972 OtherScaledCost + OtherNonLocalAdjust < OtherNonLocalAdjust;
973 OtherScaledCost += OtherNonLocalAdjust;
976 if (ThisOverflows && OtherOverflows)
979 if (ThisOverflows || OtherOverflows)
980 return ThisOverflows < OtherOverflows;
982 return ThisScaledCost < OtherScaledCost;
986 return LocalCost == Cost.LocalCost && NonLocalCost == Cost.NonLocalCost &&
987 LocalFreq == Cost.LocalFreq;
990 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 998 if (*
this == ImpossibleCost()) {
1002 if (isSaturated()) {
1006 OS << LocalFreq <<
" * " << LocalCost <<
" + " << NonLocalCost;
Pass interface - Implemented by all 'passes'.
bool canMaterialize() const override
Check whether this insertion point can be materialized.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
MachineBasicBlock * getMBB() const
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
unsigned getNumInsertPoints() const
This class represents lattice values for constants.
void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
INITIALIZE_PASS_BEGIN(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false)
const MachineFunctionProperties & getProperties() const
Get the function properties.
Helper class that represents how the value of an instruction may be mapped and what is the related co...
unsigned getCost() const
Get the cost.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned getReg() const
getReg - Returns the register number.
unsigned getOpIdx() const
Reparing code needs to happen before InsertPoints.
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
static void dump(StringRef Title, SpillInfo const &Spills)
Helper class used to get/create the virtual registers that will be used to replace the MachineOperand...
virtual const RegisterBankInfo * getRegBankInfo() const
If the information for the register banks is available, return it.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
void setRegBank(unsigned Reg, const RegisterBank &RegBank)
Set the register bank to RegBank for Reg.
Mode
List of the modes supported by the RegBankSelect pass.
void switchTo(RepairingKind NewKind)
Change the type of this repairing placement to NewKind.
iterator_range< succ_iterator > successors()
const PartialMapping * BreakDown
How the value is broken down between the different register banks.
void setMF(MachineFunction &MF)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Mark this repairing placement as impossible.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
Abstract class used to represent an insertion point in a CFG.
const MachineInstrBuilder & addUse(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
RepairingKind
Define the kind of action this repairing needs.
This file contains the simple types necessary to represent the attributes associated with functions a...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
iterator_range< SmallVectorImpl< unsigned >::const_iterator > getVRegs(unsigned OpIdx, bool ForDebug=false) const
Get all the virtual registers required to map the OpIdx-th operand of the instruction.
Target-Independent Code Generator Pass Configuration Options.
Fast - This calling convention attempts to make calls as fast as possible (e.g.
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
MachineFunction & getMF()
Getter for the function we currently build.
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
RepairingPlacement(MachineInstr &MI, unsigned OpIdx, const TargetRegisterInfo &TRI, Pass &P, RepairingKind Kind=RepairingKind::Insert)
Create a repairing placement for the OpIdx-th operand of MI.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
const RegisterBank * RegBank
Register bank where the partial value lives.
uint64_t frequency(const Pass &P) const override
Frequency of the insertion point.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
This pass implements the reg bank selector pass used in the GlobalISel pipeline.
Insertion point on an edge.
virtual const InstructionMapping & getInstrMapping(const MachineInstr &MI) const
Get the mapping of the different operands of MI on the register bank.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
bool canMaterialize() const
BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const
getblockFreq - Return block frequency.
Represent the analysis usage information of a pass.
bool isTargetSpecificOpcode(unsigned Opcode)
Check whether the given Opcode is a target-specific opcode.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
void initializeRegBankSelectPass(PassRegistry &)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
cl::opt< bool > DisableGISelLegalityCheck
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
bool isValid() const
Check whether this object is valid.
bool verify(const MachineInstr &MI) const
Verifiy that this mapping makes sense for MI.
const MachineInstr * machineFunctionIsIllegal(const MachineFunction &MF)
Checks that MIR is fully legal, returns an illegal instruction if it's not, nullptr otherwise...
RepairingKind getKind() const
bool isGlobalISelAbortEnabled() const
Check whether or not GlobalISel should abort on error.
Struct used to represent the placement of a repairing point for a given operand.
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
Create a new MachineInstr which is a copy of Orig, identical in all ways except the instruction has n...
RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
This class implements the register bank concept.
Helper struct that represents how a value is mapped through different register banks.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
A range adaptor for a pair of iterators.
bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
virtual bool canMaterialize() const
Check whether this insertion point can be materialized.
bool isUnconditionalBranch(QueryType Type=AnyInBundle) const
Return true if this is a branch which always transfers control flow to some other block...
void createVRegs(unsigned OpIdx)
Create as many new virtual registers as needed for the mapping of the OpIdx-th operand.
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
const MachineBasicBlock * getParent() const
BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Insertion point before or after an instruction.
void emplace_back(ArgTypes &&... Args)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
LLVM_NODISCARD bool empty() const
virtual unsigned copyCost(const RegisterBank &A, const RegisterBank &B, unsigned Size) const
Get the cost of a copy from B to A, or put differently, get the cost of A = COPY B.
void setMBB(MachineBasicBlock &MBB)
Set the insertion point to the end of MBB.
InstrInsertPoint(MachineInstr &Instr, bool Before=true)
Create an insertion point before (Before=true) or after Instr.
uint64_t frequency(const Pass &P) const override
Frequency of the insertion point.
bool WasMaterialized
Tell if the insert point has already been materialized.
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
void addInsertPoint(MachineBasicBlock &MBB, bool Beginning)
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
static cl::opt< RegBankSelect::Mode > RegBankSelectMode(cl::desc("Mode of the RegBankSelect pass"), cl::Hidden, cl::Optional, cl::values(clEnumValN(RegBankSelect::Mode::Fast, "regbankselect-fast", "Run the Fast mode (default mapping)"), clEnumValN(RegBankSelect::Mode::Greedy, "regbankselect-greedy", "Use the Greedy mode (best local mapping)")))
bool runOnMachineFunction(MachineFunction &MF) override
Walk through MF and assign a register bank to every virtual register that are still mapped to nothing...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool hasProperty(Property P) const
MachineBasicBlock * SplitCriticalEdge(MachineBasicBlock *Succ, Pass &P)
Split the critical edge from this block to the given successor block, and return the newly created bl...
bool operator<(int64_t V1, const APSInt &V2)
unsigned NumBreakDowns
Number of partial mapping to break down this value.
AnalysisType * getAnalysisIfAvailable() const
getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to get analysis information tha...
(Re)assign the register bank of the operand.
virtual bool isSplit() const
Does this point involve splitting an edge or block? As soon as ::getPoint is called and thus...
This class implements an extremely fast bulk output stream that can only output to a stream...
#define LLVM_LIKELY(EXPR)
const MachineInstrBuilder & addDef(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
bool operator==(uint64_t V1, const APInt &V2)
uint64_t frequency(const Pass &P) const override
Frequency of the insertion point.
unsigned getNumOperands() const
Get the number of operands.
const MachineOperand & getOperand(unsigned i) const
void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel error as a missed optimization remark to the LLVMContext's diagnostic stream...
Insertion point at the beginning or end of a basic block.
Nothing to repair, just drop this action.
bool isSplit() const override
Does this point involve splitting an edge or block? As soon as ::getPoint is called and thus...