[llvm-commits] [llvm-gcc-4.2] r100531 - in /llvm-gcc-4.2/trunk/gcc: llvm-backend.cpp llvm-convert.cpp llvm-debug.cpp llvm-debug.h llvm-internal.h

Stuart Hastings stuart at apple.com
Tue Apr 6 10:19:48 PDT 2010


Author: stuart
Date: Tue Apr  6 12:19:47 2010
New Revision: 100531

URL: http://llvm.org/viewvc/llvm-project?rev=100531&view=rev
Log:
Revise debug info machinery to digest nested functions and classes.

A certain GDB testsuite case (local.cc) has a function nested inside a
class nested inside another function.  GCC presents the innermost
function to llvm-convert first.  Heretofore, the debug info mistakenly
placed the inner function at module scope.  This patch walks the GCC
context links and instantiates the outer class and function so the
debug info is properly nested.  Radar 7426545.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-debug.h
    llvm-gcc-4.2/trunk/gcc/llvm-internal.h

Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=100531&r1=100530&r2=100531&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Tue Apr  6 12:19:47 2010
@@ -512,6 +512,8 @@
   if (!flag_pch_file &&
       debug_info_level > DINFO_LEVEL_NONE)
     TheDebugInfo = new DebugInfo(TheModule);
+  else
+    TheDebugInfo = 0;
 }
 
 /// performLateBackendInitialization - Set backend options that may only be
@@ -533,8 +535,6 @@
 }
 
 void llvm_lang_dependent_init(const char *Name) {
-  if (TheDebugInfo)
-    TheDebugInfo->Initialize();
   if (Name)
     TheModule->setModuleIdentifier(Name);
 }
@@ -1010,7 +1010,7 @@
   // Convert the AST to raw/ugly LLVM code.
   Function *Fn;
   {
-    TreeToLLVM Emitter(fndecl);
+    TreeToLLVM *Emitter = getTreeToLLVM(fndecl);
     enum symbol_visibility vis = DECL_VISIBILITY (fndecl);
 
     if (vis != VISIBILITY_DEFAULT)
@@ -1018,7 +1018,7 @@
       // visibility that's not supported by the target.
       targetm.asm_out.visibility(fndecl, vis);
 
-    Fn = Emitter.EmitFunction();
+    Fn = Emitter->EmitFunction();
   }
 
 #if 0
@@ -1317,6 +1317,10 @@
 
   timevar_push(TV_LLVM_GLOBALS);
 
+  // Insure debug info machinery initialized, even if current module
+  // lacks functions.
+  getTreeToLLVM(decl);
+
   // Get or create the global variable now.
   GlobalVariable *GV = cast<GlobalVariable>(DECL_LLVM(decl));
   

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=100531&r1=100530&r2=100531&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Apr  6 12:19:47 2010
@@ -148,7 +148,6 @@
 //===----------------------------------------------------------------------===//
 
 /// TheTreeToLLVM - Keep track of the current function being compiled.
-static TreeToLLVM *TheTreeToLLVM = 0;
 
 const TargetData &getTargetData() {
   return *TheTarget->getTargetData();
@@ -157,20 +156,22 @@
 /// EmitDebugInfo - Return true if debug info is to be emitted for current 
 /// function.
 bool TreeToLLVM::EmitDebugInfo() {
-  if (TheDebugInfo && !DECL_IGNORED_P(getFUNCTION_DECL()))
+  if (TheDebugInfo &&
+      (!getFUNCTION_DECL() || !DECL_IGNORED_P(getFUNCTION_DECL())))
     return true;
   return false;
 }
 
-TreeToLLVM::TreeToLLVM(tree fndecl) :
-    TD(getTargetData()), Builder(Context, *TheFolder) {
-  FnDecl = fndecl;
+TreeToLLVM::TreeToLLVM(tree decl) :
+  TD(getTargetData()), Builder(Context, *TheFolder) {
+  // If this isn't a FUNCITON_DECL, use only the source loc info from it.
+  FnDecl = (decl && TREE_CODE(decl) == FUNCTION_DECL) ? decl : NULL_TREE;
   Fn = 0;
   ReturnBB = UnwindBB = 0;
   ReturnOffset = 0;
 
   if (EmitDebugInfo()) {
-    expanded_location Location = expand_location(DECL_SOURCE_LOCATION (fndecl));
+    expanded_location Location = expand_location(DECL_SOURCE_LOCATION (decl));
 
     if (Location.file) {
       TheDebugInfo->setLocationFile(Location.file);
@@ -179,6 +180,7 @@
       TheDebugInfo->setLocationFile("<unknown file>");
       TheDebugInfo->setLocationLine(0);
     }
+    TheDebugInfo->Initialize();
   }
 
   AllocaInsertionPoint = 0;
@@ -188,13 +190,25 @@
   FuncEHException = 0;
   FuncEHSelector = 0;
   FuncEHGetTypeID = 0;
-
-  assert(TheTreeToLLVM == 0 && "Reentering function creation?");
-  TheTreeToLLVM = this;
 }
 
-TreeToLLVM::~TreeToLLVM() {
-  TheTreeToLLVM = 0;
+
+TreeToLLVM::~TreeToLLVM() {}
+
+TreeToLLVM *getTreeToLLVM(tree decl) {
+  // FIXME: should this static move into the TreeToLLVM class decl?
+  static std::map<tree_node *, TreeToLLVM * > FunctionMap;
+  TreeToLLVM *newTreeToLLVM = FunctionMap[decl];
+  if (!newTreeToLLVM) {
+    tree fndecl = (decl && TREE_CODE(decl) == FUNCTION_DECL) ? decl : NULL_TREE;
+    newTreeToLLVM = FunctionMap[fndecl] = new TreeToLLVM(decl);
+  }
+  return newTreeToLLVM;
+}
+
+TreeToLLVM *getCurrentTreeToLLVM(void) {
+  assert(current_function_decl && "no current_function_decl?");
+  return getTreeToLLVM(current_function_decl);
 }
 
 /// getLabelDeclBlock - Lazily get and create a basic block for the specified
@@ -308,7 +322,8 @@
       assert(TREE_CODE(TREE_TYPE(ResultDecl)) == REFERENCE_TYPE &&
              "Not type match and not passing by reference?");
       // Create an alloca for the ResultDecl.
-      Value *Tmp = TheTreeToLLVM->CreateTemporary(AI->getType());
+      TreeToLLVM *Emitter = getCurrentTreeToLLVM();
+      Value *Tmp = Emitter->CreateTemporary(AI->getType());
       Builder.CreateStore(AI, Tmp);
 
       SET_DECL_LLVM(ResultDecl, Tmp);
@@ -451,7 +466,7 @@
   }
 }
 
-void TreeToLLVM::StartFunctionBody() {
+Function *TreeToLLVM::StartFunctionBody() {
   const char *Name = "";
   // Get the name of the function.
   if (tree ID = DECL_ASSEMBLER_NAME(FnDecl))
@@ -610,10 +625,10 @@
   // Set the BLOCK_NUMBER()s to the depth of each lexical block.
   setLexicalBlockDepths(FnDecl, block_declared_vars, 1);
 
-  SeenBlocks.clear();
-
-  if (EmitDebugInfo())
-    TheDebugInfo->EmitFunctionStart(FnDecl, Fn, Builder.GetInsertBlock());
+  if (TheDebugInfo) {
+    TheDebugInfo->EmitFunctionStart(FnDecl);
+    Builder.GetInsertBlock();
+  }
 
   // Loop over all of the arguments to the function, setting Argument names and
   // creating argument alloca's for the PARM_DECLs in case their address is
@@ -628,7 +643,7 @@
   ABIConverter.HandleReturnType(TREE_TYPE(TREE_TYPE(FnDecl)), FnDecl,
                                 DECL_BUILT_IN(FnDecl));
   // Remember this for use by FinishFunctionBody.
-  TheTreeToLLVM->ReturnOffset = Client.Offset;
+  ReturnOffset = Client.Offset;
 
   // Prepend the static chain (if any) to the list of arguments.
   tree Args = static_chain ? static_chain : DECL_ARGUMENTS(FnDecl);
@@ -709,12 +724,7 @@
         block_declared_vars.count(TREE_VALUE(t)) == 0)
       EmitAutomaticVariableDecl(TREE_VALUE(t));
   }
-
-  // Push the outermost lexical block onto the RegionStack.
-  switchLexicalBlock(DECL_INITIAL(FnDecl));
-
-  // Create a new block for the return node, but don't insert it yet.
-  ReturnBB = BasicBlock::Create(Context, "return");
+  return Fn;
 }
 
 Function *TreeToLLVM::FinishFunctionBody() {
@@ -802,9 +812,19 @@
 }
 
 Function *TreeToLLVM::EmitFunction() {
-  // Set up parameters and prepare for return, for the function.
+  // Set up parameters for the function.
   StartFunctionBody();
 
+  // We'll remember the lexical BLOCKs we've seen here.
+  SeenBlocks.clear();
+
+  // FIXME: Should these two statements move to StartFunctionBody() ?
+  // Push the outermost lexical block onto the RegionStack.
+  switchLexicalBlock(DECL_INITIAL(FnDecl));
+
+  // Create a new block for the return node, but don't insert it yet.
+  ReturnBB = BasicBlock::Create(Context, "return");
+
   // Emit the body of the function iterating over all BBs
   basic_block bb;
   edge e;
@@ -2616,7 +2636,7 @@
       if (!Loc) {
         // A value.  Store to a temporary, and return the temporary's address.
         // Any future access to this argument will reuse the same address.
-        Loc = TheTreeToLLVM->CreateTemporary(TheValue->getType());
+        Loc = getCurrentTreeToLLVM()->CreateTemporary(TheValue->getType());
         Builder.CreateStore(TheValue, Loc);
       }
       return Loc;
@@ -2656,7 +2676,7 @@
         assert(ConvertType(type) ==
                cast<PointerType>(RetBuf.Ptr->getType())->getElementType() &&
                "Inconsistent result types!");
-        TheTreeToLLVM->EmitAggregateCopy(*DestLoc, RetBuf, type);
+        getCurrentTreeToLLVM()->EmitAggregateCopy(*DestLoc, RetBuf, type);
         return 0;
       } else {
         // Read out the scalar return value now.
@@ -2699,7 +2719,7 @@
 
       if (DestLoc == 0) {
         // The result is unused, but still needs to be stored somewhere.
-        Value *Buf = TheTreeToLLVM->CreateTemporary(PtrArgTy->getElementType());
+        Value *Buf = getCurrentTreeToLLVM()->CreateTemporary(PtrArgTy->getElementType());
         CallOperands.push_back(Buf);
       } else if (useReturnSlot) {
         // Letting the call write directly to the final destination is safe and
@@ -2709,7 +2729,7 @@
         // Letting the call write directly to the final destination may not be
         // safe (eg: if DestLoc aliases a parameter) and is not required - pass
         // a buffer and copy it to DestLoc after the call.
-        RetBuf = TheTreeToLLVM->CreateTempLoc(PtrArgTy->getElementType());
+        RetBuf = getCurrentTreeToLLVM()->CreateTempLoc(PtrArgTy->getElementType());
         CallOperands.push_back(RetBuf.Ptr);
       }
 
@@ -2730,7 +2750,7 @@
              "Call returns a scalar but caller expects aggregate!");
       // Create a buffer to hold the result.  The result will be loaded out of
       // it after the call.
-      RetBuf = TheTreeToLLVM->CreateTempLoc(PtrArgTy->getElementType());
+      RetBuf = getCurrentTreeToLLVM()->CreateTempLoc(PtrArgTy->getElementType());
       CallOperands.push_back(RetBuf.Ptr);
 
       // Note the use of a shadow argument.
@@ -2754,7 +2774,7 @@
         if (Loc->getType() != CalledTy) {
           assert(type && "Inconsistent parameter types?");
           bool isSigned = !TYPE_UNSIGNED(type);
-          Loc = TheTreeToLLVM->CastToAnyType(Loc, isSigned, CalledTy, false);
+          Loc = getCurrentTreeToLLVM()->CastToAnyType(Loc, isSigned, CalledTy, false);
         }
       }
 
@@ -8457,18 +8477,18 @@
 
 /// EmitLV_LABEL_DECL - Someone took the address of a label.
 Constant *TreeConstantToLLVM::EmitLV_LABEL_DECL(tree exp) {
-  assert(TheTreeToLLVM &&
+  assert(getCurrentTreeToLLVM() &&
          "taking the address of a label while not compiling the function!");
 
   // Figure out which function this is for, verify it's the one we're compiling.
   if (DECL_CONTEXT(exp)) {
     assert(TREE_CODE(DECL_CONTEXT(exp)) == FUNCTION_DECL &&
            "Address of label in nested function?");
-    assert(TheTreeToLLVM->getFUNCTION_DECL() == DECL_CONTEXT(exp) &&
+    assert(getCurrentTreeToLLVM()->getFUNCTION_DECL() == DECL_CONTEXT(exp) &&
            "Taking the address of a label that isn't in the current fn!?");
   }
 
-  return TheTreeToLLVM->EmitLV_LABEL_DECL(exp);
+  return getCurrentTreeToLLVM()->EmitLV_LABEL_DECL(exp);
 }
 
 Constant *TreeConstantToLLVM::EmitLV_COMPLEX_CST(tree exp) {

Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=100531&r1=100530&r2=100531&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Tue Apr  6 12:19:47 2010
@@ -289,12 +289,10 @@
   setCurrentLexicalBlock(desired);
 }
 
-/// EmitFunctionStart - Constructs the debug code for entering a function -
-/// "llvm.dbg.func.start."
-void DebugInfo::EmitFunctionStart(tree FnDecl, Function *Fn,
-                                  BasicBlock *CurBB) {
-  setCurrentLexicalBlock(FnDecl);
+/// CreateSubprogramFromFnDecl - Constructs the debug code for
+/// entering a function - "llvm.dbg.func.start."
 
+DISubprogram DebugInfo::CreateSubprogramFromFnDecl(tree FnDecl) {
   DIType FNType = getOrCreateType(TREE_TYPE(FnDecl));
 
   std::map<tree_node *, WeakVH >::iterator I = SPCache.find(FnDecl);
@@ -302,12 +300,9 @@
     DISubprogram SPDecl(cast<MDNode>(I->second));
     DISubprogram SP = 
       DebugFactory.CreateSubprogramDefinition(SPDecl);
-    SPDecl.getNode()->replaceAllUsesWith(SP.getNode());
-
-    // Push function on region stack.
-    RegionStack.push_back(WeakVH(SP.getNode()));
-    RegionMap[FnDecl] = WeakVH(SP.getNode());
-    return;
+    if (SP.getNode() != SPDecl.getNode())
+      SPDecl.getNode()->replaceAllUsesWith(SP.getNode());
+    return SP;
   } 
 
   bool ArtificialFnWithAbstractOrigin = false;
@@ -329,12 +324,13 @@
     DISubprogram SPDecl(cast<MDNode>(I->second));
     DISubprogram SP = 
       DebugFactory.CreateSubprogramDefinition(SPDecl);
-    SPDecl.getNode()->replaceAllUsesWith(SP.getNode());
+    if (SP.getNode() != SPDecl.getNode())
+      SPDecl.getNode()->replaceAllUsesWith(SP.getNode());
 
     // Push function on region stack.
     RegionStack.push_back(WeakVH(SP.getNode()));
     RegionMap[FnDecl] = WeakVH(SP.getNode());
-    return;
+    return SP;
   } 
 
   // Gather location information.
@@ -356,23 +352,36 @@
   }
 
   StringRef FnName = getFunctionName(FnDecl);
-
+  // If the Function * hasn't been created yet, use a bogus value for
+  // the debug internal linkage bit.
+  bool hasInternalLinkage = true;
+  if (GET_DECL_LLVM_INDEX(FnDecl)) {
+    Function *Fn = cast<Function>DECL_LLVM(FnDecl);
+    hasInternalLinkage = Fn->hasInternalLinkage();
+  }
   DISubprogram SP = 
     DebugFactory.CreateSubprogram(SPContext,
                                   FnName, FnName,
                                   LinkageName,
                                   getOrCreateFile(Loc.file), lineno,
                                   FNType,
-                                  Fn->hasInternalLinkage(),
+                                  hasInternalLinkage,
                                   true /*definition*/,
                                   Virtuality, VIndex, ContainingType);
                           
 
   SPCache[FnDecl] = WeakVH(SP.getNode());
+  RegionMap[FnDecl] = WeakVH(SP.getNode());
+  return SP;
+}
 
+/// EmitFunctionStart - Constructs the debug code for entering a function -
+/// "llvm.dbg.func.start", and pushes it onto the RegionStack.
+void DebugInfo::EmitFunctionStart(tree FnDecl) {
+  setCurrentLexicalBlock(FnDecl);
+  DISubprogram SP = CreateSubprogramFromFnDecl(FnDecl);
   // Push function on region stack.
   RegionStack.push_back(WeakVH(SP.getNode()));
-  RegionMap[FnDecl] = WeakVH(SP.getNode());
 }
 
 /// getOrCreateNameSpace - Get name space descriptor for the tree node.
@@ -405,12 +414,20 @@
     DIType Ty = getOrCreateType(Node);
     return DIDescriptor(Ty.getNode());
   } else if (DECL_P (Node)) {
-    if (TREE_CODE (Node) == NAMESPACE_DECL) {
+    switch (TREE_CODE(Node)) {
+    default:
+      /// What kind of DECL is this?
+      return findRegion (DECL_CONTEXT (Node));
+    case NAMESPACE_DECL: {
       DIDescriptor NSContext = findRegion(DECL_CONTEXT(Node));
       DINameSpace NS = getOrCreateNameSpace(Node, NSContext);
       return DIDescriptor(NS.getNode());
     }
-    return findRegion (DECL_CONTEXT (Node));
+    case FUNCTION_DECL: {
+      DISubprogram SP = CreateSubprogramFromFnDecl(Node);
+      return SP;
+    }
+    }
   } else if (TREE_CODE(Node) == BLOCK) {
     // TREE_BLOCK is GCC's lexical block.
     // Recursively create all necessary contexts:
@@ -623,7 +640,7 @@
   sprintf(FwdTypeName, "fwd.type.%d", FwdTypeCount++);
   llvm::DIType FwdType = 
     DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
-                                     getOrCreateFile(main_input_filename),
+                                     findRegion(TYPE_CONTEXT(type)),
                                      FwdTypeName,
                                      getOrCreateFile(main_input_filename),
                                      0, 0, 0, 0, 0,
@@ -709,9 +726,10 @@
       return Ty;
     }
   
+  tree type_with_context = TYPE_CONTEXT(type) ? type : TREE_TYPE(type);
   StringRef PName = FromTy.getName();
   DIType PTy = 
-    DebugFactory.CreateDerivedType(Tag, findRegion(TYPE_CONTEXT(type)), 
+    DebugFactory.CreateDerivedType(Tag, findRegion(type_with_context), 
                                    Tag == DW_TAG_pointer_type ? 
                                    StringRef() : PName,
                                    getOrCreateFile(main_input_filename),

Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.h?rev=100531&r1=100530&r2=100531&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-debug.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-debug.h Tue Apr  6 12:19:47 2010
@@ -118,9 +118,13 @@
   // by GCC's cfglayout.c:change_scope().
   void change_regions(tree_node *desired, tree_node *grand);
 
-  /// EmitFunctionStart - Constructs the debug code for entering a function -
+  /// CreateSubprogramFromFnDecl - Constructs the debug code for entering a function -
   /// "llvm.dbg.func.start."
-  void EmitFunctionStart(tree_node *FnDecl, Function *Fn, BasicBlock *CurBB);
+  DISubprogram CreateSubprogramFromFnDecl(tree_node *FnDecl);
+
+  /// EmitFunctionStart - Constructs the debug code for entering a function -
+  /// "llvm.dbg.func.start", and pushes it onto the RegionStack.
+  void EmitFunctionStart(tree_node *FnDecl);
 
   /// EmitFunctionEnd - Constructs the debug code for exiting a declarative
   /// region - "llvm.dbg.region.end."

Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=100531&r1=100530&r2=100531&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Tue Apr  6 12:19:47 2010
@@ -75,7 +75,7 @@
 extern llvm::Module *TheModule;
 
 /// TheDebugInfo - This object is responsible for gather all debug information.
-/// If it's value is NULL then no debug information should be gathered.
+/// If its value is NULL then no debug information should be gathered.
 extern llvm::DebugInfo *TheDebugInfo;
 
 /// TheTarget - The current target being compiled for.
@@ -281,6 +281,7 @@
   BasicBlock *ReturnBB;
   BasicBlock *UnwindBB;
   unsigned ReturnOffset;
+
   // Lexical BLOCKS that we have previously seen and processed.
   treeset SeenBlocks;
 
@@ -397,6 +398,10 @@
   // allocation would change with -g, and users dislike that.
   void switchLexicalBlock(tree_node *exp);
 
+  /// StartFunctionBody - Start the emission of 'FnDecl', outputing all
+  /// declarations for parameters and setting things up.
+  Function *StartFunctionBody();
+  
 private: // Helper functions.
 
   // Walk over the lexical BLOCK() tree of the given FUNCTION_DECL;
@@ -405,10 +410,6 @@
   // the given set.
   void setLexicalBlockDepths(tree_node *t, treeset &s, unsigned level);
 
-  /// StartFunctionBody - Start the emission of 'fndecl', outputing all
-  /// declarations for parameters and setting things up.
-  void StartFunctionBody();
-  
   /// FinishFunctionBody - Once the body of the function has been emitted, this
   /// cleans up and returns the result function.
   Function *FinishFunctionBody();
@@ -608,6 +609,9 @@
   Constant *EmitLV_LABEL_DECL(tree_node *exp);
 };
 
+/// Locate a previously exiting TreeToLLVM.  Construct one if necessary.
+TreeToLLVM *getTreeToLLVM(tree_node *fndecl);
+
 /// TreeConstantToLLVM - An instance of this class is created and used to 
 /// convert tree constant values to LLVM.  This is primarily for things like
 /// global variable initializers.





More information about the llvm-commits mailing list