Skip to content

Commit ee26fea

Browse files
authored
Merge pull request #33504 from meg-gupta/fixarcseqopt
Fix ARCSequenceOpts bottom up handling of terminators
2 parents a434ee8 + 4d2753b commit ee26fea

File tree

10 files changed

+124
-204
lines changed

10 files changed

+124
-204
lines changed

lib/SILOptimizer/ARC/ARCMatchingSet.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@ ARCMatchingSetBuilder::matchIncrementsToDecrements() {
6868
continue;
6969
}
7070

71-
// We need to be known safe over all increments/decrements we are matching
72-
// up to ignore insertion points.
7371
bool BUIsKnownSafe = (*BURefCountState)->second.isKnownSafe();
7472
LLVM_DEBUG(llvm::dbgs() << " BOTTOM UP KNOWNSAFE: "
7573
<< (BUIsKnownSafe ? "true" : "false") << "\n");
@@ -152,8 +150,6 @@ ARCMatchingSetBuilder::matchDecrementsToIncrements() {
152150
continue;
153151
}
154152

155-
// We need to be known safe over all increments/decrements we are matching
156-
// up to ignore insertion points.
157153
bool TDIsKnownSafe = (*TDRefCountState)->second.isKnownSafe();
158154
LLVM_DEBUG(llvm::dbgs() << " TOP DOWN KNOWNSAFE: "
159155
<< (TDIsKnownSafe ? "true" : "false") << "\n");
@@ -223,7 +219,7 @@ bool ARCMatchingSetBuilder::matchUpIncDecSetsForPtr() {
223219
LLVM_DEBUG(llvm::dbgs() << "Attempting to match up increments -> "
224220
"decrements:\n");
225221
// For each increment in our list of new increments, attempt to match them
226-
// up with decrements and gather the insertion points of the decrements.
222+
// up with decrements.
227223
auto Result = matchIncrementsToDecrements();
228224
if (!Result) {
229225
LLVM_DEBUG(llvm::dbgs() << " FAILED TO MATCH INCREMENTS -> "
@@ -287,8 +283,6 @@ bool ARCMatchingSetBuilder::matchUpIncDecSetsForPtr() {
287283
assert(MatchSet.Increments.empty() == MatchSet.Decrements.empty() &&
288284
"Match set without increments or decrements");
289285

290-
// If we do not have any insertion points but we do have increments, we must
291-
// be eliminating pairs.
292286
if (!MatchSet.Increments.empty())
293287
MatchedPair = true;
294288

lib/SILOptimizer/ARC/ARCRegionState.cpp

Lines changed: 5 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#define DEBUG_TYPE "arc-sequence-opts"
1414
#include "ARCRegionState.h"
15+
#include "ARCSequenceOptUtils.h"
1516
#include "RCStateTransitionVisitors.h"
1617
#include "swift/Basic/Range.h"
1718
#include "swift/SILOptimizer/Analysis/LoopRegionAnalysis.h"
@@ -155,77 +156,6 @@ void ARCRegionState::mergePredTopDown(ARCRegionState &PredRegionState) {
155156
// Bottom Up Dataflow
156157
//
157158

158-
static bool isARCSignificantTerminator(TermInst *TI) {
159-
switch (TI->getTermKind()) {
160-
case TermKind::UnreachableInst:
161-
// br is a forwarding use for its arguments. It cannot in of itself extend
162-
// the lifetime of an object (just like a phi-node) cannot.
163-
case TermKind::BranchInst:
164-
// A cond_br is a forwarding use for its non-operand arguments in a similar
165-
// way to br. Its operand must be an i1 that has a different lifetime from any
166-
// ref counted object.
167-
case TermKind::CondBranchInst:
168-
return false;
169-
// Be conservative for now. These actually perform some sort of operation
170-
// against the operand or can use the value in some way.
171-
case TermKind::ThrowInst:
172-
case TermKind::ReturnInst:
173-
case TermKind::UnwindInst:
174-
case TermKind::YieldInst:
175-
case TermKind::TryApplyInst:
176-
case TermKind::SwitchValueInst:
177-
case TermKind::SwitchEnumInst:
178-
case TermKind::SwitchEnumAddrInst:
179-
case TermKind::DynamicMethodBranchInst:
180-
case TermKind::CheckedCastBranchInst:
181-
case TermKind::CheckedCastValueBranchInst:
182-
case TermKind::CheckedCastAddrBranchInst:
183-
return true;
184-
}
185-
186-
llvm_unreachable("Unhandled TermKind in switch.");
187-
}
188-
189-
// Visit each one of our predecessor regions and see if any are blocks that can
190-
// use reference counted values. If any of them do, we advance the sequence for
191-
// the pointer and create an insertion point here. This state will be propagated
192-
// into all of our predecessors, allowing us to be conservatively correct in all
193-
// cases.
194-
//
195-
// The key thing to notice is that in general this cannot happen due to
196-
// critical edge splitting. To trigger this, one would need a terminator that
197-
// uses a reference counted value and only has one successor due to critical
198-
// edge splitting. This is just to be conservative when faced with the unknown
199-
// of future changes.
200-
//
201-
// We do not need to worry about loops here, since a loop exit block can only
202-
// have predecessors in the loop itself implying that loop exit blocks at the
203-
// loop region level always have only one predecessor, the loop itself.
204-
void ARCRegionState::processBlockBottomUpPredTerminators(
205-
const LoopRegion *R, AliasAnalysis *AA, LoopRegionFunctionInfo *LRFI,
206-
ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
207-
llvm::TinyPtrVector<SILInstruction *> PredTerminators;
208-
for (unsigned PredID : R->getPreds()) {
209-
auto *PredRegion = LRFI->getRegion(PredID);
210-
if (!PredRegion->isBlock())
211-
continue;
212-
213-
auto *TermInst = PredRegion->getBlock()->getTerminator();
214-
if (!isARCSignificantTerminator(TermInst))
215-
continue;
216-
PredTerminators.push_back(TermInst);
217-
}
218-
219-
for (auto &OtherState : getBottomupStates()) {
220-
// If the other state's value is blotted, skip it.
221-
if (!OtherState.hasValue())
222-
continue;
223-
224-
OtherState->second.updateForPredTerminators(PredTerminators,
225-
SetFactory, AA);
226-
}
227-
}
228-
229159
static bool processBlockBottomUpInsts(
230160
ARCRegionState &State, SILBasicBlock &BB,
231161
BottomUpDataflowRCStateVisitor<ARCRegionState> &DataflowVisitor,
@@ -239,9 +169,9 @@ static bool processBlockBottomUpInsts(
239169
if (II == IE)
240170
return false;
241171

242-
// If II is the terminator, skip it since our terminator was already processed
243-
// in our successors.
244-
if (*II == BB.getTerminator())
172+
// If II is not an arc significant terminator, skip it.
173+
if (*II == BB.getTerminator() &&
174+
!isARCSignificantTerminator(cast<TermInst>(*II)))
245175
++II;
246176

247177
bool NestingDetected = false;
@@ -298,18 +228,10 @@ bool ARCRegionState::processBlockBottomUp(
298228
RCIA, EAFI, *this, FreezeOwnedArgEpilogueReleases, IncToDecStateMap,
299229
SetFactory);
300230

301-
// Visit each non-terminator arc relevant instruction I in BB visited in
302-
// reverse...
231+
// Visit each arc relevant instruction I in BB visited in reverse...
303232
bool NestingDetected =
304233
processBlockBottomUpInsts(*this, BB, DataflowVisitor, AA, SetFactory);
305234

306-
// Now visit each one of our predecessor regions and see if any are blocks
307-
// that can use reference counted values. If any of them do, we advance the
308-
// sequence for the pointer and create an insertion point here. This state
309-
// will be propagated into all of our predecessors, allowing us to be
310-
// conservatively correct in all cases.
311-
processBlockBottomUpPredTerminators(R, AA, LRFI, SetFactory);
312-
313235
return NestingDetected;
314236
}
315237

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//===--- ARCSequenceOptUtils.cpp - ARCSequenceOpt utilities ------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "ARCSequenceOptUtils.h"
14+
15+
using namespace swift;
16+
namespace swift {
17+
bool isARCSignificantTerminator(TermInst *TI) {
18+
switch (TI->getTermKind()) {
19+
case TermKind::UnreachableInst:
20+
// br is a forwarding use for its arguments. It cannot in of itself extend
21+
// the lifetime of an object (just like a phi-node) cannot.
22+
case TermKind::BranchInst:
23+
// A cond_br is a forwarding use for its non-operand arguments in a similar
24+
// way to br. Its operand must be an i1 that has a different lifetime from any
25+
// ref counted object.
26+
case TermKind::CondBranchInst:
27+
return false;
28+
// Be conservative for now. These actually perform some sort of operation
29+
// against the operand or can use the value in some way.
30+
case TermKind::ThrowInst:
31+
case TermKind::ReturnInst:
32+
case TermKind::UnwindInst:
33+
case TermKind::YieldInst:
34+
case TermKind::TryApplyInst:
35+
case TermKind::SwitchValueInst:
36+
case TermKind::SwitchEnumInst:
37+
case TermKind::SwitchEnumAddrInst:
38+
case TermKind::DynamicMethodBranchInst:
39+
case TermKind::CheckedCastBranchInst:
40+
case TermKind::CheckedCastValueBranchInst:
41+
case TermKind::CheckedCastAddrBranchInst:
42+
return true;
43+
}
44+
45+
llvm_unreachable("Unhandled TermKind in switch.");
46+
}
47+
48+
} // end namespace 'swift'
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===--- ARCSequenceOptUtils.h - ARCSequenceOpts utilities ----*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
///
13+
/// Utilities used by the ARCSequenceOpts for analyzing and transforming
14+
/// SILInstructions.
15+
///
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef SWIFT_SILOPTIMIZER_ARC_ARCSEQUENCEOPTUTILS_H
19+
#define SWIFT_SILOPTIMIZER_ARC_ARCSEQUENCEOPTUTILS_H
20+
21+
#include "swift/SIL/SILInstruction.h"
22+
23+
namespace swift {
24+
bool isARCSignificantTerminator(TermInst *TI);
25+
} // end namespace swift
26+
27+
#endif

lib/SILOptimizer/ARC/ARCSequenceOpts.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,8 @@ llvm::cl::opt<bool> EnableLoopARC("enable-loop-arc", llvm::cl::init(false));
4545
// Code Motion
4646
//===----------------------------------------------------------------------===//
4747

48-
// This routine takes in the ARCMatchingSet \p MatchSet and inserts new
49-
// increments, decrements at the insertion points and adds the old increment,
50-
// decrements to the delete list. Sets changed to true if anything was moved or
51-
// deleted.
48+
// This routine takes in the ARCMatchingSet \p MatchSet and adds the increments
49+
// and decrements to the delete list.
5250
void ARCPairingContext::optimizeMatchingSet(
5351
ARCMatchingSet &MatchSet, llvm::SmallVectorImpl<SILInstruction *> &NewInsts,
5452
llvm::SmallVectorImpl<SILInstruction *> &DeadInsts) {
@@ -99,9 +97,6 @@ bool ARCPairingContext::performMatching(
9997
for (auto *I : Set.Decrements)
10098
DecToIncStateMap.erase(I);
10199

102-
// Add the Set to the callback. *NOTE* No instruction destruction can
103-
// happen here since we may remove instructions that are insertion points
104-
// for other instructions.
105100
optimizeMatchingSet(Set, NewInsts, DeadInsts);
106101
}
107102
}

lib/SILOptimizer/ARC/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ target_sources(swiftSILOptimizer PRIVATE
44
ARCMatchingSet.cpp
55
ARCRegionState.cpp
66
ARCSequenceOpts.cpp
7+
ARCSequenceOptUtils.cpp
78
GlobalARCSequenceDataflow.cpp
89
GlobalLoopARCSequenceDataflow.cpp
910
RCStateTransition.cpp

lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.cpp

Lines changed: 10 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#define DEBUG_TYPE "arc-sequence-opts"
1414
#include "GlobalARCSequenceDataflow.h"
1515
#include "ARCBBState.h"
16+
#include "ARCSequenceOptUtils.h"
1617
#include "RCStateTransitionVisitors.h"
1718
#include "swift/SILOptimizer/Analysis/ARCAnalysis.h"
1819
#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h"
@@ -195,39 +196,6 @@ bool ARCSequenceDataflowEvaluator::processTopDown() {
195196
// Bottom Up Dataflow
196197
//===----------------------------------------------------------------------===//
197198

198-
// This is temporary code duplication. This will be removed when Loop ARC is
199-
// finished and Block ARC is removed.
200-
static bool isARCSignificantTerminator(TermInst *TI) {
201-
switch (TI->getTermKind()) {
202-
case TermKind::UnreachableInst:
203-
// br is a forwarding use for its arguments. It cannot in of itself extend
204-
// the lifetime of an object (just like a phi-node) cannot.
205-
case TermKind::BranchInst:
206-
// A cond_br is a forwarding use for its non-operand arguments in a similar
207-
// way to br. Its operand must be an i1 that has a different lifetime from any
208-
// ref counted object.
209-
case TermKind::CondBranchInst:
210-
return false;
211-
// Be conservative for now. These actually perform some sort of operation
212-
// against the operand or can use the value in some way.
213-
case TermKind::ThrowInst:
214-
case TermKind::ReturnInst:
215-
case TermKind::UnwindInst:
216-
case TermKind::YieldInst:
217-
case TermKind::TryApplyInst:
218-
case TermKind::SwitchValueInst:
219-
case TermKind::SwitchEnumInst:
220-
case TermKind::SwitchEnumAddrInst:
221-
case TermKind::DynamicMethodBranchInst:
222-
case TermKind::CheckedCastBranchInst:
223-
case TermKind::CheckedCastValueBranchInst:
224-
case TermKind::CheckedCastAddrBranchInst:
225-
return true;
226-
}
227-
228-
llvm_unreachable("Unhandled TermKind in switch.");
229-
}
230-
231199
/// Analyze a single BB for refcount inc/dec instructions.
232200
///
233201
/// If anything was found it will be added to DecToIncStateMap.
@@ -254,8 +222,15 @@ bool ARCSequenceDataflowEvaluator::processBBBottomUp(
254222
RCIA, EAFI, BBState, FreezeOwnedArgEpilogueReleases, IncToDecStateMap,
255223
SetFactory);
256224

257-
// For each terminator instruction I in BB visited in reverse...
258-
for (auto II = std::next(BB.rbegin()), IE = BB.rend(); II != IE;) {
225+
auto II = BB.rbegin();
226+
if (isa<TermInst>(*II)) {
227+
if (!isARCSignificantTerminator(&cast<TermInst>(*II))) {
228+
II++;
229+
}
230+
}
231+
232+
// For each instruction I in BB visited in reverse...
233+
for (auto IE = BB.rend(); II != IE;) {
259234
SILInstruction &I = *II;
260235
++II;
261236

@@ -292,31 +267,6 @@ bool ARCSequenceDataflowEvaluator::processBBBottomUp(
292267
}
293268
}
294269

295-
// This is ignoring the possibility that we may have a loop with an
296-
// interesting terminator but for which, we are going to clear all state
297-
// (since it is a loop boundary). We may in such a case, be too conservative
298-
// with our other predecessors. Luckily this cannot happen since cond_br is
299-
// the only terminator that allows for critical edges and all other
300-
// "interesting terminators" always having multiple successors. This means
301-
// that this block could not have multiple predecessors since otherwise, the
302-
// edge would be broken.
303-
llvm::TinyPtrVector<SILInstruction *> PredTerminators;
304-
for (SILBasicBlock *PredBB : BB.getPredecessorBlocks()) {
305-
auto *TermInst = PredBB->getTerminator();
306-
if (!isARCSignificantTerminator(TermInst))
307-
continue;
308-
PredTerminators.push_back(TermInst);
309-
}
310-
311-
for (auto &OtherState : BBState.getBottomupStates()) {
312-
// If the other state's value is blotted, skip it.
313-
if (!OtherState.hasValue())
314-
continue;
315-
316-
OtherState->second.updateForPredTerminators(PredTerminators,
317-
SetFactory, AA);
318-
}
319-
320270
return NestingDetected;
321271
}
322272

0 commit comments

Comments
 (0)