From 74391b48b4791cded373683a3baf67314f358d50 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 22 Mar 2009 21:03:39 +0000 Subject: [PATCH] pull "runtime globals" into the same framework as other functions/global variables. No intended functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67478 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGObjC.cpp | 5 +- lib/CodeGen/CGObjCMac.cpp | 63 ++++++------ lib/CodeGen/CGObjCRuntime.h | 6 +- lib/CodeGen/CodeGenModule.cpp | 189 +++++++++++++++------------------- lib/CodeGen/CodeGenModule.h | 31 +++--- 5 files changed, 132 insertions(+), 162 deletions(-) diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index acc07c740a..de63f51b33 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -422,9 +422,8 @@ void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp, assert (0 && "bad expression node in EmitObjCPropertySet"); } -void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S) -{ - llvm::Function *EnumerationMutationFn = +void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ + llvm::Constant *EnumerationMutationFn = CGM.getObjCRuntime().EnumerationMutationFunction(); llvm::Value *DeclAddress; QualType ElementTy; diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index e14a58af4c..4ceaab03f3 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -84,33 +84,33 @@ public: /// CachePtrTy - LLVM type for struct objc_cache *. const llvm::Type *CachePtrTy; - llvm::Function *GetPropertyFn, *SetPropertyFn; + llvm::Constant *GetPropertyFn, *SetPropertyFn; - llvm::Function *EnumerationMutationFn; + llvm::Constant *EnumerationMutationFn; /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function. - llvm::Function *GcReadWeakFn; + llvm::Constant *GcReadWeakFn; /// GcAssignWeakFn -- LLVM objc_assign_weak function. - llvm::Function *GcAssignWeakFn; + llvm::Constant *GcAssignWeakFn; /// GcAssignGlobalFn -- LLVM objc_assign_global function. - llvm::Function *GcAssignGlobalFn; + llvm::Constant *GcAssignGlobalFn; /// GcAssignIvarFn -- LLVM objc_assign_ivar function. - llvm::Function *GcAssignIvarFn; + llvm::Constant *GcAssignIvarFn; /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function. - llvm::Function *GcAssignStrongCastFn; + llvm::Constant *GcAssignStrongCastFn; /// ExceptionThrowFn - LLVM objc_exception_throw function. - llvm::Function *ExceptionThrowFn; + llvm::Constant *ExceptionThrowFn; /// SyncEnterFn - LLVM object_sync_enter function. - llvm::Function *SyncEnterFn; + llvm::Constant *SyncEnterFn; /// SyncExitFn - LLVM object_sync_exit function. - llvm::Function *SyncExitFn; + llvm::Constant *SyncExitFn; ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm); ~ObjCCommonTypesHelper(){} @@ -121,8 +121,8 @@ public: class ObjCTypesHelper : public ObjCCommonTypesHelper { private: - llvm::Function *MessageSendFn, *MessageSendStretFn, *MessageSendFpretFn; - llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn, + llvm::Constant *MessageSendFn, *MessageSendStretFn, *MessageSendFpretFn; + llvm::Constant *MessageSendSuperFn, *MessageSendSuperStretFn, *MessageSendSuperFpretFn; public: @@ -181,34 +181,34 @@ public: const llvm::Type *ExceptionDataTy; /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function. - llvm::Function *ExceptionTryEnterFn; + llvm::Constant *ExceptionTryEnterFn; /// ExceptionTryExitFn - LLVM objc_exception_try_exit function. - llvm::Function *ExceptionTryExitFn; + llvm::Constant *ExceptionTryExitFn; /// ExceptionExtractFn - LLVM objc_exception_extract function. - llvm::Function *ExceptionExtractFn; + llvm::Constant *ExceptionExtractFn; /// ExceptionMatchFn - LLVM objc_exception_match function. - llvm::Function *ExceptionMatchFn; + llvm::Constant *ExceptionMatchFn; /// SetJmpFn - LLVM _setjmp function. - llvm::Function *SetJmpFn; + llvm::Constant *SetJmpFn; public: ObjCTypesHelper(CodeGen::CodeGenModule &cgm); ~ObjCTypesHelper() {} - llvm::Function *getSendFn(bool IsSuper) { + llvm::Constant *getSendFn(bool IsSuper) { return IsSuper ? MessageSendSuperFn : MessageSendFn; } - llvm::Function *getSendStretFn(bool IsSuper) { + llvm::Constant *getSendStretFn(bool IsSuper) { return IsSuper ? MessageSendSuperStretFn : MessageSendStretFn; } - llvm::Function *getSendFpretFn(bool IsSuper) { + llvm::Constant *getSendFpretFn(bool IsSuper) { return IsSuper ? MessageSendSuperFpretFn : MessageSendFpretFn; } }; @@ -217,7 +217,7 @@ public: /// modern abi class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper { public: - llvm::Function *MessageSendFixupFn, *MessageSendFpretFixupFn, + llvm::Constant *MessageSendFixupFn, *MessageSendFpretFixupFn, *MessageSendStretFixupFn, *MessageSendIdFixupFn, *MessageSendIdStretFixupFn, *MessageSendSuper2FixupFn, *MessageSendSuper2StretFixupFn; @@ -297,7 +297,7 @@ public: /// exception personality function. llvm::Value *EHPersonalityPtr; - llvm::Function *UnwindResumeOrRethrowFn, *ObjCBeginCatchFn, *ObjCEndCatchFn; + llvm::Constant *UnwindResumeOrRethrowFn, *ObjCBeginCatchFn, *ObjCEndCatchFn; const llvm::StructType *EHTypeTy; const llvm::Type *EHTypePtrTy; @@ -652,9 +652,9 @@ private: virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, const ObjCProtocolDecl *PD); - virtual llvm::Function *GetPropertyGetFunction(); - virtual llvm::Function *GetPropertySetFunction(); - virtual llvm::Function *EnumerationMutationFunction(); + virtual llvm::Constant *GetPropertyGetFunction(); + virtual llvm::Constant *GetPropertySetFunction(); + virtual llvm::Constant *EnumerationMutationFunction(); virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S); @@ -817,13 +817,13 @@ public: virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, const ObjCProtocolDecl *PD); - virtual llvm::Function *GetPropertyGetFunction(){ + virtual llvm::Constant *GetPropertyGetFunction() { return ObjCTypes.GetPropertyFn; } - virtual llvm::Function *GetPropertySetFunction(){ + virtual llvm::Constant *GetPropertySetFunction() { return ObjCTypes.SetPropertyFn; } - virtual llvm::Function *EnumerationMutationFunction() { + virtual llvm::Constant *EnumerationMutationFunction() { return ObjCTypes.EnumerationMutationFn; } @@ -1879,16 +1879,15 @@ llvm::Function *CGObjCMac::ModuleInitFunction() { return NULL; } -llvm::Function *CGObjCMac::GetPropertyGetFunction() { +llvm::Constant *CGObjCMac::GetPropertyGetFunction() { return ObjCTypes.GetPropertyFn; } -llvm::Function *CGObjCMac::GetPropertySetFunction() { +llvm::Constant *CGObjCMac::GetPropertySetFunction() { return ObjCTypes.SetPropertyFn; } -llvm::Function *CGObjCMac::EnumerationMutationFunction() -{ +llvm::Constant *CGObjCMac::EnumerationMutationFunction() { return ObjCTypes.EnumerationMutationFn; } diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index 63a7630dc0..7c66ff6f7b 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -123,10 +123,10 @@ public: const ObjCContainerDecl *CD) = 0; /// Return the runtime function for getting properties. - virtual llvm::Function *GetPropertyGetFunction() = 0; + virtual llvm::Constant *GetPropertyGetFunction() = 0; /// Return the runtime function for setting properties. - virtual llvm::Function *GetPropertySetFunction() = 0; + virtual llvm::Constant *GetPropertySetFunction() = 0; /// GetClass - Return a reference to the class for the given /// interface decl. @@ -135,7 +135,7 @@ public: /// EnumerationMutationFunction - Return the function that's called by the /// compiler when a mutation is detected during foreach iteration. - virtual llvm::Function *EnumerationMutationFunction() = 0; + virtual llvm::Constant *EnumerationMutationFunction() = 0; /// If instance variable addresses are determined at runtime then this should /// return true, otherwise instance variables will be accessed directly from diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 6f745f2b90..50743149cc 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -66,53 +66,6 @@ void CodeGenModule::Release() { EmitCtorList(GlobalDtors, "llvm.global_dtors"); EmitAnnotations(); EmitLLVMUsed(); - BindRuntimeGlobals(); -} - -void CodeGenModule::BindRuntimeGlobals() { - // Deal with protecting runtime function names. - for (unsigned i = 0, e = RuntimeGlobals.size(); i < e; ++i) { - llvm::GlobalValue *GV = RuntimeGlobals[i].first; - const std::string &Name = RuntimeGlobals[i].second; - - // Discard unused runtime declarations. - if (GV->isDeclaration() && GV->use_empty()) { - GV->eraseFromParent(); - continue; - } - - // See if there is a conflict against a function by setting the name and - // seeing if we got the desired name. - GV->setName(Name); - if (GV->isName(Name.c_str())) - continue; // Yep, it worked! - - GV->setName(""); // Zap the bogus name until we work out the conflict. - llvm::GlobalValue *Conflict = TheModule.getNamedValue(Name); - assert(Conflict && "Must have conflicted!"); - - // Decide which version to take. If the conflict is a definition - // we are forced to take that, otherwise assume the runtime - // knows best. - - // FIXME: This will fail phenomenally when the conflict is the - // wrong type of value. Just bail on it for now. This should - // really reuse something inside the LLVM Linker code. - assert(GV->getValueID() == Conflict->getValueID() && - "Unable to resolve conflict between globals of different types."); - if (!Conflict->isDeclaration()) { - llvm::Value *Casted = - llvm::ConstantExpr::getBitCast(Conflict, GV->getType()); - GV->replaceAllUsesWith(Casted); - GV->eraseFromParent(); - } else { - GV->takeName(Conflict); - llvm::Value *Casted = - llvm::ConstantExpr::getBitCast(GV, Conflict->getType()); - Conflict->replaceAllUsesWith(Casted); - Conflict->eraseFromParent(); - } - } } /// ErrorUnsupported - Print out an error that codegen doesn't support the @@ -585,17 +538,17 @@ void CodeGenModule::EmitGlobalDefinition(const ValueDecl *D) { } } -/// GetAddrOfFunction - Return the address of the given function. If Ty is -/// non-null, then this function will use the specified type if it has to -/// create it (this occurs when we see a definition of the function). -llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D, - const llvm::Type *Ty) { - // If there was no specific requested type, just convert it now. - if (!Ty) - Ty = getTypes().ConvertType(D->getType()); - +/// GetOrCreateLLVMFunction - If the specified mangled name is not in the +/// module, create and return an llvm Function with the specified type. If there +/// is something in the module with the specified name, return it potentially +/// bitcasted to the right type. +/// +/// If D is non-null, it specifies a decl that correspond to this. This is used +/// to set the attributes on the function when it is first created. +llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName, + const llvm::Type *Ty, + const FunctionDecl *D) { // Lookup the entry, lazily creating it if necessary. - const char *MangledName = getMangledName(D); llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName]; if (Entry) { if (Entry->getType()->getElementType() == Ty) @@ -610,7 +563,7 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D, // deferred decl with this name, remember that we need to emit it at the end // of the file. llvm::DenseMap::iterator DDI = - DeferredDecls.find(MangledName); + DeferredDecls.find(MangledName); if (DDI != DeferredDecls.end()) { // Move the potentially referenced deferred decl to the DeferredDeclsToEmit // list, and remove it from DeferredDecls (since we don't need it anymore). @@ -618,7 +571,6 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D, DeferredDecls.erase(DDI); } - // This function doesn't have a complete type (for example, the return // type is an incomplete struct). Use a fake type instead, and make // sure not to try to set attributes. @@ -632,35 +584,51 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D, llvm::Function::ExternalLinkage, "", &getModule()); F->setName(MangledName); - if (ShouldSetAttributes) + if (D && ShouldSetAttributes) SetFunctionAttributes(D, F); Entry = F; return F; } -/// GetAddrOfGlobalVar - Return the llvm::Constant for the address of the -/// given global variable. If Ty is non-null and if the global doesn't exist, -/// then it will be greated with the specified type instead of whatever the -/// normal requested type would be. -llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D, - const llvm::Type *Ty) { - assert(D->hasGlobalStorage() && "Not a global variable"); +/// GetAddrOfFunction - Return the address of the given function. If Ty is +/// non-null, then this function will use the specified type if it has to +/// create it (this occurs when we see a definition of the function). +llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D, + const llvm::Type *Ty) { + // If there was no specific requested type, just convert it now. + if (!Ty) + Ty = getTypes().ConvertType(D->getType()); + return GetOrCreateLLVMFunction(getMangledName(D), Ty, D); +} - QualType ASTTy = D->getType(); - if (Ty == 0) - Ty = getTypes().ConvertTypeForMem(ASTTy); +/// CreateRuntimeFunction - Create a new runtime function with the specified +/// type and name. +llvm::Constant * +CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy, + const char *Name) { + // Convert Name to be a uniqued string from the IdentifierInfo table. + Name = getContext().Idents.get(Name).getName(); + return GetOrCreateLLVMFunction(Name, FTy, 0); +} +/// GetOrCreateLLVMGlobal - If the specified mangled name is not in the module, +/// create and return an llvm GlobalVariable with the specified type. If there +/// is something in the module with the specified name, return it potentially +/// bitcasted to the right type. +/// +/// If D is non-null, it specifies a decl that correspond to this. This is used +/// to set the attributes on the global when it is first created. +llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName, + const llvm::PointerType*Ty, + const VarDecl *D) { // Lookup the entry, lazily creating it if necessary. - const char *MangledName = getMangledName(D); llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName]; if (Entry) { - if (Entry->getType()->getElementType() == Ty && - Entry->getType()->getAddressSpace() == ASTTy.getAddressSpace()) + if (Entry->getType() == Ty) return Entry; // Make sure the result is of the correct type. - const llvm::Type *PTy = llvm::PointerType::get(Ty, ASTTy.getAddressSpace()); - return llvm::ConstantExpr::getBitCast(Entry, PTy); + return llvm::ConstantExpr::getBitCast(Entry, Ty); } // This is the first use or definition of a mangled name. If there is a @@ -676,28 +644,54 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D, } llvm::GlobalVariable *GV = - new llvm::GlobalVariable(Ty, false, + new llvm::GlobalVariable(Ty->getElementType(), false, llvm::GlobalValue::ExternalLinkage, 0, "", &getModule(), - 0, ASTTy.getAddressSpace()); + 0, Ty->getAddressSpace()); GV->setName(MangledName); // Handle things which are present even on external declarations. + if (D) { + // FIXME: This code is overly simple and should be merged with + // other global handling. + GV->setConstant(D->getType().isConstant(Context)); - // FIXME: This code is overly simple and should be merged with - // other global handling. - - GV->setConstant(D->getType().isConstant(Context)); + // FIXME: Merge with other attribute handling code. + if (D->getStorageClass() == VarDecl::PrivateExtern) + setGlobalVisibility(GV, VisibilityAttr::HiddenVisibility); - // FIXME: Merge with other attribute handling code. + if (D->getAttr() || D->getAttr()) + GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); + } + + return Entry = GV; +} - if (D->getStorageClass() == VarDecl::PrivateExtern) - setGlobalVisibility(GV, VisibilityAttr::HiddenVisibility); - if (D->getAttr() || D->getAttr()) - GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); +/// GetAddrOfGlobalVar - Return the llvm::Constant for the address of the +/// given global variable. If Ty is non-null and if the global doesn't exist, +/// then it will be greated with the specified type instead of whatever the +/// normal requested type would be. +llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D, + const llvm::Type *Ty) { + assert(D->hasGlobalStorage() && "Not a global variable"); + QualType ASTTy = D->getType(); + if (Ty == 0) + Ty = getTypes().ConvertTypeForMem(ASTTy); + + const llvm::PointerType *PTy = + llvm::PointerType::get(Ty, ASTTy.getAddressSpace()); + return GetOrCreateLLVMGlobal(getMangledName(D), PTy, D); +} - return Entry = GV; +/// CreateRuntimeVariable - Create a new runtime global variable with the +/// specified type and name. +llvm::Constant * +CodeGenModule::CreateRuntimeVariable(const llvm::Type *Ty, + const char *Name) { + // Convert Name to be a uniqued string from the IdentifierInfo table. + Name = getContext().Idents.get(Name).getName(); + return GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), 0); } void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { @@ -919,27 +913,6 @@ void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) { AddGlobalDtor(Fn, DA->getPriority()); } -llvm::Function * -CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy, - const std::string &Name) { - llvm::Function *Fn = llvm::Function::Create(FTy, - llvm::Function::ExternalLinkage, - "", &TheModule); - RuntimeGlobals.push_back(std::make_pair(Fn, Name)); - return Fn; -} - -llvm::GlobalVariable * -CodeGenModule::CreateRuntimeVariable(const llvm::Type *Ty, - const std::string &Name) { - llvm::GlobalVariable *GV = - new llvm::GlobalVariable(Ty, /*Constant=*/false, - llvm::GlobalValue::ExternalLinkage, - 0, "", &TheModule); - RuntimeGlobals.push_back(std::make_pair(GV, Name)); - return GV; -} - void CodeGenModule::UpdateCompletedType(const TagDecl *TD) { // Make sure that this type is translated. Types.UpdateCompletedType(TD); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 91030e7aa3..bea2d15c40 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -82,12 +82,6 @@ class CodeGenModule : public BlockModule { llvm::Function *MemMoveFn; llvm::Function *MemSetFn; - /// RuntimeGlobal - List of runtime globals whose names must be - /// protected from introducing conflicts. These globals should be - /// created unnamed, we will name them and patch up conflicts when - /// we release the module. - std::vector > RuntimeGlobals; - /// GlobalDeclMap - Mapping of decl names (represented as unique /// character pointers from either the identifier table or the set /// of mangled names) to global variables we have already @@ -254,14 +248,14 @@ public: void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); } - /// CreateRuntimeFunction - Create a new runtime function whose name must be - /// protected from collisions. - llvm::Function *CreateRuntimeFunction(const llvm::FunctionType *Ty, - const std::string &Name); - /// CreateRuntimeVariable - Create a new runtime global variable - /// whose name must be protected from collisions. - llvm::GlobalVariable *CreateRuntimeVariable(const llvm::Type *Ty, - const std::string &Name); + /// CreateRuntimeFunction - Create a new runtime function with the specified + /// type and name. + llvm::Constant *CreateRuntimeFunction(const llvm::FunctionType *Ty, + const char *Name); + /// CreateRuntimeVariable - Create a new runtime global variable with the + /// specified type and name. + llvm::Constant *CreateRuntimeVariable(const llvm::Type *Ty, + const char *Name); void UpdateCompletedType(const TagDecl *D); @@ -306,6 +300,13 @@ public: private: + llvm::Constant *GetOrCreateLLVMFunction(const char *MangledName, + const llvm::Type *Ty, + const FunctionDecl *D); + llvm::Constant *GetOrCreateLLVMGlobal(const char *MangledName, + const llvm::PointerType *PTy, + const VarDecl *D); + /// SetGlobalValueAttributes - Set attributes for a global decl. void SetGlobalValueAttributes(const Decl *D, bool IsInternal, @@ -352,8 +353,6 @@ private: /// references to global which may otherwise be optimized out. void EmitLLVMUsed(void); - void BindRuntimeGlobals(); - /// MayDeferGeneration - Determine if the given decl can be emitted /// lazily; this is only relevant for definitions. The given decl /// must be either a function or var decl. -- 2.40.0