diff options
-rw-r--r-- | include/llvm/CodeGen/MachineOperand.h | 19 | ||||
-rw-r--r-- | lib/CodeGen/MachineInstr.cpp | 55 |
2 files changed, 53 insertions, 21 deletions
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index 1d3d60bdb2..594dc276b0 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -124,6 +124,14 @@ private: /// model the GCC inline asm '&' constraint modifier. bool IsEarlyClobber : 1; + /// IsTied - True if this MO_Register operand is tied to another operand on + /// the instruction. Tied operands form def-use pairs that must be assigned + /// the same physical register by the register allocator, but they will have + /// different virtual registers while the code is in SSA form. + /// + /// See MachineInstr::isRegTiedToUseOperand() and isRegTiedToDefOperand(). + bool IsTied : 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; @@ -299,6 +307,11 @@ public: return IsEarlyClobber; } + bool isTied() const { + assert(isReg() && "Wrong MachineOperand accessor"); + return IsTied; + } + bool isDebug() const { assert(isReg() && "Wrong MachineOperand accessor"); return IsDebug; @@ -377,6 +390,11 @@ public: IsEarlyClobber = Val; } + void setIsTied(bool Val = true) { + assert(isReg() && "Wrong MachineOperand accessor"); + IsTied = Val; + } + void setIsDebug(bool Val = true) { assert(isReg() && IsDef && "Wrong MachineOperand accessor"); IsDebug = Val; @@ -559,6 +577,7 @@ public: Op.IsUndef = isUndef; Op.IsInternalRead = isInternalRead; Op.IsEarlyClobber = isEarlyClobber; + Op.IsTied = false; Op.IsDebug = isDebug; Op.SmallContents.RegNo = Reg; Op.Contents.Reg.Prev = 0; diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index e1060046e2..24078f8943 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -262,7 +262,7 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { OS << PrintReg(getReg(), TRI, getSubReg()); if (isDef() || isKill() || isDead() || isImplicit() || isUndef() || - isInternalRead() || isEarlyClobber()) { + isInternalRead() || isEarlyClobber() || isTied()) { OS << '<'; bool NeedComma = false; if (isDef()) { @@ -282,27 +282,30 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { NeedComma = true; } - if (isKill() || isDead() || (isUndef() && isUse()) || isInternalRead()) { + if (isKill()) { if (NeedComma) OS << ','; - NeedComma = false; - if (isKill()) { - OS << "kill"; - NeedComma = true; - } - if (isDead()) { - OS << "dead"; - NeedComma = true; - } - if (isUndef() && isUse()) { - if (NeedComma) OS << ','; - OS << "undef"; - NeedComma = true; - } - if (isInternalRead()) { - if (NeedComma) OS << ','; - OS << "internal"; - NeedComma = true; - } + OS << "kill"; + NeedComma = true; + } + if (isDead()) { + if (NeedComma) OS << ','; + OS << "dead"; + NeedComma = true; + } + if (isUndef() && isUse()) { + if (NeedComma) OS << ','; + OS << "undef"; + NeedComma = true; + } + if (isInternalRead()) { + if (NeedComma) OS << ','; + OS << "internal"; + NeedComma = true; + } + if (isTied()) { + if (NeedComma) OS << ','; + OS << "tied"; + NeedComma = true; } OS << '>'; } @@ -711,6 +714,16 @@ void MachineInstr::addOperand(const MachineOperand &Op) { // Add the new operand to RegInfo. if (RegInfo) RegInfo->addRegOperandToUseList(&Operands[OpNo]); + // Set the IsTied bit if MC indicates this use is tied to a def. + if (Operands[OpNo].isUse()) { + int DefIdx = MCID->getOperandConstraint(OpNo, MCOI::TIED_TO); + if (DefIdx != -1) { + MachineOperand &DefMO = getOperand(DefIdx); + assert(DefMO.isDef() && "Use tied to operand that isn't a def"); + DefMO.IsTied = true; + Operands[OpNo].IsTied = true; + } + } // If the register operand is flagged as early, mark the operand as such. if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) Operands[OpNo].setIsEarlyClobber(true); |