mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-16 16:16:45 +00:00
Allow <undef> flags on def operands as well as uses.
The <undef> flag says that a MachineOperand doesn't read its register, or doesn't depend on the previous value of its register. A full register def never depends on the previous register value. A partial register def may depend on the previous value if it is intended to update part of a register. For example: %vreg10:dsub_0<def,undef> = COPY %vreg1 %vreg10:dsub_1<def> = COPY %vreg2 The first copy instruction defines the full %vreg10 register with the bits not covered by dsub_0 defined as <undef>. It is not considered a read of %vreg10. The second copy modifies part of %vreg10 while preserving the rest. It has an implicit read of %vreg10. This patch adds a MachineOperand::readsReg() method to determine if an operand reads its register. Previously, this was modelled by adding a full-register <imp-def> operand to the instruction. This approach makes it possible to determine directly from a MachineOperand if it reads its register. No scanning of MI operands is required. llvm-svn: 141124
This commit is contained in:
parent
386f7cb041
commit
a6045464c8
@ -83,8 +83,23 @@ private:
|
||||
/// This is only valid on definitions of registers.
|
||||
bool IsDead : 1;
|
||||
|
||||
/// IsUndef - True if this is a register def / use of "undef", i.e. register
|
||||
/// defined by an IMPLICIT_DEF. This is only valid on registers.
|
||||
/// IsUndef - True if this register operand reads an "undef" value, i.e. the
|
||||
/// read value doesn't matter. This flag can be set on both use and def
|
||||
/// operands. On a sub-register def operand, it refers to the part of the
|
||||
/// register that isn't written. On a full-register def operand, it is a
|
||||
/// noop. See readsReg().
|
||||
///
|
||||
/// This is only valid on registers.
|
||||
///
|
||||
/// Note that an instruction may have multiple <undef> operands referring to
|
||||
/// the same register. In that case, the instruction may depend on those
|
||||
/// operands reading the same dont-care value. For example:
|
||||
///
|
||||
/// %vreg1<def> = XOR %vreg2<undef>, %vreg2<undef>
|
||||
///
|
||||
/// Any register can be used for %vreg2, and its value doesn't matter, but
|
||||
/// the two operands must be the same register.
|
||||
///
|
||||
bool IsUndef : 1;
|
||||
|
||||
/// IsEarlyClobber - True if this MO_Register 'def' operand is written to
|
||||
@ -253,6 +268,15 @@ public:
|
||||
return IsDebug;
|
||||
}
|
||||
|
||||
/// readsReg - Returns true if this operand reads the previous value of its
|
||||
/// register. A use operand with the <undef> flag set doesn't read its
|
||||
/// register. A sub-register def implicitly reads the other parts of the
|
||||
/// register being redefined unless the <undef> flag is set.
|
||||
bool readsReg() const {
|
||||
assert(isReg() && "Wrong MachineOperand accessor");
|
||||
return !isUndef() && (isUse() || getSubReg());
|
||||
}
|
||||
|
||||
/// getNextOperandForReg - Return the next MachineOperand in the function that
|
||||
/// uses or defines this register.
|
||||
MachineOperand *getNextOperandForReg() const {
|
||||
|
@ -304,8 +304,15 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||
|
||||
// Make sure the first definition is not a partial redefinition. Add an
|
||||
// <imp-def> of the full register.
|
||||
if (MO.getSubReg())
|
||||
if (MO.getSubReg()) {
|
||||
mi->addRegisterDefined(interval.reg);
|
||||
// Mark all defs of interval.reg on this instruction as reading <undef>.
|
||||
for (unsigned i = MOIdx, e = mi->getNumOperands(); i != e; ++i) {
|
||||
MachineOperand &MO2 = mi->getOperand(i);
|
||||
if (MO2.isReg() && MO2.getReg() == interval.reg && MO2.getSubReg())
|
||||
MO2.setIsUndef();
|
||||
}
|
||||
}
|
||||
|
||||
MachineInstr *CopyMI = NULL;
|
||||
if (mi->isCopyLike()) {
|
||||
|
Loading…
Reference in New Issue
Block a user