diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2012-08-15 20:02:54 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2012-08-15 20:02:54 +0000 | 
| commit | 56d91b49b13fe55c918afbda19f6165b5fbff87a (patch) | |
| tree | 9abb1a658a297776086f4e0dfa6ca533de02104e /lib/CodeGen/CodeGenModule.cpp | |
| parent | 41e20f564abdb05101d6b2b29c59459a966c22cc (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/CodeGenModule.cpp')
| -rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 146 | 
1 files changed, 109 insertions, 37 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 9a55c0848006..3ae3c521300b 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());  | 
