Skip to content

Commit 2016e33

Browse files
committed
Revert today's changes to SIL AliasAnalysis.
This series of commits is reverted because it introduces risk. This type of change requires design discussion and thorough unit testing. Revert "Refactor in alias analysis. NFC" This reverts commit 3390a58. Revert "Update SILArgument alias analysis to make use of the new alias() interface" This reverts commit 5940fcc. Revert "Clean up uneeded SIL in a LIT test" This reverts commit 81ebb56. Revert "Fix LIT test in basic-aa." This reverts commit a553403. Revert "Improve comments in alias analysis" This reverts commit 44ddc5b. Revert "Implement SILArgument and select_enum handling for alias analysis" This reverts commit 23c2579.
1 parent 308f39f commit 2016e33

File tree

3 files changed

+2
-217
lines changed

3 files changed

+2
-217
lines changed

include/swift/SILAnalysis/AliasAnalysis.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,6 @@ class AliasAnalysis : public SILAnalysis {
7070

7171
SideEffectAnalysis *getSideEffectAnalysis() const { return SEA; }
7272

73-
/// Perform alias queries to see if \p V1, \p V2 can refer to the same value.
74-
/// \p V1 and \p V2 may be SILValues with multiple underlying objects. e.g.
75-
/// SILArgument. \returns MayAlias or NoAlias.
76-
AliasResult handleMultiUnderlyingObjectAlias(SILValue V1, SILValue V2);
77-
7873
/// Perform an alias query to see if V1, V2 refer to the same values.
7974
AliasResult alias(SILValue V1, SILValue V2, SILType TBAAType1 = SILType(),
8075
SILType TBAAType2 = SILType());

lib/SILAnalysis/AliasAnalysis.cpp

Lines changed: 2 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@
2828

2929
using namespace swift;
3030

31-
using SILValueSet = llvm::DenseSet<SILValue>;
32-
using SILValueList = llvm::SmallVector<SILValue, 8>;
33-
3431
//===----------------------------------------------------------------------===//
3532
// AA Debugging
3633
//===----------------------------------------------------------------------===//
@@ -102,80 +99,6 @@ llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &OS,
10299
}
103100
}
104101

105-
/// Return true if the SILValue is the result of multiple SILValues, e.g.
106-
/// select_enum, silargument.
107-
static bool isMultiUnderlyingObjectValue(SILValue V) {
108-
if (isa<SelectEnumInst>(V))
109-
return true;
110-
// We are only interested in basic block SILArguments as those are the
111-
// ones we can collect all the possible incoming values.
112-
if (auto *SA = dyn_cast<SILArgument>(V))
113-
if (!SA->isFunctionArg())
114-
return true;
115-
return false;
116-
}
117-
118-
/// Get the first level underlying objects, e.g. in case of select_enum,
119-
/// look to the possible underlying objects from all the cases.
120-
static bool getFirstLevelUnderlyingObjects(SILValue V, SILValueSet &Cache,
121-
SILValueList &WorkList) {
122-
// Look through SILArgument.
123-
if (auto *SA = dyn_cast<SILArgument>(V)) {
124-
SILValueList Args;
125-
bool Succ = SA->getIncomingValues(Args);
126-
// Unable to get SILValue for every predecessor.
127-
if (!Succ)
128-
return false;
129-
for (auto &X : Args) {
130-
if (Cache.count(X))
131-
continue;
132-
// We have not seen this SILValue before.
133-
Cache.insert(X);
134-
WorkList.push_back(X);
135-
}
136-
}
137-
138-
// Look through SelectEnumInst.
139-
if (auto *SE = dyn_cast<SelectEnumInst>(V)) {
140-
unsigned CaseNum = SE->getNumCases();
141-
for (unsigned i = 0; i < CaseNum; ++i) {
142-
SILValue C = SE->getCase(i).second;
143-
if (Cache.count(C))
144-
continue;
145-
// We have not seen this SILValue before.
146-
Cache.insert(C);
147-
WorkList.push_back(C);
148-
}
149-
}
150-
return true;
151-
}
152-
153-
/// Collect all the underlying objects for the given SILValue. Return false
154-
/// if fail to collect all possible underlying objects.
155-
static bool getTransistiveUnderlyingObjects(SILValue V, SILValueList &Objs) {
156-
// Cache keeps track of what has been processed, so that we do not collected
157-
// it again.
158-
SILValueSet Cache;
159-
SILValueList WorkList;
160-
161-
// Start with the given SILValue.
162-
WorkList.push_back(V);
163-
while(!WorkList.empty()) {
164-
SILValue V = WorkList.pop_back_val();
165-
if (isMultiUnderlyingObjectValue(V)) {
166-
if (getFirstLevelUnderlyingObjects(V, Cache, WorkList))
167-
continue;
168-
// Failed to get all possible underlying value, bail out.
169-
return false;
170-
}
171-
172-
// This is single base SILValue.
173-
Objs.push_back(V);
174-
Cache.insert(V);
175-
}
176-
return true;
177-
}
178-
179102
//===----------------------------------------------------------------------===//
180103
// Unequal Base Object AA
181104
//===----------------------------------------------------------------------===//
@@ -604,37 +527,6 @@ static bool typesMayAlias(SILType T1, SILType T2, SILType TBAA1Ty,
604527
// Entry Points
605528
//===----------------------------------------------------------------------===//
606529

607-
AliasAnalysis::AliasResult
608-
AliasAnalysis::handleMultiUnderlyingObjectAlias(SILValue V1, SILValue V2) {
609-
const unsigned AliasQueryLimit = 16;
610-
SmallVector<SILValue, 8> V1Base, V2Base;
611-
// Collect the transistive closure of all the SILValue V1 and V2 can
612-
// point to. If for some reason we can not collect all the possible
613-
// underlying objects, return MayAlias to be conservative.
614-
if (!getTransistiveUnderlyingObjects(V1, V1Base) ||
615-
!getTransistiveUnderlyingObjects(V2, V2Base))
616-
return AliasResult::MayAlias;
617-
618-
// An mxn alias analysis query, bail out if this results in too many
619-
// alias queries.
620-
if (V1Base.size() * V2Base.size() > AliasQueryLimit)
621-
return AliasResult::MayAlias;
622-
623-
// Return MayAlias if any pair does not have a NoAlias relation.
624-
for (auto &M : V1Base) {
625-
for (auto &N : V2Base) {
626-
AliasAnalysis::AliasResult R = aliasInner(M, N, findTypedAccessType(M),
627-
findTypedAccessType(N));
628-
// Return MayAlias whenever we have 1 non-NoAlias pair. This is a
629-
// tradeoff between compilation time and being conservative.
630-
if (R != AliasResult::NoAlias)
631-
return AliasResult::MayAlias;
632-
}
633-
}
634-
635-
return AliasResult::NoAlias;
636-
}
637-
638530
/// The main AA entry point. Performs various analyses on V1, V2 in an attempt
639531
/// to disambiguate the two values.
640532
AliasAnalysis::AliasResult AliasAnalysis::alias(SILValue V1, SILValue V2,
@@ -697,13 +589,8 @@ AliasAnalysis::AliasResult AliasAnalysis::aliasInner(SILValue V1, SILValue V2,
697589
}
698590
}
699591

700-
// Ok, we need to actually compute an Alias Analysis result for V1, V2. First
701-
// find whether V1, V2 potentially have multiple underlying objects.
702-
if (isMultiUnderlyingObjectValue(V1) || isMultiUnderlyingObjectValue(V2))
703-
return handleMultiUnderlyingObjectAlias(V1, V2);
704-
705-
// At this point, V1 and V2 are both single base SIlValues, begin by
706-
// finding the "base" of V1, V2 by stripping off all casts and GEPs.
592+
// Ok, we need to actually compute an Alias Analysis result for V1, V2. Begin
593+
// by finding the "base" of V1, V2 by stripping off all casts and GEPs.
707594
SILValue O1 = getUnderlyingObject(V1);
708595
SILValue O2 = getUnderlyingObject(V2);
709596
DEBUG(llvm::dbgs() << " Underlying V1:" << *O1.getDef());
@@ -739,7 +626,6 @@ AliasAnalysis::AliasResult AliasAnalysis::aliasInner(SILValue V1, SILValue V2,
739626
return AliasResult::MayAlias;
740627
}
741628

742-
743629
/// Check if this is the address of a "let" member.
744630
/// Nobody can write into let members.
745631
bool swift::isLetPointer(SILValue V) {

test/SILAnalysis/basic-aa.sil

Lines changed: 0 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -5,102 +5,6 @@
55
import Builtin
66
import Swift
77

8-
///////////////////////
9-
// Type Declarations //
10-
///////////////////////
11-
12-
struct Int {
13-
var value : Builtin.Int64
14-
}
15-
16-
enum E {
17-
case A
18-
case B
19-
case C
20-
}
21-
22-
class Base { }
23-
24-
class Derived1 : Base {}
25-
26-
class foo {
27-
@sil_stored var a: Int { get set }
28-
deinit
29-
init()
30-
}
31-
32-
sil @foo_init : $@convention(thin) (@thick foo.Type) -> @owned foo
33-
34-
// CHECK-LABEL: silargument_alias_check
35-
36-
// CHECK: PAIR #23.
37-
// CHECK: (0): %1 = alloc_ref $foo
38-
// CHECK: (0): %12 = argument of bb3 : $foo
39-
// CHECK: NoAlias
40-
sil hidden @silargument_alias_check : $@convention(thin) (Bool) -> () {
41-
bb0(%0 : $Bool):
42-
%1 = alloc_ref $foo
43-
%2 = struct_extract %0 : $Bool, #Bool._value // user: %3
44-
cond_br %2, bb1, bb2 // id: %3
45-
46-
bb1: // Preds: bb0
47-
%4 = function_ref @foo_init : $@convention(thin) (@thick foo.Type) -> @owned foo // user: %6
48-
%5 = metatype $@thick foo.Type // user: %6
49-
%6 = apply %4(%5) : $@convention(thin) (@thick foo.Type) -> @owned foo // user: %7
50-
br bb3(%6 : $foo) // id: %7
51-
52-
bb2: // Preds: bb0
53-
%8 = function_ref @foo_init : $@convention(thin) (@thick foo.Type) -> @owned foo // user: %10
54-
%9 = metatype $@thick foo.Type // user: %10
55-
%10 = apply %8(%9) : $@convention(thin) (@thick foo.Type) -> @owned foo // user: %11
56-
br bb3(%10 : $foo) // id: %11
57-
58-
bb3(%12 : $foo): // Preds: bb1 bb2
59-
strong_retain %12 : $foo // id: %13
60-
%14 = integer_literal $Builtin.Int64, 12 // user: %15
61-
%15 = struct $Int (%14 : $Builtin.Int64) // user: %17
62-
%16 = ref_element_addr %12 : $foo, #foo.a // user: %17
63-
store %15 to %16 : $*Int // id: %17
64-
%18 = tuple ()
65-
strong_release %12 : $foo // id: %19
66-
strong_release %12 : $foo // id: %20
67-
%21 = tuple () // user: %22
68-
return %21 : $() // id: %22
69-
}
70-
71-
72-
// CHECK-LABEL: select_enum_and_local_object
73-
74-
// CHECK: PAIR #61.
75-
// CHECK: (0): %5 = alloc_ref $Base
76-
// CHECK: (0): %6 = select_enum %0 : $E, case #E.A!enumelt: %1, default %2 : $Base
77-
// CHECK: NoAlias
78-
sil @select_enum_and_local_object : $@convention(thin) (E, @owned Base, @owned Base, @owned Base, @owned Base) -> Builtin.Int64 {
79-
bb0(%0 : $E, %1 : $Base, %2 : $Base, %3 : $Base, %4 : $Base):
80-
%5 = alloc_ref $Base
81-
%6 = select_enum %0 : $E, case #E.A!enumelt: %1, default %2 : $Base // user: %7
82-
checked_cast_br %6 : $Base to $Derived1, bb1, bb2 // id: %7
83-
84-
bb1(%8 : $Derived1): // Preds: bb0
85-
%9 = integer_literal $Builtin.Int64, 1 // user: %10
86-
br bb5(%9 : $Builtin.Int64) // id: %10
87-
88-
bb2: // Preds: bb0
89-
%11 = select_enum %0 : $E, case #E.B!enumelt: %3, default %4 : $Base // user: %12
90-
checked_cast_br %11 : $Base to $Derived1, bb3, bb4 // id: %12
91-
92-
bb3(%13 : $Derived1): // Preds: bb2
93-
%14 = integer_literal $Builtin.Int64, 2 // user: %15
94-
br bb5(%14 : $Builtin.Int64) // id: %15
95-
96-
bb4: // Preds: bb2
97-
%16 = integer_literal $Builtin.Int64, 3 // user: %17
98-
br bb5(%16 : $Builtin.Int64) // id: %17
99-
100-
bb5(%18 : $Builtin.Int64): // Preds: bb1 bb3 bb4
101-
return %18 : $Builtin.Int64 // id: %19
102-
}
103-
1048
// Address Arguments don't alias if they are arguments to the first BB.
1059
//
10610
// CHECK-LABEL: @address_args_dont_alias_in_first_bb

0 commit comments

Comments
 (0)