mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
COWArrayOpt: Fix the array property specializer to recompute the loop tree after cloning
Cloning the loop is going to invalidate the loop tree. Be conservative and recompute it. No test case. I did not run into an error but also don't want to in the future. Swift SVN r25733
This commit is contained in:
@@ -1245,7 +1245,6 @@ namespace {
|
|||||||
/// However, the client needs to update the dominator of the exit blocks.
|
/// However, the client needs to update the dominator of the exit blocks.
|
||||||
class RegionCloner : public SILCloner<RegionCloner> {
|
class RegionCloner : public SILCloner<RegionCloner> {
|
||||||
DominanceInfo &DomTree;
|
DominanceInfo &DomTree;
|
||||||
SILLoopInfo *LoopInfo;
|
|
||||||
SILBasicBlock *StartBB;
|
SILBasicBlock *StartBB;
|
||||||
SmallPtrSet<SILBasicBlock *, 16> OutsideBBs;
|
SmallPtrSet<SILBasicBlock *, 16> OutsideBBs;
|
||||||
|
|
||||||
@@ -1254,11 +1253,9 @@ class RegionCloner : public SILCloner<RegionCloner> {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
RegionCloner(SILBasicBlock *EntryBB,
|
RegionCloner(SILBasicBlock *EntryBB,
|
||||||
SmallVectorImpl<SILBasicBlock *> &ExitBlocks, DominanceInfo &DT,
|
SmallVectorImpl<SILBasicBlock *> &ExitBlocks, DominanceInfo &DT)
|
||||||
SILLoopInfo *LI)
|
|
||||||
: SILCloner<RegionCloner>(*EntryBB->getParent()), DomTree(DT),
|
: SILCloner<RegionCloner>(*EntryBB->getParent()), DomTree(DT),
|
||||||
LoopInfo(LI), StartBB(EntryBB),
|
StartBB(EntryBB), OutsideBBs(ExitBlocks.begin(), ExitBlocks.end()) {}
|
||||||
OutsideBBs(ExitBlocks.begin(), ExitBlocks.end()) {}
|
|
||||||
|
|
||||||
SILBasicBlock *cloneRegion() {
|
SILBasicBlock *cloneRegion() {
|
||||||
assert (DomTree.getNode(StartBB) != nullptr && "Can't cloned dead code");
|
assert (DomTree.getNode(StartBB) != nullptr && "Can't cloned dead code");
|
||||||
@@ -1409,17 +1406,23 @@ namespace {
|
|||||||
/// loop based on array.props calls.
|
/// loop based on array.props calls.
|
||||||
class ArrayPropertiesSpecializer {
|
class ArrayPropertiesSpecializer {
|
||||||
DominanceInfo *DomTree;
|
DominanceInfo *DomTree;
|
||||||
SILLoopInfo *LoopInfo;
|
SILLoopAnalysis *LoopAnalysis;
|
||||||
SILBasicBlock *HoistableLoopPreheader;
|
SILBasicBlock *HoistableLoopPreheader;
|
||||||
public:
|
public:
|
||||||
ArrayPropertiesSpecializer(DominanceInfo *DT, SILLoopInfo *LI,
|
ArrayPropertiesSpecializer(DominanceInfo *DT, SILLoopAnalysis *LA,
|
||||||
SILBasicBlock *Hoistable)
|
SILBasicBlock *Hoistable)
|
||||||
: DomTree(DT), LoopInfo(LI), HoistableLoopPreheader(Hoistable) {}
|
: DomTree(DT), LoopAnalysis(LA), HoistableLoopPreheader(Hoistable) {}
|
||||||
|
|
||||||
void run() {
|
void run() {
|
||||||
specializeLoopNest();
|
specializeLoopNest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SILLoop *getLoop() {
|
||||||
|
auto *LoopInfo =
|
||||||
|
LoopAnalysis->getLoopInfo(HoistableLoopPreheader->getParent());
|
||||||
|
return LoopInfo->getLoopFor(HoistableLoopPreheader->getSingleSuccessor());
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void specializeLoopNest();
|
void specializeLoopNest();
|
||||||
};
|
};
|
||||||
@@ -1531,6 +1534,9 @@ static void replaceArrayPropsCall(SILBuilder &B, ArraySemanticsCall C) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ArrayPropertiesSpecializer::specializeLoopNest() {
|
void ArrayPropertiesSpecializer::specializeLoopNest() {
|
||||||
|
auto *Lp = getLoop();
|
||||||
|
assert(Lp);
|
||||||
|
|
||||||
// Split of a new empty preheader. We don't want to duplicate the whole
|
// Split of a new empty preheader. We don't want to duplicate the whole
|
||||||
// original preheader it might contain instructions that we can't clone.
|
// original preheader it might contain instructions that we can't clone.
|
||||||
// This will be block that will contain the check whether to execute the
|
// This will be block that will contain the check whether to execute the
|
||||||
@@ -1541,8 +1547,6 @@ void ArrayPropertiesSpecializer::specializeLoopNest() {
|
|||||||
// Get the exit blocks of the orignal loop.
|
// Get the exit blocks of the orignal loop.
|
||||||
auto *Header = CheckBlock->getSingleSuccessor();
|
auto *Header = CheckBlock->getSingleSuccessor();
|
||||||
assert(Header);
|
assert(Header);
|
||||||
auto *Lp = LoopInfo->getLoopFor(Header);
|
|
||||||
assert(Lp);
|
|
||||||
|
|
||||||
// Our loop info is not really completedly valid anymore since the cloner does
|
// Our loop info is not really completedly valid anymore since the cloner does
|
||||||
// not update it. However, exit blocks of the original loop are still valid.
|
// not update it. However, exit blocks of the original loop are still valid.
|
||||||
@@ -1555,7 +1559,7 @@ void ArrayPropertiesSpecializer::specializeLoopNest() {
|
|||||||
|
|
||||||
// Clone the region from the new preheader up to (not including) the exit
|
// Clone the region from the new preheader up to (not including) the exit
|
||||||
// blocks. This creates a second loop nest.
|
// blocks. This creates a second loop nest.
|
||||||
RegionCloner Cloner(NewPreheader, ExitBlocks, *DomTree, LoopInfo);
|
RegionCloner Cloner(NewPreheader, ExitBlocks, *DomTree);
|
||||||
auto *ClonedPreheader = Cloner.cloneRegion();
|
auto *ClonedPreheader = Cloner.cloneRegion();
|
||||||
|
|
||||||
// Collect the array.props call that we will specialize on that we have
|
// Collect the array.props call that we will specialize on that we have
|
||||||
@@ -1587,6 +1591,10 @@ void ArrayPropertiesSpecializer::specializeLoopNest() {
|
|||||||
SILBuilder B2(ClonedPreheader->getTerminator());
|
SILBuilder B2(ClonedPreheader->getTerminator());
|
||||||
for (auto C : ArrayPropCalls)
|
for (auto C : ArrayPropCalls)
|
||||||
replaceArrayPropsCall(B2, C);
|
replaceArrayPropsCall(B2, C);
|
||||||
|
|
||||||
|
// We have potentially cloned a loop - invalidate loop info.
|
||||||
|
LoopAnalysis->invalidate(Header->getParent(),
|
||||||
|
SILAnalysis::InvalidationKind::CFG);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -1630,7 +1638,7 @@ class SwiftArrayOptPass : public SILFunctionTransform {
|
|||||||
// Process specialized loop-nests in loop-tree post-order (bottom-up).
|
// Process specialized loop-nests in loop-tree post-order (bottom-up).
|
||||||
std::reverse(HoistableLoopNests.begin(), HoistableLoopNests.end());
|
std::reverse(HoistableLoopNests.begin(), HoistableLoopNests.end());
|
||||||
for (auto &HoistableLoopNest : HoistableLoopNests)
|
for (auto &HoistableLoopNest : HoistableLoopNests)
|
||||||
ArrayPropertiesSpecializer(DT, LI, HoistableLoopNest).run();
|
ArrayPropertiesSpecializer(DT, LA, HoistableLoopNest).run();
|
||||||
DEBUG(getFunction()->viewCFG());
|
DEBUG(getFunction()->viewCFG());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user