[llvm-commits] [dragonegg] r95383 - in /dragonegg/trunk: bits_and_bobs.h llvm-backend.cpp llvm-convert.cpp llvm-internal.h

Duncan Sands baldrick at free.fr
Fri Feb 5 01:57:57 PST 2010


Author: baldrick
Date: Fri Feb  5 03:57:56 2010
New Revision: 95383

URL: http://llvm.org/viewvc/llvm-project?rev=95383&view=rev
Log:
Factorize code used for ensuring that globals are fully output (i.e. that the initial
value is output and not just a declaration).  There wouldn't be any functional change
if I hadn't ripped out a bunch of old code that mucks around with gcc internals while
there - this code shouldn't (fingers crossed!) be needed given the way the plugin works,
and might be positively harmful.

Modified:
    dragonegg/trunk/bits_and_bobs.h
    dragonegg/trunk/llvm-backend.cpp
    dragonegg/trunk/llvm-convert.cpp
    dragonegg/trunk/llvm-internal.h

Modified: dragonegg/trunk/bits_and_bobs.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/bits_and_bobs.h?rev=95383&r1=95382&r2=95383&view=diff

==============================================================================
--- dragonegg/trunk/bits_and_bobs.h (original)
+++ dragonegg/trunk/bits_and_bobs.h Fri Feb  5 03:57:56 2010
@@ -2,12 +2,6 @@
 #ifndef BITS_AND_BOBS_H
 #define BITS_AND_BOBS_H
 
-union tree_node;
-
-// emit_global - Emit the specified VAR_DECL to LLVM as a global variable.
-// FIXME: Should not be here
-void emit_global(union tree_node*);
-
 extern bool flag_odr;
 
 #endif

Modified: dragonegg/trunk/llvm-backend.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=95383&r1=95382&r2=95383&view=diff

==============================================================================
--- dragonegg/trunk/llvm-backend.cpp (original)
+++ dragonegg/trunk/llvm-backend.cpp Fri Feb  5 03:57:56 2010
@@ -1346,6 +1346,22 @@
 //TODO  timevar_pop(TV_LLVM_GLOBALS);
 }
 
+/// make_definition_llvm - Ensures that the body or initial value of the given
+/// GCC declaration will be output, and returns a declaration for it.
+Value *make_definition_llvm(tree decl) {
+  // Only need to do something special for global variables.
+  if (TREE_CODE(decl) != CONST_DECL && TREE_CODE(decl) != VAR_DECL)
+    return DECL_LLVM(decl);
+  if ((!DECL_INITIAL(decl) && TREE_PUBLIC(decl)) || DECL_EXTERNAL(decl))
+    return DECL_LLVM(decl);
+  GlobalValue *GV = cast<GlobalValue>(DECL_LLVM(decl));
+  // If we already output a definition for this declaration, then reuse it.
+  if (!GV->isDeclaration())
+    return GV;
+  emit_global(decl);
+  return DECL_LLVM(decl); // Decl could have changed if it changed type.
+}
+
 /// llvm_mark_decl_weak - Used by varasm.c, called when a decl is found to be
 /// weak, but it already had an llvm object created for it. This marks the LLVM
 /// object weak as well.
@@ -1683,17 +1699,7 @@
     else
       assert(0 && "Unsuported global value");
   } else {
-    Aliasee = cast<GlobalValue>(DECL_LLVM(target));
-
-    // If the target is an aggregate, emit it to LLVM now.
-    if (Aliasee->isDeclaration() && (TREE_CODE(target) == CONST_DECL ||
-                                     TREE_CODE(target) == VAR_DECL) &&
-        (DECL_INITIAL(target) || !TREE_PUBLIC(target)) &&
-        !DECL_EXTERNAL(target)) {
-      emit_global(target);
-      // Aliasee could have change if it changed type.
-      Aliasee = cast<GlobalValue>(DECL_LLVM(target));
-    }
+    Aliasee = cast<GlobalValue>(DEFINITION_LLVM(target));
   }
 
   GlobalValue::LinkageTypes Linkage = GlobalValue::ExternalLinkage;

Modified: dragonegg/trunk/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-convert.cpp?rev=95383&r1=95382&r2=95383&view=diff

==============================================================================
--- dragonegg/trunk/llvm-convert.cpp (original)
+++ dragonegg/trunk/llvm-convert.cpp Fri Feb  5 03:57:56 2010
@@ -317,6 +317,14 @@
   }
 }
 
+/// make_definition_local - Ensure that the body or initial value of the given
+/// GCC declaration will be output, and return a declaration for it.
+Value *TreeToLLVM::make_definition_local(tree decl) {
+  if (!isLocalDecl(decl))
+    return make_definition_llvm(decl);
+  return make_decl_local(decl);
+}
+
 /// llvm_store_scalar_argument - Store scalar argument ARGVAL of type
 /// LLVMTY at location LOC.
 static void llvm_store_scalar_argument(Value *Loc, Value *ArgVal,
@@ -5477,32 +5485,7 @@
 }
 
 LValue TreeToLLVM::EmitLV_DECL(tree exp) {
-  if (TREE_CODE(exp) == PARM_DECL || TREE_CODE(exp) == VAR_DECL ||
-      TREE_CODE(exp) == CONST_DECL) {
-    // If a static var's type was incomplete when the decl was written,
-    // but the type is complete now, lay out the decl now.
-    if (DECL_SIZE(exp) == 0 && COMPLETE_OR_UNBOUND_ARRAY_TYPE_P(TREE_TYPE(exp))
-        && (TREE_STATIC(exp) || DECL_EXTERNAL(exp))) {
-      layout_decl(exp, 0);
-
-#if 0
-      // This mirrors code in layout_decl for munging the RTL.  Here we actually
-      // emit a NEW declaration for the global variable, now that it has been
-      // laid out.  We then tell the compiler to "forward" any uses of the old
-      // global to this new one.
-      if (Value *Val = DECL_LOCAL_IF_SET(exp)) {
-        //fprintf(stderr, "***\n*** SHOULD HANDLE GLOBAL VARIABLES!\n***\n");
-        //assert(0 && "Reimplement this with replace all uses!");
-        SET_DECL_LOCAL(exp, 0);
-        // Create a new global variable declaration
-        llvm_assemble_external(exp);
-        V2GV(Val)->ForwardedGlobal = V2GV(DECL_LOCAL(exp));
-      }
-#endif
-    }
-  }
-
-  Value *Decl = DECL_LOCAL(exp);
+  Value *Decl = DEFINITION_LOCAL(exp);
   if (Decl == 0) {
     if (errorcount || sorrycount) {
       const Type *Ty = ConvertType(TREE_TYPE(exp));
@@ -5510,33 +5493,7 @@
       LValue LV(ConstantPointerNull::get(PTy), 1);
       return LV;
     }
-    assert(0 && "INTERNAL ERROR: Referencing decl that hasn't been laid out");
-    abort();
-  }
-
-  // Ensure variable marked as used even if it doesn't go through a parser.  If
-  // it hasn't been used yet, write out an external definition.
-  if (!TREE_USED(exp)) {
-    assemble_external(exp);
-    TREE_USED(exp) = 1;
-    Decl = DECL_LOCAL(exp);
-  }
-
-  if (GlobalValue *GV = dyn_cast<GlobalValue>(Decl)) {
-    // If this is an aggregate, emit it to LLVM now.  GCC happens to
-    // get this case right by forcing the initializer into memory.
-    if (TREE_CODE(exp) == CONST_DECL || TREE_CODE(exp) == VAR_DECL) {
-      if ((DECL_INITIAL(exp) || !TREE_PUBLIC(exp)) && !DECL_EXTERNAL(exp) &&
-          GV->isDeclaration()) {
-        emit_global(exp);
-        Decl = DECL_LOCAL(exp);     // Decl could have change if it changed type.
-      }
-    } else {
-      // Otherwise, inform cgraph that we used the global.
-      mark_decl_referenced(exp);
-      if (tree ID = DECL_ASSEMBLER_NAME(exp))
-        mark_referenced(ID);
-    }
+    llvm_unreachable("Referencing decl that hasn't been laid out");
   }
 
   const Type *Ty = ConvertType(TREE_TYPE(exp));
@@ -8497,31 +8454,7 @@
 }
 
 Constant *TreeConstantToLLVM::EmitLV_Decl(tree exp) {
-  GlobalValue *Val = cast<GlobalValue>(DECL_LLVM(exp));
-
-  // Ensure variable marked as used even if it doesn't go through a parser.  If
-  // it hasn't been used yet, write out an external definition.
-  if (!TREE_USED(exp)) {
-    assemble_external(exp);
-    TREE_USED(exp) = 1;
-    Val = cast<GlobalValue>(DECL_LLVM(exp));
-  }
-
-  // If this is an aggregate, emit it to LLVM now.  GCC happens to
-  // get this case right by forcing the initializer into memory.
-  if (TREE_CODE(exp) == CONST_DECL || TREE_CODE(exp) == VAR_DECL) {
-    if ((DECL_INITIAL(exp) || !TREE_PUBLIC(exp)) && !DECL_EXTERNAL(exp) &&
-        Val->isDeclaration()) {
-      emit_global(exp);
-      // Decl could have change if it changed type.
-      Val = cast<GlobalValue>(DECL_LLVM(exp));
-    }
-  } else {
-    // Otherwise, inform cgraph that we used the global.
-    mark_decl_referenced(exp);
-    if (tree ID = DECL_ASSEMBLER_NAME(exp))
-      mark_referenced(ID);
-  }
+  GlobalValue *Val = cast<GlobalValue>(DEFINITION_LLVM(exp));
 
   // The type of the global value output for exp need not match that of exp.
   // For example if the global's initializer has a different type to the global

Modified: dragonegg/trunk/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-internal.h?rev=95383&r1=95382&r2=95383&view=diff

==============================================================================
--- dragonegg/trunk/llvm-internal.h (original)
+++ dragonegg/trunk/llvm-internal.h Fri Feb  5 03:57:56 2010
@@ -100,9 +100,7 @@
 
 // Mapping between GCC declarations and LLVM values.
 
-/// DECL_LLVM - Holds the LLVM expression for the value of a global variable or
-/// function.  This value can be evaluated lazily for functions and variables
-/// with static storage duration.
+/// DECL_LLVM - Returns the LLVM declaration of a global variable or function.
 extern Value *make_decl_llvm(union tree_node *);
 #define DECL_LLVM(NODE) make_decl_llvm(NODE)
 
@@ -119,6 +117,11 @@
 /// been set.
 #define DECL_LLVM_SET_P(NODE) (DECL_LLVM_IF_SET(NODE) != NULL)
 
+/// DEFINITION_LLVM - Ensures that the body or initial value of the given GCC
+/// declaration will be output, and returns a declaration for it.
+Value *make_definition_llvm(union tree_node *decl);
+#define DEFINITION_LLVM(NODE) make_definition_llvm(NODE)
+
 void changeLLVMConstant(Constant *Old, Constant *New);
 void register_ctor_dtor(Function *, int, bool);
 void readLLVMTypesStringTable();
@@ -388,12 +391,19 @@
 
   //===---------------------- Local Declarations --------------------------===//
 
-  /// DECL_LOCAL - Like DECL_LLVM, returns the LLVM expression for the value of
-  /// a variable or function.  However DECL_LOCAL can be used with declarations
-  /// local to the current function as well as with global declarations.
+  /// DECL_LOCAL - Like DECL_LLVM, returns the LLVM declaration of a variable or
+  /// function.  However DECL_LOCAL can be used with declarations local to the
+  /// current function as well as with global declarations.
   Value *make_decl_local(union tree_node *);
   #define DECL_LOCAL(NODE) make_decl_local(NODE)
 
+  /// DEFINITION_LOCAL - Like DEFINITION_LLVM, ensures that the initial value or
+  /// body of a variable or function will be output.  However DEFINITION_LOCAL
+  /// can be used with declarations local to the current function as well as
+  /// with global declarations.
+  Value *make_definition_local(union tree_node *);
+  #define DEFINITION_LOCAL(NODE) make_definition_local(NODE)
+
   /// SET_DECL_LOCAL - Set the DECL_LOCAL for NODE to LLVM. 
   Value *set_decl_local(union tree_node *, Value *);
   #define SET_DECL_LOCAL(NODE, LLVM) set_decl_local(NODE, LLVM)





More information about the llvm-commits mailing list