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 a stable reference to the current cleanup.
|
||||
/// Retun a stable reference to the current cleanup.
|
||||
CleanupsDepth getCleanupsDepth() const {
|
||||
return Cleanups.stable_begin();
|
||||
}
|
||||
|
||||
@@ -15,73 +15,44 @@
|
||||
using namespace swift;
|
||||
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.
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -92,30 +51,7 @@ public:
|
||||
/// pop the cleanup stack.
|
||||
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 {
|
||||
|
||||
class Cleanup;
|
||||
/// FIXME: Temporary.
|
||||
typedef int Cleanup;
|
||||
|
||||
//class Cleanup;
|
||||
typedef DiverseStackImpl<Cleanup>::stable_iterator CleanupsDepth;
|
||||
|
||||
/// The destination of a direct jump. Swift currently does not
|
||||
|
||||
@@ -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; }
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
@@ -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