Skip to content

Commit a0d5180

Browse files
authored
Merge pull request #15554 from jrose-apple/SILGenPattern-cleanup
2 parents a4b6518 + 7987cdc commit a0d5180

File tree

1 file changed

+81
-79
lines changed

1 file changed

+81
-79
lines changed

lib/SILGen/SILGenPattern.cpp

Lines changed: 81 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,32 +1690,63 @@ void PatternMatchEmission::emitIsDispatch(ArrayRef<RowToSpecialize> rows,
16901690

16911691
namespace {
16921692
struct CaseInfo {
1693-
EnumElementDecl *FormalElement;
1693+
SmallVector<SpecializedRow, 2> SpecializedRows;
16941694
Pattern *FirstMatcher;
16951695
bool Irrefutable = false;
1696-
SmallVector<SpecializedRow, 2> SpecializedRows;
1696+
};
1697+
1698+
class CaseBlocks {
1699+
// These vectors are completely parallel, but the switch instructions want
1700+
// only the first two, so we split them up.
1701+
SmallVector<std::pair<EnumElementDecl *, SILBasicBlock *>, 4> CaseBBs;
1702+
SmallVector<ProfileCounter, 4> CaseCounts;
1703+
SmallVector<CaseInfo, 4> CaseInfos;
1704+
SILBasicBlock *DefaultBB = nullptr;
1705+
1706+
public:
1707+
/// Create destination blocks for switching over the cases in an enum
1708+
/// defined by \p rows.
1709+
CaseBlocks(SILGenFunction &SGF,
1710+
ArrayRef<RowToSpecialize> rows,
1711+
CanType sourceType,
1712+
SILBasicBlock *curBB);
1713+
1714+
ArrayRef<std::pair<EnumElementDecl *, SILBasicBlock *>>
1715+
getCaseBlocks() const {
1716+
return CaseBBs;
1717+
}
1718+
1719+
ArrayRef<ProfileCounter> getCounts() const { return CaseCounts; }
1720+
1721+
SILBasicBlock *getDefaultBlock() const { return DefaultBB; }
1722+
1723+
void forEachCase(llvm::function_ref<void(EnumElementDecl *,
1724+
SILBasicBlock *,
1725+
const CaseInfo &)> op) const {
1726+
for_each(CaseBBs, CaseInfos,
1727+
[op](std::pair<EnumElementDecl *, SILBasicBlock *> casePair,
1728+
const CaseInfo &info) {
1729+
op(casePair.first, casePair.second, info);
1730+
});
1731+
}
1732+
1733+
bool hasAnyRefutableCase() const {
1734+
return llvm::any_of(CaseInfos, [](const CaseInfo &info) {
1735+
return !info.Irrefutable;
1736+
});
1737+
}
16971738
};
16981739
} // end anonymous namespace
16991740

1700-
/// Create destination blocks for switching over the cases in an enum defined
1701-
/// by \p rows.
1702-
static void generateEnumCaseBlocks(
1741+
CaseBlocks::CaseBlocks(
17031742
SILGenFunction &SGF,
17041743
ArrayRef<RowToSpecialize> rows,
17051744
CanType sourceType,
1706-
SILBasicBlock *curBB,
1707-
SmallVectorImpl<std::pair<EnumElementDecl *, SILBasicBlock *>> &caseBBs,
1708-
SmallVectorImpl<ProfileCounter> &caseCounts,
1709-
SmallVectorImpl<CaseInfo> &caseInfos,
1710-
SILBasicBlock *&defaultBB) {
1745+
SILBasicBlock *curBB) {
17111746

1712-
assert(caseBBs.empty());
1713-
assert(caseCounts.empty());
1714-
assert(caseInfos.empty());
1715-
assert(defaultBB == nullptr);
1716-
1717-
caseBBs.reserve(rows.size());
1718-
caseInfos.reserve(rows.size());
1747+
CaseBBs.reserve(rows.size());
1748+
CaseInfos.reserve(rows.size());
1749+
CaseCounts.reserve(rows.size());
17191750

17201751
auto enumDecl = sourceType.getEnumOrBoundGenericEnum();
17211752

@@ -1733,22 +1764,21 @@ static void generateEnumCaseBlocks(
17331764
}
17341765
assert(formalElt->getParentEnum() == enumDecl);
17351766

1736-
unsigned index = caseInfos.size();
1767+
unsigned index = CaseInfos.size();
17371768
auto insertionResult = caseToIndex.insert({formalElt, index});
17381769
if (!insertionResult.second) {
17391770
index = insertionResult.first->second;
17401771
} else {
17411772
curBB = SGF.createBasicBlock(curBB);
1742-
caseBBs.push_back({formalElt, curBB});
1743-
caseInfos.push_back(CaseInfo());
1744-
caseInfos.back().FormalElement = formalElt;
1745-
caseInfos.back().FirstMatcher = row.Pattern;
1746-
caseCounts.push_back(row.Count);
1773+
CaseBBs.push_back({formalElt, curBB});
1774+
CaseInfos.push_back(CaseInfo());
1775+
CaseInfos.back().FirstMatcher = row.Pattern;
1776+
CaseCounts.push_back(row.Count);
17471777
}
17481778
assert(caseToIndex[formalElt] == index);
1749-
assert(caseBBs[index].first == formalElt);
1779+
assert(CaseBBs[index].first == formalElt);
17501780

1751-
auto &info = caseInfos[index];
1781+
auto &info = CaseInfos[index];
17521782
info.Irrefutable = (info.Irrefutable || row.Irrefutable);
17531783
info.SpecializedRows.push_back(SpecializedRow());
17541784
auto &specRow = info.SpecializedRows.back();
@@ -1765,7 +1795,7 @@ static void generateEnumCaseBlocks(
17651795
}
17661796
}
17671797

1768-
assert(caseBBs.size() == caseInfos.size());
1798+
assert(CaseBBs.size() == CaseInfos.size());
17691799

17701800
// Check to see if the enum may have values beyond the cases we can see
17711801
// at compile-time. This includes future cases (for resilient enums) and
@@ -1789,7 +1819,7 @@ static void generateEnumCaseBlocks(
17891819
}
17901820

17911821
if (!canAssumeExhaustive)
1792-
defaultBB = SGF.createBasicBlock(curBB);
1822+
DefaultBB = SGF.createBasicBlock(curBB);
17931823
}
17941824

17951825
/// Perform specialized dispatch for a sequence of EnumElementPattern or an
@@ -1804,37 +1834,23 @@ void PatternMatchEmission::emitEnumElementDispatchWithOwnership(
18041834
CanType sourceType = rows[0].Pattern->getType()->getCanonicalType();
18051835

18061836
// Collect the cases and specialized rows.
1807-
//
1808-
// These vectors are completely parallel, but the switch
1809-
// instructions want only the first information, so we split them up.
1810-
SmallVector<std::pair<EnumElementDecl *, SILBasicBlock *>, 4> caseBBs;
1811-
SmallVector<ProfileCounter, 4> caseCounts;
1812-
SmallVector<CaseInfo, 4> caseInfos;
1813-
SILBasicBlock *defaultBB = nullptr;
1814-
1815-
generateEnumCaseBlocks(SGF, rows, sourceType, SGF.B.getInsertionBB(),
1816-
caseBBs, caseCounts, caseInfos, defaultBB);
1837+
CaseBlocks blocks{SGF, rows, sourceType, SGF.B.getInsertionBB()};
18171838

18181839
SILLocation loc = PatternMatchStmt;
18191840
loc.setDebugLoc(rows[0].Pattern);
18201841
// SEMANTIC SIL TODO: Once we have the representation of a switch_enum that
18211842
// can take a +0 value, this extra copy should be a borrow.
18221843
SILValue srcValue = src.getFinalManagedValue().copy(SGF, loc).forward(SGF);
1823-
// FIXME: Pass caseCounts in here as well, as it is in
1824-
// emitEnumElementDispatch.
1825-
ArrayRef<ProfileCounter> caseCountsArrayRef = caseCounts;
1826-
SGF.B.createSwitchEnum(loc, srcValue, defaultBB, caseBBs, caseCountsArrayRef,
1844+
SGF.B.createSwitchEnum(loc, srcValue, blocks.getDefaultBlock(),
1845+
blocks.getCaseBlocks(), blocks.getCounts(),
18271846
defaultCastCount);
18281847

18291848
// Okay, now emit all the cases.
1830-
for (unsigned i = 0, e = caseInfos.size(); i != e; ++i) {
1831-
auto &caseInfo = caseInfos[i];
1849+
blocks.forEachCase([&](EnumElementDecl *elt, SILBasicBlock *caseBB,
1850+
const CaseInfo &caseInfo) {
18321851
SILLocation loc = caseInfo.FirstMatcher;
18331852
auto &specializedRows = caseInfo.SpecializedRows;
18341853

1835-
EnumElementDecl *elt = caseBBs[i].first;
1836-
EnumElementDecl *formalElt = caseInfos[i].FormalElement;
1837-
SILBasicBlock *caseBB = caseBBs[i].second;
18381854
SGF.B.setInsertionPoint(caseBB);
18391855

18401856
// We're in conditionally-executed code; enter a scope.
@@ -1908,8 +1924,8 @@ void PatternMatchEmission::emitEnumElementDispatchWithOwnership(
19081924

19091925
CanType substEltTy =
19101926
sourceType
1911-
->getTypeOfMember(SGF.SGM.M.getSwiftModule(), formalElt,
1912-
formalElt->getArgumentInterfaceType())
1927+
->getTypeOfMember(SGF.SGM.M.getSwiftModule(), elt,
1928+
elt->getArgumentInterfaceType())
19131929
->getCanonicalType();
19141930

19151931
AbstractionPattern origEltTy =
@@ -1923,10 +1939,10 @@ void PatternMatchEmission::emitEnumElementDispatchWithOwnership(
19231939

19241940
handleCase(eltCMV, specializedRows, outerFailure);
19251941
assert(!SGF.B.hasValidInsertionPoint() && "did not end block");
1926-
}
1942+
});
19271943

19281944
// Emit the default block if we needed one.
1929-
if (defaultBB) {
1945+
if (SILBasicBlock *defaultBB = blocks.getDefaultBlock()) {
19301946
SGF.B.setInsertionPoint(defaultBB);
19311947
SGF.B.createOwnedPHIArgument(src.getType());
19321948
outerFailure(rows.back().Pattern);
@@ -1949,16 +1965,7 @@ void PatternMatchEmission::emitEnumElementDispatch(
19491965
CanType sourceType = rows[0].Pattern->getType()->getCanonicalType();
19501966

19511967
// Collect the cases and specialized rows.
1952-
//
1953-
// These vectors are completely parallel, but the switch
1954-
// instructions want only the first information, so we split them up.
1955-
SmallVector<std::pair<EnumElementDecl*, SILBasicBlock*>, 4> caseBBs;
1956-
SmallVector<CaseInfo, 4> caseInfos;
1957-
SmallVector<ProfileCounter, 4> caseCounts;
1958-
SILBasicBlock *defaultBB = nullptr;
1959-
1960-
generateEnumCaseBlocks(SGF, rows, sourceType, SGF.B.getInsertionBB(),
1961-
caseBBs, caseCounts, caseInfos, defaultBB);
1968+
CaseBlocks blocks{SGF, rows, sourceType, SGF.B.getInsertionBB()};
19621969

19631970
// Emit the switch_enum{_addr} instruction.
19641971
bool addressOnlyEnum = src.getType().isAddress();
@@ -1977,12 +1984,9 @@ void PatternMatchEmission::emitEnumElementDispatch(
19771984
assert(!SGF.F.getModule().getOptions().EnableSILOwnership &&
19781985
"TakeOnSuccess is not supported when compiling with ownership");
19791986
// If any of the specialization cases is refutable, we must copy.
1980-
for (auto caseInfo : caseInfos)
1981-
if (!caseInfo.Irrefutable)
1982-
goto refutable;
1983-
break;
1987+
if (!blocks.hasAnyRefutableCase())
1988+
break;
19841989

1985-
refutable:
19861990
src = ConsumableManagedValue(ManagedValue::forUnmanaged(src.getValue()),
19871991
CastConsumptionKind::CopyOnSuccess);
19881992
break;
@@ -1992,24 +1996,22 @@ void PatternMatchEmission::emitEnumElementDispatch(
19921996
SILValue srcValue = src.getFinalManagedValue().forward(SGF);
19931997
SILLocation loc = PatternMatchStmt;
19941998
loc.setDebugLoc(rows[0].Pattern);
1995-
ArrayRef<ProfileCounter> caseCountsArrayRef = caseCounts;
19961999
if (addressOnlyEnum) {
1997-
SGF.B.createSwitchEnumAddr(loc, srcValue, defaultBB, caseBBs,
1998-
caseCountsArrayRef, defaultCaseCount);
2000+
SGF.B.createSwitchEnumAddr(loc, srcValue, blocks.getDefaultBlock(),
2001+
blocks.getCaseBlocks(), blocks.getCounts(),
2002+
defaultCaseCount);
19992003
} else {
2000-
SGF.B.createSwitchEnum(loc, srcValue, defaultBB, caseBBs,
2001-
caseCountsArrayRef, defaultCaseCount);
2004+
SGF.B.createSwitchEnum(loc, srcValue, blocks.getDefaultBlock(),
2005+
blocks.getCaseBlocks(), blocks.getCounts(),
2006+
defaultCaseCount);
20022007
}
20032008

20042009
// Okay, now emit all the cases.
2005-
for (unsigned i = 0, e = caseInfos.size(); i != e; ++i) {
2006-
auto &caseInfo = caseInfos[i];
2010+
blocks.forEachCase([&](EnumElementDecl *elt, SILBasicBlock *caseBB,
2011+
const CaseInfo &caseInfo) {
20072012
SILLocation loc = caseInfo.FirstMatcher;
20082013
auto &specializedRows = caseInfo.SpecializedRows;
20092014

2010-
EnumElementDecl *elt = caseBBs[i].first;
2011-
EnumElementDecl *formalElt = caseInfos[i].FormalElement;
2012-
SILBasicBlock *caseBB = caseBBs[i].second;
20132015
SGF.B.setInsertionPoint(caseBB);
20142016

20152017
// We're in conditionally-executed code; enter a scope.
@@ -2131,8 +2133,8 @@ void PatternMatchEmission::emitEnumElementDispatch(
21312133
// Reabstract to the substituted type, if needed.
21322134

21332135
CanType substEltTy =
2134-
sourceType->getTypeOfMember(SGF.SGM.M.getSwiftModule(), formalElt,
2135-
formalElt->getArgumentInterfaceType())
2136+
sourceType->getTypeOfMember(SGF.SGM.M.getSwiftModule(), elt,
2137+
elt->getArgumentInterfaceType())
21362138
->getCanonicalType();
21372139

21382140
AbstractionPattern origEltTy =
@@ -2155,10 +2157,10 @@ void PatternMatchEmission::emitEnumElementDispatch(
21552157

21562158
handleCase(eltCMV, specializedRows, *innerFailure);
21572159
assert(!SGF.B.hasValidInsertionPoint() && "did not end block");
2158-
}
2160+
});
21592161

21602162
// Emit the default block if we needed one.
2161-
if (defaultBB) {
2163+
if (SILBasicBlock *defaultBB = blocks.getDefaultBlock()) {
21622164
SGF.B.setInsertionPoint(defaultBB);
21632165
outerFailure(rows.back().Pattern);
21642166
}

0 commit comments

Comments
 (0)