Skip to content

Commit c23b4fb

Browse files
authored
[IR] Remove size argument from lifetime intrinsics (#150248)
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 (though many key places, including stack coloring, did not actually respect this).
1 parent b800930 commit c23b4fb

File tree

479 files changed

+4418
-4759
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

+4418
-4759
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

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

59865986
// Create a temporary array to hold the sizes of local pointer arguments
59875987
// for the block. \p First is the position of the first size argument.
5988-
auto CreateArrayForSizeVar = [=](unsigned First)
5989-
-> std::tuple<llvm::Value *, llvm::Value *, llvm::Value *> {
5988+
auto CreateArrayForSizeVar =
5989+
[=](unsigned First) -> std::pair<llvm::Value *, llvm::Value *> {
59905990
llvm::APInt ArraySize(32, NumArgs - First);
59915991
QualType SizeArrayTy = getContext().getConstantArrayType(
59925992
getContext().getSizeType(), ArraySize, nullptr,
@@ -5999,9 +5999,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
59995999
// actually the Alloca ascasted to the default AS, hence the
60006000
// stripPointerCasts()
60016001
llvm::Value *Alloca = TmpPtr->stripPointerCasts();
6002-
llvm::Value *TmpSize = EmitLifetimeStart(
6003-
CGM.getDataLayout().getTypeAllocSize(Tmp.getElementType()), Alloca);
60046002
llvm::Value *ElemPtr;
6003+
EmitLifetimeStart(Alloca);
60056004
// Each of the following arguments specifies the size of the corresponding
60066005
// argument passed to the enqueued block.
60076006
auto *Zero = llvm::ConstantInt::get(IntTy, 0);
@@ -6018,7 +6017,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
60186017
}
60196018
// Return the Alloca itself rather than a potential ascast as this is only
60206019
// used by the paired EmitLifetimeEnd.
6021-
return {ElemPtr, TmpSize, Alloca};
6020+
return {ElemPtr, Alloca};
60226021
};
60236022

60246023
// Could have events and/or varargs.
@@ -6030,7 +6029,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
60306029
llvm::Value *Kernel =
60316030
Builder.CreatePointerCast(Info.KernelHandle, GenericVoidPtrTy);
60326031
auto *Block = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy);
6033-
auto [ElemPtr, TmpSize, TmpPtr] = CreateArrayForSizeVar(4);
6032+
auto [ElemPtr, TmpPtr] = CreateArrayForSizeVar(4);
60346033

60356034
// Create a vector of the arguments, as well as a constant value to
60366035
// express to the runtime the number of variadic arguments.
@@ -6045,8 +6044,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
60456044
llvm::FunctionType *FTy = llvm::FunctionType::get(Int32Ty, ArgTys, false);
60466045
auto Call = RValue::get(
60476046
EmitRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Args));
6048-
if (TmpSize)
6049-
EmitLifetimeEnd(TmpSize, TmpPtr);
6047+
EmitLifetimeEnd(TmpPtr);
60506048
return Call;
60516049
}
60526050
// Any calls now have event arguments passed.
@@ -6111,15 +6109,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
61116109
ArgTys.push_back(Int32Ty);
61126110
Name = "__enqueue_kernel_events_varargs";
61136111

6114-
auto [ElemPtr, TmpSize, TmpPtr] = CreateArrayForSizeVar(7);
6112+
auto [ElemPtr, TmpPtr] = CreateArrayForSizeVar(7);
61156113
Args.push_back(ElemPtr);
61166114
ArgTys.push_back(ElemPtr->getType());
61176115

61186116
llvm::FunctionType *FTy = llvm::FunctionType::get(Int32Ty, ArgTys, false);
61196117
auto Call = RValue::get(
61206118
EmitRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Args));
6121-
if (TmpSize)
6122-
EmitLifetimeEnd(TmpSize, TmpPtr);
6119+
EmitLifetimeEnd(TmpPtr);
61236120
return Call;
61246121
}
61256122
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
@@ -1351,30 +1351,27 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D) {
13511351
}
13521352

13531353
/// Emit a lifetime.begin marker if some criteria are satisfied.
1354-
/// \return a pointer to the temporary size Value if a marker was emitted, null
1355-
/// otherwise
1356-
llvm::Value *CodeGenFunction::EmitLifetimeStart(llvm::TypeSize Size,
1357-
llvm::Value *Addr) {
1354+
/// \return whether the marker was emitted.
1355+
bool CodeGenFunction::EmitLifetimeStart(llvm::Value *Addr) {
13581356
if (!ShouldEmitLifetimeMarkers)
1359-
return nullptr;
1357+
return false;
13601358

13611359
assert(Addr->getType()->getPointerAddressSpace() ==
13621360
CGM.getDataLayout().getAllocaAddrSpace() &&
13631361
"Pointer should be in alloca address space");
1364-
llvm::Value *SizeV = llvm::ConstantInt::get(
1365-
Int64Ty, Size.isScalable() ? -1 : Size.getFixedValue());
1366-
llvm::CallInst *C =
1367-
Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {SizeV, Addr});
1362+
llvm::CallInst *C = Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {Addr});
13681363
C->setDoesNotThrow();
1369-
return SizeV;
1364+
return true;
13701365
}
13711366

1372-
void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {
1367+
void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Addr) {
1368+
if (!ShouldEmitLifetimeMarkers)
1369+
return;
1370+
13731371
assert(Addr->getType()->getPointerAddressSpace() ==
13741372
CGM.getDataLayout().getAllocaAddrSpace() &&
13751373
"Pointer should be in alloca address space");
1376-
llvm::CallInst *C =
1377-
Builder.CreateCall(CGM.getLLVMLifetimeEndFn(), {Size, Addr});
1374+
llvm::CallInst *C = Builder.CreateCall(CGM.getLLVMLifetimeEndFn(), {Addr});
13781375
C->setDoesNotThrow();
13791376
}
13801377

@@ -1632,9 +1629,8 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
16321629
// is rare.
16331630
if (!Bypasses.IsBypassed(&D) &&
16341631
!(!getLangOpts().CPlusPlus && hasLabelBeenSeenInCurrentScope())) {
1635-
llvm::TypeSize Size = CGM.getDataLayout().getTypeAllocSize(allocaTy);
1636-
emission.SizeForLifetimeMarkers =
1637-
EmitLifetimeStart(Size, AllocaAddr.getPointer());
1632+
emission.UseLifetimeMarkers =
1633+
EmitLifetimeStart(AllocaAddr.getPointer());
16381634
}
16391635
} else {
16401636
assert(!emission.useLifetimeMarkers());
@@ -1727,9 +1723,8 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
17271723

17281724
// Make sure we call @llvm.lifetime.end.
17291725
if (emission.useLifetimeMarkers())
1730-
EHStack.pushCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker,
1731-
emission.getOriginalAllocatedAddress(),
1732-
emission.getSizeForLifetimeMarkers());
1726+
EHStack.pushCleanup<CallLifetimeEnd>(
1727+
NormalEHLifetimeMarker, emission.getOriginalAllocatedAddress());
17331728

17341729
// Analogous to lifetime markers, we use a 'cleanup' to emit fake.use
17351730
// 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
@@ -588,11 +588,9 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) {
588588
} else {
589589
switch (M->getStorageDuration()) {
590590
case SD_Automatic:
591-
if (auto *Size = EmitLifetimeStart(
592-
CGM.getDataLayout().getTypeAllocSize(Alloca.getElementType()),
593-
Alloca.getPointer())) {
591+
if (EmitLifetimeStart(Alloca.getPointer())) {
594592
pushCleanupAfterFullExpr<CallLifetimeEnd>(NormalEHLifetimeMarker,
595-
Alloca, Size);
593+
Alloca);
596594
}
597595
break;
598596

@@ -623,11 +621,8 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) {
623621
Block, llvm::BasicBlock::iterator(Block->back())));
624622
}
625623

626-
if (auto *Size = EmitLifetimeStart(
627-
CGM.getDataLayout().getTypeAllocSize(Alloca.getElementType()),
628-
Alloca.getPointer())) {
629-
pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, Alloca,
630-
Size);
624+
if (EmitLifetimeStart(Alloca.getPointer())) {
625+
pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, Alloca);
631626
}
632627

633628
if (OldConditional) {
@@ -5784,13 +5779,10 @@ LValue CodeGenFunction::EmitHLSLOutArgExpr(const HLSLOutArgExpr *E,
57845779
llvm::Value *Addr = TempLV.getAddress().getBasePointer();
57855780
llvm::Type *ElTy = ConvertTypeForMem(TempLV.getType());
57865781

5787-
llvm::TypeSize Sz = CGM.getDataLayout().getTypeAllocSize(ElTy);
5788-
5789-
llvm::Value *LifetimeSize = EmitLifetimeStart(Sz, Addr);
5782+
EmitLifetimeStart(Addr);
57905783

57915784
Address TmpAddr(Addr, ElTy, TempLV.getAlignment());
5792-
Args.addWriteback(BaseLV, TmpAddr, nullptr, E->getWritebackCast(),
5793-
LifetimeSize);
5785+
Args.addWriteback(BaseLV, TmpAddr, nullptr, E->getWritebackCast());
57945786
Args.add(RValue::get(TmpAddr, *this), Ty);
57955787
return TempLV;
57965788
}

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)