[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