summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenFunction.h
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
commit344a3780b2e33f6ca763666c380202b18aab72a3 (patch)
treef0b203ee6eb71d7fdd792373e3c81eb18d6934dd /clang/lib/CodeGen/CodeGenFunction.h
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.h')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h149
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