@@ -1355,6 +1355,14 @@ void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {
13551355 C->setDoesNotThrow ();
13561356}
13571357
1358+ void CodeGenFunction::EmitFakeUse (Address Addr) {
1359+ auto NL = ApplyDebugLocation::CreateEmpty (*this );
1360+ llvm::Value *V = Builder.CreateLoad (Addr, " fake.use" );
1361+ llvm::CallInst *C = Builder.CreateCall (CGM.getLLVMFakeUseFn (), {V});
1362+ C->setDoesNotThrow ();
1363+ C->setTailCallKind (llvm::CallInst::TCK_NoTail);
1364+ }
1365+
13581366void CodeGenFunction::EmitAndRegisterVariableArrayDimensions (
13591367 CGDebugInfo *DI, const VarDecl &D, bool EmitDebugInfo) {
13601368 // For each dimension stores its QualType and corresponding
@@ -1414,6 +1422,39 @@ void CodeGenFunction::EmitAndRegisterVariableArrayDimensions(
14141422 }
14151423}
14161424
1425+ // / Return the maximum size of an aggregate for which we generate a fake use
1426+ // / intrinsic when -fextend-lifetimes is in effect.
1427+ static uint64_t maxFakeUseAggregateSize (const ASTContext &C) {
1428+ return 4 * C.getTypeSize (C.UnsignedIntTy );
1429+ }
1430+
1431+ // Helper function to determine whether a variable's or parameter's lifetime
1432+ // should be extended.
1433+ static bool shouldExtendLifetime (const ASTContext &Context,
1434+ const Decl *FuncDecl, const VarDecl &D,
1435+ ImplicitParamDecl *CXXABIThisDecl) {
1436+ // When we're not inside a valid function it is unlikely that any
1437+ // lifetime extension is useful.
1438+ if (!FuncDecl)
1439+ return false ;
1440+ if (FuncDecl->isImplicit ())
1441+ return false ;
1442+ // Do not extend compiler-created variables except for the this pointer.
1443+ if (D.isImplicit () && &D != CXXABIThisDecl)
1444+ return false ;
1445+ QualType Ty = D.getType ();
1446+ // No need to extend volatiles, they have a memory location.
1447+ if (Ty.isVolatileQualified ())
1448+ return false ;
1449+ // Don't extend variables that exceed a certain size.
1450+ if (Context.getTypeSize (Ty) > maxFakeUseAggregateSize (Context))
1451+ return false ;
1452+ // Do not extend variables in nodebug or optnone functions.
1453+ if (FuncDecl->hasAttr <NoDebugAttr>() || FuncDecl->hasAttr <OptimizeNoneAttr>())
1454+ return false ;
1455+ return true ;
1456+ }
1457+
14171458// / EmitAutoVarAlloca - Emit the alloca and debug information for a
14181459// / local variable. Does not emit initialization or destruction.
14191460CodeGenFunction::AutoVarEmission
@@ -1666,6 +1707,18 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
16661707 emission.getOriginalAllocatedAddress (),
16671708 emission.getSizeForLifetimeMarkers ());
16681709
1710+ // Analogous to lifetime markers, we use a 'cleanup' to emit fake.use
1711+ // calls for local variables. We are exempting volatile variables and
1712+ // non-scalars larger than 4 times the size of an unsigned int. Larger
1713+ // non-scalars are often allocated in memory and may create unnecessary
1714+ // overhead.
1715+ if (CGM.getCodeGenOpts ().getExtendVariableLiveness () ==
1716+ CodeGenOptions::ExtendVariableLivenessKind::All) {
1717+ if (shouldExtendLifetime (getContext (), CurCodeDecl, D, CXXABIThisDecl))
1718+ EHStack.pushCleanup <FakeUse>(NormalFakeUse,
1719+ emission.getAllocatedAddress ());
1720+ }
1721+
16691722 return emission;
16701723}
16711724
@@ -2532,6 +2585,14 @@ llvm::Function *CodeGenModule::getLLVMLifetimeEndFn() {
25322585 return LifetimeEndFn;
25332586}
25342587
2588+ // / Lazily declare the @llvm.fake.use intrinsic.
2589+ llvm::Function *CodeGenModule::getLLVMFakeUseFn () {
2590+ if (!FakeUseFn)
2591+ FakeUseFn = llvm::Intrinsic::getDeclaration (&getModule (),
2592+ llvm::Intrinsic::fake_use);
2593+ return FakeUseFn;
2594+ }
2595+
25352596namespace {
25362597 // / A cleanup to perform a release of an object at the end of a
25372598 // / function. This is used to balance out the incoming +1 of a
@@ -2725,6 +2786,18 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
27252786
27262787 setAddrOfLocalVar (&D, DeclPtr);
27272788
2789+ // Push a FakeUse 'cleanup' object onto the EHStack for the parameter,
2790+ // which may be the 'this' pointer. This causes the emission of a fake.use
2791+ // call with the parameter as argument at the end of the function.
2792+ if (CGM.getCodeGenOpts ().getExtendVariableLiveness () ==
2793+ CodeGenOptions::ExtendVariableLivenessKind::All ||
2794+ (CGM.getCodeGenOpts ().getExtendVariableLiveness () ==
2795+ CodeGenOptions::ExtendVariableLivenessKind::This &&
2796+ &D == CXXABIThisDecl)) {
2797+ if (shouldExtendLifetime (getContext (), CurCodeDecl, D, CXXABIThisDecl))
2798+ EHStack.pushCleanup <FakeUse>(NormalFakeUse, DeclPtr);
2799+ }
2800+
27282801 // Emit debug info for param declarations in non-thunk functions.
27292802 if (CGDebugInfo *DI = getDebugInfo ()) {
27302803 if (CGM.getCodeGenOpts ().hasReducedDebugInfo () && !CurFuncIsThunk &&
0 commit comments