Go to the documentation of this file.
86 #define DEBUG_TYPE "si-opt-vgpr-liverange"
114 void collectWaterfallCandidateRegisters(
126 void updateLiveRangeInElseRegion(
136 void optimizeWaterfallLiveRange(
146 return "SI Optimize VGPR LiveRange";
177 if (
BR.getOpcode() == AMDGPU::SI_ELSE)
178 return BR.getOperand(2).getMBB();
183 void SIOptimizeVGPRLiveRange::collectElseRegionBlocks(
196 if (Cur < Blocks.
size())
203 dbgs() <<
"Found Else blocks: ";
204 for (
auto *
MBB : Blocks)
211 void SIOptimizeVGPRLiveRange::findNonPHIUsesInBlock(
222 void SIOptimizeVGPRLiveRange::collectCandidateRegisters(
229 for (
auto *
Else : ElseBlocks) {
230 for (
auto &
MI :
Else->instrs()) {
231 if (
MI.isDebugInstr())
234 for (
auto &MO :
MI.operands()) {
235 if (!MO.isReg() || !MO.getReg() || MO.isDef())
249 if ((
VI.AliveBlocks.test(
If->getNumber()) || DefMBB ==
If) &&
255 KillsInElse.
insert(MOReg);
258 <<
" as Live in Endif\n");
268 for (
auto &
MI :
Endif->phis()) {
269 for (
unsigned Idx = 1; Idx <
MI.getNumOperands(); Idx += 2) {
270 auto &MO =
MI.getOperand(Idx);
271 auto *Pred =
MI.getOperand(Idx + 1).getMBB();
274 assert(ElseBlocks.contains(Pred) &&
"Should be from Else region\n");
276 if (!MO.isReg() || !MO.getReg() || MO.isUndef())
280 if (
Reg.isPhysical() || !
TRI->isVectorRegister(*
MRI,
Reg))
287 <<
" as Live in Endif\n");
294 if ((
VI.AliveBlocks.test(
If->getNumber()) || DefMBB ==
If) &&
305 auto *
UseMI =
I->getParent();
314 if ((UseMBB ==
Flow && IncomingMBB !=
If) ||
315 (UseMBB ==
Endif && IncomingMBB ==
Flow))
322 for (
auto Reg : KillsInElse) {
323 if (!IsLiveThroughThen(
Reg))
324 CandidateRegs.push_back(
Reg);
330 void SIOptimizeVGPRLiveRange::collectWaterfallCandidateRegisters(
337 auto *
MBB = LoopHeader;
340 for (
auto &
MI : *
MBB) {
341 if (
MI.isDebugInstr())
357 for (
auto *
I : Instructions) {
360 for (
auto &MO :
MI.operands()) {
361 if (!MO.isReg() || !MO.getReg() || MO.isDef())
388 CandidateRegs.
insert(MOReg);
400 void SIOptimizeVGPRLiveRange::updateLiveRangeInThenRegion(
407 while (!WorkList.empty()) {
408 auto *
MBB = WorkList.pop_back_val();
430 auto *
UseMI =
I->getParent();
442 if (
Uses.size() == 1) {
445 LV->HandleVirtRegUse(
Reg,
MBB, *(*
Uses.begin()));
446 }
else if (
Uses.size() > 1) {
463 for (
auto *
MI : OldVarInfo.
Kills) {
464 if (Blocks.contains(
MI->getParent()))
469 void SIOptimizeVGPRLiveRange::updateLiveRangeInElseRegion(
477 for (
auto *
MBB : ElseBlocks) {
488 auto I = OldVarInfo.
Kills.begin();
489 while (
I != OldVarInfo.
Kills.end()) {
490 if (ElseBlocks.contains((*I)->getParent())) {
491 NewVarInfo.
Kills.push_back(*
I);
499 void SIOptimizeVGPRLiveRange::optimizeLiveRange(
511 for (
auto *Pred :
Flow->predecessors()) {
513 PHI.addReg(
Reg).addMBB(Pred);
521 auto *
UseMI =
O.getParent();
524 if (UseBlock ==
Endif) {
539 updateLiveRangeInElseRegion(
Reg, NewReg,
Flow,
Endif, ElseBlocks);
540 updateLiveRangeInThenRegion(
Reg,
If,
Flow);
543 void SIOptimizeVGPRLiveRange::optimizeWaterfallLiveRange(
556 auto *
UseMI =
O.getParent();
570 PHI.addReg(
Reg).addMBB(Pred);
579 if (
MI->readsRegister(NewReg,
TRI)) {
580 MI->addRegisterKilled(NewReg,
TRI);
581 NewVarInfo.
Kills.push_back(
MI);
586 assert(
Kill &&
"Failed to find last usage of register in loop");
589 bool PostKillBlock =
false;
590 for (
auto *Block : Blocks) {
591 auto BBNum =
Block->getNumber();
599 PostKillBlock |= (
Block == KillBlock);
602 }
else if (Block != LoopHeader) {
611 "SI Optimize VGPR LiveRange",
false,
false)
621 return new SIOptimizeVGPRLiveRange();
624 bool SIOptimizeVGPRLiveRange::runOnMachineFunction(
MachineFunction &MF) {
627 TII =
ST.getInstrInfo();
628 TRI = &
TII->getRegisterInfo();
629 MDT = &getAnalysis<MachineDominatorTree>();
630 Loops = &getAnalysis<MachineLoopInfo>();
631 LV = &getAnalysis<LiveVariables>();
637 bool MadeChange =
false;
644 if (
MI.getOpcode() == AMDGPU::SI_IF) {
646 auto *
Endif = getElseTarget(IfTarget);
651 if (!MDT->dominates(&
MBB, IfTarget) || !MDT->dominates(IfTarget,
Endif))
663 collectElseRegionBlocks(IfTarget,
Endif, ElseBlocks);
666 collectCandidateRegisters(&
MBB, IfTarget,
Endif, ElseBlocks,
668 MadeChange |= !CandidateRegs.empty();
670 for (
auto Reg : CandidateRegs)
671 optimizeLiveRange(
Reg, &
MBB, IfTarget,
Endif, ElseBlocks);
672 }
else if (
MI.getOpcode() == AMDGPU::SI_WATERFALL_LOOP) {
673 auto *LoopHeader =
MI.getOperand(0).getMBB();
674 auto *LoopEnd = &
MBB;
683 collectWaterfallCandidateRegisters(LoopHeader, LoopEnd, CandidateRegs,
684 Blocks, Instructions);
685 MadeChange |= !CandidateRegs.
empty();
687 for (
auto Reg : CandidateRegs)
688 optimizeWaterfallLiveRange(
Reg, LoopHeader, Blocks, Instructions);
@ Undef
Value of the register doesn't matter.
bool isLiveIn(const MachineBasicBlock &MBB, Register Reg, MachineRegisterInfo &MRI)
isLiveIn - Is Reg live in to MBB? This means that Reg is live through MBB, or it is killed in MBB.
unsigned succ_size() const
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder & UseMI
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
size_type size() const
Determine the number of elements in the SetVector.
std::vector< MachineInstr * > Kills
Kills - List of MachineInstruction's which are the last use of this virtual register (kill it) in the...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
Reg
All possible values of the reg field in the ModR/M byte.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
Code Generation Notes for reduce the size of the ISel and reduce repetition in the implementation In a small number of this can cause even when no optimisation has taken place Instructions
char & SIOptimizeVGPRLiveRangeID
iterator_range< use_iterator > use_operands(Register Reg) const
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Properties which a MachineFunction may have at a given point in time.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
iterator_range< iterator > terminators()
unsigned const TargetRegisterInfo * TRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
use_nodbg_iterator use_nodbg_begin(Register RegNo) const
SmallPtrSet< MachineInstr *, 2 > Uses
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void push_back(MachineInstr *MI)
bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
unsigned pred_size() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
VarInfo - This represents the regions where a virtual register is live in the program.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const MachineOperand & getOperand(unsigned i) const
FunctionPass * createSIOptimizeVGPRLiveRangePass()
Represent the analysis usage information of a pass.
const HexagonInstrInfo * TII
MachineFunctionProperties & set(Property P)
static use_nodbg_iterator use_nodbg_end()
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
bool empty() const
Determine if the SetVector is empty or not.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
Representation of each machine instruction.
This class represents the liveness of a register, stack slot, etc.
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
bool test(unsigned Idx) const
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
succ_iterator succ_begin()
iterator_range< pred_iterator > predecessors()
bool insert(const value_type &X)
Insert a new element into the SetVector.
MachineBasicBlock * getMBB() const
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
iterator_range< succ_iterator > successors()
StringRef - Represent a constant reference to a string, i.e.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
const MachineBasicBlock * getParent() const
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
INITIALIZE_PASS_BEGIN(SIOptimizeVGPRLiveRange, DEBUG_TYPE, "SI Optimize VGPR LiveRange", false, false) INITIALIZE_PASS_END(SIOptimizeVGPRLiveRange
Function & getFunction()
Return the LLVM function that this machine code represents.
@ BR
Control flow instructions. These all have token chains.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
@ Kill
The last use of a register.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
auto reverse(ContainerTy &&C)
A SetVector that performs no allocations if smaller than a certain size.
FunctionPass class - This class is used to implement most global optimizations.
AnalysisUsage & addRequired()
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
A vector that has set insertion semantics.
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
bool contains(ConstPtrType Ptr) const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SparseBitVector AliveBlocks
AliveBlocks - Set of blocks in which this value is alive completely through.