diff --git a/llvm/include/llvm/CodeGen/AntiDepBreaker.h b/llvm/include/llvm/CodeGen/AntiDepBreaker.h --- a/llvm/include/llvm/CodeGen/AntiDepBreaker.h +++ b/llvm/include/llvm/CodeGen/AntiDepBreaker.h @@ -60,8 +60,9 @@ /// other machine instruction to use NewReg. void UpdateDbgValue(MachineInstr &MI, unsigned OldReg, unsigned NewReg) { assert(MI.isDebugValue() && "MI is not DBG_VALUE!"); - if (MI.getOperand(0).isReg() && MI.getOperand(0).getReg() == OldReg) - MI.getOperand(0).setReg(NewReg); + if (MI.getDebugOperand(0).isReg() && + MI.getDebugOperand(0).getReg() == OldReg) + MI.getDebugOperand(0).setReg(NewReg); } /// Update all DBG_VALUE instructions that may be affected by the dependency diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -408,10 +408,31 @@ /// Returns the debug location id of this MachineInstr. const DebugLoc &getDebugLoc() const { return debugLoc; } + /// Return the operand containing the offset to be used if this DBG_VALUE + /// instruction is indirect; will be an invalid register if this value is + /// not indirect, and an immediate with value 0 otherwise. + const MachineOperand &getDebugOffset() const { + assert(isDebugValue() && "not a DBG_VALUE"); + return getOperand(1); + } + MachineOperand &getDebugOffset() { + assert(isDebugValue() && "not a DBG_VALUE"); + return getOperand(1); + } + + /// Return the operand for the debug variable referenced by + /// this DBG_VALUE instruction. + const MachineOperand &getDebugVariableOp() const; + MachineOperand &getDebugVariableOp(); + /// Return the debug variable referenced by /// this DBG_VALUE instruction. const DILocalVariable *getDebugVariable() const; + /// Return the operand for the complex address expression referenced by + /// this DBG_VALUE instruction. + MachineOperand &getDebugExpressionOp(); + /// Return the complex address expression referenced by /// this DBG_VALUE instruction. const DIExpression *getDebugExpression() const; @@ -437,6 +458,11 @@ /// Retuns the total number of operands. unsigned getNumOperands() const { return NumOperands; } + /// Returns the total number of operands which are debug locations. + unsigned getNumDebugOperands() const { + return std::distance(debug_operands().begin(), debug_operands().end()); + } + const MachineOperand& getOperand(unsigned i) const { assert(i < getNumOperands() && "getOperand() out of range!"); return Operands[i]; @@ -446,6 +472,38 @@ return Operands[i]; } + MachineOperand &getDebugOperand(unsigned Index) { + assert(Index < getNumDebugOperands() && "getDebugOperand() out of range!"); + return *(debug_operands().begin() + Index); + } + const MachineOperand &getDebugOperand(unsigned Index) const { + assert(Index < getNumDebugOperands() && "getDebugOperand() out of range!"); + return *(debug_operands().begin() + Index); + } + + /// Returns a pointer to the operand corresponding to a debug use of Reg, or + /// nullptr if Reg is not used in any debug operand. + const MachineOperand *getDebugOperandForReg(Register Reg) const { + const MachineOperand *RegOp = + find_if(debug_operands(), [Reg](const MachineOperand &Op) { + return Op.isReg() && Op.getReg() == Reg; + }); + return RegOp == adl_end(debug_operands()) ? nullptr : RegOp; + } + MachineOperand *getDebugOperandForReg(Register Reg) { + MachineOperand *RegOp = + find_if(debug_operands(), [Reg](const MachineOperand &Op) { + return Op.isReg() && Op.getReg() == Reg; + }); + return RegOp == adl_end(debug_operands()) ? nullptr : RegOp; + } + + unsigned getDebugOperandIndex(const MachineOperand *Op) const { + assert(Op >= adl_begin(debug_operands()) && + Op <= adl_end(debug_operands()) && "Expected a debug operand."); + return std::distance(adl_begin(debug_operands()), Op); + } + /// Returns the total number of definitions. unsigned getNumDefs() const { return getNumExplicitDefs() + MCID->getNumImplicitDefs(); @@ -518,6 +576,17 @@ iterator_range implicit_operands() const { return make_range(explicit_operands().end(), operands_end()); } + /// Returns a range over all operands that are used to determine the variable + /// location for this DBG_VALUE instruction. + iterator_range debug_operands() { + assert(isDebugValue() && "Must be a debug value instruction."); + return make_range(operands_begin(), operands_begin() + 1); + } + /// \copydoc debug_operands() + iterator_range debug_operands() const { + assert(isDebugValue() && "Must be a debug value instruction."); + return make_range(operands_begin(), operands_begin() + 1); + } /// Returns a range over all explicit operands that are register definitions. /// Implicit definition are not included! iterator_range defs() { @@ -1075,12 +1144,12 @@ bool isDebugLabel() const { return getOpcode() == TargetOpcode::DBG_LABEL; } bool isDebugInstr() const { return isDebugValue() || isDebugLabel(); } - /// A DBG_VALUE is indirect iff the first operand is a register and - /// the second operand is an immediate. + bool isDebugOffsetImm() const { return getDebugOffset().isImm(); } + + /// A DBG_VALUE is indirect iff the location operand is a register and + /// the offset operand is an immediate. bool isIndirectDebugValue() const { - return isDebugValue() - && getOperand(0).isReg() - && getOperand(1).isImm(); + return isDebugValue() && getDebugOperand(0).isReg() && isDebugOffsetImm(); } /// A DBG_VALUE is an entry value iff its debug expression contains the @@ -1090,7 +1159,8 @@ /// Return true if the instruction is a debug value which describes a part of /// a variable as unavailable. bool isUndefDebugValue() const { - return isDebugValue() && getOperand(0).isReg() && !getOperand(0).getReg().isValid(); + return isDebugValue() && getDebugOperand(0).isReg() && + !getDebugOperand(0).getReg().isValid(); } bool isPHI() const { @@ -1686,6 +1756,16 @@ return getOperand(getNumExplicitDefs()).getIntrinsicID(); } + /// Sets all register debug operands in this debug value instruction to be + /// undef. + void setDebugValueUndef() { + assert(isDebugValue() && "Must be a debug value instruction."); + for (MachineOperand &MO : debug_operands()) { + if (MO.isReg()) + MO.setReg(0); + } + } + private: /// If this instruction is embedded into a MachineFunction, return the /// MachineRegisterInfo object for the current function, otherwise diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -879,7 +879,7 @@ OS << " <- "; // The second operand is only an offset if it's an immediate. - bool MemLoc = MI->getOperand(0).isReg() && MI->getOperand(1).isImm(); + bool MemLoc = MI->isIndirectDebugValue(); int64_t Offset = MemLoc ? MI->getOperand(1).getImm() : 0; const DIExpression *Expr = MI->getDebugExpression(); if (Expr->getNumElements()) { @@ -898,11 +898,11 @@ } // Register or immediate value. Register 0 means undef. - if (MI->getOperand(0).isFPImm()) { - APFloat APF = APFloat(MI->getOperand(0).getFPImm()->getValueAPF()); - if (MI->getOperand(0).getFPImm()->getType()->isFloatTy()) { + if (MI->getDebugOperand(0).isFPImm()) { + APFloat APF = APFloat(MI->getDebugOperand(0).getFPImm()->getValueAPF()); + if (MI->getDebugOperand(0).getFPImm()->getType()->isFloatTy()) { OS << (double)APF.convertToFloat(); - } else if (MI->getOperand(0).getFPImm()->getType()->isDoubleTy()) { + } else if (MI->getDebugOperand(0).getFPImm()->getType()->isDoubleTy()) { OS << APF.convertToDouble(); } else { // There is no good way to print long double. Convert a copy to @@ -912,23 +912,23 @@ &ignored); OS << "(long double) " << APF.convertToDouble(); } - } else if (MI->getOperand(0).isImm()) { - OS << MI->getOperand(0).getImm(); - } else if (MI->getOperand(0).isCImm()) { - MI->getOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/); - } else if (MI->getOperand(0).isTargetIndex()) { - auto Op = MI->getOperand(0); + } else if (MI->getDebugOperand(0).isImm()) { + OS << MI->getDebugOperand(0).getImm(); + } else if (MI->getDebugOperand(0).isCImm()) { + MI->getDebugOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/); + } else if (MI->getDebugOperand(0).isTargetIndex()) { + auto Op = MI->getDebugOperand(0); OS << "!target-index(" << Op.getIndex() << "," << Op.getOffset() << ")"; return true; } else { Register Reg; - if (MI->getOperand(0).isReg()) { - Reg = MI->getOperand(0).getReg(); + if (MI->getDebugOperand(0).isReg()) { + Reg = MI->getDebugOperand(0).getReg(); } else { - assert(MI->getOperand(0).isFI() && "Unknown operand type"); + assert(MI->getDebugOperand(0).isFI() && "Unknown operand type"); const TargetFrameLowering *TFI = AP.MF->getSubtarget().getFrameLowering(); - Offset += TFI->getFrameIndexReference(*AP.MF, - MI->getOperand(0).getIndex(), Reg); + Offset += TFI->getFrameIndexReference( + *AP.MF, MI->getDebugOperand(0).getIndex(), Reg); MemLoc = true; } if (Reg == 0) { diff --git a/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp b/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp @@ -47,7 +47,8 @@ return 0; // If location of variable is described using a register (directly or // indirectly), this register is always a first operand. - return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : Register(); + return MI.getDebugOperand(0).isReg() ? MI.getDebugOperand(0).getReg() + : Register(); } bool DbgValueHistoryMap::startDbgValue(InlinedEntity Var, diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp @@ -32,9 +32,9 @@ DbgVariableLocation Location; if (!Instruction.isDebugValue()) return None; - if (!Instruction.getOperand(0).isReg()) + if (!Instruction.getDebugOperand(0).isReg()) return None; - Location.Register = Instruction.getOperand(0).getReg(); + Location.Register = Instruction.getDebugOperand(0).getReg(); Location.FragmentInfo.reset(); // We only handle expressions generated by DIExpression::appendOffset, // which doesn't require a full stack machine. @@ -200,7 +200,7 @@ continue; auto IsDescribedByReg = [](const MachineInstr *MI) { - return MI->getOperand(0).isReg() && MI->getOperand(0).getReg(); + return MI->getDebugOperand(0).isReg() && MI->getDebugOperand(0).getReg(); }; // The first mention of a function argument gets the CurrentFnBegin label, diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -236,26 +236,26 @@ static DbgValueLoc getDebugLocValue(const MachineInstr *MI) { const DIExpression *Expr = MI->getDebugExpression(); assert(MI->getNumOperands() == 4); - if (MI->getOperand(0).isReg()) { - auto RegOp = MI->getOperand(0); - auto Op1 = MI->getOperand(1); + if (MI->getDebugOperand(0).isReg()) { + auto RegOp = MI->getDebugOperand(0); + auto Op1 = MI->getDebugOffset(); // If the second operand is an immediate, this is a // register-indirect address. assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset"); MachineLocation MLoc(RegOp.getReg(), Op1.isImm()); return DbgValueLoc(Expr, MLoc); } - if (MI->getOperand(0).isTargetIndex()) { - auto Op = MI->getOperand(0); + if (MI->getDebugOperand(0).isTargetIndex()) { + auto Op = MI->getDebugOperand(0); return DbgValueLoc(Expr, TargetIndexLocation(Op.getIndex(), Op.getOffset())); } - if (MI->getOperand(0).isImm()) - return DbgValueLoc(Expr, MI->getOperand(0).getImm()); - if (MI->getOperand(0).isFPImm()) - return DbgValueLoc(Expr, MI->getOperand(0).getFPImm()); - if (MI->getOperand(0).isCImm()) - return DbgValueLoc(Expr, MI->getOperand(0).getCImm()); + if (MI->getDebugOperand(0).isImm()) + return DbgValueLoc(Expr, MI->getDebugOperand(0).getImm()); + if (MI->getDebugOperand(0).isFPImm()) + return DbgValueLoc(Expr, MI->getDebugOperand(0).getFPImm()); + if (MI->getDebugOperand(0).isCImm()) + return DbgValueLoc(Expr, MI->getDebugOperand(0).getCImm()); llvm_unreachable("Unexpected 4-operand DBG_VALUE instruction!"); } @@ -1577,7 +1577,7 @@ // throughout the function. This is a hack, presumably for DWARF v2 and not // necessarily correct. It would be much better to use a dbg.declare instead // if we know the constant is live throughout the scope. - if (DbgValue->getOperand(0).isImm() && MBB->pred_empty()) + if (DbgValue->getDebugOperand(0).isImm() && MBB->pred_empty()) return true; // Now check for situations where an "open-ended" DBG_VALUE isn't enough to diff --git a/llvm/lib/CodeGen/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues.cpp --- a/llvm/lib/CodeGen/LiveDebugValues.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues.cpp @@ -174,7 +174,8 @@ assert(MI.getNumOperands() == 4 && "malformed DBG_VALUE"); // If location of variable is described using a register (directly // or indirectly), this register is always a first operand. - return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : Register(); + return MI.getDebugOperand(0).isReg() ? MI.getDebugOperand(0).getReg() + : Register(); } /// If \p Op is a stack or frame register return true, otherwise return false. @@ -334,15 +335,15 @@ if (int RegNo = isDbgValueDescribedByReg(MI)) { Kind = RegisterKind; Loc.RegNo = RegNo; - } else if (MI.getOperand(0).isImm()) { + } else if (MI.getDebugOperand(0).isImm()) { Kind = ImmediateKind; - Loc.Immediate = MI.getOperand(0).getImm(); - } else if (MI.getOperand(0).isFPImm()) { + Loc.Immediate = MI.getDebugOperand(0).getImm(); + } else if (MI.getDebugOperand(0).isFPImm()) { Kind = ImmediateKind; - Loc.FPImm = MI.getOperand(0).getFPImm(); - } else if (MI.getOperand(0).isCImm()) { + Loc.FPImm = MI.getDebugOperand(0).getFPImm(); + } else if (MI.getDebugOperand(0).isCImm()) { Kind = ImmediateKind; - Loc.CImm = MI.getOperand(0).getCImm(); + Loc.CImm = MI.getDebugOperand(0).getCImm(); } // We create the debug entry values from the factory functions rather than @@ -430,8 +431,8 @@ // expression. The register location of such DBG_VALUE is always the one // from the entry DBG_VALUE, it does not matter if the entry value was // copied in to another register due to some optimizations. - return BuildMI(MF, DbgLoc, IID, Indirect, MI.getOperand(0).getReg(), - Var, Expr); + return BuildMI(MF, DbgLoc, IID, Indirect, + MI.getDebugOperand(0).getReg(), Var, Expr); case RegisterKind: // Register locations are like the source DBG_VALUE, but with the // register number from this VarLoc. @@ -447,7 +448,7 @@ return BuildMI(MF, DbgLoc, IID, true, Base, Var, SpillExpr); } case ImmediateKind: { - MachineOperand MO = MI.getOperand(0); + MachineOperand MO = MI.getDebugOperand(0); return BuildMI(MF, DbgLoc, IID, Indirect, MO, Var, DIExpr); } case EntryValueBackupKind: @@ -1020,7 +1021,7 @@ // the entry value any more. In addition, if the debug expression from the // DBG_VALUE is not empty, we can assume the parameter's value has changed // indicating that we should stop tracking its entry value as well. - if (!MI.getOperand(0).isReg() || + if (!MI.getDebugOperand(0).isReg() || MI.getDebugExpression()->getNumElements() != 0) return true; @@ -1028,7 +1029,7 @@ // it means the parameter's value has not changed and we should be able to use // its entry value. bool TrySalvageEntryValue = false; - Register Reg = MI.getOperand(0).getReg(); + Register Reg = MI.getDebugOperand(0).getReg(); auto I = std::next(MI.getReverseIterator()); const MachineOperand *SrcRegOp, *DestRegOp; if (I != MI.getParent()->rend()) { @@ -1050,7 +1051,7 @@ for (uint64_t ID : OpenRanges.getEntryValueBackupVarLocs()) { const VarLoc &VL = VarLocIDs[LocIndex::fromRawInteger(ID)]; if (VL.getEntryValueCopyBackupReg() == Reg && - VL.MI.getOperand(0).getReg() == SrcRegOp->getReg()) + VL.MI.getDebugOperand(0).getReg() == SrcRegOp->getReg()) return false; } } @@ -1088,8 +1089,8 @@ } } - if (isDbgValueDescribedByReg(MI) || MI.getOperand(0).isImm() || - MI.getOperand(0).isFPImm() || MI.getOperand(0).isCImm()) { + if (isDbgValueDescribedByReg(MI) || MI.getDebugOperand(0).isImm() || + MI.getDebugOperand(0).isFPImm() || MI.getDebugOperand(0).isCImm()) { // Use normal VarLoc constructor for registers and immediates. VarLoc VL(MI, LS); // End all previous ranges of VL.Var. @@ -1102,7 +1103,8 @@ llvm_unreachable("DBG_VALUE with mem operand encountered after regalloc?"); } else { // This must be an undefined location. If it has an open range, erase it. - assert(MI.getOperand(0).isReg() && MI.getOperand(0).getReg() == 0 && + assert(MI.getDebugOperand(0).isReg() && + MI.getDebugOperand(0).getReg() == 0 && "Unexpected non-undef DBG_VALUE encountered"); VarLoc VL(MI, LS); OpenRanges.erase(VL); @@ -1738,14 +1740,14 @@ // Only consider parameters that are described using registers. Parameters // that are passed on the stack are not yet supported, so ignore debug // values that are described by the frame or stack pointer. - if (!isRegOtherThanSPAndFP(MI.getOperand(0), MI, TRI)) + if (!isRegOtherThanSPAndFP(MI.getDebugOperand(0), MI, TRI)) return false; // If a parameter's value has been propagated from the caller, then the // parameter's DBG_VALUE may be described using a register defined by some // instruction in the entry block, in which case we shouldn't create an // entry value. - if (DefinedRegs.count(MI.getOperand(0).getReg())) + if (DefinedRegs.count(MI.getDebugOperand(0).getReg())) return false; // TODO: Add support for parameters that have a pre-existing debug expressions diff --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp --- a/llvm/lib/CodeGen/LiveDebugVariables.cpp +++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp @@ -608,8 +608,8 @@ bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) { // DBG_VALUE loc, offset, variable if (MI.getNumOperands() != 4 || - !(MI.getOperand(1).isReg() || MI.getOperand(1).isImm()) || - !MI.getOperand(2).isMetadata()) { + !(MI.getDebugOffset().isReg() || MI.getDebugOffset().isImm()) || + !MI.getDebugVariableOp().isMetadata()) { LLVM_DEBUG(dbgs() << "Can't handle " << MI); return false; } @@ -622,9 +622,9 @@ // (and if the machine verifier is improved to catch this), then these checks // could be removed or replaced by asserts. bool Discard = false; - if (MI.getOperand(0).isReg() && - Register::isVirtualRegister(MI.getOperand(0).getReg())) { - const Register Reg = MI.getOperand(0).getReg(); + if (MI.getDebugOperand(0).isReg() && + Register::isVirtualRegister(MI.getDebugOperand(0).getReg())) { + const Register Reg = MI.getDebugOperand(0).getReg(); if (!LIS->hasInterval(Reg)) { // The DBG_VALUE is described by a virtual register that does not have a // live interval. Discard the DBG_VALUE. @@ -648,14 +648,15 @@ } // Get or create the UserValue for (variable,offset) here. - bool IsIndirect = MI.getOperand(1).isImm(); + bool IsIndirect = MI.isDebugOffsetImm(); if (IsIndirect) - assert(MI.getOperand(1).getImm() == 0 && "DBG_VALUE with nonzero offset"); + assert(MI.getDebugOffset().getImm() == 0 && + "DBG_VALUE with nonzero offset"); const DILocalVariable *Var = MI.getDebugVariable(); const DIExpression *Expr = MI.getDebugExpression(); UserValue *UV = getUserValue(Var, Expr->getFragmentInfo(), MI.getDebugLoc()); if (!Discard) - UV->addDef(Idx, MI.getOperand(0), IsIndirect, *Expr); + UV->addDef(Idx, MI.getDebugOperand(0), IsIndirect, *Expr); else { MachineOperand MO = MachineOperand::CreateReg(0U, false); MO.setIsDebug(); diff --git a/llvm/lib/CodeGen/LiveRangeShrink.cpp b/llvm/lib/CodeGen/LiveRangeShrink.cpp --- a/llvm/lib/CodeGen/LiveRangeShrink.cpp +++ b/llvm/lib/CodeGen/LiveRangeShrink.cpp @@ -234,8 +234,7 @@ MachineBasicBlock::iterator EndIter = std::next(MI.getIterator()); if (MI.getOperand(0).isReg()) for (; EndIter != MBB.end() && EndIter->isDebugValue() && - EndIter->getOperand(0).isReg() && - EndIter->getOperand(0).getReg() == MI.getOperand(0).getReg(); + EndIter->getDebugOperandForReg(MI.getOperand(0).getReg()); ++EndIter, ++Next) IOM[&*EndIter] = NewOrder; MBB.splice(I, &MBB, MI.getIterator(), EndIter); diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -834,11 +834,26 @@ return cast(getOperand(0).getMetadata()); } +const MachineOperand &MachineInstr::getDebugVariableOp() const { + assert(isDebugValue() && "not a DBG_VALUE"); + return getOperand(2); +} + +MachineOperand &MachineInstr::getDebugVariableOp() { + assert(isDebugValue() && "not a DBG_VALUE"); + return getOperand(2); +} + const DILocalVariable *MachineInstr::getDebugVariable() const { assert(isDebugValue() && "not a DBG_VALUE"); return cast(getOperand(2).getMetadata()); } +MachineOperand &MachineInstr::getDebugExpressionOp() { + assert(isDebugValue() && "not a DBG_VALUE"); + return getOperand(3); +} + const DIExpression *MachineInstr::getDebugExpression() const { assert(isDebugValue() && "not a DBG_VALUE"); return cast(getOperand(3).getMetadata()); @@ -1786,12 +1801,12 @@ } // Print extra comments for DEBUG_VALUE. - if (isDebugValue() && getOperand(e - 2).isMetadata()) { + if (isDebugValue() && getDebugVariableOp().isMetadata()) { if (!HaveSemi) { OS << ";"; HaveSemi = true; } - auto *DV = cast(getOperand(e - 2).getMetadata()); + auto *DV = getDebugVariable(); OS << " line no:" << DV->getLine(); if (isIndirectDebugValue()) OS << " indirect"; @@ -2097,7 +2112,8 @@ const DIExpression *Expr = MI.getDebugExpression(); if (MI.isIndirectDebugValue()) { - assert(MI.getOperand(1).getImm() == 0 && "DBG_VALUE with nonzero offset"); + assert(MI.getDebugOffset().getImm() == 0 && + "DBG_VALUE with nonzero offset"); Expr = DIExpression::prepend(Expr, DIExpression::DerefBefore); } return Expr; @@ -2117,9 +2133,9 @@ void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex) { const DIExpression *Expr = computeExprForSpill(Orig); - Orig.getOperand(0).ChangeToFrameIndex(FrameIndex); - Orig.getOperand(1).ChangeToImmediate(0U); - Orig.getOperand(3).setMetadata(Expr); + Orig.getDebugOperand(0).ChangeToFrameIndex(FrameIndex); + Orig.getDebugOffset().ChangeToImmediate(0U); + Orig.getDebugExpressionOp().setMetadata(Expr); } void MachineInstr::collectDebugValues( @@ -2133,8 +2149,7 @@ DI != DE; ++DI) { if (!DI->isDebugValue()) return; - if (DI->getOperand(0).isReg() && - DI->getOperand(0).getReg() == MI.getOperand(0).getReg()) + if (DI->getDebugOperandForReg(MI.getOperand(0).getReg())) DbgValues.push_back(&*DI); } } @@ -2146,21 +2161,20 @@ if (!getOperand(0).isReg()) return; - unsigned DefReg = getOperand(0).getReg(); + Register DefReg = getOperand(0).getReg(); auto *MRI = getRegInfo(); for (auto &MO : MRI->use_operands(DefReg)) { auto *DI = MO.getParent(); if (!DI->isDebugValue()) continue; - if (DI->getOperand(0).isReg() && - DI->getOperand(0).getReg() == DefReg){ + if (DI->getDebugOperandForReg(DefReg)) { DbgValues.push_back(DI); } } // Propagate Reg to debug value instructions. for (auto *DBI : DbgValues) - DBI->getOperand(0).setReg(Reg); + DBI->getDebugOperandForReg(DefReg)->setReg(Reg); } using MMOList = SmallVector; diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp --- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp +++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp @@ -550,7 +550,7 @@ nextI = std::next(I); // I is invalidated by the setReg MachineInstr *UseMI = &*I; if (UseMI->isDebugValue()) - UseMI->getOperand(0).setReg(0U); + UseMI->getDebugOperandForReg(Reg)->setReg(0U); } } diff --git a/llvm/lib/CodeGen/MachineSink.cpp b/llvm/lib/CodeGen/MachineSink.cpp --- a/llvm/lib/CodeGen/MachineSink.cpp +++ b/llvm/lib/CodeGen/MachineSink.cpp @@ -432,7 +432,7 @@ MI.getDebugLoc()->getInlinedAt()); bool SeenBefore = SeenDbgVars.count(Var) != 0; - MachineOperand &MO = MI.getOperand(0); + MachineOperand &MO = MI.getDebugOperand(0); if (MO.isReg() && MO.getReg().isVirtual()) SeenDbgUsers[MO.getReg()].push_back(SeenDbgUser(&MI, SeenBefore)); @@ -796,7 +796,7 @@ // Copy DBG_VALUE operand and set the original to undef. We then check to // see whether this is something that can be copy-forwarded. If it isn't, // continue around the loop. - MachineOperand DbgMO = DbgMI.getOperand(0); + MachineOperand &DbgMO = DbgMI.getDebugOperand(0); const MachineOperand *SrcMO = nullptr, *DstMO = nullptr; auto CopyOperands = TII.isCopyInstr(SinkInst); @@ -830,8 +830,8 @@ if (PostRA && DbgMO.getReg() != DstMO->getReg()) return false; - DbgMI.getOperand(0).setReg(SrcMO->getReg()); - DbgMI.getOperand(0).setSubReg(SrcMO->getSubReg()); + DbgMO.setReg(SrcMO->getReg()); + DbgMO.setSubReg(SrcMO->getSubReg()); return true; } @@ -866,7 +866,7 @@ SuccToSinkTo.insert(InsertPos, NewDbgMI); if (!attemptDebugCopyProp(MI, *DbgMI)) - DbgMI->getOperand(0).setReg(0); + DbgMI->setDebugValueUndef(); } } @@ -1000,7 +1000,7 @@ // This DBG_VALUE would re-order assignments. If we can't copy-propagate // it, it can't be recovered. Set it undef. if (!attemptDebugCopyProp(MI, *DbgMI)) - DbgMI->getOperand(0).setReg(0); + DbgMI->setDebugValueUndef(); } else { DbgUsersToSink.push_back(DbgMI); } @@ -1049,7 +1049,7 @@ if (User.getParent() == MI.getParent()) continue; - assert(User.getOperand(0).isReg() && + assert(User.getDebugOperand(0).isReg() && "DBG_VALUE user of vreg, but non reg operand?"); DbgDefUsers.push_back(&User); } @@ -1058,8 +1058,8 @@ // Point the users of this copy that are no longer dominated, at the source // of the copy. for (auto *User : DbgDefUsers) { - User->getOperand(0).setReg(MI.getOperand(1).getReg()); - User->getOperand(0).setSubReg(MI.getOperand(1).getSubReg()); + User->getDebugOperand(0).setReg(MI.getOperand(1).getReg()); + User->getDebugOperand(0).setSubReg(MI.getOperand(1).getSubReg()); } } @@ -1305,7 +1305,7 @@ // We must sink this DBG_VALUE if its operand is sunk. To avoid searching // for DBG_VALUEs later, record them when they're encountered. if (MI->isDebugValue()) { - auto &MO = MI->getOperand(0); + auto &MO = MI->getDebugOperand(0); if (MO.isReg() && Register::isPhysicalRegister(MO.getReg())) { // Bail if we can already tell the sink would be rejected, rather // than needlessly accumulating lots of DBG_VALUEs. diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -185,7 +185,7 @@ break; if (!MI.isDebugValue() || !MI.getDebugVariable()->isParameter()) continue; - if (MI.getOperand(0).isFI()) { + if (MI.getDebugOperand(0).isFI()) { // We can only emit valid locations for frame indices after the frame // setup, so do not stash away them. FrameIndexValues.push_back(&MI); @@ -1234,10 +1234,10 @@ bool WithStackValue = true; DIExpr = DIExpression::prependOpcodes(DIExpr, Ops, WithStackValue); // Make the DBG_VALUE direct. - MI.getOperand(1).ChangeToRegister(0, false); + MI.getDebugOffset().ChangeToRegister(0, false); } DIExpr = DIExpression::prepend(DIExpr, PrependFlags, Offset); - MI.getOperand(3).setMetadata(DIExpr); + MI.getDebugExpressionOp().setMetadata(DIExpr); continue; } diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp --- a/llvm/lib/CodeGen/RegAllocFast.cpp +++ b/llvm/lib/CodeGen/RegAllocFast.cpp @@ -1156,7 +1156,7 @@ } void RegAllocFast::handleDebugValue(MachineInstr &MI) { - MachineOperand &MO = MI.getOperand(0); + MachineOperand &MO = MI.getDebugOperand(0); // Ignore DBG_VALUEs that aren't based on virtual registers. These are // mostly constants and frame indices. diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp --- a/llvm/lib/CodeGen/RegisterCoalescer.cpp +++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -3488,7 +3488,7 @@ // vreg => DbgValueLoc map. auto CloseNewDVRange = [this, &ToInsert](SlotIndex Slot) { for (auto *X : ToInsert) - DbgVRegToValues[X->getOperand(0).getReg()].push_back({Slot, X}); + DbgVRegToValues[X->getDebugOperand(0).getReg()].push_back({Slot, X}); ToInsert.clear(); }; @@ -3500,8 +3500,8 @@ SlotIndex CurrentSlot = Slots.getMBBStartIdx(&MBB); for (auto &MI : MBB) { - if (MI.isDebugValue() && MI.getOperand(0).isReg() && - MI.getOperand(0).getReg().isVirtual()) { + if (MI.isDebugValue() && MI.getDebugOperand(0).isReg() && + MI.getDebugOperand(0).getReg().isVirtual()) { ToInsert.push_back(&MI); } else if (!MI.isDebugInstr()) { CurrentSlot = Slots.getInstructionIndex(MI); @@ -3600,10 +3600,10 @@ // "Other" is live and there is a DBG_VALUE of Reg: test if we should // set it undef. if (DbgValueSetIt->first >= SegmentIt->start && - DbgValueSetIt->second->getOperand(0).getReg() != 0 && + DbgValueSetIt->second->getDebugOperand(0).getReg() != 0 && ShouldUndef(DbgValueSetIt->first)) { // Mark undef, erase record of this DBG_VALUE to avoid revisiting. - DbgValueSetIt->second->getOperand(0).setReg(0); + DbgValueSetIt->second->setDebugValueUndef(); continue; } ++DbgValueSetIt; diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -749,11 +749,10 @@ assert(NOps == 4); OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; // cast away const; DIetc do not take const operands for some reason. - OS << cast(MI->getOperand(NOps - 2).getMetadata()) - ->getName(); + OS << MI->getDebugVariable()->getName(); OS << " <- "; // Frame address. Currently handles register +- offset only. - assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); + assert(MI->getDebugOperand(0).isReg() && MI->isDebugOffsetImm()); OS << '['; printOperand(MI, 0, OS); OS << '+'; diff --git a/llvm/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp b/llvm/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp --- a/llvm/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp @@ -74,7 +74,7 @@ MI.getOperand(0).setIsDebug(); auto *DIExpr = DIExpression::prepend( MI.getDebugExpression(), DIExpression::ApplyOffset, Offset); - MI.getOperand(3).setMetadata(DIExpr); + MI.getDebugExpressionOp().setMetadata(DIExpr); continue; } diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp --- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp @@ -271,7 +271,7 @@ // Special handling of dbg_value instructions. if (MI->isDebugValue()) { MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, /*isDef*/ false); - MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); + MI->getDebugOffset().ChangeToImmediate(Offset); return; } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp @@ -31,7 +31,7 @@ void WebAssemblyDebugValueManager::updateReg(unsigned Reg) { for (auto *DBI : DbgValues) - DBI->getOperand(0).setReg(Reg); + DBI->getDebugOperand(0).setReg(Reg); } void WebAssemblyDebugValueManager::clone(MachineInstr *Insert, @@ -40,14 +40,14 @@ MachineFunction *MF = MBB->getParent(); for (MachineInstr *DBI : reverse(DbgValues)) { MachineInstr *Clone = MF->CloneMachineInstr(DBI); - Clone->getOperand(0).setReg(NewReg); + Clone->getDebugOperand(0).setReg(NewReg); MBB->insert(Insert, Clone); } } void WebAssemblyDebugValueManager::replaceWithLocal(unsigned LocalId) { for (auto *DBI : DbgValues) { - MachineOperand &Op = DBI->getOperand(0); + MachineOperand &Op = DBI->getDebugOperand(0); Op.ChangeToTargetIndex(llvm::WebAssembly::TI_LOCAL, LocalId); } } diff --git a/llvm/lib/Target/X86/X86OptimizeLEAs.cpp b/llvm/lib/Target/X86/X86OptimizeLEAs.cpp --- a/llvm/lib/Target/X86/X86OptimizeLEAs.cpp +++ b/llvm/lib/Target/X86/X86OptimizeLEAs.cpp @@ -578,7 +578,7 @@ MachineInstr *X86OptimizeLEAPass::replaceDebugValue(MachineInstr &MI, unsigned VReg, int64_t AddrDispShift) { - DIExpression *Expr = const_cast(MI.getDebugExpression()); + const DIExpression *Expr = MI.getDebugExpression(); if (AddrDispShift != 0) Expr = DIExpression::prepend(Expr, DIExpression::StackValue, AddrDispShift);