Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce memory footprint of the Swift compiler #14

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,13 @@ class SILInstruction : public ValueBase,public llvm::ilist_node<SILInstruction>{
: ValueBase(Kind, TypeList), ParentBB(0), Location(*DebugLoc) {}

public:
/// Instructions should be allocated using a dedicated instruction allocation
/// function from the ContextTy.
template <typename ContextTy>
void *operator new(size_t Bytes, const ContextTy &C,
size_t Alignment = alignof(ValueBase)) {
return C.allocateInst(Bytes, Alignment);
}

enum class MemoryBehavior {
None,
Expand Down
10 changes: 5 additions & 5 deletions include/swift/SIL/SILModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,12 +499,12 @@ class SILModule {
bool PrintASTDecls = true) const;

/// Allocate memory using the module's internal allocator.
void *allocate(unsigned Size, unsigned Align) const {
if (getASTContext().LangOpts.UseMalloc)
return AlignedAlloc(Size, Align);
void *allocate(unsigned Size, unsigned Align) const;

/// Allocate memory for an instruction using the module's internal allocator.
void *allocateInst(unsigned Size, unsigned Align) const;


return BPA.Allocate(Size, Align);
}

/// \brief Looks up the llvm intrinsic ID and type for the builtin function.
///
Expand Down
4 changes: 2 additions & 2 deletions lib/SIL/SILFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,14 @@ SILFunction::SILFunction(SILModule &Module, SILLinkage Linkage,
}

SILFunction::~SILFunction() {
#ifndef NDEBUG
// If the function is recursive, a function_ref inst inside of the function
// will give the function a non-zero ref count triggering the assertion. Thus
// we drop all instruction references before we erase.
// We also need to drop all references if instructions are allocated using
// an allocator that may recycle freed memory.
dropAllReferences();
assert(RefCount == 0 &&
"Function cannot be deleted while function_ref's still exist");
#endif
}

void SILFunction::setDeclContext(Decl *D) {
Expand Down
11 changes: 10 additions & 1 deletion lib/SIL/SILInstruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,19 @@ void SILInstruction::replaceAllUsesWithUndef() {
}
}

namespace swift {
void deallocate(void *Ptr) {
AlignedFree(Ptr);
}
}

namespace {
class InstructionDestroyer : public SILVisitor<InstructionDestroyer> {
public:
#define VALUE(CLASS, PARENT) void visit##CLASS(CLASS *I) { I->~CLASS(); }
#define VALUE(CLASS, PARENT) void visit##CLASS(CLASS *I) { \
I->~CLASS();\
deallocate(I);\
}
#include "swift/SIL/SILNodes.def"
};
} // end anonymous namespace
Expand Down
48 changes: 24 additions & 24 deletions lib/SIL/SILInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ AllocExistentialBoxInst *AllocExistentialBoxInst::create(
SILType ConcreteLoweredType, ArrayRef<ProtocolConformance *> Conformances,
SILFunction *F) {
SILModule &Mod = F->getModule();
void *Buffer = Mod.allocate(sizeof(AllocExistentialBoxInst),
alignof(AllocExistentialBoxInst));
void *Buffer = Mod.allocateInst(sizeof(AllocExistentialBoxInst),
alignof(AllocExistentialBoxInst));
for (ProtocolConformance *C : Conformances)
declareWitnessTable(Mod, C);
return ::new (Buffer) AllocExistentialBoxInst(Loc,
Expand All @@ -142,7 +142,7 @@ BuiltinInst *BuiltinInst::create(SILDebugLocation *Loc, Identifier Name,
ArrayRef<Substitution> Substitutions,
ArrayRef<SILValue> Args,
SILFunction &F) {
void *Buffer = F.getModule().allocate(
void *Buffer = F.getModule().allocateInst(
sizeof(BuiltinInst)
+ decltype(Operands)::getExtraSize(Args.size())
+ sizeof(Substitution) * Substitutions.size(),
Expand Down Expand Up @@ -189,7 +189,7 @@ bool swift::doesApplyCalleeHaveSemantics(SILValue callee, StringRef semantics) {
}

void *swift::allocateApplyInst(SILFunction &F, size_t size, size_t alignment) {
return F.getModule().allocate(size, alignment);
return F.getModule().allocateInst(size, alignment);
}

PartialApplyInst::PartialApplyInst(SILDebugLocation *Loc, SILValue Callee,
Expand Down Expand Up @@ -275,14 +275,14 @@ static unsigned getWordsForBitWidth(unsigned bits) {

template<typename INST>
static void *allocateLiteralInstWithTextSize(SILFunction &F, unsigned length) {
return F.getModule().allocate(sizeof(INST) + length, alignof(INST));
return F.getModule().allocateInst(sizeof(INST) + length, alignof(INST));
}

template<typename INST>
static void *allocateLiteralInstWithBitSize(SILFunction &F, unsigned bits) {
unsigned words = getWordsForBitWidth(bits);
return F.getModule().allocate(sizeof(INST) + sizeof(llvm::integerPart)*words,
alignof(INST));
return F.getModule().allocateInst(
sizeof(INST) + sizeof(llvm::integerPart)*words, alignof(INST));
}

IntegerLiteralInst::IntegerLiteralInst(SILDebugLocation *Loc, SILType Ty,
Expand Down Expand Up @@ -408,7 +408,7 @@ AssignInst::AssignInst(SILDebugLocation *Loc, SILValue Src, SILValue Dest)
MarkFunctionEscapeInst *
MarkFunctionEscapeInst::create(SILDebugLocation *Loc,
ArrayRef<SILValue> Elements, SILFunction &F) {
void *Buffer = F.getModule().allocate(sizeof(MarkFunctionEscapeInst) +
void *Buffer = F.getModule().allocateInst(sizeof(MarkFunctionEscapeInst) +
decltype(Operands)::getExtraSize(Elements.size()),
alignof(MarkFunctionEscapeInst));
return ::new(Buffer) MarkFunctionEscapeInst(Loc, Elements);
Expand Down Expand Up @@ -456,7 +456,7 @@ UnconditionalCheckedCastAddrInst::UnconditionalCheckedCastAddrInst(

StructInst *StructInst::create(SILDebugLocation *Loc, SILType Ty,
ArrayRef<SILValue> Elements, SILFunction &F) {
void *Buffer = F.getModule().allocate(sizeof(StructInst) +
void *Buffer = F.getModule().allocateInst(sizeof(StructInst) +
decltype(Operands)::getExtraSize(Elements.size()),
alignof(StructInst));
return ::new(Buffer) StructInst(Loc, Ty, Elements);
Expand All @@ -470,7 +470,7 @@ StructInst::StructInst(SILDebugLocation *Loc, SILType Ty,

TupleInst *TupleInst::create(SILDebugLocation *Loc, SILType Ty,
ArrayRef<SILValue> Elements, SILFunction &F) {
void *Buffer = F.getModule().allocate(sizeof(TupleInst) +
void *Buffer = F.getModule().allocateInst(sizeof(TupleInst) +
decltype(Operands)::getExtraSize(Elements.size()),
alignof(TupleInst));
return ::new(Buffer) TupleInst(Loc, Ty, Elements);
Expand Down Expand Up @@ -673,7 +673,7 @@ BranchInst *BranchInst::create(SILDebugLocation *Loc, SILBasicBlock *DestBB,
BranchInst *BranchInst::create(SILDebugLocation *Loc,
SILBasicBlock *DestBB, ArrayRef<SILValue> Args,
SILFunction &F) {
void *Buffer = F.getModule().allocate(sizeof(BranchInst) +
void *Buffer = F.getModule().allocateInst(sizeof(BranchInst) +
decltype(Operands)::getExtraSize(Args.size()),
alignof(BranchInst));
return ::new (Buffer) BranchInst(Loc, DestBB, Args);
Expand Down Expand Up @@ -707,7 +707,7 @@ CondBranchInst::create(SILDebugLocation *Loc, SILValue Condition,
Args.append(TrueArgs.begin(), TrueArgs.end());
Args.append(FalseArgs.begin(), FalseArgs.end());

void *Buffer = F.getModule().allocate(sizeof(CondBranchInst) +
void *Buffer = F.getModule().allocateInst(sizeof(CondBranchInst) +
decltype(Operands)::getExtraSize(Args.size()),
alignof(CondBranchInst));
return ::new (Buffer) CondBranchInst(Loc, Condition, TrueBB, FalseBB, Args,
Expand Down Expand Up @@ -857,7 +857,7 @@ SwitchValueInst *SwitchValueInst::create(
size_t bufSize = sizeof(SwitchValueInst) +
decltype(Operands)::getExtraSize(Cases.size()) +
sizeof(SILSuccessor) * numSuccessors;
void *buf = F.getModule().allocate(bufSize, alignof(SwitchValueInst));
void *buf = F.getModule().allocateInst(bufSize, alignof(SwitchValueInst));
return ::new (buf) SwitchValueInst(Loc, Operand, DefaultBB, Cases, BBs);
}

Expand Down Expand Up @@ -905,7 +905,7 @@ SelectValueInst::create(SILDebugLocation *Loc, SILValue Operand, SILType Type,

size_t bufSize = sizeof(SelectValueInst) + decltype(Operands)::getExtraSize(
CaseValuesAndResults.size());
void *buf = F.getModule().allocate(bufSize, alignof(SelectValueInst));
void *buf = F.getModule().allocateInst(bufSize, alignof(SelectValueInst));
return ::new (buf)
SelectValueInst(Loc, Operand, Type, DefaultResult, CaseValuesAndResults);
}
Expand Down Expand Up @@ -946,7 +946,7 @@ SELECT_ENUM_INST *SelectEnumInstBase::createSelectEnum(
// and `CaseBBs.size() + (DefaultBB ? 1 : 0)` values.
unsigned numCases = CaseValues.size();

void *buf = F.getModule().allocate(
void *buf = F.getModule().allocateInst(
sizeof(SELECT_ENUM_INST) + sizeof(EnumElementDecl*) * numCases
+ TailAllocatedOperandList<1>::getExtraSize(numCases + (bool)DefaultValue),
alignof(SELECT_ENUM_INST));
Expand Down Expand Up @@ -1067,7 +1067,7 @@ SWITCH_ENUM_INST *SwitchEnumInstBase::createSwitchEnum(
unsigned numCases = CaseBBs.size();
unsigned numSuccessors = numCases + (DefaultBB ? 1 : 0);

void *buf = F.getModule().allocate(sizeof(SWITCH_ENUM_INST)
void *buf = F.getModule().allocateInst(sizeof(SWITCH_ENUM_INST)
+ sizeof(EnumElementDecl*) * numCases
+ sizeof(SILSuccessor) * numSuccessors,
alignof(SWITCH_ENUM_INST));
Expand Down Expand Up @@ -1133,8 +1133,8 @@ DynamicMethodBranchInst *
DynamicMethodBranchInst::create(SILDebugLocation *Loc, SILValue Operand,
SILDeclRef Member, SILBasicBlock *HasMethodBB,
SILBasicBlock *NoMethodBB, SILFunction &F) {
void *Buffer = F.getModule().allocate(sizeof(DynamicMethodBranchInst),
alignof(DynamicMethodBranchInst));
void *Buffer = F.getModule().allocateInst(sizeof(DynamicMethodBranchInst),
alignof(DynamicMethodBranchInst));
return ::new (Buffer)
DynamicMethodBranchInst(Loc, Operand, Member, HasMethodBB, NoMethodBB);
}
Expand Down Expand Up @@ -1176,7 +1176,7 @@ WitnessMethodInst::create(SILDebugLocation *Loc, CanType LookupType,
SILValue OpenedExistential, bool Volatile) {
SILModule &Mod = F->getModule();
void *Buffer =
Mod.allocate(sizeof(WitnessMethodInst), alignof(WitnessMethodInst));
Mod.allocateInst(sizeof(WitnessMethodInst), alignof(WitnessMethodInst));

declareWitnessTable(Mod, Conformance);
return ::new (Buffer) WitnessMethodInst(Loc, LookupType, Conformance, Member,
Expand All @@ -1188,8 +1188,8 @@ InitExistentialAddrInst *InitExistentialAddrInst::create(
SILType ConcreteLoweredType, ArrayRef<ProtocolConformance *> Conformances,
SILFunction *F) {
SILModule &Mod = F->getModule();
void *Buffer = Mod.allocate(sizeof(InitExistentialAddrInst),
alignof(InitExistentialAddrInst));
void *Buffer = Mod.allocateInst(sizeof(InitExistentialAddrInst),
alignof(InitExistentialAddrInst));
for (ProtocolConformance *C : Conformances)
declareWitnessTable(Mod, C);
return ::new (Buffer) InitExistentialAddrInst(Loc, Existential,
Expand All @@ -1204,8 +1204,8 @@ InitExistentialRefInst::create(SILDebugLocation *Loc, SILType ExistentialType,
ArrayRef<ProtocolConformance *> Conformances,
SILFunction *F) {
SILModule &Mod = F->getModule();
void *Buffer = Mod.allocate(sizeof(InitExistentialRefInst),
alignof(InitExistentialRefInst));
void *Buffer = Mod.allocateInst(sizeof(InitExistentialRefInst),
alignof(InitExistentialRefInst));
for (ProtocolConformance *C : Conformances) {
if (!C)
continue;
Expand Down Expand Up @@ -1239,7 +1239,7 @@ InitExistentialMetatypeInst *InitExistentialMetatypeInst::create(
unsigned size = sizeof(InitExistentialMetatypeInst);
size += conformances.size() * sizeof(ProtocolConformance *);

void *buffer = M.allocate(size, alignof(InitExistentialMetatypeInst));
void *buffer = M.allocateInst(size, alignof(InitExistentialMetatypeInst));
for (ProtocolConformance *conformance : conformances)
if (!M.lookUpWitnessTable(conformance, false).first)
declareWitnessTable(M, conformance);
Expand Down
11 changes: 11 additions & 0 deletions lib/SIL/SILModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,17 @@ SILModule::~SILModule() {
delete (SILTypeListUniquingType*)TypeListUniquing;
}

void *SILModule::allocate(unsigned Size, unsigned Align) const {
if (getASTContext().LangOpts.UseMalloc)
return AlignedAlloc(Size, Align);

return BPA.Allocate(Size, Align);
}

void *SILModule::allocateInst(unsigned Size, unsigned Align) const {
return AlignedAlloc(Size, Align);
}

SILWitnessTable *
SILModule::createWitnessTableDeclaration(ProtocolConformance *C,
SILLinkage linkage) {
Expand Down