Skip to content

Commit f38b78f

Browse files
authored
Merge pull request swiftlang#75120 from meg-gupta/boundscheckpattern2
Update Array bounds check optimization's isIdentifiedUnderlyingArrayObject
2 parents a861331 + 06faf98 commit f38b78f

File tree

4 files changed

+92
-0
lines changed

4 files changed

+92
-0
lines changed

include/swift/SIL/InstructionUtils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ SILValue stripAddressProjections(SILValue V);
6969
/// Look through any projections that transform an address -> an address.
7070
SILValue lookThroughAddressToAddressProjections(SILValue v);
7171

72+
/// Look through address and value projections
73+
SILValue lookThroughAddressAndValueProjections(SILValue V);
74+
7275
/// Return the underlying SILValue after stripping off all aggregate projection
7376
/// instructions.
7477
///

lib/SIL/Utils/InstructionUtils.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,16 @@ SILValue swift::stripValueProjections(SILValue V) {
250250
}
251251
}
252252

253+
SILValue swift::lookThroughAddressAndValueProjections(SILValue V) {
254+
while (true) {
255+
V = stripSinglePredecessorArgs(V);
256+
if (!Projection::isObjectProjection(V) &&
257+
!Projection::isAddressProjection(V))
258+
return V;
259+
V = cast<SingleValueInstruction>(V)->getOperand(0);
260+
}
261+
}
262+
253263
SILValue swift::stripIndexingInsts(SILValue V) {
254264
while (true) {
255265
if (!isa<IndexingInst>(V))

lib/SILOptimizer/LoopTransforms/ArrayBoundsCheckOpts.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,10 @@ static bool isIdentifiedUnderlyingArrayObject(SILValue V) {
177177
if (isa<SILFunctionArgument>(V))
178178
return true;
179179

180+
auto rootVal = lookThroughAddressAndValueProjections(V);
181+
if (rootVal != V) {
182+
return isIdentifiedUnderlyingArrayObject(rootVal);
183+
}
180184
return false;
181185
}
182186

test/SILOptimizer/abcopts.sil

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,3 +1543,78 @@ bb6(%32 : $Builtin.Int32):
15431543
%33 = struct $Int32 (%32 : $Builtin.Int32)
15441544
return %33 : $Int32
15451545
}
1546+
1547+
struct Wrapper {
1548+
let arr: ArrayInt
1549+
}
1550+
1551+
// HOIST-LABEL: sil @hoist_array_in_struct :
1552+
// HOIST: bb0
1553+
// HOIST: [[END:%[0-9]+]] = struct_extract %0 : $Int32, #Int32._value
1554+
// HOIST: [[ZERO:%[0-9]+]] = integer_literal $Builtin.Int32, 0
1555+
// HOIST: [[SE:%[0-9]+]] = struct_element_addr %1 : $*Wrapper, #Wrapper.arr
1556+
// HOIST: cond_br
1557+
1558+
// HOIST: bb1
1559+
// HOIST: [[CB1:%[0-9]+]] = function_ref @checkbounds
1560+
// Check start.
1561+
// HOIST: [[S1:%[0-9]+]] = struct $Int32 ([[ZERO]] : $Builtin.Int32)
1562+
// HOIST: [[L1:%[0-9]+]] = load [[SE]] : $*ArrayInt
1563+
// HOIST: retain_value [[L1]]
1564+
// HOIST: apply [[CB1]]([[S1]], {{.*}}[[L1]])
1565+
1566+
// Check end.
1567+
// HOIST: [[ONE:%[0-9]+]] = integer_literal $Builtin.Int32, 1
1568+
// HOIST: [[SUB1:%[0-9]+]] = builtin "ssub_with_overflow_Int32"([[END]] : ${{.*}}, [[ONE]]
1569+
// HOIST: [[SUB2:%[0-9]+]] = tuple_extract [[SUB1]]
1570+
// HOIST: [[SUB3:%[0-9]+]] = struct $Int32 ([[SUB2]]
1571+
// HOIST: [[L2:%[0-9]+]] = load [[SE]] : $*ArrayInt
1572+
// HOIST: retain_value [[L2]]
1573+
// HOIST: apply [[CB1]]([[SUB3]], {{.*}}[[L2]])
1574+
// HOIST: br bb3
1575+
1576+
// HOIST: bb3
1577+
// HOIST-NOT: cond_fail
1578+
// HOIST-NOT: @checkbounds
1579+
// HOIST: builtin
1580+
// HOIST: builtin
1581+
// HOIST-NOT: builtin
1582+
// HOIST: cond_br {{.*}}, {{.*}}, bb4
1583+
// HOIST: bb4
1584+
// HOIST: br bb3
1585+
1586+
// HOIST: return
1587+
sil @hoist_array_in_struct : $@convention(thin) (Int32, @inout Wrapper) -> Int32 {
1588+
bb0(%0 : $Int32, %1 : $*Wrapper):
1589+
%2 = integer_literal $Builtin.Int1, -1
1590+
%3 = struct $Bool (%2 : $Builtin.Int1)
1591+
%4 = struct_extract %0 : $Int32, #Int32._value
1592+
%5 = integer_literal $Builtin.Int32, 0
1593+
br bb1(%5 : $Builtin.Int32)
1594+
1595+
bb1(%7 : $Builtin.Int32):
1596+
%8 = builtin "cmp_eq_Int32"(%7 : $Builtin.Int32, %4 : $Builtin.Int32) : $Builtin.Int1
1597+
%9 = struct_element_addr %1 : $*Wrapper, #Wrapper.arr
1598+
cond_br %8, bb3, bb2
1599+
1600+
bb2:
1601+
%11 = struct $Int32 (%7 : $Builtin.Int32)
1602+
%12 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
1603+
%13 = load %9 : $*ArrayInt
1604+
%14 = struct_extract %13 : $ArrayInt, #ArrayInt.buffer
1605+
%15 = struct_extract %14 : $ArrayIntBuffer, #ArrayIntBuffer.storage
1606+
retain_value %15 : $Builtin.NativeObject
1607+
%17 = apply %12(%11, %3, %13) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken
1608+
%18 = integer_literal $Builtin.Int32, 1
1609+
%19 = integer_literal $Builtin.Int1, -1
1610+
%20 = builtin "sadd_with_overflow_Int32"(%7 : $Builtin.Int32, %18 : $Builtin.Int32, %19 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
1611+
%21 = tuple_extract %20 : $(Builtin.Int32, Builtin.Int1), 0
1612+
%22 = tuple_extract %20 : $(Builtin.Int32, Builtin.Int1), 1
1613+
cond_fail %22 : $Builtin.Int1, ""
1614+
br bb1(%21 : $Builtin.Int32)
1615+
1616+
bb3:
1617+
%25 = struct $Int32 (%7 : $Builtin.Int32)
1618+
return %25 : $Int32
1619+
}
1620+

0 commit comments

Comments
 (0)