[gardening] Always create SILBasicBlocks via SILFunction::createBasicBlock.

This eliminates all inline creation of SILBasicBlock via placement new.

There are a few reasons to do this:

1. A SILBasicBlock is always created with a parent function. This commit
formalizes this into the SILBasicBlock API by only allowing for SILFunctions to
create SILBasicBlocks. This is implemented via the type system by making all
SILBasicBlock constructors private. Since SILFunction is a friend of
SILBasicBlock, SILFunction can still create a SILBasicBlock without issue.

2. Since all SILBasicBlocks will be created in only a few functions, it becomes
very easy to determine using instruments the amount of memory being allocated
for SILBasicBlocks by simply inverting the call tree in Allocations.

With LTO+PGO, normal inlining can occur if profitable so there shouldn't be
overhead that we care about in shipping compilers.
This commit is contained in:
Michael Gottesman
2016-11-24 23:29:31 -06:00
parent 28656578be
commit e42bf07af4
20 changed files with 40 additions and 36 deletions

View File

@@ -51,8 +51,9 @@ private:
void operator=(const SILBasicBlock &) = delete; void operator=(const SILBasicBlock &) = delete;
void operator delete(void *Ptr, size_t) = delete; void operator delete(void *Ptr, size_t) = delete;
public:
SILBasicBlock(SILFunction *F, SILBasicBlock *afterBB = nullptr); SILBasicBlock(SILFunction *F, SILBasicBlock *afterBB = nullptr);
public:
~SILBasicBlock(); ~SILBasicBlock();
/// Gets the ID (= index in the function's block list) of the block. /// Gets the ID (= index in the function's block list) of the block.

View File

@@ -397,7 +397,7 @@ SILCloner<ImplClass>::visitSILBasicBlock(SILBasicBlock* BB) {
// Only visit a successor that has not already been visited. // Only visit a successor that has not already been visited.
if (BBI == BBMap.end()) { if (BBI == BBMap.end()) {
// Map the successor to a new BB. // Map the successor to a new BB.
auto MappedBB = new (F.getModule()) SILBasicBlock(&F); auto *MappedBB = F.createBasicBlock();
BBMap.insert(std::make_pair(Succ.getBB(), MappedBB)); BBMap.insert(std::make_pair(Succ.getBB(), MappedBB));
// Create new arguments for each of the original block's arguments. // Create new arguments for each of the original block's arguments.
for (auto &Arg : Succ.getBB()->getBBArgs()) { for (auto &Arg : Succ.getBB()->getBBArgs()) {

View File

@@ -619,6 +619,7 @@ public:
const SILBasicBlock &front() const { return *begin(); } const SILBasicBlock &front() const { return *begin(); }
SILBasicBlock *createBasicBlock(); SILBasicBlock *createBasicBlock();
SILBasicBlock *createBasicBlock(SILBasicBlock *After);
/// Splice the body of \p F into this function at end. /// Splice the body of \p F into this function at end.
void spliceBody(SILFunction *F) { void spliceBody(SILFunction *F) {

View File

@@ -368,7 +368,7 @@ public:
auto *Fn = BI->getFunction(); auto *Fn = BI->getFunction();
auto *SrcBB = BI->getParent(); auto *SrcBB = BI->getParent();
auto *DestBB = BI->getDestBB(); auto *DestBB = BI->getDestBB();
auto *EdgeBB = new (Fn->getModule()) SILBasicBlock(Fn, SrcBB); auto *EdgeBB = Fn->createBasicBlock(SrcBB);
// Create block arguments. // Create block arguments.
unsigned ArgIdx = 0; unsigned ArgIdx = 0;

View File

@@ -477,12 +477,12 @@ SILFunction *SILParser::getGlobalNameForReference(Identifier Name,
SILBasicBlock *SILParser::getBBForDefinition(Identifier Name, SourceLoc Loc) { SILBasicBlock *SILParser::getBBForDefinition(Identifier Name, SourceLoc Loc) {
// If there was no name specified for this block, just create a new one. // If there was no name specified for this block, just create a new one.
if (Name.empty()) if (Name.empty())
return new (SILMod) SILBasicBlock(F); return F->createBasicBlock();
SILBasicBlock *&BB = BlocksByName[Name]; SILBasicBlock *&BB = BlocksByName[Name];
// If the block has never been named yet, just create it. // If the block has never been named yet, just create it.
if (BB == nullptr) if (BB == nullptr)
return BB = new (SILMod) SILBasicBlock(F); return BB = F->createBasicBlock();
// If it already exists, it was either a forward reference or a redefinition. // If it already exists, it was either a forward reference or a redefinition.
// If it is a forward reference, it should be in our undefined set. // If it is a forward reference, it should be in our undefined set.
@@ -491,7 +491,7 @@ SILBasicBlock *SILParser::getBBForDefinition(Identifier Name, SourceLoc Loc) {
// instructions after the terminator. // instructions after the terminator.
P.diagnose(Loc, diag::sil_basicblock_redefinition, Name); P.diagnose(Loc, diag::sil_basicblock_redefinition, Name);
HadError = true; HadError = true;
return new (SILMod) SILBasicBlock(F); return F->createBasicBlock();
} }
// FIXME: Splice the block to the end of the function so they come out in the // FIXME: Splice the block to the end of the function so they come out in the
@@ -510,7 +510,7 @@ SILBasicBlock *SILParser::getBBForReference(Identifier Name, SourceLoc Loc) {
// Otherwise, create it and remember that this is a forward reference so // Otherwise, create it and remember that this is a forward reference so
// that we can diagnose use without definition problems. // that we can diagnose use without definition problems.
BB = new (SILMod) SILBasicBlock(F); BB = F->createBasicBlock();
UndefinedBlocks[BB] = {Loc, Name}; UndefinedBlocks[BB] = {Loc, Name};
return BB; return BB;
} }

View File

@@ -138,7 +138,7 @@ void SILBuilder::emitBlock(SILBasicBlock *BB, SILLocation BranchLoc) {
SILBasicBlock *SILBuilder::splitBlockForFallthrough() { SILBasicBlock *SILBuilder::splitBlockForFallthrough() {
// If we are concatenating, just create and return a new block. // If we are concatenating, just create and return a new block.
if (insertingAtEndOfBlock()) { if (insertingAtEndOfBlock()) {
return new (F.getModule()) SILBasicBlock(&F, BB); return F.createBasicBlock(BB);
} }
// Otherwise we need to split the current block at the insertion point. // Otherwise we need to split the current block at the insertion point.

View File

@@ -288,6 +288,10 @@ SILBasicBlock *SILFunction::createBasicBlock() {
return new (getModule()) SILBasicBlock(this); return new (getModule()) SILBasicBlock(this);
} }
SILBasicBlock *SILFunction::createBasicBlock(SILBasicBlock *AfterBlock) {
return new (getModule()) SILBasicBlock(this, AfterBlock);
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// View CFG Implementation // View CFG Implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@@ -34,12 +34,12 @@ static void diagnose(ASTContext &Context, SourceLoc loc, Diag<T...> diag,
SILBasicBlock *SILGenFunction::createBasicBlock(SILBasicBlock *afterBB) { SILBasicBlock *SILGenFunction::createBasicBlock(SILBasicBlock *afterBB) {
// Honor an explicit placement if given. // Honor an explicit placement if given.
if (afterBB) { if (afterBB) {
return new (F.getModule()) SILBasicBlock(&F, afterBB); return F.createBasicBlock(afterBB);
// If we don't have a requested placement, but we do have a current // If we don't have a requested placement, but we do have a current
// insertion point, insert there. // insertion point, insert there.
} else if (B.hasValidInsertionPoint()) { } else if (B.hasValidInsertionPoint()) {
return new (F.getModule()) SILBasicBlock(&F, B.getInsertionBB()); return F.createBasicBlock(B.getInsertionBB());
// Otherwise, insert at the end of the current section. // Otherwise, insert at the end of the current section.
} else { } else {
@@ -55,13 +55,13 @@ SILBasicBlock *SILGenFunction::createBasicBlock(FunctionSection section) {
SILBasicBlock *afterBB = (StartOfPostmatter != F.end()) SILBasicBlock *afterBB = (StartOfPostmatter != F.end())
? &*std::prev(StartOfPostmatter) ? &*std::prev(StartOfPostmatter)
: nullptr; : nullptr;
return new (F.getModule()) SILBasicBlock(&F, afterBB); return F.createBasicBlock(afterBB);
} }
case FunctionSection::Postmatter: { case FunctionSection::Postmatter: {
// The end of the postmatter section is always the end of the function. // The end of the postmatter section is always the end of the function.
// Register the new block as the start of the postmatter if needed. // Register the new block as the start of the postmatter if needed.
SILBasicBlock *newBB = new (F.getModule()) SILBasicBlock(&F, nullptr); SILBasicBlock *newBB = F.createBasicBlock(nullptr);
if (StartOfPostmatter == F.end()) if (StartOfPostmatter == F.end())
StartOfPostmatter = newBB->getIterator(); StartOfPostmatter = newBB->getIterator();
return newBB; return newBB;

View File

@@ -467,7 +467,7 @@ ClosureCloner::populateCloned() {
// Create arguments for the entry block // Create arguments for the entry block
SILBasicBlock *OrigEntryBB = &*Orig->begin(); SILBasicBlock *OrigEntryBB = &*Orig->begin();
SILBasicBlock *ClonedEntryBB = new (M) SILBasicBlock(Cloned); SILBasicBlock *ClonedEntryBB = Cloned->createBasicBlock();
unsigned ArgNo = 0; unsigned ArgNo = 0;
auto I = OrigEntryBB->bbarg_begin(), E = OrigEntryBB->bbarg_end(); auto I = OrigEntryBB->bbarg_begin(), E = OrigEntryBB->bbarg_end();
while (I != E) { while (I != E) {

View File

@@ -165,7 +165,7 @@ void CapturePropagationCloner::cloneBlocks(
// Create the entry basic block with the function arguments. // Create the entry basic block with the function arguments.
SILBasicBlock *OrigEntryBB = &*OrigF->begin(); SILBasicBlock *OrigEntryBB = &*OrigF->begin();
SILBasicBlock *ClonedEntryBB = new (M) SILBasicBlock(&CloneF); SILBasicBlock *ClonedEntryBB = CloneF.createBasicBlock();
CanSILFunctionType CloneFTy = CloneF.getLoweredFunctionType(); CanSILFunctionType CloneFTy = CloneF.getLoweredFunctionType();
// Only clone the arguments that remain in the new function type. The trailing // Only clone the arguments that remain in the new function type. The trailing

View File

@@ -572,7 +572,7 @@ void ClosureSpecCloner::populateCloned() {
// Create arguments for the entry block. // Create arguments for the entry block.
SILBasicBlock *ClosureUserEntryBB = &*ClosureUser->begin(); SILBasicBlock *ClosureUserEntryBB = &*ClosureUser->begin();
SILBasicBlock *ClonedEntryBB = new (M) SILBasicBlock(Cloned); SILBasicBlock *ClonedEntryBB = Cloned->createBasicBlock();
// Remove the closure argument. // Remove the closure argument.
SILArgument *ClosureArg = nullptr; SILArgument *ClosureArg = nullptr;

View File

@@ -1975,7 +1975,7 @@ public:
} }
// Create the cloned start basic block. // Create the cloned start basic block.
auto *ClonedStartBB = new (Mod) SILBasicBlock(CurFun); auto *ClonedStartBB = CurFun->createBasicBlock();
BBMap[StartBB] = ClonedStartBB; BBMap[StartBB] = ClonedStartBB;
// Clone the arguments. // Clone the arguments.

View File

@@ -79,7 +79,7 @@ void LoopCloner::cloneLoop() {
for (auto *ExitBB : ExitBlocks) for (auto *ExitBB : ExitBlocks)
BBMap[ExitBB] = ExitBB; BBMap[ExitBB] = ExitBB;
auto *ClonedHeader = new (Mod) SILBasicBlock(CurFun); auto *ClonedHeader = CurFun->createBasicBlock();
BBMap[Header] = ClonedHeader; BBMap[Header] = ClonedHeader;
// Clone the arguments. // Clone the arguments.

View File

@@ -125,7 +125,6 @@ static void InsertCFGDiamond(SILValue Cond, SILLocation Loc, SILBuilder &B,
SILBasicBlock *&FalseBB, SILBasicBlock *&FalseBB,
SILBasicBlock *&ContBB) { SILBasicBlock *&ContBB) {
SILBasicBlock *StartBB = B.getInsertionBB(); SILBasicBlock *StartBB = B.getInsertionBB();
SILModule &Module = StartBB->getModule();
// Start by splitting the current block. // Start by splitting the current block.
ContBB = StartBB->splitBasicBlock(B.getInsertionPoint()); ContBB = StartBB->splitBasicBlock(B.getInsertionPoint());
@@ -136,7 +135,7 @@ static void InsertCFGDiamond(SILValue Cond, SILLocation Loc, SILBuilder &B,
TrueDest = ContBB; TrueDest = ContBB;
TrueBB = nullptr; TrueBB = nullptr;
} else { } else {
TrueDest = new (Module) SILBasicBlock(StartBB->getParent()); TrueDest = StartBB->getParent()->createBasicBlock();
B.moveBlockTo(TrueDest, ContBB); B.moveBlockTo(TrueDest, ContBB);
B.setInsertionPoint(TrueDest); B.setInsertionPoint(TrueDest);
B.createBranch(Loc, ContBB); B.createBranch(Loc, ContBB);
@@ -149,7 +148,7 @@ static void InsertCFGDiamond(SILValue Cond, SILLocation Loc, SILBuilder &B,
FalseDest = ContBB; FalseDest = ContBB;
FalseBB = nullptr; FalseBB = nullptr;
} else { } else {
FalseDest = new (Module) SILBasicBlock(StartBB->getParent()); FalseDest = StartBB->getParent()->createBasicBlock();
B.moveBlockTo(FalseDest, ContBB); B.moveBlockTo(FalseDest, ContBB);
B.setInsertionPoint(FalseDest); B.setInsertionPoint(FalseDest);
B.createBranch(Loc, ContBB); B.createBranch(Loc, ContBB);

View File

@@ -589,7 +589,7 @@ PromotedParamCloner::populateCloned() {
// Create arguments for the entry block // Create arguments for the entry block
SILBasicBlock *OrigEntryBB = &*Orig->begin(); SILBasicBlock *OrigEntryBB = &*Orig->begin();
SILBasicBlock *ClonedEntryBB = new (M) SILBasicBlock(Cloned); SILBasicBlock *ClonedEntryBB = Cloned->createBasicBlock();
unsigned ArgNo = 0; unsigned ArgNo = 0;
auto I = OrigEntryBB->bbarg_begin(), E = OrigEntryBB->bbarg_end(); auto I = OrigEntryBB->bbarg_begin(), E = OrigEntryBB->bbarg_end();
while (I != E) { while (I != E) {

View File

@@ -579,7 +579,7 @@ SILBasicBlock *swift::splitEdge(TermInst *T, unsigned EdgeIdx,
SILBasicBlock *DestBB = T->getSuccessors()[EdgeIdx]; SILBasicBlock *DestBB = T->getSuccessors()[EdgeIdx];
// Create a new basic block in the edge, and insert it after the SrcBB. // Create a new basic block in the edge, and insert it after the SrcBB.
auto *EdgeBB = new (Fn->getModule()) SILBasicBlock(Fn, SrcBB); auto *EdgeBB = Fn->createBasicBlock(SrcBB);
SmallVector<SILValue, 16> Args; SmallVector<SILValue, 16> Args;
getEdgeArgs(T, EdgeIdx, EdgeBB, Args); getEdgeArgs(T, EdgeIdx, EdgeBB, Args);

View File

@@ -61,7 +61,7 @@ void GenericCloner::populateCloned() {
// Create arguments for the entry block. // Create arguments for the entry block.
SILBasicBlock *OrigEntryBB = &*Original.begin(); SILBasicBlock *OrigEntryBB = &*Original.begin();
SILBasicBlock *ClonedEntryBB = new (M) SILBasicBlock(Cloned); SILBasicBlock *ClonedEntryBB = Cloned->createBasicBlock();
getBuilder().setInsertionPoint(ClonedEntryBB); getBuilder().setInsertionPoint(ClonedEntryBB);
llvm::SmallVector<AllocStackInst *, 8> AllocStacks; llvm::SmallVector<AllocStackInst *, 8> AllocStacks;

View File

@@ -371,7 +371,7 @@ static SILFunction *createReabstractionThunk(const ReabstractionInfo &ReInfo,
if (!Thunk->empty()) if (!Thunk->empty())
return Thunk; return Thunk;
SILBasicBlock *EntryBB = new (M) SILBasicBlock(Thunk); SILBasicBlock *EntryBB = Thunk->createBasicBlock();
SILBuilder Builder(EntryBB); SILBuilder Builder(EntryBB);
SILBasicBlock *SpecEntryBB = &*SpecializedFunc->begin(); SILBasicBlock *SpecEntryBB = &*SpecializedFunc->begin();
CanSILFunctionType SpecType = SpecializedFunc->getLoweredFunctionType(); CanSILFunctionType SpecType = SpecializedFunc->getLoweredFunctionType();
@@ -421,8 +421,8 @@ static SILFunction *createReabstractionThunk(const ReabstractionInfo &ReInfo,
SILValue ReturnValue; SILValue ReturnValue;
if (SpecType->hasErrorResult()) { if (SpecType->hasErrorResult()) {
// Create the logic for calling a throwing function. // Create the logic for calling a throwing function.
SILBasicBlock *NormalBB = new (M) SILBasicBlock(Thunk); SILBasicBlock *NormalBB = Thunk->createBasicBlock();
SILBasicBlock *ErrorBB = new (M) SILBasicBlock(Thunk); SILBasicBlock *ErrorBB = Thunk->createBasicBlock();
Builder.createTryApply(Loc, FRI, SpecializedFunc->getLoweredType(), Builder.createTryApply(Loc, FRI, SpecializedFunc->getLoweredType(),
{}, Arguments, NormalBB, ErrorBB); {}, Arguments, NormalBB, ErrorBB);
auto *ErrorVal = new (M) SILArgument(ErrorBB, auto *ErrorVal = new (M) SILArgument(ErrorBB,

View File

@@ -24,8 +24,8 @@
using namespace swift; using namespace swift;
static SILBasicBlock *createInitialPreheader(SILBasicBlock *Header) { static SILBasicBlock *createInitialPreheader(SILBasicBlock *Header) {
auto *Preheader = new (Header->getModule()) auto *Preheader =
SILBasicBlock(Header->getParent(), &*std::prev(Header->getIterator())); Header->getParent()->createBasicBlock(&*std::prev(Header->getIterator()));
// Clone the arguments from header into the pre-header. // Clone the arguments from header into the pre-header.
llvm::SmallVector<SILValue, 8> Args; llvm::SmallVector<SILValue, 8> Args;
@@ -116,8 +116,7 @@ static SILBasicBlock *insertBackedgeBlock(SILLoop *L, DominanceInfo *DT,
} }
// Create and insert the new backedge block... // Create and insert the new backedge block...
SILBasicBlock *BEBlock = SILBasicBlock *BEBlock = F->createBasicBlock(BackedgeBlocks.back());
new (F->getModule()) SILBasicBlock(F, BackedgeBlocks.back());
DEBUG(llvm::dbgs() << " Inserting unique backedge block " << *BEBlock DEBUG(llvm::dbgs() << " Inserting unique backedge block " << *BEBlock
<< "\n"); << "\n");

View File

@@ -252,7 +252,7 @@ SILBasicBlock *SILDeserializer::getBBForDefinition(SILFunction *Fn,
SILBasicBlock *&BB = BlocksByID[ID]; SILBasicBlock *&BB = BlocksByID[ID];
// If the block has never been named yet, just create it. // If the block has never been named yet, just create it.
if (BB == nullptr) if (BB == nullptr)
return BB = new (SILMod) SILBasicBlock(Fn, Prev); return BB = Fn->createBasicBlock(Prev);
// If it already exists, it was either a forward reference or a redefinition. // If it already exists, it was either a forward reference or a redefinition.
// The latter should never happen. // The latter should never happen.
@@ -273,7 +273,7 @@ SILBasicBlock *SILDeserializer::getBBForReference(SILFunction *Fn,
return BB; return BB;
// Otherwise, create it and remember that this is a forward reference // Otherwise, create it and remember that this is a forward reference
BB = new (SILMod) SILBasicBlock(Fn); BB = Fn->createBasicBlock();
UndefinedBlocks[BB] = ID; UndefinedBlocks[BB] = ID;
return BB; return BB;
} }