10b57cec5SDimitry Andric //===-- CodeGenFunction.h - Per-Function state for LLVM CodeGen -*- C++ -*-===// 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 is the internal per-function state used for llvm translation. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENFUNCTION_H 140b57cec5SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_CODEGENFUNCTION_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "CGBuilder.h" 170b57cec5SDimitry Andric #include "CGDebugInfo.h" 180b57cec5SDimitry Andric #include "CGLoopInfo.h" 190b57cec5SDimitry Andric #include "CGValue.h" 200b57cec5SDimitry Andric #include "CodeGenModule.h" 210b57cec5SDimitry Andric #include "CodeGenPGO.h" 220b57cec5SDimitry Andric #include "EHScopeStack.h" 230b57cec5SDimitry Andric #include "VarBypassDetector.h" 240b57cec5SDimitry Andric #include "clang/AST/CharUnits.h" 250b57cec5SDimitry Andric #include "clang/AST/CurrentSourceLocExprScope.h" 260b57cec5SDimitry Andric #include "clang/AST/ExprCXX.h" 270b57cec5SDimitry Andric #include "clang/AST/ExprObjC.h" 280b57cec5SDimitry Andric #include "clang/AST/ExprOpenMP.h" 290fca6ea1SDimitry Andric #include "clang/AST/StmtOpenACC.h" 305ffd83dbSDimitry Andric #include "clang/AST/StmtOpenMP.h" 310b57cec5SDimitry Andric #include "clang/AST/Type.h" 320b57cec5SDimitry Andric #include "clang/Basic/ABI.h" 330b57cec5SDimitry Andric #include "clang/Basic/CapturedStmt.h" 340b57cec5SDimitry Andric #include "clang/Basic/CodeGenOptions.h" 350b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.h" 360b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 370b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 380b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 390b57cec5SDimitry Andric #include "llvm/ADT/MapVector.h" 400b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 415ffd83dbSDimitry Andric #include "llvm/Frontend/OpenMP/OMPIRBuilder.h" 420fca6ea1SDimitry Andric #include "llvm/IR/Instructions.h" 430b57cec5SDimitry Andric #include "llvm/IR/ValueHandle.h" 440b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 450b57cec5SDimitry Andric #include "llvm/Transforms/Utils/SanitizerStats.h" 46bdd1243dSDimitry Andric #include <optional> 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric namespace llvm { 490b57cec5SDimitry Andric class BasicBlock; 500b57cec5SDimitry Andric class LLVMContext; 510b57cec5SDimitry Andric class MDNode; 520b57cec5SDimitry Andric class SwitchInst; 530b57cec5SDimitry Andric class Twine; 540b57cec5SDimitry Andric class Value; 55fe6060f1SDimitry Andric class CanonicalLoopInfo; 560b57cec5SDimitry Andric } 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric namespace clang { 590b57cec5SDimitry Andric class ASTContext; 600b57cec5SDimitry Andric class CXXDestructorDecl; 610b57cec5SDimitry Andric class CXXForRangeStmt; 620b57cec5SDimitry Andric class CXXTryStmt; 630b57cec5SDimitry Andric class Decl; 640b57cec5SDimitry Andric class LabelDecl; 650b57cec5SDimitry Andric class FunctionDecl; 660b57cec5SDimitry Andric class FunctionProtoType; 670b57cec5SDimitry Andric class LabelStmt; 680b57cec5SDimitry Andric class ObjCContainerDecl; 690b57cec5SDimitry Andric class ObjCInterfaceDecl; 700b57cec5SDimitry Andric class ObjCIvarDecl; 710b57cec5SDimitry Andric class ObjCMethodDecl; 720b57cec5SDimitry Andric class ObjCImplementationDecl; 730b57cec5SDimitry Andric class ObjCPropertyImplDecl; 740b57cec5SDimitry Andric class TargetInfo; 750b57cec5SDimitry Andric class VarDecl; 760b57cec5SDimitry Andric class ObjCForCollectionStmt; 770b57cec5SDimitry Andric class ObjCAtTryStmt; 780b57cec5SDimitry Andric class ObjCAtThrowStmt; 790b57cec5SDimitry Andric class ObjCAtSynchronizedStmt; 800b57cec5SDimitry Andric class ObjCAutoreleasePoolStmt; 815ffd83dbSDimitry Andric class OMPUseDevicePtrClause; 825ffd83dbSDimitry Andric class OMPUseDeviceAddrClause; 835ffd83dbSDimitry Andric class SVETypeFlags; 845ffd83dbSDimitry Andric class OMPExecutableDirective; 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric namespace analyze_os_log { 870b57cec5SDimitry Andric class OSLogBufferLayout; 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric namespace CodeGen { 910b57cec5SDimitry Andric class CodeGenTypes; 920b57cec5SDimitry Andric class CGCallee; 930b57cec5SDimitry Andric class CGFunctionInfo; 940b57cec5SDimitry Andric class CGBlockInfo; 950b57cec5SDimitry Andric class CGCXXABI; 960b57cec5SDimitry Andric class BlockByrefHelpers; 970b57cec5SDimitry Andric class BlockByrefInfo; 980b57cec5SDimitry Andric class BlockFieldFlags; 990b57cec5SDimitry Andric class RegionCodeGenTy; 1000b57cec5SDimitry Andric class TargetCodeGenInfo; 1010b57cec5SDimitry Andric struct OMPTaskDataTy; 1020b57cec5SDimitry Andric struct CGCoroData; 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric /// The kind of evaluation to perform on values of a particular 1050b57cec5SDimitry Andric /// type. Basically, is the code in CGExprScalar, CGExprComplex, or 1060b57cec5SDimitry Andric /// CGExprAgg? 1070b57cec5SDimitry Andric /// 1080b57cec5SDimitry Andric /// TODO: should vectors maybe be split out into their own thing? 1090b57cec5SDimitry Andric enum TypeEvaluationKind { 1100b57cec5SDimitry Andric TEK_Scalar, 1110b57cec5SDimitry Andric TEK_Complex, 1120b57cec5SDimitry Andric TEK_Aggregate 1130b57cec5SDimitry Andric }; 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric #define LIST_SANITIZER_CHECKS \ 1160b57cec5SDimitry Andric SANITIZER_CHECK(AddOverflow, add_overflow, 0) \ 1170b57cec5SDimitry Andric SANITIZER_CHECK(BuiltinUnreachable, builtin_unreachable, 0) \ 1180b57cec5SDimitry Andric SANITIZER_CHECK(CFICheckFail, cfi_check_fail, 0) \ 1190b57cec5SDimitry Andric SANITIZER_CHECK(DivremOverflow, divrem_overflow, 0) \ 1200b57cec5SDimitry Andric SANITIZER_CHECK(DynamicTypeCacheMiss, dynamic_type_cache_miss, 0) \ 1210b57cec5SDimitry Andric SANITIZER_CHECK(FloatCastOverflow, float_cast_overflow, 0) \ 12206c3fb27SDimitry Andric SANITIZER_CHECK(FunctionTypeMismatch, function_type_mismatch, 0) \ 1230b57cec5SDimitry Andric SANITIZER_CHECK(ImplicitConversion, implicit_conversion, 0) \ 1240b57cec5SDimitry Andric SANITIZER_CHECK(InvalidBuiltin, invalid_builtin, 0) \ 1255ffd83dbSDimitry Andric SANITIZER_CHECK(InvalidObjCCast, invalid_objc_cast, 0) \ 1260b57cec5SDimitry Andric SANITIZER_CHECK(LoadInvalidValue, load_invalid_value, 0) \ 1270b57cec5SDimitry Andric SANITIZER_CHECK(MissingReturn, missing_return, 0) \ 1280b57cec5SDimitry Andric SANITIZER_CHECK(MulOverflow, mul_overflow, 0) \ 1290b57cec5SDimitry Andric SANITIZER_CHECK(NegateOverflow, negate_overflow, 0) \ 1300b57cec5SDimitry Andric SANITIZER_CHECK(NullabilityArg, nullability_arg, 0) \ 1310b57cec5SDimitry Andric SANITIZER_CHECK(NullabilityReturn, nullability_return, 1) \ 1320b57cec5SDimitry Andric SANITIZER_CHECK(NonnullArg, nonnull_arg, 0) \ 1330b57cec5SDimitry Andric SANITIZER_CHECK(NonnullReturn, nonnull_return, 1) \ 1340b57cec5SDimitry Andric SANITIZER_CHECK(OutOfBounds, out_of_bounds, 0) \ 1350b57cec5SDimitry Andric SANITIZER_CHECK(PointerOverflow, pointer_overflow, 0) \ 1360b57cec5SDimitry Andric SANITIZER_CHECK(ShiftOutOfBounds, shift_out_of_bounds, 0) \ 1370b57cec5SDimitry Andric SANITIZER_CHECK(SubOverflow, sub_overflow, 0) \ 1380b57cec5SDimitry Andric SANITIZER_CHECK(TypeMismatch, type_mismatch, 1) \ 1390b57cec5SDimitry Andric SANITIZER_CHECK(AlignmentAssumption, alignment_assumption, 0) \ 1400fca6ea1SDimitry Andric SANITIZER_CHECK(VLABoundNotPositive, vla_bound_not_positive, 0) \ 1410fca6ea1SDimitry Andric SANITIZER_CHECK(BoundsSafety, bounds_safety, 0) 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric enum SanitizerHandler { 1440b57cec5SDimitry Andric #define SANITIZER_CHECK(Enum, Name, Version) Enum, 1450b57cec5SDimitry Andric LIST_SANITIZER_CHECKS 1460b57cec5SDimitry Andric #undef SANITIZER_CHECK 1470b57cec5SDimitry Andric }; 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric /// Helper class with most of the code for saving a value for a 1500b57cec5SDimitry Andric /// conditional expression cleanup. 1510b57cec5SDimitry Andric struct DominatingLLVMValue { 1520b57cec5SDimitry Andric typedef llvm::PointerIntPair<llvm::Value*, 1, bool> saved_type; 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric /// Answer whether the given value needs extra work to be saved. 1550b57cec5SDimitry Andric static bool needsSaving(llvm::Value *value) { 1560fca6ea1SDimitry Andric if (!value) 1570fca6ea1SDimitry Andric return false; 1580fca6ea1SDimitry Andric 1590b57cec5SDimitry Andric // If it's not an instruction, we don't need to save. 1600b57cec5SDimitry Andric if (!isa<llvm::Instruction>(value)) return false; 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric // If it's an instruction in the entry block, we don't need to save. 1630b57cec5SDimitry Andric llvm::BasicBlock *block = cast<llvm::Instruction>(value)->getParent(); 1640b57cec5SDimitry Andric return (block != &block->getParent()->getEntryBlock()); 1650b57cec5SDimitry Andric } 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric static saved_type save(CodeGenFunction &CGF, llvm::Value *value); 1680b57cec5SDimitry Andric static llvm::Value *restore(CodeGenFunction &CGF, saved_type value); 1690b57cec5SDimitry Andric }; 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric /// A partial specialization of DominatingValue for llvm::Values that 1720b57cec5SDimitry Andric /// might be llvm::Instructions. 1730b57cec5SDimitry Andric template <class T> struct DominatingPointer<T,true> : DominatingLLVMValue { 1740b57cec5SDimitry Andric typedef T *type; 1750b57cec5SDimitry Andric static type restore(CodeGenFunction &CGF, saved_type value) { 1760b57cec5SDimitry Andric return static_cast<T*>(DominatingLLVMValue::restore(CGF, value)); 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric }; 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric /// A specialization of DominatingValue for Address. 1810b57cec5SDimitry Andric template <> struct DominatingValue<Address> { 1820b57cec5SDimitry Andric typedef Address type; 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric struct saved_type { 1850fca6ea1SDimitry Andric DominatingLLVMValue::saved_type BasePtr; 18604eeddc0SDimitry Andric llvm::Type *ElementType; 1870b57cec5SDimitry Andric CharUnits Alignment; 1880fca6ea1SDimitry Andric DominatingLLVMValue::saved_type Offset; 1890fca6ea1SDimitry Andric llvm::PointerType *EffectiveType; 1900b57cec5SDimitry Andric }; 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric static bool needsSaving(type value) { 1930fca6ea1SDimitry Andric if (DominatingLLVMValue::needsSaving(value.getBasePointer()) || 1940fca6ea1SDimitry Andric DominatingLLVMValue::needsSaving(value.getOffset())) 1950fca6ea1SDimitry Andric return true; 1960fca6ea1SDimitry Andric return false; 1970b57cec5SDimitry Andric } 1980b57cec5SDimitry Andric static saved_type save(CodeGenFunction &CGF, type value) { 1990fca6ea1SDimitry Andric return {DominatingLLVMValue::save(CGF, value.getBasePointer()), 2000fca6ea1SDimitry Andric value.getElementType(), value.getAlignment(), 2010fca6ea1SDimitry Andric DominatingLLVMValue::save(CGF, value.getOffset()), value.getType()}; 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric static type restore(CodeGenFunction &CGF, saved_type value) { 2040fca6ea1SDimitry Andric return Address(DominatingLLVMValue::restore(CGF, value.BasePtr), 2050fca6ea1SDimitry Andric value.ElementType, value.Alignment, CGPointerAuthInfo(), 2060fca6ea1SDimitry Andric DominatingLLVMValue::restore(CGF, value.Offset)); 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric }; 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric /// A specialization of DominatingValue for RValue. 2110b57cec5SDimitry Andric template <> struct DominatingValue<RValue> { 2120b57cec5SDimitry Andric typedef RValue type; 2130b57cec5SDimitry Andric class saved_type { 2140b57cec5SDimitry Andric enum Kind { ScalarLiteral, ScalarAddress, AggregateLiteral, 2150b57cec5SDimitry Andric AggregateAddress, ComplexAddress }; 2160fca6ea1SDimitry Andric union { 2170fca6ea1SDimitry Andric struct { 2180fca6ea1SDimitry Andric DominatingLLVMValue::saved_type first, second; 2190fca6ea1SDimitry Andric } Vals; 2200fca6ea1SDimitry Andric DominatingValue<Address>::saved_type AggregateAddr; 2210fca6ea1SDimitry Andric }; 2220fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(Kind) 2230b57cec5SDimitry Andric unsigned K : 3; 2240fca6ea1SDimitry Andric 2250fca6ea1SDimitry Andric saved_type(DominatingLLVMValue::saved_type Val1, unsigned K) 2260fca6ea1SDimitry Andric : Vals{Val1, DominatingLLVMValue::saved_type()}, K(K) {} 2270fca6ea1SDimitry Andric 2280fca6ea1SDimitry Andric saved_type(DominatingLLVMValue::saved_type Val1, 2290fca6ea1SDimitry Andric DominatingLLVMValue::saved_type Val2) 2300fca6ea1SDimitry Andric : Vals{Val1, Val2}, K(ComplexAddress) {} 2310fca6ea1SDimitry Andric 2320fca6ea1SDimitry Andric saved_type(DominatingValue<Address>::saved_type AggregateAddr, unsigned K) 2330fca6ea1SDimitry Andric : AggregateAddr(AggregateAddr), K(K) {} 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric public: 2360b57cec5SDimitry Andric static bool needsSaving(RValue value); 2370b57cec5SDimitry Andric static saved_type save(CodeGenFunction &CGF, RValue value); 2380b57cec5SDimitry Andric RValue restore(CodeGenFunction &CGF); 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric // implementations in CGCleanup.cpp 2410b57cec5SDimitry Andric }; 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric static bool needsSaving(type value) { 2440b57cec5SDimitry Andric return saved_type::needsSaving(value); 2450b57cec5SDimitry Andric } 2460b57cec5SDimitry Andric static saved_type save(CodeGenFunction &CGF, type value) { 2470b57cec5SDimitry Andric return saved_type::save(CGF, value); 2480b57cec5SDimitry Andric } 2490b57cec5SDimitry Andric static type restore(CodeGenFunction &CGF, saved_type value) { 2500b57cec5SDimitry Andric return value.restore(CGF); 2510b57cec5SDimitry Andric } 2520b57cec5SDimitry Andric }; 2530b57cec5SDimitry Andric 2540b57cec5SDimitry Andric /// CodeGenFunction - This class organizes the per-function state that is used 2550b57cec5SDimitry Andric /// while generating LLVM code. 2560b57cec5SDimitry Andric class CodeGenFunction : public CodeGenTypeCache { 2570b57cec5SDimitry Andric CodeGenFunction(const CodeGenFunction &) = delete; 2580b57cec5SDimitry Andric void operator=(const CodeGenFunction &) = delete; 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric friend class CGCXXABI; 2610b57cec5SDimitry Andric public: 2620b57cec5SDimitry Andric /// A jump destination is an abstract label, branching to which may 2630b57cec5SDimitry Andric /// require a jump out through normal cleanups. 2640b57cec5SDimitry Andric struct JumpDest { 26504eeddc0SDimitry Andric JumpDest() : Block(nullptr), Index(0) {} 26604eeddc0SDimitry Andric JumpDest(llvm::BasicBlock *Block, EHScopeStack::stable_iterator Depth, 2670b57cec5SDimitry Andric unsigned Index) 2680b57cec5SDimitry Andric : Block(Block), ScopeDepth(Depth), Index(Index) {} 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric bool isValid() const { return Block != nullptr; } 2710b57cec5SDimitry Andric llvm::BasicBlock *getBlock() const { return Block; } 2720b57cec5SDimitry Andric EHScopeStack::stable_iterator getScopeDepth() const { return ScopeDepth; } 2730b57cec5SDimitry Andric unsigned getDestIndex() const { return Index; } 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric // This should be used cautiously. 2760b57cec5SDimitry Andric void setScopeDepth(EHScopeStack::stable_iterator depth) { 2770b57cec5SDimitry Andric ScopeDepth = depth; 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric private: 2810b57cec5SDimitry Andric llvm::BasicBlock *Block; 2820b57cec5SDimitry Andric EHScopeStack::stable_iterator ScopeDepth; 2830b57cec5SDimitry Andric unsigned Index; 2840b57cec5SDimitry Andric }; 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric CodeGenModule &CGM; // Per-module state. 2870b57cec5SDimitry Andric const TargetInfo &Target; 2880b57cec5SDimitry Andric 2895ffd83dbSDimitry Andric // For EH/SEH outlined funclets, this field points to parent's CGF 2905ffd83dbSDimitry Andric CodeGenFunction *ParentCGF = nullptr; 2915ffd83dbSDimitry Andric 2920b57cec5SDimitry Andric typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy; 2930b57cec5SDimitry Andric LoopInfoStack LoopStack; 2940b57cec5SDimitry Andric CGBuilderTy Builder; 2950b57cec5SDimitry Andric 2960b57cec5SDimitry Andric // Stores variables for which we can't generate correct lifetime markers 2970b57cec5SDimitry Andric // because of jumps. 2980b57cec5SDimitry Andric VarBypassDetector Bypasses; 2990b57cec5SDimitry Andric 300fe6060f1SDimitry Andric /// List of recently emitted OMPCanonicalLoops. 301fe6060f1SDimitry Andric /// 302fe6060f1SDimitry Andric /// Since OMPCanonicalLoops are nested inside other statements (in particular 303fe6060f1SDimitry Andric /// CapturedStmt generated by OMPExecutableDirective and non-perfectly nested 304fe6060f1SDimitry Andric /// loops), we cannot directly call OMPEmitOMPCanonicalLoop and receive its 305fe6060f1SDimitry Andric /// llvm::CanonicalLoopInfo. Instead, we call EmitStmt and any 306fe6060f1SDimitry Andric /// OMPEmitOMPCanonicalLoop called by it will add its CanonicalLoopInfo to 307fe6060f1SDimitry Andric /// this stack when done. Entering a new loop requires clearing this list; it 308fe6060f1SDimitry Andric /// either means we start parsing a new loop nest (in which case the previous 309fe6060f1SDimitry Andric /// loop nest goes out of scope) or a second loop in the same level in which 310fe6060f1SDimitry Andric /// case it would be ambiguous into which of the two (or more) loops the loop 311fe6060f1SDimitry Andric /// nest would extend. 312fe6060f1SDimitry Andric SmallVector<llvm::CanonicalLoopInfo *, 4> OMPLoopNestStack; 313fe6060f1SDimitry Andric 3141db9f3b2SDimitry Andric /// Stack to track the Logical Operator recursion nest for MC/DC. 3151db9f3b2SDimitry Andric SmallVector<const BinaryOperator *, 16> MCDCLogOpStack; 3161db9f3b2SDimitry Andric 3170fca6ea1SDimitry Andric /// Stack to track the controlled convergence tokens. 3180fca6ea1SDimitry Andric SmallVector<llvm::IntrinsicInst *, 4> ConvergenceTokenStack; 3190fca6ea1SDimitry Andric 320349cc55cSDimitry Andric /// Number of nested loop to be consumed by the last surrounding 321349cc55cSDimitry Andric /// loop-associated directive. 322349cc55cSDimitry Andric int ExpectedOMPLoopDepth = 0; 323349cc55cSDimitry Andric 3240b57cec5SDimitry Andric // CodeGen lambda for loops and support for ordered clause 3250b57cec5SDimitry Andric typedef llvm::function_ref<void(CodeGenFunction &, const OMPLoopDirective &, 3260b57cec5SDimitry Andric JumpDest)> 3270b57cec5SDimitry Andric CodeGenLoopTy; 3280b57cec5SDimitry Andric typedef llvm::function_ref<void(CodeGenFunction &, SourceLocation, 3290b57cec5SDimitry Andric const unsigned, const bool)> 3300b57cec5SDimitry Andric CodeGenOrderedTy; 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric // Codegen lambda for loop bounds in worksharing loop constructs 3330b57cec5SDimitry Andric typedef llvm::function_ref<std::pair<LValue, LValue>( 3340b57cec5SDimitry Andric CodeGenFunction &, const OMPExecutableDirective &S)> 3350b57cec5SDimitry Andric CodeGenLoopBoundsTy; 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric // Codegen lambda for loop bounds in dispatch-based loop implementation 3380b57cec5SDimitry Andric typedef llvm::function_ref<std::pair<llvm::Value *, llvm::Value *>( 3390b57cec5SDimitry Andric CodeGenFunction &, const OMPExecutableDirective &S, Address LB, 3400b57cec5SDimitry Andric Address UB)> 3410b57cec5SDimitry Andric CodeGenDispatchBoundsTy; 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric /// CGBuilder insert helper. This function is called after an 3440b57cec5SDimitry Andric /// instruction is created using Builder. 3450b57cec5SDimitry Andric void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, 3460b57cec5SDimitry Andric llvm::BasicBlock::iterator InsertPt) const; 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric /// CurFuncDecl - Holds the Decl for the current outermost 3490b57cec5SDimitry Andric /// non-closure context. 35006c3fb27SDimitry Andric const Decl *CurFuncDecl = nullptr; 3510b57cec5SDimitry Andric /// CurCodeDecl - This is the inner-most code context, which includes blocks. 35206c3fb27SDimitry Andric const Decl *CurCodeDecl = nullptr; 35306c3fb27SDimitry Andric const CGFunctionInfo *CurFnInfo = nullptr; 3540b57cec5SDimitry Andric QualType FnRetTy; 3550b57cec5SDimitry Andric llvm::Function *CurFn = nullptr; 3560b57cec5SDimitry Andric 357fe6060f1SDimitry Andric /// Save Parameter Decl for coroutine. 358fe6060f1SDimitry Andric llvm::SmallVector<const ParmVarDecl *, 4> FnArgs; 359fe6060f1SDimitry Andric 3600b57cec5SDimitry Andric // Holds coroutine data if the current function is a coroutine. We use a 3610b57cec5SDimitry Andric // wrapper to manage its lifetime, so that we don't have to define CGCoroData 3620b57cec5SDimitry Andric // in this header. 3630b57cec5SDimitry Andric struct CGCoroInfo { 3640b57cec5SDimitry Andric std::unique_ptr<CGCoroData> Data; 36506c3fb27SDimitry Andric bool InSuspendBlock = false; 3660b57cec5SDimitry Andric CGCoroInfo(); 3670b57cec5SDimitry Andric ~CGCoroInfo(); 3680b57cec5SDimitry Andric }; 3690b57cec5SDimitry Andric CGCoroInfo CurCoro; 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric bool isCoroutine() const { 3720b57cec5SDimitry Andric return CurCoro.Data != nullptr; 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric 37506c3fb27SDimitry Andric bool inSuspendBlock() const { 37606c3fb27SDimitry Andric return isCoroutine() && CurCoro.InSuspendBlock; 37706c3fb27SDimitry Andric } 37806c3fb27SDimitry Andric 3790fca6ea1SDimitry Andric // Holds FramePtr for await_suspend wrapper generation, 3800fca6ea1SDimitry Andric // so that __builtin_coro_frame call can be lowered 3810fca6ea1SDimitry Andric // directly to value of its second argument 3820fca6ea1SDimitry Andric struct AwaitSuspendWrapperInfo { 3830fca6ea1SDimitry Andric llvm::Value *FramePtr = nullptr; 3840fca6ea1SDimitry Andric }; 3850fca6ea1SDimitry Andric AwaitSuspendWrapperInfo CurAwaitSuspendWrapper; 3860fca6ea1SDimitry Andric 3870fca6ea1SDimitry Andric // Generates wrapper function for `llvm.coro.await.suspend.*` intrinisics. 3880fca6ea1SDimitry Andric // It encapsulates SuspendExpr in a function, to separate it's body 3890fca6ea1SDimitry Andric // from the main coroutine to avoid miscompilations. Intrinisic 3900fca6ea1SDimitry Andric // is lowered to this function call in CoroSplit pass 3910fca6ea1SDimitry Andric // Function signature is: 3920fca6ea1SDimitry Andric // <type> __await_suspend_wrapper_<name>(ptr %awaiter, ptr %hdl) 3930fca6ea1SDimitry Andric // where type is one of (void, i1, ptr) 3940fca6ea1SDimitry Andric llvm::Function *generateAwaitSuspendWrapper(Twine const &CoroName, 3950fca6ea1SDimitry Andric Twine const &SuspendPointName, 3960fca6ea1SDimitry Andric CoroutineSuspendExpr const &S); 3970fca6ea1SDimitry Andric 3980b57cec5SDimitry Andric /// CurGD - The GlobalDecl for the current function being compiled. 3990b57cec5SDimitry Andric GlobalDecl CurGD; 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric /// PrologueCleanupDepth - The cleanup depth enclosing all the 4020b57cec5SDimitry Andric /// cleanups associated with the parameters. 4030b57cec5SDimitry Andric EHScopeStack::stable_iterator PrologueCleanupDepth; 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric /// ReturnBlock - Unified return block. 4060b57cec5SDimitry Andric JumpDest ReturnBlock; 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric /// ReturnValue - The temporary alloca to hold the return 4090b57cec5SDimitry Andric /// value. This is invalid iff the function has no return value. 4100b57cec5SDimitry Andric Address ReturnValue = Address::invalid(); 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andric /// ReturnValuePointer - The temporary alloca to hold a pointer to sret. 4130b57cec5SDimitry Andric /// This is invalid if sret is not in use. 4140b57cec5SDimitry Andric Address ReturnValuePointer = Address::invalid(); 4150b57cec5SDimitry Andric 4165ffd83dbSDimitry Andric /// If a return statement is being visited, this holds the return statment's 4175ffd83dbSDimitry Andric /// result expression. 4185ffd83dbSDimitry Andric const Expr *RetExpr = nullptr; 4195ffd83dbSDimitry Andric 4200b57cec5SDimitry Andric /// Return true if a label was seen in the current scope. 4210b57cec5SDimitry Andric bool hasLabelBeenSeenInCurrentScope() const { 4220b57cec5SDimitry Andric if (CurLexicalScope) 4230b57cec5SDimitry Andric return CurLexicalScope->hasLabels(); 4240b57cec5SDimitry Andric return !LabelMap.empty(); 4250b57cec5SDimitry Andric } 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric /// AllocaInsertPoint - This is an instruction in the entry block before which 4280b57cec5SDimitry Andric /// we prefer to insert allocas. 4290b57cec5SDimitry Andric llvm::AssertingVH<llvm::Instruction> AllocaInsertPt; 4300b57cec5SDimitry Andric 431349cc55cSDimitry Andric private: 432349cc55cSDimitry Andric /// PostAllocaInsertPt - This is a place in the prologue where code can be 433349cc55cSDimitry Andric /// inserted that will be dominated by all the static allocas. This helps 434349cc55cSDimitry Andric /// achieve two things: 435349cc55cSDimitry Andric /// 1. Contiguity of all static allocas (within the prologue) is maintained. 436349cc55cSDimitry Andric /// 2. All other prologue code (which are dominated by static allocas) do 437349cc55cSDimitry Andric /// appear in the source order immediately after all static allocas. 438349cc55cSDimitry Andric /// 439349cc55cSDimitry Andric /// PostAllocaInsertPt will be lazily created when it is *really* required. 440349cc55cSDimitry Andric llvm::AssertingVH<llvm::Instruction> PostAllocaInsertPt = nullptr; 441349cc55cSDimitry Andric 442349cc55cSDimitry Andric public: 443349cc55cSDimitry Andric /// Return PostAllocaInsertPt. If it is not yet created, then insert it 444349cc55cSDimitry Andric /// immediately after AllocaInsertPt. 445349cc55cSDimitry Andric llvm::Instruction *getPostAllocaInsertPoint() { 446349cc55cSDimitry Andric if (!PostAllocaInsertPt) { 447349cc55cSDimitry Andric assert(AllocaInsertPt && 448349cc55cSDimitry Andric "Expected static alloca insertion point at function prologue"); 449349cc55cSDimitry Andric assert(AllocaInsertPt->getParent()->isEntryBlock() && 450349cc55cSDimitry Andric "EBB should be entry block of the current code gen function"); 451349cc55cSDimitry Andric PostAllocaInsertPt = AllocaInsertPt->clone(); 452349cc55cSDimitry Andric PostAllocaInsertPt->setName("postallocapt"); 453349cc55cSDimitry Andric PostAllocaInsertPt->insertAfter(AllocaInsertPt); 454349cc55cSDimitry Andric } 455349cc55cSDimitry Andric 456349cc55cSDimitry Andric return PostAllocaInsertPt; 457349cc55cSDimitry Andric } 458349cc55cSDimitry Andric 4590b57cec5SDimitry Andric /// API for captured statement code generation. 4600b57cec5SDimitry Andric class CGCapturedStmtInfo { 4610b57cec5SDimitry Andric public: 4620b57cec5SDimitry Andric explicit CGCapturedStmtInfo(CapturedRegionKind K = CR_Default) 4630b57cec5SDimitry Andric : Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) {} 4640b57cec5SDimitry Andric explicit CGCapturedStmtInfo(const CapturedStmt &S, 4650b57cec5SDimitry Andric CapturedRegionKind K = CR_Default) 4660b57cec5SDimitry Andric : Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) { 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric RecordDecl::field_iterator Field = 4690b57cec5SDimitry Andric S.getCapturedRecordDecl()->field_begin(); 4700b57cec5SDimitry Andric for (CapturedStmt::const_capture_iterator I = S.capture_begin(), 4710b57cec5SDimitry Andric E = S.capture_end(); 4720b57cec5SDimitry Andric I != E; ++I, ++Field) { 4730b57cec5SDimitry Andric if (I->capturesThis()) 4740b57cec5SDimitry Andric CXXThisFieldDecl = *Field; 4750b57cec5SDimitry Andric else if (I->capturesVariable()) 4760b57cec5SDimitry Andric CaptureFields[I->getCapturedVar()->getCanonicalDecl()] = *Field; 4770b57cec5SDimitry Andric else if (I->capturesVariableByCopy()) 4780b57cec5SDimitry Andric CaptureFields[I->getCapturedVar()->getCanonicalDecl()] = *Field; 4790b57cec5SDimitry Andric } 4800b57cec5SDimitry Andric } 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andric virtual ~CGCapturedStmtInfo(); 4830b57cec5SDimitry Andric 4840b57cec5SDimitry Andric CapturedRegionKind getKind() const { return Kind; } 4850b57cec5SDimitry Andric 4860b57cec5SDimitry Andric virtual void setContextValue(llvm::Value *V) { ThisValue = V; } 4870b57cec5SDimitry Andric // Retrieve the value of the context parameter. 4880b57cec5SDimitry Andric virtual llvm::Value *getContextValue() const { return ThisValue; } 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric /// Lookup the captured field decl for a variable. 4910b57cec5SDimitry Andric virtual const FieldDecl *lookup(const VarDecl *VD) const { 4920b57cec5SDimitry Andric return CaptureFields.lookup(VD->getCanonicalDecl()); 4930b57cec5SDimitry Andric } 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andric bool isCXXThisExprCaptured() const { return getThisFieldDecl() != nullptr; } 4960b57cec5SDimitry Andric virtual FieldDecl *getThisFieldDecl() const { return CXXThisFieldDecl; } 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric static bool classof(const CGCapturedStmtInfo *) { 4990b57cec5SDimitry Andric return true; 5000b57cec5SDimitry Andric } 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric /// Emit the captured statement body. 5030b57cec5SDimitry Andric virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S) { 5040b57cec5SDimitry Andric CGF.incrementProfileCounter(S); 5050b57cec5SDimitry Andric CGF.EmitStmt(S); 5060b57cec5SDimitry Andric } 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric /// Get the name of the capture helper. 5090b57cec5SDimitry Andric virtual StringRef getHelperName() const { return "__captured_stmt"; } 5100b57cec5SDimitry Andric 5110eae32dcSDimitry Andric /// Get the CaptureFields 5120eae32dcSDimitry Andric llvm::SmallDenseMap<const VarDecl *, FieldDecl *> getCaptureFields() { 5130eae32dcSDimitry Andric return CaptureFields; 5140eae32dcSDimitry Andric } 5150eae32dcSDimitry Andric 5160b57cec5SDimitry Andric private: 5170b57cec5SDimitry Andric /// The kind of captured statement being generated. 5180b57cec5SDimitry Andric CapturedRegionKind Kind; 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric /// Keep the map between VarDecl and FieldDecl. 5210b57cec5SDimitry Andric llvm::SmallDenseMap<const VarDecl *, FieldDecl *> CaptureFields; 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andric /// The base address of the captured record, passed in as the first 5240b57cec5SDimitry Andric /// argument of the parallel region function. 5250b57cec5SDimitry Andric llvm::Value *ThisValue; 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric /// Captured 'this' type. 5280b57cec5SDimitry Andric FieldDecl *CXXThisFieldDecl; 5290b57cec5SDimitry Andric }; 5300b57cec5SDimitry Andric CGCapturedStmtInfo *CapturedStmtInfo = nullptr; 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric /// RAII for correct setting/restoring of CapturedStmtInfo. 5330b57cec5SDimitry Andric class CGCapturedStmtRAII { 5340b57cec5SDimitry Andric private: 5350b57cec5SDimitry Andric CodeGenFunction &CGF; 5360b57cec5SDimitry Andric CGCapturedStmtInfo *PrevCapturedStmtInfo; 5370b57cec5SDimitry Andric public: 5380b57cec5SDimitry Andric CGCapturedStmtRAII(CodeGenFunction &CGF, 5390b57cec5SDimitry Andric CGCapturedStmtInfo *NewCapturedStmtInfo) 5400b57cec5SDimitry Andric : CGF(CGF), PrevCapturedStmtInfo(CGF.CapturedStmtInfo) { 5410b57cec5SDimitry Andric CGF.CapturedStmtInfo = NewCapturedStmtInfo; 5420b57cec5SDimitry Andric } 5430b57cec5SDimitry Andric ~CGCapturedStmtRAII() { CGF.CapturedStmtInfo = PrevCapturedStmtInfo; } 5440b57cec5SDimitry Andric }; 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric /// An abstract representation of regular/ObjC call/message targets. 5470b57cec5SDimitry Andric class AbstractCallee { 5480b57cec5SDimitry Andric /// The function declaration of the callee. 5490b57cec5SDimitry Andric const Decl *CalleeDecl; 5500b57cec5SDimitry Andric 5510b57cec5SDimitry Andric public: 5520b57cec5SDimitry Andric AbstractCallee() : CalleeDecl(nullptr) {} 5530b57cec5SDimitry Andric AbstractCallee(const FunctionDecl *FD) : CalleeDecl(FD) {} 5540b57cec5SDimitry Andric AbstractCallee(const ObjCMethodDecl *OMD) : CalleeDecl(OMD) {} 5550b57cec5SDimitry Andric bool hasFunctionDecl() const { 556349cc55cSDimitry Andric return isa_and_nonnull<FunctionDecl>(CalleeDecl); 5570b57cec5SDimitry Andric } 5580b57cec5SDimitry Andric const Decl *getDecl() const { return CalleeDecl; } 5590b57cec5SDimitry Andric unsigned getNumParams() const { 5600b57cec5SDimitry Andric if (const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl)) 5610b57cec5SDimitry Andric return FD->getNumParams(); 5620b57cec5SDimitry Andric return cast<ObjCMethodDecl>(CalleeDecl)->param_size(); 5630b57cec5SDimitry Andric } 5640b57cec5SDimitry Andric const ParmVarDecl *getParamDecl(unsigned I) const { 5650b57cec5SDimitry Andric if (const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl)) 5660b57cec5SDimitry Andric return FD->getParamDecl(I); 5670b57cec5SDimitry Andric return *(cast<ObjCMethodDecl>(CalleeDecl)->param_begin() + I); 5680b57cec5SDimitry Andric } 5690b57cec5SDimitry Andric }; 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric /// Sanitizers enabled for this function. 5720b57cec5SDimitry Andric SanitizerSet SanOpts; 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric /// True if CodeGen currently emits code implementing sanitizer checks. 5750b57cec5SDimitry Andric bool IsSanitizerScope = false; 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric /// RAII object to set/unset CodeGenFunction::IsSanitizerScope. 5780b57cec5SDimitry Andric class SanitizerScope { 5790b57cec5SDimitry Andric CodeGenFunction *CGF; 5800b57cec5SDimitry Andric public: 5810b57cec5SDimitry Andric SanitizerScope(CodeGenFunction *CGF); 5820b57cec5SDimitry Andric ~SanitizerScope(); 5830b57cec5SDimitry Andric }; 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andric /// In C++, whether we are code generating a thunk. This controls whether we 5860b57cec5SDimitry Andric /// should emit cleanups. 5870b57cec5SDimitry Andric bool CurFuncIsThunk = false; 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric /// In ARC, whether we should autorelease the return value. 5900b57cec5SDimitry Andric bool AutoreleaseResult = false; 5910b57cec5SDimitry Andric 5920b57cec5SDimitry Andric /// Whether we processed a Microsoft-style asm block during CodeGen. These can 5930b57cec5SDimitry Andric /// potentially set the return value. 5940b57cec5SDimitry Andric bool SawAsmBlock = false; 5950b57cec5SDimitry Andric 596bdd1243dSDimitry Andric GlobalDecl CurSEHParent; 5970b57cec5SDimitry Andric 5980b57cec5SDimitry Andric /// True if the current function is an outlined SEH helper. This can be a 5990b57cec5SDimitry Andric /// finally block or filter expression. 6000b57cec5SDimitry Andric bool IsOutlinedSEHHelper = false; 6010b57cec5SDimitry Andric 6020b57cec5SDimitry Andric /// True if CodeGen currently emits code inside presereved access index 6030b57cec5SDimitry Andric /// region. 6040b57cec5SDimitry Andric bool IsInPreservedAIRegion = false; 6050b57cec5SDimitry Andric 6065ffd83dbSDimitry Andric /// True if the current statement has nomerge attribute. 6075ffd83dbSDimitry Andric bool InNoMergeAttributedStmt = false; 6085ffd83dbSDimitry Andric 60981ad6265SDimitry Andric /// True if the current statement has noinline attribute. 61081ad6265SDimitry Andric bool InNoInlineAttributedStmt = false; 61181ad6265SDimitry Andric 61281ad6265SDimitry Andric /// True if the current statement has always_inline attribute. 61381ad6265SDimitry Andric bool InAlwaysInlineAttributedStmt = false; 61481ad6265SDimitry Andric 615fe6060f1SDimitry Andric // The CallExpr within the current statement that the musttail attribute 616fe6060f1SDimitry Andric // applies to. nullptr if there is no 'musttail' on the current statement. 617fe6060f1SDimitry Andric const CallExpr *MustTailCall = nullptr; 618e8d8bef9SDimitry Andric 619fe6060f1SDimitry Andric /// Returns true if a function must make progress, which means the 620fe6060f1SDimitry Andric /// mustprogress attribute can be added. 621fe6060f1SDimitry Andric bool checkIfFunctionMustProgress() { 622d409305fSDimitry Andric if (CGM.getCodeGenOpts().getFiniteLoops() == 623d409305fSDimitry Andric CodeGenOptions::FiniteLoopsKind::Never) 624d409305fSDimitry Andric return false; 625d409305fSDimitry Andric 626fe6060f1SDimitry Andric // C++11 and later guarantees that a thread eventually will do one of the 627bdd1243dSDimitry Andric // following (C++11 [intro.multithread]p24 and C++17 [intro.progress]p1): 628fe6060f1SDimitry Andric // - terminate, 629fe6060f1SDimitry Andric // - make a call to a library I/O function, 630fe6060f1SDimitry Andric // - perform an access through a volatile glvalue, or 631fe6060f1SDimitry Andric // - perform a synchronization operation or an atomic operation. 632fe6060f1SDimitry Andric // 633fe6060f1SDimitry Andric // Hence each function is 'mustprogress' in C++11 or later. 634fe6060f1SDimitry Andric return getLangOpts().CPlusPlus11; 635e8d8bef9SDimitry Andric } 636e8d8bef9SDimitry Andric 637fe6060f1SDimitry Andric /// Returns true if a loop must make progress, which means the mustprogress 638fe6060f1SDimitry Andric /// attribute can be added. \p HasConstantCond indicates whether the branch 639fe6060f1SDimitry Andric /// condition is a known constant. 6400fca6ea1SDimitry Andric bool checkIfLoopMustProgress(const Expr *, bool HasEmptyBody); 641e8d8bef9SDimitry Andric 6420b57cec5SDimitry Andric const CodeGen::CGBlockInfo *BlockInfo = nullptr; 6430b57cec5SDimitry Andric llvm::Value *BlockPointer = nullptr; 6440b57cec5SDimitry Andric 645bdd1243dSDimitry Andric llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields; 6460b57cec5SDimitry Andric FieldDecl *LambdaThisCaptureField = nullptr; 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric /// A mapping from NRVO variables to the flags used to indicate 6490b57cec5SDimitry Andric /// when the NRVO has been applied to this variable. 6500b57cec5SDimitry Andric llvm::DenseMap<const VarDecl *, llvm::Value *> NRVOFlags; 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric EHScopeStack EHStack; 6530b57cec5SDimitry Andric llvm::SmallVector<char, 256> LifetimeExtendedCleanupStack; 6540fca6ea1SDimitry Andric 6550fca6ea1SDimitry Andric // A stack of cleanups which were added to EHStack but have to be deactivated 6560fca6ea1SDimitry Andric // later before being popped or emitted. These are usually deactivated on 6570fca6ea1SDimitry Andric // exiting a `CleanupDeactivationScope` scope. For instance, after a 6580fca6ea1SDimitry Andric // full-expr. 6590fca6ea1SDimitry Andric // 6600fca6ea1SDimitry Andric // These are specially useful for correctly emitting cleanups while 6610fca6ea1SDimitry Andric // encountering branches out of expression (through stmt-expr or coroutine 6620fca6ea1SDimitry Andric // suspensions). 6630fca6ea1SDimitry Andric struct DeferredDeactivateCleanup { 6640fca6ea1SDimitry Andric EHScopeStack::stable_iterator Cleanup; 6650fca6ea1SDimitry Andric llvm::Instruction *DominatingIP; 6660fca6ea1SDimitry Andric }; 6670fca6ea1SDimitry Andric llvm::SmallVector<DeferredDeactivateCleanup> DeferredDeactivationCleanupStack; 6680fca6ea1SDimitry Andric 6690fca6ea1SDimitry Andric // Enters a new scope for capturing cleanups which are deferred to be 6700fca6ea1SDimitry Andric // deactivated, all of which will be deactivated once the scope is exited. 6710fca6ea1SDimitry Andric struct CleanupDeactivationScope { 6720fca6ea1SDimitry Andric CodeGenFunction &CGF; 6730fca6ea1SDimitry Andric size_t OldDeactivateCleanupStackSize; 6740fca6ea1SDimitry Andric bool Deactivated; 6750fca6ea1SDimitry Andric CleanupDeactivationScope(CodeGenFunction &CGF) 6760fca6ea1SDimitry Andric : CGF(CGF), OldDeactivateCleanupStackSize( 6770fca6ea1SDimitry Andric CGF.DeferredDeactivationCleanupStack.size()), 6780fca6ea1SDimitry Andric Deactivated(false) {} 6790fca6ea1SDimitry Andric 6800fca6ea1SDimitry Andric void ForceDeactivate() { 6810fca6ea1SDimitry Andric assert(!Deactivated && "Deactivating already deactivated scope"); 6820fca6ea1SDimitry Andric auto &Stack = CGF.DeferredDeactivationCleanupStack; 6830fca6ea1SDimitry Andric for (size_t I = Stack.size(); I > OldDeactivateCleanupStackSize; I--) { 6840fca6ea1SDimitry Andric CGF.DeactivateCleanupBlock(Stack[I - 1].Cleanup, 6850fca6ea1SDimitry Andric Stack[I - 1].DominatingIP); 6860fca6ea1SDimitry Andric Stack[I - 1].DominatingIP->eraseFromParent(); 6870fca6ea1SDimitry Andric } 6880fca6ea1SDimitry Andric Stack.resize(OldDeactivateCleanupStackSize); 6890fca6ea1SDimitry Andric Deactivated = true; 6900fca6ea1SDimitry Andric } 6910fca6ea1SDimitry Andric 6920fca6ea1SDimitry Andric ~CleanupDeactivationScope() { 6930fca6ea1SDimitry Andric if (Deactivated) 6940fca6ea1SDimitry Andric return; 6950fca6ea1SDimitry Andric ForceDeactivate(); 6960fca6ea1SDimitry Andric } 6970fca6ea1SDimitry Andric }; 6980fca6ea1SDimitry Andric 6990b57cec5SDimitry Andric llvm::SmallVector<const JumpDest *, 2> SEHTryEpilogueStack; 7000b57cec5SDimitry Andric 7010b57cec5SDimitry Andric llvm::Instruction *CurrentFuncletPad = nullptr; 7020b57cec5SDimitry Andric 7030b57cec5SDimitry Andric class CallLifetimeEnd final : public EHScopeStack::Cleanup { 704fe6060f1SDimitry Andric bool isRedundantBeforeReturn() override { return true; } 705fe6060f1SDimitry Andric 7060b57cec5SDimitry Andric llvm::Value *Addr; 7070b57cec5SDimitry Andric llvm::Value *Size; 7080b57cec5SDimitry Andric 7090b57cec5SDimitry Andric public: 7100fca6ea1SDimitry Andric CallLifetimeEnd(RawAddress addr, llvm::Value *size) 7110b57cec5SDimitry Andric : Addr(addr.getPointer()), Size(size) {} 7120b57cec5SDimitry Andric 7130b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 7140b57cec5SDimitry Andric CGF.EmitLifetimeEnd(Size, Addr); 7150b57cec5SDimitry Andric } 7160b57cec5SDimitry Andric }; 7170b57cec5SDimitry Andric 7180b57cec5SDimitry Andric /// Header for data within LifetimeExtendedCleanupStack. 7190b57cec5SDimitry Andric struct LifetimeExtendedCleanupHeader { 7200b57cec5SDimitry Andric /// The size of the following cleanup object. 7210b57cec5SDimitry Andric unsigned Size; 7220fca6ea1SDimitry Andric /// The kind of cleanup to push. 7230fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(CleanupKind) 7240b57cec5SDimitry Andric unsigned Kind : 31; 7250b57cec5SDimitry Andric /// Whether this is a conditional cleanup. 7260fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 7270b57cec5SDimitry Andric unsigned IsConditional : 1; 7280b57cec5SDimitry Andric 7290b57cec5SDimitry Andric size_t getSize() const { return Size; } 7300b57cec5SDimitry Andric CleanupKind getKind() const { return (CleanupKind)Kind; } 7310b57cec5SDimitry Andric bool isConditional() const { return IsConditional; } 7320b57cec5SDimitry Andric }; 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric /// i32s containing the indexes of the cleanup destinations. 7350fca6ea1SDimitry Andric RawAddress NormalCleanupDest = RawAddress::invalid(); 7360b57cec5SDimitry Andric 7370b57cec5SDimitry Andric unsigned NextCleanupDestIndex = 1; 7380b57cec5SDimitry Andric 7390b57cec5SDimitry Andric /// EHResumeBlock - Unified block containing a call to llvm.eh.resume. 7400b57cec5SDimitry Andric llvm::BasicBlock *EHResumeBlock = nullptr; 7410b57cec5SDimitry Andric 7420b57cec5SDimitry Andric /// The exception slot. All landing pads write the current exception pointer 7430b57cec5SDimitry Andric /// into this alloca. 7440b57cec5SDimitry Andric llvm::Value *ExceptionSlot = nullptr; 7450b57cec5SDimitry Andric 7460b57cec5SDimitry Andric /// The selector slot. Under the MandatoryCleanup model, all landing pads 7470b57cec5SDimitry Andric /// write the current selector value into this alloca. 7480b57cec5SDimitry Andric llvm::AllocaInst *EHSelectorSlot = nullptr; 7490b57cec5SDimitry Andric 7500b57cec5SDimitry Andric /// A stack of exception code slots. Entering an __except block pushes a slot 7510b57cec5SDimitry Andric /// on the stack and leaving pops one. The __exception_code() intrinsic loads 7520b57cec5SDimitry Andric /// a value from the top of the stack. 7530b57cec5SDimitry Andric SmallVector<Address, 1> SEHCodeSlotStack; 7540b57cec5SDimitry Andric 7550b57cec5SDimitry Andric /// Value returned by __exception_info intrinsic. 7560b57cec5SDimitry Andric llvm::Value *SEHInfo = nullptr; 7570b57cec5SDimitry Andric 7580b57cec5SDimitry Andric /// Emits a landing pad for the current EH stack. 7590b57cec5SDimitry Andric llvm::BasicBlock *EmitLandingPad(); 7600b57cec5SDimitry Andric 7610b57cec5SDimitry Andric llvm::BasicBlock *getInvokeDestImpl(); 7620b57cec5SDimitry Andric 7635ffd83dbSDimitry Andric /// Parent loop-based directive for scan directive. 7645ffd83dbSDimitry Andric const OMPExecutableDirective *OMPParentLoopDirectiveForScan = nullptr; 7655ffd83dbSDimitry Andric llvm::BasicBlock *OMPBeforeScanBlock = nullptr; 7665ffd83dbSDimitry Andric llvm::BasicBlock *OMPAfterScanBlock = nullptr; 7675ffd83dbSDimitry Andric llvm::BasicBlock *OMPScanExitBlock = nullptr; 7685ffd83dbSDimitry Andric llvm::BasicBlock *OMPScanDispatch = nullptr; 7695ffd83dbSDimitry Andric bool OMPFirstScanLoop = false; 7705ffd83dbSDimitry Andric 7715ffd83dbSDimitry Andric /// Manages parent directive for scan directives. 7725ffd83dbSDimitry Andric class ParentLoopDirectiveForScanRegion { 7735ffd83dbSDimitry Andric CodeGenFunction &CGF; 7745ffd83dbSDimitry Andric const OMPExecutableDirective *ParentLoopDirectiveForScan; 7755ffd83dbSDimitry Andric 7765ffd83dbSDimitry Andric public: 7775ffd83dbSDimitry Andric ParentLoopDirectiveForScanRegion( 7785ffd83dbSDimitry Andric CodeGenFunction &CGF, 7795ffd83dbSDimitry Andric const OMPExecutableDirective &ParentLoopDirectiveForScan) 7805ffd83dbSDimitry Andric : CGF(CGF), 7815ffd83dbSDimitry Andric ParentLoopDirectiveForScan(CGF.OMPParentLoopDirectiveForScan) { 7825ffd83dbSDimitry Andric CGF.OMPParentLoopDirectiveForScan = &ParentLoopDirectiveForScan; 7835ffd83dbSDimitry Andric } 7845ffd83dbSDimitry Andric ~ParentLoopDirectiveForScanRegion() { 7855ffd83dbSDimitry Andric CGF.OMPParentLoopDirectiveForScan = ParentLoopDirectiveForScan; 7865ffd83dbSDimitry Andric } 7875ffd83dbSDimitry Andric }; 7885ffd83dbSDimitry Andric 7890b57cec5SDimitry Andric template <class T> 7900b57cec5SDimitry Andric typename DominatingValue<T>::saved_type saveValueInCond(T value) { 7910b57cec5SDimitry Andric return DominatingValue<T>::save(*this, value); 7920b57cec5SDimitry Andric } 7930b57cec5SDimitry Andric 7945ffd83dbSDimitry Andric class CGFPOptionsRAII { 7955ffd83dbSDimitry Andric public: 7965ffd83dbSDimitry Andric CGFPOptionsRAII(CodeGenFunction &CGF, FPOptions FPFeatures); 797e8d8bef9SDimitry Andric CGFPOptionsRAII(CodeGenFunction &CGF, const Expr *E); 7985ffd83dbSDimitry Andric ~CGFPOptionsRAII(); 7995ffd83dbSDimitry Andric 8005ffd83dbSDimitry Andric private: 801e8d8bef9SDimitry Andric void ConstructorHelper(FPOptions FPFeatures); 8025ffd83dbSDimitry Andric CodeGenFunction &CGF; 8035ffd83dbSDimitry Andric FPOptions OldFPFeatures; 804e8d8bef9SDimitry Andric llvm::fp::ExceptionBehavior OldExcept; 805e8d8bef9SDimitry Andric llvm::RoundingMode OldRounding; 806bdd1243dSDimitry Andric std::optional<CGBuilderTy::FastMathFlagGuard> FMFGuard; 8075ffd83dbSDimitry Andric }; 8085ffd83dbSDimitry Andric FPOptions CurFPFeatures; 8095ffd83dbSDimitry Andric 8100b57cec5SDimitry Andric public: 8110b57cec5SDimitry Andric /// ObjCEHValueStack - Stack of Objective-C exception values, used for 8120b57cec5SDimitry Andric /// rethrows. 8130b57cec5SDimitry Andric SmallVector<llvm::Value*, 8> ObjCEHValueStack; 8140b57cec5SDimitry Andric 8150b57cec5SDimitry Andric /// A class controlling the emission of a finally block. 8160b57cec5SDimitry Andric class FinallyInfo { 8170b57cec5SDimitry Andric /// Where the catchall's edge through the cleanup should go. 8180b57cec5SDimitry Andric JumpDest RethrowDest; 8190b57cec5SDimitry Andric 8200b57cec5SDimitry Andric /// A function to call to enter the catch. 8210b57cec5SDimitry Andric llvm::FunctionCallee BeginCatchFn; 8220b57cec5SDimitry Andric 8230b57cec5SDimitry Andric /// An i1 variable indicating whether or not the @finally is 8240b57cec5SDimitry Andric /// running for an exception. 82506c3fb27SDimitry Andric llvm::AllocaInst *ForEHVar = nullptr; 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric /// An i8* variable into which the exception pointer to rethrow 8280b57cec5SDimitry Andric /// has been saved. 82906c3fb27SDimitry Andric llvm::AllocaInst *SavedExnVar = nullptr; 8300b57cec5SDimitry Andric 8310b57cec5SDimitry Andric public: 8320b57cec5SDimitry Andric void enter(CodeGenFunction &CGF, const Stmt *Finally, 8330b57cec5SDimitry Andric llvm::FunctionCallee beginCatchFn, 8340b57cec5SDimitry Andric llvm::FunctionCallee endCatchFn, llvm::FunctionCallee rethrowFn); 8350b57cec5SDimitry Andric void exit(CodeGenFunction &CGF); 8360b57cec5SDimitry Andric }; 8370b57cec5SDimitry Andric 8380b57cec5SDimitry Andric /// Returns true inside SEH __try blocks. 8390b57cec5SDimitry Andric bool isSEHTryScope() const { return !SEHTryEpilogueStack.empty(); } 8400b57cec5SDimitry Andric 8410b57cec5SDimitry Andric /// Returns true while emitting a cleanuppad. 8420b57cec5SDimitry Andric bool isCleanupPadScope() const { 8430b57cec5SDimitry Andric return CurrentFuncletPad && isa<llvm::CleanupPadInst>(CurrentFuncletPad); 8440b57cec5SDimitry Andric } 8450b57cec5SDimitry Andric 8460b57cec5SDimitry Andric /// pushFullExprCleanup - Push a cleanup to be run at the end of the 8470b57cec5SDimitry Andric /// current full-expression. Safe against the possibility that 8480b57cec5SDimitry Andric /// we're currently inside a conditionally-evaluated expression. 8490b57cec5SDimitry Andric template <class T, class... As> 8500b57cec5SDimitry Andric void pushFullExprCleanup(CleanupKind kind, As... A) { 8510b57cec5SDimitry Andric // If we're not in a conditional branch, or if none of the 8520b57cec5SDimitry Andric // arguments requires saving, then use the unconditional cleanup. 8530b57cec5SDimitry Andric if (!isInConditionalBranch()) 8540b57cec5SDimitry Andric return EHStack.pushCleanup<T>(kind, A...); 8550b57cec5SDimitry Andric 8560b57cec5SDimitry Andric // Stash values in a tuple so we can guarantee the order of saves. 8570b57cec5SDimitry Andric typedef std::tuple<typename DominatingValue<As>::saved_type...> SavedTuple; 8580b57cec5SDimitry Andric SavedTuple Saved{saveValueInCond(A)...}; 8590b57cec5SDimitry Andric 8600b57cec5SDimitry Andric typedef EHScopeStack::ConditionalCleanup<T, As...> CleanupType; 8610b57cec5SDimitry Andric EHStack.pushCleanupTuple<CleanupType>(kind, Saved); 8620b57cec5SDimitry Andric initFullExprCleanup(); 8630b57cec5SDimitry Andric } 8640b57cec5SDimitry Andric 865e8d8bef9SDimitry Andric /// Queue a cleanup to be pushed after finishing the current full-expression, 866e8d8bef9SDimitry Andric /// potentially with an active flag. 8670b57cec5SDimitry Andric template <class T, class... As> 8680b57cec5SDimitry Andric void pushCleanupAfterFullExpr(CleanupKind Kind, As... A) { 8690b57cec5SDimitry Andric if (!isInConditionalBranch()) 8700fca6ea1SDimitry Andric return pushCleanupAfterFullExprWithActiveFlag<T>( 8710fca6ea1SDimitry Andric Kind, RawAddress::invalid(), A...); 8720b57cec5SDimitry Andric 8730fca6ea1SDimitry Andric RawAddress ActiveFlag = createCleanupActiveFlag(); 8740b57cec5SDimitry Andric assert(!DominatingValue<Address>::needsSaving(ActiveFlag) && 8750b57cec5SDimitry Andric "cleanup active flag should never need saving"); 8760b57cec5SDimitry Andric 8770b57cec5SDimitry Andric typedef std::tuple<typename DominatingValue<As>::saved_type...> SavedTuple; 8780b57cec5SDimitry Andric SavedTuple Saved{saveValueInCond(A)...}; 8790b57cec5SDimitry Andric 8800b57cec5SDimitry Andric typedef EHScopeStack::ConditionalCleanup<T, As...> CleanupType; 881e8d8bef9SDimitry Andric pushCleanupAfterFullExprWithActiveFlag<CleanupType>(Kind, ActiveFlag, Saved); 8820b57cec5SDimitry Andric } 8830b57cec5SDimitry Andric 8840b57cec5SDimitry Andric template <class T, class... As> 885e8d8bef9SDimitry Andric void pushCleanupAfterFullExprWithActiveFlag(CleanupKind Kind, 8860fca6ea1SDimitry Andric RawAddress ActiveFlag, As... A) { 8870b57cec5SDimitry Andric LifetimeExtendedCleanupHeader Header = {sizeof(T), Kind, 8880b57cec5SDimitry Andric ActiveFlag.isValid()}; 8890b57cec5SDimitry Andric 8900b57cec5SDimitry Andric size_t OldSize = LifetimeExtendedCleanupStack.size(); 8910b57cec5SDimitry Andric LifetimeExtendedCleanupStack.resize( 8920b57cec5SDimitry Andric LifetimeExtendedCleanupStack.size() + sizeof(Header) + Header.Size + 8930b57cec5SDimitry Andric (Header.IsConditional ? sizeof(ActiveFlag) : 0)); 8940b57cec5SDimitry Andric 8950b57cec5SDimitry Andric static_assert(sizeof(Header) % alignof(T) == 0, 8960b57cec5SDimitry Andric "Cleanup will be allocated on misaligned address"); 8970b57cec5SDimitry Andric char *Buffer = &LifetimeExtendedCleanupStack[OldSize]; 8980b57cec5SDimitry Andric new (Buffer) LifetimeExtendedCleanupHeader(Header); 8990b57cec5SDimitry Andric new (Buffer + sizeof(Header)) T(A...); 9000b57cec5SDimitry Andric if (Header.IsConditional) 9010fca6ea1SDimitry Andric new (Buffer + sizeof(Header) + sizeof(T)) RawAddress(ActiveFlag); 9020fca6ea1SDimitry Andric } 9030fca6ea1SDimitry Andric 9040fca6ea1SDimitry Andric // Push a cleanup onto EHStack and deactivate it later. It is usually 9050fca6ea1SDimitry Andric // deactivated when exiting a `CleanupDeactivationScope` (for example: after a 9060fca6ea1SDimitry Andric // full expression). 9070fca6ea1SDimitry Andric template <class T, class... As> 9080fca6ea1SDimitry Andric void pushCleanupAndDeferDeactivation(CleanupKind Kind, As... A) { 9090fca6ea1SDimitry Andric // Placeholder dominating IP for this cleanup. 9100fca6ea1SDimitry Andric llvm::Instruction *DominatingIP = 9110fca6ea1SDimitry Andric Builder.CreateFlagLoad(llvm::Constant::getNullValue(Int8PtrTy)); 9120fca6ea1SDimitry Andric EHStack.pushCleanup<T>(Kind, A...); 9130fca6ea1SDimitry Andric DeferredDeactivationCleanupStack.push_back( 9140fca6ea1SDimitry Andric {EHStack.stable_begin(), DominatingIP}); 9150b57cec5SDimitry Andric } 9160b57cec5SDimitry Andric 9170b57cec5SDimitry Andric /// Set up the last cleanup that was pushed as a conditional 9180b57cec5SDimitry Andric /// full-expression cleanup. 9190b57cec5SDimitry Andric void initFullExprCleanup() { 9200b57cec5SDimitry Andric initFullExprCleanupWithFlag(createCleanupActiveFlag()); 9210b57cec5SDimitry Andric } 9220b57cec5SDimitry Andric 9230fca6ea1SDimitry Andric void initFullExprCleanupWithFlag(RawAddress ActiveFlag); 9240fca6ea1SDimitry Andric RawAddress createCleanupActiveFlag(); 9250b57cec5SDimitry Andric 9260b57cec5SDimitry Andric /// PushDestructorCleanup - Push a cleanup to call the 9270b57cec5SDimitry Andric /// complete-object destructor of an object of the given type at the 9280b57cec5SDimitry Andric /// given address. Does nothing if T is not a C++ class type with a 9290b57cec5SDimitry Andric /// non-trivial destructor. 9300b57cec5SDimitry Andric void PushDestructorCleanup(QualType T, Address Addr); 9310b57cec5SDimitry Andric 9320b57cec5SDimitry Andric /// PushDestructorCleanup - Push a cleanup to call the 9330b57cec5SDimitry Andric /// complete-object variant of the given destructor on the object at 9340b57cec5SDimitry Andric /// the given address. 9350b57cec5SDimitry Andric void PushDestructorCleanup(const CXXDestructorDecl *Dtor, QualType T, 9360b57cec5SDimitry Andric Address Addr); 9370b57cec5SDimitry Andric 9380b57cec5SDimitry Andric /// PopCleanupBlock - Will pop the cleanup entry on the stack and 9390b57cec5SDimitry Andric /// process all branch fixups. 9400fca6ea1SDimitry Andric void PopCleanupBlock(bool FallThroughIsBranchThrough = false, 9410fca6ea1SDimitry Andric bool ForDeactivation = false); 9420b57cec5SDimitry Andric 9430b57cec5SDimitry Andric /// DeactivateCleanupBlock - Deactivates the given cleanup block. 9440b57cec5SDimitry Andric /// The block cannot be reactivated. Pops it if it's the top of the 9450b57cec5SDimitry Andric /// stack. 9460b57cec5SDimitry Andric /// 9470b57cec5SDimitry Andric /// \param DominatingIP - An instruction which is known to 9480b57cec5SDimitry Andric /// dominate the current IP (if set) and which lies along 9490b57cec5SDimitry Andric /// all paths of execution between the current IP and the 9500b57cec5SDimitry Andric /// the point at which the cleanup comes into scope. 9510b57cec5SDimitry Andric void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, 9520b57cec5SDimitry Andric llvm::Instruction *DominatingIP); 9530b57cec5SDimitry Andric 9540b57cec5SDimitry Andric /// ActivateCleanupBlock - Activates an initially-inactive cleanup. 9550b57cec5SDimitry Andric /// Cannot be used to resurrect a deactivated cleanup. 9560b57cec5SDimitry Andric /// 9570b57cec5SDimitry Andric /// \param DominatingIP - An instruction which is known to 9580b57cec5SDimitry Andric /// dominate the current IP (if set) and which lies along 9590b57cec5SDimitry Andric /// all paths of execution between the current IP and the 9600b57cec5SDimitry Andric /// the point at which the cleanup comes into scope. 9610b57cec5SDimitry Andric void ActivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, 9620b57cec5SDimitry Andric llvm::Instruction *DominatingIP); 9630b57cec5SDimitry Andric 9640b57cec5SDimitry Andric /// Enters a new scope for capturing cleanups, all of which 9650b57cec5SDimitry Andric /// will be executed once the scope is exited. 9660b57cec5SDimitry Andric class RunCleanupsScope { 9670b57cec5SDimitry Andric EHScopeStack::stable_iterator CleanupStackDepth, OldCleanupScopeDepth; 9680b57cec5SDimitry Andric size_t LifetimeExtendedCleanupStackSize; 9690fca6ea1SDimitry Andric CleanupDeactivationScope DeactivateCleanups; 9700b57cec5SDimitry Andric bool OldDidCallStackSave; 9710b57cec5SDimitry Andric protected: 9720b57cec5SDimitry Andric bool PerformCleanup; 9730b57cec5SDimitry Andric private: 9740b57cec5SDimitry Andric 9750b57cec5SDimitry Andric RunCleanupsScope(const RunCleanupsScope &) = delete; 9760b57cec5SDimitry Andric void operator=(const RunCleanupsScope &) = delete; 9770b57cec5SDimitry Andric 9780b57cec5SDimitry Andric protected: 9790b57cec5SDimitry Andric CodeGenFunction& CGF; 9800b57cec5SDimitry Andric 9810b57cec5SDimitry Andric public: 9820b57cec5SDimitry Andric /// Enter a new cleanup scope. 9830b57cec5SDimitry Andric explicit RunCleanupsScope(CodeGenFunction &CGF) 9840fca6ea1SDimitry Andric : DeactivateCleanups(CGF), PerformCleanup(true), CGF(CGF) { 9850b57cec5SDimitry Andric CleanupStackDepth = CGF.EHStack.stable_begin(); 9860b57cec5SDimitry Andric LifetimeExtendedCleanupStackSize = 9870b57cec5SDimitry Andric CGF.LifetimeExtendedCleanupStack.size(); 9880b57cec5SDimitry Andric OldDidCallStackSave = CGF.DidCallStackSave; 9890b57cec5SDimitry Andric CGF.DidCallStackSave = false; 9900b57cec5SDimitry Andric OldCleanupScopeDepth = CGF.CurrentCleanupScopeDepth; 9910b57cec5SDimitry Andric CGF.CurrentCleanupScopeDepth = CleanupStackDepth; 9920b57cec5SDimitry Andric } 9930b57cec5SDimitry Andric 9940b57cec5SDimitry Andric /// Exit this cleanup scope, emitting any accumulated cleanups. 9950b57cec5SDimitry Andric ~RunCleanupsScope() { 9960b57cec5SDimitry Andric if (PerformCleanup) 9970b57cec5SDimitry Andric ForceCleanup(); 9980b57cec5SDimitry Andric } 9990b57cec5SDimitry Andric 10000b57cec5SDimitry Andric /// Determine whether this scope requires any cleanups. 10010b57cec5SDimitry Andric bool requiresCleanups() const { 10020b57cec5SDimitry Andric return CGF.EHStack.stable_begin() != CleanupStackDepth; 10030b57cec5SDimitry Andric } 10040b57cec5SDimitry Andric 10050b57cec5SDimitry Andric /// Force the emission of cleanups now, instead of waiting 10060b57cec5SDimitry Andric /// until this object is destroyed. 10070b57cec5SDimitry Andric /// \param ValuesToReload - A list of values that need to be available at 10080b57cec5SDimitry Andric /// the insertion point after cleanup emission. If cleanup emission created 10090b57cec5SDimitry Andric /// a shared cleanup block, these value pointers will be rewritten. 10100b57cec5SDimitry Andric /// Otherwise, they not will be modified. 10110b57cec5SDimitry Andric void ForceCleanup(std::initializer_list<llvm::Value**> ValuesToReload = {}) { 10120b57cec5SDimitry Andric assert(PerformCleanup && "Already forced cleanup"); 10130b57cec5SDimitry Andric CGF.DidCallStackSave = OldDidCallStackSave; 10140fca6ea1SDimitry Andric DeactivateCleanups.ForceDeactivate(); 10150b57cec5SDimitry Andric CGF.PopCleanupBlocks(CleanupStackDepth, LifetimeExtendedCleanupStackSize, 10160b57cec5SDimitry Andric ValuesToReload); 10170b57cec5SDimitry Andric PerformCleanup = false; 10180b57cec5SDimitry Andric CGF.CurrentCleanupScopeDepth = OldCleanupScopeDepth; 10190b57cec5SDimitry Andric } 10200b57cec5SDimitry Andric }; 10210b57cec5SDimitry Andric 10220b57cec5SDimitry Andric // Cleanup stack depth of the RunCleanupsScope that was pushed most recently. 10230b57cec5SDimitry Andric EHScopeStack::stable_iterator CurrentCleanupScopeDepth = 10240b57cec5SDimitry Andric EHScopeStack::stable_end(); 10250b57cec5SDimitry Andric 10260b57cec5SDimitry Andric class LexicalScope : public RunCleanupsScope { 10270b57cec5SDimitry Andric SourceRange Range; 10280b57cec5SDimitry Andric SmallVector<const LabelDecl*, 4> Labels; 10290b57cec5SDimitry Andric LexicalScope *ParentScope; 10300b57cec5SDimitry Andric 10310b57cec5SDimitry Andric LexicalScope(const LexicalScope &) = delete; 10320b57cec5SDimitry Andric void operator=(const LexicalScope &) = delete; 10330b57cec5SDimitry Andric 10340b57cec5SDimitry Andric public: 10350b57cec5SDimitry Andric /// Enter a new cleanup scope. 10360b57cec5SDimitry Andric explicit LexicalScope(CodeGenFunction &CGF, SourceRange Range) 10370b57cec5SDimitry Andric : RunCleanupsScope(CGF), Range(Range), ParentScope(CGF.CurLexicalScope) { 10380b57cec5SDimitry Andric CGF.CurLexicalScope = this; 10390b57cec5SDimitry Andric if (CGDebugInfo *DI = CGF.getDebugInfo()) 10400b57cec5SDimitry Andric DI->EmitLexicalBlockStart(CGF.Builder, Range.getBegin()); 10410b57cec5SDimitry Andric } 10420b57cec5SDimitry Andric 10430b57cec5SDimitry Andric void addLabel(const LabelDecl *label) { 10440b57cec5SDimitry Andric assert(PerformCleanup && "adding label to dead scope?"); 10450b57cec5SDimitry Andric Labels.push_back(label); 10460b57cec5SDimitry Andric } 10470b57cec5SDimitry Andric 10480b57cec5SDimitry Andric /// Exit this cleanup scope, emitting any accumulated 10490b57cec5SDimitry Andric /// cleanups. 10500b57cec5SDimitry Andric ~LexicalScope() { 10510b57cec5SDimitry Andric if (CGDebugInfo *DI = CGF.getDebugInfo()) 10520b57cec5SDimitry Andric DI->EmitLexicalBlockEnd(CGF.Builder, Range.getEnd()); 10530b57cec5SDimitry Andric 10540b57cec5SDimitry Andric // If we should perform a cleanup, force them now. Note that 10550b57cec5SDimitry Andric // this ends the cleanup scope before rescoping any labels. 10560b57cec5SDimitry Andric if (PerformCleanup) { 10570b57cec5SDimitry Andric ApplyDebugLocation DL(CGF, Range.getEnd()); 10580b57cec5SDimitry Andric ForceCleanup(); 10590b57cec5SDimitry Andric } 10600b57cec5SDimitry Andric } 10610b57cec5SDimitry Andric 10620b57cec5SDimitry Andric /// Force the emission of cleanups now, instead of waiting 10630b57cec5SDimitry Andric /// until this object is destroyed. 10640b57cec5SDimitry Andric void ForceCleanup() { 10650b57cec5SDimitry Andric CGF.CurLexicalScope = ParentScope; 10660b57cec5SDimitry Andric RunCleanupsScope::ForceCleanup(); 10670b57cec5SDimitry Andric 10680b57cec5SDimitry Andric if (!Labels.empty()) 10690b57cec5SDimitry Andric rescopeLabels(); 10700b57cec5SDimitry Andric } 10710b57cec5SDimitry Andric 10720b57cec5SDimitry Andric bool hasLabels() const { 10730b57cec5SDimitry Andric return !Labels.empty(); 10740b57cec5SDimitry Andric } 10750b57cec5SDimitry Andric 10760b57cec5SDimitry Andric void rescopeLabels(); 10770b57cec5SDimitry Andric }; 10780b57cec5SDimitry Andric 10790b57cec5SDimitry Andric typedef llvm::DenseMap<const Decl *, Address> DeclMapTy; 10800b57cec5SDimitry Andric 10810b57cec5SDimitry Andric /// The class used to assign some variables some temporarily addresses. 10820b57cec5SDimitry Andric class OMPMapVars { 10830b57cec5SDimitry Andric DeclMapTy SavedLocals; 10840b57cec5SDimitry Andric DeclMapTy SavedTempAddresses; 10850b57cec5SDimitry Andric OMPMapVars(const OMPMapVars &) = delete; 10860b57cec5SDimitry Andric void operator=(const OMPMapVars &) = delete; 10870b57cec5SDimitry Andric 10880b57cec5SDimitry Andric public: 10890b57cec5SDimitry Andric explicit OMPMapVars() = default; 10900b57cec5SDimitry Andric ~OMPMapVars() { 10910b57cec5SDimitry Andric assert(SavedLocals.empty() && "Did not restored original addresses."); 10920b57cec5SDimitry Andric }; 10930b57cec5SDimitry Andric 10940b57cec5SDimitry Andric /// Sets the address of the variable \p LocalVD to be \p TempAddr in 10950b57cec5SDimitry Andric /// function \p CGF. 10960b57cec5SDimitry Andric /// \return true if at least one variable was set already, false otherwise. 10970b57cec5SDimitry Andric bool setVarAddr(CodeGenFunction &CGF, const VarDecl *LocalVD, 10980b57cec5SDimitry Andric Address TempAddr) { 10990b57cec5SDimitry Andric LocalVD = LocalVD->getCanonicalDecl(); 11000b57cec5SDimitry Andric // Only save it once. 11010b57cec5SDimitry Andric if (SavedLocals.count(LocalVD)) return false; 11020b57cec5SDimitry Andric 11030b57cec5SDimitry Andric // Copy the existing local entry to SavedLocals. 11040b57cec5SDimitry Andric auto it = CGF.LocalDeclMap.find(LocalVD); 11050b57cec5SDimitry Andric if (it != CGF.LocalDeclMap.end()) 11060b57cec5SDimitry Andric SavedLocals.try_emplace(LocalVD, it->second); 11070b57cec5SDimitry Andric else 11080b57cec5SDimitry Andric SavedLocals.try_emplace(LocalVD, Address::invalid()); 11090b57cec5SDimitry Andric 11100b57cec5SDimitry Andric // Generate the private entry. 11110b57cec5SDimitry Andric QualType VarTy = LocalVD->getType(); 11120b57cec5SDimitry Andric if (VarTy->isReferenceType()) { 11130b57cec5SDimitry Andric Address Temp = CGF.CreateMemTemp(VarTy); 11140fca6ea1SDimitry Andric CGF.Builder.CreateStore(TempAddr.emitRawPointer(CGF), Temp); 11150b57cec5SDimitry Andric TempAddr = Temp; 11160b57cec5SDimitry Andric } 11170b57cec5SDimitry Andric SavedTempAddresses.try_emplace(LocalVD, TempAddr); 11180b57cec5SDimitry Andric 11190b57cec5SDimitry Andric return true; 11200b57cec5SDimitry Andric } 11210b57cec5SDimitry Andric 11220b57cec5SDimitry Andric /// Applies new addresses to the list of the variables. 11230b57cec5SDimitry Andric /// \return true if at least one variable is using new address, false 11240b57cec5SDimitry Andric /// otherwise. 11250b57cec5SDimitry Andric bool apply(CodeGenFunction &CGF) { 11260b57cec5SDimitry Andric copyInto(SavedTempAddresses, CGF.LocalDeclMap); 11270b57cec5SDimitry Andric SavedTempAddresses.clear(); 11280b57cec5SDimitry Andric return !SavedLocals.empty(); 11290b57cec5SDimitry Andric } 11300b57cec5SDimitry Andric 11310b57cec5SDimitry Andric /// Restores original addresses of the variables. 11320b57cec5SDimitry Andric void restore(CodeGenFunction &CGF) { 11330b57cec5SDimitry Andric if (!SavedLocals.empty()) { 11340b57cec5SDimitry Andric copyInto(SavedLocals, CGF.LocalDeclMap); 11350b57cec5SDimitry Andric SavedLocals.clear(); 11360b57cec5SDimitry Andric } 11370b57cec5SDimitry Andric } 11380b57cec5SDimitry Andric 11390b57cec5SDimitry Andric private: 11400b57cec5SDimitry Andric /// Copy all the entries in the source map over the corresponding 11410b57cec5SDimitry Andric /// entries in the destination, which must exist. 11420b57cec5SDimitry Andric static void copyInto(const DeclMapTy &Src, DeclMapTy &Dest) { 11430b57cec5SDimitry Andric for (auto &Pair : Src) { 11440b57cec5SDimitry Andric if (!Pair.second.isValid()) { 11450b57cec5SDimitry Andric Dest.erase(Pair.first); 11460b57cec5SDimitry Andric continue; 11470b57cec5SDimitry Andric } 11480b57cec5SDimitry Andric 11490b57cec5SDimitry Andric auto I = Dest.find(Pair.first); 11500b57cec5SDimitry Andric if (I != Dest.end()) 11510b57cec5SDimitry Andric I->second = Pair.second; 11520b57cec5SDimitry Andric else 11530b57cec5SDimitry Andric Dest.insert(Pair); 11540b57cec5SDimitry Andric } 11550b57cec5SDimitry Andric } 11560b57cec5SDimitry Andric }; 11570b57cec5SDimitry Andric 11580b57cec5SDimitry Andric /// The scope used to remap some variables as private in the OpenMP loop body 11590b57cec5SDimitry Andric /// (or other captured region emitted without outlining), and to restore old 11600b57cec5SDimitry Andric /// vars back on exit. 11610b57cec5SDimitry Andric class OMPPrivateScope : public RunCleanupsScope { 11620b57cec5SDimitry Andric OMPMapVars MappedVars; 11630b57cec5SDimitry Andric OMPPrivateScope(const OMPPrivateScope &) = delete; 11640b57cec5SDimitry Andric void operator=(const OMPPrivateScope &) = delete; 11650b57cec5SDimitry Andric 11660b57cec5SDimitry Andric public: 11670b57cec5SDimitry Andric /// Enter a new OpenMP private scope. 11680b57cec5SDimitry Andric explicit OMPPrivateScope(CodeGenFunction &CGF) : RunCleanupsScope(CGF) {} 11690b57cec5SDimitry Andric 117081ad6265SDimitry Andric /// Registers \p LocalVD variable as a private with \p Addr as the address 117181ad6265SDimitry Andric /// of the corresponding private variable. \p 117281ad6265SDimitry Andric /// PrivateGen is the address of the generated private variable. 11730b57cec5SDimitry Andric /// \return true if the variable is registered as private, false if it has 11740b57cec5SDimitry Andric /// been privatized already. 117581ad6265SDimitry Andric bool addPrivate(const VarDecl *LocalVD, Address Addr) { 11760b57cec5SDimitry Andric assert(PerformCleanup && "adding private to dead scope"); 117781ad6265SDimitry Andric return MappedVars.setVarAddr(CGF, LocalVD, Addr); 11780b57cec5SDimitry Andric } 11790b57cec5SDimitry Andric 11800b57cec5SDimitry Andric /// Privatizes local variables previously registered as private. 11810b57cec5SDimitry Andric /// Registration is separate from the actual privatization to allow 11820b57cec5SDimitry Andric /// initializers use values of the original variables, not the private one. 11830b57cec5SDimitry Andric /// This is important, for example, if the private variable is a class 11840b57cec5SDimitry Andric /// variable initialized by a constructor that references other private 11850b57cec5SDimitry Andric /// variables. But at initialization original variables must be used, not 11860b57cec5SDimitry Andric /// private copies. 11870b57cec5SDimitry Andric /// \return true if at least one variable was privatized, false otherwise. 11880b57cec5SDimitry Andric bool Privatize() { return MappedVars.apply(CGF); } 11890b57cec5SDimitry Andric 11900b57cec5SDimitry Andric void ForceCleanup() { 11910b57cec5SDimitry Andric RunCleanupsScope::ForceCleanup(); 1192a4a491e2SDimitry Andric restoreMap(); 11930b57cec5SDimitry Andric } 11940b57cec5SDimitry Andric 11950b57cec5SDimitry Andric /// Exit scope - all the mapped variables are restored. 11960b57cec5SDimitry Andric ~OMPPrivateScope() { 11970b57cec5SDimitry Andric if (PerformCleanup) 11980b57cec5SDimitry Andric ForceCleanup(); 11990b57cec5SDimitry Andric } 12000b57cec5SDimitry Andric 12010b57cec5SDimitry Andric /// Checks if the global variable is captured in current function. 12020b57cec5SDimitry Andric bool isGlobalVarCaptured(const VarDecl *VD) const { 12030b57cec5SDimitry Andric VD = VD->getCanonicalDecl(); 12040b57cec5SDimitry Andric return !VD->isLocalVarDeclOrParm() && CGF.LocalDeclMap.count(VD) > 0; 12050b57cec5SDimitry Andric } 1206a4a491e2SDimitry Andric 1207a4a491e2SDimitry Andric /// Restore all mapped variables w/o clean up. This is usefully when we want 1208a4a491e2SDimitry Andric /// to reference the original variables but don't want the clean up because 1209a4a491e2SDimitry Andric /// that could emit lifetime end too early, causing backend issue #56913. 1210a4a491e2SDimitry Andric void restoreMap() { MappedVars.restore(CGF); } 12110b57cec5SDimitry Andric }; 12120b57cec5SDimitry Andric 1213480093f4SDimitry Andric /// Save/restore original map of previously emitted local vars in case when we 1214480093f4SDimitry Andric /// need to duplicate emission of the same code several times in the same 1215480093f4SDimitry Andric /// function for OpenMP code. 1216480093f4SDimitry Andric class OMPLocalDeclMapRAII { 1217480093f4SDimitry Andric CodeGenFunction &CGF; 1218480093f4SDimitry Andric DeclMapTy SavedMap; 1219480093f4SDimitry Andric 1220480093f4SDimitry Andric public: 1221480093f4SDimitry Andric OMPLocalDeclMapRAII(CodeGenFunction &CGF) 1222480093f4SDimitry Andric : CGF(CGF), SavedMap(CGF.LocalDeclMap) {} 1223480093f4SDimitry Andric ~OMPLocalDeclMapRAII() { SavedMap.swap(CGF.LocalDeclMap); } 1224480093f4SDimitry Andric }; 1225480093f4SDimitry Andric 12260b57cec5SDimitry Andric /// Takes the old cleanup stack size and emits the cleanup blocks 12270b57cec5SDimitry Andric /// that have been added. 12280b57cec5SDimitry Andric void 12290b57cec5SDimitry Andric PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize, 12300b57cec5SDimitry Andric std::initializer_list<llvm::Value **> ValuesToReload = {}); 12310b57cec5SDimitry Andric 12320b57cec5SDimitry Andric /// Takes the old cleanup stack size and emits the cleanup blocks 12330b57cec5SDimitry Andric /// that have been added, then adds all lifetime-extended cleanups from 12340b57cec5SDimitry Andric /// the given position to the stack. 12350b57cec5SDimitry Andric void 12360b57cec5SDimitry Andric PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize, 12370b57cec5SDimitry Andric size_t OldLifetimeExtendedStackSize, 12380b57cec5SDimitry Andric std::initializer_list<llvm::Value **> ValuesToReload = {}); 12390b57cec5SDimitry Andric 12400b57cec5SDimitry Andric void ResolveBranchFixups(llvm::BasicBlock *Target); 12410b57cec5SDimitry Andric 12420b57cec5SDimitry Andric /// The given basic block lies in the current EH scope, but may be a 12430b57cec5SDimitry Andric /// target of a potentially scope-crossing jump; get a stable handle 12440b57cec5SDimitry Andric /// to which we can perform this jump later. 12450b57cec5SDimitry Andric JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target) { 12460b57cec5SDimitry Andric return JumpDest(Target, 12470b57cec5SDimitry Andric EHStack.getInnermostNormalCleanup(), 12480b57cec5SDimitry Andric NextCleanupDestIndex++); 12490b57cec5SDimitry Andric } 12500b57cec5SDimitry Andric 12510b57cec5SDimitry Andric /// The given basic block lies in the current EH scope, but may be a 12520b57cec5SDimitry Andric /// target of a potentially scope-crossing jump; get a stable handle 12530b57cec5SDimitry Andric /// to which we can perform this jump later. 12540b57cec5SDimitry Andric JumpDest getJumpDestInCurrentScope(StringRef Name = StringRef()) { 12550b57cec5SDimitry Andric return getJumpDestInCurrentScope(createBasicBlock(Name)); 12560b57cec5SDimitry Andric } 12570b57cec5SDimitry Andric 12580b57cec5SDimitry Andric /// EmitBranchThroughCleanup - Emit a branch from the current insert 12590b57cec5SDimitry Andric /// block through the normal cleanup handling code (if any) and then 12600b57cec5SDimitry Andric /// on to \arg Dest. 12610b57cec5SDimitry Andric void EmitBranchThroughCleanup(JumpDest Dest); 12620b57cec5SDimitry Andric 12630b57cec5SDimitry Andric /// isObviouslyBranchWithoutCleanups - Return true if a branch to the 12640b57cec5SDimitry Andric /// specified destination obviously has no cleanups to run. 'false' is always 12650b57cec5SDimitry Andric /// a conservatively correct answer for this method. 12660b57cec5SDimitry Andric bool isObviouslyBranchWithoutCleanups(JumpDest Dest) const; 12670b57cec5SDimitry Andric 12680b57cec5SDimitry Andric /// popCatchScope - Pops the catch scope at the top of the EHScope 12690b57cec5SDimitry Andric /// stack, emitting any required code (other than the catch handlers 12700b57cec5SDimitry Andric /// themselves). 12710b57cec5SDimitry Andric void popCatchScope(); 12720b57cec5SDimitry Andric 12730b57cec5SDimitry Andric llvm::BasicBlock *getEHResumeBlock(bool isCleanup); 12740b57cec5SDimitry Andric llvm::BasicBlock *getEHDispatchBlock(EHScopeStack::stable_iterator scope); 12750b57cec5SDimitry Andric llvm::BasicBlock * 12760b57cec5SDimitry Andric getFuncletEHDispatchBlock(EHScopeStack::stable_iterator scope); 12770b57cec5SDimitry Andric 12780b57cec5SDimitry Andric /// An object to manage conditionally-evaluated expressions. 12790b57cec5SDimitry Andric class ConditionalEvaluation { 12800b57cec5SDimitry Andric llvm::BasicBlock *StartBB; 12810b57cec5SDimitry Andric 12820b57cec5SDimitry Andric public: 12830b57cec5SDimitry Andric ConditionalEvaluation(CodeGenFunction &CGF) 12840b57cec5SDimitry Andric : StartBB(CGF.Builder.GetInsertBlock()) {} 12850b57cec5SDimitry Andric 12860b57cec5SDimitry Andric void begin(CodeGenFunction &CGF) { 12870b57cec5SDimitry Andric assert(CGF.OutermostConditional != this); 12880b57cec5SDimitry Andric if (!CGF.OutermostConditional) 12890b57cec5SDimitry Andric CGF.OutermostConditional = this; 12900b57cec5SDimitry Andric } 12910b57cec5SDimitry Andric 12920b57cec5SDimitry Andric void end(CodeGenFunction &CGF) { 12930b57cec5SDimitry Andric assert(CGF.OutermostConditional != nullptr); 12940b57cec5SDimitry Andric if (CGF.OutermostConditional == this) 12950b57cec5SDimitry Andric CGF.OutermostConditional = nullptr; 12960b57cec5SDimitry Andric } 12970b57cec5SDimitry Andric 12980b57cec5SDimitry Andric /// Returns a block which will be executed prior to each 12990b57cec5SDimitry Andric /// evaluation of the conditional code. 13000b57cec5SDimitry Andric llvm::BasicBlock *getStartingBlock() const { 13010b57cec5SDimitry Andric return StartBB; 13020b57cec5SDimitry Andric } 13030b57cec5SDimitry Andric }; 13040b57cec5SDimitry Andric 13050b57cec5SDimitry Andric /// isInConditionalBranch - Return true if we're currently emitting 13060b57cec5SDimitry Andric /// one branch or the other of a conditional expression. 13070b57cec5SDimitry Andric bool isInConditionalBranch() const { return OutermostConditional != nullptr; } 13080b57cec5SDimitry Andric 13090fca6ea1SDimitry Andric void setBeforeOutermostConditional(llvm::Value *value, Address addr, 13100fca6ea1SDimitry Andric CodeGenFunction &CGF) { 13110b57cec5SDimitry Andric assert(isInConditionalBranch()); 13120b57cec5SDimitry Andric llvm::BasicBlock *block = OutermostConditional->getStartingBlock(); 13130fca6ea1SDimitry Andric auto store = 13140fca6ea1SDimitry Andric new llvm::StoreInst(value, addr.emitRawPointer(CGF), &block->back()); 1315a7dea167SDimitry Andric store->setAlignment(addr.getAlignment().getAsAlign()); 13160b57cec5SDimitry Andric } 13170b57cec5SDimitry Andric 13180b57cec5SDimitry Andric /// An RAII object to record that we're evaluating a statement 13190b57cec5SDimitry Andric /// expression. 13200b57cec5SDimitry Andric class StmtExprEvaluation { 13210b57cec5SDimitry Andric CodeGenFunction &CGF; 13220b57cec5SDimitry Andric 13230b57cec5SDimitry Andric /// We have to save the outermost conditional: cleanups in a 13240b57cec5SDimitry Andric /// statement expression aren't conditional just because the 13250b57cec5SDimitry Andric /// StmtExpr is. 13260b57cec5SDimitry Andric ConditionalEvaluation *SavedOutermostConditional; 13270b57cec5SDimitry Andric 13280b57cec5SDimitry Andric public: 13290b57cec5SDimitry Andric StmtExprEvaluation(CodeGenFunction &CGF) 13300b57cec5SDimitry Andric : CGF(CGF), SavedOutermostConditional(CGF.OutermostConditional) { 13310b57cec5SDimitry Andric CGF.OutermostConditional = nullptr; 13320b57cec5SDimitry Andric } 13330b57cec5SDimitry Andric 13340b57cec5SDimitry Andric ~StmtExprEvaluation() { 13350b57cec5SDimitry Andric CGF.OutermostConditional = SavedOutermostConditional; 13360b57cec5SDimitry Andric CGF.EnsureInsertPoint(); 13370b57cec5SDimitry Andric } 13380b57cec5SDimitry Andric }; 13390b57cec5SDimitry Andric 13400b57cec5SDimitry Andric /// An object which temporarily prevents a value from being 13410b57cec5SDimitry Andric /// destroyed by aggressive peephole optimizations that assume that 13420b57cec5SDimitry Andric /// all uses of a value have been realized in the IR. 13430b57cec5SDimitry Andric class PeepholeProtection { 13445f757f3fSDimitry Andric llvm::Instruction *Inst = nullptr; 13450b57cec5SDimitry Andric friend class CodeGenFunction; 13460b57cec5SDimitry Andric 13470b57cec5SDimitry Andric public: 13485f757f3fSDimitry Andric PeepholeProtection() = default; 13490b57cec5SDimitry Andric }; 13500b57cec5SDimitry Andric 13510b57cec5SDimitry Andric /// A non-RAII class containing all the information about a bound 13520b57cec5SDimitry Andric /// opaque value. OpaqueValueMapping, below, is a RAII wrapper for 13530b57cec5SDimitry Andric /// this which makes individual mappings very simple; using this 13540b57cec5SDimitry Andric /// class directly is useful when you have a variable number of 13550b57cec5SDimitry Andric /// opaque values or don't want the RAII functionality for some 13560b57cec5SDimitry Andric /// reason. 13570b57cec5SDimitry Andric class OpaqueValueMappingData { 13580b57cec5SDimitry Andric const OpaqueValueExpr *OpaqueValue; 13590b57cec5SDimitry Andric bool BoundLValue; 13600b57cec5SDimitry Andric CodeGenFunction::PeepholeProtection Protection; 13610b57cec5SDimitry Andric 13620b57cec5SDimitry Andric OpaqueValueMappingData(const OpaqueValueExpr *ov, 13630b57cec5SDimitry Andric bool boundLValue) 13640b57cec5SDimitry Andric : OpaqueValue(ov), BoundLValue(boundLValue) {} 13650b57cec5SDimitry Andric public: 13660b57cec5SDimitry Andric OpaqueValueMappingData() : OpaqueValue(nullptr) {} 13670b57cec5SDimitry Andric 13680b57cec5SDimitry Andric static bool shouldBindAsLValue(const Expr *expr) { 13690b57cec5SDimitry Andric // gl-values should be bound as l-values for obvious reasons. 13700b57cec5SDimitry Andric // Records should be bound as l-values because IR generation 13710b57cec5SDimitry Andric // always keeps them in memory. Expressions of function type 13720b57cec5SDimitry Andric // act exactly like l-values but are formally required to be 13730b57cec5SDimitry Andric // r-values in C. 13740b57cec5SDimitry Andric return expr->isGLValue() || 13750b57cec5SDimitry Andric expr->getType()->isFunctionType() || 13760b57cec5SDimitry Andric hasAggregateEvaluationKind(expr->getType()); 13770b57cec5SDimitry Andric } 13780b57cec5SDimitry Andric 13790b57cec5SDimitry Andric static OpaqueValueMappingData bind(CodeGenFunction &CGF, 13800b57cec5SDimitry Andric const OpaqueValueExpr *ov, 13810b57cec5SDimitry Andric const Expr *e) { 13820b57cec5SDimitry Andric if (shouldBindAsLValue(ov)) 13830b57cec5SDimitry Andric return bind(CGF, ov, CGF.EmitLValue(e)); 13840b57cec5SDimitry Andric return bind(CGF, ov, CGF.EmitAnyExpr(e)); 13850b57cec5SDimitry Andric } 13860b57cec5SDimitry Andric 13870b57cec5SDimitry Andric static OpaqueValueMappingData bind(CodeGenFunction &CGF, 13880b57cec5SDimitry Andric const OpaqueValueExpr *ov, 13890b57cec5SDimitry Andric const LValue &lv) { 13900b57cec5SDimitry Andric assert(shouldBindAsLValue(ov)); 13910b57cec5SDimitry Andric CGF.OpaqueLValues.insert(std::make_pair(ov, lv)); 13920b57cec5SDimitry Andric return OpaqueValueMappingData(ov, true); 13930b57cec5SDimitry Andric } 13940b57cec5SDimitry Andric 13950b57cec5SDimitry Andric static OpaqueValueMappingData bind(CodeGenFunction &CGF, 13960b57cec5SDimitry Andric const OpaqueValueExpr *ov, 13970b57cec5SDimitry Andric const RValue &rv) { 13980b57cec5SDimitry Andric assert(!shouldBindAsLValue(ov)); 13990b57cec5SDimitry Andric CGF.OpaqueRValues.insert(std::make_pair(ov, rv)); 14000b57cec5SDimitry Andric 14010b57cec5SDimitry Andric OpaqueValueMappingData data(ov, false); 14020b57cec5SDimitry Andric 14030b57cec5SDimitry Andric // Work around an extremely aggressive peephole optimization in 14040b57cec5SDimitry Andric // EmitScalarConversion which assumes that all other uses of a 14050b57cec5SDimitry Andric // value are extant. 14060b57cec5SDimitry Andric data.Protection = CGF.protectFromPeepholes(rv); 14070b57cec5SDimitry Andric 14080b57cec5SDimitry Andric return data; 14090b57cec5SDimitry Andric } 14100b57cec5SDimitry Andric 14110b57cec5SDimitry Andric bool isValid() const { return OpaqueValue != nullptr; } 14120b57cec5SDimitry Andric void clear() { OpaqueValue = nullptr; } 14130b57cec5SDimitry Andric 14140b57cec5SDimitry Andric void unbind(CodeGenFunction &CGF) { 14150b57cec5SDimitry Andric assert(OpaqueValue && "no data to unbind!"); 14160b57cec5SDimitry Andric 14170b57cec5SDimitry Andric if (BoundLValue) { 14180b57cec5SDimitry Andric CGF.OpaqueLValues.erase(OpaqueValue); 14190b57cec5SDimitry Andric } else { 14200b57cec5SDimitry Andric CGF.OpaqueRValues.erase(OpaqueValue); 14210b57cec5SDimitry Andric CGF.unprotectFromPeepholes(Protection); 14220b57cec5SDimitry Andric } 14230b57cec5SDimitry Andric } 14240b57cec5SDimitry Andric }; 14250b57cec5SDimitry Andric 14260b57cec5SDimitry Andric /// An RAII object to set (and then clear) a mapping for an OpaqueValueExpr. 14270b57cec5SDimitry Andric class OpaqueValueMapping { 14280b57cec5SDimitry Andric CodeGenFunction &CGF; 14290b57cec5SDimitry Andric OpaqueValueMappingData Data; 14300b57cec5SDimitry Andric 14310b57cec5SDimitry Andric public: 14320b57cec5SDimitry Andric static bool shouldBindAsLValue(const Expr *expr) { 14330b57cec5SDimitry Andric return OpaqueValueMappingData::shouldBindAsLValue(expr); 14340b57cec5SDimitry Andric } 14350b57cec5SDimitry Andric 14360b57cec5SDimitry Andric /// Build the opaque value mapping for the given conditional 14370b57cec5SDimitry Andric /// operator if it's the GNU ?: extension. This is a common 14380b57cec5SDimitry Andric /// enough pattern that the convenience operator is really 14390b57cec5SDimitry Andric /// helpful. 14400b57cec5SDimitry Andric /// 14410b57cec5SDimitry Andric OpaqueValueMapping(CodeGenFunction &CGF, 14420b57cec5SDimitry Andric const AbstractConditionalOperator *op) : CGF(CGF) { 14430b57cec5SDimitry Andric if (isa<ConditionalOperator>(op)) 14440b57cec5SDimitry Andric // Leave Data empty. 14450b57cec5SDimitry Andric return; 14460b57cec5SDimitry Andric 14470b57cec5SDimitry Andric const BinaryConditionalOperator *e = cast<BinaryConditionalOperator>(op); 14480b57cec5SDimitry Andric Data = OpaqueValueMappingData::bind(CGF, e->getOpaqueValue(), 14490b57cec5SDimitry Andric e->getCommon()); 14500b57cec5SDimitry Andric } 14510b57cec5SDimitry Andric 14520b57cec5SDimitry Andric /// Build the opaque value mapping for an OpaqueValueExpr whose source 14530b57cec5SDimitry Andric /// expression is set to the expression the OVE represents. 14540b57cec5SDimitry Andric OpaqueValueMapping(CodeGenFunction &CGF, const OpaqueValueExpr *OV) 14550b57cec5SDimitry Andric : CGF(CGF) { 14560b57cec5SDimitry Andric if (OV) { 14570b57cec5SDimitry Andric assert(OV->getSourceExpr() && "wrong form of OpaqueValueMapping used " 14580b57cec5SDimitry Andric "for OVE with no source expression"); 14590b57cec5SDimitry Andric Data = OpaqueValueMappingData::bind(CGF, OV, OV->getSourceExpr()); 14600b57cec5SDimitry Andric } 14610b57cec5SDimitry Andric } 14620b57cec5SDimitry Andric 14630b57cec5SDimitry Andric OpaqueValueMapping(CodeGenFunction &CGF, 14640b57cec5SDimitry Andric const OpaqueValueExpr *opaqueValue, 14650b57cec5SDimitry Andric LValue lvalue) 14660b57cec5SDimitry Andric : CGF(CGF), Data(OpaqueValueMappingData::bind(CGF, opaqueValue, lvalue)) { 14670b57cec5SDimitry Andric } 14680b57cec5SDimitry Andric 14690b57cec5SDimitry Andric OpaqueValueMapping(CodeGenFunction &CGF, 14700b57cec5SDimitry Andric const OpaqueValueExpr *opaqueValue, 14710b57cec5SDimitry Andric RValue rvalue) 14720b57cec5SDimitry Andric : CGF(CGF), Data(OpaqueValueMappingData::bind(CGF, opaqueValue, rvalue)) { 14730b57cec5SDimitry Andric } 14740b57cec5SDimitry Andric 14750b57cec5SDimitry Andric void pop() { 14760b57cec5SDimitry Andric Data.unbind(CGF); 14770b57cec5SDimitry Andric Data.clear(); 14780b57cec5SDimitry Andric } 14790b57cec5SDimitry Andric 14800b57cec5SDimitry Andric ~OpaqueValueMapping() { 14810b57cec5SDimitry Andric if (Data.isValid()) Data.unbind(CGF); 14820b57cec5SDimitry Andric } 14830b57cec5SDimitry Andric }; 14840b57cec5SDimitry Andric 14850b57cec5SDimitry Andric private: 14860b57cec5SDimitry Andric CGDebugInfo *DebugInfo; 14870b57cec5SDimitry Andric /// Used to create unique names for artificial VLA size debug info variables. 14880b57cec5SDimitry Andric unsigned VLAExprCounter = 0; 14890b57cec5SDimitry Andric bool DisableDebugInfo = false; 14900b57cec5SDimitry Andric 14910b57cec5SDimitry Andric /// DidCallStackSave - Whether llvm.stacksave has been called. Used to avoid 14920b57cec5SDimitry Andric /// calling llvm.stacksave for multiple VLAs in the same scope. 14930b57cec5SDimitry Andric bool DidCallStackSave = false; 14940b57cec5SDimitry Andric 14950b57cec5SDimitry Andric /// IndirectBranch - The first time an indirect goto is seen we create a block 14960b57cec5SDimitry Andric /// with an indirect branch. Every time we see the address of a label taken, 14970b57cec5SDimitry Andric /// we add the label to the indirect goto. Every subsequent indirect goto is 14980b57cec5SDimitry Andric /// codegen'd as a jump to the IndirectBranch's basic block. 14990b57cec5SDimitry Andric llvm::IndirectBrInst *IndirectBranch = nullptr; 15000b57cec5SDimitry Andric 15010b57cec5SDimitry Andric /// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C 15020b57cec5SDimitry Andric /// decls. 15030b57cec5SDimitry Andric DeclMapTy LocalDeclMap; 15040b57cec5SDimitry Andric 15050b57cec5SDimitry Andric // Keep track of the cleanups for callee-destructed parameters pushed to the 15060b57cec5SDimitry Andric // cleanup stack so that they can be deactivated later. 15070b57cec5SDimitry Andric llvm::DenseMap<const ParmVarDecl *, EHScopeStack::stable_iterator> 15080b57cec5SDimitry Andric CalleeDestructedParamCleanups; 15090b57cec5SDimitry Andric 15100b57cec5SDimitry Andric /// SizeArguments - If a ParmVarDecl had the pass_object_size attribute, this 15110b57cec5SDimitry Andric /// will contain a mapping from said ParmVarDecl to its implicit "object_size" 15120b57cec5SDimitry Andric /// parameter. 15130b57cec5SDimitry Andric llvm::SmallDenseMap<const ParmVarDecl *, const ImplicitParamDecl *, 2> 15140b57cec5SDimitry Andric SizeArguments; 15150b57cec5SDimitry Andric 15160b57cec5SDimitry Andric /// Track escaped local variables with auto storage. Used during SEH 15170b57cec5SDimitry Andric /// outlining to produce a call to llvm.localescape. 15180b57cec5SDimitry Andric llvm::DenseMap<llvm::AllocaInst *, int> EscapedLocals; 15190b57cec5SDimitry Andric 15200b57cec5SDimitry Andric /// LabelMap - This keeps track of the LLVM basic block for each C label. 15210b57cec5SDimitry Andric llvm::DenseMap<const LabelDecl*, JumpDest> LabelMap; 15220b57cec5SDimitry Andric 15230b57cec5SDimitry Andric // BreakContinueStack - This keeps track of where break and continue 15240b57cec5SDimitry Andric // statements should jump to. 15250b57cec5SDimitry Andric struct BreakContinue { 15260b57cec5SDimitry Andric BreakContinue(JumpDest Break, JumpDest Continue) 15270b57cec5SDimitry Andric : BreakBlock(Break), ContinueBlock(Continue) {} 15280b57cec5SDimitry Andric 15290b57cec5SDimitry Andric JumpDest BreakBlock; 15300b57cec5SDimitry Andric JumpDest ContinueBlock; 15310b57cec5SDimitry Andric }; 15320b57cec5SDimitry Andric SmallVector<BreakContinue, 8> BreakContinueStack; 15330b57cec5SDimitry Andric 15340b57cec5SDimitry Andric /// Handles cancellation exit points in OpenMP-related constructs. 15350b57cec5SDimitry Andric class OpenMPCancelExitStack { 15360b57cec5SDimitry Andric /// Tracks cancellation exit point and join point for cancel-related exit 15370b57cec5SDimitry Andric /// and normal exit. 15380b57cec5SDimitry Andric struct CancelExit { 15390b57cec5SDimitry Andric CancelExit() = default; 15400b57cec5SDimitry Andric CancelExit(OpenMPDirectiveKind Kind, JumpDest ExitBlock, 15410b57cec5SDimitry Andric JumpDest ContBlock) 15420b57cec5SDimitry Andric : Kind(Kind), ExitBlock(ExitBlock), ContBlock(ContBlock) {} 1543480093f4SDimitry Andric OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown; 15440b57cec5SDimitry Andric /// true if the exit block has been emitted already by the special 15450b57cec5SDimitry Andric /// emitExit() call, false if the default codegen is used. 15460b57cec5SDimitry Andric bool HasBeenEmitted = false; 15470b57cec5SDimitry Andric JumpDest ExitBlock; 15480b57cec5SDimitry Andric JumpDest ContBlock; 15490b57cec5SDimitry Andric }; 15500b57cec5SDimitry Andric 15510b57cec5SDimitry Andric SmallVector<CancelExit, 8> Stack; 15520b57cec5SDimitry Andric 15530b57cec5SDimitry Andric public: 15540b57cec5SDimitry Andric OpenMPCancelExitStack() : Stack(1) {} 15550b57cec5SDimitry Andric ~OpenMPCancelExitStack() = default; 15560b57cec5SDimitry Andric /// Fetches the exit block for the current OpenMP construct. 15570b57cec5SDimitry Andric JumpDest getExitBlock() const { return Stack.back().ExitBlock; } 15580b57cec5SDimitry Andric /// Emits exit block with special codegen procedure specific for the related 15590b57cec5SDimitry Andric /// OpenMP construct + emits code for normal construct cleanup. 15600b57cec5SDimitry Andric void emitExit(CodeGenFunction &CGF, OpenMPDirectiveKind Kind, 15610b57cec5SDimitry Andric const llvm::function_ref<void(CodeGenFunction &)> CodeGen) { 15620b57cec5SDimitry Andric if (Stack.back().Kind == Kind && getExitBlock().isValid()) { 15630b57cec5SDimitry Andric assert(CGF.getOMPCancelDestination(Kind).isValid()); 15640b57cec5SDimitry Andric assert(CGF.HaveInsertPoint()); 15650b57cec5SDimitry Andric assert(!Stack.back().HasBeenEmitted); 15660b57cec5SDimitry Andric auto IP = CGF.Builder.saveAndClearIP(); 15670b57cec5SDimitry Andric CGF.EmitBlock(Stack.back().ExitBlock.getBlock()); 15680b57cec5SDimitry Andric CodeGen(CGF); 15690b57cec5SDimitry Andric CGF.EmitBranch(Stack.back().ContBlock.getBlock()); 15700b57cec5SDimitry Andric CGF.Builder.restoreIP(IP); 15710b57cec5SDimitry Andric Stack.back().HasBeenEmitted = true; 15720b57cec5SDimitry Andric } 15730b57cec5SDimitry Andric CodeGen(CGF); 15740b57cec5SDimitry Andric } 15750b57cec5SDimitry Andric /// Enter the cancel supporting \a Kind construct. 15760b57cec5SDimitry Andric /// \param Kind OpenMP directive that supports cancel constructs. 15770b57cec5SDimitry Andric /// \param HasCancel true, if the construct has inner cancel directive, 15780b57cec5SDimitry Andric /// false otherwise. 15790b57cec5SDimitry Andric void enter(CodeGenFunction &CGF, OpenMPDirectiveKind Kind, bool HasCancel) { 15800b57cec5SDimitry Andric Stack.push_back({Kind, 15810b57cec5SDimitry Andric HasCancel ? CGF.getJumpDestInCurrentScope("cancel.exit") 15820b57cec5SDimitry Andric : JumpDest(), 15830b57cec5SDimitry Andric HasCancel ? CGF.getJumpDestInCurrentScope("cancel.cont") 15840b57cec5SDimitry Andric : JumpDest()}); 15850b57cec5SDimitry Andric } 15860b57cec5SDimitry Andric /// Emits default exit point for the cancel construct (if the special one 15870b57cec5SDimitry Andric /// has not be used) + join point for cancel/normal exits. 15880b57cec5SDimitry Andric void exit(CodeGenFunction &CGF) { 15890b57cec5SDimitry Andric if (getExitBlock().isValid()) { 15900b57cec5SDimitry Andric assert(CGF.getOMPCancelDestination(Stack.back().Kind).isValid()); 15910b57cec5SDimitry Andric bool HaveIP = CGF.HaveInsertPoint(); 15920b57cec5SDimitry Andric if (!Stack.back().HasBeenEmitted) { 15930b57cec5SDimitry Andric if (HaveIP) 15940b57cec5SDimitry Andric CGF.EmitBranchThroughCleanup(Stack.back().ContBlock); 15950b57cec5SDimitry Andric CGF.EmitBlock(Stack.back().ExitBlock.getBlock()); 15960b57cec5SDimitry Andric CGF.EmitBranchThroughCleanup(Stack.back().ContBlock); 15970b57cec5SDimitry Andric } 15980b57cec5SDimitry Andric CGF.EmitBlock(Stack.back().ContBlock.getBlock()); 15990b57cec5SDimitry Andric if (!HaveIP) { 16000b57cec5SDimitry Andric CGF.Builder.CreateUnreachable(); 16010b57cec5SDimitry Andric CGF.Builder.ClearInsertionPoint(); 16020b57cec5SDimitry Andric } 16030b57cec5SDimitry Andric } 16040b57cec5SDimitry Andric Stack.pop_back(); 16050b57cec5SDimitry Andric } 16060b57cec5SDimitry Andric }; 16070b57cec5SDimitry Andric OpenMPCancelExitStack OMPCancelStack; 16080b57cec5SDimitry Andric 1609fe6060f1SDimitry Andric /// Lower the Likelihood knowledge about the \p Cond via llvm.expect intrin. 1610fe6060f1SDimitry Andric llvm::Value *emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond, 1611fe6060f1SDimitry Andric Stmt::Likelihood LH); 1612e8d8bef9SDimitry Andric 16130b57cec5SDimitry Andric CodeGenPGO PGO; 16140b57cec5SDimitry Andric 16151db9f3b2SDimitry Andric /// Bitmap used by MC/DC to track condition outcomes of a boolean expression. 16161db9f3b2SDimitry Andric Address MCDCCondBitmapAddr = Address::invalid(); 16171db9f3b2SDimitry Andric 16180b57cec5SDimitry Andric /// Calculate branch weights appropriate for PGO data 1619e8d8bef9SDimitry Andric llvm::MDNode *createProfileWeights(uint64_t TrueCount, 1620e8d8bef9SDimitry Andric uint64_t FalseCount) const; 1621e8d8bef9SDimitry Andric llvm::MDNode *createProfileWeights(ArrayRef<uint64_t> Weights) const; 16220b57cec5SDimitry Andric llvm::MDNode *createProfileWeightsForLoop(const Stmt *Cond, 1623e8d8bef9SDimitry Andric uint64_t LoopCount) const; 1624e8d8bef9SDimitry Andric 16250b57cec5SDimitry Andric public: 16260b57cec5SDimitry Andric /// Increment the profiler's counter for the given statement by \p StepV. 16270b57cec5SDimitry Andric /// If \p StepV is null, the default increment is 1. 16280b57cec5SDimitry Andric void incrementProfileCounter(const Stmt *S, llvm::Value *StepV = nullptr) { 1629e8d8bef9SDimitry Andric if (CGM.getCodeGenOpts().hasProfileClangInstr() && 1630bdd1243dSDimitry Andric !CurFn->hasFnAttribute(llvm::Attribute::NoProfile) && 16310fca6ea1SDimitry Andric !CurFn->hasFnAttribute(llvm::Attribute::SkipProfile)) { 16320fca6ea1SDimitry Andric auto AL = ApplyDebugLocation::CreateArtificial(*this); 16330fca6ea1SDimitry Andric PGO.emitCounterSetOrIncrement(Builder, S, StepV); 16340fca6ea1SDimitry Andric } 16350b57cec5SDimitry Andric PGO.setCurrentStmt(S); 16360b57cec5SDimitry Andric } 16370b57cec5SDimitry Andric 16381db9f3b2SDimitry Andric bool isMCDCCoverageEnabled() const { 16391db9f3b2SDimitry Andric return (CGM.getCodeGenOpts().hasProfileClangInstr() && 16401db9f3b2SDimitry Andric CGM.getCodeGenOpts().MCDCCoverage && 16411db9f3b2SDimitry Andric !CurFn->hasFnAttribute(llvm::Attribute::NoProfile)); 16421db9f3b2SDimitry Andric } 16431db9f3b2SDimitry Andric 16441db9f3b2SDimitry Andric /// Allocate a temp value on the stack that MCDC can use to track condition 16451db9f3b2SDimitry Andric /// results. 16461db9f3b2SDimitry Andric void maybeCreateMCDCCondBitmap() { 16471db9f3b2SDimitry Andric if (isMCDCCoverageEnabled()) { 16481db9f3b2SDimitry Andric PGO.emitMCDCParameters(Builder); 16491db9f3b2SDimitry Andric MCDCCondBitmapAddr = 16501db9f3b2SDimitry Andric CreateIRTemp(getContext().UnsignedIntTy, "mcdc.addr"); 16511db9f3b2SDimitry Andric } 16521db9f3b2SDimitry Andric } 16531db9f3b2SDimitry Andric 16541db9f3b2SDimitry Andric bool isBinaryLogicalOp(const Expr *E) const { 16551db9f3b2SDimitry Andric const BinaryOperator *BOp = dyn_cast<BinaryOperator>(E->IgnoreParens()); 16561db9f3b2SDimitry Andric return (BOp && BOp->isLogicalOp()); 16571db9f3b2SDimitry Andric } 16581db9f3b2SDimitry Andric 16591db9f3b2SDimitry Andric /// Zero-init the MCDC temp value. 16601db9f3b2SDimitry Andric void maybeResetMCDCCondBitmap(const Expr *E) { 16611db9f3b2SDimitry Andric if (isMCDCCoverageEnabled() && isBinaryLogicalOp(E)) { 16621db9f3b2SDimitry Andric PGO.emitMCDCCondBitmapReset(Builder, E, MCDCCondBitmapAddr); 16631db9f3b2SDimitry Andric PGO.setCurrentStmt(E); 16641db9f3b2SDimitry Andric } 16651db9f3b2SDimitry Andric } 16661db9f3b2SDimitry Andric 16671db9f3b2SDimitry Andric /// Increment the profiler's counter for the given expression by \p StepV. 16681db9f3b2SDimitry Andric /// If \p StepV is null, the default increment is 1. 16691db9f3b2SDimitry Andric void maybeUpdateMCDCTestVectorBitmap(const Expr *E) { 16701db9f3b2SDimitry Andric if (isMCDCCoverageEnabled() && isBinaryLogicalOp(E)) { 16710fca6ea1SDimitry Andric PGO.emitMCDCTestVectorBitmapUpdate(Builder, E, MCDCCondBitmapAddr, *this); 16721db9f3b2SDimitry Andric PGO.setCurrentStmt(E); 16731db9f3b2SDimitry Andric } 16741db9f3b2SDimitry Andric } 16751db9f3b2SDimitry Andric 16761db9f3b2SDimitry Andric /// Update the MCDC temp value with the condition's evaluated result. 16771db9f3b2SDimitry Andric void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val) { 16781db9f3b2SDimitry Andric if (isMCDCCoverageEnabled()) { 16790fca6ea1SDimitry Andric PGO.emitMCDCCondBitmapUpdate(Builder, E, MCDCCondBitmapAddr, Val, *this); 16801db9f3b2SDimitry Andric PGO.setCurrentStmt(E); 16811db9f3b2SDimitry Andric } 16821db9f3b2SDimitry Andric } 16831db9f3b2SDimitry Andric 16840b57cec5SDimitry Andric /// Get the profiler's count for the given statement. 16850b57cec5SDimitry Andric uint64_t getProfileCount(const Stmt *S) { 168681ad6265SDimitry Andric return PGO.getStmtCount(S).value_or(0); 16870b57cec5SDimitry Andric } 16880b57cec5SDimitry Andric 16890b57cec5SDimitry Andric /// Set the profiler's current count. 16900b57cec5SDimitry Andric void setCurrentProfileCount(uint64_t Count) { 16910b57cec5SDimitry Andric PGO.setCurrentRegionCount(Count); 16920b57cec5SDimitry Andric } 16930b57cec5SDimitry Andric 16940b57cec5SDimitry Andric /// Get the profiler's current count. This is generally the count for the most 16950b57cec5SDimitry Andric /// recently incremented counter. 16960b57cec5SDimitry Andric uint64_t getCurrentProfileCount() { 16970b57cec5SDimitry Andric return PGO.getCurrentRegionCount(); 16980b57cec5SDimitry Andric } 16990b57cec5SDimitry Andric 17000b57cec5SDimitry Andric private: 17010b57cec5SDimitry Andric 17020b57cec5SDimitry Andric /// SwitchInsn - This is nearest current switch instruction. It is null if 17030b57cec5SDimitry Andric /// current context is not in a switch. 17040b57cec5SDimitry Andric llvm::SwitchInst *SwitchInsn = nullptr; 17050b57cec5SDimitry Andric /// The branch weights of SwitchInsn when doing instrumentation based PGO. 17060b57cec5SDimitry Andric SmallVector<uint64_t, 16> *SwitchWeights = nullptr; 17070b57cec5SDimitry Andric 1708e8d8bef9SDimitry Andric /// The likelihood attributes of the SwitchCase. 1709e8d8bef9SDimitry Andric SmallVector<Stmt::Likelihood, 16> *SwitchLikelihood = nullptr; 1710e8d8bef9SDimitry Andric 17110b57cec5SDimitry Andric /// CaseRangeBlock - This block holds if condition check for last case 17120b57cec5SDimitry Andric /// statement range in current switch instruction. 17130b57cec5SDimitry Andric llvm::BasicBlock *CaseRangeBlock = nullptr; 17140b57cec5SDimitry Andric 17150b57cec5SDimitry Andric /// OpaqueLValues - Keeps track of the current set of opaque value 17160b57cec5SDimitry Andric /// expressions. 17170b57cec5SDimitry Andric llvm::DenseMap<const OpaqueValueExpr *, LValue> OpaqueLValues; 17180b57cec5SDimitry Andric llvm::DenseMap<const OpaqueValueExpr *, RValue> OpaqueRValues; 17190b57cec5SDimitry Andric 17200b57cec5SDimitry Andric // VLASizeMap - This keeps track of the associated size for each VLA type. 17210b57cec5SDimitry Andric // We track this by the size expression rather than the type itself because 17220b57cec5SDimitry Andric // in certain situations, like a const qualifier applied to an VLA typedef, 17230b57cec5SDimitry Andric // multiple VLA types can share the same size expression. 17240b57cec5SDimitry Andric // FIXME: Maybe this could be a stack of maps that is pushed/popped as we 17250b57cec5SDimitry Andric // enter/leave scopes. 17260b57cec5SDimitry Andric llvm::DenseMap<const Expr*, llvm::Value*> VLASizeMap; 17270b57cec5SDimitry Andric 17280b57cec5SDimitry Andric /// A block containing a single 'unreachable' instruction. Created 17290b57cec5SDimitry Andric /// lazily by getUnreachableBlock(). 17300b57cec5SDimitry Andric llvm::BasicBlock *UnreachableBlock = nullptr; 17310b57cec5SDimitry Andric 17320b57cec5SDimitry Andric /// Counts of the number return expressions in the function. 17330b57cec5SDimitry Andric unsigned NumReturnExprs = 0; 17340b57cec5SDimitry Andric 17350b57cec5SDimitry Andric /// Count the number of simple (constant) return expressions in the function. 17360b57cec5SDimitry Andric unsigned NumSimpleReturnExprs = 0; 17370b57cec5SDimitry Andric 17380b57cec5SDimitry Andric /// The last regular (non-return) debug location (breakpoint) in the function. 17390b57cec5SDimitry Andric SourceLocation LastStopPoint; 17400b57cec5SDimitry Andric 17410b57cec5SDimitry Andric public: 17420b57cec5SDimitry Andric /// Source location information about the default argument or member 17430b57cec5SDimitry Andric /// initializer expression we're evaluating, if any. 17440b57cec5SDimitry Andric CurrentSourceLocExprScope CurSourceLocExprScope; 17450b57cec5SDimitry Andric using SourceLocExprScopeGuard = 17460b57cec5SDimitry Andric CurrentSourceLocExprScope::SourceLocExprScopeGuard; 17470b57cec5SDimitry Andric 17480b57cec5SDimitry Andric /// A scope within which we are constructing the fields of an object which 17490b57cec5SDimitry Andric /// might use a CXXDefaultInitExpr. This stashes away a 'this' value to use 17500b57cec5SDimitry Andric /// if we need to evaluate a CXXDefaultInitExpr within the evaluation. 17510b57cec5SDimitry Andric class FieldConstructionScope { 17520b57cec5SDimitry Andric public: 17530b57cec5SDimitry Andric FieldConstructionScope(CodeGenFunction &CGF, Address This) 17540b57cec5SDimitry Andric : CGF(CGF), OldCXXDefaultInitExprThis(CGF.CXXDefaultInitExprThis) { 17550b57cec5SDimitry Andric CGF.CXXDefaultInitExprThis = This; 17560b57cec5SDimitry Andric } 17570b57cec5SDimitry Andric ~FieldConstructionScope() { 17580b57cec5SDimitry Andric CGF.CXXDefaultInitExprThis = OldCXXDefaultInitExprThis; 17590b57cec5SDimitry Andric } 17600b57cec5SDimitry Andric 17610b57cec5SDimitry Andric private: 17620b57cec5SDimitry Andric CodeGenFunction &CGF; 17630b57cec5SDimitry Andric Address OldCXXDefaultInitExprThis; 17640b57cec5SDimitry Andric }; 17650b57cec5SDimitry Andric 17660b57cec5SDimitry Andric /// The scope of a CXXDefaultInitExpr. Within this scope, the value of 'this' 17670b57cec5SDimitry Andric /// is overridden to be the object under construction. 17680b57cec5SDimitry Andric class CXXDefaultInitExprScope { 17690b57cec5SDimitry Andric public: 17700b57cec5SDimitry Andric CXXDefaultInitExprScope(CodeGenFunction &CGF, const CXXDefaultInitExpr *E) 17710b57cec5SDimitry Andric : CGF(CGF), OldCXXThisValue(CGF.CXXThisValue), 17720b57cec5SDimitry Andric OldCXXThisAlignment(CGF.CXXThisAlignment), 17730b57cec5SDimitry Andric SourceLocScope(E, CGF.CurSourceLocExprScope) { 17740fca6ea1SDimitry Andric CGF.CXXThisValue = CGF.CXXDefaultInitExprThis.getBasePointer(); 17750b57cec5SDimitry Andric CGF.CXXThisAlignment = CGF.CXXDefaultInitExprThis.getAlignment(); 17760b57cec5SDimitry Andric } 17770b57cec5SDimitry Andric ~CXXDefaultInitExprScope() { 17780b57cec5SDimitry Andric CGF.CXXThisValue = OldCXXThisValue; 17790b57cec5SDimitry Andric CGF.CXXThisAlignment = OldCXXThisAlignment; 17800b57cec5SDimitry Andric } 17810b57cec5SDimitry Andric 17820b57cec5SDimitry Andric public: 17830b57cec5SDimitry Andric CodeGenFunction &CGF; 17840b57cec5SDimitry Andric llvm::Value *OldCXXThisValue; 17850b57cec5SDimitry Andric CharUnits OldCXXThisAlignment; 17860b57cec5SDimitry Andric SourceLocExprScopeGuard SourceLocScope; 17870b57cec5SDimitry Andric }; 17880b57cec5SDimitry Andric 17890b57cec5SDimitry Andric struct CXXDefaultArgExprScope : SourceLocExprScopeGuard { 17900b57cec5SDimitry Andric CXXDefaultArgExprScope(CodeGenFunction &CGF, const CXXDefaultArgExpr *E) 17910b57cec5SDimitry Andric : SourceLocExprScopeGuard(E, CGF.CurSourceLocExprScope) {} 17920b57cec5SDimitry Andric }; 17930b57cec5SDimitry Andric 17940b57cec5SDimitry Andric /// The scope of an ArrayInitLoopExpr. Within this scope, the value of the 17950b57cec5SDimitry Andric /// current loop index is overridden. 17960b57cec5SDimitry Andric class ArrayInitLoopExprScope { 17970b57cec5SDimitry Andric public: 17980b57cec5SDimitry Andric ArrayInitLoopExprScope(CodeGenFunction &CGF, llvm::Value *Index) 17990b57cec5SDimitry Andric : CGF(CGF), OldArrayInitIndex(CGF.ArrayInitIndex) { 18000b57cec5SDimitry Andric CGF.ArrayInitIndex = Index; 18010b57cec5SDimitry Andric } 18020b57cec5SDimitry Andric ~ArrayInitLoopExprScope() { 18030b57cec5SDimitry Andric CGF.ArrayInitIndex = OldArrayInitIndex; 18040b57cec5SDimitry Andric } 18050b57cec5SDimitry Andric 18060b57cec5SDimitry Andric private: 18070b57cec5SDimitry Andric CodeGenFunction &CGF; 18080b57cec5SDimitry Andric llvm::Value *OldArrayInitIndex; 18090b57cec5SDimitry Andric }; 18100b57cec5SDimitry Andric 18110b57cec5SDimitry Andric class InlinedInheritingConstructorScope { 18120b57cec5SDimitry Andric public: 18130b57cec5SDimitry Andric InlinedInheritingConstructorScope(CodeGenFunction &CGF, GlobalDecl GD) 18140b57cec5SDimitry Andric : CGF(CGF), OldCurGD(CGF.CurGD), OldCurFuncDecl(CGF.CurFuncDecl), 18150b57cec5SDimitry Andric OldCurCodeDecl(CGF.CurCodeDecl), 18160b57cec5SDimitry Andric OldCXXABIThisDecl(CGF.CXXABIThisDecl), 18170b57cec5SDimitry Andric OldCXXABIThisValue(CGF.CXXABIThisValue), 18180b57cec5SDimitry Andric OldCXXThisValue(CGF.CXXThisValue), 18190b57cec5SDimitry Andric OldCXXABIThisAlignment(CGF.CXXABIThisAlignment), 18200b57cec5SDimitry Andric OldCXXThisAlignment(CGF.CXXThisAlignment), 18210b57cec5SDimitry Andric OldReturnValue(CGF.ReturnValue), OldFnRetTy(CGF.FnRetTy), 18220b57cec5SDimitry Andric OldCXXInheritedCtorInitExprArgs( 18230b57cec5SDimitry Andric std::move(CGF.CXXInheritedCtorInitExprArgs)) { 18240b57cec5SDimitry Andric CGF.CurGD = GD; 18250b57cec5SDimitry Andric CGF.CurFuncDecl = CGF.CurCodeDecl = 18260b57cec5SDimitry Andric cast<CXXConstructorDecl>(GD.getDecl()); 18270b57cec5SDimitry Andric CGF.CXXABIThisDecl = nullptr; 18280b57cec5SDimitry Andric CGF.CXXABIThisValue = nullptr; 18290b57cec5SDimitry Andric CGF.CXXThisValue = nullptr; 18300b57cec5SDimitry Andric CGF.CXXABIThisAlignment = CharUnits(); 18310b57cec5SDimitry Andric CGF.CXXThisAlignment = CharUnits(); 18320b57cec5SDimitry Andric CGF.ReturnValue = Address::invalid(); 18330b57cec5SDimitry Andric CGF.FnRetTy = QualType(); 18340b57cec5SDimitry Andric CGF.CXXInheritedCtorInitExprArgs.clear(); 18350b57cec5SDimitry Andric } 18360b57cec5SDimitry Andric ~InlinedInheritingConstructorScope() { 18370b57cec5SDimitry Andric CGF.CurGD = OldCurGD; 18380b57cec5SDimitry Andric CGF.CurFuncDecl = OldCurFuncDecl; 18390b57cec5SDimitry Andric CGF.CurCodeDecl = OldCurCodeDecl; 18400b57cec5SDimitry Andric CGF.CXXABIThisDecl = OldCXXABIThisDecl; 18410b57cec5SDimitry Andric CGF.CXXABIThisValue = OldCXXABIThisValue; 18420b57cec5SDimitry Andric CGF.CXXThisValue = OldCXXThisValue; 18430b57cec5SDimitry Andric CGF.CXXABIThisAlignment = OldCXXABIThisAlignment; 18440b57cec5SDimitry Andric CGF.CXXThisAlignment = OldCXXThisAlignment; 18450b57cec5SDimitry Andric CGF.ReturnValue = OldReturnValue; 18460b57cec5SDimitry Andric CGF.FnRetTy = OldFnRetTy; 18470b57cec5SDimitry Andric CGF.CXXInheritedCtorInitExprArgs = 18480b57cec5SDimitry Andric std::move(OldCXXInheritedCtorInitExprArgs); 18490b57cec5SDimitry Andric } 18500b57cec5SDimitry Andric 18510b57cec5SDimitry Andric private: 18520b57cec5SDimitry Andric CodeGenFunction &CGF; 18530b57cec5SDimitry Andric GlobalDecl OldCurGD; 18540b57cec5SDimitry Andric const Decl *OldCurFuncDecl; 18550b57cec5SDimitry Andric const Decl *OldCurCodeDecl; 18560b57cec5SDimitry Andric ImplicitParamDecl *OldCXXABIThisDecl; 18570b57cec5SDimitry Andric llvm::Value *OldCXXABIThisValue; 18580b57cec5SDimitry Andric llvm::Value *OldCXXThisValue; 18590b57cec5SDimitry Andric CharUnits OldCXXABIThisAlignment; 18600b57cec5SDimitry Andric CharUnits OldCXXThisAlignment; 18610b57cec5SDimitry Andric Address OldReturnValue; 18620b57cec5SDimitry Andric QualType OldFnRetTy; 18630b57cec5SDimitry Andric CallArgList OldCXXInheritedCtorInitExprArgs; 18640b57cec5SDimitry Andric }; 18650b57cec5SDimitry Andric 18665ffd83dbSDimitry Andric // Helper class for the OpenMP IR Builder. Allows reusability of code used for 18675ffd83dbSDimitry Andric // region body, and finalization codegen callbacks. This will class will also 18685ffd83dbSDimitry Andric // contain privatization functions used by the privatization call backs 18695ffd83dbSDimitry Andric // 18705ffd83dbSDimitry Andric // TODO: this is temporary class for things that are being moved out of 18715ffd83dbSDimitry Andric // CGOpenMPRuntime, new versions of current CodeGenFunction methods, or 18725ffd83dbSDimitry Andric // utility function for use with the OMPBuilder. Once that move to use the 18735ffd83dbSDimitry Andric // OMPBuilder is done, everything here will either become part of CodeGenFunc. 18745ffd83dbSDimitry Andric // directly, or a new helper class that will contain functions used by both 18755ffd83dbSDimitry Andric // this and the OMPBuilder 18765ffd83dbSDimitry Andric 18775ffd83dbSDimitry Andric struct OMPBuilderCBHelpers { 18785ffd83dbSDimitry Andric 18795ffd83dbSDimitry Andric OMPBuilderCBHelpers() = delete; 18805ffd83dbSDimitry Andric OMPBuilderCBHelpers(const OMPBuilderCBHelpers &) = delete; 18815ffd83dbSDimitry Andric OMPBuilderCBHelpers &operator=(const OMPBuilderCBHelpers &) = delete; 18825ffd83dbSDimitry Andric 18835ffd83dbSDimitry Andric using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; 18845ffd83dbSDimitry Andric 18855ffd83dbSDimitry Andric /// Cleanup action for allocate support. 18865ffd83dbSDimitry Andric class OMPAllocateCleanupTy final : public EHScopeStack::Cleanup { 18875ffd83dbSDimitry Andric 18885ffd83dbSDimitry Andric private: 18895ffd83dbSDimitry Andric llvm::CallInst *RTLFnCI; 18905ffd83dbSDimitry Andric 18915ffd83dbSDimitry Andric public: 18925ffd83dbSDimitry Andric OMPAllocateCleanupTy(llvm::CallInst *RLFnCI) : RTLFnCI(RLFnCI) { 18935ffd83dbSDimitry Andric RLFnCI->removeFromParent(); 18945ffd83dbSDimitry Andric } 18955ffd83dbSDimitry Andric 18965ffd83dbSDimitry Andric void Emit(CodeGenFunction &CGF, Flags /*flags*/) override { 18975ffd83dbSDimitry Andric if (!CGF.HaveInsertPoint()) 18985ffd83dbSDimitry Andric return; 18995ffd83dbSDimitry Andric CGF.Builder.Insert(RTLFnCI); 19005ffd83dbSDimitry Andric } 19015ffd83dbSDimitry Andric }; 19025ffd83dbSDimitry Andric 19035ffd83dbSDimitry Andric /// Returns address of the threadprivate variable for the current 19045ffd83dbSDimitry Andric /// thread. This Also create any necessary OMP runtime calls. 19055ffd83dbSDimitry Andric /// 19065ffd83dbSDimitry Andric /// \param VD VarDecl for Threadprivate variable. 19075ffd83dbSDimitry Andric /// \param VDAddr Address of the Vardecl 19085ffd83dbSDimitry Andric /// \param Loc The location where the barrier directive was encountered 19095ffd83dbSDimitry Andric static Address getAddrOfThreadPrivate(CodeGenFunction &CGF, 19105ffd83dbSDimitry Andric const VarDecl *VD, Address VDAddr, 19115ffd83dbSDimitry Andric SourceLocation Loc); 19125ffd83dbSDimitry Andric 19135ffd83dbSDimitry Andric /// Gets the OpenMP-specific address of the local variable /p VD. 19145ffd83dbSDimitry Andric static Address getAddressOfLocalVariable(CodeGenFunction &CGF, 19155ffd83dbSDimitry Andric const VarDecl *VD); 19165ffd83dbSDimitry Andric /// Get the platform-specific name separator. 19175ffd83dbSDimitry Andric /// \param Parts different parts of the final name that needs separation 19185ffd83dbSDimitry Andric /// \param FirstSeparator First separator used between the initial two 19195ffd83dbSDimitry Andric /// parts of the name. 19205ffd83dbSDimitry Andric /// \param Separator separator used between all of the rest consecutinve 19215ffd83dbSDimitry Andric /// parts of the name 19225ffd83dbSDimitry Andric static std::string getNameWithSeparators(ArrayRef<StringRef> Parts, 19235ffd83dbSDimitry Andric StringRef FirstSeparator = ".", 19245ffd83dbSDimitry Andric StringRef Separator = "."); 19255ffd83dbSDimitry Andric /// Emit the Finalization for an OMP region 19265ffd83dbSDimitry Andric /// \param CGF The Codegen function this belongs to 19275ffd83dbSDimitry Andric /// \param IP Insertion point for generating the finalization code. 19285ffd83dbSDimitry Andric static void FinalizeOMPRegion(CodeGenFunction &CGF, InsertPointTy IP) { 19295ffd83dbSDimitry Andric CGBuilderTy::InsertPointGuard IPG(CGF.Builder); 19305ffd83dbSDimitry Andric assert(IP.getBlock()->end() != IP.getPoint() && 19315ffd83dbSDimitry Andric "OpenMP IR Builder should cause terminated block!"); 19325ffd83dbSDimitry Andric 19335ffd83dbSDimitry Andric llvm::BasicBlock *IPBB = IP.getBlock(); 19345ffd83dbSDimitry Andric llvm::BasicBlock *DestBB = IPBB->getUniqueSuccessor(); 19355ffd83dbSDimitry Andric assert(DestBB && "Finalization block should have one successor!"); 19365ffd83dbSDimitry Andric 19375ffd83dbSDimitry Andric // erase and replace with cleanup branch. 19385ffd83dbSDimitry Andric IPBB->getTerminator()->eraseFromParent(); 19395ffd83dbSDimitry Andric CGF.Builder.SetInsertPoint(IPBB); 19405ffd83dbSDimitry Andric CodeGenFunction::JumpDest Dest = CGF.getJumpDestInCurrentScope(DestBB); 19415ffd83dbSDimitry Andric CGF.EmitBranchThroughCleanup(Dest); 19425ffd83dbSDimitry Andric } 19435ffd83dbSDimitry Andric 19445ffd83dbSDimitry Andric /// Emit the body of an OMP region 19455ffd83dbSDimitry Andric /// \param CGF The Codegen function this belongs to 19465ffd83dbSDimitry Andric /// \param RegionBodyStmt The body statement for the OpenMP region being 19475ffd83dbSDimitry Andric /// generated 194881ad6265SDimitry Andric /// \param AllocaIP Where to insert alloca instructions 194981ad6265SDimitry Andric /// \param CodeGenIP Where to insert the region code 195081ad6265SDimitry Andric /// \param RegionName Name to be used for new blocks 195181ad6265SDimitry Andric static void EmitOMPInlinedRegionBody(CodeGenFunction &CGF, 19525ffd83dbSDimitry Andric const Stmt *RegionBodyStmt, 195381ad6265SDimitry Andric InsertPointTy AllocaIP, 19545ffd83dbSDimitry Andric InsertPointTy CodeGenIP, 195581ad6265SDimitry Andric Twine RegionName); 19565ffd83dbSDimitry Andric 1957349cc55cSDimitry Andric static void EmitCaptureStmt(CodeGenFunction &CGF, InsertPointTy CodeGenIP, 1958349cc55cSDimitry Andric llvm::BasicBlock &FiniBB, llvm::Function *Fn, 1959349cc55cSDimitry Andric ArrayRef<llvm::Value *> Args) { 1960349cc55cSDimitry Andric llvm::BasicBlock *CodeGenIPBB = CodeGenIP.getBlock(); 1961349cc55cSDimitry Andric if (llvm::Instruction *CodeGenIPBBTI = CodeGenIPBB->getTerminator()) 1962349cc55cSDimitry Andric CodeGenIPBBTI->eraseFromParent(); 1963349cc55cSDimitry Andric 1964349cc55cSDimitry Andric CGF.Builder.SetInsertPoint(CodeGenIPBB); 1965349cc55cSDimitry Andric 1966349cc55cSDimitry Andric if (Fn->doesNotThrow()) 1967349cc55cSDimitry Andric CGF.EmitNounwindRuntimeCall(Fn, Args); 1968349cc55cSDimitry Andric else 1969349cc55cSDimitry Andric CGF.EmitRuntimeCall(Fn, Args); 1970349cc55cSDimitry Andric 1971349cc55cSDimitry Andric if (CGF.Builder.saveIP().isSet()) 1972349cc55cSDimitry Andric CGF.Builder.CreateBr(&FiniBB); 1973349cc55cSDimitry Andric } 1974349cc55cSDimitry Andric 197581ad6265SDimitry Andric /// Emit the body of an OMP region that will be outlined in 197681ad6265SDimitry Andric /// OpenMPIRBuilder::finalize(). 197781ad6265SDimitry Andric /// \param CGF The Codegen function this belongs to 197881ad6265SDimitry Andric /// \param RegionBodyStmt The body statement for the OpenMP region being 197981ad6265SDimitry Andric /// generated 198081ad6265SDimitry Andric /// \param AllocaIP Where to insert alloca instructions 198181ad6265SDimitry Andric /// \param CodeGenIP Where to insert the region code 198281ad6265SDimitry Andric /// \param RegionName Name to be used for new blocks 198381ad6265SDimitry Andric static void EmitOMPOutlinedRegionBody(CodeGenFunction &CGF, 198481ad6265SDimitry Andric const Stmt *RegionBodyStmt, 198581ad6265SDimitry Andric InsertPointTy AllocaIP, 198681ad6265SDimitry Andric InsertPointTy CodeGenIP, 198781ad6265SDimitry Andric Twine RegionName); 198881ad6265SDimitry Andric 19895ffd83dbSDimitry Andric /// RAII for preserving necessary info during Outlined region body codegen. 19905ffd83dbSDimitry Andric class OutlinedRegionBodyRAII { 19915ffd83dbSDimitry Andric 19925ffd83dbSDimitry Andric llvm::AssertingVH<llvm::Instruction> OldAllocaIP; 19935ffd83dbSDimitry Andric CodeGenFunction::JumpDest OldReturnBlock; 19945ffd83dbSDimitry Andric CodeGenFunction &CGF; 19955ffd83dbSDimitry Andric 19965ffd83dbSDimitry Andric public: 19975ffd83dbSDimitry Andric OutlinedRegionBodyRAII(CodeGenFunction &cgf, InsertPointTy &AllocaIP, 19985ffd83dbSDimitry Andric llvm::BasicBlock &RetBB) 19995ffd83dbSDimitry Andric : CGF(cgf) { 20005ffd83dbSDimitry Andric assert(AllocaIP.isSet() && 20015ffd83dbSDimitry Andric "Must specify Insertion point for allocas of outlined function"); 20025ffd83dbSDimitry Andric OldAllocaIP = CGF.AllocaInsertPt; 20035ffd83dbSDimitry Andric CGF.AllocaInsertPt = &*AllocaIP.getPoint(); 20045ffd83dbSDimitry Andric 20055ffd83dbSDimitry Andric OldReturnBlock = CGF.ReturnBlock; 20065ffd83dbSDimitry Andric CGF.ReturnBlock = CGF.getJumpDestInCurrentScope(&RetBB); 20075ffd83dbSDimitry Andric } 20085ffd83dbSDimitry Andric 20095ffd83dbSDimitry Andric ~OutlinedRegionBodyRAII() { 20105ffd83dbSDimitry Andric CGF.AllocaInsertPt = OldAllocaIP; 20115ffd83dbSDimitry Andric CGF.ReturnBlock = OldReturnBlock; 20125ffd83dbSDimitry Andric } 20135ffd83dbSDimitry Andric }; 20145ffd83dbSDimitry Andric 20155ffd83dbSDimitry Andric /// RAII for preserving necessary info during inlined region body codegen. 20165ffd83dbSDimitry Andric class InlinedRegionBodyRAII { 20175ffd83dbSDimitry Andric 20185ffd83dbSDimitry Andric llvm::AssertingVH<llvm::Instruction> OldAllocaIP; 20195ffd83dbSDimitry Andric CodeGenFunction &CGF; 20205ffd83dbSDimitry Andric 20215ffd83dbSDimitry Andric public: 20225ffd83dbSDimitry Andric InlinedRegionBodyRAII(CodeGenFunction &cgf, InsertPointTy &AllocaIP, 20235ffd83dbSDimitry Andric llvm::BasicBlock &FiniBB) 20245ffd83dbSDimitry Andric : CGF(cgf) { 20255ffd83dbSDimitry Andric // Alloca insertion block should be in the entry block of the containing 20265ffd83dbSDimitry Andric // function so it expects an empty AllocaIP in which case will reuse the 20275ffd83dbSDimitry Andric // old alloca insertion point, or a new AllocaIP in the same block as 20285ffd83dbSDimitry Andric // the old one 20295ffd83dbSDimitry Andric assert((!AllocaIP.isSet() || 20305ffd83dbSDimitry Andric CGF.AllocaInsertPt->getParent() == AllocaIP.getBlock()) && 20315ffd83dbSDimitry Andric "Insertion point should be in the entry block of containing " 20325ffd83dbSDimitry Andric "function!"); 20335ffd83dbSDimitry Andric OldAllocaIP = CGF.AllocaInsertPt; 20345ffd83dbSDimitry Andric if (AllocaIP.isSet()) 20355ffd83dbSDimitry Andric CGF.AllocaInsertPt = &*AllocaIP.getPoint(); 20365ffd83dbSDimitry Andric 20375ffd83dbSDimitry Andric // TODO: Remove the call, after making sure the counter is not used by 20385ffd83dbSDimitry Andric // the EHStack. 20395ffd83dbSDimitry Andric // Since this is an inlined region, it should not modify the 20405ffd83dbSDimitry Andric // ReturnBlock, and should reuse the one for the enclosing outlined 20415ffd83dbSDimitry Andric // region. So, the JumpDest being return by the function is discarded 20425ffd83dbSDimitry Andric (void)CGF.getJumpDestInCurrentScope(&FiniBB); 20435ffd83dbSDimitry Andric } 20445ffd83dbSDimitry Andric 20455ffd83dbSDimitry Andric ~InlinedRegionBodyRAII() { CGF.AllocaInsertPt = OldAllocaIP; } 20465ffd83dbSDimitry Andric }; 20475ffd83dbSDimitry Andric }; 20485ffd83dbSDimitry Andric 20490b57cec5SDimitry Andric private: 20500b57cec5SDimitry Andric /// CXXThisDecl - When generating code for a C++ member function, 20510b57cec5SDimitry Andric /// this will hold the implicit 'this' declaration. 20520b57cec5SDimitry Andric ImplicitParamDecl *CXXABIThisDecl = nullptr; 20530b57cec5SDimitry Andric llvm::Value *CXXABIThisValue = nullptr; 20540b57cec5SDimitry Andric llvm::Value *CXXThisValue = nullptr; 20550b57cec5SDimitry Andric CharUnits CXXABIThisAlignment; 20560b57cec5SDimitry Andric CharUnits CXXThisAlignment; 20570b57cec5SDimitry Andric 20580b57cec5SDimitry Andric /// The value of 'this' to use when evaluating CXXDefaultInitExprs within 20590b57cec5SDimitry Andric /// this expression. 20600b57cec5SDimitry Andric Address CXXDefaultInitExprThis = Address::invalid(); 20610b57cec5SDimitry Andric 20620b57cec5SDimitry Andric /// The current array initialization index when evaluating an 20630b57cec5SDimitry Andric /// ArrayInitIndexExpr within an ArrayInitLoopExpr. 20640b57cec5SDimitry Andric llvm::Value *ArrayInitIndex = nullptr; 20650b57cec5SDimitry Andric 20660b57cec5SDimitry Andric /// The values of function arguments to use when evaluating 20670b57cec5SDimitry Andric /// CXXInheritedCtorInitExprs within this context. 20680b57cec5SDimitry Andric CallArgList CXXInheritedCtorInitExprArgs; 20690b57cec5SDimitry Andric 20700b57cec5SDimitry Andric /// CXXStructorImplicitParamDecl - When generating code for a constructor or 20710b57cec5SDimitry Andric /// destructor, this will hold the implicit argument (e.g. VTT). 20720b57cec5SDimitry Andric ImplicitParamDecl *CXXStructorImplicitParamDecl = nullptr; 20730b57cec5SDimitry Andric llvm::Value *CXXStructorImplicitParamValue = nullptr; 20740b57cec5SDimitry Andric 20750b57cec5SDimitry Andric /// OutermostConditional - Points to the outermost active 20760b57cec5SDimitry Andric /// conditional control. This is used so that we know if a 20770b57cec5SDimitry Andric /// temporary should be destroyed conditionally. 20780b57cec5SDimitry Andric ConditionalEvaluation *OutermostConditional = nullptr; 20790b57cec5SDimitry Andric 20800b57cec5SDimitry Andric /// The current lexical scope. 20810b57cec5SDimitry Andric LexicalScope *CurLexicalScope = nullptr; 20820b57cec5SDimitry Andric 20830b57cec5SDimitry Andric /// The current source location that should be used for exception 20840b57cec5SDimitry Andric /// handling code. 20850b57cec5SDimitry Andric SourceLocation CurEHLocation; 20860b57cec5SDimitry Andric 20870b57cec5SDimitry Andric /// BlockByrefInfos - For each __block variable, contains 20880b57cec5SDimitry Andric /// information about the layout of the variable. 20890b57cec5SDimitry Andric llvm::DenseMap<const ValueDecl *, BlockByrefInfo> BlockByrefInfos; 20900b57cec5SDimitry Andric 20910b57cec5SDimitry Andric /// Used by -fsanitize=nullability-return to determine whether the return 20920b57cec5SDimitry Andric /// value can be checked. 20930b57cec5SDimitry Andric llvm::Value *RetValNullabilityPrecondition = nullptr; 20940b57cec5SDimitry Andric 20950b57cec5SDimitry Andric /// Check if -fsanitize=nullability-return instrumentation is required for 20960b57cec5SDimitry Andric /// this function. 20970b57cec5SDimitry Andric bool requiresReturnValueNullabilityCheck() const { 20980b57cec5SDimitry Andric return RetValNullabilityPrecondition; 20990b57cec5SDimitry Andric } 21000b57cec5SDimitry Andric 21010b57cec5SDimitry Andric /// Used to store precise source locations for return statements by the 21020b57cec5SDimitry Andric /// runtime return value checks. 21030b57cec5SDimitry Andric Address ReturnLocation = Address::invalid(); 21040b57cec5SDimitry Andric 21050b57cec5SDimitry Andric /// Check if the return value of this function requires sanitization. 2106480093f4SDimitry Andric bool requiresReturnValueCheck() const; 21070b57cec5SDimitry Andric 21088a4dda33SDimitry Andric bool isInAllocaArgument(CGCXXABI &ABI, QualType Ty); 21098a4dda33SDimitry Andric bool hasInAllocaArg(const CXXMethodDecl *MD); 21108a4dda33SDimitry Andric 21110b57cec5SDimitry Andric llvm::BasicBlock *TerminateLandingPad = nullptr; 21120b57cec5SDimitry Andric llvm::BasicBlock *TerminateHandler = nullptr; 2113e8d8bef9SDimitry Andric llvm::SmallVector<llvm::BasicBlock *, 2> TrapBBs; 21140b57cec5SDimitry Andric 21150b57cec5SDimitry Andric /// Terminate funclets keyed by parent funclet pad. 21160b57cec5SDimitry Andric llvm::MapVector<llvm::Value *, llvm::BasicBlock *> TerminateFunclets; 21170b57cec5SDimitry Andric 21180b57cec5SDimitry Andric /// Largest vector width used in ths function. Will be used to create a 21190b57cec5SDimitry Andric /// function attribute. 21200b57cec5SDimitry Andric unsigned LargestVectorWidth = 0; 21210b57cec5SDimitry Andric 2122fe6060f1SDimitry Andric /// True if we need emit the life-time markers. This is initially set in 2123fe6060f1SDimitry Andric /// the constructor, but could be overwritten to true if this is a coroutine. 2124fe6060f1SDimitry Andric bool ShouldEmitLifetimeMarkers; 21250b57cec5SDimitry Andric 21260b57cec5SDimitry Andric /// Add OpenCL kernel arg metadata and the kernel attribute metadata to 21270b57cec5SDimitry Andric /// the function metadata. 212881ad6265SDimitry Andric void EmitKernelMetadata(const FunctionDecl *FD, llvm::Function *Fn); 21290b57cec5SDimitry Andric 21300b57cec5SDimitry Andric public: 21310b57cec5SDimitry Andric CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext=false); 21320b57cec5SDimitry Andric ~CodeGenFunction(); 21330b57cec5SDimitry Andric 21340b57cec5SDimitry Andric CodeGenTypes &getTypes() const { return CGM.getTypes(); } 21350b57cec5SDimitry Andric ASTContext &getContext() const { return CGM.getContext(); } 21360b57cec5SDimitry Andric CGDebugInfo *getDebugInfo() { 21370b57cec5SDimitry Andric if (DisableDebugInfo) 21380b57cec5SDimitry Andric return nullptr; 21390b57cec5SDimitry Andric return DebugInfo; 21400b57cec5SDimitry Andric } 21410b57cec5SDimitry Andric void disableDebugInfo() { DisableDebugInfo = true; } 21420b57cec5SDimitry Andric void enableDebugInfo() { DisableDebugInfo = false; } 21430b57cec5SDimitry Andric 21440b57cec5SDimitry Andric bool shouldUseFusedARCCalls() { 21450b57cec5SDimitry Andric return CGM.getCodeGenOpts().OptimizationLevel == 0; 21460b57cec5SDimitry Andric } 21470b57cec5SDimitry Andric 21480b57cec5SDimitry Andric const LangOptions &getLangOpts() const { return CGM.getLangOpts(); } 21490b57cec5SDimitry Andric 21500b57cec5SDimitry Andric /// Returns a pointer to the function's exception object and selector slot, 21510b57cec5SDimitry Andric /// which is assigned in every landing pad. 21520b57cec5SDimitry Andric Address getExceptionSlot(); 21530b57cec5SDimitry Andric Address getEHSelectorSlot(); 21540b57cec5SDimitry Andric 21550b57cec5SDimitry Andric /// Returns the contents of the function's exception object and selector 21560b57cec5SDimitry Andric /// slots. 21570b57cec5SDimitry Andric llvm::Value *getExceptionFromSlot(); 21580b57cec5SDimitry Andric llvm::Value *getSelectorFromSlot(); 21590b57cec5SDimitry Andric 21600fca6ea1SDimitry Andric RawAddress getNormalCleanupDestSlot(); 21610b57cec5SDimitry Andric 21620b57cec5SDimitry Andric llvm::BasicBlock *getUnreachableBlock() { 21630b57cec5SDimitry Andric if (!UnreachableBlock) { 21640b57cec5SDimitry Andric UnreachableBlock = createBasicBlock("unreachable"); 21650b57cec5SDimitry Andric new llvm::UnreachableInst(getLLVMContext(), UnreachableBlock); 21660b57cec5SDimitry Andric } 21670b57cec5SDimitry Andric return UnreachableBlock; 21680b57cec5SDimitry Andric } 21690b57cec5SDimitry Andric 21700b57cec5SDimitry Andric llvm::BasicBlock *getInvokeDest() { 21710b57cec5SDimitry Andric if (!EHStack.requiresLandingPad()) return nullptr; 21720b57cec5SDimitry Andric return getInvokeDestImpl(); 21730b57cec5SDimitry Andric } 21740b57cec5SDimitry Andric 2175bdd1243dSDimitry Andric bool currentFunctionUsesSEHTry() const { return !!CurSEHParent; } 21760b57cec5SDimitry Andric 21770b57cec5SDimitry Andric const TargetInfo &getTarget() const { return Target; } 21780b57cec5SDimitry Andric llvm::LLVMContext &getLLVMContext() { return CGM.getLLVMContext(); } 21790b57cec5SDimitry Andric const TargetCodeGenInfo &getTargetHooks() const { 21800b57cec5SDimitry Andric return CGM.getTargetCodeGenInfo(); 21810b57cec5SDimitry Andric } 21820b57cec5SDimitry Andric 21830b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 21840b57cec5SDimitry Andric // Cleanups 21850b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 21860b57cec5SDimitry Andric 21870b57cec5SDimitry Andric typedef void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty); 21880b57cec5SDimitry Andric 21890b57cec5SDimitry Andric void pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin, 21900b57cec5SDimitry Andric Address arrayEndPointer, 21910b57cec5SDimitry Andric QualType elementType, 21920b57cec5SDimitry Andric CharUnits elementAlignment, 21930b57cec5SDimitry Andric Destroyer *destroyer); 21940b57cec5SDimitry Andric void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin, 21950b57cec5SDimitry Andric llvm::Value *arrayEnd, 21960b57cec5SDimitry Andric QualType elementType, 21970b57cec5SDimitry Andric CharUnits elementAlignment, 21980b57cec5SDimitry Andric Destroyer *destroyer); 21990b57cec5SDimitry Andric 22000b57cec5SDimitry Andric void pushDestroy(QualType::DestructionKind dtorKind, 22010b57cec5SDimitry Andric Address addr, QualType type); 22020b57cec5SDimitry Andric void pushEHDestroy(QualType::DestructionKind dtorKind, 22030b57cec5SDimitry Andric Address addr, QualType type); 22040b57cec5SDimitry Andric void pushDestroy(CleanupKind kind, Address addr, QualType type, 22050b57cec5SDimitry Andric Destroyer *destroyer, bool useEHCleanupForArray); 22060fca6ea1SDimitry Andric void pushDestroyAndDeferDeactivation(QualType::DestructionKind dtorKind, 22070fca6ea1SDimitry Andric Address addr, QualType type); 22080fca6ea1SDimitry Andric void pushDestroyAndDeferDeactivation(CleanupKind cleanupKind, Address addr, 22090fca6ea1SDimitry Andric QualType type, Destroyer *destroyer, 22100fca6ea1SDimitry Andric bool useEHCleanupForArray); 22110b57cec5SDimitry Andric void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr, 22120b57cec5SDimitry Andric QualType type, Destroyer *destroyer, 22130b57cec5SDimitry Andric bool useEHCleanupForArray); 22140b57cec5SDimitry Andric void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete, 22150b57cec5SDimitry Andric llvm::Value *CompletePtr, 22160b57cec5SDimitry Andric QualType ElementType); 22170b57cec5SDimitry Andric void pushStackRestore(CleanupKind kind, Address SPMem); 221806c3fb27SDimitry Andric void pushKmpcAllocFree(CleanupKind Kind, 221906c3fb27SDimitry Andric std::pair<llvm::Value *, llvm::Value *> AddrSizePair); 22200b57cec5SDimitry Andric void emitDestroy(Address addr, QualType type, Destroyer *destroyer, 22210b57cec5SDimitry Andric bool useEHCleanupForArray); 22220b57cec5SDimitry Andric llvm::Function *generateDestroyHelper(Address addr, QualType type, 22230b57cec5SDimitry Andric Destroyer *destroyer, 22240b57cec5SDimitry Andric bool useEHCleanupForArray, 22250b57cec5SDimitry Andric const VarDecl *VD); 22260b57cec5SDimitry Andric void emitArrayDestroy(llvm::Value *begin, llvm::Value *end, 22270b57cec5SDimitry Andric QualType elementType, CharUnits elementAlign, 22280b57cec5SDimitry Andric Destroyer *destroyer, 22290b57cec5SDimitry Andric bool checkZeroLength, bool useEHCleanup); 22300b57cec5SDimitry Andric 22310b57cec5SDimitry Andric Destroyer *getDestroyer(QualType::DestructionKind destructionKind); 22320b57cec5SDimitry Andric 22330b57cec5SDimitry Andric /// Determines whether an EH cleanup is required to destroy a type 22340b57cec5SDimitry Andric /// with the given destruction kind. 22350b57cec5SDimitry Andric bool needsEHCleanup(QualType::DestructionKind kind) { 22360b57cec5SDimitry Andric switch (kind) { 22370b57cec5SDimitry Andric case QualType::DK_none: 22380b57cec5SDimitry Andric return false; 22390b57cec5SDimitry Andric case QualType::DK_cxx_destructor: 22400b57cec5SDimitry Andric case QualType::DK_objc_weak_lifetime: 22410b57cec5SDimitry Andric case QualType::DK_nontrivial_c_struct: 22420b57cec5SDimitry Andric return getLangOpts().Exceptions; 22430b57cec5SDimitry Andric case QualType::DK_objc_strong_lifetime: 22440b57cec5SDimitry Andric return getLangOpts().Exceptions && 22450b57cec5SDimitry Andric CGM.getCodeGenOpts().ObjCAutoRefCountExceptions; 22460b57cec5SDimitry Andric } 22470b57cec5SDimitry Andric llvm_unreachable("bad destruction kind"); 22480b57cec5SDimitry Andric } 22490b57cec5SDimitry Andric 22500b57cec5SDimitry Andric CleanupKind getCleanupKind(QualType::DestructionKind kind) { 22510b57cec5SDimitry Andric return (needsEHCleanup(kind) ? NormalAndEHCleanup : NormalCleanup); 22520b57cec5SDimitry Andric } 22530b57cec5SDimitry Andric 22540b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 22550b57cec5SDimitry Andric // Objective-C 22560b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 22570b57cec5SDimitry Andric 22580b57cec5SDimitry Andric void GenerateObjCMethod(const ObjCMethodDecl *OMD); 22590b57cec5SDimitry Andric 22600b57cec5SDimitry Andric void StartObjCMethod(const ObjCMethodDecl *MD, const ObjCContainerDecl *CD); 22610b57cec5SDimitry Andric 22620b57cec5SDimitry Andric /// GenerateObjCGetter - Synthesize an Objective-C property getter function. 22630b57cec5SDimitry Andric void GenerateObjCGetter(ObjCImplementationDecl *IMP, 22640b57cec5SDimitry Andric const ObjCPropertyImplDecl *PID); 22650b57cec5SDimitry Andric void generateObjCGetterBody(const ObjCImplementationDecl *classImpl, 22660b57cec5SDimitry Andric const ObjCPropertyImplDecl *propImpl, 22670b57cec5SDimitry Andric const ObjCMethodDecl *GetterMothodDecl, 22680b57cec5SDimitry Andric llvm::Constant *AtomicHelperFn); 22690b57cec5SDimitry Andric 22700b57cec5SDimitry Andric void GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP, 22710b57cec5SDimitry Andric ObjCMethodDecl *MD, bool ctor); 22720b57cec5SDimitry Andric 22730b57cec5SDimitry Andric /// GenerateObjCSetter - Synthesize an Objective-C property setter function 22740b57cec5SDimitry Andric /// for the given property. 22750b57cec5SDimitry Andric void GenerateObjCSetter(ObjCImplementationDecl *IMP, 22760b57cec5SDimitry Andric const ObjCPropertyImplDecl *PID); 22770b57cec5SDimitry Andric void generateObjCSetterBody(const ObjCImplementationDecl *classImpl, 22780b57cec5SDimitry Andric const ObjCPropertyImplDecl *propImpl, 22790b57cec5SDimitry Andric llvm::Constant *AtomicHelperFn); 22800b57cec5SDimitry Andric 22810b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 22820b57cec5SDimitry Andric // Block Bits 22830b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 22840b57cec5SDimitry Andric 22850b57cec5SDimitry Andric /// Emit block literal. 22860b57cec5SDimitry Andric /// \return an LLVM value which is a pointer to a struct which contains 22870b57cec5SDimitry Andric /// information about the block, including the block invoke function, the 22880b57cec5SDimitry Andric /// captured variables, etc. 22890b57cec5SDimitry Andric llvm::Value *EmitBlockLiteral(const BlockExpr *); 22900b57cec5SDimitry Andric 22910b57cec5SDimitry Andric llvm::Function *GenerateBlockFunction(GlobalDecl GD, 22920b57cec5SDimitry Andric const CGBlockInfo &Info, 22930b57cec5SDimitry Andric const DeclMapTy &ldm, 22940b57cec5SDimitry Andric bool IsLambdaConversionToBlock, 22950b57cec5SDimitry Andric bool BuildGlobalBlock); 22960b57cec5SDimitry Andric 22970b57cec5SDimitry Andric /// Check if \p T is a C++ class that has a destructor that can throw. 22980b57cec5SDimitry Andric static bool cxxDestructorCanThrow(QualType T); 22990b57cec5SDimitry Andric 23000b57cec5SDimitry Andric llvm::Constant *GenerateCopyHelperFunction(const CGBlockInfo &blockInfo); 23010b57cec5SDimitry Andric llvm::Constant *GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo); 23020b57cec5SDimitry Andric llvm::Constant *GenerateObjCAtomicSetterCopyHelperFunction( 23030b57cec5SDimitry Andric const ObjCPropertyImplDecl *PID); 23040b57cec5SDimitry Andric llvm::Constant *GenerateObjCAtomicGetterCopyHelperFunction( 23050b57cec5SDimitry Andric const ObjCPropertyImplDecl *PID); 23060b57cec5SDimitry Andric llvm::Value *EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty); 23070b57cec5SDimitry Andric 23080b57cec5SDimitry Andric void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags, 23090b57cec5SDimitry Andric bool CanThrow); 23100b57cec5SDimitry Andric 23110b57cec5SDimitry Andric class AutoVarEmission; 23120b57cec5SDimitry Andric 23130b57cec5SDimitry Andric void emitByrefStructureInit(const AutoVarEmission &emission); 23140b57cec5SDimitry Andric 23150b57cec5SDimitry Andric /// Enter a cleanup to destroy a __block variable. Note that this 23160b57cec5SDimitry Andric /// cleanup should be a no-op if the variable hasn't left the stack 23170b57cec5SDimitry Andric /// yet; if a cleanup is required for the variable itself, that needs 23180b57cec5SDimitry Andric /// to be done externally. 23190b57cec5SDimitry Andric /// 23200b57cec5SDimitry Andric /// \param Kind Cleanup kind. 23210b57cec5SDimitry Andric /// 23220b57cec5SDimitry Andric /// \param Addr When \p LoadBlockVarAddr is false, the address of the __block 23230b57cec5SDimitry Andric /// structure that will be passed to _Block_object_dispose. When 23240b57cec5SDimitry Andric /// \p LoadBlockVarAddr is true, the address of the field of the block 23250b57cec5SDimitry Andric /// structure that holds the address of the __block structure. 23260b57cec5SDimitry Andric /// 23270b57cec5SDimitry Andric /// \param Flags The flag that will be passed to _Block_object_dispose. 23280b57cec5SDimitry Andric /// 23290b57cec5SDimitry Andric /// \param LoadBlockVarAddr Indicates whether we need to emit a load from 23300b57cec5SDimitry Andric /// \p Addr to get the address of the __block structure. 23310b57cec5SDimitry Andric void enterByrefCleanup(CleanupKind Kind, Address Addr, BlockFieldFlags Flags, 23320b57cec5SDimitry Andric bool LoadBlockVarAddr, bool CanThrow); 23330b57cec5SDimitry Andric 23340b57cec5SDimitry Andric void setBlockContextParameter(const ImplicitParamDecl *D, unsigned argNum, 23350b57cec5SDimitry Andric llvm::Value *ptr); 23360b57cec5SDimitry Andric 23370b57cec5SDimitry Andric Address LoadBlockStruct(); 23380b57cec5SDimitry Andric Address GetAddrOfBlockDecl(const VarDecl *var); 23390b57cec5SDimitry Andric 23400b57cec5SDimitry Andric /// BuildBlockByrefAddress - Computes the location of the 23410b57cec5SDimitry Andric /// data in a variable which is declared as __block. 23420b57cec5SDimitry Andric Address emitBlockByrefAddress(Address baseAddr, const VarDecl *V, 23430b57cec5SDimitry Andric bool followForward = true); 23440b57cec5SDimitry Andric Address emitBlockByrefAddress(Address baseAddr, 23450b57cec5SDimitry Andric const BlockByrefInfo &info, 23460b57cec5SDimitry Andric bool followForward, 23470b57cec5SDimitry Andric const llvm::Twine &name); 23480b57cec5SDimitry Andric 23490b57cec5SDimitry Andric const BlockByrefInfo &getBlockByrefInfo(const VarDecl *var); 23500b57cec5SDimitry Andric 23510b57cec5SDimitry Andric QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args); 23520b57cec5SDimitry Andric 23530b57cec5SDimitry Andric void GenerateCode(GlobalDecl GD, llvm::Function *Fn, 23540b57cec5SDimitry Andric const CGFunctionInfo &FnInfo); 23550b57cec5SDimitry Andric 23560b57cec5SDimitry Andric /// Annotate the function with an attribute that disables TSan checking at 23570b57cec5SDimitry Andric /// runtime. 23580b57cec5SDimitry Andric void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn); 23590b57cec5SDimitry Andric 23600b57cec5SDimitry Andric /// Emit code for the start of a function. 23610b57cec5SDimitry Andric /// \param Loc The location to be associated with the function. 23620b57cec5SDimitry Andric /// \param StartLoc The location of the function body. 23630b57cec5SDimitry Andric void StartFunction(GlobalDecl GD, 23640b57cec5SDimitry Andric QualType RetTy, 23650b57cec5SDimitry Andric llvm::Function *Fn, 23660b57cec5SDimitry Andric const CGFunctionInfo &FnInfo, 23670b57cec5SDimitry Andric const FunctionArgList &Args, 23680b57cec5SDimitry Andric SourceLocation Loc = SourceLocation(), 23690b57cec5SDimitry Andric SourceLocation StartLoc = SourceLocation()); 23700b57cec5SDimitry Andric 23710b57cec5SDimitry Andric static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor); 23720b57cec5SDimitry Andric 23730b57cec5SDimitry Andric void EmitConstructorBody(FunctionArgList &Args); 23740b57cec5SDimitry Andric void EmitDestructorBody(FunctionArgList &Args); 23750b57cec5SDimitry Andric void emitImplicitAssignmentOperatorBody(FunctionArgList &Args); 23760b57cec5SDimitry Andric void EmitFunctionBody(const Stmt *Body); 23770b57cec5SDimitry Andric void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S); 23780b57cec5SDimitry Andric 23790b57cec5SDimitry Andric void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator, 23808a4dda33SDimitry Andric CallArgList &CallArgs, 23818a4dda33SDimitry Andric const CGFunctionInfo *CallOpFnInfo = nullptr, 23828a4dda33SDimitry Andric llvm::Constant *CallOpFn = nullptr); 23830b57cec5SDimitry Andric void EmitLambdaBlockInvokeBody(); 23840b57cec5SDimitry Andric void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD); 23858a4dda33SDimitry Andric void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD, 23868a4dda33SDimitry Andric CallArgList &CallArgs); 23878a4dda33SDimitry Andric void EmitLambdaInAllocaImplFn(const CXXMethodDecl *CallOp, 23888a4dda33SDimitry Andric const CGFunctionInfo **ImplFnInfo, 23898a4dda33SDimitry Andric llvm::Function **ImplFn); 23908a4dda33SDimitry Andric void EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD); 23910b57cec5SDimitry Andric void EmitLambdaVLACapture(const VariableArrayType *VAT, LValue LV) { 23920b57cec5SDimitry Andric EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV); 23930b57cec5SDimitry Andric } 23940b57cec5SDimitry Andric void EmitAsanPrologueOrEpilogue(bool Prologue); 23950b57cec5SDimitry Andric 23960b57cec5SDimitry Andric /// Emit the unified return block, trying to avoid its emission when 23970b57cec5SDimitry Andric /// possible. 23980b57cec5SDimitry Andric /// \return The debug location of the user written return statement if the 2399bdd1243dSDimitry Andric /// return block is avoided. 24000b57cec5SDimitry Andric llvm::DebugLoc EmitReturnBlock(); 24010b57cec5SDimitry Andric 24020b57cec5SDimitry Andric /// FinishFunction - Complete IR generation of the current function. It is 24030b57cec5SDimitry Andric /// legal to call this function even if there is no current insertion point. 24040b57cec5SDimitry Andric void FinishFunction(SourceLocation EndLoc=SourceLocation()); 24050b57cec5SDimitry Andric 24060b57cec5SDimitry Andric void StartThunk(llvm::Function *Fn, GlobalDecl GD, 24070b57cec5SDimitry Andric const CGFunctionInfo &FnInfo, bool IsUnprototyped); 24080b57cec5SDimitry Andric 24090b57cec5SDimitry Andric void EmitCallAndReturnForThunk(llvm::FunctionCallee Callee, 24100b57cec5SDimitry Andric const ThunkInfo *Thunk, bool IsUnprototyped); 24110b57cec5SDimitry Andric 24120b57cec5SDimitry Andric void FinishThunk(); 24130b57cec5SDimitry Andric 24140b57cec5SDimitry Andric /// Emit a musttail call for a thunk with a potentially adjusted this pointer. 24150b57cec5SDimitry Andric void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr, 24160b57cec5SDimitry Andric llvm::FunctionCallee Callee); 24170b57cec5SDimitry Andric 24180b57cec5SDimitry Andric /// Generate a thunk for the given method. 24190b57cec5SDimitry Andric void generateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, 24200b57cec5SDimitry Andric GlobalDecl GD, const ThunkInfo &Thunk, 24210b57cec5SDimitry Andric bool IsUnprototyped); 24220b57cec5SDimitry Andric 24230b57cec5SDimitry Andric llvm::Function *GenerateVarArgsThunk(llvm::Function *Fn, 24240b57cec5SDimitry Andric const CGFunctionInfo &FnInfo, 24250b57cec5SDimitry Andric GlobalDecl GD, const ThunkInfo &Thunk); 24260b57cec5SDimitry Andric 24270b57cec5SDimitry Andric void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type, 24280b57cec5SDimitry Andric FunctionArgList &Args); 24290b57cec5SDimitry Andric 24300b57cec5SDimitry Andric void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init); 24310b57cec5SDimitry Andric 24320b57cec5SDimitry Andric /// Struct with all information about dynamic [sub]class needed to set vptr. 24330b57cec5SDimitry Andric struct VPtr { 24340b57cec5SDimitry Andric BaseSubobject Base; 24350b57cec5SDimitry Andric const CXXRecordDecl *NearestVBase; 24360b57cec5SDimitry Andric CharUnits OffsetFromNearestVBase; 24370b57cec5SDimitry Andric const CXXRecordDecl *VTableClass; 24380b57cec5SDimitry Andric }; 24390b57cec5SDimitry Andric 24400b57cec5SDimitry Andric /// Initialize the vtable pointer of the given subobject. 24410b57cec5SDimitry Andric void InitializeVTablePointer(const VPtr &vptr); 24420b57cec5SDimitry Andric 24430b57cec5SDimitry Andric typedef llvm::SmallVector<VPtr, 4> VPtrsVector; 24440b57cec5SDimitry Andric 24450b57cec5SDimitry Andric typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; 24460b57cec5SDimitry Andric VPtrsVector getVTablePointers(const CXXRecordDecl *VTableClass); 24470b57cec5SDimitry Andric 24480b57cec5SDimitry Andric void getVTablePointers(BaseSubobject Base, const CXXRecordDecl *NearestVBase, 24490b57cec5SDimitry Andric CharUnits OffsetFromNearestVBase, 24500b57cec5SDimitry Andric bool BaseIsNonVirtualPrimaryBase, 24510b57cec5SDimitry Andric const CXXRecordDecl *VTableClass, 24520b57cec5SDimitry Andric VisitedVirtualBasesSetTy &VBases, VPtrsVector &vptrs); 24530b57cec5SDimitry Andric 24540b57cec5SDimitry Andric void InitializeVTablePointers(const CXXRecordDecl *ClassDecl); 24550b57cec5SDimitry Andric 24560fca6ea1SDimitry Andric // VTableTrapMode - whether we guarantee that loading the 24570fca6ea1SDimitry Andric // vtable is guaranteed to trap on authentication failure, 24580fca6ea1SDimitry Andric // even if the resulting vtable pointer is unused. 24590fca6ea1SDimitry Andric enum class VTableAuthMode { 24600fca6ea1SDimitry Andric Authenticate, 24610fca6ea1SDimitry Andric MustTrap, 24620fca6ea1SDimitry Andric UnsafeUbsanStrip // Should only be used for Vptr UBSan check 24630fca6ea1SDimitry Andric }; 24640b57cec5SDimitry Andric /// GetVTablePtr - Return the Value of the vtable pointer member pointed 24650b57cec5SDimitry Andric /// to by This. 24660fca6ea1SDimitry Andric llvm::Value * 24670fca6ea1SDimitry Andric GetVTablePtr(Address This, llvm::Type *VTableTy, 24680fca6ea1SDimitry Andric const CXXRecordDecl *VTableClass, 24690fca6ea1SDimitry Andric VTableAuthMode AuthMode = VTableAuthMode::Authenticate); 24700b57cec5SDimitry Andric 24710b57cec5SDimitry Andric enum CFITypeCheckKind { 24720b57cec5SDimitry Andric CFITCK_VCall, 24730b57cec5SDimitry Andric CFITCK_NVCall, 24740b57cec5SDimitry Andric CFITCK_DerivedCast, 24750b57cec5SDimitry Andric CFITCK_UnrelatedCast, 24760b57cec5SDimitry Andric CFITCK_ICall, 24770b57cec5SDimitry Andric CFITCK_NVMFCall, 24780b57cec5SDimitry Andric CFITCK_VMFCall, 24790b57cec5SDimitry Andric }; 24800b57cec5SDimitry Andric 24810b57cec5SDimitry Andric /// Derived is the presumed address of an object of type T after a 24820b57cec5SDimitry Andric /// cast. If T is a polymorphic class type, emit a check that the virtual 24830b57cec5SDimitry Andric /// table for Derived belongs to a class derived from T. 248481ad6265SDimitry Andric void EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull, 248581ad6265SDimitry Andric CFITypeCheckKind TCK, SourceLocation Loc); 24860b57cec5SDimitry Andric 24870b57cec5SDimitry Andric /// EmitVTablePtrCheckForCall - Virtual method MD is being called via VTable. 24880b57cec5SDimitry Andric /// If vptr CFI is enabled, emit a check that VTable is valid. 24890b57cec5SDimitry Andric void EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, llvm::Value *VTable, 24900b57cec5SDimitry Andric CFITypeCheckKind TCK, SourceLocation Loc); 24910b57cec5SDimitry Andric 24920b57cec5SDimitry Andric /// EmitVTablePtrCheck - Emit a check that VTable is a valid virtual table for 24930b57cec5SDimitry Andric /// RD using llvm.type.test. 24940b57cec5SDimitry Andric void EmitVTablePtrCheck(const CXXRecordDecl *RD, llvm::Value *VTable, 24950b57cec5SDimitry Andric CFITypeCheckKind TCK, SourceLocation Loc); 24960b57cec5SDimitry Andric 24970b57cec5SDimitry Andric /// If whole-program virtual table optimization is enabled, emit an assumption 24980b57cec5SDimitry Andric /// that VTable is a member of RD's type identifier. Or, if vptr CFI is 24990b57cec5SDimitry Andric /// enabled, emit a check that VTable is a member of RD's type identifier. 25000b57cec5SDimitry Andric void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, 25010b57cec5SDimitry Andric llvm::Value *VTable, SourceLocation Loc); 25020b57cec5SDimitry Andric 25030b57cec5SDimitry Andric /// Returns whether we should perform a type checked load when loading a 25040b57cec5SDimitry Andric /// virtual function for virtual calls to members of RD. This is generally 25050b57cec5SDimitry Andric /// true when both vcall CFI and whole-program-vtables are enabled. 25060b57cec5SDimitry Andric bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD); 25070b57cec5SDimitry Andric 25080b57cec5SDimitry Andric /// Emit a type checked load from the given vtable. 250981ad6265SDimitry Andric llvm::Value *EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, 251081ad6265SDimitry Andric llvm::Value *VTable, 251181ad6265SDimitry Andric llvm::Type *VTableTy, 25120b57cec5SDimitry Andric uint64_t VTableByteOffset); 25130b57cec5SDimitry Andric 25140b57cec5SDimitry Andric /// EnterDtorCleanups - Enter the cleanups necessary to complete the 25150b57cec5SDimitry Andric /// given phase of destruction for a destructor. The end result 25160b57cec5SDimitry Andric /// should call destructors on members and base classes in reverse 25170b57cec5SDimitry Andric /// order of their construction. 25180b57cec5SDimitry Andric void EnterDtorCleanups(const CXXDestructorDecl *Dtor, CXXDtorType Type); 25190b57cec5SDimitry Andric 25200b57cec5SDimitry Andric /// ShouldInstrumentFunction - Return true if the current function should be 25210b57cec5SDimitry Andric /// instrumented with __cyg_profile_func_* calls 25220b57cec5SDimitry Andric bool ShouldInstrumentFunction(); 25230b57cec5SDimitry Andric 2524349cc55cSDimitry Andric /// ShouldSkipSanitizerInstrumentation - Return true if the current function 2525349cc55cSDimitry Andric /// should not be instrumented with sanitizers. 2526349cc55cSDimitry Andric bool ShouldSkipSanitizerInstrumentation(); 2527349cc55cSDimitry Andric 25280b57cec5SDimitry Andric /// ShouldXRayInstrument - Return true if the current function should be 25290b57cec5SDimitry Andric /// instrumented with XRay nop sleds. 25300b57cec5SDimitry Andric bool ShouldXRayInstrumentFunction() const; 25310b57cec5SDimitry Andric 25320b57cec5SDimitry Andric /// AlwaysEmitXRayCustomEvents - Return true if we must unconditionally emit 25330b57cec5SDimitry Andric /// XRay custom event handling calls. 25340b57cec5SDimitry Andric bool AlwaysEmitXRayCustomEvents() const; 25350b57cec5SDimitry Andric 25360b57cec5SDimitry Andric /// AlwaysEmitXRayTypedEvents - Return true if clang must unconditionally emit 25370b57cec5SDimitry Andric /// XRay typed event handling calls. 25380b57cec5SDimitry Andric bool AlwaysEmitXRayTypedEvents() const; 25390b57cec5SDimitry Andric 254006c3fb27SDimitry Andric /// Return a type hash constant for a function instrumented by 254106c3fb27SDimitry Andric /// -fsanitize=function. 254206c3fb27SDimitry Andric llvm::ConstantInt *getUBSanFunctionTypeHash(QualType T) const; 25430b57cec5SDimitry Andric 25440b57cec5SDimitry Andric /// EmitFunctionProlog - Emit the target specific LLVM code to load the 25450b57cec5SDimitry Andric /// arguments for the given function. This is also responsible for naming the 25460b57cec5SDimitry Andric /// LLVM function arguments. 25470b57cec5SDimitry Andric void EmitFunctionProlog(const CGFunctionInfo &FI, 25480b57cec5SDimitry Andric llvm::Function *Fn, 25490b57cec5SDimitry Andric const FunctionArgList &Args); 25500b57cec5SDimitry Andric 25510b57cec5SDimitry Andric /// EmitFunctionEpilog - Emit the target specific LLVM code to return the 25520b57cec5SDimitry Andric /// given temporary. 25530b57cec5SDimitry Andric void EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc, 25540b57cec5SDimitry Andric SourceLocation EndLoc); 25550b57cec5SDimitry Andric 25560b57cec5SDimitry Andric /// Emit a test that checks if the return value \p RV is nonnull. 25570b57cec5SDimitry Andric void EmitReturnValueCheck(llvm::Value *RV); 25580b57cec5SDimitry Andric 25590b57cec5SDimitry Andric /// EmitStartEHSpec - Emit the start of the exception spec. 25600b57cec5SDimitry Andric void EmitStartEHSpec(const Decl *D); 25610b57cec5SDimitry Andric 25620b57cec5SDimitry Andric /// EmitEndEHSpec - Emit the end of the exception spec. 25630b57cec5SDimitry Andric void EmitEndEHSpec(const Decl *D); 25640b57cec5SDimitry Andric 25650b57cec5SDimitry Andric /// getTerminateLandingPad - Return a landing pad that just calls terminate. 25660b57cec5SDimitry Andric llvm::BasicBlock *getTerminateLandingPad(); 25670b57cec5SDimitry Andric 25680b57cec5SDimitry Andric /// getTerminateLandingPad - Return a cleanup funclet that just calls 25690b57cec5SDimitry Andric /// terminate. 25700b57cec5SDimitry Andric llvm::BasicBlock *getTerminateFunclet(); 25710b57cec5SDimitry Andric 25720b57cec5SDimitry Andric /// getTerminateHandler - Return a handler (not a landing pad, just 25730b57cec5SDimitry Andric /// a catch handler) that just calls terminate. This is used when 25740b57cec5SDimitry Andric /// a terminate scope encloses a try. 25750b57cec5SDimitry Andric llvm::BasicBlock *getTerminateHandler(); 25760b57cec5SDimitry Andric 25770b57cec5SDimitry Andric llvm::Type *ConvertTypeForMem(QualType T); 25780b57cec5SDimitry Andric llvm::Type *ConvertType(QualType T); 25790fca6ea1SDimitry Andric llvm::Type *convertTypeForLoadStore(QualType ASTTy, 25800fca6ea1SDimitry Andric llvm::Type *LLVMTy = nullptr); 25810b57cec5SDimitry Andric llvm::Type *ConvertType(const TypeDecl *T) { 25820b57cec5SDimitry Andric return ConvertType(getContext().getTypeDeclType(T)); 25830b57cec5SDimitry Andric } 25840b57cec5SDimitry Andric 25850b57cec5SDimitry Andric /// LoadObjCSelf - Load the value of self. This function is only valid while 25860b57cec5SDimitry Andric /// generating code for an Objective-C method. 25870b57cec5SDimitry Andric llvm::Value *LoadObjCSelf(); 25880b57cec5SDimitry Andric 25890b57cec5SDimitry Andric /// TypeOfSelfObject - Return type of object that this self represents. 25900b57cec5SDimitry Andric QualType TypeOfSelfObject(); 25910b57cec5SDimitry Andric 25920b57cec5SDimitry Andric /// getEvaluationKind - Return the TypeEvaluationKind of QualType \c T. 25930b57cec5SDimitry Andric static TypeEvaluationKind getEvaluationKind(QualType T); 25940b57cec5SDimitry Andric 25950b57cec5SDimitry Andric static bool hasScalarEvaluationKind(QualType T) { 25960b57cec5SDimitry Andric return getEvaluationKind(T) == TEK_Scalar; 25970b57cec5SDimitry Andric } 25980b57cec5SDimitry Andric 25990b57cec5SDimitry Andric static bool hasAggregateEvaluationKind(QualType T) { 26000b57cec5SDimitry Andric return getEvaluationKind(T) == TEK_Aggregate; 26010b57cec5SDimitry Andric } 26020b57cec5SDimitry Andric 26030b57cec5SDimitry Andric /// createBasicBlock - Create an LLVM basic block. 26040b57cec5SDimitry Andric llvm::BasicBlock *createBasicBlock(const Twine &name = "", 26050b57cec5SDimitry Andric llvm::Function *parent = nullptr, 26060b57cec5SDimitry Andric llvm::BasicBlock *before = nullptr) { 26070b57cec5SDimitry Andric return llvm::BasicBlock::Create(getLLVMContext(), name, parent, before); 26080b57cec5SDimitry Andric } 26090b57cec5SDimitry Andric 26100b57cec5SDimitry Andric /// getBasicBlockForLabel - Return the LLVM basicblock that the specified 26110b57cec5SDimitry Andric /// label maps to. 26120b57cec5SDimitry Andric JumpDest getJumpDestForLabel(const LabelDecl *S); 26130b57cec5SDimitry Andric 26140b57cec5SDimitry Andric /// SimplifyForwardingBlocks - If the given basic block is only a branch to 26150b57cec5SDimitry Andric /// another basic block, simplify it. This assumes that no other code could 26160b57cec5SDimitry Andric /// potentially reference the basic block. 26170b57cec5SDimitry Andric void SimplifyForwardingBlocks(llvm::BasicBlock *BB); 26180b57cec5SDimitry Andric 26190b57cec5SDimitry Andric /// EmitBlock - Emit the given block \arg BB and set it as the insert point, 26200b57cec5SDimitry Andric /// adding a fall-through branch from the current insert block if 26210b57cec5SDimitry Andric /// necessary. It is legal to call this function even if there is no current 26220b57cec5SDimitry Andric /// insertion point. 26230b57cec5SDimitry Andric /// 26240b57cec5SDimitry Andric /// IsFinished - If true, indicates that the caller has finished emitting 26250b57cec5SDimitry Andric /// branches to the given block and does not expect to emit code into it. This 26260b57cec5SDimitry Andric /// means the block can be ignored if it is unreachable. 26270b57cec5SDimitry Andric void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false); 26280b57cec5SDimitry Andric 26290b57cec5SDimitry Andric /// EmitBlockAfterUses - Emit the given block somewhere hopefully 26300b57cec5SDimitry Andric /// near its uses, and leave the insertion point in it. 26310b57cec5SDimitry Andric void EmitBlockAfterUses(llvm::BasicBlock *BB); 26320b57cec5SDimitry Andric 26330b57cec5SDimitry Andric /// EmitBranch - Emit a branch to the specified basic block from the current 26340b57cec5SDimitry Andric /// insert block, taking care to avoid creation of branches from dummy 26350b57cec5SDimitry Andric /// blocks. It is legal to call this function even if there is no current 26360b57cec5SDimitry Andric /// insertion point. 26370b57cec5SDimitry Andric /// 26380b57cec5SDimitry Andric /// This function clears the current insertion point. The caller should follow 26390b57cec5SDimitry Andric /// calls to this function with calls to Emit*Block prior to generation new 26400b57cec5SDimitry Andric /// code. 26410b57cec5SDimitry Andric void EmitBranch(llvm::BasicBlock *Block); 26420b57cec5SDimitry Andric 26430b57cec5SDimitry Andric /// HaveInsertPoint - True if an insertion point is defined. If not, this 26440b57cec5SDimitry Andric /// indicates that the current code being emitted is unreachable. 26450b57cec5SDimitry Andric bool HaveInsertPoint() const { 26460b57cec5SDimitry Andric return Builder.GetInsertBlock() != nullptr; 26470b57cec5SDimitry Andric } 26480b57cec5SDimitry Andric 26490b57cec5SDimitry Andric /// EnsureInsertPoint - Ensure that an insertion point is defined so that 26500b57cec5SDimitry Andric /// emitted IR has a place to go. Note that by definition, if this function 26510b57cec5SDimitry Andric /// creates a block then that block is unreachable; callers may do better to 26520b57cec5SDimitry Andric /// detect when no insertion point is defined and simply skip IR generation. 26530b57cec5SDimitry Andric void EnsureInsertPoint() { 26540b57cec5SDimitry Andric if (!HaveInsertPoint()) 26550b57cec5SDimitry Andric EmitBlock(createBasicBlock()); 26560b57cec5SDimitry Andric } 26570b57cec5SDimitry Andric 26580b57cec5SDimitry Andric /// ErrorUnsupported - Print out an error that codegen doesn't support the 26590b57cec5SDimitry Andric /// specified stmt yet. 26600b57cec5SDimitry Andric void ErrorUnsupported(const Stmt *S, const char *Type); 26610b57cec5SDimitry Andric 26620b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 26630b57cec5SDimitry Andric // Helpers 26640b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 26650b57cec5SDimitry Andric 26660fca6ea1SDimitry Andric Address mergeAddressesInConditionalExpr(Address LHS, Address RHS, 26670fca6ea1SDimitry Andric llvm::BasicBlock *LHSBlock, 26680fca6ea1SDimitry Andric llvm::BasicBlock *RHSBlock, 26690fca6ea1SDimitry Andric llvm::BasicBlock *MergeBlock, 26700fca6ea1SDimitry Andric QualType MergedType) { 26710fca6ea1SDimitry Andric Builder.SetInsertPoint(MergeBlock); 26720fca6ea1SDimitry Andric llvm::PHINode *PtrPhi = Builder.CreatePHI(LHS.getType(), 2, "cond"); 26730fca6ea1SDimitry Andric PtrPhi->addIncoming(LHS.getBasePointer(), LHSBlock); 26740fca6ea1SDimitry Andric PtrPhi->addIncoming(RHS.getBasePointer(), RHSBlock); 26750fca6ea1SDimitry Andric LHS.replaceBasePointer(PtrPhi); 26760fca6ea1SDimitry Andric LHS.setAlignment(std::min(LHS.getAlignment(), RHS.getAlignment())); 26770fca6ea1SDimitry Andric return LHS; 26780fca6ea1SDimitry Andric } 26790fca6ea1SDimitry Andric 26800fca6ea1SDimitry Andric /// Construct an address with the natural alignment of T. If a pointer to T 26810fca6ea1SDimitry Andric /// is expected to be signed, the pointer passed to this function must have 26820fca6ea1SDimitry Andric /// been signed, and the returned Address will have the pointer authentication 26830fca6ea1SDimitry Andric /// information needed to authenticate the signed pointer. 26840fca6ea1SDimitry Andric Address makeNaturalAddressForPointer( 26850fca6ea1SDimitry Andric llvm::Value *Ptr, QualType T, CharUnits Alignment = CharUnits::Zero(), 26860fca6ea1SDimitry Andric bool ForPointeeType = false, LValueBaseInfo *BaseInfo = nullptr, 26870fca6ea1SDimitry Andric TBAAAccessInfo *TBAAInfo = nullptr, 26880fca6ea1SDimitry Andric KnownNonNull_t IsKnownNonNull = NotKnownNonNull) { 26890fca6ea1SDimitry Andric if (Alignment.isZero()) 26900fca6ea1SDimitry Andric Alignment = 26910fca6ea1SDimitry Andric CGM.getNaturalTypeAlignment(T, BaseInfo, TBAAInfo, ForPointeeType); 26920fca6ea1SDimitry Andric return Address(Ptr, ConvertTypeForMem(T), Alignment, 26930fca6ea1SDimitry Andric CGM.getPointerAuthInfoForPointeeType(T), /*Offset=*/nullptr, 26940fca6ea1SDimitry Andric IsKnownNonNull); 26950fca6ea1SDimitry Andric } 26960fca6ea1SDimitry Andric 26970b57cec5SDimitry Andric LValue MakeAddrLValue(Address Addr, QualType T, 26980b57cec5SDimitry Andric AlignmentSource Source = AlignmentSource::Type) { 26990fca6ea1SDimitry Andric return MakeAddrLValue(Addr, T, LValueBaseInfo(Source), 27000b57cec5SDimitry Andric CGM.getTBAAAccessInfo(T)); 27010b57cec5SDimitry Andric } 27020b57cec5SDimitry Andric 27030b57cec5SDimitry Andric LValue MakeAddrLValue(Address Addr, QualType T, LValueBaseInfo BaseInfo, 27040b57cec5SDimitry Andric TBAAAccessInfo TBAAInfo) { 27050b57cec5SDimitry Andric return LValue::MakeAddr(Addr, T, getContext(), BaseInfo, TBAAInfo); 27060b57cec5SDimitry Andric } 27070b57cec5SDimitry Andric 27080b57cec5SDimitry Andric LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, 27090b57cec5SDimitry Andric AlignmentSource Source = AlignmentSource::Type) { 27100fca6ea1SDimitry Andric return MakeAddrLValue(makeNaturalAddressForPointer(V, T, Alignment), T, 27110fca6ea1SDimitry Andric LValueBaseInfo(Source), CGM.getTBAAAccessInfo(T)); 27120fca6ea1SDimitry Andric } 27130fca6ea1SDimitry Andric 27140fca6ea1SDimitry Andric /// Same as MakeAddrLValue above except that the pointer is known to be 27150fca6ea1SDimitry Andric /// unsigned. 27160fca6ea1SDimitry Andric LValue MakeRawAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, 27170fca6ea1SDimitry Andric AlignmentSource Source = AlignmentSource::Type) { 27180eae32dcSDimitry Andric Address Addr(V, ConvertTypeForMem(T), Alignment); 27190eae32dcSDimitry Andric return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source), 27200eae32dcSDimitry Andric CGM.getTBAAAccessInfo(T)); 27210b57cec5SDimitry Andric } 27220b57cec5SDimitry Andric 27230eae32dcSDimitry Andric LValue 27240eae32dcSDimitry Andric MakeAddrLValueWithoutTBAA(Address Addr, QualType T, 27250eae32dcSDimitry Andric AlignmentSource Source = AlignmentSource::Type) { 27260eae32dcSDimitry Andric return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source), 27270eae32dcSDimitry Andric TBAAAccessInfo()); 27280b57cec5SDimitry Andric } 27290b57cec5SDimitry Andric 27300fca6ea1SDimitry Andric /// Given a value of type T* that may not be to a complete object, construct 27310fca6ea1SDimitry Andric /// an l-value with the natural pointee alignment of T. 27320b57cec5SDimitry Andric LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T); 27330fca6ea1SDimitry Andric 27340fca6ea1SDimitry Andric LValue 27350fca6ea1SDimitry Andric MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, 27360fca6ea1SDimitry Andric KnownNonNull_t IsKnownNonNull = NotKnownNonNull); 27370fca6ea1SDimitry Andric 27380fca6ea1SDimitry Andric /// Same as MakeNaturalAlignPointeeAddrLValue except that the pointer is known 27390fca6ea1SDimitry Andric /// to be unsigned. 27400fca6ea1SDimitry Andric LValue MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V, QualType T); 27410fca6ea1SDimitry Andric 27420fca6ea1SDimitry Andric LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T); 27430b57cec5SDimitry Andric 27440b57cec5SDimitry Andric Address EmitLoadOfReference(LValue RefLVal, 27450b57cec5SDimitry Andric LValueBaseInfo *PointeeBaseInfo = nullptr, 27460b57cec5SDimitry Andric TBAAAccessInfo *PointeeTBAAInfo = nullptr); 27470b57cec5SDimitry Andric LValue EmitLoadOfReferenceLValue(LValue RefLVal); 27480b57cec5SDimitry Andric LValue EmitLoadOfReferenceLValue(Address RefAddr, QualType RefTy, 27490b57cec5SDimitry Andric AlignmentSource Source = 27500b57cec5SDimitry Andric AlignmentSource::Type) { 27510b57cec5SDimitry Andric LValue RefLVal = MakeAddrLValue(RefAddr, RefTy, LValueBaseInfo(Source), 27520b57cec5SDimitry Andric CGM.getTBAAAccessInfo(RefTy)); 27530b57cec5SDimitry Andric return EmitLoadOfReferenceLValue(RefLVal); 27540b57cec5SDimitry Andric } 27550b57cec5SDimitry Andric 275681ad6265SDimitry Andric /// Load a pointer with type \p PtrTy stored at address \p Ptr. 275781ad6265SDimitry Andric /// Note that \p PtrTy is the type of the loaded pointer, not the addresses 275881ad6265SDimitry Andric /// it is loaded from. 27590b57cec5SDimitry Andric Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, 27600b57cec5SDimitry Andric LValueBaseInfo *BaseInfo = nullptr, 27610b57cec5SDimitry Andric TBAAAccessInfo *TBAAInfo = nullptr); 27620b57cec5SDimitry Andric LValue EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy); 27630b57cec5SDimitry Andric 27640fca6ea1SDimitry Andric private: 27650fca6ea1SDimitry Andric struct AllocaTracker { 27660fca6ea1SDimitry Andric void Add(llvm::AllocaInst *I) { Allocas.push_back(I); } 27670fca6ea1SDimitry Andric llvm::SmallVector<llvm::AllocaInst *> Take() { return std::move(Allocas); } 27680fca6ea1SDimitry Andric 27690fca6ea1SDimitry Andric private: 27700fca6ea1SDimitry Andric llvm::SmallVector<llvm::AllocaInst *> Allocas; 27710fca6ea1SDimitry Andric }; 27720fca6ea1SDimitry Andric AllocaTracker *Allocas = nullptr; 27730fca6ea1SDimitry Andric 27740fca6ea1SDimitry Andric public: 27750fca6ea1SDimitry Andric // Captures all the allocas created during the scope of its RAII object. 27760fca6ea1SDimitry Andric struct AllocaTrackerRAII { 27770fca6ea1SDimitry Andric AllocaTrackerRAII(CodeGenFunction &CGF) 27780fca6ea1SDimitry Andric : CGF(CGF), OldTracker(CGF.Allocas) { 27790fca6ea1SDimitry Andric CGF.Allocas = &Tracker; 27800fca6ea1SDimitry Andric } 27810fca6ea1SDimitry Andric ~AllocaTrackerRAII() { CGF.Allocas = OldTracker; } 27820fca6ea1SDimitry Andric 27830fca6ea1SDimitry Andric llvm::SmallVector<llvm::AllocaInst *> Take() { return Tracker.Take(); } 27840fca6ea1SDimitry Andric 27850fca6ea1SDimitry Andric private: 27860fca6ea1SDimitry Andric CodeGenFunction &CGF; 27870fca6ea1SDimitry Andric AllocaTracker *OldTracker; 27880fca6ea1SDimitry Andric AllocaTracker Tracker; 27890fca6ea1SDimitry Andric }; 27900fca6ea1SDimitry Andric 27910b57cec5SDimitry Andric /// CreateTempAlloca - This creates an alloca and inserts it into the entry 27920b57cec5SDimitry Andric /// block if \p ArraySize is nullptr, otherwise inserts it at the current 27930b57cec5SDimitry Andric /// insertion point of the builder. The caller is responsible for setting an 27940b57cec5SDimitry Andric /// appropriate alignment on 27950b57cec5SDimitry Andric /// the alloca. 27960b57cec5SDimitry Andric /// 27970b57cec5SDimitry Andric /// \p ArraySize is the number of array elements to be allocated if it 27980b57cec5SDimitry Andric /// is not nullptr. 27990b57cec5SDimitry Andric /// 28000b57cec5SDimitry Andric /// LangAS::Default is the address space of pointers to local variables and 28010b57cec5SDimitry Andric /// temporaries, as exposed in the source language. In certain 28020b57cec5SDimitry Andric /// configurations, this is not the same as the alloca address space, and a 28030b57cec5SDimitry Andric /// cast is needed to lift the pointer from the alloca AS into 28040b57cec5SDimitry Andric /// LangAS::Default. This can happen when the target uses a restricted 28050b57cec5SDimitry Andric /// address space for the stack but the source language requires 28060b57cec5SDimitry Andric /// LangAS::Default to be a generic address space. The latter condition is 28070b57cec5SDimitry Andric /// common for most programming languages; OpenCL is an exception in that 28080b57cec5SDimitry Andric /// LangAS::Default is the private address space, which naturally maps 28090b57cec5SDimitry Andric /// to the stack. 28100b57cec5SDimitry Andric /// 28110b57cec5SDimitry Andric /// Because the address of a temporary is often exposed to the program in 28120b57cec5SDimitry Andric /// various ways, this function will perform the cast. The original alloca 28130b57cec5SDimitry Andric /// instruction is returned through \p Alloca if it is not nullptr. 28140b57cec5SDimitry Andric /// 28150b57cec5SDimitry Andric /// The cast is not performaed in CreateTempAllocaWithoutCast. This is 28160b57cec5SDimitry Andric /// more efficient if the caller knows that the address will not be exposed. 28170b57cec5SDimitry Andric llvm::AllocaInst *CreateTempAlloca(llvm::Type *Ty, const Twine &Name = "tmp", 28180b57cec5SDimitry Andric llvm::Value *ArraySize = nullptr); 28190fca6ea1SDimitry Andric RawAddress CreateTempAlloca(llvm::Type *Ty, CharUnits align, 28200b57cec5SDimitry Andric const Twine &Name = "tmp", 28210b57cec5SDimitry Andric llvm::Value *ArraySize = nullptr, 28220fca6ea1SDimitry Andric RawAddress *Alloca = nullptr); 28230fca6ea1SDimitry Andric RawAddress CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits align, 28240b57cec5SDimitry Andric const Twine &Name = "tmp", 28250b57cec5SDimitry Andric llvm::Value *ArraySize = nullptr); 28260b57cec5SDimitry Andric 28270b57cec5SDimitry Andric /// CreateDefaultAlignedTempAlloca - This creates an alloca with the 28280b57cec5SDimitry Andric /// default ABI alignment of the given LLVM type. 28290b57cec5SDimitry Andric /// 28300b57cec5SDimitry Andric /// IMPORTANT NOTE: This is *not* generally the right alignment for 28310b57cec5SDimitry Andric /// any given AST type that happens to have been lowered to the 28320b57cec5SDimitry Andric /// given IR type. This should only ever be used for function-local, 28330b57cec5SDimitry Andric /// IR-driven manipulations like saving and restoring a value. Do 28340b57cec5SDimitry Andric /// not hand this address off to arbitrary IRGen routines, and especially 28350b57cec5SDimitry Andric /// do not pass it as an argument to a function that might expect a 28360b57cec5SDimitry Andric /// properly ABI-aligned value. 28370fca6ea1SDimitry Andric RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, 28380b57cec5SDimitry Andric const Twine &Name = "tmp"); 28390b57cec5SDimitry Andric 28400b57cec5SDimitry Andric /// CreateIRTemp - Create a temporary IR object of the given type, with 28410b57cec5SDimitry Andric /// appropriate alignment. This routine should only be used when an temporary 28420b57cec5SDimitry Andric /// value needs to be stored into an alloca (for example, to avoid explicit 28430b57cec5SDimitry Andric /// PHI construction), but the type is the IR type, not the type appropriate 28440b57cec5SDimitry Andric /// for storing in memory. 28450b57cec5SDimitry Andric /// 28460b57cec5SDimitry Andric /// That is, this is exactly equivalent to CreateMemTemp, but calling 28470b57cec5SDimitry Andric /// ConvertType instead of ConvertTypeForMem. 28480fca6ea1SDimitry Andric RawAddress CreateIRTemp(QualType T, const Twine &Name = "tmp"); 28490b57cec5SDimitry Andric 28500b57cec5SDimitry Andric /// CreateMemTemp - Create a temporary memory object of the given type, with 28510b57cec5SDimitry Andric /// appropriate alignmen and cast it to the default address space. Returns 28520b57cec5SDimitry Andric /// the original alloca instruction by \p Alloca if it is not nullptr. 28530fca6ea1SDimitry Andric RawAddress CreateMemTemp(QualType T, const Twine &Name = "tmp", 28540fca6ea1SDimitry Andric RawAddress *Alloca = nullptr); 28550fca6ea1SDimitry Andric RawAddress CreateMemTemp(QualType T, CharUnits Align, 28560fca6ea1SDimitry Andric const Twine &Name = "tmp", 28570fca6ea1SDimitry Andric RawAddress *Alloca = nullptr); 28580b57cec5SDimitry Andric 28590b57cec5SDimitry Andric /// CreateMemTemp - Create a temporary memory object of the given type, with 28600b57cec5SDimitry Andric /// appropriate alignmen without casting it to the default address space. 28610fca6ea1SDimitry Andric RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name = "tmp"); 28620fca6ea1SDimitry Andric RawAddress CreateMemTempWithoutCast(QualType T, CharUnits Align, 28630b57cec5SDimitry Andric const Twine &Name = "tmp"); 28640b57cec5SDimitry Andric 28650b57cec5SDimitry Andric /// CreateAggTemp - Create a temporary memory object for the given 28660b57cec5SDimitry Andric /// aggregate type. 28675ffd83dbSDimitry Andric AggValueSlot CreateAggTemp(QualType T, const Twine &Name = "tmp", 28680fca6ea1SDimitry Andric RawAddress *Alloca = nullptr) { 28690fca6ea1SDimitry Andric return AggValueSlot::forAddr( 28700fca6ea1SDimitry Andric CreateMemTemp(T, Name, Alloca), T.getQualifiers(), 28710fca6ea1SDimitry Andric AggValueSlot::IsNotDestructed, AggValueSlot::DoesNotNeedGCBarriers, 28720fca6ea1SDimitry Andric AggValueSlot::IsNotAliased, AggValueSlot::DoesNotOverlap); 28730b57cec5SDimitry Andric } 28740b57cec5SDimitry Andric 28750b57cec5SDimitry Andric /// EvaluateExprAsBool - Perform the usual unary conversions on the specified 28760b57cec5SDimitry Andric /// expression and compare the result against zero, returning an Int1Ty value. 28770b57cec5SDimitry Andric llvm::Value *EvaluateExprAsBool(const Expr *E); 28780b57cec5SDimitry Andric 28790fca6ea1SDimitry Andric /// Retrieve the implicit cast expression of the rhs in a binary operator 28800fca6ea1SDimitry Andric /// expression by passing pointers to Value and QualType 28810fca6ea1SDimitry Andric /// This is used for implicit bitfield conversion checks, which 28820fca6ea1SDimitry Andric /// must compare with the value before potential truncation. 28830fca6ea1SDimitry Andric llvm::Value *EmitWithOriginalRHSBitfieldAssignment(const BinaryOperator *E, 28840fca6ea1SDimitry Andric llvm::Value **Previous, 28850fca6ea1SDimitry Andric QualType *SrcType); 28860fca6ea1SDimitry Andric 28870fca6ea1SDimitry Andric /// Emit a check that an [implicit] conversion of a bitfield. It is not UB, 28880fca6ea1SDimitry Andric /// so we use the value after conversion. 28890fca6ea1SDimitry Andric void EmitBitfieldConversionCheck(llvm::Value *Src, QualType SrcType, 28900fca6ea1SDimitry Andric llvm::Value *Dst, QualType DstType, 28910fca6ea1SDimitry Andric const CGBitFieldInfo &Info, 28920fca6ea1SDimitry Andric SourceLocation Loc); 28930fca6ea1SDimitry Andric 28940b57cec5SDimitry Andric /// EmitIgnoredExpr - Emit an expression in a context which ignores the result. 28950b57cec5SDimitry Andric void EmitIgnoredExpr(const Expr *E); 28960b57cec5SDimitry Andric 28970b57cec5SDimitry Andric /// EmitAnyExpr - Emit code to compute the specified expression which can have 28980b57cec5SDimitry Andric /// any type. The result is returned as an RValue struct. If this is an 28990b57cec5SDimitry Andric /// aggregate expression, the aggloc/agglocvolatile arguments indicate where 29000b57cec5SDimitry Andric /// the result should be returned. 29010b57cec5SDimitry Andric /// 29020b57cec5SDimitry Andric /// \param ignoreResult True if the resulting value isn't used. 29030b57cec5SDimitry Andric RValue EmitAnyExpr(const Expr *E, 29040b57cec5SDimitry Andric AggValueSlot aggSlot = AggValueSlot::ignored(), 29050b57cec5SDimitry Andric bool ignoreResult = false); 29060b57cec5SDimitry Andric 29070b57cec5SDimitry Andric // EmitVAListRef - Emit a "reference" to a va_list; this is either the address 29080b57cec5SDimitry Andric // or the value of the expression, depending on how va_list is defined. 29090b57cec5SDimitry Andric Address EmitVAListRef(const Expr *E); 29100b57cec5SDimitry Andric 29110b57cec5SDimitry Andric /// Emit a "reference" to a __builtin_ms_va_list; this is 29120b57cec5SDimitry Andric /// always the value of the expression, because a __builtin_ms_va_list is a 29130b57cec5SDimitry Andric /// pointer to a char. 29140b57cec5SDimitry Andric Address EmitMSVAListRef(const Expr *E); 29150b57cec5SDimitry Andric 29160b57cec5SDimitry Andric /// EmitAnyExprToTemp - Similarly to EmitAnyExpr(), however, the result will 29170b57cec5SDimitry Andric /// always be accessible even if no aggregate location is provided. 29180b57cec5SDimitry Andric RValue EmitAnyExprToTemp(const Expr *E); 29190b57cec5SDimitry Andric 29200b57cec5SDimitry Andric /// EmitAnyExprToMem - Emits the code necessary to evaluate an 29210b57cec5SDimitry Andric /// arbitrary expression into the given memory location. 29220b57cec5SDimitry Andric void EmitAnyExprToMem(const Expr *E, Address Location, 29230b57cec5SDimitry Andric Qualifiers Quals, bool IsInitializer); 29240b57cec5SDimitry Andric 29250b57cec5SDimitry Andric void EmitAnyExprToExn(const Expr *E, Address Addr); 29260b57cec5SDimitry Andric 29270b57cec5SDimitry Andric /// EmitExprAsInit - Emits the code necessary to initialize a 29280b57cec5SDimitry Andric /// location in memory with the given initializer. 29290b57cec5SDimitry Andric void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, 29300b57cec5SDimitry Andric bool capturedByInit); 29310b57cec5SDimitry Andric 29320b57cec5SDimitry Andric /// hasVolatileMember - returns true if aggregate type has a volatile 29330b57cec5SDimitry Andric /// member. 29340b57cec5SDimitry Andric bool hasVolatileMember(QualType T) { 29350b57cec5SDimitry Andric if (const RecordType *RT = T->getAs<RecordType>()) { 29360b57cec5SDimitry Andric const RecordDecl *RD = cast<RecordDecl>(RT->getDecl()); 29370b57cec5SDimitry Andric return RD->hasVolatileMember(); 29380b57cec5SDimitry Andric } 29390b57cec5SDimitry Andric return false; 29400b57cec5SDimitry Andric } 29410b57cec5SDimitry Andric 29420b57cec5SDimitry Andric /// Determine whether a return value slot may overlap some other object. 29430b57cec5SDimitry Andric AggValueSlot::Overlap_t getOverlapForReturnValue() { 29440b57cec5SDimitry Andric // FIXME: Assuming no overlap here breaks guaranteed copy elision for base 29450b57cec5SDimitry Andric // class subobjects. These cases may need to be revisited depending on the 29460b57cec5SDimitry Andric // resolution of the relevant core issue. 29470b57cec5SDimitry Andric return AggValueSlot::DoesNotOverlap; 29480b57cec5SDimitry Andric } 29490b57cec5SDimitry Andric 29500b57cec5SDimitry Andric /// Determine whether a field initialization may overlap some other object. 29510b57cec5SDimitry Andric AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *FD); 29520b57cec5SDimitry Andric 29530b57cec5SDimitry Andric /// Determine whether a base class initialization may overlap some other 29540b57cec5SDimitry Andric /// object. 29550b57cec5SDimitry Andric AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *RD, 29560b57cec5SDimitry Andric const CXXRecordDecl *BaseRD, 29570b57cec5SDimitry Andric bool IsVirtual); 29580b57cec5SDimitry Andric 29590b57cec5SDimitry Andric /// Emit an aggregate assignment. 29600b57cec5SDimitry Andric void EmitAggregateAssign(LValue Dest, LValue Src, QualType EltTy) { 29610b57cec5SDimitry Andric bool IsVolatile = hasVolatileMember(EltTy); 29620b57cec5SDimitry Andric EmitAggregateCopy(Dest, Src, EltTy, AggValueSlot::MayOverlap, IsVolatile); 29630b57cec5SDimitry Andric } 29640b57cec5SDimitry Andric 29650b57cec5SDimitry Andric void EmitAggregateCopyCtor(LValue Dest, LValue Src, 29660b57cec5SDimitry Andric AggValueSlot::Overlap_t MayOverlap) { 29670b57cec5SDimitry Andric EmitAggregateCopy(Dest, Src, Src.getType(), MayOverlap); 29680b57cec5SDimitry Andric } 29690b57cec5SDimitry Andric 29700b57cec5SDimitry Andric /// EmitAggregateCopy - Emit an aggregate copy. 29710b57cec5SDimitry Andric /// 29720b57cec5SDimitry Andric /// \param isVolatile \c true iff either the source or the destination is 29730b57cec5SDimitry Andric /// volatile. 29740b57cec5SDimitry Andric /// \param MayOverlap Whether the tail padding of the destination might be 29750b57cec5SDimitry Andric /// occupied by some other object. More efficient code can often be 29760b57cec5SDimitry Andric /// generated if not. 29770b57cec5SDimitry Andric void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, 29780b57cec5SDimitry Andric AggValueSlot::Overlap_t MayOverlap, 29790b57cec5SDimitry Andric bool isVolatile = false); 29800b57cec5SDimitry Andric 29810b57cec5SDimitry Andric /// GetAddrOfLocalVar - Return the address of a local variable. 29820b57cec5SDimitry Andric Address GetAddrOfLocalVar(const VarDecl *VD) { 29830b57cec5SDimitry Andric auto it = LocalDeclMap.find(VD); 29840b57cec5SDimitry Andric assert(it != LocalDeclMap.end() && 29850b57cec5SDimitry Andric "Invalid argument to GetAddrOfLocalVar(), no decl!"); 29860b57cec5SDimitry Andric return it->second; 29870b57cec5SDimitry Andric } 29880b57cec5SDimitry Andric 29890b57cec5SDimitry Andric /// Given an opaque value expression, return its LValue mapping if it exists, 29900b57cec5SDimitry Andric /// otherwise create one. 29910b57cec5SDimitry Andric LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e); 29920b57cec5SDimitry Andric 29930b57cec5SDimitry Andric /// Given an opaque value expression, return its RValue mapping if it exists, 29940b57cec5SDimitry Andric /// otherwise create one. 29950b57cec5SDimitry Andric RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e); 29960b57cec5SDimitry Andric 29970b57cec5SDimitry Andric /// Get the index of the current ArrayInitLoopExpr, if any. 29980b57cec5SDimitry Andric llvm::Value *getArrayInitIndex() { return ArrayInitIndex; } 29990b57cec5SDimitry Andric 30000b57cec5SDimitry Andric /// getAccessedFieldNo - Given an encoded value and a result number, return 30010b57cec5SDimitry Andric /// the input field number being accessed. 30020b57cec5SDimitry Andric static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts); 30030b57cec5SDimitry Andric 30040b57cec5SDimitry Andric llvm::BlockAddress *GetAddrOfLabel(const LabelDecl *L); 30050b57cec5SDimitry Andric llvm::BasicBlock *GetIndirectGotoBlock(); 30060b57cec5SDimitry Andric 30070b57cec5SDimitry Andric /// Check if \p E is a C++ "this" pointer wrapped in value-preserving casts. 30080b57cec5SDimitry Andric static bool IsWrappedCXXThis(const Expr *E); 30090b57cec5SDimitry Andric 30100b57cec5SDimitry Andric /// EmitNullInitialization - Generate code to set a value of the given type to 30110b57cec5SDimitry Andric /// null, If the type contains data member pointers, they will be initialized 30120b57cec5SDimitry Andric /// to -1 in accordance with the Itanium C++ ABI. 30130b57cec5SDimitry Andric void EmitNullInitialization(Address DestPtr, QualType Ty); 30140b57cec5SDimitry Andric 30150b57cec5SDimitry Andric /// Emits a call to an LLVM variable-argument intrinsic, either 30160b57cec5SDimitry Andric /// \c llvm.va_start or \c llvm.va_end. 30170b57cec5SDimitry Andric /// \param ArgValue A reference to the \c va_list as emitted by either 30180b57cec5SDimitry Andric /// \c EmitVAListRef or \c EmitMSVAListRef. 30190b57cec5SDimitry Andric /// \param IsStart If \c true, emits a call to \c llvm.va_start; otherwise, 30200b57cec5SDimitry Andric /// calls \c llvm.va_end. 30210b57cec5SDimitry Andric llvm::Value *EmitVAStartEnd(llvm::Value *ArgValue, bool IsStart); 30220b57cec5SDimitry Andric 30230b57cec5SDimitry Andric /// Generate code to get an argument from the passed in pointer 30240b57cec5SDimitry Andric /// and update it accordingly. 30250b57cec5SDimitry Andric /// \param VE The \c VAArgExpr for which to generate code. 30260b57cec5SDimitry Andric /// \param VAListAddr Receives a reference to the \c va_list as emitted by 30270b57cec5SDimitry Andric /// either \c EmitVAListRef or \c EmitMSVAListRef. 30280b57cec5SDimitry Andric /// \returns A pointer to the argument. 30290b57cec5SDimitry Andric // FIXME: We should be able to get rid of this method and use the va_arg 30300b57cec5SDimitry Andric // instruction in LLVM instead once it works well enough. 30310fca6ea1SDimitry Andric RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr, 30320fca6ea1SDimitry Andric AggValueSlot Slot = AggValueSlot::ignored()); 30330b57cec5SDimitry Andric 30340b57cec5SDimitry Andric /// emitArrayLength - Compute the length of an array, even if it's a 30350b57cec5SDimitry Andric /// VLA, and drill down to the base element type. 30360b57cec5SDimitry Andric llvm::Value *emitArrayLength(const ArrayType *arrayType, 30370b57cec5SDimitry Andric QualType &baseType, 30380b57cec5SDimitry Andric Address &addr); 30390b57cec5SDimitry Andric 30400b57cec5SDimitry Andric /// EmitVLASize - Capture all the sizes for the VLA expressions in 30410b57cec5SDimitry Andric /// the given variably-modified type and store them in the VLASizeMap. 30420b57cec5SDimitry Andric /// 30430b57cec5SDimitry Andric /// This function can be called with a null (unreachable) insert point. 30440b57cec5SDimitry Andric void EmitVariablyModifiedType(QualType Ty); 30450b57cec5SDimitry Andric 30460b57cec5SDimitry Andric struct VlaSizePair { 30470b57cec5SDimitry Andric llvm::Value *NumElts; 30480b57cec5SDimitry Andric QualType Type; 30490b57cec5SDimitry Andric 30500b57cec5SDimitry Andric VlaSizePair(llvm::Value *NE, QualType T) : NumElts(NE), Type(T) {} 30510b57cec5SDimitry Andric }; 30520b57cec5SDimitry Andric 30530b57cec5SDimitry Andric /// Return the number of elements for a single dimension 30540b57cec5SDimitry Andric /// for the given array type. 30550b57cec5SDimitry Andric VlaSizePair getVLAElements1D(const VariableArrayType *vla); 30560b57cec5SDimitry Andric VlaSizePair getVLAElements1D(QualType vla); 30570b57cec5SDimitry Andric 30580b57cec5SDimitry Andric /// Returns an LLVM value that corresponds to the size, 30590b57cec5SDimitry Andric /// in non-variably-sized elements, of a variable length array type, 30600b57cec5SDimitry Andric /// plus that largest non-variably-sized element type. Assumes that 30610b57cec5SDimitry Andric /// the type has already been emitted with EmitVariablyModifiedType. 30620b57cec5SDimitry Andric VlaSizePair getVLASize(const VariableArrayType *vla); 30630b57cec5SDimitry Andric VlaSizePair getVLASize(QualType vla); 30640b57cec5SDimitry Andric 30650b57cec5SDimitry Andric /// LoadCXXThis - Load the value of 'this'. This function is only valid while 30660b57cec5SDimitry Andric /// generating code for an C++ member function. 30670b57cec5SDimitry Andric llvm::Value *LoadCXXThis() { 30680b57cec5SDimitry Andric assert(CXXThisValue && "no 'this' value for this function"); 30690b57cec5SDimitry Andric return CXXThisValue; 30700b57cec5SDimitry Andric } 30710b57cec5SDimitry Andric Address LoadCXXThisAddress(); 30720b57cec5SDimitry Andric 30730b57cec5SDimitry Andric /// LoadCXXVTT - Load the VTT parameter to base constructors/destructors have 30740b57cec5SDimitry Andric /// virtual bases. 30750b57cec5SDimitry Andric // FIXME: Every place that calls LoadCXXVTT is something 30760b57cec5SDimitry Andric // that needs to be abstracted properly. 30770b57cec5SDimitry Andric llvm::Value *LoadCXXVTT() { 30780b57cec5SDimitry Andric assert(CXXStructorImplicitParamValue && "no VTT value for this function"); 30790b57cec5SDimitry Andric return CXXStructorImplicitParamValue; 30800b57cec5SDimitry Andric } 30810b57cec5SDimitry Andric 30820b57cec5SDimitry Andric /// GetAddressOfBaseOfCompleteClass - Convert the given pointer to a 30830b57cec5SDimitry Andric /// complete class to the given direct base. 30840b57cec5SDimitry Andric Address 30850b57cec5SDimitry Andric GetAddressOfDirectBaseInCompleteClass(Address Value, 30860b57cec5SDimitry Andric const CXXRecordDecl *Derived, 30870b57cec5SDimitry Andric const CXXRecordDecl *Base, 30880b57cec5SDimitry Andric bool BaseIsVirtual); 30890b57cec5SDimitry Andric 30900b57cec5SDimitry Andric static bool ShouldNullCheckClassCastValue(const CastExpr *Cast); 30910b57cec5SDimitry Andric 30920b57cec5SDimitry Andric /// GetAddressOfBaseClass - This function will add the necessary delta to the 30930b57cec5SDimitry Andric /// load of 'this' and returns address of the base class. 30940b57cec5SDimitry Andric Address GetAddressOfBaseClass(Address Value, 30950b57cec5SDimitry Andric const CXXRecordDecl *Derived, 30960b57cec5SDimitry Andric CastExpr::path_const_iterator PathBegin, 30970b57cec5SDimitry Andric CastExpr::path_const_iterator PathEnd, 30980b57cec5SDimitry Andric bool NullCheckValue, SourceLocation Loc); 30990b57cec5SDimitry Andric 31000b57cec5SDimitry Andric Address GetAddressOfDerivedClass(Address Value, 31010b57cec5SDimitry Andric const CXXRecordDecl *Derived, 31020b57cec5SDimitry Andric CastExpr::path_const_iterator PathBegin, 31030b57cec5SDimitry Andric CastExpr::path_const_iterator PathEnd, 31040b57cec5SDimitry Andric bool NullCheckValue); 31050b57cec5SDimitry Andric 31060b57cec5SDimitry Andric /// GetVTTParameter - Return the VTT parameter that should be passed to a 31070b57cec5SDimitry Andric /// base constructor/destructor with virtual bases. 31080b57cec5SDimitry Andric /// FIXME: VTTs are Itanium ABI-specific, so the definition should move 31090b57cec5SDimitry Andric /// to ItaniumCXXABI.cpp together with all the references to VTT. 31100b57cec5SDimitry Andric llvm::Value *GetVTTParameter(GlobalDecl GD, bool ForVirtualBase, 31110b57cec5SDimitry Andric bool Delegating); 31120b57cec5SDimitry Andric 31130b57cec5SDimitry Andric void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, 31140b57cec5SDimitry Andric CXXCtorType CtorType, 31150b57cec5SDimitry Andric const FunctionArgList &Args, 31160b57cec5SDimitry Andric SourceLocation Loc); 31170b57cec5SDimitry Andric // It's important not to confuse this and the previous function. Delegating 31180b57cec5SDimitry Andric // constructors are the C++0x feature. The constructor delegate optimization 31190b57cec5SDimitry Andric // is used to reduce duplication in the base and complete consturctors where 31200b57cec5SDimitry Andric // they are substantially the same. 31210b57cec5SDimitry Andric void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, 31220b57cec5SDimitry Andric const FunctionArgList &Args); 31230b57cec5SDimitry Andric 31240b57cec5SDimitry Andric /// Emit a call to an inheriting constructor (that is, one that invokes a 31250b57cec5SDimitry Andric /// constructor inherited from a base class) by inlining its definition. This 31260b57cec5SDimitry Andric /// is necessary if the ABI does not support forwarding the arguments to the 31270b57cec5SDimitry Andric /// base class constructor (because they're variadic or similar). 31280b57cec5SDimitry Andric void EmitInlinedInheritingCXXConstructorCall(const CXXConstructorDecl *Ctor, 31290b57cec5SDimitry Andric CXXCtorType CtorType, 31300b57cec5SDimitry Andric bool ForVirtualBase, 31310b57cec5SDimitry Andric bool Delegating, 31320b57cec5SDimitry Andric CallArgList &Args); 31330b57cec5SDimitry Andric 31340b57cec5SDimitry Andric /// Emit a call to a constructor inherited from a base class, passing the 31350b57cec5SDimitry Andric /// current constructor's arguments along unmodified (without even making 31360b57cec5SDimitry Andric /// a copy). 31370b57cec5SDimitry Andric void EmitInheritedCXXConstructorCall(const CXXConstructorDecl *D, 31380b57cec5SDimitry Andric bool ForVirtualBase, Address This, 31390b57cec5SDimitry Andric bool InheritedFromVBase, 31400b57cec5SDimitry Andric const CXXInheritedCtorInitExpr *E); 31410b57cec5SDimitry Andric 31420b57cec5SDimitry Andric void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, 31430b57cec5SDimitry Andric bool ForVirtualBase, bool Delegating, 31440b57cec5SDimitry Andric AggValueSlot ThisAVS, const CXXConstructExpr *E); 31450b57cec5SDimitry Andric 31460b57cec5SDimitry Andric void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, 31470b57cec5SDimitry Andric bool ForVirtualBase, bool Delegating, 31480b57cec5SDimitry Andric Address This, CallArgList &Args, 31490b57cec5SDimitry Andric AggValueSlot::Overlap_t Overlap, 31500b57cec5SDimitry Andric SourceLocation Loc, bool NewPointerIsChecked); 31510b57cec5SDimitry Andric 3152bdd1243dSDimitry Andric /// Emit assumption load for all bases. Requires to be called only on 31530b57cec5SDimitry Andric /// most-derived class and not under construction of the object. 31540b57cec5SDimitry Andric void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, Address This); 31550b57cec5SDimitry Andric 31560b57cec5SDimitry Andric /// Emit assumption that vptr load == global vtable. 31570b57cec5SDimitry Andric void EmitVTableAssumptionLoad(const VPtr &vptr, Address This); 31580b57cec5SDimitry Andric 31590b57cec5SDimitry Andric void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, 31600b57cec5SDimitry Andric Address This, Address Src, 31610b57cec5SDimitry Andric const CXXConstructExpr *E); 31620b57cec5SDimitry Andric 31630b57cec5SDimitry Andric void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, 31640b57cec5SDimitry Andric const ArrayType *ArrayTy, 31650b57cec5SDimitry Andric Address ArrayPtr, 31660b57cec5SDimitry Andric const CXXConstructExpr *E, 31670b57cec5SDimitry Andric bool NewPointerIsChecked, 31680b57cec5SDimitry Andric bool ZeroInitialization = false); 31690b57cec5SDimitry Andric 31700b57cec5SDimitry Andric void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, 31710b57cec5SDimitry Andric llvm::Value *NumElements, 31720b57cec5SDimitry Andric Address ArrayPtr, 31730b57cec5SDimitry Andric const CXXConstructExpr *E, 31740b57cec5SDimitry Andric bool NewPointerIsChecked, 31750b57cec5SDimitry Andric bool ZeroInitialization = false); 31760b57cec5SDimitry Andric 31770b57cec5SDimitry Andric static Destroyer destroyCXXObject; 31780b57cec5SDimitry Andric 31790b57cec5SDimitry Andric void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, 31800b57cec5SDimitry Andric bool ForVirtualBase, bool Delegating, Address This, 31810b57cec5SDimitry Andric QualType ThisTy); 31820b57cec5SDimitry Andric 31830b57cec5SDimitry Andric void EmitNewArrayInitializer(const CXXNewExpr *E, QualType elementType, 31840b57cec5SDimitry Andric llvm::Type *ElementTy, Address NewPtr, 31850b57cec5SDimitry Andric llvm::Value *NumElements, 31860b57cec5SDimitry Andric llvm::Value *AllocSizeWithoutCookie); 31870b57cec5SDimitry Andric 31880b57cec5SDimitry Andric void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType, 31890b57cec5SDimitry Andric Address Ptr); 31900b57cec5SDimitry Andric 3191fe6060f1SDimitry Andric void EmitSehCppScopeBegin(); 3192fe6060f1SDimitry Andric void EmitSehCppScopeEnd(); 3193fe6060f1SDimitry Andric void EmitSehTryScopeBegin(); 3194fe6060f1SDimitry Andric void EmitSehTryScopeEnd(); 3195fe6060f1SDimitry Andric 3196fe6060f1SDimitry Andric llvm::Value *EmitLifetimeStart(llvm::TypeSize Size, llvm::Value *Addr); 31970b57cec5SDimitry Andric void EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr); 31980b57cec5SDimitry Andric 31990b57cec5SDimitry Andric llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E); 32000b57cec5SDimitry Andric void EmitCXXDeleteExpr(const CXXDeleteExpr *E); 32010b57cec5SDimitry Andric 32020b57cec5SDimitry Andric void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, 32030b57cec5SDimitry Andric QualType DeleteTy, llvm::Value *NumElements = nullptr, 32040b57cec5SDimitry Andric CharUnits CookieSize = CharUnits()); 32050b57cec5SDimitry Andric 32060b57cec5SDimitry Andric RValue EmitBuiltinNewDeleteCall(const FunctionProtoType *Type, 32070b57cec5SDimitry Andric const CallExpr *TheCallExpr, bool IsDelete); 32080b57cec5SDimitry Andric 32090b57cec5SDimitry Andric llvm::Value *EmitCXXTypeidExpr(const CXXTypeidExpr *E); 32100b57cec5SDimitry Andric llvm::Value *EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE); 32110b57cec5SDimitry Andric Address EmitCXXUuidofExpr(const CXXUuidofExpr *E); 32120b57cec5SDimitry Andric 32130b57cec5SDimitry Andric /// Situations in which we might emit a check for the suitability of a 32145ffd83dbSDimitry Andric /// pointer or glvalue. Needs to be kept in sync with ubsan_handlers.cpp in 32155ffd83dbSDimitry Andric /// compiler-rt. 32160b57cec5SDimitry Andric enum TypeCheckKind { 32170b57cec5SDimitry Andric /// Checking the operand of a load. Must be suitably sized and aligned. 32180b57cec5SDimitry Andric TCK_Load, 32190b57cec5SDimitry Andric /// Checking the destination of a store. Must be suitably sized and aligned. 32200b57cec5SDimitry Andric TCK_Store, 32210b57cec5SDimitry Andric /// Checking the bound value in a reference binding. Must be suitably sized 32220b57cec5SDimitry Andric /// and aligned, but is not required to refer to an object (until the 32230b57cec5SDimitry Andric /// reference is used), per core issue 453. 32240b57cec5SDimitry Andric TCK_ReferenceBinding, 32250b57cec5SDimitry Andric /// Checking the object expression in a non-static data member access. Must 32260b57cec5SDimitry Andric /// be an object within its lifetime. 32270b57cec5SDimitry Andric TCK_MemberAccess, 32280b57cec5SDimitry Andric /// Checking the 'this' pointer for a call to a non-static member function. 32290b57cec5SDimitry Andric /// Must be an object within its lifetime. 32300b57cec5SDimitry Andric TCK_MemberCall, 32310b57cec5SDimitry Andric /// Checking the 'this' pointer for a constructor call. 32320b57cec5SDimitry Andric TCK_ConstructorCall, 32330b57cec5SDimitry Andric /// Checking the operand of a static_cast to a derived pointer type. Must be 32340b57cec5SDimitry Andric /// null or an object within its lifetime. 32350b57cec5SDimitry Andric TCK_DowncastPointer, 32360b57cec5SDimitry Andric /// Checking the operand of a static_cast to a derived reference type. Must 32370b57cec5SDimitry Andric /// be an object within its lifetime. 32380b57cec5SDimitry Andric TCK_DowncastReference, 32390b57cec5SDimitry Andric /// Checking the operand of a cast to a base object. Must be suitably sized 32400b57cec5SDimitry Andric /// and aligned. 32410b57cec5SDimitry Andric TCK_Upcast, 32420b57cec5SDimitry Andric /// Checking the operand of a cast to a virtual base object. Must be an 32430b57cec5SDimitry Andric /// object within its lifetime. 32440b57cec5SDimitry Andric TCK_UpcastToVirtualBase, 32450b57cec5SDimitry Andric /// Checking the value assigned to a _Nonnull pointer. Must not be null. 32460b57cec5SDimitry Andric TCK_NonnullAssign, 32470b57cec5SDimitry Andric /// Checking the operand of a dynamic_cast or a typeid expression. Must be 32480b57cec5SDimitry Andric /// null or an object within its lifetime. 32490b57cec5SDimitry Andric TCK_DynamicOperation 32500b57cec5SDimitry Andric }; 32510b57cec5SDimitry Andric 32520b57cec5SDimitry Andric /// Determine whether the pointer type check \p TCK permits null pointers. 32530b57cec5SDimitry Andric static bool isNullPointerAllowed(TypeCheckKind TCK); 32540b57cec5SDimitry Andric 32550b57cec5SDimitry Andric /// Determine whether the pointer type check \p TCK requires a vptr check. 32560b57cec5SDimitry Andric static bool isVptrCheckRequired(TypeCheckKind TCK, QualType Ty); 32570b57cec5SDimitry Andric 32580b57cec5SDimitry Andric /// Whether any type-checking sanitizers are enabled. If \c false, 32590b57cec5SDimitry Andric /// calls to EmitTypeCheck can be skipped. 32600b57cec5SDimitry Andric bool sanitizePerformTypeCheck() const; 32610b57cec5SDimitry Andric 32620fca6ea1SDimitry Andric void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, 32630fca6ea1SDimitry Andric QualType Type, SanitizerSet SkippedChecks = SanitizerSet(), 32640fca6ea1SDimitry Andric llvm::Value *ArraySize = nullptr) { 32650fca6ea1SDimitry Andric if (!sanitizePerformTypeCheck()) 32660fca6ea1SDimitry Andric return; 32670fca6ea1SDimitry Andric EmitTypeCheck(TCK, Loc, LV.emitRawPointer(*this), Type, LV.getAlignment(), 32680fca6ea1SDimitry Andric SkippedChecks, ArraySize); 32690fca6ea1SDimitry Andric } 32700fca6ea1SDimitry Andric 32710fca6ea1SDimitry Andric void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, Address Addr, 32720fca6ea1SDimitry Andric QualType Type, CharUnits Alignment = CharUnits::Zero(), 32730fca6ea1SDimitry Andric SanitizerSet SkippedChecks = SanitizerSet(), 32740fca6ea1SDimitry Andric llvm::Value *ArraySize = nullptr) { 32750fca6ea1SDimitry Andric if (!sanitizePerformTypeCheck()) 32760fca6ea1SDimitry Andric return; 32770fca6ea1SDimitry Andric EmitTypeCheck(TCK, Loc, Addr.emitRawPointer(*this), Type, Alignment, 32780fca6ea1SDimitry Andric SkippedChecks, ArraySize); 32790fca6ea1SDimitry Andric } 32800fca6ea1SDimitry Andric 32810b57cec5SDimitry Andric /// Emit a check that \p V is the address of storage of the 32820b57cec5SDimitry Andric /// appropriate size and alignment for an object of type \p Type 32830b57cec5SDimitry Andric /// (or if ArraySize is provided, for an array of that bound). 32840b57cec5SDimitry Andric void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V, 32850b57cec5SDimitry Andric QualType Type, CharUnits Alignment = CharUnits::Zero(), 32860b57cec5SDimitry Andric SanitizerSet SkippedChecks = SanitizerSet(), 32870b57cec5SDimitry Andric llvm::Value *ArraySize = nullptr); 32880b57cec5SDimitry Andric 32890b57cec5SDimitry Andric /// Emit a check that \p Base points into an array object, which 32900b57cec5SDimitry Andric /// we can access at index \p Index. \p Accessed should be \c false if we 32910b57cec5SDimitry Andric /// this expression is used as an lvalue, for instance in "&Arr[Idx]". 32920b57cec5SDimitry Andric void EmitBoundsCheck(const Expr *E, const Expr *Base, llvm::Value *Index, 32930b57cec5SDimitry Andric QualType IndexType, bool Accessed); 3294297eecfbSDimitry Andric void EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound, 3295297eecfbSDimitry Andric llvm::Value *Index, QualType IndexType, 3296297eecfbSDimitry Andric QualType IndexedType, bool Accessed); 3297297eecfbSDimitry Andric 32980fca6ea1SDimitry Andric // Find a struct's flexible array member and get its offset. It may be 32990fca6ea1SDimitry Andric // embedded inside multiple sub-structs, but must still be the last field. 33000fca6ea1SDimitry Andric const FieldDecl * 33010fca6ea1SDimitry Andric FindFlexibleArrayMemberFieldAndOffset(ASTContext &Ctx, const RecordDecl *RD, 33020fca6ea1SDimitry Andric const FieldDecl *FAMDecl, 3303297eecfbSDimitry Andric uint64_t &Offset); 3304297eecfbSDimitry Andric 3305297eecfbSDimitry Andric /// Find the FieldDecl specified in a FAM's "counted_by" attribute. Returns 3306297eecfbSDimitry Andric /// \p nullptr if either the attribute or the field doesn't exist. 3307297eecfbSDimitry Andric const FieldDecl *FindCountedByField(const FieldDecl *FD); 3308297eecfbSDimitry Andric 3309297eecfbSDimitry Andric /// Build an expression accessing the "counted_by" field. 3310297eecfbSDimitry Andric llvm::Value *EmitCountedByFieldExpr(const Expr *Base, 3311297eecfbSDimitry Andric const FieldDecl *FAMDecl, 3312297eecfbSDimitry Andric const FieldDecl *CountDecl); 33130b57cec5SDimitry Andric 33140b57cec5SDimitry Andric llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, 33150b57cec5SDimitry Andric bool isInc, bool isPre); 33160b57cec5SDimitry Andric ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV, 33170b57cec5SDimitry Andric bool isInc, bool isPre); 33180b57cec5SDimitry Andric 33190b57cec5SDimitry Andric /// Converts Location to a DebugLoc, if debug information is enabled. 33200b57cec5SDimitry Andric llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location); 33210b57cec5SDimitry Andric 33220b57cec5SDimitry Andric /// Get the record field index as represented in debug info. 33230b57cec5SDimitry Andric unsigned getDebugInfoFIndex(const RecordDecl *Rec, unsigned FieldIndex); 33240b57cec5SDimitry Andric 33250b57cec5SDimitry Andric 33260b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 33270b57cec5SDimitry Andric // Declaration Emission 33280b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 33290b57cec5SDimitry Andric 33300b57cec5SDimitry Andric /// EmitDecl - Emit a declaration. 33310b57cec5SDimitry Andric /// 33320b57cec5SDimitry Andric /// This function can be called with a null (unreachable) insert point. 33330b57cec5SDimitry Andric void EmitDecl(const Decl &D); 33340b57cec5SDimitry Andric 33350b57cec5SDimitry Andric /// EmitVarDecl - Emit a local variable declaration. 33360b57cec5SDimitry Andric /// 33370b57cec5SDimitry Andric /// This function can be called with a null (unreachable) insert point. 33380b57cec5SDimitry Andric void EmitVarDecl(const VarDecl &D); 33390b57cec5SDimitry Andric 33400b57cec5SDimitry Andric void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, 33410b57cec5SDimitry Andric bool capturedByInit); 33420b57cec5SDimitry Andric 33430b57cec5SDimitry Andric typedef void SpecialInitFn(CodeGenFunction &Init, const VarDecl &D, 33440b57cec5SDimitry Andric llvm::Value *Address); 33450b57cec5SDimitry Andric 33460b57cec5SDimitry Andric /// Determine whether the given initializer is trivial in the sense 33470b57cec5SDimitry Andric /// that it requires no code to be generated. 33480b57cec5SDimitry Andric bool isTrivialInitializer(const Expr *Init); 33490b57cec5SDimitry Andric 33500b57cec5SDimitry Andric /// EmitAutoVarDecl - Emit an auto variable declaration. 33510b57cec5SDimitry Andric /// 33520b57cec5SDimitry Andric /// This function can be called with a null (unreachable) insert point. 33530b57cec5SDimitry Andric void EmitAutoVarDecl(const VarDecl &D); 33540b57cec5SDimitry Andric 33550b57cec5SDimitry Andric class AutoVarEmission { 33560b57cec5SDimitry Andric friend class CodeGenFunction; 33570b57cec5SDimitry Andric 33580b57cec5SDimitry Andric const VarDecl *Variable; 33590b57cec5SDimitry Andric 33600b57cec5SDimitry Andric /// The address of the alloca for languages with explicit address space 33610b57cec5SDimitry Andric /// (e.g. OpenCL) or alloca casted to generic pointer for address space 33620b57cec5SDimitry Andric /// agnostic languages (e.g. C++). Invalid if the variable was emitted 33630b57cec5SDimitry Andric /// as a global constant. 33640b57cec5SDimitry Andric Address Addr; 33650b57cec5SDimitry Andric 33660b57cec5SDimitry Andric llvm::Value *NRVOFlag; 33670b57cec5SDimitry Andric 33680b57cec5SDimitry Andric /// True if the variable is a __block variable that is captured by an 33690b57cec5SDimitry Andric /// escaping block. 33700b57cec5SDimitry Andric bool IsEscapingByRef; 33710b57cec5SDimitry Andric 33720b57cec5SDimitry Andric /// True if the variable is of aggregate type and has a constant 33730b57cec5SDimitry Andric /// initializer. 33740b57cec5SDimitry Andric bool IsConstantAggregate; 33750b57cec5SDimitry Andric 33760b57cec5SDimitry Andric /// Non-null if we should use lifetime annotations. 33770b57cec5SDimitry Andric llvm::Value *SizeForLifetimeMarkers; 33780b57cec5SDimitry Andric 33790b57cec5SDimitry Andric /// Address with original alloca instruction. Invalid if the variable was 33800b57cec5SDimitry Andric /// emitted as a global constant. 33810fca6ea1SDimitry Andric RawAddress AllocaAddr; 33820b57cec5SDimitry Andric 33830b57cec5SDimitry Andric struct Invalid {}; 33840b57cec5SDimitry Andric AutoVarEmission(Invalid) 33850b57cec5SDimitry Andric : Variable(nullptr), Addr(Address::invalid()), 33860fca6ea1SDimitry Andric AllocaAddr(RawAddress::invalid()) {} 33870b57cec5SDimitry Andric 33880b57cec5SDimitry Andric AutoVarEmission(const VarDecl &variable) 33890b57cec5SDimitry Andric : Variable(&variable), Addr(Address::invalid()), NRVOFlag(nullptr), 33900b57cec5SDimitry Andric IsEscapingByRef(false), IsConstantAggregate(false), 33910fca6ea1SDimitry Andric SizeForLifetimeMarkers(nullptr), AllocaAddr(RawAddress::invalid()) {} 33920b57cec5SDimitry Andric 33930b57cec5SDimitry Andric bool wasEmittedAsGlobal() const { return !Addr.isValid(); } 33940b57cec5SDimitry Andric 33950b57cec5SDimitry Andric public: 33960b57cec5SDimitry Andric static AutoVarEmission invalid() { return AutoVarEmission(Invalid()); } 33970b57cec5SDimitry Andric 33980b57cec5SDimitry Andric bool useLifetimeMarkers() const { 33990b57cec5SDimitry Andric return SizeForLifetimeMarkers != nullptr; 34000b57cec5SDimitry Andric } 34010b57cec5SDimitry Andric llvm::Value *getSizeForLifetimeMarkers() const { 34020b57cec5SDimitry Andric assert(useLifetimeMarkers()); 34030b57cec5SDimitry Andric return SizeForLifetimeMarkers; 34040b57cec5SDimitry Andric } 34050b57cec5SDimitry Andric 34060b57cec5SDimitry Andric /// Returns the raw, allocated address, which is not necessarily 34070b57cec5SDimitry Andric /// the address of the object itself. It is casted to default 34080b57cec5SDimitry Andric /// address space for address space agnostic languages. 34090b57cec5SDimitry Andric Address getAllocatedAddress() const { 34100b57cec5SDimitry Andric return Addr; 34110b57cec5SDimitry Andric } 34120b57cec5SDimitry Andric 34130b57cec5SDimitry Andric /// Returns the address for the original alloca instruction. 34140fca6ea1SDimitry Andric RawAddress getOriginalAllocatedAddress() const { return AllocaAddr; } 34150b57cec5SDimitry Andric 34160b57cec5SDimitry Andric /// Returns the address of the object within this declaration. 34170b57cec5SDimitry Andric /// Note that this does not chase the forwarding pointer for 34180b57cec5SDimitry Andric /// __block decls. 34190b57cec5SDimitry Andric Address getObjectAddress(CodeGenFunction &CGF) const { 34200b57cec5SDimitry Andric if (!IsEscapingByRef) return Addr; 34210b57cec5SDimitry Andric 34220b57cec5SDimitry Andric return CGF.emitBlockByrefAddress(Addr, Variable, /*forward*/ false); 34230b57cec5SDimitry Andric } 34240b57cec5SDimitry Andric }; 34250b57cec5SDimitry Andric AutoVarEmission EmitAutoVarAlloca(const VarDecl &var); 34260b57cec5SDimitry Andric void EmitAutoVarInit(const AutoVarEmission &emission); 34270b57cec5SDimitry Andric void EmitAutoVarCleanups(const AutoVarEmission &emission); 34280b57cec5SDimitry Andric void emitAutoVarTypeCleanup(const AutoVarEmission &emission, 34290b57cec5SDimitry Andric QualType::DestructionKind dtorKind); 34300b57cec5SDimitry Andric 34310b57cec5SDimitry Andric /// Emits the alloca and debug information for the size expressions for each 34320b57cec5SDimitry Andric /// dimension of an array. It registers the association of its (1-dimensional) 34330b57cec5SDimitry Andric /// QualTypes and size expression's debug node, so that CGDebugInfo can 34340b57cec5SDimitry Andric /// reference this node when creating the DISubrange object to describe the 34350b57cec5SDimitry Andric /// array types. 34360b57cec5SDimitry Andric void EmitAndRegisterVariableArrayDimensions(CGDebugInfo *DI, 34370b57cec5SDimitry Andric const VarDecl &D, 34380b57cec5SDimitry Andric bool EmitDebugInfo); 34390b57cec5SDimitry Andric 34400b57cec5SDimitry Andric void EmitStaticVarDecl(const VarDecl &D, 34410b57cec5SDimitry Andric llvm::GlobalValue::LinkageTypes Linkage); 34420b57cec5SDimitry Andric 34430b57cec5SDimitry Andric class ParamValue { 34440fca6ea1SDimitry Andric union { 34450fca6ea1SDimitry Andric Address Addr; 34460b57cec5SDimitry Andric llvm::Value *Value; 34470fca6ea1SDimitry Andric }; 34480fca6ea1SDimitry Andric 34490fca6ea1SDimitry Andric bool IsIndirect; 34500fca6ea1SDimitry Andric 34510fca6ea1SDimitry Andric ParamValue(llvm::Value *V) : Value(V), IsIndirect(false) {} 34520fca6ea1SDimitry Andric ParamValue(Address A) : Addr(A), IsIndirect(true) {} 34530fca6ea1SDimitry Andric 34540b57cec5SDimitry Andric public: 34550b57cec5SDimitry Andric static ParamValue forDirect(llvm::Value *value) { 34560fca6ea1SDimitry Andric return ParamValue(value); 34570b57cec5SDimitry Andric } 34580b57cec5SDimitry Andric static ParamValue forIndirect(Address addr) { 34590b57cec5SDimitry Andric assert(!addr.getAlignment().isZero()); 34600fca6ea1SDimitry Andric return ParamValue(addr); 34610b57cec5SDimitry Andric } 34620b57cec5SDimitry Andric 34630fca6ea1SDimitry Andric bool isIndirect() const { return IsIndirect; } 34640fca6ea1SDimitry Andric llvm::Value *getAnyValue() const { 34650fca6ea1SDimitry Andric if (!isIndirect()) 34660fca6ea1SDimitry Andric return Value; 34670fca6ea1SDimitry Andric assert(!Addr.hasOffset() && "unexpected offset"); 34680fca6ea1SDimitry Andric return Addr.getBasePointer(); 34690fca6ea1SDimitry Andric } 34700b57cec5SDimitry Andric 34710b57cec5SDimitry Andric llvm::Value *getDirectValue() const { 34720b57cec5SDimitry Andric assert(!isIndirect()); 34730b57cec5SDimitry Andric return Value; 34740b57cec5SDimitry Andric } 34750b57cec5SDimitry Andric 34760b57cec5SDimitry Andric Address getIndirectAddress() const { 34770b57cec5SDimitry Andric assert(isIndirect()); 34780fca6ea1SDimitry Andric return Addr; 34790b57cec5SDimitry Andric } 34800b57cec5SDimitry Andric }; 34810b57cec5SDimitry Andric 34820b57cec5SDimitry Andric /// EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl. 34830b57cec5SDimitry Andric void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo); 34840b57cec5SDimitry Andric 34850b57cec5SDimitry Andric /// protectFromPeepholes - Protect a value that we're intending to 34860b57cec5SDimitry Andric /// store to the side, but which will probably be used later, from 34870b57cec5SDimitry Andric /// aggressive peepholing optimizations that might delete it. 34880b57cec5SDimitry Andric /// 34890b57cec5SDimitry Andric /// Pass the result to unprotectFromPeepholes to declare that 34900b57cec5SDimitry Andric /// protection is no longer required. 34910b57cec5SDimitry Andric /// 34920b57cec5SDimitry Andric /// There's no particular reason why this shouldn't apply to 34930b57cec5SDimitry Andric /// l-values, it's just that no existing peepholes work on pointers. 34940b57cec5SDimitry Andric PeepholeProtection protectFromPeepholes(RValue rvalue); 34950b57cec5SDimitry Andric void unprotectFromPeepholes(PeepholeProtection protection); 34960b57cec5SDimitry Andric 34975ffd83dbSDimitry Andric void emitAlignmentAssumptionCheck(llvm::Value *Ptr, QualType Ty, 34980b57cec5SDimitry Andric SourceLocation Loc, 34990b57cec5SDimitry Andric SourceLocation AssumptionLoc, 35000b57cec5SDimitry Andric llvm::Value *Alignment, 35010b57cec5SDimitry Andric llvm::Value *OffsetValue, 35020b57cec5SDimitry Andric llvm::Value *TheCheck, 35030b57cec5SDimitry Andric llvm::Instruction *Assumption); 35040b57cec5SDimitry Andric 35055ffd83dbSDimitry Andric void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, 35060b57cec5SDimitry Andric SourceLocation Loc, SourceLocation AssumptionLoc, 35070b57cec5SDimitry Andric llvm::Value *Alignment, 35080b57cec5SDimitry Andric llvm::Value *OffsetValue = nullptr); 35090b57cec5SDimitry Andric 35105ffd83dbSDimitry Andric void emitAlignmentAssumption(llvm::Value *PtrValue, const Expr *E, 35115ffd83dbSDimitry Andric SourceLocation AssumptionLoc, 35125ffd83dbSDimitry Andric llvm::Value *Alignment, 35130b57cec5SDimitry Andric llvm::Value *OffsetValue = nullptr); 35140b57cec5SDimitry Andric 35150b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 35160b57cec5SDimitry Andric // Statement Emission 35170b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 35180b57cec5SDimitry Andric 35190b57cec5SDimitry Andric /// EmitStopPoint - Emit a debug stoppoint if we are emitting debug info. 35200b57cec5SDimitry Andric void EmitStopPoint(const Stmt *S); 35210b57cec5SDimitry Andric 35220b57cec5SDimitry Andric /// EmitStmt - Emit the code for the statement \arg S. It is legal to call 35230b57cec5SDimitry Andric /// this function even if there is no current insertion point. 35240b57cec5SDimitry Andric /// 35250b57cec5SDimitry Andric /// This function may clear the current insertion point; callers should use 35260b57cec5SDimitry Andric /// EnsureInsertPoint if they wish to subsequently generate code without first 35270b57cec5SDimitry Andric /// calling EmitBlock, EmitBranch, or EmitStmt. 3528bdd1243dSDimitry Andric void EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs = std::nullopt); 35290b57cec5SDimitry Andric 35300b57cec5SDimitry Andric /// EmitSimpleStmt - Try to emit a "simple" statement which does not 35310b57cec5SDimitry Andric /// necessarily require an insertion point or debug information; typically 35320b57cec5SDimitry Andric /// because the statement amounts to a jump or a container of other 35330b57cec5SDimitry Andric /// statements. 35340b57cec5SDimitry Andric /// 35350b57cec5SDimitry Andric /// \return True if the statement was handled. 3536e8d8bef9SDimitry Andric bool EmitSimpleStmt(const Stmt *S, ArrayRef<const Attr *> Attrs); 35370b57cec5SDimitry Andric 35380b57cec5SDimitry Andric Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false, 35390b57cec5SDimitry Andric AggValueSlot AVS = AggValueSlot::ignored()); 35400b57cec5SDimitry Andric Address EmitCompoundStmtWithoutScope(const CompoundStmt &S, 35410b57cec5SDimitry Andric bool GetLast = false, 35420b57cec5SDimitry Andric AggValueSlot AVS = 35430b57cec5SDimitry Andric AggValueSlot::ignored()); 35440b57cec5SDimitry Andric 35450b57cec5SDimitry Andric /// EmitLabel - Emit the block for the given label. It is legal to call this 35460b57cec5SDimitry Andric /// function even if there is no current insertion point. 35470b57cec5SDimitry Andric void EmitLabel(const LabelDecl *D); // helper for EmitLabelStmt. 35480b57cec5SDimitry Andric 35490b57cec5SDimitry Andric void EmitLabelStmt(const LabelStmt &S); 35500b57cec5SDimitry Andric void EmitAttributedStmt(const AttributedStmt &S); 35510b57cec5SDimitry Andric void EmitGotoStmt(const GotoStmt &S); 35520b57cec5SDimitry Andric void EmitIndirectGotoStmt(const IndirectGotoStmt &S); 35530b57cec5SDimitry Andric void EmitIfStmt(const IfStmt &S); 35540b57cec5SDimitry Andric 35550b57cec5SDimitry Andric void EmitWhileStmt(const WhileStmt &S, 3556bdd1243dSDimitry Andric ArrayRef<const Attr *> Attrs = std::nullopt); 3557bdd1243dSDimitry Andric void EmitDoStmt(const DoStmt &S, ArrayRef<const Attr *> Attrs = std::nullopt); 35580b57cec5SDimitry Andric void EmitForStmt(const ForStmt &S, 3559bdd1243dSDimitry Andric ArrayRef<const Attr *> Attrs = std::nullopt); 35600b57cec5SDimitry Andric void EmitReturnStmt(const ReturnStmt &S); 35610b57cec5SDimitry Andric void EmitDeclStmt(const DeclStmt &S); 35620b57cec5SDimitry Andric void EmitBreakStmt(const BreakStmt &S); 35630b57cec5SDimitry Andric void EmitContinueStmt(const ContinueStmt &S); 35640b57cec5SDimitry Andric void EmitSwitchStmt(const SwitchStmt &S); 3565e8d8bef9SDimitry Andric void EmitDefaultStmt(const DefaultStmt &S, ArrayRef<const Attr *> Attrs); 3566e8d8bef9SDimitry Andric void EmitCaseStmt(const CaseStmt &S, ArrayRef<const Attr *> Attrs); 3567e8d8bef9SDimitry Andric void EmitCaseStmtRange(const CaseStmt &S, ArrayRef<const Attr *> Attrs); 35680b57cec5SDimitry Andric void EmitAsmStmt(const AsmStmt &S); 35690b57cec5SDimitry Andric 35700b57cec5SDimitry Andric void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S); 35710b57cec5SDimitry Andric void EmitObjCAtTryStmt(const ObjCAtTryStmt &S); 35720b57cec5SDimitry Andric void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S); 35730b57cec5SDimitry Andric void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S); 35740b57cec5SDimitry Andric void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S); 35750b57cec5SDimitry Andric 35760b57cec5SDimitry Andric void EmitCoroutineBody(const CoroutineBodyStmt &S); 35770b57cec5SDimitry Andric void EmitCoreturnStmt(const CoreturnStmt &S); 35780b57cec5SDimitry Andric RValue EmitCoawaitExpr(const CoawaitExpr &E, 35790b57cec5SDimitry Andric AggValueSlot aggSlot = AggValueSlot::ignored(), 35800b57cec5SDimitry Andric bool ignoreResult = false); 35810b57cec5SDimitry Andric LValue EmitCoawaitLValue(const CoawaitExpr *E); 35820b57cec5SDimitry Andric RValue EmitCoyieldExpr(const CoyieldExpr &E, 35830b57cec5SDimitry Andric AggValueSlot aggSlot = AggValueSlot::ignored(), 35840b57cec5SDimitry Andric bool ignoreResult = false); 35850b57cec5SDimitry Andric LValue EmitCoyieldLValue(const CoyieldExpr *E); 35860b57cec5SDimitry Andric RValue EmitCoroutineIntrinsic(const CallExpr *E, unsigned int IID); 35870b57cec5SDimitry Andric 35880b57cec5SDimitry Andric void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false); 35890b57cec5SDimitry Andric void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false); 35900b57cec5SDimitry Andric 35910b57cec5SDimitry Andric void EmitCXXTryStmt(const CXXTryStmt &S); 35920b57cec5SDimitry Andric void EmitSEHTryStmt(const SEHTryStmt &S); 35930b57cec5SDimitry Andric void EmitSEHLeaveStmt(const SEHLeaveStmt &S); 35940b57cec5SDimitry Andric void EnterSEHTryStmt(const SEHTryStmt &S); 35950b57cec5SDimitry Andric void ExitSEHTryStmt(const SEHTryStmt &S); 3596fe6060f1SDimitry Andric void VolatilizeTryBlocks(llvm::BasicBlock *BB, 3597fe6060f1SDimitry Andric llvm::SmallPtrSet<llvm::BasicBlock *, 10> &V); 35980b57cec5SDimitry Andric 35990b57cec5SDimitry Andric void pushSEHCleanup(CleanupKind kind, 36000b57cec5SDimitry Andric llvm::Function *FinallyFunc); 36010b57cec5SDimitry Andric void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter, 36020b57cec5SDimitry Andric const Stmt *OutlinedStmt); 36030b57cec5SDimitry Andric 36040b57cec5SDimitry Andric llvm::Function *GenerateSEHFilterFunction(CodeGenFunction &ParentCGF, 36050b57cec5SDimitry Andric const SEHExceptStmt &Except); 36060b57cec5SDimitry Andric 36070b57cec5SDimitry Andric llvm::Function *GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF, 36080b57cec5SDimitry Andric const SEHFinallyStmt &Finally); 36090b57cec5SDimitry Andric 36100b57cec5SDimitry Andric void EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF, 36110b57cec5SDimitry Andric llvm::Value *ParentFP, 36120b57cec5SDimitry Andric llvm::Value *EntryEBP); 36130b57cec5SDimitry Andric llvm::Value *EmitSEHExceptionCode(); 36140b57cec5SDimitry Andric llvm::Value *EmitSEHExceptionInfo(); 36150b57cec5SDimitry Andric llvm::Value *EmitSEHAbnormalTermination(); 36160b57cec5SDimitry Andric 36170b57cec5SDimitry Andric /// Emit simple code for OpenMP directives in Simd-only mode. 36180b57cec5SDimitry Andric void EmitSimpleOMPExecutableDirective(const OMPExecutableDirective &D); 36190b57cec5SDimitry Andric 36200b57cec5SDimitry Andric /// Scan the outlined statement for captures from the parent function. For 36210b57cec5SDimitry Andric /// each capture, mark the capture as escaped and emit a call to 36220b57cec5SDimitry Andric /// llvm.localrecover. Insert the localrecover result into the LocalDeclMap. 36230b57cec5SDimitry Andric void EmitCapturedLocals(CodeGenFunction &ParentCGF, const Stmt *OutlinedStmt, 36240b57cec5SDimitry Andric bool IsFilter); 36250b57cec5SDimitry Andric 36260b57cec5SDimitry Andric /// Recovers the address of a local in a parent function. ParentVar is the 36270b57cec5SDimitry Andric /// address of the variable used in the immediate parent function. It can 36280b57cec5SDimitry Andric /// either be an alloca or a call to llvm.localrecover if there are nested 36290b57cec5SDimitry Andric /// outlined functions. ParentFP is the frame pointer of the outermost parent 36300b57cec5SDimitry Andric /// frame. 36310b57cec5SDimitry Andric Address recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, 36320b57cec5SDimitry Andric Address ParentVar, 36330b57cec5SDimitry Andric llvm::Value *ParentFP); 36340b57cec5SDimitry Andric 36350b57cec5SDimitry Andric void EmitCXXForRangeStmt(const CXXForRangeStmt &S, 3636bdd1243dSDimitry Andric ArrayRef<const Attr *> Attrs = std::nullopt); 36370b57cec5SDimitry Andric 36380b57cec5SDimitry Andric /// Controls insertion of cancellation exit blocks in worksharing constructs. 36390b57cec5SDimitry Andric class OMPCancelStackRAII { 36400b57cec5SDimitry Andric CodeGenFunction &CGF; 36410b57cec5SDimitry Andric 36420b57cec5SDimitry Andric public: 36430b57cec5SDimitry Andric OMPCancelStackRAII(CodeGenFunction &CGF, OpenMPDirectiveKind Kind, 36440b57cec5SDimitry Andric bool HasCancel) 36450b57cec5SDimitry Andric : CGF(CGF) { 36460b57cec5SDimitry Andric CGF.OMPCancelStack.enter(CGF, Kind, HasCancel); 36470b57cec5SDimitry Andric } 36480b57cec5SDimitry Andric ~OMPCancelStackRAII() { CGF.OMPCancelStack.exit(CGF); } 36490b57cec5SDimitry Andric }; 36500b57cec5SDimitry Andric 36510b57cec5SDimitry Andric /// Returns calculated size of the specified type. 36520b57cec5SDimitry Andric llvm::Value *getTypeSize(QualType Ty); 36530b57cec5SDimitry Andric LValue InitCapturedStruct(const CapturedStmt &S); 36540b57cec5SDimitry Andric llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K); 36550b57cec5SDimitry Andric llvm::Function *GenerateCapturedStmtFunction(const CapturedStmt &S); 36560b57cec5SDimitry Andric Address GenerateCapturedStmtArgument(const CapturedStmt &S); 36575ffd83dbSDimitry Andric llvm::Function *GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S, 36585ffd83dbSDimitry Andric SourceLocation Loc); 36590b57cec5SDimitry Andric void GenerateOpenMPCapturedVars(const CapturedStmt &S, 36600b57cec5SDimitry Andric SmallVectorImpl<llvm::Value *> &CapturedVars); 36610b57cec5SDimitry Andric void emitOMPSimpleStore(LValue LVal, RValue RVal, QualType RValTy, 36620b57cec5SDimitry Andric SourceLocation Loc); 36630b57cec5SDimitry Andric /// Perform element by element copying of arrays with type \a 36640b57cec5SDimitry Andric /// OriginalType from \a SrcAddr to \a DestAddr using copying procedure 36650b57cec5SDimitry Andric /// generated by \a CopyGen. 36660b57cec5SDimitry Andric /// 36670b57cec5SDimitry Andric /// \param DestAddr Address of the destination array. 36680b57cec5SDimitry Andric /// \param SrcAddr Address of the source array. 36690b57cec5SDimitry Andric /// \param OriginalType Type of destination and source arrays. 36700b57cec5SDimitry Andric /// \param CopyGen Copying procedure that copies value of single array element 36710b57cec5SDimitry Andric /// to another single array element. 36720b57cec5SDimitry Andric void EmitOMPAggregateAssign( 36730b57cec5SDimitry Andric Address DestAddr, Address SrcAddr, QualType OriginalType, 36740b57cec5SDimitry Andric const llvm::function_ref<void(Address, Address)> CopyGen); 36750b57cec5SDimitry Andric /// Emit proper copying of data from one variable to another. 36760b57cec5SDimitry Andric /// 36770b57cec5SDimitry Andric /// \param OriginalType Original type of the copied variables. 36780b57cec5SDimitry Andric /// \param DestAddr Destination address. 36790b57cec5SDimitry Andric /// \param SrcAddr Source address. 36800b57cec5SDimitry Andric /// \param DestVD Destination variable used in \a CopyExpr (for arrays, has 36810b57cec5SDimitry Andric /// type of the base array element). 36820b57cec5SDimitry Andric /// \param SrcVD Source variable used in \a CopyExpr (for arrays, has type of 36830b57cec5SDimitry Andric /// the base array element). 36840b57cec5SDimitry Andric /// \param Copy Actual copygin expression for copying data from \a SrcVD to \a 36850b57cec5SDimitry Andric /// DestVD. 36860b57cec5SDimitry Andric void EmitOMPCopy(QualType OriginalType, 36870b57cec5SDimitry Andric Address DestAddr, Address SrcAddr, 36880b57cec5SDimitry Andric const VarDecl *DestVD, const VarDecl *SrcVD, 36890b57cec5SDimitry Andric const Expr *Copy); 36900b57cec5SDimitry Andric /// Emit atomic update code for constructs: \a X = \a X \a BO \a E or 36910b57cec5SDimitry Andric /// \a X = \a E \a BO \a E. 36920b57cec5SDimitry Andric /// 36930b57cec5SDimitry Andric /// \param X Value to be updated. 36940b57cec5SDimitry Andric /// \param E Update value. 36950b57cec5SDimitry Andric /// \param BO Binary operation for update operation. 36960b57cec5SDimitry Andric /// \param IsXLHSInRHSPart true if \a X is LHS in RHS part of the update 36970b57cec5SDimitry Andric /// expression, false otherwise. 36980b57cec5SDimitry Andric /// \param AO Atomic ordering of the generated atomic instructions. 36990b57cec5SDimitry Andric /// \param CommonGen Code generator for complex expressions that cannot be 37000b57cec5SDimitry Andric /// expressed through atomicrmw instruction. 37010b57cec5SDimitry Andric /// \returns <true, OldAtomicValue> if simple 'atomicrmw' instruction was 37020b57cec5SDimitry Andric /// generated, <false, RValue::get(nullptr)> otherwise. 37030b57cec5SDimitry Andric std::pair<bool, RValue> EmitOMPAtomicSimpleUpdateExpr( 37040b57cec5SDimitry Andric LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart, 37050b57cec5SDimitry Andric llvm::AtomicOrdering AO, SourceLocation Loc, 37060b57cec5SDimitry Andric const llvm::function_ref<RValue(RValue)> CommonGen); 37070b57cec5SDimitry Andric bool EmitOMPFirstprivateClause(const OMPExecutableDirective &D, 37080b57cec5SDimitry Andric OMPPrivateScope &PrivateScope); 37090b57cec5SDimitry Andric void EmitOMPPrivateClause(const OMPExecutableDirective &D, 37100b57cec5SDimitry Andric OMPPrivateScope &PrivateScope); 37110b57cec5SDimitry Andric void EmitOMPUseDevicePtrClause( 37125ffd83dbSDimitry Andric const OMPUseDevicePtrClause &C, OMPPrivateScope &PrivateScope, 371306c3fb27SDimitry Andric const llvm::DenseMap<const ValueDecl *, llvm::Value *> 371406c3fb27SDimitry Andric CaptureDeviceAddrMap); 37155ffd83dbSDimitry Andric void EmitOMPUseDeviceAddrClause( 37165ffd83dbSDimitry Andric const OMPUseDeviceAddrClause &C, OMPPrivateScope &PrivateScope, 371706c3fb27SDimitry Andric const llvm::DenseMap<const ValueDecl *, llvm::Value *> 371806c3fb27SDimitry Andric CaptureDeviceAddrMap); 37190b57cec5SDimitry Andric /// Emit code for copyin clause in \a D directive. The next code is 37200b57cec5SDimitry Andric /// generated at the start of outlined functions for directives: 37210b57cec5SDimitry Andric /// \code 37220b57cec5SDimitry Andric /// threadprivate_var1 = master_threadprivate_var1; 37230b57cec5SDimitry Andric /// operator=(threadprivate_var2, master_threadprivate_var2); 37240b57cec5SDimitry Andric /// ... 37250b57cec5SDimitry Andric /// __kmpc_barrier(&loc, global_tid); 37260b57cec5SDimitry Andric /// \endcode 37270b57cec5SDimitry Andric /// 37280b57cec5SDimitry Andric /// \param D OpenMP directive possibly with 'copyin' clause(s). 37290b57cec5SDimitry Andric /// \returns true if at least one copyin variable is found, false otherwise. 37300b57cec5SDimitry Andric bool EmitOMPCopyinClause(const OMPExecutableDirective &D); 37310b57cec5SDimitry Andric /// Emit initial code for lastprivate variables. If some variable is 37320b57cec5SDimitry Andric /// not also firstprivate, then the default initialization is used. Otherwise 37330b57cec5SDimitry Andric /// initialization of this variable is performed by EmitOMPFirstprivateClause 37340b57cec5SDimitry Andric /// method. 37350b57cec5SDimitry Andric /// 37360b57cec5SDimitry Andric /// \param D Directive that may have 'lastprivate' directives. 37370b57cec5SDimitry Andric /// \param PrivateScope Private scope for capturing lastprivate variables for 37380b57cec5SDimitry Andric /// proper codegen in internal captured statement. 37390b57cec5SDimitry Andric /// 37400b57cec5SDimitry Andric /// \returns true if there is at least one lastprivate variable, false 37410b57cec5SDimitry Andric /// otherwise. 37420b57cec5SDimitry Andric bool EmitOMPLastprivateClauseInit(const OMPExecutableDirective &D, 37430b57cec5SDimitry Andric OMPPrivateScope &PrivateScope); 37440b57cec5SDimitry Andric /// Emit final copying of lastprivate values to original variables at 37450b57cec5SDimitry Andric /// the end of the worksharing or simd directive. 37460b57cec5SDimitry Andric /// 37470b57cec5SDimitry Andric /// \param D Directive that has at least one 'lastprivate' directives. 37480b57cec5SDimitry Andric /// \param IsLastIterCond Boolean condition that must be set to 'i1 true' if 37490b57cec5SDimitry Andric /// it is the last iteration of the loop code in associated directive, or to 37500b57cec5SDimitry Andric /// 'i1 false' otherwise. If this item is nullptr, no final check is required. 37510b57cec5SDimitry Andric void EmitOMPLastprivateClauseFinal(const OMPExecutableDirective &D, 37520b57cec5SDimitry Andric bool NoFinals, 37530b57cec5SDimitry Andric llvm::Value *IsLastIterCond = nullptr); 37540b57cec5SDimitry Andric /// Emit initial code for linear clauses. 37550b57cec5SDimitry Andric void EmitOMPLinearClause(const OMPLoopDirective &D, 37560b57cec5SDimitry Andric CodeGenFunction::OMPPrivateScope &PrivateScope); 37570b57cec5SDimitry Andric /// Emit final code for linear clauses. 37580b57cec5SDimitry Andric /// \param CondGen Optional conditional code for final part of codegen for 37590b57cec5SDimitry Andric /// linear clause. 37600b57cec5SDimitry Andric void EmitOMPLinearClauseFinal( 37610b57cec5SDimitry Andric const OMPLoopDirective &D, 37620b57cec5SDimitry Andric const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen); 37630b57cec5SDimitry Andric /// Emit initial code for reduction variables. Creates reduction copies 37640b57cec5SDimitry Andric /// and initializes them with the values according to OpenMP standard. 37650b57cec5SDimitry Andric /// 37660b57cec5SDimitry Andric /// \param D Directive (possibly) with the 'reduction' clause. 37670b57cec5SDimitry Andric /// \param PrivateScope Private scope for capturing reduction variables for 37680b57cec5SDimitry Andric /// proper codegen in internal captured statement. 37690b57cec5SDimitry Andric /// 37700b57cec5SDimitry Andric void EmitOMPReductionClauseInit(const OMPExecutableDirective &D, 37715ffd83dbSDimitry Andric OMPPrivateScope &PrivateScope, 37725ffd83dbSDimitry Andric bool ForInscan = false); 37730b57cec5SDimitry Andric /// Emit final update of reduction values to original variables at 37740b57cec5SDimitry Andric /// the end of the directive. 37750b57cec5SDimitry Andric /// 37760b57cec5SDimitry Andric /// \param D Directive that has at least one 'reduction' directives. 37770b57cec5SDimitry Andric /// \param ReductionKind The kind of reduction to perform. 37780b57cec5SDimitry Andric void EmitOMPReductionClauseFinal(const OMPExecutableDirective &D, 37790b57cec5SDimitry Andric const OpenMPDirectiveKind ReductionKind); 37800b57cec5SDimitry Andric /// Emit initial code for linear variables. Creates private copies 37810b57cec5SDimitry Andric /// and initializes them with the values according to OpenMP standard. 37820b57cec5SDimitry Andric /// 37830b57cec5SDimitry Andric /// \param D Directive (possibly) with the 'linear' clause. 37840b57cec5SDimitry Andric /// \return true if at least one linear variable is found that should be 37850b57cec5SDimitry Andric /// initialized with the value of the original variable, false otherwise. 37860b57cec5SDimitry Andric bool EmitOMPLinearClauseInit(const OMPLoopDirective &D); 37870b57cec5SDimitry Andric 37880b57cec5SDimitry Andric typedef const llvm::function_ref<void(CodeGenFunction & /*CGF*/, 37890b57cec5SDimitry Andric llvm::Function * /*OutlinedFn*/, 37900b57cec5SDimitry Andric const OMPTaskDataTy & /*Data*/)> 37910b57cec5SDimitry Andric TaskGenTy; 37920b57cec5SDimitry Andric void EmitOMPTaskBasedDirective(const OMPExecutableDirective &S, 37930b57cec5SDimitry Andric const OpenMPDirectiveKind CapturedRegion, 37940b57cec5SDimitry Andric const RegionCodeGenTy &BodyGen, 37950b57cec5SDimitry Andric const TaskGenTy &TaskGen, OMPTaskDataTy &Data); 37960b57cec5SDimitry Andric struct OMPTargetDataInfo { 37970b57cec5SDimitry Andric Address BasePointersArray = Address::invalid(); 37980b57cec5SDimitry Andric Address PointersArray = Address::invalid(); 37990b57cec5SDimitry Andric Address SizesArray = Address::invalid(); 3800e8d8bef9SDimitry Andric Address MappersArray = Address::invalid(); 38010b57cec5SDimitry Andric unsigned NumberOfTargetItems = 0; 38020b57cec5SDimitry Andric explicit OMPTargetDataInfo() = default; 38030b57cec5SDimitry Andric OMPTargetDataInfo(Address BasePointersArray, Address PointersArray, 3804e8d8bef9SDimitry Andric Address SizesArray, Address MappersArray, 3805e8d8bef9SDimitry Andric unsigned NumberOfTargetItems) 38060b57cec5SDimitry Andric : BasePointersArray(BasePointersArray), PointersArray(PointersArray), 3807e8d8bef9SDimitry Andric SizesArray(SizesArray), MappersArray(MappersArray), 3808e8d8bef9SDimitry Andric NumberOfTargetItems(NumberOfTargetItems) {} 38090b57cec5SDimitry Andric }; 38100b57cec5SDimitry Andric void EmitOMPTargetTaskBasedDirective(const OMPExecutableDirective &S, 38110b57cec5SDimitry Andric const RegionCodeGenTy &BodyGen, 38120b57cec5SDimitry Andric OMPTargetDataInfo &InputInfo); 381381ad6265SDimitry Andric void processInReduction(const OMPExecutableDirective &S, 381481ad6265SDimitry Andric OMPTaskDataTy &Data, 381581ad6265SDimitry Andric CodeGenFunction &CGF, 381681ad6265SDimitry Andric const CapturedStmt *CS, 381781ad6265SDimitry Andric OMPPrivateScope &Scope); 3818349cc55cSDimitry Andric void EmitOMPMetaDirective(const OMPMetaDirective &S); 38190b57cec5SDimitry Andric void EmitOMPParallelDirective(const OMPParallelDirective &S); 38200b57cec5SDimitry Andric void EmitOMPSimdDirective(const OMPSimdDirective &S); 3821fe6060f1SDimitry Andric void EmitOMPTileDirective(const OMPTileDirective &S); 3822fe6060f1SDimitry Andric void EmitOMPUnrollDirective(const OMPUnrollDirective &S); 38230fca6ea1SDimitry Andric void EmitOMPReverseDirective(const OMPReverseDirective &S); 38240fca6ea1SDimitry Andric void EmitOMPInterchangeDirective(const OMPInterchangeDirective &S); 38250b57cec5SDimitry Andric void EmitOMPForDirective(const OMPForDirective &S); 38260b57cec5SDimitry Andric void EmitOMPForSimdDirective(const OMPForSimdDirective &S); 38270b57cec5SDimitry Andric void EmitOMPSectionsDirective(const OMPSectionsDirective &S); 38280b57cec5SDimitry Andric void EmitOMPSectionDirective(const OMPSectionDirective &S); 38290b57cec5SDimitry Andric void EmitOMPSingleDirective(const OMPSingleDirective &S); 38300b57cec5SDimitry Andric void EmitOMPMasterDirective(const OMPMasterDirective &S); 3831fe6060f1SDimitry Andric void EmitOMPMaskedDirective(const OMPMaskedDirective &S); 38320b57cec5SDimitry Andric void EmitOMPCriticalDirective(const OMPCriticalDirective &S); 38330b57cec5SDimitry Andric void EmitOMPParallelForDirective(const OMPParallelForDirective &S); 38340b57cec5SDimitry Andric void EmitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &S); 38350b57cec5SDimitry Andric void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S); 3836480093f4SDimitry Andric void EmitOMPParallelMasterDirective(const OMPParallelMasterDirective &S); 38370b57cec5SDimitry Andric void EmitOMPTaskDirective(const OMPTaskDirective &S); 38380b57cec5SDimitry Andric void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S); 3839bdd1243dSDimitry Andric void EmitOMPErrorDirective(const OMPErrorDirective &S); 38400b57cec5SDimitry Andric void EmitOMPBarrierDirective(const OMPBarrierDirective &S); 38410b57cec5SDimitry Andric void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S); 38420b57cec5SDimitry Andric void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S); 38430b57cec5SDimitry Andric void EmitOMPFlushDirective(const OMPFlushDirective &S); 38445ffd83dbSDimitry Andric void EmitOMPDepobjDirective(const OMPDepobjDirective &S); 38455ffd83dbSDimitry Andric void EmitOMPScanDirective(const OMPScanDirective &S); 38460b57cec5SDimitry Andric void EmitOMPOrderedDirective(const OMPOrderedDirective &S); 38470b57cec5SDimitry Andric void EmitOMPAtomicDirective(const OMPAtomicDirective &S); 38480b57cec5SDimitry Andric void EmitOMPTargetDirective(const OMPTargetDirective &S); 38490b57cec5SDimitry Andric void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S); 38500b57cec5SDimitry Andric void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S); 38510b57cec5SDimitry Andric void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S); 38520b57cec5SDimitry Andric void EmitOMPTargetUpdateDirective(const OMPTargetUpdateDirective &S); 38530b57cec5SDimitry Andric void EmitOMPTargetParallelDirective(const OMPTargetParallelDirective &S); 38540b57cec5SDimitry Andric void 38550b57cec5SDimitry Andric EmitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &S); 38560b57cec5SDimitry Andric void EmitOMPTeamsDirective(const OMPTeamsDirective &S); 38570b57cec5SDimitry Andric void 38580b57cec5SDimitry Andric EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S); 38590b57cec5SDimitry Andric void EmitOMPCancelDirective(const OMPCancelDirective &S); 38600b57cec5SDimitry Andric void EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S); 38610b57cec5SDimitry Andric void EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S); 38620b57cec5SDimitry Andric void EmitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &S); 3863a7dea167SDimitry Andric void EmitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective &S); 3864a7dea167SDimitry Andric void 3865a7dea167SDimitry Andric EmitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective &S); 3866a7dea167SDimitry Andric void EmitOMPParallelMasterTaskLoopDirective( 3867a7dea167SDimitry Andric const OMPParallelMasterTaskLoopDirective &S); 3868480093f4SDimitry Andric void EmitOMPParallelMasterTaskLoopSimdDirective( 3869480093f4SDimitry Andric const OMPParallelMasterTaskLoopSimdDirective &S); 38700b57cec5SDimitry Andric void EmitOMPDistributeDirective(const OMPDistributeDirective &S); 38710b57cec5SDimitry Andric void EmitOMPDistributeParallelForDirective( 38720b57cec5SDimitry Andric const OMPDistributeParallelForDirective &S); 38730b57cec5SDimitry Andric void EmitOMPDistributeParallelForSimdDirective( 38740b57cec5SDimitry Andric const OMPDistributeParallelForSimdDirective &S); 38750b57cec5SDimitry Andric void EmitOMPDistributeSimdDirective(const OMPDistributeSimdDirective &S); 38760b57cec5SDimitry Andric void EmitOMPTargetParallelForSimdDirective( 38770b57cec5SDimitry Andric const OMPTargetParallelForSimdDirective &S); 38780b57cec5SDimitry Andric void EmitOMPTargetSimdDirective(const OMPTargetSimdDirective &S); 38790b57cec5SDimitry Andric void EmitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective &S); 38800b57cec5SDimitry Andric void 38810b57cec5SDimitry Andric EmitOMPTeamsDistributeSimdDirective(const OMPTeamsDistributeSimdDirective &S); 38820b57cec5SDimitry Andric void EmitOMPTeamsDistributeParallelForSimdDirective( 38830b57cec5SDimitry Andric const OMPTeamsDistributeParallelForSimdDirective &S); 38840b57cec5SDimitry Andric void EmitOMPTeamsDistributeParallelForDirective( 38850b57cec5SDimitry Andric const OMPTeamsDistributeParallelForDirective &S); 38860b57cec5SDimitry Andric void EmitOMPTargetTeamsDirective(const OMPTargetTeamsDirective &S); 38870b57cec5SDimitry Andric void EmitOMPTargetTeamsDistributeDirective( 38880b57cec5SDimitry Andric const OMPTargetTeamsDistributeDirective &S); 38890b57cec5SDimitry Andric void EmitOMPTargetTeamsDistributeParallelForDirective( 38900b57cec5SDimitry Andric const OMPTargetTeamsDistributeParallelForDirective &S); 38910b57cec5SDimitry Andric void EmitOMPTargetTeamsDistributeParallelForSimdDirective( 38920b57cec5SDimitry Andric const OMPTargetTeamsDistributeParallelForSimdDirective &S); 38930b57cec5SDimitry Andric void EmitOMPTargetTeamsDistributeSimdDirective( 38940b57cec5SDimitry Andric const OMPTargetTeamsDistributeSimdDirective &S); 3895349cc55cSDimitry Andric void EmitOMPGenericLoopDirective(const OMPGenericLoopDirective &S); 389606c3fb27SDimitry Andric void EmitOMPParallelGenericLoopDirective(const OMPLoopDirective &S); 389706c3fb27SDimitry Andric void EmitOMPTargetParallelGenericLoopDirective( 389806c3fb27SDimitry Andric const OMPTargetParallelGenericLoopDirective &S); 389906c3fb27SDimitry Andric void EmitOMPTargetTeamsGenericLoopDirective( 390006c3fb27SDimitry Andric const OMPTargetTeamsGenericLoopDirective &S); 390106c3fb27SDimitry Andric void EmitOMPTeamsGenericLoopDirective(const OMPTeamsGenericLoopDirective &S); 39021fd87a68SDimitry Andric void EmitOMPInteropDirective(const OMPInteropDirective &S); 390306c3fb27SDimitry Andric void EmitOMPParallelMaskedDirective(const OMPParallelMaskedDirective &S); 39040b57cec5SDimitry Andric 39050b57cec5SDimitry Andric /// Emit device code for the target directive. 39060b57cec5SDimitry Andric static void EmitOMPTargetDeviceFunction(CodeGenModule &CGM, 39070b57cec5SDimitry Andric StringRef ParentName, 39080b57cec5SDimitry Andric const OMPTargetDirective &S); 39090b57cec5SDimitry Andric static void 39100b57cec5SDimitry Andric EmitOMPTargetParallelDeviceFunction(CodeGenModule &CGM, StringRef ParentName, 39110b57cec5SDimitry Andric const OMPTargetParallelDirective &S); 39120b57cec5SDimitry Andric /// Emit device code for the target parallel for directive. 39130b57cec5SDimitry Andric static void EmitOMPTargetParallelForDeviceFunction( 39140b57cec5SDimitry Andric CodeGenModule &CGM, StringRef ParentName, 39150b57cec5SDimitry Andric const OMPTargetParallelForDirective &S); 39160b57cec5SDimitry Andric /// Emit device code for the target parallel for simd directive. 39170b57cec5SDimitry Andric static void EmitOMPTargetParallelForSimdDeviceFunction( 39180b57cec5SDimitry Andric CodeGenModule &CGM, StringRef ParentName, 39190b57cec5SDimitry Andric const OMPTargetParallelForSimdDirective &S); 39200b57cec5SDimitry Andric /// Emit device code for the target teams directive. 39210b57cec5SDimitry Andric static void 39220b57cec5SDimitry Andric EmitOMPTargetTeamsDeviceFunction(CodeGenModule &CGM, StringRef ParentName, 39230b57cec5SDimitry Andric const OMPTargetTeamsDirective &S); 39240b57cec5SDimitry Andric /// Emit device code for the target teams distribute directive. 39250b57cec5SDimitry Andric static void EmitOMPTargetTeamsDistributeDeviceFunction( 39260b57cec5SDimitry Andric CodeGenModule &CGM, StringRef ParentName, 39270b57cec5SDimitry Andric const OMPTargetTeamsDistributeDirective &S); 39280b57cec5SDimitry Andric /// Emit device code for the target teams distribute simd directive. 39290b57cec5SDimitry Andric static void EmitOMPTargetTeamsDistributeSimdDeviceFunction( 39300b57cec5SDimitry Andric CodeGenModule &CGM, StringRef ParentName, 39310b57cec5SDimitry Andric const OMPTargetTeamsDistributeSimdDirective &S); 39320b57cec5SDimitry Andric /// Emit device code for the target simd directive. 39330b57cec5SDimitry Andric static void EmitOMPTargetSimdDeviceFunction(CodeGenModule &CGM, 39340b57cec5SDimitry Andric StringRef ParentName, 39350b57cec5SDimitry Andric const OMPTargetSimdDirective &S); 39360b57cec5SDimitry Andric /// Emit device code for the target teams distribute parallel for simd 39370b57cec5SDimitry Andric /// directive. 39380b57cec5SDimitry Andric static void EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction( 39390b57cec5SDimitry Andric CodeGenModule &CGM, StringRef ParentName, 39400b57cec5SDimitry Andric const OMPTargetTeamsDistributeParallelForSimdDirective &S); 39410b57cec5SDimitry Andric 394206c3fb27SDimitry Andric /// Emit device code for the target teams loop directive. 394306c3fb27SDimitry Andric static void EmitOMPTargetTeamsGenericLoopDeviceFunction( 394406c3fb27SDimitry Andric CodeGenModule &CGM, StringRef ParentName, 394506c3fb27SDimitry Andric const OMPTargetTeamsGenericLoopDirective &S); 394606c3fb27SDimitry Andric 394706c3fb27SDimitry Andric /// Emit device code for the target parallel loop directive. 394806c3fb27SDimitry Andric static void EmitOMPTargetParallelGenericLoopDeviceFunction( 394906c3fb27SDimitry Andric CodeGenModule &CGM, StringRef ParentName, 395006c3fb27SDimitry Andric const OMPTargetParallelGenericLoopDirective &S); 395106c3fb27SDimitry Andric 39520b57cec5SDimitry Andric static void EmitOMPTargetTeamsDistributeParallelForDeviceFunction( 39530b57cec5SDimitry Andric CodeGenModule &CGM, StringRef ParentName, 39540b57cec5SDimitry Andric const OMPTargetTeamsDistributeParallelForDirective &S); 3955fe6060f1SDimitry Andric 3956fe6060f1SDimitry Andric /// Emit the Stmt \p S and return its topmost canonical loop, if any. 3957fe6060f1SDimitry Andric /// TODO: The \p Depth paramter is not yet implemented and must be 1. In the 3958fe6060f1SDimitry Andric /// future it is meant to be the number of loops expected in the loop nests 3959fe6060f1SDimitry Andric /// (usually specified by the "collapse" clause) that are collapsed to a 3960fe6060f1SDimitry Andric /// single loop by this function. 3961fe6060f1SDimitry Andric llvm::CanonicalLoopInfo *EmitOMPCollapsedCanonicalLoopNest(const Stmt *S, 3962fe6060f1SDimitry Andric int Depth); 3963fe6060f1SDimitry Andric 3964fe6060f1SDimitry Andric /// Emit an OMPCanonicalLoop using the OpenMPIRBuilder. 3965fe6060f1SDimitry Andric void EmitOMPCanonicalLoop(const OMPCanonicalLoop *S); 3966fe6060f1SDimitry Andric 39670b57cec5SDimitry Andric /// Emit inner loop of the worksharing/simd construct. 39680b57cec5SDimitry Andric /// 39690b57cec5SDimitry Andric /// \param S Directive, for which the inner loop must be emitted. 39700b57cec5SDimitry Andric /// \param RequiresCleanup true, if directive has some associated private 39710b57cec5SDimitry Andric /// variables. 39720b57cec5SDimitry Andric /// \param LoopCond Bollean condition for loop continuation. 39730b57cec5SDimitry Andric /// \param IncExpr Increment expression for loop control variable. 39740b57cec5SDimitry Andric /// \param BodyGen Generator for the inner body of the inner loop. 39750b57cec5SDimitry Andric /// \param PostIncGen Genrator for post-increment code (required for ordered 39760b57cec5SDimitry Andric /// loop directvies). 39770b57cec5SDimitry Andric void EmitOMPInnerLoop( 39785ffd83dbSDimitry Andric const OMPExecutableDirective &S, bool RequiresCleanup, 39795ffd83dbSDimitry Andric const Expr *LoopCond, const Expr *IncExpr, 39800b57cec5SDimitry Andric const llvm::function_ref<void(CodeGenFunction &)> BodyGen, 39810b57cec5SDimitry Andric const llvm::function_ref<void(CodeGenFunction &)> PostIncGen); 39820b57cec5SDimitry Andric 39830b57cec5SDimitry Andric JumpDest getOMPCancelDestination(OpenMPDirectiveKind Kind); 39840b57cec5SDimitry Andric /// Emit initial code for loop counters of loop-based directives. 39850b57cec5SDimitry Andric void EmitOMPPrivateLoopCounters(const OMPLoopDirective &S, 39860b57cec5SDimitry Andric OMPPrivateScope &LoopScope); 39870b57cec5SDimitry Andric 39880b57cec5SDimitry Andric /// Helper for the OpenMP loop directives. 39890b57cec5SDimitry Andric void EmitOMPLoopBody(const OMPLoopDirective &D, JumpDest LoopExit); 39900b57cec5SDimitry Andric 39910b57cec5SDimitry Andric /// Emit code for the worksharing loop-based directive. 39920b57cec5SDimitry Andric /// \return true, if this construct has any lastprivate clause, false - 39930b57cec5SDimitry Andric /// otherwise. 39940b57cec5SDimitry Andric bool EmitOMPWorksharingLoop(const OMPLoopDirective &S, Expr *EUB, 39950b57cec5SDimitry Andric const CodeGenLoopBoundsTy &CodeGenLoopBounds, 39960b57cec5SDimitry Andric const CodeGenDispatchBoundsTy &CGDispatchBounds); 39970b57cec5SDimitry Andric 39980b57cec5SDimitry Andric /// Emit code for the distribute loop-based directive. 39990b57cec5SDimitry Andric void EmitOMPDistributeLoop(const OMPLoopDirective &S, 40000b57cec5SDimitry Andric const CodeGenLoopTy &CodeGenLoop, Expr *IncExpr); 40010b57cec5SDimitry Andric 40020b57cec5SDimitry Andric /// Helpers for the OpenMP loop directives. 4003fe6060f1SDimitry Andric void EmitOMPSimdInit(const OMPLoopDirective &D); 40040b57cec5SDimitry Andric void EmitOMPSimdFinal( 40050b57cec5SDimitry Andric const OMPLoopDirective &D, 40060b57cec5SDimitry Andric const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen); 40070b57cec5SDimitry Andric 40080b57cec5SDimitry Andric /// Emits the lvalue for the expression with possibly captured variable. 40090b57cec5SDimitry Andric LValue EmitOMPSharedLValue(const Expr *E); 40100b57cec5SDimitry Andric 40110b57cec5SDimitry Andric private: 40120b57cec5SDimitry Andric /// Helpers for blocks. 40130b57cec5SDimitry Andric llvm::Value *EmitBlockLiteral(const CGBlockInfo &Info); 40140b57cec5SDimitry Andric 40150b57cec5SDimitry Andric /// struct with the values to be passed to the OpenMP loop-related functions 40160b57cec5SDimitry Andric struct OMPLoopArguments { 40170b57cec5SDimitry Andric /// loop lower bound 40180b57cec5SDimitry Andric Address LB = Address::invalid(); 40190b57cec5SDimitry Andric /// loop upper bound 40200b57cec5SDimitry Andric Address UB = Address::invalid(); 40210b57cec5SDimitry Andric /// loop stride 40220b57cec5SDimitry Andric Address ST = Address::invalid(); 40230b57cec5SDimitry Andric /// isLastIteration argument for runtime functions 40240b57cec5SDimitry Andric Address IL = Address::invalid(); 40250b57cec5SDimitry Andric /// Chunk value generated by sema 40260b57cec5SDimitry Andric llvm::Value *Chunk = nullptr; 40270b57cec5SDimitry Andric /// EnsureUpperBound 40280b57cec5SDimitry Andric Expr *EUB = nullptr; 40290b57cec5SDimitry Andric /// IncrementExpression 40300b57cec5SDimitry Andric Expr *IncExpr = nullptr; 40310b57cec5SDimitry Andric /// Loop initialization 40320b57cec5SDimitry Andric Expr *Init = nullptr; 40330b57cec5SDimitry Andric /// Loop exit condition 40340b57cec5SDimitry Andric Expr *Cond = nullptr; 40350b57cec5SDimitry Andric /// Update of LB after a whole chunk has been executed 40360b57cec5SDimitry Andric Expr *NextLB = nullptr; 40370b57cec5SDimitry Andric /// Update of UB after a whole chunk has been executed 40380b57cec5SDimitry Andric Expr *NextUB = nullptr; 40390fca6ea1SDimitry Andric /// Distinguish between the for distribute and sections 40400fca6ea1SDimitry Andric OpenMPDirectiveKind DKind = llvm::omp::OMPD_unknown; 40410b57cec5SDimitry Andric OMPLoopArguments() = default; 40420b57cec5SDimitry Andric OMPLoopArguments(Address LB, Address UB, Address ST, Address IL, 40430b57cec5SDimitry Andric llvm::Value *Chunk = nullptr, Expr *EUB = nullptr, 40440b57cec5SDimitry Andric Expr *IncExpr = nullptr, Expr *Init = nullptr, 40450b57cec5SDimitry Andric Expr *Cond = nullptr, Expr *NextLB = nullptr, 40460b57cec5SDimitry Andric Expr *NextUB = nullptr) 40470b57cec5SDimitry Andric : LB(LB), UB(UB), ST(ST), IL(IL), Chunk(Chunk), EUB(EUB), 40480b57cec5SDimitry Andric IncExpr(IncExpr), Init(Init), Cond(Cond), NextLB(NextLB), 40490b57cec5SDimitry Andric NextUB(NextUB) {} 40500b57cec5SDimitry Andric }; 40510b57cec5SDimitry Andric void EmitOMPOuterLoop(bool DynamicOrOrdered, bool IsMonotonic, 40520b57cec5SDimitry Andric const OMPLoopDirective &S, OMPPrivateScope &LoopScope, 40530b57cec5SDimitry Andric const OMPLoopArguments &LoopArgs, 40540b57cec5SDimitry Andric const CodeGenLoopTy &CodeGenLoop, 40550b57cec5SDimitry Andric const CodeGenOrderedTy &CodeGenOrdered); 40560b57cec5SDimitry Andric void EmitOMPForOuterLoop(const OpenMPScheduleTy &ScheduleKind, 40570b57cec5SDimitry Andric bool IsMonotonic, const OMPLoopDirective &S, 40580b57cec5SDimitry Andric OMPPrivateScope &LoopScope, bool Ordered, 40590b57cec5SDimitry Andric const OMPLoopArguments &LoopArgs, 40600b57cec5SDimitry Andric const CodeGenDispatchBoundsTy &CGDispatchBounds); 40610b57cec5SDimitry Andric void EmitOMPDistributeOuterLoop(OpenMPDistScheduleClauseKind ScheduleKind, 40620b57cec5SDimitry Andric const OMPLoopDirective &S, 40630b57cec5SDimitry Andric OMPPrivateScope &LoopScope, 40640b57cec5SDimitry Andric const OMPLoopArguments &LoopArgs, 40650b57cec5SDimitry Andric const CodeGenLoopTy &CodeGenLoopContent); 40660b57cec5SDimitry Andric /// Emit code for sections directive. 40670b57cec5SDimitry Andric void EmitSections(const OMPExecutableDirective &S); 40680b57cec5SDimitry Andric 40690b57cec5SDimitry Andric public: 40700fca6ea1SDimitry Andric //===--------------------------------------------------------------------===// 40710fca6ea1SDimitry Andric // OpenACC Emission 40720fca6ea1SDimitry Andric //===--------------------------------------------------------------------===// 40730fca6ea1SDimitry Andric void EmitOpenACCComputeConstruct(const OpenACCComputeConstruct &S) { 40740fca6ea1SDimitry Andric // TODO OpenACC: Implement this. It is currently implemented as a 'no-op', 40750fca6ea1SDimitry Andric // simply emitting its structured block, but in the future we will implement 40760fca6ea1SDimitry Andric // some sort of IR. 40770fca6ea1SDimitry Andric EmitStmt(S.getStructuredBlock()); 40780fca6ea1SDimitry Andric } 40790fca6ea1SDimitry Andric 40800fca6ea1SDimitry Andric void EmitOpenACCLoopConstruct(const OpenACCLoopConstruct &S) { 40810fca6ea1SDimitry Andric // TODO OpenACC: Implement this. It is currently implemented as a 'no-op', 40820fca6ea1SDimitry Andric // simply emitting its loop, but in the future we will implement 40830fca6ea1SDimitry Andric // some sort of IR. 40840fca6ea1SDimitry Andric EmitStmt(S.getLoop()); 40850fca6ea1SDimitry Andric } 40860b57cec5SDimitry Andric 40870b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 40880b57cec5SDimitry Andric // LValue Expression Emission 40890b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 40900b57cec5SDimitry Andric 4091e8d8bef9SDimitry Andric /// Create a check that a scalar RValue is non-null. 4092e8d8bef9SDimitry Andric llvm::Value *EmitNonNullRValueCheck(RValue RV, QualType T); 4093e8d8bef9SDimitry Andric 40940b57cec5SDimitry Andric /// GetUndefRValue - Get an appropriate 'undef' rvalue for the given type. 40950b57cec5SDimitry Andric RValue GetUndefRValue(QualType Ty); 40960b57cec5SDimitry Andric 40970b57cec5SDimitry Andric /// EmitUnsupportedRValue - Emit a dummy r-value using the type of E 40980b57cec5SDimitry Andric /// and issue an ErrorUnsupported style diagnostic (using the 40990b57cec5SDimitry Andric /// provided Name). 41000b57cec5SDimitry Andric RValue EmitUnsupportedRValue(const Expr *E, 41010b57cec5SDimitry Andric const char *Name); 41020b57cec5SDimitry Andric 41030b57cec5SDimitry Andric /// EmitUnsupportedLValue - Emit a dummy l-value using the type of E and issue 41040b57cec5SDimitry Andric /// an ErrorUnsupported style diagnostic (using the provided Name). 41050b57cec5SDimitry Andric LValue EmitUnsupportedLValue(const Expr *E, 41060b57cec5SDimitry Andric const char *Name); 41070b57cec5SDimitry Andric 41080b57cec5SDimitry Andric /// EmitLValue - Emit code to compute a designator that specifies the location 41090b57cec5SDimitry Andric /// of the expression. 41100b57cec5SDimitry Andric /// 41110b57cec5SDimitry Andric /// This can return one of two things: a simple address or a bitfield 41120b57cec5SDimitry Andric /// reference. In either case, the LLVM Value* in the LValue structure is 41130b57cec5SDimitry Andric /// guaranteed to be an LLVM pointer type. 41140b57cec5SDimitry Andric /// 41150b57cec5SDimitry Andric /// If this returns a bitfield reference, nothing about the pointee type of 41160b57cec5SDimitry Andric /// the LLVM value is known: For example, it may not be a pointer to an 41170b57cec5SDimitry Andric /// integer. 41180b57cec5SDimitry Andric /// 41190b57cec5SDimitry Andric /// If this returns a normal address, and if the lvalue's C type is fixed 41200b57cec5SDimitry Andric /// size, this method guarantees that the returned pointer type will point to 41210b57cec5SDimitry Andric /// an LLVM type of the same size of the lvalue's type. If the lvalue has a 41220b57cec5SDimitry Andric /// variable length type, this is not possible. 41230b57cec5SDimitry Andric /// 412406c3fb27SDimitry Andric LValue EmitLValue(const Expr *E, 412506c3fb27SDimitry Andric KnownNonNull_t IsKnownNonNull = NotKnownNonNull); 41260b57cec5SDimitry Andric 412706c3fb27SDimitry Andric private: 412806c3fb27SDimitry Andric LValue EmitLValueHelper(const Expr *E, KnownNonNull_t IsKnownNonNull); 412906c3fb27SDimitry Andric 413006c3fb27SDimitry Andric public: 41310b57cec5SDimitry Andric /// Same as EmitLValue but additionally we generate checking code to 41320b57cec5SDimitry Andric /// guard against undefined behavior. This is only suitable when we know 41330b57cec5SDimitry Andric /// that the address will be used to access the object. 41340b57cec5SDimitry Andric LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK); 41350b57cec5SDimitry Andric 41360b57cec5SDimitry Andric RValue convertTempToRValue(Address addr, QualType type, 41370b57cec5SDimitry Andric SourceLocation Loc); 41380b57cec5SDimitry Andric 41390b57cec5SDimitry Andric void EmitAtomicInit(Expr *E, LValue lvalue); 41400b57cec5SDimitry Andric 41410b57cec5SDimitry Andric bool LValueIsSuitableForInlineAtomic(LValue Src); 41420b57cec5SDimitry Andric 41430b57cec5SDimitry Andric RValue EmitAtomicLoad(LValue LV, SourceLocation SL, 41440b57cec5SDimitry Andric AggValueSlot Slot = AggValueSlot::ignored()); 41450b57cec5SDimitry Andric 41460b57cec5SDimitry Andric RValue EmitAtomicLoad(LValue lvalue, SourceLocation loc, 41470b57cec5SDimitry Andric llvm::AtomicOrdering AO, bool IsVolatile = false, 41480b57cec5SDimitry Andric AggValueSlot slot = AggValueSlot::ignored()); 41490b57cec5SDimitry Andric 41500b57cec5SDimitry Andric void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit); 41510b57cec5SDimitry Andric 41520b57cec5SDimitry Andric void EmitAtomicStore(RValue rvalue, LValue lvalue, llvm::AtomicOrdering AO, 41530b57cec5SDimitry Andric bool IsVolatile, bool isInit); 41540b57cec5SDimitry Andric 41550b57cec5SDimitry Andric std::pair<RValue, llvm::Value *> EmitAtomicCompareExchange( 41560b57cec5SDimitry Andric LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc, 41570b57cec5SDimitry Andric llvm::AtomicOrdering Success = 41580b57cec5SDimitry Andric llvm::AtomicOrdering::SequentiallyConsistent, 41590b57cec5SDimitry Andric llvm::AtomicOrdering Failure = 41600b57cec5SDimitry Andric llvm::AtomicOrdering::SequentiallyConsistent, 41610b57cec5SDimitry Andric bool IsWeak = false, AggValueSlot Slot = AggValueSlot::ignored()); 41620b57cec5SDimitry Andric 41630b57cec5SDimitry Andric void EmitAtomicUpdate(LValue LVal, llvm::AtomicOrdering AO, 41640b57cec5SDimitry Andric const llvm::function_ref<RValue(RValue)> &UpdateOp, 41650b57cec5SDimitry Andric bool IsVolatile); 41660b57cec5SDimitry Andric 41670b57cec5SDimitry Andric /// EmitToMemory - Change a scalar value from its value 41680b57cec5SDimitry Andric /// representation to its in-memory representation. 41690b57cec5SDimitry Andric llvm::Value *EmitToMemory(llvm::Value *Value, QualType Ty); 41700b57cec5SDimitry Andric 41710b57cec5SDimitry Andric /// EmitFromMemory - Change a scalar value from its memory 41720b57cec5SDimitry Andric /// representation to its value representation. 41730b57cec5SDimitry Andric llvm::Value *EmitFromMemory(llvm::Value *Value, QualType Ty); 41740b57cec5SDimitry Andric 41750b57cec5SDimitry Andric /// Check if the scalar \p Value is within the valid range for the given 41760b57cec5SDimitry Andric /// type \p Ty. 41770b57cec5SDimitry Andric /// 41780b57cec5SDimitry Andric /// Returns true if a check is needed (even if the range is unknown). 41790b57cec5SDimitry Andric bool EmitScalarRangeCheck(llvm::Value *Value, QualType Ty, 41800b57cec5SDimitry Andric SourceLocation Loc); 41810b57cec5SDimitry Andric 41820b57cec5SDimitry Andric /// EmitLoadOfScalar - Load a scalar value from an address, taking 41830b57cec5SDimitry Andric /// care to appropriately convert from the memory representation to 41840b57cec5SDimitry Andric /// the LLVM value representation. 41850b57cec5SDimitry Andric llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, 41860b57cec5SDimitry Andric SourceLocation Loc, 41870b57cec5SDimitry Andric AlignmentSource Source = AlignmentSource::Type, 41880b57cec5SDimitry Andric bool isNontemporal = false) { 41890b57cec5SDimitry Andric return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, LValueBaseInfo(Source), 41900b57cec5SDimitry Andric CGM.getTBAAAccessInfo(Ty), isNontemporal); 41910b57cec5SDimitry Andric } 41920b57cec5SDimitry Andric 41930b57cec5SDimitry Andric llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, 41940b57cec5SDimitry Andric SourceLocation Loc, LValueBaseInfo BaseInfo, 41950b57cec5SDimitry Andric TBAAAccessInfo TBAAInfo, 41960b57cec5SDimitry Andric bool isNontemporal = false); 41970b57cec5SDimitry Andric 41980b57cec5SDimitry Andric /// EmitLoadOfScalar - Load a scalar value from an address, taking 41990b57cec5SDimitry Andric /// care to appropriately convert from the memory representation to 42000b57cec5SDimitry Andric /// the LLVM value representation. The l-value must be a simple 42010b57cec5SDimitry Andric /// l-value. 42020b57cec5SDimitry Andric llvm::Value *EmitLoadOfScalar(LValue lvalue, SourceLocation Loc); 42030b57cec5SDimitry Andric 42040b57cec5SDimitry Andric /// EmitStoreOfScalar - Store a scalar value to an address, taking 42050b57cec5SDimitry Andric /// care to appropriately convert from the memory representation to 42060b57cec5SDimitry Andric /// the LLVM value representation. 42070b57cec5SDimitry Andric void EmitStoreOfScalar(llvm::Value *Value, Address Addr, 42080b57cec5SDimitry Andric bool Volatile, QualType Ty, 42090b57cec5SDimitry Andric AlignmentSource Source = AlignmentSource::Type, 42100b57cec5SDimitry Andric bool isInit = false, bool isNontemporal = false) { 42110b57cec5SDimitry Andric EmitStoreOfScalar(Value, Addr, Volatile, Ty, LValueBaseInfo(Source), 42120b57cec5SDimitry Andric CGM.getTBAAAccessInfo(Ty), isInit, isNontemporal); 42130b57cec5SDimitry Andric } 42140b57cec5SDimitry Andric 42150b57cec5SDimitry Andric void EmitStoreOfScalar(llvm::Value *Value, Address Addr, 42160b57cec5SDimitry Andric bool Volatile, QualType Ty, 42170b57cec5SDimitry Andric LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo, 42180b57cec5SDimitry Andric bool isInit = false, bool isNontemporal = false); 42190b57cec5SDimitry Andric 42200b57cec5SDimitry Andric /// EmitStoreOfScalar - Store a scalar value to an address, taking 42210b57cec5SDimitry Andric /// care to appropriately convert from the memory representation to 42220b57cec5SDimitry Andric /// the LLVM value representation. The l-value must be a simple 42230b57cec5SDimitry Andric /// l-value. The isInit flag indicates whether this is an initialization. 42240b57cec5SDimitry Andric /// If so, atomic qualifiers are ignored and the store is always non-atomic. 42250b57cec5SDimitry Andric void EmitStoreOfScalar(llvm::Value *value, LValue lvalue, bool isInit=false); 42260b57cec5SDimitry Andric 42270b57cec5SDimitry Andric /// EmitLoadOfLValue - Given an expression that represents a value lvalue, 42280b57cec5SDimitry Andric /// this method emits the address of the lvalue, then loads the result as an 42290b57cec5SDimitry Andric /// rvalue, returning the rvalue. 42300b57cec5SDimitry Andric RValue EmitLoadOfLValue(LValue V, SourceLocation Loc); 42310b57cec5SDimitry Andric RValue EmitLoadOfExtVectorElementLValue(LValue V); 42320b57cec5SDimitry Andric RValue EmitLoadOfBitfieldLValue(LValue LV, SourceLocation Loc); 42330b57cec5SDimitry Andric RValue EmitLoadOfGlobalRegLValue(LValue LV); 42340b57cec5SDimitry Andric 42350fca6ea1SDimitry Andric /// Like EmitLoadOfLValue but also handles complex and aggregate types. 42360fca6ea1SDimitry Andric RValue EmitLoadOfAnyValue(LValue V, 42370fca6ea1SDimitry Andric AggValueSlot Slot = AggValueSlot::ignored(), 42380fca6ea1SDimitry Andric SourceLocation Loc = {}); 42390fca6ea1SDimitry Andric 42400b57cec5SDimitry Andric /// EmitStoreThroughLValue - Store the specified rvalue into the specified 42410b57cec5SDimitry Andric /// lvalue, where both are guaranteed to the have the same type, and that type 42420b57cec5SDimitry Andric /// is 'Ty'. 42430b57cec5SDimitry Andric void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit = false); 42440b57cec5SDimitry Andric void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst); 42450b57cec5SDimitry Andric void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst); 42460b57cec5SDimitry Andric 42470b57cec5SDimitry Andric /// EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints 42480b57cec5SDimitry Andric /// as EmitStoreThroughLValue. 42490b57cec5SDimitry Andric /// 42500b57cec5SDimitry Andric /// \param Result [out] - If non-null, this will be set to a Value* for the 42510b57cec5SDimitry Andric /// bit-field contents after the store, appropriate for use as the result of 42520b57cec5SDimitry Andric /// an assignment to the bit-field. 42530b57cec5SDimitry Andric void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, 42540b57cec5SDimitry Andric llvm::Value **Result=nullptr); 42550b57cec5SDimitry Andric 42560b57cec5SDimitry Andric /// Emit an l-value for an assignment (simple or compound) of complex type. 42570b57cec5SDimitry Andric LValue EmitComplexAssignmentLValue(const BinaryOperator *E); 42580b57cec5SDimitry Andric LValue EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E); 42590b57cec5SDimitry Andric LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, 42600b57cec5SDimitry Andric llvm::Value *&Result); 42610b57cec5SDimitry Andric 42620b57cec5SDimitry Andric // Note: only available for agg return types 42630b57cec5SDimitry Andric LValue EmitBinaryOperatorLValue(const BinaryOperator *E); 42640b57cec5SDimitry Andric LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E); 42650b57cec5SDimitry Andric // Note: only available for agg return types 42660b57cec5SDimitry Andric LValue EmitCallExprLValue(const CallExpr *E); 42670b57cec5SDimitry Andric // Note: only available for agg return types 42680b57cec5SDimitry Andric LValue EmitVAArgExprLValue(const VAArgExpr *E); 42690b57cec5SDimitry Andric LValue EmitDeclRefLValue(const DeclRefExpr *E); 42700b57cec5SDimitry Andric LValue EmitStringLiteralLValue(const StringLiteral *E); 42710b57cec5SDimitry Andric LValue EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E); 42720b57cec5SDimitry Andric LValue EmitPredefinedLValue(const PredefinedExpr *E); 42730b57cec5SDimitry Andric LValue EmitUnaryOpLValue(const UnaryOperator *E); 42740b57cec5SDimitry Andric LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E, 42750b57cec5SDimitry Andric bool Accessed = false); 42765ffd83dbSDimitry Andric LValue EmitMatrixSubscriptExpr(const MatrixSubscriptExpr *E); 42770fca6ea1SDimitry Andric LValue EmitArraySectionExpr(const ArraySectionExpr *E, 42780b57cec5SDimitry Andric bool IsLowerBound = true); 42790b57cec5SDimitry Andric LValue EmitExtVectorElementExpr(const ExtVectorElementExpr *E); 42800b57cec5SDimitry Andric LValue EmitMemberExpr(const MemberExpr *E); 42810b57cec5SDimitry Andric LValue EmitObjCIsaExpr(const ObjCIsaExpr *E); 42820b57cec5SDimitry Andric LValue EmitCompoundLiteralLValue(const CompoundLiteralExpr *E); 42830b57cec5SDimitry Andric LValue EmitInitListLValue(const InitListExpr *E); 428481ad6265SDimitry Andric void EmitIgnoredConditionalOperator(const AbstractConditionalOperator *E); 42850b57cec5SDimitry Andric LValue EmitConditionalOperatorLValue(const AbstractConditionalOperator *E); 42860b57cec5SDimitry Andric LValue EmitCastLValue(const CastExpr *E); 42870b57cec5SDimitry Andric LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E); 42880b57cec5SDimitry Andric LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e); 42890b57cec5SDimitry Andric 42900b57cec5SDimitry Andric Address EmitExtVectorElementLValue(LValue V); 42910b57cec5SDimitry Andric 42920b57cec5SDimitry Andric RValue EmitRValueForField(LValue LV, const FieldDecl *FD, SourceLocation Loc); 42930b57cec5SDimitry Andric 42940b57cec5SDimitry Andric Address EmitArrayToPointerDecay(const Expr *Array, 42950b57cec5SDimitry Andric LValueBaseInfo *BaseInfo = nullptr, 42960b57cec5SDimitry Andric TBAAAccessInfo *TBAAInfo = nullptr); 42970b57cec5SDimitry Andric 42980b57cec5SDimitry Andric class ConstantEmission { 42990b57cec5SDimitry Andric llvm::PointerIntPair<llvm::Constant*, 1, bool> ValueAndIsReference; 43000b57cec5SDimitry Andric ConstantEmission(llvm::Constant *C, bool isReference) 43010b57cec5SDimitry Andric : ValueAndIsReference(C, isReference) {} 43020b57cec5SDimitry Andric public: 43030b57cec5SDimitry Andric ConstantEmission() {} 43040b57cec5SDimitry Andric static ConstantEmission forReference(llvm::Constant *C) { 43050b57cec5SDimitry Andric return ConstantEmission(C, true); 43060b57cec5SDimitry Andric } 43070b57cec5SDimitry Andric static ConstantEmission forValue(llvm::Constant *C) { 43080b57cec5SDimitry Andric return ConstantEmission(C, false); 43090b57cec5SDimitry Andric } 43100b57cec5SDimitry Andric 43110b57cec5SDimitry Andric explicit operator bool() const { 43120b57cec5SDimitry Andric return ValueAndIsReference.getOpaqueValue() != nullptr; 43130b57cec5SDimitry Andric } 43140b57cec5SDimitry Andric 43150b57cec5SDimitry Andric bool isReference() const { return ValueAndIsReference.getInt(); } 43160b57cec5SDimitry Andric LValue getReferenceLValue(CodeGenFunction &CGF, Expr *refExpr) const { 43170b57cec5SDimitry Andric assert(isReference()); 43180b57cec5SDimitry Andric return CGF.MakeNaturalAlignAddrLValue(ValueAndIsReference.getPointer(), 43190b57cec5SDimitry Andric refExpr->getType()); 43200b57cec5SDimitry Andric } 43210b57cec5SDimitry Andric 43220b57cec5SDimitry Andric llvm::Constant *getValue() const { 43230b57cec5SDimitry Andric assert(!isReference()); 43240b57cec5SDimitry Andric return ValueAndIsReference.getPointer(); 43250b57cec5SDimitry Andric } 43260b57cec5SDimitry Andric }; 43270b57cec5SDimitry Andric 43280b57cec5SDimitry Andric ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr); 43290b57cec5SDimitry Andric ConstantEmission tryEmitAsConstant(const MemberExpr *ME); 43300b57cec5SDimitry Andric llvm::Value *emitScalarConstant(const ConstantEmission &Constant, Expr *E); 43310b57cec5SDimitry Andric 43320b57cec5SDimitry Andric RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, 43330b57cec5SDimitry Andric AggValueSlot slot = AggValueSlot::ignored()); 43340b57cec5SDimitry Andric LValue EmitPseudoObjectLValue(const PseudoObjectExpr *e); 43350b57cec5SDimitry Andric 43360b57cec5SDimitry Andric llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface, 43370b57cec5SDimitry Andric const ObjCIvarDecl *Ivar); 4338bdd1243dSDimitry Andric llvm::Value *EmitIvarOffsetAsPointerDiff(const ObjCInterfaceDecl *Interface, 4339bdd1243dSDimitry Andric const ObjCIvarDecl *Ivar); 43400b57cec5SDimitry Andric LValue EmitLValueForField(LValue Base, const FieldDecl* Field); 43410b57cec5SDimitry Andric LValue EmitLValueForLambdaField(const FieldDecl *Field); 43425f757f3fSDimitry Andric LValue EmitLValueForLambdaField(const FieldDecl *Field, 43435f757f3fSDimitry Andric llvm::Value *ThisValue); 43440b57cec5SDimitry Andric 43450b57cec5SDimitry Andric /// EmitLValueForFieldInitialization - Like EmitLValueForField, except that 43460b57cec5SDimitry Andric /// if the Field is a reference, this will return the address of the reference 43470b57cec5SDimitry Andric /// and not the address of the value stored in the reference. 43480b57cec5SDimitry Andric LValue EmitLValueForFieldInitialization(LValue Base, 43490b57cec5SDimitry Andric const FieldDecl* Field); 43500b57cec5SDimitry Andric 43510b57cec5SDimitry Andric LValue EmitLValueForIvar(QualType ObjectTy, 43520b57cec5SDimitry Andric llvm::Value* Base, const ObjCIvarDecl *Ivar, 43530b57cec5SDimitry Andric unsigned CVRQualifiers); 43540b57cec5SDimitry Andric 43550b57cec5SDimitry Andric LValue EmitCXXConstructLValue(const CXXConstructExpr *E); 43560b57cec5SDimitry Andric LValue EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E); 43570b57cec5SDimitry Andric LValue EmitCXXTypeidLValue(const CXXTypeidExpr *E); 43580b57cec5SDimitry Andric LValue EmitCXXUuidofLValue(const CXXUuidofExpr *E); 43590b57cec5SDimitry Andric 43600b57cec5SDimitry Andric LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E); 43610b57cec5SDimitry Andric LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E); 43620b57cec5SDimitry Andric LValue EmitStmtExprLValue(const StmtExpr *E); 43630b57cec5SDimitry Andric LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E); 43640b57cec5SDimitry Andric LValue EmitObjCSelectorLValue(const ObjCSelectorExpr *E); 43650b57cec5SDimitry Andric void EmitDeclRefExprDbgValue(const DeclRefExpr *E, const APValue &Init); 43660b57cec5SDimitry Andric 43670b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 43680b57cec5SDimitry Andric // Scalar Expression Emission 43690b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 43700b57cec5SDimitry Andric 43710b57cec5SDimitry Andric /// EmitCall - Generate a call of the given function, expecting the given 43720b57cec5SDimitry Andric /// result type, and using the given argument list which specifies both the 43730b57cec5SDimitry Andric /// LLVM arguments and the types they were derived from. 43740b57cec5SDimitry Andric RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, 43750b57cec5SDimitry Andric ReturnValueSlot ReturnValue, const CallArgList &Args, 4376fe6060f1SDimitry Andric llvm::CallBase **callOrInvoke, bool IsMustTail, 43770fca6ea1SDimitry Andric SourceLocation Loc, 43780fca6ea1SDimitry Andric bool IsVirtualFunctionPointerThunk = false); 43790b57cec5SDimitry Andric RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, 43800b57cec5SDimitry Andric ReturnValueSlot ReturnValue, const CallArgList &Args, 4381fe6060f1SDimitry Andric llvm::CallBase **callOrInvoke = nullptr, 4382fe6060f1SDimitry Andric bool IsMustTail = false) { 43830b57cec5SDimitry Andric return EmitCall(CallInfo, Callee, ReturnValue, Args, callOrInvoke, 4384fe6060f1SDimitry Andric IsMustTail, SourceLocation()); 43850b57cec5SDimitry Andric } 43860b57cec5SDimitry Andric RValue EmitCall(QualType FnType, const CGCallee &Callee, const CallExpr *E, 43870b57cec5SDimitry Andric ReturnValueSlot ReturnValue, llvm::Value *Chain = nullptr); 43880b57cec5SDimitry Andric RValue EmitCallExpr(const CallExpr *E, 43890b57cec5SDimitry Andric ReturnValueSlot ReturnValue = ReturnValueSlot()); 43900b57cec5SDimitry Andric RValue EmitSimpleCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue); 43910b57cec5SDimitry Andric CGCallee EmitCallee(const Expr *E); 43920b57cec5SDimitry Andric 43930b57cec5SDimitry Andric void checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl); 43940b57cec5SDimitry Andric void checkTargetFeatures(SourceLocation Loc, const FunctionDecl *TargetDecl); 43950b57cec5SDimitry Andric 43960b57cec5SDimitry Andric llvm::CallInst *EmitRuntimeCall(llvm::FunctionCallee callee, 43970b57cec5SDimitry Andric const Twine &name = ""); 43980b57cec5SDimitry Andric llvm::CallInst *EmitRuntimeCall(llvm::FunctionCallee callee, 43990b57cec5SDimitry Andric ArrayRef<llvm::Value *> args, 44000b57cec5SDimitry Andric const Twine &name = ""); 44010b57cec5SDimitry Andric llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, 44020b57cec5SDimitry Andric const Twine &name = ""); 44030b57cec5SDimitry Andric llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, 44040fca6ea1SDimitry Andric ArrayRef<Address> args, 44050fca6ea1SDimitry Andric const Twine &name = ""); 44060fca6ea1SDimitry Andric llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, 44070b57cec5SDimitry Andric ArrayRef<llvm::Value *> args, 44080b57cec5SDimitry Andric const Twine &name = ""); 44090b57cec5SDimitry Andric 44100b57cec5SDimitry Andric SmallVector<llvm::OperandBundleDef, 1> 44110b57cec5SDimitry Andric getBundlesForFunclet(llvm::Value *Callee); 44120b57cec5SDimitry Andric 44130b57cec5SDimitry Andric llvm::CallBase *EmitCallOrInvoke(llvm::FunctionCallee Callee, 44140b57cec5SDimitry Andric ArrayRef<llvm::Value *> Args, 44150b57cec5SDimitry Andric const Twine &Name = ""); 44160b57cec5SDimitry Andric llvm::CallBase *EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, 44170b57cec5SDimitry Andric ArrayRef<llvm::Value *> args, 44180b57cec5SDimitry Andric const Twine &name = ""); 44190b57cec5SDimitry Andric llvm::CallBase *EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, 44200b57cec5SDimitry Andric const Twine &name = ""); 44210b57cec5SDimitry Andric void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, 44220b57cec5SDimitry Andric ArrayRef<llvm::Value *> args); 44230b57cec5SDimitry Andric 44240b57cec5SDimitry Andric CGCallee BuildAppleKextVirtualCall(const CXXMethodDecl *MD, 44250b57cec5SDimitry Andric NestedNameSpecifier *Qual, 44260b57cec5SDimitry Andric llvm::Type *Ty); 44270b57cec5SDimitry Andric 44280b57cec5SDimitry Andric CGCallee BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD, 44290b57cec5SDimitry Andric CXXDtorType Type, 44300b57cec5SDimitry Andric const CXXRecordDecl *RD); 44310b57cec5SDimitry Andric 44320fca6ea1SDimitry Andric bool isPointerKnownNonNull(const Expr *E); 44330fca6ea1SDimitry Andric 44340fca6ea1SDimitry Andric /// Create the discriminator from the storage address and the entity hash. 44350fca6ea1SDimitry Andric llvm::Value *EmitPointerAuthBlendDiscriminator(llvm::Value *StorageAddress, 44360fca6ea1SDimitry Andric llvm::Value *Discriminator); 44370fca6ea1SDimitry Andric CGPointerAuthInfo EmitPointerAuthInfo(const PointerAuthSchema &Schema, 44380fca6ea1SDimitry Andric llvm::Value *StorageAddress, 44390fca6ea1SDimitry Andric GlobalDecl SchemaDecl, 44400fca6ea1SDimitry Andric QualType SchemaType); 44410fca6ea1SDimitry Andric 44420fca6ea1SDimitry Andric llvm::Value *EmitPointerAuthSign(const CGPointerAuthInfo &Info, 44430fca6ea1SDimitry Andric llvm::Value *Pointer); 44440fca6ea1SDimitry Andric 44450fca6ea1SDimitry Andric llvm::Value *EmitPointerAuthAuth(const CGPointerAuthInfo &Info, 44460fca6ea1SDimitry Andric llvm::Value *Pointer); 44470fca6ea1SDimitry Andric 44480fca6ea1SDimitry Andric llvm::Value *emitPointerAuthResign(llvm::Value *Pointer, QualType PointerType, 44490fca6ea1SDimitry Andric const CGPointerAuthInfo &CurAuthInfo, 44500fca6ea1SDimitry Andric const CGPointerAuthInfo &NewAuthInfo, 44510fca6ea1SDimitry Andric bool IsKnownNonNull); 44520fca6ea1SDimitry Andric llvm::Value *emitPointerAuthResignCall(llvm::Value *Pointer, 44530fca6ea1SDimitry Andric const CGPointerAuthInfo &CurInfo, 44540fca6ea1SDimitry Andric const CGPointerAuthInfo &NewInfo); 44550fca6ea1SDimitry Andric 44560fca6ea1SDimitry Andric void EmitPointerAuthOperandBundle( 44570fca6ea1SDimitry Andric const CGPointerAuthInfo &Info, 44580fca6ea1SDimitry Andric SmallVectorImpl<llvm::OperandBundleDef> &Bundles); 44590fca6ea1SDimitry Andric 44600fca6ea1SDimitry Andric llvm::Value *authPointerToPointerCast(llvm::Value *ResultPtr, 44610fca6ea1SDimitry Andric QualType SourceType, QualType DestType); 44620fca6ea1SDimitry Andric Address authPointerToPointerCast(Address Ptr, QualType SourceType, 44630fca6ea1SDimitry Andric QualType DestType); 44640fca6ea1SDimitry Andric 44650fca6ea1SDimitry Andric Address getAsNaturalAddressOf(Address Addr, QualType PointeeTy); 44660fca6ea1SDimitry Andric 44670fca6ea1SDimitry Andric llvm::Value *getAsNaturalPointerTo(Address Addr, QualType PointeeType) { 44680fca6ea1SDimitry Andric return getAsNaturalAddressOf(Addr, PointeeType).getBasePointer(); 44690fca6ea1SDimitry Andric } 44700fca6ea1SDimitry Andric 44710b57cec5SDimitry Andric // Return the copy constructor name with the prefix "__copy_constructor_" 44720b57cec5SDimitry Andric // removed. 44730b57cec5SDimitry Andric static std::string getNonTrivialCopyConstructorStr(QualType QT, 44740b57cec5SDimitry Andric CharUnits Alignment, 44750b57cec5SDimitry Andric bool IsVolatile, 44760b57cec5SDimitry Andric ASTContext &Ctx); 44770b57cec5SDimitry Andric 44780b57cec5SDimitry Andric // Return the destructor name with the prefix "__destructor_" removed. 44790b57cec5SDimitry Andric static std::string getNonTrivialDestructorStr(QualType QT, 44800b57cec5SDimitry Andric CharUnits Alignment, 44810b57cec5SDimitry Andric bool IsVolatile, 44820b57cec5SDimitry Andric ASTContext &Ctx); 44830b57cec5SDimitry Andric 44840b57cec5SDimitry Andric // These functions emit calls to the special functions of non-trivial C 44850b57cec5SDimitry Andric // structs. 44860b57cec5SDimitry Andric void defaultInitNonTrivialCStructVar(LValue Dst); 44870b57cec5SDimitry Andric void callCStructDefaultConstructor(LValue Dst); 44880b57cec5SDimitry Andric void callCStructDestructor(LValue Dst); 44890b57cec5SDimitry Andric void callCStructCopyConstructor(LValue Dst, LValue Src); 44900b57cec5SDimitry Andric void callCStructMoveConstructor(LValue Dst, LValue Src); 44910b57cec5SDimitry Andric void callCStructCopyAssignmentOperator(LValue Dst, LValue Src); 44920b57cec5SDimitry Andric void callCStructMoveAssignmentOperator(LValue Dst, LValue Src); 44930b57cec5SDimitry Andric 44940b57cec5SDimitry Andric RValue 44950b57cec5SDimitry Andric EmitCXXMemberOrOperatorCall(const CXXMethodDecl *Method, 44960b57cec5SDimitry Andric const CGCallee &Callee, 44970b57cec5SDimitry Andric ReturnValueSlot ReturnValue, llvm::Value *This, 44980b57cec5SDimitry Andric llvm::Value *ImplicitParam, 44990b57cec5SDimitry Andric QualType ImplicitParamTy, const CallExpr *E, 45000b57cec5SDimitry Andric CallArgList *RtlArgs); 45010b57cec5SDimitry Andric RValue EmitCXXDestructorCall(GlobalDecl Dtor, const CGCallee &Callee, 45020b57cec5SDimitry Andric llvm::Value *This, QualType ThisTy, 45030b57cec5SDimitry Andric llvm::Value *ImplicitParam, 45040b57cec5SDimitry Andric QualType ImplicitParamTy, const CallExpr *E); 45050b57cec5SDimitry Andric RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E, 45060b57cec5SDimitry Andric ReturnValueSlot ReturnValue); 45070b57cec5SDimitry Andric RValue EmitCXXMemberOrOperatorMemberCallExpr(const CallExpr *CE, 45080b57cec5SDimitry Andric const CXXMethodDecl *MD, 45090b57cec5SDimitry Andric ReturnValueSlot ReturnValue, 45100b57cec5SDimitry Andric bool HasQualifier, 45110b57cec5SDimitry Andric NestedNameSpecifier *Qualifier, 45120b57cec5SDimitry Andric bool IsArrow, const Expr *Base); 45130b57cec5SDimitry Andric // Compute the object pointer. 45140b57cec5SDimitry Andric Address EmitCXXMemberDataPointerAddress(const Expr *E, Address base, 45150b57cec5SDimitry Andric llvm::Value *memberPtr, 45160b57cec5SDimitry Andric const MemberPointerType *memberPtrType, 45170b57cec5SDimitry Andric LValueBaseInfo *BaseInfo = nullptr, 45180b57cec5SDimitry Andric TBAAAccessInfo *TBAAInfo = nullptr); 45190b57cec5SDimitry Andric RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, 45200b57cec5SDimitry Andric ReturnValueSlot ReturnValue); 45210b57cec5SDimitry Andric 45220b57cec5SDimitry Andric RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, 45230b57cec5SDimitry Andric const CXXMethodDecl *MD, 45240b57cec5SDimitry Andric ReturnValueSlot ReturnValue); 45250b57cec5SDimitry Andric RValue EmitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E); 45260b57cec5SDimitry Andric 45270b57cec5SDimitry Andric RValue EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E, 45280b57cec5SDimitry Andric ReturnValueSlot ReturnValue); 45290b57cec5SDimitry Andric 4530349cc55cSDimitry Andric RValue EmitNVPTXDevicePrintfCallExpr(const CallExpr *E); 4531349cc55cSDimitry Andric RValue EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E); 4532349cc55cSDimitry Andric RValue EmitOpenMPDevicePrintfCallExpr(const CallExpr *E); 45330b57cec5SDimitry Andric 45340b57cec5SDimitry Andric RValue EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, 45350b57cec5SDimitry Andric const CallExpr *E, ReturnValueSlot ReturnValue); 45360b57cec5SDimitry Andric 45370b57cec5SDimitry Andric RValue emitRotate(const CallExpr *E, bool IsRotateRight); 45380b57cec5SDimitry Andric 45390b57cec5SDimitry Andric /// Emit IR for __builtin_os_log_format. 45400b57cec5SDimitry Andric RValue emitBuiltinOSLogFormat(const CallExpr &E); 45410b57cec5SDimitry Andric 4542480093f4SDimitry Andric /// Emit IR for __builtin_is_aligned. 4543480093f4SDimitry Andric RValue EmitBuiltinIsAligned(const CallExpr *E); 4544480093f4SDimitry Andric /// Emit IR for __builtin_align_up/__builtin_align_down. 4545480093f4SDimitry Andric RValue EmitBuiltinAlignTo(const CallExpr *E, bool AlignUp); 4546480093f4SDimitry Andric 45470b57cec5SDimitry Andric llvm::Function *generateBuiltinOSLogHelperFunction( 45480b57cec5SDimitry Andric const analyze_os_log::OSLogBufferLayout &Layout, 45490b57cec5SDimitry Andric CharUnits BufferAlignment); 45500b57cec5SDimitry Andric 45510b57cec5SDimitry Andric RValue EmitBlockCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue); 45520b57cec5SDimitry Andric 45530b57cec5SDimitry Andric /// EmitTargetBuiltinExpr - Emit the given builtin call. Returns 0 if the call 45540b57cec5SDimitry Andric /// is unhandled by the current target. 4555480093f4SDimitry Andric llvm::Value *EmitTargetBuiltinExpr(unsigned BuiltinID, const CallExpr *E, 4556480093f4SDimitry Andric ReturnValueSlot ReturnValue); 45570b57cec5SDimitry Andric 45580b57cec5SDimitry Andric llvm::Value *EmitAArch64CompareBuiltinExpr(llvm::Value *Op, llvm::Type *Ty, 45590b57cec5SDimitry Andric const llvm::CmpInst::Predicate Fp, 45600b57cec5SDimitry Andric const llvm::CmpInst::Predicate Ip, 45610b57cec5SDimitry Andric const llvm::Twine &Name = ""); 45620b57cec5SDimitry Andric llvm::Value *EmitARMBuiltinExpr(unsigned BuiltinID, const CallExpr *E, 4563480093f4SDimitry Andric ReturnValueSlot ReturnValue, 4564480093f4SDimitry Andric llvm::Triple::ArchType Arch); 4565480093f4SDimitry Andric llvm::Value *EmitARMMVEBuiltinExpr(unsigned BuiltinID, const CallExpr *E, 4566480093f4SDimitry Andric ReturnValueSlot ReturnValue, 45670b57cec5SDimitry Andric llvm::Triple::ArchType Arch); 45685ffd83dbSDimitry Andric llvm::Value *EmitARMCDEBuiltinExpr(unsigned BuiltinID, const CallExpr *E, 45695ffd83dbSDimitry Andric ReturnValueSlot ReturnValue, 45705ffd83dbSDimitry Andric llvm::Triple::ArchType Arch); 45715ffd83dbSDimitry Andric llvm::Value *EmitCMSEClearRecord(llvm::Value *V, llvm::IntegerType *ITy, 45725ffd83dbSDimitry Andric QualType RTy); 45735ffd83dbSDimitry Andric llvm::Value *EmitCMSEClearRecord(llvm::Value *V, llvm::ArrayType *ATy, 45745ffd83dbSDimitry Andric QualType RTy); 45750b57cec5SDimitry Andric 45760b57cec5SDimitry Andric llvm::Value *EmitCommonNeonBuiltinExpr(unsigned BuiltinID, 45770b57cec5SDimitry Andric unsigned LLVMIntrinsic, 45780b57cec5SDimitry Andric unsigned AltLLVMIntrinsic, 45790b57cec5SDimitry Andric const char *NameHint, 45800b57cec5SDimitry Andric unsigned Modifier, 45810b57cec5SDimitry Andric const CallExpr *E, 45820b57cec5SDimitry Andric SmallVectorImpl<llvm::Value *> &Ops, 45830b57cec5SDimitry Andric Address PtrOp0, Address PtrOp1, 45840b57cec5SDimitry Andric llvm::Triple::ArchType Arch); 45850b57cec5SDimitry Andric 45860b57cec5SDimitry Andric llvm::Function *LookupNeonLLVMIntrinsic(unsigned IntrinsicID, 45870b57cec5SDimitry Andric unsigned Modifier, llvm::Type *ArgTy, 45880b57cec5SDimitry Andric const CallExpr *E); 45890b57cec5SDimitry Andric llvm::Value *EmitNeonCall(llvm::Function *F, 45900b57cec5SDimitry Andric SmallVectorImpl<llvm::Value*> &O, 45910b57cec5SDimitry Andric const char *name, 45920b57cec5SDimitry Andric unsigned shift = 0, bool rightshift = false); 45935ffd83dbSDimitry Andric llvm::Value *EmitNeonSplat(llvm::Value *V, llvm::Constant *Idx, 45945ffd83dbSDimitry Andric const llvm::ElementCount &Count); 45950b57cec5SDimitry Andric llvm::Value *EmitNeonSplat(llvm::Value *V, llvm::Constant *Idx); 45960b57cec5SDimitry Andric llvm::Value *EmitNeonShiftVector(llvm::Value *V, llvm::Type *Ty, 45970b57cec5SDimitry Andric bool negateForRightShift); 45980b57cec5SDimitry Andric llvm::Value *EmitNeonRShiftImm(llvm::Value *Vec, llvm::Value *Amt, 45990b57cec5SDimitry Andric llvm::Type *Ty, bool usgn, const char *name); 46000b57cec5SDimitry Andric llvm::Value *vectorWrapScalar16(llvm::Value *Op); 46015ffd83dbSDimitry Andric /// SVEBuiltinMemEltTy - Returns the memory element type for this memory 46025ffd83dbSDimitry Andric /// access builtin. Only required if it can't be inferred from the base 46035ffd83dbSDimitry Andric /// pointer operand. 4604349cc55cSDimitry Andric llvm::Type *SVEBuiltinMemEltTy(const SVETypeFlags &TypeFlags); 46055ffd83dbSDimitry Andric 4606349cc55cSDimitry Andric SmallVector<llvm::Type *, 2> 4607349cc55cSDimitry Andric getSVEOverloadTypes(const SVETypeFlags &TypeFlags, llvm::Type *ReturnType, 46085ffd83dbSDimitry Andric ArrayRef<llvm::Value *> Ops); 4609349cc55cSDimitry Andric llvm::Type *getEltType(const SVETypeFlags &TypeFlags); 46105ffd83dbSDimitry Andric llvm::ScalableVectorType *getSVEType(const SVETypeFlags &TypeFlags); 4611349cc55cSDimitry Andric llvm::ScalableVectorType *getSVEPredType(const SVETypeFlags &TypeFlags); 4612bdd1243dSDimitry Andric llvm::Value *EmitSVETupleSetOrGet(const SVETypeFlags &TypeFlags, 4613bdd1243dSDimitry Andric llvm::Type *ReturnType, 4614bdd1243dSDimitry Andric ArrayRef<llvm::Value *> Ops); 4615bdd1243dSDimitry Andric llvm::Value *EmitSVETupleCreate(const SVETypeFlags &TypeFlags, 4616bdd1243dSDimitry Andric llvm::Type *ReturnType, 4617bdd1243dSDimitry Andric ArrayRef<llvm::Value *> Ops); 4618349cc55cSDimitry Andric llvm::Value *EmitSVEAllTruePred(const SVETypeFlags &TypeFlags); 46195ffd83dbSDimitry Andric llvm::Value *EmitSVEDupX(llvm::Value *Scalar); 46205ffd83dbSDimitry Andric llvm::Value *EmitSVEDupX(llvm::Value *Scalar, llvm::Type *Ty); 46215ffd83dbSDimitry Andric llvm::Value *EmitSVEReinterpret(llvm::Value *Val, llvm::Type *Ty); 4622349cc55cSDimitry Andric llvm::Value *EmitSVEPMull(const SVETypeFlags &TypeFlags, 46235ffd83dbSDimitry Andric llvm::SmallVectorImpl<llvm::Value *> &Ops, 46245ffd83dbSDimitry Andric unsigned BuiltinID); 4625349cc55cSDimitry Andric llvm::Value *EmitSVEMovl(const SVETypeFlags &TypeFlags, 46265ffd83dbSDimitry Andric llvm::ArrayRef<llvm::Value *> Ops, 46275ffd83dbSDimitry Andric unsigned BuiltinID); 46285ffd83dbSDimitry Andric llvm::Value *EmitSVEPredicateCast(llvm::Value *Pred, 46295ffd83dbSDimitry Andric llvm::ScalableVectorType *VTy); 4630349cc55cSDimitry Andric llvm::Value *EmitSVEGatherLoad(const SVETypeFlags &TypeFlags, 46315ffd83dbSDimitry Andric llvm::SmallVectorImpl<llvm::Value *> &Ops, 46325ffd83dbSDimitry Andric unsigned IntID); 4633349cc55cSDimitry Andric llvm::Value *EmitSVEScatterStore(const SVETypeFlags &TypeFlags, 46345ffd83dbSDimitry Andric llvm::SmallVectorImpl<llvm::Value *> &Ops, 46355ffd83dbSDimitry Andric unsigned IntID); 46365ffd83dbSDimitry Andric llvm::Value *EmitSVEMaskedLoad(const CallExpr *, llvm::Type *ReturnTy, 46375ffd83dbSDimitry Andric SmallVectorImpl<llvm::Value *> &Ops, 46385ffd83dbSDimitry Andric unsigned BuiltinID, bool IsZExtReturn); 46395ffd83dbSDimitry Andric llvm::Value *EmitSVEMaskedStore(const CallExpr *, 46405ffd83dbSDimitry Andric SmallVectorImpl<llvm::Value *> &Ops, 46415ffd83dbSDimitry Andric unsigned BuiltinID); 4642349cc55cSDimitry Andric llvm::Value *EmitSVEPrefetchLoad(const SVETypeFlags &TypeFlags, 46435ffd83dbSDimitry Andric SmallVectorImpl<llvm::Value *> &Ops, 46445ffd83dbSDimitry Andric unsigned BuiltinID); 4645349cc55cSDimitry Andric llvm::Value *EmitSVEGatherPrefetch(const SVETypeFlags &TypeFlags, 46465ffd83dbSDimitry Andric SmallVectorImpl<llvm::Value *> &Ops, 46475ffd83dbSDimitry Andric unsigned IntID); 4648349cc55cSDimitry Andric llvm::Value *EmitSVEStructLoad(const SVETypeFlags &TypeFlags, 4649349cc55cSDimitry Andric SmallVectorImpl<llvm::Value *> &Ops, 4650349cc55cSDimitry Andric unsigned IntID); 4651349cc55cSDimitry Andric llvm::Value *EmitSVEStructStore(const SVETypeFlags &TypeFlags, 46525ffd83dbSDimitry Andric SmallVectorImpl<llvm::Value *> &Ops, 46535ffd83dbSDimitry Andric unsigned IntID); 46545f757f3fSDimitry Andric /// FormSVEBuiltinResult - Returns the struct of scalable vectors as a wider 46555f757f3fSDimitry Andric /// vector. It extracts the scalable vector from the struct and inserts into 46565f757f3fSDimitry Andric /// the wider vector. This avoids the error when allocating space in llvm 46575f757f3fSDimitry Andric /// for struct of scalable vectors if a function returns struct. 46585f757f3fSDimitry Andric llvm::Value *FormSVEBuiltinResult(llvm::Value *Call); 46595f757f3fSDimitry Andric 46605ffd83dbSDimitry Andric llvm::Value *EmitAArch64SVEBuiltinExpr(unsigned BuiltinID, const CallExpr *E); 46615ffd83dbSDimitry Andric 46625f757f3fSDimitry Andric llvm::Value *EmitSMELd1St1(const SVETypeFlags &TypeFlags, 466306c3fb27SDimitry Andric llvm::SmallVectorImpl<llvm::Value *> &Ops, 466406c3fb27SDimitry Andric unsigned IntID); 46655f757f3fSDimitry Andric llvm::Value *EmitSMEReadWrite(const SVETypeFlags &TypeFlags, 466606c3fb27SDimitry Andric llvm::SmallVectorImpl<llvm::Value *> &Ops, 466706c3fb27SDimitry Andric unsigned IntID); 46685f757f3fSDimitry Andric llvm::Value *EmitSMEZero(const SVETypeFlags &TypeFlags, 466906c3fb27SDimitry Andric llvm::SmallVectorImpl<llvm::Value *> &Ops, 467006c3fb27SDimitry Andric unsigned IntID); 46715f757f3fSDimitry Andric llvm::Value *EmitSMELdrStr(const SVETypeFlags &TypeFlags, 467206c3fb27SDimitry Andric llvm::SmallVectorImpl<llvm::Value *> &Ops, 467306c3fb27SDimitry Andric unsigned IntID); 46745f757f3fSDimitry Andric 46755f757f3fSDimitry Andric void GetAArch64SVEProcessedOperands(unsigned BuiltinID, const CallExpr *E, 46765f757f3fSDimitry Andric SmallVectorImpl<llvm::Value *> &Ops, 46775f757f3fSDimitry Andric SVETypeFlags TypeFlags); 46785f757f3fSDimitry Andric 467906c3fb27SDimitry Andric llvm::Value *EmitAArch64SMEBuiltinExpr(unsigned BuiltinID, const CallExpr *E); 468006c3fb27SDimitry Andric 46810b57cec5SDimitry Andric llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E, 46820b57cec5SDimitry Andric llvm::Triple::ArchType Arch); 4683a7dea167SDimitry Andric llvm::Value *EmitBPFBuiltinExpr(unsigned BuiltinID, const CallExpr *E); 46840b57cec5SDimitry Andric 46850b57cec5SDimitry Andric llvm::Value *BuildVector(ArrayRef<llvm::Value*> Ops); 46860b57cec5SDimitry Andric llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E); 46870b57cec5SDimitry Andric llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E); 46880b57cec5SDimitry Andric llvm::Value *EmitAMDGPUBuiltinExpr(unsigned BuiltinID, const CallExpr *E); 46890fca6ea1SDimitry Andric llvm::Value *EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E); 46905f757f3fSDimitry Andric llvm::Value *EmitScalarOrConstFoldImmArg(unsigned ICEArguments, unsigned Idx, 46915f757f3fSDimitry Andric const CallExpr *E); 46920b57cec5SDimitry Andric llvm::Value *EmitSystemZBuiltinExpr(unsigned BuiltinID, const CallExpr *E); 46930b57cec5SDimitry Andric llvm::Value *EmitNVPTXBuiltinExpr(unsigned BuiltinID, const CallExpr *E); 46940b57cec5SDimitry Andric llvm::Value *EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, 46950b57cec5SDimitry Andric const CallExpr *E); 46960b57cec5SDimitry Andric llvm::Value *EmitHexagonBuiltinExpr(unsigned BuiltinID, const CallExpr *E); 4697fe6060f1SDimitry Andric llvm::Value *EmitRISCVBuiltinExpr(unsigned BuiltinID, const CallExpr *E, 4698fe6060f1SDimitry Andric ReturnValueSlot ReturnValue); 46990fca6ea1SDimitry Andric 47000fca6ea1SDimitry Andric void AddAMDGPUFenceAddressSpaceMMRA(llvm::Instruction *Inst, 47010fca6ea1SDimitry Andric const CallExpr *E); 4702bdd1243dSDimitry Andric void ProcessOrderScopeAMDGCN(llvm::Value *Order, llvm::Value *Scope, 47035ffd83dbSDimitry Andric llvm::AtomicOrdering &AO, 47045ffd83dbSDimitry Andric llvm::SyncScope::ID &SSID); 47050b57cec5SDimitry Andric 47060b57cec5SDimitry Andric enum class MSVCIntrin; 47070b57cec5SDimitry Andric llvm::Value *EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, const CallExpr *E); 47080b57cec5SDimitry Andric 4709e8d8bef9SDimitry Andric llvm::Value *EmitBuiltinAvailable(const VersionTuple &Version); 47100b57cec5SDimitry Andric 47110b57cec5SDimitry Andric llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E); 47120b57cec5SDimitry Andric llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E); 47130b57cec5SDimitry Andric llvm::Value *EmitObjCBoxedExpr(const ObjCBoxedExpr *E); 47140b57cec5SDimitry Andric llvm::Value *EmitObjCArrayLiteral(const ObjCArrayLiteral *E); 47150b57cec5SDimitry Andric llvm::Value *EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E); 47160b57cec5SDimitry Andric llvm::Value *EmitObjCCollectionLiteral(const Expr *E, 47170b57cec5SDimitry Andric const ObjCMethodDecl *MethodWithObjects); 47180b57cec5SDimitry Andric llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E); 47190b57cec5SDimitry Andric RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, 47200b57cec5SDimitry Andric ReturnValueSlot Return = ReturnValueSlot()); 47210b57cec5SDimitry Andric 47220b57cec5SDimitry Andric /// Retrieves the default cleanup kind for an ARC cleanup. 47230b57cec5SDimitry Andric /// Except under -fobjc-arc-eh, ARC cleanups are normal-only. 47240b57cec5SDimitry Andric CleanupKind getARCCleanupKind() { 47250b57cec5SDimitry Andric return CGM.getCodeGenOpts().ObjCAutoRefCountExceptions 47260b57cec5SDimitry Andric ? NormalAndEHCleanup : NormalCleanup; 47270b57cec5SDimitry Andric } 47280b57cec5SDimitry Andric 47290b57cec5SDimitry Andric // ARC primitives. 47300b57cec5SDimitry Andric void EmitARCInitWeak(Address addr, llvm::Value *value); 47310b57cec5SDimitry Andric void EmitARCDestroyWeak(Address addr); 47320b57cec5SDimitry Andric llvm::Value *EmitARCLoadWeak(Address addr); 47330b57cec5SDimitry Andric llvm::Value *EmitARCLoadWeakRetained(Address addr); 47340b57cec5SDimitry Andric llvm::Value *EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored); 47350b57cec5SDimitry Andric void emitARCCopyAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr); 47360b57cec5SDimitry Andric void emitARCMoveAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr); 47370b57cec5SDimitry Andric void EmitARCCopyWeak(Address dst, Address src); 47380b57cec5SDimitry Andric void EmitARCMoveWeak(Address dst, Address src); 47390b57cec5SDimitry Andric llvm::Value *EmitARCRetainAutorelease(QualType type, llvm::Value *value); 47400b57cec5SDimitry Andric llvm::Value *EmitARCRetainAutoreleaseNonBlock(llvm::Value *value); 47410b57cec5SDimitry Andric llvm::Value *EmitARCStoreStrong(LValue lvalue, llvm::Value *value, 47420b57cec5SDimitry Andric bool resultIgnored); 47430b57cec5SDimitry Andric llvm::Value *EmitARCStoreStrongCall(Address addr, llvm::Value *value, 47440b57cec5SDimitry Andric bool resultIgnored); 47450b57cec5SDimitry Andric llvm::Value *EmitARCRetain(QualType type, llvm::Value *value); 47460b57cec5SDimitry Andric llvm::Value *EmitARCRetainNonBlock(llvm::Value *value); 47470b57cec5SDimitry Andric llvm::Value *EmitARCRetainBlock(llvm::Value *value, bool mandatory); 47480b57cec5SDimitry Andric void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise); 47490b57cec5SDimitry Andric void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise); 47500b57cec5SDimitry Andric llvm::Value *EmitARCAutorelease(llvm::Value *value); 47510b57cec5SDimitry Andric llvm::Value *EmitARCAutoreleaseReturnValue(llvm::Value *value); 47520b57cec5SDimitry Andric llvm::Value *EmitARCRetainAutoreleaseReturnValue(llvm::Value *value); 47530b57cec5SDimitry Andric llvm::Value *EmitARCRetainAutoreleasedReturnValue(llvm::Value *value); 47540b57cec5SDimitry Andric llvm::Value *EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value); 47550b57cec5SDimitry Andric 47560b57cec5SDimitry Andric llvm::Value *EmitObjCAutorelease(llvm::Value *value, llvm::Type *returnType); 47570b57cec5SDimitry Andric llvm::Value *EmitObjCRetainNonBlock(llvm::Value *value, 47580b57cec5SDimitry Andric llvm::Type *returnType); 47590b57cec5SDimitry Andric void EmitObjCRelease(llvm::Value *value, ARCPreciseLifetime_t precise); 47600b57cec5SDimitry Andric 47610b57cec5SDimitry Andric std::pair<LValue,llvm::Value*> 47620b57cec5SDimitry Andric EmitARCStoreAutoreleasing(const BinaryOperator *e); 47630b57cec5SDimitry Andric std::pair<LValue,llvm::Value*> 47640b57cec5SDimitry Andric EmitARCStoreStrong(const BinaryOperator *e, bool ignored); 47650b57cec5SDimitry Andric std::pair<LValue,llvm::Value*> 47660b57cec5SDimitry Andric EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored); 47670b57cec5SDimitry Andric 47680b57cec5SDimitry Andric llvm::Value *EmitObjCAlloc(llvm::Value *value, 47690b57cec5SDimitry Andric llvm::Type *returnType); 47700b57cec5SDimitry Andric llvm::Value *EmitObjCAllocWithZone(llvm::Value *value, 47710b57cec5SDimitry Andric llvm::Type *returnType); 47720b57cec5SDimitry Andric llvm::Value *EmitObjCAllocInit(llvm::Value *value, llvm::Type *resultType); 47730b57cec5SDimitry Andric 47740b57cec5SDimitry Andric llvm::Value *EmitObjCThrowOperand(const Expr *expr); 47750b57cec5SDimitry Andric llvm::Value *EmitObjCConsumeObject(QualType T, llvm::Value *Ptr); 47760b57cec5SDimitry Andric llvm::Value *EmitObjCExtendObjectLifetime(QualType T, llvm::Value *Ptr); 47770b57cec5SDimitry Andric 47780b57cec5SDimitry Andric llvm::Value *EmitARCExtendBlockObject(const Expr *expr); 47790b57cec5SDimitry Andric llvm::Value *EmitARCReclaimReturnedObject(const Expr *e, 47800b57cec5SDimitry Andric bool allowUnsafeClaim); 47810b57cec5SDimitry Andric llvm::Value *EmitARCRetainScalarExpr(const Expr *expr); 47820b57cec5SDimitry Andric llvm::Value *EmitARCRetainAutoreleaseScalarExpr(const Expr *expr); 47830b57cec5SDimitry Andric llvm::Value *EmitARCUnsafeUnretainedScalarExpr(const Expr *expr); 47840b57cec5SDimitry Andric 47850b57cec5SDimitry Andric void EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values); 47860b57cec5SDimitry Andric 4787fe6060f1SDimitry Andric void EmitARCNoopIntrinsicUse(ArrayRef<llvm::Value *> values); 4788fe6060f1SDimitry Andric 47890b57cec5SDimitry Andric static Destroyer destroyARCStrongImprecise; 47900b57cec5SDimitry Andric static Destroyer destroyARCStrongPrecise; 47910b57cec5SDimitry Andric static Destroyer destroyARCWeak; 47920b57cec5SDimitry Andric static Destroyer emitARCIntrinsicUse; 47930b57cec5SDimitry Andric static Destroyer destroyNonTrivialCStruct; 47940b57cec5SDimitry Andric 47950b57cec5SDimitry Andric void EmitObjCAutoreleasePoolPop(llvm::Value *Ptr); 47960b57cec5SDimitry Andric llvm::Value *EmitObjCAutoreleasePoolPush(); 47970b57cec5SDimitry Andric llvm::Value *EmitObjCMRRAutoreleasePoolPush(); 47980b57cec5SDimitry Andric void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr); 47990b57cec5SDimitry Andric void EmitObjCMRRAutoreleasePoolPop(llvm::Value *Ptr); 48000b57cec5SDimitry Andric 48010b57cec5SDimitry Andric /// Emits a reference binding to the passed in expression. 48020b57cec5SDimitry Andric RValue EmitReferenceBindingToExpr(const Expr *E); 48030b57cec5SDimitry Andric 48040b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 48050b57cec5SDimitry Andric // Expression Emission 48060b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 48070b57cec5SDimitry Andric 48080b57cec5SDimitry Andric // Expressions are broken into three classes: scalar, complex, aggregate. 48090b57cec5SDimitry Andric 48100b57cec5SDimitry Andric /// EmitScalarExpr - Emit the computation of the specified expression of LLVM 48110b57cec5SDimitry Andric /// scalar type, returning the result. 48120b57cec5SDimitry Andric llvm::Value *EmitScalarExpr(const Expr *E , bool IgnoreResultAssign = false); 48130b57cec5SDimitry Andric 48140b57cec5SDimitry Andric /// Emit a conversion from the specified type to the specified destination 48150b57cec5SDimitry Andric /// type, both of which are LLVM scalar types. 48160b57cec5SDimitry Andric llvm::Value *EmitScalarConversion(llvm::Value *Src, QualType SrcTy, 48170b57cec5SDimitry Andric QualType DstTy, SourceLocation Loc); 48180b57cec5SDimitry Andric 48190b57cec5SDimitry Andric /// Emit a conversion from the specified complex type to the specified 48200b57cec5SDimitry Andric /// destination type, where the destination type is an LLVM scalar type. 48210b57cec5SDimitry Andric llvm::Value *EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, 48220b57cec5SDimitry Andric QualType DstTy, 48230b57cec5SDimitry Andric SourceLocation Loc); 48240b57cec5SDimitry Andric 48250b57cec5SDimitry Andric /// EmitAggExpr - Emit the computation of the specified expression 48260b57cec5SDimitry Andric /// of aggregate type. The result is computed into the given slot, 48270b57cec5SDimitry Andric /// which may be null to indicate that the value is not needed. 48280b57cec5SDimitry Andric void EmitAggExpr(const Expr *E, AggValueSlot AS); 48290b57cec5SDimitry Andric 48300b57cec5SDimitry Andric /// EmitAggExprToLValue - Emit the computation of the specified expression of 48310b57cec5SDimitry Andric /// aggregate type into a temporary LValue. 48320b57cec5SDimitry Andric LValue EmitAggExprToLValue(const Expr *E); 48330b57cec5SDimitry Andric 48340fca6ea1SDimitry Andric enum ExprValueKind { EVK_RValue, EVK_NonRValue }; 48350fca6ea1SDimitry Andric 48360fca6ea1SDimitry Andric /// EmitAggFinalDestCopy - Emit copy of the specified aggregate into 48370fca6ea1SDimitry Andric /// destination address. 48380fca6ea1SDimitry Andric void EmitAggFinalDestCopy(QualType Type, AggValueSlot Dest, const LValue &Src, 48390fca6ea1SDimitry Andric ExprValueKind SrcKind); 48400fca6ea1SDimitry Andric 4841*c80e69b0SDimitry Andric /// Create a store to \arg DstPtr from \arg Src, truncating the stored value 4842*c80e69b0SDimitry Andric /// to at most \arg DstSize bytes. 4843*c80e69b0SDimitry Andric void CreateCoercedStore(llvm::Value *Src, Address Dst, llvm::TypeSize DstSize, 4844*c80e69b0SDimitry Andric bool DstIsVolatile); 48455ffd83dbSDimitry Andric 48460b57cec5SDimitry Andric /// EmitExtendGCLifetime - Given a pointer to an Objective-C object, 48470b57cec5SDimitry Andric /// make sure it survives garbage collection until this point. 48480b57cec5SDimitry Andric void EmitExtendGCLifetime(llvm::Value *object); 48490b57cec5SDimitry Andric 48500b57cec5SDimitry Andric /// EmitComplexExpr - Emit the computation of the specified expression of 48510b57cec5SDimitry Andric /// complex type, returning the result. 48520b57cec5SDimitry Andric ComplexPairTy EmitComplexExpr(const Expr *E, 48530b57cec5SDimitry Andric bool IgnoreReal = false, 48540b57cec5SDimitry Andric bool IgnoreImag = false); 48550b57cec5SDimitry Andric 48560b57cec5SDimitry Andric /// EmitComplexExprIntoLValue - Emit the given expression of complex 48570b57cec5SDimitry Andric /// type and place its result into the specified l-value. 48580b57cec5SDimitry Andric void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit); 48590b57cec5SDimitry Andric 48600b57cec5SDimitry Andric /// EmitStoreOfComplex - Store a complex number into the specified l-value. 48610b57cec5SDimitry Andric void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit); 48620b57cec5SDimitry Andric 48630b57cec5SDimitry Andric /// EmitLoadOfComplex - Load a complex number from the specified l-value. 48640b57cec5SDimitry Andric ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc); 48650b57cec5SDimitry Andric 4866bdd1243dSDimitry Andric ComplexPairTy EmitPromotedComplexExpr(const Expr *E, QualType PromotionType); 4867bdd1243dSDimitry Andric llvm::Value *EmitPromotedScalarExpr(const Expr *E, QualType PromotionType); 4868bdd1243dSDimitry Andric ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType); 4869bdd1243dSDimitry Andric ComplexPairTy EmitUnPromotedValue(ComplexPairTy result, QualType PromotionType); 4870bdd1243dSDimitry Andric 48710b57cec5SDimitry Andric Address emitAddrOfRealComponent(Address complex, QualType complexType); 48720b57cec5SDimitry Andric Address emitAddrOfImagComponent(Address complex, QualType complexType); 48730b57cec5SDimitry Andric 48740b57cec5SDimitry Andric /// AddInitializerToStaticVarDecl - Add the initializer for 'D' to the 48750b57cec5SDimitry Andric /// global variable that has already been created for it. If the initializer 48760b57cec5SDimitry Andric /// has a different type than GV does, this may free GV and return a different 48770b57cec5SDimitry Andric /// one. Otherwise it just returns GV. 48780b57cec5SDimitry Andric llvm::GlobalVariable * 48790b57cec5SDimitry Andric AddInitializerToStaticVarDecl(const VarDecl &D, 48800b57cec5SDimitry Andric llvm::GlobalVariable *GV); 48810b57cec5SDimitry Andric 48820b57cec5SDimitry Andric // Emit an @llvm.invariant.start call for the given memory region. 48830b57cec5SDimitry Andric void EmitInvariantStart(llvm::Constant *Addr, CharUnits Size); 48840b57cec5SDimitry Andric 48850b57cec5SDimitry Andric /// EmitCXXGlobalVarDeclInit - Create the initializer for a C++ 48860b57cec5SDimitry Andric /// variable with global storage. 48870eae32dcSDimitry Andric void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV, 48880b57cec5SDimitry Andric bool PerformInit); 48890b57cec5SDimitry Andric 48900fca6ea1SDimitry Andric llvm::Constant *createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, 48910b57cec5SDimitry Andric llvm::Constant *Addr); 48920b57cec5SDimitry Andric 4893fe6060f1SDimitry Andric llvm::Function *createTLSAtExitStub(const VarDecl &VD, 4894fe6060f1SDimitry Andric llvm::FunctionCallee Dtor, 4895fe6060f1SDimitry Andric llvm::Constant *Addr, 4896fe6060f1SDimitry Andric llvm::FunctionCallee &AtExit); 4897fe6060f1SDimitry Andric 48980b57cec5SDimitry Andric /// Call atexit() with a function that passes the given argument to 48990b57cec5SDimitry Andric /// the given function. 49000b57cec5SDimitry Andric void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, 49010b57cec5SDimitry Andric llvm::Constant *addr); 49020b57cec5SDimitry Andric 49035f757f3fSDimitry Andric /// Registers the dtor using 'llvm.global_dtors' for platforms that do not 49045f757f3fSDimitry Andric /// support an 'atexit()' function. 49055f757f3fSDimitry Andric void registerGlobalDtorWithLLVM(const VarDecl &D, llvm::FunctionCallee fn, 49065f757f3fSDimitry Andric llvm::Constant *addr); 49075f757f3fSDimitry Andric 49080b57cec5SDimitry Andric /// Call atexit() with function dtorStub. 49090b57cec5SDimitry Andric void registerGlobalDtorWithAtExit(llvm::Constant *dtorStub); 49100b57cec5SDimitry Andric 49115ffd83dbSDimitry Andric /// Call unatexit() with function dtorStub. 4912e8d8bef9SDimitry Andric llvm::Value *unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub); 49135ffd83dbSDimitry Andric 49140b57cec5SDimitry Andric /// Emit code in this function to perform a guarded variable 49150b57cec5SDimitry Andric /// initialization. Guarded initializations are used when it's not 49160b57cec5SDimitry Andric /// possible to prove that an initialization will be done exactly 49170b57cec5SDimitry Andric /// once, e.g. with a static local variable or a static data member 49180b57cec5SDimitry Andric /// of a class template. 49190b57cec5SDimitry Andric void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr, 49200b57cec5SDimitry Andric bool PerformInit); 49210b57cec5SDimitry Andric 49220b57cec5SDimitry Andric enum class GuardKind { VariableGuard, TlsGuard }; 49230b57cec5SDimitry Andric 49240b57cec5SDimitry Andric /// Emit a branch to select whether or not to perform guarded initialization. 49250b57cec5SDimitry Andric void EmitCXXGuardedInitBranch(llvm::Value *NeedsInit, 49260b57cec5SDimitry Andric llvm::BasicBlock *InitBlock, 49270b57cec5SDimitry Andric llvm::BasicBlock *NoInitBlock, 49280b57cec5SDimitry Andric GuardKind Kind, const VarDecl *D); 49290b57cec5SDimitry Andric 49300b57cec5SDimitry Andric /// GenerateCXXGlobalInitFunc - Generates code for initializing global 49310b57cec5SDimitry Andric /// variables. 49320b57cec5SDimitry Andric void 49330b57cec5SDimitry Andric GenerateCXXGlobalInitFunc(llvm::Function *Fn, 49340b57cec5SDimitry Andric ArrayRef<llvm::Function *> CXXThreadLocals, 49350b57cec5SDimitry Andric ConstantAddress Guard = ConstantAddress::invalid()); 49360b57cec5SDimitry Andric 49375ffd83dbSDimitry Andric /// GenerateCXXGlobalCleanUpFunc - Generates code for cleaning up global 49380b57cec5SDimitry Andric /// variables. 49395ffd83dbSDimitry Andric void GenerateCXXGlobalCleanUpFunc( 49400b57cec5SDimitry Andric llvm::Function *Fn, 4941fe6060f1SDimitry Andric ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH, 4942fe6060f1SDimitry Andric llvm::Constant *>> 4943fe6060f1SDimitry Andric DtorsOrStermFinalizers); 49440b57cec5SDimitry Andric 49450b57cec5SDimitry Andric void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, 49460b57cec5SDimitry Andric const VarDecl *D, 49470b57cec5SDimitry Andric llvm::GlobalVariable *Addr, 49480b57cec5SDimitry Andric bool PerformInit); 49490b57cec5SDimitry Andric 49500b57cec5SDimitry Andric void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest); 49510b57cec5SDimitry Andric 49520b57cec5SDimitry Andric void EmitSynthesizedCXXCopyCtor(Address Dest, Address Src, const Expr *Exp); 49530b57cec5SDimitry Andric 49540b57cec5SDimitry Andric void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint = true); 49550b57cec5SDimitry Andric 49560b57cec5SDimitry Andric RValue EmitAtomicExpr(AtomicExpr *E); 49570b57cec5SDimitry Andric 49580b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 49590b57cec5SDimitry Andric // Annotations Emission 49600b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 49610b57cec5SDimitry Andric 49620b57cec5SDimitry Andric /// Emit an annotation call (intrinsic). 49630b57cec5SDimitry Andric llvm::Value *EmitAnnotationCall(llvm::Function *AnnotationFn, 49640b57cec5SDimitry Andric llvm::Value *AnnotatedVal, 49650b57cec5SDimitry Andric StringRef AnnotationStr, 4966e8d8bef9SDimitry Andric SourceLocation Location, 4967e8d8bef9SDimitry Andric const AnnotateAttr *Attr); 49680b57cec5SDimitry Andric 49690b57cec5SDimitry Andric /// Emit local annotations for the local variable V, declared by D. 49700b57cec5SDimitry Andric void EmitVarAnnotations(const VarDecl *D, llvm::Value *V); 49710b57cec5SDimitry Andric 49720b57cec5SDimitry Andric /// Emit field annotations for the given field & value. Returns the 49730b57cec5SDimitry Andric /// annotation result. 49740b57cec5SDimitry Andric Address EmitFieldAnnotations(const FieldDecl *D, Address V); 49750b57cec5SDimitry Andric 49760b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 49770b57cec5SDimitry Andric // Internal Helpers 49780b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 49790b57cec5SDimitry Andric 49800b57cec5SDimitry Andric /// ContainsLabel - Return true if the statement contains a label in it. If 49810b57cec5SDimitry Andric /// this statement is not executed normally, it not containing a label means 49820b57cec5SDimitry Andric /// that we can just remove the code. 49830b57cec5SDimitry Andric static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts = false); 49840b57cec5SDimitry Andric 49850b57cec5SDimitry Andric /// containsBreak - Return true if the statement contains a break out of it. 49860b57cec5SDimitry Andric /// If the statement (recursively) contains a switch or loop with a break 49870b57cec5SDimitry Andric /// inside of it, this is fine. 49880b57cec5SDimitry Andric static bool containsBreak(const Stmt *S); 49890b57cec5SDimitry Andric 49900b57cec5SDimitry Andric /// Determine if the given statement might introduce a declaration into the 49910b57cec5SDimitry Andric /// current scope, by being a (possibly-labelled) DeclStmt. 49920b57cec5SDimitry Andric static bool mightAddDeclToScope(const Stmt *S); 49930b57cec5SDimitry Andric 49940b57cec5SDimitry Andric /// ConstantFoldsToSimpleInteger - If the specified expression does not fold 49950b57cec5SDimitry Andric /// to a constant, or if it does but contains a label, return false. If it 49960b57cec5SDimitry Andric /// constant folds return true and set the boolean result in Result. 49970b57cec5SDimitry Andric bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, 49980b57cec5SDimitry Andric bool AllowLabels = false); 49990b57cec5SDimitry Andric 50000b57cec5SDimitry Andric /// ConstantFoldsToSimpleInteger - If the specified expression does not fold 50010b57cec5SDimitry Andric /// to a constant, or if it does but contains a label, return false. If it 50020b57cec5SDimitry Andric /// constant folds return true and set the folded value. 50030b57cec5SDimitry Andric bool ConstantFoldsToSimpleInteger(const Expr *Cond, llvm::APSInt &Result, 50040b57cec5SDimitry Andric bool AllowLabels = false); 50050b57cec5SDimitry Andric 50061db9f3b2SDimitry Andric /// Ignore parentheses and logical-NOT to track conditions consistently. 50071db9f3b2SDimitry Andric static const Expr *stripCond(const Expr *C); 50081db9f3b2SDimitry Andric 5009e8d8bef9SDimitry Andric /// isInstrumentedCondition - Determine whether the given condition is an 5010e8d8bef9SDimitry Andric /// instrumentable condition (i.e. no "&&" or "||"). 5011e8d8bef9SDimitry Andric static bool isInstrumentedCondition(const Expr *C); 5012e8d8bef9SDimitry Andric 5013e8d8bef9SDimitry Andric /// EmitBranchToCounterBlock - Emit a conditional branch to a new block that 5014e8d8bef9SDimitry Andric /// increments a profile counter based on the semantics of the given logical 5015e8d8bef9SDimitry Andric /// operator opcode. This is used to instrument branch condition coverage 5016e8d8bef9SDimitry Andric /// for logical operators. 5017e8d8bef9SDimitry Andric void EmitBranchToCounterBlock(const Expr *Cond, BinaryOperator::Opcode LOp, 5018e8d8bef9SDimitry Andric llvm::BasicBlock *TrueBlock, 5019e8d8bef9SDimitry Andric llvm::BasicBlock *FalseBlock, 5020e8d8bef9SDimitry Andric uint64_t TrueCount = 0, 5021e8d8bef9SDimitry Andric Stmt::Likelihood LH = Stmt::LH_None, 5022e8d8bef9SDimitry Andric const Expr *CntrIdx = nullptr); 5023e8d8bef9SDimitry Andric 50240b57cec5SDimitry Andric /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an 50250b57cec5SDimitry Andric /// if statement) to the specified blocks. Based on the condition, this might 50260b57cec5SDimitry Andric /// try to simplify the codegen of the conditional based on the branch. 50270b57cec5SDimitry Andric /// TrueCount should be the number of times we expect the condition to 50280b57cec5SDimitry Andric /// evaluate to true based on PGO data. 50290b57cec5SDimitry Andric void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, 5030e8d8bef9SDimitry Andric llvm::BasicBlock *FalseBlock, uint64_t TrueCount, 50311db9f3b2SDimitry Andric Stmt::Likelihood LH = Stmt::LH_None, 50321db9f3b2SDimitry Andric const Expr *ConditionalOp = nullptr); 50330b57cec5SDimitry Andric 50340b57cec5SDimitry Andric /// Given an assignment `*LHS = RHS`, emit a test that checks if \p RHS is 50350b57cec5SDimitry Andric /// nonnull, if \p LHS is marked _Nonnull. 50360b57cec5SDimitry Andric void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc); 50370b57cec5SDimitry Andric 50380b57cec5SDimitry Andric /// An enumeration which makes it easier to specify whether or not an 50390b57cec5SDimitry Andric /// operation is a subtraction. 50400b57cec5SDimitry Andric enum { NotSubtraction = false, IsSubtraction = true }; 50410b57cec5SDimitry Andric 50420b57cec5SDimitry Andric /// Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to 50430b57cec5SDimitry Andric /// detect undefined behavior when the pointer overflow sanitizer is enabled. 50440b57cec5SDimitry Andric /// \p SignedIndices indicates whether any of the GEP indices are signed. 50450b57cec5SDimitry Andric /// \p IsSubtraction indicates whether the expression used to form the GEP 50460b57cec5SDimitry Andric /// is a subtraction. 50470eae32dcSDimitry Andric llvm::Value *EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr, 50480b57cec5SDimitry Andric ArrayRef<llvm::Value *> IdxList, 50490b57cec5SDimitry Andric bool SignedIndices, 50500b57cec5SDimitry Andric bool IsSubtraction, 50510b57cec5SDimitry Andric SourceLocation Loc, 50520b57cec5SDimitry Andric const Twine &Name = ""); 50530b57cec5SDimitry Andric 50540fca6ea1SDimitry Andric Address EmitCheckedInBoundsGEP(Address Addr, ArrayRef<llvm::Value *> IdxList, 50550fca6ea1SDimitry Andric llvm::Type *elementType, bool SignedIndices, 50560fca6ea1SDimitry Andric bool IsSubtraction, SourceLocation Loc, 50570fca6ea1SDimitry Andric CharUnits Align, const Twine &Name = ""); 50580fca6ea1SDimitry Andric 50590b57cec5SDimitry Andric /// Specifies which type of sanitizer check to apply when handling a 50600b57cec5SDimitry Andric /// particular builtin. 50610b57cec5SDimitry Andric enum BuiltinCheckKind { 50620b57cec5SDimitry Andric BCK_CTZPassedZero, 50630b57cec5SDimitry Andric BCK_CLZPassedZero, 50640b57cec5SDimitry Andric }; 50650b57cec5SDimitry Andric 50660b57cec5SDimitry Andric /// Emits an argument for a call to a builtin. If the builtin sanitizer is 50670b57cec5SDimitry Andric /// enabled, a runtime check specified by \p Kind is also emitted. 50680b57cec5SDimitry Andric llvm::Value *EmitCheckedArgForBuiltin(const Expr *E, BuiltinCheckKind Kind); 50690b57cec5SDimitry Andric 50700b57cec5SDimitry Andric /// Emit a description of a type in a format suitable for passing to 50710b57cec5SDimitry Andric /// a runtime sanitizer handler. 50720b57cec5SDimitry Andric llvm::Constant *EmitCheckTypeDescriptor(QualType T); 50730b57cec5SDimitry Andric 50740b57cec5SDimitry Andric /// Convert a value into a format suitable for passing to a runtime 50750b57cec5SDimitry Andric /// sanitizer handler. 50760b57cec5SDimitry Andric llvm::Value *EmitCheckValue(llvm::Value *V); 50770b57cec5SDimitry Andric 50780b57cec5SDimitry Andric /// Emit a description of a source location in a format suitable for 50790b57cec5SDimitry Andric /// passing to a runtime sanitizer handler. 50800b57cec5SDimitry Andric llvm::Constant *EmitCheckSourceLocation(SourceLocation Loc); 50810b57cec5SDimitry Andric 5082bdd1243dSDimitry Andric void EmitKCFIOperandBundle(const CGCallee &Callee, 5083bdd1243dSDimitry Andric SmallVectorImpl<llvm::OperandBundleDef> &Bundles); 5084bdd1243dSDimitry Andric 50850b57cec5SDimitry Andric /// Create a basic block that will either trap or call a handler function in 50860b57cec5SDimitry Andric /// the UBSan runtime with the provided arguments, and create a conditional 50870b57cec5SDimitry Andric /// branch to it. 50880b57cec5SDimitry Andric void EmitCheck(ArrayRef<std::pair<llvm::Value *, SanitizerMask>> Checked, 50890b57cec5SDimitry Andric SanitizerHandler Check, ArrayRef<llvm::Constant *> StaticArgs, 50900b57cec5SDimitry Andric ArrayRef<llvm::Value *> DynamicArgs); 50910b57cec5SDimitry Andric 50920b57cec5SDimitry Andric /// Emit a slow path cross-DSO CFI check which calls __cfi_slowpath 50930b57cec5SDimitry Andric /// if Cond if false. 50940b57cec5SDimitry Andric void EmitCfiSlowPathCheck(SanitizerMask Kind, llvm::Value *Cond, 50950b57cec5SDimitry Andric llvm::ConstantInt *TypeId, llvm::Value *Ptr, 50960b57cec5SDimitry Andric ArrayRef<llvm::Constant *> StaticArgs); 50970b57cec5SDimitry Andric 50980b57cec5SDimitry Andric /// Emit a reached-unreachable diagnostic if \p Loc is valid and runtime 50990b57cec5SDimitry Andric /// checking is enabled. Otherwise, just emit an unreachable instruction. 51000b57cec5SDimitry Andric void EmitUnreachable(SourceLocation Loc); 51010b57cec5SDimitry Andric 51020b57cec5SDimitry Andric /// Create a basic block that will call the trap intrinsic, and emit a 51030b57cec5SDimitry Andric /// conditional branch to it, for the -ftrapv checks. 5104e8d8bef9SDimitry Andric void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID); 51050b57cec5SDimitry Andric 51060b57cec5SDimitry Andric /// Emit a call to trap or debugtrap and attach function attribute 51070b57cec5SDimitry Andric /// "trap-func-name" if specified. 51080b57cec5SDimitry Andric llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID); 51090b57cec5SDimitry Andric 51100b57cec5SDimitry Andric /// Emit a stub for the cross-DSO CFI check function. 51110b57cec5SDimitry Andric void EmitCfiCheckStub(); 51120b57cec5SDimitry Andric 51130b57cec5SDimitry Andric /// Emit a cross-DSO CFI failure handling function. 51140b57cec5SDimitry Andric void EmitCfiCheckFail(); 51150b57cec5SDimitry Andric 51160b57cec5SDimitry Andric /// Create a check for a function parameter that may potentially be 51170b57cec5SDimitry Andric /// declared as non-null. 51180b57cec5SDimitry Andric void EmitNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc, 51190b57cec5SDimitry Andric AbstractCallee AC, unsigned ParmNum); 51200b57cec5SDimitry Andric 51210fca6ea1SDimitry Andric void EmitNonNullArgCheck(Address Addr, QualType ArgType, 51220fca6ea1SDimitry Andric SourceLocation ArgLoc, AbstractCallee AC, 51230fca6ea1SDimitry Andric unsigned ParmNum); 51240fca6ea1SDimitry Andric 51250b57cec5SDimitry Andric /// EmitCallArg - Emit a single call argument. 51260b57cec5SDimitry Andric void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType); 51270b57cec5SDimitry Andric 51280b57cec5SDimitry Andric /// EmitDelegateCallArg - We are performing a delegate call; that 51290b57cec5SDimitry Andric /// is, the current function is delegating to another one. Produce 51300b57cec5SDimitry Andric /// a r-value suitable for passing the given parameter. 51310b57cec5SDimitry Andric void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, 51320b57cec5SDimitry Andric SourceLocation loc); 51330b57cec5SDimitry Andric 51340b57cec5SDimitry Andric /// SetFPAccuracy - Set the minimum required accuracy of the given floating 51350b57cec5SDimitry Andric /// point operation, expressed as the maximum relative error in ulp. 51360b57cec5SDimitry Andric void SetFPAccuracy(llvm::Value *Val, float Accuracy); 51370b57cec5SDimitry Andric 513806c3fb27SDimitry Andric /// Set the minimum required accuracy of the given sqrt operation 513906c3fb27SDimitry Andric /// based on CodeGenOpts. 514006c3fb27SDimitry Andric void SetSqrtFPAccuracy(llvm::Value *Val); 514106c3fb27SDimitry Andric 514206c3fb27SDimitry Andric /// Set the minimum required accuracy of the given sqrt operation based on 514306c3fb27SDimitry Andric /// CodeGenOpts. 514406c3fb27SDimitry Andric void SetDivFPAccuracy(llvm::Value *Val); 514506c3fb27SDimitry Andric 51465ffd83dbSDimitry Andric /// Set the codegen fast-math flags. 51475ffd83dbSDimitry Andric void SetFastMathFlags(FPOptions FPFeatures); 51485ffd83dbSDimitry Andric 514981ad6265SDimitry Andric // Truncate or extend a boolean vector to the requested number of elements. 515081ad6265SDimitry Andric llvm::Value *emitBoolVecConversion(llvm::Value *SrcVec, 515181ad6265SDimitry Andric unsigned NumElementsDst, 515281ad6265SDimitry Andric const llvm::Twine &Name = ""); 51530fca6ea1SDimitry Andric // Adds a convergence_ctrl token to |Input| and emits the required parent 51540fca6ea1SDimitry Andric // convergence instructions. 51550fca6ea1SDimitry Andric template <typename CallType> 51560fca6ea1SDimitry Andric CallType *addControlledConvergenceToken(CallType *Input) { 51570fca6ea1SDimitry Andric return cast<CallType>( 51580fca6ea1SDimitry Andric addConvergenceControlToken(Input, ConvergenceTokenStack.back())); 51590fca6ea1SDimitry Andric } 51600fca6ea1SDimitry Andric 51610fca6ea1SDimitry Andric private: 51620fca6ea1SDimitry Andric // Emits a convergence_loop instruction for the given |BB|, with |ParentToken| 51630fca6ea1SDimitry Andric // as it's parent convergence instr. 51640fca6ea1SDimitry Andric llvm::IntrinsicInst *emitConvergenceLoopToken(llvm::BasicBlock *BB, 51650fca6ea1SDimitry Andric llvm::Value *ParentToken); 51660fca6ea1SDimitry Andric // Adds a convergence_ctrl token with |ParentToken| as parent convergence 51670fca6ea1SDimitry Andric // instr to the call |Input|. 51680fca6ea1SDimitry Andric llvm::CallBase *addConvergenceControlToken(llvm::CallBase *Input, 51690fca6ea1SDimitry Andric llvm::Value *ParentToken); 51700fca6ea1SDimitry Andric // Find the convergence_entry instruction |F|, or emits ones if none exists. 51710fca6ea1SDimitry Andric // Returns the convergence instruction. 51720fca6ea1SDimitry Andric llvm::IntrinsicInst *getOrEmitConvergenceEntryToken(llvm::Function *F); 51730fca6ea1SDimitry Andric // Find the convergence_loop instruction for the loop defined by |LI|, or 51740fca6ea1SDimitry Andric // emits one if none exists. Returns the convergence instruction. 51750fca6ea1SDimitry Andric llvm::IntrinsicInst *getOrEmitConvergenceLoopToken(const LoopInfo *LI); 517681ad6265SDimitry Andric 51770b57cec5SDimitry Andric private: 51780b57cec5SDimitry Andric llvm::MDNode *getRangeForLoadFromType(QualType Ty); 51790b57cec5SDimitry Andric void EmitReturnOfRValue(RValue RV, QualType Ty); 51800b57cec5SDimitry Andric 51810b57cec5SDimitry Andric void deferPlaceholderReplacement(llvm::Instruction *Old, llvm::Value *New); 51820b57cec5SDimitry Andric 5183fe6060f1SDimitry Andric llvm::SmallVector<std::pair<llvm::WeakTrackingVH, llvm::Value *>, 4> 51840b57cec5SDimitry Andric DeferredReplacements; 51850b57cec5SDimitry Andric 51860b57cec5SDimitry Andric /// Set the address of a local variable. 51870b57cec5SDimitry Andric void setAddrOfLocalVar(const VarDecl *VD, Address Addr) { 51880b57cec5SDimitry Andric assert(!LocalDeclMap.count(VD) && "Decl already exists in LocalDeclMap!"); 51890b57cec5SDimitry Andric LocalDeclMap.insert({VD, Addr}); 51900b57cec5SDimitry Andric } 51910b57cec5SDimitry Andric 51920b57cec5SDimitry Andric /// ExpandTypeFromArgs - Reconstruct a structure of type \arg Ty 51930b57cec5SDimitry Andric /// from function arguments into \arg Dst. See ABIArgInfo::Expand. 51940b57cec5SDimitry Andric /// 51950b57cec5SDimitry Andric /// \param AI - The first function argument of the expansion. 51960b57cec5SDimitry Andric void ExpandTypeFromArgs(QualType Ty, LValue Dst, 51975ffd83dbSDimitry Andric llvm::Function::arg_iterator &AI); 51980b57cec5SDimitry Andric 51990b57cec5SDimitry Andric /// ExpandTypeToArgs - Expand an CallArg \arg Arg, with the LLVM type for \arg 52000b57cec5SDimitry Andric /// Ty, into individual arguments on the provided vector \arg IRCallArgs, 52010b57cec5SDimitry Andric /// starting at index \arg IRCallArgPos. See ABIArgInfo::Expand. 52020b57cec5SDimitry Andric void ExpandTypeToArgs(QualType Ty, CallArg Arg, llvm::FunctionType *IRFuncTy, 52030b57cec5SDimitry Andric SmallVectorImpl<llvm::Value *> &IRCallArgs, 52040b57cec5SDimitry Andric unsigned &IRCallArgPos); 52050b57cec5SDimitry Andric 520604eeddc0SDimitry Andric std::pair<llvm::Value *, llvm::Type *> 520704eeddc0SDimitry Andric EmitAsmInput(const TargetInfo::ConstraintInfo &Info, const Expr *InputExpr, 520804eeddc0SDimitry Andric std::string &ConstraintStr); 52090b57cec5SDimitry Andric 521004eeddc0SDimitry Andric std::pair<llvm::Value *, llvm::Type *> 521104eeddc0SDimitry Andric EmitAsmInputLValue(const TargetInfo::ConstraintInfo &Info, LValue InputValue, 521204eeddc0SDimitry Andric QualType InputType, std::string &ConstraintStr, 52130b57cec5SDimitry Andric SourceLocation Loc); 52140b57cec5SDimitry Andric 52150b57cec5SDimitry Andric /// Attempts to statically evaluate the object size of E. If that 52160b57cec5SDimitry Andric /// fails, emits code to figure the size of E out for us. This is 52170b57cec5SDimitry Andric /// pass_object_size aware. 52180b57cec5SDimitry Andric /// 52190b57cec5SDimitry Andric /// If EmittedExpr is non-null, this will use that instead of re-emitting E. 52200b57cec5SDimitry Andric llvm::Value *evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type, 52210b57cec5SDimitry Andric llvm::IntegerType *ResType, 52220b57cec5SDimitry Andric llvm::Value *EmittedE, 52230b57cec5SDimitry Andric bool IsDynamic); 52240b57cec5SDimitry Andric 52250b57cec5SDimitry Andric /// Emits the size of E, as required by __builtin_object_size. This 52260b57cec5SDimitry Andric /// function is aware of pass_object_size parameters, and will act accordingly 52270b57cec5SDimitry Andric /// if E is a parameter with the pass_object_size attribute. 52280b57cec5SDimitry Andric llvm::Value *emitBuiltinObjectSize(const Expr *E, unsigned Type, 52290b57cec5SDimitry Andric llvm::IntegerType *ResType, 52300b57cec5SDimitry Andric llvm::Value *EmittedE, 52310b57cec5SDimitry Andric bool IsDynamic); 52320b57cec5SDimitry Andric 5233297eecfbSDimitry Andric llvm::Value *emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, 5234297eecfbSDimitry Andric llvm::IntegerType *ResType); 5235297eecfbSDimitry Andric 52360b57cec5SDimitry Andric void emitZeroOrPatternForAutoVarInit(QualType type, const VarDecl &D, 52370b57cec5SDimitry Andric Address Loc); 52380b57cec5SDimitry Andric 52390b57cec5SDimitry Andric public: 52400b57cec5SDimitry Andric enum class EvaluationOrder { 52410b57cec5SDimitry Andric ///! No language constraints on evaluation order. 52420b57cec5SDimitry Andric Default, 52430b57cec5SDimitry Andric ///! Language semantics require left-to-right evaluation. 52440b57cec5SDimitry Andric ForceLeftToRight, 52450b57cec5SDimitry Andric ///! Language semantics require right-to-left evaluation. 52460b57cec5SDimitry Andric ForceRightToLeft 52470b57cec5SDimitry Andric }; 52480b57cec5SDimitry Andric 5249e8d8bef9SDimitry Andric // Wrapper for function prototype sources. Wraps either a FunctionProtoType or 5250e8d8bef9SDimitry Andric // an ObjCMethodDecl. 5251e8d8bef9SDimitry Andric struct PrototypeWrapper { 5252e8d8bef9SDimitry Andric llvm::PointerUnion<const FunctionProtoType *, const ObjCMethodDecl *> P; 52530b57cec5SDimitry Andric 5254e8d8bef9SDimitry Andric PrototypeWrapper(const FunctionProtoType *FT) : P(FT) {} 5255e8d8bef9SDimitry Andric PrototypeWrapper(const ObjCMethodDecl *MD) : P(MD) {} 5256e8d8bef9SDimitry Andric }; 52570b57cec5SDimitry Andric 5258e8d8bef9SDimitry Andric void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, 52590b57cec5SDimitry Andric llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange, 52600b57cec5SDimitry Andric AbstractCallee AC = AbstractCallee(), 52610b57cec5SDimitry Andric unsigned ParamsToSkip = 0, 52620b57cec5SDimitry Andric EvaluationOrder Order = EvaluationOrder::Default); 52630b57cec5SDimitry Andric 52640b57cec5SDimitry Andric /// EmitPointerWithAlignment - Given an expression with a pointer type, 52650b57cec5SDimitry Andric /// emit the value and compute our best estimate of the alignment of the 52660b57cec5SDimitry Andric /// pointee. 52670b57cec5SDimitry Andric /// 52680b57cec5SDimitry Andric /// \param BaseInfo - If non-null, this will be initialized with 52690b57cec5SDimitry Andric /// information about the source of the alignment and the may-alias 52700b57cec5SDimitry Andric /// attribute. Note that this function will conservatively fall back on 52710b57cec5SDimitry Andric /// the type when it doesn't recognize the expression and may-alias will 52720b57cec5SDimitry Andric /// be set to false. 52730b57cec5SDimitry Andric /// 52740b57cec5SDimitry Andric /// One reasonable way to use this information is when there's a language 52750b57cec5SDimitry Andric /// guarantee that the pointer must be aligned to some stricter value, and 52760b57cec5SDimitry Andric /// we're simply trying to ensure that sufficiently obvious uses of under- 52770b57cec5SDimitry Andric /// aligned objects don't get miscompiled; for example, a placement new 52780b57cec5SDimitry Andric /// into the address of a local variable. In such a case, it's quite 52790b57cec5SDimitry Andric /// reasonable to just ignore the returned alignment when it isn't from an 52800b57cec5SDimitry Andric /// explicit source. 528106c3fb27SDimitry Andric Address 528206c3fb27SDimitry Andric EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo = nullptr, 528306c3fb27SDimitry Andric TBAAAccessInfo *TBAAInfo = nullptr, 528406c3fb27SDimitry Andric KnownNonNull_t IsKnownNonNull = NotKnownNonNull); 52850b57cec5SDimitry Andric 52860b57cec5SDimitry Andric /// If \p E references a parameter with pass_object_size info or a constant 52870b57cec5SDimitry Andric /// array size modifier, emit the object size divided by the size of \p EltTy. 52880b57cec5SDimitry Andric /// Otherwise return null. 52890b57cec5SDimitry Andric llvm::Value *LoadPassedObjectSize(const Expr *E, QualType EltTy); 52900b57cec5SDimitry Andric 52910b57cec5SDimitry Andric void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK); 52920b57cec5SDimitry Andric 52930b57cec5SDimitry Andric struct MultiVersionResolverOption { 52940b57cec5SDimitry Andric llvm::Function *Function; 52950b57cec5SDimitry Andric struct Conds { 52960b57cec5SDimitry Andric StringRef Architecture; 52970b57cec5SDimitry Andric llvm::SmallVector<StringRef, 8> Features; 52980b57cec5SDimitry Andric 52990b57cec5SDimitry Andric Conds(StringRef Arch, ArrayRef<StringRef> Feats) 53000b57cec5SDimitry Andric : Architecture(Arch), Features(Feats.begin(), Feats.end()) {} 53010b57cec5SDimitry Andric } Conditions; 53020b57cec5SDimitry Andric 53030b57cec5SDimitry Andric MultiVersionResolverOption(llvm::Function *F, StringRef Arch, 53040b57cec5SDimitry Andric ArrayRef<StringRef> Feats) 53050b57cec5SDimitry Andric : Function(F), Conditions(Arch, Feats) {} 53060b57cec5SDimitry Andric }; 53070b57cec5SDimitry Andric 53080b57cec5SDimitry Andric // Emits the body of a multiversion function's resolver. Assumes that the 53090b57cec5SDimitry Andric // options are already sorted in the proper order, with the 'default' option 53100b57cec5SDimitry Andric // last (if it exists). 53110b57cec5SDimitry Andric void EmitMultiVersionResolver(llvm::Function *Resolver, 53120b57cec5SDimitry Andric ArrayRef<MultiVersionResolverOption> Options); 5313bdd1243dSDimitry Andric void 5314bdd1243dSDimitry Andric EmitX86MultiVersionResolver(llvm::Function *Resolver, 5315bdd1243dSDimitry Andric ArrayRef<MultiVersionResolverOption> Options); 5316bdd1243dSDimitry Andric void 5317bdd1243dSDimitry Andric EmitAArch64MultiVersionResolver(llvm::Function *Resolver, 5318bdd1243dSDimitry Andric ArrayRef<MultiVersionResolverOption> Options); 53190b57cec5SDimitry Andric 53200b57cec5SDimitry Andric private: 53210b57cec5SDimitry Andric QualType getVarArgType(const Expr *Arg); 53220b57cec5SDimitry Andric 53230b57cec5SDimitry Andric void EmitDeclMetadata(); 53240b57cec5SDimitry Andric 53250b57cec5SDimitry Andric BlockByrefHelpers *buildByrefHelpers(llvm::StructType &byrefType, 53260b57cec5SDimitry Andric const AutoVarEmission &emission); 53270b57cec5SDimitry Andric 53280b57cec5SDimitry Andric void AddObjCARCExceptionMetadata(llvm::Instruction *Inst); 53290b57cec5SDimitry Andric 53300b57cec5SDimitry Andric llvm::Value *GetValueForARMHint(unsigned BuiltinID); 53310b57cec5SDimitry Andric llvm::Value *EmitX86CpuIs(const CallExpr *E); 53320b57cec5SDimitry Andric llvm::Value *EmitX86CpuIs(StringRef CPUStr); 53330b57cec5SDimitry Andric llvm::Value *EmitX86CpuSupports(const CallExpr *E); 53340b57cec5SDimitry Andric llvm::Value *EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs); 53355f757f3fSDimitry Andric llvm::Value *EmitX86CpuSupports(std::array<uint32_t, 4> FeatureMask); 53360b57cec5SDimitry Andric llvm::Value *EmitX86CpuInit(); 5337bdd1243dSDimitry Andric llvm::Value *FormX86ResolverCondition(const MultiVersionResolverOption &RO); 5338bdd1243dSDimitry Andric llvm::Value *EmitAArch64CpuInit(); 5339bdd1243dSDimitry Andric llvm::Value * 5340bdd1243dSDimitry Andric FormAArch64ResolverCondition(const MultiVersionResolverOption &RO); 53410fca6ea1SDimitry Andric llvm::Value *EmitAArch64CpuSupports(const CallExpr *E); 5342bdd1243dSDimitry Andric llvm::Value *EmitAArch64CpuSupports(ArrayRef<StringRef> FeatureStrs); 53430b57cec5SDimitry Andric }; 53440b57cec5SDimitry Andric 53450b57cec5SDimitry Andric inline DominatingLLVMValue::saved_type 53460b57cec5SDimitry Andric DominatingLLVMValue::save(CodeGenFunction &CGF, llvm::Value *value) { 53470b57cec5SDimitry Andric if (!needsSaving(value)) return saved_type(value, false); 53480b57cec5SDimitry Andric 53490b57cec5SDimitry Andric // Otherwise, we need an alloca. 53500b57cec5SDimitry Andric auto align = CharUnits::fromQuantity( 5351bdd1243dSDimitry Andric CGF.CGM.getDataLayout().getPrefTypeAlign(value->getType())); 53520b57cec5SDimitry Andric Address alloca = 53530b57cec5SDimitry Andric CGF.CreateTempAlloca(value->getType(), align, "cond-cleanup.save"); 53540b57cec5SDimitry Andric CGF.Builder.CreateStore(value, alloca); 53550b57cec5SDimitry Andric 53560fca6ea1SDimitry Andric return saved_type(alloca.emitRawPointer(CGF), true); 53570b57cec5SDimitry Andric } 53580b57cec5SDimitry Andric 53590b57cec5SDimitry Andric inline llvm::Value *DominatingLLVMValue::restore(CodeGenFunction &CGF, 53600b57cec5SDimitry Andric saved_type value) { 53610b57cec5SDimitry Andric // If the value says it wasn't saved, trust that it's still dominating. 53620b57cec5SDimitry Andric if (!value.getInt()) return value.getPointer(); 53630b57cec5SDimitry Andric 53640b57cec5SDimitry Andric // Otherwise, it should be an alloca instruction, as set up in save(). 53650b57cec5SDimitry Andric auto alloca = cast<llvm::AllocaInst>(value.getPointer()); 5366fe6060f1SDimitry Andric return CGF.Builder.CreateAlignedLoad(alloca->getAllocatedType(), alloca, 5367fe6060f1SDimitry Andric alloca->getAlign()); 53680b57cec5SDimitry Andric } 53690b57cec5SDimitry Andric 53700b57cec5SDimitry Andric } // end namespace CodeGen 53715ffd83dbSDimitry Andric 53725ffd83dbSDimitry Andric // Map the LangOption for floating point exception behavior into 53735ffd83dbSDimitry Andric // the corresponding enum in the IR. 53745ffd83dbSDimitry Andric llvm::fp::ExceptionBehavior 53755ffd83dbSDimitry Andric ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind); 53760b57cec5SDimitry Andric } // end namespace clang 53770b57cec5SDimitry Andric 53780b57cec5SDimitry Andric #endif 5379