Skip to content

Commit 5666408

Browse files
committed
[semantic-arc] Expand out the infrastructure for disabling/enabling specific opts and use that to add new split up semantic-arc tests.
This split will ensure we are testing only what a specific optimization is doing rather than all together. NOTE: The way I split up the tests is I first split up each of the tests by subject area by hand that I thought were specifically testing one pass. Then any tests where the FileCheck tests started to fail due to us not running the other passes, I put back a copy in the original semantic-arc-opts.sil to ensure we do not regress. Note, the tests that I copied for each of these passes are originally from semantic-arc-opts.sil. I left them there as well so we could see all of the opts together. I also only copied the ones that were testing pass specific functionality.
1 parent 887464b commit 5666408

11 files changed

+2035
-1701
lines changed

lib/SILOptimizer/SemanticARC/BorrowScopeOpts.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,17 @@
1818
///
1919
//===----------------------------------------------------------------------===//
2020

21+
#include "Context.h"
2122
#include "SemanticARCOptVisitor.h"
2223

2324
using namespace swift;
2425
using namespace swift::semanticarc;
2526

2627
bool SemanticARCOptVisitor::visitBeginBorrowInst(BeginBorrowInst *bbi) {
28+
// Quickly check if we are supposed to perform this transformation.
29+
if (!ctx.shouldPerform(ARCTransformKind::RedundantBorrowScopeElimPeephole))
30+
return false;
31+
2732
auto kind = bbi->getOperand().getOwnershipKind();
2833
SmallVector<EndBorrowInst *, 16> endBorrows;
2934
for (auto *op : bbi->getUses()) {

lib/SILOptimizer/SemanticARC/Context.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define SWIFT_SILOPTIMIZER_SEMANTICARC_CONTEXT_H
1515

1616
#include "OwnershipLiveRange.h"
17+
#include "SemanticARCOpts.h"
1718

1819
#include "swift/Basic/BlotSetVector.h"
1920
#include "swift/Basic/FrozenMultiMap.h"
@@ -30,6 +31,7 @@ namespace semanticarc {
3031

3132
struct LLVM_LIBRARY_VISIBILITY Context {
3233
SILFunction &fn;
34+
ARCTransformKind transformKind = ARCTransformKind::All;
3335
Optional<DeadEndBlocks> deadEndBlocks;
3436
ValueLifetimeAnalysis::Frontier lifetimeFrontier;
3537
SmallMultiMapCache<SILValue, Operand *> addressToExhaustiveWriteListCache;
@@ -91,6 +93,25 @@ struct LLVM_LIBRARY_VISIBILITY Context {
9193

9294
void verify() const;
9395

96+
bool shouldPerform(ARCTransformKind testKind) const {
97+
// When asserts are enabled, we allow for specific arc transforms to be
98+
// turned on/off via LLVM args. So check that if we have asserts, perform
99+
// all optimizations otherwise.
100+
#ifndef NDEBUG
101+
if (transformKind == ARCTransformKind::Invalid)
102+
return false;
103+
return bool(testKind & transformKind);
104+
#else
105+
return true;
106+
#endif
107+
}
108+
109+
void reset() {
110+
lifetimeFrontier.clear();
111+
addressToExhaustiveWriteListCache.clear();
112+
joinedOwnedIntroducerToConsumedOperands.reset();
113+
}
114+
94115
private:
95116
static bool
96117
constructCacheValue(SILValue initialValue,

lib/SILOptimizer/SemanticARC/CopyValueOpts.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -517,22 +517,26 @@ bool SemanticARCOptVisitor::tryPerformOwnedCopyValueOptimization(
517517
bool SemanticARCOptVisitor::visitCopyValueInst(CopyValueInst *cvi) {
518518
// If our copy value inst has only destroy_value users, it is a dead live
519519
// range. Try to eliminate them.
520-
if (eliminateDeadLiveRangeCopyValue(cvi)) {
520+
if (ctx.shouldPerform(ARCTransformKind::RedundantCopyValueElimPeephole) &&
521+
eliminateDeadLiveRangeCopyValue(cvi)) {
521522
return true;
522523
}
523524

524525
// Then see if copy_value operand's lifetime ends after our copy_value via a
525526
// destroy_value. If so, we can join their lifetimes.
526-
if (tryJoiningCopyValueLiveRangeWithOperand(cvi)) {
527+
if (ctx.shouldPerform(ARCTransformKind::LifetimeJoiningPeephole) &&
528+
tryJoiningCopyValueLiveRangeWithOperand(cvi)) {
527529
return true;
528530
}
529531

530532
// Then try to perform the guaranteed copy value optimization.
531-
if (performGuaranteedCopyValueOptimization(cvi)) {
533+
if (ctx.shouldPerform(ARCTransformKind::RedundantCopyValueElimPeephole) &&
534+
performGuaranteedCopyValueOptimization(cvi)) {
532535
return true;
533536
}
534537

535-
if (tryPerformOwnedCopyValueOptimization(cvi)) {
538+
if (ctx.shouldPerform(ARCTransformKind::RedundantCopyValueElimPeephole) &&
539+
tryPerformOwnedCopyValueOptimization(cvi)) {
536540
return true;
537541
}
538542

lib/SILOptimizer/SemanticARC/LoadCopyToLoadBorrowOpt.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,10 @@ bool SemanticARCOptVisitor::visitLoadInst(LoadInst *li) {
329329
if (ctx.onlyGuaranteedOpts)
330330
return false;
331331

332+
// If we are not supposed to perform this transform, bail.
333+
if (!ctx.shouldPerform(ARCTransformKind::LoadCopyToLoadBorrowPeephole))
334+
return false;
335+
332336
if (li->getOwnershipQualifier() != LoadOwnershipQualifier::Copy)
333337
return false;
334338

lib/SILOptimizer/SemanticARC/SemanticARCOptVisitor.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@
2323
using namespace swift;
2424
using namespace swift::semanticarc;
2525

26+
bool SemanticARCOptVisitor::optimizeWithoutFixedPoint() {
27+
bool madeChange = false;
28+
29+
// First process the worklist until we reach a fixed point.
30+
madeChange |= processWorklist();
31+
32+
return madeChange;
33+
}
34+
2635
bool SemanticARCOptVisitor::optimize() {
2736
bool madeChange = false;
2837

lib/SILOptimizer/SemanticARC/SemanticARCOptVisitor.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
#include "Context.h"
1717
#include "OwnershipLiveRange.h"
18+
#include "SemanticARCOpts.h"
19+
1820
#include "swift/Basic/BlotSetVector.h"
1921
#include "swift/Basic/FrozenMultiMap.h"
2022
#include "swift/Basic/MultiMapCache.h"
@@ -56,6 +58,12 @@ struct LLVM_LIBRARY_VISIBILITY SemanticARCOptVisitor
5658
eraseAndRAUWSingleValueInstruction(i, value);
5759
})) {}
5860

61+
void reset() {
62+
ctx.reset();
63+
worklist.clear();
64+
visitedSinceLastMutation.clear();
65+
}
66+
5967
DeadEndBlocks &getDeadEndBlocks() { return ctx.getDeadEndBlocks(); }
6068

6169
/// Given a single value instruction, RAUW it with newValue, add newValue to
@@ -192,6 +200,7 @@ struct LLVM_LIBRARY_VISIBILITY SemanticARCOptVisitor
192200

193201
bool processWorklist();
194202
bool optimize();
203+
bool optimizeWithoutFixedPoint();
195204

196205
bool performGuaranteedCopyValueOptimization(CopyValueInst *cvi);
197206
bool eliminateDeadLiveRangeCopyValue(CopyValueInst *cvi);

lib/SILOptimizer/SemanticARC/SemanticARCOpts.cpp

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

1313
#define DEBUG_TYPE "sil-semantic-arc-opts"
1414

15+
#include "SemanticARCOpts.h"
1516
#include "SemanticARCOptVisitor.h"
1617
#include "Transforms.h"
1718

@@ -22,22 +23,24 @@
2223
using namespace swift;
2324
using namespace swift::semanticarc;
2425

25-
namespace {
26-
27-
/// An enum used so that at the command line, we can override
28-
enum class TransformToPerformKind {
29-
Peepholes,
30-
OwnedToGuaranteedPhi,
31-
};
32-
33-
} // anonymous namespace
34-
35-
static llvm::cl::list<TransformToPerformKind> TransformsToPerform(
26+
static llvm::cl::list<ARCTransformKind> TransformsToPerform(
3627
llvm::cl::values(
37-
clEnumValN(TransformToPerformKind::Peepholes,
38-
"sil-semantic-arc-peepholes",
39-
"Perform ARC canonicalizations and peepholes"),
40-
clEnumValN(TransformToPerformKind::OwnedToGuaranteedPhi,
28+
clEnumValN(ARCTransformKind::AllPeepholes,
29+
"sil-semantic-arc-peepholes-all",
30+
"Perform All ARC canonicalizations and peepholes"),
31+
clEnumValN(ARCTransformKind::LoadCopyToLoadBorrowPeephole,
32+
"sil-semantic-arc-peepholes-loadcopy-to-loadborrow",
33+
"Perform the load [copy] to load_borrow peephole"),
34+
clEnumValN(ARCTransformKind::RedundantBorrowScopeElimPeephole,
35+
"sil-semantic-arc-peepholes-redundant-borrowscope-elim",
36+
"Perform the redundant borrow scope elimination peephole"),
37+
clEnumValN(ARCTransformKind::RedundantCopyValueElimPeephole,
38+
"sil-semantic-arc-peepholes-redundant-copyvalue-elim",
39+
"Perform the redundant copy_value peephole"),
40+
clEnumValN(ARCTransformKind::LifetimeJoiningPeephole,
41+
"sil-semantic-arc-peepholes-lifetime-joining",
42+
"Perform the join lifetimes peephole"),
43+
clEnumValN(ARCTransformKind::OwnedToGuaranteedPhi,
4144
"sil-semantic-arc-owned-to-guaranteed-phi",
4245
"Perform Owned To Guaranteed Phi. NOTE: Seeded by peephole "
4346
"optimizer for compile time saving purposes, so run this "
@@ -64,23 +67,52 @@ struct SemanticARCOpts : SILFunctionTransform {
6467
#ifndef NDEBUG
6568
void performCommandlineSpecifiedTransforms(SemanticARCOptVisitor &visitor) {
6669
for (auto transform : TransformsToPerform) {
70+
visitor.ctx.transformKind = transform;
71+
SWIFT_DEFER {
72+
visitor.ctx.transformKind = ARCTransformKind::Invalid;
73+
visitor.reset();
74+
};
6775
switch (transform) {
68-
case TransformToPerformKind::Peepholes:
69-
if (performPeepholes(visitor)) {
76+
case ARCTransformKind::LifetimeJoiningPeephole:
77+
case ARCTransformKind::RedundantCopyValueElimPeephole:
78+
case ARCTransformKind::RedundantBorrowScopeElimPeephole:
79+
case ARCTransformKind::LoadCopyToLoadBorrowPeephole:
80+
case ARCTransformKind::AllPeepholes:
81+
// We never assume we are at fixed point when running these transforms.
82+
if (performPeepholesWithoutFixedPoint(visitor)) {
7083
invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions);
7184
}
7285
continue;
73-
case TransformToPerformKind::OwnedToGuaranteedPhi:
86+
case ARCTransformKind::OwnedToGuaranteedPhi:
7487
if (tryConvertOwnedPhisToGuaranteedPhis(visitor.ctx)) {
7588
invalidateAnalysis(
7689
SILAnalysis::InvalidationKind::BranchesAndInstructions);
7790
}
7891
continue;
92+
case ARCTransformKind::All:
93+
case ARCTransformKind::Invalid:
94+
llvm_unreachable("unsupported option");
7995
}
8096
}
8197
}
8298
#endif
8399

100+
bool performPeepholesWithoutFixedPoint(SemanticARCOptVisitor &visitor) {
101+
// Add all the results of all instructions that we want to visit to the
102+
// worklist.
103+
for (auto &block : *getFunction()) {
104+
for (auto &inst : block) {
105+
if (SemanticARCOptVisitor::shouldVisitInst(&inst)) {
106+
for (SILValue v : inst.getResults()) {
107+
visitor.worklist.insert(v);
108+
}
109+
}
110+
}
111+
}
112+
// Then process the worklist, performing peepholes.
113+
return visitor.optimizeWithoutFixedPoint();
114+
}
115+
84116
bool performPeepholes(SemanticARCOptVisitor &visitor) {
85117
// Add all the results of all instructions that we want to visit to the
86118
// worklist.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//===--- SemanticARCOpts.h ------------------------------------------------===//
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+
#ifndef SWIFT_SILOPTIMIZER_SEMANTICARC_SEMANTICARCOPTS_H
14+
#define SWIFT_SILOPTIMIZER_SEMANTICARC_SEMANTICARCOPTS_H
15+
16+
#include <cstdint>
17+
#include <type_traits>
18+
19+
namespace swift {
20+
namespace semanticarc {
21+
22+
/// An enum used so that at the command line, we can override which transforms
23+
/// we perform.
24+
enum class ARCTransformKind : uint64_t {
25+
Invalid = 0,
26+
OwnedToGuaranteedPhi = 0x1,
27+
LoadCopyToLoadBorrowPeephole = 0x2,
28+
RedundantBorrowScopeElimPeephole = 0x4,
29+
// TODO: Split RedundantCopyValueElimPeephole into more granular categories
30+
// such as dead live range, guaranteed copy_value opt, etc.
31+
RedundantCopyValueElimPeephole = 0x8,
32+
LifetimeJoiningPeephole = 0x10,
33+
34+
AllPeepholes = LoadCopyToLoadBorrowPeephole |
35+
RedundantBorrowScopeElimPeephole |
36+
RedundantCopyValueElimPeephole | LifetimeJoiningPeephole,
37+
All = AllPeepholes | OwnedToGuaranteedPhi,
38+
};
39+
40+
inline ARCTransformKind operator&(ARCTransformKind lhs, ARCTransformKind rhs) {
41+
using UnderlyingTy = std::underlying_type<ARCTransformKind>::type;
42+
return ARCTransformKind(UnderlyingTy(lhs) & UnderlyingTy(rhs));
43+
}
44+
45+
} // namespace semanticarc
46+
} // namespace swift
47+
48+
#endif

0 commit comments

Comments
 (0)