Remove the LLVM stack promotion pass and related SIL optimization logic.

It's not needed anymore because array buffers are now allocated with alloc_ref instead of a swift_bufferAllocate runtime call.
This commit is contained in:
Erik Eckstein
2016-09-09 15:33:21 -07:00
parent b67959a6c1
commit bd0d2bfed4
13 changed files with 37 additions and 820 deletions

View File

@@ -24,6 +24,7 @@ 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
/// ...
@@ -37,10 +38,6 @@ 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).
@@ -57,10 +54,6 @@ 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,
@@ -91,11 +84,6 @@ void ReleaseDevirtualizer::run() {
LastRelease = nullptr;
continue;
}
if (auto *AI = dyn_cast<ApplyInst>(&I)) {
Changed |= devirtualizeReleaseOfBuffer(LastRelease, AI);
LastRelease = nullptr;
continue;
}
}
if (isa<ReleaseValueInst>(&I) ||
@@ -139,51 +127,6 @@ 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) {