Index: include/llvm/CodeGen/AsmPrinter.h =================================================================== --- include/llvm/CodeGen/AsmPrinter.h +++ include/llvm/CodeGen/AsmPrinter.h @@ -432,10 +432,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 @@ -752,21 +752,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 @@ -1570,10 +1570,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 @@ -59,10 +59,6 @@ /// - 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-left dwarf expression. - void AddShl(unsigned ShiftBy); - /// 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. @@ -73,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 MayUsePieceForSubRegMask Use a DW_OP_piece to more efficiently mask + /// a sub-register at offet 0. This conflicts with + /// the previous two parameters and should not be + /// used for DW_AT_frame_base. /// /// If size and offset is zero an operation for the entire /// register is emitted: Some targets do not provide a DWARF @@ -83,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 MayUsePieceForSubRegMask = 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,18 +59,6 @@ } } -void DwarfExpression::AddShl(unsigned ShiftBy) { - EmitOp(dwarf::DW_OP_constu); - EmitUnsigned(ShiftBy); - EmitOp(dwarf::DW_OP_shl); -} - -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. @@ -89,7 +77,8 @@ bool DwarfExpression::AddMachineRegPiece(unsigned MachineReg, unsigned PieceSizeInBits, - unsigned PieceOffsetInBits) { + unsigned PieceOffsetInBits, + bool MayUsePieceForSubRegMask) { if (!TRI.isPhysicalRegister(MachineReg)) return false; @@ -109,23 +98,39 @@ Reg = TRI.getDwarfRegNum(*SR, false); if (Reg >= 0) { unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg); - unsigned Size = TRI.getSubRegIdxSize(Idx); - unsigned SubRegOffset = TRI.getSubRegIdxOffset(Idx); - unsigned SuperSize = TRI.getRegClass(*SR)->getSize() * 8; - assert(SuperSize >= (SubRegOffset + Size)); + uint64_t Size = TRI.getSubRegIdxSize(Idx); + uint64_t SubRegOffset = TRI.getSubRegIdxOffset(Idx); + // +--------------+------+-----------+ + // | SubRegOffset | Size | UpperBits | + // +--------------+------+-----------+ AddReg(Reg, "super-register"); - // Mask out the uninteresting higher bits by shifting left first. - unsigned UpperBits = SuperSize - (SubRegOffset+Size); - if (UpperBits) - AddShl(UpperBits); - // 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 (SubRegOffset+UpperBits) - AddShr(SubRegOffset+UpperBits); + // 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 (MayUsePieceForSubRegMask && SubRegOffset == 0) { + // Use the smaller DW_OP_piece instead of creating a mask for a + // subregister at offset 0. + assert((PieceOffsetInBits == 0) && (PieceSizeInBits == 0) && + "MayUsePieceForSubRegMask used on a Piece"); + PieceSizeInBits = Size; + } + if (Size > 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(Size <= 64 && "cannot create a mask larger than 64 bits"); + uint64_t Mask = ~uint64_t(0ULL) >> (64 - Size); + EmitOp(dwarf::DW_OP_constu); + EmitUnsigned(Mask); + EmitOp(dwarf::DW_OP_and); + } if (PieceSizeInBits) - AddOpPiece(Size, PieceOffsetInBits); + AddOpPiece(PieceSizeInBits, PieceOffsetInBits); return true; } } Index: lib/CodeGen/AsmPrinter/DwarfUnit.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfUnit.h +++ lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -255,17 +255,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