diff options
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.h')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 543 |
1 files changed, 352 insertions, 191 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 22f6f6c5a56..86154e923eb 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -81,6 +81,8 @@ class CGFunctionInfo; class CGRecordLayout; class CGBlockInfo; class CGCXXABI; +class BlockByrefHelpers; +class BlockByrefInfo; class BlockFlags; class BlockFieldFlags; @@ -160,9 +162,9 @@ public: /// ReturnBlock - Unified return block. JumpDest ReturnBlock; - /// ReturnValue - The temporary alloca to hold the return value. This is null - /// iff the function has no return value. - llvm::Value *ReturnValue; + /// ReturnValue - The temporary alloca to hold the return + /// value. This is invalid iff the function has no return value. + Address ReturnValue; /// AllocaInsertPoint - This is an instruction in the entry block before which /// we prefer to insert allocas. @@ -328,7 +330,7 @@ public: /// A stack of exception code slots. Entering an __except block pushes a slot /// on the stack and leaving pops one. The __exception_code() intrinsic loads /// a value from the top of the stack. - SmallVector<llvm::Value *, 1> SEHCodeSlotStack; + SmallVector<Address, 1> SEHCodeSlotStack; /// Value returned by __exception_info intrinsic. llvm::Value *SEHInfo = nullptr; @@ -420,13 +422,12 @@ public: /// complete-object destructor of an object of the given type at the /// given address. Does nothing if T is not a C++ class type with a /// non-trivial destructor. - void PushDestructorCleanup(QualType T, llvm::Value *Addr); + void PushDestructorCleanup(QualType T, Address Addr); /// PushDestructorCleanup - Push a cleanup to call the /// complete-object variant of the given destructor on the object at /// the given address. - void PushDestructorCleanup(const CXXDestructorDecl *Dtor, - llvm::Value *Addr); + void PushDestructorCleanup(const CXXDestructorDecl *Dtor, Address Addr); /// PopCleanupBlock - Will pop the cleanup entry on the stack and /// process all branch fixups. @@ -556,13 +557,14 @@ public: void rescopeLabels(); }; + typedef llvm::DenseMap<const Decl *, Address> DeclMapTy; + /// \brief The scope used to remap some variables as private in the OpenMP /// loop body (or other captured region emitted without outlining), and to /// restore old vars back on exit. class OMPPrivateScope : public RunCleanupsScope { - typedef llvm::DenseMap<const VarDecl *, llvm::Value *> VarDeclMapTy; - VarDeclMapTy SavedLocals; - VarDeclMapTy SavedPrivates; + DeclMapTy SavedLocals; + DeclMapTy SavedPrivates; private: OMPPrivateScope(const OMPPrivateScope &) = delete; @@ -579,21 +581,30 @@ public: /// been privatized already. bool addPrivate(const VarDecl *LocalVD, - const std::function<llvm::Value *()> &PrivateGen) { + llvm::function_ref<Address()> PrivateGen) { assert(PerformCleanup && "adding private to dead scope"); - if (SavedLocals.count(LocalVD) > 0) return false; - SavedLocals[LocalVD] = CGF.LocalDeclMap.lookup(LocalVD); - CGF.LocalDeclMap.erase(LocalVD); - auto *V = PrivateGen(); + + // Only save it once. + if (SavedLocals.count(LocalVD)) return false; + + // Copy the existing local entry to SavedLocals. + auto it = CGF.LocalDeclMap.find(LocalVD); + if (it != CGF.LocalDeclMap.end()) { + SavedLocals.insert({LocalVD, it->second}); + } else { + SavedLocals.insert({LocalVD, Address::invalid()}); + } + + // Generate the private entry. + Address Addr = PrivateGen(); QualType VarTy = LocalVD->getType(); if (VarTy->isReferenceType()) { - auto *TempAlloca = CGF.CreateMemTemp(VarTy); - LValue RefLVal = CGF.MakeNaturalAlignAddrLValue(TempAlloca, VarTy); - CGF.EmitStoreOfScalar(V, RefLVal); - V = TempAlloca; + Address Temp = CGF.CreateMemTemp(VarTy); + CGF.Builder.CreateStore(Addr.getPointer(), Temp); + Addr = Temp; } - SavedPrivates[LocalVD] = V; - CGF.LocalDeclMap[LocalVD] = SavedLocals[LocalVD]; + SavedPrivates.insert({LocalVD, Addr}); + return true; } @@ -606,19 +617,14 @@ public: /// private copies. /// \return true if at least one variable was privatized, false otherwise. bool Privatize() { - for (auto VDPair : SavedPrivates) { - CGF.LocalDeclMap[VDPair.first] = VDPair.second; - } + copyInto(SavedPrivates, CGF.LocalDeclMap); SavedPrivates.clear(); return !SavedLocals.empty(); } void ForceCleanup() { RunCleanupsScope::ForceCleanup(); - // Remap vars back to the original values. - for (auto I : SavedLocals) { - CGF.LocalDeclMap[I.first] = I.second; - } + copyInto(SavedLocals, CGF.LocalDeclMap); SavedLocals.clear(); } @@ -627,6 +633,25 @@ public: if (PerformCleanup) ForceCleanup(); } + + private: + /// Copy all the entries in the source map over the corresponding + /// entries in the destination, which must exist. + static void copyInto(const DeclMapTy &src, DeclMapTy &dest) { + for (auto &pair : src) { + if (!pair.second.isValid()) { + dest.erase(pair.first); + continue; + } + + auto it = dest.find(pair.first); + if (it != dest.end()) { + it->second = pair.second; + } else { + dest.insert(pair); + } + } + } }; /// \brief Takes the old cleanup stack size and emits the cleanup blocks @@ -707,10 +732,11 @@ public: /// one branch or the other of a conditional expression. bool isInConditionalBranch() const { return OutermostConditional != nullptr; } - void setBeforeOutermostConditional(llvm::Value *value, llvm::Value *addr) { + void setBeforeOutermostConditional(llvm::Value *value, Address addr) { assert(isInConditionalBranch()); llvm::BasicBlock *block = OutermostConditional->getStartingBlock(); - new llvm::StoreInst(value, addr, &block->back()); + auto store = new llvm::StoreInst(value, addr.getPointer(), &block->back()); + store->setAlignment(addr.getAlignment().getQuantity()); } /// An RAII object to record that we're evaluating a statement @@ -869,15 +895,6 @@ public: } }; - /// getByrefValueFieldNumber - Given a declaration, returns the LLVM field - /// number that holds the value. - std::pair<llvm::Type *, unsigned> - getByRefValueLLVMField(const ValueDecl *VD) const; - - /// BuildBlockByrefAddress - Computes address location of the - /// variable which is declared as __block. - llvm::Value *BuildBlockByrefAddress(llvm::Value *BaseAddr, - const VarDecl *V); private: CGDebugInfo *DebugInfo; bool DisableDebugInfo; @@ -894,7 +911,6 @@ private: /// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C /// decls. - typedef llvm::DenseMap<const Decl*, llvm::Value*> DeclMapTy; DeclMapTy LocalDeclMap; /// Track escaped local variables with auto storage. Used during SEH @@ -994,7 +1010,7 @@ public: /// if we need to evaluate a CXXDefaultInitExpr within the evaluation. class FieldConstructionScope { public: - FieldConstructionScope(CodeGenFunction &CGF, llvm::Value *This) + FieldConstructionScope(CodeGenFunction &CGF, Address This) : CGF(CGF), OldCXXDefaultInitExprThis(CGF.CXXDefaultInitExprThis) { CGF.CXXDefaultInitExprThis = This; } @@ -1004,7 +1020,7 @@ public: private: CodeGenFunction &CGF; - llvm::Value *OldCXXDefaultInitExprThis; + Address OldCXXDefaultInitExprThis; }; /// The scope of a CXXDefaultInitExpr. Within this scope, the value of 'this' @@ -1012,16 +1028,20 @@ public: class CXXDefaultInitExprScope { public: CXXDefaultInitExprScope(CodeGenFunction &CGF) - : CGF(CGF), OldCXXThisValue(CGF.CXXThisValue) { - CGF.CXXThisValue = CGF.CXXDefaultInitExprThis; + : CGF(CGF), OldCXXThisValue(CGF.CXXThisValue), + OldCXXThisAlignment(CGF.CXXThisAlignment) { + CGF.CXXThisValue = CGF.CXXDefaultInitExprThis.getPointer(); + CGF.CXXThisAlignment = CGF.CXXDefaultInitExprThis.getAlignment(); } ~CXXDefaultInitExprScope() { CGF.CXXThisValue = OldCXXThisValue; + CGF.CXXThisAlignment = OldCXXThisAlignment; } public: CodeGenFunction &CGF; llvm::Value *OldCXXThisValue; + CharUnits OldCXXThisAlignment; }; private: @@ -1030,10 +1050,12 @@ private: ImplicitParamDecl *CXXABIThisDecl; llvm::Value *CXXABIThisValue; llvm::Value *CXXThisValue; + CharUnits CXXABIThisAlignment; + CharUnits CXXThisAlignment; /// The value of 'this' to use when evaluating CXXDefaultInitExprs within /// this expression. - llvm::Value *CXXDefaultInitExprThis; + Address CXXDefaultInitExprThis = Address::invalid(); /// CXXStructorImplicitParamDecl - When generating code for a constructor or /// destructor, this will hold the implicit argument (e.g. VTT). @@ -1052,10 +1074,9 @@ private: /// handling code. SourceLocation CurEHLocation; - /// ByrefValueInfoMap - For each __block variable, contains a pair of the LLVM - /// type as well as the field number that contains the actual data. - llvm::DenseMap<const ValueDecl *, std::pair<llvm::Type *, - unsigned> > ByRefValueInfo; + /// BlockByrefInfos - For each __block variable, contains + /// information about the layout of the variable. + llvm::DenseMap<const ValueDecl *, BlockByrefInfo> BlockByrefInfos; llvm::BasicBlock *TerminateLandingPad; llvm::BasicBlock *TerminateHandler; @@ -1096,15 +1117,15 @@ public: /// Returns a pointer to the function's exception object and selector slot, /// which is assigned in every landing pad. - llvm::Value *getExceptionSlot(); - llvm::Value *getEHSelectorSlot(); + Address getExceptionSlot(); + Address getEHSelectorSlot(); /// Returns the contents of the function's exception object and selector /// slots. llvm::Value *getExceptionFromSlot(); llvm::Value *getSelectorFromSlot(); - llvm::Value *getNormalCleanupDestSlot(); + Address getNormalCleanupDestSlot(); llvm::BasicBlock *getUnreachableBlock() { if (!UnreachableBlock) { @@ -1131,38 +1152,41 @@ public: // Cleanups //===--------------------------------------------------------------------===// - typedef void Destroyer(CodeGenFunction &CGF, llvm::Value *addr, QualType ty); + typedef void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty); void pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin, - llvm::Value *arrayEndPointer, + Address arrayEndPointer, QualType elementType, + CharUnits elementAlignment, Destroyer *destroyer); void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin, llvm::Value *arrayEnd, QualType elementType, + CharUnits elementAlignment, Destroyer *destroyer); void pushDestroy(QualType::DestructionKind dtorKind, - llvm::Value *addr, QualType type); + Address addr, QualType type); void pushEHDestroy(QualType::DestructionKind dtorKind, - llvm::Value *addr, QualType type); - void pushDestroy(CleanupKind kind, llvm::Value *addr, QualType type, + Address addr, QualType type); + void pushDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray); - void pushLifetimeExtendedDestroy(CleanupKind kind, llvm::Value *addr, + void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray); void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete, llvm::Value *CompletePtr, QualType ElementType); - void pushStackRestore(CleanupKind kind, llvm::Value *SPMem); - void emitDestroy(llvm::Value *addr, QualType type, Destroyer *destroyer, + void pushStackRestore(CleanupKind kind, Address SPMem); + void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray); - llvm::Function *generateDestroyHelper(llvm::Constant *addr, QualType type, + llvm::Function *generateDestroyHelper(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray, const VarDecl *VD); void emitArrayDestroy(llvm::Value *begin, llvm::Value *end, - QualType type, Destroyer *destroyer, + QualType elementType, CharUnits elementAlign, + Destroyer *destroyer, bool checkZeroLength, bool useEHCleanup); Destroyer *getDestroyer(QualType::DestructionKind destructionKind); @@ -1248,15 +1272,25 @@ public: void emitByrefStructureInit(const AutoVarEmission &emission); void enterByrefCleanup(const AutoVarEmission &emission); - llvm::Value *LoadBlockStruct() { - assert(BlockPointer && "no block pointer set!"); - return BlockPointer; - } + void setBlockContextParameter(const ImplicitParamDecl *D, unsigned argNum, + llvm::Value *ptr); + + Address LoadBlockStruct(); void AllocateBlockCXXThisPointer(const CXXThisExpr *E); void AllocateBlockDecl(const DeclRefExpr *E); - llvm::Value *GetAddrOfBlockDecl(const VarDecl *var, bool ByRef); - llvm::Type *BuildByRefType(const VarDecl *var); + Address GetAddrOfBlockDecl(const VarDecl *var, bool ByRef); + + /// BuildBlockByrefAddress - Computes the location of the + /// data in a variable which is declared as __block. + Address emitBlockByrefAddress(Address baseAddr, const VarDecl *V, + bool followForward = true); + Address emitBlockByrefAddress(Address baseAddr, + const BlockByrefInfo &info, + bool followForward, + const llvm::Twine &name); + + const BlockByrefInfo &getBlockByrefInfo(const VarDecl *var); void GenerateCode(GlobalDecl GD, llvm::Function *Fn, const CGFunctionInfo &FnInfo); @@ -1300,6 +1334,8 @@ public: void EmitCallAndReturnForThunk(llvm::Value *Callee, const ThunkInfo *Thunk); + void FinishThunk(); + /// Emit a musttail call for a thunk with a potentially adjusted this pointer. void EmitMustTailThunk(const CXXMethodDecl *MD, llvm::Value *AdjustedThisPtr, llvm::Value *Callee); @@ -1338,7 +1374,7 @@ public: /// GetVTablePtr - Return the Value of the vtable pointer member pointed /// to by This. - llvm::Value *GetVTablePtr(llvm::Value *This, llvm::Type *Ty); + llvm::Value *GetVTablePtr(Address This, llvm::Type *Ty); enum CFITypeCheckKind { CFITCK_VCall, @@ -1505,39 +1541,79 @@ public: // Helpers //===--------------------------------------------------------------------===// - LValue MakeAddrLValue(llvm::Value *V, QualType T, - CharUnits Alignment = CharUnits()) { - return LValue::MakeAddr(V, T, Alignment, getContext(), + LValue MakeAddrLValue(Address Addr, QualType T, + AlignmentSource AlignSource = AlignmentSource::Type) { + return LValue::MakeAddr(Addr, T, getContext(), AlignSource, CGM.getTBAAInfo(T)); } + LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, + AlignmentSource AlignSource = AlignmentSource::Type) { + return LValue::MakeAddr(Address(V, Alignment), T, getContext(), + AlignSource, CGM.getTBAAInfo(T)); + } + + LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T); LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T); + CharUnits getNaturalTypeAlignment(QualType T, + AlignmentSource *Source = nullptr, + bool forPointeeType = false); + CharUnits getNaturalPointeeTypeAlignment(QualType T, + AlignmentSource *Source = nullptr); + + Address EmitLoadOfReference(Address Ref, const ReferenceType *RefTy, + AlignmentSource *Source = nullptr); + LValue EmitLoadOfReferenceLValue(Address Ref, const ReferenceType *RefTy); /// CreateTempAlloca - This creates a alloca and inserts it into the entry /// block. The caller is responsible for setting an appropriate alignment on /// the alloca. llvm::AllocaInst *CreateTempAlloca(llvm::Type *Ty, const Twine &Name = "tmp"); + Address CreateTempAlloca(llvm::Type *Ty, CharUnits align, + const Twine &Name = "tmp"); - /// InitTempAlloca - Provide an initial value for the given alloca. - void InitTempAlloca(llvm::AllocaInst *Alloca, llvm::Value *Value); + /// CreateDefaultAlignedTempAlloca - This creates an alloca with the + /// default ABI alignment of the given LLVM type. + /// + /// IMPORTANT NOTE: This is *not* generally the right alignment for + /// any given AST type that happens to have been lowered to the + /// given IR type. This should only ever be used for function-local, + /// IR-driven manipulations like saving and restoring a value. Do + /// not hand this address off to arbitrary IRGen routines, and especially + /// do not pass it as an argument to a function that might expect a + /// properly ABI-aligned value. + Address CreateDefaultAlignTempAlloca(llvm::Type *Ty, + const Twine &Name = "tmp"); + + /// InitTempAlloca - Provide an initial value for the given alloca which + /// will be observable at all locations in the function. + /// + /// The address should be something that was returned from one of + /// the CreateTempAlloca or CreateMemTemp routines, and the + /// initializer must be valid in the entry block (i.e. it must + /// either be a constant or an argument value). + void InitTempAlloca(Address Alloca, llvm::Value *Value); /// CreateIRTemp - Create a temporary IR object of the given type, with /// appropriate alignment. This routine should only be used when an temporary /// value needs to be stored into an alloca (for example, to avoid explicit /// PHI construction), but the type is the IR type, not the type appropriate /// for storing in memory. - llvm::AllocaInst *CreateIRTemp(QualType T, const Twine &Name = "tmp"); + /// + /// That is, this is exactly equivalent to CreateMemTemp, but calling + /// ConvertType instead of ConvertTypeForMem. + Address CreateIRTemp(QualType T, const Twine &Name = "tmp"); /// CreateMemTemp - Create a temporary memory object of the given type, with /// appropriate alignment. - llvm::AllocaInst *CreateMemTemp(QualType T, const Twine &Name = "tmp"); + Address CreateMemTemp(QualType T, const Twine &Name = "tmp"); + Address CreateMemTemp(QualType T, CharUnits Align, const Twine &Name = "tmp"); /// CreateAggTemp - Create a temporary memory object for the given /// aggregate type. AggValueSlot CreateAggTemp(QualType T, const Twine &Name = "tmp") { - CharUnits Alignment = getContext().getTypeAlignInChars(T); - return AggValueSlot::forAddr(CreateMemTemp(T, Name), Alignment, + return AggValueSlot::forAddr(CreateMemTemp(T, Name), T.getQualifiers(), AggValueSlot::IsNotDestructed, AggValueSlot::DoesNotNeedGCBarriers, @@ -1570,7 +1646,7 @@ public: // EmitVAListRef - Emit a "reference" to a va_list; this is either the address // or the value of the expression, depending on how va_list is defined. - llvm::Value *EmitVAListRef(const Expr *E); + Address EmitVAListRef(const Expr *E); /// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result will /// always be accessible even if no aggregate location is provided. @@ -1578,10 +1654,10 @@ public: /// EmitAnyExprToMem - Emits the code necessary to evaluate an /// arbitrary expression into the given memory location. - void EmitAnyExprToMem(const Expr *E, llvm::Value *Location, + void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer); - void EmitAnyExprToExn(const Expr *E, llvm::Value *Addr); + void EmitAnyExprToExn(const Expr *E, Address Addr); /// EmitExprAsInit - Emits the code necessary to initialize a /// location in memory with the given initializer. @@ -1601,19 +1677,15 @@ public: /// /// The difference to EmitAggregateCopy is that tail padding is not copied. /// This is required for correctness when assigning non-POD structures in C++. - void EmitAggregateAssign(llvm::Value *DestPtr, llvm::Value *SrcPtr, + void EmitAggregateAssign(Address DestPtr, Address SrcPtr, QualType EltTy) { bool IsVolatile = hasVolatileMember(EltTy); - EmitAggregateCopy(DestPtr, SrcPtr, EltTy, IsVolatile, CharUnits::Zero(), - true); + EmitAggregateCopy(DestPtr, SrcPtr, EltTy, IsVolatile, true); } - void EmitAggregateCopyCtor(llvm::Value *DestPtr, llvm::Value *SrcPtr, - QualType DestTy, QualType SrcTy) { - CharUnits DestTypeAlign = getContext().getTypeAlignInChars(DestTy); - CharUnits SrcTypeAlign = getContext().getTypeAlignInChars(SrcTy); + void EmitAggregateCopyCtor(Address DestPtr, Address SrcPtr, + QualType DestTy, QualType SrcTy) { EmitAggregateCopy(DestPtr, SrcPtr, SrcTy, /*IsVolatile=*/false, - std::min(DestTypeAlign, SrcTypeAlign), /*IsAssignment=*/false); } @@ -1623,9 +1695,8 @@ public: /// volatile. /// \param isAssignment - If false, allow padding to be copied. This often /// yields more efficient. - void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr, + void EmitAggregateCopy(Address DestPtr, Address SrcPtr, QualType EltTy, bool isVolatile=false, - CharUnits Alignment = CharUnits::Zero(), bool isAssignment = false); /// StartBlock - Start new block named N. If insert block is a dummy block @@ -1633,10 +1704,11 @@ public: void StartBlock(const char *N); /// GetAddrOfLocalVar - Return the address of a local variable. - llvm::Value *GetAddrOfLocalVar(const VarDecl *VD) { - llvm::Value *Res = LocalDeclMap[VD]; - assert(Res && "Invalid argument to GetAddrOfLocalVar(), no decl!"); - return Res; + Address GetAddrOfLocalVar(const VarDecl *VD) { + auto it = LocalDeclMap.find(VD); + assert(it != LocalDeclMap.end() && + "Invalid argument to GetAddrOfLocalVar(), no decl!"); + return it->second; } /// getOpaqueLValueMapping - Given an opaque value expression (which @@ -1671,19 +1743,19 @@ public: /// EmitNullInitialization - Generate code to set a value of the given type to /// null, If the type contains data member pointers, they will be initialized /// to -1 in accordance with the Itanium C++ ABI. - void EmitNullInitialization(llvm::Value *DestPtr, QualType Ty); + void EmitNullInitialization(Address DestPtr, QualType Ty); // EmitVAArg - Generate code to get an argument from the passed in pointer // and update it accordingly. The return value is a pointer to the argument. // FIXME: We should be able to get rid of this method and use the va_arg // instruction in LLVM instead once it works well enough. - llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty); + Address EmitVAArg(Address VAListAddr, QualType Ty); /// emitArrayLength - Compute the length of an array, even if it's a /// VLA, and drill down to the base element type. llvm::Value *emitArrayLength(const ArrayType *arrayType, QualType &baseType, - llvm::Value *&addr); + Address &addr); /// EmitVLASize - Capture all the sizes for the VLA expressions in /// the given variably-modified type and store them in the VLASizeMap. @@ -1704,6 +1776,7 @@ public: assert(CXXThisValue && "no 'this' value for this function"); return CXXThisValue; } + Address LoadCXXThisAddress(); /// LoadCXXVTT - Load the VTT parameter to base constructors/destructors have /// virtual bases. @@ -1724,25 +1797,27 @@ public: /// GetAddressOfBaseOfCompleteClass - Convert the given pointer to a /// complete class to the given direct base. - llvm::Value * - GetAddressOfDirectBaseInCompleteClass(llvm::Value *Value, + Address + GetAddressOfDirectBaseInCompleteClass(Address Value, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, bool BaseIsVirtual); + static bool ShouldNullCheckClassCastValue(const CastExpr *Cast); + /// GetAddressOfBaseClass - This function will add the necessary delta to the /// load of 'this' and returns address of the base class. - llvm::Value *GetAddressOfBaseClass(llvm::Value *Value, - const CXXRecordDecl *Derived, - CastExpr::path_const_iterator PathBegin, - CastExpr::path_const_iterator PathEnd, - bool NullCheckValue, SourceLocation Loc); - - llvm::Value *GetAddressOfDerivedClass(llvm::Value *Value, - const CXXRecordDecl *Derived, - CastExpr::path_const_iterator PathBegin, - CastExpr::path_const_iterator PathEnd, - bool NullCheckValue); + Address GetAddressOfBaseClass(Address Value, + const CXXRecordDecl *Derived, + CastExpr::path_const_iterator PathBegin, + CastExpr::path_const_iterator PathEnd, + bool NullCheckValue, SourceLocation Loc); + + Address GetAddressOfDerivedClass(Address Value, + const CXXRecordDecl *Derived, + CastExpr::path_const_iterator PathBegin, + CastExpr::path_const_iterator PathEnd, + bool NullCheckValue); /// GetVTTParameter - Return the VTT parameter that should be passed to a /// base constructor/destructor with virtual bases. @@ -1763,21 +1838,21 @@ public: const FunctionArgList &Args); void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, - llvm::Value *This, const CXXConstructExpr *E); + Address This, const CXXConstructExpr *E); void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, - llvm::Value *This, llvm::Value *Src, - const CXXConstructExpr *E); + Address This, Address Src, + const CXXConstructExpr *E); void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, const ConstantArrayType *ArrayTy, - llvm::Value *ArrayPtr, + Address ArrayPtr, const CXXConstructExpr *E, bool ZeroInitialization = false); void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, llvm::Value *NumElements, - llvm::Value *ArrayPtr, + Address ArrayPtr, const CXXConstructExpr *E, bool ZeroInitialization = false); @@ -1785,15 +1860,15 @@ public: void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, - llvm::Value *This); + Address This); void EmitNewArrayInitializer(const CXXNewExpr *E, QualType elementType, - llvm::Type *ElementTy, llvm::Value *NewPtr, + llvm::Type *ElementTy, Address NewPtr, llvm::Value *NumElements, llvm::Value *AllocSizeWithoutCookie); void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType, - llvm::Value *Ptr); + Address Ptr); llvm::Value *EmitLifetimeStart(uint64_t Size, llvm::Value *Addr); void EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr); @@ -1807,9 +1882,9 @@ public: RValue EmitBuiltinNewDeleteCall(const FunctionProtoType *Type, const Expr *Arg, bool IsDelete); - llvm::Value* EmitCXXTypeidExpr(const CXXTypeidExpr *E); - llvm::Value *EmitDynamicCast(llvm::Value *V, const CXXDynamicCastExpr *DCE); - llvm::Value* EmitCXXUuidofExpr(const CXXUuidofExpr *E); + llvm::Value *EmitCXXTypeidExpr(const CXXTypeidExpr *E); + llvm::Value *EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE); + Address EmitCXXUuidofExpr(const CXXUuidofExpr *E); /// \brief Situations in which we might emit a check for the suitability of a /// pointer or glvalue. @@ -1906,12 +1981,9 @@ public: const VarDecl *Variable; - /// The alignment of the variable. - CharUnits Alignment; - - /// The address of the alloca. Null if the variable was emitted + /// The address of the alloca. Invalid if the variable was emitted /// as a global constant. - llvm::Value *Address; + Address Addr; llvm::Value *NRVOFlag; @@ -1926,14 +1998,14 @@ public: llvm::Value *SizeForLifetimeMarkers; struct Invalid {}; - AutoVarEmission(Invalid) : Variable(nullptr) {} + AutoVarEmission(Invalid) : Variable(nullptr), Addr(Address::invalid()) {} AutoVarEmission(const VarDecl &variable) - : Variable(&variable), Address(nullptr), NRVOFlag(nullptr), + : Variable(&variable), Addr(Address::invalid()), NRVOFlag(nullptr), IsByRef(false), IsConstantAggregate(false), SizeForLifetimeMarkers(nullptr) {} - bool wasEmittedAsGlobal() const { return Address == nullptr; } + bool wasEmittedAsGlobal() const { return !Addr.isValid(); } public: static AutoVarEmission invalid() { return AutoVarEmission(Invalid()); } @@ -1948,19 +2020,17 @@ public: /// Returns the raw, allocated address, which is not necessarily /// the address of the object itself. - llvm::Value *getAllocatedAddress() const { - return Address; + Address getAllocatedAddress() const { + return Addr; } /// Returns the address of the object within this declaration. /// Note that this does not chase the forwarding pointer for /// __block decls. - llvm::Value *getObjectAddress(CodeGenFunction &CGF) const { - if (!IsByRef) return Address; + Address getObjectAddress(CodeGenFunction &CGF) const { + if (!IsByRef) return Addr; - auto F = CGF.getByRefValueLLVMField(Variable); - return CGF.Builder.CreateStructGEP(F.first, Address, F.second, - Variable->getNameAsString()); + return CGF.emitBlockByrefAddress(Addr, Variable, /*forward*/ false); } }; AutoVarEmission EmitAutoVarAlloca(const VarDecl &var); @@ -1972,9 +2042,35 @@ public: void EmitStaticVarDecl(const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage); + class ParamValue { + llvm::Value *Value; + unsigned Alignment; + ParamValue(llvm::Value *V, unsigned A) : Value(V), Alignment(A) {} + public: + static ParamValue forDirect(llvm::Value *value) { + return ParamValue(value, 0); + } + static ParamValue forIndirect(Address addr) { + assert(!addr.getAlignment().isZero()); + return ParamValue(addr.getPointer(), addr.getAlignment().getQuantity()); + } + + bool isIndirect() const { return Alignment != 0; } + llvm::Value *getAnyValue() const { return Value; } + + llvm::Value *getDirectValue() const { + assert(!isIndirect()); + return Value; + } + + Address getIndirectAddress() const { + assert(isIndirect()); + return Address(Value, CharUnits::fromQuantity(Alignment)); + } + }; + /// EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl. - void EmitParmDecl(const VarDecl &D, llvm::Value *Arg, bool ArgIsPointer, - unsigned ArgNo); + void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo); /// protectFromPeepholes - Protect a value that we're intending to /// store to the side, but which will probably be used later, from @@ -2011,11 +2107,11 @@ public: /// \return True if the statement was handled. bool EmitSimpleStmt(const Stmt *S); - llvm::Value *EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false, - AggValueSlot AVS = AggValueSlot::ignored()); - llvm::Value *EmitCompoundStmtWithoutScope(const CompoundStmt &S, - bool GetLast = false, - AggValueSlot AVS = + Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false, + AggValueSlot AVS = AggValueSlot::ignored()); + Address EmitCompoundStmtWithoutScope(const CompoundStmt &S, + bool GetLast = false, + AggValueSlot AVS = AggValueSlot::ignored()); /// EmitLabel - Emit the block for the given label. It is legal to call this @@ -2085,9 +2181,9 @@ public: /// either be an alloca or a call to llvm.localrecover if there are nested /// outlined functions. ParentFP is the frame pointer of the outermost parent /// frame. - llvm::Value *recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, - llvm::Value *ParentVar, - llvm::Value *ParentFP); + Address recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, + Address ParentVar, + llvm::Value *ParentFP); void EmitCXXForRangeStmt(const CXXForRangeStmt &S, ArrayRef<const Attr *> Attrs = None); @@ -2097,7 +2193,7 @@ public: void GenerateCapturedStmtFunctionProlog(const CapturedStmt &S); llvm::Function *GenerateCapturedStmtFunctionEpilog(const CapturedStmt &S); llvm::Function *GenerateCapturedStmtFunction(const CapturedStmt &S); - llvm::Value *GenerateCapturedStmtArgument(const CapturedStmt &S); + Address GenerateCapturedStmtArgument(const CapturedStmt &S); /// \brief Perform element by element copying of arrays with type \a /// OriginalType from \a SrcAddr to \a DestAddr using copying procedure /// generated by \a CopyGen. @@ -2108,8 +2204,8 @@ public: /// \param CopyGen Copying procedure that copies value of single array element /// to another single array element. void EmitOMPAggregateAssign( - llvm::Value *DestAddr, llvm::Value *SrcAddr, QualType OriginalType, - const llvm::function_ref<void(llvm::Value *, llvm::Value *)> &CopyGen); + Address DestAddr, Address SrcAddr, QualType OriginalType, + const llvm::function_ref<void(Address, Address)> &CopyGen); /// \brief Emit proper copying of data from one variable to another. /// /// \param OriginalType Original type of the copied variables. @@ -2121,8 +2217,8 @@ public: /// the base array element). /// \param Copy Actual copygin expression for copying data from \a SrcVD to \a /// DestVD. - void EmitOMPCopy(CodeGenFunction &CGF, QualType OriginalType, - llvm::Value *DestAddr, llvm::Value *SrcAddr, + void EmitOMPCopy(QualType OriginalType, + Address DestAddr, Address SrcAddr, const VarDecl *DestVD, const VarDecl *SrcVD, const Expr *Copy); /// \brief Emit atomic update code for constructs: \a X = \a X \a BO \a E or @@ -2258,8 +2354,8 @@ private: void EmitOMPForOuterLoop(OpenMPScheduleClauseKind ScheduleKind, const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered, - llvm::Value *LB, llvm::Value *UB, llvm::Value *ST, - llvm::Value *IL, llvm::Value *Chunk); + Address LB, Address UB, Address ST, + Address IL, llvm::Value *Chunk); /// \brief Emit code for sections directive. OpenMPDirectiveKind EmitSections(const OMPExecutableDirective &S); @@ -2306,7 +2402,7 @@ public: /// that the address will be used to access the object. LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK); - RValue convertTempToRValue(llvm::Value *addr, QualType type, + RValue convertTempToRValue(Address addr, QualType type, SourceLocation Loc); void EmitAtomicInit(Expr *E, LValue lvalue); @@ -2347,9 +2443,10 @@ public: /// EmitLoadOfScalar - Load a scalar value from an address, taking /// care to appropriately convert from the memory representation to /// the LLVM value representation. - llvm::Value *EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, - unsigned Alignment, QualType Ty, + llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, + AlignmentSource AlignSource = + AlignmentSource::Type, llvm::MDNode *TBAAInfo = nullptr, QualType TBAABaseTy = QualType(), uint64_t TBAAOffset = 0); @@ -2363,8 +2460,9 @@ public: /// EmitStoreOfScalar - Store a scalar value to an address, taking /// care to appropriately convert from the memory representation to /// the LLVM value representation. - void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, - bool Volatile, unsigned Alignment, QualType Ty, + void EmitStoreOfScalar(llvm::Value *Value, Address Addr, + bool Volatile, QualType Ty, + AlignmentSource AlignSource = AlignmentSource::Type, llvm::MDNode *TBAAInfo = nullptr, bool isInit = false, QualType TBAABaseTy = QualType(), uint64_t TBAAOffset = 0); @@ -2433,10 +2531,13 @@ public: LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E); LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e); - llvm::Value *EmitExtVectorElementLValue(LValue V); + Address EmitExtVectorElementLValue(LValue V); RValue EmitRValueForField(LValue LV, const FieldDecl *FD, SourceLocation Loc); + Address EmitArrayToPointerDecay(const Expr *Array, + AlignmentSource *AlignSource = nullptr); + class ConstantEmission { llvm::PointerIntPair<llvm::Constant*, 1, bool> ValueAndIsReference; ConstantEmission(llvm::Constant *C, bool isReference) @@ -2576,6 +2677,10 @@ public: NestedNameSpecifier *Qualifier, bool IsArrow, const Expr *Base); // Compute the object pointer. + Address EmitCXXMemberDataPointerAddress(const Expr *E, Address base, + llvm::Value *memberPtr, + const MemberPointerType *memberPtrType, + AlignmentSource *AlignSource = nullptr); RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, ReturnValueSlot ReturnValue); @@ -2610,7 +2715,7 @@ public: unsigned Modifier, const CallExpr *E, SmallVectorImpl<llvm::Value *> &Ops, - llvm::Value *Align = nullptr); + Address PtrOp0, Address PtrOp1); llvm::Function *LookupNeonLLVMIntrinsic(unsigned IntrinsicID, unsigned Modifier, llvm::Type *ArgTy, const CallExpr *E); @@ -2656,24 +2761,23 @@ public: } // ARC primitives. - void EmitARCInitWeak(llvm::Value *value, llvm::Value *addr); - void EmitARCDestroyWeak(llvm::Value *addr); - llvm::Value *EmitARCLoadWeak(llvm::Value *addr); - llvm::Value *EmitARCLoadWeakRetained(llvm::Value *addr); - llvm::Value *EmitARCStoreWeak(llvm::Value *value, llvm::Value *addr, - bool ignored); - void EmitARCCopyWeak(llvm::Value *dst, llvm::Value *src); - void EmitARCMoveWeak(llvm::Value *dst, llvm::Value *src); + void EmitARCInitWeak(Address addr, llvm::Value *value); + void EmitARCDestroyWeak(Address addr); + llvm::Value *EmitARCLoadWeak(Address addr); + llvm::Value *EmitARCLoadWeakRetained(Address addr); + llvm::Value *EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored); + void EmitARCCopyWeak(Address dst, Address src); + void EmitARCMoveWeak(Address dst, Address src); llvm::Value *EmitARCRetainAutorelease(QualType type, llvm::Value *value); llvm::Value *EmitARCRetainAutoreleaseNonBlock(llvm::Value *value); llvm::Value *EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored); - llvm::Value *EmitARCStoreStrongCall(llvm::Value *addr, llvm::Value *value, + llvm::Value *EmitARCStoreStrongCall(Address addr, llvm::Value *value, bool resultIgnored); llvm::Value *EmitARCRetain(QualType type, llvm::Value *value); llvm::Value *EmitARCRetainNonBlock(llvm::Value *value); llvm::Value *EmitARCRetainBlock(llvm::Value *value, bool mandatory); - void EmitARCDestroyStrong(llvm::Value *addr, ARCPreciseLifetime_t precise); + void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise); void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise); llvm::Value *EmitARCAutorelease(llvm::Value *value); llvm::Value *EmitARCAutoreleaseReturnValue(llvm::Value *value); @@ -2765,6 +2869,9 @@ public: /// EmitLoadOfComplex - Load a complex number from the specified l-value. ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc); + Address emitAddrOfRealComponent(Address complex, QualType complexType); + Address emitAddrOfImagComponent(Address complex, QualType complexType); + /// AddInitializerToStaticVarDecl - Add the initializer for 'D' to the /// global variable that has already been created for it. If the initializer /// has a different type than GV does, this may free GV and return a different @@ -2799,7 +2906,7 @@ public: /// variables. void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef<llvm::Function *> CXXThreadLocals, - llvm::GlobalVariable *Guard = nullptr); + Address Guard = Address::invalid()); /// GenerateCXXGlobalDtorsFunc - Generates code for destroying global /// variables. @@ -2814,8 +2921,7 @@ public: void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest); - void EmitSynthesizedCXXCopyCtor(llvm::Value *Dest, llvm::Value *Src, - const Expr *Exp); + void EmitSynthesizedCXXCopyCtor(Address Dest, Address Src, const Expr *Exp); void enterFullExpression(const ExprWithCleanups *E) { if (E->getNumObjects() == 0) return; @@ -2827,7 +2933,7 @@ public: void EmitLambdaExpr(const LambdaExpr *E, AggValueSlot Dest); - RValue EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest = nullptr); + RValue EmitAtomicExpr(AtomicExpr *E, Address Dest = Address::invalid()); //===--------------------------------------------------------------------===// // Annotations Emission @@ -2844,7 +2950,7 @@ public: /// Emit field annotations for the given field & value. Returns the /// annotation result. - llvm::Value *EmitFieldAnnotations(const FieldDecl *D, llvm::Value *V); + Address EmitFieldAnnotations(const FieldDecl *D, Address V); //===--------------------------------------------------------------------===// // Internal Helpers @@ -2932,6 +3038,12 @@ private: llvm::SmallVector<std::pair<llvm::Instruction *, llvm::Value *>, 4> DeferredReplacements; + /// Set the address of a local variable. + void setAddrOfLocalVar(const VarDecl *VD, Address Addr) { + assert(!LocalDeclMap.count(VD) && "Decl already exists in LocalDeclMap!"); + LocalDeclMap.insert({VD, Addr}); + } + /// ExpandTypeFromArgs - Reconstruct a structure of type \arg Ty /// from function arguments into \arg Dst. See ABIArgInfo::Expand. /// @@ -3028,6 +3140,30 @@ public: const FunctionDecl *CalleeDecl = nullptr, unsigned ParamsToSkip = 0); + /// EmitPointerWithAlignment - Given an expression with a pointer + /// type, emit the value and compute our best estimate of the + /// alignment of the pointee. + /// + /// Note that this function will conservatively fall back on the type + /// when it doesn't + /// + /// \param Source - If non-null, this will be initialized with + /// information about the source of the alignment. Note that this + /// function will conservatively fall back on the type when it + /// doesn't recognize the expression, which means that sometimes + /// + /// a worst-case One + /// reasonable way to use this information is when there's a + /// language guarantee that the pointer must be aligned to some + /// stricter value, and we're simply trying to ensure that + /// sufficiently obvious uses of under-aligned objects don't get + /// miscompiled; for example, a placement new into the address of + /// a local variable. In such a case, it's quite reasonable to + /// just ignore the returned alignment when it isn't from an + /// explicit source. + Address EmitPointerWithAlignment(const Expr *Addr, + AlignmentSource *Source = nullptr); + private: QualType getVarArgType(const Expr *Arg); @@ -3037,16 +3173,11 @@ private: void EmitDeclMetadata(); - CodeGenModule::ByrefHelpers * - buildByrefHelpers(llvm::StructType &byrefType, - const AutoVarEmission &emission); + BlockByrefHelpers *buildByrefHelpers(llvm::StructType &byrefType, + const AutoVarEmission &emission); void AddObjCARCExceptionMetadata(llvm::Instruction *Inst); - /// GetPointeeAlignment - Given an expression with a pointer type, emit the - /// value and compute our best estimate of the alignment of the pointee. - std::pair<llvm::Value*, unsigned> EmitPointerWithAlignment(const Expr *Addr); - llvm::Value *GetValueForARMHint(unsigned BuiltinID); }; @@ -3069,17 +3200,23 @@ struct DominatingLLVMValue { static saved_type save(CodeGenFunction &CGF, llvm::Value *value) { if (!needsSaving(value)) return saved_type(value, false); - // Otherwise we need an alloca. - llvm::Value *alloca = - CGF.CreateTempAlloca(value->getType(), "cond-cleanup.save"); + // Otherwise, we need an alloca. + auto align = CharUnits::fromQuantity( + CGF.CGM.getDataLayout().getPrefTypeAlignment(value->getType())); + Address alloca = + CGF.CreateTempAlloca(value->getType(), align, "cond-cleanup.save"); CGF.Builder.CreateStore(value, alloca); - return saved_type(alloca, true); + return saved_type(alloca.getPointer(), true); } static llvm::Value *restore(CodeGenFunction &CGF, saved_type value) { + // If the value says it wasn't saved, trust that it's still dominating. if (!value.getInt()) return value.getPointer(); - return CGF.Builder.CreateLoad(value.getPointer()); + + // Otherwise, it should be an alloca instruction, as set up in save(). + auto alloca = cast<llvm::AllocaInst>(value.getPointer()); + return CGF.Builder.CreateAlignedLoad(alloca, alloca->getAlignment()); } }; @@ -3092,6 +3229,28 @@ template <class T> struct DominatingPointer<T,true> : DominatingLLVMValue { } }; +/// A specialization of DominatingValue for Address. +template <> struct DominatingValue<Address> { + typedef Address type; + + struct saved_type { + DominatingLLVMValue::saved_type SavedValue; + CharUnits Alignment; + }; + + static bool needsSaving(type value) { + return DominatingLLVMValue::needsSaving(value.getPointer()); + } + static saved_type save(CodeGenFunction &CGF, type value) { + return { DominatingLLVMValue::save(CGF, value.getPointer()), + value.getAlignment() }; + } + static type restore(CodeGenFunction &CGF, saved_type value) { + return Address(DominatingLLVMValue::restore(CGF, value.SavedValue), + value.Alignment); + } +}; + /// A specialization of DominatingValue for RValue. template <> struct DominatingValue<RValue> { typedef RValue type; @@ -3100,15 +3259,17 @@ template <> struct DominatingValue<RValue> { AggregateAddress, ComplexAddress }; llvm::Value *Value; - Kind K; - saved_type(llvm::Value *v, Kind k) : Value(v), K(k) {} + unsigned K : 3; + unsigned Align : 29; + saved_type(llvm::Value *v, Kind k, unsigned a = 0) + : Value(v), K(k), Align(a) {} public: static bool needsSaving(RValue value); static saved_type save(CodeGenFunction &CGF, RValue value); RValue restore(CodeGenFunction &CGF); - // implementations in CGExprCXX.cpp + // implementations in CGCleanup.cpp }; static bool needsSaving(type value) { |