mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Revert "New SIL instructions to support tail-allocated arrays in SIL."
This commit is contained in:
@@ -24,7 +24,6 @@ using namespace swift;
|
||||
namespace {
|
||||
|
||||
/// Devirtualizes release instructions which are known to destruct the object.
|
||||
///
|
||||
/// This means, it replaces a sequence of
|
||||
/// %x = alloc_ref [stack] $X
|
||||
/// ...
|
||||
@@ -38,6 +37,10 @@ namespace {
|
||||
/// %a = apply %d(%x)
|
||||
/// dealloc_ref [stack] %x
|
||||
///
|
||||
/// It also works for array buffers, where the allocation/deallocation is done
|
||||
/// by calls to the swift_bufferAllocateOnStack/swift_bufferDeallocateFromStack
|
||||
/// functions.
|
||||
///
|
||||
/// The optimization is only done for stack promoted objects because they are
|
||||
/// known to have no associated objects (which are not explicitly released
|
||||
/// in the deinit method).
|
||||
@@ -54,6 +57,10 @@ private:
|
||||
bool devirtualizeReleaseOfObject(SILInstruction *ReleaseInst,
|
||||
DeallocRefInst *DeallocInst);
|
||||
|
||||
/// Devirtualize releases of swift objects.
|
||||
bool devirtualizeReleaseOfBuffer(SILInstruction *ReleaseInst,
|
||||
ApplyInst *DeallocCall);
|
||||
|
||||
/// Replace the release-instruction \p ReleaseInst with an explicit call to
|
||||
/// the deallocating destructor of \p AllocType for \p object.
|
||||
bool createDeallocCall(SILType AllocType, SILInstruction *ReleaseInst,
|
||||
@@ -84,6 +91,11 @@ void ReleaseDevirtualizer::run() {
|
||||
LastRelease = nullptr;
|
||||
continue;
|
||||
}
|
||||
if (auto *AI = dyn_cast<ApplyInst>(&I)) {
|
||||
Changed |= devirtualizeReleaseOfBuffer(LastRelease, AI);
|
||||
LastRelease = nullptr;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (isa<ReleaseValueInst>(&I) ||
|
||||
@@ -127,6 +139,51 @@ devirtualizeReleaseOfObject(SILInstruction *ReleaseInst,
|
||||
return createDeallocCall(AllocType, ReleaseInst, ARI);
|
||||
}
|
||||
|
||||
bool ReleaseDevirtualizer::
|
||||
devirtualizeReleaseOfBuffer(SILInstruction *ReleaseInst,
|
||||
ApplyInst *DeallocCall) {
|
||||
|
||||
DEBUG(llvm::dbgs() << " try to devirtualize " << *ReleaseInst);
|
||||
|
||||
// Is this a deallocation of a buffer?
|
||||
SILFunction *DeallocFn = DeallocCall->getReferencedFunction();
|
||||
if (!DeallocFn || DeallocFn->getName() != "swift_bufferDeallocateFromStack")
|
||||
return false;
|
||||
|
||||
// Is the deallocation call paired with an allocation call?
|
||||
ApplyInst *AllocAI = dyn_cast<ApplyInst>(DeallocCall->getArgument(0));
|
||||
if (!AllocAI || AllocAI->getNumArguments() < 1)
|
||||
return false;
|
||||
|
||||
SILFunction *AllocFunc = AllocAI->getReferencedFunction();
|
||||
if (!AllocFunc || AllocFunc->getName() != "swift_bufferAllocateOnStack")
|
||||
return false;
|
||||
|
||||
// Can we find the buffer type which is allocated? It's metatype is passed
|
||||
// as first argument to the allocation function.
|
||||
auto *IEMTI = dyn_cast<InitExistentialMetatypeInst>(AllocAI->getArgument(0));
|
||||
if (!IEMTI)
|
||||
return false;
|
||||
|
||||
SILType MType = IEMTI->getOperand()->getType();
|
||||
auto *MetaType = MType.getSwiftRValueType()->getAs<AnyMetatypeType>();
|
||||
if (!MetaType)
|
||||
return false;
|
||||
|
||||
// Is the allocated buffer a class type? This should always be the case.
|
||||
auto *ClType = MetaType->getInstanceType()->getAs<BoundGenericClassType>();
|
||||
if (!ClType)
|
||||
return false;
|
||||
|
||||
// Does the last release really release the allocated buffer?
|
||||
SILValue rcRoot = RCIA->getRCIdentityRoot(ReleaseInst->getOperand(0));
|
||||
if (rcRoot != AllocAI)
|
||||
return false;
|
||||
|
||||
SILType SILClType = SILType::getPrimitiveObjectType(CanType(ClType));
|
||||
return createDeallocCall(SILClType, ReleaseInst, AllocAI);
|
||||
}
|
||||
|
||||
bool ReleaseDevirtualizer::createDeallocCall(SILType AllocType,
|
||||
SILInstruction *ReleaseInst,
|
||||
SILValue object) {
|
||||
|
||||
Reference in New Issue
Block a user