mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-31 09:25:42 +00:00
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:
@@ -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;
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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.
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user