summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorcdevadas <cdevadas@amd.com>2019-10-26 14:33:36 +0530
committercdevadas <cdevadas@amd.com>2019-10-26 14:37:45 +0530
commite921ede54068b94702efcc1654dd0027c844012c (patch)
tree73b51e9005851c71c03411bc631730ce1b1236ff /llvm/lib/Target
parent5e307808557f4786c6438c9cfd67784073c5a3b7 (diff)
downloadbcm5719-llvm-e921ede54068b94702efcc1654dd0027c844012c.tar.gz
bcm5719-llvm-e921ede54068b94702efcc1654dd0027c844012c.zip
[AMDGPU] Fix Vreg_1 PHI lowering in SILowerI1Copies.
There is a minor flaw in the implementation of function lowerPhis. This function replaces values of regclass Vreg_1 (boolean values) involved in PHIs into an SGPR. Currently it iterates over the MBBs and performs an inplace lowering of PHIs and fails to lower any incoming value that itself is another PHI of Vreg_1 regclass. The failure occurs only when the MBB where the incoming PHI value belongs is not visited/lowered yet. To fix this problem, collect all Vreg_1 PHIs upfront and then perform the lowering. Differential Revision: https://reviews.llvm.org/D69182
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/AMDGPU/SILowerI1Copies.cpp179
1 files changed, 89 insertions, 90 deletions
diff --git a/llvm/lib/Target/AMDGPU/SILowerI1Copies.cpp b/llvm/lib/Target/AMDGPU/SILowerI1Copies.cpp
index b4541253635..0eb64972d61 100644
--- a/llvm/lib/Target/AMDGPU/SILowerI1Copies.cpp
+++ b/llvm/lib/Target/AMDGPU/SILowerI1Copies.cpp
@@ -541,7 +541,7 @@ void SILowerI1Copies::lowerPhis() {
MachineSSAUpdater SSAUpdater(*MF);
LoopFinder LF(*DT, *PDT);
PhiIncomingAnalysis PIA(*PDT);
- SmallVector<MachineInstr *, 4> DeadPhis;
+ SmallVector<MachineInstr *, 4> Vreg1Phis;
SmallVector<MachineBasicBlock *, 4> IncomingBlocks;
SmallVector<unsigned, 4> IncomingRegs;
SmallVector<unsigned, 4> IncomingUpdated;
@@ -550,118 +550,117 @@ void SILowerI1Copies::lowerPhis() {
#endif
for (MachineBasicBlock &MBB : *MF) {
- LF.initialize(MBB);
-
for (MachineInstr &MI : MBB.phis()) {
- Register DstReg = MI.getOperand(0).getReg();
- if (!isVreg1(DstReg))
- continue;
+ if (isVreg1(MI.getOperand(0).getReg()))
+ Vreg1Phis.push_back(&MI);
+ }
+ }
- LLVM_DEBUG(dbgs() << "Lower PHI: " << MI);
+ MachineBasicBlock *PrevMBB = nullptr;
+ for (MachineInstr *MI : Vreg1Phis) {
+ MachineBasicBlock &MBB = *MI->getParent();
+ if (&MBB != PrevMBB) {
+ LF.initialize(MBB);
+ PrevMBB = &MBB;
+ }
- MRI->setRegClass(DstReg, IsWave32 ? &AMDGPU::SReg_32RegClass
- : &AMDGPU::SReg_64RegClass);
+ LLVM_DEBUG(dbgs() << "Lower PHI: " << *MI);
- // Collect incoming values.
- for (unsigned i = 1; i < MI.getNumOperands(); i += 2) {
- assert(i + 1 < MI.getNumOperands());
- Register IncomingReg = MI.getOperand(i).getReg();
- MachineBasicBlock *IncomingMBB = MI.getOperand(i + 1).getMBB();
- MachineInstr *IncomingDef = MRI->getUniqueVRegDef(IncomingReg);
-
- if (IncomingDef->getOpcode() == AMDGPU::COPY) {
- IncomingReg = IncomingDef->getOperand(1).getReg();
- assert(isLaneMaskReg(IncomingReg) || isVreg1(IncomingReg));
- assert(!IncomingDef->getOperand(1).getSubReg());
- } else if (IncomingDef->getOpcode() == AMDGPU::IMPLICIT_DEF) {
- continue;
- } else {
- assert(IncomingDef->isPHI() || PhiRegisters.count(IncomingReg));
- }
+ Register DstReg = MI->getOperand(0).getReg();
+ MRI->setRegClass(DstReg, IsWave32 ? &AMDGPU::SReg_32RegClass
+ : &AMDGPU::SReg_64RegClass);
+
+ // Collect incoming values.
+ for (unsigned i = 1; i < MI->getNumOperands(); i += 2) {
+ assert(i + 1 < MI->getNumOperands());
+ Register IncomingReg = MI->getOperand(i).getReg();
+ MachineBasicBlock *IncomingMBB = MI->getOperand(i + 1).getMBB();
+ MachineInstr *IncomingDef = MRI->getUniqueVRegDef(IncomingReg);
- IncomingBlocks.push_back(IncomingMBB);
- IncomingRegs.push_back(IncomingReg);
+ if (IncomingDef->getOpcode() == AMDGPU::COPY) {
+ IncomingReg = IncomingDef->getOperand(1).getReg();
+ assert(isLaneMaskReg(IncomingReg) || isVreg1(IncomingReg));
+ assert(!IncomingDef->getOperand(1).getSubReg());
+ } else if (IncomingDef->getOpcode() == AMDGPU::IMPLICIT_DEF) {
+ continue;
+ } else {
+ assert(IncomingDef->isPHI() || PhiRegisters.count(IncomingReg));
}
+ IncomingBlocks.push_back(IncomingMBB);
+ IncomingRegs.push_back(IncomingReg);
+ }
+
#ifndef NDEBUG
- PhiRegisters.insert(DstReg);
+ PhiRegisters.insert(DstReg);
#endif
- // Phis in a loop that are observed outside the loop receive a simple but
- // conservatively correct treatment.
- std::vector<MachineBasicBlock *> DomBlocks = {&MBB};
- for (MachineInstr &Use : MRI->use_instructions(DstReg))
- DomBlocks.push_back(Use.getParent());
+ // Phis in a loop that are observed outside the loop receive a simple but
+ // conservatively correct treatment.
+ std::vector<MachineBasicBlock *> DomBlocks = {&MBB};
+ for (MachineInstr &Use : MRI->use_instructions(DstReg))
+ DomBlocks.push_back(Use.getParent());
- MachineBasicBlock *PostDomBound =
- PDT->findNearestCommonDominator(DomBlocks);
- unsigned FoundLoopLevel = LF.findLoop(PostDomBound);
-
- SSAUpdater.Initialize(DstReg);
-
- if (FoundLoopLevel) {
- LF.addLoopEntries(FoundLoopLevel, SSAUpdater, IncomingBlocks);
+ MachineBasicBlock *PostDomBound =
+ PDT->findNearestCommonDominator(DomBlocks);
+ unsigned FoundLoopLevel = LF.findLoop(PostDomBound);
- for (unsigned i = 0; i < IncomingRegs.size(); ++i) {
- IncomingUpdated.push_back(createLaneMaskReg(*MF));
- SSAUpdater.AddAvailableValue(IncomingBlocks[i],
- IncomingUpdated.back());
- }
+ SSAUpdater.Initialize(DstReg);
- for (unsigned i = 0; i < IncomingRegs.size(); ++i) {
- MachineBasicBlock &IMBB = *IncomingBlocks[i];
- buildMergeLaneMasks(
- IMBB, getSaluInsertionAtEnd(IMBB), {}, IncomingUpdated[i],
- SSAUpdater.GetValueInMiddleOfBlock(&IMBB), IncomingRegs[i]);
- }
- } else {
- // The phi is not observed from outside a loop. Use a more accurate
- // lowering.
- PIA.analyze(MBB, IncomingBlocks);
-
- for (MachineBasicBlock *MBB : PIA.predecessors())
- SSAUpdater.AddAvailableValue(MBB, insertUndefLaneMask(*MBB));
-
- for (unsigned i = 0; i < IncomingRegs.size(); ++i) {
- MachineBasicBlock &IMBB = *IncomingBlocks[i];
- if (PIA.isSource(IMBB)) {
- IncomingUpdated.push_back(0);
- SSAUpdater.AddAvailableValue(&IMBB, IncomingRegs[i]);
- } else {
- IncomingUpdated.push_back(createLaneMaskReg(*MF));
- SSAUpdater.AddAvailableValue(&IMBB, IncomingUpdated.back());
- }
- }
+ if (FoundLoopLevel) {
+ LF.addLoopEntries(FoundLoopLevel, SSAUpdater, IncomingBlocks);
- for (unsigned i = 0; i < IncomingRegs.size(); ++i) {
- if (!IncomingUpdated[i])
- continue;
+ for (unsigned i = 0; i < IncomingRegs.size(); ++i) {
+ IncomingUpdated.push_back(createLaneMaskReg(*MF));
+ SSAUpdater.AddAvailableValue(IncomingBlocks[i],
+ IncomingUpdated.back());
+ }
- MachineBasicBlock &IMBB = *IncomingBlocks[i];
- buildMergeLaneMasks(
- IMBB, getSaluInsertionAtEnd(IMBB), {}, IncomingUpdated[i],
- SSAUpdater.GetValueInMiddleOfBlock(&IMBB), IncomingRegs[i]);
+ for (unsigned i = 0; i < IncomingRegs.size(); ++i) {
+ MachineBasicBlock &IMBB = *IncomingBlocks[i];
+ buildMergeLaneMasks(
+ IMBB, getSaluInsertionAtEnd(IMBB), {}, IncomingUpdated[i],
+ SSAUpdater.GetValueInMiddleOfBlock(&IMBB), IncomingRegs[i]);
+ }
+ } else {
+ // The phi is not observed from outside a loop. Use a more accurate
+ // lowering.
+ PIA.analyze(MBB, IncomingBlocks);
+
+ for (MachineBasicBlock *MBB : PIA.predecessors())
+ SSAUpdater.AddAvailableValue(MBB, insertUndefLaneMask(*MBB));
+
+ for (unsigned i = 0; i < IncomingRegs.size(); ++i) {
+ MachineBasicBlock &IMBB = *IncomingBlocks[i];
+ if (PIA.isSource(IMBB)) {
+ IncomingUpdated.push_back(0);
+ SSAUpdater.AddAvailableValue(&IMBB, IncomingRegs[i]);
+ } else {
+ IncomingUpdated.push_back(createLaneMaskReg(*MF));
+ SSAUpdater.AddAvailableValue(&IMBB, IncomingUpdated.back());
}
}
- unsigned NewReg = SSAUpdater.GetValueInMiddleOfBlock(&MBB);
- if (NewReg != DstReg) {
- MRI->replaceRegWith(NewReg, DstReg);
+ for (unsigned i = 0; i < IncomingRegs.size(); ++i) {
+ if (!IncomingUpdated[i])
+ continue;
- // Ensure that DstReg has a single def and mark the old PHI node for
- // deletion.
- MI.getOperand(0).setReg(NewReg);
- DeadPhis.push_back(&MI);
+ MachineBasicBlock &IMBB = *IncomingBlocks[i];
+ buildMergeLaneMasks(
+ IMBB, getSaluInsertionAtEnd(IMBB), {}, IncomingUpdated[i],
+ SSAUpdater.GetValueInMiddleOfBlock(&IMBB), IncomingRegs[i]);
}
-
- IncomingBlocks.clear();
- IncomingRegs.clear();
- IncomingUpdated.clear();
}
- for (MachineInstr *MI : DeadPhis)
+ unsigned NewReg = SSAUpdater.GetValueInMiddleOfBlock(&MBB);
+ if (NewReg != DstReg) {
+ MRI->replaceRegWith(NewReg, DstReg);
MI->eraseFromParent();
- DeadPhis.clear();
+ }
+
+ IncomingBlocks.clear();
+ IncomingRegs.clear();
+ IncomingUpdated.clear();
}
}
OpenPOWER on IntegriCloud