diff options
Diffstat (limited to 'clang/lib/CodeGen/CGStmt.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 113 |
1 files changed, 79 insertions, 34 deletions
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 138459c68dbf..672909849bb7 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "CGDebugInfo.h" +#include "CGOpenMPRuntime.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" #include "TargetInfo.h" @@ -18,12 +19,14 @@ #include "clang/AST/StmtVisitor.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/PrettyStackTrace.h" +#include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/StringExtras.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/MDBuilder.h" +#include "llvm/Support/SaveAndRestore.h" using namespace clang; using namespace CodeGen; @@ -246,6 +249,12 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) { case Stmt::OMPFlushDirectiveClass: EmitOMPFlushDirective(cast<OMPFlushDirective>(*S)); break; + case Stmt::OMPDepobjDirectiveClass: + EmitOMPDepobjDirective(cast<OMPDepobjDirective>(*S)); + break; + case Stmt::OMPScanDirectiveClass: + EmitOMPScanDirective(cast<OMPScanDirective>(*S)); + break; case Stmt::OMPOrderedDirectiveClass: EmitOMPOrderedDirective(cast<OMPOrderedDirective>(*S)); break; @@ -601,6 +610,13 @@ void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) { } void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) { + bool nomerge = false; + for (const auto *A : S.getAttrs()) + if (A->getKind() == attr::NoMerge) { + nomerge = true; + break; + } + SaveAndRestore<bool> save_nomerge(InNoMergeAttributedStmt, nomerge); EmitStmt(S.getSubStmt(), S.getAttrs()); } @@ -721,8 +737,8 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S, EmitBlock(LoopHeader.getBlock()); const SourceRange &R = S.getSourceRange(); - LoopStack.push(LoopHeader.getBlock(), CGM.getContext(), WhileAttrs, - SourceLocToDebugLoc(R.getBegin()), + LoopStack.push(LoopHeader.getBlock(), CGM.getContext(), CGM.getCodeGenOpts(), + WhileAttrs, SourceLocToDebugLoc(R.getBegin()), SourceLocToDebugLoc(R.getEnd())); // Create an exit block for when the condition fails, which will @@ -823,7 +839,7 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S, EmitBlock(LoopCond.getBlock()); const SourceRange &R = S.getSourceRange(); - LoopStack.push(LoopBody, CGM.getContext(), DoAttrs, + LoopStack.push(LoopBody, CGM.getContext(), CGM.getCodeGenOpts(), DoAttrs, SourceLocToDebugLoc(R.getBegin()), SourceLocToDebugLoc(R.getEnd())); @@ -881,7 +897,7 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S, EmitBlock(CondBlock); const SourceRange &R = S.getSourceRange(); - LoopStack.push(CondBlock, CGM.getContext(), ForAttrs, + LoopStack.push(CondBlock, CGM.getContext(), CGM.getCodeGenOpts(), ForAttrs, SourceLocToDebugLoc(R.getBegin()), SourceLocToDebugLoc(R.getEnd())); @@ -982,7 +998,7 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S, EmitBlock(CondBlock); const SourceRange &R = S.getSourceRange(); - LoopStack.push(CondBlock, CGM.getContext(), ForAttrs, + LoopStack.push(CondBlock, CGM.getContext(), CGM.getCodeGenOpts(), ForAttrs, SourceLocToDebugLoc(R.getBegin()), SourceLocToDebugLoc(R.getEnd())); @@ -1054,6 +1070,19 @@ void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) { EmitBranchThroughCleanup(ReturnBlock); } +namespace { +// RAII struct used to save and restore a return statment's result expression. +struct SaveRetExprRAII { + SaveRetExprRAII(const Expr *RetExpr, CodeGenFunction &CGF) + : OldRetExpr(CGF.RetExpr), CGF(CGF) { + CGF.RetExpr = RetExpr; + } + ~SaveRetExprRAII() { CGF.RetExpr = OldRetExpr; } + const Expr *OldRetExpr; + CodeGenFunction &CGF; +}; +} // namespace + /// EmitReturnStmt - Note that due to GCC extensions, this can have an operand /// if the function returns void, or may be missing one if the function returns /// non-void. Fun stuff :). @@ -1079,20 +1108,28 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { // Emit the result value, even if unused, to evaluate the side effects. const Expr *RV = S.getRetValue(); - // Treat block literals in a return expression as if they appeared - // in their own scope. This permits a small, easily-implemented - // exception to our over-conservative rules about not jumping to - // statements following block literals with non-trivial cleanups. - RunCleanupsScope cleanupScope(*this); - if (const FullExpr *fe = dyn_cast_or_null<FullExpr>(RV)) { - enterFullExpression(fe); - RV = fe->getSubExpr(); - } + // Record the result expression of the return statement. The recorded + // expression is used to determine whether a block capture's lifetime should + // end at the end of the full expression as opposed to the end of the scope + // enclosing the block expression. + // + // This permits a small, easily-implemented exception to our over-conservative + // rules about not jumping to statements following block literals with + // non-trivial cleanups. + SaveRetExprRAII SaveRetExpr(RV, *this); + RunCleanupsScope cleanupScope(*this); + if (const auto *EWC = dyn_cast_or_null<ExprWithCleanups>(RV)) + RV = EWC->getSubExpr(); // FIXME: Clean this up by using an LValue for ReturnTemp, // EmitStoreThroughLValue, and EmitAnyExpr. - if (getLangOpts().ElideConstructors && - S.getNRVOCandidate() && S.getNRVOCandidate()->isNRVOVariable()) { + // Check if the NRVO candidate was not globalized in OpenMP mode. + if (getLangOpts().ElideConstructors && S.getNRVOCandidate() && + S.getNRVOCandidate()->isNRVOVariable() && + (!getLangOpts().OpenMP || + !CGM.getOpenMPRuntime() + .getAddressOfLocalVariable(*this, S.getNRVOCandidate()) + .isValid())) { // Apply the named return value optimization for this return statement, // which means doing nothing: the appropriate result has already been // constructed into the NRVO variable. @@ -2091,8 +2128,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { // Update largest vector width for any vector types. if (auto *VT = dyn_cast<llvm::VectorType>(ResultRegTypes.back())) - LargestVectorWidth = std::max((uint64_t)LargestVectorWidth, - VT->getPrimitiveSizeInBits().getFixedSize()); + LargestVectorWidth = + std::max((uint64_t)LargestVectorWidth, + VT->getPrimitiveSizeInBits().getKnownMinSize()); } else { ArgTypes.push_back(Dest.getAddress(*this).getType()); Args.push_back(Dest.getPointer(*this)); @@ -2116,8 +2154,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { // Update largest vector width for any vector types. if (auto *VT = dyn_cast<llvm::VectorType>(Arg->getType())) - LargestVectorWidth = std::max((uint64_t)LargestVectorWidth, - VT->getPrimitiveSizeInBits().getFixedSize()); + LargestVectorWidth = + std::max((uint64_t)LargestVectorWidth, + VT->getPrimitiveSizeInBits().getKnownMinSize()); if (Info.allowsRegister()) InOutConstraints += llvm::utostr(i); else @@ -2203,21 +2242,15 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { // Update largest vector width for any vector types. if (auto *VT = dyn_cast<llvm::VectorType>(Arg->getType())) - LargestVectorWidth = std::max((uint64_t)LargestVectorWidth, - VT->getPrimitiveSizeInBits().getFixedSize()); + LargestVectorWidth = + std::max((uint64_t)LargestVectorWidth, + VT->getPrimitiveSizeInBits().getKnownMinSize()); ArgTypes.push_back(Arg->getType()); Args.push_back(Arg); Constraints += InputConstraint; } - // Append the "input" part of inout constraints last. - for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) { - ArgTypes.push_back(InOutArgTypes[i]); - Args.push_back(InOutArgs[i]); - } - Constraints += InOutConstraints; - // Labels SmallVector<llvm::BasicBlock *, 16> Transfer; llvm::BasicBlock *Fallthrough = nullptr; @@ -2225,7 +2258,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { if (const auto *GS = dyn_cast<GCCAsmStmt>(&S)) { IsGCCAsmGoto = GS->isAsmGoto(); if (IsGCCAsmGoto) { - for (auto *E : GS->labels()) { + for (const auto *E : GS->labels()) { JumpDest Dest = getJumpDestForLabel(E->getLabel()); Transfer.push_back(Dest.getBlock()); llvm::BlockAddress *BA = @@ -2236,19 +2269,31 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { Constraints += ','; Constraints += 'X'; } - StringRef Name = "asm.fallthrough"; - Fallthrough = createBasicBlock(Name); + Fallthrough = createBasicBlock("asm.fallthrough"); } } + // Append the "input" part of inout constraints last. + for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) { + ArgTypes.push_back(InOutArgTypes[i]); + Args.push_back(InOutArgs[i]); + } + Constraints += InOutConstraints; + // Clobbers for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) { StringRef Clobber = S.getClobber(i); if (Clobber == "memory") ReadOnly = ReadNone = false; - else if (Clobber != "cc") + else if (Clobber != "cc") { Clobber = getTarget().getNormalizedGCCRegisterName(Clobber); + if (CGM.getCodeGenOpts().StackClashProtector && + getTarget().isSPRegName(Clobber)) { + CGM.getDiags().Report(S.getAsmLoc(), + diag::warn_stack_clash_protection_inline_asm); + } + } if (!Constraints.empty()) Constraints += ','; @@ -2287,9 +2332,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { if (IsGCCAsmGoto) { llvm::CallBrInst *Result = Builder.CreateCallBr(IA, Fallthrough, Transfer, Args); + EmitBlock(Fallthrough); UpdateAsmCallInst(cast<llvm::CallBase>(*Result), HasSideEffect, ReadOnly, ReadNone, S, ResultRegTypes, *this, RegResults); - EmitBlock(Fallthrough); } else { llvm::CallInst *Result = Builder.CreateCall(IA, Args, getBundlesForFunclet(IA)); |