summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2012-08-15 20:02:54 +0000
committerdim <dim@FreeBSD.org>2012-08-15 20:02:54 +0000
commit554bcb69c2d785a011a30e7db87a36a87fe7db10 (patch)
tree9abb1a658a297776086f4e0dfa6ca533de02104e /lib/CodeGen/CodeGenModule.cpp
parentbb67ca86b31f67faee50bd10c3b036d65751745a (diff)
downloadFreeBSD-src-554bcb69c2d785a011a30e7db87a36a87fe7db10.zip
FreeBSD-src-554bcb69c2d785a011a30e7db87a36a87fe7db10.tar.gz
Vendor import of clang trunk r161861:
http://llvm.org/svn/llvm-project/cfe/trunk@161861
Diffstat (limited to 'lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--lib/CodeGen/CodeGenModule.cpp146
1 files changed, 109 insertions, 37 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 9a55c08..3ae3c52 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -102,14 +102,16 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
if (LangOpts.CUDA)
createCUDARuntime();
- // Enable TBAA unless it's suppressed.
- if (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0)
- TBAA = new CodeGenTBAA(Context, VMContext, getLangOpts(),
+ // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0.
+ if (LangOpts.ThreadSanitizer ||
+ (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0))
+ TBAA = new CodeGenTBAA(Context, VMContext, CodeGenOpts, getLangOpts(),
ABI.getMangleContext());
// If debug info or coverage generation is enabled, create the CGDebugInfo
// object.
- if (CodeGenOpts.DebugInfo || CodeGenOpts.EmitGcovArcs ||
+ if (CodeGenOpts.DebugInfo != CodeGenOptions::NoDebugInfo ||
+ CodeGenOpts.EmitGcovArcs ||
CodeGenOpts.EmitGcovNotes)
DebugInfo = new CGDebugInfo(*this);
@@ -133,10 +135,22 @@ CodeGenModule::~CodeGenModule() {
}
void CodeGenModule::createObjCRuntime() {
- if (!LangOpts.NeXTRuntime)
+ // This is just isGNUFamily(), but we want to force implementors of
+ // new ABIs to decide how best to do this.
+ switch (LangOpts.ObjCRuntime.getKind()) {
+ case ObjCRuntime::GNUstep:
+ case ObjCRuntime::GCC:
+ case ObjCRuntime::ObjFW:
ObjCRuntime = CreateGNUObjCRuntime(*this);
- else
+ return;
+
+ case ObjCRuntime::FragileMacOSX:
+ case ObjCRuntime::MacOSX:
+ case ObjCRuntime::iOS:
ObjCRuntime = CreateMacObjCRuntime(*this);
+ return;
+ }
+ llvm_unreachable("bad runtime kind");
}
void CodeGenModule::createOpenCLRuntime() {
@@ -245,6 +259,45 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
GV->setVisibility(GetLLVMVisibility(LV.visibility()));
}
+static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(StringRef S) {
+ return llvm::StringSwitch<llvm::GlobalVariable::ThreadLocalMode>(S)
+ .Case("global-dynamic", llvm::GlobalVariable::GeneralDynamicTLSModel)
+ .Case("local-dynamic", llvm::GlobalVariable::LocalDynamicTLSModel)
+ .Case("initial-exec", llvm::GlobalVariable::InitialExecTLSModel)
+ .Case("local-exec", llvm::GlobalVariable::LocalExecTLSModel);
+}
+
+static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(
+ CodeGenOptions::TLSModel M) {
+ switch (M) {
+ case CodeGenOptions::GeneralDynamicTLSModel:
+ return llvm::GlobalVariable::GeneralDynamicTLSModel;
+ case CodeGenOptions::LocalDynamicTLSModel:
+ return llvm::GlobalVariable::LocalDynamicTLSModel;
+ case CodeGenOptions::InitialExecTLSModel:
+ return llvm::GlobalVariable::InitialExecTLSModel;
+ case CodeGenOptions::LocalExecTLSModel:
+ return llvm::GlobalVariable::LocalExecTLSModel;
+ }
+ llvm_unreachable("Invalid TLS model!");
+}
+
+void CodeGenModule::setTLSMode(llvm::GlobalVariable *GV,
+ const VarDecl &D) const {
+ assert(D.isThreadSpecified() && "setting TLS mode on non-TLS var!");
+
+ llvm::GlobalVariable::ThreadLocalMode TLM;
+ TLM = GetLLVMTLSModel(CodeGenOpts.DefaultTLSModel);
+
+ // Override the TLS model if it is explicitly specified.
+ if (D.hasAttr<TLSModelAttr>()) {
+ const TLSModelAttr *Attr = D.getAttr<TLSModelAttr>();
+ TLM = GetLLVMTLSModel(Attr->getModel());
+ }
+
+ GV->setThreadLocalMode(TLM);
+}
+
/// Set the symbol visibility of type information (vtable and RTTI)
/// associated with the given type.
void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV,
@@ -334,7 +387,8 @@ StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
else if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND))
getCXXABI().getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Out);
else if (const BlockDecl *BD = dyn_cast<BlockDecl>(ND))
- getCXXABI().getMangleContext().mangleBlock(BD, Out);
+ getCXXABI().getMangleContext().mangleBlock(BD, Out,
+ dyn_cast_or_null<VarDecl>(initializedGlobalDecl.getDecl()));
else
getCXXABI().getMangleContext().mangleName(ND, Out);
@@ -355,7 +409,8 @@ void CodeGenModule::getBlockMangledName(GlobalDecl GD, MangleBuffer &Buffer,
const Decl *D = GD.getDecl();
llvm::raw_svector_ostream Out(Buffer.getBuffer());
if (D == 0)
- MangleCtx.mangleGlobalBlock(BD, Out);
+ MangleCtx.mangleGlobalBlock(BD,
+ dyn_cast_or_null<VarDecl>(initializedGlobalDecl.getDecl()), Out);
else if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))
MangleCtx.mangleCtorBlock(CD, GD.getCtorType(), BD, Out);
else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D))
@@ -474,8 +529,7 @@ void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D,
unsigned CallingConv;
AttributeListType AttributeList;
ConstructAttributeList(Info, D, AttributeList, CallingConv);
- F->setAttributes(llvm::AttrListPtr::get(AttributeList.begin(),
- AttributeList.size()));
+ F->setAttributes(llvm::AttrListPtr::get(AttributeList));
F->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
}
@@ -493,7 +547,7 @@ static bool hasUnwindExceptions(const LangOptions &LangOpts) {
// If ObjC exceptions are enabled, this depends on the ABI.
if (LangOpts.ObjCExceptions) {
- if (!LangOpts.ObjCNonFragileABI) return false;
+ return LangOpts.ObjCRuntime.hasUnwindExceptions();
}
return true;
@@ -517,10 +571,14 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
F->addFnAttr(llvm::Attribute::NoInline);
// (noinline wins over always_inline, and we can't specify both in IR)
- if (D->hasAttr<AlwaysInlineAttr>() &&
+ if ((D->hasAttr<AlwaysInlineAttr>() || D->hasAttr<ForceInlineAttr>()) &&
!F->hasFnAttr(llvm::Attribute::NoInline))
F->addFnAttr(llvm::Attribute::AlwaysInline);
+ // FIXME: Communicate hot and cold attributes to LLVM more directly.
+ if (D->hasAttr<ColdAttr>())
+ F->addFnAttr(llvm::Attribute::OptimizeForSize);
+
if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D))
F->setUnnamedAddr(true);
@@ -652,7 +710,7 @@ void CodeGenModule::EmitDeferred() {
if (!DeferredVTables.empty()) {
const CXXRecordDecl *RD = DeferredVTables.back();
DeferredVTables.pop_back();
- getVTables().GenerateClassData(getVTableLinkage(RD), RD);
+ getCXXABI().EmitVTables(RD);
continue;
}
@@ -930,7 +988,7 @@ CodeGenModule::shouldEmitFunction(const FunctionDecl *F) {
if (getFunctionLinkage(F) != llvm::Function::AvailableExternallyLinkage)
return true;
if (CodeGenOpts.OptimizationLevel == 0 &&
- !F->hasAttr<AlwaysInlineAttr>())
+ !F->hasAttr<AlwaysInlineAttr>() && !F->hasAttr<ForceInlineAttr>())
return false;
// PR9614. Avoid cases where the source code is lying to us. An available
// externally function should have an equivalent function somewhere else,
@@ -1054,6 +1112,7 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,
} else if (getLangOpts().CPlusPlus && D.getDecl()) {
// Look for a declaration that's lexically in a record.
const FunctionDecl *FD = cast<FunctionDecl>(D.getDecl());
+ FD = FD->getMostRecentDecl();
do {
if (isa<CXXRecordDecl>(FD->getLexicalDeclContext())) {
if (FD->isImplicit() && !ForVTable) {
@@ -1166,11 +1225,12 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
DeferredDecls.erase(DDI);
}
+ unsigned AddrSpace = GetGlobalVarAddressSpace(D, Ty->getAddressSpace());
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(getModule(), Ty->getElementType(), false,
llvm::GlobalValue::ExternalLinkage,
0, MangledName, 0,
- false, Ty->getAddressSpace());
+ llvm::GlobalVariable::NotThreadLocal, AddrSpace);
// Handle things which are present even on external declarations.
if (D) {
@@ -1193,10 +1253,14 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
GV->setVisibility(GetLLVMVisibility(LV.visibility()));
}
- GV->setThreadLocal(D->isThreadSpecified());
+ if (D->isThreadSpecified())
+ setTLSMode(GV, *D);
}
- return GV;
+ if (AddrSpace != Ty->getAddressSpace())
+ return llvm::ConstantExpr::getBitCast(GV, Ty);
+ else
+ return GV;
}
@@ -1286,7 +1350,7 @@ void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) {
void CodeGenModule::EmitVTable(CXXRecordDecl *Class, bool DefinitionRequired) {
if (DefinitionRequired)
- getVTables().GenerateClassData(getVTableLinkage(Class), Class);
+ getCXXABI().EmitVTables(Class);
}
llvm::GlobalVariable::LinkageTypes
@@ -1481,6 +1545,20 @@ CodeGenModule::MaybeEmitGlobalStdInitializerListInitializer(const VarDecl *D,
return llvmInit;
}
+unsigned CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D,
+ unsigned AddrSpace) {
+ if (LangOpts.CUDA && CodeGenOpts.CUDAIsDevice) {
+ if (D->hasAttr<CUDAConstantAttr>())
+ AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_constant);
+ else if (D->hasAttr<CUDASharedAttr>())
+ AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_shared);
+ else
+ AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_device);
+ }
+
+ return AddrSpace;
+}
+
void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
llvm::Constant *Init = 0;
QualType ASTTy = D->getType();
@@ -1511,8 +1589,10 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
// FIXME: It does so in a global constructor, which is *not* what we
// want.
- if (!Init)
+ if (!Init) {
+ initializedGlobalDecl = GlobalDecl(D);
Init = EmitConstantInit(*InitDecl);
+ }
if (!Init) {
QualType T = InitExpr->getType();
if (D->getType()->isReferenceType())
@@ -1560,7 +1640,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
if (GV == 0 ||
GV->getType()->getElementType() != InitType ||
GV->getType()->getAddressSpace() !=
- getContext().getTargetAddressSpace(ASTTy)) {
+ GetGlobalVarAddressSpace(D, getContext().getTargetAddressSpace(ASTTy))) {
// Move the old entry aside so that we'll create a new one.
Entry->setName(StringRef());
@@ -1604,7 +1684,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
// Emit global variable debug information.
if (CGDebugInfo *DI = getModuleDebugInfo())
- DI->EmitGlobalVariable(GV, D);
+ if (getCodeGenOpts().DebugInfo >= CodeGenOptions::LimitedDebugInfo)
+ DI->EmitGlobalVariable(GV, D);
}
llvm::GlobalValue::LinkageTypes
@@ -1710,8 +1791,7 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old,
ArgList.clear();
if (!NewCall->getType()->isVoidTy())
NewCall->takeName(CI);
- NewCall->setAttributes(llvm::AttrListPtr::get(AttrVec.begin(),
- AttrVec.end()));
+ NewCall->setAttributes(llvm::AttrListPtr::get(AttrVec));
NewCall->setCallingConv(CI->getCallingConv());
// Finally, remove the old call, replacing any uses with the new one.
@@ -2059,7 +2139,7 @@ CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) {
std::string StringClass(getLangOpts().ObjCConstantStringClass);
llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
llvm::Constant *GV;
- if (LangOpts.ObjCNonFragileABI) {
+ if (LangOpts.ObjCRuntime.isNonFragile()) {
std::string str =
StringClass.empty() ? "OBJC_CLASS_$_NSConstantString"
: "OBJC_CLASS_$_" + StringClass;
@@ -2104,7 +2184,7 @@ CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) {
FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false,
- /*HasInit=*/false);
+ ICIS_NoInit);
Field->setAccess(AS_public);
D->addDecl(Field);
}
@@ -2147,7 +2227,7 @@ CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) {
"_unnamed_nsstring_");
// FIXME. Fix section.
if (const char *Sect =
- LangOpts.ObjCNonFragileABI
+ LangOpts.ObjCRuntime.isNonFragile()
? getContext().getTargetInfo().getNSStringNonFragileABISection()
: getContext().getTargetInfo().getNSStringSection())
GV->setSection(Sect);
@@ -2179,7 +2259,7 @@ QualType CodeGenModule::getObjCFastEnumerationStateType() {
FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false,
- /*HasInit=*/false);
+ ICIS_NoInit);
Field->setAccess(AS_public);
D->addDecl(Field);
}
@@ -2506,14 +2586,8 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
// Forward declarations, no (immediate) code generation.
case Decl::ObjCInterface:
+ case Decl::ObjCCategory:
break;
-
- case Decl::ObjCCategory: {
- ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
- if (CD->IsClassExtension() && CD->hasSynthBitfield())
- Context.ResetObjCLayout(CD->getClassInterface());
- break;
- }
case Decl::ObjCProtocol: {
ObjCProtocolDecl *Proto = cast<ObjCProtocolDecl>(D);
@@ -2530,8 +2604,6 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
case Decl::ObjCImplementation: {
ObjCImplementationDecl *OMD = cast<ObjCImplementationDecl>(D);
- if (LangOpts.ObjCNonFragileABI2 && OMD->hasSynthBitfield())
- Context.ResetObjCLayout(OMD->getClassInterface());
EmitObjCPropertyImplementations(OMD);
EmitObjCIvarInitializations(OMD);
ObjCRuntime->GenerateClass(OMD);
@@ -2564,7 +2636,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
const std::string &S = getModule().getModuleInlineAsm();
if (S.empty())
getModule().setModuleInlineAsm(AsmString);
- else if (*--S.end() == '\n')
+ else if (S.end()[-1] == '\n')
getModule().setModuleInlineAsm(S + AsmString.str());
else
getModule().setModuleInlineAsm(S + '\n' + AsmString.str());
OpenPOWER on IntegriCloud