Move use list management into MachineRegisterInfo.

Register MachineOperands are kept in linked lists accessible via MRI's
reg_iterator interfaces. The linked list management was handled partly
by MachineOperand methods, partly by MRI methods.

Move all of the list management into MRI, delete
MO::AddRegOperandToRegInfo() and MO::RemoveRegOperandFromRegInfo().

Be more explicit about handling the cases where an MRI pointer isn't
available.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161632 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2012-08-09 22:49:37 +00:00
parent df1c637ac4
commit ff2b99afc8
6 changed files with 92 additions and 102 deletions

View File

@ -936,12 +936,12 @@ private:
/// RemoveRegOperandsFromUseLists - Unlink all of the register operands in
/// this instruction from their respective use lists. This requires that the
/// operands already be on their use lists.
void RemoveRegOperandsFromUseLists();
void RemoveRegOperandsFromUseLists(MachineRegisterInfo&);
/// AddRegOperandsToUseLists - Add all of the register operands in
/// this instruction from their respective use lists. This requires that the
/// operands not be on their use lists yet.
void AddRegOperandsToUseLists(MachineRegisterInfo &RegInfo);
void AddRegOperandsToUseLists(MachineRegisterInfo&);
/// hasPropertyInBundle - Slow path for hasProperty when we're dealing with a
/// bundle.

View File

@ -666,15 +666,6 @@ private:
assert(isReg() && "Can only add reg operand to use lists");
return Contents.Reg.Prev != 0;
}
/// AddRegOperandToRegInfo - Add this register operand to the specified
/// MachineRegisterInfo. If it is null, then the next/prev fields should be
/// explicitly nulled out.
void AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo);
/// RemoveRegOperandFromRegInfo - Remove this register operand from the
/// MachineRegisterInfo it is linked with.
void RemoveRegOperandFromRegInfo();
};
inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand& MO) {

View File

@ -57,6 +57,20 @@ class MachineRegisterInfo {
/// physical registers.
MachineOperand **PhysRegUseDefLists;
/// getRegUseDefListHead - Return the head pointer for the register use/def
/// list for the specified virtual or physical register.
MachineOperand *&getRegUseDefListHead(unsigned RegNo) {
if (TargetRegisterInfo::isVirtualRegister(RegNo))
return VRegInfo[RegNo].second;
return PhysRegUseDefLists[RegNo];
}
MachineOperand *getRegUseDefListHead(unsigned RegNo) const {
if (TargetRegisterInfo::isVirtualRegister(RegNo))
return VRegInfo[RegNo].second;
return PhysRegUseDefLists[RegNo];
}
/// Get the next element in the use-def chain.
static MachineOperand *getNextOperandForReg(const MachineOperand *MO) {
assert(MO && MO->isReg() && "This is not a register operand!");
@ -135,6 +149,12 @@ public:
// Register Info
//===--------------------------------------------------------------------===//
// Strictly for use by MachineInstr.cpp.
void addRegOperandToUseList(MachineOperand *MO);
// Strictly for use by MachineInstr.cpp.
void removeRegOperandFromUseList(MachineOperand *MO);
/// reg_begin/reg_end - Provide iteration support to walk over all definitions
/// and uses of a register within the MachineFunction that corresponds to this
/// MachineRegisterInfo object.
@ -241,20 +261,6 @@ public:
/// constraints.
void replaceRegWith(unsigned FromReg, unsigned ToReg);
/// getRegUseDefListHead - Return the head pointer for the register use/def
/// list for the specified virtual or physical register.
MachineOperand *&getRegUseDefListHead(unsigned RegNo) {
if (TargetRegisterInfo::isVirtualRegister(RegNo))
return VRegInfo[RegNo].second;
return PhysRegUseDefLists[RegNo];
}
MachineOperand *getRegUseDefListHead(unsigned RegNo) const {
if (TargetRegisterInfo::isVirtualRegister(RegNo))
return VRegInfo[RegNo].second;
return PhysRegUseDefLists[RegNo];
}
/// getVRegDef - Return the machine instr that defines the specified virtual
/// register or null if none is found. This assumes that the code is in SSA
/// form, so there should only be one definition.

View File

@ -109,7 +109,8 @@ void ilist_traits<MachineInstr>::removeNodeFromList(MachineInstr *N) {
assert(N->getParent() != 0 && "machine instruction not in a basic block");
// Remove from the use/def lists.
N->RemoveRegOperandsFromUseLists();
if (MachineFunction *MF = N->getParent()->getParent())
N->RemoveRegOperandsFromUseLists(MF->getRegInfo());
N->setParent(0);

View File

@ -47,55 +47,6 @@ using namespace llvm;
// MachineOperand Implementation
//===----------------------------------------------------------------------===//
/// AddRegOperandToRegInfo - Add this register operand to the specified
/// MachineRegisterInfo. If it is null, then the next/prev fields should be
/// explicitly nulled out.
void MachineOperand::AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo) {
assert(isReg() && "Can only add reg operand to use lists");
// If the reginfo pointer is null, just explicitly null out or next/prev
// pointers, to ensure they are not garbage.
if (RegInfo == 0) {
Contents.Reg.Prev = 0;
Contents.Reg.Next = 0;
return;
}
// Otherwise, add this operand to the head of the registers use/def list.
MachineOperand **Head = &RegInfo->getRegUseDefListHead(getReg());
// For SSA values, we prefer to keep the definition at the start of the list.
// we do this by skipping over the definition if it is at the head of the
// list.
if (*Head && (*Head)->isDef())
Head = &(*Head)->Contents.Reg.Next;
Contents.Reg.Next = *Head;
if (Contents.Reg.Next) {
assert(getReg() == Contents.Reg.Next->getReg() &&
"Different regs on the same list!");
Contents.Reg.Next->Contents.Reg.Prev = &Contents.Reg.Next;
}
Contents.Reg.Prev = Head;
*Head = this;
}
/// RemoveRegOperandFromRegInfo - Remove this register operand from the
/// MachineRegisterInfo it is linked with.
void MachineOperand::RemoveRegOperandFromRegInfo() {
assert(isOnRegUseList() && "Reg operand is not on a use list");
// Unlink this from the doubly linked list of operands.
MachineOperand *NextOp = Contents.Reg.Next;
*Contents.Reg.Prev = NextOp;
if (NextOp) {
assert(NextOp->getReg() == getReg() && "Corrupt reg use/def chain!");
NextOp->Contents.Reg.Prev = Contents.Reg.Prev;
}
Contents.Reg.Prev = 0;
Contents.Reg.Next = 0;
}
void MachineOperand::setReg(unsigned Reg) {
if (getReg() == Reg) return; // No change.
@ -105,9 +56,10 @@ void MachineOperand::setReg(unsigned Reg) {
if (MachineInstr *MI = getParent())
if (MachineBasicBlock *MBB = MI->getParent())
if (MachineFunction *MF = MBB->getParent()) {
RemoveRegOperandFromRegInfo();
MachineRegisterInfo &MRI = MF->getRegInfo();
MRI.removeRegOperandFromUseList(this);
SmallContents.RegNo = Reg;
AddRegOperandToRegInfo(&MF->getRegInfo());
MRI.addRegOperandToUseList(this);
return;
}
@ -142,9 +94,11 @@ void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) {
void MachineOperand::ChangeToImmediate(int64_t ImmVal) {
// If this operand is currently a register operand, and if this is in a
// function, deregister the operand from the register's use/def list.
if (isReg() && getParent() && getParent()->getParent() &&
getParent()->getParent()->getParent())
RemoveRegOperandFromRegInfo();
if (isReg() && isOnRegUseList())
if (MachineInstr *MI = getParent())
if (MachineBasicBlock *MBB = MI->getParent())
if (MachineFunction *MF = MBB->getParent())
MF->getRegInfo().removeRegOperandFromUseList(this);
OpKind = MO_Immediate;
Contents.ImmVal = ImmVal;
@ -165,13 +119,15 @@ void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
// Otherwise, change this to a register and set the reg#.
OpKind = MO_Register;
SmallContents.RegNo = Reg;
// Ensure isOnRegUseList() returns false.
Contents.Reg.Prev = 0;
// If this operand is embedded in a function, add the operand to the
// register's use/def list.
if (MachineInstr *MI = getParent())
if (MachineBasicBlock *MBB = MI->getParent())
if (MachineFunction *MF = MBB->getParent())
AddRegOperandToRegInfo(&MF->getRegInfo());
MF->getRegInfo().addRegOperandToUseList(this);
}
IsDef = isDef;
@ -657,24 +613,21 @@ MachineRegisterInfo *MachineInstr::getRegInfo() {
/// RemoveRegOperandsFromUseLists - Unlink all of the register operands in
/// this instruction from their respective use lists. This requires that the
/// operands already be on their use lists.
void MachineInstr::RemoveRegOperandsFromUseLists() {
for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
void MachineInstr::RemoveRegOperandsFromUseLists(MachineRegisterInfo &MRI) {
for (unsigned i = 0, e = Operands.size(); i != e; ++i)
if (Operands[i].isReg())
Operands[i].RemoveRegOperandFromRegInfo();
}
MRI.removeRegOperandFromUseList(&Operands[i]);
}
/// AddRegOperandsToUseLists - Add all of the register operands in
/// this instruction from their respective use lists. This requires that the
/// operands not be on their use lists yet.
void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &RegInfo) {
for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &MRI) {
for (unsigned i = 0, e = Operands.size(); i != e; ++i)
if (Operands[i].isReg())
Operands[i].AddRegOperandToRegInfo(&RegInfo);
}
MRI.addRegOperandToUseList(&Operands[i]);
}
/// addOperand - Add the specified operand to the instruction. If it is an
/// implicit operand, it is added to the end of the operand list. If it is
/// an explicit operand it is added at the end of the explicit operand list
@ -702,7 +655,7 @@ void MachineInstr::addOperand(const MachineOperand &Op) {
while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) {
--OpNo;
if (RegInfo)
Operands[OpNo].RemoveRegOperandFromRegInfo();
RegInfo->removeRegOperandFromUseList(&Operands[OpNo]);
}
}
@ -719,7 +672,7 @@ void MachineInstr::addOperand(const MachineOperand &Op) {
if (Reallocate)
for (unsigned i = 0; i != OpNo; ++i)
if (Operands[i].isReg())
Operands[i].RemoveRegOperandFromRegInfo();
RegInfo->removeRegOperandFromUseList(&Operands[i]);
// Insert the new operand at OpNo.
Operands.insert(Operands.begin() + OpNo, Op);
@ -730,13 +683,15 @@ void MachineInstr::addOperand(const MachineOperand &Op) {
if (Reallocate)
for (unsigned i = 0; i != OpNo; ++i)
if (Operands[i].isReg())
Operands[i].AddRegOperandToRegInfo(RegInfo);
RegInfo->addRegOperandToUseList(&Operands[i]);
// When adding a register operand, tell RegInfo about it.
if (Operands[OpNo].isReg()) {
// Add the new operand to RegInfo, even when RegInfo is NULL.
// This will initialize the linked list pointers.
Operands[OpNo].AddRegOperandToRegInfo(RegInfo);
// Ensure isOnRegUseList() returns false, regardless of Op's status.
Operands[OpNo].Contents.Reg.Prev = 0;
// Add the new operand to RegInfo.
if (RegInfo)
RegInfo->addRegOperandToUseList(&Operands[OpNo]);
// If the register operand is flagged as early, mark the operand as such.
if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1)
Operands[OpNo].setIsEarlyClobber(true);
@ -746,7 +701,7 @@ void MachineInstr::addOperand(const MachineOperand &Op) {
if (RegInfo) {
for (unsigned i = OpNo + 1, e = Operands.size(); i != e; ++i) {
assert(Operands[i].isReg() && "Should only be an implicit reg!");
Operands[i].AddRegOperandToRegInfo(RegInfo);
RegInfo->addRegOperandToUseList(&Operands[i]);
}
}
}
@ -756,12 +711,13 @@ void MachineInstr::addOperand(const MachineOperand &Op) {
///
void MachineInstr::RemoveOperand(unsigned OpNo) {
assert(OpNo < Operands.size() && "Invalid operand number");
MachineRegisterInfo *RegInfo = getRegInfo();
// Special case removing the last one.
if (OpNo == Operands.size()-1) {
// If needed, remove from the reg def/use list.
if (Operands.back().isReg() && Operands.back().isOnRegUseList())
Operands.back().RemoveRegOperandFromRegInfo();
if (RegInfo && Operands.back().isReg() && Operands.back().isOnRegUseList())
RegInfo->removeRegOperandFromUseList(&Operands.back());
Operands.pop_back();
return;
@ -770,11 +726,10 @@ void MachineInstr::RemoveOperand(unsigned OpNo) {
// Otherwise, we are removing an interior operand. If we have reginfo to
// update, remove all operands that will be shifted down from their reg lists,
// move everything down, then re-add them.
MachineRegisterInfo *RegInfo = getRegInfo();
if (RegInfo) {
for (unsigned i = OpNo, e = Operands.size(); i != e; ++i) {
if (Operands[i].isReg())
Operands[i].RemoveRegOperandFromRegInfo();
RegInfo->removeRegOperandFromUseList(&Operands[i]);
}
}
@ -783,7 +738,7 @@ void MachineInstr::RemoveOperand(unsigned OpNo) {
if (RegInfo) {
for (unsigned i = OpNo, e = Operands.size(); i != e; ++i) {
if (Operands[i].isReg())
Operands[i].AddRegOperandToRegInfo(RegInfo);
RegInfo->addRegOperandToUseList(&Operands[i]);
}
}
}

View File

@ -126,6 +126,43 @@ void MachineRegisterInfo::clearVirtRegs() {
VRegInfo.clear();
}
/// Add MO to the linked list of operands for its register.
void MachineRegisterInfo::addRegOperandToUseList(MachineOperand *MO) {
assert(!MO->isOnRegUseList() && "Already on list");
MachineOperand **Head = &getRegUseDefListHead(MO->getReg());
// For SSA values, we prefer to keep the definition at the start of the list.
// we do this by skipping over the definition if it is at the head of the
// list.
if (*Head && (*Head)->isDef())
Head = &(*Head)->Contents.Reg.Next;
MO->Contents.Reg.Next = *Head;
if (MO->Contents.Reg.Next) {
assert(MO->getReg() == MO->Contents.Reg.Next->getReg() &&
"Different regs on the same list!");
MO->Contents.Reg.Next->Contents.Reg.Prev = &MO->Contents.Reg.Next;
}
MO->Contents.Reg.Prev = Head;
*Head = MO;
}
/// Remove MO from its use-def list.
void MachineRegisterInfo::removeRegOperandFromUseList(MachineOperand *MO) {
assert(MO->isOnRegUseList() && "Operand not on use list");
// Unlink this from the doubly linked list of operands.
MachineOperand *NextOp = MO->Contents.Reg.Next;
*MO->Contents.Reg.Prev = NextOp;
if (NextOp) {
assert(NextOp->getReg() == MO->getReg() && "Corrupt reg use/def chain!");
NextOp->Contents.Reg.Prev = MO->Contents.Reg.Prev;
}
MO->Contents.Reg.Prev = 0;
MO->Contents.Reg.Next = 0;
}
/// HandleVRegListReallocation - We just added a virtual register to the
/// VRegInfo info list and it reallocated. Update the use/def lists info
/// pointers.