10b57cec5SDimitry Andric //===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This contains code to emit Decl nodes as LLVM code. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "CGBlocks.h" 140b57cec5SDimitry Andric #include "CGCXXABI.h" 150b57cec5SDimitry Andric #include "CGCleanup.h" 160b57cec5SDimitry Andric #include "CGDebugInfo.h" 170b57cec5SDimitry Andric #include "CGOpenCLRuntime.h" 180b57cec5SDimitry Andric #include "CGOpenMPRuntime.h" 190b57cec5SDimitry Andric #include "CodeGenFunction.h" 200b57cec5SDimitry Andric #include "CodeGenModule.h" 210b57cec5SDimitry Andric #include "ConstantEmitter.h" 22*0fca6ea1SDimitry Andric #include "EHScopeStack.h" 230b57cec5SDimitry Andric #include "PatternInit.h" 240b57cec5SDimitry Andric #include "TargetInfo.h" 250b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 26480093f4SDimitry Andric #include "clang/AST/Attr.h" 270b57cec5SDimitry Andric #include "clang/AST/CharUnits.h" 280b57cec5SDimitry Andric #include "clang/AST/Decl.h" 290b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h" 300b57cec5SDimitry Andric #include "clang/AST/DeclOpenMP.h" 310b57cec5SDimitry Andric #include "clang/Basic/CodeGenOptions.h" 320b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h" 330b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 340b57cec5SDimitry Andric #include "clang/CodeGen/CGFunctionInfo.h" 355ffd83dbSDimitry Andric #include "clang/Sema/Sema.h" 36*0fca6ea1SDimitry Andric #include "llvm/Analysis/ConstantFolding.h" 370b57cec5SDimitry Andric #include "llvm/Analysis/ValueTracking.h" 380b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 390b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h" 40*0fca6ea1SDimitry Andric #include "llvm/IR/Instructions.h" 410b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h" 420b57cec5SDimitry Andric #include "llvm/IR/Type.h" 43bdd1243dSDimitry Andric #include <optional> 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric using namespace clang; 460b57cec5SDimitry Andric using namespace CodeGen; 470b57cec5SDimitry Andric 485ffd83dbSDimitry Andric static_assert(clang::Sema::MaximumAlignment <= llvm::Value::MaximumAlignment, 495ffd83dbSDimitry Andric "Clang max alignment greater than what LLVM supports?"); 505ffd83dbSDimitry Andric 510b57cec5SDimitry Andric void CodeGenFunction::EmitDecl(const Decl &D) { 520b57cec5SDimitry Andric switch (D.getKind()) { 530b57cec5SDimitry Andric case Decl::BuiltinTemplate: 540b57cec5SDimitry Andric case Decl::TranslationUnit: 550b57cec5SDimitry Andric case Decl::ExternCContext: 560b57cec5SDimitry Andric case Decl::Namespace: 570b57cec5SDimitry Andric case Decl::UnresolvedUsingTypename: 580b57cec5SDimitry Andric case Decl::ClassTemplateSpecialization: 590b57cec5SDimitry Andric case Decl::ClassTemplatePartialSpecialization: 600b57cec5SDimitry Andric case Decl::VarTemplateSpecialization: 610b57cec5SDimitry Andric case Decl::VarTemplatePartialSpecialization: 620b57cec5SDimitry Andric case Decl::TemplateTypeParm: 630b57cec5SDimitry Andric case Decl::UnresolvedUsingValue: 640b57cec5SDimitry Andric case Decl::NonTypeTemplateParm: 650b57cec5SDimitry Andric case Decl::CXXDeductionGuide: 660b57cec5SDimitry Andric case Decl::CXXMethod: 670b57cec5SDimitry Andric case Decl::CXXConstructor: 680b57cec5SDimitry Andric case Decl::CXXDestructor: 690b57cec5SDimitry Andric case Decl::CXXConversion: 700b57cec5SDimitry Andric case Decl::Field: 710b57cec5SDimitry Andric case Decl::MSProperty: 720b57cec5SDimitry Andric case Decl::IndirectField: 730b57cec5SDimitry Andric case Decl::ObjCIvar: 740b57cec5SDimitry Andric case Decl::ObjCAtDefsField: 750b57cec5SDimitry Andric case Decl::ParmVar: 760b57cec5SDimitry Andric case Decl::ImplicitParam: 770b57cec5SDimitry Andric case Decl::ClassTemplate: 780b57cec5SDimitry Andric case Decl::VarTemplate: 790b57cec5SDimitry Andric case Decl::FunctionTemplate: 800b57cec5SDimitry Andric case Decl::TypeAliasTemplate: 810b57cec5SDimitry Andric case Decl::TemplateTemplateParm: 820b57cec5SDimitry Andric case Decl::ObjCMethod: 830b57cec5SDimitry Andric case Decl::ObjCCategory: 840b57cec5SDimitry Andric case Decl::ObjCProtocol: 850b57cec5SDimitry Andric case Decl::ObjCInterface: 860b57cec5SDimitry Andric case Decl::ObjCCategoryImpl: 870b57cec5SDimitry Andric case Decl::ObjCImplementation: 880b57cec5SDimitry Andric case Decl::ObjCProperty: 890b57cec5SDimitry Andric case Decl::ObjCCompatibleAlias: 900b57cec5SDimitry Andric case Decl::PragmaComment: 910b57cec5SDimitry Andric case Decl::PragmaDetectMismatch: 920b57cec5SDimitry Andric case Decl::AccessSpec: 930b57cec5SDimitry Andric case Decl::LinkageSpec: 940b57cec5SDimitry Andric case Decl::Export: 950b57cec5SDimitry Andric case Decl::ObjCPropertyImpl: 960b57cec5SDimitry Andric case Decl::FileScopeAsm: 97bdd1243dSDimitry Andric case Decl::TopLevelStmt: 980b57cec5SDimitry Andric case Decl::Friend: 990b57cec5SDimitry Andric case Decl::FriendTemplate: 1000b57cec5SDimitry Andric case Decl::Block: 1010b57cec5SDimitry Andric case Decl::Captured: 1020b57cec5SDimitry Andric case Decl::UsingShadow: 1030b57cec5SDimitry Andric case Decl::ConstructorUsingShadow: 1040b57cec5SDimitry Andric case Decl::ObjCTypeParam: 1050b57cec5SDimitry Andric case Decl::Binding: 106fe6060f1SDimitry Andric case Decl::UnresolvedUsingIfExists: 107bdd1243dSDimitry Andric case Decl::HLSLBuffer: 1080b57cec5SDimitry Andric llvm_unreachable("Declaration should not be in declstmts!"); 1090b57cec5SDimitry Andric case Decl::Record: // struct/union/class X; 1100b57cec5SDimitry Andric case Decl::CXXRecord: // struct/union/class X; [C++] 111e8d8bef9SDimitry Andric if (CGDebugInfo *DI = getDebugInfo()) 112e8d8bef9SDimitry Andric if (cast<RecordDecl>(D).getDefinition()) 113e8d8bef9SDimitry Andric DI->EmitAndRetainType(getContext().getRecordType(cast<RecordDecl>(&D))); 114e8d8bef9SDimitry Andric return; 115e8d8bef9SDimitry Andric case Decl::Enum: // enum X; 116e8d8bef9SDimitry Andric if (CGDebugInfo *DI = getDebugInfo()) 117e8d8bef9SDimitry Andric if (cast<EnumDecl>(D).getDefinition()) 118e8d8bef9SDimitry Andric DI->EmitAndRetainType(getContext().getEnumType(cast<EnumDecl>(&D))); 119e8d8bef9SDimitry Andric return; 120e8d8bef9SDimitry Andric case Decl::Function: // void X(); 121e8d8bef9SDimitry Andric case Decl::EnumConstant: // enum ? { X = ? } 1220b57cec5SDimitry Andric case Decl::StaticAssert: // static_assert(X, ""); [C++0x] 1230b57cec5SDimitry Andric case Decl::Label: // __label__ x; 1240b57cec5SDimitry Andric case Decl::Import: 1255ffd83dbSDimitry Andric case Decl::MSGuid: // __declspec(uuid("...")) 12681ad6265SDimitry Andric case Decl::UnnamedGlobalConstant: 127e8d8bef9SDimitry Andric case Decl::TemplateParamObject: 1280b57cec5SDimitry Andric case Decl::OMPThreadPrivate: 1290b57cec5SDimitry Andric case Decl::OMPAllocate: 1300b57cec5SDimitry Andric case Decl::OMPCapturedExpr: 1310b57cec5SDimitry Andric case Decl::OMPRequires: 1320b57cec5SDimitry Andric case Decl::Empty: 1330b57cec5SDimitry Andric case Decl::Concept: 134bdd1243dSDimitry Andric case Decl::ImplicitConceptSpecialization: 135480093f4SDimitry Andric case Decl::LifetimeExtendedTemporary: 13655e4f9d5SDimitry Andric case Decl::RequiresExprBody: 1370b57cec5SDimitry Andric // None of these decls require codegen support. 1380b57cec5SDimitry Andric return; 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric case Decl::NamespaceAlias: 1410b57cec5SDimitry Andric if (CGDebugInfo *DI = getDebugInfo()) 1420b57cec5SDimitry Andric DI->EmitNamespaceAlias(cast<NamespaceAliasDecl>(D)); 1430b57cec5SDimitry Andric return; 1440b57cec5SDimitry Andric case Decl::Using: // using X; [C++] 1450b57cec5SDimitry Andric if (CGDebugInfo *DI = getDebugInfo()) 1460b57cec5SDimitry Andric DI->EmitUsingDecl(cast<UsingDecl>(D)); 1470b57cec5SDimitry Andric return; 148fe6060f1SDimitry Andric case Decl::UsingEnum: // using enum X; [C++] 149fe6060f1SDimitry Andric if (CGDebugInfo *DI = getDebugInfo()) 150fe6060f1SDimitry Andric DI->EmitUsingEnumDecl(cast<UsingEnumDecl>(D)); 151fe6060f1SDimitry Andric return; 1520b57cec5SDimitry Andric case Decl::UsingPack: 1530b57cec5SDimitry Andric for (auto *Using : cast<UsingPackDecl>(D).expansions()) 1540b57cec5SDimitry Andric EmitDecl(*Using); 1550b57cec5SDimitry Andric return; 1560b57cec5SDimitry Andric case Decl::UsingDirective: // using namespace X; [C++] 1570b57cec5SDimitry Andric if (CGDebugInfo *DI = getDebugInfo()) 1580b57cec5SDimitry Andric DI->EmitUsingDirective(cast<UsingDirectiveDecl>(D)); 1590b57cec5SDimitry Andric return; 1600b57cec5SDimitry Andric case Decl::Var: 1610b57cec5SDimitry Andric case Decl::Decomposition: { 1620b57cec5SDimitry Andric const VarDecl &VD = cast<VarDecl>(D); 1630b57cec5SDimitry Andric assert(VD.isLocalVarDecl() && 1640b57cec5SDimitry Andric "Should not see file-scope variables inside a function!"); 1650b57cec5SDimitry Andric EmitVarDecl(VD); 1660b57cec5SDimitry Andric if (auto *DD = dyn_cast<DecompositionDecl>(&VD)) 1670b57cec5SDimitry Andric for (auto *B : DD->bindings()) 1680b57cec5SDimitry Andric if (auto *HD = B->getHoldingVar()) 1690b57cec5SDimitry Andric EmitVarDecl(*HD); 1700b57cec5SDimitry Andric return; 1710b57cec5SDimitry Andric } 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric case Decl::OMPDeclareReduction: 1740b57cec5SDimitry Andric return CGM.EmitOMPDeclareReduction(cast<OMPDeclareReductionDecl>(&D), this); 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric case Decl::OMPDeclareMapper: 1770b57cec5SDimitry Andric return CGM.EmitOMPDeclareMapper(cast<OMPDeclareMapperDecl>(&D), this); 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric case Decl::Typedef: // typedef int X; 1800b57cec5SDimitry Andric case Decl::TypeAlias: { // using X = int; [C++0x] 181e8d8bef9SDimitry Andric QualType Ty = cast<TypedefNameDecl>(D).getUnderlyingType(); 182e8d8bef9SDimitry Andric if (CGDebugInfo *DI = getDebugInfo()) 183e8d8bef9SDimitry Andric DI->EmitAndRetainType(Ty); 1840b57cec5SDimitry Andric if (Ty->isVariablyModifiedType()) 1850b57cec5SDimitry Andric EmitVariablyModifiedType(Ty); 1860b57cec5SDimitry Andric return; 1870b57cec5SDimitry Andric } 1880b57cec5SDimitry Andric } 1890b57cec5SDimitry Andric } 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric /// EmitVarDecl - This method handles emission of any variable declaration 1920b57cec5SDimitry Andric /// inside a function, including static vars etc. 1930b57cec5SDimitry Andric void CodeGenFunction::EmitVarDecl(const VarDecl &D) { 1940b57cec5SDimitry Andric if (D.hasExternalStorage()) 1950b57cec5SDimitry Andric // Don't emit it now, allow it to be emitted lazily on its first use. 1960b57cec5SDimitry Andric return; 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric // Some function-scope variable does not have static storage but still 1990b57cec5SDimitry Andric // needs to be emitted like a static variable, e.g. a function-scope 2000b57cec5SDimitry Andric // variable in constant address space in OpenCL. 2010b57cec5SDimitry Andric if (D.getStorageDuration() != SD_Automatic) { 2020b57cec5SDimitry Andric // Static sampler variables translated to function calls. 2030b57cec5SDimitry Andric if (D.getType()->isSamplerT()) 2040b57cec5SDimitry Andric return; 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric llvm::GlobalValue::LinkageTypes Linkage = 2078a4dda33SDimitry Andric CGM.getLLVMLinkageVarDefinition(&D); 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric // FIXME: We need to force the emission/use of a guard variable for 2100b57cec5SDimitry Andric // some variables even if we can constant-evaluate them because 2110b57cec5SDimitry Andric // we can't guarantee every translation unit will constant-evaluate them. 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric return EmitStaticVarDecl(D, Linkage); 2140b57cec5SDimitry Andric } 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric if (D.getType().getAddressSpace() == LangAS::opencl_local) 2170b57cec5SDimitry Andric return CGM.getOpenCLRuntime().EmitWorkGroupLocalVarDecl(*this, D); 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric assert(D.hasLocalStorage()); 2200b57cec5SDimitry Andric return EmitAutoVarDecl(D); 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric static std::string getStaticDeclName(CodeGenModule &CGM, const VarDecl &D) { 2240b57cec5SDimitry Andric if (CGM.getLangOpts().CPlusPlus) 2250b57cec5SDimitry Andric return CGM.getMangledName(&D).str(); 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric // If this isn't C++, we don't need a mangled name, just a pretty one. 2280b57cec5SDimitry Andric assert(!D.isExternallyVisible() && "name shouldn't matter"); 2290b57cec5SDimitry Andric std::string ContextName; 2300b57cec5SDimitry Andric const DeclContext *DC = D.getDeclContext(); 2310b57cec5SDimitry Andric if (auto *CD = dyn_cast<CapturedDecl>(DC)) 2320b57cec5SDimitry Andric DC = cast<DeclContext>(CD->getNonClosureContext()); 2330b57cec5SDimitry Andric if (const auto *FD = dyn_cast<FunctionDecl>(DC)) 2345ffd83dbSDimitry Andric ContextName = std::string(CGM.getMangledName(FD)); 2350b57cec5SDimitry Andric else if (const auto *BD = dyn_cast<BlockDecl>(DC)) 2365ffd83dbSDimitry Andric ContextName = std::string(CGM.getBlockMangledName(GlobalDecl(), BD)); 2370b57cec5SDimitry Andric else if (const auto *OMD = dyn_cast<ObjCMethodDecl>(DC)) 2380b57cec5SDimitry Andric ContextName = OMD->getSelector().getAsString(); 2390b57cec5SDimitry Andric else 2400b57cec5SDimitry Andric llvm_unreachable("Unknown context for static var decl"); 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric ContextName += "." + D.getNameAsString(); 2430b57cec5SDimitry Andric return ContextName; 2440b57cec5SDimitry Andric } 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric llvm::Constant *CodeGenModule::getOrCreateStaticVarDecl( 2470b57cec5SDimitry Andric const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage) { 2480b57cec5SDimitry Andric // In general, we don't always emit static var decls once before we reference 2490b57cec5SDimitry Andric // them. It is possible to reference them before emitting the function that 2500b57cec5SDimitry Andric // contains them, and it is possible to emit the containing function multiple 2510b57cec5SDimitry Andric // times. 2520b57cec5SDimitry Andric if (llvm::Constant *ExistingGV = StaticLocalDeclMap[&D]) 2530b57cec5SDimitry Andric return ExistingGV; 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric QualType Ty = D.getType(); 2560b57cec5SDimitry Andric assert(Ty->isConstantSizeType() && "VLAs can't be static"); 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric // Use the label if the variable is renamed with the asm-label extension. 2590b57cec5SDimitry Andric std::string Name; 2600b57cec5SDimitry Andric if (D.hasAttr<AsmLabelAttr>()) 2615ffd83dbSDimitry Andric Name = std::string(getMangledName(&D)); 2620b57cec5SDimitry Andric else 2630b57cec5SDimitry Andric Name = getStaticDeclName(*this, D); 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric llvm::Type *LTy = getTypes().ConvertTypeForMem(Ty); 2660b57cec5SDimitry Andric LangAS AS = GetGlobalVarAddressSpace(&D); 2670b57cec5SDimitry Andric unsigned TargetAS = getContext().getTargetAddressSpace(AS); 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric // OpenCL variables in local address space and CUDA shared 2700b57cec5SDimitry Andric // variables cannot have an initializer. 2710b57cec5SDimitry Andric llvm::Constant *Init = nullptr; 2720b57cec5SDimitry Andric if (Ty.getAddressSpace() == LangAS::opencl_local || 2735ffd83dbSDimitry Andric D.hasAttr<CUDASharedAttr>() || D.hasAttr<LoaderUninitializedAttr>()) 2740b57cec5SDimitry Andric Init = llvm::UndefValue::get(LTy); 2750b57cec5SDimitry Andric else 2760b57cec5SDimitry Andric Init = EmitNullConstant(Ty); 2770b57cec5SDimitry Andric 2780b57cec5SDimitry Andric llvm::GlobalVariable *GV = new llvm::GlobalVariable( 2790b57cec5SDimitry Andric getModule(), LTy, Ty.isConstant(getContext()), Linkage, Init, Name, 2800b57cec5SDimitry Andric nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS); 281a7dea167SDimitry Andric GV->setAlignment(getContext().getDeclAlign(&D).getAsAlign()); 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric if (supportsCOMDAT() && GV->isWeakForLinker()) 2840b57cec5SDimitry Andric GV->setComdat(TheModule.getOrInsertComdat(GV->getName())); 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric if (D.getTLSKind()) 2870b57cec5SDimitry Andric setTLSMode(GV, D); 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric setGVProperties(GV, &D); 290*0fca6ea1SDimitry Andric getTargetCodeGenInfo().setTargetAttributes(cast<Decl>(&D), GV, *this); 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric // Make sure the result is of the correct type. 2930b57cec5SDimitry Andric LangAS ExpectedAS = Ty.getAddressSpace(); 2940b57cec5SDimitry Andric llvm::Constant *Addr = GV; 2950b57cec5SDimitry Andric if (AS != ExpectedAS) { 2960b57cec5SDimitry Andric Addr = getTargetCodeGenInfo().performAddrSpaceCast( 2970b57cec5SDimitry Andric *this, GV, AS, ExpectedAS, 29806c3fb27SDimitry Andric llvm::PointerType::get(getLLVMContext(), 29906c3fb27SDimitry Andric getContext().getTargetAddressSpace(ExpectedAS))); 3000b57cec5SDimitry Andric } 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric setStaticLocalDeclAddress(&D, Addr); 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric // Ensure that the static local gets initialized by making sure the parent 3050b57cec5SDimitry Andric // function gets emitted eventually. 3060b57cec5SDimitry Andric const Decl *DC = cast<Decl>(D.getDeclContext()); 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric // We can't name blocks or captured statements directly, so try to emit their 3090b57cec5SDimitry Andric // parents. 3100b57cec5SDimitry Andric if (isa<BlockDecl>(DC) || isa<CapturedDecl>(DC)) { 3110b57cec5SDimitry Andric DC = DC->getNonClosureContext(); 3120b57cec5SDimitry Andric // FIXME: Ensure that global blocks get emitted. 3130b57cec5SDimitry Andric if (!DC) 3140b57cec5SDimitry Andric return Addr; 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric GlobalDecl GD; 3180b57cec5SDimitry Andric if (const auto *CD = dyn_cast<CXXConstructorDecl>(DC)) 3190b57cec5SDimitry Andric GD = GlobalDecl(CD, Ctor_Base); 3200b57cec5SDimitry Andric else if (const auto *DD = dyn_cast<CXXDestructorDecl>(DC)) 3210b57cec5SDimitry Andric GD = GlobalDecl(DD, Dtor_Base); 3220b57cec5SDimitry Andric else if (const auto *FD = dyn_cast<FunctionDecl>(DC)) 3230b57cec5SDimitry Andric GD = GlobalDecl(FD); 3240b57cec5SDimitry Andric else { 3250b57cec5SDimitry Andric // Don't do anything for Obj-C method decls or global closures. We should 3260b57cec5SDimitry Andric // never defer them. 3270b57cec5SDimitry Andric assert(isa<ObjCMethodDecl>(DC) && "unexpected parent code decl"); 3280b57cec5SDimitry Andric } 3290b57cec5SDimitry Andric if (GD.getDecl()) { 3300b57cec5SDimitry Andric // Disable emission of the parent function for the OpenMP device codegen. 3310b57cec5SDimitry Andric CGOpenMPRuntime::DisableAutoDeclareTargetRAII NoDeclTarget(*this); 3320b57cec5SDimitry Andric (void)GetAddrOfGlobal(GD); 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric return Addr; 3360b57cec5SDimitry Andric } 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric /// AddInitializerToStaticVarDecl - Add the initializer for 'D' to the 3390b57cec5SDimitry Andric /// global variable that has already been created for it. If the initializer 3400b57cec5SDimitry Andric /// has a different type than GV does, this may free GV and return a different 3410b57cec5SDimitry Andric /// one. Otherwise it just returns GV. 3420b57cec5SDimitry Andric llvm::GlobalVariable * 3430b57cec5SDimitry Andric CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D, 3440b57cec5SDimitry Andric llvm::GlobalVariable *GV) { 3450b57cec5SDimitry Andric ConstantEmitter emitter(*this); 3460b57cec5SDimitry Andric llvm::Constant *Init = emitter.tryEmitForInitializer(D); 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric // If constant emission failed, then this should be a C++ static 3490b57cec5SDimitry Andric // initializer. 3500b57cec5SDimitry Andric if (!Init) { 3510b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) 3520b57cec5SDimitry Andric CGM.ErrorUnsupported(D.getInit(), "constant l-value expression"); 35381ad6265SDimitry Andric else if (D.hasFlexibleArrayInit(getContext())) 35481ad6265SDimitry Andric CGM.ErrorUnsupported(D.getInit(), "flexible array initializer"); 3550b57cec5SDimitry Andric else if (HaveInsertPoint()) { 3560b57cec5SDimitry Andric // Since we have a static initializer, this global variable can't 3570b57cec5SDimitry Andric // be constant. 3580b57cec5SDimitry Andric GV->setConstant(false); 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric EmitCXXGuardedInit(D, GV, /*PerformInit*/true); 3610b57cec5SDimitry Andric } 3620b57cec5SDimitry Andric return GV; 3630b57cec5SDimitry Andric } 3640b57cec5SDimitry Andric 36581ad6265SDimitry Andric #ifndef NDEBUG 36681ad6265SDimitry Andric CharUnits VarSize = CGM.getContext().getTypeSizeInChars(D.getType()) + 36781ad6265SDimitry Andric D.getFlexibleArrayInitChars(getContext()); 36881ad6265SDimitry Andric CharUnits CstSize = CharUnits::fromQuantity( 36981ad6265SDimitry Andric CGM.getDataLayout().getTypeAllocSize(Init->getType())); 37081ad6265SDimitry Andric assert(VarSize == CstSize && "Emitted constant has unexpected size"); 37181ad6265SDimitry Andric #endif 37281ad6265SDimitry Andric 3730b57cec5SDimitry Andric // The initializer may differ in type from the global. Rewrite 3740b57cec5SDimitry Andric // the global to match the initializer. (We have to do this 3750b57cec5SDimitry Andric // because some types, like unions, can't be completely represented 3760b57cec5SDimitry Andric // in the LLVM type system.) 3775ffd83dbSDimitry Andric if (GV->getValueType() != Init->getType()) { 3780b57cec5SDimitry Andric llvm::GlobalVariable *OldGV = GV; 3790b57cec5SDimitry Andric 380e8d8bef9SDimitry Andric GV = new llvm::GlobalVariable( 381e8d8bef9SDimitry Andric CGM.getModule(), Init->getType(), OldGV->isConstant(), 3820b57cec5SDimitry Andric OldGV->getLinkage(), Init, "", 383e8d8bef9SDimitry Andric /*InsertBefore*/ OldGV, OldGV->getThreadLocalMode(), 384e8d8bef9SDimitry Andric OldGV->getType()->getPointerAddressSpace()); 3850b57cec5SDimitry Andric GV->setVisibility(OldGV->getVisibility()); 3860b57cec5SDimitry Andric GV->setDSOLocal(OldGV->isDSOLocal()); 3870b57cec5SDimitry Andric GV->setComdat(OldGV->getComdat()); 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric // Steal the name of the old global 3900b57cec5SDimitry Andric GV->takeName(OldGV); 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric // Replace all uses of the old global with the new global 3935f757f3fSDimitry Andric OldGV->replaceAllUsesWith(GV); 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric // Erase the old global, since it is no longer used. 3960b57cec5SDimitry Andric OldGV->eraseFromParent(); 3970b57cec5SDimitry Andric } 3980b57cec5SDimitry Andric 39906c3fb27SDimitry Andric bool NeedsDtor = 40006c3fb27SDimitry Andric D.needsDestruction(getContext()) == QualType::DK_cxx_destructor; 40106c3fb27SDimitry Andric 4025f757f3fSDimitry Andric GV->setConstant( 4035f757f3fSDimitry Andric D.getType().isConstantStorage(getContext(), true, !NeedsDtor)); 4040b57cec5SDimitry Andric GV->setInitializer(Init); 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric emitter.finalize(GV); 4070b57cec5SDimitry Andric 40806c3fb27SDimitry Andric if (NeedsDtor && HaveInsertPoint()) { 4090b57cec5SDimitry Andric // We have a constant initializer, but a nontrivial destructor. We still 4100b57cec5SDimitry Andric // need to perform a guarded "initialization" in order to register the 4110b57cec5SDimitry Andric // destructor. 4120b57cec5SDimitry Andric EmitCXXGuardedInit(D, GV, /*PerformInit*/false); 4130b57cec5SDimitry Andric } 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric return GV; 4160b57cec5SDimitry Andric } 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D, 4190b57cec5SDimitry Andric llvm::GlobalValue::LinkageTypes Linkage) { 4200b57cec5SDimitry Andric // Check to see if we already have a global variable for this 4210b57cec5SDimitry Andric // declaration. This can happen when double-emitting function 4220b57cec5SDimitry Andric // bodies, e.g. with complete and base constructors. 4230b57cec5SDimitry Andric llvm::Constant *addr = CGM.getOrCreateStaticVarDecl(D, Linkage); 4240b57cec5SDimitry Andric CharUnits alignment = getContext().getDeclAlign(&D); 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric // Store into LocalDeclMap before generating initializer to handle 4270b57cec5SDimitry Andric // circular references. 4280eae32dcSDimitry Andric llvm::Type *elemTy = ConvertTypeForMem(D.getType()); 4290eae32dcSDimitry Andric setAddrOfLocalVar(&D, Address(addr, elemTy, alignment)); 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric // We can't have a VLA here, but we can have a pointer to a VLA, 4320b57cec5SDimitry Andric // even though that doesn't really make any sense. 4330b57cec5SDimitry Andric // Make sure to evaluate VLA bounds now so that we have them for later. 4340b57cec5SDimitry Andric if (D.getType()->isVariablyModifiedType()) 4350b57cec5SDimitry Andric EmitVariablyModifiedType(D.getType()); 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric // Save the type in case adding the initializer forces a type change. 4380b57cec5SDimitry Andric llvm::Type *expectedType = addr->getType(); 4390b57cec5SDimitry Andric 4400b57cec5SDimitry Andric llvm::GlobalVariable *var = 4410b57cec5SDimitry Andric cast<llvm::GlobalVariable>(addr->stripPointerCasts()); 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric // CUDA's local and local static __shared__ variables should not 4440b57cec5SDimitry Andric // have any non-empty initializers. This is ensured by Sema. 4450b57cec5SDimitry Andric // Whatever initializer such variable may have when it gets here is 4460b57cec5SDimitry Andric // a no-op and should not be emitted. 4470b57cec5SDimitry Andric bool isCudaSharedVar = getLangOpts().CUDA && getLangOpts().CUDAIsDevice && 4480b57cec5SDimitry Andric D.hasAttr<CUDASharedAttr>(); 4490b57cec5SDimitry Andric // If this value has an initializer, emit it. 4500b57cec5SDimitry Andric if (D.getInit() && !isCudaSharedVar) 4510b57cec5SDimitry Andric var = AddInitializerToStaticVarDecl(D, var); 4520b57cec5SDimitry Andric 453a7dea167SDimitry Andric var->setAlignment(alignment.getAsAlign()); 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric if (D.hasAttr<AnnotateAttr>()) 4560b57cec5SDimitry Andric CGM.AddGlobalAnnotations(&D, var); 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric if (auto *SA = D.getAttr<PragmaClangBSSSectionAttr>()) 4590b57cec5SDimitry Andric var->addAttribute("bss-section", SA->getName()); 4600b57cec5SDimitry Andric if (auto *SA = D.getAttr<PragmaClangDataSectionAttr>()) 4610b57cec5SDimitry Andric var->addAttribute("data-section", SA->getName()); 4620b57cec5SDimitry Andric if (auto *SA = D.getAttr<PragmaClangRodataSectionAttr>()) 4630b57cec5SDimitry Andric var->addAttribute("rodata-section", SA->getName()); 464a7dea167SDimitry Andric if (auto *SA = D.getAttr<PragmaClangRelroSectionAttr>()) 465a7dea167SDimitry Andric var->addAttribute("relro-section", SA->getName()); 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andric if (const SectionAttr *SA = D.getAttr<SectionAttr>()) 4680b57cec5SDimitry Andric var->setSection(SA->getName()); 4690b57cec5SDimitry Andric 470fe6060f1SDimitry Andric if (D.hasAttr<RetainAttr>()) 4710b57cec5SDimitry Andric CGM.addUsedGlobal(var); 472fe6060f1SDimitry Andric else if (D.hasAttr<UsedAttr>()) 473fe6060f1SDimitry Andric CGM.addUsedOrCompilerUsedGlobal(var); 4740b57cec5SDimitry Andric 47506c3fb27SDimitry Andric if (CGM.getCodeGenOpts().KeepPersistentStorageVariables) 47606c3fb27SDimitry Andric CGM.addUsedOrCompilerUsedGlobal(var); 47706c3fb27SDimitry Andric 4780b57cec5SDimitry Andric // We may have to cast the constant because of the initializer 4790b57cec5SDimitry Andric // mismatch above. 4800b57cec5SDimitry Andric // 4810b57cec5SDimitry Andric // FIXME: It is really dangerous to store this in the map; if anyone 4820b57cec5SDimitry Andric // RAUW's the GV uses of this constant will be invalid. 4830b57cec5SDimitry Andric llvm::Constant *castedAddr = 4840b57cec5SDimitry Andric llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(var, expectedType); 4850eae32dcSDimitry Andric LocalDeclMap.find(&D)->second = Address(castedAddr, elemTy, alignment); 4860b57cec5SDimitry Andric CGM.setStaticLocalDeclAddress(&D, castedAddr); 4870b57cec5SDimitry Andric 48881ad6265SDimitry Andric CGM.getSanitizerMetadata()->reportGlobal(var, D); 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric // Emit global variable debug descriptor for static vars. 4910b57cec5SDimitry Andric CGDebugInfo *DI = getDebugInfo(); 492480093f4SDimitry Andric if (DI && CGM.getCodeGenOpts().hasReducedDebugInfo()) { 4930b57cec5SDimitry Andric DI->setLocation(D.getLocation()); 4940b57cec5SDimitry Andric DI->EmitGlobalVariable(var, &D); 4950b57cec5SDimitry Andric } 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric namespace { 4990b57cec5SDimitry Andric struct DestroyObject final : EHScopeStack::Cleanup { 5000b57cec5SDimitry Andric DestroyObject(Address addr, QualType type, 5010b57cec5SDimitry Andric CodeGenFunction::Destroyer *destroyer, 5020b57cec5SDimitry Andric bool useEHCleanupForArray) 5030b57cec5SDimitry Andric : addr(addr), type(type), destroyer(destroyer), 5040b57cec5SDimitry Andric useEHCleanupForArray(useEHCleanupForArray) {} 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric Address addr; 5070b57cec5SDimitry Andric QualType type; 5080b57cec5SDimitry Andric CodeGenFunction::Destroyer *destroyer; 5090b57cec5SDimitry Andric bool useEHCleanupForArray; 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 5120b57cec5SDimitry Andric // Don't use an EH cleanup recursively from an EH cleanup. 5130b57cec5SDimitry Andric bool useEHCleanupForArray = 5140b57cec5SDimitry Andric flags.isForNormalCleanup() && this->useEHCleanupForArray; 5150b57cec5SDimitry Andric 5160b57cec5SDimitry Andric CGF.emitDestroy(addr, type, destroyer, useEHCleanupForArray); 5170b57cec5SDimitry Andric } 5180b57cec5SDimitry Andric }; 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric template <class Derived> 5210b57cec5SDimitry Andric struct DestroyNRVOVariable : EHScopeStack::Cleanup { 5220b57cec5SDimitry Andric DestroyNRVOVariable(Address addr, QualType type, llvm::Value *NRVOFlag) 5230b57cec5SDimitry Andric : NRVOFlag(NRVOFlag), Loc(addr), Ty(type) {} 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andric llvm::Value *NRVOFlag; 5260b57cec5SDimitry Andric Address Loc; 5270b57cec5SDimitry Andric QualType Ty; 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 5300b57cec5SDimitry Andric // Along the exceptions path we always execute the dtor. 5310b57cec5SDimitry Andric bool NRVO = flags.isForNormalCleanup() && NRVOFlag; 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andric llvm::BasicBlock *SkipDtorBB = nullptr; 5340b57cec5SDimitry Andric if (NRVO) { 5350b57cec5SDimitry Andric // If we exited via NRVO, we skip the destructor call. 5360b57cec5SDimitry Andric llvm::BasicBlock *RunDtorBB = CGF.createBasicBlock("nrvo.unused"); 5370b57cec5SDimitry Andric SkipDtorBB = CGF.createBasicBlock("nrvo.skipdtor"); 5380b57cec5SDimitry Andric llvm::Value *DidNRVO = 5390b57cec5SDimitry Andric CGF.Builder.CreateFlagLoad(NRVOFlag, "nrvo.val"); 5400b57cec5SDimitry Andric CGF.Builder.CreateCondBr(DidNRVO, SkipDtorBB, RunDtorBB); 5410b57cec5SDimitry Andric CGF.EmitBlock(RunDtorBB); 5420b57cec5SDimitry Andric } 5430b57cec5SDimitry Andric 5440b57cec5SDimitry Andric static_cast<Derived *>(this)->emitDestructorCall(CGF); 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric if (NRVO) CGF.EmitBlock(SkipDtorBB); 5470b57cec5SDimitry Andric } 5480b57cec5SDimitry Andric 5490b57cec5SDimitry Andric virtual ~DestroyNRVOVariable() = default; 5500b57cec5SDimitry Andric }; 5510b57cec5SDimitry Andric 5520b57cec5SDimitry Andric struct DestroyNRVOVariableCXX final 5530b57cec5SDimitry Andric : DestroyNRVOVariable<DestroyNRVOVariableCXX> { 5540b57cec5SDimitry Andric DestroyNRVOVariableCXX(Address addr, QualType type, 5550b57cec5SDimitry Andric const CXXDestructorDecl *Dtor, llvm::Value *NRVOFlag) 5560b57cec5SDimitry Andric : DestroyNRVOVariable<DestroyNRVOVariableCXX>(addr, type, NRVOFlag), 5570b57cec5SDimitry Andric Dtor(Dtor) {} 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andric const CXXDestructorDecl *Dtor; 5600b57cec5SDimitry Andric 5610b57cec5SDimitry Andric void emitDestructorCall(CodeGenFunction &CGF) { 5620b57cec5SDimitry Andric CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, 5630b57cec5SDimitry Andric /*ForVirtualBase=*/false, 5640b57cec5SDimitry Andric /*Delegating=*/false, Loc, Ty); 5650b57cec5SDimitry Andric } 5660b57cec5SDimitry Andric }; 5670b57cec5SDimitry Andric 5680b57cec5SDimitry Andric struct DestroyNRVOVariableC final 5690b57cec5SDimitry Andric : DestroyNRVOVariable<DestroyNRVOVariableC> { 5700b57cec5SDimitry Andric DestroyNRVOVariableC(Address addr, llvm::Value *NRVOFlag, QualType Ty) 5710b57cec5SDimitry Andric : DestroyNRVOVariable<DestroyNRVOVariableC>(addr, Ty, NRVOFlag) {} 5720b57cec5SDimitry Andric 5730b57cec5SDimitry Andric void emitDestructorCall(CodeGenFunction &CGF) { 5740b57cec5SDimitry Andric CGF.destroyNonTrivialCStruct(CGF, Loc, Ty); 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric }; 5770b57cec5SDimitry Andric 5780b57cec5SDimitry Andric struct CallStackRestore final : EHScopeStack::Cleanup { 5790b57cec5SDimitry Andric Address Stack; 5800b57cec5SDimitry Andric CallStackRestore(Address Stack) : Stack(Stack) {} 581fe6060f1SDimitry Andric bool isRedundantBeforeReturn() override { return true; } 5820b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 5830b57cec5SDimitry Andric llvm::Value *V = CGF.Builder.CreateLoad(Stack); 5845f757f3fSDimitry Andric CGF.Builder.CreateStackRestore(V); 5850b57cec5SDimitry Andric } 5860b57cec5SDimitry Andric }; 5870b57cec5SDimitry Andric 58806c3fb27SDimitry Andric struct KmpcAllocFree final : EHScopeStack::Cleanup { 58906c3fb27SDimitry Andric std::pair<llvm::Value *, llvm::Value *> AddrSizePair; 59006c3fb27SDimitry Andric KmpcAllocFree(const std::pair<llvm::Value *, llvm::Value *> &AddrSizePair) 59106c3fb27SDimitry Andric : AddrSizePair(AddrSizePair) {} 59206c3fb27SDimitry Andric void Emit(CodeGenFunction &CGF, Flags EmissionFlags) override { 59306c3fb27SDimitry Andric auto &RT = CGF.CGM.getOpenMPRuntime(); 59406c3fb27SDimitry Andric RT.getKmpcFreeShared(CGF, AddrSizePair); 59506c3fb27SDimitry Andric } 59606c3fb27SDimitry Andric }; 59706c3fb27SDimitry Andric 5980b57cec5SDimitry Andric struct ExtendGCLifetime final : EHScopeStack::Cleanup { 5990b57cec5SDimitry Andric const VarDecl &Var; 6000b57cec5SDimitry Andric ExtendGCLifetime(const VarDecl *var) : Var(*var) {} 6010b57cec5SDimitry Andric 6020b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 6030b57cec5SDimitry Andric // Compute the address of the local variable, in case it's a 6040b57cec5SDimitry Andric // byref or something. 6050b57cec5SDimitry Andric DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(&Var), false, 6060b57cec5SDimitry Andric Var.getType(), VK_LValue, SourceLocation()); 6070b57cec5SDimitry Andric llvm::Value *value = CGF.EmitLoadOfScalar(CGF.EmitDeclRefLValue(&DRE), 6080b57cec5SDimitry Andric SourceLocation()); 6090b57cec5SDimitry Andric CGF.EmitExtendGCLifetime(value); 6100b57cec5SDimitry Andric } 6110b57cec5SDimitry Andric }; 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andric struct CallCleanupFunction final : EHScopeStack::Cleanup { 6140b57cec5SDimitry Andric llvm::Constant *CleanupFn; 6150b57cec5SDimitry Andric const CGFunctionInfo &FnInfo; 6160b57cec5SDimitry Andric const VarDecl &Var; 6170b57cec5SDimitry Andric 6180b57cec5SDimitry Andric CallCleanupFunction(llvm::Constant *CleanupFn, const CGFunctionInfo *Info, 6190b57cec5SDimitry Andric const VarDecl *Var) 6200b57cec5SDimitry Andric : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {} 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 6230b57cec5SDimitry Andric DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(&Var), false, 6240b57cec5SDimitry Andric Var.getType(), VK_LValue, SourceLocation()); 6250b57cec5SDimitry Andric // Compute the address of the local variable, in case it's a byref 6260b57cec5SDimitry Andric // or something. 627480093f4SDimitry Andric llvm::Value *Addr = CGF.EmitDeclRefLValue(&DRE).getPointer(CGF); 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric // In some cases, the type of the function argument will be different from 6300b57cec5SDimitry Andric // the type of the pointer. An example of this is 6310b57cec5SDimitry Andric // void f(void* arg); 6320b57cec5SDimitry Andric // __attribute__((cleanup(f))) void *g; 6330b57cec5SDimitry Andric // 6340b57cec5SDimitry Andric // To fix this we insert a bitcast here. 6350b57cec5SDimitry Andric QualType ArgTy = FnInfo.arg_begin()->type; 6360b57cec5SDimitry Andric llvm::Value *Arg = 6370b57cec5SDimitry Andric CGF.Builder.CreateBitCast(Addr, CGF.ConvertType(ArgTy)); 6380b57cec5SDimitry Andric 6390b57cec5SDimitry Andric CallArgList Args; 6400b57cec5SDimitry Andric Args.add(RValue::get(Arg), 6410b57cec5SDimitry Andric CGF.getContext().getPointerType(Var.getType())); 6420b57cec5SDimitry Andric auto Callee = CGCallee::forDirect(CleanupFn); 6430b57cec5SDimitry Andric CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args); 6440b57cec5SDimitry Andric } 6450b57cec5SDimitry Andric }; 6460b57cec5SDimitry Andric } // end anonymous namespace 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric /// EmitAutoVarWithLifetime - Does the setup required for an automatic 6490b57cec5SDimitry Andric /// variable with lifetime. 6500b57cec5SDimitry Andric static void EmitAutoVarWithLifetime(CodeGenFunction &CGF, const VarDecl &var, 6510b57cec5SDimitry Andric Address addr, 6520b57cec5SDimitry Andric Qualifiers::ObjCLifetime lifetime) { 6530b57cec5SDimitry Andric switch (lifetime) { 6540b57cec5SDimitry Andric case Qualifiers::OCL_None: 6550b57cec5SDimitry Andric llvm_unreachable("present but none"); 6560b57cec5SDimitry Andric 6570b57cec5SDimitry Andric case Qualifiers::OCL_ExplicitNone: 6580b57cec5SDimitry Andric // nothing to do 6590b57cec5SDimitry Andric break; 6600b57cec5SDimitry Andric 6610b57cec5SDimitry Andric case Qualifiers::OCL_Strong: { 6620b57cec5SDimitry Andric CodeGenFunction::Destroyer *destroyer = 6630b57cec5SDimitry Andric (var.hasAttr<ObjCPreciseLifetimeAttr>() 6640b57cec5SDimitry Andric ? CodeGenFunction::destroyARCStrongPrecise 6650b57cec5SDimitry Andric : CodeGenFunction::destroyARCStrongImprecise); 6660b57cec5SDimitry Andric 6670b57cec5SDimitry Andric CleanupKind cleanupKind = CGF.getARCCleanupKind(); 6680b57cec5SDimitry Andric CGF.pushDestroy(cleanupKind, addr, var.getType(), destroyer, 6690b57cec5SDimitry Andric cleanupKind & EHCleanup); 6700b57cec5SDimitry Andric break; 6710b57cec5SDimitry Andric } 6720b57cec5SDimitry Andric case Qualifiers::OCL_Autoreleasing: 6730b57cec5SDimitry Andric // nothing to do 6740b57cec5SDimitry Andric break; 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andric case Qualifiers::OCL_Weak: 6770b57cec5SDimitry Andric // __weak objects always get EH cleanups; otherwise, exceptions 6780b57cec5SDimitry Andric // could cause really nasty crashes instead of mere leaks. 6790b57cec5SDimitry Andric CGF.pushDestroy(NormalAndEHCleanup, addr, var.getType(), 6800b57cec5SDimitry Andric CodeGenFunction::destroyARCWeak, 6810b57cec5SDimitry Andric /*useEHCleanup*/ true); 6820b57cec5SDimitry Andric break; 6830b57cec5SDimitry Andric } 6840b57cec5SDimitry Andric } 6850b57cec5SDimitry Andric 6860b57cec5SDimitry Andric static bool isAccessedBy(const VarDecl &var, const Stmt *s) { 6870b57cec5SDimitry Andric if (const Expr *e = dyn_cast<Expr>(s)) { 6880b57cec5SDimitry Andric // Skip the most common kinds of expressions that make 6890b57cec5SDimitry Andric // hierarchy-walking expensive. 6900b57cec5SDimitry Andric s = e = e->IgnoreParenCasts(); 6910b57cec5SDimitry Andric 6920b57cec5SDimitry Andric if (const DeclRefExpr *ref = dyn_cast<DeclRefExpr>(e)) 6930b57cec5SDimitry Andric return (ref->getDecl() == &var); 6940b57cec5SDimitry Andric if (const BlockExpr *be = dyn_cast<BlockExpr>(e)) { 6950b57cec5SDimitry Andric const BlockDecl *block = be->getBlockDecl(); 6960b57cec5SDimitry Andric for (const auto &I : block->captures()) { 6970b57cec5SDimitry Andric if (I.getVariable() == &var) 6980b57cec5SDimitry Andric return true; 6990b57cec5SDimitry Andric } 7000b57cec5SDimitry Andric } 7010b57cec5SDimitry Andric } 7020b57cec5SDimitry Andric 7030b57cec5SDimitry Andric for (const Stmt *SubStmt : s->children()) 7040b57cec5SDimitry Andric // SubStmt might be null; as in missing decl or conditional of an if-stmt. 7050b57cec5SDimitry Andric if (SubStmt && isAccessedBy(var, SubStmt)) 7060b57cec5SDimitry Andric return true; 7070b57cec5SDimitry Andric 7080b57cec5SDimitry Andric return false; 7090b57cec5SDimitry Andric } 7100b57cec5SDimitry Andric 7110b57cec5SDimitry Andric static bool isAccessedBy(const ValueDecl *decl, const Expr *e) { 7120b57cec5SDimitry Andric if (!decl) return false; 7130b57cec5SDimitry Andric if (!isa<VarDecl>(decl)) return false; 7140b57cec5SDimitry Andric const VarDecl *var = cast<VarDecl>(decl); 7150b57cec5SDimitry Andric return isAccessedBy(*var, e); 7160b57cec5SDimitry Andric } 7170b57cec5SDimitry Andric 7180b57cec5SDimitry Andric static bool tryEmitARCCopyWeakInit(CodeGenFunction &CGF, 7190b57cec5SDimitry Andric const LValue &destLV, const Expr *init) { 7200b57cec5SDimitry Andric bool needsCast = false; 7210b57cec5SDimitry Andric 7220b57cec5SDimitry Andric while (auto castExpr = dyn_cast<CastExpr>(init->IgnoreParens())) { 7230b57cec5SDimitry Andric switch (castExpr->getCastKind()) { 7240b57cec5SDimitry Andric // Look through casts that don't require representation changes. 7250b57cec5SDimitry Andric case CK_NoOp: 7260b57cec5SDimitry Andric case CK_BitCast: 7270b57cec5SDimitry Andric case CK_BlockPointerToObjCPointerCast: 7280b57cec5SDimitry Andric needsCast = true; 7290b57cec5SDimitry Andric break; 7300b57cec5SDimitry Andric 7310b57cec5SDimitry Andric // If we find an l-value to r-value cast from a __weak variable, 7320b57cec5SDimitry Andric // emit this operation as a copy or move. 7330b57cec5SDimitry Andric case CK_LValueToRValue: { 7340b57cec5SDimitry Andric const Expr *srcExpr = castExpr->getSubExpr(); 7350b57cec5SDimitry Andric if (srcExpr->getType().getObjCLifetime() != Qualifiers::OCL_Weak) 7360b57cec5SDimitry Andric return false; 7370b57cec5SDimitry Andric 7380b57cec5SDimitry Andric // Emit the source l-value. 7390b57cec5SDimitry Andric LValue srcLV = CGF.EmitLValue(srcExpr); 7400b57cec5SDimitry Andric 7410b57cec5SDimitry Andric // Handle a formal type change to avoid asserting. 742*0fca6ea1SDimitry Andric auto srcAddr = srcLV.getAddress(); 7430b57cec5SDimitry Andric if (needsCast) { 744*0fca6ea1SDimitry Andric srcAddr = srcAddr.withElementType(destLV.getAddress().getElementType()); 7450b57cec5SDimitry Andric } 7460b57cec5SDimitry Andric 7470b57cec5SDimitry Andric // If it was an l-value, use objc_copyWeak. 748fe6060f1SDimitry Andric if (srcExpr->isLValue()) { 749*0fca6ea1SDimitry Andric CGF.EmitARCCopyWeak(destLV.getAddress(), srcAddr); 7500b57cec5SDimitry Andric } else { 751fe6060f1SDimitry Andric assert(srcExpr->isXValue()); 752*0fca6ea1SDimitry Andric CGF.EmitARCMoveWeak(destLV.getAddress(), srcAddr); 7530b57cec5SDimitry Andric } 7540b57cec5SDimitry Andric return true; 7550b57cec5SDimitry Andric } 7560b57cec5SDimitry Andric 7570b57cec5SDimitry Andric // Stop at anything else. 7580b57cec5SDimitry Andric default: 7590b57cec5SDimitry Andric return false; 7600b57cec5SDimitry Andric } 7610b57cec5SDimitry Andric 7620b57cec5SDimitry Andric init = castExpr->getSubExpr(); 7630b57cec5SDimitry Andric } 7640b57cec5SDimitry Andric return false; 7650b57cec5SDimitry Andric } 7660b57cec5SDimitry Andric 7670b57cec5SDimitry Andric static void drillIntoBlockVariable(CodeGenFunction &CGF, 7680b57cec5SDimitry Andric LValue &lvalue, 7690b57cec5SDimitry Andric const VarDecl *var) { 770*0fca6ea1SDimitry Andric lvalue.setAddress(CGF.emitBlockByrefAddress(lvalue.getAddress(), var)); 7710b57cec5SDimitry Andric } 7720b57cec5SDimitry Andric 7730b57cec5SDimitry Andric void CodeGenFunction::EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, 7740b57cec5SDimitry Andric SourceLocation Loc) { 7750b57cec5SDimitry Andric if (!SanOpts.has(SanitizerKind::NullabilityAssign)) 7760b57cec5SDimitry Andric return; 7770b57cec5SDimitry Andric 778bdd1243dSDimitry Andric auto Nullability = LHS.getType()->getNullability(); 7790b57cec5SDimitry Andric if (!Nullability || *Nullability != NullabilityKind::NonNull) 7800b57cec5SDimitry Andric return; 7810b57cec5SDimitry Andric 7820b57cec5SDimitry Andric // Check if the right hand side of the assignment is nonnull, if the left 7830b57cec5SDimitry Andric // hand side must be nonnull. 7840b57cec5SDimitry Andric SanitizerScope SanScope(this); 7850b57cec5SDimitry Andric llvm::Value *IsNotNull = Builder.CreateIsNotNull(RHS); 7860b57cec5SDimitry Andric llvm::Constant *StaticData[] = { 7870b57cec5SDimitry Andric EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(LHS.getType()), 7880b57cec5SDimitry Andric llvm::ConstantInt::get(Int8Ty, 0), // The LogAlignment info is unused. 7890b57cec5SDimitry Andric llvm::ConstantInt::get(Int8Ty, TCK_NonnullAssign)}; 7900b57cec5SDimitry Andric EmitCheck({{IsNotNull, SanitizerKind::NullabilityAssign}}, 7910b57cec5SDimitry Andric SanitizerHandler::TypeMismatch, StaticData, RHS); 7920b57cec5SDimitry Andric } 7930b57cec5SDimitry Andric 7940b57cec5SDimitry Andric void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D, 7950b57cec5SDimitry Andric LValue lvalue, bool capturedByInit) { 7960b57cec5SDimitry Andric Qualifiers::ObjCLifetime lifetime = lvalue.getObjCLifetime(); 7970b57cec5SDimitry Andric if (!lifetime) { 7980b57cec5SDimitry Andric llvm::Value *value = EmitScalarExpr(init); 7990b57cec5SDimitry Andric if (capturedByInit) 8000b57cec5SDimitry Andric drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D)); 8010b57cec5SDimitry Andric EmitNullabilityCheck(lvalue, value, init->getExprLoc()); 8020b57cec5SDimitry Andric EmitStoreThroughLValue(RValue::get(value), lvalue, true); 8030b57cec5SDimitry Andric return; 8040b57cec5SDimitry Andric } 8050b57cec5SDimitry Andric 8060b57cec5SDimitry Andric if (const CXXDefaultInitExpr *DIE = dyn_cast<CXXDefaultInitExpr>(init)) 8070b57cec5SDimitry Andric init = DIE->getExpr(); 8080b57cec5SDimitry Andric 8090b57cec5SDimitry Andric // If we're emitting a value with lifetime, we have to do the 8100b57cec5SDimitry Andric // initialization *before* we leave the cleanup scopes. 811fe6060f1SDimitry Andric if (auto *EWC = dyn_cast<ExprWithCleanups>(init)) { 8120b57cec5SDimitry Andric CodeGenFunction::RunCleanupsScope Scope(*this); 813fe6060f1SDimitry Andric return EmitScalarInit(EWC->getSubExpr(), D, lvalue, capturedByInit); 814fe6060f1SDimitry Andric } 8150b57cec5SDimitry Andric 8160b57cec5SDimitry Andric // We have to maintain the illusion that the variable is 8170b57cec5SDimitry Andric // zero-initialized. If the variable might be accessed in its 8180b57cec5SDimitry Andric // initializer, zero-initialize before running the initializer, then 8190b57cec5SDimitry Andric // actually perform the initialization with an assign. 8200b57cec5SDimitry Andric bool accessedByInit = false; 8210b57cec5SDimitry Andric if (lifetime != Qualifiers::OCL_ExplicitNone) 8220b57cec5SDimitry Andric accessedByInit = (capturedByInit || isAccessedBy(D, init)); 8230b57cec5SDimitry Andric if (accessedByInit) { 8240b57cec5SDimitry Andric LValue tempLV = lvalue; 8250b57cec5SDimitry Andric // Drill down to the __block object if necessary. 8260b57cec5SDimitry Andric if (capturedByInit) { 8270b57cec5SDimitry Andric // We can use a simple GEP for this because it can't have been 8280b57cec5SDimitry Andric // moved yet. 829*0fca6ea1SDimitry Andric tempLV.setAddress(emitBlockByrefAddress(tempLV.getAddress(), 8300b57cec5SDimitry Andric cast<VarDecl>(D), 8310b57cec5SDimitry Andric /*follow*/ false)); 8320b57cec5SDimitry Andric } 8330b57cec5SDimitry Andric 834*0fca6ea1SDimitry Andric auto ty = cast<llvm::PointerType>(tempLV.getAddress().getElementType()); 8350b57cec5SDimitry Andric llvm::Value *zero = CGM.getNullPointer(ty, tempLV.getType()); 8360b57cec5SDimitry Andric 8370b57cec5SDimitry Andric // If __weak, we want to use a barrier under certain conditions. 8380b57cec5SDimitry Andric if (lifetime == Qualifiers::OCL_Weak) 839*0fca6ea1SDimitry Andric EmitARCInitWeak(tempLV.getAddress(), zero); 8400b57cec5SDimitry Andric 8410b57cec5SDimitry Andric // Otherwise just do a simple store. 8420b57cec5SDimitry Andric else 8430b57cec5SDimitry Andric EmitStoreOfScalar(zero, tempLV, /* isInitialization */ true); 8440b57cec5SDimitry Andric } 8450b57cec5SDimitry Andric 8460b57cec5SDimitry Andric // Emit the initializer. 8470b57cec5SDimitry Andric llvm::Value *value = nullptr; 8480b57cec5SDimitry Andric 8490b57cec5SDimitry Andric switch (lifetime) { 8500b57cec5SDimitry Andric case Qualifiers::OCL_None: 8510b57cec5SDimitry Andric llvm_unreachable("present but none"); 8520b57cec5SDimitry Andric 8530b57cec5SDimitry Andric case Qualifiers::OCL_Strong: { 8540b57cec5SDimitry Andric if (!D || !isa<VarDecl>(D) || !cast<VarDecl>(D)->isARCPseudoStrong()) { 8550b57cec5SDimitry Andric value = EmitARCRetainScalarExpr(init); 8560b57cec5SDimitry Andric break; 8570b57cec5SDimitry Andric } 8580b57cec5SDimitry Andric // If D is pseudo-strong, treat it like __unsafe_unretained here. This means 8590b57cec5SDimitry Andric // that we omit the retain, and causes non-autoreleased return values to be 8600b57cec5SDimitry Andric // immediately released. 861bdd1243dSDimitry Andric [[fallthrough]]; 8620b57cec5SDimitry Andric } 8630b57cec5SDimitry Andric 8640b57cec5SDimitry Andric case Qualifiers::OCL_ExplicitNone: 8650b57cec5SDimitry Andric value = EmitARCUnsafeUnretainedScalarExpr(init); 8660b57cec5SDimitry Andric break; 8670b57cec5SDimitry Andric 8680b57cec5SDimitry Andric case Qualifiers::OCL_Weak: { 8690b57cec5SDimitry Andric // If it's not accessed by the initializer, try to emit the 8700b57cec5SDimitry Andric // initialization with a copy or move. 8710b57cec5SDimitry Andric if (!accessedByInit && tryEmitARCCopyWeakInit(*this, lvalue, init)) { 8720b57cec5SDimitry Andric return; 8730b57cec5SDimitry Andric } 8740b57cec5SDimitry Andric 8750b57cec5SDimitry Andric // No way to optimize a producing initializer into this. It's not 8760b57cec5SDimitry Andric // worth optimizing for, because the value will immediately 8770b57cec5SDimitry Andric // disappear in the common case. 8780b57cec5SDimitry Andric value = EmitScalarExpr(init); 8790b57cec5SDimitry Andric 8800b57cec5SDimitry Andric if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D)); 8810b57cec5SDimitry Andric if (accessedByInit) 882*0fca6ea1SDimitry Andric EmitARCStoreWeak(lvalue.getAddress(), value, /*ignored*/ true); 8830b57cec5SDimitry Andric else 884*0fca6ea1SDimitry Andric EmitARCInitWeak(lvalue.getAddress(), value); 8850b57cec5SDimitry Andric return; 8860b57cec5SDimitry Andric } 8870b57cec5SDimitry Andric 8880b57cec5SDimitry Andric case Qualifiers::OCL_Autoreleasing: 8890b57cec5SDimitry Andric value = EmitARCRetainAutoreleaseScalarExpr(init); 8900b57cec5SDimitry Andric break; 8910b57cec5SDimitry Andric } 8920b57cec5SDimitry Andric 8930b57cec5SDimitry Andric if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D)); 8940b57cec5SDimitry Andric 8950b57cec5SDimitry Andric EmitNullabilityCheck(lvalue, value, init->getExprLoc()); 8960b57cec5SDimitry Andric 8970b57cec5SDimitry Andric // If the variable might have been accessed by its initializer, we 8980b57cec5SDimitry Andric // might have to initialize with a barrier. We have to do this for 8990b57cec5SDimitry Andric // both __weak and __strong, but __weak got filtered out above. 9000b57cec5SDimitry Andric if (accessedByInit && lifetime == Qualifiers::OCL_Strong) { 9010b57cec5SDimitry Andric llvm::Value *oldValue = EmitLoadOfScalar(lvalue, init->getExprLoc()); 9020b57cec5SDimitry Andric EmitStoreOfScalar(value, lvalue, /* isInitialization */ true); 9030b57cec5SDimitry Andric EmitARCRelease(oldValue, ARCImpreciseLifetime); 9040b57cec5SDimitry Andric return; 9050b57cec5SDimitry Andric } 9060b57cec5SDimitry Andric 9070b57cec5SDimitry Andric EmitStoreOfScalar(value, lvalue, /* isInitialization */ true); 9080b57cec5SDimitry Andric } 9090b57cec5SDimitry Andric 9100b57cec5SDimitry Andric /// Decide whether we can emit the non-zero parts of the specified initializer 9110b57cec5SDimitry Andric /// with equal or fewer than NumStores scalar stores. 9120b57cec5SDimitry Andric static bool canEmitInitWithFewStoresAfterBZero(llvm::Constant *Init, 9130b57cec5SDimitry Andric unsigned &NumStores) { 9140b57cec5SDimitry Andric // Zero and Undef never requires any extra stores. 9150b57cec5SDimitry Andric if (isa<llvm::ConstantAggregateZero>(Init) || 9160b57cec5SDimitry Andric isa<llvm::ConstantPointerNull>(Init) || 9170b57cec5SDimitry Andric isa<llvm::UndefValue>(Init)) 9180b57cec5SDimitry Andric return true; 9190b57cec5SDimitry Andric if (isa<llvm::ConstantInt>(Init) || isa<llvm::ConstantFP>(Init) || 9200b57cec5SDimitry Andric isa<llvm::ConstantVector>(Init) || isa<llvm::BlockAddress>(Init) || 9210b57cec5SDimitry Andric isa<llvm::ConstantExpr>(Init)) 9220b57cec5SDimitry Andric return Init->isNullValue() || NumStores--; 9230b57cec5SDimitry Andric 9240b57cec5SDimitry Andric // See if we can emit each element. 9250b57cec5SDimitry Andric if (isa<llvm::ConstantArray>(Init) || isa<llvm::ConstantStruct>(Init)) { 9260b57cec5SDimitry Andric for (unsigned i = 0, e = Init->getNumOperands(); i != e; ++i) { 9270b57cec5SDimitry Andric llvm::Constant *Elt = cast<llvm::Constant>(Init->getOperand(i)); 9280b57cec5SDimitry Andric if (!canEmitInitWithFewStoresAfterBZero(Elt, NumStores)) 9290b57cec5SDimitry Andric return false; 9300b57cec5SDimitry Andric } 9310b57cec5SDimitry Andric return true; 9320b57cec5SDimitry Andric } 9330b57cec5SDimitry Andric 9340b57cec5SDimitry Andric if (llvm::ConstantDataSequential *CDS = 9350b57cec5SDimitry Andric dyn_cast<llvm::ConstantDataSequential>(Init)) { 9360b57cec5SDimitry Andric for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) { 9370b57cec5SDimitry Andric llvm::Constant *Elt = CDS->getElementAsConstant(i); 9380b57cec5SDimitry Andric if (!canEmitInitWithFewStoresAfterBZero(Elt, NumStores)) 9390b57cec5SDimitry Andric return false; 9400b57cec5SDimitry Andric } 9410b57cec5SDimitry Andric return true; 9420b57cec5SDimitry Andric } 9430b57cec5SDimitry Andric 9440b57cec5SDimitry Andric // Anything else is hard and scary. 9450b57cec5SDimitry Andric return false; 9460b57cec5SDimitry Andric } 9470b57cec5SDimitry Andric 9480b57cec5SDimitry Andric /// For inits that canEmitInitWithFewStoresAfterBZero returned true for, emit 9490b57cec5SDimitry Andric /// the scalar stores that would be required. 9500b57cec5SDimitry Andric static void emitStoresForInitAfterBZero(CodeGenModule &CGM, 9510b57cec5SDimitry Andric llvm::Constant *Init, Address Loc, 952e8d8bef9SDimitry Andric bool isVolatile, CGBuilderTy &Builder, 953e8d8bef9SDimitry Andric bool IsAutoInit) { 9540b57cec5SDimitry Andric assert(!Init->isNullValue() && !isa<llvm::UndefValue>(Init) && 9550b57cec5SDimitry Andric "called emitStoresForInitAfterBZero for zero or undef value."); 9560b57cec5SDimitry Andric 9570b57cec5SDimitry Andric if (isa<llvm::ConstantInt>(Init) || isa<llvm::ConstantFP>(Init) || 9580b57cec5SDimitry Andric isa<llvm::ConstantVector>(Init) || isa<llvm::BlockAddress>(Init) || 9590b57cec5SDimitry Andric isa<llvm::ConstantExpr>(Init)) { 960e8d8bef9SDimitry Andric auto *I = Builder.CreateStore(Init, Loc, isVolatile); 961e8d8bef9SDimitry Andric if (IsAutoInit) 962e8d8bef9SDimitry Andric I->addAnnotationMetadata("auto-init"); 9630b57cec5SDimitry Andric return; 9640b57cec5SDimitry Andric } 9650b57cec5SDimitry Andric 9660b57cec5SDimitry Andric if (llvm::ConstantDataSequential *CDS = 9670b57cec5SDimitry Andric dyn_cast<llvm::ConstantDataSequential>(Init)) { 9680b57cec5SDimitry Andric for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) { 9690b57cec5SDimitry Andric llvm::Constant *Elt = CDS->getElementAsConstant(i); 9700b57cec5SDimitry Andric 9710b57cec5SDimitry Andric // If necessary, get a pointer to the element and emit it. 9720b57cec5SDimitry Andric if (!Elt->isNullValue() && !isa<llvm::UndefValue>(Elt)) 9730b57cec5SDimitry Andric emitStoresForInitAfterBZero( 9740b57cec5SDimitry Andric CGM, Elt, Builder.CreateConstInBoundsGEP2_32(Loc, 0, i), isVolatile, 975e8d8bef9SDimitry Andric Builder, IsAutoInit); 9760b57cec5SDimitry Andric } 9770b57cec5SDimitry Andric return; 9780b57cec5SDimitry Andric } 9790b57cec5SDimitry Andric 9800b57cec5SDimitry Andric assert((isa<llvm::ConstantStruct>(Init) || isa<llvm::ConstantArray>(Init)) && 9810b57cec5SDimitry Andric "Unknown value type!"); 9820b57cec5SDimitry Andric 9830b57cec5SDimitry Andric for (unsigned i = 0, e = Init->getNumOperands(); i != e; ++i) { 9840b57cec5SDimitry Andric llvm::Constant *Elt = cast<llvm::Constant>(Init->getOperand(i)); 9850b57cec5SDimitry Andric 9860b57cec5SDimitry Andric // If necessary, get a pointer to the element and emit it. 9870b57cec5SDimitry Andric if (!Elt->isNullValue() && !isa<llvm::UndefValue>(Elt)) 9880b57cec5SDimitry Andric emitStoresForInitAfterBZero(CGM, Elt, 9890b57cec5SDimitry Andric Builder.CreateConstInBoundsGEP2_32(Loc, 0, i), 990e8d8bef9SDimitry Andric isVolatile, Builder, IsAutoInit); 9910b57cec5SDimitry Andric } 9920b57cec5SDimitry Andric } 9930b57cec5SDimitry Andric 9940b57cec5SDimitry Andric /// Decide whether we should use bzero plus some stores to initialize a local 9950b57cec5SDimitry Andric /// variable instead of using a memcpy from a constant global. It is beneficial 9960b57cec5SDimitry Andric /// to use bzero if the global is all zeros, or mostly zeros and large. 9970b57cec5SDimitry Andric static bool shouldUseBZeroPlusStoresToInitialize(llvm::Constant *Init, 9980b57cec5SDimitry Andric uint64_t GlobalSize) { 9990b57cec5SDimitry Andric // If a global is all zeros, always use a bzero. 10000b57cec5SDimitry Andric if (isa<llvm::ConstantAggregateZero>(Init)) return true; 10010b57cec5SDimitry Andric 10020b57cec5SDimitry Andric // If a non-zero global is <= 32 bytes, always use a memcpy. If it is large, 10030b57cec5SDimitry Andric // do it if it will require 6 or fewer scalar stores. 10040b57cec5SDimitry Andric // TODO: Should budget depends on the size? Avoiding a large global warrants 10050b57cec5SDimitry Andric // plopping in more stores. 10060b57cec5SDimitry Andric unsigned StoreBudget = 6; 10070b57cec5SDimitry Andric uint64_t SizeLimit = 32; 10080b57cec5SDimitry Andric 10090b57cec5SDimitry Andric return GlobalSize > SizeLimit && 10100b57cec5SDimitry Andric canEmitInitWithFewStoresAfterBZero(Init, StoreBudget); 10110b57cec5SDimitry Andric } 10120b57cec5SDimitry Andric 10130b57cec5SDimitry Andric /// Decide whether we should use memset to initialize a local variable instead 10140b57cec5SDimitry Andric /// of using a memcpy from a constant global. Assumes we've already decided to 10150b57cec5SDimitry Andric /// not user bzero. 10160b57cec5SDimitry Andric /// FIXME We could be more clever, as we are for bzero above, and generate 10170b57cec5SDimitry Andric /// memset followed by stores. It's unclear that's worth the effort. 10180b57cec5SDimitry Andric static llvm::Value *shouldUseMemSetToInitialize(llvm::Constant *Init, 10190b57cec5SDimitry Andric uint64_t GlobalSize, 10200b57cec5SDimitry Andric const llvm::DataLayout &DL) { 10210b57cec5SDimitry Andric uint64_t SizeLimit = 32; 10220b57cec5SDimitry Andric if (GlobalSize <= SizeLimit) 10230b57cec5SDimitry Andric return nullptr; 10240b57cec5SDimitry Andric return llvm::isBytewiseValue(Init, DL); 10250b57cec5SDimitry Andric } 10260b57cec5SDimitry Andric 10270b57cec5SDimitry Andric /// Decide whether we want to split a constant structure or array store into a 10280b57cec5SDimitry Andric /// sequence of its fields' stores. This may cost us code size and compilation 10290b57cec5SDimitry Andric /// speed, but plays better with store optimizations. 10300b57cec5SDimitry Andric static bool shouldSplitConstantStore(CodeGenModule &CGM, 10310b57cec5SDimitry Andric uint64_t GlobalByteSize) { 10320b57cec5SDimitry Andric // Don't break things that occupy more than one cacheline. 10330b57cec5SDimitry Andric uint64_t ByteSizeLimit = 64; 10340b57cec5SDimitry Andric if (CGM.getCodeGenOpts().OptimizationLevel == 0) 10350b57cec5SDimitry Andric return false; 10360b57cec5SDimitry Andric if (GlobalByteSize <= ByteSizeLimit) 10370b57cec5SDimitry Andric return true; 10380b57cec5SDimitry Andric return false; 10390b57cec5SDimitry Andric } 10400b57cec5SDimitry Andric 10410b57cec5SDimitry Andric enum class IsPattern { No, Yes }; 10420b57cec5SDimitry Andric 10430b57cec5SDimitry Andric /// Generate a constant filled with either a pattern or zeroes. 10440b57cec5SDimitry Andric static llvm::Constant *patternOrZeroFor(CodeGenModule &CGM, IsPattern isPattern, 10450b57cec5SDimitry Andric llvm::Type *Ty) { 10460b57cec5SDimitry Andric if (isPattern == IsPattern::Yes) 10470b57cec5SDimitry Andric return initializationPatternFor(CGM, Ty); 10480b57cec5SDimitry Andric else 10490b57cec5SDimitry Andric return llvm::Constant::getNullValue(Ty); 10500b57cec5SDimitry Andric } 10510b57cec5SDimitry Andric 10520b57cec5SDimitry Andric static llvm::Constant *constWithPadding(CodeGenModule &CGM, IsPattern isPattern, 10530b57cec5SDimitry Andric llvm::Constant *constant); 10540b57cec5SDimitry Andric 10550b57cec5SDimitry Andric /// Helper function for constWithPadding() to deal with padding in structures. 10560b57cec5SDimitry Andric static llvm::Constant *constStructWithPadding(CodeGenModule &CGM, 10570b57cec5SDimitry Andric IsPattern isPattern, 10580b57cec5SDimitry Andric llvm::StructType *STy, 10590b57cec5SDimitry Andric llvm::Constant *constant) { 10600b57cec5SDimitry Andric const llvm::DataLayout &DL = CGM.getDataLayout(); 10610b57cec5SDimitry Andric const llvm::StructLayout *Layout = DL.getStructLayout(STy); 10620b57cec5SDimitry Andric llvm::Type *Int8Ty = llvm::IntegerType::getInt8Ty(CGM.getLLVMContext()); 10630b57cec5SDimitry Andric unsigned SizeSoFar = 0; 10640b57cec5SDimitry Andric SmallVector<llvm::Constant *, 8> Values; 10650b57cec5SDimitry Andric bool NestedIntact = true; 10660b57cec5SDimitry Andric for (unsigned i = 0, e = STy->getNumElements(); i != e; i++) { 10670b57cec5SDimitry Andric unsigned CurOff = Layout->getElementOffset(i); 10680b57cec5SDimitry Andric if (SizeSoFar < CurOff) { 10690b57cec5SDimitry Andric assert(!STy->isPacked()); 10700b57cec5SDimitry Andric auto *PadTy = llvm::ArrayType::get(Int8Ty, CurOff - SizeSoFar); 10710b57cec5SDimitry Andric Values.push_back(patternOrZeroFor(CGM, isPattern, PadTy)); 10720b57cec5SDimitry Andric } 10730b57cec5SDimitry Andric llvm::Constant *CurOp; 10740b57cec5SDimitry Andric if (constant->isZeroValue()) 10750b57cec5SDimitry Andric CurOp = llvm::Constant::getNullValue(STy->getElementType(i)); 10760b57cec5SDimitry Andric else 10770b57cec5SDimitry Andric CurOp = cast<llvm::Constant>(constant->getAggregateElement(i)); 10780b57cec5SDimitry Andric auto *NewOp = constWithPadding(CGM, isPattern, CurOp); 10790b57cec5SDimitry Andric if (CurOp != NewOp) 10800b57cec5SDimitry Andric NestedIntact = false; 10810b57cec5SDimitry Andric Values.push_back(NewOp); 10820b57cec5SDimitry Andric SizeSoFar = CurOff + DL.getTypeAllocSize(CurOp->getType()); 10830b57cec5SDimitry Andric } 10840b57cec5SDimitry Andric unsigned TotalSize = Layout->getSizeInBytes(); 10850b57cec5SDimitry Andric if (SizeSoFar < TotalSize) { 10860b57cec5SDimitry Andric auto *PadTy = llvm::ArrayType::get(Int8Ty, TotalSize - SizeSoFar); 10870b57cec5SDimitry Andric Values.push_back(patternOrZeroFor(CGM, isPattern, PadTy)); 10880b57cec5SDimitry Andric } 10890b57cec5SDimitry Andric if (NestedIntact && Values.size() == STy->getNumElements()) 10900b57cec5SDimitry Andric return constant; 10910b57cec5SDimitry Andric return llvm::ConstantStruct::getAnon(Values, STy->isPacked()); 10920b57cec5SDimitry Andric } 10930b57cec5SDimitry Andric 10940b57cec5SDimitry Andric /// Replace all padding bytes in a given constant with either a pattern byte or 10950b57cec5SDimitry Andric /// 0x00. 10960b57cec5SDimitry Andric static llvm::Constant *constWithPadding(CodeGenModule &CGM, IsPattern isPattern, 10970b57cec5SDimitry Andric llvm::Constant *constant) { 10980b57cec5SDimitry Andric llvm::Type *OrigTy = constant->getType(); 10990b57cec5SDimitry Andric if (const auto STy = dyn_cast<llvm::StructType>(OrigTy)) 11000b57cec5SDimitry Andric return constStructWithPadding(CGM, isPattern, STy, constant); 11015ffd83dbSDimitry Andric if (auto *ArrayTy = dyn_cast<llvm::ArrayType>(OrigTy)) { 11020b57cec5SDimitry Andric llvm::SmallVector<llvm::Constant *, 8> Values; 11035ffd83dbSDimitry Andric uint64_t Size = ArrayTy->getNumElements(); 11040b57cec5SDimitry Andric if (!Size) 11050b57cec5SDimitry Andric return constant; 11065ffd83dbSDimitry Andric llvm::Type *ElemTy = ArrayTy->getElementType(); 11075ffd83dbSDimitry Andric bool ZeroInitializer = constant->isNullValue(); 11080b57cec5SDimitry Andric llvm::Constant *OpValue, *PaddedOp; 11090b57cec5SDimitry Andric if (ZeroInitializer) { 11100b57cec5SDimitry Andric OpValue = llvm::Constant::getNullValue(ElemTy); 11110b57cec5SDimitry Andric PaddedOp = constWithPadding(CGM, isPattern, OpValue); 11120b57cec5SDimitry Andric } 11130b57cec5SDimitry Andric for (unsigned Op = 0; Op != Size; ++Op) { 11140b57cec5SDimitry Andric if (!ZeroInitializer) { 11150b57cec5SDimitry Andric OpValue = constant->getAggregateElement(Op); 11160b57cec5SDimitry Andric PaddedOp = constWithPadding(CGM, isPattern, OpValue); 11170b57cec5SDimitry Andric } 11180b57cec5SDimitry Andric Values.push_back(PaddedOp); 11190b57cec5SDimitry Andric } 11200b57cec5SDimitry Andric auto *NewElemTy = Values[0]->getType(); 11210b57cec5SDimitry Andric if (NewElemTy == ElemTy) 11220b57cec5SDimitry Andric return constant; 11235ffd83dbSDimitry Andric auto *NewArrayTy = llvm::ArrayType::get(NewElemTy, Size); 11245ffd83dbSDimitry Andric return llvm::ConstantArray::get(NewArrayTy, Values); 11250b57cec5SDimitry Andric } 11265ffd83dbSDimitry Andric // FIXME: Add handling for tail padding in vectors. Vectors don't 11275ffd83dbSDimitry Andric // have padding between or inside elements, but the total amount of 11285ffd83dbSDimitry Andric // data can be less than the allocated size. 11290b57cec5SDimitry Andric return constant; 11300b57cec5SDimitry Andric } 11310b57cec5SDimitry Andric 11320b57cec5SDimitry Andric Address CodeGenModule::createUnnamedGlobalFrom(const VarDecl &D, 11330b57cec5SDimitry Andric llvm::Constant *Constant, 11340b57cec5SDimitry Andric CharUnits Align) { 11350b57cec5SDimitry Andric auto FunctionName = [&](const DeclContext *DC) -> std::string { 11360b57cec5SDimitry Andric if (const auto *FD = dyn_cast<FunctionDecl>(DC)) { 11370b57cec5SDimitry Andric if (const auto *CC = dyn_cast<CXXConstructorDecl>(FD)) 11380b57cec5SDimitry Andric return CC->getNameAsString(); 11390b57cec5SDimitry Andric if (const auto *CD = dyn_cast<CXXDestructorDecl>(FD)) 11400b57cec5SDimitry Andric return CD->getNameAsString(); 11415ffd83dbSDimitry Andric return std::string(getMangledName(FD)); 11420b57cec5SDimitry Andric } else if (const auto *OM = dyn_cast<ObjCMethodDecl>(DC)) { 11430b57cec5SDimitry Andric return OM->getNameAsString(); 11440b57cec5SDimitry Andric } else if (isa<BlockDecl>(DC)) { 11450b57cec5SDimitry Andric return "<block>"; 11460b57cec5SDimitry Andric } else if (isa<CapturedDecl>(DC)) { 11470b57cec5SDimitry Andric return "<captured>"; 11480b57cec5SDimitry Andric } else { 11490b57cec5SDimitry Andric llvm_unreachable("expected a function or method"); 11500b57cec5SDimitry Andric } 11510b57cec5SDimitry Andric }; 11520b57cec5SDimitry Andric 11530b57cec5SDimitry Andric // Form a simple per-variable cache of these values in case we find we 11540b57cec5SDimitry Andric // want to reuse them. 11550b57cec5SDimitry Andric llvm::GlobalVariable *&CacheEntry = InitializerConstants[&D]; 11560b57cec5SDimitry Andric if (!CacheEntry || CacheEntry->getInitializer() != Constant) { 11570b57cec5SDimitry Andric auto *Ty = Constant->getType(); 11580b57cec5SDimitry Andric bool isConstant = true; 11590b57cec5SDimitry Andric llvm::GlobalVariable *InsertBefore = nullptr; 11600b57cec5SDimitry Andric unsigned AS = 1161fe6060f1SDimitry Andric getContext().getTargetAddressSpace(GetGlobalConstantAddressSpace()); 11620b57cec5SDimitry Andric std::string Name; 11630b57cec5SDimitry Andric if (D.hasGlobalStorage()) 11640b57cec5SDimitry Andric Name = getMangledName(&D).str() + ".const"; 11650b57cec5SDimitry Andric else if (const DeclContext *DC = D.getParentFunctionOrMethod()) 11660b57cec5SDimitry Andric Name = ("__const." + FunctionName(DC) + "." + D.getName()).str(); 11670b57cec5SDimitry Andric else 11680b57cec5SDimitry Andric llvm_unreachable("local variable has no parent function or method"); 11690b57cec5SDimitry Andric llvm::GlobalVariable *GV = new llvm::GlobalVariable( 11700b57cec5SDimitry Andric getModule(), Ty, isConstant, llvm::GlobalValue::PrivateLinkage, 11710b57cec5SDimitry Andric Constant, Name, InsertBefore, llvm::GlobalValue::NotThreadLocal, AS); 1172a7dea167SDimitry Andric GV->setAlignment(Align.getAsAlign()); 11730b57cec5SDimitry Andric GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); 11740b57cec5SDimitry Andric CacheEntry = GV; 1175349cc55cSDimitry Andric } else if (CacheEntry->getAlignment() < uint64_t(Align.getQuantity())) { 1176a7dea167SDimitry Andric CacheEntry->setAlignment(Align.getAsAlign()); 11770b57cec5SDimitry Andric } 11780b57cec5SDimitry Andric 11790eae32dcSDimitry Andric return Address(CacheEntry, CacheEntry->getValueType(), Align); 11800b57cec5SDimitry Andric } 11810b57cec5SDimitry Andric 11820b57cec5SDimitry Andric static Address createUnnamedGlobalForMemcpyFrom(CodeGenModule &CGM, 11830b57cec5SDimitry Andric const VarDecl &D, 11840b57cec5SDimitry Andric CGBuilderTy &Builder, 11850b57cec5SDimitry Andric llvm::Constant *Constant, 11860b57cec5SDimitry Andric CharUnits Align) { 11870b57cec5SDimitry Andric Address SrcPtr = CGM.createUnnamedGlobalFrom(D, Constant, Align); 118806c3fb27SDimitry Andric return SrcPtr.withElementType(CGM.Int8Ty); 11890b57cec5SDimitry Andric } 11900b57cec5SDimitry Andric 11910b57cec5SDimitry Andric static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, 11920b57cec5SDimitry Andric Address Loc, bool isVolatile, 11930b57cec5SDimitry Andric CGBuilderTy &Builder, 1194e8d8bef9SDimitry Andric llvm::Constant *constant, bool IsAutoInit) { 11950b57cec5SDimitry Andric auto *Ty = constant->getType(); 11960b57cec5SDimitry Andric uint64_t ConstantSize = CGM.getDataLayout().getTypeAllocSize(Ty); 11970b57cec5SDimitry Andric if (!ConstantSize) 11980b57cec5SDimitry Andric return; 11990b57cec5SDimitry Andric 12000b57cec5SDimitry Andric bool canDoSingleStore = Ty->isIntOrIntVectorTy() || 12010b57cec5SDimitry Andric Ty->isPtrOrPtrVectorTy() || Ty->isFPOrFPVectorTy(); 12020b57cec5SDimitry Andric if (canDoSingleStore) { 1203e8d8bef9SDimitry Andric auto *I = Builder.CreateStore(constant, Loc, isVolatile); 1204e8d8bef9SDimitry Andric if (IsAutoInit) 1205e8d8bef9SDimitry Andric I->addAnnotationMetadata("auto-init"); 12060b57cec5SDimitry Andric return; 12070b57cec5SDimitry Andric } 12080b57cec5SDimitry Andric 12090b57cec5SDimitry Andric auto *SizeVal = llvm::ConstantInt::get(CGM.IntPtrTy, ConstantSize); 12100b57cec5SDimitry Andric 12110b57cec5SDimitry Andric // If the initializer is all or mostly the same, codegen with bzero / memset 12120b57cec5SDimitry Andric // then do a few stores afterward. 12130b57cec5SDimitry Andric if (shouldUseBZeroPlusStoresToInitialize(constant, ConstantSize)) { 1214e8d8bef9SDimitry Andric auto *I = Builder.CreateMemSet(Loc, llvm::ConstantInt::get(CGM.Int8Ty, 0), 1215e8d8bef9SDimitry Andric SizeVal, isVolatile); 1216e8d8bef9SDimitry Andric if (IsAutoInit) 1217e8d8bef9SDimitry Andric I->addAnnotationMetadata("auto-init"); 12180b57cec5SDimitry Andric 12190b57cec5SDimitry Andric bool valueAlreadyCorrect = 12200b57cec5SDimitry Andric constant->isNullValue() || isa<llvm::UndefValue>(constant); 12210b57cec5SDimitry Andric if (!valueAlreadyCorrect) { 122206c3fb27SDimitry Andric Loc = Loc.withElementType(Ty); 1223e8d8bef9SDimitry Andric emitStoresForInitAfterBZero(CGM, constant, Loc, isVolatile, Builder, 1224e8d8bef9SDimitry Andric IsAutoInit); 12250b57cec5SDimitry Andric } 12260b57cec5SDimitry Andric return; 12270b57cec5SDimitry Andric } 12280b57cec5SDimitry Andric 12290b57cec5SDimitry Andric // If the initializer is a repeated byte pattern, use memset. 12300b57cec5SDimitry Andric llvm::Value *Pattern = 12310b57cec5SDimitry Andric shouldUseMemSetToInitialize(constant, ConstantSize, CGM.getDataLayout()); 12320b57cec5SDimitry Andric if (Pattern) { 12330b57cec5SDimitry Andric uint64_t Value = 0x00; 12340b57cec5SDimitry Andric if (!isa<llvm::UndefValue>(Pattern)) { 12350b57cec5SDimitry Andric const llvm::APInt &AP = cast<llvm::ConstantInt>(Pattern)->getValue(); 12360b57cec5SDimitry Andric assert(AP.getBitWidth() <= 8); 12370b57cec5SDimitry Andric Value = AP.getLimitedValue(); 12380b57cec5SDimitry Andric } 1239e8d8bef9SDimitry Andric auto *I = Builder.CreateMemSet( 1240e8d8bef9SDimitry Andric Loc, llvm::ConstantInt::get(CGM.Int8Ty, Value), SizeVal, isVolatile); 1241e8d8bef9SDimitry Andric if (IsAutoInit) 1242e8d8bef9SDimitry Andric I->addAnnotationMetadata("auto-init"); 12430b57cec5SDimitry Andric return; 12440b57cec5SDimitry Andric } 12450b57cec5SDimitry Andric 1246439352acSDimitry Andric // If the initializer is small or trivialAutoVarInit is set, use a handful of 1247439352acSDimitry Andric // stores. 1248439352acSDimitry Andric bool IsTrivialAutoVarInitPattern = 1249439352acSDimitry Andric CGM.getContext().getLangOpts().getTrivialAutoVarInit() == 1250439352acSDimitry Andric LangOptions::TrivialAutoVarInitKind::Pattern; 12510b57cec5SDimitry Andric if (shouldSplitConstantStore(CGM, ConstantSize)) { 12520b57cec5SDimitry Andric if (auto *STy = dyn_cast<llvm::StructType>(Ty)) { 1253439352acSDimitry Andric if (STy == Loc.getElementType() || 1254439352acSDimitry Andric (STy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) { 12555f757f3fSDimitry Andric const llvm::StructLayout *Layout = 12565f757f3fSDimitry Andric CGM.getDataLayout().getStructLayout(STy); 12570b57cec5SDimitry Andric for (unsigned i = 0; i != constant->getNumOperands(); i++) { 1258439352acSDimitry Andric CharUnits CurOff = 1259439352acSDimitry Andric CharUnits::fromQuantity(Layout->getElementOffset(i)); 12605f757f3fSDimitry Andric Address EltPtr = Builder.CreateConstInBoundsByteGEP( 12615f757f3fSDimitry Andric Loc.withElementType(CGM.Int8Ty), CurOff); 12625f757f3fSDimitry Andric emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, 12635f757f3fSDimitry Andric constant->getAggregateElement(i), IsAutoInit); 12640b57cec5SDimitry Andric } 12650b57cec5SDimitry Andric return; 1266439352acSDimitry Andric } 12670b57cec5SDimitry Andric } else if (auto *ATy = dyn_cast<llvm::ArrayType>(Ty)) { 1268439352acSDimitry Andric if (ATy == Loc.getElementType() || 1269439352acSDimitry Andric (ATy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) { 12700b57cec5SDimitry Andric for (unsigned i = 0; i != ATy->getNumElements(); i++) { 12715f757f3fSDimitry Andric Address EltPtr = Builder.CreateConstGEP( 12725f757f3fSDimitry Andric Loc.withElementType(ATy->getElementType()), i); 12735f757f3fSDimitry Andric emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder, 12745f757f3fSDimitry Andric constant->getAggregateElement(i), IsAutoInit); 12750b57cec5SDimitry Andric } 12760b57cec5SDimitry Andric return; 12770b57cec5SDimitry Andric } 12780b57cec5SDimitry Andric } 1279439352acSDimitry Andric } 12800b57cec5SDimitry Andric 12810b57cec5SDimitry Andric // Copy from a global. 1282e8d8bef9SDimitry Andric auto *I = 12830b57cec5SDimitry Andric Builder.CreateMemCpy(Loc, 12840b57cec5SDimitry Andric createUnnamedGlobalForMemcpyFrom( 12850b57cec5SDimitry Andric CGM, D, Builder, constant, Loc.getAlignment()), 12860b57cec5SDimitry Andric SizeVal, isVolatile); 1287e8d8bef9SDimitry Andric if (IsAutoInit) 1288e8d8bef9SDimitry Andric I->addAnnotationMetadata("auto-init"); 12890b57cec5SDimitry Andric } 12900b57cec5SDimitry Andric 12910b57cec5SDimitry Andric static void emitStoresForZeroInit(CodeGenModule &CGM, const VarDecl &D, 12920b57cec5SDimitry Andric Address Loc, bool isVolatile, 12930b57cec5SDimitry Andric CGBuilderTy &Builder) { 12940b57cec5SDimitry Andric llvm::Type *ElTy = Loc.getElementType(); 12950b57cec5SDimitry Andric llvm::Constant *constant = 12960b57cec5SDimitry Andric constWithPadding(CGM, IsPattern::No, llvm::Constant::getNullValue(ElTy)); 1297e8d8bef9SDimitry Andric emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant, 1298e8d8bef9SDimitry Andric /*IsAutoInit=*/true); 12990b57cec5SDimitry Andric } 13000b57cec5SDimitry Andric 13010b57cec5SDimitry Andric static void emitStoresForPatternInit(CodeGenModule &CGM, const VarDecl &D, 13020b57cec5SDimitry Andric Address Loc, bool isVolatile, 13030b57cec5SDimitry Andric CGBuilderTy &Builder) { 13040b57cec5SDimitry Andric llvm::Type *ElTy = Loc.getElementType(); 13050b57cec5SDimitry Andric llvm::Constant *constant = constWithPadding( 13060b57cec5SDimitry Andric CGM, IsPattern::Yes, initializationPatternFor(CGM, ElTy)); 13070b57cec5SDimitry Andric assert(!isa<llvm::UndefValue>(constant)); 1308e8d8bef9SDimitry Andric emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant, 1309e8d8bef9SDimitry Andric /*IsAutoInit=*/true); 13100b57cec5SDimitry Andric } 13110b57cec5SDimitry Andric 13120b57cec5SDimitry Andric static bool containsUndef(llvm::Constant *constant) { 13130b57cec5SDimitry Andric auto *Ty = constant->getType(); 13140b57cec5SDimitry Andric if (isa<llvm::UndefValue>(constant)) 13150b57cec5SDimitry Andric return true; 13160b57cec5SDimitry Andric if (Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()) 13170b57cec5SDimitry Andric for (llvm::Use &Op : constant->operands()) 13180b57cec5SDimitry Andric if (containsUndef(cast<llvm::Constant>(Op))) 13190b57cec5SDimitry Andric return true; 13200b57cec5SDimitry Andric return false; 13210b57cec5SDimitry Andric } 13220b57cec5SDimitry Andric 13230b57cec5SDimitry Andric static llvm::Constant *replaceUndef(CodeGenModule &CGM, IsPattern isPattern, 13240b57cec5SDimitry Andric llvm::Constant *constant) { 13250b57cec5SDimitry Andric auto *Ty = constant->getType(); 13260b57cec5SDimitry Andric if (isa<llvm::UndefValue>(constant)) 13270b57cec5SDimitry Andric return patternOrZeroFor(CGM, isPattern, Ty); 13280b57cec5SDimitry Andric if (!(Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy())) 13290b57cec5SDimitry Andric return constant; 13300b57cec5SDimitry Andric if (!containsUndef(constant)) 13310b57cec5SDimitry Andric return constant; 13320b57cec5SDimitry Andric llvm::SmallVector<llvm::Constant *, 8> Values(constant->getNumOperands()); 13330b57cec5SDimitry Andric for (unsigned Op = 0, NumOp = constant->getNumOperands(); Op != NumOp; ++Op) { 13340b57cec5SDimitry Andric auto *OpValue = cast<llvm::Constant>(constant->getOperand(Op)); 13350b57cec5SDimitry Andric Values[Op] = replaceUndef(CGM, isPattern, OpValue); 13360b57cec5SDimitry Andric } 13370b57cec5SDimitry Andric if (Ty->isStructTy()) 13380b57cec5SDimitry Andric return llvm::ConstantStruct::get(cast<llvm::StructType>(Ty), Values); 13390b57cec5SDimitry Andric if (Ty->isArrayTy()) 13400b57cec5SDimitry Andric return llvm::ConstantArray::get(cast<llvm::ArrayType>(Ty), Values); 13410b57cec5SDimitry Andric assert(Ty->isVectorTy()); 13420b57cec5SDimitry Andric return llvm::ConstantVector::get(Values); 13430b57cec5SDimitry Andric } 13440b57cec5SDimitry Andric 13450b57cec5SDimitry Andric /// EmitAutoVarDecl - Emit code and set up an entry in LocalDeclMap for a 13460b57cec5SDimitry Andric /// variable declaration with auto, register, or no storage class specifier. 13470b57cec5SDimitry Andric /// These turn into simple stack objects, or GlobalValues depending on target. 13480b57cec5SDimitry Andric void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D) { 13490b57cec5SDimitry Andric AutoVarEmission emission = EmitAutoVarAlloca(D); 13500b57cec5SDimitry Andric EmitAutoVarInit(emission); 13510b57cec5SDimitry Andric EmitAutoVarCleanups(emission); 13520b57cec5SDimitry Andric } 13530b57cec5SDimitry Andric 13540b57cec5SDimitry Andric /// Emit a lifetime.begin marker if some criteria are satisfied. 13550b57cec5SDimitry Andric /// \return a pointer to the temporary size Value if a marker was emitted, null 13560b57cec5SDimitry Andric /// otherwise 1357fe6060f1SDimitry Andric llvm::Value *CodeGenFunction::EmitLifetimeStart(llvm::TypeSize Size, 13580b57cec5SDimitry Andric llvm::Value *Addr) { 13590b57cec5SDimitry Andric if (!ShouldEmitLifetimeMarkers) 13600b57cec5SDimitry Andric return nullptr; 13610b57cec5SDimitry Andric 13620b57cec5SDimitry Andric assert(Addr->getType()->getPointerAddressSpace() == 13630b57cec5SDimitry Andric CGM.getDataLayout().getAllocaAddrSpace() && 13640b57cec5SDimitry Andric "Pointer should be in alloca address space"); 1365fe6060f1SDimitry Andric llvm::Value *SizeV = llvm::ConstantInt::get( 1366fe6060f1SDimitry Andric Int64Ty, Size.isScalable() ? -1 : Size.getFixedValue()); 13670b57cec5SDimitry Andric llvm::CallInst *C = 13680b57cec5SDimitry Andric Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {SizeV, Addr}); 13690b57cec5SDimitry Andric C->setDoesNotThrow(); 13700b57cec5SDimitry Andric return SizeV; 13710b57cec5SDimitry Andric } 13720b57cec5SDimitry Andric 13730b57cec5SDimitry Andric void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) { 13740b57cec5SDimitry Andric assert(Addr->getType()->getPointerAddressSpace() == 13750b57cec5SDimitry Andric CGM.getDataLayout().getAllocaAddrSpace() && 13760b57cec5SDimitry Andric "Pointer should be in alloca address space"); 13770b57cec5SDimitry Andric llvm::CallInst *C = 13780b57cec5SDimitry Andric Builder.CreateCall(CGM.getLLVMLifetimeEndFn(), {Size, Addr}); 13790b57cec5SDimitry Andric C->setDoesNotThrow(); 13800b57cec5SDimitry Andric } 13810b57cec5SDimitry Andric 13820b57cec5SDimitry Andric void CodeGenFunction::EmitAndRegisterVariableArrayDimensions( 13830b57cec5SDimitry Andric CGDebugInfo *DI, const VarDecl &D, bool EmitDebugInfo) { 13840b57cec5SDimitry Andric // For each dimension stores its QualType and corresponding 13850b57cec5SDimitry Andric // size-expression Value. 13860b57cec5SDimitry Andric SmallVector<CodeGenFunction::VlaSizePair, 4> Dimensions; 1387*0fca6ea1SDimitry Andric SmallVector<const IdentifierInfo *, 4> VLAExprNames; 13880b57cec5SDimitry Andric 13890b57cec5SDimitry Andric // Break down the array into individual dimensions. 13900b57cec5SDimitry Andric QualType Type1D = D.getType(); 13910b57cec5SDimitry Andric while (getContext().getAsVariableArrayType(Type1D)) { 13920b57cec5SDimitry Andric auto VlaSize = getVLAElements1D(Type1D); 13930b57cec5SDimitry Andric if (auto *C = dyn_cast<llvm::ConstantInt>(VlaSize.NumElts)) 13940b57cec5SDimitry Andric Dimensions.emplace_back(C, Type1D.getUnqualifiedType()); 13950b57cec5SDimitry Andric else { 13960b57cec5SDimitry Andric // Generate a locally unique name for the size expression. 13970b57cec5SDimitry Andric Twine Name = Twine("__vla_expr") + Twine(VLAExprCounter++); 13980b57cec5SDimitry Andric SmallString<12> Buffer; 13990b57cec5SDimitry Andric StringRef NameRef = Name.toStringRef(Buffer); 14000b57cec5SDimitry Andric auto &Ident = getContext().Idents.getOwn(NameRef); 14010b57cec5SDimitry Andric VLAExprNames.push_back(&Ident); 14020b57cec5SDimitry Andric auto SizeExprAddr = 14030b57cec5SDimitry Andric CreateDefaultAlignTempAlloca(VlaSize.NumElts->getType(), NameRef); 14040b57cec5SDimitry Andric Builder.CreateStore(VlaSize.NumElts, SizeExprAddr); 14050b57cec5SDimitry Andric Dimensions.emplace_back(SizeExprAddr.getPointer(), 14060b57cec5SDimitry Andric Type1D.getUnqualifiedType()); 14070b57cec5SDimitry Andric } 14080b57cec5SDimitry Andric Type1D = VlaSize.Type; 14090b57cec5SDimitry Andric } 14100b57cec5SDimitry Andric 14110b57cec5SDimitry Andric if (!EmitDebugInfo) 14120b57cec5SDimitry Andric return; 14130b57cec5SDimitry Andric 14140b57cec5SDimitry Andric // Register each dimension's size-expression with a DILocalVariable, 14150b57cec5SDimitry Andric // so that it can be used by CGDebugInfo when instantiating a DISubrange 14160b57cec5SDimitry Andric // to describe this array. 14170b57cec5SDimitry Andric unsigned NameIdx = 0; 14180b57cec5SDimitry Andric for (auto &VlaSize : Dimensions) { 14190b57cec5SDimitry Andric llvm::Metadata *MD; 14200b57cec5SDimitry Andric if (auto *C = dyn_cast<llvm::ConstantInt>(VlaSize.NumElts)) 14210b57cec5SDimitry Andric MD = llvm::ConstantAsMetadata::get(C); 14220b57cec5SDimitry Andric else { 14230b57cec5SDimitry Andric // Create an artificial VarDecl to generate debug info for. 1424*0fca6ea1SDimitry Andric const IdentifierInfo *NameIdent = VLAExprNames[NameIdx++]; 14250b57cec5SDimitry Andric auto QT = getContext().getIntTypeForBitwidth( 142604eeddc0SDimitry Andric SizeTy->getScalarSizeInBits(), false); 14270b57cec5SDimitry Andric auto *ArtificialDecl = VarDecl::Create( 14280b57cec5SDimitry Andric getContext(), const_cast<DeclContext *>(D.getDeclContext()), 14290b57cec5SDimitry Andric D.getLocation(), D.getLocation(), NameIdent, QT, 14300b57cec5SDimitry Andric getContext().CreateTypeSourceInfo(QT), SC_Auto); 14310b57cec5SDimitry Andric ArtificialDecl->setImplicit(); 14320b57cec5SDimitry Andric 14330b57cec5SDimitry Andric MD = DI->EmitDeclareOfAutoVariable(ArtificialDecl, VlaSize.NumElts, 14340b57cec5SDimitry Andric Builder); 14350b57cec5SDimitry Andric } 14360b57cec5SDimitry Andric assert(MD && "No Size expression debug node created"); 14370b57cec5SDimitry Andric DI->registerVLASizeExpression(VlaSize.Type, MD); 14380b57cec5SDimitry Andric } 14390b57cec5SDimitry Andric } 14400b57cec5SDimitry Andric 14410b57cec5SDimitry Andric /// EmitAutoVarAlloca - Emit the alloca and debug information for a 14420b57cec5SDimitry Andric /// local variable. Does not emit initialization or destruction. 14430b57cec5SDimitry Andric CodeGenFunction::AutoVarEmission 14440b57cec5SDimitry Andric CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { 14450b57cec5SDimitry Andric QualType Ty = D.getType(); 14460b57cec5SDimitry Andric assert( 14470b57cec5SDimitry Andric Ty.getAddressSpace() == LangAS::Default || 14480b57cec5SDimitry Andric (Ty.getAddressSpace() == LangAS::opencl_private && getLangOpts().OpenCL)); 14490b57cec5SDimitry Andric 14500b57cec5SDimitry Andric AutoVarEmission emission(D); 14510b57cec5SDimitry Andric 14520b57cec5SDimitry Andric bool isEscapingByRef = D.isEscapingByref(); 14530b57cec5SDimitry Andric emission.IsEscapingByRef = isEscapingByRef; 14540b57cec5SDimitry Andric 14550b57cec5SDimitry Andric CharUnits alignment = getContext().getDeclAlign(&D); 14560b57cec5SDimitry Andric 14570b57cec5SDimitry Andric // If the type is variably-modified, emit all the VLA sizes for it. 14580b57cec5SDimitry Andric if (Ty->isVariablyModifiedType()) 14590b57cec5SDimitry Andric EmitVariablyModifiedType(Ty); 14600b57cec5SDimitry Andric 14610b57cec5SDimitry Andric auto *DI = getDebugInfo(); 1462480093f4SDimitry Andric bool EmitDebugInfo = DI && CGM.getCodeGenOpts().hasReducedDebugInfo(); 14630b57cec5SDimitry Andric 14640b57cec5SDimitry Andric Address address = Address::invalid(); 1465*0fca6ea1SDimitry Andric RawAddress AllocaAddr = RawAddress::invalid(); 14665ffd83dbSDimitry Andric Address OpenMPLocalAddr = Address::invalid(); 14675ffd83dbSDimitry Andric if (CGM.getLangOpts().OpenMPIRBuilder) 14685ffd83dbSDimitry Andric OpenMPLocalAddr = OMPBuilderCBHelpers::getAddressOfLocalVariable(*this, &D); 14695ffd83dbSDimitry Andric else 14705ffd83dbSDimitry Andric OpenMPLocalAddr = 14710b57cec5SDimitry Andric getLangOpts().OpenMP 14720b57cec5SDimitry Andric ? CGM.getOpenMPRuntime().getAddressOfLocalVariable(*this, &D) 14730b57cec5SDimitry Andric : Address::invalid(); 14745ffd83dbSDimitry Andric 14750b57cec5SDimitry Andric bool NRVO = getLangOpts().ElideConstructors && D.isNRVOVariable(); 14760b57cec5SDimitry Andric 14770b57cec5SDimitry Andric if (getLangOpts().OpenMP && OpenMPLocalAddr.isValid()) { 14780b57cec5SDimitry Andric address = OpenMPLocalAddr; 1479349cc55cSDimitry Andric AllocaAddr = OpenMPLocalAddr; 14800b57cec5SDimitry Andric } else if (Ty->isConstantSizeType()) { 14810b57cec5SDimitry Andric // If this value is an array or struct with a statically determinable 14820b57cec5SDimitry Andric // constant initializer, there are optimizations we can do. 14830b57cec5SDimitry Andric // 14840b57cec5SDimitry Andric // TODO: We should constant-evaluate the initializer of any variable, 14850b57cec5SDimitry Andric // as long as it is initialized by a constant expression. Currently, 14860b57cec5SDimitry Andric // isConstantInitializer produces wrong answers for structs with 14870b57cec5SDimitry Andric // reference or bitfield members, and a few other cases, and checking 14880b57cec5SDimitry Andric // for POD-ness protects us from some of these. 14890b57cec5SDimitry Andric if (D.getInit() && (Ty->isArrayType() || Ty->isRecordType()) && 14900b57cec5SDimitry Andric (D.isConstexpr() || 14910b57cec5SDimitry Andric ((Ty.isPODType(getContext()) || 14920b57cec5SDimitry Andric getContext().getBaseElementType(Ty)->isObjCObjectPointerType()) && 14930b57cec5SDimitry Andric D.getInit()->isConstantInitializer(getContext(), false)))) { 14940b57cec5SDimitry Andric 14950b57cec5SDimitry Andric // If the variable's a const type, and it's neither an NRVO 14960b57cec5SDimitry Andric // candidate nor a __block variable and has no mutable members, 14970b57cec5SDimitry Andric // emit it as a global instead. 14980b57cec5SDimitry Andric // Exception is if a variable is located in non-constant address space 14990b57cec5SDimitry Andric // in OpenCL. 150006c3fb27SDimitry Andric bool NeedsDtor = 150106c3fb27SDimitry Andric D.needsDestruction(getContext()) == QualType::DK_cxx_destructor; 15020b57cec5SDimitry Andric if ((!getLangOpts().OpenCL || 15030b57cec5SDimitry Andric Ty.getAddressSpace() == LangAS::opencl_constant) && 15040b57cec5SDimitry Andric (CGM.getCodeGenOpts().MergeAllConstants && !NRVO && 15055f757f3fSDimitry Andric !isEscapingByRef && 15065f757f3fSDimitry Andric Ty.isConstantStorage(getContext(), true, !NeedsDtor))) { 15070b57cec5SDimitry Andric EmitStaticVarDecl(D, llvm::GlobalValue::InternalLinkage); 15080b57cec5SDimitry Andric 15090b57cec5SDimitry Andric // Signal this condition to later callbacks. 15100b57cec5SDimitry Andric emission.Addr = Address::invalid(); 15110b57cec5SDimitry Andric assert(emission.wasEmittedAsGlobal()); 15120b57cec5SDimitry Andric return emission; 15130b57cec5SDimitry Andric } 15140b57cec5SDimitry Andric 15150b57cec5SDimitry Andric // Otherwise, tell the initialization code that we're in this case. 15160b57cec5SDimitry Andric emission.IsConstantAggregate = true; 15170b57cec5SDimitry Andric } 15180b57cec5SDimitry Andric 15190b57cec5SDimitry Andric // A normal fixed sized variable becomes an alloca in the entry block, 15200b57cec5SDimitry Andric // unless: 15210b57cec5SDimitry Andric // - it's an NRVO variable. 15220b57cec5SDimitry Andric // - we are compiling OpenMP and it's an OpenMP local variable. 15230b57cec5SDimitry Andric if (NRVO) { 15240b57cec5SDimitry Andric // The named return value optimization: allocate this variable in the 15250b57cec5SDimitry Andric // return slot, so that we can elide the copy when returning this 15260b57cec5SDimitry Andric // variable (C++0x [class.copy]p34). 15270b57cec5SDimitry Andric address = ReturnValue; 1528*0fca6ea1SDimitry Andric AllocaAddr = 1529*0fca6ea1SDimitry Andric RawAddress(ReturnValue.emitRawPointer(*this), 1530*0fca6ea1SDimitry Andric ReturnValue.getElementType(), ReturnValue.getAlignment()); 1531*0fca6ea1SDimitry Andric ; 15320b57cec5SDimitry Andric 15330b57cec5SDimitry Andric if (const RecordType *RecordTy = Ty->getAs<RecordType>()) { 15340b57cec5SDimitry Andric const auto *RD = RecordTy->getDecl(); 15350b57cec5SDimitry Andric const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD); 15360b57cec5SDimitry Andric if ((CXXRD && !CXXRD->hasTrivialDestructor()) || 15370b57cec5SDimitry Andric RD->isNonTrivialToPrimitiveDestroy()) { 15380b57cec5SDimitry Andric // Create a flag that is used to indicate when the NRVO was applied 15390b57cec5SDimitry Andric // to this variable. Set it to zero to indicate that NRVO was not 15400b57cec5SDimitry Andric // applied. 15410b57cec5SDimitry Andric llvm::Value *Zero = Builder.getFalse(); 1542*0fca6ea1SDimitry Andric RawAddress NRVOFlag = 15435f757f3fSDimitry Andric CreateTempAlloca(Zero->getType(), CharUnits::One(), "nrvo"); 15440b57cec5SDimitry Andric EnsureInsertPoint(); 15450b57cec5SDimitry Andric Builder.CreateStore(Zero, NRVOFlag); 15460b57cec5SDimitry Andric 15470b57cec5SDimitry Andric // Record the NRVO flag for this variable. 15480b57cec5SDimitry Andric NRVOFlags[&D] = NRVOFlag.getPointer(); 15490b57cec5SDimitry Andric emission.NRVOFlag = NRVOFlag.getPointer(); 15500b57cec5SDimitry Andric } 15510b57cec5SDimitry Andric } 15520b57cec5SDimitry Andric } else { 15530b57cec5SDimitry Andric CharUnits allocaAlignment; 15540b57cec5SDimitry Andric llvm::Type *allocaTy; 15550b57cec5SDimitry Andric if (isEscapingByRef) { 15560b57cec5SDimitry Andric auto &byrefInfo = getBlockByrefInfo(&D); 15570b57cec5SDimitry Andric allocaTy = byrefInfo.Type; 15580b57cec5SDimitry Andric allocaAlignment = byrefInfo.ByrefAlignment; 15590b57cec5SDimitry Andric } else { 15600b57cec5SDimitry Andric allocaTy = ConvertTypeForMem(Ty); 15610b57cec5SDimitry Andric allocaAlignment = alignment; 15620b57cec5SDimitry Andric } 15630b57cec5SDimitry Andric 15640b57cec5SDimitry Andric // Create the alloca. Note that we set the name separately from 15650b57cec5SDimitry Andric // building the instruction so that it's there even in no-asserts 15660b57cec5SDimitry Andric // builds. 15670b57cec5SDimitry Andric address = CreateTempAlloca(allocaTy, allocaAlignment, D.getName(), 15680b57cec5SDimitry Andric /*ArraySize=*/nullptr, &AllocaAddr); 15690b57cec5SDimitry Andric 15700b57cec5SDimitry Andric // Don't emit lifetime markers for MSVC catch parameters. The lifetime of 15710b57cec5SDimitry Andric // the catch parameter starts in the catchpad instruction, and we can't 15720b57cec5SDimitry Andric // insert code in those basic blocks. 15730b57cec5SDimitry Andric bool IsMSCatchParam = 15740b57cec5SDimitry Andric D.isExceptionVariable() && getTarget().getCXXABI().isMicrosoft(); 15750b57cec5SDimitry Andric 15760b57cec5SDimitry Andric // Emit a lifetime intrinsic if meaningful. There's no point in doing this 15770b57cec5SDimitry Andric // if we don't have a valid insertion point (?). 15780b57cec5SDimitry Andric if (HaveInsertPoint() && !IsMSCatchParam) { 15790b57cec5SDimitry Andric // If there's a jump into the lifetime of this variable, its lifetime 15800b57cec5SDimitry Andric // gets broken up into several regions in IR, which requires more work 15810b57cec5SDimitry Andric // to handle correctly. For now, just omit the intrinsics; this is a 15820b57cec5SDimitry Andric // rare case, and it's better to just be conservatively correct. 15830b57cec5SDimitry Andric // PR28267. 15840b57cec5SDimitry Andric // 15850b57cec5SDimitry Andric // We have to do this in all language modes if there's a jump past the 15860b57cec5SDimitry Andric // declaration. We also have to do it in C if there's a jump to an 15870b57cec5SDimitry Andric // earlier point in the current block because non-VLA lifetimes begin as 15880b57cec5SDimitry Andric // soon as the containing block is entered, not when its variables 15890b57cec5SDimitry Andric // actually come into scope; suppressing the lifetime annotations 15900b57cec5SDimitry Andric // completely in this case is unnecessarily pessimistic, but again, this 15910b57cec5SDimitry Andric // is rare. 15920b57cec5SDimitry Andric if (!Bypasses.IsBypassed(&D) && 15930b57cec5SDimitry Andric !(!getLangOpts().CPlusPlus && hasLabelBeenSeenInCurrentScope())) { 1594fe6060f1SDimitry Andric llvm::TypeSize Size = CGM.getDataLayout().getTypeAllocSize(allocaTy); 15950b57cec5SDimitry Andric emission.SizeForLifetimeMarkers = 1596fe6060f1SDimitry Andric EmitLifetimeStart(Size, AllocaAddr.getPointer()); 15970b57cec5SDimitry Andric } 15980b57cec5SDimitry Andric } else { 15990b57cec5SDimitry Andric assert(!emission.useLifetimeMarkers()); 16000b57cec5SDimitry Andric } 16010b57cec5SDimitry Andric } 16020b57cec5SDimitry Andric } else { 16030b57cec5SDimitry Andric EnsureInsertPoint(); 16040b57cec5SDimitry Andric 160506c3fb27SDimitry Andric // Delayed globalization for variable length declarations. This ensures that 160606c3fb27SDimitry Andric // the expression representing the length has been emitted and can be used 160706c3fb27SDimitry Andric // by the definition of the VLA. Since this is an escaped declaration, in 160806c3fb27SDimitry Andric // OpenMP we have to use a call to __kmpc_alloc_shared(). The matching 160906c3fb27SDimitry Andric // deallocation call to __kmpc_free_shared() is emitted later. 161006c3fb27SDimitry Andric bool VarAllocated = false; 161106c3fb27SDimitry Andric if (getLangOpts().OpenMPIsTargetDevice) { 161206c3fb27SDimitry Andric auto &RT = CGM.getOpenMPRuntime(); 161306c3fb27SDimitry Andric if (RT.isDelayedVariableLengthDecl(*this, &D)) { 161406c3fb27SDimitry Andric // Emit call to __kmpc_alloc_shared() instead of the alloca. 161506c3fb27SDimitry Andric std::pair<llvm::Value *, llvm::Value *> AddrSizePair = 161606c3fb27SDimitry Andric RT.getKmpcAllocShared(*this, &D); 161706c3fb27SDimitry Andric 161806c3fb27SDimitry Andric // Save the address of the allocation: 161906c3fb27SDimitry Andric LValue Base = MakeAddrLValue(AddrSizePair.first, D.getType(), 162006c3fb27SDimitry Andric CGM.getContext().getDeclAlign(&D), 162106c3fb27SDimitry Andric AlignmentSource::Decl); 1622*0fca6ea1SDimitry Andric address = Base.getAddress(); 162306c3fb27SDimitry Andric 162406c3fb27SDimitry Andric // Push a cleanup block to emit the call to __kmpc_free_shared in the 162506c3fb27SDimitry Andric // appropriate location at the end of the scope of the 162606c3fb27SDimitry Andric // __kmpc_alloc_shared functions: 162706c3fb27SDimitry Andric pushKmpcAllocFree(NormalCleanup, AddrSizePair); 162806c3fb27SDimitry Andric 162906c3fb27SDimitry Andric // Mark variable as allocated: 163006c3fb27SDimitry Andric VarAllocated = true; 163106c3fb27SDimitry Andric } 163206c3fb27SDimitry Andric } 163306c3fb27SDimitry Andric 163406c3fb27SDimitry Andric if (!VarAllocated) { 16350b57cec5SDimitry Andric if (!DidCallStackSave) { 16360b57cec5SDimitry Andric // Save the stack. 16370b57cec5SDimitry Andric Address Stack = 16385f757f3fSDimitry Andric CreateDefaultAlignTempAlloca(AllocaInt8PtrTy, "saved_stack"); 16390b57cec5SDimitry Andric 16405f757f3fSDimitry Andric llvm::Value *V = Builder.CreateStackSave(); 16415f757f3fSDimitry Andric assert(V->getType() == AllocaInt8PtrTy); 16420b57cec5SDimitry Andric Builder.CreateStore(V, Stack); 16430b57cec5SDimitry Andric 16440b57cec5SDimitry Andric DidCallStackSave = true; 16450b57cec5SDimitry Andric 16460b57cec5SDimitry Andric // Push a cleanup block and restore the stack there. 16470b57cec5SDimitry Andric // FIXME: in general circumstances, this should be an EH cleanup. 16480b57cec5SDimitry Andric pushStackRestore(NormalCleanup, Stack); 16490b57cec5SDimitry Andric } 16500b57cec5SDimitry Andric 16510b57cec5SDimitry Andric auto VlaSize = getVLASize(Ty); 16520b57cec5SDimitry Andric llvm::Type *llvmTy = ConvertTypeForMem(VlaSize.Type); 16530b57cec5SDimitry Andric 16540b57cec5SDimitry Andric // Allocate memory for the array. 16550b57cec5SDimitry Andric address = CreateTempAlloca(llvmTy, alignment, "vla", VlaSize.NumElts, 16560b57cec5SDimitry Andric &AllocaAddr); 165706c3fb27SDimitry Andric } 16580b57cec5SDimitry Andric 16590b57cec5SDimitry Andric // If we have debug info enabled, properly describe the VLA dimensions for 16600b57cec5SDimitry Andric // this type by registering the vla size expression for each of the 16610b57cec5SDimitry Andric // dimensions. 16620b57cec5SDimitry Andric EmitAndRegisterVariableArrayDimensions(DI, D, EmitDebugInfo); 16630b57cec5SDimitry Andric } 16640b57cec5SDimitry Andric 16650b57cec5SDimitry Andric setAddrOfLocalVar(&D, address); 16660b57cec5SDimitry Andric emission.Addr = address; 16670b57cec5SDimitry Andric emission.AllocaAddr = AllocaAddr; 16680b57cec5SDimitry Andric 16690b57cec5SDimitry Andric // Emit debug info for local var declaration. 16700b57cec5SDimitry Andric if (EmitDebugInfo && HaveInsertPoint()) { 16710b57cec5SDimitry Andric Address DebugAddr = address; 16720b57cec5SDimitry Andric bool UsePointerValue = NRVO && ReturnValuePointer.isValid(); 16730b57cec5SDimitry Andric DI->setLocation(D.getLocation()); 16740b57cec5SDimitry Andric 16750b57cec5SDimitry Andric // If NRVO, use a pointer to the return address. 1676349cc55cSDimitry Andric if (UsePointerValue) { 16770b57cec5SDimitry Andric DebugAddr = ReturnValuePointer; 1678349cc55cSDimitry Andric AllocaAddr = ReturnValuePointer; 1679349cc55cSDimitry Andric } 1680349cc55cSDimitry Andric (void)DI->EmitDeclareOfAutoVariable(&D, AllocaAddr.getPointer(), Builder, 16810b57cec5SDimitry Andric UsePointerValue); 16820b57cec5SDimitry Andric } 16830b57cec5SDimitry Andric 16840b57cec5SDimitry Andric if (D.hasAttr<AnnotateAttr>() && HaveInsertPoint()) 1685*0fca6ea1SDimitry Andric EmitVarAnnotations(&D, address.emitRawPointer(*this)); 16860b57cec5SDimitry Andric 16870b57cec5SDimitry Andric // Make sure we call @llvm.lifetime.end. 16880b57cec5SDimitry Andric if (emission.useLifetimeMarkers()) 16890b57cec5SDimitry Andric EHStack.pushCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, 16900b57cec5SDimitry Andric emission.getOriginalAllocatedAddress(), 16910b57cec5SDimitry Andric emission.getSizeForLifetimeMarkers()); 16920b57cec5SDimitry Andric 16930b57cec5SDimitry Andric return emission; 16940b57cec5SDimitry Andric } 16950b57cec5SDimitry Andric 16960b57cec5SDimitry Andric static bool isCapturedBy(const VarDecl &, const Expr *); 16970b57cec5SDimitry Andric 16980b57cec5SDimitry Andric /// Determines whether the given __block variable is potentially 16990b57cec5SDimitry Andric /// captured by the given statement. 17000b57cec5SDimitry Andric static bool isCapturedBy(const VarDecl &Var, const Stmt *S) { 17010b57cec5SDimitry Andric if (const Expr *E = dyn_cast<Expr>(S)) 17020b57cec5SDimitry Andric return isCapturedBy(Var, E); 17030b57cec5SDimitry Andric for (const Stmt *SubStmt : S->children()) 17040b57cec5SDimitry Andric if (isCapturedBy(Var, SubStmt)) 17050b57cec5SDimitry Andric return true; 17060b57cec5SDimitry Andric return false; 17070b57cec5SDimitry Andric } 17080b57cec5SDimitry Andric 17090b57cec5SDimitry Andric /// Determines whether the given __block variable is potentially 17100b57cec5SDimitry Andric /// captured by the given expression. 17110b57cec5SDimitry Andric static bool isCapturedBy(const VarDecl &Var, const Expr *E) { 17120b57cec5SDimitry Andric // Skip the most common kinds of expressions that make 17130b57cec5SDimitry Andric // hierarchy-walking expensive. 17140b57cec5SDimitry Andric E = E->IgnoreParenCasts(); 17150b57cec5SDimitry Andric 17160b57cec5SDimitry Andric if (const BlockExpr *BE = dyn_cast<BlockExpr>(E)) { 17170b57cec5SDimitry Andric const BlockDecl *Block = BE->getBlockDecl(); 17180b57cec5SDimitry Andric for (const auto &I : Block->captures()) { 17190b57cec5SDimitry Andric if (I.getVariable() == &Var) 17200b57cec5SDimitry Andric return true; 17210b57cec5SDimitry Andric } 17220b57cec5SDimitry Andric 17230b57cec5SDimitry Andric // No need to walk into the subexpressions. 17240b57cec5SDimitry Andric return false; 17250b57cec5SDimitry Andric } 17260b57cec5SDimitry Andric 17270b57cec5SDimitry Andric if (const StmtExpr *SE = dyn_cast<StmtExpr>(E)) { 17280b57cec5SDimitry Andric const CompoundStmt *CS = SE->getSubStmt(); 17290b57cec5SDimitry Andric for (const auto *BI : CS->body()) 17300b57cec5SDimitry Andric if (const auto *BIE = dyn_cast<Expr>(BI)) { 17310b57cec5SDimitry Andric if (isCapturedBy(Var, BIE)) 17320b57cec5SDimitry Andric return true; 17330b57cec5SDimitry Andric } 17340b57cec5SDimitry Andric else if (const auto *DS = dyn_cast<DeclStmt>(BI)) { 17350b57cec5SDimitry Andric // special case declarations 17360b57cec5SDimitry Andric for (const auto *I : DS->decls()) { 17370b57cec5SDimitry Andric if (const auto *VD = dyn_cast<VarDecl>((I))) { 17380b57cec5SDimitry Andric const Expr *Init = VD->getInit(); 17390b57cec5SDimitry Andric if (Init && isCapturedBy(Var, Init)) 17400b57cec5SDimitry Andric return true; 17410b57cec5SDimitry Andric } 17420b57cec5SDimitry Andric } 17430b57cec5SDimitry Andric } 17440b57cec5SDimitry Andric else 17450b57cec5SDimitry Andric // FIXME. Make safe assumption assuming arbitrary statements cause capturing. 17460b57cec5SDimitry Andric // Later, provide code to poke into statements for capture analysis. 17470b57cec5SDimitry Andric return true; 17480b57cec5SDimitry Andric return false; 17490b57cec5SDimitry Andric } 17500b57cec5SDimitry Andric 17510b57cec5SDimitry Andric for (const Stmt *SubStmt : E->children()) 17520b57cec5SDimitry Andric if (isCapturedBy(Var, SubStmt)) 17530b57cec5SDimitry Andric return true; 17540b57cec5SDimitry Andric 17550b57cec5SDimitry Andric return false; 17560b57cec5SDimitry Andric } 17570b57cec5SDimitry Andric 17580b57cec5SDimitry Andric /// Determine whether the given initializer is trivial in the sense 17590b57cec5SDimitry Andric /// that it requires no code to be generated. 17600b57cec5SDimitry Andric bool CodeGenFunction::isTrivialInitializer(const Expr *Init) { 17610b57cec5SDimitry Andric if (!Init) 17620b57cec5SDimitry Andric return true; 17630b57cec5SDimitry Andric 17640b57cec5SDimitry Andric if (const CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init)) 17650b57cec5SDimitry Andric if (CXXConstructorDecl *Constructor = Construct->getConstructor()) 17660b57cec5SDimitry Andric if (Constructor->isTrivial() && 17670b57cec5SDimitry Andric Constructor->isDefaultConstructor() && 17680b57cec5SDimitry Andric !Construct->requiresZeroInitialization()) 17690b57cec5SDimitry Andric return true; 17700b57cec5SDimitry Andric 17710b57cec5SDimitry Andric return false; 17720b57cec5SDimitry Andric } 17730b57cec5SDimitry Andric 17740b57cec5SDimitry Andric void CodeGenFunction::emitZeroOrPatternForAutoVarInit(QualType type, 17750b57cec5SDimitry Andric const VarDecl &D, 17760b57cec5SDimitry Andric Address Loc) { 17770b57cec5SDimitry Andric auto trivialAutoVarInit = getContext().getLangOpts().getTrivialAutoVarInit(); 17787a6dacacSDimitry Andric auto trivialAutoVarInitMaxSize = 17797a6dacacSDimitry Andric getContext().getLangOpts().TrivialAutoVarInitMaxSize; 17800b57cec5SDimitry Andric CharUnits Size = getContext().getTypeSizeInChars(type); 17810b57cec5SDimitry Andric bool isVolatile = type.isVolatileQualified(); 17820b57cec5SDimitry Andric if (!Size.isZero()) { 17837a6dacacSDimitry Andric // We skip auto-init variables by their alloc size. Take this as an example: 17847a6dacacSDimitry Andric // "struct Foo {int x; char buff[1024];}" Assume the max-size flag is 1023. 17857a6dacacSDimitry Andric // All Foo type variables will be skipped. Ideally, we only skip the buff 17867a6dacacSDimitry Andric // array and still auto-init X in this example. 17877a6dacacSDimitry Andric // TODO: Improve the size filtering to by member size. 17887a6dacacSDimitry Andric auto allocSize = CGM.getDataLayout().getTypeAllocSize(Loc.getElementType()); 17890b57cec5SDimitry Andric switch (trivialAutoVarInit) { 17900b57cec5SDimitry Andric case LangOptions::TrivialAutoVarInitKind::Uninitialized: 17910b57cec5SDimitry Andric llvm_unreachable("Uninitialized handled by caller"); 17920b57cec5SDimitry Andric case LangOptions::TrivialAutoVarInitKind::Zero: 17935ffd83dbSDimitry Andric if (CGM.stopAutoInit()) 17945ffd83dbSDimitry Andric return; 17957a6dacacSDimitry Andric if (trivialAutoVarInitMaxSize > 0 && 17967a6dacacSDimitry Andric allocSize > trivialAutoVarInitMaxSize) 17977a6dacacSDimitry Andric return; 17980b57cec5SDimitry Andric emitStoresForZeroInit(CGM, D, Loc, isVolatile, Builder); 17990b57cec5SDimitry Andric break; 18000b57cec5SDimitry Andric case LangOptions::TrivialAutoVarInitKind::Pattern: 18015ffd83dbSDimitry Andric if (CGM.stopAutoInit()) 18025ffd83dbSDimitry Andric return; 18037a6dacacSDimitry Andric if (trivialAutoVarInitMaxSize > 0 && 18047a6dacacSDimitry Andric allocSize > trivialAutoVarInitMaxSize) 18057a6dacacSDimitry Andric return; 18060b57cec5SDimitry Andric emitStoresForPatternInit(CGM, D, Loc, isVolatile, Builder); 18070b57cec5SDimitry Andric break; 18080b57cec5SDimitry Andric } 18090b57cec5SDimitry Andric return; 18100b57cec5SDimitry Andric } 18110b57cec5SDimitry Andric 18120b57cec5SDimitry Andric // VLAs look zero-sized to getTypeInfo. We can't emit constant stores to 18130b57cec5SDimitry Andric // them, so emit a memcpy with the VLA size to initialize each element. 18140b57cec5SDimitry Andric // Technically zero-sized or negative-sized VLAs are undefined, and UBSan 18150b57cec5SDimitry Andric // will catch that code, but there exists code which generates zero-sized 18160b57cec5SDimitry Andric // VLAs. Be nice and initialize whatever they requested. 18170b57cec5SDimitry Andric const auto *VlaType = getContext().getAsVariableArrayType(type); 18180b57cec5SDimitry Andric if (!VlaType) 18190b57cec5SDimitry Andric return; 18200b57cec5SDimitry Andric auto VlaSize = getVLASize(VlaType); 18210b57cec5SDimitry Andric auto SizeVal = VlaSize.NumElts; 18220b57cec5SDimitry Andric CharUnits EltSize = getContext().getTypeSizeInChars(VlaSize.Type); 18230b57cec5SDimitry Andric switch (trivialAutoVarInit) { 18240b57cec5SDimitry Andric case LangOptions::TrivialAutoVarInitKind::Uninitialized: 18250b57cec5SDimitry Andric llvm_unreachable("Uninitialized handled by caller"); 18260b57cec5SDimitry Andric 1827e8d8bef9SDimitry Andric case LangOptions::TrivialAutoVarInitKind::Zero: { 18285ffd83dbSDimitry Andric if (CGM.stopAutoInit()) 18295ffd83dbSDimitry Andric return; 18300b57cec5SDimitry Andric if (!EltSize.isOne()) 18310b57cec5SDimitry Andric SizeVal = Builder.CreateNUWMul(SizeVal, CGM.getSize(EltSize)); 1832e8d8bef9SDimitry Andric auto *I = Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, 0), 1833e8d8bef9SDimitry Andric SizeVal, isVolatile); 1834e8d8bef9SDimitry Andric I->addAnnotationMetadata("auto-init"); 18350b57cec5SDimitry Andric break; 1836e8d8bef9SDimitry Andric } 18370b57cec5SDimitry Andric 18380b57cec5SDimitry Andric case LangOptions::TrivialAutoVarInitKind::Pattern: { 18395ffd83dbSDimitry Andric if (CGM.stopAutoInit()) 18405ffd83dbSDimitry Andric return; 18410b57cec5SDimitry Andric llvm::Type *ElTy = Loc.getElementType(); 18420b57cec5SDimitry Andric llvm::Constant *Constant = constWithPadding( 18430b57cec5SDimitry Andric CGM, IsPattern::Yes, initializationPatternFor(CGM, ElTy)); 18440b57cec5SDimitry Andric CharUnits ConstantAlign = getContext().getTypeAlignInChars(VlaSize.Type); 18450b57cec5SDimitry Andric llvm::BasicBlock *SetupBB = createBasicBlock("vla-setup.loop"); 18460b57cec5SDimitry Andric llvm::BasicBlock *LoopBB = createBasicBlock("vla-init.loop"); 18470b57cec5SDimitry Andric llvm::BasicBlock *ContBB = createBasicBlock("vla-init.cont"); 18480b57cec5SDimitry Andric llvm::Value *IsZeroSizedVLA = Builder.CreateICmpEQ( 18490b57cec5SDimitry Andric SizeVal, llvm::ConstantInt::get(SizeVal->getType(), 0), 18500b57cec5SDimitry Andric "vla.iszerosized"); 18510b57cec5SDimitry Andric Builder.CreateCondBr(IsZeroSizedVLA, ContBB, SetupBB); 18520b57cec5SDimitry Andric EmitBlock(SetupBB); 18530b57cec5SDimitry Andric if (!EltSize.isOne()) 18540b57cec5SDimitry Andric SizeVal = Builder.CreateNUWMul(SizeVal, CGM.getSize(EltSize)); 18550b57cec5SDimitry Andric llvm::Value *BaseSizeInChars = 18560b57cec5SDimitry Andric llvm::ConstantInt::get(IntPtrTy, EltSize.getQuantity()); 185706c3fb27SDimitry Andric Address Begin = Loc.withElementType(Int8Ty); 1858*0fca6ea1SDimitry Andric llvm::Value *End = Builder.CreateInBoundsGEP(Begin.getElementType(), 1859*0fca6ea1SDimitry Andric Begin.emitRawPointer(*this), 1860*0fca6ea1SDimitry Andric SizeVal, "vla.end"); 18610b57cec5SDimitry Andric llvm::BasicBlock *OriginBB = Builder.GetInsertBlock(); 18620b57cec5SDimitry Andric EmitBlock(LoopBB); 18630b57cec5SDimitry Andric llvm::PHINode *Cur = Builder.CreatePHI(Begin.getType(), 2, "vla.cur"); 1864*0fca6ea1SDimitry Andric Cur->addIncoming(Begin.emitRawPointer(*this), OriginBB); 18650b57cec5SDimitry Andric CharUnits CurAlign = Loc.getAlignment().alignmentOfArrayElement(EltSize); 1866e8d8bef9SDimitry Andric auto *I = 186781ad6265SDimitry Andric Builder.CreateMemCpy(Address(Cur, Int8Ty, CurAlign), 18680b57cec5SDimitry Andric createUnnamedGlobalForMemcpyFrom( 18690b57cec5SDimitry Andric CGM, D, Builder, Constant, ConstantAlign), 18700b57cec5SDimitry Andric BaseSizeInChars, isVolatile); 1871e8d8bef9SDimitry Andric I->addAnnotationMetadata("auto-init"); 18720b57cec5SDimitry Andric llvm::Value *Next = 18730b57cec5SDimitry Andric Builder.CreateInBoundsGEP(Int8Ty, Cur, BaseSizeInChars, "vla.next"); 18740b57cec5SDimitry Andric llvm::Value *Done = Builder.CreateICmpEQ(Next, End, "vla-init.isdone"); 18750b57cec5SDimitry Andric Builder.CreateCondBr(Done, ContBB, LoopBB); 18760b57cec5SDimitry Andric Cur->addIncoming(Next, LoopBB); 18770b57cec5SDimitry Andric EmitBlock(ContBB); 18780b57cec5SDimitry Andric } break; 18790b57cec5SDimitry Andric } 18800b57cec5SDimitry Andric } 18810b57cec5SDimitry Andric 18820b57cec5SDimitry Andric void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { 18830b57cec5SDimitry Andric assert(emission.Variable && "emission was not valid!"); 18840b57cec5SDimitry Andric 18850b57cec5SDimitry Andric // If this was emitted as a global constant, we're done. 18860b57cec5SDimitry Andric if (emission.wasEmittedAsGlobal()) return; 18870b57cec5SDimitry Andric 18880b57cec5SDimitry Andric const VarDecl &D = *emission.Variable; 18890b57cec5SDimitry Andric auto DL = ApplyDebugLocation::CreateDefaultArtificial(*this, D.getLocation()); 18900b57cec5SDimitry Andric QualType type = D.getType(); 18910b57cec5SDimitry Andric 18920b57cec5SDimitry Andric // If this local has an initializer, emit it now. 18930b57cec5SDimitry Andric const Expr *Init = D.getInit(); 18940b57cec5SDimitry Andric 18950b57cec5SDimitry Andric // If we are at an unreachable point, we don't need to emit the initializer 18960b57cec5SDimitry Andric // unless it contains a label. 18970b57cec5SDimitry Andric if (!HaveInsertPoint()) { 18980b57cec5SDimitry Andric if (!Init || !ContainsLabel(Init)) return; 18990b57cec5SDimitry Andric EnsureInsertPoint(); 19000b57cec5SDimitry Andric } 19010b57cec5SDimitry Andric 19020b57cec5SDimitry Andric // Initialize the structure of a __block variable. 19030b57cec5SDimitry Andric if (emission.IsEscapingByRef) 19040b57cec5SDimitry Andric emitByrefStructureInit(emission); 19050b57cec5SDimitry Andric 19060b57cec5SDimitry Andric // Initialize the variable here if it doesn't have a initializer and it is a 19070b57cec5SDimitry Andric // C struct that is non-trivial to initialize or an array containing such a 19080b57cec5SDimitry Andric // struct. 19090b57cec5SDimitry Andric if (!Init && 19100b57cec5SDimitry Andric type.isNonTrivialToPrimitiveDefaultInitialize() == 19110b57cec5SDimitry Andric QualType::PDIK_Struct) { 19120b57cec5SDimitry Andric LValue Dst = MakeAddrLValue(emission.getAllocatedAddress(), type); 19130b57cec5SDimitry Andric if (emission.IsEscapingByRef) 19140b57cec5SDimitry Andric drillIntoBlockVariable(*this, Dst, &D); 19150b57cec5SDimitry Andric defaultInitNonTrivialCStructVar(Dst); 19160b57cec5SDimitry Andric return; 19170b57cec5SDimitry Andric } 19180b57cec5SDimitry Andric 19190b57cec5SDimitry Andric // Check whether this is a byref variable that's potentially 19200b57cec5SDimitry Andric // captured and moved by its own initializer. If so, we'll need to 19210b57cec5SDimitry Andric // emit the initializer first, then copy into the variable. 19220b57cec5SDimitry Andric bool capturedByInit = 19230b57cec5SDimitry Andric Init && emission.IsEscapingByRef && isCapturedBy(D, Init); 19240b57cec5SDimitry Andric 19250b57cec5SDimitry Andric bool locIsByrefHeader = !capturedByInit; 19260b57cec5SDimitry Andric const Address Loc = 19270b57cec5SDimitry Andric locIsByrefHeader ? emission.getObjectAddress(*this) : emission.Addr; 19280b57cec5SDimitry Andric 19290b57cec5SDimitry Andric // Note: constexpr already initializes everything correctly. 19300b57cec5SDimitry Andric LangOptions::TrivialAutoVarInitKind trivialAutoVarInit = 19310b57cec5SDimitry Andric (D.isConstexpr() 19320b57cec5SDimitry Andric ? LangOptions::TrivialAutoVarInitKind::Uninitialized 19330b57cec5SDimitry Andric : (D.getAttr<UninitializedAttr>() 19340b57cec5SDimitry Andric ? LangOptions::TrivialAutoVarInitKind::Uninitialized 19350b57cec5SDimitry Andric : getContext().getLangOpts().getTrivialAutoVarInit())); 19360b57cec5SDimitry Andric 19370b57cec5SDimitry Andric auto initializeWhatIsTechnicallyUninitialized = [&](Address Loc) { 19380b57cec5SDimitry Andric if (trivialAutoVarInit == 19390b57cec5SDimitry Andric LangOptions::TrivialAutoVarInitKind::Uninitialized) 19400b57cec5SDimitry Andric return; 19410b57cec5SDimitry Andric 19420b57cec5SDimitry Andric // Only initialize a __block's storage: we always initialize the header. 19430b57cec5SDimitry Andric if (emission.IsEscapingByRef && !locIsByrefHeader) 19440b57cec5SDimitry Andric Loc = emitBlockByrefAddress(Loc, &D, /*follow=*/false); 19450b57cec5SDimitry Andric 19460b57cec5SDimitry Andric return emitZeroOrPatternForAutoVarInit(type, D, Loc); 19470b57cec5SDimitry Andric }; 19480b57cec5SDimitry Andric 19490b57cec5SDimitry Andric if (isTrivialInitializer(Init)) 19500b57cec5SDimitry Andric return initializeWhatIsTechnicallyUninitialized(Loc); 19510b57cec5SDimitry Andric 19520b57cec5SDimitry Andric llvm::Constant *constant = nullptr; 19530b57cec5SDimitry Andric if (emission.IsConstantAggregate || 19540b57cec5SDimitry Andric D.mightBeUsableInConstantExpressions(getContext())) { 19550b57cec5SDimitry Andric assert(!capturedByInit && "constant init contains a capturing block?"); 19560b57cec5SDimitry Andric constant = ConstantEmitter(*this).tryEmitAbstractForInitializer(D); 19570b57cec5SDimitry Andric if (constant && !constant->isZeroValue() && 19580b57cec5SDimitry Andric (trivialAutoVarInit != 19590b57cec5SDimitry Andric LangOptions::TrivialAutoVarInitKind::Uninitialized)) { 19600b57cec5SDimitry Andric IsPattern isPattern = 19610b57cec5SDimitry Andric (trivialAutoVarInit == LangOptions::TrivialAutoVarInitKind::Pattern) 19620b57cec5SDimitry Andric ? IsPattern::Yes 19630b57cec5SDimitry Andric : IsPattern::No; 19640b57cec5SDimitry Andric // C guarantees that brace-init with fewer initializers than members in 19650b57cec5SDimitry Andric // the aggregate will initialize the rest of the aggregate as-if it were 19660b57cec5SDimitry Andric // static initialization. In turn static initialization guarantees that 19670b57cec5SDimitry Andric // padding is initialized to zero bits. We could instead pattern-init if D 19680b57cec5SDimitry Andric // has any ImplicitValueInitExpr, but that seems to be unintuitive 19690b57cec5SDimitry Andric // behavior. 19700b57cec5SDimitry Andric constant = constWithPadding(CGM, IsPattern::No, 19710b57cec5SDimitry Andric replaceUndef(CGM, isPattern, constant)); 19720b57cec5SDimitry Andric } 1973*0fca6ea1SDimitry Andric 1974*0fca6ea1SDimitry Andric if (D.getType()->isBitIntType() && 1975*0fca6ea1SDimitry Andric CGM.getTypes().typeRequiresSplitIntoByteArray(D.getType())) { 1976*0fca6ea1SDimitry Andric // Constants for long _BitInt types are split into individual bytes. 1977*0fca6ea1SDimitry Andric // Try to fold these back into an integer constant so it can be stored 1978*0fca6ea1SDimitry Andric // properly. 1979*0fca6ea1SDimitry Andric llvm::Type *LoadType = CGM.getTypes().convertTypeForLoadStore( 1980*0fca6ea1SDimitry Andric D.getType(), constant->getType()); 1981*0fca6ea1SDimitry Andric constant = llvm::ConstantFoldLoadFromConst( 1982*0fca6ea1SDimitry Andric constant, LoadType, llvm::APInt::getZero(32), CGM.getDataLayout()); 1983*0fca6ea1SDimitry Andric } 19840b57cec5SDimitry Andric } 19850b57cec5SDimitry Andric 19860b57cec5SDimitry Andric if (!constant) { 1987*0fca6ea1SDimitry Andric if (trivialAutoVarInit != 1988*0fca6ea1SDimitry Andric LangOptions::TrivialAutoVarInitKind::Uninitialized) { 1989*0fca6ea1SDimitry Andric // At this point, we know D has an Init expression, but isn't a constant. 1990*0fca6ea1SDimitry Andric // - If D is not a scalar, auto-var-init conservatively (members may be 1991*0fca6ea1SDimitry Andric // left uninitialized by constructor Init expressions for example). 1992*0fca6ea1SDimitry Andric // - If D is a scalar, we only need to auto-var-init if there is a 1993*0fca6ea1SDimitry Andric // self-reference. Otherwise, the Init expression should be sufficient. 1994*0fca6ea1SDimitry Andric // It may be that the Init expression uses other uninitialized memory, 1995*0fca6ea1SDimitry Andric // but auto-var-init here would not help, as auto-init would get 1996*0fca6ea1SDimitry Andric // overwritten by Init. 1997*0fca6ea1SDimitry Andric if (!D.getType()->isScalarType() || capturedByInit || 1998*0fca6ea1SDimitry Andric isAccessedBy(D, Init)) { 19990b57cec5SDimitry Andric initializeWhatIsTechnicallyUninitialized(Loc); 2000*0fca6ea1SDimitry Andric } 2001*0fca6ea1SDimitry Andric } 20020b57cec5SDimitry Andric LValue lv = MakeAddrLValue(Loc, type); 20030b57cec5SDimitry Andric lv.setNonGC(true); 20040b57cec5SDimitry Andric return EmitExprAsInit(Init, &D, lv, capturedByInit); 20050b57cec5SDimitry Andric } 20060b57cec5SDimitry Andric 20070b57cec5SDimitry Andric if (!emission.IsConstantAggregate) { 20080b57cec5SDimitry Andric // For simple scalar/complex initialization, store the value directly. 20090b57cec5SDimitry Andric LValue lv = MakeAddrLValue(Loc, type); 20100b57cec5SDimitry Andric lv.setNonGC(true); 20110b57cec5SDimitry Andric return EmitStoreThroughLValue(RValue::get(constant), lv, true); 20120b57cec5SDimitry Andric } 20130b57cec5SDimitry Andric 201406c3fb27SDimitry Andric emitStoresForConstant(CGM, D, Loc.withElementType(CGM.Int8Ty), 201581ad6265SDimitry Andric type.isVolatileQualified(), Builder, constant, 201681ad6265SDimitry Andric /*IsAutoInit=*/false); 20170b57cec5SDimitry Andric } 20180b57cec5SDimitry Andric 20190b57cec5SDimitry Andric /// Emit an expression as an initializer for an object (variable, field, etc.) 20200b57cec5SDimitry Andric /// at the given location. The expression is not necessarily the normal 20210b57cec5SDimitry Andric /// initializer for the object, and the address is not necessarily 20220b57cec5SDimitry Andric /// its normal location. 20230b57cec5SDimitry Andric /// 20240b57cec5SDimitry Andric /// \param init the initializing expression 20250b57cec5SDimitry Andric /// \param D the object to act as if we're initializing 20265ffd83dbSDimitry Andric /// \param lvalue the lvalue to initialize 20270b57cec5SDimitry Andric /// \param capturedByInit true if \p D is a __block variable 20280b57cec5SDimitry Andric /// whose address is potentially changed by the initializer 20290b57cec5SDimitry Andric void CodeGenFunction::EmitExprAsInit(const Expr *init, const ValueDecl *D, 20300b57cec5SDimitry Andric LValue lvalue, bool capturedByInit) { 20310b57cec5SDimitry Andric QualType type = D->getType(); 20320b57cec5SDimitry Andric 20330b57cec5SDimitry Andric if (type->isReferenceType()) { 20340b57cec5SDimitry Andric RValue rvalue = EmitReferenceBindingToExpr(init); 20350b57cec5SDimitry Andric if (capturedByInit) 20360b57cec5SDimitry Andric drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D)); 20370b57cec5SDimitry Andric EmitStoreThroughLValue(rvalue, lvalue, true); 20380b57cec5SDimitry Andric return; 20390b57cec5SDimitry Andric } 20400b57cec5SDimitry Andric switch (getEvaluationKind(type)) { 20410b57cec5SDimitry Andric case TEK_Scalar: 20420b57cec5SDimitry Andric EmitScalarInit(init, D, lvalue, capturedByInit); 20430b57cec5SDimitry Andric return; 20440b57cec5SDimitry Andric case TEK_Complex: { 20450b57cec5SDimitry Andric ComplexPairTy complex = EmitComplexExpr(init); 20460b57cec5SDimitry Andric if (capturedByInit) 20470b57cec5SDimitry Andric drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D)); 20480b57cec5SDimitry Andric EmitStoreOfComplex(complex, lvalue, /*init*/ true); 20490b57cec5SDimitry Andric return; 20500b57cec5SDimitry Andric } 20510b57cec5SDimitry Andric case TEK_Aggregate: 20520b57cec5SDimitry Andric if (type->isAtomicType()) { 20530b57cec5SDimitry Andric EmitAtomicInit(const_cast<Expr*>(init), lvalue); 20540b57cec5SDimitry Andric } else { 20550b57cec5SDimitry Andric AggValueSlot::Overlap_t Overlap = AggValueSlot::MayOverlap; 20560b57cec5SDimitry Andric if (isa<VarDecl>(D)) 20570b57cec5SDimitry Andric Overlap = AggValueSlot::DoesNotOverlap; 20580b57cec5SDimitry Andric else if (auto *FD = dyn_cast<FieldDecl>(D)) 20590b57cec5SDimitry Andric Overlap = getOverlapForFieldInit(FD); 20600b57cec5SDimitry Andric // TODO: how can we delay here if D is captured by its initializer? 2061*0fca6ea1SDimitry Andric EmitAggExpr(init, 2062*0fca6ea1SDimitry Andric AggValueSlot::forLValue(lvalue, AggValueSlot::IsDestructed, 20630b57cec5SDimitry Andric AggValueSlot::DoesNotNeedGCBarriers, 2064480093f4SDimitry Andric AggValueSlot::IsNotAliased, Overlap)); 20650b57cec5SDimitry Andric } 20660b57cec5SDimitry Andric return; 20670b57cec5SDimitry Andric } 20680b57cec5SDimitry Andric llvm_unreachable("bad evaluation kind"); 20690b57cec5SDimitry Andric } 20700b57cec5SDimitry Andric 20710b57cec5SDimitry Andric /// Enter a destroy cleanup for the given local variable. 20720b57cec5SDimitry Andric void CodeGenFunction::emitAutoVarTypeCleanup( 20730b57cec5SDimitry Andric const CodeGenFunction::AutoVarEmission &emission, 20740b57cec5SDimitry Andric QualType::DestructionKind dtorKind) { 20750b57cec5SDimitry Andric assert(dtorKind != QualType::DK_none); 20760b57cec5SDimitry Andric 20770b57cec5SDimitry Andric // Note that for __block variables, we want to destroy the 20780b57cec5SDimitry Andric // original stack object, not the possibly forwarded object. 20790b57cec5SDimitry Andric Address addr = emission.getObjectAddress(*this); 20800b57cec5SDimitry Andric 20810b57cec5SDimitry Andric const VarDecl *var = emission.Variable; 20820b57cec5SDimitry Andric QualType type = var->getType(); 20830b57cec5SDimitry Andric 20840b57cec5SDimitry Andric CleanupKind cleanupKind = NormalAndEHCleanup; 20850b57cec5SDimitry Andric CodeGenFunction::Destroyer *destroyer = nullptr; 20860b57cec5SDimitry Andric 20870b57cec5SDimitry Andric switch (dtorKind) { 20880b57cec5SDimitry Andric case QualType::DK_none: 20890b57cec5SDimitry Andric llvm_unreachable("no cleanup for trivially-destructible variable"); 20900b57cec5SDimitry Andric 20910b57cec5SDimitry Andric case QualType::DK_cxx_destructor: 20920b57cec5SDimitry Andric // If there's an NRVO flag on the emission, we need a different 20930b57cec5SDimitry Andric // cleanup. 20940b57cec5SDimitry Andric if (emission.NRVOFlag) { 20950b57cec5SDimitry Andric assert(!type->isArrayType()); 20960b57cec5SDimitry Andric CXXDestructorDecl *dtor = type->getAsCXXRecordDecl()->getDestructor(); 20970b57cec5SDimitry Andric EHStack.pushCleanup<DestroyNRVOVariableCXX>(cleanupKind, addr, type, dtor, 20980b57cec5SDimitry Andric emission.NRVOFlag); 20990b57cec5SDimitry Andric return; 21000b57cec5SDimitry Andric } 21010b57cec5SDimitry Andric break; 21020b57cec5SDimitry Andric 21030b57cec5SDimitry Andric case QualType::DK_objc_strong_lifetime: 21040b57cec5SDimitry Andric // Suppress cleanups for pseudo-strong variables. 21050b57cec5SDimitry Andric if (var->isARCPseudoStrong()) return; 21060b57cec5SDimitry Andric 21070b57cec5SDimitry Andric // Otherwise, consider whether to use an EH cleanup or not. 21080b57cec5SDimitry Andric cleanupKind = getARCCleanupKind(); 21090b57cec5SDimitry Andric 21100b57cec5SDimitry Andric // Use the imprecise destroyer by default. 21110b57cec5SDimitry Andric if (!var->hasAttr<ObjCPreciseLifetimeAttr>()) 21120b57cec5SDimitry Andric destroyer = CodeGenFunction::destroyARCStrongImprecise; 21130b57cec5SDimitry Andric break; 21140b57cec5SDimitry Andric 21150b57cec5SDimitry Andric case QualType::DK_objc_weak_lifetime: 21160b57cec5SDimitry Andric break; 21170b57cec5SDimitry Andric 21180b57cec5SDimitry Andric case QualType::DK_nontrivial_c_struct: 21190b57cec5SDimitry Andric destroyer = CodeGenFunction::destroyNonTrivialCStruct; 21200b57cec5SDimitry Andric if (emission.NRVOFlag) { 21210b57cec5SDimitry Andric assert(!type->isArrayType()); 21220b57cec5SDimitry Andric EHStack.pushCleanup<DestroyNRVOVariableC>(cleanupKind, addr, 21230b57cec5SDimitry Andric emission.NRVOFlag, type); 21240b57cec5SDimitry Andric return; 21250b57cec5SDimitry Andric } 21260b57cec5SDimitry Andric break; 21270b57cec5SDimitry Andric } 21280b57cec5SDimitry Andric 21290b57cec5SDimitry Andric // If we haven't chosen a more specific destroyer, use the default. 21300b57cec5SDimitry Andric if (!destroyer) destroyer = getDestroyer(dtorKind); 21310b57cec5SDimitry Andric 21320b57cec5SDimitry Andric // Use an EH cleanup in array destructors iff the destructor itself 21330b57cec5SDimitry Andric // is being pushed as an EH cleanup. 21340b57cec5SDimitry Andric bool useEHCleanup = (cleanupKind & EHCleanup); 21350b57cec5SDimitry Andric EHStack.pushCleanup<DestroyObject>(cleanupKind, addr, type, destroyer, 21360b57cec5SDimitry Andric useEHCleanup); 21370b57cec5SDimitry Andric } 21380b57cec5SDimitry Andric 21390b57cec5SDimitry Andric void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) { 21400b57cec5SDimitry Andric assert(emission.Variable && "emission was not valid!"); 21410b57cec5SDimitry Andric 21420b57cec5SDimitry Andric // If this was emitted as a global constant, we're done. 21430b57cec5SDimitry Andric if (emission.wasEmittedAsGlobal()) return; 21440b57cec5SDimitry Andric 21450b57cec5SDimitry Andric // If we don't have an insertion point, we're done. Sema prevents 21460b57cec5SDimitry Andric // us from jumping into any of these scopes anyway. 21470b57cec5SDimitry Andric if (!HaveInsertPoint()) return; 21480b57cec5SDimitry Andric 21490b57cec5SDimitry Andric const VarDecl &D = *emission.Variable; 21500b57cec5SDimitry Andric 21510b57cec5SDimitry Andric // Check the type for a cleanup. 2152a7dea167SDimitry Andric if (QualType::DestructionKind dtorKind = D.needsDestruction(getContext())) 21530b57cec5SDimitry Andric emitAutoVarTypeCleanup(emission, dtorKind); 21540b57cec5SDimitry Andric 21550b57cec5SDimitry Andric // In GC mode, honor objc_precise_lifetime. 21560b57cec5SDimitry Andric if (getLangOpts().getGC() != LangOptions::NonGC && 21570b57cec5SDimitry Andric D.hasAttr<ObjCPreciseLifetimeAttr>()) { 21580b57cec5SDimitry Andric EHStack.pushCleanup<ExtendGCLifetime>(NormalCleanup, &D); 21590b57cec5SDimitry Andric } 21600b57cec5SDimitry Andric 21610b57cec5SDimitry Andric // Handle the cleanup attribute. 21620b57cec5SDimitry Andric if (const CleanupAttr *CA = D.getAttr<CleanupAttr>()) { 21630b57cec5SDimitry Andric const FunctionDecl *FD = CA->getFunctionDecl(); 21640b57cec5SDimitry Andric 21650b57cec5SDimitry Andric llvm::Constant *F = CGM.GetAddrOfFunction(FD); 21660b57cec5SDimitry Andric assert(F && "Could not find function!"); 21670b57cec5SDimitry Andric 21680b57cec5SDimitry Andric const CGFunctionInfo &Info = CGM.getTypes().arrangeFunctionDeclaration(FD); 21690b57cec5SDimitry Andric EHStack.pushCleanup<CallCleanupFunction>(NormalAndEHCleanup, F, &Info, &D); 21700b57cec5SDimitry Andric } 21710b57cec5SDimitry Andric 21720b57cec5SDimitry Andric // If this is a block variable, call _Block_object_destroy 21730b57cec5SDimitry Andric // (on the unforwarded address). Don't enter this cleanup if we're in pure-GC 21740b57cec5SDimitry Andric // mode. 21750b57cec5SDimitry Andric if (emission.IsEscapingByRef && 21760b57cec5SDimitry Andric CGM.getLangOpts().getGC() != LangOptions::GCOnly) { 21770b57cec5SDimitry Andric BlockFieldFlags Flags = BLOCK_FIELD_IS_BYREF; 21780b57cec5SDimitry Andric if (emission.Variable->getType().isObjCGCWeak()) 21790b57cec5SDimitry Andric Flags |= BLOCK_FIELD_IS_WEAK; 21800b57cec5SDimitry Andric enterByrefCleanup(NormalAndEHCleanup, emission.Addr, Flags, 21810b57cec5SDimitry Andric /*LoadBlockVarAddr*/ false, 21820b57cec5SDimitry Andric cxxDestructorCanThrow(emission.Variable->getType())); 21830b57cec5SDimitry Andric } 21840b57cec5SDimitry Andric } 21850b57cec5SDimitry Andric 21860b57cec5SDimitry Andric CodeGenFunction::Destroyer * 21870b57cec5SDimitry Andric CodeGenFunction::getDestroyer(QualType::DestructionKind kind) { 21880b57cec5SDimitry Andric switch (kind) { 21890b57cec5SDimitry Andric case QualType::DK_none: llvm_unreachable("no destroyer for trivial dtor"); 21900b57cec5SDimitry Andric case QualType::DK_cxx_destructor: 21910b57cec5SDimitry Andric return destroyCXXObject; 21920b57cec5SDimitry Andric case QualType::DK_objc_strong_lifetime: 21930b57cec5SDimitry Andric return destroyARCStrongPrecise; 21940b57cec5SDimitry Andric case QualType::DK_objc_weak_lifetime: 21950b57cec5SDimitry Andric return destroyARCWeak; 21960b57cec5SDimitry Andric case QualType::DK_nontrivial_c_struct: 21970b57cec5SDimitry Andric return destroyNonTrivialCStruct; 21980b57cec5SDimitry Andric } 21990b57cec5SDimitry Andric llvm_unreachable("Unknown DestructionKind"); 22000b57cec5SDimitry Andric } 22010b57cec5SDimitry Andric 22020b57cec5SDimitry Andric /// pushEHDestroy - Push the standard destructor for the given type as 22030b57cec5SDimitry Andric /// an EH-only cleanup. 22040b57cec5SDimitry Andric void CodeGenFunction::pushEHDestroy(QualType::DestructionKind dtorKind, 22050b57cec5SDimitry Andric Address addr, QualType type) { 22060b57cec5SDimitry Andric assert(dtorKind && "cannot push destructor for trivial type"); 22070b57cec5SDimitry Andric assert(needsEHCleanup(dtorKind)); 22080b57cec5SDimitry Andric 22090b57cec5SDimitry Andric pushDestroy(EHCleanup, addr, type, getDestroyer(dtorKind), true); 22100b57cec5SDimitry Andric } 22110b57cec5SDimitry Andric 22120b57cec5SDimitry Andric /// pushDestroy - Push the standard destructor for the given type as 22130b57cec5SDimitry Andric /// at least a normal cleanup. 22140b57cec5SDimitry Andric void CodeGenFunction::pushDestroy(QualType::DestructionKind dtorKind, 22150b57cec5SDimitry Andric Address addr, QualType type) { 22160b57cec5SDimitry Andric assert(dtorKind && "cannot push destructor for trivial type"); 22170b57cec5SDimitry Andric 22180b57cec5SDimitry Andric CleanupKind cleanupKind = getCleanupKind(dtorKind); 22190b57cec5SDimitry Andric pushDestroy(cleanupKind, addr, type, getDestroyer(dtorKind), 22200b57cec5SDimitry Andric cleanupKind & EHCleanup); 22210b57cec5SDimitry Andric } 22220b57cec5SDimitry Andric 22230b57cec5SDimitry Andric void CodeGenFunction::pushDestroy(CleanupKind cleanupKind, Address addr, 22240b57cec5SDimitry Andric QualType type, Destroyer *destroyer, 22250b57cec5SDimitry Andric bool useEHCleanupForArray) { 22260b57cec5SDimitry Andric pushFullExprCleanup<DestroyObject>(cleanupKind, addr, type, 22270b57cec5SDimitry Andric destroyer, useEHCleanupForArray); 22280b57cec5SDimitry Andric } 22290b57cec5SDimitry Andric 2230*0fca6ea1SDimitry Andric // Pushes a destroy and defers its deactivation until its 2231*0fca6ea1SDimitry Andric // CleanupDeactivationScope is exited. 2232*0fca6ea1SDimitry Andric void CodeGenFunction::pushDestroyAndDeferDeactivation( 2233*0fca6ea1SDimitry Andric QualType::DestructionKind dtorKind, Address addr, QualType type) { 2234*0fca6ea1SDimitry Andric assert(dtorKind && "cannot push destructor for trivial type"); 2235*0fca6ea1SDimitry Andric 2236*0fca6ea1SDimitry Andric CleanupKind cleanupKind = getCleanupKind(dtorKind); 2237*0fca6ea1SDimitry Andric pushDestroyAndDeferDeactivation( 2238*0fca6ea1SDimitry Andric cleanupKind, addr, type, getDestroyer(dtorKind), cleanupKind & EHCleanup); 2239*0fca6ea1SDimitry Andric } 2240*0fca6ea1SDimitry Andric 2241*0fca6ea1SDimitry Andric void CodeGenFunction::pushDestroyAndDeferDeactivation( 2242*0fca6ea1SDimitry Andric CleanupKind cleanupKind, Address addr, QualType type, Destroyer *destroyer, 2243*0fca6ea1SDimitry Andric bool useEHCleanupForArray) { 2244*0fca6ea1SDimitry Andric llvm::Instruction *DominatingIP = 2245*0fca6ea1SDimitry Andric Builder.CreateFlagLoad(llvm::Constant::getNullValue(Int8PtrTy)); 2246*0fca6ea1SDimitry Andric pushDestroy(cleanupKind, addr, type, destroyer, useEHCleanupForArray); 2247*0fca6ea1SDimitry Andric DeferredDeactivationCleanupStack.push_back( 2248*0fca6ea1SDimitry Andric {EHStack.stable_begin(), DominatingIP}); 2249*0fca6ea1SDimitry Andric } 2250*0fca6ea1SDimitry Andric 22510b57cec5SDimitry Andric void CodeGenFunction::pushStackRestore(CleanupKind Kind, Address SPMem) { 22520b57cec5SDimitry Andric EHStack.pushCleanup<CallStackRestore>(Kind, SPMem); 22530b57cec5SDimitry Andric } 22540b57cec5SDimitry Andric 225506c3fb27SDimitry Andric void CodeGenFunction::pushKmpcAllocFree( 225606c3fb27SDimitry Andric CleanupKind Kind, std::pair<llvm::Value *, llvm::Value *> AddrSizePair) { 225706c3fb27SDimitry Andric EHStack.pushCleanup<KmpcAllocFree>(Kind, AddrSizePair); 225806c3fb27SDimitry Andric } 225906c3fb27SDimitry Andric 2260e8d8bef9SDimitry Andric void CodeGenFunction::pushLifetimeExtendedDestroy(CleanupKind cleanupKind, 2261e8d8bef9SDimitry Andric Address addr, QualType type, 2262e8d8bef9SDimitry Andric Destroyer *destroyer, 2263e8d8bef9SDimitry Andric bool useEHCleanupForArray) { 2264e8d8bef9SDimitry Andric // If we're not in a conditional branch, we don't need to bother generating a 2265e8d8bef9SDimitry Andric // conditional cleanup. 2266e8d8bef9SDimitry Andric if (!isInConditionalBranch()) { 22670b57cec5SDimitry Andric // FIXME: When popping normal cleanups, we need to keep this EH cleanup 22680b57cec5SDimitry Andric // around in case a temporary's destructor throws an exception. 22690b57cec5SDimitry Andric 2270*0fca6ea1SDimitry Andric // Add the cleanup to the EHStack. After the full-expr, this would be 2271*0fca6ea1SDimitry Andric // deactivated before being popped from the stack. 2272*0fca6ea1SDimitry Andric pushDestroyAndDeferDeactivation(cleanupKind, addr, type, destroyer, 2273*0fca6ea1SDimitry Andric useEHCleanupForArray); 2274*0fca6ea1SDimitry Andric 2275*0fca6ea1SDimitry Andric // Since this is lifetime-extended, push it once again to the EHStack after 2276*0fca6ea1SDimitry Andric // the full expression. 2277e8d8bef9SDimitry Andric return pushCleanupAfterFullExprWithActiveFlag<DestroyObject>( 2278*0fca6ea1SDimitry Andric cleanupKind, Address::invalid(), addr, type, destroyer, 2279*0fca6ea1SDimitry Andric useEHCleanupForArray); 2280e8d8bef9SDimitry Andric } 2281e8d8bef9SDimitry Andric 2282e8d8bef9SDimitry Andric // Otherwise, we should only destroy the object if it's been initialized. 2283e8d8bef9SDimitry Andric 2284e8d8bef9SDimitry Andric using ConditionalCleanupType = 2285e8d8bef9SDimitry Andric EHScopeStack::ConditionalCleanup<DestroyObject, Address, QualType, 2286e8d8bef9SDimitry Andric Destroyer *, bool>; 2287*0fca6ea1SDimitry Andric DominatingValue<Address>::saved_type SavedAddr = saveValueInCond(addr); 2288e8d8bef9SDimitry Andric 2289*0fca6ea1SDimitry Andric // Remember to emit cleanup if we branch-out before end of full-expression 2290*0fca6ea1SDimitry Andric // (eg: through stmt-expr or coro suspensions). 2291*0fca6ea1SDimitry Andric AllocaTrackerRAII DeactivationAllocas(*this); 2292*0fca6ea1SDimitry Andric Address ActiveFlagForDeactivation = createCleanupActiveFlag(); 2293e8d8bef9SDimitry Andric 2294*0fca6ea1SDimitry Andric pushCleanupAndDeferDeactivation<ConditionalCleanupType>( 2295*0fca6ea1SDimitry Andric cleanupKind, SavedAddr, type, destroyer, useEHCleanupForArray); 2296*0fca6ea1SDimitry Andric initFullExprCleanupWithFlag(ActiveFlagForDeactivation); 2297*0fca6ea1SDimitry Andric EHCleanupScope &cleanup = cast<EHCleanupScope>(*EHStack.begin()); 2298*0fca6ea1SDimitry Andric // Erase the active flag if the cleanup was not emitted. 2299*0fca6ea1SDimitry Andric cleanup.AddAuxAllocas(std::move(DeactivationAllocas).Take()); 2300e8d8bef9SDimitry Andric 2301*0fca6ea1SDimitry Andric // Since this is lifetime-extended, push it once again to the EHStack after 2302*0fca6ea1SDimitry Andric // the full expression. 2303*0fca6ea1SDimitry Andric // The previous active flag would always be 'false' due to forced deferred 2304*0fca6ea1SDimitry Andric // deactivation. Use a separate flag for lifetime-extension to correctly 2305*0fca6ea1SDimitry Andric // remember if this branch was taken and the object was initialized. 2306*0fca6ea1SDimitry Andric Address ActiveFlagForLifetimeExt = createCleanupActiveFlag(); 2307e8d8bef9SDimitry Andric pushCleanupAfterFullExprWithActiveFlag<ConditionalCleanupType>( 2308*0fca6ea1SDimitry Andric cleanupKind, ActiveFlagForLifetimeExt, SavedAddr, type, destroyer, 2309e8d8bef9SDimitry Andric useEHCleanupForArray); 23100b57cec5SDimitry Andric } 23110b57cec5SDimitry Andric 23120b57cec5SDimitry Andric /// emitDestroy - Immediately perform the destruction of the given 23130b57cec5SDimitry Andric /// object. 23140b57cec5SDimitry Andric /// 23150b57cec5SDimitry Andric /// \param addr - the address of the object; a type* 23160b57cec5SDimitry Andric /// \param type - the type of the object; if an array type, all 23170b57cec5SDimitry Andric /// objects are destroyed in reverse order 23180b57cec5SDimitry Andric /// \param destroyer - the function to call to destroy individual 23190b57cec5SDimitry Andric /// elements 23200b57cec5SDimitry Andric /// \param useEHCleanupForArray - whether an EH cleanup should be 23210b57cec5SDimitry Andric /// used when destroying array elements, in case one of the 23220b57cec5SDimitry Andric /// destructions throws an exception 23230b57cec5SDimitry Andric void CodeGenFunction::emitDestroy(Address addr, QualType type, 23240b57cec5SDimitry Andric Destroyer *destroyer, 23250b57cec5SDimitry Andric bool useEHCleanupForArray) { 23260b57cec5SDimitry Andric const ArrayType *arrayType = getContext().getAsArrayType(type); 23270b57cec5SDimitry Andric if (!arrayType) 23280b57cec5SDimitry Andric return destroyer(*this, addr, type); 23290b57cec5SDimitry Andric 23300b57cec5SDimitry Andric llvm::Value *length = emitArrayLength(arrayType, type, addr); 23310b57cec5SDimitry Andric 23320b57cec5SDimitry Andric CharUnits elementAlign = 23330b57cec5SDimitry Andric addr.getAlignment() 23340b57cec5SDimitry Andric .alignmentOfArrayElement(getContext().getTypeSizeInChars(type)); 23350b57cec5SDimitry Andric 23360b57cec5SDimitry Andric // Normally we have to check whether the array is zero-length. 23370b57cec5SDimitry Andric bool checkZeroLength = true; 23380b57cec5SDimitry Andric 23390b57cec5SDimitry Andric // But if the array length is constant, we can suppress that. 23400b57cec5SDimitry Andric if (llvm::ConstantInt *constLength = dyn_cast<llvm::ConstantInt>(length)) { 23410b57cec5SDimitry Andric // ...and if it's constant zero, we can just skip the entire thing. 23420b57cec5SDimitry Andric if (constLength->isZero()) return; 23430b57cec5SDimitry Andric checkZeroLength = false; 23440b57cec5SDimitry Andric } 23450b57cec5SDimitry Andric 2346*0fca6ea1SDimitry Andric llvm::Value *begin = addr.emitRawPointer(*this); 2347fe6060f1SDimitry Andric llvm::Value *end = 2348fe6060f1SDimitry Andric Builder.CreateInBoundsGEP(addr.getElementType(), begin, length); 23490b57cec5SDimitry Andric emitArrayDestroy(begin, end, type, elementAlign, destroyer, 23500b57cec5SDimitry Andric checkZeroLength, useEHCleanupForArray); 23510b57cec5SDimitry Andric } 23520b57cec5SDimitry Andric 23530b57cec5SDimitry Andric /// emitArrayDestroy - Destroys all the elements of the given array, 23540b57cec5SDimitry Andric /// beginning from last to first. The array cannot be zero-length. 23550b57cec5SDimitry Andric /// 23560b57cec5SDimitry Andric /// \param begin - a type* denoting the first element of the array 23570b57cec5SDimitry Andric /// \param end - a type* denoting one past the end of the array 23580b57cec5SDimitry Andric /// \param elementType - the element type of the array 23590b57cec5SDimitry Andric /// \param destroyer - the function to call to destroy elements 23600b57cec5SDimitry Andric /// \param useEHCleanup - whether to push an EH cleanup to destroy 23610b57cec5SDimitry Andric /// the remaining elements in case the destruction of a single 23620b57cec5SDimitry Andric /// element throws 23630b57cec5SDimitry Andric void CodeGenFunction::emitArrayDestroy(llvm::Value *begin, 23640b57cec5SDimitry Andric llvm::Value *end, 23650b57cec5SDimitry Andric QualType elementType, 23660b57cec5SDimitry Andric CharUnits elementAlign, 23670b57cec5SDimitry Andric Destroyer *destroyer, 23680b57cec5SDimitry Andric bool checkZeroLength, 23690b57cec5SDimitry Andric bool useEHCleanup) { 23700b57cec5SDimitry Andric assert(!elementType->isArrayType()); 23710b57cec5SDimitry Andric 23720b57cec5SDimitry Andric // The basic structure here is a do-while loop, because we don't 23730b57cec5SDimitry Andric // need to check for the zero-element case. 23740b57cec5SDimitry Andric llvm::BasicBlock *bodyBB = createBasicBlock("arraydestroy.body"); 23750b57cec5SDimitry Andric llvm::BasicBlock *doneBB = createBasicBlock("arraydestroy.done"); 23760b57cec5SDimitry Andric 23770b57cec5SDimitry Andric if (checkZeroLength) { 23780b57cec5SDimitry Andric llvm::Value *isEmpty = Builder.CreateICmpEQ(begin, end, 23790b57cec5SDimitry Andric "arraydestroy.isempty"); 23800b57cec5SDimitry Andric Builder.CreateCondBr(isEmpty, doneBB, bodyBB); 23810b57cec5SDimitry Andric } 23820b57cec5SDimitry Andric 23830b57cec5SDimitry Andric // Enter the loop body, making that address the current address. 23840b57cec5SDimitry Andric llvm::BasicBlock *entryBB = Builder.GetInsertBlock(); 23850b57cec5SDimitry Andric EmitBlock(bodyBB); 23860b57cec5SDimitry Andric llvm::PHINode *elementPast = 23870b57cec5SDimitry Andric Builder.CreatePHI(begin->getType(), 2, "arraydestroy.elementPast"); 23880b57cec5SDimitry Andric elementPast->addIncoming(end, entryBB); 23890b57cec5SDimitry Andric 23900b57cec5SDimitry Andric // Shift the address back by one element. 23910b57cec5SDimitry Andric llvm::Value *negativeOne = llvm::ConstantInt::get(SizeTy, -1, true); 239204eeddc0SDimitry Andric llvm::Type *llvmElementType = ConvertTypeForMem(elementType); 2393fe6060f1SDimitry Andric llvm::Value *element = Builder.CreateInBoundsGEP( 239404eeddc0SDimitry Andric llvmElementType, elementPast, negativeOne, "arraydestroy.element"); 23950b57cec5SDimitry Andric 23960b57cec5SDimitry Andric if (useEHCleanup) 23970b57cec5SDimitry Andric pushRegularPartialArrayCleanup(begin, element, elementType, elementAlign, 23980b57cec5SDimitry Andric destroyer); 23990b57cec5SDimitry Andric 24000b57cec5SDimitry Andric // Perform the actual destruction there. 240104eeddc0SDimitry Andric destroyer(*this, Address(element, llvmElementType, elementAlign), 240204eeddc0SDimitry Andric elementType); 24030b57cec5SDimitry Andric 24040b57cec5SDimitry Andric if (useEHCleanup) 24050b57cec5SDimitry Andric PopCleanupBlock(); 24060b57cec5SDimitry Andric 24070b57cec5SDimitry Andric // Check whether we've reached the end. 24080b57cec5SDimitry Andric llvm::Value *done = Builder.CreateICmpEQ(element, begin, "arraydestroy.done"); 24090b57cec5SDimitry Andric Builder.CreateCondBr(done, doneBB, bodyBB); 24100b57cec5SDimitry Andric elementPast->addIncoming(element, Builder.GetInsertBlock()); 24110b57cec5SDimitry Andric 24120b57cec5SDimitry Andric // Done. 24130b57cec5SDimitry Andric EmitBlock(doneBB); 24140b57cec5SDimitry Andric } 24150b57cec5SDimitry Andric 24160b57cec5SDimitry Andric /// Perform partial array destruction as if in an EH cleanup. Unlike 24170b57cec5SDimitry Andric /// emitArrayDestroy, the element type here may still be an array type. 24180b57cec5SDimitry Andric static void emitPartialArrayDestroy(CodeGenFunction &CGF, 24190b57cec5SDimitry Andric llvm::Value *begin, llvm::Value *end, 24200b57cec5SDimitry Andric QualType type, CharUnits elementAlign, 24210b57cec5SDimitry Andric CodeGenFunction::Destroyer *destroyer) { 242281ad6265SDimitry Andric llvm::Type *elemTy = CGF.ConvertTypeForMem(type); 242381ad6265SDimitry Andric 24240b57cec5SDimitry Andric // If the element type is itself an array, drill down. 24250b57cec5SDimitry Andric unsigned arrayDepth = 0; 24260b57cec5SDimitry Andric while (const ArrayType *arrayType = CGF.getContext().getAsArrayType(type)) { 24270b57cec5SDimitry Andric // VLAs don't require a GEP index to walk into. 24280b57cec5SDimitry Andric if (!isa<VariableArrayType>(arrayType)) 24290b57cec5SDimitry Andric arrayDepth++; 24300b57cec5SDimitry Andric type = arrayType->getElementType(); 24310b57cec5SDimitry Andric } 24320b57cec5SDimitry Andric 24330b57cec5SDimitry Andric if (arrayDepth) { 24340b57cec5SDimitry Andric llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0); 24350b57cec5SDimitry Andric 24360b57cec5SDimitry Andric SmallVector<llvm::Value*,4> gepIndices(arrayDepth+1, zero); 2437fe6060f1SDimitry Andric begin = CGF.Builder.CreateInBoundsGEP( 2438fe6060f1SDimitry Andric elemTy, begin, gepIndices, "pad.arraybegin"); 2439fe6060f1SDimitry Andric end = CGF.Builder.CreateInBoundsGEP( 2440fe6060f1SDimitry Andric elemTy, end, gepIndices, "pad.arrayend"); 24410b57cec5SDimitry Andric } 24420b57cec5SDimitry Andric 24430b57cec5SDimitry Andric // Destroy the array. We don't ever need an EH cleanup because we 24440b57cec5SDimitry Andric // assume that we're in an EH cleanup ourselves, so a throwing 24450b57cec5SDimitry Andric // destructor causes an immediate terminate. 24460b57cec5SDimitry Andric CGF.emitArrayDestroy(begin, end, type, elementAlign, destroyer, 24470b57cec5SDimitry Andric /*checkZeroLength*/ true, /*useEHCleanup*/ false); 24480b57cec5SDimitry Andric } 24490b57cec5SDimitry Andric 24500b57cec5SDimitry Andric namespace { 24510b57cec5SDimitry Andric /// RegularPartialArrayDestroy - a cleanup which performs a partial 24520b57cec5SDimitry Andric /// array destroy where the end pointer is regularly determined and 24530b57cec5SDimitry Andric /// does not need to be loaded from a local. 24540b57cec5SDimitry Andric class RegularPartialArrayDestroy final : public EHScopeStack::Cleanup { 24550b57cec5SDimitry Andric llvm::Value *ArrayBegin; 24560b57cec5SDimitry Andric llvm::Value *ArrayEnd; 24570b57cec5SDimitry Andric QualType ElementType; 24580b57cec5SDimitry Andric CodeGenFunction::Destroyer *Destroyer; 24590b57cec5SDimitry Andric CharUnits ElementAlign; 24600b57cec5SDimitry Andric public: 24610b57cec5SDimitry Andric RegularPartialArrayDestroy(llvm::Value *arrayBegin, llvm::Value *arrayEnd, 24620b57cec5SDimitry Andric QualType elementType, CharUnits elementAlign, 24630b57cec5SDimitry Andric CodeGenFunction::Destroyer *destroyer) 24640b57cec5SDimitry Andric : ArrayBegin(arrayBegin), ArrayEnd(arrayEnd), 24650b57cec5SDimitry Andric ElementType(elementType), Destroyer(destroyer), 24660b57cec5SDimitry Andric ElementAlign(elementAlign) {} 24670b57cec5SDimitry Andric 24680b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 24690b57cec5SDimitry Andric emitPartialArrayDestroy(CGF, ArrayBegin, ArrayEnd, 24700b57cec5SDimitry Andric ElementType, ElementAlign, Destroyer); 24710b57cec5SDimitry Andric } 24720b57cec5SDimitry Andric }; 24730b57cec5SDimitry Andric 24740b57cec5SDimitry Andric /// IrregularPartialArrayDestroy - a cleanup which performs a 24750b57cec5SDimitry Andric /// partial array destroy where the end pointer is irregularly 24760b57cec5SDimitry Andric /// determined and must be loaded from a local. 24770b57cec5SDimitry Andric class IrregularPartialArrayDestroy final : public EHScopeStack::Cleanup { 24780b57cec5SDimitry Andric llvm::Value *ArrayBegin; 24790b57cec5SDimitry Andric Address ArrayEndPointer; 24800b57cec5SDimitry Andric QualType ElementType; 24810b57cec5SDimitry Andric CodeGenFunction::Destroyer *Destroyer; 24820b57cec5SDimitry Andric CharUnits ElementAlign; 24830b57cec5SDimitry Andric public: 24840b57cec5SDimitry Andric IrregularPartialArrayDestroy(llvm::Value *arrayBegin, 24850b57cec5SDimitry Andric Address arrayEndPointer, 24860b57cec5SDimitry Andric QualType elementType, 24870b57cec5SDimitry Andric CharUnits elementAlign, 24880b57cec5SDimitry Andric CodeGenFunction::Destroyer *destroyer) 24890b57cec5SDimitry Andric : ArrayBegin(arrayBegin), ArrayEndPointer(arrayEndPointer), 24900b57cec5SDimitry Andric ElementType(elementType), Destroyer(destroyer), 24910b57cec5SDimitry Andric ElementAlign(elementAlign) {} 24920b57cec5SDimitry Andric 24930b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 24940b57cec5SDimitry Andric llvm::Value *arrayEnd = CGF.Builder.CreateLoad(ArrayEndPointer); 24950b57cec5SDimitry Andric emitPartialArrayDestroy(CGF, ArrayBegin, arrayEnd, 24960b57cec5SDimitry Andric ElementType, ElementAlign, Destroyer); 24970b57cec5SDimitry Andric } 24980b57cec5SDimitry Andric }; 24990b57cec5SDimitry Andric } // end anonymous namespace 25000b57cec5SDimitry Andric 2501*0fca6ea1SDimitry Andric /// pushIrregularPartialArrayCleanup - Push a NormalAndEHCleanup to 2502*0fca6ea1SDimitry Andric /// destroy already-constructed elements of the given array. The cleanup may be 2503*0fca6ea1SDimitry Andric /// popped with DeactivateCleanupBlock or PopCleanupBlock. 25040b57cec5SDimitry Andric /// 25050b57cec5SDimitry Andric /// \param elementType - the immediate element type of the array; 25060b57cec5SDimitry Andric /// possibly still an array type 25070b57cec5SDimitry Andric void CodeGenFunction::pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin, 25080b57cec5SDimitry Andric Address arrayEndPointer, 25090b57cec5SDimitry Andric QualType elementType, 25100b57cec5SDimitry Andric CharUnits elementAlign, 25110b57cec5SDimitry Andric Destroyer *destroyer) { 2512*0fca6ea1SDimitry Andric pushFullExprCleanup<IrregularPartialArrayDestroy>( 2513*0fca6ea1SDimitry Andric NormalAndEHCleanup, arrayBegin, arrayEndPointer, elementType, 2514*0fca6ea1SDimitry Andric elementAlign, destroyer); 25150b57cec5SDimitry Andric } 25160b57cec5SDimitry Andric 25170b57cec5SDimitry Andric /// pushRegularPartialArrayCleanup - Push an EH cleanup to destroy 25180b57cec5SDimitry Andric /// already-constructed elements of the given array. The cleanup 25190b57cec5SDimitry Andric /// may be popped with DeactivateCleanupBlock or PopCleanupBlock. 25200b57cec5SDimitry Andric /// 25210b57cec5SDimitry Andric /// \param elementType - the immediate element type of the array; 25220b57cec5SDimitry Andric /// possibly still an array type 25230b57cec5SDimitry Andric void CodeGenFunction::pushRegularPartialArrayCleanup(llvm::Value *arrayBegin, 25240b57cec5SDimitry Andric llvm::Value *arrayEnd, 25250b57cec5SDimitry Andric QualType elementType, 25260b57cec5SDimitry Andric CharUnits elementAlign, 25270b57cec5SDimitry Andric Destroyer *destroyer) { 25280b57cec5SDimitry Andric pushFullExprCleanup<RegularPartialArrayDestroy>(EHCleanup, 25290b57cec5SDimitry Andric arrayBegin, arrayEnd, 25300b57cec5SDimitry Andric elementType, elementAlign, 25310b57cec5SDimitry Andric destroyer); 25320b57cec5SDimitry Andric } 25330b57cec5SDimitry Andric 25340b57cec5SDimitry Andric /// Lazily declare the @llvm.lifetime.start intrinsic. 25350b57cec5SDimitry Andric llvm::Function *CodeGenModule::getLLVMLifetimeStartFn() { 25360b57cec5SDimitry Andric if (LifetimeStartFn) 25370b57cec5SDimitry Andric return LifetimeStartFn; 25380b57cec5SDimitry Andric LifetimeStartFn = llvm::Intrinsic::getDeclaration(&getModule(), 25390b57cec5SDimitry Andric llvm::Intrinsic::lifetime_start, AllocaInt8PtrTy); 25400b57cec5SDimitry Andric return LifetimeStartFn; 25410b57cec5SDimitry Andric } 25420b57cec5SDimitry Andric 25430b57cec5SDimitry Andric /// Lazily declare the @llvm.lifetime.end intrinsic. 25440b57cec5SDimitry Andric llvm::Function *CodeGenModule::getLLVMLifetimeEndFn() { 25450b57cec5SDimitry Andric if (LifetimeEndFn) 25460b57cec5SDimitry Andric return LifetimeEndFn; 25470b57cec5SDimitry Andric LifetimeEndFn = llvm::Intrinsic::getDeclaration(&getModule(), 25480b57cec5SDimitry Andric llvm::Intrinsic::lifetime_end, AllocaInt8PtrTy); 25490b57cec5SDimitry Andric return LifetimeEndFn; 25500b57cec5SDimitry Andric } 25510b57cec5SDimitry Andric 25520b57cec5SDimitry Andric namespace { 25530b57cec5SDimitry Andric /// A cleanup to perform a release of an object at the end of a 25540b57cec5SDimitry Andric /// function. This is used to balance out the incoming +1 of a 25550b57cec5SDimitry Andric /// ns_consumed argument when we can't reasonably do that just by 25560b57cec5SDimitry Andric /// not doing the initial retain for a __block argument. 25570b57cec5SDimitry Andric struct ConsumeARCParameter final : EHScopeStack::Cleanup { 25580b57cec5SDimitry Andric ConsumeARCParameter(llvm::Value *param, 25590b57cec5SDimitry Andric ARCPreciseLifetime_t precise) 25600b57cec5SDimitry Andric : Param(param), Precise(precise) {} 25610b57cec5SDimitry Andric 25620b57cec5SDimitry Andric llvm::Value *Param; 25630b57cec5SDimitry Andric ARCPreciseLifetime_t Precise; 25640b57cec5SDimitry Andric 25650b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 25660b57cec5SDimitry Andric CGF.EmitARCRelease(Param, Precise); 25670b57cec5SDimitry Andric } 25680b57cec5SDimitry Andric }; 25690b57cec5SDimitry Andric } // end anonymous namespace 25700b57cec5SDimitry Andric 25710b57cec5SDimitry Andric /// Emit an alloca (or GlobalValue depending on target) 25720b57cec5SDimitry Andric /// for the specified parameter and set up LocalDeclMap. 25730b57cec5SDimitry Andric void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg, 25740b57cec5SDimitry Andric unsigned ArgNo) { 257581ad6265SDimitry Andric bool NoDebugInfo = false; 25760b57cec5SDimitry Andric // FIXME: Why isn't ImplicitParamDecl a ParmVarDecl? 25770b57cec5SDimitry Andric assert((isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)) && 25780b57cec5SDimitry Andric "Invalid argument to EmitParmDecl"); 25790b57cec5SDimitry Andric 258006c3fb27SDimitry Andric // Set the name of the parameter's initial value to make IR easier to 258106c3fb27SDimitry Andric // read. Don't modify the names of globals. 258206c3fb27SDimitry Andric if (!isa<llvm::GlobalValue>(Arg.getAnyValue())) 25830b57cec5SDimitry Andric Arg.getAnyValue()->setName(D.getName()); 25840b57cec5SDimitry Andric 25850b57cec5SDimitry Andric QualType Ty = D.getType(); 25860b57cec5SDimitry Andric 25870b57cec5SDimitry Andric // Use better IR generation for certain implicit parameters. 25880b57cec5SDimitry Andric if (auto IPD = dyn_cast<ImplicitParamDecl>(&D)) { 25890b57cec5SDimitry Andric // The only implicit argument a block has is its literal. 25900b57cec5SDimitry Andric // This may be passed as an inalloca'ed value on Windows x86. 25910b57cec5SDimitry Andric if (BlockInfo) { 25920b57cec5SDimitry Andric llvm::Value *V = Arg.isIndirect() 25930b57cec5SDimitry Andric ? Builder.CreateLoad(Arg.getIndirectAddress()) 25940b57cec5SDimitry Andric : Arg.getDirectValue(); 25950b57cec5SDimitry Andric setBlockContextParameter(IPD, ArgNo, V); 25960b57cec5SDimitry Andric return; 25970b57cec5SDimitry Andric } 259881ad6265SDimitry Andric // Suppressing debug info for ThreadPrivateVar parameters, else it hides 259981ad6265SDimitry Andric // debug info of TLS variables. 260081ad6265SDimitry Andric NoDebugInfo = 26015f757f3fSDimitry Andric (IPD->getParameterKind() == ImplicitParamKind::ThreadPrivateVar); 26020b57cec5SDimitry Andric } 26030b57cec5SDimitry Andric 26040b57cec5SDimitry Andric Address DeclPtr = Address::invalid(); 2605*0fca6ea1SDimitry Andric RawAddress AllocaPtr = Address::invalid(); 26060b57cec5SDimitry Andric bool DoStore = false; 26070b57cec5SDimitry Andric bool IsScalar = hasScalarEvaluationKind(Ty); 260806c3fb27SDimitry Andric bool UseIndirectDebugAddress = false; 260906c3fb27SDimitry Andric 26100b57cec5SDimitry Andric // If we already have a pointer to the argument, reuse the input pointer. 26110b57cec5SDimitry Andric if (Arg.isIndirect()) { 261281ad6265SDimitry Andric DeclPtr = Arg.getIndirectAddress(); 261306c3fb27SDimitry Andric DeclPtr = DeclPtr.withElementType(ConvertTypeForMem(Ty)); 26140b57cec5SDimitry Andric // Indirect argument is in alloca address space, which may be different 26150b57cec5SDimitry Andric // from the default address space. 26160b57cec5SDimitry Andric auto AllocaAS = CGM.getASTAllocaAddressSpace(); 2617*0fca6ea1SDimitry Andric auto *V = DeclPtr.emitRawPointer(*this); 2618*0fca6ea1SDimitry Andric AllocaPtr = RawAddress(V, DeclPtr.getElementType(), DeclPtr.getAlignment()); 261906c3fb27SDimitry Andric 262006c3fb27SDimitry Andric // For truly ABI indirect arguments -- those that are not `byval` -- store 262106c3fb27SDimitry Andric // the address of the argument on the stack to preserve debug information. 262206c3fb27SDimitry Andric ABIArgInfo ArgInfo = CurFnInfo->arguments()[ArgNo - 1].info; 262306c3fb27SDimitry Andric if (ArgInfo.isIndirect()) 262406c3fb27SDimitry Andric UseIndirectDebugAddress = !ArgInfo.getIndirectByVal(); 262506c3fb27SDimitry Andric if (UseIndirectDebugAddress) { 262606c3fb27SDimitry Andric auto PtrTy = getContext().getPointerType(Ty); 262706c3fb27SDimitry Andric AllocaPtr = CreateMemTemp(PtrTy, getContext().getTypeAlignInChars(PtrTy), 262806c3fb27SDimitry Andric D.getName() + ".indirect_addr"); 262906c3fb27SDimitry Andric EmitStoreOfScalar(V, AllocaPtr, /* Volatile */ false, PtrTy); 263006c3fb27SDimitry Andric } 263106c3fb27SDimitry Andric 26320b57cec5SDimitry Andric auto SrcLangAS = getLangOpts().OpenCL ? LangAS::opencl_private : AllocaAS; 26330b57cec5SDimitry Andric auto DestLangAS = 26340b57cec5SDimitry Andric getLangOpts().OpenCL ? LangAS::opencl_private : LangAS::Default; 26350b57cec5SDimitry Andric if (SrcLangAS != DestLangAS) { 26360b57cec5SDimitry Andric assert(getContext().getTargetAddressSpace(SrcLangAS) == 26370b57cec5SDimitry Andric CGM.getDataLayout().getAllocaAddrSpace()); 26380b57cec5SDimitry Andric auto DestAS = getContext().getTargetAddressSpace(DestLangAS); 263906c3fb27SDimitry Andric auto *T = llvm::PointerType::get(getLLVMContext(), DestAS); 264006c3fb27SDimitry Andric DeclPtr = 264106c3fb27SDimitry Andric DeclPtr.withPointer(getTargetHooks().performAddrSpaceCast( 264206c3fb27SDimitry Andric *this, V, SrcLangAS, DestLangAS, T, true), 264306c3fb27SDimitry Andric DeclPtr.isKnownNonNull()); 26440b57cec5SDimitry Andric } 26450b57cec5SDimitry Andric 26460b57cec5SDimitry Andric // Push a destructor cleanup for this parameter if the ABI requires it. 26470b57cec5SDimitry Andric // Don't push a cleanup in a thunk for a method that will also emit a 26480b57cec5SDimitry Andric // cleanup. 2649fe6060f1SDimitry Andric if (Ty->isRecordType() && !CurFuncIsThunk && 2650a7dea167SDimitry Andric Ty->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee()) { 2651a7dea167SDimitry Andric if (QualType::DestructionKind DtorKind = 2652a7dea167SDimitry Andric D.needsDestruction(getContext())) { 26530b57cec5SDimitry Andric assert((DtorKind == QualType::DK_cxx_destructor || 26540b57cec5SDimitry Andric DtorKind == QualType::DK_nontrivial_c_struct) && 26550b57cec5SDimitry Andric "unexpected destructor type"); 26560b57cec5SDimitry Andric pushDestroy(DtorKind, DeclPtr, Ty); 26570b57cec5SDimitry Andric CalleeDestructedParamCleanups[cast<ParmVarDecl>(&D)] = 26580b57cec5SDimitry Andric EHStack.stable_begin(); 26590b57cec5SDimitry Andric } 26600b57cec5SDimitry Andric } 26610b57cec5SDimitry Andric } else { 26620b57cec5SDimitry Andric // Check if the parameter address is controlled by OpenMP runtime. 26630b57cec5SDimitry Andric Address OpenMPLocalAddr = 26640b57cec5SDimitry Andric getLangOpts().OpenMP 26650b57cec5SDimitry Andric ? CGM.getOpenMPRuntime().getAddressOfLocalVariable(*this, &D) 26660b57cec5SDimitry Andric : Address::invalid(); 26670b57cec5SDimitry Andric if (getLangOpts().OpenMP && OpenMPLocalAddr.isValid()) { 26680b57cec5SDimitry Andric DeclPtr = OpenMPLocalAddr; 2669349cc55cSDimitry Andric AllocaPtr = DeclPtr; 26700b57cec5SDimitry Andric } else { 26710b57cec5SDimitry Andric // Otherwise, create a temporary to hold the value. 26720b57cec5SDimitry Andric DeclPtr = CreateMemTemp(Ty, getContext().getDeclAlign(&D), 2673349cc55cSDimitry Andric D.getName() + ".addr", &AllocaPtr); 26740b57cec5SDimitry Andric } 26750b57cec5SDimitry Andric DoStore = true; 26760b57cec5SDimitry Andric } 26770b57cec5SDimitry Andric 26780b57cec5SDimitry Andric llvm::Value *ArgVal = (DoStore ? Arg.getDirectValue() : nullptr); 26790b57cec5SDimitry Andric 26800b57cec5SDimitry Andric LValue lv = MakeAddrLValue(DeclPtr, Ty); 26810b57cec5SDimitry Andric if (IsScalar) { 26820b57cec5SDimitry Andric Qualifiers qs = Ty.getQualifiers(); 26830b57cec5SDimitry Andric if (Qualifiers::ObjCLifetime lt = qs.getObjCLifetime()) { 26840b57cec5SDimitry Andric // We honor __attribute__((ns_consumed)) for types with lifetime. 26850b57cec5SDimitry Andric // For __strong, it's handled by just skipping the initial retain; 26860b57cec5SDimitry Andric // otherwise we have to balance out the initial +1 with an extra 26870b57cec5SDimitry Andric // cleanup to do the release at the end of the function. 26880b57cec5SDimitry Andric bool isConsumed = D.hasAttr<NSConsumedAttr>(); 26890b57cec5SDimitry Andric 26900b57cec5SDimitry Andric // If a parameter is pseudo-strong then we can omit the implicit retain. 26910b57cec5SDimitry Andric if (D.isARCPseudoStrong()) { 26920b57cec5SDimitry Andric assert(lt == Qualifiers::OCL_Strong && 26930b57cec5SDimitry Andric "pseudo-strong variable isn't strong?"); 26940b57cec5SDimitry Andric assert(qs.hasConst() && "pseudo-strong variable should be const!"); 26950b57cec5SDimitry Andric lt = Qualifiers::OCL_ExplicitNone; 26960b57cec5SDimitry Andric } 26970b57cec5SDimitry Andric 26980b57cec5SDimitry Andric // Load objects passed indirectly. 26990b57cec5SDimitry Andric if (Arg.isIndirect() && !ArgVal) 27000b57cec5SDimitry Andric ArgVal = Builder.CreateLoad(DeclPtr); 27010b57cec5SDimitry Andric 27020b57cec5SDimitry Andric if (lt == Qualifiers::OCL_Strong) { 27030b57cec5SDimitry Andric if (!isConsumed) { 27040b57cec5SDimitry Andric if (CGM.getCodeGenOpts().OptimizationLevel == 0) { 27050b57cec5SDimitry Andric // use objc_storeStrong(&dest, value) for retaining the 27060b57cec5SDimitry Andric // object. But first, store a null into 'dest' because 27070b57cec5SDimitry Andric // objc_storeStrong attempts to release its old value. 27080b57cec5SDimitry Andric llvm::Value *Null = CGM.EmitNullConstant(D.getType()); 27090b57cec5SDimitry Andric EmitStoreOfScalar(Null, lv, /* isInitialization */ true); 2710*0fca6ea1SDimitry Andric EmitARCStoreStrongCall(lv.getAddress(), ArgVal, true); 27110b57cec5SDimitry Andric DoStore = false; 27120b57cec5SDimitry Andric } 27130b57cec5SDimitry Andric else 27140b57cec5SDimitry Andric // Don't use objc_retainBlock for block pointers, because we 27150b57cec5SDimitry Andric // don't want to Block_copy something just because we got it 27160b57cec5SDimitry Andric // as a parameter. 27170b57cec5SDimitry Andric ArgVal = EmitARCRetainNonBlock(ArgVal); 27180b57cec5SDimitry Andric } 27190b57cec5SDimitry Andric } else { 27200b57cec5SDimitry Andric // Push the cleanup for a consumed parameter. 27210b57cec5SDimitry Andric if (isConsumed) { 27220b57cec5SDimitry Andric ARCPreciseLifetime_t precise = (D.hasAttr<ObjCPreciseLifetimeAttr>() 27230b57cec5SDimitry Andric ? ARCPreciseLifetime : ARCImpreciseLifetime); 27240b57cec5SDimitry Andric EHStack.pushCleanup<ConsumeARCParameter>(getARCCleanupKind(), ArgVal, 27250b57cec5SDimitry Andric precise); 27260b57cec5SDimitry Andric } 27270b57cec5SDimitry Andric 27280b57cec5SDimitry Andric if (lt == Qualifiers::OCL_Weak) { 27290b57cec5SDimitry Andric EmitARCInitWeak(DeclPtr, ArgVal); 27300b57cec5SDimitry Andric DoStore = false; // The weak init is a store, no need to do two. 27310b57cec5SDimitry Andric } 27320b57cec5SDimitry Andric } 27330b57cec5SDimitry Andric 27340b57cec5SDimitry Andric // Enter the cleanup scope. 27350b57cec5SDimitry Andric EmitAutoVarWithLifetime(*this, D, DeclPtr, lt); 27360b57cec5SDimitry Andric } 27370b57cec5SDimitry Andric } 27380b57cec5SDimitry Andric 27390b57cec5SDimitry Andric // Store the initial value into the alloca. 27400b57cec5SDimitry Andric if (DoStore) 27410b57cec5SDimitry Andric EmitStoreOfScalar(ArgVal, lv, /* isInitialization */ true); 27420b57cec5SDimitry Andric 27430b57cec5SDimitry Andric setAddrOfLocalVar(&D, DeclPtr); 27440b57cec5SDimitry Andric 2745a7dea167SDimitry Andric // Emit debug info for param declarations in non-thunk functions. 27460b57cec5SDimitry Andric if (CGDebugInfo *DI = getDebugInfo()) { 274781ad6265SDimitry Andric if (CGM.getCodeGenOpts().hasReducedDebugInfo() && !CurFuncIsThunk && 274881ad6265SDimitry Andric !NoDebugInfo) { 2749fe6060f1SDimitry Andric llvm::DILocalVariable *DILocalVar = DI->EmitDeclareOfArgVariable( 275006c3fb27SDimitry Andric &D, AllocaPtr.getPointer(), ArgNo, Builder, UseIndirectDebugAddress); 2751fe6060f1SDimitry Andric if (const auto *Var = dyn_cast_or_null<ParmVarDecl>(&D)) 2752fe6060f1SDimitry Andric DI->getParamDbgMappings().insert({Var, DILocalVar}); 27530b57cec5SDimitry Andric } 27540b57cec5SDimitry Andric } 27550b57cec5SDimitry Andric 27560b57cec5SDimitry Andric if (D.hasAttr<AnnotateAttr>()) 2757*0fca6ea1SDimitry Andric EmitVarAnnotations(&D, DeclPtr.emitRawPointer(*this)); 27580b57cec5SDimitry Andric 27590b57cec5SDimitry Andric // We can only check return value nullability if all arguments to the 27600b57cec5SDimitry Andric // function satisfy their nullability preconditions. This makes it necessary 27610b57cec5SDimitry Andric // to emit null checks for args in the function body itself. 27620b57cec5SDimitry Andric if (requiresReturnValueNullabilityCheck()) { 2763bdd1243dSDimitry Andric auto Nullability = Ty->getNullability(); 27640b57cec5SDimitry Andric if (Nullability && *Nullability == NullabilityKind::NonNull) { 27650b57cec5SDimitry Andric SanitizerScope SanScope(this); 27660b57cec5SDimitry Andric RetValNullabilityPrecondition = 27670b57cec5SDimitry Andric Builder.CreateAnd(RetValNullabilityPrecondition, 27680b57cec5SDimitry Andric Builder.CreateIsNotNull(Arg.getAnyValue())); 27690b57cec5SDimitry Andric } 27700b57cec5SDimitry Andric } 27710b57cec5SDimitry Andric } 27720b57cec5SDimitry Andric 27730b57cec5SDimitry Andric void CodeGenModule::EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D, 27740b57cec5SDimitry Andric CodeGenFunction *CGF) { 27750b57cec5SDimitry Andric if (!LangOpts.OpenMP || (!LangOpts.EmitAllDecls && !D->isUsed())) 27760b57cec5SDimitry Andric return; 27770b57cec5SDimitry Andric getOpenMPRuntime().emitUserDefinedReduction(CGF, D); 27780b57cec5SDimitry Andric } 27790b57cec5SDimitry Andric 27800b57cec5SDimitry Andric void CodeGenModule::EmitOMPDeclareMapper(const OMPDeclareMapperDecl *D, 27810b57cec5SDimitry Andric CodeGenFunction *CGF) { 2782a7dea167SDimitry Andric if (!LangOpts.OpenMP || LangOpts.OpenMPSimd || 2783a7dea167SDimitry Andric (!LangOpts.EmitAllDecls && !D->isUsed())) 27840b57cec5SDimitry Andric return; 2785a7dea167SDimitry Andric getOpenMPRuntime().emitUserDefinedMapper(D, CGF); 27860b57cec5SDimitry Andric } 27870b57cec5SDimitry Andric 27880b57cec5SDimitry Andric void CodeGenModule::EmitOMPRequiresDecl(const OMPRequiresDecl *D) { 27895ffd83dbSDimitry Andric getOpenMPRuntime().processRequiresDirective(D); 27900b57cec5SDimitry Andric } 2791fe6060f1SDimitry Andric 2792fe6060f1SDimitry Andric void CodeGenModule::EmitOMPAllocateDecl(const OMPAllocateDecl *D) { 2793fe6060f1SDimitry Andric for (const Expr *E : D->varlists()) { 2794fe6060f1SDimitry Andric const auto *DE = cast<DeclRefExpr>(E); 2795fe6060f1SDimitry Andric const auto *VD = cast<VarDecl>(DE->getDecl()); 2796fe6060f1SDimitry Andric 2797fe6060f1SDimitry Andric // Skip all but globals. 2798fe6060f1SDimitry Andric if (!VD->hasGlobalStorage()) 2799fe6060f1SDimitry Andric continue; 2800fe6060f1SDimitry Andric 2801fe6060f1SDimitry Andric // Check if the global has been materialized yet or not. If not, we are done 2802fe6060f1SDimitry Andric // as any later generation will utilize the OMPAllocateDeclAttr. However, if 2803fe6060f1SDimitry Andric // we already emitted the global we might have done so before the 2804fe6060f1SDimitry Andric // OMPAllocateDeclAttr was attached, leading to the wrong address space 2805fe6060f1SDimitry Andric // (potentially). While not pretty, common practise is to remove the old IR 2806fe6060f1SDimitry Andric // global and generate a new one, so we do that here too. Uses are replaced 2807fe6060f1SDimitry Andric // properly. 2808fe6060f1SDimitry Andric StringRef MangledName = getMangledName(VD); 2809fe6060f1SDimitry Andric llvm::GlobalValue *Entry = GetGlobalValue(MangledName); 2810fe6060f1SDimitry Andric if (!Entry) 2811fe6060f1SDimitry Andric continue; 2812fe6060f1SDimitry Andric 2813fe6060f1SDimitry Andric // We can also keep the existing global if the address space is what we 2814fe6060f1SDimitry Andric // expect it to be, if not, it is replaced. 2815fe6060f1SDimitry Andric QualType ASTTy = VD->getType(); 2816fe6060f1SDimitry Andric clang::LangAS GVAS = GetGlobalVarAddressSpace(VD); 2817fe6060f1SDimitry Andric auto TargetAS = getContext().getTargetAddressSpace(GVAS); 2818fe6060f1SDimitry Andric if (Entry->getType()->getAddressSpace() == TargetAS) 2819fe6060f1SDimitry Andric continue; 2820fe6060f1SDimitry Andric 2821fe6060f1SDimitry Andric // Make a new global with the correct type / address space. 2822fe6060f1SDimitry Andric llvm::Type *Ty = getTypes().ConvertTypeForMem(ASTTy); 2823fe6060f1SDimitry Andric llvm::PointerType *PTy = llvm::PointerType::get(Ty, TargetAS); 2824fe6060f1SDimitry Andric 2825fe6060f1SDimitry Andric // Replace all uses of the old global with a cast. Since we mutate the type 2826fe6060f1SDimitry Andric // in place we neeed an intermediate that takes the spot of the old entry 2827fe6060f1SDimitry Andric // until we can create the cast. 2828fe6060f1SDimitry Andric llvm::GlobalVariable *DummyGV = new llvm::GlobalVariable( 2829fe6060f1SDimitry Andric getModule(), Entry->getValueType(), false, 2830fe6060f1SDimitry Andric llvm::GlobalValue::CommonLinkage, nullptr, "dummy", nullptr, 2831fe6060f1SDimitry Andric llvm::GlobalVariable::NotThreadLocal, Entry->getAddressSpace()); 2832fe6060f1SDimitry Andric Entry->replaceAllUsesWith(DummyGV); 2833fe6060f1SDimitry Andric 2834fe6060f1SDimitry Andric Entry->mutateType(PTy); 2835fe6060f1SDimitry Andric llvm::Constant *NewPtrForOldDecl = 2836fe6060f1SDimitry Andric llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast( 2837fe6060f1SDimitry Andric Entry, DummyGV->getType()); 2838fe6060f1SDimitry Andric 2839fe6060f1SDimitry Andric // Now we have a casted version of the changed global, the dummy can be 2840fe6060f1SDimitry Andric // replaced and deleted. 2841fe6060f1SDimitry Andric DummyGV->replaceAllUsesWith(NewPtrForOldDecl); 2842fe6060f1SDimitry Andric DummyGV->eraseFromParent(); 2843fe6060f1SDimitry Andric } 2844fe6060f1SDimitry Andric } 284581ad6265SDimitry Andric 2846bdd1243dSDimitry Andric std::optional<CharUnits> 284781ad6265SDimitry Andric CodeGenModule::getOMPAllocateAlignment(const VarDecl *VD) { 284881ad6265SDimitry Andric if (const auto *AA = VD->getAttr<OMPAllocateDeclAttr>()) { 284981ad6265SDimitry Andric if (Expr *Alignment = AA->getAlignment()) { 285081ad6265SDimitry Andric unsigned UserAlign = 285181ad6265SDimitry Andric Alignment->EvaluateKnownConstInt(getContext()).getExtValue(); 285281ad6265SDimitry Andric CharUnits NaturalAlign = 285381ad6265SDimitry Andric getNaturalTypeAlignment(VD->getType().getNonReferenceType()); 285481ad6265SDimitry Andric 285581ad6265SDimitry Andric // OpenMP5.1 pg 185 lines 7-10 285681ad6265SDimitry Andric // Each item in the align modifier list must be aligned to the maximum 285781ad6265SDimitry Andric // of the specified alignment and the type's natural alignment. 285881ad6265SDimitry Andric return CharUnits::fromQuantity( 285981ad6265SDimitry Andric std::max<unsigned>(UserAlign, NaturalAlign.getQuantity())); 286081ad6265SDimitry Andric } 286181ad6265SDimitry Andric } 2862bdd1243dSDimitry Andric return std::nullopt; 286381ad6265SDimitry Andric } 2864