forked from OSchip/llvm-project
[CodeGen][AArch64] Use RegUnits to track register aliases. (NFC)
Use RegUnits to track register aliases in AArch64RedundantCopyElimination. Differential Revision: https://reviews.llvm.org/D47269 llvm-svn: 333107
This commit is contained in:
parent
6b6c553bb8
commit
3f66363139
|
@ -55,6 +55,7 @@
|
|||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/CodeGen/LiveRegUnits.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
|
@ -72,10 +73,10 @@ class AArch64RedundantCopyElimination : public MachineFunctionPass {
|
|||
|
||||
// DomBBClobberedRegs is used when computing known values in the dominating
|
||||
// BB.
|
||||
BitVector DomBBClobberedRegs;
|
||||
LiveRegUnits DomBBClobberedRegs, DomBBUsedRegs;
|
||||
|
||||
// OptBBClobberedRegs is used when optimizing away redundant copies/moves.
|
||||
BitVector OptBBClobberedRegs;
|
||||
LiveRegUnits OptBBClobberedRegs, OptBBUsedRegs;
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
|
@ -109,28 +110,6 @@ char AArch64RedundantCopyElimination::ID = 0;
|
|||
INITIALIZE_PASS(AArch64RedundantCopyElimination, "aarch64-copyelim",
|
||||
"AArch64 redundant copy elimination pass", false, false)
|
||||
|
||||
/// Remember what registers the specified instruction modifies.
|
||||
static void trackRegDefs(const MachineInstr &MI, BitVector &ClobberedRegs,
|
||||
const TargetRegisterInfo *TRI) {
|
||||
for (const MachineOperand &MO : MI.operands()) {
|
||||
if (MO.isRegMask()) {
|
||||
ClobberedRegs.setBitsNotInMask(MO.getRegMask());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!MO.isReg())
|
||||
continue;
|
||||
unsigned Reg = MO.getReg();
|
||||
if (!Reg)
|
||||
continue;
|
||||
if (!MO.isDef())
|
||||
continue;
|
||||
|
||||
for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
|
||||
ClobberedRegs.set(*AI);
|
||||
}
|
||||
}
|
||||
|
||||
/// It's possible to determine the value of a register based on a dominating
|
||||
/// condition. To do so, this function checks to see if the basic block \p MBB
|
||||
/// is the target of a conditional branch \p CondBr with an equality comparison.
|
||||
|
@ -182,7 +161,8 @@ bool AArch64RedundantCopyElimination::knownRegValInBlock(
|
|||
|
||||
// Registers clobbered in PredMBB between CondBr instruction and current
|
||||
// instruction being checked in loop.
|
||||
DomBBClobberedRegs.reset();
|
||||
DomBBClobberedRegs.clear();
|
||||
DomBBUsedRegs.clear();
|
||||
|
||||
// Find compare instruction that sets NZCV used by CondBr.
|
||||
MachineBasicBlock::reverse_iterator RIt = CondBr.getReverseIterator();
|
||||
|
@ -212,7 +192,7 @@ bool AArch64RedundantCopyElimination::knownRegValInBlock(
|
|||
// register of the compare is not modified (including a self-clobbering
|
||||
// compare) between the compare and conditional branch we known the value
|
||||
// of the 1st source operand.
|
||||
if (PredI.getOperand(2).isImm() && !DomBBClobberedRegs[SrcReg] &&
|
||||
if (PredI.getOperand(2).isImm() && DomBBClobberedRegs.available(SrcReg) &&
|
||||
SrcReg != DstReg) {
|
||||
// We've found the instruction that sets NZCV.
|
||||
int32_t KnownImm = PredI.getOperand(2).getImm();
|
||||
|
@ -232,7 +212,7 @@ bool AArch64RedundantCopyElimination::knownRegValInBlock(
|
|||
|
||||
// The destination register must not be modified between the NZCV setting
|
||||
// instruction and the conditional branch.
|
||||
if (DomBBClobberedRegs[DstReg])
|
||||
if (!DomBBClobberedRegs.available(DstReg))
|
||||
return Res;
|
||||
|
||||
FirstUse = PredI;
|
||||
|
@ -276,7 +256,7 @@ bool AArch64RedundantCopyElimination::knownRegValInBlock(
|
|||
|
||||
// The destination register of the NZCV setting instruction must not be
|
||||
// modified before the conditional branch.
|
||||
if (DomBBClobberedRegs[DstReg])
|
||||
if (!DomBBClobberedRegs.available(DstReg))
|
||||
return false;
|
||||
|
||||
// We've found the instruction that sets NZCV whose DstReg == 0.
|
||||
|
@ -290,8 +270,9 @@ bool AArch64RedundantCopyElimination::knownRegValInBlock(
|
|||
if (PredI.definesRegister(AArch64::NZCV))
|
||||
return false;
|
||||
|
||||
// Track clobbered registers.
|
||||
trackRegDefs(PredI, DomBBClobberedRegs, TRI);
|
||||
// Track clobbered and used registers.
|
||||
LiveRegUnits::accumulateUsedDefed(PredI, DomBBClobberedRegs, DomBBUsedRegs,
|
||||
TRI);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -330,8 +311,9 @@ bool AArch64RedundantCopyElimination::optimizeBlock(MachineBasicBlock *MBB) {
|
|||
if (!knownRegValInBlock(*Itr, MBB, KnownRegs, FirstUse))
|
||||
continue;
|
||||
|
||||
// Reset the clobber list.
|
||||
OptBBClobberedRegs.reset();
|
||||
// Reset the clobbered and used register units.
|
||||
OptBBClobberedRegs.clear();
|
||||
OptBBUsedRegs.clear();
|
||||
|
||||
// Look backward in PredMBB for COPYs from the known reg to find other
|
||||
// registers that are known to be a constant value.
|
||||
|
@ -343,11 +325,12 @@ bool AArch64RedundantCopyElimination::optimizeBlock(MachineBasicBlock *MBB) {
|
|||
MCPhysReg CopyDstReg = PredI->getOperand(0).getReg();
|
||||
MCPhysReg CopySrcReg = PredI->getOperand(1).getReg();
|
||||
for (auto &KnownReg : KnownRegs) {
|
||||
if (OptBBClobberedRegs[KnownReg.Reg])
|
||||
if (!OptBBClobberedRegs.available(KnownReg.Reg))
|
||||
continue;
|
||||
// If we have X = COPY Y, and Y is known to be zero, then now X is
|
||||
// known to be zero.
|
||||
if (CopySrcReg == KnownReg.Reg && !OptBBClobberedRegs[CopyDstReg]) {
|
||||
if (CopySrcReg == KnownReg.Reg &&
|
||||
OptBBClobberedRegs.available(CopyDstReg)) {
|
||||
KnownRegs.push_back(RegImm(CopyDstReg, KnownReg.Imm));
|
||||
if (SeenFirstUse)
|
||||
FirstUse = PredI;
|
||||
|
@ -355,7 +338,8 @@ bool AArch64RedundantCopyElimination::optimizeBlock(MachineBasicBlock *MBB) {
|
|||
}
|
||||
// If we have X = COPY Y, and X is known to be zero, then now Y is
|
||||
// known to be zero.
|
||||
if (CopyDstReg == KnownReg.Reg && !OptBBClobberedRegs[CopySrcReg]) {
|
||||
if (CopyDstReg == KnownReg.Reg &&
|
||||
OptBBClobberedRegs.available(CopySrcReg)) {
|
||||
KnownRegs.push_back(RegImm(CopySrcReg, KnownReg.Imm));
|
||||
if (SeenFirstUse)
|
||||
FirstUse = PredI;
|
||||
|
@ -368,10 +352,11 @@ bool AArch64RedundantCopyElimination::optimizeBlock(MachineBasicBlock *MBB) {
|
|||
if (PredI == PredMBB->begin())
|
||||
break;
|
||||
|
||||
trackRegDefs(*PredI, OptBBClobberedRegs, TRI);
|
||||
LiveRegUnits::accumulateUsedDefed(*PredI, OptBBClobberedRegs,
|
||||
OptBBUsedRegs, TRI);
|
||||
// Stop if all of the known-zero regs have been clobbered.
|
||||
if (all_of(KnownRegs, [&](RegImm KnownReg) {
|
||||
return OptBBClobberedRegs[KnownReg.Reg];
|
||||
return !OptBBClobberedRegs.available(KnownReg.Reg);
|
||||
}))
|
||||
break;
|
||||
}
|
||||
|
@ -490,10 +475,12 @@ bool AArch64RedundantCopyElimination::runOnMachineFunction(
|
|||
TRI = MF.getSubtarget().getRegisterInfo();
|
||||
MRI = &MF.getRegInfo();
|
||||
|
||||
// Resize the clobber register bitfield trackers. We do this once per
|
||||
// Resize the clobbered and used register unit trackers. We do this once per
|
||||
// function.
|
||||
DomBBClobberedRegs.resize(TRI->getNumRegs());
|
||||
OptBBClobberedRegs.resize(TRI->getNumRegs());
|
||||
DomBBClobberedRegs.init(*TRI);
|
||||
DomBBUsedRegs.init(*TRI);
|
||||
OptBBClobberedRegs.init(*TRI);
|
||||
OptBBUsedRegs.init(*TRI);
|
||||
|
||||
bool Changed = false;
|
||||
for (MachineBasicBlock &MBB : MF)
|
||||
|
|
Loading…
Reference in New Issue