Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions llvm/include/llvm/CodeGen/MachineRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,14 @@ class MachineRegisterInfo {
/// form, so there should only be one definition.
LLVM_ABI MachineInstr *getVRegDef(Register Reg) const;

/// getDomVRegDefInBasicBlock - Return the last machine instr that defines
/// the specified virtual register in the basic block, searching backwards
/// from instruction I (exclusive). Returns MBB.end() if no definition is
/// found.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment seems bit misleading, as the last instruction while searching backward implies the very first definition in the MBB. I think you can separate the two lines : the last instruction encountered in the MBB & you search in the backward manner from I.

LLVM_ABI MachineBasicBlock::iterator
getDomVRegDefInBasicBlock(Register Reg, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;

/// getUniqueVRegDef - Return the unique machine instr that defines the
/// specified virtual register or null if none is found. If there are
/// multiple definitions or no definition, return null.
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/CodeGen/MachineRegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,3 +674,16 @@ bool MachineRegisterInfo::isReservedRegUnit(MCRegUnit Unit) const {
}
return false;
}

MachineBasicBlock::iterator MachineRegisterInfo::getDomVRegDefInBasicBlock(
Register Reg, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const {
if (I == MBB.begin())
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code can be simplified into a while (I != MBB.begin()) { .... } loop, right? also return a pointer of MachineInstr seems more straightforward?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. Turn it into a for/while loop and add this condition check as the loop terminator. I second that idea of returning a MachineInstr*. All the machinery of checking I != MBB.end() at the call-sites (after this function returns) can be simplified with a !MI.

return MBB.end();
// Iterate backwards from I (exclusive) to the beginning of the basic block
do {
--I;
if (I->modifiesRegister(Reg, getTargetRegisterInfo()))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (I->modifiesRegister(Reg, getTargetRegisterInfo()))
if (I->definesRegister(Reg, getTargetRegisterInfo()))

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you looking for those instructions only that fully define Reg use the above suggestion because the existing one also accounts for the case of partial definition!

return I;
} while (I != MBB.begin());
return MBB.end();
}
46 changes: 26 additions & 20 deletions llvm/lib/Target/AMDGPU/AMDGPUWaveTransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1839,7 +1839,7 @@ void ControlFlowRewriter::rewrite() {
Opcode = AMDGPU::S_CBRANCH_SCC1;
} else {
Register CondReg = Info.OrigCondition;
if (!LMA.isSubsetOfExec(CondReg, *Node->Block)) {
if (!LMA.isSubsetOfExec(CondReg, *Node->Block, Node->Block->end())) {
CondReg = LMU.createLaneMaskReg();
BuildMI(*Node->Block, Node->Block->end(), {}, TII.get(LMC.AndOpc),
CondReg)
Expand Down Expand Up @@ -1876,7 +1876,6 @@ void ControlFlowRewriter::rewrite() {
RegMap;
GCNLaneMaskUpdater Updater(Function);
Updater.setLaneMaskAnalysis(&LMA);
Updater.setAccumulating(true);

for (WaveNode *LaneTarget : NodeOrder) {
CFGNodeInfo &LaneTargetInfo = NodeInfo.find(LaneTarget)->second;
Expand Down Expand Up @@ -1937,7 +1936,8 @@ void ControlFlowRewriter::rewrite() {
}
} else {
CondReg = LaneOrigin.CondReg;
if (!LMA.isSubsetOfExec(LaneOrigin.CondReg, *LaneOrigin.Node->Block)) {
if (!LMA.isSubsetOfExec(LaneOrigin.CondReg, *LaneOrigin.Node->Block,
LaneOrigin.Node->Block->getFirstTerminator())) {
Register Prev = CondReg;
CondReg = LMU.createLaneMaskReg();
BuildMI(*LaneOrigin.Node->Block,
Expand Down Expand Up @@ -2033,28 +2033,34 @@ void ControlFlowRewriter::rewrite() {
CFGNodeInfo &PredInfo = NodeInfo.find(Pred)->second;
Register PrimaryExec = PredInfo.PrimarySuccessorExec;

MachineInstr *PrimaryExecDef;
for (;;) {
PrimaryExecDef = MRI.getVRegDef(PrimaryExec);
if (PrimaryExecDef->getOpcode() != AMDGPU::COPY)
break;
PrimaryExec = PrimaryExecDef->getOperand(1).getReg();
}
// Turning off this copy-chain optimization to retain the Accumulator as
// the PrimaryExec

// MachineInstr *PrimaryExecDef;
// for (;;) {
// PrimaryExecDef = MRI.getVRegDef(PrimaryExec);
// if (PrimaryExecDef->getOpcode() != AMDGPU::COPY)
// break;
// PrimaryExec = PrimaryExecDef->getOperand(1).getReg();
// }

// Rejoin = EXEC ^ PrimaryExec
//
// Fold immediately if PrimaryExec was obtained via XOR as well.
Register Rejoin;

if (PrimaryExecDef->getParent() == Pred->Block &&
PrimaryExecDef->getOpcode() == LMC.XorOpc &&
PrimaryExecDef->getOperand(1).isReg() &&
PrimaryExecDef->getOperand(2).isReg()) {
if (PrimaryExecDef->getOperand(1).getReg() == LMC.ExecReg)
Rejoin = PrimaryExecDef->getOperand(2).getReg();
else if (PrimaryExecDef->getOperand(2).getReg() == LMC.ExecReg)
Rejoin = PrimaryExecDef->getOperand(1).getReg();
}
// Turning off this XOR optimiztion since buildMergeLaneMasks() will not
// introduce XOR instruction for creating the PrimaryExec

// if (PrimaryExecDef->getParent() == Pred->Block &&
// PrimaryExecDef->getOpcode() == LMC.XorOpc &&
// PrimaryExecDef->getOperand(1).isReg() &&
// PrimaryExecDef->getOperand(2).isReg()) {
// if (PrimaryExecDef->getOperand(1).getReg() == LMC.ExecReg)
// Rejoin = PrimaryExecDef->getOperand(2).getReg();
// else if (PrimaryExecDef->getOperand(2).getReg() == LMC.ExecReg)
// Rejoin = PrimaryExecDef->getOperand(1).getReg();
// }

if (!Rejoin) {
// Try to find a previously generated XOR (or merely masked) value
Expand Down Expand Up @@ -2091,7 +2097,7 @@ void ControlFlowRewriter::rewrite() {

LLVM_DEBUG(Function.dump());
}

Updater.insertAccumulatorResets();
Updater.cleanup();
}

Expand Down
Loading