Skip to content

NFC: SILBasicBlock utilties for handling critical edges. #20111

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

Merged
merged 6 commits into from
Oct 29, 2018
Merged
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
28 changes: 28 additions & 0 deletions include/swift/SIL/BasicBlockUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,40 @@
#ifndef SWIFT_SIL_DEADENDBLOCKS_H
#define SWIFT_SIL_DEADENDBLOCKS_H

#include "swift/SIL/SILValue.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"

namespace swift {

class SILFunction;
class SILBasicBlock;
class TermInst;
class DominanceInfo;
class SILLoopInfo;

/// \brief Replace a branch target.
///
/// \param T The terminating instruction to modify.
/// \param edgeIdx The successor edges index that will be replaced.
/// \param newDest The new target block.
/// \param preserveArgs If set, preserve arguments on the replaced edge.
void changeBranchTarget(TermInst *T, unsigned edgeIdx, SILBasicBlock *newDest,
bool preserveArgs);

/// Returns the arguments values on the specified CFG edge. If necessary, may
/// add create new SILPHIArguments, using `NewEdgeBB` as the placeholder.
void getEdgeArgs(TermInst *T, unsigned edgeIdx, SILBasicBlock *newEdgeBB,
llvm::SmallVectorImpl<SILValue> &args);

/// \brief Splits the edge from terminator.
///
/// Also updates dominance and loop information if not null.
///
/// Returns the newly created basic block.
SILBasicBlock *splitEdge(TermInst *T, unsigned edgeIdx,
DominanceInfo *DT = nullptr,
SILLoopInfo *LI = nullptr);

/// \brief Merge a basic block ending in a branch with its successor
/// if possible.
Expand Down
16 changes: 15 additions & 1 deletion include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,18 @@ class SILBuilder {
/// Build instructions before the given insertion point, inheriting the debug
/// location.
///
/// Clients should prefer this constructor.
/// SILBuilderContext must outlive this SILBuilder instance.
SILBuilder(SILInstruction *I, const SILDebugScope *DS, SILBuilderContext &C)
: TempContext(C.getModule()), C(C), F(I->getFunction()) {
assert(DS && "instruction has no debug scope");
setCurrentDebugScope(DS);
setInsertionPoint(I);
}

/// Build instructions before the given insertion point, inheriting the debug
/// location.
///
/// SILBuilderContext must outlive this SILBuilder instance.
SILBuilder(SILBasicBlock *BB, const SILDebugScope *DS, SILBuilderContext &C)
: TempContext(C.getModule()), C(C), F(BB->getParent()) {
assert(DS && "block has no debug scope");
Expand Down Expand Up @@ -371,6 +375,16 @@ class SILBuilder {
/// continuation block.
SILBasicBlock *splitBlockForFallthrough();

/// Convenience for creating a fall-through basic block on-the-fly without
/// affecting the insertion point.
SILBasicBlock *createFallthroughBlock(SILLocation loc,
SILBasicBlock *targetBB) {
auto *newBB = F->createBasicBlock();
SILBuilder(newBB, this->getCurrentDebugScope(), this->getBuilderContext())
.createBranch(loc, targetBB);
return newBB;
}

//===--------------------------------------------------------------------===//
// SILInstruction Creation Methods
//===--------------------------------------------------------------------===//
Expand Down
8 changes: 4 additions & 4 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,13 +285,13 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
///
/// Assumes that `isValueCloned` is true.
SILValue getOpValue(SILValue Value) {
return asImpl().remapValue(Value);
return asImpl().getMappedValue(Value);
}
template <size_t N, typename ArrayRefType>
SmallVector<SILValue, N> getOpValueArray(ArrayRefType Values) {
SmallVector<SILValue, N> Ret(Values.size());
for (unsigned i = 0, e = Values.size(); i != e; ++i)
Ret[i] = asImpl().remapValue(Values[i]);
Ret[i] = asImpl().getMappedValue(Values[i]);
return Ret;
}

Expand Down Expand Up @@ -351,7 +351,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
ProtocolConformanceRef remapConformance(Type Ty, ProtocolConformanceRef C) {
return C;
}
SILValue remapValue(SILValue Value);
SILValue getMappedValue(SILValue Value);
SILFunction *remapFunction(SILFunction *Func) { return Func; }
SILBasicBlock *remapBasicBlock(SILBasicBlock *BB);
void postProcess(SILInstruction *Orig, SILInstruction *Cloned);
Expand Down Expand Up @@ -472,7 +472,7 @@ class SILClonerWithScopes : public SILCloner<ImplClass> {

template<typename ImplClass>
SILValue
SILCloner<ImplClass>::remapValue(SILValue Value) {
SILCloner<ImplClass>::getMappedValue(SILValue Value) {
auto VI = ValueMap.find(Value);
if (VI != ValueMap.end())
return VI->second;
Expand Down
23 changes: 5 additions & 18 deletions include/swift/SILOptimizer/Utils/CFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,14 @@ TermInst *addNewEdgeValueToBranch(TermInst *Branch, SILBasicBlock *Dest,
TermInst *changeEdgeValue(TermInst *Branch, SILBasicBlock *Dest, size_t Idx,
SILValue Val);

/// \brief Replace a branch target.
///
/// \param T The terminating instruction to modify.
/// \param EdgeIdx The successor edges index that will be replaced.
/// \param NewDest The new target block.
/// \param PreserveArgs If set, preserve arguments on the replaced edge.
void changeBranchTarget(TermInst *T, unsigned EdgeIdx, SILBasicBlock *NewDest,
bool PreserveArgs);

/// \brief Replace a branch target.
///
/// \param T The terminating instruction to modify.
/// \param OldDest The successor block that will be replaced.
/// \param NewDest The new target block.
/// \param PreserveArgs If set, preserve arguments on the replaced edge.
void replaceBranchTarget(TermInst *T, SILBasicBlock *OldDest, SILBasicBlock *NewDest,
bool PreserveArgs);
void replaceBranchTarget(TermInst *T, SILBasicBlock *OldDest,
SILBasicBlock *NewDest, bool PreserveArgs);

/// \brief Check if the edge from the terminator is critical.
bool isCriticalEdge(TermInst *T, unsigned EdgeIdx);
Expand All @@ -85,13 +76,9 @@ SILBasicBlock *splitIfCriticalEdge(SILBasicBlock *From, SILBasicBlock *To,
DominanceInfo *DT = nullptr,
SILLoopInfo *LI = nullptr);

/// \brief Splits the edge from terminator.
///
/// Updates dominance information and loop information if not null.
/// Returns the newly created basic block.
SILBasicBlock *splitEdge(TermInst *T, unsigned EdgeIdx,
DominanceInfo *DT = nullptr,
SILLoopInfo *LI = nullptr);
/// Splits all critical edges originating from `fromBB`.
bool splitCriticalEdgesFrom(SILBasicBlock *fromBB, DominanceInfo *DT = nullptr,
SILLoopInfo *LI = nullptr);

/// \brief Splits the edges between two basic blocks.
///
Expand Down
5 changes: 2 additions & 3 deletions include/swift/SILOptimizer/Utils/Local.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ class BaseThreadingCloner : public SILClonerWithScopes<BaseThreadingCloner> {

SILBasicBlock *remapBasicBlock(SILBasicBlock *BB) { return BB; }

SILValue remapValue(SILValue Value) {
SILValue getMappedValue(SILValue Value) {
// If this is a use of an instruction in another block, then just use it.
if (auto SI = Value->getDefiningInstruction()) {
if (SI->getParent() != FromBB)
Expand All @@ -334,8 +334,7 @@ class BaseThreadingCloner : public SILClonerWithScopes<BaseThreadingCloner> {
assert(isa<SILUndef>(Value) && "Unexpected Value kind");
return Value;
}

return SILCloner<BaseThreadingCloner>::remapValue(Value);
return SILCloner<BaseThreadingCloner>::getMappedValue(Value);
}

void postProcess(SILInstruction *Orig, SILInstruction *Cloned) {
Expand Down
Loading