diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-08-09 23:31:36 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-08-09 23:31:36 +0000 |
commit | 1134aae4e743290da2ad29a7ac76d3a1f9dcfce8 (patch) | |
tree | 05569eb1e6e4b27731f81088a79f4290d3cf4ac5 /lib/CodeGen | |
parent | 81a6995243380668e6f991fa4e11dd0a6e37e030 (diff) | |
download | external_llvm-1134aae4e743290da2ad29a7ac76d3a1f9dcfce8.zip external_llvm-1134aae4e743290da2ad29a7ac76d3a1f9dcfce8.tar.gz external_llvm-1134aae4e743290da2ad29a7ac76d3a1f9dcfce8.tar.bz2 |
Revert r161633-161634 "Partition use lists so defs always come before uses."
These commits broke a number of buildbots.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161640 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/MachineRegisterInfo.cpp | 92 |
1 files changed, 45 insertions, 47 deletions
diff --git a/lib/CodeGen/MachineRegisterInfo.cpp b/lib/CodeGen/MachineRegisterInfo.cpp index 5fb938f..6d05d35 100644 --- a/lib/CodeGen/MachineRegisterInfo.cpp +++ b/lib/CodeGen/MachineRegisterInfo.cpp @@ -102,9 +102,17 @@ MachineRegisterInfo::createVirtualRegister(const TargetRegisterClass *RegClass){ // New virtual register number. unsigned Reg = TargetRegisterInfo::index2VirtReg(getNumVirtRegs()); + + // Add a reg, but keep track of whether the vector reallocated or not. + const unsigned FirstVirtReg = TargetRegisterInfo::index2VirtReg(0); + void *ArrayBase = getNumVirtRegs() == 0 ? 0 : &VRegInfo[FirstVirtReg]; VRegInfo.grow(Reg); VRegInfo[Reg].first = RegClass; RegAllocHints.grow(Reg); + + if (ArrayBase && &VRegInfo[FirstVirtReg] != ArrayBase) + // The vector reallocated, handle this now. + HandleVRegListReallocation(); return Reg; } @@ -121,65 +129,55 @@ void MachineRegisterInfo::clearVirtRegs() { /// Add MO to the linked list of operands for its register. void MachineRegisterInfo::addRegOperandToUseList(MachineOperand *MO) { assert(!MO->isOnRegUseList() && "Already on list"); - MachineOperand *&HeadRef = getRegUseDefListHead(MO->getReg()); - MachineOperand *const Head = HeadRef; - - // Head points to the first list element. - // Next is NULL on the last list element. - // Prev pointers are circular, so Head->Prev == Last. - - // Head is NULL for an empty list. - if (!Head) { - MO->Contents.Reg.Prev = MO; - MO->Contents.Reg.Next = 0; - HeadRef = MO; - return; - } - assert(MO->getReg() == Head->getReg() && "Different regs on the same list!"); - - // Insert MO between Last and Head in the circular Prev chain. - MachineOperand *Last = Head->Contents.Reg.Prev; - assert(Last && "Inconsistent use list"); - assert(MO->getReg() == Last->getReg() && "Different regs on the same list!"); - Head->Contents.Reg.Prev = MO; - MO->Contents.Reg.Prev = Last; - - // Def operands always precede uses. This allows def_iterator to stop early. - // Insert def operands at the front, and use operands at the back. - if (MO->isDef()) { - // Insert def at the front. - MO->Contents.Reg.Next = Head; - HeadRef = MO; - } else { - // Insert use at the end. - MO->Contents.Reg.Next = 0; - Last->Contents.Reg.Next = MO; + 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"); - MachineOperand *&HeadRef = getRegUseDefListHead(MO->getReg()); - MachineOperand *const Head = HeadRef; - assert(Head && "List already empty"); // Unlink this from the doubly linked list of operands. - MachineOperand *Next = MO->Contents.Reg.Next; - MachineOperand *Prev = MO->Contents.Reg.Prev; - - // Prev links are circular, next link is NULL instead of looping back to Head. - if (MO == Head) - HeadRef = Next; - else - Prev->Contents.Reg.Next = Next; - - (Next ? Next : Head)->Contents.Reg.Prev = Prev; - + 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. +void MachineRegisterInfo::HandleVRegListReallocation() { + // The back pointers for the vreg lists point into the previous vector. + // Update them to point to their correct slots. + for (unsigned i = 0, e = getNumVirtRegs(); i != e; ++i) { + unsigned Reg = TargetRegisterInfo::index2VirtReg(i); + MachineOperand *List = VRegInfo[Reg].second; + if (!List) continue; + // Update the back-pointer to be accurate once more. + List->Contents.Reg.Prev = &VRegInfo[Reg].second; + } +} + /// replaceRegWith - Replace all instances of FromReg with ToReg in the /// machine function. This is like llvm-level X->replaceAllUsesWith(Y), /// except that it also changes any definitions of the register as well. |