Skip to content

Commit f18cd08

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 129a354 commit f18cd08

File tree

479 files changed

+4516
-5159
lines changed

Some content is hidden

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

479 files changed

+4516
-5159
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
@@ -4319,10 +4319,7 @@ static void emitWriteback(CodeGenFunction &CGF,
43194319

43204320
if (writeback.WritebackExpr) {
43214321
CGF.EmitIgnoredExpr(writeback.WritebackExpr);
4322-
4323-
if (writeback.LifetimeSz)
4324-
CGF.EmitLifetimeEnd(writeback.LifetimeSz,
4325-
writeback.Temporary.getBasePointer());
4322+
CGF.EmitLifetimeEnd(writeback.Temporary.getBasePointer());
43264323
return;
43274324
}
43284325

@@ -5282,7 +5279,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
52825279
// If the call returns a temporary with struct return, create a temporary
52835280
// alloca to hold the result, unless one is given to us.
52845281
Address SRetPtr = Address::invalid();
5285-
llvm::Value *UnusedReturnSizePtr = nullptr;
5282+
bool NeedSRetLifetimeEnd = false;
52865283
if (RetAI.isIndirect() || RetAI.isInAlloca() || RetAI.isCoerceAndExpand()) {
52875284
// For virtual function pointer thunks and musttail calls, we must always
52885285
// forward an incoming SRet pointer to the callee, because a local alloca
@@ -5296,11 +5293,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
52965293
SRetPtr = ReturnValue.getAddress();
52975294
} else {
52985295
SRetPtr = CreateMemTempWithoutCast(RetTy, "tmp");
5299-
if (HaveInsertPoint() && ReturnValue.isUnused()) {
5300-
llvm::TypeSize size =
5301-
CGM.getDataLayout().getTypeAllocSize(ConvertTypeForMem(RetTy));
5302-
UnusedReturnSizePtr = EmitLifetimeStart(size, SRetPtr.getBasePointer());
5303-
}
5296+
if (HaveInsertPoint() && ReturnValue.isUnused())
5297+
NeedSRetLifetimeEnd = EmitLifetimeStart(SRetPtr.getBasePointer());
53045298
}
53055299
if (IRFunctionArgs.hasSRetArg()) {
53065300
// A mismatch between the allocated return value's AS and the target's
@@ -5484,15 +5478,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
54845478
Val = Builder.CreateFreeze(Val);
54855479
IRCallArgs[FirstIRArg] = Val;
54865480

5487-
// Emit lifetime markers for the temporary alloca.
5488-
llvm::TypeSize ByvalTempElementSize =
5489-
CGM.getDataLayout().getTypeAllocSize(AI.getElementType());
5490-
llvm::Value *LifetimeSize =
5491-
EmitLifetimeStart(ByvalTempElementSize, AI.getPointer());
5492-
5493-
// Add cleanup code to emit the end lifetime marker after the call.
5494-
if (LifetimeSize) // In case we disabled lifetime markers.
5495-
CallLifetimeEndAfterCall.emplace_back(AI, LifetimeSize);
5481+
// Emit lifetime markers for the temporary alloca and add cleanup code to
5482+
// emit the end lifetime marker after the call.
5483+
if (EmitLifetimeStart(AI.getPointer()))
5484+
CallLifetimeEndAfterCall.emplace_back(AI);
54965485

54975486
// Generate the copy.
54985487
I->copyInto(*this, AI);
@@ -5653,9 +5642,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
56535642
auto unpaddedCoercionType = ArgInfo.getUnpaddedCoerceAndExpandType();
56545643
auto *unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoercionType);
56555644

5656-
llvm::Value *tempSize = nullptr;
56575645
Address addr = Address::invalid();
56585646
RawAddress AllocaAddr = RawAddress::invalid();
5647+
bool NeedLifetimeEnd = false;
56595648
if (I->isAggregate()) {
56605649
addr = I->hasLValue() ? I->getKnownLValue().getAddress()
56615650
: I->getKnownRValue().getAggregateAddress();
@@ -5665,7 +5654,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
56655654
assert(RV.isScalar()); // complex should always just be direct
56665655

56675656
llvm::Type *scalarType = RV.getScalarVal()->getType();
5668-
auto scalarSize = CGM.getDataLayout().getTypeAllocSize(scalarType);
56695657
auto scalarAlign = CGM.getDataLayout().getPrefTypeAlign(scalarType);
56705658

56715659
// Materialize to a temporary.
@@ -5674,7 +5662,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
56745662
layout->getAlignment(), scalarAlign)),
56755663
"tmp",
56765664
/*ArraySize=*/nullptr, &AllocaAddr);
5677-
tempSize = EmitLifetimeStart(scalarSize, AllocaAddr.getPointer());
5665+
NeedLifetimeEnd = EmitLifetimeStart(AllocaAddr.getPointer());
56785666

56795667
Builder.CreateStore(RV.getScalarVal(), addr);
56805668
}
@@ -5699,10 +5687,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
56995687
}
57005688
assert(IRArgPos == FirstIRArg + NumIRArgs);
57015689

5702-
if (tempSize) {
5703-
EmitLifetimeEnd(tempSize, AllocaAddr.getPointer());
5704-
}
5705-
5690+
if (NeedLifetimeEnd)
5691+
EmitLifetimeEnd(AllocaAddr.getPointer());
57065692
break;
57075693
}
57085694

@@ -5871,9 +5857,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
58715857
// can't depend on being inside of an ExprWithCleanups, so we need to manually
58725858
// pop this cleanup later on. Being eager about this is OK, since this
58735859
// temporary is 'invisible' outside of the callee.
5874-
if (UnusedReturnSizePtr)
5875-
pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, SRetPtr,
5876-
UnusedReturnSizePtr);
5860+
if (NeedSRetLifetimeEnd)
5861+
pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, SRetPtr);
58775862

58785863
llvm::BasicBlock *InvokeDest = CannotThrow ? nullptr : getInvokeDest();
58795864

@@ -6007,7 +5992,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
60075992
// insertion point; this allows the rest of IRGen to discard
60085993
// unreachable code.
60095994
if (CI->doesNotReturn()) {
6010-
if (UnusedReturnSizePtr)
5995+
if (NeedSRetLifetimeEnd)
60115996
PopCleanupBlock();
60125997

60135998
// Strip away the noreturn attribute to better diagnose unreachable UB.
@@ -6122,7 +6107,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
61226107
case ABIArgInfo::InAlloca:
61236108
case ABIArgInfo::Indirect: {
61246109
RValue ret = convertTempToRValue(SRetPtr, RetTy, SourceLocation());
6125-
if (UnusedReturnSizePtr)
6110+
if (NeedSRetLifetimeEnd)
61266111
PopCleanupBlock();
61276112
return ret;
61286113
}

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)