mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-23 20:45:06 +00:00
Maintain a vaild isTied bit as operands are added and removed.
The isTied bit is set automatically when a tied use is added and MCInstrDesc indicates a tied operand. The tie is broken when one of the tied operands is removed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162814 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
14b5bac547
commit
699ac04951
@ -782,6 +782,11 @@ public:
|
||||
const TargetInstrInfo *TII,
|
||||
const TargetRegisterInfo *TRI) const;
|
||||
|
||||
/// findTiedOperandIdx - Given the index of a tied register operand, find the
|
||||
/// operand it is tied to. Defs are tied to uses and vice versa. Returns the
|
||||
/// index of the tied operand which must exist.
|
||||
unsigned findTiedOperandIdx(unsigned OpIdx) const;
|
||||
|
||||
/// isRegTiedToUseOperand - Given the index of a register def operand,
|
||||
/// check if the register def is tied to a source operand, due to either
|
||||
/// two-address elimination or inline assembly constraints. Returns the
|
||||
@ -935,6 +940,13 @@ private:
|
||||
/// return null.
|
||||
MachineRegisterInfo *getRegInfo();
|
||||
|
||||
/// untieRegOperand - Break any tie involving OpIdx.
|
||||
void untieRegOperand(unsigned OpIdx) {
|
||||
const MachineOperand &MO = getOperand(OpIdx);
|
||||
if (MO.isReg() && MO.isTied())
|
||||
getOperand(findTiedOperandIdx(OpIdx)).setIsTied(false);
|
||||
}
|
||||
|
||||
/// addImplicitDefUseOperands - Add all implicit def and use operands to
|
||||
/// this instruction.
|
||||
void addImplicitDefUseOperands();
|
||||
|
@ -111,6 +111,7 @@ void MachineOperand::setIsDef(bool Val) {
|
||||
/// the specified value. If an operand is known to be an immediate already,
|
||||
/// the setImm method should be used.
|
||||
void MachineOperand::ChangeToImmediate(int64_t ImmVal) {
|
||||
assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm");
|
||||
// If this operand is currently a register operand, and if this is in a
|
||||
// function, deregister the operand from the register's use/def list.
|
||||
if (isReg() && isOnRegUseList())
|
||||
@ -136,7 +137,8 @@ void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
|
||||
RegInfo = &MF->getRegInfo();
|
||||
// If this operand is already a register operand, remove it from the
|
||||
// register's use/def lists.
|
||||
if (RegInfo && isReg())
|
||||
bool WasReg = isReg();
|
||||
if (RegInfo && WasReg)
|
||||
RegInfo->removeRegOperandFromUseList(this);
|
||||
|
||||
// Change this to a register and set the reg#.
|
||||
@ -153,6 +155,9 @@ void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
|
||||
IsDebug = isDebug;
|
||||
// Ensure isOnRegUseList() returns false.
|
||||
Contents.Reg.Prev = 0;
|
||||
// Preserve the tie bit when the operand was already a register.
|
||||
if (!WasReg)
|
||||
IsTied = false;
|
||||
|
||||
// If this operand is embedded in a function, add the operand to the
|
||||
// register's use/def list.
|
||||
@ -711,6 +716,8 @@ void MachineInstr::addOperand(const MachineOperand &Op) {
|
||||
if (Operands[OpNo].isReg()) {
|
||||
// Ensure isOnRegUseList() returns false, regardless of Op's status.
|
||||
Operands[OpNo].Contents.Reg.Prev = 0;
|
||||
// Ignore existing IsTied bit. This is not a property that can be copied.
|
||||
Operands[OpNo].IsTied = false;
|
||||
// Add the new operand to RegInfo.
|
||||
if (RegInfo)
|
||||
RegInfo->addRegOperandToUseList(&Operands[OpNo]);
|
||||
@ -743,6 +750,7 @@ void MachineInstr::addOperand(const MachineOperand &Op) {
|
||||
///
|
||||
void MachineInstr::RemoveOperand(unsigned OpNo) {
|
||||
assert(OpNo < Operands.size() && "Invalid operand number");
|
||||
untieRegOperand(OpNo);
|
||||
MachineRegisterInfo *RegInfo = getRegInfo();
|
||||
|
||||
// Special case removing the last one.
|
||||
@ -1127,6 +1135,36 @@ int MachineInstr::findFirstPredOperandIdx() const {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// Given the index of a tied register operand, find the operand it is tied to.
|
||||
/// Defs are tied to uses and vice versa. Returns the index of the tied operand
|
||||
/// which must exist.
|
||||
unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const {
|
||||
// It doesn't usually happen, but an instruction can have multiple pairs of
|
||||
// tied operands.
|
||||
SmallVector<unsigned, 4> Uses, Defs;
|
||||
unsigned PairNo = ~0u;
|
||||
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
|
||||
const MachineOperand &MO = getOperand(i);
|
||||
if (!MO.isReg() || !MO.isTied())
|
||||
continue;
|
||||
if (MO.isUse()) {
|
||||
if (i == OpIdx)
|
||||
PairNo = Uses.size();
|
||||
Uses.push_back(i);
|
||||
} else {
|
||||
if (i == OpIdx)
|
||||
PairNo = Defs.size();
|
||||
Defs.push_back(i);
|
||||
}
|
||||
}
|
||||
// For each tied use there must be a tied def and vice versa.
|
||||
assert(Uses.size() == Defs.size() && "Tied uses and defs don't match");
|
||||
assert(PairNo < Uses.size() && "OpIdx must be a tied register operand");
|
||||
|
||||
// Find the matching operand.
|
||||
return (getOperand(OpIdx).isDef() ? Uses : Defs)[PairNo];
|
||||
}
|
||||
|
||||
/// isRegTiedToUseOperand - Given the index of a register def operand,
|
||||
/// check if the register def is tied to a source operand, due to either
|
||||
/// two-address elimination or inline assembly constraints. Returns the
|
||||
|
Loading…
Reference in New Issue
Block a user