diff options
| author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2017-03-06 17:09:06 +0000 |
|---|---|---|
| committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2017-03-06 17:09:06 +0000 |
| commit | e16ce15687991ffed596fe5b65df95f0859718e2 (patch) | |
| tree | 88d6d20883e6f72729bc64f782bb72fb550140ad /llvm/lib/Target | |
| parent | 143158b72e32cd5516eef23aa0504f274896c85a (diff) | |
| download | bcm5719-llvm-e16ce15687991ffed596fe5b65df95f0859718e2.tar.gz bcm5719-llvm-e16ce15687991ffed596fe5b65df95f0859718e2.zip | |
[Hexagon] Mark dead defs as <dead> in expand-condsets
The code in updateDeadFlags removed unnecessary <dead> flags, but there
can be cases where such a flag is not set, and yet a register has become
dead. For example, if a mux with identical inputs is replaced with a COPY,
the predicate register may no longer be used after that.
llvm-svn: 297032
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp b/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp index 624a713a80d..d8ba5dcd35a 100644 --- a/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp +++ b/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp @@ -362,14 +362,16 @@ void HexagonExpandCondsets::updateDeadsInRange(unsigned Reg, LaneBitmask LM, if (Range.empty()) return; - auto IsRegDef = [this,Reg,LM] (MachineOperand &Op) -> bool { + // Return two booleans: { def-modifes-reg, def-covers-reg }. + auto IsRegDef = [this,Reg,LM] (MachineOperand &Op) -> std::pair<bool,bool> { if (!Op.isReg() || !Op.isDef()) - return false; + return { false, false }; unsigned DR = Op.getReg(), DSR = Op.getSubReg(); if (!TargetRegisterInfo::isVirtualRegister(DR) || DR != Reg) - return false; + return { false, false }; LaneBitmask SLM = getLaneMask(DR, DSR); - return (SLM & LM).any(); + LaneBitmask A = SLM & LM; + return { A.any(), A == SLM }; }; // The splitting step will create pairs of predicated definitions without @@ -453,20 +455,27 @@ void HexagonExpandCondsets::updateDeadsInRange(unsigned Reg, LaneBitmask LM, // Remove <dead> flags from all defs that are not dead after live range // extension, and collect all def operands. They will be used to generate // the necessary implicit uses. + // At the same time, add <dead> flag to all defs that are actually dead. + // This can happen, for example, when a mux with identical inputs is + // replaced with a COPY: the use of the predicate register disappears and + // the dead can become dead. std::set<RegisterRef> DefRegs; for (auto &Seg : Range) { if (!Seg.start.isRegister()) continue; MachineInstr *DefI = LIS->getInstructionFromIndex(Seg.start); for (auto &Op : DefI->operands()) { - if (Seg.start.isDead() || !IsRegDef(Op)) - continue; - DefRegs.insert(Op); - Op.setIsDead(false); + auto P = IsRegDef(Op); + if (P.second && Seg.end.isDead()) { + Op.setIsDead(true); + } else if (P.first) { + DefRegs.insert(Op); + Op.setIsDead(false); + } } } - // Finally, add implicit uses to each predicated def that is reached + // Now, add implicit uses to each predicated def that is reached // by other defs. for (auto &Seg : Range) { if (!Seg.start.isRegister() || !Range.liveAt(Seg.start.getPrevSlot())) @@ -486,6 +495,7 @@ void HexagonExpandCondsets::updateDeadsInRange(unsigned Reg, LaneBitmask LM, for (RegisterRef R : ImpUses) MachineInstrBuilder(MF, DefI).addReg(R.Reg, RegState::Implicit, R.Sub); } + } void HexagonExpandCondsets::updateDeadFlags(unsigned Reg) { @@ -622,6 +632,12 @@ bool HexagonExpandCondsets::split(MachineInstr &MI, bool ReadUndef = MD.isUndef(); MachineBasicBlock::iterator At = MI; + auto updateRegs = [&UpdRegs] (const MachineInstr &MI) -> void { + for (auto &Op : MI.operands()) + if (Op.isReg()) + UpdRegs.insert(Op.getReg()); + }; + // If this is a mux of the same register, just replace it with COPY. // Ideally, this would happen earlier, so that register coalescing would // see it. @@ -630,6 +646,8 @@ bool HexagonExpandCondsets::split(MachineInstr &MI, if (ST.isReg() && SF.isReg()) { RegisterRef RT(ST); if (RT == RegisterRef(SF)) { + // Copy regs to update first. + updateRegs(MI); MI.setDesc(HII->get(TargetOpcode::COPY)); unsigned S = getRegState(ST); while (MI.getNumOperands() > 1) @@ -651,9 +669,7 @@ bool HexagonExpandCondsets::split(MachineInstr &MI, LIS->InsertMachineInstrInMaps(*TfrF); // Will need to recalculate live intervals for all registers in MI. - for (auto &Op : MI.operands()) - if (Op.isReg()) - UpdRegs.insert(Op.getReg()); + updateRegs(MI); removeInstr(MI); return true; |

