aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/CodeGen/MachineInstr.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-12-18 20:30:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-04-06 20:11:55 +0000
commit5f757f3ff9144b609b3c433dfd370cc6bdc191ad (patch)
tree1b4e980b866cd26a00af34c0a653eb640bd09caf /contrib/llvm-project/llvm/lib/CodeGen/MachineInstr.cpp
parent3e1c8a35f741a5d114d0ba670b15191355711fe9 (diff)
parent312c0ed19cc5276a17bacf2120097bec4515b0f1 (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/MachineInstr.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/MachineInstr.cpp149
1 files changed, 117 insertions, 32 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/MachineInstr.cpp b/contrib/llvm-project/llvm/lib/CodeGen/MachineInstr.cpp
index a9309487a7a7..27eae372f8ad 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/MachineInstr.cpp
@@ -138,6 +138,12 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)
setFlags(MI.Flags);
}
+void MachineInstr::setDesc(const MCInstrDesc &TID) {
+ if (getParent())
+ getMF()->handleChangeDesc(*this, TID);
+ MCID = &TID;
+}
+
void MachineInstr::moveBefore(MachineInstr *MovePos) {
MovePos->getParent()->splice(MovePos, getParent(), getIterator());
}
@@ -225,10 +231,6 @@ void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) {
// OpNo now points as the desired insertion point. Unless this is a variadic
// instruction, only implicit regs are allowed beyond MCID->getNumOperands().
// RegMask operands go between the explicit and implicit operands.
- assert((MCID->isVariadic() || OpNo < MCID->getNumOperands() ||
- Op.isValidExcessOperand()) &&
- "Trying to add an operand to a machine instr that is already done!");
-
MachineRegisterInfo *MRI = getRegInfo();
// Determine if the Operands array needs to be reallocated.
@@ -845,7 +847,8 @@ int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx,
// If we reach the implicit register operands, stop looking.
if (!FlagMO.isImm())
return -1;
- NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm());
+ const InlineAsm::Flag F(FlagMO.getImm());
+ NumOps = 1 + F.getNumOperandRegisters();
if (i + NumOps > OpIdx) {
if (GroupNo)
*GroupNo = Group;
@@ -922,16 +925,14 @@ MachineInstr::getRegClassConstraint(unsigned OpIdx,
if (FlagIdx < 0)
return nullptr;
- unsigned Flag = getOperand(FlagIdx).getImm();
+ const InlineAsm::Flag F(getOperand(FlagIdx).getImm());
unsigned RCID;
- if ((InlineAsm::getKind(Flag) == InlineAsm::Kind_RegUse ||
- InlineAsm::getKind(Flag) == InlineAsm::Kind_RegDef ||
- InlineAsm::getKind(Flag) == InlineAsm::Kind_RegDefEarlyClobber) &&
- InlineAsm::hasRegClassConstraint(Flag, RCID))
+ if ((F.isRegUseKind() || F.isRegDefKind() || F.isRegDefEarlyClobberKind()) &&
+ F.hasRegClassConstraint(RCID))
return TRI->getRegClass(RCID);
// Assume that all registers in a memory operand are pointers.
- if (InlineAsm::getKind(Flag) == InlineAsm::Kind_Mem)
+ if (F.isMemKind())
return TRI->getPointerRegClass(MF);
return nullptr;
@@ -1196,12 +1197,13 @@ unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const {
assert(FlagMO.isImm() && "Invalid tied operand on inline asm");
unsigned CurGroup = GroupIdx.size();
GroupIdx.push_back(i);
- NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm());
+ const InlineAsm::Flag F(FlagMO.getImm());
+ NumOps = 1 + F.getNumOperandRegisters();
// OpIdx belongs to this operand group.
if (OpIdx > i && OpIdx < i + NumOps)
OpIdxGroup = CurGroup;
unsigned TiedGroup;
- if (!InlineAsm::isUseOperandTiedToDef(FlagMO.getImm(), TiedGroup))
+ if (!F.isUseOperandTiedToDef(TiedGroup))
continue;
// Operands in this group are tied to operands in TiedGroup which must be
// earlier. Find the number of operands between the two groups.
@@ -1263,7 +1265,8 @@ bool MachineInstr::isSafeToMove(AAResults *AA, bool &SawStore) const {
}
if (isPosition() || isDebugInstr() || isTerminator() ||
- mayRaiseFPException() || hasUnmodeledSideEffects())
+ mayRaiseFPException() || hasUnmodeledSideEffects() ||
+ isJumpTableDebugInfo())
return false;
// See if this instruction does a load. If so, we have to guarantee that the
@@ -1497,6 +1500,16 @@ bool MachineInstr::allDefsAreDead() const {
return true;
}
+bool MachineInstr::allImplicitDefsAreDead() const {
+ for (const MachineOperand &MO : implicit_operands()) {
+ if (!MO.isReg() || MO.isUse())
+ continue;
+ if (!MO.isDead())
+ return false;
+ }
+ return true;
+}
+
/// copyImplicitOps - Copy implicit register operands from specified
/// instruction to this instruction.
void MachineInstr::copyImplicitOps(MachineFunction &MF,
@@ -1754,31 +1767,37 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
// Pretty print the inline asm operand descriptor.
OS << '$' << AsmOpCount++;
unsigned Flag = MO.getImm();
+ const InlineAsm::Flag F(Flag);
OS << ":[";
- OS << InlineAsm::getKindName(InlineAsm::getKind(Flag));
+ OS << F.getKindName();
- unsigned RCID = 0;
- if (!InlineAsm::isImmKind(Flag) && !InlineAsm::isMemKind(Flag) &&
- InlineAsm::hasRegClassConstraint(Flag, RCID)) {
+ unsigned RCID;
+ if (!F.isImmKind() && !F.isMemKind() && F.hasRegClassConstraint(RCID)) {
if (TRI) {
OS << ':' << TRI->getRegClassName(TRI->getRegClass(RCID));
} else
OS << ":RC" << RCID;
}
- if (InlineAsm::isMemKind(Flag)) {
- unsigned MCID = InlineAsm::getMemoryConstraintID(Flag);
+ if (F.isMemKind()) {
+ const InlineAsm::ConstraintCode MCID = F.getMemoryConstraintID();
OS << ":" << InlineAsm::getMemConstraintName(MCID);
}
- unsigned TiedTo = 0;
- if (InlineAsm::isUseOperandTiedToDef(Flag, TiedTo))
+ unsigned TiedTo;
+ if (F.isUseOperandTiedToDef(TiedTo))
OS << " tiedto:$" << TiedTo;
+ if ((F.isRegDefKind() || F.isRegDefEarlyClobberKind() ||
+ F.isRegUseKind()) &&
+ F.getRegMayBeFolded()) {
+ OS << " foldable";
+ }
+
OS << ']';
// Compute the index of the next operand descriptor.
- AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag);
+ AsmDescOp += 1 + F.getNumOperandRegisters();
} else {
LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{};
unsigned TiedOperandIdx = getTiedOperandIdx(i);
@@ -1883,16 +1902,20 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
DL.print(OS);
}
- // Print extra comments for DEBUG_VALUE.
- if (isDebugValueLike() && getDebugVariableOp().isMetadata()) {
- if (!HaveSemi) {
- OS << ";";
- HaveSemi = true;
+ // Print extra comments for DEBUG_VALUE and friends if they are well-formed.
+ if ((isNonListDebugValue() && getNumOperands() >= 4) ||
+ (isDebugValueList() && getNumOperands() >= 2) ||
+ (isDebugRef() && getNumOperands() >= 3)) {
+ if (getDebugVariableOp().isMetadata()) {
+ if (!HaveSemi) {
+ OS << ";";
+ HaveSemi = true;
+ }
+ auto *DV = getDebugVariable();
+ OS << " line no:" << DV->getLine();
+ if (isIndirectDebugValue())
+ OS << " indirect";
}
- auto *DV = getDebugVariable();
- OS << " line no:" << DV->getLine();
- if (isIndirectDebugValue())
- OS << " indirect";
}
// TODO: DBG_LABEL
@@ -2460,3 +2483,65 @@ MachineInstr::getFirst5RegLLTs() const {
Reg2, getRegInfo()->getType(Reg2), Reg3, getRegInfo()->getType(Reg3),
Reg4, getRegInfo()->getType(Reg4));
}
+
+void MachineInstr::insert(mop_iterator InsertBefore,
+ ArrayRef<MachineOperand> Ops) {
+ assert(InsertBefore != nullptr && "invalid iterator");
+ assert(InsertBefore->getParent() == this &&
+ "iterator points to operand of other inst");
+ if (Ops.empty())
+ return;
+
+ // Do one pass to untie operands.
+ SmallDenseMap<unsigned, unsigned> TiedOpIndices;
+ for (const MachineOperand &MO : operands()) {
+ if (MO.isReg() && MO.isTied()) {
+ unsigned OpNo = getOperandNo(&MO);
+ unsigned TiedTo = findTiedOperandIdx(OpNo);
+ TiedOpIndices[OpNo] = TiedTo;
+ untieRegOperand(OpNo);
+ }
+ }
+
+ unsigned OpIdx = getOperandNo(InsertBefore);
+ unsigned NumOperands = getNumOperands();
+ unsigned OpsToMove = NumOperands - OpIdx;
+
+ SmallVector<MachineOperand> MovingOps;
+ MovingOps.reserve(OpsToMove);
+
+ for (unsigned I = 0; I < OpsToMove; ++I) {
+ MovingOps.emplace_back(getOperand(OpIdx));
+ removeOperand(OpIdx);
+ }
+ for (const MachineOperand &MO : Ops)
+ addOperand(MO);
+ for (const MachineOperand &OpMoved : MovingOps)
+ addOperand(OpMoved);
+
+ // Re-tie operands.
+ for (auto [Tie1, Tie2] : TiedOpIndices) {
+ if (Tie1 >= OpIdx)
+ Tie1 += Ops.size();
+ if (Tie2 >= OpIdx)
+ Tie2 += Ops.size();
+ tieOperands(Tie1, Tie2);
+ }
+}
+
+bool MachineInstr::mayFoldInlineAsmRegOp(unsigned OpId) const {
+ assert(OpId && "expected non-zero operand id");
+ assert(isInlineAsm() && "should only be used on inline asm");
+
+ if (!getOperand(OpId).isReg())
+ return false;
+
+ const MachineOperand &MD = getOperand(OpId - 1);
+ if (!MD.isImm())
+ return false;
+
+ InlineAsm::Flag F(MD.getImm());
+ if (F.isRegUseKind() || F.isRegDefKind() || F.isRegDefEarlyClobberKind())
+ return F.getRegMayBeFolded();
+ return false;
+}