Skip to content

Commit 861d36e

Browse files
committed
[IR] Remove size argument from lifetime intrinsics
Now that #149310 has restricted lifetime intrinsics to only work on allocas, we can also drop the explicit size argument. Instead, the size is implied by the alloca. This removes the ability to only mark a prefix of an alloca alive/dead. We never used that capability, so we should remove the need to handle that possibility everywhere (many key places, including stack coloring, did not actually respect this).
1 parent a647bb4 commit 861d36e

File tree

464 files changed

+4444
-5081
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

464 files changed

+4444
-5081
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5981,8 +5981,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
59815981

59825982
// Create a temporary array to hold the sizes of local pointer arguments
59835983
// for the block. \p First is the position of the first size argument.
5984-
auto CreateArrayForSizeVar = [=](unsigned First)
5985-
-> std::tuple<llvm::Value *, llvm::Value *, llvm::Value *> {
5984+
auto CreateArrayForSizeVar =
5985+
[=](unsigned First) -> std::pair<llvm::Value *, llvm::Value *> {
59865986
llvm::APInt ArraySize(32, NumArgs - First);
59875987
QualType SizeArrayTy = getContext().getConstantArrayType(
59885988
getContext().getSizeType(), ArraySize, nullptr,
@@ -5995,9 +5995,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
59955995
// actually the Alloca ascasted to the default AS, hence the
59965996
// stripPointerCasts()
59975997
llvm::Value *Alloca = TmpPtr->stripPointerCasts();
5998-
llvm::Value *TmpSize = EmitLifetimeStart(
5999-
CGM.getDataLayout().getTypeAllocSize(Tmp.getElementType()), Alloca);
60005998
llvm::Value *ElemPtr;
5999+
EmitLifetimeStart(Alloca);
60016000
// Each of the following arguments specifies the size of the corresponding
60026001
// argument passed to the enqueued block.
60036002
auto *Zero = llvm::ConstantInt::get(IntTy, 0);
@@ -6014,7 +6013,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
60146013
}
60156014
// Return the Alloca itself rather than a potential ascast as this is only
60166015
// used by the paired EmitLifetimeEnd.
6017-
return {ElemPtr, TmpSize, Alloca};
6016+
return {ElemPtr, Alloca};
60186017
};
60196018

60206019
// Could have events and/or varargs.
@@ -6026,7 +6025,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
60266025
llvm::Value *Kernel =
60276026
Builder.CreatePointerCast(Info.KernelHandle, GenericVoidPtrTy);
60286027
auto *Block = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy);
6029-
auto [ElemPtr, TmpSize, TmpPtr] = CreateArrayForSizeVar(4);
6028+
auto [ElemPtr, TmpPtr] = CreateArrayForSizeVar(4);
60306029

60316030
// Create a vector of the arguments, as well as a constant value to
60326031
// express to the runtime the number of variadic arguments.
@@ -6041,8 +6040,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
60416040
llvm::FunctionType *FTy = llvm::FunctionType::get(Int32Ty, ArgTys, false);
60426041
auto Call = RValue::get(
60436042
EmitRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Args));
6044-
if (TmpSize)
6045-
EmitLifetimeEnd(TmpSize, TmpPtr);
6043+
EmitLifetimeEnd(TmpPtr);
60466044
return Call;
60476045
}
60486046
// Any calls now have event arguments passed.
@@ -6107,15 +6105,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
61076105
ArgTys.push_back(Int32Ty);
61086106
Name = "__enqueue_kernel_events_varargs";
61096107

6110-
auto [ElemPtr, TmpSize, TmpPtr] = CreateArrayForSizeVar(7);
6108+
auto [ElemPtr, TmpPtr] = CreateArrayForSizeVar(7);
61116109
Args.push_back(ElemPtr);
61126110
ArgTys.push_back(ElemPtr->getType());
61136111

61146112
llvm::FunctionType *FTy = llvm::FunctionType::get(Int32Ty, ArgTys, false);
61156113
auto Call = RValue::get(
61166114
EmitRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Args));
6117-
if (TmpSize)
6118-
EmitLifetimeEnd(TmpSize, TmpPtr);
6115+
EmitLifetimeEnd(TmpPtr);
61196116
return Call;
61206117
}
61216118
llvm_unreachable("Unexpected enqueue_kernel signature");

clang/lib/CodeGen/CGCall.cpp

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4311,10 +4311,7 @@ static void emitWriteback(CodeGenFunction &CGF,
43114311

43124312
if (writeback.WritebackExpr) {
43134313
CGF.EmitIgnoredExpr(writeback.WritebackExpr);
4314-
4315-
if (writeback.LifetimeSz)
4316-
CGF.EmitLifetimeEnd(writeback.LifetimeSz,
4317-
writeback.Temporary.getBasePointer());
4314+
CGF.EmitLifetimeEnd(writeback.Temporary.getBasePointer());
43184315
return;
43194316
}
43204317

@@ -5274,7 +5271,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
52745271
// If the call returns a temporary with struct return, create a temporary
52755272
// alloca to hold the result, unless one is given to us.
52765273
Address SRetPtr = Address::invalid();
5277-
llvm::Value *UnusedReturnSizePtr = nullptr;
5274+
bool NeedSRetLifetimeEnd = false;
52785275
if (RetAI.isIndirect() || RetAI.isInAlloca() || RetAI.isCoerceAndExpand()) {
52795276
// For virtual function pointer thunks and musttail calls, we must always
52805277
// forward an incoming SRet pointer to the callee, because a local alloca
@@ -5288,11 +5285,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
52885285
SRetPtr = ReturnValue.getAddress();
52895286
} else {
52905287
SRetPtr = CreateMemTempWithoutCast(RetTy, "tmp");
5291-
if (HaveInsertPoint() && ReturnValue.isUnused()) {
5292-
llvm::TypeSize size =
5293-
CGM.getDataLayout().getTypeAllocSize(ConvertTypeForMem(RetTy));
5294-
UnusedReturnSizePtr = EmitLifetimeStart(size, SRetPtr.getBasePointer());
5295-
}
5288+
if (HaveInsertPoint() && ReturnValue.isUnused())
5289+
NeedSRetLifetimeEnd = EmitLifetimeStart(SRetPtr.getBasePointer());
52965290
}
52975291
if (IRFunctionArgs.hasSRetArg()) {
52985292
// A mismatch between the allocated return value's AS and the target's
@@ -5476,15 +5470,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
54765470
Val = Builder.CreateFreeze(Val);
54775471
IRCallArgs[FirstIRArg] = Val;
54785472

5479-
// Emit lifetime markers for the temporary alloca.
5480-
llvm::TypeSize ByvalTempElementSize =
5481-
CGM.getDataLayout().getTypeAllocSize(AI.getElementType());
5482-
llvm::Value *LifetimeSize =
5483-
EmitLifetimeStart(ByvalTempElementSize, AI.getPointer());
5484-
5485-
// Add cleanup code to emit the end lifetime marker after the call.
5486-
if (LifetimeSize) // In case we disabled lifetime markers.
5487-
CallLifetimeEndAfterCall.emplace_back(AI, LifetimeSize);
5473+
// Emit lifetime markers for the temporary alloca and add cleanup code to
5474+
// emit the end lifetime marker after the call.
5475+
if (EmitLifetimeStart(AI.getPointer()))
5476+
CallLifetimeEndAfterCall.emplace_back(AI);
54885477

54895478
// Generate the copy.
54905479
I->copyInto(*this, AI);
@@ -5645,9 +5634,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
56455634
auto unpaddedCoercionType = ArgInfo.getUnpaddedCoerceAndExpandType();
56465635
auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
56475636

5648-
llvm::Value *tempSize = nullptr;
56495637
Address addr = Address::invalid();
56505638
RawAddress AllocaAddr = RawAddress::invalid();
5639+
bool NeedLifetimeEnd = false;
56515640
if (I->isAggregate()) {
56525641
addr = I->hasLValue() ? I->getKnownLValue().getAddress()
56535642
: I->getKnownRValue().getAggregateAddress();
@@ -5657,7 +5646,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
56575646
assert(RV.isScalar()); // complex should always just be direct
56585647

56595648
llvm::Type *scalarType = RV.getScalarVal()->getType();
5660-
auto scalarSize = CGM.getDataLayout().getTypeAllocSize(scalarType);
56615649
auto scalarAlign = CGM.getDataLayout().getPrefTypeAlign(scalarType);
56625650

56635651
// Materialize to a temporary.
@@ -5666,7 +5654,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
56665654
layout->getAlignment(), scalarAlign)),
56675655
"tmp",
56685656
/*ArraySize=*/nullptr, &AllocaAddr);
5669-
tempSize = EmitLifetimeStart(scalarSize, AllocaAddr.getPointer());
5657+
NeedLifetimeEnd = EmitLifetimeStart(AllocaAddr.getPointer());
56705658

56715659
Builder.CreateStore(RV.getScalarVal(), addr);
56725660
}
@@ -5691,10 +5679,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
56915679
}
56925680
assert(IRArgPos == FirstIRArg + NumIRArgs);
56935681

5694-
if (tempSize) {
5695-
EmitLifetimeEnd(tempSize, AllocaAddr.getPointer());
5696-
}
5697-
5682+
if (NeedLifetimeEnd)
5683+
EmitLifetimeEnd(AllocaAddr.getPointer());
56985684
break;
56995685
}
57005686

@@ -5863,9 +5849,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
58635849
// can't depend on being inside of an ExprWithCleanups, so we need to manually
58645850
// pop this cleanup later on. Being eager about this is OK, since this
58655851
// temporary is 'invisible' outside of the callee.
5866-
if (UnusedReturnSizePtr)
5867-
pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, SRetPtr,
5868-
UnusedReturnSizePtr);
5852+
if (NeedSRetLifetimeEnd)
5853+
pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, SRetPtr);
58695854

58705855
llvm::BasicBlock *InvokeDest = CannotThrow ? nullptr : getInvokeDest();
58715856

@@ -5999,7 +5984,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
59995984
// insertion point; this allows the rest of IRGen to discard
60005985
// unreachable code.
60015986
if (CI->doesNotReturn()) {
6002-
if (UnusedReturnSizePtr)
5987+
if (NeedSRetLifetimeEnd)
60035988
PopCleanupBlock();
60045989

60055990
// Strip away the noreturn attribute to better diagnose unreachable UB.
@@ -6114,7 +6099,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
61146099
case ABIArgInfo::InAlloca:
61156100
case ABIArgInfo::Indirect: {
61166101
RValue ret = convertTempToRValue(SRetPtr, RetTy, SourceLocation());
6117-
if (UnusedReturnSizePtr)
6102+
if (NeedSRetLifetimeEnd)
61186103
PopCleanupBlock();
61196104
return ret;
61206105
}

clang/lib/CodeGen/CGCall.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -289,9 +289,6 @@ class CallArgList : public SmallVector<CallArg, 8> {
289289
/// An Expression (optional) that performs the writeback with any required
290290
/// casting.
291291
const Expr *WritebackExpr;
292-
293-
// Size for optional lifetime end on the temporary.
294-
llvm::Value *LifetimeSz;
295292
};
296293

297294
struct CallArgCleanup {
@@ -321,9 +318,8 @@ class CallArgList : public SmallVector<CallArg, 8> {
321318
}
322319

323320
void addWriteback(LValue srcLV, Address temporary, llvm::Value *toUse,
324-
const Expr *writebackExpr = nullptr,
325-
llvm::Value *lifetimeSz = nullptr) {
326-
Writeback writeback = {srcLV, temporary, toUse, writebackExpr, lifetimeSz};
321+
const Expr *writebackExpr = nullptr) {
322+
Writeback writeback = {srcLV, temporary, toUse, writebackExpr};
327323
Writebacks.push_back(writeback);
328324
}
329325

clang/lib/CodeGen/CGDecl.cpp

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,30 +1347,27 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D) {
13471347
}
13481348

13491349
/// Emit a lifetime.begin marker if some criteria are satisfied.
1350-
/// \return a pointer to the temporary size Value if a marker was emitted, null
1351-
/// otherwise
1352-
llvm::Value *CodeGenFunction::EmitLifetimeStart(llvm::TypeSize Size,
1353-
llvm::Value *Addr) {
1350+
/// \return whether the marker was emitted.
1351+
bool CodeGenFunction::EmitLifetimeStart(llvm::Value *Addr) {
13541352
if (!ShouldEmitLifetimeMarkers)
1355-
return nullptr;
1353+
return false;
13561354

13571355
assert(Addr->getType()->getPointerAddressSpace() ==
13581356
CGM.getDataLayout().getAllocaAddrSpace() &&
13591357
"Pointer should be in alloca address space");
1360-
llvm::Value *SizeV = llvm::ConstantInt::get(
1361-
Int64Ty, Size.isScalable() ? -1 : Size.getFixedValue());
1362-
llvm::CallInst *C =
1363-
Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {SizeV, Addr});
1358+
llvm::CallInst *C = Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {Addr});
13641359
C->setDoesNotThrow();
1365-
return SizeV;
1360+
return true;
13661361
}
13671362

1368-
void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {
1363+
void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Addr) {
1364+
if (!ShouldEmitLifetimeMarkers)
1365+
return;
1366+
13691367
assert(Addr->getType()->getPointerAddressSpace() ==
13701368
CGM.getDataLayout().getAllocaAddrSpace() &&
13711369
"Pointer should be in alloca address space");
1372-
llvm::CallInst *C =
1373-
Builder.CreateCall(CGM.getLLVMLifetimeEndFn(), {Size, Addr});
1370+
llvm::CallInst *C = Builder.CreateCall(CGM.getLLVMLifetimeEndFn(), {Addr});
13741371
C->setDoesNotThrow();
13751372
}
13761373

@@ -1628,9 +1625,8 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
16281625
// is rare.
16291626
if (!Bypasses.IsBypassed(&D) &&
16301627
!(!getLangOpts().CPlusPlus && hasLabelBeenSeenInCurrentScope())) {
1631-
llvm::TypeSize Size = CGM.getDataLayout().getTypeAllocSize(allocaTy);
1632-
emission.SizeForLifetimeMarkers =
1633-
EmitLifetimeStart(Size, AllocaAddr.getPointer());
1628+
emission.UseLifetimeMarkers =
1629+
EmitLifetimeStart(AllocaAddr.getPointer());
16341630
}
16351631
} else {
16361632
assert(!emission.useLifetimeMarkers());
@@ -1723,9 +1719,8 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
17231719

17241720
// Make sure we call @llvm.lifetime.end.
17251721
if (emission.useLifetimeMarkers())
1726-
EHStack.pushCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker,
1727-
emission.getOriginalAllocatedAddress(),
1728-
emission.getSizeForLifetimeMarkers());
1722+
EHStack.pushCleanup<CallLifetimeEnd>(
1723+
NormalEHLifetimeMarker, emission.getOriginalAllocatedAddress());
17291724

17301725
// Analogous to lifetime markers, we use a 'cleanup' to emit fake.use
17311726
// calls for local variables. We are exempting volatile variables and

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -577,11 +577,9 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) {
577577
} else {
578578
switch (M->getStorageDuration()) {
579579
case SD_Automatic:
580-
if (auto *Size = EmitLifetimeStart(
581-
CGM.getDataLayout().getTypeAllocSize(Alloca.getElementType()),
582-
Alloca.getPointer())) {
580+
if (EmitLifetimeStart(Alloca.getPointer())) {
583581
pushCleanupAfterFullExpr<CallLifetimeEnd>(NormalEHLifetimeMarker,
584-
Alloca, Size);
582+
Alloca);
585583
}
586584
break;
587585

@@ -612,11 +610,8 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) {
612610
Block, llvm::BasicBlock::iterator(Block->back())));
613611
}
614612

615-
if (auto *Size = EmitLifetimeStart(
616-
CGM.getDataLayout().getTypeAllocSize(Alloca.getElementType()),
617-
Alloca.getPointer())) {
618-
pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, Alloca,
619-
Size);
613+
if (EmitLifetimeStart(Alloca.getPointer())) {
614+
pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, Alloca);
620615
}
621616

622617
if (OldConditional) {
@@ -5743,13 +5738,10 @@ LValue CodeGenFunction::EmitHLSLOutArgExpr(const HLSLOutArgExpr *E,
57435738
llvm::Value *Addr = TempLV.getAddress().getBasePointer();
57445739
llvm::Type *ElTy = ConvertTypeForMem(TempLV.getType());
57455740

5746-
llvm::TypeSize Sz = CGM.getDataLayout().getTypeAllocSize(ElTy);
5747-
5748-
llvm::Value *LifetimeSize = EmitLifetimeStart(Sz, Addr);
5741+
EmitLifetimeStart(Addr);
57495742

57505743
Address TmpAddr(Addr, ElTy, TempLV.getAlignment());
5751-
Args.addWriteback(BaseLV, TmpAddr, nullptr, E->getWritebackCast(),
5752-
LifetimeSize);
5744+
Args.addWriteback(BaseLV, TmpAddr, nullptr, E->getWritebackCast());
57535745
Args.add(RValue::get(TmpAddr, *this), Ty);
57545746
return TempLV;
57555747
}

clang/lib/CodeGen/CGExprAgg.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -300,24 +300,20 @@ void AggExprEmitter::withReturnValueSlot(
300300
Address RetAddr = Address::invalid();
301301

302302
EHScopeStack::stable_iterator LifetimeEndBlock;
303-
llvm::Value *LifetimeSizePtr = nullptr;
304303
llvm::IntrinsicInst *LifetimeStartInst = nullptr;
305304
if (!UseTemp) {
306305
RetAddr = Dest.getAddress();
307306
} else {
308307
RetAddr = CGF.CreateMemTempWithoutCast(RetTy, "tmp");
309-
llvm::TypeSize Size =
310-
CGF.CGM.getDataLayout().getTypeAllocSize(CGF.ConvertTypeForMem(RetTy));
311-
LifetimeSizePtr = CGF.EmitLifetimeStart(Size, RetAddr.getBasePointer());
312-
if (LifetimeSizePtr) {
308+
if (CGF.EmitLifetimeStart(RetAddr.getBasePointer())) {
313309
LifetimeStartInst =
314310
cast<llvm::IntrinsicInst>(std::prev(Builder.GetInsertPoint()));
315311
assert(LifetimeStartInst->getIntrinsicID() ==
316312
llvm::Intrinsic::lifetime_start &&
317313
"Last insertion wasn't a lifetime.start?");
318314

319315
CGF.pushFullExprCleanup<CodeGenFunction::CallLifetimeEnd>(
320-
NormalEHLifetimeMarker, RetAddr, LifetimeSizePtr);
316+
NormalEHLifetimeMarker, RetAddr);
321317
LifetimeEndBlock = CGF.EHStack.stable_begin();
322318
}
323319
}
@@ -338,7 +334,7 @@ void AggExprEmitter::withReturnValueSlot(
338334
// Since we're not guaranteed to be in an ExprWithCleanups, clean up
339335
// eagerly.
340336
CGF.DeactivateCleanupBlock(LifetimeEndBlock, LifetimeStartInst);
341-
CGF.EmitLifetimeEnd(LifetimeSizePtr, RetAddr.getBasePointer());
337+
CGF.EmitLifetimeEnd(RetAddr.getBasePointer());
342338
}
343339
}
344340

0 commit comments

Comments
 (0)