diff --git a/lib/IRGen/IRGenFunction.h b/lib/IRGen/IRGenFunction.h index 83ba5fe7226..2692869eb90 100644 --- a/lib/IRGen/IRGenFunction.h +++ b/lib/IRGen/IRGenFunction.h @@ -192,7 +192,7 @@ public: return pushCleanupInState(state, ::std::forward(args)...); } - /// Return a stable reference to the current cleanup. + /// Retun a stable reference to the current cleanup. CleanupsDepth getCleanupsDepth() const { return Cleanups.stable_begin(); } diff --git a/lib/SIL/SILGen/Cleanup.cpp b/lib/SIL/SILGen/Cleanup.cpp index 61df5b94084..0d151707eeb 100644 --- a/lib/SIL/SILGen/Cleanup.cpp +++ b/lib/SIL/SILGen/Cleanup.cpp @@ -15,73 +15,44 @@ using namespace swift; using namespace Lowering; -/// Are there any active cleanups in the given range? -static bool hasAnyActiveCleanups(DiverseStackImpl::iterator begin, - DiverseStackImpl::iterator end) { - for (; begin != end; ++begin) - if (begin->isActive()) - return true; - return false; -} - -/// Transition the state of a cleanup. -/// FIXME: transition logic -static void setCleanupState(Cleanup &cleanup, - CleanupState state) { - cleanup.setState(state); -} - -namespace { - /// A CleanupBuffer is a location to which to temporarily copy a - /// cleanup. - class CleanupBuffer { - llvm::SmallVector Data; - - public: - CleanupBuffer(const Cleanup &cleanup) { - size_t size = cleanup.allocated_size(); - Data.set_size(size); - memcpy(Data.data(), reinterpret_cast(&cleanup), size); - } - - Cleanup &getCopy() { return *reinterpret_cast(Data.data()); } - }; -} - -void CleanupManager::popAndEmitTopCleanup() { - Cleanup &stackCleanup = *Stack.begin(); - assert(stackCleanup.isDead() && "popping a living cleanup"); - - // Copy it off the cleanups stack. - CleanupBuffer buffer(stackCleanup); - Cleanup &cleanup = buffer.getCopy(); - - // Pop now. - Stack.pop(); - - cleanup.emit(Gen); -} /// Leave a scope, with all its cleanups. void CleanupManager::endScope(CleanupsDepth depth) { Stack.checkIterator(depth); - // FIXME: Thread a branch through the cleanups if there are any active - // cleanups and we have a valid insertion point. - - if (!hasAnyActiveCleanups(Stack.begin(), Stack.find(depth))) + // Fast path: no cleanups to leave in this scope. + if (Stack.stable_begin() == depth) { + // FIXME. + //popAndEmitTopDeadCleanups(*this, Cleanups, InnermostScope); return; + } + +#if 0 // FIXME: Cleanups. + + // Thread a branch through the cleanups if there are any active + // cleanups and we have a valid insertion point. + BasicBlock *contBB = nullptr; + if (B.hasValidInsertionPoint() && + hasAnyActiveCleanups(Cleanups.begin(), Cleanups.find(depth))) { + contBB = new (C) BasicBlock(&C, "cleanups.fallthrough"); + emitBranch(JumpDest(contBB, depth)); + } // Iteratively mark cleanups dead and pop them. // Maybe we'd get better results if we marked them all dead in one shot? - while (Stack.stable_begin() != depth) { + while (Cleanups.stable_begin() != depth) { // Mark the cleanup dead. - if (!Stack.begin()->isDead()) - setCleanupState(*Stack.begin(), CleanupState::Dead); + if (!Cleanups.begin()->isDead()) + setCleanupState(*Cleanups.begin(), CleanupState::Dead); // Pop it. - popAndEmitTopCleanup(); + popAndEmitTopCleanup(*this, Cleanups); } + + // Emit the continuation block if we made one. + if (contBB) + B.emitMergeableBlock(contBB); +#endif } @@ -94,12 +65,3 @@ void CleanupManager::emitBranchAndCleanups(JumpDest Dest) { assert(Stack.empty() && "FIXME: Implement cleanup support"); B.createBranch(Dest.getBlock()); } - -Cleanup &CleanupManager::initCleanup(Cleanup &cleanup, - size_t allocSize, - CleanupState state) -{ - cleanup.allocatedSize = allocSize; - cleanup.state = state; - return cleanup; -} diff --git a/lib/SIL/SILGen/Cleanup.h b/lib/SIL/SILGen/Cleanup.h index 7c0a027e854..fbd28ed8adc 100644 --- a/lib/SIL/SILGen/Cleanup.h +++ b/lib/SIL/SILGen/Cleanup.h @@ -20,46 +20,8 @@ #include "JumpDest.h" namespace swift { - class BasicBlock; - class Function; - namespace Lowering { class SILGen; - class CleanupOutflows; - -/// The valid states that a cleanup can be in. -enum class CleanupState { - /// The cleanup is inactive but may be activated later. - Dormant, - - /// The cleanup is currently active. - Active, - - /// The cleanup is inactive and will not be activated later. - Dead -}; - -class LLVM_LIBRARY_VISIBILITY Cleanup { - unsigned allocatedSize; - CleanupState state; - - friend class CleanupManager; -protected: - Cleanup() {} - virtual ~Cleanup() {} - -public: - /// Return the allocated size of this object. This is required by - /// DiverseStack for iteration. - size_t allocated_size() const { return allocatedSize; } - - CleanupState getState() const { return state; } - void setState(CleanupState newState) { state = newState; } - bool isActive() const { return state == CleanupState::Active; } - bool isDead() const { return state == CleanupState::Dead; } - - virtual void emit(SILGen &Gen) = 0; -}; class LLVM_LIBRARY_VISIBILITY CleanupManager { friend class Scope; @@ -74,15 +36,12 @@ class LLVM_LIBRARY_VISIBILITY CleanupManager { /// endScope - used by the Scope class. void endScope(CleanupsDepth Depth); - void popAndEmitTopCleanup(); - - Cleanup &initCleanup(Cleanup &cleanup, size_t allocSize, CleanupState state); public: CleanupManager(SILGen &Gen) : Gen(Gen), InnermostScope(Stack.stable_end()) { } - /// Return a stable reference to the current cleanup. + /// Retun a stable reference to the current cleanup. CleanupsDepth getCleanupsDepth() const { return Stack.stable_begin(); } @@ -91,31 +50,8 @@ public: /// threading out through any cleanups we might need to run. This does not /// pop the cleanup stack. void emitBranchAndCleanups(JumpDest Dest); - - /// pushCleanup - Push a new cleanup. - template - T &pushCleanupInState(CleanupState state, - A &&... args) { - assert(state != CleanupState::Dead); -#ifndef NDEBUG - CleanupsDepth oldTop = Stack.stable_begin(); -#endif - - T &cleanup = Stack.push(::std::forward(args)...); - T &result = static_cast(initCleanup(cleanup, sizeof(T), state)); - -#ifndef NDEBUG - auto newTop = Stack.begin(); ++newTop; - assert(newTop == Stack.find(oldTop)); -#endif - return result; - } - template - T &pushCleanup(A &&... args) { - return pushCleanupInState(CleanupState::Active, - ::std::forward(args)...); - } + }; diff --git a/lib/SIL/SILGen/JumpDest.h b/lib/SIL/SILGen/JumpDest.h index 167a1882b31..31208e6a12b 100644 --- a/lib/SIL/SILGen/JumpDest.h +++ b/lib/SIL/SILGen/JumpDest.h @@ -25,7 +25,10 @@ namespace swift { namespace Lowering { -class Cleanup; +/// FIXME: Temporary. +typedef int Cleanup; + +//class Cleanup; typedef DiverseStackImpl::stable_iterator CleanupsDepth; /// The destination of a direct jump. Swift currently does not diff --git a/lib/SIL/SILGen/SILGen.h b/lib/SIL/SILGen/SILGen.h index 89b819580c8..5be9ef45ebd 100644 --- a/lib/SIL/SILGen/SILGen.h +++ b/lib/SIL/SILGen/SILGen.h @@ -54,12 +54,11 @@ public: void emitProlog(FuncExpr *FE); - /// Return a stable reference to the current cleanup. + /// Retun a stable reference to the current cleanup. CleanupsDepth getCleanupsDepth() const { return Cleanups.getCleanupsDepth(); } - Function &getFunction() { return F; } SILBuilder &getBuilder() { return B; } //===--------------------------------------------------------------------===// diff --git a/test/SIL/lifetime.swift b/test/SIL/lifetime.swift deleted file mode 100644 index 1fede49a60d..00000000000 --- a/test/SIL/lifetime.swift +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %swift -dump-sil %s | FileCheck %s - -class Ref { -} -struct Val { -} - -// CHECK: func_decl local_reftype -func local_reftype() { - var a = new Ref() - // CHECK: alloc_var a - // CHECK: release a -} - -// CHECK: func_decl local_valtype -func local_valtype() { - var b = new Val() - // CHECK: alloc_var b - // CHECK: release b -}