Move REG_SEQUENCE removal to 2addr pass.

llvm-svn: 103109
This commit is contained in:
Evan Cheng 2010-05-05 18:45:40 +00:00
parent d7f69cb7ef
commit 4b6abd8c2b
4 changed files with 71 additions and 63 deletions

View File

@ -223,6 +223,9 @@ public:
bool isSubregToReg() const {
return getOpcode() == TargetOpcode::SUBREG_TO_REG;
}
bool isRegSequence() const {
return getOpcode() == TargetOpcode::REG_SEQUENCE;
}
/// readsRegister - Return true if the MachineInstr reads the specified
/// register. If TargetRegisterInfo is passed, then it also checks if there

View File

@ -27,10 +27,8 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <map>
using namespace llvm;
@ -88,10 +86,6 @@ bool llvm::PHIElimination::runOnMachineFunction(MachineFunction &MF) {
ImpDefs.clear();
VRegPHIUseCount.clear();
// Eliminate REG_SEQUENCE instructions. Their whole purpose was to preseve
// SSA form.
Changed |= EliminateRegSequences(MF);
return Changed;
}
@ -449,58 +443,3 @@ MachineBasicBlock *PHIElimination::SplitCriticalEdge(MachineBasicBlock *A,
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;
}

View File

@ -94,8 +94,6 @@ namespace llvm {
return I;
}
bool EliminateRegSequences(MachineFunction &MF);
typedef std::pair<unsigned, unsigned> BBVRegPair;
typedef DenseMap<BBVRegPair, unsigned> VRegPHIUse;

View File

@ -40,6 +40,7 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
@ -77,6 +78,10 @@ namespace {
// registers from virtual registers. e.g. r1 = move v1024.
DenseMap<unsigned, unsigned> DstRegMap;
/// RegSequences - Keep track the list of REG_SEQUENCE instructions seen
/// during the initial walk of the machine function.
SmallVector<MachineInstr*, 16> RegSequences;
bool Sink3AddrInstruction(MachineBasicBlock *MBB, MachineInstr *MI,
unsigned Reg,
MachineBasicBlock::iterator OldPos);
@ -123,6 +128,10 @@ namespace {
void ProcessCopy(MachineInstr *MI, MachineBasicBlock *MBB,
SmallPtrSet<MachineInstr*, 8> &Processed);
/// EliminateRegSequences - Eliminate REG_SEQUENCE instructions as part
/// of the de-ssa process. This replaces sources of REG_SEQUENCE as
/// sub-register references of the register defined by REG_SEQUENCE.
bool EliminateRegSequences();
public:
static char ID; // Pass identification, replacement for typeid
TwoAddressInstructionPass() : MachineFunctionPass(&ID) {}
@ -929,6 +938,10 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
continue;
}
// Remember REG_SEQUENCE instructions, we'll deal with them later.
if (mi->isRegSequence())
RegSequences.push_back(&*mi);
const TargetInstrDesc &TID = mi->getDesc();
bool FirstTied = true;
@ -1110,5 +1123,60 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
VReg = ReMatRegs.find_next(VReg);
}
// Eliminate REG_SEQUENCE instructions. Their whole purpose was to preseve
// SSA form. It's now safe to de-SSA.
MadeChange |= EliminateRegSequences();
return MadeChange;
}
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 part
/// of the 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 TwoAddressInstructionPass::EliminateRegSequences() {
if (RegSequences.empty())
return false;
for (unsigned i = 0, e = RegSequences.size(); i != e; ++i) {
MachineInstr *MI = RegSequences[i];
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);
}
DEBUG(dbgs() << "Eliminated: " << *MI);
MI->eraseFromParent();
}
return true;
}