From d2000b45d033c06dc7973f59909a0ad12887ff51 Mon Sep 17 00:00:00 2001 From: Stephen Tozer Date: Thu, 4 Mar 2021 11:59:21 +0000 Subject: [PATCH] Revert "[DebugInfo] Add new instruction and DIExpression operator for variadic debug values" This reverts commit d07f106f4a48b6e941266525b6f7177834d7b74e. --- llvm/docs/LangRef.rst | 8 -- llvm/docs/SourceLevelDebugging.rst | 22 +--- llvm/include/llvm/BinaryFormat/Dwarf.h | 1 - llvm/include/llvm/CodeGen/MachineInstr.h | 88 ++++---------- llvm/include/llvm/CodeGen/MachineInstrBuilder.h | 22 +--- llvm/include/llvm/IR/DebugInfoMetadata.h | 8 -- llvm/include/llvm/Support/TargetOpcodes.def | 4 - llvm/include/llvm/Target/Target.td | 6 - llvm/lib/BinaryFormat/Dwarf.cpp | 3 - llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 3 +- llvm/lib/CodeGen/InlineSpiller.cpp | 2 +- llvm/lib/CodeGen/LiveRangeShrink.cpp | 2 +- llvm/lib/CodeGen/MIRParser/MIParser.cpp | 4 +- llvm/lib/CodeGen/MachineInstr.cpp | 126 ++++++--------------- llvm/lib/CodeGen/MachineRegisterInfo.cpp | 6 +- llvm/lib/CodeGen/PrologEpilogInserter.cpp | 42 +++---- llvm/lib/CodeGen/RegAllocFast.cpp | 91 +++++++-------- llvm/lib/IR/DebugInfoMetadata.cpp | 26 ----- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 5 +- llvm/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp | 27 ++--- llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp | 14 +-- .../WebAssembly/WebAssemblyDebugValueManager.cpp | 2 +- llvm/lib/Target/X86/X86OptimizeLEAs.cpp | 47 ++------ llvm/test/CodeGen/MIR/Generic/dbg-value-list.mir | 64 ----------- 24 files changed, 147 insertions(+), 476 deletions(-) delete mode 100644 llvm/test/CodeGen/MIR/Generic/dbg-value-list.mir diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 06194da..fef7a2a 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -5311,14 +5311,6 @@ The current supported opcode vocabulary is limited: ``AsmPrinter`` pass when a call site parameter value (``DW_AT_call_site_parameter_value``) is represented as entry value of the parameter. -- ``DW_OP_LLVM_arg, N`` is used in debug intrinsics that refer to more than one - value, such as one that calculates the sum of two registers. This is always - used in combination with an ordered list of values, such that - ``DW_OP_LLVM_arg, N`` refers to the ``N``th element in that list. For - example, ``!DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_minus, - DW_OP_stack_value)`` used with the list ``(%reg1, %reg2)`` would evaluate to - ``%reg1 - reg2``. This list of values should be provided by the containing - intrinsic/instruction. - ``DW_OP_breg`` (or ``DW_OP_bregx``) represents a content on the provided signed offset of the specified register. The opcode is only generated by the ``AsmPrinter`` pass to describe call site parameter value which requires an diff --git a/llvm/docs/SourceLevelDebugging.rst b/llvm/docs/SourceLevelDebugging.rst index 357f720..e5984cd 100644 --- a/llvm/docs/SourceLevelDebugging.rst +++ b/llvm/docs/SourceLevelDebugging.rst @@ -576,15 +576,13 @@ the equivalent location is used. After MIR locations are assigned to each variable, machine pseudo-instructions corresponding to each ``llvm.dbg.value`` and ``llvm.dbg.addr`` intrinsic are -inserted. There are two forms of this type of instruction. - -The first form, ``DBG_VALUE``, appears thus: +inserted. These ``DBG_VALUE`` instructions appear thus: .. code-block:: text DBG_VALUE %1, $noreg, !123, !DIExpression() -And has the following operands: +And have the following operands: * The first operand can record the variable location as a register, a frame index, an immediate, or the base address register if the original debug intrinsic referred to memory. ``$noreg`` indicates the variable @@ -596,22 +594,6 @@ And has the following operands: * Operand 3 is the Variable field of the original debug intrinsic. * Operand 4 is the Expression field of the original debug intrinsic. -The second form, ``DBG_VALUE_LIST``, appears thus: - -.. code-block:: text - - DBG_VALUE_LIST !123, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), %1, %2 - -And has the following operands: - * The first operand is the Variable field of the original debug intrinsic. - * The second operand is the Expression field of the original debug intrinsic. - * Any number of operands, from the 3rd onwards, record a sequence of variable - location operands, which may take any of the same values as the first - operand of the ``DBG_VALUE`` instruction above. These variable location - operands are inserted into the final DWARF Expression in positions indicated - by the DW_OP_LLVM_arg operator in the DIExpression, as described in - :ref:`DIExpression<_DIExpression>`. - The position at which the DBG_VALUEs are inserted should correspond to the positions of their matching ``llvm.dbg.value`` intrinsics in the IR block. As with optimization, LLVM aims to preserve the order in which variable diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h index a725aff..765d5d6 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.h +++ b/llvm/include/llvm/BinaryFormat/Dwarf.h @@ -144,7 +144,6 @@ enum LocationAtom { DW_OP_LLVM_tag_offset = 0x1002, ///< Only used in LLVM metadata. DW_OP_LLVM_entry_value = 0x1003, ///< Only used in LLVM metadata. DW_OP_LLVM_implicit_pointer = 0x1004, ///< Only used in LLVM metadata. - DW_OP_LLVM_arg = 0x1005, ///< Only used in LLVM metadata. }; enum TypeKind : uint8_t { diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h index 6071f73..c4ddd05 100644 --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -420,11 +420,11 @@ public: /// 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(isNonListDebugValue() && "not a DBG_VALUE"); + assert(isDebugValue() && "not a DBG_VALUE"); return getOperand(1); } MachineOperand &getDebugOffset() { - assert(isNonListDebugValue() && "not a DBG_VALUE"); + assert(isDebugValue() && "not a DBG_VALUE"); return getOperand(1); } @@ -439,7 +439,6 @@ public: /// Return the operand for the complex address expression referenced by /// this DBG_VALUE instruction. - const MachineOperand &getDebugExpressionOp() const; MachineOperand &getDebugExpressionOp(); /// Return the complex address expression referenced by @@ -502,43 +501,26 @@ public: return *(debug_operands().begin() + Index); } - /// Returns whether this debug value has at least one debug operand with the - /// register \p Reg. - bool hasDebugOperandForReg(Register Reg) const { - return any_of(debug_operands(), [Reg](const MachineOperand &Op) { - return Op.isReg() && Op.getReg() == Reg; - }); + /// 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; } - - /// Returns a range of all of the operands that correspond to a debug use of - /// \p Reg. - template - static iterator_range< - filter_iterator>> - getDebugOperandsForReg(Instruction *MI, Register Reg) { - std::function OpUsesReg( - [Reg](Operand &Op) { return Op.isReg() && Op.getReg() == Reg; }); - return make_filter_range(MI->debug_operands(), OpUsesReg); - } - iterator_range>> - getDebugOperandsForReg(Register Reg) const { - return MachineInstr::getDebugOperandsForReg(this, Reg); - } - iterator_range>> - getDebugOperandsForReg(Register Reg) { - return MachineInstr::getDebugOperandsForReg( - this, Reg); - } - - bool isDebugOperand(const MachineOperand *Op) const { - return Op >= adl_begin(debug_operands()) && Op <= adl_end(debug_operands()); + 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(isDebugOperand(Op) && "Expected a debug operand."); + assert(Op >= adl_begin(debug_operands()) && + Op <= adl_end(debug_operands()) && "Expected a debug operand."); return std::distance(adl_begin(debug_operands()), Op); } @@ -618,16 +600,12 @@ public: /// location for this DBG_VALUE instruction. iterator_range debug_operands() { assert(isDebugValue() && "Must be a debug value instruction."); - return isDebugValueList() - ? make_range(operands_begin() + 2, operands_end()) - : make_range(operands_begin(), operands_begin() + 1); + 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 isDebugValueList() - ? make_range(operands_begin() + 2, operands_end()) - : make_range(operands_begin(), operands_begin() + 1); + return make_range(operands_begin(), operands_begin() + 1); } /// Returns a range over all explicit operands that are register definitions. /// Implicit definition are not included! @@ -1186,15 +1164,7 @@ public: // True if the instruction represents a position in the function. bool isPosition() const { return isLabel() || isCFIInstruction(); } - bool isNonListDebugValue() const { - return getOpcode() == TargetOpcode::DBG_VALUE; - } - bool isDebugValueList() const { - return getOpcode() == TargetOpcode::DBG_VALUE_LIST; - } - bool isDebugValue() const { - return isNonListDebugValue() || isDebugValueList(); - } + bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; } bool isDebugLabel() const { return getOpcode() == TargetOpcode::DBG_LABEL; } bool isDebugRef() const { return getOpcode() == TargetOpcode::DBG_INSTR_REF; } bool isDebugInstr() const { @@ -1204,14 +1174,12 @@ public: return isDebugInstr() || isPseudoProbe(); } - bool isDebugOffsetImm() const { - return isNonListDebugValue() && getDebugOffset().isImm(); - } + 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 isDebugOffsetImm() && getDebugOperand(0).isReg(); + return isDebugValue() && getDebugOperand(0).isReg() && isDebugOffsetImm(); } /// A DBG_VALUE is an entry value iff its debug expression contains the @@ -1221,13 +1189,8 @@ public: /// Return true if the instruction is a debug value which describes a part of /// a variable as unavailable. bool isUndefDebugValue() const { - if (!isDebugValue()) - return false; - // If any $noreg locations are given, this DV is undef. - for (const MachineOperand &Op : debug_operands()) - if (Op.isReg() && !Op.getReg().isValid()) - return true; - return false; + return isDebugValue() && getDebugOperand(0).isReg() && + !getDebugOperand(0).getReg().isValid(); } bool isPHI() const { @@ -1302,7 +1265,6 @@ public: case TargetOpcode::EH_LABEL: case TargetOpcode::GC_LABEL: case TargetOpcode::DBG_VALUE: - case TargetOpcode::DBG_VALUE_LIST: case TargetOpcode::DBG_INSTR_REF: case TargetOpcode::DBG_LABEL: case TargetOpcode::LIFETIME_START: diff --git a/llvm/include/llvm/CodeGen/MachineInstrBuilder.h b/llvm/include/llvm/CodeGen/MachineInstrBuilder.h index 18786b7..115c501 100644 --- a/llvm/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/llvm/include/llvm/CodeGen/MachineInstrBuilder.h @@ -451,16 +451,9 @@ MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, /// for a MachineOperand. MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID, bool IsIndirect, - const MachineOperand &MO, const MDNode *Variable, + MachineOperand &MO, const MDNode *Variable, const MDNode *Expr); -/// This version of the builder builds a DBG_VALUE or DBG_VALUE_LIST intrinsic -/// for a MachineOperand. -MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, - const MCInstrDesc &MCID, bool IsIndirect, - ArrayRef MOs, - const MDNode *Variable, const MDNode *Expr); - /// This version of the builder builds a DBG_VALUE intrinsic /// for either a value in a register or a register-indirect /// address and inserts it at position I. @@ -478,23 +471,14 @@ MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineOperand &MO, const MDNode *Variable, const MDNode *Expr); -/// This version of the builder builds a DBG_VALUE or DBG_VALUE_LIST intrinsic -/// for a machine operand and inserts it at position I. -MachineInstrBuilder BuildMI(MachineBasicBlock &BB, - MachineBasicBlock::iterator I, const DebugLoc &DL, - const MCInstrDesc &MCID, bool IsIndirect, - ArrayRef MOs, - const MDNode *Variable, const MDNode *Expr); - /// Clone a DBG_VALUE whose value has been spilled to FrameIndex. MachineInstr *buildDbgValueForSpill(MachineBasicBlock &BB, MachineBasicBlock::iterator I, - const MachineInstr &Orig, int FrameIndex, - Register SpillReg); + const MachineInstr &Orig, int FrameIndex); /// Update a DBG_VALUE whose value has been spilled to FrameIndex. Useful when /// modifying an instruction in place while iterating over a basic block. -void updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex, Register Reg); +void updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex); inline unsigned getDefRegState(bool B) { return B ? RegState::Define : 0; diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index 9cfcdba..a82418f 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -2775,14 +2775,6 @@ public: static DIExpression *appendToStack(const DIExpression *Expr, ArrayRef Ops); - /// Create a copy of \p Expr by appending the given list of \p Ops to each - /// instance of the operand `DW_OP_LLVM_arg, \p ArgNo`. This is used to - /// modify a specific location used by \p Expr, such as when salvaging that - /// location. - static DIExpression *appendOpsToArg(const DIExpression *Expr, - ArrayRef Ops, unsigned ArgNo, - bool StackValue = false); - /// Create a DIExpression to describe one part of an aggregate variable that /// is fragmented across multiple Values. The DW_OP_LLVM_fragment operation /// will be appended to the elements of \c Expr. If \c Expr already contains diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def index 63964b4..04d41a4 100644 --- a/llvm/include/llvm/Support/TargetOpcodes.def +++ b/llvm/include/llvm/Support/TargetOpcodes.def @@ -77,10 +77,6 @@ HANDLE_TARGET_OPCODE(SUBREG_TO_REG) /// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic HANDLE_TARGET_OPCODE(DBG_VALUE) -/// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic with a variadic -/// list of locations -HANDLE_TARGET_OPCODE(DBG_VALUE_LIST) - /// DBG_INSTR_REF - A mapping of llvm.dbg.value referring to the instruction /// that defines the value, rather than a virtual register. HANDLE_TARGET_OPCODE(DBG_INSTR_REF) diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td index 1f0f897..332de74 100644 --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -1107,12 +1107,6 @@ def DBG_VALUE : StandardPseudoInstruction { let AsmString = "DBG_VALUE"; let hasSideEffects = false; } -def DBG_VALUE_LIST : StandardPseudoInstruction { - let OutOperandList = (outs); - let InOperandList = (ins variable_ops); - let AsmString = "DBG_VALUE_LIST"; - let hasSideEffects = 0; -} def DBG_INSTR_REF : StandardPseudoInstruction { let OutOperandList = (outs); let InOperandList = (ins variable_ops); diff --git a/llvm/lib/BinaryFormat/Dwarf.cpp b/llvm/lib/BinaryFormat/Dwarf.cpp index c884257..e474736 100644 --- a/llvm/lib/BinaryFormat/Dwarf.cpp +++ b/llvm/lib/BinaryFormat/Dwarf.cpp @@ -153,8 +153,6 @@ StringRef llvm::dwarf::OperationEncodingString(unsigned Encoding) { return "DW_OP_LLVM_entry_value"; case DW_OP_LLVM_implicit_pointer: return "DW_OP_LLVM_implicit_pointer"; - case DW_OP_LLVM_arg: - return "DW_OP_LLVM_arg"; } } @@ -168,7 +166,6 @@ unsigned llvm::dwarf::getOperationEncoding(StringRef OperationEncodingString) { .Case("DW_OP_LLVM_tag_offset", DW_OP_LLVM_tag_offset) .Case("DW_OP_LLVM_entry_value", DW_OP_LLVM_entry_value) .Case("DW_OP_LLVM_implicit_pointer", DW_OP_LLVM_implicit_pointer) - .Case("DW_OP_LLVM_arg", DW_OP_LLVM_arg) .Default(0); } diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 37d8798..9eaf486 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -905,7 +905,7 @@ static void emitKill(const MachineInstr *MI, AsmPrinter &AP) { /// means the target will need to handle MI in EmitInstruction. static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) { // This code handles only the 4-operand target-independent form. - if (MI->isNonListDebugValue() && MI->getNumOperands() != 4) + if (MI->getNumOperands() != 4) return false; SmallString<128> Str; @@ -1228,7 +1228,6 @@ void AsmPrinter::emitFunctionBody() { emitInlineAsm(&MI); break; case TargetOpcode::DBG_VALUE: - case TargetOpcode::DBG_VALUE_LIST: if (isVerbose()) { if (!emitDebugValueComment(&MI, *this)) emitInstruction(&MI); diff --git a/llvm/lib/CodeGen/InlineSpiller.cpp b/llvm/lib/CodeGen/InlineSpiller.cpp index 4635daf..7c28023 100644 --- a/llvm/lib/CodeGen/InlineSpiller.cpp +++ b/llvm/lib/CodeGen/InlineSpiller.cpp @@ -1048,7 +1048,7 @@ void InlineSpiller::spillAroundUses(Register Reg) { // Modify DBG_VALUE now that the value is in a spill slot. MachineBasicBlock *MBB = MI->getParent(); LLVM_DEBUG(dbgs() << "Modifying debug info due to spill:\t" << *MI); - buildDbgValueForSpill(*MBB, MI, *MI, StackSlot, Reg); + buildDbgValueForSpill(*MBB, MI, *MI, StackSlot); MBB->erase(MI); continue; } diff --git a/llvm/lib/CodeGen/LiveRangeShrink.cpp b/llvm/lib/CodeGen/LiveRangeShrink.cpp index 6c03a87..7fa14fd 100644 --- a/llvm/lib/CodeGen/LiveRangeShrink.cpp +++ b/llvm/lib/CodeGen/LiveRangeShrink.cpp @@ -235,7 +235,7 @@ bool LiveRangeShrink::runOnMachineFunction(MachineFunction &MF) { MachineBasicBlock::iterator EndIter = std::next(MI.getIterator()); if (MI.getOperand(0).isReg()) for (; EndIter != MBB.end() && EndIter->isDebugValue() && - EndIter->hasDebugOperandForReg(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/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp index a3f84f3..fe979b9 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -987,9 +987,7 @@ bool MIParser::parse(MachineInstr *&MI) { Optional TiedDefIdx; if (parseMachineOperandAndTargetFlags(OpCode, Operands.size(), MO, TiedDefIdx)) return true; - if ((OpCode == TargetOpcode::DBG_VALUE || - OpCode == TargetOpcode::DBG_VALUE_LIST) && - MO.isReg()) + if (OpCode == TargetOpcode::DBG_VALUE && MO.isReg()) MO.setIsDebug(); Operands.push_back( ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx)); diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp index c1b04d7..94afaff 100644 --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -841,35 +841,28 @@ const DILabel *MachineInstr::getDebugLabel() const { } const MachineOperand &MachineInstr::getDebugVariableOp() const { - assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE*"); - unsigned VariableOp = isDebugValueList() ? 0 : 2; - return getOperand(VariableOp); + assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE"); + return getOperand(2); } MachineOperand &MachineInstr::getDebugVariableOp() { - assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE*"); - unsigned VariableOp = isDebugValueList() ? 0 : 2; - return getOperand(VariableOp); + assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE"); + return getOperand(2); } const DILocalVariable *MachineInstr::getDebugVariable() const { - return cast(getDebugVariableOp().getMetadata()); -} - -const MachineOperand &MachineInstr::getDebugExpressionOp() const { - assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE*"); - unsigned ExpressionOp = isDebugValueList() ? 1 : 3; - return getOperand(ExpressionOp); + assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE"); + return cast(getOperand(2).getMetadata()); } MachineOperand &MachineInstr::getDebugExpressionOp() { - assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE*"); - unsigned ExpressionOp = isDebugValueList() ? 1 : 3; - return getOperand(ExpressionOp); + assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE"); + return getOperand(3); } const DIExpression *MachineInstr::getDebugExpression() const { - return cast(getDebugExpressionOp().getMetadata()); + assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE"); + return cast(getOperand(3).getMetadata()); } bool MachineInstr::isDebugEntryValue() const { @@ -1719,7 +1712,7 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, OS << " "; if (isDebugValue() && MO.isMetadata()) { - // Pretty print DBG_VALUE* instructions. + // Pretty print DBG_VALUE instructions. auto *DIV = dyn_cast(MO.getMetadata()); if (DIV && !DIV->getName().empty()) OS << "!\"" << DIV->getName() << '\"'; @@ -2123,8 +2116,8 @@ MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL, MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID, bool IsIndirect, - const MachineOperand &MO, - const MDNode *Variable, const MDNode *Expr) { + MachineOperand &MO, const MDNode *Variable, + const MDNode *Expr) { assert(isa(Variable) && "not a variable"); assert(cast(Expr)->isValid() && "not an expression"); assert(cast(Variable)->isValidLocationForIntrinsic(DL) && @@ -2138,28 +2131,7 @@ MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL, else MIB.addReg(0U, RegState::Debug); return MIB.addMetadata(Variable).addMetadata(Expr); -} - -MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL, - const MCInstrDesc &MCID, bool IsIndirect, - ArrayRef MOs, - const MDNode *Variable, const MDNode *Expr) { - assert(isa(Variable) && "not a variable"); - assert(cast(Expr)->isValid() && "not an expression"); - assert(cast(Variable)->isValidLocationForIntrinsic(DL) && - "Expected inlined-at fields to agree"); - if (MCID.Opcode == TargetOpcode::DBG_VALUE) - return BuildMI(MF, DL, MCID, IsIndirect, MOs[0], Variable, Expr); - - auto MIB = BuildMI(MF, DL, MCID); - MIB.addMetadata(Variable).addMetadata(Expr); - for (const MachineOperand &MO : MOs) - if (MO.isReg()) - MIB.addReg(MO.getReg(), RegState::Debug); - else - MIB.add(MO); - return MIB; -} + } MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB, MachineBasicBlock::iterator I, @@ -2183,22 +2155,10 @@ MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB, return MachineInstrBuilder(MF, *MI); } -MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB, - MachineBasicBlock::iterator I, - const DebugLoc &DL, const MCInstrDesc &MCID, - bool IsIndirect, ArrayRef MOs, - const MDNode *Variable, const MDNode *Expr) { - MachineFunction &MF = *BB.getParent(); - MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, MOs, Variable, Expr); - BB.insert(I, MI); - return MachineInstrBuilder(MF, *MI); -} - /// Compute the new DIExpression to use with a DBG_VALUE for a spill slot. /// This prepends DW_OP_deref when spilling an indirect DBG_VALUE. -static const DIExpression *computeExprForSpill(const MachineInstr &MI, - Register SpillReg) { - assert(MI.hasDebugOperandForReg(SpillReg) && "Spill Reg is not used in MI."); +static const DIExpression *computeExprForSpill(const MachineInstr &MI) { + assert(MI.getOperand(0).isReg() && "can't spill non-register"); assert(MI.getDebugVariable()->isValidLocationForIntrinsic(MI.getDebugLoc()) && "Expected inlined-at fields to agree"); @@ -2207,14 +2167,6 @@ static const DIExpression *computeExprForSpill(const MachineInstr &MI, assert(MI.getDebugOffset().getImm() == 0 && "DBG_VALUE with nonzero offset"); Expr = DIExpression::prepend(Expr, DIExpression::DerefBefore); - } else if (MI.isDebugValueList()) { - // We will replace the spilled register with a frame index, so - // immediately deref all references to the spilled register. - std::array Ops{{dwarf::DW_OP_deref}}; - for (const MachineOperand &Op : MI.getDebugOperandsForReg(SpillReg)) { - unsigned OpIdx = MI.getDebugOperandIndex(&Op); - Expr = DIExpression::appendOpsToArg(Expr, Ops, OpIdx); - } } return Expr; } @@ -2222,32 +2174,19 @@ static const DIExpression *computeExprForSpill(const MachineInstr &MI, MachineInstr *llvm::buildDbgValueForSpill(MachineBasicBlock &BB, MachineBasicBlock::iterator I, const MachineInstr &Orig, - int FrameIndex, Register SpillReg) { - const DIExpression *Expr = computeExprForSpill(Orig, SpillReg); - MachineInstrBuilder NewMI = - BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc()); - // Non-Variadic Operands: Location, Offset, Variable, Expression - // Variadic Operands: Variable, Expression, Locations... - if (Orig.isNonListDebugValue()) - NewMI.addFrameIndex(FrameIndex).addImm(0U); - NewMI.addMetadata(Orig.getDebugVariable()).addMetadata(Expr); - if (Orig.isDebugValueList()) { - for (const MachineOperand &Op : Orig.debug_operands()) - if (Op.isReg() && Op.getReg() == SpillReg) - NewMI.addFrameIndex(FrameIndex); - else - NewMI.add(MachineOperand(Op)); - } - return NewMI; -} - -void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex, - Register Reg) { - const DIExpression *Expr = computeExprForSpill(Orig, Reg); - if (Orig.isNonListDebugValue()) - Orig.getDebugOffset().ChangeToImmediate(0U); - for (MachineOperand &Op : Orig.getDebugOperandsForReg(Reg)) - Op.ChangeToFrameIndex(FrameIndex); + int FrameIndex) { + const DIExpression *Expr = computeExprForSpill(Orig); + return BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc()) + .addFrameIndex(FrameIndex) + .addImm(0U) + .addMetadata(Orig.getDebugVariable()) + .addMetadata(Expr); +} + +void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex) { + const DIExpression *Expr = computeExprForSpill(Orig); + Orig.getDebugOperand(0).ChangeToFrameIndex(FrameIndex); + Orig.getDebugOffset().ChangeToImmediate(0U); Orig.getDebugExpressionOp().setMetadata(Expr); } @@ -2262,7 +2201,7 @@ void MachineInstr::collectDebugValues( DI != DE; ++DI) { if (!DI->isDebugValue()) return; - if (DI->hasDebugOperandForReg(MI.getOperand(0).getReg())) + if (DI->getDebugOperandForReg(MI.getOperand(0).getReg())) DbgValues.push_back(&*DI); } } @@ -2280,15 +2219,14 @@ void MachineInstr::changeDebugValuesDefReg(Register Reg) { auto *DI = MO.getParent(); if (!DI->isDebugValue()) continue; - if (DI->hasDebugOperandForReg(DefReg)) { + if (DI->getDebugOperandForReg(DefReg)) { DbgValues.push_back(DI); } } // Propagate Reg to debug value instructions. for (auto *DBI : DbgValues) - for (MachineOperand &Op : DBI->getDebugOperandsForReg(DefReg)) - Op.setReg(Reg); + DBI->getDebugOperandForReg(DefReg)->setReg(Reg); } using MMOList = SmallVector; diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp index 58bb866..d7444ec 100644 --- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp +++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp @@ -530,11 +530,11 @@ bool MachineRegisterInfo::isConstantPhysReg(MCRegister PhysReg) const { /// specified register as undefined which causes the DBG_VALUE to be /// deleted during LiveDebugVariables analysis. void MachineRegisterInfo::markUsesInDebugValueAsUndef(Register Reg) const { - // Mark any DBG_VALUE* that uses Reg as undef (but don't delete it.) + // Mark any DBG_VALUE that uses Reg as undef (but don't delete it.) // We use make_early_inc_range because setReg invalidates the iterator. for (MachineInstr &UseMI : llvm::make_early_inc_range(use_instructions(Reg))) { - if (UseMI.isDebugValue() && UseMI.hasDebugOperandForReg(Reg)) - UseMI.setDebugValueUndef(); + if (UseMI.isDebugValue()) + UseMI.getDebugOperandForReg(Reg)->setReg(0U); } } diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index 91c6911..84bb292 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -1233,33 +1233,23 @@ void PEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &MF, // complex location that is interpreted as being a memory address. // This changes a pointer-valued variable to dereference that pointer, // which is incorrect. Fix by adding DW_OP_stack_value. - - if (MI.isNonListDebugValue()) { - unsigned PrependFlags = DIExpression::ApplyOffset; - if (!MI.isIndirectDebugValue() && !DIExpr->isComplex()) - PrependFlags |= DIExpression::StackValue; - - // If we have DBG_VALUE that is indirect and has a Implicit location - // expression need to insert a deref before prepending a Memory - // location expression. Also after doing this we change the DBG_VALUE - // to be direct. - if (MI.isIndirectDebugValue() && DIExpr->isImplicit()) { - SmallVector Ops = {dwarf::DW_OP_deref_size, Size}; - bool WithStackValue = true; - DIExpr = DIExpression::prependOpcodes(DIExpr, Ops, WithStackValue); - // Make the DBG_VALUE direct. - MI.getDebugOffset().ChangeToRegister(0, false); - } - DIExpr = TRI.prependOffsetExpression(DIExpr, PrependFlags, Offset); - } else { - // The debug operand at DebugOpIndex was a frame index at offset - // `Offset`; now the operand has been replaced with the frame - // register, we must add Offset with `register x, plus Offset`. - unsigned DebugOpIndex = MI.getDebugOperandIndex(&MI.getOperand(i)); - SmallVector Ops; - TRI.getOffsetOpcodes(Offset, Ops); - DIExpr = DIExpression::appendOpsToArg(DIExpr, Ops, DebugOpIndex); + unsigned PrependFlags = DIExpression::ApplyOffset; + if (!MI.isIndirectDebugValue() && !DIExpr->isComplex()) + PrependFlags |= DIExpression::StackValue; + + // If we have DBG_VALUE that is indirect and has a Implicit location + // expression need to insert a deref before prepending a Memory + // location expression. Also after doing this we change the DBG_VALUE + // to be direct. + if (MI.isIndirectDebugValue() && DIExpr->isImplicit()) { + SmallVector Ops = {dwarf::DW_OP_deref_size, Size}; + bool WithStackValue = true; + DIExpr = DIExpression::prependOpcodes(DIExpr, Ops, WithStackValue); + // Make the DBG_VALUE direct. + MI.getDebugOffset().ChangeToRegister(0, false); } + + DIExpr = TRI.prependOffsetExpression(DIExpr, PrependFlags, Offset); MI.getDebugExpressionOp().setMetadata(DIExpr); continue; } diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp index 79d6762..256faa2 100644 --- a/llvm/lib/CodeGen/RegAllocFast.cpp +++ b/llvm/lib/CodeGen/RegAllocFast.cpp @@ -408,8 +408,7 @@ void RegAllocFast::spill(MachineBasicBlock::iterator Before, Register VirtReg, // to just reference the stack slot. SmallVectorImpl &LRIDbgValues = LiveDbgValueMap[VirtReg]; for (MachineInstr *DBG : LRIDbgValues) { - MachineInstr *NewDV = - buildDbgValueForSpill(*MBB, Before, *DBG, FI, AssignedReg); + MachineInstr *NewDV = buildDbgValueForSpill(*MBB, Before, *DBG, FI); assert(NewDV->getParent() == MBB && "dangling parent pointer"); (void)NewDV; LLVM_DEBUG(dbgs() << "Inserting debug info due to spill:\n" << *NewDV); @@ -425,14 +424,9 @@ void RegAllocFast::spill(MachineBasicBlock::iterator Before, Register VirtReg, } // Rewrite unassigned dbg_values to use the stack slot. - // TODO We can potentially do this for list debug values as well if we know - // how the dbg_values are getting unassigned. - if (DBG->isNonListDebugValue()) { - MachineOperand &MO = DBG->getDebugOperand(0); - if (MO.isReg() && MO.getReg() == 0) { - updateDbgValueForSpill(*DBG, FI, 0); - } - } + MachineOperand &MO = DBG->getOperand(0); + if (MO.isReg() && MO.getReg() == 0) + updateDbgValueForSpill(*DBG, FI); } // Now this register is spilled there is should not be any DBG_VALUE // pointing to this register because they are all pointing to spilled value @@ -629,7 +623,8 @@ void RegAllocFast::assignDanglingDebugValues(MachineInstr &Definition, SmallVectorImpl &Dangling = UDBGValIter->second; for (MachineInstr *DbgValue : Dangling) { assert(DbgValue->isDebugValue()); - if (!DbgValue->hasDebugOperandForReg(VirtReg)) + MachineOperand &MO = DbgValue->getOperand(0); + if (!MO.isReg()) continue; // Test whether the physreg survives from the definition to the DBG_VALUE. @@ -644,11 +639,9 @@ void RegAllocFast::assignDanglingDebugValues(MachineInstr &Definition, break; } } - for (MachineOperand &MO : DbgValue->getDebugOperandsForReg(VirtReg)) { - MO.setReg(SetToReg); - if (SetToReg != 0) - MO.setIsRenamable(); - } + MO.setReg(SetToReg); + if (SetToReg != 0) + MO.setIsRenamable(); } Dangling.clear(); } @@ -1367,44 +1360,37 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) { } void RegAllocFast::handleDebugValue(MachineInstr &MI) { - SmallSet SeenRegisters; - for (MachineOperand &MO : MI.debug_operands()) { - // Ignore DBG_VALUEs that aren't based on virtual registers. These are - // mostly constants and frame indices. - if (!MO.isReg()) - continue; - Register Reg = MO.getReg(); - if (!Register::isVirtualRegister(Reg)) - continue; - // Only process each register once per MI, each use of that register will - // be updated if necessary. - if (!SeenRegisters.insert(Reg).second) - continue; + MachineOperand &MO = MI.getDebugOperand(0); - // Already spilled to a stackslot? - int SS = StackSlotForVirtReg[Reg]; - if (SS != -1) { - // Modify DBG_VALUE now that the value is in a spill slot. - updateDbgValueForSpill(MI, SS, Reg); - LLVM_DEBUG(dbgs() << "Rewrite DBG_VALUE for spilled memory: " << MI); - continue; - } + // Ignore DBG_VALUEs that aren't based on virtual registers. These are + // mostly constants and frame indices. + if (!MO.isReg()) + return; + Register Reg = MO.getReg(); + if (!Register::isVirtualRegister(Reg)) + return; - // See if this virtual register has already been allocated to a physical - // register or spilled to a stack slot. - LiveRegMap::iterator LRI = findLiveVirtReg(Reg); - if (LRI != LiveVirtRegs.end() && LRI->PhysReg) { - // Update every use of Reg within MI. - for (auto &RegMO : MI.getDebugOperandsForReg(Reg)) - setPhysReg(MI, RegMO, LRI->PhysReg); - } else { - DanglingDbgValues[Reg].push_back(&MI); - } + // Already spilled to a stackslot? + int SS = StackSlotForVirtReg[Reg]; + if (SS != -1) { + // Modify DBG_VALUE now that the value is in a spill slot. + updateDbgValueForSpill(MI, SS); + LLVM_DEBUG(dbgs() << "Rewrite DBG_VALUE for spilled memory: " << MI); + return; + } - // If Reg hasn't been spilled, put this DBG_VALUE in LiveDbgValueMap so - // that future spills of Reg will have DBG_VALUEs. - LiveDbgValueMap[Reg].push_back(&MI); + // See if this virtual register has already been allocated to a physical + // register or spilled to a stack slot. + LiveRegMap::iterator LRI = findLiveVirtReg(Reg); + if (LRI != LiveVirtRegs.end() && LRI->PhysReg) { + setPhysReg(MI, MO, LRI->PhysReg); + } else { + DanglingDbgValues[Reg].push_back(&MI); } + + // If Reg hasn't been spilled, put this DBG_VALUE in LiveDbgValueMap so + // that future spills of Reg will have DBG_VALUEs. + LiveDbgValueMap[Reg].push_back(&MI); } void RegAllocFast::handleBundle(MachineInstr &MI) { @@ -1486,12 +1472,13 @@ void RegAllocFast::allocateBasicBlock(MachineBasicBlock &MBB) { for (auto &UDBGPair : DanglingDbgValues) { for (MachineInstr *DbgValue : UDBGPair.second) { assert(DbgValue->isDebugValue() && "expected DBG_VALUE"); + MachineOperand &MO = DbgValue->getOperand(0); // Nothing to do if the vreg was spilled in the meantime. - if (!DbgValue->hasDebugOperandForReg(UDBGPair.first)) + if (!MO.isReg()) continue; LLVM_DEBUG(dbgs() << "Register did not survive for " << *DbgValue << '\n'); - DbgValue->setDebugValueUndef(); + MO.setReg(0); } } DanglingDbgValues.clear(); diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index ba2638e..973020c 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -1059,7 +1059,6 @@ unsigned DIExpression::ExprOperand::getSize() const { case dwarf::DW_OP_plus_uconst: case dwarf::DW_OP_LLVM_tag_offset: case dwarf::DW_OP_LLVM_entry_value: - case dwarf::DW_OP_LLVM_arg: case dwarf::DW_OP_regx: return 2; default: @@ -1116,7 +1115,6 @@ bool DIExpression::isValid() const { } case dwarf::DW_OP_LLVM_implicit_pointer: case dwarf::DW_OP_LLVM_convert: - case dwarf::DW_OP_LLVM_arg: case dwarf::DW_OP_LLVM_tag_offset: case dwarf::DW_OP_constu: case dwarf::DW_OP_plus_uconst: @@ -1272,30 +1270,6 @@ DIExpression *DIExpression::prepend(const DIExpression *Expr, uint8_t Flags, return prependOpcodes(Expr, Ops, StackValue, EntryValue); } -DIExpression *DIExpression::appendOpsToArg(const DIExpression *Expr, - ArrayRef Ops, - unsigned ArgNo, bool StackValue) { - assert(Expr && "Can't add ops to this expression"); - - // Handle non-variadic intrinsics by prepending the opcodes. - if (!any_of(Expr->expr_ops(), - [](auto Op) { return Op.getOp() == dwarf::DW_OP_LLVM_arg; })) { - assert(ArgNo == 0 && - "Location Index must be 0 for a non-variadic expression."); - SmallVector NewOps(Ops.begin(), Ops.end()); - return DIExpression::prependOpcodes(Expr, NewOps, StackValue); - } - - SmallVector NewOps; - for (auto Op : Expr->expr_ops()) { - Op.appendToVector(NewOps); - if (Op.getOp() == dwarf::DW_OP_LLVM_arg && Op.getArg(0) == ArgNo) - NewOps.insert(NewOps.end(), Ops.begin(), Ops.end()); - } - - return DIExpression::get(Expr->getContext(), NewOps); -} - DIExpression *DIExpression::prependOpcodes(const DIExpression *Expr, SmallVectorImpl &Ops, bool StackValue, diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 289df8e..672efdf 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -1210,8 +1210,7 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { } break; - case AArch64::DBG_VALUE: - case AArch64::DBG_VALUE_LIST: { + case AArch64::DBG_VALUE: { if (isVerbose() && OutStreamer->hasRawTextSupport()) { SmallString<128> TmpStr; raw_svector_ostream OS(TmpStr); @@ -1232,7 +1231,7 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { OutStreamer->emitCFIBKeyFrame(); return; } - } + } // Tail calls use pseudo instructions so they have the proper code-gen // attributes (isCall, isReturn, etc.). We lower them to the real diff --git a/llvm/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp b/llvm/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp index 0c1f741..756355f 100644 --- a/llvm/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp @@ -65,25 +65,16 @@ bool NVPTXPrologEpilogPass::runOnMachineFunction(MachineFunction &MF) { // way with simply the frame index and offset rather than any // target-specific addressing mode. if (MI.isDebugValue()) { - MachineOperand &Op = MI.getOperand(i); - assert( - MI.isDebugOperand(&Op) && - "Frame indices can only appear as a debug operand in a DBG_VALUE*" - " machine instruction"); + assert(i == 0 && "Frame indices can only appear as the first " + "operand of a DBG_VALUE machine instruction"); Register Reg; - auto Offset = - TFI.getFrameIndexReference(MF, Op.getIndex(), Reg); - Op.ChangeToRegister(Reg, /*isDef=*/false); - Op.setIsDebug(); - const DIExpression *DIExpr = MI.getDebugExpression(); - if (MI.isNonListDebugValue()) { - DIExpr = TRI.prependOffsetExpression(MI.getDebugExpression(), DIExpression::ApplyOffset, Offset); - } else { - SmallVector Ops; - TRI.getOffsetOpcodes(Offset, Ops); - unsigned OpIdx = MI.getDebugOperandIndex(&Op); - DIExpr = DIExpression::appendOpsToArg(DIExpr, Ops, OpIdx); - } + int64_t Offset = + TFI.getFrameIndexReference(MF, MI.getOperand(0).getIndex(), Reg) + .getFixed(); + MI.getOperand(0).ChangeToRegister(Reg, /*isDef=*/false); + MI.getOperand(0).setIsDebug(); + auto *DIExpr = DIExpression::prepend( + MI.getDebugExpression(), DIExpression::ApplyOffset, Offset); MI.getDebugExpressionOp().setMetadata(DIExpr); continue; } diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp index da91316..055daf3 100644 --- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp @@ -9,13 +9,12 @@ #include "SystemZRegisterInfo.h" #include "SystemZInstrInfo.h" #include "SystemZSubtarget.h" -#include "llvm/ADT/SmallSet.h" #include "llvm/CodeGen/LiveIntervals.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/TargetFrameLowering.h" #include "llvm/CodeGen/VirtRegMap.h" -#include "llvm/IR/DebugInfoMetadata.h" using namespace llvm; @@ -274,16 +273,7 @@ SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI, // Special handling of dbg_value instructions. if (MI->isDebugValue()) { MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, /*isDef*/ false); - if (MI->isNonListDebugValue()) { - MI->getDebugOffset().ChangeToImmediate(Offset); - } else { - unsigned OpIdx = MI->getDebugOperandIndex(&MI->getOperand(FIOperandNum)); - SmallVector Ops; - DIExpression::appendOffset( - Ops, TFI->getFrameIndexReference(MF, FrameIndex, BasePtr).getFixed()); - MI->getDebugExpressionOp().setMetadata( - DIExpression::appendOpsToArg(MI->getDebugExpression(), Ops, OpIdx)); - } + MI->getDebugOffset().ChangeToImmediate(Offset); return; } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp index d511fde..c63656a 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp @@ -30,7 +30,7 @@ WebAssemblyDebugValueManager::WebAssemblyDebugValueManager( for (MachineBasicBlock::iterator DE = Instr->getParent()->end(); DI != DE; ++DI) { if (DI->isDebugValue() && - DI->hasDebugOperandForReg(Instr->getOperand(0).getReg())) + DI->getDebugOperandForReg(Instr->getOperand(0).getReg())) DbgValues.push_back(&*DI); } } diff --git a/llvm/lib/Target/X86/X86OptimizeLEAs.cpp b/llvm/lib/Target/X86/X86OptimizeLEAs.cpp index 220fd0b..c8899a8 100644 --- a/llvm/lib/Target/X86/X86OptimizeLEAs.cpp +++ b/llvm/lib/Target/X86/X86OptimizeLEAs.cpp @@ -295,8 +295,8 @@ private: /// Replace debug value MI with a new debug value instruction using register /// VReg with an appropriate offset and DIExpression to incorporate the /// address displacement AddrDispShift. Return new debug value instruction. - MachineInstr *replaceDebugValue(MachineInstr &MI, unsigned OldReg, - unsigned NewReg, int64_t AddrDispShift); + MachineInstr *replaceDebugValue(MachineInstr &MI, unsigned VReg, + int64_t AddrDispShift); /// Removes LEAs which calculate similar addresses. bool removeRedundantLEAs(MemOpMap &LEAs); @@ -576,50 +576,21 @@ bool X86OptimizeLEAPass::removeRedundantAddrCalc(MemOpMap &LEAs) { } MachineInstr *X86OptimizeLEAPass::replaceDebugValue(MachineInstr &MI, - unsigned OldReg, - unsigned NewReg, + unsigned VReg, int64_t AddrDispShift) { const DIExpression *Expr = MI.getDebugExpression(); - if (AddrDispShift != 0) { - if (MI.isNonListDebugValue()) { - Expr = - DIExpression::prepend(Expr, DIExpression::StackValue, AddrDispShift); - } else { - // Update the Expression, appending an offset of `AddrDispShift` to the - // Op corresponding to `OldReg`. - SmallVector Ops; - DIExpression::appendOffset(Ops, AddrDispShift); - for (MachineOperand &Op : MI.getDebugOperandsForReg(OldReg)) { - unsigned OpIdx = MI.getDebugOperandIndex(&Op); - Expr = DIExpression::appendOpsToArg(Expr, Ops, OpIdx); - } - } - } + if (AddrDispShift != 0) + Expr = DIExpression::prepend(Expr, DIExpression::StackValue, AddrDispShift); // Replace DBG_VALUE instruction with modified version. MachineBasicBlock *MBB = MI.getParent(); DebugLoc DL = MI.getDebugLoc(); bool IsIndirect = MI.isIndirectDebugValue(); const MDNode *Var = MI.getDebugVariable(); - unsigned Opcode = MI.isNonListDebugValue() ? TargetOpcode::DBG_VALUE - : TargetOpcode::DBG_VALUE_LIST; if (IsIndirect) - assert(MI.getDebugOffset().getImm() == 0 && - "DBG_VALUE with nonzero offset"); - SmallVector NewOps; - // If we encounter an operand using the old register, replace it with an - // operand that uses the new register; otherwise keep the old operand. - auto replaceOldReg = [OldReg, NewReg](const MachineOperand &Op) { - if (Op.isReg() && Op.getReg() == OldReg) - return MachineOperand::CreateReg(NewReg, false, false, false, false, - false, false, false, false, 0, - /*IsRenamable*/ true); - return Op; - }; - for (const MachineOperand &Op : MI.debug_operands()) - NewOps.push_back(replaceOldReg(Op)); - return BuildMI(*MBB, MBB->erase(&MI), DL, TII->get(Opcode), IsIndirect, - NewOps, Var, Expr); + assert(MI.getOperand(1).getImm() == 0 && "DBG_VALUE with nonzero offset"); + return BuildMI(*MBB, MBB->erase(&MI), DL, TII->get(TargetOpcode::DBG_VALUE), + IsIndirect, VReg, Var, Expr); } // Try to find similar LEAs in the list and replace one with another. @@ -664,7 +635,7 @@ bool X86OptimizeLEAPass::removeRedundantLEAs(MemOpMap &LEAs) { // Replace DBG_VALUE instruction with modified version using the // register from the replacing LEA and the address displacement // between the LEA instructions. - replaceDebugValue(MI, LastVReg, FirstVReg, AddrDispShift); + replaceDebugValue(MI, FirstVReg, AddrDispShift); continue; } diff --git a/llvm/test/CodeGen/MIR/Generic/dbg-value-list.mir b/llvm/test/CodeGen/MIR/Generic/dbg-value-list.mir deleted file mode 100644 index e17843a..0000000 --- a/llvm/test/CodeGen/MIR/Generic/dbg-value-list.mir +++ /dev/null @@ -1,64 +0,0 @@ -# RUN: llc -run-pass machineverifier -o - %s | FileCheck %s -# Simple round-trip test for DBG_VALUE_LIST. -# CHECK: [[VAR_C:![0-9]+]] = !DILocalVariable(name: "c" -# CHECK: DBG_VALUE_LIST [[VAR_C]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value), $edi, $esi, debug-location ---- | - ; ModuleID = 'test.cpp' - source_filename = "test.cpp" - target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" - target triple = "x86_64-unknown-linux-gnu" - - ; Function Attrs: norecurse nounwind readnone uwtable - define dso_local i32 @_Z3fooii(i32 %a, i32 %b) local_unnamed_addr !dbg !7 { - entry: - call void @llvm.dbg.value(metadata i32 %a, metadata !12, metadata !DIExpression()), !dbg !15 - call void @llvm.dbg.value(metadata i32 %b, metadata !13, metadata !DIExpression()), !dbg !15 - call void @llvm.dbg.value(metadata i32 undef, metadata !14, metadata !DIExpression()), !dbg !15 - %mul = mul nsw i32 %b, %a, !dbg !16 - ret i32 %mul, !dbg !17 - } - - ; Function Attrs: nounwind readnone speculatable willreturn - declare void @llvm.dbg.value(metadata, metadata, metadata) - - !llvm.dbg.cu = !{!0} - !llvm.module.flags = !{!3, !4, !5} - !llvm.ident = !{!6} - - !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 11.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) - !1 = !DIFile(filename: "test.cpp", directory: "/") - !2 = !{} - !3 = !{i32 7, !"Dwarf Version", i32 4} - !4 = !{i32 2, !"Debug Info Version", i32 3} - !5 = !{i32 1, !"wchar_size", i32 4} - !6 = !{!"clang version 11.0.0"} - !7 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooii", scope: !1, file: !1, line: 2, type: !8, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11) - !8 = !DISubroutineType(types: !9) - !9 = !{!10, !10, !10} - !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) - !11 = !{!12, !13, !14} - !12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 2, type: !10) - !13 = !DILocalVariable(name: "b", arg: 2, scope: !7, file: !1, line: 2, type: !10) - !14 = !DILocalVariable(name: "c", scope: !7, file: !1, line: 3, type: !10) - !15 = !DILocation(line: 0, scope: !7) - !16 = !DILocation(line: 4, column: 12, scope: !7) - !17 = !DILocation(line: 4, column: 3, scope: !7) - -... ---- -name: _Z3fooii -body: | - bb.0.entry: - liveins: $edi, $esi - - DBG_VALUE $edi, $noreg, !12, !DIExpression(), debug-location !15 - DBG_VALUE $esi, $noreg, !13, !DIExpression(), debug-location !15 - $eax = MOV32rr $edi - DBG_VALUE_LIST !14, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value), $edi, $esi, debug-location !15 - DBG_VALUE $esi, $noreg, !13, !DIExpression(), debug-location !15 - DBG_VALUE $eax, $noreg, !12, !DIExpression(), debug-location !15 - renamable $eax = nsw IMUL32rr killed renamable $eax, killed renamable $esi, implicit-def dead $eflags, debug-location !16 - RETQ $eax, debug-location !17 - -... - -- 2.7.4