All,

As the SVN mirror is lagging by a few days again, I thought I'd make it
easier to keep up to date. The attached patch combines Apple patches
123989, 123990, 123991, 123994, and  123995 (see llvm-commits archive
for details). This patch applies to r276 of the SVN mirror for llvm-gcc.
I believe these are all the changes made since the mirror updated to
r276. 

Hope this helps.

Reid.
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 276)
+++ gcc/tree.h	(working copy)
@@ -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.
Index: gcc/llvm-backend.cpp
===================================================================
--- gcc/llvm-backend.cpp	(revision 276)
+++ gcc/llvm-backend.cpp	(working copy)
@@ -76,8 +76,6 @@
 
 std::vector<std::pair<Function*, int> > StaticCtors, StaticDtors;
 std::vector<GlobalValue*> AttributeUsedGlobals;
-std::map<std::string, GlobalVariable*> EmittedGlobalVars;
-std::map<std::string, Function*> EmittedFunctions;
 
 /// PerFunctionPasses - This is the list of cleanup passes run per-function
 /// as each is compiled.  In cases where we are not doing IPO, it includes the 
@@ -214,6 +212,8 @@
 
   // Read LLVM Types string table
   readLLVMTypesStringTable();
+  readLLVMValuesStringTable();
+
   flag_llvm_pch_read = 1;
 }
 
@@ -432,8 +432,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())
@@ -584,7 +586,6 @@
     GV->replaceAllUsesWith(ConstantExpr::getBitCast(NGV, GV->getType()));
     delete GV;
     SET_DECL_LLVM(decl, NGV);
-    EmittedGlobalVars[NGV->getName()] = NGV;
     GV = NGV;
   }
  
@@ -755,7 +756,7 @@
     assert(Name[0] && "Function with empty name!");
     // If this function has already been created, reuse the decl.  This happens
     // when we have something like __builtin_memset and memset in the same file.
-    Function *&FnEntry = EmittedFunctions[Name];
+    Function *FnEntry = TheModule->getFunction(Name);
     if (FnEntry == 0) {
       unsigned CC;
       const FunctionType *Ty = 
@@ -806,11 +807,11 @@
     } else {
       // If the global has a name, prevent multiple vars with the same name from
       // being created.
-      GlobalVariable *&GVE = EmittedGlobalVars[Name];
+      GlobalVariable *GVE = TheModule->getGlobalVariable(Name);
     
       if (GVE == 0) {
-        GVE = GV = new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage,0,
-                                      Name, TheModule);
+        GV = new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage,0,
+                                Name, TheModule);
 
         // Check for external weak linkage
         if (DECL_EXTERNAL(decl) && DECL_WEAK(decl))
Index: gcc/llvm-convert.cpp
===================================================================
--- gcc/llvm-convert.cpp	(revision 276)
+++ gcc/llvm-convert.cpp	(working copy)
@@ -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
@@ -298,7 +431,7 @@
     else if (DECL_VISIBILITY(FnDecl) == VISIBILITY_DEFAULT)
       Fn->setVisibility(Function::DefaultVisibility);
   } else {
-    Function *&FnEntry = EmittedFunctions[Name];
+    Function *FnEntry = TheModule->getFunction(Name);
     if (FnEntry) {
       assert(FnEntry->getName() == Name && "Same entry, different name?");
       assert(FnEntry->isDeclaration() &&
@@ -322,7 +455,6 @@
       FnEntry->eraseFromParent();
     }
     SET_DECL_LLVM(FnDecl, Fn);
-    FnEntry = Fn;
   }
 
   // The function should not already have a body.
@@ -5160,8 +5292,11 @@
   GlobalVariable *&Slot = StringCSTCache[Init];
   if (Slot) return Slot;
     
+  // Support -fwritable-strings.
+  bool StringIsConstant = !flag_writable_strings;
+  
   // Create a new string global.
-  return Slot = new GlobalVariable(Init->getType(), true,
+  return Slot = new GlobalVariable(Init->getType(), StringIsConstant,
                                    GlobalVariable::InternalLinkage,
                                    Init, "str", TheModule);
 }
Index: gcc/llvm-internal.h
===================================================================
--- gcc/llvm-internal.h	(revision 276)
+++ gcc/llvm-internal.h	(working copy)
@@ -86,16 +86,10 @@
 /// AttributeUsedGlobals - The list of globals that are marked attribute(used).
 extern std::vector<GlobalValue*> AttributeUsedGlobals;
 
-/// EmittedGlobalVars/EmittedFunctions - Keep track of the global variables and
-/// functions we have already emitted.  GCC periodically likes to create
-/// multiple VAR_DECL nodes with the same name and expects them to be linked
-/// together (particularly the objc front-end) and does the same for functions
-/// e.g. builtin_memset vs memset).  Emulate this functionality.
-extern std::map<std::string, GlobalVariable*> EmittedGlobalVars;
-extern std::map<std::string, Function*> EmittedFunctions;
-
 extern void readLLVMTypesStringTable();
 extern void writeLLVMTypesStringTable();
+extern void readLLVMValuesStringTable();
+extern void writeLLVMValuesStringTable();
 
 struct StructTypeConversionInfo;
 
Index: gcc/llvm-types.cpp
===================================================================
--- gcc/llvm-types.cpp	(revision 276)
+++ gcc/llvm-types.cpp	(working copy)
@@ -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;
@@ -212,7 +212,7 @@
 bool isPassedByInvisibleReference(tree Type) {
   // FIXME: Search for TREE_ADDRESSABLE in calls.c, and see if there are other
   // cases that make arguments automatically passed in by reference.
-  return TREE_ADDRESSABLE(Type);
+  return TREE_ADDRESSABLE(Type) || TREE_CODE(TYPE_SIZE(Type)) != INTEGER_CST;
 }
 
 /// GetTypeName - Return a fully qualified (with namespace prefixes) name for
Index: gcc/c-common.c
===================================================================
--- gcc/c-common.c	(revision 276)
+++ gcc/c-common.c	(working copy)
@@ -2414,6 +2414,11 @@
     folded = fold (result);
     if (folded == result)
       TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop);
+    
+    /* If the original was void* + int, we converted it to char* + int.  Convert
+       back to the appropriate void* result.  */
+    if (!size_set)
+      folded = convert(result_type, folded);
     return folded;
   }
 #endif
Index: gcc/llvm-abi.h
===================================================================
--- gcc/llvm-abi.h	(revision 276)
+++ gcc/llvm-abi.h	(working copy)
@@ -96,6 +96,10 @@
   default:
     return 0;
   case RECORD_TYPE:
+    // If this record has variable length, reject it.
+    if (TREE_CODE(TYPE_SIZE(type)) != INTEGER_CST)
+      return 0;
+
     for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field))
       if (TREE_CODE(Field) == FIELD_DECL) {
         if (!FoundField)
@@ -108,7 +112,8 @@
     tree Domain = TYPE_DOMAIN(type);
     if (!Domain || !TYPE_MIN_VALUE(Domain) || !TYPE_MAX_VALUE(Domain))
       return 0;
-    if (TREE_CODE(TYPE_MIN_VALUE(Domain)) != INTEGER_CST ||
+    if (TREE_CODE(TYPE_SIZE(type)) != INTEGER_CST ||
+        TREE_CODE(TYPE_MIN_VALUE(Domain)) != INTEGER_CST ||
         TREE_CODE(TYPE_MAX_VALUE(Domain)) != INTEGER_CST)
       return 0;
     if (TREE_INT_CST_LOW(TYPE_MAX_VALUE(Domain)) !=
@@ -194,7 +199,7 @@
   void HandleArgument(tree type) {
     const Type *Ty = ConvertType(type);
 
-    if (TREE_ADDRESSABLE(type)) {    // Constructible object, pass by-ref
+    if (isPassedByInvisibleReference(type)) { // variable size -> by-ref.
       C.HandleScalarArgument(PointerType::get(Ty), type);
     } else if (Ty->isFirstClassType()) {
       C.HandleScalarArgument(Ty, type);
_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to