Pass "earlyclobber" bit through to machine

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



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56161 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dale Johannesen 2008-09-12 17:49:03 +00:00
parent f5aeb1a8e4
commit 913d3dfac4
4 changed files with 42 additions and 7 deletions

View File

@ -68,6 +68,13 @@ private:
/// This is only valid on definitions of registers. /// This is only valid on definitions of registers.
bool IsDead : 1; 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 /// SubReg - Subregister number, only valid for MO_Register. A value of 0
/// indicates the MO_Register has no subReg. /// indicates the MO_Register has no subReg.
unsigned char SubReg; unsigned char SubReg;
@ -181,6 +188,11 @@ public:
return IsKill; return IsKill;
} }
bool isEarlyClobber() const {
assert(isRegister() && "Wrong MachineOperand accessor");
return IsEarlyClobber;
}
/// 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 {
@ -226,6 +238,10 @@ public:
IsDead = Val; IsDead = Val;
} }
void setIsEarlyClobber(bool Val = true) {
assert(isRegister() && IsDef && "Wrong MachineOperand accessor");
IsEarlyClobber = Val;
}
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Accessors for various operand types. // Accessors for various operand types.
@ -311,7 +327,8 @@ public:
/// the specified value. If an operand is known to be an register already, /// the specified value. If an operand is known to be an register already,
/// the setReg method should be used. /// the setReg method should be used.
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false, 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. // Construction methods.
@ -331,12 +348,14 @@ public:
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp = false, static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp = false,
bool isKill = false, bool isDead = false, bool isKill = false, bool isDead = false,
unsigned SubReg = 0) { unsigned SubReg = 0,
bool isEarlyClobber = false) {
MachineOperand Op(MachineOperand::MO_Register); MachineOperand Op(MachineOperand::MO_Register);
Op.IsDef = isDef; Op.IsDef = isDef;
Op.IsImp = isImp; Op.IsImp = isImp;
Op.IsKill = isKill; Op.IsKill = isKill;
Op.IsDead = isDead; Op.IsDead = isDead;
Op.IsEarlyClobber = isEarlyClobber;
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;
@ -382,6 +401,7 @@ public:
IsImp = MO.IsImp; IsImp = MO.IsImp;
IsKill = MO.IsKill; IsKill = MO.IsKill;
IsDead = MO.IsDead; IsDead = MO.IsDead;
IsEarlyClobber = MO.IsEarlyClobber;
SubReg = MO.SubReg; SubReg = MO.SubReg;
ParentMI = MO.ParentMI; ParentMI = MO.ParentMI;
Contents = MO.Contents; 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 specified value. If an operand is known to be an register already,
/// the setReg method should be used. /// the setReg method should be used.
void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp, 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 // If this operand is already a register operand, use setReg to update the
// register's use/def lists. // register's use/def lists.
if (isReg()) { if (isReg()) {
@ -126,6 +127,7 @@ void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
IsImp = isImp; IsImp = isImp;
IsKill = isKill; IsKill = isKill;
IsDead = isDead; IsDead = isDead;
IsEarlyClobber = isEarlyClobber;
SubReg = 0; SubReg = 0;
} }
@ -181,13 +183,15 @@ void MachineOperand::print(std::ostream &OS, const TargetMachine *TM) const {
OS << "%mreg" << getReg(); OS << "%mreg" << getReg();
} }
if (isDef() || isKill() || isDead() || isImplicit()) { if (isDef() || isKill() || isDead() || isImplicit() || isEarlyClobber()) {
OS << "<"; OS << "<";
bool NeedComma = false; bool NeedComma = false;
if (isImplicit()) { if (isImplicit()) {
OS << (isDef() ? "imp-def" : "imp-use"); OS << (isDef() ? "imp-def" : "imp-use");
NeedComma = true; NeedComma = true;
} else if (isDef()) { } else if (isDef()) {
if (isEarlyClobber())
OS << "earlyclobber,";
OS << "def"; OS << "def";
NeedComma = true; NeedComma = true;
} }

View File

@ -592,6 +592,13 @@ void ScheduleDAG::EmitNode(SDNode *Node, bool IsClone,
MI->addOperand(MachineOperand::CreateReg(Reg, true)); MI->addOperand(MachineOperand::CreateReg(Reg, true));
} }
break; 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 1: // Use of register.
case 3: // Immediate. case 3: // Immediate.
case 4: // Addressing mode. 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 // Add information to the INLINEASM node to know that this register is
// set. // set.
OpInfo.AssignedRegs.AddInlineAsmOperands(2 /*REGDEF*/, DAG, OpInfo.AssignedRegs.AddInlineAsmOperands(OpInfo.isEarlyClobber ?
AsmNodeOperands); 6 /* EARLYCLOBBER REGDEF */ :
2 /* REGDEF */ ,
DAG, AsmNodeOperands);
break; break;
} }
case InlineAsm::isInput: { case InlineAsm::isInput: {
@ -4959,6 +4961,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
unsigned NumOps = unsigned NumOps =
cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue(); cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue();
assert(((NumOps & 7) == 2 /*REGDEF*/ || assert(((NumOps & 7) == 2 /*REGDEF*/ ||
(NumOps & 7) == 6 /*EARLYCLOBBER REGDEF*/ ||
(NumOps & 7) == 4 /*MEM*/) && (NumOps & 7) == 4 /*MEM*/) &&
"Skipped past definitions?"); "Skipped past definitions?");
CurOp += (NumOps>>3)+1; CurOp += (NumOps>>3)+1;
@ -4966,7 +4969,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
unsigned NumOps = unsigned NumOps =
cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue(); 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. // Add NumOps>>3 registers to MatchedRegs.
RegsForValue MatchedRegs; RegsForValue MatchedRegs;
MatchedRegs.TLI = &TLI; MatchedRegs.TLI = &TLI;