diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
| commit | 344a3780b2e33f6ca763666c380202b18aab72a3 (patch) | |
| tree | f0b203ee6eb71d7fdd792373e3c81eb18d6934dd /clang/lib/CodeGen/CodeGenFunction.h | |
| parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) | |
vendor/llvm-project/llvmorg-13-init-16847-g88e66fa60ae5vendor/llvm-project/llvmorg-12.0.1-rc2-0-ge7dac564cd0evendor/llvm-project/llvmorg-12.0.1-0-gfed41342a82f
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.h')
| -rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 149 |
1 files changed, 113 insertions, 36 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 8eb7adbc8fcb..4e087ce51e37 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -50,6 +50,7 @@ class Module; class SwitchInst; class Twine; class Value; +class CanonicalLoopInfo; } namespace clang { @@ -276,6 +277,20 @@ public: // because of jumps. VarBypassDetector Bypasses; + /// List of recently emitted OMPCanonicalLoops. + /// + /// Since OMPCanonicalLoops are nested inside other statements (in particular + /// CapturedStmt generated by OMPExecutableDirective and non-perfectly nested + /// loops), we cannot directly call OMPEmitOMPCanonicalLoop and receive its + /// llvm::CanonicalLoopInfo. Instead, we call EmitStmt and any + /// OMPEmitOMPCanonicalLoop called by it will add its CanonicalLoopInfo to + /// this stack when done. Entering a new loop requires clearing this list; it + /// either means we start parsing a new loop nest (in which case the previous + /// loop nest goes out of scope) or a second loop in the same level in which + /// case it would be ambiguous into which of the two (or more) loops the loop + /// nest would extend. + SmallVector<llvm::CanonicalLoopInfo *, 4> OMPLoopNestStack; + // CodeGen lambda for loops and support for ordered clause typedef llvm::function_ref<void(CodeGenFunction &, const OMPLoopDirective &, JumpDest)> @@ -310,6 +325,9 @@ public: QualType FnRetTy; llvm::Function *CurFn = nullptr; + /// Save Parameter Decl for coroutine. + llvm::SmallVector<const ParmVarDecl *, 4> FnArgs; + // Holds coroutine data if the current function is a coroutine. We use a // wrapper to manage its lifetime, so that we don't have to define CGCoroData // in this header. @@ -502,24 +520,52 @@ public: /// True if the current statement has nomerge attribute. bool InNoMergeAttributedStmt = false; - /// True if the current function should be marked mustprogress. - bool FnIsMustProgress = false; + // The CallExpr within the current statement that the musttail attribute + // applies to. nullptr if there is no 'musttail' on the current statement. + const CallExpr *MustTailCall = nullptr; - /// True if the C++ Standard Requires Progress. - bool CPlusPlusWithProgress() { - return getLangOpts().CPlusPlus11 || getLangOpts().CPlusPlus14 || - getLangOpts().CPlusPlus17 || getLangOpts().CPlusPlus20; - } + /// Returns true if a function must make progress, which means the + /// mustprogress attribute can be added. + bool checkIfFunctionMustProgress() { + if (CGM.getCodeGenOpts().getFiniteLoops() == + CodeGenOptions::FiniteLoopsKind::Never) + return false; - /// True if the C Standard Requires Progress. - bool CWithProgress() { - return getLangOpts().C11 || getLangOpts().C17 || getLangOpts().C2x; + // C++11 and later guarantees that a thread eventually will do one of the + // following (6.9.2.3.1 in C++11): + // - terminate, + // - make a call to a library I/O function, + // - perform an access through a volatile glvalue, or + // - perform a synchronization operation or an atomic operation. + // + // Hence each function is 'mustprogress' in C++11 or later. + return getLangOpts().CPlusPlus11; } - /// True if the language standard requires progress in functions or - /// in infinite loops with non-constant conditionals. - bool LanguageRequiresProgress() { - return CWithProgress() || CPlusPlusWithProgress(); + /// Returns true if a loop must make progress, which means the mustprogress + /// attribute can be added. \p HasConstantCond indicates whether the branch + /// condition is a known constant. + bool checkIfLoopMustProgress(bool HasConstantCond) { + if (CGM.getCodeGenOpts().getFiniteLoops() == + CodeGenOptions::FiniteLoopsKind::Always) + return true; + if (CGM.getCodeGenOpts().getFiniteLoops() == + CodeGenOptions::FiniteLoopsKind::Never) + return false; + + // If the containing function must make progress, loops also must make + // progress (as in C++11 and later). + if (checkIfFunctionMustProgress()) + return true; + + // Now apply rules for plain C (see 6.8.5.6 in C11). + // Loops with constant conditions do not have to make progress in any C + // version. + if (HasConstantCond) + return false; + + // Loops with non-constant conditions must make progress in C11 and later. + return getLangOpts().C11; } const CodeGen::CGBlockInfo *BlockInfo = nullptr; @@ -539,6 +585,8 @@ public: llvm::Instruction *CurrentFuncletPad = nullptr; class CallLifetimeEnd final : public EHScopeStack::Cleanup { + bool isRedundantBeforeReturn() override { return true; } + llvm::Value *Addr; llvm::Value *Size; @@ -1419,8 +1467,9 @@ private: }; OpenMPCancelExitStack OMPCancelStack; - /// Calculate branch weights for the likelihood attribute - llvm::MDNode *createBranchWeights(Stmt::Likelihood LH) const; + /// Lower the Likelihood knowledge about the \p Cond via llvm.expect intrin. + llvm::Value *emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond, + Stmt::Likelihood LH); CodeGenPGO PGO; @@ -1431,13 +1480,6 @@ private: llvm::MDNode *createProfileWeightsForLoop(const Stmt *Cond, uint64_t LoopCount) const; - /// Calculate the branch weight for PGO data or the likelihood attribute. - /// The function tries to get the weight of \ref createProfileWeightsForLoop. - /// If that fails it gets the weight of \ref createBranchWeights. - llvm::MDNode *createProfileOrBranchWeightsForLoop(const Stmt *Cond, - uint64_t LoopCount, - const Stmt *Body) const; - public: /// Increment the profiler's counter for the given statement by \p StepV. /// If \p StepV is null, the default increment is 1. @@ -1866,8 +1908,9 @@ private: /// function attribute. unsigned LargestVectorWidth = 0; - /// True if we need emit the life-time markers. - const bool ShouldEmitLifetimeMarkers; + /// True if we need emit the life-time markers. This is initially set in + /// the constructor, but could be overwritten to true if this is a coroutine. + bool ShouldEmitLifetimeMarkers; /// Add OpenCL kernel arg metadata and the kernel attribute metadata to /// the function metadata. @@ -2824,7 +2867,12 @@ public: void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType, Address Ptr); - llvm::Value *EmitLifetimeStart(uint64_t Size, llvm::Value *Addr); + void EmitSehCppScopeBegin(); + void EmitSehCppScopeEnd(); + void EmitSehTryScopeBegin(); + void EmitSehTryScopeEnd(); + + llvm::Value *EmitLifetimeStart(llvm::TypeSize Size, llvm::Value *Addr); void EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr); llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E); @@ -3174,6 +3222,8 @@ public: void EmitSEHLeaveStmt(const SEHLeaveStmt &S); void EnterSEHTryStmt(const SEHTryStmt &S); void ExitSEHTryStmt(const SEHTryStmt &S); + void VolatilizeTryBlocks(llvm::BasicBlock *BB, + llvm::SmallPtrSet<llvm::BasicBlock *, 10> &V); void pushSEHCleanup(CleanupKind kind, llvm::Function *FinallyFunc); @@ -3390,12 +3440,15 @@ public: void EmitOMPParallelDirective(const OMPParallelDirective &S); void EmitOMPSimdDirective(const OMPSimdDirective &S); + void EmitOMPTileDirective(const OMPTileDirective &S); + void EmitOMPUnrollDirective(const OMPUnrollDirective &S); void EmitOMPForDirective(const OMPForDirective &S); void EmitOMPForSimdDirective(const OMPForSimdDirective &S); void EmitOMPSectionsDirective(const OMPSectionsDirective &S); void EmitOMPSectionDirective(const OMPSectionDirective &S); void EmitOMPSingleDirective(const OMPSingleDirective &S); void EmitOMPMasterDirective(const OMPMasterDirective &S); + void EmitOMPMaskedDirective(const OMPMaskedDirective &S); void EmitOMPCriticalDirective(const OMPCriticalDirective &S); void EmitOMPParallelForDirective(const OMPParallelForDirective &S); void EmitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &S); @@ -3499,6 +3552,18 @@ public: static void EmitOMPTargetTeamsDistributeParallelForDeviceFunction( CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeParallelForDirective &S); + + /// Emit the Stmt \p S and return its topmost canonical loop, if any. + /// TODO: The \p Depth paramter is not yet implemented and must be 1. In the + /// future it is meant to be the number of loops expected in the loop nests + /// (usually specified by the "collapse" clause) that are collapsed to a + /// single loop by this function. + llvm::CanonicalLoopInfo *EmitOMPCollapsedCanonicalLoopNest(const Stmt *S, + int Depth); + + /// Emit an OMPCanonicalLoop using the OpenMPIRBuilder. + void EmitOMPCanonicalLoop(const OMPCanonicalLoop *S); + /// Emit inner loop of the worksharing/simd construct. /// /// \param S Directive, for which the inner loop must be emitted. @@ -3535,7 +3600,7 @@ public: const CodeGenLoopTy &CodeGenLoop, Expr *IncExpr); /// Helpers for the OpenMP loop directives. - void EmitOMPSimdInit(const OMPLoopDirective &D, bool IsMonotonic = false); + void EmitOMPSimdInit(const OMPLoopDirective &D); void EmitOMPSimdFinal( const OMPLoopDirective &D, const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen); @@ -3875,12 +3940,14 @@ public: /// LLVM arguments and the types they were derived from. RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, - llvm::CallBase **callOrInvoke, SourceLocation Loc); + llvm::CallBase **callOrInvoke, bool IsMustTail, + SourceLocation Loc); RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, - llvm::CallBase **callOrInvoke = nullptr) { + llvm::CallBase **callOrInvoke = nullptr, + bool IsMustTail = false) { return EmitCall(CallInfo, Callee, ReturnValue, Args, callOrInvoke, - SourceLocation()); + IsMustTail, SourceLocation()); } RValue EmitCall(QualType FnType, const CGCallee &Callee, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Value *Chain = nullptr); @@ -4117,6 +4184,8 @@ public: llvm::Value *EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitHexagonBuiltinExpr(unsigned BuiltinID, const CallExpr *E); + llvm::Value *EmitRISCVBuiltinExpr(unsigned BuiltinID, const CallExpr *E, + ReturnValueSlot ReturnValue); bool ProcessOrderScopeAMDGCN(llvm::Value *Order, llvm::Value *Scope, llvm::AtomicOrdering &AO, llvm::SyncScope::ID &SSID); @@ -4202,6 +4271,8 @@ public: void EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values); + void EmitARCNoopIntrinsicUse(ArrayRef<llvm::Value *> values); + static Destroyer destroyARCStrongImprecise; static Destroyer destroyARCStrongPrecise; static Destroyer destroyARCWeak; @@ -4293,6 +4364,11 @@ public: llvm::Function *createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr); + llvm::Function *createTLSAtExitStub(const VarDecl &VD, + llvm::FunctionCallee Dtor, + llvm::Constant *Addr, + llvm::FunctionCallee &AtExit); + /// Call atexit() with a function that passes the given argument to /// the given function. void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, @@ -4331,8 +4407,9 @@ public: /// variables. void GenerateCXXGlobalCleanUpFunc( llvm::Function *Fn, - const std::vector<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH, - llvm::Constant *>> &DtorsOrStermFinalizers); + ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH, + llvm::Constant *>> + DtorsOrStermFinalizers); void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, const VarDecl *D, @@ -4523,8 +4600,8 @@ private: void deferPlaceholderReplacement(llvm::Instruction *Old, llvm::Value *New); - llvm::SmallVector<std::pair<llvm::Instruction *, llvm::Value *>, 4> - DeferredReplacements; + llvm::SmallVector<std::pair<llvm::WeakTrackingVH, llvm::Value *>, 4> + DeferredReplacements; /// Set the address of a local variable. void setAddrOfLocalVar(const VarDecl *VD, Address Addr) { @@ -4630,7 +4707,6 @@ public: struct MultiVersionResolverOption { llvm::Function *Function; - FunctionDecl *FD; struct Conds { StringRef Architecture; llvm::SmallVector<StringRef, 8> Features; @@ -4764,7 +4840,8 @@ inline llvm::Value *DominatingLLVMValue::restore(CodeGenFunction &CGF, // Otherwise, it should be an alloca instruction, as set up in save(). auto alloca = cast<llvm::AllocaInst>(value.getPointer()); - return CGF.Builder.CreateAlignedLoad(alloca, alloca->getAlign()); + return CGF.Builder.CreateAlignedLoad(alloca->getAllocatedType(), alloca, + alloca->getAlign()); } } // end namespace CodeGen |
