aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp153
1 files changed, 94 insertions, 59 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 826171a46e23..01da75005610 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "CodeGenFunction.h"
+#include "CGCleanup.h"
#include "CGCUDARuntime.h"
#include "CGCXXABI.h"
#include "CGDebugInfo.h"
@@ -40,10 +41,11 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
CurFn(nullptr), CapturedStmtInfo(nullptr),
SanOpts(CGM.getLangOpts().Sanitize), IsSanitizerScope(false),
CurFuncIsThunk(false), AutoreleaseResult(false), SawAsmBlock(false),
- BlockInfo(nullptr), BlockPointer(nullptr),
+ IsOutlinedSEHHelper(false), BlockInfo(nullptr), BlockPointer(nullptr),
LambdaThisCaptureField(nullptr), NormalCleanupDest(nullptr),
NextCleanupDestIndex(1), FirstBlockInfo(nullptr), EHResumeBlock(nullptr),
ExceptionSlot(nullptr), EHSelectorSlot(nullptr),
+ AbnormalTerminationSlot(nullptr), SEHPointersDecl(nullptr),
DebugInfo(CGM.getModuleDebugInfo()), DisableDebugInfo(false),
DidCallStackSave(false), IndirectBranch(nullptr), PGO(cgm),
SwitchInsn(nullptr), SwitchWeights(nullptr), CaseRangeBlock(nullptr),
@@ -69,6 +71,9 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
if (CGM.getCodeGenOpts().NoSignedZeros) {
FMF.setNoSignedZeros();
}
+ if (CGM.getCodeGenOpts().ReciprocalMath) {
+ FMF.setAllowReciprocal();
+ }
Builder.SetFastMathFlags(FMF);
}
@@ -82,7 +87,7 @@ CodeGenFunction::~CodeGenFunction() {
destroyBlockInfos(FirstBlockInfo);
if (getLangOpts().OpenMP) {
- CGM.getOpenMPRuntime().FunctionFinished(*this);
+ CGM.getOpenMPRuntime().functionFinished(*this);
}
}
@@ -239,17 +244,18 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
// parameters. Do this in whatever block we're currently in; it's
// important to do this before we enter the return block or return
// edges will be *really* confused.
- bool EmitRetDbgLoc = true;
- if (EHStack.stable_begin() != PrologueCleanupDepth) {
- PopCleanupBlocks(PrologueCleanupDepth);
-
+ bool HasCleanups = EHStack.stable_begin() != PrologueCleanupDepth;
+ bool HasOnlyLifetimeMarkers =
+ HasCleanups && EHStack.containsOnlyLifetimeMarkers(PrologueCleanupDepth);
+ bool EmitRetDbgLoc = !HasCleanups || HasOnlyLifetimeMarkers;
+ if (HasCleanups) {
// Make sure the line table doesn't jump back into the body for
// the ret after it's been at EndLoc.
- EmitRetDbgLoc = false;
-
if (CGDebugInfo *DI = getDebugInfo())
if (OnlySimpleReturnStmts)
DI->EmitLocation(Builder, EndLoc);
+
+ PopCleanupBlocks(PrologueCleanupDepth);
}
// Emit function epilog (to return).
@@ -278,6 +284,20 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
Builder.ClearInsertionPoint();
}
+ // If some of our locals escaped, insert a call to llvm.frameescape in the
+ // entry block.
+ if (!EscapedLocals.empty()) {
+ // Invert the map from local to index into a simple vector. There should be
+ // no holes.
+ SmallVector<llvm::Value *, 4> EscapeArgs;
+ EscapeArgs.resize(EscapedLocals.size());
+ for (auto &Pair : EscapedLocals)
+ EscapeArgs[Pair.second] = Pair.first;
+ llvm::Function *FrameEscapeFn = llvm::Intrinsic::getDeclaration(
+ &CGM.getModule(), llvm::Intrinsic::frameescape);
+ CGBuilderTy(AllocaInsertPt).CreateCall(FrameEscapeFn, EscapeArgs);
+ }
+
// Remove the AllocaInsertPt instruction, which is just a convenience for us.
llvm::Instruction *Ptr = AllocaInsertPt;
AllocaInsertPt = nullptr;
@@ -588,6 +608,20 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
if (CGM.isInSanitizerBlacklist(Fn, Loc))
SanOpts.clear();
+ if (D) {
+ // Apply the no_sanitize* attributes to SanOpts.
+ for (auto Attr : D->specific_attrs<NoSanitizeAttr>())
+ SanOpts.Mask &= ~Attr->getMask();
+ }
+
+ // Apply sanitizer attributes to the function.
+ if (SanOpts.has(SanitizerKind::Address))
+ Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
+ if (SanOpts.has(SanitizerKind::Thread))
+ Fn->addFnAttr(llvm::Attribute::SanitizeThread);
+ if (SanOpts.has(SanitizerKind::Memory))
+ Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
+
// Pass inline keyword to optimizer if it appears explicitly on any
// declaration. Also, in the case of -fno-inline attach NoInline
// attribute to all function that are not marked AlwaysInline.
@@ -679,7 +713,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
unsigned Idx = CurFnInfo->getReturnInfo().getInAllocaFieldIndex();
llvm::Function::arg_iterator EI = CurFn->arg_end();
--EI;
- llvm::Value *Addr = Builder.CreateStructGEP(EI, Idx);
+ llvm::Value *Addr = Builder.CreateStructGEP(nullptr, EI, Idx);
ReturnValue = Builder.CreateLoad(Addr, "agg.result");
} else {
ReturnValue = CreateIRTemp(RetTy, "retval");
@@ -753,8 +787,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args,
const Stmt *Body) {
- RegionCounter Cnt = getPGORegionCounter(Body);
- Cnt.beginRegion(Builder);
+ incrementProfileCounter(Body);
if (const CompoundStmt *S = dyn_cast<CompoundStmt>(Body))
EmitCompoundStmtWithoutScope(*S);
else
@@ -766,7 +799,7 @@ void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args,
/// emit a branch around the instrumentation code. When not instrumenting,
/// this just calls EmitBlock().
void CodeGenFunction::EmitBlockWithFallThrough(llvm::BasicBlock *BB,
- RegionCounter &Cnt) {
+ const Stmt *S) {
llvm::BasicBlock *SkipCountBB = nullptr;
if (HaveInsertPoint() && CGM.getCodeGenOpts().ProfileInstrGenerate) {
// When instrumenting for profiling, the fallthrough to certain
@@ -776,7 +809,9 @@ void CodeGenFunction::EmitBlockWithFallThrough(llvm::BasicBlock *BB,
EmitBranch(SkipCountBB);
}
EmitBlock(BB);
- Cnt.beginRegion(Builder, /*AddIncomingFallThrough=*/true);
+ uint64_t CurrentCount = getCurrentProfileCount();
+ incrementProfileCounter(S);
+ setCurrentProfileCount(getCurrentProfileCount() + CurrentCount);
if (SkipCountBB)
EmitBlock(SkipCountBB);
}
@@ -801,17 +836,6 @@ static void TryMarkNoThrow(llvm::Function *F) {
F->setDoesNotThrow();
}
-static void EmitSizedDeallocationFunction(CodeGenFunction &CGF,
- const FunctionDecl *UnsizedDealloc) {
- // This is a weak discardable definition of the sized deallocation function.
- CGF.CurFn->setLinkage(llvm::Function::LinkOnceAnyLinkage);
-
- // Call the unsized deallocation function and forward the first argument
- // unchanged.
- llvm::Constant *Unsized = CGF.CGM.GetAddrOfFunction(UnsizedDealloc);
- CGF.Builder.CreateCall(Unsized, &*CGF.CurFn->arg_begin());
-}
-
void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
const CGFunctionInfo &FnInfo) {
const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
@@ -832,7 +856,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
ResTy = CGM.getContext().VoidPtrTy;
CGM.getCXXABI().buildThisParam(*this, Args);
}
-
+
Args.append(FD->param_begin(), FD->param_end());
if (MD && (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)))
@@ -866,9 +890,9 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
else if (isa<CXXConstructorDecl>(FD))
EmitConstructorBody(Args);
else if (getLangOpts().CUDA &&
- !CGM.getCodeGenOpts().CUDAIsDevice &&
+ !getLangOpts().CUDAIsDevice &&
FD->hasAttr<CUDAGlobalAttr>())
- CGM.getCUDARuntime().EmitDeviceStubBody(*this, Args);
+ CGM.getCUDARuntime().emitDeviceStub(*this, Args);
else if (isa<CXXConversionDecl>(FD) &&
cast<CXXConversionDecl>(FD)->isLambdaToBlockPointerConversion()) {
// The lambda conversion to block pointer is special; the semantics can't be
@@ -887,11 +911,6 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
emitImplicitAssignmentOperatorBody(Args);
} else if (Stmt *Body = FD->getBody()) {
EmitFunctionBody(Args, Body);
- } else if (FunctionDecl *UnsizedDealloc =
- FD->getCorrespondingUnsizedGlobalDeallocationFunction()) {
- // Global sized deallocation functions get an implicit weak definition if
- // they don't have an explicit definition.
- EmitSizedDeallocationFunction(*this, UnsizedDealloc);
} else
llvm_unreachable("no definition for emitted function");
@@ -910,7 +929,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
"missing_return", EmitCheckSourceLocation(FD->getLocation()),
None);
} else if (CGM.getCodeGenOpts().OptimizationLevel == 0)
- Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::trap));
+ Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::trap), {});
Builder.CreateUnreachable();
Builder.ClearInsertionPoint();
}
@@ -1028,15 +1047,13 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
// Handle X && Y in a condition.
if (CondBOp->getOpcode() == BO_LAnd) {
- RegionCounter Cnt = getPGORegionCounter(CondBOp);
-
// If we have "1 && X", simplify the code. "0 && X" would have constant
// folded if the case was simple enough.
bool ConstantBool = false;
if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) &&
ConstantBool) {
// br(1 && X) -> br(X).
- Cnt.beginRegion(Builder);
+ incrementProfileCounter(CondBOp);
return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock,
TrueCount);
}
@@ -1055,14 +1072,19 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
llvm::BasicBlock *LHSTrue = createBasicBlock("land.lhs.true");
// The counter tells us how often we evaluate RHS, and all of TrueCount
// can be propagated to that branch.
- uint64_t RHSCount = Cnt.getCount();
+ uint64_t RHSCount = getProfileCount(CondBOp->getRHS());
ConditionalEvaluation eval(*this);
- EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock, RHSCount);
- EmitBlock(LHSTrue);
+ {
+ ApplyDebugLocation DL(*this, Cond);
+ EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock, RHSCount);
+ EmitBlock(LHSTrue);
+ }
+
+ incrementProfileCounter(CondBOp);
+ setCurrentProfileCount(getProfileCount(CondBOp->getRHS()));
// Any temporaries created here are conditional.
- Cnt.beginRegion(Builder);
eval.begin(*this);
EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock, TrueCount);
eval.end(*this);
@@ -1071,15 +1093,13 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
}
if (CondBOp->getOpcode() == BO_LOr) {
- RegionCounter Cnt = getPGORegionCounter(CondBOp);
-
// If we have "0 || X", simplify the code. "1 || X" would have constant
// folded if the case was simple enough.
bool ConstantBool = false;
if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) &&
!ConstantBool) {
// br(0 || X) -> br(X).
- Cnt.beginRegion(Builder);
+ incrementProfileCounter(CondBOp);
return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock,
TrueCount);
}
@@ -1099,15 +1119,21 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
// We have the count for entry to the RHS and for the whole expression
// being true, so we can divy up True count between the short circuit and
// the RHS.
- uint64_t LHSCount = Cnt.getParentCount() - Cnt.getCount();
+ uint64_t LHSCount =
+ getCurrentProfileCount() - getProfileCount(CondBOp->getRHS());
uint64_t RHSCount = TrueCount - LHSCount;
ConditionalEvaluation eval(*this);
- EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse, LHSCount);
- EmitBlock(LHSFalse);
+ {
+ ApplyDebugLocation DL(*this, Cond);
+ EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse, LHSCount);
+ EmitBlock(LHSFalse);
+ }
+
+ incrementProfileCounter(CondBOp);
+ setCurrentProfileCount(getProfileCount(CondBOp->getRHS()));
// Any temporaries created here are conditional.
- Cnt.beginRegion(Builder);
eval.begin(*this);
EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock, RHSCount);
@@ -1121,7 +1147,7 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
// br(!x, t, f) -> br(x, f, t)
if (CondUOp->getOpcode() == UO_LNot) {
// Negate the count.
- uint64_t FalseCount = PGO.getCurrentRegionCount() - TrueCount;
+ uint64_t FalseCount = getCurrentProfileCount() - TrueCount;
// Negate the condition and swap the destination blocks.
return EmitBranchOnBoolExpr(CondUOp->getSubExpr(), FalseBlock, TrueBlock,
FalseCount);
@@ -1133,9 +1159,9 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true");
llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false");
- RegionCounter Cnt = getPGORegionCounter(CondOp);
ConditionalEvaluation cond(*this);
- EmitBranchOnBoolExpr(CondOp->getCond(), LHSBlock, RHSBlock, Cnt.getCount());
+ EmitBranchOnBoolExpr(CondOp->getCond(), LHSBlock, RHSBlock,
+ getProfileCount(CondOp));
// When computing PGO branch weights, we only know the overall count for
// the true block. This code is essentially doing tail duplication of the
@@ -1144,15 +1170,19 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
// the conditional operator.
uint64_t LHSScaledTrueCount = 0;
if (TrueCount) {
- double LHSRatio = Cnt.getCount() / (double) Cnt.getParentCount();
+ double LHSRatio =
+ getProfileCount(CondOp) / (double)getCurrentProfileCount();
LHSScaledTrueCount = TrueCount * LHSRatio;
}
cond.begin(*this);
EmitBlock(LHSBlock);
- Cnt.beginRegion(Builder);
- EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock,
- LHSScaledTrueCount);
+ incrementProfileCounter(CondOp);
+ {
+ ApplyDebugLocation DL(*this, Cond);
+ EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock,
+ LHSScaledTrueCount);
+ }
cond.end(*this);
cond.begin(*this);
@@ -1176,12 +1206,16 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
// Create branch weights based on the number of times we get here and the
// number of times the condition should be true.
- uint64_t CurrentCount = std::max(PGO.getCurrentRegionCount(), TrueCount);
- llvm::MDNode *Weights = PGO.createBranchWeights(TrueCount,
- CurrentCount - TrueCount);
+ uint64_t CurrentCount = std::max(getCurrentProfileCount(), TrueCount);
+ llvm::MDNode *Weights =
+ createProfileWeights(TrueCount, CurrentCount - TrueCount);
// Emit the code with the fully general case.
- llvm::Value *CondV = EvaluateExprAsBool(Cond);
+ llvm::Value *CondV;
+ {
+ ApplyDebugLocation DL(*this, Cond);
+ CondV = EvaluateExprAsBool(Cond);
+ }
Builder.CreateCondBr(CondV, TrueBlock, FalseBlock, Weights);
}
@@ -1231,7 +1265,8 @@ static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType,
/*volatile*/ false);
// Go to the next element.
- llvm::Value *next = Builder.CreateConstInBoundsGEP1_32(cur, 1, "vla.next");
+ llvm::Value *next = Builder.CreateConstInBoundsGEP1_32(Builder.getInt8Ty(),
+ cur, 1, "vla.next");
// Leave if that's the end of the VLA.
llvm::Value *done = Builder.CreateICmpEQ(next, end, "vla-init.isdone");