[llvm-commits] [llvm] r83120 - in /llvm/trunk: include/llvm/Analysis/DebugInfo.h lib/Analysis/DebugInfo.cpp lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/AsmPrinter/DwarfDebug.h

Devang Patel devang.patel at gmail.com
Wed Sep 30 09:41:13 PDT 2009


Mike,

On Tue, Sep 29, 2009 at 5:08 PM, Mike Stump <mrs at apple.com> wrote:
> Author: mrs
> Date: Tue Sep 29 19:08:22 2009
> New Revision: 83120
>
> URL: http://llvm.org/viewvc/llvm-project?rev=83120&view=rev
> Log:
> Add a way for a frontend to generate more complex dwarf location
> information.  This allows arbitrary code involving DW_OP_plus_uconst
> and DW_OP_deref.  The scheme allows for easy extention to include,
> any, or all of the DW_OP_ opcodes.  I thought about just exposing all
> of them, but, wasn't sure if people wanted the dwarf opcodes exposed
> in the api.  Is that a layering violation?

We do not want to encode DWARF directly in LLVM IR using MDNodes. The
debug info encoded in LLVM IR should be independent of debugging
format. So far we have been successful. So yes,  exposing all dwarf
opcodes is not a good idea.

DebugInfo.h interface uses dwarf specific tags etc.. but DebugInfo.h
is not *required* to manage debug info in LLVM IR.

> With this scheme, the entire existing block scheme used by llvm-gcc
> can be switched over to the new scheme.  I think that would be
> cleaner, as then the compiler specific bits are not present in llvm
> proper.

But the downside is, DWARF like opcodes are introduced.

> Before the old code can be yanked however, similar code in
> clang would have to be removed.
>
> Next up, more testing.

Please pay attention to build bots running gdb testsuites.

>
> Modified:
>    llvm/trunk/include/llvm/Analysis/DebugInfo.h
>    llvm/trunk/lib/Analysis/DebugInfo.cpp
>    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
>    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
>
> Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=83120&r1=83119&r2=83120&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original)
> +++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Tue Sep 29 19:08:22 2009
> @@ -187,10 +187,10 @@
>   class DIType : public DIDescriptor {
>   public:
>     enum {
> -      FlagPrivate    = 1 << 0,
> -      FlagProtected  = 1 << 1,
> -      FlagFwdDecl    = 1 << 2,
> -      FlagAppleBlock = 1 << 3,
> +      FlagPrivate          = 1 << 0,
> +      FlagProtected        = 1 << 1,
> +      FlagFwdDecl          = 1 << 2,
> +      FlagAppleBlock       = 1 << 3,
>       FlagBlockByrefStruct = 1 << 4
>     };
>
> @@ -409,6 +409,17 @@
>     /// Verify - Verify that a variable descriptor is well formed.
>     bool Verify() const;
>
> +    /// HasComplexAddr - Return true if the variable has a complex address.
> +    bool hasComplexAddress() const {
> +      return getNumAddrElements() > 0;
> +    }
> +
> +    unsigned getNumAddrElements() const { return DbgNode->getNumElements()-6; }
> +
> +    uint64_t getAddrElement(unsigned Idx) const {
> +      return getUInt64Field(Idx+6);
> +    }
> +
>     /// isBlockByrefVariable - Return true if the variable was declared as
>     /// a "__block" variable (Apple Blocks).
>     bool isBlockByrefVariable() const {
> @@ -463,6 +474,8 @@
>     DIFactory(const DIFactory &);     // DO NOT IMPLEMENT
>     void operator=(const DIFactory&); // DO NOT IMPLEMENT
>   public:
> +    enum ComplexAddrKind { OpPlus=1, OpDeref };

Please move this in DIVariable and use DW_ prefix.

> +
>     explicit DIFactory(Module &m);
>
>     /// GetOrCreateArray - Create an descriptor for an array of descriptors.
> @@ -540,6 +553,14 @@
>                               DICompileUnit CompileUnit, unsigned LineNo,
>                               DIType Type);
>
> +    /// CreateComplexVariable - Create a new descriptor for the specified
> +    /// variable which has a complex address expression for its address.
> +    DIVariable CreateComplexVariable(unsigned Tag, DIDescriptor Context,
> +                                     const std::string &Name,
> +                                     DICompileUnit CompileUnit, unsigned LineNo,
> +                                     DIType Type,
> +                                     SmallVector<Value *, 9> &addr);
> +
>     /// CreateLexicalBlock - This creates a descriptor for a lexical block
>     /// with the specified parent context.
>     DILexicalBlock CreateLexicalBlock(DIDescriptor Context);
>
> Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=83120&r1=83119&r2=83120&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original)
> +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Tue Sep 29 19:08:22 2009
> @@ -531,6 +531,8 @@
>   errs() << " [" << getLineNumber() << "] ";
>   getType().dump();
>   errs() << "\n";
> +
> +  // FIXME: Dump complex addresses
>  }
>
>  //===----------------------------------------------------------------------===//
> @@ -781,6 +783,26 @@
>  }
>
>
> +/// CreateComplexVariable - Create a new descriptor for the specified variable
> +/// which has a complex address expression for its address.
> +DIVariable DIFactory::CreateComplexVariable(unsigned Tag, DIDescriptor Context,
> +                                            const std::string &Name,
> +                                            DICompileUnit CompileUnit,
> +                                            unsigned LineNo,
> +                                   DIType Type, SmallVector<Value *, 9> &addr) {

How about "AddrComputation" instead of "addr" ?

> +  SmallVector<Value *, 9> Elts;
> +  Elts.push_back(GetTagConstant(Tag));
> +  Elts.push_back(Context.getNode());
> +  Elts.push_back(MDString::get(VMContext, Name));
> +  Elts.push_back(CompileUnit.getNode());
> +  Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), LineNo));
> +  Elts.push_back(Type.getNode());
> +  Elts.insert(Elts.end(), addr.begin(), addr.end());
> +
> +  return DIVariable(MDNode::get(VMContext, &Elts[0], 6+addr.size()));
> +}
> +
> +
>  /// CreateBlock - This creates a descriptor for a lexical block with the
>  /// specified parent VMContext.
>  DILexicalBlock DIFactory::CreateLexicalBlock(DIDescriptor Context) {
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=83120&r1=83119&r2=83120&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Sep 29 19:08:22 2009
> @@ -556,7 +556,7 @@
>   unsigned tag = Ty.getTag();
>
>   if (tag == dwarf::DW_TAG_pointer_type) {
> -    DIDerivedType DTy = DIDerivedType (Ty.getNode());
> +    DIDerivedType DTy = DIDerivedType(Ty.getNode());
>     subType = DTy.getTypeDerivedFrom();
>   }
>
> @@ -577,6 +577,56 @@
>   return Ty;
>  }
>
> +/// AddComplexAddress - Start with the address based on the location provided,
> +/// and generate the DWARF information necessary to find the actual variable
> +/// given the extra address information encoded in the DIVariable, starting from
> +/// the starting location.  Add the DWARF information to the die.
> +///
> +void DwarfDebug::AddComplexAddress(DbgVariable *&DV, DIE *Die,
> +                                   unsigned Attribute,
> +                                   const MachineLocation &Location) {
> +  const DIVariable &VD = DV->getVariable();
> +  DIType Ty = VD.getType();
> +
> +  // Decode the original location, and use that as the start of the byref
> +  // variable's location.
> +  unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
> +  DIEBlock *Block = new DIEBlock();
> +
> +  if (Location.isReg()) {
> +    if (Reg < 32) {
> +      AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
> +    } else {
> +      Reg = Reg - dwarf::DW_OP_reg0;
> +      AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
> +      AddUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
> +    }
> +  } else {
> +    if (Reg < 32)
> +      AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
> +    else {
> +      AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
> +      AddUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
> +    }
> +
> +    AddUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
> +  }
> +
> +  for (unsigned i = 0, N = VD.getNumAddrElements(); i < N; ++i) {
> +    uint64_t Element = VD.getAddrElement(i);
> +
> +    if (Element == DIFactory::OpPlus) {
> +      AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
> +      AddUInt(Block, 0, dwarf::DW_FORM_udata, VD.getAddrElement(++i));
> +    } else if (Element == DIFactory::OpDeref) {
> +      AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
> +    } else llvm_unreachable("unknown DIFactory Opcode");
> +  }
> +
> +  // Now attach the location information to the DIE.
> +  AddBlock(Die, Attribute, 0, Block);
> +}
> +
>  /* 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
> @@ -649,7 +699,7 @@
>   const char *varName = VD.getName();
>
>   if (Tag == dwarf::DW_TAG_pointer_type) {
> -    DIDerivedType DTy = DIDerivedType (Ty.getNode());
> +    DIDerivedType DTy = DIDerivedType(Ty.getNode());
>     TmpTy = DTy.getTypeDerivedFrom();
>     isPointer = true;
>   }
> @@ -790,7 +840,6 @@
>   else {
>     assert(Ty.isDerivedType() && "Unknown kind of DIType");
>     ConstructTypeDIE(DW_Unit, Buffer, DIDerivedType(Ty.getNode()));
> -
>   }
>
>   // Add debug information entry to entity and appropriate context.
> @@ -1187,6 +1236,7 @@
>   AddSourceLine(VariableDie, &VD);
>
>   // Add variable type.
> +  // FIXME: isBlockByrefVariable should be reformulated in terms of complex addresses instead.
>   if (VD.isBlockByrefVariable())
>     AddType(Unit, VariableDie, GetBlockByrefType(VD.getType(), Name));
>   else
> @@ -1200,7 +1250,10 @@
>     Location.set(RI->getFrameRegister(*MF),
>                  RI->getFrameIndexOffset(*MF, DV->getFrameIndex()));
>
> -    if (VD.isBlockByrefVariable())
> +
> +    if (VD.hasComplexAddress())
> +      AddComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
> +    else if (VD.isBlockByrefVariable())
>       AddBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
>     else
>       AddAddress(VariableDie, dwarf::DW_AT_location, Location);
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=83120&r1=83119&r2=83120&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Tue Sep 29 19:08:22 2009
> @@ -284,10 +284,20 @@
>   void AddAddress(DIE *Die, unsigned Attribute,
>                   const MachineLocation &Location);
>
> +  /// AddComplexAddress - Start with the address based on the location provided,
> +  /// and generate the DWARF information necessary to find the actual variable
> +  /// (navigating the extra location information encoded in the type) based on
> +  /// the starting location.  Add the DWARF information to the die.
> +  ///
> +  void AddComplexAddress(DbgVariable *&DV, DIE *Die, unsigned Attribute,
> +                         const MachineLocation &Location);
> +
> +  // 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
>   /// actual Block variable (navigating the Block struct) based on the
> -  /// starting location.  Add the DWARF information to the die.
> +  /// starting location.  Add the DWARF information to the die.  Obsolete,
> +  /// please use AddComplexAddress instead.
>   ///
>   void AddBlockByrefAddress(DbgVariable *&DV, DIE *Die, unsigned Attribute,
>                             const MachineLocation &Location);
> @@ -459,8 +469,9 @@
>
>   void ConstructSubprogram(MDNode *N);
>
> +  // FIXME: This should go away in favor of complex addresses.
>   /// Find the type the programmer originally declared the variable to be
> -  /// and return that type.
> +  /// and return that type.  Obsolete, use GetComplexAddrType instead.
>   ///
>   DIType GetBlockByrefType(DIType Ty, std::string Name);
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>


Thanks!
-
Devang




More information about the llvm-commits mailing list