[llvm-commits] [123989] Save and Restore LLVM values to GCC DECL tree link.

dpatel at apple.com dpatel at apple.com
Fri Feb 16 16:10:51 PST 2007


Revision: 123989
Author:   dpatel
Date:     2007-02-16 16:10:49 -0800 (Fri, 16 Feb 2007)

Log Message:
-----------
Save and Restore LLVM values to GCC DECL tree link.

Modified Paths:
--------------
    apple-local/branches/llvm/gcc/llvm-backend.cpp
    apple-local/branches/llvm/gcc/llvm-convert.cpp
    apple-local/branches/llvm/gcc/llvm-internal.h
    apple-local/branches/llvm/gcc/llvm-types.cpp
    apple-local/branches/llvm/gcc/tree.h

Modified: apple-local/branches/llvm/gcc/llvm-backend.cpp
===================================================================
--- apple-local/branches/llvm/gcc/llvm-backend.cpp	2007-02-16 23:44:15 UTC (rev 123988)
+++ apple-local/branches/llvm/gcc/llvm-backend.cpp	2007-02-17 00:10:49 UTC (rev 123989)
@@ -214,6 +214,8 @@
 
   // Read LLVM Types string table
   readLLVMTypesStringTable();
+  readLLVMValuesStringTable();
+
   flag_llvm_pch_read = 1;
 }
 
@@ -432,8 +434,10 @@
   timevar_push(TV_LLVM_PERFILE);
   llvm_shutdown_obj X;  // Call llvm_shutdown() on exit.
 
-  if (flag_pch_file)
+  if (flag_pch_file) {
     writeLLVMTypesStringTable();
+    writeLLVMValuesStringTable();
+  }
 
   // Add an llvm.global_ctors global if needed.
   if (!StaticCtors.empty())

Modified: apple-local/branches/llvm/gcc/llvm-convert.cpp
===================================================================
--- apple-local/branches/llvm/gcc/llvm-convert.cpp	2007-02-16 23:44:15 UTC (rev 123988)
+++ apple-local/branches/llvm/gcc/llvm-convert.cpp	2007-02-17 00:10:49 UTC (rev 123989)
@@ -24,6 +24,7 @@
 // This is the code that converts GCC AST nodes into LLVM code.
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ValueSymbolTable.h"
 #include "llvm-abi.h"
 #include "llvm-internal.h"
 #include "llvm-debug.h"
@@ -38,6 +39,7 @@
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/DenseMap.h"
 #include <iostream>
 
 extern "C" {
@@ -61,6 +63,137 @@
 extern int get_pointer_alignment (tree exp, unsigned int max_align);
 }
 
+//===----------------------------------------------------------------------===//
+//                   Matching LLVM Values with GCC DECL trees
+//===----------------------------------------------------------------------===//
+//
+// LLVMValues is a vector of LLVM Values. GCC tree nodes keep track of LLVM 
+// Values using this vector's index. It is easier to save and restore the index 
+// than the LLVM Value pointer while usig PCH. 
+
+// Collection of LLVM Values
+static std::vector<Value *> LLVMValues;
+typedef DenseMap<Value *, unsigned> LLVMValuesMapTy;
+static LLVMValuesMapTy LLVMValuesMap;
+
+// Remember the LLVM value for GCC tree node.
+void llvm_set_decl(tree Tr, Value *V) {
+
+  // If there is not any value then do not add new LLVMValues entry.
+  // However clear Tr index if it is non zero.
+  if (!V) {
+    if (GET_DECL_LLVM_INDEX(Tr))
+      SET_DECL_LLVM_INDEX(Tr, 0);
+    return;
+  }
+
+  unsigned &ValueSlot = LLVMValuesMap[V];
+  if (ValueSlot) {
+    // Already in map
+    SET_DECL_LLVM_INDEX(Tr, ValueSlot);
+    return;
+  }
+
+  unsigned Index = LLVMValues.size() + 1;
+  LLVMValues.push_back(V);
+  SET_DECL_LLVM_INDEX(Tr, Index);
+  LLVMValuesMap[V] = Index;
+}
+
+// Return TRUE if there is a LLVM Value associate with GCC tree node.
+bool llvm_set_decl_p(tree Tr) {
+  unsigned Index = GET_DECL_LLVM_INDEX(Tr);
+  if (Index == 0)
+    return false;
+
+  if (LLVMValues[Index - 1])
+    return true;
+
+  return false;
+}
+
+// Get LLVM Value for the GCC tree node based on LLVMValues vector index.
+// If there is not any value associated then use make_decl_llvm() to 
+// make LLVM value. When GCC tree node is initialized, it has 0 as the 
+// index value. This is why all recorded indices are offset by 1.
+Value *llvm_get_decl(tree Tr) {
+
+  unsigned Index = GET_DECL_LLVM_INDEX(Tr);
+  if (Index == 0) {
+    make_decl_llvm(Tr);
+    Index = GET_DECL_LLVM_INDEX(Tr);
+  }
+  assert ((Index - 1) < LLVMValues.size() && "Invalid LLVM Value index");
+
+  return LLVMValues[Index - 1];
+}
+
+// Read LLVM Types string table
+void readLLVMValuesStringTable() {
+
+  GlobalValue *V = TheModule->getNamedGlobal("llvm.pch.values");
+  if (!V)
+    return;
+
+  GlobalVariable *GV = cast<GlobalVariable>(V);
+  ConstantStruct *LValueNames = cast<ConstantStruct>(GV->getOperand(0));
+
+  for (unsigned i = 0; i < LValueNames->getNumOperands(); ++i) {
+    Value *Va = LValueNames->getOperand(i);
+
+    if (!Va) {
+      // If V is empty then nsert NULL to represent empty entries.
+      LLVMValues.push_back(Va);
+      continue;
+    }
+    if (ConstantArray *CA = dyn_cast<ConstantArray>(Va)) {
+      std::string Str = CA->getAsString();
+      Va = TheModule->getValueSymbolTable().lookup(Str);
+    } 
+    assert (Va != NULL && "Invalid Value in LLVMValues string table");
+    LLVMValues.push_back(Va);
+  }
+
+  // Now, llvm.pch.values is not required so remove it from the symbol table.
+  GV->eraseFromParent();
+}
+
+// GCC tree's uses LLVMValues vector's index to reach LLVM Values.
+// Create a string table to hold these LLVM Values' names. This string
+// table will be used to recreate LTypes vector after loading PCH.
+void writeLLVMValuesStringTable() {
+  
+  if (LLVMValues.empty()) 
+    return;
+
+  std::vector<Constant *> LLVMValuesNames;
+
+  for (std::vector<Value *>::iterator I = LLVMValues.begin(),
+         E = LLVMValues.end(); I != E; ++I)  {
+    Value *V = *I;
+
+    if (!V) {
+      LLVMValuesNames.push_back(ConstantArray::get("", false));      
+      continue;
+    }
+
+    // Give names to nameless values.
+    if (!V->hasName())
+      V->setName("llvm.fe.val");
+
+    LLVMValuesNames.push_back(ConstantArray::get(V->getName(), false));
+  }
+
+  // Create string table.
+  Constant *LLVMValuesNameTable = ConstantStruct::get(LLVMValuesNames, false);
+
+  // Create variable to hold this string table.
+  GlobalVariable *GV = new GlobalVariable(LLVMValuesNameTable->getType(), true,
+                                          GlobalValue::ExternalLinkage, 
+                                          LLVMValuesNameTable,
+                                          "llvm.pch.values", TheModule);
+}
+
 /// isGCC_SSA_Temporary - Return true if this is an SSA temporary that we can
 /// directly compile into an LLVM temporary.  This saves us from creating an
 /// alloca and creating loads/stores of that alloca (a compile-time win).  We

Modified: apple-local/branches/llvm/gcc/llvm-internal.h
===================================================================
--- apple-local/branches/llvm/gcc/llvm-internal.h	2007-02-16 23:44:15 UTC (rev 123988)
+++ apple-local/branches/llvm/gcc/llvm-internal.h	2007-02-17 00:10:49 UTC (rev 123989)
@@ -96,6 +96,8 @@
 
 extern void readLLVMTypesStringTable();
 extern void writeLLVMTypesStringTable();
+extern void readLLVMValuesStringTable();
+extern void writeLLVMValuesStringTable();
 
 struct StructTypeConversionInfo;
 

Modified: apple-local/branches/llvm/gcc/llvm-types.cpp
===================================================================
--- apple-local/branches/llvm/gcc/llvm-types.cpp	2007-02-16 23:44:15 UTC (rev 123988)
+++ apple-local/branches/llvm/gcc/llvm-types.cpp	2007-02-17 00:10:49 UTC (rev 123989)
@@ -58,7 +58,7 @@
 // refined and replaced by another LLVM Type. This is achieved by maintaining 
 // a map.
 
-// Collection of LLVM Types and their names
+// Collection of LLVM Types
 static std::vector<const Type *> LTypes;
 typedef DenseMap<const Type *, unsigned> LTypesMapTy;
 static LTypesMapTy LTypesMap;

Modified: apple-local/branches/llvm/gcc/tree.h
===================================================================
--- apple-local/branches/llvm/gcc/tree.h	2007-02-16 23:44:15 UTC (rev 123988)
+++ apple-local/branches/llvm/gcc/tree.h	2007-02-17 00:10:49 UTC (rev 123989)
@@ -2071,23 +2071,23 @@
 #ifdef __cplusplus
 namespace llvm { class Value; }
 /* C++ versions */
-#define DECL_LLVM(NODE)						\
-  ((llvm::Value*)(DECL_CHECK (NODE)->decl.llvm			\
-   ? (void*)(NODE)->decl.llvm					\
-   : (make_decl_llvm (NODE), (void*)(NODE)->decl.llvm)))
-#define SET_DECL_LLVM(NODE, LLVM) \
-  (DECL_CHECK (NODE)->decl.llvm = (long)(Value*)LLVM)
-
+extern void llvm_set_decl (tree, Value *);
+extern Value *llvm_get_decl(tree);
+#define DECL_LLVM(NODE) (llvm_get_decl(NODE))
 #else
 /* C versions */
-#define DECL_LLVM(NODE)					\
-  ((void*)(DECL_CHECK (NODE)->decl.llvm			\
-                 ? (void*)(NODE)->decl.llvm		\
-                 : (make_decl_llvm (NODE), (void*)(NODE)->decl.llvm)))
-#define SET_DECL_LLVM(NODE, LLVM) (DECL_CHECK (NODE)->decl.llvm = (long)LLVM)
+extern void llvm_set_decl (tree, void *);
+extern void *llvm_get_decl(tree);
+#define DECL_LLVM(NODE) ((void *) llvm_get_decl(NODE))
 #endif
+
+#define SET_DECL_LLVM(NODE, LLVM) (llvm_set_decl (NODE,LLVM))
+#define SET_DECL_LLVM_INDEX(NODE, INDEX) (DECL_CHECK (NODE)->decl.llvm = INDEX)
+#define GET_DECL_LLVM_INDEX(NODE) (DECL_CHECK (NODE)->decl.llvm)
+
 /* Returns nonzero if the DECL_LLVM for NODE has already been set.  */
-#define DECL_LLVM_SET_P(NODE) (DECL_CHECK (NODE)->decl.llvm != 0)
+extern bool llvm_set_decl_p(tree);
+#define DECL_LLVM_SET_P(NODE) (llvm_set_decl_p(NODE))
 /* Copy the LLVM from NODE1 to NODE2.  If the LLVM was not set for
    NODE1, it will not be set for NODE2; this is a lazy copy.  */
 #define COPY_DECL_LLVM(NODE1, NODE2)  \
@@ -2529,9 +2529,9 @@
   tree assembler_name;
   tree section_name;
   tree attributes;
+  rtx rtl;	  /* RTL representation for object.  */
   /* APPLE LOCAL begin LLVM */
-  rtx rtl;	  /* RTL representation for object.  */
-  long llvm;      /* LLVM representation for object. */
+  unsigned llvm;      /* LLVM representation for object. */
   /* APPLE LOCAL end LLVM */
 
   /* In FUNCTION_DECL, if it is inline, holds the saved insn chain.





More information about the llvm-commits mailing list