mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-25 13:35:10 +00:00
Add MachineRegisterInfo::moveOperands().
This function works like memmove() for MachineOperands, except it also updates any use-def chains containing the moved operands. The use-def chains are updated without affecting the order of operands in the list. That isn't possible when using the removeRegOperandFromUseList() and addRegOperandToUseList() functions. Callers to follow soon. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171597 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
64e407be0d
commit
bced5cd924
@ -156,6 +156,9 @@ public:
|
||||
// Strictly for use by MachineInstr.cpp.
|
||||
void removeRegOperandFromUseList(MachineOperand *MO);
|
||||
|
||||
// Strictly for use by MachineInstr.cpp.
|
||||
void moveOperands(MachineOperand *Dst, MachineOperand *Src, unsigned NumOps);
|
||||
|
||||
/// 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.
|
||||
|
@ -180,6 +180,55 @@ void MachineRegisterInfo::removeRegOperandFromUseList(MachineOperand *MO) {
|
||||
MO->Contents.Reg.Next = 0;
|
||||
}
|
||||
|
||||
/// Move NumOps operands from Src to Dst, updating use-def lists as needed.
|
||||
///
|
||||
/// The Dst range is assumed to be uninitialized memory. (Or it may contain
|
||||
/// operands that won't be destroyed, which is OK because the MO destructor is
|
||||
/// trivial anyway).
|
||||
///
|
||||
/// The Src and Dst ranges may overlap.
|
||||
void MachineRegisterInfo::moveOperands(MachineOperand *Dst,
|
||||
MachineOperand *Src,
|
||||
unsigned NumOps) {
|
||||
assert(Src != Dst && NumOps && "Noop moveOperands");
|
||||
|
||||
// Copy backwards if Dst is within the Src range.
|
||||
int Stride = 1;
|
||||
if (Dst >= Src && Dst < Src + NumOps) {
|
||||
Stride = -1;
|
||||
Dst += NumOps - 1;
|
||||
Src += NumOps - 1;
|
||||
}
|
||||
|
||||
// Copy one operand at a time.
|
||||
do {
|
||||
new (Dst) MachineOperand(*Src);
|
||||
|
||||
// Dst takes Src's place in the use-def chain.
|
||||
if (Src->isReg()) {
|
||||
MachineOperand *&Head = getRegUseDefListHead(Src->getReg());
|
||||
MachineOperand *Prev = Src->Contents.Reg.Prev;
|
||||
MachineOperand *Next = Src->Contents.Reg.Next;
|
||||
assert(Head && "List empty, but operand is chained");
|
||||
assert(Prev && "Operand was not on use-def list");
|
||||
|
||||
// Prev links are circular, next link is NULL instead of looping back to
|
||||
// Head.
|
||||
if (Src == Head)
|
||||
Head = Dst;
|
||||
else
|
||||
Prev->Contents.Reg.Next = Dst;
|
||||
|
||||
// Update Prev pointer. This also works when Src was pointing to itself
|
||||
// in a 1-element list. In that case Head == Dst.
|
||||
(Next ? Next : Head)->Contents.Reg.Prev = Dst;
|
||||
}
|
||||
|
||||
Dst += Stride;
|
||||
Src += Stride;
|
||||
} while (--NumOps);
|
||||
}
|
||||
|
||||
/// 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.
|
||||
|
Loading…
Reference in New Issue
Block a user