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. _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits