summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-03-22 21:03:39 +0000
committerChris Lattner <sabre@nondot.org>2009-03-22 21:03:39 +0000
commitd4808924450e86391475b7c6e6c119cd642ae971 (patch)
tree6fa1597da14c0600a825823161b452148fbf8cca /clang/lib/CodeGen/CodeGenModule.cpp
parentd6a7b72944cefcc7c780f1a635706756755d98b7 (diff)
downloadbcm5719-llvm-d4808924450e86391475b7c6e6c119cd642ae971.tar.gz
bcm5719-llvm-d4808924450e86391475b7c6e6c119cd642ae971.zip
pull "runtime globals" into the same framework as other functions/global variables.
No intended functionality change. llvm-svn: 67478
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp189
1 files changed, 81 insertions, 108 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 6f745f2b90c..50743149cc9 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/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<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 @@ 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<WeakAttr>() || D->getAttr<WeakImportAttr>())
+ GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
+ }
+
+ return Entry = GV;
+}
- if (D->getStorageClass() == VarDecl::PrivateExtern)
- setGlobalVisibility(GV, VisibilityAttr::HiddenVisibility);
- if (D->getAttr<WeakAttr>() || D->getAttr<WeakImportAttr>())
- 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);
OpenPOWER on IntegriCloud