mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Revert "WIP"
Not ready for prime time, sorry. This reverts commit 3185. Swift SVN r3189
This commit is contained in:
@@ -192,7 +192,7 @@ public:
|
|||||||
return pushCleanupInState<T, A...>(state, ::std::forward<A>(args)...);
|
return pushCleanupInState<T, A...>(state, ::std::forward<A>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a stable reference to the current cleanup.
|
/// Retun a stable reference to the current cleanup.
|
||||||
CleanupsDepth getCleanupsDepth() const {
|
CleanupsDepth getCleanupsDepth() const {
|
||||||
return Cleanups.stable_begin();
|
return Cleanups.stable_begin();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,73 +15,44 @@
|
|||||||
using namespace swift;
|
using namespace swift;
|
||||||
using namespace Lowering;
|
using namespace Lowering;
|
||||||
|
|
||||||
/// Are there any active cleanups in the given range?
|
|
||||||
static bool hasAnyActiveCleanups(DiverseStackImpl<Cleanup>::iterator begin,
|
|
||||||
DiverseStackImpl<Cleanup>::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<char, sizeof(Cleanup) + 10 * sizeof(void*)> Data;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CleanupBuffer(const Cleanup &cleanup) {
|
|
||||||
size_t size = cleanup.allocated_size();
|
|
||||||
Data.set_size(size);
|
|
||||||
memcpy(Data.data(), reinterpret_cast<const void*>(&cleanup), size);
|
|
||||||
}
|
|
||||||
|
|
||||||
Cleanup &getCopy() { return *reinterpret_cast<Cleanup*>(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.
|
/// Leave a scope, with all its cleanups.
|
||||||
void CleanupManager::endScope(CleanupsDepth depth) {
|
void CleanupManager::endScope(CleanupsDepth depth) {
|
||||||
Stack.checkIterator(depth);
|
Stack.checkIterator(depth);
|
||||||
|
|
||||||
// FIXME: Thread a branch through the cleanups if there are any active
|
// Fast path: no cleanups to leave in this scope.
|
||||||
// cleanups and we have a valid insertion point.
|
if (Stack.stable_begin() == depth) {
|
||||||
|
// FIXME.
|
||||||
if (!hasAnyActiveCleanups(Stack.begin(), Stack.find(depth)))
|
//popAndEmitTopDeadCleanups(*this, Cleanups, InnermostScope);
|
||||||
return;
|
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.
|
// Iteratively mark cleanups dead and pop them.
|
||||||
// Maybe we'd get better results if we marked them all dead in one shot?
|
// 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.
|
// Mark the cleanup dead.
|
||||||
if (!Stack.begin()->isDead())
|
if (!Cleanups.begin()->isDead())
|
||||||
setCleanupState(*Stack.begin(), CleanupState::Dead);
|
setCleanupState(*Cleanups.begin(), CleanupState::Dead);
|
||||||
|
|
||||||
// Pop it.
|
// 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");
|
assert(Stack.empty() && "FIXME: Implement cleanup support");
|
||||||
B.createBranch(Dest.getBlock());
|
B.createBranch(Dest.getBlock());
|
||||||
}
|
}
|
||||||
|
|
||||||
Cleanup &CleanupManager::initCleanup(Cleanup &cleanup,
|
|
||||||
size_t allocSize,
|
|
||||||
CleanupState state)
|
|
||||||
{
|
|
||||||
cleanup.allocatedSize = allocSize;
|
|
||||||
cleanup.state = state;
|
|
||||||
return cleanup;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -20,46 +20,8 @@
|
|||||||
#include "JumpDest.h"
|
#include "JumpDest.h"
|
||||||
|
|
||||||
namespace swift {
|
namespace swift {
|
||||||
class BasicBlock;
|
|
||||||
class Function;
|
|
||||||
|
|
||||||
namespace Lowering {
|
namespace Lowering {
|
||||||
class SILGen;
|
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 {
|
class LLVM_LIBRARY_VISIBILITY CleanupManager {
|
||||||
friend class Scope;
|
friend class Scope;
|
||||||
@@ -74,15 +36,12 @@ class LLVM_LIBRARY_VISIBILITY CleanupManager {
|
|||||||
/// endScope - used by the Scope class.
|
/// endScope - used by the Scope class.
|
||||||
void endScope(CleanupsDepth Depth);
|
void endScope(CleanupsDepth Depth);
|
||||||
|
|
||||||
void popAndEmitTopCleanup();
|
|
||||||
|
|
||||||
Cleanup &initCleanup(Cleanup &cleanup, size_t allocSize, CleanupState state);
|
|
||||||
public:
|
public:
|
||||||
CleanupManager(SILGen &Gen)
|
CleanupManager(SILGen &Gen)
|
||||||
: Gen(Gen), InnermostScope(Stack.stable_end()) {
|
: 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 {
|
CleanupsDepth getCleanupsDepth() const {
|
||||||
return Stack.stable_begin();
|
return Stack.stable_begin();
|
||||||
}
|
}
|
||||||
@@ -91,31 +50,8 @@ public:
|
|||||||
/// threading out through any cleanups we might need to run. This does not
|
/// threading out through any cleanups we might need to run. This does not
|
||||||
/// pop the cleanup stack.
|
/// pop the cleanup stack.
|
||||||
void emitBranchAndCleanups(JumpDest Dest);
|
void emitBranchAndCleanups(JumpDest Dest);
|
||||||
|
|
||||||
/// pushCleanup - Push a new cleanup.
|
|
||||||
template<class T, class... A>
|
|
||||||
T &pushCleanupInState(CleanupState state,
|
|
||||||
A &&... args) {
|
|
||||||
assert(state != CleanupState::Dead);
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
CleanupsDepth oldTop = Stack.stable_begin();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
T &cleanup = Stack.push<T, A...>(::std::forward<A>(args)...);
|
|
||||||
T &result = static_cast<T&>(initCleanup(cleanup, sizeof(T), state));
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
auto newTop = Stack.begin(); ++newTop;
|
|
||||||
assert(newTop == Stack.find(oldTop));
|
|
||||||
#endif
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
template<class T, class... A>
|
|
||||||
T &pushCleanup(A &&... args) {
|
|
||||||
return pushCleanupInState<T, A...>(CleanupState::Active,
|
|
||||||
::std::forward<A>(args)...);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,10 @@ namespace swift {
|
|||||||
|
|
||||||
namespace Lowering {
|
namespace Lowering {
|
||||||
|
|
||||||
class Cleanup;
|
/// FIXME: Temporary.
|
||||||
|
typedef int Cleanup;
|
||||||
|
|
||||||
|
//class Cleanup;
|
||||||
typedef DiverseStackImpl<Cleanup>::stable_iterator CleanupsDepth;
|
typedef DiverseStackImpl<Cleanup>::stable_iterator CleanupsDepth;
|
||||||
|
|
||||||
/// The destination of a direct jump. Swift currently does not
|
/// The destination of a direct jump. Swift currently does not
|
||||||
|
|||||||
@@ -54,12 +54,11 @@ public:
|
|||||||
|
|
||||||
void emitProlog(FuncExpr *FE);
|
void emitProlog(FuncExpr *FE);
|
||||||
|
|
||||||
/// Return a stable reference to the current cleanup.
|
/// Retun a stable reference to the current cleanup.
|
||||||
CleanupsDepth getCleanupsDepth() const {
|
CleanupsDepth getCleanupsDepth() const {
|
||||||
return Cleanups.getCleanupsDepth();
|
return Cleanups.getCleanupsDepth();
|
||||||
}
|
}
|
||||||
|
|
||||||
Function &getFunction() { return F; }
|
|
||||||
SILBuilder &getBuilder() { return B; }
|
SILBuilder &getBuilder() { return B; }
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user