forked from OSchip/llvm-project
Add a Debug bit to MachineOperand, for uses that
are from debug info. Add an iterator to MachineRegisterInfo to skip Debug operands when walking the use list. No functional change yet. llvm-svn: 95473
This commit is contained in:
parent
0da714a3e2
commit
0a741b7258
|
@ -32,6 +32,7 @@ namespace RegState {
|
||||||
Dead = 0x10,
|
Dead = 0x10,
|
||||||
Undef = 0x20,
|
Undef = 0x20,
|
||||||
EarlyClobber = 0x40,
|
EarlyClobber = 0x40,
|
||||||
|
Debug = 0x80,
|
||||||
ImplicitDefine = Implicit | Define,
|
ImplicitDefine = Implicit | Define,
|
||||||
ImplicitKill = Implicit | Kill
|
ImplicitKill = Implicit | Kill
|
||||||
};
|
};
|
||||||
|
@ -62,7 +63,8 @@ public:
|
||||||
flags & RegState::Dead,
|
flags & RegState::Dead,
|
||||||
flags & RegState::Undef,
|
flags & RegState::Undef,
|
||||||
flags & RegState::EarlyClobber,
|
flags & RegState::EarlyClobber,
|
||||||
SubReg));
|
SubReg,
|
||||||
|
flags & RegState::Debug));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,10 @@ private:
|
||||||
/// model the GCC inline asm '&' constraint modifier.
|
/// model the GCC inline asm '&' constraint modifier.
|
||||||
bool IsEarlyClobber : 1;
|
bool IsEarlyClobber : 1;
|
||||||
|
|
||||||
|
/// IsDebug - True if this MO_Register 'use' operand is in a debug pseudo,
|
||||||
|
/// not a real instruction. Such uses should be ignored during codegen.
|
||||||
|
bool IsDebug : 1;
|
||||||
|
|
||||||
/// ParentMI - This is the instruction that this operand is embedded into.
|
/// ParentMI - This is the instruction that this operand is embedded into.
|
||||||
/// This is valid for all operand types, when the operand is in an instr.
|
/// This is valid for all operand types, when the operand is in an instr.
|
||||||
MachineInstr *ParentMI;
|
MachineInstr *ParentMI;
|
||||||
|
@ -214,6 +218,12 @@ public:
|
||||||
return IsEarlyClobber;
|
return IsEarlyClobber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isDebug() const {
|
||||||
|
assert(isReg() && "Wrong MachineOperand accessor");
|
||||||
|
assert(!isDef() && "Wrong MachineOperand accessor");
|
||||||
|
return IsDebug;
|
||||||
|
}
|
||||||
|
|
||||||
/// getNextOperandForReg - Return the next MachineOperand in the function that
|
/// getNextOperandForReg - Return the next MachineOperand in the function that
|
||||||
/// uses or defines this register.
|
/// uses or defines this register.
|
||||||
MachineOperand *getNextOperandForReg() const {
|
MachineOperand *getNextOperandForReg() const {
|
||||||
|
@ -388,7 +398,8 @@ public:
|
||||||
bool isKill = false, bool isDead = false,
|
bool isKill = false, bool isDead = false,
|
||||||
bool isUndef = false,
|
bool isUndef = false,
|
||||||
bool isEarlyClobber = false,
|
bool isEarlyClobber = false,
|
||||||
unsigned SubReg = 0) {
|
unsigned SubReg = 0,
|
||||||
|
bool isDebug = false) {
|
||||||
MachineOperand Op(MachineOperand::MO_Register);
|
MachineOperand Op(MachineOperand::MO_Register);
|
||||||
Op.IsDef = isDef;
|
Op.IsDef = isDef;
|
||||||
Op.IsImp = isImp;
|
Op.IsImp = isImp;
|
||||||
|
@ -396,6 +407,7 @@ public:
|
||||||
Op.IsDead = isDead;
|
Op.IsDead = isDead;
|
||||||
Op.IsUndef = isUndef;
|
Op.IsUndef = isUndef;
|
||||||
Op.IsEarlyClobber = isEarlyClobber;
|
Op.IsEarlyClobber = isEarlyClobber;
|
||||||
|
Op.IsDebug = isDebug;
|
||||||
Op.Contents.Reg.RegNo = Reg;
|
Op.Contents.Reg.RegNo = Reg;
|
||||||
Op.Contents.Reg.Prev = 0;
|
Op.Contents.Reg.Prev = 0;
|
||||||
Op.Contents.Reg.Next = 0;
|
Op.Contents.Reg.Next = 0;
|
||||||
|
|
|
@ -78,12 +78,12 @@ public:
|
||||||
/// reg_begin/reg_end - Provide iteration support to walk over all definitions
|
/// reg_begin/reg_end - Provide iteration support to walk over all definitions
|
||||||
/// and uses of a register within the MachineFunction that corresponds to this
|
/// and uses of a register within the MachineFunction that corresponds to this
|
||||||
/// MachineRegisterInfo object.
|
/// MachineRegisterInfo object.
|
||||||
template<bool Uses, bool Defs>
|
template<bool Uses, bool Defs, bool SkipDebug>
|
||||||
class defusechain_iterator;
|
class defusechain_iterator;
|
||||||
|
|
||||||
/// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified
|
/// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified
|
||||||
/// register.
|
/// register.
|
||||||
typedef defusechain_iterator<true,true> reg_iterator;
|
typedef defusechain_iterator<true,true,false> reg_iterator;
|
||||||
reg_iterator reg_begin(unsigned RegNo) const {
|
reg_iterator reg_begin(unsigned RegNo) const {
|
||||||
return reg_iterator(getRegUseDefListHead(RegNo));
|
return reg_iterator(getRegUseDefListHead(RegNo));
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ public:
|
||||||
bool reg_empty(unsigned RegNo) const { return reg_begin(RegNo) == reg_end(); }
|
bool reg_empty(unsigned RegNo) const { return reg_begin(RegNo) == reg_end(); }
|
||||||
|
|
||||||
/// def_iterator/def_begin/def_end - Walk all defs of the specified register.
|
/// def_iterator/def_begin/def_end - Walk all defs of the specified register.
|
||||||
typedef defusechain_iterator<false,true> def_iterator;
|
typedef defusechain_iterator<false,true,false> def_iterator;
|
||||||
def_iterator def_begin(unsigned RegNo) const {
|
def_iterator def_begin(unsigned RegNo) const {
|
||||||
return def_iterator(getRegUseDefListHead(RegNo));
|
return def_iterator(getRegUseDefListHead(RegNo));
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ public:
|
||||||
bool def_empty(unsigned RegNo) const { return def_begin(RegNo) == def_end(); }
|
bool def_empty(unsigned RegNo) const { return def_begin(RegNo) == def_end(); }
|
||||||
|
|
||||||
/// use_iterator/use_begin/use_end - Walk all uses of the specified register.
|
/// use_iterator/use_begin/use_end - Walk all uses of the specified register.
|
||||||
typedef defusechain_iterator<true,false> use_iterator;
|
typedef defusechain_iterator<true,false,false> use_iterator;
|
||||||
use_iterator use_begin(unsigned RegNo) const {
|
use_iterator use_begin(unsigned RegNo) const {
|
||||||
return use_iterator(getRegUseDefListHead(RegNo));
|
return use_iterator(getRegUseDefListHead(RegNo));
|
||||||
}
|
}
|
||||||
|
@ -115,6 +115,19 @@ public:
|
||||||
/// register.
|
/// register.
|
||||||
bool use_empty(unsigned RegNo) const { return use_begin(RegNo) == use_end(); }
|
bool use_empty(unsigned RegNo) const { return use_begin(RegNo) == use_end(); }
|
||||||
|
|
||||||
|
/// use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the
|
||||||
|
/// specified register, skipping those marked as Debug.
|
||||||
|
typedef defusechain_iterator<true,false,true> use_nodbg_iterator;
|
||||||
|
use_nodbg_iterator use_nodbg_begin(unsigned RegNo) const {
|
||||||
|
return use_nodbg_iterator(getRegUseDefListHead(RegNo));
|
||||||
|
}
|
||||||
|
static use_nodbg_iterator use_nodbg_end() { return use_nodbg_iterator(0); }
|
||||||
|
|
||||||
|
/// use_nodbg_empty - Return true if there are no non-Debug instructions
|
||||||
|
/// using the specified register.
|
||||||
|
bool use_nodbg_empty(unsigned RegNo) const {
|
||||||
|
return use_nodbg_begin(RegNo) == use_nodbg_end();
|
||||||
|
}
|
||||||
|
|
||||||
/// replaceRegWith - Replace all instances of FromReg with ToReg in the
|
/// replaceRegWith - Replace all instances of FromReg with ToReg in the
|
||||||
/// machine function. This is like llvm-level X->replaceAllUsesWith(Y),
|
/// machine function. This is like llvm-level X->replaceAllUsesWith(Y),
|
||||||
|
@ -258,8 +271,9 @@ public:
|
||||||
/// operands in the function that use or define a specific register. If
|
/// operands in the function that use or define a specific register. If
|
||||||
/// ReturnUses is true it returns uses of registers, if ReturnDefs is true it
|
/// ReturnUses is true it returns uses of registers, if ReturnDefs is true it
|
||||||
/// returns defs. If neither are true then you are silly and it always
|
/// returns defs. If neither are true then you are silly and it always
|
||||||
/// returns end().
|
/// returns end(). If SkipDebug is true it skips uses marked Debug
|
||||||
template<bool ReturnUses, bool ReturnDefs>
|
/// when incrementing.
|
||||||
|
template<bool ReturnUses, bool ReturnDefs, bool SkipDebug>
|
||||||
class defusechain_iterator
|
class defusechain_iterator
|
||||||
: public std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t> {
|
: public std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t> {
|
||||||
MachineOperand *Op;
|
MachineOperand *Op;
|
||||||
|
@ -268,7 +282,8 @@ public:
|
||||||
// we are interested in.
|
// we are interested in.
|
||||||
if (op) {
|
if (op) {
|
||||||
if ((!ReturnUses && op->isUse()) ||
|
if ((!ReturnUses && op->isUse()) ||
|
||||||
(!ReturnDefs && op->isDef()))
|
(!ReturnDefs && op->isDef()) ||
|
||||||
|
(SkipDebug && op->isDebug()))
|
||||||
++*this;
|
++*this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -299,7 +314,8 @@ public:
|
||||||
|
|
||||||
// If this is an operand we don't care about, skip it.
|
// If this is an operand we don't care about, skip it.
|
||||||
while (Op && ((!ReturnUses && Op->isUse()) ||
|
while (Op && ((!ReturnUses && Op->isUse()) ||
|
||||||
(!ReturnDefs && Op->isDef())))
|
(!ReturnDefs && Op->isDef()) ||
|
||||||
|
(SkipDebug && Op->isDebug())))
|
||||||
Op = Op->getNextOperandForReg();
|
Op = Op->getNextOperandForReg();
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
|
Loading…
Reference in New Issue