remove the Cleanup subclasses.

Swift SVN r4839
This commit is contained in:
Chris Lattner
2013-04-21 05:06:52 +00:00
parent ef79e16137
commit e3d6a489af
11 changed files with 10 additions and 281 deletions

View File

@@ -29,7 +29,6 @@ namespace irgen {
class Cleanup {
unsigned AllocatedSize;
unsigned State : 2;
llvm::BasicBlock *NormalEntryBB;
friend Cleanup &IRGenFunction::initCleanup(Cleanup &, size_t, CleanupState);
protected:
@@ -51,11 +50,6 @@ public:
bool isActive() const { return getState() == CleanupState::Active; }
bool isDead() const { return getState() == CleanupState::Dead; }
llvm::BasicBlock *getNormalEntryBlock() const { return NormalEntryBB; }
void setNormalEntryBlock(llvm::BasicBlock *BB) { NormalEntryBB = BB; }
virtual void emit(IRGenFunction &IGF) const = 0;
private:
virtual void _anchor();
};

View File

@@ -425,32 +425,6 @@ OwnedAddress irgen::projectPhysicalClassMemberAddress(IRGenFunction &IGF,
}
namespace {
class ClassDestroyCleanup : public Cleanup {
llvm::Value *ThisValue;
const ClassTypeInfo &info;
public:
ClassDestroyCleanup(llvm::Value *ThisValue, const ClassTypeInfo &info)
: ThisValue(ThisValue), info(info) {}
void emit(IRGenFunction &IGF) const {
// FIXME: This implementation will be wrong once we get dynamic
// class layout.
auto &layout = info.getLayout(IGF.IGM);
Address baseAddr = layout.emitCastTo(IGF, ThisValue);
// Destroy all the instance variables of the class.
for (auto &field : layout.getElements()) {
if (field.Type->isPOD(ResilienceScope::Local))
continue;
field.Type->destroy(IGF, field.project(IGF, baseAddr));
}
}
};
}
/// Emit the deallocating destructor for a class in terms of its destroying
/// destructor.
void irgen::emitDeallocatingDestructor(IRGenModule &IGM,

View File

@@ -111,8 +111,6 @@ Cleanup &IRGenFunction::initCleanup(Cleanup &cleanup, size_t allocSize,
CleanupState state) {
cleanup.AllocatedSize = allocSize;
cleanup.State = unsigned(state);
cleanup.NormalEntryBB = nullptr;
return cleanup;
}
@@ -120,12 +118,6 @@ Cleanup &IRGenFunction::initCleanup(Cleanup &cleanup, size_t allocSize,
/// Change the state of a cleanup.
void IRGenFunction::setCleanupState(CleanupsDepth depth,
CleanupState newState) {
auto iter = Cleanups.find(depth);
assert(iter != Cleanups.end() && "changing state of end of stack");
setCleanupState(*iter, newState);
if (newState == CleanupState::Dead && iter == Cleanups.begin())
popAndEmitTopDeadCleanups(*this, Cleanups, InnermostScope);
}
void IRGenFunction::setCleanupState(Cleanup &cleanup, CleanupState newState) {

View File

@@ -629,14 +629,14 @@ static void emitReleaseCall(IRGenFunction &IGF, llvm::Value *value) {
llvm::Constant *fn = IGF.IGM.getReleaseFn();
if (value->getType() != IGF.IGM.RefCountedPtrTy) {
llvm::FunctionType *fnType =
llvm::FunctionType::get(IGF.IGM.VoidTy, value->getType(), false);
llvm::FunctionType::get(IGF.IGM.VoidTy, value->getType(), false);
fn = llvm::ConstantExpr::getBitCast(fn, fnType->getPointerTo());
}
// The call itself can never throw.
llvm::CallInst *call = IGF.Builder.CreateCall(fn, value);
call->setCallingConv(IGF.IGM.RuntimeCC);
call->setDoesNotThrow();
call->setDoesNotThrow();
}
/// Emit a release of a live value.
@@ -645,45 +645,11 @@ void IRGenFunction::emitRelease(llvm::Value *value) {
return emitReleaseCall(*this, value);
}
namespace {
struct CallRelease : Cleanup {
llvm::Value *Value;
CallRelease(llvm::Value *value) : Value(value) {}
void emit(IRGenFunction &IGF) const {
emitReleaseCall(IGF, Value);
}
};
}
/// Enter a cleanup to release an object.
ManagedValue IRGenFunction::enterReleaseCleanup(llvm::Value *value) {
if (doesNotRequireRefCounting(value))
return ManagedValue(value);
pushFullExprCleanup<CallRelease>(value);
return ManagedValue(value, getCleanupsDepth());
}
namespace {
class CallDealloc : public Cleanup {
llvm::Value *Allocation;
llvm::Value *Size;
public:
CallDealloc(llvm::Value *allocation, llvm::Value *size)
: Allocation(allocation), Size(size) {}
void emit(IRGenFunction &IGF) const {
IGF.emitDeallocObjectCall(Allocation, Size);
}
};
}
/// Enter a cleanup to call swift_dealloc on the given pointer.
/// This cleanup will usually be deactivated as soon as the
/// initializer completes.
CleanupsDepth
IRGenFunction::pushDeallocCleanup(llvm::Value *allocation,
llvm::Value *size) {
pushFullExprCleanup<CallDealloc>(allocation, size);
return getCleanupsDepth();
}

View File

@@ -34,73 +34,24 @@
using namespace swift;
using namespace irgen;
namespace {
/// A cleanup to destroy an object whose address isn't actually known yet.
class UnboundDestroy : public Cleanup {
const TypeInfo &TI;
OwnedAddress Addr;
public:
UnboundDestroy(const TypeInfo &TI) : TI(TI) {}
void setAddress(OwnedAddress addr) {
assert(!Addr.isValid());
Addr = addr;
}
void emit(IRGenFunction &IGF) const {
assert(Addr.isValid());
llvm::Value *owner = Addr.getOwner();
if (!isa<llvm::ConstantPointerNull>(owner)) {
IGF.emitRelease(owner);
} else {
TI.destroy(IGF, Addr);
}
}
};
}
/// Enter a cleanup to destroy an object of arbitrary type. Adds the
/// address value to the given explosion, along with the appropriate
/// cleanup.
void IRGenFunction::enterDestroyCleanup(Address addr,
const TypeInfo &addrTI,
Explosion &out) {
enterDestroyCleanup(addr, addrTI);
out.add(ManagedValue(addr.getAddress(), getCleanupsDepth()));
}
/// Enter a cleanup to destroy an object of arbitrary type.
void IRGenFunction::enterDestroyCleanup(Address addr,
const TypeInfo &addrTI) {
assert(!addrTI.isPOD(ResilienceScope::Local) &&
"destroying something known to be POD");
// The use of UnboundDestroy here is not important.
UnboundDestroy &destroy = pushCleanup<UnboundDestroy>(addrTI);
destroy.setAddress(OwnedAddress(addr, IGM.RefCountedNull));
}
/// Register an object with the initialization process.
CleanupsDepth Initialization::registerObject(IRGenFunction &IGF,
InitializedObject object,
OnHeap_t onHeap,
const TypeInfo &objectTI) {
// Create the appropriate destroy cleanup.
CleanupsDepth destroy;
registerObject(object, CleanupsDepth::invalid());
// We need a destroy cleanup if the object is on the heap or non-POD.
if (onHeap || !objectTI.isPOD(ResilienceScope::Local)) {
IGF.pushFullExprCleanupInState<UnboundDestroy>(CleanupState::Dormant,
objectTI);
destroy = IGF.getCleanupsDepth();
} else {
destroy = CleanupsDepth::invalid();
}
registerObject(object, destroy);
return destroy;
return CleanupsDepth::invalid();
}
void Initialization::registerObjectWithoutDestroy(InitializedObject object) {
@@ -128,13 +79,6 @@ void Initialization::markAllocated(IRGenFunction &IGF,
"object was not registered with initialization");
ValueRecord &record = Records.find(object.Opaque)->second;
record.DeallocCleanup = dealloc;
// Update the destroy cleanup if present.
if (record.DestroyCleanup.isValid()) {
UnboundDestroy &destroy =
static_cast<UnboundDestroy&>(IGF.findCleanup(record.DestroyCleanup));
destroy.setAddress(address);
}
}
/// Emit a global variable.
@@ -211,13 +155,8 @@ OwnedAddress FixedTypeInfo::allocate(IRGenFunction &IGF, Initialization &init,
Address rawAddr = layout.emitCastTo(IGF, allocation);
rawAddr = elt.project(IGF, rawAddr, name);
// Push a cleanup to dealloc the allocation.
// FIXME: don't emit the size twice!
CleanupsDepth deallocCleanup
= IGF.pushDeallocCleanup(allocation, layout.emitSize(IGF));
OwnedAddress addr(rawAddr, allocation);
init.markAllocated(IGF, object, addr, deallocCleanup);
init.markAllocated(IGF, object, addr, CleanupsDepth::invalid());
return addr;
}

View File

@@ -199,19 +199,8 @@ static llvm::Value *emitObjCAutoreleaseReturnValue(IRGenFunction &IGF,
return call;
}
namespace {
struct CallObjCRelease : Cleanup {
llvm::Value *Value;
CallObjCRelease(llvm::Value *value) : Value(value) {}
void emit(IRGenFunction &IGF) const {
IGF.emitObjCRelease(Value);
}
};
}
ManagedValue IRGenFunction::enterObjCReleaseCleanup(llvm::Value *value) {
pushFullExprCleanup<CallObjCRelease>(value);
return ManagedValue(value, getCleanupsDepth());
}

View File

@@ -468,18 +468,7 @@ static void emitDestroyBufferCall(IRGenFunction &IGF,
setHelperAttributes(call);
}
/// Emit a call to do a 'deallocateBuffer' operation.
static void emitDeallocateBufferCall(IRGenFunction &IGF,
llvm::Value *witnessTable,
llvm::Value *metadata,
Address buffer) {
llvm::Value *fn = loadValueWitness(IGF, witnessTable,
ValueWitness::DeallocateBuffer);
llvm::CallInst *call =
IGF.Builder.CreateCall2(fn, buffer.getAddress(), metadata);
call->setCallingConv(IGF.IGM.RuntimeCC);
setHelperAttributes(call);
}
/// Given the address of an existential object, destroy it.
static void emitDestroyExistential(IRGenFunction &IGF, Address addr,
@@ -500,51 +489,6 @@ static llvm::Constant *getAssignExistentialsFunction(IRGenModule &IGM,
ExistentialLayout layout);
namespace {
struct DestroyBuffer : Cleanup {
Address Buffer;
llvm::Value *Table;
llvm::Value *Metatype;
DestroyBuffer(Address buffer, llvm::Value *table, llvm::Value *metatype)
: Buffer(buffer), Table(table), Metatype(metatype) {}
void emit(IRGenFunction &IGF) const {
emitDestroyBufferCall(IGF, Table, Metatype, Buffer);
}
};
struct DeallocateBuffer : Cleanup {
Address Buffer;
llvm::Value *Table;
llvm::Value *Metatype;
DeallocateBuffer(Address buffer, llvm::Value *table, llvm::Value *metatype)
: Buffer(buffer), Table(table), Metatype(metatype) {}
void emit(IRGenFunction &IGF) const {
emitDeallocateBufferCall(IGF, Table, Metatype, Buffer);
}
};
struct DeallocateBox : Cleanup {
llvm::Value *Box;
llvm::Value *Type;
DeallocateBox(llvm::Value *box, llvm::Value *type)
: Box(box), Type(type) {}
void emit(IRGenFunction &IGF) const {
IGF.emitDeallocBoxCall(Box, Type);
}
};
struct DestroyExistential : Cleanup {
ExistentialLayout Layout;
Address Addr;
DestroyExistential(ExistentialLayout layout, Address addr)
: Layout(layout), Addr(addr) {}
void emit(IRGenFunction &IGF) const {
emitDestroyExistential(IGF, Addr, Layout);
}
};
/// A CRTP class for visiting the witnesses of a protocol.
///
@@ -1011,10 +955,8 @@ namespace {
Address rawAddr(address, Alignment(1));
// Push a cleanup to dealloc the allocation.
IGF.pushCleanup<DeallocateBox>(box, metadata);
CleanupsDepth dealloc = IGF.getCleanupsDepth();
OwnedAddress addr(rawAddr, box);
init.markAllocated(IGF, object, addr, dealloc);
init.markAllocated(IGF, object, addr, IGF.getCleanupsDepth());
return addr;
}
@@ -1031,9 +973,7 @@ namespace {
OwnedAddress ownedAddr(allocated, IGF.IGM.RefCountedNull);
// Push a cleanup to dealloc it.
IGF.pushCleanup<DeallocateBuffer>(buffer, wtable, metadata);
CleanupsDepth dealloc = IGF.getCleanupsDepth();
init.markAllocated(IGF, object, ownedAddr, dealloc);
init.markAllocated(IGF, object, ownedAddr, IGF.getCleanupsDepth());
return ownedAddr;
}
@@ -1452,26 +1392,6 @@ static void emitDeallocateBuffer(IRGenFunction &IGF,
}
llvm_unreachable("bad packing!");
}
namespace {
/// A cleanup for deallocating a buffer when the concrete type
/// stored there is known.
class DeallocateConcreteBuffer : public Cleanup {
Address Buffer;
FixedPacking Packing;
const TypeInfo &ConcreteTI;
public:
DeallocateConcreteBuffer(Address buffer, FixedPacking packing,
const TypeInfo &concreteTI)
: Buffer(buffer), Packing(packing), ConcreteTI(concreteTI) {}
void emit(IRGenFunction &IGF) const {
emitDeallocateBuffer(IGF, ConcreteTI, Packing, Buffer);
}
};
}
/// Emit a 'destroyObject' operation.
static void emitDestroyObject(IRGenFunction &IGF,
const TypeInfo &type,

View File

@@ -187,18 +187,6 @@ void IRGenFunction::emitDeallocRawCall(llvm::Value *pointer,
return emitDeallocatingCall(*this, IGM.getSlowRawDeallocFn(), pointer, size);
}
/// Deallocate an object which was allocated but has not actually been
/// initialized.
void IRGenFunction::emitDeallocObjectCall(llvm::Value *ptr, llvm::Value *size) {
// For now, all we have is swift_deallocObject.
return emitDeallocatingCall(*this, IGM.getDeallocObjectFn(), ptr, size);
}
void IRGenFunction::emitDeallocBoxCall(llvm::Value *box, llvm::Value *type) {
llvm::CallInst *call = Builder.CreateCall2(IGM.getDeallocBoxFn(), box, type);
call->setCallingConv(IGM.RuntimeCC);
call->setDoesNotThrow();
}
void IRGenFunction::unimplemented(SourceLoc Loc, StringRef Message) {
return IGM.unimplemented(Loc, Message);

View File

@@ -199,7 +199,6 @@ public:
void enterDestroyCleanup(Address addr, const TypeInfo &addrTI,
Explosion &out);
void enterDestroyCleanup(Address addr, const TypeInfo &addrTI);
/// Is the current emission point conditionally evaluated? Right
/// now we don't have any expressions which introduce conditional
@@ -256,7 +255,6 @@ public:
llvm::Value *emitAllocObjectCall(llvm::Value *metadata, llvm::Value *size,
llvm::Value *align,
const llvm::Twine &name = "");
void emitDeallocObjectCall(llvm::Value *pointer, llvm::Value *size);
llvm::Value *emitAllocRawCall(llvm::Value *size, llvm::Value *align,
const llvm::Twine &name ="");
void emitDeallocRawCall(llvm::Value *pointer, llvm::Value *size);
@@ -264,7 +262,6 @@ public:
void emitAllocBoxCall(llvm::Value *typeMetadata,
llvm::Value *&box,
llvm::Value *&valueAddress);
void emitDeallocBoxCall(llvm::Value *box, llvm::Value *type);
private:
llvm::Instruction *AllocaIP;
@@ -273,8 +270,6 @@ private:
public:
llvm::Value *emitUnmanagedAlloc(const HeapLayout &layout,
const llvm::Twine &name);
CleanupsDepth pushDeallocCleanup(llvm::Value *allocation,
llvm::Value *size);
void emitLoadAndRetain(Address addr, Explosion &explosion);
void emitAssignRetained(llvm::Value *value, Address addr);
void emitInitializeRetained(llvm::Value *value, Address addr);

View File

@@ -57,8 +57,6 @@ IRGenModule::IRGenModule(ASTContext &Context,
AllocBoxFn = nullptr;
RetainNoResultFn = nullptr;
ReleaseFn = nullptr;
DeallocObjectFn = nullptr;
DeallocBoxFn = nullptr;
ObjCRetainFn = nullptr;
ObjCReleaseFn = nullptr;
RawAllocFn = nullptr;
@@ -364,28 +362,6 @@ llvm::Constant *IRGenModule::getReleaseFn() {
return ReleaseFn;
}
llvm::Constant *IRGenModule::getDeallocObjectFn() {
if (DeallocObjectFn) return DeallocObjectFn;
// void swift_deallocObject(void *ptr, size_t size);
llvm::Type *argTypes[] = { RefCountedPtrTy, SizeTy };
llvm::FunctionType *fnType =
llvm::FunctionType::get(VoidTy, argTypes, false);
DeallocObjectFn = createRuntimeFunction(*this, "swift_deallocObject", fnType);
return DeallocObjectFn;
}
llvm::Constant *IRGenModule::getDeallocBoxFn() {
if (DeallocObjectFn) return DeallocBoxFn;
// void swift_deallocBox(void *ptr, Metadata *type);
llvm::Type *argTypes[] = { RefCountedPtrTy, TypeMetadataPtrTy };
llvm::FunctionType *fnType =
llvm::FunctionType::get(VoidTy, argTypes, false);
DeallocObjectFn = createRuntimeFunction(*this, "swift_deallocBox", fnType);
return DeallocObjectFn;
}
llvm::Constant *IRGenModule::getGetFunctionMetadataFn() {
if (GetFunctionMetadataFn) return GetFunctionMetadataFn;

View File

@@ -222,9 +222,7 @@ public:
llvm::Constant *getAllocBoxFn();
llvm::Constant *getRetainNoResultFn();
llvm::Constant *getReleaseFn();
llvm::Constant *getDeallocObjectFn();
llvm::Constant *getDeallocBoxFn();
llvm::Constant *getRawAllocFn();
llvm::Constant *getRawDeallocFn();
llvm::Constant *getSlowAllocFn();
@@ -266,8 +264,6 @@ private:
llvm::Constant *AllocBoxFn;
llvm::Constant *RetainNoResultFn;
llvm::Constant *ReleaseFn;
llvm::Constant *DeallocObjectFn;
llvm::Constant *DeallocBoxFn;
llvm::Constant *RawAllocFn;
llvm::Constant *RawDeallocFn;
llvm::Constant *SlowAllocFn;