-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Fix ARCSequenceOpts bottom up handling of terminators #33504
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
//===--- ARCSequenceOptUtils.cpp - ARCSequenceOpt utilities ------------===// | ||
// | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See https://swift.org/LICENSE.txt for license information | ||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "ARCSequenceOptUtils.h" | ||
|
||
using namespace swift; | ||
namespace swift { | ||
bool isARCSignificantTerminator(TermInst *TI) { | ||
switch (TI->getTermKind()) { | ||
case TermKind::UnreachableInst: | ||
// br is a forwarding use for its arguments. It cannot in of itself extend | ||
// the lifetime of an object (just like a phi-node) cannot. | ||
case TermKind::BranchInst: | ||
// A cond_br is a forwarding use for its non-operand arguments in a similar | ||
// way to br. Its operand must be an i1 that has a different lifetime from any | ||
// ref counted object. | ||
case TermKind::CondBranchInst: | ||
return false; | ||
// Be conservative for now. These actually perform some sort of operation | ||
// against the operand or can use the value in some way. | ||
case TermKind::ThrowInst: | ||
case TermKind::ReturnInst: | ||
case TermKind::UnwindInst: | ||
case TermKind::YieldInst: | ||
case TermKind::TryApplyInst: | ||
case TermKind::SwitchValueInst: | ||
case TermKind::SwitchEnumInst: | ||
case TermKind::SwitchEnumAddrInst: | ||
case TermKind::DynamicMethodBranchInst: | ||
case TermKind::CheckedCastBranchInst: | ||
case TermKind::CheckedCastValueBranchInst: | ||
case TermKind::CheckedCastAddrBranchInst: | ||
return true; | ||
} | ||
|
||
llvm_unreachable("Unhandled TermKind in switch."); | ||
} | ||
|
||
} // end namespace 'swift' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
//===--- ARCSequenceOptUtils.h - ARCSequenceOpts utilities ----*- C++ -*-===// | ||
// | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See https://swift.org/LICENSE.txt for license information | ||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
// | ||
//===----------------------------------------------------------------------===// | ||
/// | ||
/// Utilities used by the ARCSequenceOpts for analyzing and transforming | ||
/// SILInstructions. | ||
/// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef SWIFT_SILOPTIMIZER_ARC_ARCSEQUENCEOPTUTILS_H | ||
#define SWIFT_SILOPTIMIZER_ARC_ARCSEQUENCEOPTUTILS_H | ||
|
||
#include "swift/SIL/SILInstruction.h" | ||
|
||
namespace swift { | ||
bool isARCSignificantTerminator(TermInst *TI); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please do not indent here. See LLVM Style: https://llvm.org/docs/CodingStandards.html#namespace-indentation |
||
} // end namespace swift | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ | |
#define DEBUG_TYPE "arc-sequence-opts" | ||
#include "GlobalARCSequenceDataflow.h" | ||
#include "ARCBBState.h" | ||
#include "ARCSequenceOptUtils.h" | ||
#include "RCStateTransitionVisitors.h" | ||
#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" | ||
#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h" | ||
|
@@ -195,39 +196,6 @@ bool ARCSequenceDataflowEvaluator::processTopDown() { | |
// Bottom Up Dataflow | ||
//===----------------------------------------------------------------------===// | ||
|
||
// This is temporary code duplication. This will be removed when Loop ARC is | ||
// finished and Block ARC is removed. | ||
static bool isARCSignificantTerminator(TermInst *TI) { | ||
switch (TI->getTermKind()) { | ||
case TermKind::UnreachableInst: | ||
// br is a forwarding use for its arguments. It cannot in of itself extend | ||
// the lifetime of an object (just like a phi-node) cannot. | ||
case TermKind::BranchInst: | ||
// A cond_br is a forwarding use for its non-operand arguments in a similar | ||
// way to br. Its operand must be an i1 that has a different lifetime from any | ||
// ref counted object. | ||
case TermKind::CondBranchInst: | ||
return false; | ||
// Be conservative for now. These actually perform some sort of operation | ||
// against the operand or can use the value in some way. | ||
case TermKind::ThrowInst: | ||
case TermKind::ReturnInst: | ||
case TermKind::UnwindInst: | ||
case TermKind::YieldInst: | ||
case TermKind::TryApplyInst: | ||
case TermKind::SwitchValueInst: | ||
case TermKind::SwitchEnumInst: | ||
case TermKind::SwitchEnumAddrInst: | ||
case TermKind::DynamicMethodBranchInst: | ||
case TermKind::CheckedCastBranchInst: | ||
case TermKind::CheckedCastValueBranchInst: | ||
case TermKind::CheckedCastAddrBranchInst: | ||
return true; | ||
} | ||
|
||
llvm_unreachable("Unhandled TermKind in switch."); | ||
} | ||
|
||
/// Analyze a single BB for refcount inc/dec instructions. | ||
/// | ||
/// If anything was found it will be added to DecToIncStateMap. | ||
|
@@ -254,8 +222,15 @@ bool ARCSequenceDataflowEvaluator::processBBBottomUp( | |
RCIA, EAFI, BBState, FreezeOwnedArgEpilogueReleases, IncToDecStateMap, | ||
SetFactory); | ||
|
||
// For each terminator instruction I in BB visited in reverse... | ||
for (auto II = std::next(BB.rbegin()), IE = BB.rend(); II != IE;) { | ||
auto II = BB.rbegin(); | ||
if (isa<TermInst>(*II)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is going to be a TermInst. I would change this to be a cast. |
||
if (!isARCSignificantTerminator(&cast<TermInst>(*II))) { | ||
II++; | ||
} | ||
} | ||
|
||
// For each instruction I in BB visited in reverse... | ||
for (auto IE = BB.rend(); II != IE;) { | ||
SILInstruction &I = *II; | ||
++II; | ||
|
||
|
@@ -292,31 +267,6 @@ bool ARCSequenceDataflowEvaluator::processBBBottomUp( | |
} | ||
} | ||
|
||
// This is ignoring the possibility that we may have a loop with an | ||
// interesting terminator but for which, we are going to clear all state | ||
// (since it is a loop boundary). We may in such a case, be too conservative | ||
// with our other predecessors. Luckily this cannot happen since cond_br is | ||
// the only terminator that allows for critical edges and all other | ||
// "interesting terminators" always having multiple successors. This means | ||
// that this block could not have multiple predecessors since otherwise, the | ||
// edge would be broken. | ||
llvm::TinyPtrVector<SILInstruction *> PredTerminators; | ||
for (SILBasicBlock *PredBB : BB.getPredecessorBlocks()) { | ||
auto *TermInst = PredBB->getTerminator(); | ||
if (!isARCSignificantTerminator(TermInst)) | ||
continue; | ||
PredTerminators.push_back(TermInst); | ||
} | ||
|
||
for (auto &OtherState : BBState.getBottomupStates()) { | ||
// If the other state's value is blotted, skip it. | ||
if (!OtherState.hasValue()) | ||
continue; | ||
|
||
OtherState->second.updateForPredTerminators(PredTerminators, | ||
SetFactory, AA); | ||
} | ||
|
||
return NestingDetected; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@meg-gupta We generally do not create namespaces for stuff like this. Can you instead do
swift::isARCSignificantTerminator
. We are pretty consistent about it in the code-base.