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