Skip to content

Commit c938e19

Browse files
author
David Ungar
authored
---
yaml --- r: 294653 b: refs/heads/tensorflow c: fe9b48c h: refs/heads/master i: 294651: 50416c0
1 parent 741eb61 commit c938e19

File tree

9 files changed

+300
-14
lines changed

9 files changed

+300
-14
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ refs/tags/swift-DEVELOPMENT-SNAPSHOT-2018-04-25-a: 22f738a831d43aff2b9c9773bcb65
816816
refs/tags/swift-DEVELOPMENT-SNAPSHOT-2018-05-08-a: 7d98cc16689baba5c8a3b90a9329bdcc1a12b4e9
817817
refs/heads/cherr42: a566ad54b073c2c56ac0a705d0a5bed9743135a5
818818
"refs/heads/codable_test_comment_fix": fc8f6824f7f347e1e8db55bff62db385c5728b5a
819-
refs/heads/tensorflow: 71228603b3a00d6b838517312a58f08498ab6f5d
819+
refs/heads/tensorflow: fe9b48c28d827afa9d6d7dbc39cc3d0b6d1f5004
820820
refs/tags/swift-4.1-DEVELOPMENT-SNAPSHOT-2018-05-11-a: 8126fd7a652e2f70ad6d76505239e34fb2ef3e1a
821821
refs/tags/swift-4.1-DEVELOPMENT-SNAPSHOT-2018-05-12-a: b3fd3dd84df6717f2e2e9df58c6d7e99fed57086
822822
refs/tags/swift-4.1-DEVELOPMENT-SNAPSHOT-2018-05-13-a: 71135119579039dc321c5f65d870050fe36efda2

branches/tensorflow/lib/IDE/REPLCodeCompletion.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "swift/IDE/REPLCodeCompletion.h"
1818
#include "swift/AST/ASTContext.h"
19+
#include "swift/AST/DiagnosticSuppression.h"
1920
#include "swift/AST/Module.h"
2021
#include "swift/Basic/LLVM.h"
2122
#include "swift/Basic/SourceManager.h"
@@ -193,7 +194,7 @@ doCodeCompletion(SourceFile &SF, StringRef EnteredCode, unsigned *BufferID,
193194
CodeCompletionCallbacksFactory *CompletionCallbacksFactory) {
194195
// Temporarily disable printing the diagnostics.
195196
ASTContext &Ctx = SF.getASTContext();
196-
DiagnosticTransaction DelayedDiags(Ctx.Diags);
197+
DiagnosticSuppression SuppressedDiags(Ctx.Diags);
197198

198199
std::string AugmentedCode = EnteredCode.str();
199200
AugmentedCode += '\0';
@@ -222,7 +223,10 @@ doCodeCompletion(SourceFile &SF, StringRef EnteredCode, unsigned *BufferID,
222223
// Now we are done with code completion. Remove the declarations we
223224
// temporarily inserted.
224225
SF.Decls.resize(OriginalDeclCount);
225-
DelayedDiags.abort();
226+
227+
// Reset the error state because it's only relevant to the code that we just
228+
// processed, which now gets thrown away.
229+
Ctx.Diags.resetHadAnyError();
226230
}
227231

228232
void REPLCompletions::populate(SourceFile &SF, StringRef EnteredCode) {

branches/tensorflow/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,7 @@ static void fixupReferenceCounts(
8888
DeadEndBlocks deadEndBlocks(pai->getFunction());
8989
SmallVector<SILBasicBlock *, 4> leakingBlocks;
9090

91-
auto errorBehavior =
92-
ownership::ErrorBehaviorKind::ReturnFalseOnLeakAssertOtherwise;
91+
auto errorBehavior = ownership::ErrorBehaviorKind::ReturnFalse;
9392

9493
// Add a copy of each non-address type capture argument to lifetime extend the
9594
// captured argument over at least the inlined function and till the end of a
@@ -142,21 +141,33 @@ static void fixupReferenceCounts(
142141
auto error =
143142
valueHasLinearLifetime(copy, {applySite}, {}, visitedBlocks,
144143
deadEndBlocks, errorBehavior, &leakingBlocks);
145-
if (error.getFoundError()) {
144+
if (error.getFoundLeak()) {
146145
while (!leakingBlocks.empty()) {
147146
auto *leakingBlock = leakingBlocks.pop_back_val();
148147
auto loc = RegularLocation::getAutoGeneratedLocation();
149148
SILBuilderWithScope builder(leakingBlock->begin());
149+
if (hasOwnership) {
150+
builder.createEndBorrow(loc, argument);
151+
}
150152
builder.emitDestroyValueOperation(loc, copy);
151153
}
152154
}
153155

154-
insertAfterApply(applySite, [&](SILBasicBlock::iterator iter) {
155-
if (hasOwnership) {
156-
SILBuilderWithScope(iter).createEndBorrow(loc, argument);
157-
}
158-
SILBuilderWithScope(iter).emitDestroyValueOperation(loc, copy);
159-
});
156+
// If we found an over consume it means that our value is consumed within
157+
// the loop. That means our leak code will have lifetime extended the
158+
// value over the loop. So we should /not/ insert a destroy after the
159+
// apply site. In contrast, if we do not have an over consume, we must
160+
// have been compensating for uses in the top of a diamond and need to
161+
// insert a destroy after the apply since the leak will just cover the
162+
// other path.
163+
if (!error.getFoundOverConsume()) {
164+
insertAfterApply(applySite, [&](SILBasicBlock::iterator iter) {
165+
if (hasOwnership) {
166+
SILBuilderWithScope(iter).createEndBorrow(loc, argument);
167+
}
168+
SILBuilderWithScope(iter).emitDestroyValueOperation(loc, copy);
169+
});
170+
}
160171
v = argument;
161172
break;
162173
}

branches/tensorflow/lib/SILOptimizer/Utils/ConstantFolding.cpp

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ APInt swift::constantFoldCast(APInt val, const BuiltinInfo &BI) {
113113
SrcTy->castTo<BuiltinIntegerType>()->getGreatestWidth();
114114
uint32_t DestBitWidth =
115115
DestTy->castTo<BuiltinIntegerType>()->getGreatestWidth();
116-
116+
117117
APInt CastResV;
118118
if (SrcBitWidth == DestBitWidth) {
119119
return val;
@@ -1761,7 +1761,46 @@ ConstantFolder::processWorkList() {
17611761
FoldedUsers.insert(TI);
17621762
}
17631763

1764-
// We were able to fold, so all users should use the new folded value.
1764+
// We were able to fold, so all users should use the new folded
1765+
// value. If we don't have any such users, continue.
1766+
//
1767+
// NOTE: The reason why we check if our result has uses is that if
1768+
// User is a MultipleValueInstruction an infinite loop can result if
1769+
// User has a result different than the one at Index that we can not
1770+
// constant fold and if C's defining instruction is an aggregate that
1771+
// defines an operand of I.
1772+
//
1773+
// As an elucidating example, consider the following SIL:
1774+
//
1775+
// %w = integer_literal $Builtin.Word, 1
1776+
// %0 = struct $Int (%w : $Builtin.Word) (*)
1777+
// %1 = apply %f() : $@convention(thin) () -> @owned Klass
1778+
// %2 = tuple (%0 : $Int, %1 : $Klass)
1779+
// (%3, %4) = destructure_tuple %2 : $(Int, Klass)
1780+
// store %4 to [init] %mem2: %*Klass
1781+
//
1782+
// Without this check, we would infinite loop by processing our
1783+
// worklist as follows:
1784+
//
1785+
// 1. We visit %w and add %0 to the worklist unconditionally since it
1786+
// is a StructInst.
1787+
//
1788+
// 2. We visit %0 and then since %2 is a tuple, we add %2 to the
1789+
// worklist unconditionally.
1790+
//
1791+
// 3. We visit %2 and see that it has a destructure_tuple user. We see
1792+
// that we can simplify %3 -> %0, but cannot simplify %4. This
1793+
// means that if we just assume success if we can RAUW %3 without
1794+
// checking if we will actually replace anything, we will add %0's
1795+
// defining instruction (*) to the worklist. Q.E.D.
1796+
//
1797+
// In contrast, if we realize that RAUWing %3 does nothing and skip
1798+
// it, we exit the worklist as expected.
1799+
SILValue r = User->getResult(Index);
1800+
if (r->use_empty())
1801+
continue;
1802+
1803+
// Otherwise, do the RAUW.
17651804
User->getResult(Index)->replaceAllUsesWith(C);
17661805

17671806
// The new constant could be further folded now, add it to the
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// While running completion on this, the typechecker produces a diagnostic and
2+
// an AST with an error type. If the ASTVerifier ran on the AST with the error
3+
// type, then it would fail. This test verifies that the ASTVerifier does not
4+
// run on ASTs with error types produced by completion requests.
5+
6+
// RUN: %target-swift-ide-test -repl-code-completion -source-filename=%s
7+
8+
let bar: NotARealType = 0; ba
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-run-simple-swift
2+
3+
func test(reportError: ((String) -> (Void))? = nil) {
4+
let reportError = reportError ?? { error in
5+
print(error)
6+
}
7+
8+
for _ in 0..<1 {
9+
reportError("foo bar baz")
10+
}
11+
}
12+
13+
func main() {
14+
test { error in
15+
print(error)
16+
}
17+
}
18+
19+
main()

branches/tensorflow/test/SILOptimizer/constant_propagation_ownership.sil

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
import Swift
55
import Builtin
66

7+
//////////////////
8+
// Declarations //
9+
//////////////////
10+
711
struct UInt {
812
var value: Builtin.Word
913
}
@@ -20,6 +24,15 @@ struct UInt64 {
2024
var value: Builtin.Int64
2125
}
2226

27+
class Klass {}
28+
29+
sil @klass_allocator : $@convention(method) (@thick Klass.Type) -> @owned Klass
30+
sil @generic_user : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
31+
32+
///////////
33+
// Tests //
34+
///////////
35+
2336
sil [ossa] @count_leading_zeros_corner_case : $@convention(thin) () -> Builtin.Int64 {
2437
bb0:
2538
%zero64 = integer_literal $Builtin.Int64, 0
@@ -1132,3 +1145,39 @@ bb2(%8 : @owned $AnSubObject):
11321145
bb3(%11 : $Builtin.Int1):
11331146
return %11 : $Builtin.Int1
11341147
}
1148+
1149+
sil [ossa] @do_not_infinite_loop : $@convention(thin) () -> () {
1150+
bb0:
1151+
%0 = integer_literal $Builtin.Word, 1
1152+
%1 = struct $Int (%0 : $Builtin.Word)
1153+
%2 = metatype $@thick Klass.Type
1154+
%3 = function_ref @klass_allocator : $@convention(method) (@thick Klass.Type) -> @owned Klass
1155+
%4 = apply %3(%2) : $@convention(method) (@thick Klass.Type) -> @owned Klass
1156+
// We can never in constant propagation forward %5 today since we would need
1157+
// to know that we are eliminting all of its uses. But the pass doesn't
1158+
// understand that today and so destroy_value %5 in bb2 stops our ability to
1159+
// optimize.
1160+
%5 = tuple (%1 : $Int, %4 : $Klass)
1161+
cond_br undef, bb1, bb2
1162+
1163+
bb1:
1164+
%6 = alloc_stack $(Int, Klass)
1165+
%7 = tuple_element_addr %6 : $*(Int, Klass), 0
1166+
%8 = tuple_element_addr %6 : $*(Int, Klass), 1
1167+
(%9, %10) = destructure_tuple %5 : $(Int, Klass)
1168+
store %1 to [trivial] %7 : $*Int
1169+
store %10 to [init] %8 : $*Klass
1170+
%13 = function_ref @generic_user : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
1171+
%14 = apply %13<(Int, Klass)>(%6) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
1172+
destroy_addr %6 : $*(Int, Klass)
1173+
dealloc_stack %6 : $*(Int, Klass)
1174+
br bb3
1175+
1176+
bb2:
1177+
destroy_value %5 : $(Int, Klass)
1178+
br bb3
1179+
1180+
bb3:
1181+
%9999 = tuple()
1182+
return %9999 : $()
1183+
}

branches/tensorflow/test/SILOptimizer/mandatory_inlining.sil

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,3 +1200,143 @@ bb0(%0: $C):
12001200
%tuple = tuple()
12011201
return %tuple : $()
12021202
}
1203+
1204+
// CHECK-LABEL: sil @test_apply_pai_in_loop : $@convention(thin) (@guaranteed C) -> () {
1205+
// CHECK: bb0([[ARG:%.*]] : $C):
1206+
// CHECK-NEXT: strong_retain [[ARG]]
1207+
// CHECK-NEXT: strong_retain [[ARG]]
1208+
// CHECK-NEXT: br bb1
1209+
//
1210+
// CHECK: bb1:
1211+
// CHECK-NEXT: cond_br undef, bb2, bb3
1212+
//
1213+
// CHECK: bb2:
1214+
// CHECK-NEXT: function_ref use_c
1215+
// CHECK-NEXT: [[FUNC:%.*]] = function_ref @use_c
1216+
// CHECK-NEXT: apply [[FUNC]]([[ARG]])
1217+
// CHECK-NEXT: tuple
1218+
// CHECK-NEXT: br bb1
1219+
//
1220+
// CHECK: bb3:
1221+
// CHECK-NEXT: strong_release [[ARG]]
1222+
// CHECK-NEXT: strong_release [[ARG]]
1223+
// CHECK-NEXT: tuple
1224+
// CHECK-NEXT: return
1225+
// CHECK-NEXT: } // end sil function 'test_apply_pai_in_loop'
1226+
sil @test_apply_pai_in_loop : $@convention(thin) (@guaranteed C) -> () {
1227+
bb0(%0: $C):
1228+
strong_retain %0 : $C
1229+
%closure_fun = function_ref @guaranteed_closure_func : $@convention(thin) (@guaranteed C) -> ()
1230+
%closure = partial_apply [callee_guaranteed] %closure_fun(%0) : $@convention(thin) (@guaranteed C) -> ()
1231+
br bb1
1232+
1233+
bb1:
1234+
cond_br undef, bb2, bb3
1235+
1236+
bb2:
1237+
apply %closure() : $@callee_guaranteed () -> ()
1238+
br bb1
1239+
1240+
bb3:
1241+
strong_release %0: $C
1242+
%tuple = tuple()
1243+
return %tuple : $()
1244+
}
1245+
1246+
// CHECK-LABEL: sil @test_apply_pai_in_loop_with_diamond : $@convention(thin) (@guaranteed C) -> () {
1247+
// CHECK: bb0([[ARG:%.*]] : $C):
1248+
// CHECK-NEXT: strong_retain [[ARG]]
1249+
// CHECK-NEXT: strong_retain [[ARG]]
1250+
// CHECK-NEXT: strong_retain [[ARG]]
1251+
// CHECK-NEXT: cond_br undef, bb1, bb4
1252+
//
1253+
// CHECK: bb1:
1254+
// CHECK-NEXT: function_ref use_c
1255+
// CHECK-NEXT: [[FUNC:%.*]] = function_ref @use_c
1256+
// CHECK-NEXT: apply [[FUNC]]([[ARG]])
1257+
// CHECK-NEXT: tuple
1258+
// CHECK-NEXT: cond_br undef, bb2, bb3
1259+
//
1260+
// CHECK: bb2:
1261+
// CHECK-NEXT: function_ref use_c
1262+
// CHECK-NEXT: [[FUNC:%.*]] = function_ref @use_c
1263+
// CHECK-NEXT: apply [[FUNC]]([[ARG]])
1264+
// CHECK-NEXT: tuple
1265+
// CHECK-NEXT: br bb1
1266+
//
1267+
// CHECK: bb3:
1268+
// CHECK-NEXT: br bb1
1269+
//
1270+
// CHECK: bb4:
1271+
// CHECK-NEXT: strong_release [[ARG]]
1272+
// CHECK-NEXT: strong_release [[ARG]]
1273+
// CHECK-NEXT: strong_release [[ARG]]
1274+
// CHECK-NEXT: tuple
1275+
// CHECK-NEXT: return
1276+
// CHECK-NEXT: } // end sil function 'test_apply_pai_in_loop_with_diamond'
1277+
sil @test_apply_pai_in_loop_with_diamond : $@convention(thin) (@guaranteed C) -> () {
1278+
bb0(%0: $C):
1279+
strong_retain %0 : $C
1280+
%closure_fun = function_ref @guaranteed_closure_func : $@convention(thin) (@guaranteed C) -> ()
1281+
%closure = partial_apply [callee_guaranteed] %closure_fun(%0) : $@convention(thin) (@guaranteed C) -> ()
1282+
cond_br undef, bb2, bb5
1283+
1284+
bb2:
1285+
apply %closure() : $@callee_guaranteed () -> ()
1286+
cond_br undef, bb3, bb4
1287+
1288+
bb3:
1289+
apply %closure() : $@callee_guaranteed () -> ()
1290+
br bb2
1291+
1292+
bb4:
1293+
br bb2
1294+
1295+
bb5:
1296+
strong_release %0: $C
1297+
%tuple = tuple()
1298+
return %tuple : $()
1299+
}
1300+
1301+
// CHECK-LABEL: sil @test_apply_pai_in_diamond : $@convention(thin) (@guaranteed C) -> () {
1302+
// CHECK: bb0([[ARG:%.*]] : $C):
1303+
// CHECK-NEXT: strong_retain [[ARG]]
1304+
// CHECK-NEXT: strong_retain [[ARG]]
1305+
// CHECK-NEXT: cond_br undef, bb1, bb2
1306+
//
1307+
// CHECK: bb1:
1308+
// CHECK-NEXT: strong_release [[ARG]]
1309+
// CHECK-NEXT: br bb3
1310+
//
1311+
// CHECK: bb2:
1312+
// CHECK-NEXT: function_ref use_c
1313+
// CHECK-NEXT: [[FUNC:%.*]] = function_ref @use_c
1314+
// CHECK-NEXT: apply [[FUNC]]([[ARG]])
1315+
// CHECK-NEXT: tuple
1316+
// CHECK-NEXT: strong_release [[ARG]]
1317+
// CHECK-NEXT: br bb3
1318+
//
1319+
// CHECK: bb3:
1320+
// CHECK-NEXT: strong_release [[ARG]]
1321+
// CHECK-NEXT: tuple
1322+
// CHECK-NEXT: return
1323+
// CHECK-NEXT: } // end sil function 'test_apply_pai_in_diamond'
1324+
sil @test_apply_pai_in_diamond : $@convention(thin) (@guaranteed C) -> () {
1325+
bb0(%0: $C):
1326+
strong_retain %0 : $C
1327+
%closure_fun = function_ref @guaranteed_closure_func : $@convention(thin) (@guaranteed C) -> ()
1328+
%closure = partial_apply [callee_guaranteed] %closure_fun(%0) : $@convention(thin) (@guaranteed C) -> ()
1329+
cond_br undef, bb1, bb2
1330+
1331+
bb1:
1332+
br bb3
1333+
1334+
bb2:
1335+
apply %closure() : $@callee_guaranteed () -> ()
1336+
br bb3
1337+
1338+
bb3:
1339+
strong_release %0: $C
1340+
%tuple = tuple()
1341+
return %tuple : $()
1342+
}

0 commit comments

Comments
 (0)