diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-18 20:30:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-06 20:11:55 +0000 |
commit | 5f757f3ff9144b609b3c433dfd370cc6bdc191ad (patch) | |
tree | 1b4e980b866cd26a00af34c0a653eb640bd09caf /contrib/llvm-project/llvm/lib/CodeGen/MachineInstr.cpp | |
parent | 3e1c8a35f741a5d114d0ba670b15191355711fe9 (diff) | |
parent | 312c0ed19cc5276a17bacf2120097bec4515b0f1 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/MachineInstr.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/MachineInstr.cpp | 149 |
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; +} |