summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-08-09 22:49:37 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-08-09 22:49:37 +0000
commitff2b99afc8cbc6cfa73181072888e0f9f07deb7e (patch)
tree05569eb1e6e4b27731f81088a79f4290d3cf4ac5
parentdf1c637ac4b6f6587c037be55cafed665c732d8f (diff)
downloadllvm-ff2b99afc8cbc6cfa73181072888e0f9f07deb7e.tar.gz
llvm-ff2b99afc8cbc6cfa73181072888e0f9f07deb7e.tar.bz2
llvm-ff2b99afc8cbc6cfa73181072888e0f9f07deb7e.tar.xz
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
-rw-r--r--include/llvm/CodeGen/MachineInstr.h4
-rw-r--r--include/llvm/CodeGen/MachineOperand.h9
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h34
-rw-r--r--lib/CodeGen/MachineBasicBlock.cpp3
-rw-r--r--lib/CodeGen/MachineInstr.cpp107
-rw-r--r--lib/CodeGen/MachineRegisterInfo.cpp37
6 files changed, 92 insertions, 102 deletions
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index 30433a20f5..4c5eb8b36f 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -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.
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index d46101884c..0cde75d1df 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -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) {
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index aad79f624b..0fac1a85bb 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -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.
diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp
index f361d1ac29..151b402168 100644
--- a/lib/CodeGen/MachineBasicBlock.cpp
+++ b/lib/CodeGen/MachineBasicBlock.cpp
@@ -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);
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp
index 131fdc898a..9dd8e78618 100644
--- a/lib/CodeGen/MachineInstr.cpp
+++ b/lib/CodeGen/MachineInstr.cpp
@@ -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]);
}
}
}
diff --git a/lib/CodeGen/MachineRegisterInfo.cpp b/lib/CodeGen/MachineRegisterInfo.cpp
index 3a4eb8c967..6d05d35d7a 100644
--- a/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/lib/CodeGen/MachineRegisterInfo.cpp
@@ -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.