Index: include/llvm/CodeGen/AsmPrinter.h =================================================================== --- include/llvm/CodeGen/AsmPrinter.h +++ include/llvm/CodeGen/AsmPrinter.h @@ -433,10 +433,6 @@ /// Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified. virtual unsigned getISAEncoding(const Function *) { return 0; } - /// EmitDwarfRegOp - Emit a dwarf register operation. - virtual void EmitDwarfRegOp(ByteStreamer &BS, - const MachineLocation &MLoc) const; - //===------------------------------------------------------------------===// // Dwarf Lowering Routines //===------------------------------------------------------------------===// Index: lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -180,36 +180,6 @@ EmitLabelDifference(Label, Label->getSection().getBeginSymbol(), 4); } -/// EmitDwarfRegOp - Emit dwarf register operation. -void AsmPrinter::EmitDwarfRegOp(ByteStreamer &Streamer, - const MachineLocation &MLoc) const { - DebugLocDwarfExpression Expr(*MF->getSubtarget().getRegisterInfo(), - getDwarfDebug()->getDwarfVersion(), Streamer); - const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo(); - int Reg = MRI->getDwarfRegNum(MLoc.getReg(), false); - if (Reg < 0) { - // We assume that pointers are always in an addressable register. - if (MLoc.isIndirect()) - // FIXME: We have no reasonable way of handling errors in here. The - // caller might be in the middle of a dwarf expression. We should - // probably assert that Reg >= 0 once debug info generation is more - // mature. - return Expr.EmitOp(dwarf::DW_OP_nop, - "nop (could not find a dwarf register number)"); - - // Attempt to find a valid super- or sub-register. - if (!Expr.AddMachineRegPiece(MLoc.getReg())) - Expr.EmitOp(dwarf::DW_OP_nop, - "nop (could not find a dwarf register number)"); - return; - } - - if (MLoc.isIndirect()) - Expr.AddRegIndirect(Reg, MLoc.getOffset()); - else - Expr.AddReg(Reg); -} - //===----------------------------------------------------------------------===// // Dwarf Lowering Routines //===----------------------------------------------------------------------===// Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -197,7 +197,8 @@ MachineLocation Location); /// Add an address attribute to a die based on the location provided. void addAddress(DIE &Die, dwarf::Attribute Attribute, - const MachineLocation &Location); + const MachineLocation &Location, + bool MayUsePieceForSubRegMask = false); /// Start with the address based on the location provided, and generate the /// DWARF information necessary to find the actual variable (navigating the Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -743,21 +743,23 @@ else if (DV.isBlockByrefVariable()) addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location); else - addAddress(Die, dwarf::DW_AT_location, Location); + addAddress(Die, dwarf::DW_AT_location, Location, + /*MayUsePieceForSubRegMask*/ true); } /// Add an address attribute to a die based on the location provided. void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, - const MachineLocation &Location) { + const MachineLocation &Location, + bool MayUsePieceForSubRegMask) { DIELoc *Loc = new (DIEValueAllocator) DIELoc(); - bool validReg; - if (Location.isReg()) - validReg = addRegisterOpPiece(*Loc, Location.getReg()); - else - validReg = addRegisterOffset(*Loc, Location.getReg(), Location.getOffset()); + DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); + bool ValidReg = Location.isIndirect() + ? DwarfExpr.AddMachineRegIndirect(Location.getReg(), Location.getOffset()) + : DwarfExpr.AddMachineRegPiece(Location.getReg(), 0, 0, + MayUsePieceForSubRegMask); - if (!validReg) + if (!ValidReg) return; // Now attach the location information to the DIE. Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1531,10 +1531,17 @@ } else if (Value.isLocation()) { MachineLocation Loc = Value.getLoc(); DIExpression Expr = Value.getExpression(); - if (!Expr || (Expr.getNumElements() == 0)) + if (!Expr || (Expr.getNumElements() == 0)) { // Regular entry. - AP.EmitDwarfRegOp(Streamer, Loc); - else { + bool ValidReg = Loc.isIndirect() + ? DwarfExpr.AddMachineRegIndirect(Loc.getReg(), Loc.getOffset()) + : DwarfExpr.AddMachineRegPiece(Loc.getReg(), 0, 0, + /*MayUsePieceForSubRegMask*/true); + + if (!ValidReg) + DwarfExpr.EmitOp(dwarf::DW_OP_nop, + "nop (could not find a dwarf register number)"); + } else { // Complex address entry. if (Loc.getOffset()) { DwarfExpr.AddMachineRegIndirect(Loc.getReg(), Loc.getOffset()); Index: lib/CodeGen/AsmPrinter/DwarfExpression.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfExpression.h +++ lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -55,12 +55,10 @@ /// Emit an (double-)indirect dwarf register operation. void AddRegIndirect(int DwarfReg, int Offset, bool Deref = false); - /// Emit a dwarf register operation for describing + /// Emit a dwarf operation for describing /// - a small value occupying only part of a register or /// - a register representing only part of a value. void AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0); - /// Emit a shift-right dwarf expression. - void AddShr(unsigned ShiftBy); /// Emit an indirect dwarf register operation for the given machine register. /// \return false if no DWARF register exists for MachineReg. @@ -71,6 +69,10 @@ /// \param PieceSizeInBits size and /// \param PieceOffsetInBits offset of the piece in bits, if this is one /// piece of an aggregate value. + /// \param MayEmitOpPiece Controls whether DW_OP_piece may be emitted to + /// construct super-registers or mask subregisters at + /// offet 0. If any of the previous two parameters + /// are nonzero, then this must be true. /// /// If size and offset is zero an operation for the entire /// register is emitted: Some targets do not provide a DWARF @@ -81,7 +83,8 @@ /// /// \return false if no DWARF register exists for MachineReg. bool AddMachineRegPiece(unsigned MachineReg, unsigned PieceSizeInBits = 0, - unsigned PieceOffsetInBits = 0); + unsigned PieceOffsetInBits = 0, + bool MayEmitOpPiece = false); /// Emit a signed constant. void AddSignedConstant(int Value); Index: lib/CodeGen/AsmPrinter/DwarfExpression.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -59,12 +59,6 @@ } } -void DwarfExpression::AddShr(unsigned ShiftBy) { - EmitOp(dwarf::DW_OP_constu); - EmitUnsigned(ShiftBy); - EmitOp(dwarf::DW_OP_shr); -} - bool DwarfExpression::AddMachineRegIndirect(unsigned MachineReg, int Offset) { if (isFrameRegister(MachineReg)) { // If variable offset is based in frame register then use fbreg. @@ -83,7 +77,11 @@ bool DwarfExpression::AddMachineRegPiece(unsigned MachineReg, unsigned PieceSizeInBits, - unsigned PieceOffsetInBits) { + unsigned PieceOffsetInBits, + bool MayEmitOpPiece) { + assert((PieceOffsetInBits || PieceSizeInBits) ? MayEmitOpPiece : true && + "piece requested, but MayEmitOpPiece is false"); + if (!TRI.isPhysicalRegister(MachineReg)) return false; @@ -103,24 +101,39 @@ Reg = TRI.getDwarfRegNum(*SR, false); if (Reg >= 0) { unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg); - unsigned Size = TRI.getSubRegIdxSize(Idx); - unsigned RegOffset = TRI.getSubRegIdxOffset(Idx); + uint64_t SubRegSize = TRI.getSubRegIdxSize(Idx); + uint64_t SubRegOffset = TRI.getSubRegIdxOffset(Idx); AddReg(Reg, "super-register"); - if (PieceOffsetInBits == RegOffset) { - AddOpPiece(Size, RegOffset); - } else { - // If this is part of a variable in a sub-register at a - // non-zero offset, we need to manually shift the value into - // place, since the DW_OP_piece describes the part of the - // variable, not the position of the subregister. - if (RegOffset) - AddShr(RegOffset); - AddOpPiece(Size, PieceOffsetInBits); + // If this is in a sub-register at a non-zero offset, we need to manually + // shift the value into place, since the DW_OP_piece describes the part of + // the variable, not the position of the subregister. + if (SubRegOffset > 0) { + EmitOp(dwarf::DW_OP_constu); + EmitUnsigned(SubRegOffset); + EmitOp(dwarf::DW_OP_shr); } + if (MayEmitOpPiece && SubRegOffset == 0) { + // Use the shorter DW_OP_piece to describe a subregister at offset 0. + PieceSizeInBits = SubRegSize; + } else if (SubRegSize > PieceSizeInBits) { + // Mask out the uninteresting higher bits. + // Use a DW_OP_and with a constant for this, because the size of DWARF + // stack elements is not well defined. + assert(SubRegSize <= 64 && "cannot create a mask larger than 64 bits"); + uint64_t Mask = ~uint64_t(0ULL) >> (64 - SubRegSize); + EmitOp(dwarf::DW_OP_constu); + EmitUnsigned(Mask); + EmitOp(dwarf::DW_OP_and); + } + if (PieceSizeInBits) + AddOpPiece(PieceSizeInBits, PieceOffsetInBits); return true; } } + if (!MayEmitOpPiece) + return false; + // Otherwise, attempt to find a covering set of sub-register numbers. // For example, Q0 on ARM is a composition of D0+D1. // @@ -209,7 +222,7 @@ unsigned SizeInBits = I->getArg(2); // Piece always comes at the end of the expression. return AddMachineRegPiece(MachineReg, SizeInBits, - getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); + getOffsetOrZero(OffsetInBits, PieceOffsetInBits), true); } case dwarf::DW_OP_plus: { // [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset]. Index: lib/CodeGen/AsmPrinter/DwarfUnit.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfUnit.h +++ lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -258,17 +258,6 @@ /// addTemplateParams - Add template parameters in buffer. void addTemplateParams(DIE &Buffer, DIArray TParams); - /// \brief Add register operand. - /// \returns false if the register does not exist, e.g., because it was never - /// materialized. - bool addRegisterOpPiece(DIELoc &TheDie, unsigned Reg, - unsigned SizeInBits = 0, unsigned OffsetInBits = 0); - - /// \brief Add register offset. - /// \returns false if the register does not exist, e.g., because it was never - /// materialized. - bool addRegisterOffset(DIELoc &TheDie, unsigned Reg, int64_t Offset); - // FIXME: Should be reformulated in terms of addComplexAddress. /// addBlockByrefAddress - Start with the address based on the location /// provided, and generate the DWARF information necessary to find the Index: lib/CodeGen/AsmPrinter/DwarfUnit.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -445,21 +445,6 @@ addSourceLine(Die, NS.getLineNumber(), NS.getFilename(), NS.getDirectory()); } -/// addRegisterOp - Add register operand. -bool DwarfUnit::addRegisterOpPiece(DIELoc &TheDie, unsigned Reg, - unsigned SizeInBits, unsigned OffsetInBits) { - DIEDwarfExpression Expr(*Asm, *this, TheDie); - Expr.AddMachineRegPiece(Reg, SizeInBits, OffsetInBits); - return true; -} - -/// addRegisterOffset - Add register offset. -bool DwarfUnit::addRegisterOffset(DIELoc &TheDie, unsigned Reg, - int64_t Offset) { - DIEDwarfExpression Expr(*Asm, *this, TheDie); - return Expr.AddMachineRegIndirect(Reg, Offset); -} - /* Byref variables, in Blocks, are declared by the programmer as "SomeType VarName;", but the compiler creates a __Block_byref_x_VarName struct, and gives the variable VarName either the struct, or a pointer to the struct, as @@ -561,13 +546,13 @@ // variable's location. DIELoc *Loc = new (DIEValueAllocator) DIELoc(); - bool validReg; - if (Location.isReg()) - validReg = addRegisterOpPiece(*Loc, Location.getReg()); - else - validReg = addRegisterOffset(*Loc, Location.getReg(), Location.getOffset()); + DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); + bool ValidReg = Location.isIndirect() + ? DwarfExpr.AddMachineRegIndirect(Location.getReg(), Location.getOffset()) + : DwarfExpr.AddMachineRegPiece(Location.getReg(), 0, 0, + /*MayUsePieceForSubRegMask*/true); - if (!validReg) + if (!ValidReg) return; // If we started with a pointer to the __Block_byref... struct, then Index: test/DebugInfo/X86/frame-register.ll =================================================================== --- test/DebugInfo/X86/frame-register.ll +++ test/DebugInfo/X86/frame-register.ll @@ -1,11 +1,14 @@ ; RUN: llc %s -filetype=obj -o - | llvm-dwarfdump --debug-dump=info - | FileCheck %s +; This should be a mask operation to extract the lower 32 bits and not a DW_OP_piece. +; CHECK: DW_AT_frame_base [DW_FORM_exprloc] (<0x8> 57 10 ff ff ff ff 0f 1a ) + ; CHECK: DW_TAG_variable ; DW_OP_fbreg ; CHECK-NEXT: DW_AT_location [DW_FORM_exprloc] (<0x2> 91 00 ) -; CHECK-NEXT: DW_AT_name {{.*}}"i" +; CHECK-NEXT: DW_AT_name {{.*}}i target datalayout = "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-apple-darwin" +target triple = "x86_64-pc-linux-gnux32" ; Function Attrs: nounwind uwtable declare i32 @foo(i32 %i) #0