diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp | 180 |
1 files changed, 108 insertions, 72 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp index e3bdf86..7a0b8a3 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp @@ -88,6 +88,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { case Stmt::ContinueStmtClass: case Stmt::DefaultStmtClass: case Stmt::CaseStmtClass: + case Stmt::SEHLeaveStmtClass: llvm_unreachable("should have emitted these statements as simple"); #define STMT(Type, Base) @@ -173,9 +174,6 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { case Stmt::SEHTryStmtClass: EmitSEHTryStmt(cast<SEHTryStmt>(*S)); break; - case Stmt::SEHLeaveStmtClass: - EmitSEHLeaveStmt(cast<SEHLeaveStmt>(*S)); - break; case Stmt::OMPParallelDirectiveClass: EmitOMPParallelDirective(cast<OMPParallelDirective>(*S)); break; @@ -224,6 +222,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { case Stmt::OMPTaskwaitDirectiveClass: EmitOMPTaskwaitDirective(cast<OMPTaskwaitDirective>(*S)); break; + case Stmt::OMPTaskgroupDirectiveClass: + EmitOMPTaskgroupDirective(cast<OMPTaskgroupDirective>(*S)); + break; case Stmt::OMPFlushDirectiveClass: EmitOMPFlushDirective(cast<OMPFlushDirective>(*S)); break; @@ -239,6 +240,12 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { case Stmt::OMPTeamsDirectiveClass: EmitOMPTeamsDirective(cast<OMPTeamsDirective>(*S)); break; + case Stmt::OMPCancellationPointDirectiveClass: + EmitOMPCancellationPointDirective(cast<OMPCancellationPointDirective>(*S)); + break; + case Stmt::OMPCancelDirectiveClass: + EmitOMPCancelDirective(cast<OMPCancelDirective>(*S)); + break; } } @@ -256,6 +263,7 @@ bool CodeGenFunction::EmitSimpleStmt(const Stmt *S) { case Stmt::ContinueStmtClass: EmitContinueStmt(cast<ContinueStmt>(*S)); break; case Stmt::DefaultStmtClass: EmitDefaultStmt(cast<DefaultStmt>(*S)); break; case Stmt::CaseStmtClass: EmitCaseStmt(cast<CaseStmt>(*S)); break; + case Stmt::SEHLeaveStmtClass: EmitSEHLeaveStmt(cast<SEHLeaveStmt>(*S)); break; } return true; @@ -424,9 +432,8 @@ void CodeGenFunction::EmitLabel(const LabelDecl *D) { ResolveBranchFixups(Dest.getBlock()); } - RegionCounter Cnt = getPGORegionCounter(D->getStmt()); EmitBlock(Dest.getBlock()); - Cnt.beginRegion(Builder); + incrementProfileCounter(D->getStmt()); } /// Change the cleanup scope of the labels in this lexical scope to @@ -514,7 +521,6 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { // C99 6.8.4.1: The first substatement is executed if the expression compares // unequal to 0. The condition must be a scalar type. LexicalScope ConditionScope(*this, S.getCond()->getSourceRange()); - RegionCounter Cnt = getPGORegionCounter(&S); if (S.getConditionVariable()) EmitAutoVarDecl(*S.getConditionVariable()); @@ -533,7 +539,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { // This avoids emitting dead code and simplifies the CFG substantially. if (!ContainsLabel(Skipped)) { if (CondConstant) - Cnt.beginRegion(Builder); + incrementProfileCounter(&S); if (Executed) { RunCleanupsScope ExecutedScope(*this); EmitStmt(Executed); @@ -550,11 +556,12 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { if (S.getElse()) ElseBlock = createBasicBlock("if.else"); - EmitBranchOnBoolExpr(S.getCond(), ThenBlock, ElseBlock, Cnt.getCount()); + EmitBranchOnBoolExpr(S.getCond(), ThenBlock, ElseBlock, + getProfileCount(S.getThen())); // Emit the 'then' code. EmitBlock(ThenBlock); - Cnt.beginRegion(Builder); + incrementProfileCounter(&S); { RunCleanupsScope ThenScope(*this); EmitStmt(S.getThen()); @@ -564,8 +571,8 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { // Emit the 'else' code if present. if (const Stmt *Else = S.getElse()) { { - // There is no need to emit line number for unconditional branch. - ApplyDebugLocation DL(*this); + // There is no need to emit line number for an unconditional branch. + auto NL = ApplyDebugLocation::CreateEmpty(*this); EmitBlock(ElseBlock); } { @@ -573,8 +580,8 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { EmitStmt(Else); } { - // There is no need to emit line number for unconditional branch. - ApplyDebugLocation DL(*this); + // There is no need to emit line number for an unconditional branch. + auto NL = ApplyDebugLocation::CreateEmpty(*this); EmitBranch(ContBlock); } } @@ -679,14 +686,12 @@ void CodeGenFunction::EmitCondBrHints(llvm::LLVMContext &Context, void CodeGenFunction::EmitWhileStmt(const WhileStmt &S, ArrayRef<const Attr *> WhileAttrs) { - RegionCounter Cnt = getPGORegionCounter(&S); - // Emit the header for the loop, which will also become // the continue target. JumpDest LoopHeader = getJumpDestInCurrentScope("while.cond"); EmitBlock(LoopHeader.getBlock()); - LoopStack.push(LoopHeader.getBlock()); + LoopStack.push(LoopHeader.getBlock(), WhileAttrs); // Create an exit block for when the condition fails, which will // also become the break target. @@ -725,9 +730,9 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S, llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); if (ConditionScope.requiresCleanups()) ExitBlock = createBasicBlock("while.exit"); - llvm::BranchInst *CondBr = - Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock, - PGO.createLoopWeights(S.getCond(), Cnt)); + llvm::BranchInst *CondBr = Builder.CreateCondBr( + BoolCondVal, LoopBody, ExitBlock, + createProfileWeightsForLoop(S.getCond(), getProfileCount(S.getBody()))); if (ExitBlock != LoopExit.getBlock()) { EmitBlock(ExitBlock); @@ -743,7 +748,7 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S, { RunCleanupsScope BodyScope(*this); EmitBlock(LoopBody); - Cnt.beginRegion(Builder); + incrementProfileCounter(&S); EmitStmt(S.getBody()); } @@ -772,7 +777,7 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S, JumpDest LoopExit = getJumpDestInCurrentScope("do.end"); JumpDest LoopCond = getJumpDestInCurrentScope("do.cond"); - RegionCounter Cnt = getPGORegionCounter(&S); + uint64_t ParentCount = getCurrentProfileCount(); // Store the blocks to use for break and continue. BreakContinueStack.push_back(BreakContinue(LoopExit, LoopCond)); @@ -780,9 +785,9 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S, // Emit the body of the loop. llvm::BasicBlock *LoopBody = createBasicBlock("do.body"); - LoopStack.push(LoopBody); + LoopStack.push(LoopBody, DoAttrs); - EmitBlockWithFallThrough(LoopBody, Cnt); + EmitBlockWithFallThrough(LoopBody, &S); { RunCleanupsScope BodyScope(*this); EmitStmt(S.getBody()); @@ -809,9 +814,10 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S, // As long as the condition is true, iterate the loop. if (EmitBoolCondBranch) { - llvm::BranchInst *CondBr = - Builder.CreateCondBr(BoolCondVal, LoopBody, LoopExit.getBlock(), - PGO.createLoopWeights(S.getCond(), Cnt)); + uint64_t BackedgeCount = getProfileCount(S.getBody()) - ParentCount; + llvm::BranchInst *CondBr = Builder.CreateCondBr( + BoolCondVal, LoopBody, LoopExit.getBlock(), + createProfileWeightsForLoop(S.getCond(), BackedgeCount)); // Attach metadata to loop body conditional branch. EmitCondBrHints(LoopBody->getContext(), CondBr, DoAttrs); @@ -838,8 +844,6 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S, if (S.getInit()) EmitStmt(S.getInit()); - RegionCounter Cnt = getPGORegionCounter(&S); - // Start the loop with a block that tests the condition. // If there's an increment, the continue scope will be overwritten // later. @@ -847,7 +851,7 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S, llvm::BasicBlock *CondBlock = Continue.getBlock(); EmitBlock(CondBlock); - LoopStack.push(CondBlock); + LoopStack.push(CondBlock, ForAttrs); // If the for loop doesn't have an increment we can just use the // condition as the continue block. Otherwise we'll need to create @@ -881,9 +885,9 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S, // C99 6.8.5p2/p4: The first substatement is executed if the expression // compares unequal to 0. The condition must be a scalar type. llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); - llvm::BranchInst *CondBr = - Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, - PGO.createLoopWeights(S.getCond(), Cnt)); + llvm::BranchInst *CondBr = Builder.CreateCondBr( + BoolCondVal, ForBody, ExitBlock, + createProfileWeightsForLoop(S.getCond(), getProfileCount(S.getBody()))); // Attach metadata to loop body conditional branch. EmitCondBrHints(ForBody->getContext(), CondBr, ForAttrs); @@ -898,7 +902,7 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S, // Treat it as a non-zero constant. Don't even create a new block for the // body, just fall into it. } - Cnt.beginRegion(Builder); + incrementProfileCounter(&S); { // Create a separate cleanup scope for the body, in case it is not @@ -939,15 +943,13 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S, EmitStmt(S.getRangeStmt()); EmitStmt(S.getBeginEndStmt()); - RegionCounter Cnt = getPGORegionCounter(&S); - // Start the loop with a block that tests the condition. // If there's an increment, the continue scope will be overwritten // later. llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); EmitBlock(CondBlock); - LoopStack.push(CondBlock); + LoopStack.push(CondBlock, ForAttrs); // If there are any cleanups between here and the loop-exit scope, // create a block to stage a loop exit along. @@ -962,7 +964,8 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S, // to bool, is true. llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); llvm::BranchInst *CondBr = Builder.CreateCondBr( - BoolCondVal, ForBody, ExitBlock, PGO.createLoopWeights(S.getCond(), Cnt)); + BoolCondVal, ForBody, ExitBlock, + createProfileWeightsForLoop(S.getCond(), getProfileCount(S.getBody()))); // Attach metadata to loop body conditional branch. EmitCondBrHints(ForBody->getContext(), CondBr, ForAttrs); @@ -973,7 +976,7 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S, } EmitBlock(ForBody); - Cnt.beginRegion(Builder); + incrementProfileCounter(&S); // Create a block for the increment. In case of a 'continue', we jump there. JumpDest Continue = getJumpDestInCurrentScope("for.inc"); @@ -1022,6 +1025,12 @@ void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) { /// if the function returns void, or may be missing one if the function returns /// non-void. Fun stuff :). void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { + // Returning from an outlined SEH helper is UB, and we already warn on it. + if (IsOutlinedSEHHelper) { + Builder.CreateUnreachable(); + Builder.ClearInsertionPoint(); + } + // Emit the result value, even if unused, to evalute the side effects. const Expr *RV = S.getRetValue(); @@ -1133,13 +1142,11 @@ void CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) { llvm::APSInt LHS = S.getLHS()->EvaluateKnownConstInt(getContext()); llvm::APSInt RHS = S.getRHS()->EvaluateKnownConstInt(getContext()); - RegionCounter CaseCnt = getPGORegionCounter(&S); - // Emit the code for this case. We do this first to make sure it is // properly chained from our predecessor before generating the // switch machinery to enter this block. llvm::BasicBlock *CaseDest = createBasicBlock("sw.bb"); - EmitBlockWithFallThrough(CaseDest, CaseCnt); + EmitBlockWithFallThrough(CaseDest, &S); EmitStmt(S.getSubStmt()); // If range is empty, do nothing. @@ -1150,7 +1157,7 @@ void CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) { // FIXME: parameters such as this should not be hardcoded. if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) { // Range is small enough to add multiple switch instruction cases. - uint64_t Total = CaseCnt.getCount(); + uint64_t Total = getProfileCount(&S); unsigned NCases = Range.getZExtValue() + 1; // We only have one region counter for the entire set of cases here, so we // need to divide the weights evenly between the generated cases, ensuring @@ -1189,9 +1196,9 @@ void CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) { llvm::MDNode *Weights = nullptr; if (SwitchWeights) { - uint64_t ThisCount = CaseCnt.getCount(); + uint64_t ThisCount = getProfileCount(&S); uint64_t DefaultCount = (*SwitchWeights)[0]; - Weights = PGO.createBranchWeights(ThisCount, DefaultCount); + Weights = createProfileWeights(ThisCount, DefaultCount); // Since we're chaining the switch default through each large case range, we // need to update the weight for the default, ie, the first case, to include @@ -1224,7 +1231,6 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) { return; } - RegionCounter CaseCnt = getPGORegionCounter(&S); llvm::ConstantInt *CaseVal = Builder.getInt(S.getLHS()->EvaluateKnownConstInt(getContext())); @@ -1239,7 +1245,7 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) { // Only do this optimization if there are no cleanups that need emitting. if (isObviouslyBranchWithoutCleanups(Block)) { if (SwitchWeights) - SwitchWeights->push_back(CaseCnt.getCount()); + SwitchWeights->push_back(getProfileCount(&S)); SwitchInsn->addCase(CaseVal, Block.getBlock()); // If there was a fallthrough into this case, make sure to redirect it to @@ -1253,9 +1259,9 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) { } llvm::BasicBlock *CaseDest = createBasicBlock("sw.bb"); - EmitBlockWithFallThrough(CaseDest, CaseCnt); + EmitBlockWithFallThrough(CaseDest, &S); if (SwitchWeights) - SwitchWeights->push_back(CaseCnt.getCount()); + SwitchWeights->push_back(getProfileCount(&S)); SwitchInsn->addCase(CaseVal, CaseDest); // Recursively emitting the statement is acceptable, but is not wonderful for @@ -1276,12 +1282,11 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) { llvm::ConstantInt *CaseVal = Builder.getInt(CurCase->getLHS()->EvaluateKnownConstInt(getContext())); - CaseCnt = getPGORegionCounter(NextCase); if (SwitchWeights) - SwitchWeights->push_back(CaseCnt.getCount()); + SwitchWeights->push_back(getProfileCount(NextCase)); if (CGM.getCodeGenOpts().ProfileInstrGenerate) { CaseDest = createBasicBlock("sw.bb"); - EmitBlockWithFallThrough(CaseDest, CaseCnt); + EmitBlockWithFallThrough(CaseDest, &S); } SwitchInsn->addCase(CaseVal, CaseDest); @@ -1297,8 +1302,7 @@ void CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S) { assert(DefaultBlock->empty() && "EmitDefaultStmt: Default block already defined?"); - RegionCounter Cnt = getPGORegionCounter(&S); - EmitBlockWithFallThrough(DefaultBlock, Cnt); + EmitBlockWithFallThrough(DefaultBlock, &S); EmitStmt(S.getSubStmt()); } @@ -1520,10 +1524,8 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { const SwitchCase *Case = nullptr; if (FindCaseStatementsForValue(S, ConstantCondValue, CaseStmts, getContext(), Case)) { - if (Case) { - RegionCounter CaseCnt = getPGORegionCounter(Case); - CaseCnt.beginRegion(Builder); - } + if (Case) + incrementProfileCounter(Case); RunCleanupsScope ExecutedScope(*this); // Emit the condition variable if needed inside the entire cleanup scope @@ -1540,8 +1542,7 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { // specified series of statements and we're good. for (unsigned i = 0, e = CaseStmts.size(); i != e; ++i) EmitStmt(CaseStmts[i]); - RegionCounter ExitCnt = getPGORegionCounter(&S); - ExitCnt.beginRegion(Builder); + incrementProfileCounter(&S); // Now we want to restore the saved switch instance so that nested // switches continue to function properly @@ -1572,7 +1573,7 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { Case; Case = Case->getNextSwitchCase()) { if (isa<DefaultStmt>(Case)) - DefaultCount = getPGORegionCounter(Case).getCount(); + DefaultCount = getProfileCount(Case); NumCases += 1; } SwitchWeights = new SmallVector<uint64_t, 16>(); @@ -1621,8 +1622,7 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { // Emit continuation. EmitBlock(SwitchExit.getBlock(), true); - RegionCounter ExitCnt = getPGORegionCounter(&S); - ExitCnt.beginRegion(Builder); + incrementProfileCounter(&S); if (SwitchWeights) { assert(SwitchWeights->size() == 1 + SwitchInsn->getNumCases() && @@ -1630,7 +1630,7 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { // If there's only one jump destination there's no sense weighting it. if (SwitchWeights->size() > 1) SwitchInsn->setMetadata(llvm::LLVMContext::MD_prof, - PGO.createBranchWeights(*SwitchWeights)); + createProfileWeights(*SwitchWeights)); delete SwitchWeights; } SwitchInsn = SavedSwitchInsn; @@ -1696,7 +1696,7 @@ SimplifyConstraint(const char *Constraint, const TargetInfo &Target, static std::string AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr, const TargetInfo &Target, CodeGenModule &CGM, - const AsmStmt &Stmt) { + const AsmStmt &Stmt, const bool EarlyClobber) { const DeclRefExpr *AsmDeclRef = dyn_cast<DeclRefExpr>(&AsmExpr); if (!AsmDeclRef) return Constraint; @@ -1721,7 +1721,7 @@ AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr, } // Canonicalize the register here before returning it. Register = Target.getNormalizedGCCRegisterName(Register); - return "{" + Register.str() + "}"; + return (EarlyClobber ? "&{" : "{") + Register.str() + "}"; } llvm::Value* @@ -1759,6 +1759,16 @@ llvm::Value* CodeGenFunction::EmitAsmInput( const TargetInfo::ConstraintInfo &Info, const Expr *InputExpr, std::string &ConstraintStr) { + // If this can't be a register or memory, i.e., has to be a constant + // (immediate or symbolic), try to emit it as such. + if (!Info.allowsRegister() && !Info.allowsMemory()) { + llvm::APSInt Result; + if (InputExpr->EvaluateAsInt(Result, getContext())) + return llvm::ConstantInt::get(getLLVMContext(), Result); + assert(!Info.requiresImmediateConstant() && + "Required-immediate inlineasm arg isn't constant?"); + } + if (Info.allowsRegister() || !Info.allowsMemory()) if (CodeGenFunction::hasScalarEvaluationKind(InputExpr->getType())) return EmitScalarExpr(InputExpr); @@ -1842,6 +1852,14 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { std::vector<llvm::Value*> InOutArgs; std::vector<llvm::Type*> InOutArgTypes; + // An inline asm can be marked readonly if it meets the following conditions: + // - it doesn't have any sideeffects + // - it doesn't clobber memory + // - it doesn't return a value by-reference + // It can be marked readnone if it doesn't have any input memory constraints + // in addition to meeting the conditions listed above. + bool ReadOnly = true, ReadNone = true; + for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) { TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i]; @@ -1854,7 +1872,8 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { OutExpr = OutExpr->IgnoreParenNoopCasts(getContext()); OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr, - getTarget(), CGM, S); + getTarget(), CGM, S, + Info.earlyClobber()); LValue Dest = EmitLValue(OutExpr); if (!Constraints.empty()) @@ -1904,6 +1923,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { Args.push_back(Dest.getAddress()); Constraints += "=*"; Constraints += OutputConstraint; + ReadOnly = ReadNone = false; } if (Info.isReadWrite()) { @@ -1948,6 +1968,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i]; + if (Info.allowsMemory()) + ReadNone = false; + if (!Constraints.empty()) Constraints += ','; @@ -1956,10 +1979,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { InputConstraint = SimplifyConstraint(InputConstraint.c_str(), getTarget(), &OutputConstraintInfos); - InputConstraint = - AddVariableConstraints(InputConstraint, - *InputExpr->IgnoreParenNoopCasts(getContext()), - getTarget(), CGM, S); + InputConstraint = AddVariableConstraints( + InputConstraint, *InputExpr->IgnoreParenNoopCasts(getContext()), + getTarget(), CGM, S, false /* No EarlyClobber */); llvm::Value *Arg = EmitAsmInput(Info, InputExpr, Constraints); @@ -2013,7 +2035,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) { StringRef Clobber = S.getClobber(i); - if (Clobber != "memory" && Clobber != "cc") + if (Clobber == "memory") + ReadOnly = ReadNone = false; + else if (Clobber != "cc") Clobber = getTarget().getNormalizedGCCRegisterName(Clobber); if (!Constraints.empty()) @@ -2053,6 +2077,16 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { Result->addAttribute(llvm::AttributeSet::FunctionIndex, llvm::Attribute::NoUnwind); + // Attach readnone and readonly attributes. + if (!HasSideEffect) { + if (ReadNone) + Result->addAttribute(llvm::AttributeSet::FunctionIndex, + llvm::Attribute::ReadNone); + else if (ReadOnly) + Result->addAttribute(llvm::AttributeSet::FunctionIndex, + llvm::Attribute::ReadOnly); + } + // Slap the source location of the inline asm into a !srcloc metadata on the // call. if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(&S)) { @@ -2145,7 +2179,7 @@ CodeGenFunction::EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K) { // Emit the CapturedDecl CodeGenFunction CGF(CGM, true); - CGF.CapturedStmtInfo = new CGCapturedStmtInfo(S, K); + CGCapturedStmtRAII CapInfoRAII(CGF, new CGCapturedStmtInfo(S, K)); llvm::Function *F = CGF.GenerateCapturedStmtFunction(S); delete CGF.CapturedStmtInfo; @@ -2187,6 +2221,8 @@ CodeGenFunction::GenerateCapturedStmtFunction(const CapturedStmt &S) { llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage, CapturedStmtInfo->getHelperName(), &CGM.getModule()); CGM.SetInternalFunctionAttributes(CD, F, FuncInfo); + if (CD->isNothrow()) + F->addFnAttr(llvm::Attribute::NoUnwind); // Generate the function. StartFunction(CD, Ctx.VoidTy, F, FuncInfo, Args, |