mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-15 04:29:42 +00:00
[RDA] Attempt to make RDA subreg aware
This attempts to make more of RDA aware of potentially overlapping subregisters. Some of this was already in place, with it iterating through MCRegUnitIterators. This also replaces calls to LiveRegs.contains(..) with !LiveRegs.available(..), and updates the isValidRegUseOf and isValidRegDefOf to search subregs. Differential Revision: https://reviews.llvm.org/D107351
This commit is contained in:
parent
ff9958b70e
commit
eeddcba525
@ -30,16 +30,32 @@ static bool isValidRegUse(const MachineOperand &MO) {
|
||||
return isValidReg(MO) && MO.isUse();
|
||||
}
|
||||
|
||||
static bool isValidRegUseOf(const MachineOperand &MO, MCRegister PhysReg) {
|
||||
return isValidRegUse(MO) && MO.getReg() == PhysReg;
|
||||
static bool isValidRegUseOf(const MachineOperand &MO, MCRegister PhysReg,
|
||||
const TargetRegisterInfo *TRI) {
|
||||
if (!isValidRegUse(MO))
|
||||
return false;
|
||||
if (MO.getReg() == PhysReg)
|
||||
return true;
|
||||
for (MCRegAliasIterator R(PhysReg, TRI, false); R.isValid(); ++R)
|
||||
if (MO.getReg() == *R)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isValidRegDef(const MachineOperand &MO) {
|
||||
return isValidReg(MO) && MO.isDef();
|
||||
}
|
||||
|
||||
static bool isValidRegDefOf(const MachineOperand &MO, MCRegister PhysReg) {
|
||||
return isValidRegDef(MO) && MO.getReg() == PhysReg;
|
||||
static bool isValidRegDefOf(const MachineOperand &MO, MCRegister PhysReg,
|
||||
const TargetRegisterInfo *TRI) {
|
||||
if (!isValidRegDef(MO))
|
||||
return false;
|
||||
if (MO.getReg() == PhysReg)
|
||||
return true;
|
||||
for (MCRegAliasIterator R(PhysReg, TRI, false); R.isValid(); ++R)
|
||||
if (MO.getReg() == *R)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void ReachingDefAnalysis::enterBasicBlock(MachineBasicBlock *MBB) {
|
||||
@ -337,7 +353,7 @@ void ReachingDefAnalysis::getReachingLocalUses(MachineInstr *Def,
|
||||
return;
|
||||
|
||||
for (auto &MO : MI->operands()) {
|
||||
if (!isValidRegUseOf(MO, PhysReg))
|
||||
if (!isValidRegUseOf(MO, PhysReg, TRI))
|
||||
continue;
|
||||
|
||||
Uses.insert(&*MI);
|
||||
@ -353,7 +369,7 @@ bool ReachingDefAnalysis::getLiveInUses(MachineBasicBlock *MBB,
|
||||
for (MachineInstr &MI :
|
||||
instructionsWithoutDebug(MBB->instr_begin(), MBB->instr_end())) {
|
||||
for (auto &MO : MI.operands()) {
|
||||
if (!isValidRegUseOf(MO, PhysReg))
|
||||
if (!isValidRegUseOf(MO, PhysReg, TRI))
|
||||
continue;
|
||||
if (getReachingDef(&MI, PhysReg) >= 0)
|
||||
return false;
|
||||
@ -419,7 +435,7 @@ void ReachingDefAnalysis::getLiveOuts(MachineBasicBlock *MBB,
|
||||
VisitedBBs.insert(MBB);
|
||||
LivePhysRegs LiveRegs(*TRI);
|
||||
LiveRegs.addLiveOuts(*MBB);
|
||||
if (!LiveRegs.contains(PhysReg))
|
||||
if (LiveRegs.available(MBB->getParent()->getRegInfo(), PhysReg))
|
||||
return;
|
||||
|
||||
if (auto *Def = getLocalLiveOutMIDef(MBB, PhysReg))
|
||||
@ -469,7 +485,7 @@ bool ReachingDefAnalysis::isRegUsedAfter(MachineInstr *MI,
|
||||
LiveRegs.addLiveOuts(*MBB);
|
||||
|
||||
// Yes if the register is live out of the basic block.
|
||||
if (LiveRegs.contains(PhysReg))
|
||||
if (!LiveRegs.available(MBB->getParent()->getRegInfo(), PhysReg))
|
||||
return true;
|
||||
|
||||
// Walk backwards through the block to see if the register is live at some
|
||||
@ -477,7 +493,7 @@ bool ReachingDefAnalysis::isRegUsedAfter(MachineInstr *MI,
|
||||
for (MachineInstr &Last :
|
||||
instructionsWithoutDebug(MBB->instr_rbegin(), MBB->instr_rend())) {
|
||||
LiveRegs.stepBackward(Last);
|
||||
if (LiveRegs.contains(PhysReg))
|
||||
if (!LiveRegs.available(MBB->getParent()->getRegInfo(), PhysReg))
|
||||
return InstIds.lookup(&Last) > InstIds.lookup(MI);
|
||||
}
|
||||
return false;
|
||||
@ -502,7 +518,7 @@ bool ReachingDefAnalysis::isReachingDefLiveOut(MachineInstr *MI,
|
||||
MachineBasicBlock *MBB = MI->getParent();
|
||||
LivePhysRegs LiveRegs(*TRI);
|
||||
LiveRegs.addLiveOuts(*MBB);
|
||||
if (!LiveRegs.contains(PhysReg))
|
||||
if (LiveRegs.available(MBB->getParent()->getRegInfo(), PhysReg))
|
||||
return false;
|
||||
|
||||
auto Last = MBB->getLastNonDebugInstr();
|
||||
@ -512,7 +528,7 @@ bool ReachingDefAnalysis::isReachingDefLiveOut(MachineInstr *MI,
|
||||
|
||||
// Finally check that the last instruction doesn't redefine the register.
|
||||
for (auto &MO : Last->operands())
|
||||
if (isValidRegDefOf(MO, PhysReg))
|
||||
if (isValidRegDefOf(MO, PhysReg, TRI))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -523,7 +539,7 @@ ReachingDefAnalysis::getLocalLiveOutMIDef(MachineBasicBlock *MBB,
|
||||
MCRegister PhysReg) const {
|
||||
LivePhysRegs LiveRegs(*TRI);
|
||||
LiveRegs.addLiveOuts(*MBB);
|
||||
if (!LiveRegs.contains(PhysReg))
|
||||
if (LiveRegs.available(MBB->getParent()->getRegInfo(), PhysReg))
|
||||
return nullptr;
|
||||
|
||||
auto Last = MBB->getLastNonDebugInstr();
|
||||
@ -532,7 +548,7 @@ ReachingDefAnalysis::getLocalLiveOutMIDef(MachineBasicBlock *MBB,
|
||||
|
||||
int Def = getReachingDef(&*Last, PhysReg);
|
||||
for (auto &MO : Last->operands())
|
||||
if (isValidRegDefOf(MO, PhysReg))
|
||||
if (isValidRegDefOf(MO, PhysReg, TRI))
|
||||
return &*Last;
|
||||
|
||||
return Def < 0 ? nullptr : getInstFromId(MBB, Def);
|
||||
@ -700,7 +716,7 @@ bool ReachingDefAnalysis::isSafeToDefRegAt(MachineInstr *MI, MCRegister PhysReg,
|
||||
if (Ignore.count(&*I))
|
||||
continue;
|
||||
for (auto &MO : I->operands())
|
||||
if (isValidRegDefOf(MO, PhysReg))
|
||||
if (isValidRegDefOf(MO, PhysReg, TRI))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -80,14 +80,25 @@ body: |
|
||||
; CHECK: bb.1.while.body.preheader:
|
||||
; CHECK: successors: %bb.2(0x80000000)
|
||||
; CHECK: liveins: $r1, $r2
|
||||
; CHECK: $r0 = tMOVr $r2, 14 /* CC::al */, $noreg
|
||||
; CHECK: tCMPi8 renamable $r2, 4, 14 /* CC::al */, $noreg, implicit-def $cpsr
|
||||
; CHECK: t2IT 10, 8, implicit-def $itstate
|
||||
; CHECK: renamable $r0 = tMOVi8 $noreg, 4, 10 /* CC::ge */, killed $cpsr, implicit killed renamable $r0, implicit killed $itstate
|
||||
; CHECK: renamable $r0, dead $cpsr = tSUBrr renamable $r2, killed renamable $r0, 14 /* CC::al */, $noreg
|
||||
; CHECK: renamable $r0, dead $cpsr = tADDi8 killed renamable $r0, 3, 14 /* CC::al */, $noreg
|
||||
; CHECK: renamable $r3, dead $cpsr = tMOVi8 1, 14 /* CC::al */, $noreg
|
||||
; CHECK: renamable $r0 = nuw nsw t2ADDrs killed renamable $r3, killed renamable $r0, 19, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: renamable $q0 = MVE_VMOVimmi32 1, 0, $noreg, undef renamable $q0
|
||||
; CHECK: $lr = MVE_DLSTP_32 killed renamable $r2
|
||||
; CHECK: $lr = t2DLS killed renamable $r0
|
||||
; CHECK: bb.2.while.body (align 4):
|
||||
; CHECK: successors: %bb.2(0x7c000000), %bb.4(0x04000000)
|
||||
; CHECK: liveins: $lr, $q0, $r1
|
||||
; CHECK: renamable $r1, renamable $q1 = MVE_VLDRWU32_post killed renamable $r1, 16, 0, killed $noreg :: (load (s128) from %ir.y.addr.0161, align 4)
|
||||
; CHECK: liveins: $lr, $q0, $r1, $r2
|
||||
; CHECK: renamable $vpr = MVE_VCTP32 renamable $r2, 0, $noreg
|
||||
; CHECK: MVE_VPST 8, implicit $vpr
|
||||
; CHECK: renamable $r1, renamable $q1 = MVE_VLDRWU32_post killed renamable $r1, 16, 1, killed renamable $vpr :: (load (s128) from %ir.y.addr.0161, align 4)
|
||||
; CHECK: renamable $q0 = MVE_VMULi32 killed renamable $q1, killed renamable $q0, 0, $noreg, undef renamable $q0
|
||||
; CHECK: $lr = MVE_LETP killed renamable $lr, %bb.2
|
||||
; CHECK: renamable $r2, dead $cpsr = tSUBi8 killed renamable $r2, 4, 14 /* CC::al */, $noreg
|
||||
; CHECK: $lr = t2LEUpdate killed renamable $lr, %bb.2
|
||||
; CHECK: tB %bb.4, 14 /* CC::al */, $noreg
|
||||
; CHECK: bb.3:
|
||||
; CHECK: successors: %bb.4(0x80000000)
|
||||
|
Loading…
x
Reference in New Issue
Block a user