[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 delete(void *Ptr, size_t) = delete;
public:
SILBasicBlock(SILFunction *F, SILBasicBlock *afterBB = nullptr);
public:
~SILBasicBlock();
/// 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.
if (BBI == BBMap.end()) {
// 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));
// Create new arguments for each of the original block's arguments.
for (auto &Arg : Succ.getBB()->getBBArgs()) {

View File

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

View File

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

View File

@@ -477,12 +477,12 @@ SILFunction *SILParser::getGlobalNameForReference(Identifier Name,
SILBasicBlock *SILParser::getBBForDefinition(Identifier Name, SourceLoc Loc) {
// If there was no name specified for this block, just create a new one.
if (Name.empty())
return new (SILMod) SILBasicBlock(F);
return F->createBasicBlock();
SILBasicBlock *&BB = BlocksByName[Name];
// If the block has never been named yet, just create it.
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 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.
P.diagnose(Loc, diag::sil_basicblock_redefinition, Name);
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
@@ -510,7 +510,7 @@ SILBasicBlock *SILParser::getBBForReference(Identifier Name, SourceLoc Loc) {
// Otherwise, create it and remember that this is a forward reference so
// that we can diagnose use without definition problems.
BB = new (SILMod) SILBasicBlock(F);
BB = F->createBasicBlock();
UndefinedBlocks[BB] = {Loc, Name};
return BB;
}

View File

@@ -138,7 +138,7 @@ void SILBuilder::emitBlock(SILBasicBlock *BB, SILLocation BranchLoc) {
SILBasicBlock *SILBuilder::splitBlockForFallthrough() {
// If we are concatenating, just create and return a new block.
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.

View File

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

View File

@@ -34,14 +34,14 @@ static void diagnose(ASTContext &Context, SourceLoc loc, Diag<T...> diag,
SILBasicBlock *SILGenFunction::createBasicBlock(SILBasicBlock *afterBB) {
// Honor an explicit placement if given.
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
// insertion point, insert there.
// If we don't have a requested placement, but we do have a current
// insertion point, insert there.
} 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 {
return createBasicBlock(CurFunctionSection);
}
@@ -55,13 +55,13 @@ SILBasicBlock *SILGenFunction::createBasicBlock(FunctionSection section) {
SILBasicBlock *afterBB = (StartOfPostmatter != F.end())
? &*std::prev(StartOfPostmatter)
: nullptr;
return new (F.getModule()) SILBasicBlock(&F, afterBB);
return F.createBasicBlock(afterBB);
}
case FunctionSection::Postmatter: {
// 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.
SILBasicBlock *newBB = new (F.getModule()) SILBasicBlock(&F, nullptr);
SILBasicBlock *newBB = F.createBasicBlock(nullptr);
if (StartOfPostmatter == F.end())
StartOfPostmatter = newBB->getIterator();
return newBB;

View File

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

View File

@@ -165,7 +165,7 @@ void CapturePropagationCloner::cloneBlocks(
// Create the entry basic block with the function arguments.
SILBasicBlock *OrigEntryBB = &*OrigF->begin();
SILBasicBlock *ClonedEntryBB = new (M) SILBasicBlock(&CloneF);
SILBasicBlock *ClonedEntryBB = CloneF.createBasicBlock();
CanSILFunctionType CloneFTy = CloneF.getLoweredFunctionType();
// 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.
SILBasicBlock *ClosureUserEntryBB = &*ClosureUser->begin();
SILBasicBlock *ClonedEntryBB = new (M) SILBasicBlock(Cloned);
SILBasicBlock *ClonedEntryBB = Cloned->createBasicBlock();
// Remove the closure argument.
SILArgument *ClosureArg = nullptr;

View File

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

View File

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

View File

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

View File

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

View File

@@ -579,7 +579,7 @@ SILBasicBlock *swift::splitEdge(TermInst *T, unsigned EdgeIdx,
SILBasicBlock *DestBB = T->getSuccessors()[EdgeIdx];
// 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;
getEdgeArgs(T, EdgeIdx, EdgeBB, Args);

View File

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

View File

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

View File

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

View File

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