Implement automatically updated def/use lists for all MachineInstr register

operands.  The lists are currently kept in MachineRegisterInfo, but it does
not yet provide an iterator interface to them.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45477 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2008-01-01 01:12:31 +00:00
parent 264e6fec9f
commit 62ed6b9ade
6 changed files with 438 additions and 58 deletions

View File

@ -45,6 +45,7 @@ class MachineInstr {
// Intrusive list support
friend struct ilist_traits<MachineInstr>;
friend struct ilist_traits<MachineBasicBlock>;
void setParent(MachineBasicBlock *P) { Parent = P; }
public:
/// MachineInstr ctor - This constructor creates a dummy MachineInstr with
@ -154,27 +155,14 @@ public:
void dump() const;
//===--------------------------------------------------------------------===//
// Accessors to add operands when building up machine instructions.
//
void addOperand(const MachineOperand &Op) {
bool isImpReg = Op.isRegister() && Op.isImplicit();
assert((isImpReg || !OperandsComplete()) &&
"Trying to add an operand to a machine instr that is already done!");
if (isImpReg || NumImplicitOps == 0) {// This is true most of the time.
Operands.push_back(Op);
Operands.back().ParentMI = this;
} else {
// Insert a real operand before any implicit ones.
unsigned OpNo = Operands.size()-NumImplicitOps;
Operands.insert(Operands.begin()+OpNo, Op);
Operands[OpNo].ParentMI = this;
}
}
//===--------------------------------------------------------------------===//
// Accessors used to modify instructions in place.
//
// Accessors used to build up machine instructions.
/// 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
/// (before the first implicit operand).
void addOperand(const MachineOperand &Op);
/// setInstrDescriptor - Replace the instruction descriptor (thus opcode) of
/// the current instruction with a new one.
///
@ -183,14 +171,27 @@ public:
/// RemoveOperand - Erase an operand from an instruction, leaving it with one
/// fewer operand than it started with.
///
void RemoveOperand(unsigned i) {
Operands.erase(Operands.begin()+i);
}
void RemoveOperand(unsigned i);
private:
/// getRegInfo - If this instruction is embedded into a MachineFunction,
/// return the MachineRegisterInfo object for the current function, otherwise
/// return null.
MachineRegisterInfo *getRegInfo();
/// addImplicitDefUseOperands - Add all implicit def and use operands to
/// this instruction.
void addImplicitDefUseOperands();
/// 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();
/// 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);
};
//===----------------------------------------------------------------------===//

View File

@ -25,6 +25,7 @@ class MachineBasicBlock;
class GlobalValue;
class MachineInstr;
class TargetMachine;
class MachineRegisterInfo;
/// MachineOperand class - Representation of each machine instruction operand.
///
@ -76,8 +77,13 @@ private:
/// Contents union - This contains the payload for the various operand types.
union {
MachineBasicBlock *MBB; // For MO_MachineBasicBlock.
unsigned RegNo; // For MO_Register.
int64_t ImmVal; // For MO_Immediate.
struct { // For MO_Register.
unsigned RegNo;
MachineOperand **Prev; // Access list for register.
MachineOperand *Next;
} Reg;
/// OffsetedInfo - This struct contains the offset and an object identifier.
/// this represent the object as with an optional offset from it.
@ -92,7 +98,6 @@ private:
} Contents;
MachineOperand(MachineOperandType K) : OpKind(K), ParentMI(0) {}
public:
MachineOperand(const MachineOperand &M) {
*this = M;
@ -138,7 +143,7 @@ public:
/// getReg - Returns the register number.
unsigned getReg() const {
assert(isRegister() && "This is not a register operand!");
return Contents.RegNo;
return Contents.Reg.RegNo;
}
unsigned getSubReg() const {
@ -175,11 +180,10 @@ public:
// Mutators for Register Operands
//===--------------------------------------------------------------------===//
void setReg(unsigned Reg) {
assert(isRegister() && "This is not a register operand!");
Contents.RegNo = Reg;
}
/// Change the register this operand corresponds to.
///
void setReg(unsigned Reg);
void setSubReg(unsigned subReg) {
assert(isRegister() && "Wrong MachineOperand accessor");
SubReg = (unsigned char)subReg;
@ -284,24 +288,13 @@ public:
/// ChangeToImmediate - Replace this operand with a new immediate operand of
/// the specified value. If an operand is known to be an immediate already,
/// the setImm method should be used.
void ChangeToImmediate(int64_t ImmVal) {
OpKind = MO_Immediate;
Contents.ImmVal = ImmVal;
}
void ChangeToImmediate(int64_t ImmVal);
/// ChangeToRegister - Replace this operand with a new register operand of
/// the specified value. If an operand is known to be an register already,
/// the setReg method should be used.
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
bool isKill = false, bool isDead = false) {
OpKind = MO_Register;
Contents.RegNo = Reg;
IsDef = isDef;
IsImp = isImp;
IsKill = isKill;
IsDead = isDead;
SubReg = 0;
}
bool isKill = false, bool isDead = false);
//===--------------------------------------------------------------------===//
// Construction methods.
@ -321,7 +314,9 @@ public:
Op.IsImp = isImp;
Op.IsKill = isKill;
Op.IsDead = isDead;
Op.Contents.RegNo = Reg;
Op.Contents.Reg.RegNo = Reg;
Op.Contents.Reg.Prev = 0;
Op.Contents.Reg.Next = 0;
Op.SubReg = SubReg;
return Op;
}
@ -371,6 +366,37 @@ public:
}
friend class MachineInstr;
friend class MachineRegisterInfo;
private:
//===--------------------------------------------------------------------===//
// Methods for handling register use/def lists.
//===--------------------------------------------------------------------===//
/// isOnRegUseList - Return true if this operand is on a register use/def list
/// or false if not. This can only be called for register operands that are
/// part of a machine instruction.
bool isOnRegUseList() const {
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);
void RemoveRegOperandFromRegInfo() {
assert(isOnRegUseList() && "Can only add reg operand to use lists");
// 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;
}
};
inline std::ostream &operator<<(std::ostream &OS, const MachineOperand &MO) {

View File

@ -26,7 +26,14 @@ class MachineRegisterInfo {
/// VRegInfo - Information we keep for each virtual register. The entries in
/// this vector are actually converted to vreg numbers by adding the
/// MRegisterInfo::FirstVirtualRegister delta to their index.
std::vector<const TargetRegisterClass*> VRegInfo;
///
/// Each element in this list contains the register class of the vreg and the
/// start of the use/def list for the register.
std::vector<std::pair<const TargetRegisterClass*, MachineOperand*> > VRegInfo;
/// PhysRegUseDefLists - This is an array of the head of the use/def list for
/// physical registers.
MachineOperand **PhysRegUseDefLists;
/// UsedPhysRegs - This is a bit vector that is computed and set by the
/// register allocator, and must be kept up to date by passes that run after
@ -42,8 +49,21 @@ class MachineRegisterInfo {
/// stored in the second element.
std::vector<std::pair<unsigned, unsigned> > LiveIns;
std::vector<unsigned> LiveOuts;
MachineRegisterInfo(const MachineRegisterInfo&); // DO NOT IMPLEMENT
void operator=(const MachineRegisterInfo&); // DO NOT IMPLEMENT
public:
MachineRegisterInfo(const MRegisterInfo &MRI);
~MachineRegisterInfo();
/// getRegUseDefListHead - Return the head pointer for the register use/def
/// list for the specified virtual or physical register.
MachineOperand *&getRegUseDefListHead(unsigned RegNo) {
if (RegNo < MRegisterInfo::FirstVirtualRegister)
return PhysRegUseDefLists[RegNo];
RegNo -= MRegisterInfo::FirstVirtualRegister;
return VRegInfo[RegNo].second;
}
//===--------------------------------------------------------------------===//
@ -54,15 +74,23 @@ public:
const TargetRegisterClass *getRegClass(unsigned Reg) {
Reg -= MRegisterInfo::FirstVirtualRegister;
assert(Reg < VRegInfo.size() && "Invalid vreg!");
return VRegInfo[Reg];
return VRegInfo[Reg].first;
}
/// createVirtualRegister - Create and return a new virtual register in the
/// function with the specified register class.
///
unsigned createVirtualRegister(const TargetRegisterClass *RegClass) {
assert(RegClass && "Cannot create register without RegClass!");
VRegInfo.push_back(RegClass);
// Add a reg, but keep track of whether the vector reallocated or not.
void *ArrayBase = &VRegInfo[0];
VRegInfo.push_back(std::make_pair(RegClass, (MachineOperand*)0));
if (&VRegInfo[0] == ArrayBase)
return getLastVirtReg();
// Otherwise, the vector reallocated, handle this now.
HandleVRegListReallocation();
return getLastVirtReg();
}
@ -111,6 +139,8 @@ public:
liveout_iterator liveout_begin() const { return LiveOuts.begin(); }
liveout_iterator liveout_end() const { return LiveOuts.end(); }
bool liveout_empty() const { return LiveOuts.empty(); }
private:
void HandleVRegListReallocation();
};
} // End llvm namespace