Skip to content

Commit 4180acf

Browse files
committed
Add dynamic alignment optimization for 32-bit SIL.
1 parent c47fe03 commit 4180acf

File tree

2 files changed

+61
-16
lines changed

2 files changed

+61
-16
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,14 +269,25 @@ SILCombiner::optimizeAlignment(PointerToAddressInst *ptrAdrInst) {
269269
if (newAlign && newAlign.valueOrOne() <= oldAlign)
270270
return nullptr;
271271

272-
// Case #1: the pointer is assumed naturally aligned, or Case #2: the
273-
// pointer is assumed to have non-zero alignment greater than it current
274-
// alignment. In either case, rewrite the address alignment with the assumed
275-
// alignment, and bypass the Builtin.assumeAlign.
272+
// Case #1: the pointer is assumed naturally aligned
273+
//
274+
// Or Case #2: the pointer is assumed to have non-zero alignment greater
275+
// than it current alignment.
276+
//
277+
// In either case, rewrite the address alignment with the assumed alignment,
278+
// and bypass the Builtin.assumeAlign.
276279
return Builder.createPointerToAddress(
277280
ptrAdrInst->getLoc(), ptrSrc, ptrAdrInst->getType(),
278281
ptrAdrInst->isStrict(), ptrAdrInst->isInvariant(), newAlign);
279282
}
283+
// Handle possible 32-bit sign-extension.
284+
SILValue extendedAlignment;
285+
if (match(alignOper,
286+
m_ApplyInst(BuiltinValueKind::SExtOrBitCast,
287+
m_ApplyInst(BuiltinValueKind::TruncOrBitCast,
288+
m_SILValue(extendedAlignment))))) {
289+
alignOper = extendedAlignment;
290+
}
280291
MetatypeInst *metatype;
281292
if (match(alignOper,
282293
m_ApplyInst(BuiltinValueKind::Alignof, m_MetatypeInst(metatype)))) {

test/SILOptimizer/sil_combine_casts.sil

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -214,14 +214,14 @@ bb0(%0 : @owned $Optional<Klass>):
214214
//
215215
// Erases the `pointer_to_address` `[align=]` attribute:
216216
//
217-
// CHECK-LABEL: sil @$s8builtins20testNaturalAlignmentyxBp_xmtlF : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
217+
// CHECK-LABEL: sil @test_zero_alignment : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
218218
// CHECK: bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
219219
// CHECK-NOT: integer_literal
220220
// CHECK-NOT: builtin "assumeAlignment"
221221
// CHECK: [[PTR:%.*]] = pointer_to_address %1 : $Builtin.RawPointer to $*T
222222
// CHECK: copy_addr [[PTR]] to [initialization] %0 : $*T
223-
// CHECK-LABEL: } // end sil function '$s8builtins20testNaturalAlignmentyxBp_xmtlF'
224-
sil @$s8builtins20testNaturalAlignmentyxBp_xmtlF : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
223+
// CHECK-LABEL: } // end sil function 'test_zero_alignment'
224+
sil @test_zero_alignment : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
225225
bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
226226
debug_value %1 : $Builtin.RawPointer, let, name "rawPointer", argno 1
227227
debug_value %2 : $@thick T.Type, let, name "_1", argno 2
@@ -234,7 +234,6 @@ bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
234234
return %10 : $()
235235
}
236236

237-
//
238237
// Case #2. Literal nonzero = forced alignment.
239238
//
240239
// %1 = integer_literal $Builtin.Int64, 16
@@ -244,14 +243,14 @@ bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
244243
//
245244
// Promotes the `pointer_to_address` `[align=]` attribute to a higher value.
246245
//
247-
// CHECK-LABEL: sil @$s8builtins18testFixedAlignmentyxBp_xmtlF : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
246+
// CHECK-LABEL: sil @test_nonzero_alignment : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
248247
// CHECK: bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
249248
// CHECK-NOT: integer_literal
250249
// CHECK-NOT: builtin "assumeAlignment"
251250
// CHECK: [[PTR:%.*]] = pointer_to_address %1 : $Builtin.RawPointer to [align=8] $*T
252251
// CHECK: copy_addr [[PTR]] to [initialization] %0 : $*T
253-
// CHECK-LABEL: } // end sil function '$s8builtins18testFixedAlignmentyxBp_xmtlF'
254-
sil @$s8builtins18testFixedAlignmentyxBp_xmtlF : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
252+
// CHECK-LABEL: } // end sil function 'test_nonzero_alignment'
253+
sil @test_nonzero_alignment : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
255254
bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
256255
debug_value %1 : $Builtin.RawPointer, let, name "rawPointer", argno 1
257256
debug_value %2 : $@thick T.Type, let, name "_1", argno 2
@@ -273,23 +272,23 @@ bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
273272
//
274273
// Erases the `pointer_to_address` `[align=]` attribute.
275274
//
276-
// CHECK-LABEL: sil @$s8builtins20testDynamicAlignmentyxBp_xmtlF : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
275+
// CHECK-LABEL: sil @test_dynamic_alignment : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
277276
// CHECK: bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
278277
// CHECK-NOT: metatype
279278
// CHECK-NOT: builtin "alignOf"
280279
// CHECK-NOT: builtin "assumeAlignment"
281280
// CHECK: [[PTR:%.*]] = pointer_to_address %1 : $Builtin.RawPointer to $*T
282281
// CHECK: copy_addr [[PTR]] to [initialization] %0 : $*T
283-
// CHECK-LABEL: } // end sil function '$s8builtins20testDynamicAlignmentyxBp_xmtlF'
284-
sil @$s8builtins20testDynamicAlignmentyxBp_xmtlF : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
282+
// CHECK-LABEL: } // end sil function 'test_dynamic_alignment'
283+
sil @test_dynamic_alignment : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
285284
bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
286285
debug_value %1 : $Builtin.RawPointer, let, name "rawPointer", argno 1
287286
debug_value %2 : $@thick T.Type, let, name "_1", argno 2
288287
%5 = metatype $@thick T.Type
289288
%6 = builtin "alignof"<T>(%5 : $@thick T.Type) : $Builtin.Word
290289
%7 = builtin "sextOrBitCast_Word_Int64"(%6 : $Builtin.Word) : $Builtin.Int64
291-
%8 = struct $Int (%7 : $Builtin.Int64)
292-
debug_value %8 : $Int, let, name "align"
290+
%8 = struct $Int64 (%7 : $Builtin.Int64)
291+
debug_value %8 : $Int64, let, name "align"
293292
%10 = builtin "truncOrBitCast_Int64_Word"(%7 : $Builtin.Int64) : $Builtin.Word
294293
%11 = builtin "assumeAlignment"(%1 : $Builtin.RawPointer, %10 : $Builtin.Word) : $Builtin.RawPointer
295294
debug_value %11 : $Builtin.RawPointer, let, name "alignedPointer"
@@ -298,3 +297,38 @@ bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
298297
%15 = tuple ()
299298
return %15 : $()
300299
}
300+
301+
// Case #3b. Folded dynamic alignment; 32-bit
302+
//
303+
// %1 = builtin "alignof"<T>(%0 : $@thin T.Type) : $Builtin.Word
304+
// %2 = builtin "assumeAlignment"
305+
// (%0 : $Builtin.RawPointer, %1 : $Builtin.Int64) : $Builtin.RawPointer
306+
// %3 = pointer_to_address %2 : $Builtin.RawPointer to [align=1] $*T
307+
//
308+
// Erases the `pointer_to_address` `[align=]` attribute.
309+
//
310+
// CHECK-LABEL: sil @test_dynamic_alignment32 : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
311+
// CHECK: bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
312+
// CHECK-NOT: metatype
313+
// CHECK-NOT: builtin "alignOf"
314+
// CHECK-NOT: builtin "assumeAlignment"
315+
// CHECK: [[PTR:%.*]] = pointer_to_address %1 : $Builtin.RawPointer to $*T
316+
// CHECK: copy_addr [[PTR]] to [initialization] %0 : $*T
317+
// CHECK-LABEL: } // end sil function 'test_dynamic_alignment32'
318+
sil @test_dynamic_alignment32 : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
319+
bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
320+
debug_value %1 : $Builtin.RawPointer, let, name "rawPointer", argno 1
321+
debug_value %2 : $@thick T.Type, let, name "_1", argno 2
322+
%5 = metatype $@thick T.Type
323+
%6 = builtin "alignof"<T>(%5 : $@thick T.Type) : $Builtin.Word
324+
%7 = builtin "truncOrBitCast_Word_Int32"(%6 : $Builtin.Word) : $Builtin.Int32
325+
%8 = struct $Int32 (%7 : $Builtin.Int32)
326+
debug_value %8 : $Int32, let, name "align"
327+
%10 = builtin "sextOrBitCast_Int32_Word"(%7 : $Builtin.Int32) : $Builtin.Word
328+
%11 = builtin "assumeAlignment"(%1 : $Builtin.RawPointer, %10 : $Builtin.Word) : $Builtin.RawPointer
329+
debug_value %11 : $Builtin.RawPointer, let, name "alignedPointer"
330+
%13 = pointer_to_address %11 : $Builtin.RawPointer to [align=1] $*T
331+
copy_addr %13 to [initialization] %0 : $*T
332+
%15 = tuple ()
333+
return %15 : $()
334+
}

0 commit comments

Comments
 (0)