Pass "earlyclobber" bit through to machine

representation; coalescer and RA need to know
about it.  No functional change.

llvm-svn: 56161
This commit is contained in:
Dale Johannesen 2008-09-12 17:49:03 +00:00
parent effb894453
commit 1f3ab86804
4 changed files with 42 additions and 7 deletions

View File

@ -68,6 +68,13 @@ private:
/// This is only valid on definitions of registers.
bool IsDead : 1;
/// IsEarlyClobber flag - this is only valid for MO_Register operands in
/// an inline asm.
/// IsEarlyClobber - True if this operand is marked earlyclobber in an
/// inline asm. See gcc doc for description of earlyclobber.
bool IsEarlyClobber : 1;
/// SubReg - Subregister number, only valid for MO_Register. A value of 0
/// indicates the MO_Register has no subReg.
unsigned char SubReg;
@ -181,6 +188,11 @@ public:
return IsKill;
}
bool isEarlyClobber() const {
assert(isRegister() && "Wrong MachineOperand accessor");
return IsEarlyClobber;
}
/// getNextOperandForReg - Return the next MachineOperand in the function that
/// uses or defines this register.
MachineOperand *getNextOperandForReg() const {
@ -226,6 +238,10 @@ public:
IsDead = Val;
}
void setIsEarlyClobber(bool Val = true) {
assert(isRegister() && IsDef && "Wrong MachineOperand accessor");
IsEarlyClobber = Val;
}
//===--------------------------------------------------------------------===//
// Accessors for various operand types.
@ -311,7 +327,8 @@ public:
/// 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);
bool isKill = false, bool isDead = false,
bool isEarlyClobber = false);
//===--------------------------------------------------------------------===//
// Construction methods.
@ -331,12 +348,14 @@ public:
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp = false,
bool isKill = false, bool isDead = false,
unsigned SubReg = 0) {
unsigned SubReg = 0,
bool isEarlyClobber = false) {
MachineOperand Op(MachineOperand::MO_Register);
Op.IsDef = isDef;
Op.IsImp = isImp;
Op.IsKill = isKill;
Op.IsDead = isDead;
Op.IsEarlyClobber = isEarlyClobber;
Op.Contents.Reg.RegNo = Reg;
Op.Contents.Reg.Prev = 0;
Op.Contents.Reg.Next = 0;
@ -382,6 +401,7 @@ public:
IsImp = MO.IsImp;
IsKill = MO.IsKill;
IsDead = MO.IsDead;
IsEarlyClobber = MO.IsEarlyClobber;
SubReg = MO.SubReg;
ParentMI = MO.ParentMI;
Contents = MO.Contents;

View File

@ -104,7 +104,8 @@ void MachineOperand::ChangeToImmediate(int64_t ImmVal) {
/// the specified value. If an operand is known to be an register already,
/// the setReg method should be used.
void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
bool isKill, bool isDead) {
bool isKill, bool isDead,
bool isEarlyClobber) {
// If this operand is already a register operand, use setReg to update the
// register's use/def lists.
if (isReg()) {
@ -126,6 +127,7 @@ void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
IsImp = isImp;
IsKill = isKill;
IsDead = isDead;
IsEarlyClobber = isEarlyClobber;
SubReg = 0;
}
@ -181,13 +183,15 @@ void MachineOperand::print(std::ostream &OS, const TargetMachine *TM) const {
OS << "%mreg" << getReg();
}
if (isDef() || isKill() || isDead() || isImplicit()) {
if (isDef() || isKill() || isDead() || isImplicit() || isEarlyClobber()) {
OS << "<";
bool NeedComma = false;
if (isImplicit()) {
OS << (isDef() ? "imp-def" : "imp-use");
NeedComma = true;
} else if (isDef()) {
if (isEarlyClobber())
OS << "earlyclobber,";
OS << "def";
NeedComma = true;
}

View File

@ -592,6 +592,13 @@ void ScheduleDAG::EmitNode(SDNode *Node, bool IsClone,
MI->addOperand(MachineOperand::CreateReg(Reg, true));
}
break;
case 6: // Def of earlyclobber register.
for (; NumVals; --NumVals, ++i) {
unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
MI->addOperand(MachineOperand::CreateReg(Reg, true, false, false,
false, 0, true));
}
break;
case 1: // Use of register.
case 3: // Immediate.
case 4: // Addressing mode.

View File

@ -4939,8 +4939,10 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
// Add information to the INLINEASM node to know that this register is
// set.
OpInfo.AssignedRegs.AddInlineAsmOperands(2 /*REGDEF*/, DAG,
AsmNodeOperands);
OpInfo.AssignedRegs.AddInlineAsmOperands(OpInfo.isEarlyClobber ?
6 /* EARLYCLOBBER REGDEF */ :
2 /* REGDEF */ ,
DAG, AsmNodeOperands);
break;
}
case InlineAsm::isInput: {
@ -4959,6 +4961,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
unsigned NumOps =
cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue();
assert(((NumOps & 7) == 2 /*REGDEF*/ ||
(NumOps & 7) == 6 /*EARLYCLOBBER REGDEF*/ ||
(NumOps & 7) == 4 /*MEM*/) &&
"Skipped past definitions?");
CurOp += (NumOps>>3)+1;
@ -4966,7 +4969,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
unsigned NumOps =
cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue();
if ((NumOps & 7) == 2 /*REGDEF*/) {
if ((NumOps & 7) == 2 /*REGDEF*/
|| (NumOps & 7) == 6 /* EARLYCLOBBER REGDEF */) {
// Add NumOps>>3 registers to MatchedRegs.
RegsForValue MatchedRegs;
MatchedRegs.TLI = &TLI;