From 5561f87ef2b035e5537af00ed44cfeddd9d2f106 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Wed, 2 Nov 2016 16:12:20 +0000 Subject: [PATCH] Simplify control flow in the the DWARF expression compiler by refactoring common code into a DwarfExpressionCursor wrapper. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285827 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/DebugInfoMetadata.h | 2 + lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 29 ++++----- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 15 ++--- lib/CodeGen/AsmPrinter/DwarfExpression.cpp | 69 +++++++++------------ lib/CodeGen/AsmPrinter/DwarfExpression.h | 61 +++++++++++++++--- 5 files changed, 107 insertions(+), 69 deletions(-) diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index ba0d5c4f678..15d12734301 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -1951,6 +1951,7 @@ public: const uint64_t *Op; public: + ExprOperand() : Op(nullptr) {}; explicit ExprOperand(const uint64_t *Op) : Op(Op) {} const uint64_t *get() const { return Op; } @@ -1977,6 +1978,7 @@ public: ExprOperand Op; public: + expr_op_iterator() = default; explicit expr_op_iterator(element_iterator I) : Op(I) {} element_iterator getBase() const { return Op.get(); } diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 9345fac2a99..8b5df7c7aef 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -176,7 +176,7 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE( if (Expr) { DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); - DwarfExpr.AddExpression(Expr->expr_op_begin(), Expr->expr_op_end()); + DwarfExpr.AddExpression(Expr); } } @@ -495,7 +495,7 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); // If there is an expression, emit raw unsigned bytes. DwarfExpr.AddUnsignedConstant(DVInsn->getOperand(0).getImm()); - DwarfExpr.AddExpression(Expr->expr_op_begin(), Expr->expr_op_end()); + DwarfExpr.AddExpression(Expr); addBlock(*VariableDie, dwarf::DW_AT_location, Loc); } else addConstantValue(*VariableDie, DVInsn->getOperand(0), DV.getType()); @@ -522,7 +522,7 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, assert(Expr != DV.getExpression().end() && "Wrong number of expressions"); DwarfExpr.AddMachineRegIndirect(*Asm->MF->getSubtarget().getRegisterInfo(), FrameReg, Offset); - DwarfExpr.AddExpression((*Expr)->expr_op_begin(), (*Expr)->expr_op_end()); + DwarfExpr.AddExpression(*Expr); ++Expr; } addBlock(*VariableDie, dwarf::DW_AT_location, Loc); @@ -746,20 +746,21 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, const MachineLocation &Location) { DIELoc *Loc = new (DIEValueAllocator) DIELoc; DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); - const DIExpression *Expr = DV.getSingleExpression(); - bool ValidReg; + DIExpressionCursor ExprCursor(DV.getSingleExpression()); const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); - if (Location.getOffset()) { - ValidReg = DwarfExpr.AddMachineRegIndirect(TRI, Location.getReg(), - Location.getOffset()); - if (ValidReg) - DwarfExpr.AddExpression(Expr->expr_op_begin(), Expr->expr_op_end()); - } else - ValidReg = DwarfExpr.AddMachineRegExpression(TRI, Expr, Location.getReg()); + auto Reg = Location.getReg(); + bool ValidReg = + Location.getOffset() + ? DwarfExpr.AddMachineRegIndirect(TRI, Reg, Location.getOffset()) + : DwarfExpr.AddMachineRegExpression(TRI, ExprCursor, Reg); + + if (!ValidReg) + return; + + DwarfExpr.AddExpression(std::move(ExprCursor)); // Now attach the location information to the DIE. - if (ValidReg) - addBlock(Die, Attribute, Loc); + addBlock(Die, Attribute, Loc); } /// Add a Dwarf loclistptr attribute data and value. diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index d98524b66cc..ef21f6bb9c1 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1406,7 +1406,7 @@ static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, ByteStreamer &Streamer, const DebugLocEntry::Value &Value, unsigned PieceOffsetInBits) { - const DIExpression *Expr = Value.getExpression(); + DIExpressionCursor ExprCursor(Value.getExpression()); DebugLocDwarfExpression DwarfExpr(AP.getDwarfDebug()->getDwarfVersion(), Streamer); // Regular entry. @@ -1418,26 +1418,23 @@ static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, DwarfExpr.AddUnsignedConstant(Value.getInt()); } else if (Value.isLocation()) { MachineLocation Loc = Value.getLoc(); - if (!Expr || !Expr->getNumElements()) + if (!ExprCursor) // Regular entry. AP.EmitDwarfRegOp(Streamer, Loc); else { // Complex address entry. const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo(); - if (Loc.getOffset()) { + if (Loc.getOffset()) DwarfExpr.AddMachineRegIndirect(TRI, Loc.getReg(), Loc.getOffset()); - } else { - DwarfExpr.AddMachineRegExpression(TRI, Expr, Loc.getReg(), + else + DwarfExpr.AddMachineRegExpression(TRI, ExprCursor, Loc.getReg(), PieceOffsetInBits); - return; - } } } else if (Value.isConstantFP()) { APInt RawBytes = Value.getConstantFP()->getValueAPF().bitcastToAPInt(); DwarfExpr.AddUnsignedConstant(RawBytes); } - DwarfExpr.AddExpression(Expr->expr_op_begin(), Expr->expr_op_end(), - PieceOffsetInBits); + DwarfExpr.AddExpression(std::move(ExprCursor), PieceOffsetInBits); } void DebugLocEntry::finalize(const AsmPrinter &AP, diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index d3e63e3b34f..12273aa1824 100644 --- a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -203,76 +203,69 @@ static unsigned getOffsetOrZero(unsigned OffsetInBits, } bool DwarfExpression::AddMachineRegExpression(const TargetRegisterInfo &TRI, - const DIExpression *Expr, + DIExpressionCursor &ExprCursor, unsigned MachineReg, unsigned PieceOffsetInBits) { - auto I = Expr->expr_op_begin(); - auto E = Expr->expr_op_end(); - if (I == E) + if (!ExprCursor) return AddMachineRegPiece(TRI, MachineReg); // Pattern-match combinations for which more efficient representations exist // first. bool ValidReg = false; - switch (I->getOp()) { + auto Op = ExprCursor.peek(); + switch (Op->getOp()) { case dwarf::DW_OP_bit_piece: { - unsigned OffsetInBits = I->getArg(0); - unsigned SizeInBits = I->getArg(1); + unsigned OffsetInBits = Op->getArg(0); + unsigned SizeInBits = Op->getArg(1); // Piece always comes at the end of the expression. - return AddMachineRegPiece(TRI, MachineReg, SizeInBits, - getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); + AddMachineRegPiece(TRI, MachineReg, SizeInBits, + getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); + ExprCursor.take(); + break; } case dwarf::DW_OP_plus: case dwarf::DW_OP_minus: { // [DW_OP_reg,Offset,DW_OP_plus, DW_OP_deref] --> [DW_OP_breg, Offset]. // [DW_OP_reg,Offset,DW_OP_minus,DW_OP_deref] --> [DW_OP_breg,-Offset]. - auto N = I.getNext(); - if (N != E && N->getOp() == dwarf::DW_OP_deref) { - unsigned Offset = I->getArg(0); + auto N = ExprCursor.peekNext(); + if (N && N->getOp() == dwarf::DW_OP_deref) { + unsigned Offset = Op->getArg(0); ValidReg = AddMachineRegIndirect( - TRI, MachineReg, I->getOp() == dwarf::DW_OP_plus ? Offset : -Offset); - std::advance(I, 2); - break; + TRI, MachineReg, Op->getOp() == dwarf::DW_OP_plus ? Offset : -Offset); + ExprCursor.consume(2); } else ValidReg = AddMachineRegPiece(TRI, MachineReg); + break; } - case dwarf::DW_OP_deref: { - // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg]. - ValidReg = AddMachineRegIndirect(TRI, MachineReg); - ++I; - break; - } - default: - llvm_unreachable("unsupported operand"); + case dwarf::DW_OP_deref: + // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg]. + ValidReg = AddMachineRegIndirect(TRI, MachineReg); + ExprCursor.take(); + break; } - if (!ValidReg) - return false; - - // Emit remaining elements of the expression. - AddExpression(I, E, PieceOffsetInBits); - return true; + return ValidReg; } -void DwarfExpression::AddExpression(DIExpression::expr_op_iterator I, - DIExpression::expr_op_iterator E, +void DwarfExpression::AddExpression(DIExpressionCursor &&ExprCursor, unsigned PieceOffsetInBits) { - for (; I != E; ++I) { - switch (I->getOp()) { + while (ExprCursor) { + auto Op = ExprCursor.take(); + switch (Op->getOp()) { case dwarf::DW_OP_bit_piece: { - unsigned OffsetInBits = I->getArg(0); - unsigned SizeInBits = I->getArg(1); + unsigned OffsetInBits = Op->getArg(0); + unsigned SizeInBits = Op->getArg(1); AddOpPiece(SizeInBits, getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); break; } case dwarf::DW_OP_plus: EmitOp(dwarf::DW_OP_plus_uconst); - EmitUnsigned(I->getArg(0)); + EmitUnsigned(Op->getArg(0)); break; case dwarf::DW_OP_minus: // There is no OP_minus_uconst. EmitOp(dwarf::DW_OP_constu); - EmitUnsigned(I->getArg(0)); + EmitUnsigned(Op->getArg(0)); EmitOp(dwarf::DW_OP_minus); break; case dwarf::DW_OP_deref: @@ -280,7 +273,7 @@ void DwarfExpression::AddExpression(DIExpression::expr_op_iterator I, break; case dwarf::DW_OP_constu: EmitOp(dwarf::DW_OP_constu); - EmitUnsigned(I->getArg(0)); + EmitUnsigned(Op->getArg(0)); break; case dwarf::DW_OP_stack_value: AddStackValue(); diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.h b/lib/CodeGen/AsmPrinter/DwarfExpression.h index 5fff28d8a13..89768a3c3d3 100644 --- a/lib/CodeGen/AsmPrinter/DwarfExpression.h +++ b/lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -25,6 +25,51 @@ class TargetRegisterInfo; class DwarfUnit; class DIELoc; +/// Holds a DIExpression and keeps track of how many operands have been consumed +/// so far. +class DIExpressionCursor { + DIExpression::expr_op_iterator Start, End; +public: + DIExpressionCursor(const DIExpression *Expr) { + if (!Expr) { + assert(Start == End); + return; + } + Start = Expr->expr_op_begin(); + End = Expr->expr_op_end(); + } + + /// Consume one operation. + Optional take() { + if (Start == End) + return None; + return *(Start++); + } + + /// Consume N operations. + void consume(unsigned N) { std::advance(Start, N); } + + /// Return the current operation. + Optional peek() const { + if (Start == End) + return None; + return *(Start); + } + + /// Return the next operation. + Optional peekNext() const { + if (Start == End) + return None; + + auto Next = Start.getNext(); + if (Next == End) + return None; + + return *Next; + } + operator bool() const { return Start != End; } +}; + /// Base class containing the logic for constructing DWARF expressions /// independently of whether they are emitted into a DIE or into a .debug_loc /// entry. @@ -77,7 +122,7 @@ public: bool AddMachineRegIndirect(const TargetRegisterInfo &TRI, unsigned MachineReg, int Offset = 0); - /// \brief Emit a partial DWARF register operation. + /// Emit a partial DWARF register operation. /// \param MachineReg the register /// \param PieceSizeInBits size and /// \param PieceOffsetInBits offset of the piece in bits, if this is one @@ -102,19 +147,19 @@ public: /// Emit an unsigned constant. void AddUnsignedConstant(const APInt &Value); - /// \brief Emit an entire expression on top of a machine register location. + /// Emit a machine register location while consuming the prefix of a + /// DwarfExpression. /// - /// \param PieceOffsetInBits If this is one piece out of a fragmented + /// \param PieceOffsetInBits If this is one piece out of a fragmented /// location, this is the offset of the piece inside the entire variable. /// \return false if no DWARF register exists for MachineReg. bool AddMachineRegExpression(const TargetRegisterInfo &TRI, - const DIExpression *Expr, unsigned MachineReg, + DIExpressionCursor &Expr, unsigned MachineReg, unsigned PieceOffsetInBits = 0); - /// Emit a the operations remaining the DIExpressionIterator I. - /// \param PieceOffsetInBits If this is one piece out of a fragmented + /// Emit all remaining operations in the DIExpressionCursor. + /// \param PieceOffsetInBits If this is one piece out of a fragmented /// location, this is the offset of the piece inside the entire variable. - void AddExpression(DIExpression::expr_op_iterator I, - DIExpression::expr_op_iterator E, + void AddExpression(DIExpressionCursor &&Expr, unsigned PieceOffsetInBits = 0); }; -- 2.40.0