[llvm-commits] [123874] Maintain GCC Type Tree <--> LLVM Type connection during

dpatel at apple.com dpatel at apple.com
Wed Feb 14 13:54:22 PST 2007


Revision: 123874
Author:   dpatel
Date:     2007-02-14 13:54:21 -0800 (Wed, 14 Feb 2007)

Log Message:
-----------
Maintain GCC Type Tree <--> LLVM Type connection during
PCH write and PCH read.

Use LLVM Type vector index, instead of pointer to LLVM Type,
to connect LLVM Type with GCC Type Tree node.

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

Modified: apple-local/branches/llvm/gcc/flags.h
===================================================================
--- apple-local/branches/llvm/gcc/flags.h	2007-02-14 20:34:14 UTC (rev 123873)
+++ apple-local/branches/llvm/gcc/flags.h	2007-02-14 21:54:21 UTC (rev 123874)
@@ -334,4 +334,7 @@
 extern int flag_save_repository;
 /* APPLE LOCAL end ss2 */
 
+/* APPLE LOCAL LLVM */
+extern int flag_llvm_pch_read;
+
 #endif /* ! GCC_FLAGS_H */

Modified: apple-local/branches/llvm/gcc/llvm-backend.cpp
===================================================================
--- apple-local/branches/llvm/gcc/llvm-backend.cpp	2007-02-14 20:34:14 UTC (rev 123873)
+++ apple-local/branches/llvm/gcc/llvm-backend.cpp	2007-02-14 21:54:21 UTC (rev 123874)
@@ -64,6 +64,9 @@
 #include "tree-inline.h"
 }
 
+// Non-zero if bytecode from PCH is successfully read.
+int flag_llvm_pch_read;
+
 // Global state for the LLVM backend.
 Module *TheModule = 0;
 DebugInfo *TheDebugInfo = 0;
@@ -184,6 +187,8 @@
 
 oFILEstream *AsmOutStream = 0;
 
+/// Read bytecode from PCH file. Initialize TheModue and setup
+/// LTypes vector.
 void llvm_pch_read(void) {
 
   if (TheModule)
@@ -199,10 +204,15 @@
     cerr << ErrMsg << "\n";
     exit(1);
   }
+
+  // Read LLVM Types string table
+  readLLVMTypesStringTable();
+  flag_llvm_pch_read = 1;
 }
 
 // Initialize PCH writing. 
 void llvm_pch_write_init(void) {
+
   timevar_push(TV_LLVM_INIT);
   AsmOutStream = new oFILEstream(asm_out_file);
   AsmOutFile = new OStream(*AsmOutStream);
@@ -218,6 +228,8 @@
   // wrong for llvm/.bc emission cases.
   flag_no_ident = 1;
 
+  flag_llvm_pch_read = 0;
+
   timevar_pop(TV_LLVM_INIT);
 }
 
@@ -227,6 +239,8 @@
   AsmOutStream = new oFILEstream(asm_out_file);
   AsmOutFile = new OStream(*AsmOutStream);
   
+  flag_llvm_pch_read = 0;
+
   // Create and set up the per-function pass manager.
   // FIXME: Move the code generator to be function-at-a-time.
   PerFunctionPasses =
@@ -410,7 +424,10 @@
 void llvm_asm_file_end(void) {
   timevar_push(TV_LLVM_PERFILE);
   llvm_shutdown_obj X;  // Call llvm_shutdown() on exit.
-  
+
+  if (flag_pch_file)
+    writeLLVMTypesStringTable();
+
   // Add an llvm.global_ctors global if needed.
   if (!StaticCtors.empty())
     CreateStructorsList(StaticCtors, "llvm.global_ctors");

Modified: apple-local/branches/llvm/gcc/llvm-internal.h
===================================================================
--- apple-local/branches/llvm/gcc/llvm-internal.h	2007-02-14 20:34:14 UTC (rev 123873)
+++ apple-local/branches/llvm/gcc/llvm-internal.h	2007-02-14 21:54:21 UTC (rev 123874)
@@ -94,6 +94,9 @@
 extern std::map<std::string, GlobalVariable*> EmittedGlobalVars;
 extern std::map<std::string, Function*> EmittedFunctions;
 
+extern void readLLVMTypesStringTable();
+extern void writeLLVMTypesStringTable();
+
 struct StructTypeConversionInfo;
 
 /// TypeConverter - Implement the converter from GCC types to LLVM types.

Modified: apple-local/branches/llvm/gcc/llvm-types.cpp
===================================================================
--- apple-local/branches/llvm/gcc/llvm-types.cpp	2007-02-14 20:34:14 UTC (rev 123873)
+++ apple-local/branches/llvm/gcc/llvm-types.cpp	2007-02-14 21:54:21 UTC (rev 123874)
@@ -29,9 +29,11 @@
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Module.h"
+#include "llvm/TypeSymbolTable.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Assembly/Writer.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringExtras.h"
 #include <iostream>
 #include <map>
@@ -45,7 +47,149 @@
 #include "llvm-abi.h"
 
 
+//===----------------------------------------------------------------------===//
+//                   Matching LLVM types with GCC trees
+//===----------------------------------------------------------------------===//
+//
+// LTypes is a vector of LLVM types. GCC tree nodes keep track of LLVM types 
+// using this vector's index. It is easier to save and restore the index than 
+// the LLVM type pointer while usig PCH. STL vector does not provide fast 
+// searching mechanism which is required to remove LLVM Type entry when type is 
+// refined and replaced by another LLVM Type. This is achieved by maintaining 
+// a map.
 
+// Collection of LLVM Types and their names
+static std::vector<const Type *> LTypes;
+typedef DenseMap<const Type *, unsigned> LTypesMapTy;
+static LTypesMapTy LTypesMap;
+
+// GET_TYPE_LLVM/SET_TYPE_LLVM - Associate an LLVM type with each TREE type.
+// These are lazily computed by ConvertType, accessors available only to C++
+// code.
+
+#define SET_TYPE_SYMTAB_LLVM(NODE, index) (TYPE_CHECK (NODE)->type.symtab.llvm = index)
+
+// Note down LLVM type for GCC tree node.
+static const Type * llvm_set_type(tree Tr, const Type *Ty) {
+
+  unsigned &TypeSlot = LTypesMap[Ty];
+  if (TypeSlot) {
+    // Already in map.
+    SET_TYPE_SYMTAB_LLVM(Tr, TypeSlot);
+    return Ty;
+  }
+
+  unsigned Index = LTypes.size() + 1;
+  LTypes.push_back(Ty);
+  SET_TYPE_SYMTAB_LLVM(Tr, Index);
+  LTypesMap[Ty] = Index;
+
+  return Ty;
+}
+
+#define SET_TYPE_LLVM(NODE, TYPE) (const Type *)llvm_set_type(NODE, TYPE)
+
+// Get LLVM Type for the GCC tree node based on LTypes vector index.
+// When GCC tree node is initialized, it has 0 as the index value. This is
+// why all recorded indexes are offset by 1. 
+static inline const Type *llvm_get_type(unsigned Index) {
+
+  if (Index == 0)
+    return NULL;
+  assert ((Index - 1) < LTypes.size() && "Invalid LLVM Type index");
+  return LTypes[Index - 1];
+}
+
+#define GET_TYPE_LLVM(NODE) \
+  (const Type *)llvm_get_type( TYPE_CHECK (NODE)->type.symtab.llvm)
+
+// Erase type from LTypes vector
+static void llvmEraseLType(const Type *Ty) {
+
+  LTypesMapTy::iterator I = LTypesMap.find(Ty);
+
+  if (I != LTypesMap.end()) {
+    // It is OK to clear this entry instead of removing this entry
+    // to avoid re-indexing of other entries.
+    LTypes[ LTypesMap[Ty] - 1] = NULL;
+    LTypesMap.erase(I);
+  }
+}
+
+// Read LLVM Types string table
+void readLLVMTypesStringTable() {
+
+  GlobalValue *V = TheModule->getNamedGlobal("llvm.pch.types");
+  if (!V)
+    return;
+
+  //  Value *GV = TheModule->getValueSymbolTable().lookup("llvm.pch.types");
+  GlobalVariable *GV = cast<GlobalVariable>(V);
+  ConstantStruct *LTypesNames = cast<ConstantStruct>(GV->getOperand(0));
+
+  for (unsigned i = 0; i < LTypesNames->getNumOperands(); ++i) {
+    const Type *Ty = NULL;
+
+    if (ConstantArray *CA = 
+        dyn_cast<ConstantArray>(LTypesNames->getOperand(i))) {
+      std::string Str = CA->getAsString();
+      Ty = TheModule->getTypeByName(Str);
+      assert (Ty != NULL && "Invalid Type in LTypes string table");
+    } 
+    // If V is not a string then it is empty. Insert NULL to represent 
+    // empty entries.
+    LTypes.push_back(Ty);
+  }
+
+  // Now, llvm.pch.types value is not required so remove it from the symbol table.
+  GV->eraseFromParent();
+}
+
+
+// GCC tree's uses LTypes vector's index to reach LLVM types.
+// Create a string table to hold these LLVM types' names. This string
+// table will be used to recreate LTypes vector after loading PCH.
+void writeLLVMTypesStringTable() {
+  
+  if (LTypes.empty()) 
+    return;
+
+  std::vector<Constant *> LTypesNames;
+  std::map < const Type *, std::string > TypeNameMap;
+
+  // Collect Type Names in advance.
+  const TypeSymbolTable &ST = TheModule->getTypeSymbolTable();
+  TypeSymbolTable::const_iterator TI = ST.begin();
+  for (; TI != ST.end(); ++TI) {
+    TypeNameMap[TI->second] = TI->first;
+  }
+
+  // Populate LTypesNames vector.
+  for (std::vector<const Type *>::iterator I = LTypes.begin(),
+         E = LTypes.end(); I != E; ++I)  {
+    const Type *Ty = *I;
+
+    // Give names to nameless types.
+    if (Ty && TypeNameMap[Ty].empty()) {
+      std::string NewName = TheModule->getTypeSymbolTable().getUniqueName("llvm.fe.ty");
+      TheModule->addTypeName (NewName, Ty);
+      TypeNameMap[*I] = NewName;
+    }
+
+    const std::string &TypeName = TypeNameMap[*I];
+    LTypesNames.push_back(ConstantArray::get(TypeName, false));
+  }
+
+  // Create string table.
+  Constant *LTypesNameTable = ConstantStruct::get(LTypesNames, false);
+
+  // Create variable to hold this string table.
+  GlobalVariable *GV = new GlobalVariable(LTypesNameTable->getType(), true,
+                                          GlobalValue::ExternalLinkage, 
+                                          LTypesNameTable,
+                                          "llvm.pch.types", TheModule);
+}
+
 //===----------------------------------------------------------------------===//
 //                   Recursive Type Handling Code and Data
 //===----------------------------------------------------------------------===//
@@ -193,7 +337,6 @@
   }
 }
 
-
 /// refineAbstractType - The callback method invoked when an abstract type is
 /// resolved to another type.  An object must override this method to update
 /// its internal state to reference NewType instead of OldType.
@@ -223,6 +366,7 @@
     }
   }
   
+  llvmEraseLType(OldTy);
   TypeUsers.erase(I);
   
   // Next, remove OldTy's entry in the TargetData object if it has one.

Modified: apple-local/branches/llvm/gcc/toplev.c
===================================================================
--- apple-local/branches/llvm/gcc/toplev.c	2007-02-14 20:34:14 UTC (rev 123873)
+++ apple-local/branches/llvm/gcc/toplev.c	2007-02-14 21:54:21 UTC (rev 123874)
@@ -2279,6 +2279,13 @@
 	unlink (asm_file_name2);
       else if (fclose (asm_out_file) != 0)
 	/* APPLE LOCAL end ss2 */
+        /* APPLE LOCAL begin LLVM */
+#ifdef ENABLE_LLVM
+        /* While reading bytecodes from PCH file, asm_out_file was already 
+           closed by llvm-backend.  */
+        if (!flag_llvm_pch_read)
+#endif
+          /* APPLE LOCAL end LLVM */
 	fatal_error ("error closing %s: %m", asm_file_name);
     }
 

Modified: apple-local/branches/llvm/gcc/tree.h
===================================================================
--- apple-local/branches/llvm/gcc/tree.h	2007-02-14 20:34:14 UTC (rev 123873)
+++ apple-local/branches/llvm/gcc/tree.h	2007-02-14 21:54:21 UTC (rev 123874)
@@ -1750,7 +1750,7 @@
     char * GTY ((tag ("1"))) pointer;
     struct die_struct * GTY ((tag ("2"))) die;
     /* APPLE LOCAL begin LLVM */
-    long GTY ((tag ("3"))) llvm;   /* Really an LLVM "Type*" */
+    unsigned GTY ((tag ("3"))) llvm;   /* Really an LLVM Type vector (LTypes) index */
   } GTY ((desc ("LLVM_IS_ENABLED ? 3 : debug_hooks == &sdb_debug_hooks ? 1 : debug_hooks == &dwarf2_debug_hooks ? 2 : 0"),
 	  descbits ("2"))) symtab;
 /* APPLE LOCAL end LLVM */
@@ -2078,13 +2078,6 @@
 #define SET_DECL_LLVM(NODE, LLVM) \
   (DECL_CHECK (NODE)->decl.llvm = (long)(Value*)LLVM)
 
-/* GET_TYPE_LLVM/SET_TYPE_LLVM - Associate an LLVM type with each TREE type.
- * These are lazily computed by ConvertType, accessors available only to C++
- * code.
- */
-#define GET_TYPE_LLVM(NODE) (const Type *)(TYPE_CHECK (NODE)->type.symtab.llvm)
-#define SET_TYPE_LLVM(NODE, TYPE) \
-   (const Type*)((TYPE_CHECK (NODE)->type.symtab.llvm) = (long)(TYPE))
 #else
 /* C versions */
 #define DECL_LLVM(NODE)					\





More information about the llvm-commits mailing list