diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h | 413 |
1 files changed, 272 insertions, 141 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h index db291e3..59cc30d 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h @@ -16,9 +16,11 @@ #include "CGBuilder.h" #include "CGDebugInfo.h" +#include "CGLoopInfo.h" #include "CGValue.h" -#include "EHScopeStack.h" #include "CodeGenModule.h" +#include "CodeGenPGO.h" +#include "EHScopeStack.h" #include "clang/AST/CharUnits.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" @@ -30,55 +32,55 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/IR/ValueHandle.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/ValueHandle.h" namespace llvm { - class BasicBlock; - class LLVMContext; - class MDNode; - class Module; - class SwitchInst; - class Twine; - class Value; - class CallSite; +class BasicBlock; +class LLVMContext; +class MDNode; +class Module; +class SwitchInst; +class Twine; +class Value; +class CallSite; } namespace clang { - class ASTContext; - class BlockDecl; - class CXXDestructorDecl; - class CXXForRangeStmt; - class CXXTryStmt; - class Decl; - class LabelDecl; - class EnumConstantDecl; - class FunctionDecl; - class FunctionProtoType; - class LabelStmt; - class ObjCContainerDecl; - class ObjCInterfaceDecl; - class ObjCIvarDecl; - class ObjCMethodDecl; - class ObjCImplementationDecl; - class ObjCPropertyImplDecl; - class TargetInfo; - class TargetCodeGenInfo; - class VarDecl; - class ObjCForCollectionStmt; - class ObjCAtTryStmt; - class ObjCAtThrowStmt; - class ObjCAtSynchronizedStmt; - class ObjCAutoreleasePoolStmt; +class ASTContext; +class BlockDecl; +class CXXDestructorDecl; +class CXXForRangeStmt; +class CXXTryStmt; +class Decl; +class LabelDecl; +class EnumConstantDecl; +class FunctionDecl; +class FunctionProtoType; +class LabelStmt; +class ObjCContainerDecl; +class ObjCInterfaceDecl; +class ObjCIvarDecl; +class ObjCMethodDecl; +class ObjCImplementationDecl; +class ObjCPropertyImplDecl; +class TargetInfo; +class TargetCodeGenInfo; +class VarDecl; +class ObjCForCollectionStmt; +class ObjCAtTryStmt; +class ObjCAtThrowStmt; +class ObjCAtSynchronizedStmt; +class ObjCAutoreleasePoolStmt; namespace CodeGen { - class CodeGenTypes; - class CGFunctionInfo; - class CGRecordLayout; - class CGBlockInfo; - class CGCXXABI; - class BlockFlags; - class BlockFieldFlags; +class CodeGenTypes; +class CGFunctionInfo; +class CGRecordLayout; +class CGBlockInfo; +class CGCXXABI; +class BlockFlags; +class BlockFieldFlags; /// The kind of evaluation to perform on values of a particular /// type. Basically, is the code in CGExprScalar, CGExprComplex, or @@ -91,6 +93,19 @@ enum TypeEvaluationKind { TEK_Aggregate }; +class SuppressDebugLocation { + llvm::DebugLoc CurLoc; + llvm::IRBuilderBase &Builder; +public: + SuppressDebugLocation(llvm::IRBuilderBase &Builder) + : CurLoc(Builder.getCurrentDebugLocation()), Builder(Builder) { + Builder.SetCurrentDebugLocation(llvm::DebugLoc()); + } + ~SuppressDebugLocation() { + Builder.SetCurrentDebugLocation(CurLoc); + } +}; + /// CodeGenFunction - This class organizes the per-function state that is used /// while generating LLVM code. class CodeGenFunction : public CodeGenTypeCache { @@ -102,13 +117,13 @@ public: /// A jump destination is an abstract label, branching to which may /// require a jump out through normal cleanups. struct JumpDest { - JumpDest() : Block(0), ScopeDepth(), Index(0) {} + JumpDest() : Block(nullptr), ScopeDepth(), Index(0) {} JumpDest(llvm::BasicBlock *Block, EHScopeStack::stable_iterator Depth, unsigned Index) : Block(Block), ScopeDepth(Depth), Index(Index) {} - bool isValid() const { return Block != 0; } + bool isValid() const { return Block != nullptr; } llvm::BasicBlock *getBlock() const { return Block; } EHScopeStack::stable_iterator getScopeDepth() const { return ScopeDepth; } unsigned getDestIndex() const { return Index; } @@ -128,8 +143,15 @@ public: const TargetInfo &Target; typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy; + LoopInfoStack LoopStack; CGBuilderTy Builder; + /// \brief CGBuilder insert helper. This function is called after an + /// instruction is created using Builder. + void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, + llvm::BasicBlock *BB, + llvm::BasicBlock::iterator InsertPt) const; + /// CurFuncDecl - Holds the Decl for the current outermost /// non-closure context. const Decl *CurFuncDecl; @@ -162,7 +184,7 @@ public: public: explicit CGCapturedStmtInfo(const CapturedStmt &S, CapturedRegionKind K = CR_Default) - : Kind(K), ThisValue(0), CXXThisFieldDecl(0) { + : Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) { RecordDecl::field_iterator Field = S.getCapturedRecordDecl()->field_begin(); @@ -189,11 +211,13 @@ public: return CaptureFields.lookup(VD); } - bool isCXXThisExprCaptured() const { return CXXThisFieldDecl != 0; } + bool isCXXThisExprCaptured() const { return CXXThisFieldDecl != nullptr; } FieldDecl *getThisFieldDecl() const { return CXXThisFieldDecl; } /// \brief Emit the captured statement body. virtual void EmitBody(CodeGenFunction &CGF, Stmt *S) { + RegionCounter Cnt = CGF.getPGORegionCounter(S); + Cnt.beginRegion(CGF.Builder); CGF.EmitStmt(S); } @@ -220,13 +244,20 @@ public: /// potentially higher performance penalties. unsigned char BoundsChecking; - /// \brief Whether any type-checking sanitizers are enabled. If \c false, - /// calls to EmitTypeCheck can be skipped. - bool SanitizePerformTypeCheck; - /// \brief Sanitizer options to use for this function. const SanitizerOptions *SanOpts; + /// \brief True if CodeGen currently emits code implementing sanitizer checks. + bool IsSanitizerScope; + + /// \brief RAII object to set/unset CodeGenFunction::IsSanitizerScope. + class SanitizerScope { + CodeGenFunction *CGF; + public: + SanitizerScope(CodeGenFunction *CGF); + ~SanitizerScope(); + }; + /// In ARC, whether we should autorelease the return value. bool AutoreleaseResult; @@ -608,9 +639,9 @@ public: } void end(CodeGenFunction &CGF) { - assert(CGF.OutermostConditional != 0); + assert(CGF.OutermostConditional != nullptr); if (CGF.OutermostConditional == this) - CGF.OutermostConditional = 0; + CGF.OutermostConditional = nullptr; } /// Returns a block which will be executed prior to each @@ -622,7 +653,7 @@ public: /// isInConditionalBranch - Return true if we're currently emitting /// one branch or the other of a conditional expression. - bool isInConditionalBranch() const { return OutermostConditional != 0; } + bool isInConditionalBranch() const { return OutermostConditional != nullptr; } void setBeforeOutermostConditional(llvm::Value *value, llvm::Value *addr) { assert(isInConditionalBranch()); @@ -643,7 +674,7 @@ public: public: StmtExprEvaluation(CodeGenFunction &CGF) : CGF(CGF), SavedOutermostConditional(CGF.OutermostConditional) { - CGF.OutermostConditional = 0; + CGF.OutermostConditional = nullptr; } ~StmtExprEvaluation() { @@ -660,7 +691,7 @@ public: friend class CodeGenFunction; public: - PeepholeProtection() : Inst(0) {} + PeepholeProtection() : Inst(nullptr) {} }; /// A non-RAII class containing all the information about a bound @@ -678,7 +709,7 @@ public: bool boundLValue) : OpaqueValue(ov), BoundLValue(boundLValue) {} public: - OpaqueValueMappingData() : OpaqueValue(0) {} + OpaqueValueMappingData() : OpaqueValue(nullptr) {} static bool shouldBindAsLValue(const Expr *expr) { // gl-values should be bound as l-values for obvious reasons. @@ -687,8 +718,8 @@ public: // act exactly like l-values but are formally required to be // r-values in C. return expr->isGLValue() || - expr->getType()->isRecordType() || - expr->getType()->isFunctionType(); + expr->getType()->isFunctionType() || + hasAggregateEvaluationKind(expr->getType()); } static OpaqueValueMappingData bind(CodeGenFunction &CGF, @@ -723,8 +754,8 @@ public: return data; } - bool isValid() const { return OpaqueValue != 0; } - void clear() { OpaqueValue = 0; } + bool isValid() const { return OpaqueValue != nullptr; } + void clear() { OpaqueValue = nullptr; } void unbind(CodeGenFunction &CGF) { assert(OpaqueValue && "no data to unbind!"); @@ -827,9 +858,21 @@ private: }; SmallVector<BreakContinue, 8> BreakContinueStack; + CodeGenPGO PGO; + +public: + /// Get a counter for instrumentation of the region associated with the given + /// statement. + RegionCounter getPGORegionCounter(const Stmt *S) { + return RegionCounter(PGO, S); + } +private: + /// SwitchInsn - This is nearest current switch instruction. It is null if /// current context is not in a switch. llvm::SwitchInst *SwitchInsn; + /// The branch weights of SwitchInsn when doing instrumentation based PGO. + SmallVector<uint64_t, 16> *SwitchWeights; /// CaseRangeBlock - This block holds if condition check for last case /// statement range in current switch instruction. @@ -955,7 +998,7 @@ public: ASTContext &getContext() const { return CGM.getContext(); } CGDebugInfo *getDebugInfo() { if (DisableDebugInfo) - return NULL; + return nullptr; return DebugInfo; } void disableDebugInfo() { DisableDebugInfo = true; } @@ -988,7 +1031,7 @@ public: } llvm::BasicBlock *getInvokeDest() { - if (!EHStack.requiresLandingPad()) return 0; + if (!EHStack.requiresLandingPad()) return nullptr; return getInvokeDestImpl(); } @@ -1019,6 +1062,7 @@ public: void pushLifetimeExtendedDestroy(CleanupKind kind, llvm::Value *addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray); + void pushStackRestore(CleanupKind kind, llvm::Value *SPMem); void emitDestroy(llvm::Value *addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray); llvm::Function *generateDestroyHelper(llvm::Constant *addr, QualType type, @@ -1126,17 +1170,22 @@ public: void GenerateCode(GlobalDecl GD, llvm::Function *Fn, const CGFunctionInfo &FnInfo); + /// \brief Emit code for the start of a function. + /// \param Loc The location to be associated with the function. + /// \param StartLoc The location of the function body. void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, - SourceLocation StartLoc); + SourceLocation Loc = SourceLocation(), + SourceLocation StartLoc = SourceLocation()); void EmitConstructorBody(FunctionArgList &Args); void EmitDestructorBody(FunctionArgList &Args); void emitImplicitAssignmentOperatorBody(FunctionArgList &Args); void EmitFunctionBody(FunctionArgList &Args, const Stmt *Body); + void EmitBlockWithFallThrough(llvm::BasicBlock *BB, RegionCounter &Cnt); void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator, CallArgList &CallArgs); @@ -1270,8 +1319,8 @@ public: /// createBasicBlock - Create an LLVM basic block. llvm::BasicBlock *createBasicBlock(const Twine &name = "", - llvm::Function *parent = 0, - llvm::BasicBlock *before = 0) { + llvm::Function *parent = nullptr, + llvm::BasicBlock *before = nullptr) { #ifdef NDEBUG return llvm::BasicBlock::Create(getLLVMContext(), "", parent, before); #else @@ -1315,7 +1364,7 @@ public: /// HaveInsertPoint - True if an insertion point is defined. If not, this /// indicates that the current code being emitted is unreachable. bool HaveInsertPoint() const { - return Builder.GetInsertBlock() != 0; + return Builder.GetInsertBlock() != nullptr; } /// EnsureInsertPoint - Ensure that an insertion point is defined so that @@ -1380,6 +1429,10 @@ public: AggValueSlot::IsNotAliased); } + /// CreateInAllocaTmp - Create a temporary memory object for the given + /// aggregate type. + AggValueSlot CreateInAllocaTmp(QualType T, const Twine &Name = "inalloca"); + /// Emit a cast to void* in the appropriate address space. llvm::Value *EmitCastToVoidPtr(llvm::Value *value); @@ -1614,7 +1667,8 @@ public: llvm::Value *This); void EmitNewArrayInitializer(const CXXNewExpr *E, QualType elementType, - llvm::Value *NewPtr, llvm::Value *NumElements); + llvm::Value *NewPtr, llvm::Value *NumElements, + llvm::Value *AllocSizeWithoutCookie); void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType, llvm::Value *Ptr); @@ -1625,6 +1679,9 @@ public: void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy); + 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); @@ -1656,6 +1713,10 @@ public: TCK_DowncastReference }; + /// \brief Whether any type-checking sanitizers are enabled. If \c false, + /// calls to EmitTypeCheck can be skipped. + bool sanitizePerformTypeCheck() const; + /// \brief Emit a check that \p V is the address of storage of the /// appropriate size and alignment for an object of type \p Type. void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V, @@ -1722,19 +1783,21 @@ public: llvm::Value *SizeForLifetimeMarkers; struct Invalid {}; - AutoVarEmission(Invalid) : Variable(0) {} + AutoVarEmission(Invalid) : Variable(nullptr) {} AutoVarEmission(const VarDecl &variable) - : Variable(&variable), Address(0), NRVOFlag(0), + : Variable(&variable), Address(nullptr), NRVOFlag(nullptr), IsByRef(false), IsConstantAggregate(false), - SizeForLifetimeMarkers(0) {} + SizeForLifetimeMarkers(nullptr) {} - bool wasEmittedAsGlobal() const { return Address == 0; } + bool wasEmittedAsGlobal() const { return Address == nullptr; } public: static AutoVarEmission invalid() { return AutoVarEmission(Invalid()); } - bool useLifetimeMarkers() const { return SizeForLifetimeMarkers != 0; } + bool useLifetimeMarkers() const { + return SizeForLifetimeMarkers != nullptr; + } llvm::Value *getSizeForLifetimeMarkers() const { assert(useLifetimeMarkers()); return SizeForLifetimeMarkers; @@ -1767,7 +1830,8 @@ public: llvm::GlobalValue::LinkageTypes Linkage); /// EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl. - void EmitParmDecl(const VarDecl &D, llvm::Value *Arg, unsigned ArgNo); + void EmitParmDecl(const VarDecl &D, llvm::Value *Arg, bool ArgIsPointer, + unsigned ArgNo); /// protectFromPeepholes - Protect a value that we're intending to /// store to the side, but which will probably be used later, from @@ -1820,9 +1884,14 @@ public: void EmitGotoStmt(const GotoStmt &S); void EmitIndirectGotoStmt(const IndirectGotoStmt &S); void EmitIfStmt(const IfStmt &S); - void EmitWhileStmt(const WhileStmt &S); - void EmitDoStmt(const DoStmt &S); - void EmitForStmt(const ForStmt &S); + + void EmitCondBrHints(llvm::LLVMContext &Context, llvm::BranchInst *CondBr, + const ArrayRef<const Attr *> &Attrs); + void EmitWhileStmt(const WhileStmt &S, + const ArrayRef<const Attr *> &Attrs = None); + void EmitDoStmt(const DoStmt &S, const ArrayRef<const Attr *> &Attrs = None); + void EmitForStmt(const ForStmt &S, + const ArrayRef<const Attr *> &Attrs = None); void EmitReturnStmt(const ReturnStmt &S); void EmitDeclStmt(const DeclStmt &S); void EmitBreakStmt(const BreakStmt &S); @@ -1839,19 +1908,34 @@ public: void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S); void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S); - llvm::Constant *getUnwindResumeFn(); - llvm::Constant *getUnwindResumeOrRethrowFn(); void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false); void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false); void EmitCXXTryStmt(const CXXTryStmt &S); void EmitSEHTryStmt(const SEHTryStmt &S); - void EmitCXXForRangeStmt(const CXXForRangeStmt &S); + void EmitSEHLeaveStmt(const SEHLeaveStmt &S); + void EmitCXXForRangeStmt(const CXXForRangeStmt &S, + const ArrayRef<const Attr *> &Attrs = None); llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K); - llvm::Function *GenerateCapturedStmtFunction(const CapturedDecl *CD, - const RecordDecl *RD, - SourceLocation Loc); + llvm::Function *GenerateCapturedStmtFunction(const CapturedStmt &S); + llvm::Value *GenerateCapturedStmtArgument(const CapturedStmt &S); + + void EmitOMPParallelDirective(const OMPParallelDirective &S); + void EmitOMPSimdDirective(const OMPSimdDirective &S); + void EmitOMPForDirective(const OMPForDirective &S); + void EmitOMPSectionsDirective(const OMPSectionsDirective &S); + void EmitOMPSectionDirective(const OMPSectionDirective &S); + void EmitOMPSingleDirective(const OMPSingleDirective &S); + void EmitOMPMasterDirective(const OMPMasterDirective &S); + void EmitOMPCriticalDirective(const OMPCriticalDirective &S); + void EmitOMPParallelForDirective(const OMPParallelForDirective &S); + void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S); + void EmitOMPTaskDirective(const OMPTaskDirective &S); + void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S); + void EmitOMPBarrierDirective(const OMPBarrierDirective &S); + void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S); + void EmitOMPFlushDirective(const OMPFlushDirective &S); //===--------------------------------------------------------------------===// // LValue Expression Emission @@ -1918,7 +2002,7 @@ public: llvm::Value *EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, SourceLocation Loc, - llvm::MDNode *TBAAInfo = 0, + llvm::MDNode *TBAAInfo = nullptr, QualType TBAABaseTy = QualType(), uint64_t TBAAOffset = 0); @@ -1933,7 +2017,7 @@ public: /// the LLVM value representation. void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, - llvm::MDNode *TBAAInfo = 0, bool isInit = false, + llvm::MDNode *TBAAInfo = nullptr, bool isInit = false, QualType TBAABaseTy = QualType(), uint64_t TBAAOffset = 0); @@ -1950,12 +2034,14 @@ public: RValue EmitLoadOfLValue(LValue V, SourceLocation Loc); RValue EmitLoadOfExtVectorElementLValue(LValue V); RValue EmitLoadOfBitfieldLValue(LValue LV); + RValue EmitLoadOfGlobalRegLValue(LValue LV); /// EmitStoreThroughLValue - Store the specified rvalue into the specified /// lvalue, where both are guaranteed to the have the same type, and that type /// is 'Ty'. void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false); void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst); + void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst); /// EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints /// as EmitStoreThroughLValue. @@ -1964,7 +2050,7 @@ public: /// bit-field contents after the store, appropriate for use as the result of /// an assignment to the bit-field. void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, - llvm::Value **Result=0); + llvm::Value **Result=nullptr); /// Emit an l-value for an assignment (simple or compound) of complex type. LValue EmitComplexAssignmentLValue(const BinaryOperator *E); @@ -1980,6 +2066,7 @@ public: // Note: only available for agg return types LValue EmitVAArgExprLValue(const VAArgExpr *E); LValue EmitDeclRefLValue(const DeclRefExpr *E); + LValue EmitReadRegister(const VarDecl *VD); LValue EmitStringLiteralLValue(const StringLiteral *E); LValue EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E); LValue EmitPredefinedLValue(const PredefinedExpr *E); @@ -2011,7 +2098,9 @@ public: return ConstantEmission(C, false); } - LLVM_EXPLICIT operator bool() const { return ValueAndIsReference.getOpaqueValue() != 0; } + LLVM_EXPLICIT operator bool() const { + return ValueAndIsReference.getOpaqueValue() != nullptr; + } bool isReference() const { return ValueAndIsReference.getInt(); } LValue getReferenceLValue(CodeGenFunction &CGF, Expr *refExpr) const { @@ -2074,15 +2163,15 @@ public: llvm::Value *Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, - const Decl *TargetDecl = 0, - llvm::Instruction **callOrInvoke = 0); + const Decl *TargetDecl = nullptr, + llvm::Instruction **callOrInvoke = nullptr); RValue EmitCall(QualType FnType, llvm::Value *Callee, SourceLocation CallLoc, ReturnValueSlot ReturnValue, CallExpr::const_arg_iterator ArgBeg, CallExpr::const_arg_iterator ArgEnd, - const Decl *TargetDecl = 0); + const Decl *TargetDecl = nullptr); RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue = ReturnValueSlot()); @@ -2156,9 +2245,19 @@ public: const llvm::CmpInst::Predicate Fp, const llvm::CmpInst::Predicate Ip, const llvm::Twine &Name = ""); - llvm::Value *EmitAArch64CompareBuiltinExpr(llvm::Value *Op, llvm::Type *Ty); - llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitARMBuiltinExpr(unsigned BuiltinID, const CallExpr *E); + + llvm::Value *EmitCommonNeonBuiltinExpr(unsigned BuiltinID, + unsigned LLVMIntrinsic, + unsigned AltLLVMIntrinsic, + const char *NameHint, + unsigned Modifier, + const CallExpr *E, + SmallVectorImpl<llvm::Value *> &Ops, + llvm::Value *Align = nullptr); + llvm::Function *LookupNeonLLVMIntrinsic(unsigned IntrinsicID, + unsigned Modifier, llvm::Type *ArgTy, + const CallExpr *E); llvm::Value *EmitNeonCall(llvm::Function *F, SmallVectorImpl<llvm::Value*> &O, const char *name, @@ -2168,10 +2267,22 @@ public: bool negateForRightShift); llvm::Value *EmitNeonRShiftImm(llvm::Value *Vec, llvm::Value *Amt, llvm::Type *Ty, bool usgn, const char *name); + // Helper functions for EmitAArch64BuiltinExpr. + llvm::Value *vectorWrapScalar8(llvm::Value *Op); + llvm::Value *vectorWrapScalar16(llvm::Value *Op); + llvm::Value *emitVectorWrappedScalar8Intrinsic( + unsigned Int, SmallVectorImpl<llvm::Value *> &Ops, const char *Name); + llvm::Value *emitVectorWrappedScalar16Intrinsic( + unsigned Int, SmallVectorImpl<llvm::Value *> &Ops, const char *Name); + llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E); + llvm::Value *EmitNeon64Call(llvm::Function *F, + llvm::SmallVectorImpl<llvm::Value *> &O, + const char *name); llvm::Value *BuildVector(ArrayRef<llvm::Value*> Ops); llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E); + llvm::Value *EmitR600BuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E); llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E); @@ -2231,7 +2342,7 @@ public: llvm::Value *EmitARCRetainScalarExpr(const Expr *expr); llvm::Value *EmitARCRetainAutoreleaseScalarExpr(const Expr *expr); - void EmitARCIntrinsicUse(llvm::ArrayRef<llvm::Value*> values); + void EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values); static Destroyer destroyARCStrongImprecise; static Destroyer destroyARCStrongPrecise; @@ -2304,9 +2415,9 @@ public: /// CreateStaticVarDecl - Create a zero-initialized LLVM global for /// a static local variable. - llvm::GlobalVariable *CreateStaticVarDecl(const VarDecl &D, - const char *Separator, - llvm::GlobalValue::LinkageTypes Linkage); + llvm::Constant *CreateStaticVarDecl(const VarDecl &D, + const char *Separator, + llvm::GlobalValue::LinkageTypes Linkage); /// AddInitializerToStaticVarDecl - Add the initializer for 'D' to the /// global variable that has already been created for it. If the initializer @@ -2339,7 +2450,7 @@ public: /// variables. void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef<llvm::Constant *> Decls, - llvm::GlobalVariable *Guard = 0); + llvm::GlobalVariable *Guard = nullptr); /// GenerateCXXGlobalDtorsFunc - Generates code for destroying global /// variables. @@ -2367,7 +2478,7 @@ public: void EmitLambdaExpr(const LambdaExpr *E, AggValueSlot Dest); - RValue EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest = 0); + RValue EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest = nullptr); //===--------------------------------------------------------------------===// // Annotations Emission @@ -2413,8 +2524,10 @@ public: /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an /// if statement) to the specified blocks. Based on the condition, this might /// try to simplify the codegen of the conditional based on the branch. + /// TrueCount should be the number of times we expect the condition to + /// evaluate to true based on PGO data. void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, - llvm::BasicBlock *FalseBlock); + llvm::BasicBlock *FalseBlock, uint64_t TrueCount); /// \brief Emit a description of a type in a format suitable for passing to /// a runtime sanitizer handler. @@ -2467,6 +2580,11 @@ private: llvm::MDNode *getRangeForLoadFromType(QualType Ty); void EmitReturnOfRValue(RValue RV, QualType Ty); + void deferPlaceholderReplacement(llvm::Instruction *Old, llvm::Value *New); + + llvm::SmallVector<std::pair<llvm::Instruction *, llvm::Value *>, 4> + DeferredReplacements; + /// ExpandTypeFromArgs - Reconstruct a structure of type \arg Ty /// from function arguments into \arg Dst. See ABIArgInfo::Expand. /// @@ -2492,69 +2610,82 @@ private: std::string &ConstraintStr, SourceLocation Loc); +public: /// EmitCallArgs - Emit call arguments for a function. - /// The CallArgTypeInfo parameter is used for iterating over the known - /// argument types of the function being called. - template<typename T> - void EmitCallArgs(CallArgList& Args, const T* CallArgTypeInfo, + template <typename T> + void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo, CallExpr::const_arg_iterator ArgBeg, CallExpr::const_arg_iterator ArgEnd, bool ForceColumnInfo = false) { - CGDebugInfo *DI = getDebugInfo(); - SourceLocation CallLoc; - if (DI) CallLoc = DI->getLocation(); + if (CallArgTypeInfo) { + EmitCallArgs(Args, CallArgTypeInfo->isVariadic(), + CallArgTypeInfo->param_type_begin(), + CallArgTypeInfo->param_type_end(), ArgBeg, ArgEnd, + ForceColumnInfo); + } else { + // T::param_type_iterator might not have a default ctor. + const QualType *NoIter = nullptr; + EmitCallArgs(Args, /*AllowExtraArguments=*/true, NoIter, NoIter, ArgBeg, + ArgEnd, ForceColumnInfo); + } + } + template<typename ArgTypeIterator> + void EmitCallArgs(CallArgList& Args, + bool AllowExtraArguments, + ArgTypeIterator ArgTypeBeg, + ArgTypeIterator ArgTypeEnd, + CallExpr::const_arg_iterator ArgBeg, + CallExpr::const_arg_iterator ArgEnd, + bool ForceColumnInfo = false) { + SmallVector<QualType, 16> ArgTypes; CallExpr::const_arg_iterator Arg = ArgBeg; // First, use the argument types that the type info knows about - if (CallArgTypeInfo) { - for (typename T::arg_type_iterator I = CallArgTypeInfo->arg_type_begin(), - E = CallArgTypeInfo->arg_type_end(); I != E; ++I, ++Arg) { - assert(Arg != ArgEnd && "Running over edge of argument list!"); - QualType ArgType = *I; + for (ArgTypeIterator I = ArgTypeBeg, E = ArgTypeEnd; I != E; ++I, ++Arg) { + assert(Arg != ArgEnd && "Running over edge of argument list!"); #ifndef NDEBUG - QualType ActualArgType = Arg->getType(); - if (ArgType->isPointerType() && ActualArgType->isPointerType()) { - QualType ActualBaseType = + QualType ArgType = *I; + QualType ActualArgType = Arg->getType(); + if (ArgType->isPointerType() && ActualArgType->isPointerType()) { + QualType ActualBaseType = ActualArgType->getAs<PointerType>()->getPointeeType(); - QualType ArgBaseType = + QualType ArgBaseType = ArgType->getAs<PointerType>()->getPointeeType(); - if (ArgBaseType->isVariableArrayType()) { - if (const VariableArrayType *VAT = - getContext().getAsVariableArrayType(ActualBaseType)) { - if (!VAT->getSizeExpr()) - ActualArgType = ArgType; - } + if (ArgBaseType->isVariableArrayType()) { + if (const VariableArrayType *VAT = + getContext().getAsVariableArrayType(ActualBaseType)) { + if (!VAT->getSizeExpr()) + ActualArgType = ArgType; } } - assert(getContext().getCanonicalType(ArgType.getNonReferenceType()). - getTypePtr() == - getContext().getCanonicalType(ActualArgType).getTypePtr() && - "type mismatch in call argument!"); -#endif - EmitCallArg(Args, *Arg, ArgType); - - // Each argument expression could modify the debug - // location. Restore it. - if (DI) DI->EmitLocation(Builder, CallLoc, ForceColumnInfo); } - - // Either we've emitted all the call args, or we have a call to a - // variadic function. - assert((Arg == ArgEnd || CallArgTypeInfo->isVariadic()) && - "Extra arguments in non-variadic function!"); - + assert(getContext().getCanonicalType(ArgType.getNonReferenceType()). + getTypePtr() == + getContext().getCanonicalType(ActualArgType).getTypePtr() && + "type mismatch in call argument!"); +#endif + ArgTypes.push_back(*I); } + // Either we've emitted all the call args, or we have a call to variadic + // function or some other call that allows extra arguments. + assert((Arg == ArgEnd || AllowExtraArguments) && + "Extra arguments in non-variadic function!"); + // If we still have any arguments, emit them using the type of the argument. - for (; Arg != ArgEnd; ++Arg) { - EmitCallArg(Args, *Arg, Arg->getType()); + for (; Arg != ArgEnd; ++Arg) + ArgTypes.push_back(Arg->getType()); - // Restore the debug location. - if (DI) DI->EmitLocation(Builder, CallLoc, ForceColumnInfo); - } + EmitCallArgs(Args, ArgTypes, ArgBeg, ArgEnd, ForceColumnInfo); } + void EmitCallArgs(CallArgList &Args, ArrayRef<QualType> ArgTypes, + CallExpr::const_arg_iterator ArgBeg, + CallExpr::const_arg_iterator ArgEnd, + bool ForceColumnInfo = false); + +private: const TargetCodeGenInfo &getTargetHooks() const { return CGM.getTargetCodeGenInfo(); } |