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
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index acc07c7..de63f51 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -422,9 +422,8 @@
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 e14a58a..4ceaab0 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -84,33 +84,33 @@
/// 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 @@
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 @@
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 @@
/// modern abi
class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
public:
- llvm::Function *MessageSendFixupFn, *MessageSendFpretFixupFn,
+ llvm::Constant *MessageSendFixupFn, *MessageSendFpretFixupFn,
*MessageSendStretFixupFn, *MessageSendIdFixupFn,
*MessageSendIdStretFixupFn, *MessageSendSuper2FixupFn,
*MessageSendSuper2StretFixupFn;
@@ -297,7 +297,7 @@
/// 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 @@
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 @@
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 @@
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 63a7630..7c66ff6 100644
--- a/lib/CodeGen/CGObjCRuntime.h
+++ b/lib/CodeGen/CGObjCRuntime.h
@@ -123,10 +123,10 @@
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 @@
/// 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 6f745f2..5074314 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -66,53 +66,6 @@
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 @@
}
}
-/// 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 @@
// deferred decl with this name, remember that we need to emit it at the end
// of the file.
llvm::DenseMap<const char*, const ValueDecl*>::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 @@
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::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,30 +644,56 @@
}
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.
+ // FIXME: Merge with other attribute handling code.
+ if (D->getStorageClass() == VarDecl::PrivateExtern)
+ setGlobalVisibility(GV, VisibilityAttr::HiddenVisibility);
- GV->setConstant(D->getType().isConstant(Context));
-
- // FIXME: Merge with other attribute handling code.
-
- if (D->getStorageClass() == VarDecl::PrivateExtern)
- setGlobalVisibility(GV, VisibilityAttr::HiddenVisibility);
-
- if (D->getAttr<WeakAttr>() || D->getAttr<WeakImportAttr>())
- GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
-
+ if (D->getAttr<WeakAttr>() || D->getAttr<WeakImportAttr>())
+ GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
+ }
+
return Entry = GV;
}
+
+/// 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);
+}
+
+/// 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) {
llvm::Constant *Init = 0;
QualType ASTTy = D->getType();
@@ -919,27 +913,6 @@
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 91030e7..bea2d15 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -82,12 +82,6 @@
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<std::pair<llvm::GlobalValue*, std::string> > 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 @@
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 @@
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 @@
/// 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.