@@ -1598,11 +1598,33 @@ struct PartitionOpBuilder {
1598
1598
1599
1599
// / List of partition ops mapped to the current instruction. Used when
1600
1600
// / generating partition ops.
1601
- SmallVector<PartitionOp, 8 > currentInstPartitionOps;
1601
+ std::vector<PartitionOp> *currentInstPartitionOps = nullptr ;
1602
+
1603
+ // / The initial partition op index since the last reset. We use this so that
1604
+ // / we can dump out the partition ops that we generated for a specific
1605
+ // / instruction without needing to waste cycles maintaining a separate
1606
+ // / SmallVector of PartitionOps inside of PartitionOpBuilder.
1607
+ unsigned initialPartitionOpIndex = 0 ;
1608
+
1609
+ void initialize (std::vector<PartitionOp> &foundPartitionOps) {
1610
+ assert (foundPartitionOps.empty ());
1611
+ currentInstPartitionOps = &foundPartitionOps;
1612
+ initialPartitionOpIndex = currentInstPartitionOps->size ();
1613
+ }
1602
1614
1603
1615
void reset (SILInstruction *inst) {
1616
+ assert (currentInstPartitionOps);
1604
1617
currentInst = inst;
1605
- currentInstPartitionOps.clear ();
1618
+ initialPartitionOpIndex = currentInstPartitionOps->size ();
1619
+ }
1620
+
1621
+ // / Return an ArrayRef containing the PartitionOps associated with the current
1622
+ // / instruction being built.
1623
+ ArrayRef<PartitionOp> getPartitionOpsForCurrentInst () const {
1624
+ assert (currentInstPartitionOps);
1625
+ unsigned numElts =
1626
+ currentInstPartitionOps->size () - initialPartitionOpIndex;
1627
+ return llvm::ArrayRef (*currentInstPartitionOps).take_back (numElts);
1606
1628
}
1607
1629
1608
1630
Element lookupValueID (SILValue value);
@@ -1614,7 +1636,7 @@ struct PartitionOpBuilder {
1614
1636
if (value.isSendable ())
1615
1637
return ;
1616
1638
auto id = lookupValueID (value.getRepresentative ().getValue ());
1617
- currentInstPartitionOps. emplace_back (
1639
+ currentInstPartitionOps-> emplace_back (
1618
1640
PartitionOp::AssignFresh (id, currentInst));
1619
1641
}
1620
1642
@@ -1623,15 +1645,15 @@ struct PartitionOpBuilder {
1623
1645
return ;
1624
1646
1625
1647
auto first = lookupValueID (values.front ());
1626
- currentInstPartitionOps. emplace_back (
1648
+ currentInstPartitionOps-> emplace_back (
1627
1649
PartitionOp::AssignFresh (first, currentInst));
1628
1650
1629
1651
auto transformedCollection =
1630
1652
makeTransformRange (values.drop_front (), [&](SILValue value) {
1631
1653
return lookupValueID (value);
1632
1654
});
1633
1655
for (auto id : transformedCollection) {
1634
- currentInstPartitionOps. emplace_back (
1656
+ currentInstPartitionOps-> emplace_back (
1635
1657
PartitionOp::AssignFreshAssign (id, first, currentInst));
1636
1658
}
1637
1659
}
@@ -1650,7 +1672,7 @@ struct PartitionOpBuilder {
1650
1672
return ;
1651
1673
}
1652
1674
1653
- currentInstPartitionOps. emplace_back (
1675
+ currentInstPartitionOps-> emplace_back (
1654
1676
PartitionOp::Assign (lookupValueID (destValue),
1655
1677
lookupValueID (srcOperand->get ()), srcOperand));
1656
1678
}
@@ -1663,15 +1685,15 @@ struct PartitionOpBuilder {
1663
1685
assert (valueHasID (representative) &&
1664
1686
" sent value should already have been encountered" );
1665
1687
1666
- currentInstPartitionOps. emplace_back (
1688
+ currentInstPartitionOps-> emplace_back (
1667
1689
PartitionOp::Send (lookupValueID (representative), op));
1668
1690
}
1669
1691
1670
1692
void addUndoSend (SILValue representative, SILInstruction *unsendingInst) {
1671
1693
assert (valueHasID (representative) &&
1672
1694
" value should already have been encountered" );
1673
1695
1674
- currentInstPartitionOps. emplace_back (
1696
+ currentInstPartitionOps-> emplace_back (
1675
1697
PartitionOp::UndoSend (lookupValueID (representative), unsendingInst));
1676
1698
}
1677
1699
@@ -1686,7 +1708,7 @@ struct PartitionOpBuilder {
1686
1708
if (lookupValueID (rep) == lookupValueID (srcOperand->get ()))
1687
1709
return ;
1688
1710
1689
- currentInstPartitionOps. emplace_back (PartitionOp::Merge (
1711
+ currentInstPartitionOps-> emplace_back (PartitionOp::Merge (
1690
1712
lookupValueID (rep), lookupValueID (srcOperand->get ()), srcOperand));
1691
1713
}
1692
1714
@@ -1698,9 +1720,9 @@ struct PartitionOpBuilder {
1698
1720
" merged values should already have been encountered" );
1699
1721
1700
1722
auto elt = getActorIntroducingRepresentative (actorIsolation);
1701
- currentInstPartitionOps. emplace_back (
1723
+ currentInstPartitionOps-> emplace_back (
1702
1724
PartitionOp::AssignFresh (elt, currentInst));
1703
- currentInstPartitionOps. emplace_back (
1725
+ currentInstPartitionOps-> emplace_back (
1704
1726
PartitionOp::Merge (lookupValueID (sourceValue), elt, sourceOperand));
1705
1727
}
1706
1728
@@ -1723,7 +1745,7 @@ struct PartitionOpBuilder {
1723
1745
auto rep = value.getRepresentative ().getValue ();
1724
1746
assert (valueHasID (rep, /* dumpIfHasNoID=*/ true ) &&
1725
1747
" required value should already have been encountered" );
1726
- currentInstPartitionOps. emplace_back (
1748
+ currentInstPartitionOps-> emplace_back (
1727
1749
PartitionOp::InOutSendingAtFunctionExit (lookupValueID (rep),
1728
1750
currentInst));
1729
1751
}
@@ -1733,15 +1755,15 @@ struct PartitionOpBuilder {
1733
1755
llvm::report_fatal_error (
1734
1756
" RegionIsolation: Aborting on unknown pattern match error" );
1735
1757
}
1736
- currentInstPartitionOps. emplace_back (
1758
+ currentInstPartitionOps-> emplace_back (
1737
1759
PartitionOp::UnknownPatternError (lookupValueID (value), currentInst));
1738
1760
}
1739
1761
1740
1762
void addNonSendableIsolationCrossingResultError (TrackableValue value) {
1741
1763
if (value.isSendable ())
1742
1764
return ;
1743
1765
auto rep = value.getRepresentative ().getValue ();
1744
- currentInstPartitionOps. emplace_back (
1766
+ currentInstPartitionOps-> emplace_back (
1745
1767
PartitionOp::NonSendableIsolationCrossingResult (lookupValueID (rep),
1746
1768
currentInst));
1747
1769
}
@@ -1917,8 +1939,11 @@ class PartitionOpTranslator {
1917
1939
1918
1940
SILFunction *function;
1919
1941
1920
- // / A cache of argument IDs.
1921
- std::optional<Partition> functionArgPartition;
1942
+ // / The initial partition of the entry block.
1943
+ // /
1944
+ // / This contains a single region for non-sending parameters as well as
1945
+ // / separate regions for each sending parameter.
1946
+ std::optional<Partition> initialEntryBlockPartition;
1922
1947
1923
1948
// / A builder struct that we use to convert individual instructions into lists
1924
1949
// / of PartitionOps.
@@ -1983,7 +2008,7 @@ class PartitionOpTranslator {
1983
2008
PartitionOpTranslator (SILFunction *function, PostOrderFunctionInfo *pofi,
1984
2009
RegionAnalysisValueMap &valueMap,
1985
2010
IsolationHistory::Factory &historyFactory)
1986
- : function(function), functionArgPartition(), builder (),
2011
+ : function(function), initialEntryBlockPartition (),
1987
2012
partialApplyReachabilityDataflow (function, valueMap, pofi),
1988
2013
valueMap(valueMap) {
1989
2014
builder.translator = this ;
@@ -2006,8 +2031,8 @@ class PartitionOpTranslator {
2006
2031
auto functionArguments = function->getArguments ();
2007
2032
if (functionArguments.empty ()) {
2008
2033
REGIONBASEDISOLATION_LOG (llvm::dbgs () << " None.\n " );
2009
- functionArgPartition = Partition::singleRegion (SILLocation::invalid (), {},
2010
- historyFactory.get ());
2034
+ initialEntryBlockPartition = Partition::singleRegion (
2035
+ SILLocation::invalid (), {}, historyFactory.get ());
2011
2036
return ;
2012
2037
}
2013
2038
@@ -2044,10 +2069,10 @@ class PartitionOpTranslator {
2044
2069
}
2045
2070
}
2046
2071
2047
- functionArgPartition = Partition::singleRegion (
2072
+ initialEntryBlockPartition = Partition::singleRegion (
2048
2073
SILLocation::invalid (), nonSendableJoinedIndices, historyFactory.get ());
2049
2074
for (Element elt : nonSendableSeparateIndices) {
2050
- functionArgPartition ->trackNewElement (elt);
2075
+ initialEntryBlockPartition ->trackNewElement (elt);
2051
2076
}
2052
2077
}
2053
2078
@@ -2116,8 +2141,10 @@ class PartitionOpTranslator {
2116
2141
public:
2117
2142
// / Return the partition consisting of all function arguments.
2118
2143
// /
2119
- // / Used to initialize the entry blocko of our analysis.
2120
- const Partition &getEntryPartition () const { return *functionArgPartition; }
2144
+ // / Used to initialize the initial partition of the entry block of the CFG.
2145
+ const Partition &getInitialEntryPartition () const {
2146
+ return *initialEntryBlockPartition;
2147
+ }
2121
2148
2122
2149
// / Get the results of an apply instruction.
2123
2150
// /
@@ -3002,13 +3029,13 @@ class PartitionOpTranslator {
3002
3029
basicBlock->printID (llvm::dbgs ()); llvm::dbgs () << SEP_STR;
3003
3030
basicBlock->print (llvm::dbgs ());
3004
3031
llvm::dbgs () << SEP_STR << " Results:\n " ;);
3032
+
3005
3033
// Translate each SIL instruction to the PartitionOps that it represents if
3006
3034
// any.
3035
+ builder.initialize (foundPartitionOps);
3007
3036
for (auto &instruction : *basicBlock) {
3008
3037
REGIONBASEDISOLATION_LOG (llvm::dbgs () << " Visiting: " << instruction);
3009
3038
translateSILInstruction (&instruction);
3010
- copy (builder.currentInstPartitionOps ,
3011
- std::back_inserter (foundPartitionOps));
3012
3039
}
3013
3040
}
3014
3041
@@ -3136,7 +3163,8 @@ bool PartitionOpBuilder::valueHasID(SILValue value, bool dumpIfHasNoID) {
3136
3163
void PartitionOpBuilder::print (llvm::raw_ostream &os) const {
3137
3164
#ifndef NDEBUG
3138
3165
// If we do not have anything to dump, just return.
3139
- if (currentInstPartitionOps.empty ())
3166
+ auto ops = getPartitionOpsForCurrentInst ();
3167
+ if (ops.empty ())
3140
3168
return ;
3141
3169
3142
3170
// First line.
@@ -3148,8 +3176,6 @@ void PartitionOpBuilder::print(llvm::raw_ostream &os) const {
3148
3176
currentInst->getLoc ().getSourceLoc ().printLineAndColumn (
3149
3177
llvm::dbgs (), currentInst->getFunction ()->getASTContext ().SourceMgr );
3150
3178
3151
- auto ops = llvm::ArrayRef (currentInstPartitionOps);
3152
-
3153
3179
// First op on its own line.
3154
3180
llvm::dbgs () << " \n ├─────╼ " ;
3155
3181
ops.front ().print (llvm::dbgs ());
@@ -3192,9 +3218,7 @@ void PartitionOpBuilder::addRequire(TrackableValue value,
3192
3218
assert (valueHasID (silValue, /* dumpIfHasNoID=*/ true ) &&
3193
3219
" required value should already have been encountered" );
3194
3220
3195
- // Check if this value
3196
-
3197
- currentInstPartitionOps.emplace_back (
3221
+ currentInstPartitionOps->emplace_back (
3198
3222
PartitionOp::Require (lookupValueID (silValue), currentInst, options));
3199
3223
}
3200
3224
@@ -4139,7 +4163,7 @@ RegionAnalysisFunctionInfo::RegionAnalysisFunctionInfo(
4139
4163
}
4140
4164
// Set our entry partition to have the "entry partition".
4141
4165
(*blockStates)[fn->getEntryBlock ()].entryPartition =
4142
- translator->getEntryPartition ();
4166
+ translator->getInitialEntryPartition ();
4143
4167
runDataflow ();
4144
4168
}
4145
4169
0 commit comments