Revert "New SIL instructions to support tail-allocated arrays in SIL."

This commit is contained in:
Dmitri Gribenko
2016-09-15 00:25:25 -07:00
committed by GitHub
parent cd07c2c125
commit fbb3cf35a5
68 changed files with 1145 additions and 1470 deletions

View File

@@ -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) {