mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-11 13:46:13 +00:00
Teach PHI elimination to remove REG_SEQUENCE instructions and update references of the source operands with references of the destination with subreg indices. e.g.
%reg1029<def>, %reg1030<def> = VLD1q16 %reg1024<kill>, ... %reg1031<def> = REG_SEQUENCE %reg1029<kill>, 5, %reg1030<kill>, 6 => %reg1031:5<def>, %reg1031:6<def> = VLD1q16 %reg1024<kill>, ... PHI elimination now does more than phi elimination. It is really a de-SSA pass. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103039 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
55cd6cb141
commit
afff40a62d
@ -262,6 +262,23 @@ static void printRegName(unsigned reg, const TargetRegisterInfo* tri_) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static
|
||||||
|
bool MultipleDefsByMI(const MachineInstr &MI, unsigned MOIdx) {
|
||||||
|
unsigned Reg = MI.getOperand(MOIdx).getReg();
|
||||||
|
for (unsigned i = MOIdx+1, e = MI.getNumOperands(); i < e; ++i) {
|
||||||
|
const MachineOperand &MO = MI.getOperand(i);
|
||||||
|
if (!MO.isReg())
|
||||||
|
continue;
|
||||||
|
if (MO.getReg() == Reg && MO.isDef()) {
|
||||||
|
assert(MI.getOperand(MOIdx).getSubReg() != MO.getSubReg() &&
|
||||||
|
MI.getOperand(MOIdx).getSubReg() &&
|
||||||
|
MO.getSubReg());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||||
MachineBasicBlock::iterator mi,
|
MachineBasicBlock::iterator mi,
|
||||||
SlotIndex MIIdx,
|
SlotIndex MIIdx,
|
||||||
@ -372,6 +389,13 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if (MultipleDefsByMI(*mi, MOIdx))
|
||||||
|
// Mutple defs of the same virtual register by the same instruction. e.g.
|
||||||
|
// %reg1031:5<def>, %reg1031:6<def> = VLD1q16 %reg1024<kill>, ...
|
||||||
|
// This is likely due to elimination of REG_SEQUENCE instructions. Return
|
||||||
|
// here since there is nothing to do.
|
||||||
|
return;
|
||||||
|
|
||||||
// If this is the second time we see a virtual register definition, it
|
// If this is the second time we see a virtual register definition, it
|
||||||
// must be due to phi elimination or two addr elimination. If this is
|
// must be due to phi elimination or two addr elimination. If this is
|
||||||
// the result of two address elimination, then the vreg is one of the
|
// the result of two address elimination, then the vreg is one of the
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <map>
|
#include <map>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
@ -87,6 +88,10 @@ bool llvm::PHIElimination::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
ImpDefs.clear();
|
ImpDefs.clear();
|
||||||
VRegPHIUseCount.clear();
|
VRegPHIUseCount.clear();
|
||||||
|
|
||||||
|
// Eliminate REG_SEQUENCE instructions. Their whole purpose was to preseve
|
||||||
|
// SSA form.
|
||||||
|
Changed |= EliminateRegSequences(MF);
|
||||||
|
|
||||||
return Changed;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,3 +449,58 @@ MachineBasicBlock *PHIElimination::SplitCriticalEdge(MachineBasicBlock *A,
|
|||||||
|
|
||||||
return NMBB;
|
return NMBB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void UpdateRegSequenceSrcs(unsigned SrcReg,
|
||||||
|
unsigned DstReg, unsigned SrcIdx,
|
||||||
|
MachineRegisterInfo *MRI) {
|
||||||
|
for (MachineRegisterInfo::reg_iterator RI = MRI->reg_begin(SrcReg),
|
||||||
|
UE = MRI->reg_end(); RI != UE; ) {
|
||||||
|
MachineOperand &MO = RI.getOperand();
|
||||||
|
++RI;
|
||||||
|
MO.setReg(DstReg);
|
||||||
|
MO.setSubReg(SrcIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// EliminateRegSequences - Eliminate REG_SEQUENCE instructions as second part
|
||||||
|
/// of de-ssa process. This replaces sources of REG_SEQUENCE as sub-register
|
||||||
|
/// references of the register defined by REG_SEQUENCE. e.g.
|
||||||
|
///
|
||||||
|
/// %reg1029<def>, %reg1030<def> = VLD1q16 %reg1024<kill>, ...
|
||||||
|
/// %reg1031<def> = REG_SEQUENCE %reg1029<kill>, 5, %reg1030<kill>, 6
|
||||||
|
/// =>
|
||||||
|
/// %reg1031:5<def>, %reg1031:6<def> = VLD1q16 %reg1024<kill>, ...
|
||||||
|
bool PHIElimination::EliminateRegSequences(MachineFunction &MF) {
|
||||||
|
bool Changed = false;
|
||||||
|
|
||||||
|
for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
|
||||||
|
for (MachineBasicBlock::iterator BBI = I->begin(), BBE = I->end();
|
||||||
|
BBI != BBE; ) {
|
||||||
|
MachineInstr &MI = *BBI;
|
||||||
|
++BBI;
|
||||||
|
if (MI.getOpcode() != TargetOpcode::REG_SEQUENCE)
|
||||||
|
continue;
|
||||||
|
unsigned DstReg = MI.getOperand(0).getReg();
|
||||||
|
if (MI.getOperand(0).getSubReg() ||
|
||||||
|
TargetRegisterInfo::isPhysicalRegister(DstReg) ||
|
||||||
|
!(MI.getNumOperands() & 1)) {
|
||||||
|
DEBUG(dbgs() << "Illegal REG_SEQUENCE instruction:" << MI);
|
||||||
|
llvm_unreachable(0);
|
||||||
|
}
|
||||||
|
for (unsigned i = 1, e = MI.getNumOperands(); i < e; i += 2) {
|
||||||
|
unsigned SrcReg = MI.getOperand(i).getReg();
|
||||||
|
if (MI.getOperand(i).getSubReg() ||
|
||||||
|
TargetRegisterInfo::isPhysicalRegister(SrcReg)) {
|
||||||
|
DEBUG(dbgs() << "Illegal REG_SEQUENCE instruction:" << MI);
|
||||||
|
llvm_unreachable(0);
|
||||||
|
}
|
||||||
|
unsigned SrcIdx = MI.getOperand(i+1).getImm();
|
||||||
|
UpdateRegSequenceSrcs(SrcReg, DstReg, SrcIdx, MRI);
|
||||||
|
}
|
||||||
|
|
||||||
|
MI.eraseFromParent();
|
||||||
|
Changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Changed;
|
||||||
|
}
|
||||||
|
@ -94,6 +94,8 @@ namespace llvm {
|
|||||||
return I;
|
return I;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EliminateRegSequences(MachineFunction &MF);
|
||||||
|
|
||||||
typedef std::pair<unsigned, unsigned> BBVRegPair;
|
typedef std::pair<unsigned, unsigned> BBVRegPair;
|
||||||
typedef DenseMap<BBVRegPair, unsigned> VRegPHIUse;
|
typedef DenseMap<BBVRegPair, unsigned> VRegPHIUse;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user