mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
The intent for `@inline(always)` is to act as an optimization control. The user can rely on inlining to happen or the compiler will emit an error message. Because function values can be dynamic (closures, protocol/class lookup) this guarantee can only be upheld for direct function references. In cases where the optimizer can resolve dynamic function values the attribute shall be respected. rdar://148608854
1148 lines
62 KiB
Plaintext
1148 lines
62 KiB
Plaintext
// RUN: %target-sil-opt -sil-print-types -os-log-optimization -enable-sil-verify-all %s 2>&1 | %FileCheck %s
|
|
|
|
// SIL tests for the OSLogOptimization pass which performs compile-time analysis
|
|
// and optimization of os log APIs. This test checks specific aspects of the
|
|
// OSLogOptimization pass on hand-crafted SIL code. The tests here do not depend
|
|
// on any library.
|
|
|
|
import Swift
|
|
import Builtin
|
|
|
|
/// A type that mimics the OSLogInterpolation struct in the tests in this file.
|
|
struct OSLogInterpolationStub {
|
|
var formatString: String
|
|
}
|
|
|
|
/// A type that mimics the OSLogMessage struct in the tests in this file.
|
|
struct OSLogMessageStub {
|
|
var interpolation: OSLogInterpolationStub
|
|
}
|
|
|
|
/// A stub for OSLogMessage.init.
|
|
sil [ossa] [Onone] [_semantics "constant_evaluable"] [_semantics "oslog.message.init_stub"] @oslogMessageInit : $@convention(thin) (@owned String) -> @owned OSLogMessageStub {
|
|
bb0(%0 : @owned $String):
|
|
%1 = struct $OSLogInterpolationStub(%0 : $String)
|
|
%2 = struct $OSLogMessageStub (%1 : $OSLogInterpolationStub)
|
|
return %2 : $OSLogMessageStub
|
|
}
|
|
|
|
// String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
sil [serialized] [heuristic_always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
|
|
/// A function that models the use of a string in some arbitrary way.
|
|
sil @useFormatString: $@convention(thin) (@guaranteed String) -> ()
|
|
|
|
// CHECK-LABEL: @testConstantFoldingOfStructExtract :
|
|
// CHECK-DAG: [[STRINGUSE:%[0-9]+]] = function_ref @useFormatString
|
|
// CHECK-DAG: {{%.*}} = apply [[STRINGUSE]]([[BORROW:%[0-9]+]])
|
|
// CHECK-DAG: [[BORROW]] = begin_borrow [[STRINGCONST:%[0-9]+]]
|
|
// CHECK-DAG: [[STRINGCONST]] = apply [[STRINGINIT:%[0-9]+]]([[LIT:%[0-9]+]], {{%.*}}, {{%.*}}, {{%.*}})
|
|
// CHECK-DAG: [[STRINGINIT]] = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
|
|
// CHECK-DAG: [[LIT]] = string_literal oslog "test message: %lld"
|
|
// CHECK-DAG: destroy_value [[STRINGCONST]] : $String
|
|
sil [ossa] @testConstantFoldingOfStructExtract : $@convention(thin) () -> () {
|
|
bb0:
|
|
// Construct an OSLogMessageStub instance.
|
|
%0 = string_literal utf8 "test message: %lld"
|
|
%1 = integer_literal $Builtin.Word, 18
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = metatype $@thin String.Type
|
|
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = function_ref @oslogMessageInit : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
%7 = apply %6(%5) : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
|
|
// Use the formatString property of OSLogMessageStub which will be constant
|
|
// folded by the OSLogOptimization pass, as checked below.
|
|
%8 = begin_borrow %7 : $OSLogMessageStub
|
|
%9 = struct_extract %8 : $OSLogMessageStub, #OSLogMessageStub.interpolation
|
|
%10 = struct_extract %9 : $OSLogInterpolationStub, #OSLogInterpolationStub.formatString
|
|
%11 = function_ref @useFormatString : $@convention(thin) (@guaranteed String) -> ()
|
|
%12 = apply %11(%10) : $@convention(thin) (@guaranteed String) -> ()
|
|
end_borrow %8 : $OSLogMessageStub
|
|
destroy_value %7 : $OSLogMessageStub
|
|
%13 = tuple ()
|
|
return %13 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @testConstantFoldingOfStructExtractMetatypeArg :
|
|
// CHECK-DAG: [[STRINGUSE:%[0-9]+]] = function_ref @useFormatString
|
|
// CHECK-DAG: {{%.*}} = apply [[STRINGUSE]]([[BORROW:%[0-9]+]])
|
|
// CHECK-DAG: [[BORROW]] = begin_borrow [[STRINGCONST:%[0-9]+]]
|
|
// CHECK-DAG: [[STRINGCONST]] = apply [[STRINGINIT:%[0-9]+]]([[LIT:%[0-9]+]], {{%.*}}, {{%.*}}, {{%.*}})
|
|
// CHECK-DAG: [[STRINGINIT]] = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
|
|
// CHECK-DAG: [[LIT]] = string_literal oslog "test message: %lld"
|
|
// CHECK-DAG: destroy_value [[STRINGCONST]] : $String
|
|
sil [ossa] @testConstantFoldingOfStructExtractMetatypeArg : $@convention(thin) (@thin String.Type) -> () {
|
|
bb0(%0 : $@thin String.Type):
|
|
%1 = string_literal utf8 "test message: %lld"
|
|
%2 = integer_literal $Builtin.Word, 18
|
|
%3 = integer_literal $Builtin.Int1, -1
|
|
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%5 = apply %4(%1, %2, %3, %0) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = function_ref @oslogMessageInit : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
%7 = apply %6(%5) : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
%8 = begin_borrow %7
|
|
%9 = struct_extract %8, #OSLogMessageStub.interpolation
|
|
%10 = struct_extract %9, #OSLogInterpolationStub.formatString
|
|
%11 = function_ref @useFormatString : $@convention(thin) (@guaranteed String) -> ()
|
|
%12 = apply %11(%10) : $@convention(thin) (@guaranteed String) -> ()
|
|
end_borrow %8
|
|
destroy_value %7
|
|
%15 = tuple ()
|
|
return %15
|
|
}
|
|
|
|
/// A function that models the use of a string in some arbitrary way.
|
|
sil @useFormatStringIndirect: $@convention(thin) (@in_guaranteed String) -> ()
|
|
|
|
// CHECK-LABEL: @testBorrowScopeIdentificationUsingStoreBorrow
|
|
sil [ossa] @testBorrowScopeIdentificationUsingStoreBorrow : $@convention(thin) () -> () {
|
|
bb0:
|
|
// Construct an OSLogMessageStub instance.
|
|
%0 = string_literal utf8 "some long message: %llx"
|
|
%1 = integer_literal $Builtin.Word, 23
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = metatype $@thin String.Type
|
|
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = function_ref @oslogMessageInit : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
%7 = apply %6(%5) : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
|
|
// Use the formatString property of OSLogMessageStub which will be constant
|
|
// folded by the OSLogOptimization pass, as checked below.
|
|
%8 = begin_borrow %7 : $OSLogMessageStub
|
|
%9 = struct_extract %8 : $OSLogMessageStub, #OSLogMessageStub.interpolation
|
|
%10 = struct_extract %9 : $OSLogInterpolationStub, #OSLogInterpolationStub.formatString
|
|
%11 = alloc_stack $String
|
|
%12 = store_borrow %10 to %11 : $*String
|
|
%13 = function_ref @useFormatStringIndirect : $@convention(thin) (@in_guaranteed String) -> ()
|
|
%14 = apply %13(%12) : $@convention(thin) (@in_guaranteed String) -> ()
|
|
end_borrow %12 : $*String
|
|
end_borrow %8 : $OSLogMessageStub
|
|
destroy_value %7 : $OSLogMessageStub
|
|
dealloc_stack %11 : $*String
|
|
%15 = tuple ()
|
|
return %15 : $()
|
|
// CHECK: [[LIT:%[0-9]+]] = string_literal oslog "some long message: %llx"
|
|
// CHECK: [[STRINGINIT:%[0-9]+]] = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
|
|
// CHECK: [[STRINGCONST:%[0-9]+]] = apply [[STRINGINIT]]([[LIT]], {{%.*}}, {{%.*}}, {{%.*}})
|
|
// CHECK: [[BORROW:%[0-9]+]] = begin_borrow [[STRINGCONST]]
|
|
// CHECK: store_borrow [[BORROW]] to {{%.*}} : $*String
|
|
// CHECK: [[STRINGUSE:%[0-9]+]] = function_ref @useFormatStringIndirect
|
|
// CHECK: end_borrow [[BORROW]]
|
|
// CHECK: destroy_value [[STRINGCONST]]
|
|
}
|
|
|
|
// CHECK-LABEL: @testConstantFoldingOfOwnedValue
|
|
sil [ossa] @testConstantFoldingOfOwnedValue : $@convention(thin) () -> () {
|
|
bb0:
|
|
// Construct an OSLogMessageStub instance.
|
|
%0 = string_literal utf8 "test message: %lld"
|
|
%1 = integer_literal $Builtin.Word, 18
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = metatype $@thin String.Type
|
|
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = function_ref @oslogMessageInit : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
%7 = apply %6(%5) : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
|
|
// Extract the formatString property of OSLogMessageStub as a owned value and
|
|
// use it. The uses of this owned value should be constant folded.
|
|
%8 = function_ref @extractFormatStringAsOwned : $@convention(thin) (@guaranteed OSLogMessageStub) -> @owned String
|
|
%9 = apply %8(%7) : $@convention(thin) (@guaranteed OSLogMessageStub) -> @owned String
|
|
%11 = function_ref @useFormatString : $@convention(thin) (@guaranteed String) -> ()
|
|
%12 = apply %11(%9) : $@convention(thin) (@guaranteed String) -> ()
|
|
destroy_value %7 : $OSLogMessageStub
|
|
destroy_value %9 : $String
|
|
%13 = tuple ()
|
|
return %13 : $()
|
|
// CHECK-DAG: [[STRINGUSE:%[0-9]+]] = function_ref @useFormatString
|
|
// CHECK-DAG: {{%.*}} = apply [[STRINGUSE]]([[STRINGCONST:%[0-9]+]])
|
|
// CHECK-DAG: [[STRINGCONST]] = apply [[STRINGINIT:%[0-9]+]]([[LIT:%[0-9]+]], {{%.*}}, {{%.*}}, {{%.*}})
|
|
// CHECK-DAG: [[STRINGINIT]] = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
|
|
// CHECK-DAG: [[LIT]] = string_literal oslog "test message: %lld"
|
|
// FIXME: function_ref @extractFormatStringAsOwned will not be removed as of
|
|
// now by OSLogOptimization pass even though it is folded as function calls
|
|
// are not dead-code eliminated.
|
|
}
|
|
|
|
sil [ossa] [_semantics "constant_evaluable"] @extractFormatStringAsOwned : $@convention(thin) (@guaranteed OSLogMessageStub) -> @owned String {
|
|
bb0(%0 : @guaranteed $OSLogMessageStub):
|
|
%1 = struct_extract %0 : $OSLogMessageStub, #OSLogMessageStub.interpolation
|
|
%2 = struct_extract %1 : $OSLogInterpolationStub, #OSLogInterpolationStub.formatString
|
|
%3 = copy_value %2 : $String
|
|
return %3 : $String
|
|
}
|
|
|
|
// CHECK-LABEL: @testConstantFoldingOfDestructureStruct
|
|
sil [ossa] @testConstantFoldingOfDestructureStruct : $@convention(thin) () -> () {
|
|
bb0:
|
|
// Construct an OSLogMessageStub instance.
|
|
%0 = string_literal utf8 "test message: %lld"
|
|
%1 = integer_literal $Builtin.Word, 18
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = metatype $@thin String.Type
|
|
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = function_ref @oslogMessageInit : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
%7 = apply %6(%5) : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
|
|
// Destructure the OSLogMessage instance and use the formatString property
|
|
// which should be constant folded by the OSLogOptimization pass.
|
|
(%8) = destructure_struct %7 : $OSLogMessageStub
|
|
(%9) = destructure_struct %8 : $OSLogInterpolationStub
|
|
%10 = function_ref @useFormatString : $@convention(thin) (@guaranteed String) -> ()
|
|
%11 = apply %10(%9) : $@convention(thin) (@guaranteed String) -> ()
|
|
destroy_value %9 : $String
|
|
%12 = tuple ()
|
|
return %12 : $()
|
|
// CHECK-DAG: [[STRINGUSE:%[0-9]+]] = function_ref @useFormatString
|
|
// CHECK-DAG: {{%.*}} = apply [[STRINGUSE]]([[STRINGCONST:%[0-9]+]])
|
|
// CHECK-DAG: [[STRINGCONST]] = apply [[STRINGINIT:%[0-9]+]]([[LIT:%[0-9]+]], {{%.*}}, {{%.*}}, {{%.*}})
|
|
// CHECK-DAG: [[STRINGINIT]] = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
|
|
// CHECK-DAG: [[LIT]] = string_literal oslog "test message: %lld"
|
|
// CHECK-DAG: destroy_value [[STRINGCONST]] : $String
|
|
}
|
|
|
|
// Test that the OSLogOptimization pass does not fold instructions that define
|
|
// ownership scopes like `begin_borrow`, and `copy_value`.
|
|
// CHECK-LABEL: @testNonFoldingOfOwnershipScopes
|
|
sil [ossa] @testNonFoldingOfOwnershipScopes : $@convention(thin) () -> () {
|
|
bb0:
|
|
// Construct an OSLogMessageStub instance.
|
|
%0 = string_literal utf8 "test message: %lld"
|
|
%1 = integer_literal $Builtin.Word, 18
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = metatype $@thin String.Type
|
|
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = function_ref @oslogMessageInit : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
%7 = apply %6(%5) : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
|
|
// Use the formatString property of OSLogMessageStub which will be constant
|
|
// folded by the OSLogOptimization pass, as checked below.
|
|
%8 = begin_borrow %7 : $OSLogMessageStub
|
|
%9 = struct_extract %8 : $OSLogMessageStub, #OSLogMessageStub.interpolation
|
|
%10 = struct_extract %9 : $OSLogInterpolationStub, #OSLogInterpolationStub.formatString
|
|
%11 = copy_value %10 : $String
|
|
%12 = begin_borrow %11 : $String
|
|
%13 = function_ref @useFormatString : $@convention(thin) (@guaranteed String) -> ()
|
|
%14 = apply %13(%12) : $@convention(thin) (@guaranteed String) -> ()
|
|
end_borrow %12 : $String
|
|
destroy_value %11 : $String
|
|
end_borrow %8 : $OSLogMessageStub
|
|
destroy_value %7 : $OSLogMessageStub
|
|
%15 = tuple ()
|
|
return %15 : $()
|
|
// CHECK-DAG: [[STRINGUSE:%[0-9]+]] = function_ref @useFormatString
|
|
// CHECK-DAG: {{%.*}} = apply [[STRINGUSE]]([[BORROW:%[0-9]+]])
|
|
// CHECK-DAG: [[BORROW]] = begin_borrow [[COPYVAL:%[0-9]+]]
|
|
// CHECK-DAG: [[COPYVAL]] = copy_value [[BORROW2:%[0-9]+]]
|
|
// CHECK-DAG: [[BORROW2]] = begin_borrow [[STRINGCONST:%[0-9]+]]
|
|
// CHECK-DAG: [[STRINGCONST]] = apply [[STRINGINIT:%[0-9]+]]([[LIT:%[0-9]+]], {{%.*}}, {{%.*}}, {{%.*}})
|
|
// CHECK-DAG: [[STRINGINIT]] = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
|
|
// CHECK-DAG: [[LIT]] = string_literal oslog "test message: %lld"
|
|
// CHECK-DAG: destroy_value [[STRINGCONST]] : $String
|
|
}
|
|
|
|
// CHECK-LABEL: @testPostdominatorComputation
|
|
sil [ossa] @testPostdominatorComputation : $@convention(thin) () -> () {
|
|
bb0:
|
|
// Construct an OSLogMessageStub instance.
|
|
%0 = string_literal utf8 "test message: %lld"
|
|
%1 = integer_literal $Builtin.Word, 18
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = metatype $@thin String.Type
|
|
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = function_ref @oslogMessageInit : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
%7 = apply %6(%5) : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
%8 = begin_borrow %7 : $OSLogMessageStub
|
|
%14 = struct_extract %8 : $OSLogMessageStub, #OSLogMessageStub.interpolation
|
|
%15 = struct_extract %14 : $OSLogInterpolationStub, #OSLogInterpolationStub.formatString
|
|
%9 = function_ref @useFormatString : $@convention(thin) (@guaranteed String) -> ()
|
|
cond_br %2, bb1, bb4
|
|
|
|
// Use the OSLogMessage instance along different branches. The following code
|
|
// deliberately uses a borrowed operation like struct_extract so that when it
|
|
// is replaced with a folded value, it needs to be destroyed at the post-
|
|
// dominating points of its uses.
|
|
bb1:
|
|
%10 = struct_extract %8 : $OSLogMessageStub, #OSLogMessageStub.interpolation
|
|
%11 = struct_extract %10 : $OSLogInterpolationStub, #OSLogInterpolationStub.formatString
|
|
cond_br %2, bb2, bb3
|
|
|
|
bb2:
|
|
%12 = apply %9(%11) : $@convention(thin) (@guaranteed String) -> ()
|
|
br bb5
|
|
|
|
bb3:
|
|
%13 = apply %9(%11) : $@convention(thin) (@guaranteed String) -> ()
|
|
br bb5
|
|
|
|
bb4:
|
|
%16 = apply %9(%15) : $@convention(thin) (@guaranteed String) -> ()
|
|
br bb5
|
|
|
|
bb5:
|
|
end_borrow %8 : $OSLogMessageStub
|
|
destroy_value %7 : $OSLogMessageStub
|
|
%17 = tuple ()
|
|
return %17 : $()
|
|
// We must have all string literals at the beginning of the borrowed scope,
|
|
// and destroys of the literals at the end of the borrow scope.
|
|
|
|
// CHECK: [[LIT:%[0-9]+]] = string_literal oslog "test message: %lld"
|
|
// CHECK: [[STRINGINIT:%[0-9]+]] = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
|
|
// CHECK: [[STRINGCONST:%[0-9]+]] = apply [[STRINGINIT]]([[LIT]], {{%.*}}, {{%.*}}, {{%.*}})
|
|
// CHECK: [[BORROW:%[0-9]+]] = begin_borrow [[STRINGCONST]]
|
|
|
|
// CHECK: [[LIT2:%[0-9]+]] = string_literal oslog "test message: %lld"
|
|
// CHECK: [[STRINGINIT2:%[0-9]+]] = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
|
|
// CHECK: [[STRINGCONST2:%[0-9]+]] = apply [[STRINGINIT2]]([[LIT2]], {{%.*}}, {{%.*}}, {{%.*}})
|
|
// CHECK: [[BORROW2:%[0-9]+]] = begin_borrow [[STRINGCONST2]]
|
|
|
|
// CHECK-LABEL: bb1:
|
|
// CHECK-LABEL: bb5:
|
|
// CHECK: end_borrow [[BORROW]]
|
|
// CHECK: destroy_value [[STRINGCONST]] : $String
|
|
// CHECK: end_borrow [[BORROW2]]
|
|
// CHECK: destroy_value [[STRINGCONST2]] : $String
|
|
}
|
|
|
|
// This test checks whether values that are transitively data dependent on
|
|
// an OSLogMessage instance are folded. These can be alive even beyond the
|
|
// lifetime of OSLogMessage.
|
|
// CHECK-LABEL: @testFoldingOfTransitiveDataDependencies
|
|
sil [ossa] @testFoldingOfTransitiveDataDependencies : $@convention(thin) () -> () {
|
|
bb0:
|
|
// Construct an OSLogMessageStub instance.
|
|
%0 = string_literal utf8 "test message: %lld"
|
|
%1 = integer_literal $Builtin.Word, 18
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = metatype $@thin String.Type
|
|
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = function_ref @oslogMessageInit : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
%7 = apply %6(%5) : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
%8 = copy_value %7 : $OSLogMessageStub
|
|
destroy_value %7 : $OSLogMessageStub
|
|
%10 = begin_borrow %8 : $OSLogMessageStub
|
|
%14 = struct_extract %10 : $OSLogMessageStub, #OSLogMessageStub.interpolation
|
|
%15 = struct_extract %14 : $OSLogInterpolationStub, #OSLogInterpolationStub.formatString
|
|
%12 = copy_value %15 : $String
|
|
end_borrow %10 : $OSLogMessageStub
|
|
destroy_value %8 : $OSLogMessageStub
|
|
%9 = function_ref @useFormatString : $@convention(thin) (@guaranteed String) -> ()
|
|
%16 = apply %9(%12) : $@convention(thin) (@guaranteed String) -> ()
|
|
destroy_value %12 : $String
|
|
%17 = tuple ()
|
|
return %17 : $()
|
|
// CHECK-DAG: [[STRINGUSE:%[0-9]+]] = function_ref @useFormatString
|
|
// CHECK-DAG: {{%.*}} = apply [[STRINGUSE]]([[CONSTCOPY:%[0-9]+]])
|
|
// CHECK-DAG: [[CONSTCOPY]] = copy_value [[BORROW:%[0-9]+]]
|
|
// CHECK-DAG: [[BORROW]] = begin_borrow [[STRINGCONST:%[0-9]+]]
|
|
// CHECK-DAG: [[STRINGCONST]] = apply [[STRINGINIT:%[0-9]+]]([[LIT:%[0-9]+]], {{%.*}}, {{%.*}}, {{%.*}})
|
|
// CHECK-DAG: [[STRINGINIT]] = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
|
|
// CHECK-DAG: [[LIT]] = string_literal oslog "test message: %lld"
|
|
// CHECK-DAG: destroy_value [[STRINGCONST]] : $String
|
|
}
|
|
|
|
// Check folding of arrays by the OSLogOptimization pass.
|
|
|
|
/// A simplified stub for OSLogInterpolation type for testing array folding.
|
|
struct OSLogInterpolationArrayStub {
|
|
var arguments: [Int64]
|
|
}
|
|
|
|
/// A simplified stub for OSLogMessage for testing array folding.
|
|
struct OSLogMessageArrayStub {
|
|
var interpolation: OSLogInterpolationArrayStub
|
|
}
|
|
|
|
/// A stub for OSLogMessage.init. The optimization is driven by this function.
|
|
/// This function must take at least one argument which is required by the pass.
|
|
sil [Onone] [_semantics "constant_evaluable"] [_semantics "oslog.message.init_stub"] @oslogMessageArrayStubInit : $@convention(thin) (Builtin.Int1) -> @owned OSLogMessageArrayStub {
|
|
bb0(%0 : $Builtin.Int1):
|
|
// Create an array with elements 99, 98 and 90
|
|
%1 = integer_literal $Builtin.Word, 3
|
|
// function_ref _allocateUninitializedArray<A>(_:)
|
|
%2 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
%3 = apply %2<Int64>(%1) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
%4 = tuple_extract %3 : $(Array<Int64>, Builtin.RawPointer), 0
|
|
%5 = tuple_extract %3 : $(Array<Int64>, Builtin.RawPointer), 1
|
|
%6 = pointer_to_address %5 : $Builtin.RawPointer to [strict] $*Int64
|
|
%7 = integer_literal $Builtin.Int64, 99
|
|
%8 = struct $Int64 (%7 : $Builtin.Int64)
|
|
store %8 to %6 : $*Int64
|
|
%10 = integer_literal $Builtin.Word, 1
|
|
%11 = index_addr %6 : $*Int64, %10 : $Builtin.Word
|
|
%12 = integer_literal $Builtin.Int64, 98
|
|
%13 = struct $Int64 (%12 : $Builtin.Int64)
|
|
store %13 to %11 : $*Int64
|
|
%15 = integer_literal $Builtin.Word, 2
|
|
%16 = index_addr %6 : $*Int64, %15 : $Builtin.Word
|
|
%17 = integer_literal $Builtin.Int64, 90
|
|
%18 = struct $Int64 (%17 : $Builtin.Int64)
|
|
store %18 to %16 : $*Int64
|
|
|
|
// Create an instance of OSLogMessageArrayStub using the above array.
|
|
%20 = struct $OSLogInterpolationArrayStub(%4 : $Array<Int64>)
|
|
%21 = struct $OSLogMessageArrayStub(%20 : $OSLogInterpolationArrayStub)
|
|
return %21 : $OSLogMessageArrayStub
|
|
}
|
|
|
|
// _allocateUninitializedArray<A>(_:)
|
|
sil [serialized] [heuristic_always_inline] [_semantics "array.uninitialized_intrinsic"] @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
|
|
/// A function that models the use of an array.
|
|
sil @useArray: $@convention(thin) (@guaranteed Array<Int64>) -> ()
|
|
|
|
// CHECK-LABEL: @testConstantFoldingOfArray
|
|
sil [ossa] @testConstantFoldingOfArray : $@convention(thin) () -> () {
|
|
bb0:
|
|
// Construct an OSLogMessageArrayStub instance.
|
|
%0 = integer_literal $Builtin.Int1, 1
|
|
%1 = function_ref @oslogMessageArrayStubInit : $@convention(thin) (Builtin.Int1) -> @owned OSLogMessageArrayStub
|
|
%2 = apply %1(%0) : $@convention(thin) (Builtin.Int1) -> @owned OSLogMessageArrayStub
|
|
|
|
// Use the arguments property of OSLogMessageArrayStub which will be constant
|
|
// folded by the OSLogOptimization pass, as checked below.
|
|
%3 = begin_borrow %2 : $OSLogMessageArrayStub
|
|
%4 = struct_extract %3 : $OSLogMessageArrayStub, #OSLogMessageArrayStub.interpolation
|
|
%5 = struct_extract %4 : $OSLogInterpolationArrayStub, #OSLogInterpolationArrayStub.arguments
|
|
%6 = function_ref @useArray : $@convention(thin) (@guaranteed Array<Int64>) -> ()
|
|
%7 = apply %6(%5) : $@convention(thin) (@guaranteed Array<Int64>) -> ()
|
|
end_borrow %3 : $OSLogMessageArrayStub
|
|
destroy_value %2 : $OSLogMessageArrayStub
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
// CHECK: [[ELEM1:%[0-9]+]] = integer_literal $Builtin.Int64, 99
|
|
// CHECK: [[ELEM1INT:%[0-9]+]] = struct $Int64 ([[ELEM1]] : $Builtin.Int64)
|
|
// CHECK: [[ELEM2:%[0-9]+]] = integer_literal $Builtin.Int64, 98
|
|
// CHECK: [[ELEM2INT:%[0-9]+]] = struct $Int64 ([[ELEM2]] : $Builtin.Int64)
|
|
// CHECK: [[ELEM3:%[0-9]+]] = integer_literal $Builtin.Int64, 90
|
|
// CHECK: [[ELEM3INT:%[0-9]+]] = struct $Int64 ([[ELEM3]] : $Builtin.Int64)
|
|
// CHECK: [[NUMELEMS:%[0-9]+]] = integer_literal $Builtin.Word, 3
|
|
// CHECK: [[ALLOCATORREF:%[0-9]+]] = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF
|
|
// CHECK: [[TUPLE:%[0-9]+]] = apply [[ALLOCATORREF]]<Int64>([[NUMELEMS]])
|
|
// CHECK: ([[ARRAY:%[0-9]+]], [[STORAGEPTR:%[0-9]+]]) = destructure_tuple [[TUPLE]]
|
|
// CHECK: [[MDI:%.*]] = mark_dependence [[STORAGEPTR]] : $Builtin.RawPointer on [[ARRAY]] : $Array<Int64>
|
|
// CHECK: [[STORAGEADDR:%[0-9]+]] = pointer_to_address [[MDI]] : $Builtin.RawPointer to [strict] $*Int64
|
|
// CHECK: store [[ELEM1INT]] to [trivial] [[STORAGEADDR]] : $*Int64
|
|
// CHECK: [[INDEX1:%[0-9]+]] = integer_literal $Builtin.Word, 1
|
|
// CHECK: [[INDEXADDR1:%[0-9]+]] = index_addr [[STORAGEADDR]] : $*Int64, [[INDEX1]] : $Builtin.Word
|
|
// CHECK: store [[ELEM2INT]] to [trivial] [[INDEXADDR1]] : $*Int64
|
|
// CHECK: [[INDEX2:%[0-9]+]] = integer_literal $Builtin.Word, 2
|
|
// CHECK: [[INDEXADDR2:%[0-9]+]] = index_addr [[STORAGEADDR]] : $*Int64, [[INDEX2]] : $Builtin.Word
|
|
// CHECK: store [[ELEM3INT]] to [trivial] [[INDEXADDR2]] : $*Int64
|
|
// CHECK: [[FINALIZEREF:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF
|
|
// CHECK: [[FINALIZED:%[0-9]+]] = apply [[FINALIZEREF]]<Int64>([[ARRAY]])
|
|
// CHECK: [[BORROW:%[0-9]+]] = begin_borrow [[FINALIZED]]
|
|
// CHECK: [[USEREF:%[0-9]+]] = function_ref @useArray
|
|
// CHECK: apply [[USEREF]]([[BORROW]])
|
|
// CHECK: end_borrow [[BORROW]]
|
|
// CHECK: destroy_value [[FINALIZED]] : $Array<Int64>
|
|
}
|
|
|
|
/// A stub for OSLogMessage.init. The optimization is driven by this function.
|
|
/// This function must take at least one argument which is required by the pass.
|
|
sil [Onone] [_semantics "constant_evaluable"] [_semantics "oslog.message.init_stub"] @oslogMessageStubEmptyArrayInit : $@convention(thin) (Builtin.Int1) -> @owned OSLogMessageArrayStub {
|
|
bb0(%0 : $Builtin.Int1):
|
|
// Create an empty array
|
|
%1 = integer_literal $Builtin.Word, 0
|
|
// function_ref _allocateUninitializedArray<A>(_:)
|
|
%2 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
%3 = apply %2<Int64>(%1) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
%4 = tuple_extract %3 : $(Array<Int64>, Builtin.RawPointer), 0
|
|
|
|
// Create an instance of OSLogMessageArrayStub using the above array.
|
|
%20 = struct $OSLogInterpolationArrayStub(%4 : $Array<Int64>)
|
|
%21 = struct $OSLogMessageArrayStub(%20 : $OSLogInterpolationArrayStub)
|
|
return %21 : $OSLogMessageArrayStub
|
|
}
|
|
|
|
// CHECK-LABEL: @testConstantFoldingOfEmptyArray
|
|
sil [ossa] @testConstantFoldingOfEmptyArray : $@convention(thin) () -> () {
|
|
bb0:
|
|
// Construct an OSLogMessageArrayStub instance.
|
|
%0 = integer_literal $Builtin.Int1, 1
|
|
%1 = function_ref @oslogMessageStubEmptyArrayInit : $@convention(thin) (Builtin.Int1) -> @owned OSLogMessageArrayStub
|
|
%2 = apply %1(%0) : $@convention(thin) (Builtin.Int1) -> @owned OSLogMessageArrayStub
|
|
|
|
// Use the arguments property of OSLogMessageArrayStub which will be constant
|
|
// folded by the OSLogOptimization pass, as checked below.
|
|
%3 = begin_borrow %2 : $OSLogMessageArrayStub
|
|
%4 = struct_extract %3 : $OSLogMessageArrayStub, #OSLogMessageArrayStub.interpolation
|
|
%5 = struct_extract %4 : $OSLogInterpolationArrayStub, #OSLogInterpolationArrayStub.arguments
|
|
%6 = function_ref @useArray : $@convention(thin) (@guaranteed Array<Int64>) -> ()
|
|
%7 = apply %6(%5) : $@convention(thin) (@guaranteed Array<Int64>) -> ()
|
|
end_borrow %3 : $OSLogMessageArrayStub
|
|
destroy_value %2 : $OSLogMessageArrayStub
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
// CHECK: [[NUMELEMS:%[0-9]+]] = integer_literal $Builtin.Word, 0
|
|
// CHECK: [[ALLOCATORREF:%[0-9]+]] = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF
|
|
// CHECK: [[TUPLE:%[0-9]+]] = apply [[ALLOCATORREF]]<Int64>([[NUMELEMS]])
|
|
// CHECK: ([[ARRAY:%[0-9]+]], [[STORAGEPTR:%[0-9]+]]) = destructure_tuple [[TUPLE]]
|
|
// CHECK: [[BORROW:%[0-9]+]] = begin_borrow [[ARRAY]]
|
|
// CHECK: [[USEREF:%[0-9]+]] = function_ref @useArray
|
|
// CHECK: apply [[USEREF]]([[BORROW]])
|
|
// CHECK: end_borrow [[BORROW]]
|
|
// CHECK: destroy_value [[ARRAY]] : $Array<Int64>
|
|
}
|
|
|
|
/// A simplified stub for OSLogInterpolation type for testing folding of array
|
|
/// of strings.
|
|
struct OSLogInterpolationStringArrayStub {
|
|
var arguments: [String]
|
|
}
|
|
|
|
/// A simplified stub for OSLogMessage for testing folding of array of strings.
|
|
struct OSLogMessageStringArrayStub {
|
|
var interpolation: OSLogInterpolationStringArrayStub
|
|
}
|
|
|
|
/// A stub for OSLogMessage.init. The os_log optimization is driven by this
|
|
/// function. This function must take at least one argument which is required
|
|
/// by the pass.
|
|
sil [Onone] [_semantics "constant_evaluable"] [_semantics "oslog.message.init_stub"] @oslogMessageStringArrayStubInit : $@convention(thin) (@owned String) -> @owned OSLogMessageStringArrayStub {
|
|
bb0(%0 : $String):
|
|
// Create an array with one element "a"
|
|
%1 = integer_literal $Builtin.Word, 1
|
|
// function_ref _allocateUninitializedArray<A>(_:)
|
|
%2 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
%3 = apply %2<String>(%1) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
%4 = tuple_extract %3 : $(Array<String>, Builtin.RawPointer), 0
|
|
%5 = tuple_extract %3 : $(Array<String>, Builtin.RawPointer), 1
|
|
%6 = pointer_to_address %5 : $Builtin.RawPointer to [strict] $*String
|
|
store %0 to %6 : $*String
|
|
|
|
// Create an instance of OSLogMessageArrayStub using the above array.
|
|
%20 = struct $OSLogInterpolationStringArrayStub(%4 : $Array<String>)
|
|
%21 = struct $OSLogMessageStringArrayStub(%20 : $OSLogInterpolationStringArrayStub)
|
|
return %21 : $OSLogMessageStringArrayStub
|
|
}
|
|
|
|
/// A function that models the use of an array.
|
|
sil @useArrayString: $@convention(thin) (@guaranteed Array<String>) -> ()
|
|
|
|
// CHECK-LABEL: @testConstantFoldingOfStringArray
|
|
sil [ossa] @testConstantFoldingOfStringArray : $@convention(thin) () -> () {
|
|
bb0:
|
|
// Construct an OSLogMessageStringArrayStub instance.
|
|
%10 = string_literal utf8 "ab"
|
|
%11 = integer_literal $Builtin.Word, 2
|
|
%12 = integer_literal $Builtin.Int1, -1
|
|
%13 = metatype $@thin String.Type
|
|
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
%14 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%15 = apply %14(%10, %11, %12, %13) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%1 = function_ref @oslogMessageStringArrayStubInit : $@convention(thin) (@owned String) -> @owned OSLogMessageStringArrayStub
|
|
%2 = apply %1(%15) : $@convention(thin) (@owned String) -> @owned OSLogMessageStringArrayStub
|
|
|
|
// Use the arguments property of OSLogMessageStringArrayStub which will be constant
|
|
// folded by the OSLogOptimization pass, as checked below.
|
|
%3 = begin_borrow %2 : $OSLogMessageStringArrayStub
|
|
%4 = struct_extract %3 : $OSLogMessageStringArrayStub, #OSLogMessageStringArrayStub.interpolation
|
|
%5 = struct_extract %4 : $OSLogInterpolationStringArrayStub, #OSLogInterpolationStringArrayStub.arguments
|
|
%6 = function_ref @useArrayString : $@convention(thin) (@guaranteed Array<String>) -> ()
|
|
%7 = apply %6(%5) : $@convention(thin) (@guaranteed Array<String>) -> ()
|
|
end_borrow %3 : $OSLogMessageStringArrayStub
|
|
destroy_value %2 : $OSLogMessageStringArrayStub
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
// The first instance of "ab" will be dead code eliminated.
|
|
// CHECK: [[LIT:%[0-9]+]] = string_literal oslog "ab"
|
|
// CHECK: [[STRINGINIT:%[0-9]+]] = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
|
|
// CHECK: [[STRINGCONST:%[0-9]+]] = apply [[STRINGINIT]]([[LIT]], {{%.*}}, {{%.*}}, {{%.*}})
|
|
// CHECK: [[NUMELEMS:%[0-9]+]] = integer_literal $Builtin.Word, 1
|
|
// CHECK: [[ALLOCATORREF:%[0-9]+]] = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF
|
|
// CHECK: [[TUPLE:%[0-9]+]] = apply [[ALLOCATORREF]]<String>([[NUMELEMS]])
|
|
// CHECK: ([[ARRAY:%[0-9]+]], [[STORAGEPTR:%[0-9]+]]) = destructure_tuple [[TUPLE]]
|
|
// CHECK: [[MDI:%.*]] = mark_dependence [[STORAGEPTR]] : $Builtin.RawPointer on [[ARRAY]] : $Array<String>
|
|
// CHECK: [[STORAGEADDR:%[0-9]+]] = pointer_to_address [[MDI]] : $Builtin.RawPointer to [strict] $*String
|
|
// CHECK: store [[STRINGCONST]] to [init] [[STORAGEADDR]] : $*String
|
|
// CHECK: [[FINALIZEREF:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF
|
|
// CHECK: [[FINALIZED:%[0-9]+]] = apply [[FINALIZEREF]]<String>([[ARRAY]])
|
|
// CHECK: [[BORROW:%[0-9]+]] = begin_borrow [[FINALIZED]]
|
|
// CHECK: [[USEREF:%[0-9]+]] = function_ref @useArrayString
|
|
// CHECK: apply [[USEREF]]([[BORROW]])
|
|
// CHECK: end_borrow [[BORROW]]
|
|
// CHECK: destroy_value [[FINALIZED]] : $Array<String>
|
|
}
|
|
|
|
sil [ossa] [Onone] [_semantics "constant_evaluable"] [_semantics "oslog.message.init_stub"] @oslogMessageArrayInterpolationInit : $@convention(thin) (@owned OSLogInterpolationArrayStub)
|
|
-> @owned OSLogMessageArrayStub {
|
|
bb0(%0 : @owned $OSLogInterpolationArrayStub):
|
|
%1 = struct $OSLogMessageArrayStub(%0 : $OSLogInterpolationArrayStub)
|
|
return %1 : $OSLogMessageArrayStub
|
|
}
|
|
|
|
// CHECK-LABEL: @testNoFoldingOfArrayLiterals
|
|
sil [ossa] @testNoFoldingOfArrayLiterals : $@convention(thin) () -> () {
|
|
bb0:
|
|
// Create an empty array
|
|
%1 = integer_literal $Builtin.Word, 0
|
|
// function_ref _allocateUninitializedArray<A>(_:)
|
|
%2 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
%3 = apply %2<Int64>(%1) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
(%4, %ignore) = destructure_tuple %3 : $(Array<Int64>, Builtin.RawPointer)
|
|
%5 = copy_value %4 : $Array<Int64>
|
|
%6 = struct $OSLogInterpolationArrayStub(%4 : $Array<Int64>)
|
|
%7 = function_ref @oslogMessageArrayInterpolationInit : $@convention(thin) (@owned OSLogInterpolationArrayStub) -> @owned OSLogMessageArrayStub
|
|
%8 = apply %7(%6) : $@convention(thin) (@owned OSLogInterpolationArrayStub) -> @owned OSLogMessageArrayStub
|
|
// Use the array literal.
|
|
%9 = function_ref @useArray : $@convention(thin) (@guaranteed Array<Int64>) -> ()
|
|
%10 = apply %9(%5) : $@convention(thin) (@guaranteed Array<Int64>) -> ()
|
|
destroy_value %5 : $Array<Int64>
|
|
destroy_value %8 : $OSLogMessageArrayStub
|
|
%11 = tuple ()
|
|
return %11 : $()
|
|
// There should be only one instance of _allocateUninitializedArray
|
|
// CHECK-LABEL: function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF
|
|
// CHECK-NOT: function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF
|
|
}
|
|
|
|
// Check folding of closures by the OSLogOptimization pass.
|
|
|
|
/// A simplified stub for OSLogInterpolation type for testing closure folding.
|
|
struct OSLogInterpolationClosureStub {
|
|
var closure: () -> Int32
|
|
}
|
|
|
|
/// A simplified stub for OSLogMessage for testing closure folding.
|
|
struct OSLogMessageClosureStub {
|
|
var interpolation: OSLogInterpolationClosureStub
|
|
}
|
|
|
|
sil private @idFunction : $@convention(thin) (Int32) -> Int32 {
|
|
bb0(%0 : $Int32):
|
|
return %0 : $Int32
|
|
}
|
|
|
|
/// A stub for OSLogMessage.init. The optimization is driven by this function.
|
|
/// This function must take at least one argument which is required by the pass.
|
|
sil [ossa] [Onone] [_semantics "constant_evaluable"] [_semantics "oslog.message.init_stub"] @oslogMessageClosureStubInit : $@convention(thin) (Builtin.Int1) -> @owned OSLogMessageClosureStub {
|
|
bb0(%0 : $Builtin.Int1):
|
|
%7 = integer_literal $Builtin.Int32, 81
|
|
%8 = struct $Int32 (%7 : $Builtin.Int32)
|
|
%9 = function_ref @idFunction : $@convention(thin) (Int32) -> Int32
|
|
%10 = partial_apply [callee_guaranteed] %9(%8) : $@convention(thin) (Int32) -> Int32
|
|
|
|
// Create an instance of OSLogMessageClosureStub using the above closure.
|
|
%20 = struct $OSLogInterpolationClosureStub(%10 : $@callee_guaranteed () -> Int32)
|
|
%21 = struct $OSLogMessageClosureStub(%20 : $OSLogInterpolationClosureStub)
|
|
return %21 : $OSLogMessageClosureStub
|
|
}
|
|
|
|
/// A function that models the use of a closure.
|
|
sil @useClosure: $@convention(thin) (@callee_guaranteed () -> Int32) -> ()
|
|
|
|
// CHECK-LABEL: @testConstantFoldingOfClosure
|
|
sil [ossa] @testConstantFoldingOfClosure : $@convention(thin) () -> () {
|
|
bb0:
|
|
// Construct an OSLogMessageClosureStub instance.
|
|
%0 = integer_literal $Builtin.Int1, 1
|
|
%1 = function_ref @oslogMessageClosureStubInit : $@convention(thin) (Builtin.Int1) -> @owned OSLogMessageClosureStub
|
|
%2 = apply %1(%0) : $@convention(thin) (Builtin.Int1) -> @owned OSLogMessageClosureStub
|
|
|
|
// Use the closure property of OSLogMessageClosureStub which will be constant
|
|
// folded by the OSLogOptimization pass, as checked below.
|
|
%3 = begin_borrow %2 : $OSLogMessageClosureStub
|
|
%4 = struct_extract %3 : $OSLogMessageClosureStub, #OSLogMessageClosureStub.interpolation
|
|
%5 = struct_extract %4 : $OSLogInterpolationClosureStub, #OSLogInterpolationClosureStub.closure
|
|
%6 = function_ref @useClosure : $@convention(thin) (@callee_guaranteed () -> Int32) -> ()
|
|
%7 = apply %6(%5) : $@convention(thin) (@callee_guaranteed () -> Int32) -> ()
|
|
end_borrow %3 : $OSLogMessageClosureStub
|
|
destroy_value %2 : $OSLogMessageClosureStub
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
// CHECK: [[LIT:%[0-9]+]] = integer_literal $Builtin.Int32, 81
|
|
// CHECK: [[INT:%[0-9]+]] = struct $Int32 ([[LIT]] : $Builtin.Int32)
|
|
// CHECK: [[FUNREF:%[0-9]+]] = function_ref @idFunction
|
|
// CHECK: [[CLOSURE:%[0-9]+]] = partial_apply [callee_guaranteed] [[FUNREF]]([[INT]])
|
|
// CHECK: [[BORROW:%[0-9]+]] = begin_borrow [[CLOSURE]] : $@callee_guaranteed () -> Int32
|
|
// CHECK: [[USE:%[0-9]+]] = function_ref @useClosure
|
|
// CHECK: apply [[USE]]([[BORROW]])
|
|
// CHECK: end_borrow [[BORROW]]
|
|
// CHECK: destroy_value [[CLOSURE]]
|
|
}
|
|
|
|
sil private @constantFunction : $@convention(thin) () -> Int32 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int32, 91
|
|
%1 = struct $Int32 (%0 : $Builtin.Int32)
|
|
return %1 : $Int32
|
|
}
|
|
|
|
sil [ossa] [Onone] [_semantics "constant_evaluable"] [_semantics "oslog.message.init_stub"] @oslogMessageThinClosureStubInit : $@convention(thin) (Builtin.Int1) -> @owned OSLogMessageClosureStub {
|
|
bb0(%0 : $Builtin.Int1):
|
|
%7 = integer_literal $Builtin.Int32, 81
|
|
%8 = struct $Int32 (%7 : $Builtin.Int32)
|
|
%9 = function_ref @constantFunction : $@convention(thin) () -> Int32
|
|
%10 = thin_to_thick_function %9 : $@convention(thin) () -> Int32 to $@callee_guaranteed () -> Int32
|
|
// Create an instance of OSLogMessageClosureStub using the above closure.
|
|
%20 = struct $OSLogInterpolationClosureStub(%10 : $@callee_guaranteed () -> Int32)
|
|
%21 = struct $OSLogMessageClosureStub(%20 : $OSLogInterpolationClosureStub)
|
|
return %21 : $OSLogMessageClosureStub
|
|
}
|
|
|
|
// CHECK-LABEL: @testConstantFoldingOfThinClosure
|
|
sil [ossa] @testConstantFoldingOfThinClosure : $@convention(thin) () -> () {
|
|
bb0:
|
|
// Construct an OSLogMessageClosureStub instance.
|
|
%0 = integer_literal $Builtin.Int1, 1
|
|
%1 = function_ref @oslogMessageThinClosureStubInit : $@convention(thin) (Builtin.Int1) -> @owned OSLogMessageClosureStub
|
|
%2 = apply %1(%0) : $@convention(thin) (Builtin.Int1) -> @owned OSLogMessageClosureStub
|
|
|
|
%3 = begin_borrow %2 : $OSLogMessageClosureStub
|
|
%4 = struct_extract %3 : $OSLogMessageClosureStub, #OSLogMessageClosureStub.interpolation
|
|
%5 = struct_extract %4 : $OSLogInterpolationClosureStub, #OSLogInterpolationClosureStub.closure
|
|
%6 = function_ref @useClosure : $@convention(thin) (@callee_guaranteed () -> Int32) -> ()
|
|
%7 = apply %6(%5) : $@convention(thin) (@callee_guaranteed () -> Int32) -> ()
|
|
end_borrow %3 : $OSLogMessageClosureStub
|
|
destroy_value %2 : $OSLogMessageClosureStub
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
// CHECK: [[FUNREF:%[0-9]+]] = function_ref @constantFunction
|
|
// CHECK: [[CLOSURE:%[0-9]+]] = partial_apply [callee_guaranteed] [[FUNREF]]()
|
|
// CHECK: [[BORROW:%[0-9]+]] = begin_borrow [[CLOSURE]] : $@callee_guaranteed () -> Int32
|
|
// CHECK: [[USE:%[0-9]+]] = function_ref @useClosure
|
|
// CHECK: apply [[USE]]([[BORROW]])
|
|
// CHECK: end_borrow [[BORROW]]
|
|
// CHECK: destroy_value [[CLOSURE]]
|
|
}
|
|
|
|
/// A simplified stub for OSLogInterpolation type for testing folding of
|
|
/// closures with non-trivial captures.
|
|
struct OSLogInterpolationStringCapture {
|
|
var closure: () -> String
|
|
}
|
|
|
|
/// A simplified stub for OSLogMessage for testing folding of closures with
|
|
/// non-trivial captures.
|
|
struct OSLogMessageStringCapture {
|
|
var interpolation: OSLogInterpolationStringCapture
|
|
}
|
|
|
|
sil [ossa] @idString : $@convention(thin) (@guaranteed String) -> @owned String {
|
|
bb0(%0 : @guaranteed $String):
|
|
%1 = copy_value %0 : $String
|
|
return %1 : $String
|
|
}
|
|
|
|
sil [ossa] [Onone] [_semantics "constant_evaluable"] [_semantics "oslog.message.init_stub"] @oslogMessageStringCaptureInit : $@convention(thin) (@owned OSLogInterpolationStringCapture)
|
|
-> @owned OSLogMessageStringCapture {
|
|
bb0(%0 : @owned $OSLogInterpolationStringCapture):
|
|
%5 = struct $OSLogMessageStringCapture(%0 : $OSLogInterpolationStringCapture)
|
|
return %5 : $OSLogMessageStringCapture
|
|
}
|
|
|
|
sil @useStringCapture: $@convention(thin) (@callee_guaranteed () -> @owned String) -> ()
|
|
|
|
// CHECK-LABEL: @testConstantFoldingOfStringCapture
|
|
sil [ossa] @testConstantFoldingOfStringCapture : $@convention(thin) (@guaranteed String) -> () {
|
|
bb0(%0 : @guaranteed $String):
|
|
%1 = function_ref @idString : $@convention(thin) (@guaranteed String) -> @owned String
|
|
%2 = copy_value %0 : $String
|
|
%3 = partial_apply [callee_guaranteed] %1(%2) : $@convention(thin) (@guaranteed String) -> @owned String
|
|
%4 = struct $OSLogInterpolationStringCapture(%3 : $@callee_guaranteed () -> @owned String)
|
|
%5 = function_ref @oslogMessageStringCaptureInit : $@convention(thin) (@owned OSLogInterpolationStringCapture) -> @owned OSLogMessageStringCapture
|
|
%6 = apply %5(%4) : $@convention(thin) (@owned OSLogInterpolationStringCapture) -> @owned OSLogMessageStringCapture
|
|
|
|
%13 = begin_borrow %6 : $OSLogMessageStringCapture
|
|
%14 = struct_extract %13 : $OSLogMessageStringCapture, #OSLogMessageStringCapture.interpolation
|
|
%15 = struct_extract %14 : $OSLogInterpolationStringCapture, #OSLogInterpolationStringCapture.closure
|
|
%16 = function_ref @useStringCapture : $@convention(thin) (@callee_guaranteed () -> @owned String) -> ()
|
|
%17 = apply %16(%15) : $@convention(thin) (@callee_guaranteed () -> @owned String) -> ()
|
|
end_borrow %13 : $OSLogMessageStringCapture
|
|
destroy_value %6 : $OSLogMessageStringCapture
|
|
%18 = tuple ()
|
|
return %18 : $()
|
|
// CHECK: [[FUNREF:%[0-9]+]] = function_ref @idString
|
|
// CHECK: [[ORIGCAPTURE:%[0-9]+]] = copy_value %0 : $String
|
|
// CHECK: [[CLOSURE:%[0-9]+]] = partial_apply [callee_guaranteed] [[FUNREF]]([[ORIGCAPTURE]])
|
|
// CHECK: [[CLOSURECOPY:%[0-9]+]] = copy_value [[CLOSURE]]
|
|
// CHECK: [[BORROW:%[0-9]+]] = begin_borrow [[CLOSURECOPY]] : $@callee_guaranteed () -> @owned String
|
|
// CHECK: [[USE:%[0-9]+]] = function_ref @useStringCapture
|
|
// CHECK: apply [[USE]]([[BORROW]])
|
|
// CHECK: end_borrow [[BORROW]]
|
|
// CHECK: destroy_value [[CLOSURECOPY]]
|
|
}
|
|
|
|
sil [ossa] @genericFunction : $@convention(thin) <U, V> (@in_guaranteed U, @in_guaranteed V) -> Int32 {
|
|
bb0(%0 : $*U, %1 : $*V):
|
|
%2 = integer_literal $Builtin.Int32, 99
|
|
%3 = struct $Int32 (%2 : $Builtin.Int32)
|
|
return %3 : $Int32
|
|
}
|
|
|
|
sil [ossa] [Onone] [_semantics "constant_evaluable"] [_semantics "oslog.message.init_stub"] @oslogMessageGenericClosureInit : $@convention(thin) (@owned OSLogInterpolationClosureStub) -> @owned OSLogMessageClosureStub {
|
|
bb0(%0 : @owned $OSLogInterpolationClosureStub):
|
|
%5 = struct $OSLogMessageClosureStub(%0 : $OSLogInterpolationClosureStub)
|
|
return %5 : $OSLogMessageClosureStub
|
|
}
|
|
|
|
// CHECK-LABEL: @testConstantFoldingOfGenericClosure
|
|
sil [ossa] @testConstantFoldingOfGenericClosure : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int1, 1
|
|
%1 = alloc_stack $Int64
|
|
%2 = alloc_stack $Bool
|
|
%3 = struct $Bool (%0 : $Builtin.Int1)
|
|
store %3 to [trivial] %2 : $*Bool
|
|
%4 = integer_literal $Builtin.Int64, 81
|
|
%5 = struct $Int64 (%4 : $Builtin.Int64)
|
|
store %5 to [trivial] %1 : $*Int64
|
|
|
|
%6 = function_ref @genericFunction : $@convention(thin) <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> Int32
|
|
%7 = partial_apply [callee_guaranteed] %6<Int64, Bool>(%1, %2) : $@convention(thin) <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> Int32
|
|
%8 = struct $OSLogInterpolationClosureStub(%7 : $@callee_guaranteed () -> Int32)
|
|
%11 = function_ref @oslogMessageGenericClosureInit : $@convention(thin) (@owned OSLogInterpolationClosureStub) -> @owned OSLogMessageClosureStub
|
|
%12 = apply %11(%8) : $@convention(thin) (@owned OSLogInterpolationClosureStub) -> @owned OSLogMessageClosureStub
|
|
|
|
%13 = begin_borrow %12 : $OSLogMessageClosureStub
|
|
%14 = struct_extract %13 : $OSLogMessageClosureStub, #OSLogMessageClosureStub.interpolation
|
|
%15 = struct_extract %14 : $OSLogInterpolationClosureStub, #OSLogInterpolationClosureStub.closure
|
|
%16 = function_ref @useClosure : $@convention(thin) (@callee_guaranteed () -> Int32) -> ()
|
|
%17 = apply %16(%15) : $@convention(thin) (@callee_guaranteed () -> Int32) -> ()
|
|
end_borrow %13 : $OSLogMessageClosureStub
|
|
destroy_value %12 : $OSLogMessageClosureStub
|
|
dealloc_stack %2 : $*Bool
|
|
dealloc_stack %1 : $*Int64
|
|
%18 = tuple ()
|
|
return %18 : $()
|
|
// The first instance of function_ref @genericFunction will be dead-code eliminated.
|
|
// CHECK: [[FUNREF:%[0-9]+]] = function_ref @genericFunction
|
|
// CHECK: [[CLOSURE:%[0-9]+]] = partial_apply [callee_guaranteed] [[FUNREF]]<Int64, Bool>([[CAPTURE1:%[0-9]+]], [[CAPTURE2:%[0-9]+]])
|
|
// CHECK: [[CLOSURECOPY:%[0-9]+]] = copy_value [[CLOSURE]]
|
|
// CHECK: [[BORROW:%[0-9]+]] = begin_borrow [[CLOSURECOPY]] : $@callee_guaranteed () -> Int32
|
|
// CHECK: [[USE:%[0-9]+]] = function_ref @useClosure
|
|
// CHECK: apply [[USE]]([[BORROW]])
|
|
// CHECK: end_borrow [[BORROW]]
|
|
// CHECK: destroy_value [[CLOSURECOPY]]
|
|
}
|
|
|
|
// Check folding of array of closures. This is essentially the feature needed
|
|
// by the OSLog overlay.
|
|
|
|
/// A simplified stub for OSLogInterpolation type for testing folding of array
|
|
/// of closures.
|
|
struct OSLogInterpolationClosureArrayStub {
|
|
var closure: [() -> Int32]
|
|
}
|
|
|
|
/// A simplified stub for OSLogMessage for testing folding of array of closures.
|
|
struct OSLogMessageClosureArrayStub {
|
|
var interpolation: OSLogInterpolationClosureArrayStub
|
|
}
|
|
|
|
sil private @closure1 : $@convention(thin) (Int32) -> Int32 {
|
|
bb0(%0 : $Int32):
|
|
return %0 : $Int32
|
|
}
|
|
|
|
sil shared [transparent] [reabstraction_thunk] @$ss5Int32VIegd_ABIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> Int32) -> @out Int32 {
|
|
bb0(%0 : $*Int32, %1 : $@callee_guaranteed () -> Int32):
|
|
%2 = apply %1() : $@callee_guaranteed () -> Int32
|
|
store %2 to %0 : $*Int32
|
|
%4 = tuple ()
|
|
return %4 : $()
|
|
}
|
|
|
|
/// A stub for OSLogMessage.init. The optimization is driven by this function.
|
|
/// This function must take at least one argument which is required by the pass.
|
|
sil [Onone] [_semantics "constant_evaluable"] [_semantics "oslog.message.init_stub"] @oslogMessageClosureArrayStubInit : $@convention(thin) (Builtin.Int1) -> @owned OSLogMessageClosureArrayStub {
|
|
bb0(%0 : $Builtin.Int1):
|
|
%1 = integer_literal $Builtin.Word, 1
|
|
// function_ref _allocateUninitializedArray<A>(_:)
|
|
%2 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
%3 = apply %2<() -> Int32>(%1) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
%4 = tuple_extract %3 : $(Array<() -> Int32>, Builtin.RawPointer), 0
|
|
%5 = tuple_extract %3 : $(Array<() -> Int32>, Builtin.RawPointer), 1
|
|
%6 = pointer_to_address %5 : $Builtin.RawPointer to [strict] $*@callee_guaranteed @substituted <A> () -> @out A for <Int32>
|
|
%7 = integer_literal $Builtin.Int32, 81
|
|
%8 = struct $Int32 (%7 : $Builtin.Int32)
|
|
%9 = function_ref @closure1 : $@convention(thin) (Int32) -> Int32
|
|
%10 = partial_apply [callee_guaranteed] %9(%8) : $@convention(thin) (Int32) -> Int32
|
|
%11 = function_ref @$ss5Int32VIegd_ABIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> Int32) -> @out Int32
|
|
%12 = partial_apply [callee_guaranteed] %11(%10) : $@convention(thin) (@guaranteed @callee_guaranteed () -> Int32) -> @out Int32
|
|
%13 = convert_function %12 : $@callee_guaranteed () -> @out Int32 to $@callee_guaranteed @substituted <A> () -> @out A for <Int32>
|
|
store %13 to %6 : $*@callee_guaranteed @substituted <A> () -> @out A for <Int32>
|
|
|
|
// Create an instance of OSLogMessageClosureArrayStub using the above array
|
|
// of closures.
|
|
%20 = struct $OSLogInterpolationClosureArrayStub(%4 : $Array<() -> Int32>)
|
|
%21 = struct $OSLogMessageClosureArrayStub(%20 : $OSLogInterpolationClosureArrayStub)
|
|
return %21 : $OSLogMessageClosureArrayStub
|
|
}
|
|
|
|
/// A function that models the use of an array of closures.
|
|
sil @useClosureArray: $@convention(thin) (@guaranteed Array<() -> Int32>) -> ()
|
|
|
|
// CHECK-LABEL: @testConstantFoldingOfClosureArray
|
|
sil [ossa] @testConstantFoldingOfClosureArray : $@convention(thin) () -> () {
|
|
bb0:
|
|
// Construct an OSLogMessageClosureArrayStub instance.
|
|
%0 = integer_literal $Builtin.Int1, 1
|
|
%1 = function_ref @oslogMessageClosureArrayStubInit : $@convention(thin) (Builtin.Int1) -> @owned OSLogMessageClosureArrayStub
|
|
%2 = apply %1(%0) : $@convention(thin) (Builtin.Int1) -> @owned OSLogMessageClosureArrayStub
|
|
|
|
// Use the arguments property of OSLogMessageClosureArrayStub which will be constant
|
|
// folded by the OSLogOptimization pass, as checked below.
|
|
%3 = begin_borrow %2 : $OSLogMessageClosureArrayStub
|
|
%4 = struct_extract %3 : $OSLogMessageClosureArrayStub, #OSLogMessageClosureArrayStub.interpolation
|
|
%5 = struct_extract %4 : $OSLogInterpolationClosureArrayStub, #OSLogInterpolationClosureArrayStub.closure
|
|
%6 = function_ref @useClosureArray : $@convention(thin) (@guaranteed Array<() -> Int32>) -> ()
|
|
%7 = apply %6(%5) : $@convention(thin) (@guaranteed Array<() -> Int32>) -> ()
|
|
end_borrow %3 : $OSLogMessageClosureArrayStub
|
|
destroy_value %2 : $OSLogMessageClosureArrayStub
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
}
|
|
|
|
// The following tests are for checking dead-code elimination performed by the
|
|
// OSLogOptimization pass.
|
|
|
|
struct OSLogInterpolationDCEStub {
|
|
var formatString: String
|
|
}
|
|
|
|
struct OSLogMessageDCEStub {
|
|
var interpolation: OSLogInterpolationDCEStub
|
|
}
|
|
|
|
sil [ossa] [Onone] [_semantics "constant_evaluable"] [_semantics "oslog.message.init_stub"] @oslogMessageDCEInit : $@convention(thin) (@owned OSLogInterpolationDCEStub) -> @owned OSLogMessageDCEStub {
|
|
bb0(%0 : @owned $OSLogInterpolationDCEStub):
|
|
%1 = struct $OSLogMessageDCEStub (%0 : $OSLogInterpolationDCEStub)
|
|
return %1 : $OSLogMessageDCEStub
|
|
}
|
|
|
|
// CHECK-LABEL: @testDCEOfStructCreation
|
|
sil [ossa] @testDCEOfStructCreation : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = string_literal utf8 "some message"
|
|
%1 = integer_literal $Builtin.Word, 12
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = metatype $@thin String.Type
|
|
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = struct $OSLogInterpolationDCEStub(%5 : $String)
|
|
%7 = copy_value %6 : $OSLogInterpolationDCEStub
|
|
%8 = function_ref @oslogMessageDCEInit : $@convention(thin) (@owned OSLogInterpolationDCEStub) -> @owned OSLogMessageDCEStub
|
|
%9 = apply %8(%7) : $@convention(thin) (@owned OSLogInterpolationDCEStub) -> @owned OSLogMessageDCEStub
|
|
%10 = begin_borrow %9 : $OSLogMessageDCEStub
|
|
end_borrow %10 : $OSLogMessageDCEStub
|
|
destroy_value %9 : $OSLogMessageDCEStub
|
|
destroy_value %6 : $OSLogInterpolationDCEStub
|
|
%13 = tuple ()
|
|
return %13 : $()
|
|
// CHECK: bb0
|
|
// CHECK-NEXT: [[EMPTYTUP:%[0-9]+]] = tuple ()
|
|
// CHECK-NEXT: return [[EMPTYTUP]]
|
|
}
|
|
|
|
sil [ossa] [Onone] [_semantics "constant_evaluable"] [_semantics "oslog.message.init_stub"] @oslogMessageGuaranteedInit : $@convention(thin) (@guaranteed OSLogInterpolationDCEStub) -> @owned OSLogMessageDCEStub {
|
|
bb0(%0 : @guaranteed $OSLogInterpolationDCEStub):
|
|
%2 = copy_value %0 : $OSLogInterpolationDCEStub
|
|
%3 = struct $OSLogMessageDCEStub (%2 : $OSLogInterpolationDCEStub)
|
|
return %3 : $OSLogMessageDCEStub
|
|
}
|
|
|
|
// CHECK-LABEL: @testDCEOfGuaranteedStructCreation
|
|
sil [ossa] @testDCEOfGuaranteedStructCreation : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = string_literal utf8 "some message"
|
|
%1 = integer_literal $Builtin.Word, 12
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = metatype $@thin String.Type
|
|
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = struct $OSLogInterpolationDCEStub(%5 : $String)
|
|
%7 = begin_borrow %6 : $OSLogInterpolationDCEStub
|
|
%9 = function_ref @oslogMessageGuaranteedInit : $@convention(thin) (@guaranteed OSLogInterpolationDCEStub) -> @owned OSLogMessageDCEStub
|
|
%10 = apply %9(%7) : $@convention(thin) (@guaranteed OSLogInterpolationDCEStub) -> @owned OSLogMessageDCEStub
|
|
destroy_value %10 : $OSLogMessageDCEStub
|
|
end_borrow %7 : $OSLogInterpolationDCEStub
|
|
destroy_value %6 : $OSLogInterpolationDCEStub
|
|
%13 = tuple ()
|
|
return %13 : $()
|
|
// CHECK: bb0
|
|
// CHECK-NEXT: [[EMPTYTUP:%[0-9]+]] = tuple ()
|
|
// CHECK-NEXT: return [[EMPTYTUP]]
|
|
}
|
|
|
|
// CHECK-LABEL: @testLifetimeAdjustmentOfDCE
|
|
sil [ossa] @testLifetimeAdjustmentOfDCE : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = string_literal utf8 "some message"
|
|
%1 = integer_literal $Builtin.Word, 12
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = metatype $@thin String.Type
|
|
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = copy_value %5 : $String
|
|
%7 = struct $OSLogInterpolationDCEStub(%5 : $String)
|
|
%8 = function_ref @oslogMessageDCEInit : $@convention(thin) (@owned OSLogInterpolationDCEStub) -> @owned OSLogMessageDCEStub
|
|
%9 = apply %8(%7) : $@convention(thin) (@owned OSLogInterpolationDCEStub) -> @owned OSLogMessageDCEStub
|
|
destroy_value %9 : $OSLogMessageDCEStub
|
|
%11 = function_ref @useFormatString : $@convention(thin) (@guaranteed String) -> ()
|
|
%12 = apply %11(%6) : $@convention(thin) (@guaranteed String) -> ()
|
|
destroy_value %6 : $String
|
|
%13 = tuple ()
|
|
return %13 : $()
|
|
// CHECK: [[STRINGINITREF:%[0-9]+]] = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
|
|
// CHECK: [[STRING:%[0-9]+]] = apply [[STRINGINITREF]](
|
|
// CHECK-NEXT: [[COPY:%[0-9]+]] = copy_value [[STRING]]
|
|
// CHECK-NEXT: destroy_value [[STRING]]
|
|
// CHECK-NOT: OSLogInterpolationDCEStub
|
|
// CHECK-NOT: OSLogMessageDCEStub
|
|
// CHECK: return
|
|
}
|
|
|
|
// Check dead-code elimination of alloc stack used only as inout parameter of a
|
|
// constant evaluable call (that only writes into that inout parameter).
|
|
sil [ossa] [_semantics "constant_evaluable"] @appendInterpolationStub : $@convention(thin) (@inout OSLogInterpolationDCEStub) -> () {
|
|
bb0(%0 : $*OSLogInterpolationDCEStub):
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @testDCEOfAllocStack :
|
|
// CHECK: bb0
|
|
// CHECK-NEXT: [[EMPTYTUP:%[0-9]+]] = tuple ()
|
|
// CHECK-NEXT: return [[EMPTYTUP]]
|
|
sil [ossa] @testDCEOfAllocStack : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = string_literal utf8 "some message"
|
|
%1 = integer_literal $Builtin.Word, 12
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = metatype $@thin String.Type
|
|
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = struct $OSLogInterpolationDCEStub(%5 : $String)
|
|
%7 = alloc_stack $OSLogInterpolationDCEStub
|
|
store %6 to [init] %7 : $*OSLogInterpolationDCEStub
|
|
%8 = function_ref @appendInterpolationStub : $@convention(thin) (@inout OSLogInterpolationDCEStub) -> ()
|
|
%9 = apply %8(%7) : $@convention(thin) (@inout OSLogInterpolationDCEStub) -> ()
|
|
%10 = load [copy] %7 : $*OSLogInterpolationDCEStub
|
|
%11 = function_ref @oslogMessageDCEInit : $@convention(thin) (@owned OSLogInterpolationDCEStub) -> @owned OSLogMessageDCEStub
|
|
%12 = apply %11(%10) : $@convention(thin) (@owned OSLogInterpolationDCEStub) -> @owned OSLogMessageDCEStub
|
|
destroy_value %12 : $OSLogMessageDCEStub
|
|
destroy_addr %7 : $*OSLogInterpolationDCEStub
|
|
dealloc_stack %7 : $*OSLogInterpolationDCEStub
|
|
%13 = tuple ()
|
|
return %13 : $()
|
|
}
|
|
|
|
// Check that dead-code elimination of alloc stack does not happen when there
|
|
// are multiple writable parameters
|
|
sil [ossa] [_semantics "constant_evaluable"] @appendInterpolationStubError : $@convention(thin) (@inout OSLogInterpolationDCEStub, @inout Builtin.Int32) -> () {
|
|
bb0(%0 : $*OSLogInterpolationDCEStub, %1 : $*Builtin.Int32):
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @testNoDCEOfAllocStack
|
|
sil [ossa] @testNoDCEOfAllocStack : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = string_literal utf8 "some message"
|
|
%1 = integer_literal $Builtin.Word, 12
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = metatype $@thin String.Type
|
|
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = struct $OSLogInterpolationDCEStub(%5 : $String)
|
|
%7 = alloc_stack $OSLogInterpolationDCEStub
|
|
store %6 to [init] %7 : $*OSLogInterpolationDCEStub
|
|
%8 = alloc_stack $Builtin.Int32
|
|
%lit = integer_literal $Builtin.Int32, -1
|
|
store %lit to [trivial] %8 : $*Builtin.Int32
|
|
%9 = function_ref @appendInterpolationStubError : $@convention(thin) (@inout OSLogInterpolationDCEStub, @inout Builtin.Int32) -> ()
|
|
%10 = apply %9(%7, %8) : $@convention(thin) (@inout OSLogInterpolationDCEStub, @inout Builtin.Int32) -> ()
|
|
%11 = load [copy] %7 : $*OSLogInterpolationDCEStub
|
|
%12 = function_ref @oslogMessageDCEInit : $@convention(thin) (@owned OSLogInterpolationDCEStub) -> @owned OSLogMessageDCEStub
|
|
%13 = apply %12(%11) : $@convention(thin) (@owned OSLogInterpolationDCEStub) -> @owned OSLogMessageDCEStub
|
|
destroy_value %13 : $OSLogMessageDCEStub
|
|
destroy_addr %7 : $*OSLogInterpolationDCEStub
|
|
dealloc_stack %8 : $*Builtin.Int32
|
|
dealloc_stack %7 : $*OSLogInterpolationDCEStub
|
|
%14 = tuple ()
|
|
return %14 : $()
|
|
// CHECK: bb0
|
|
// CHECK: alloc_stack $OSLogInterpolationDCEStub
|
|
}
|
|
|
|
// The following tests are for checking that constant folding doesn't
|
|
// cause a crash when evaluating the instructions of an animation signpost.
|
|
|
|
// Protocol stub for CVarArgStub
|
|
protocol CVarArgStub {}
|
|
|
|
// Ensure that Int conforms to our protocol stub
|
|
extension Int64 : CVarArgStub {}
|
|
|
|
// _finalizeUninitializedArray<A>(_:)
|
|
sil shared [serialized] [_semantics "array.finalize_intrinsic"] @$ss27_finalizeUninitializedArrayySayxGABnlF : $@convention(thin) <Element> (@owned Array<Element>) -> @owned Array<Element> {
|
|
bb0(%0 : $Array<Element>):
|
|
return %0 : $Array<Element>
|
|
}
|
|
|
|
// Test that the OSLogOptimization does not fail while attempting to
|
|
// fold CVarArgStubs in animation signposts.
|
|
// CHECK-LABEL: @testFoldingOfCVarArgStubConstruction
|
|
sil [ossa] @testFoldingOfCVarArgStubConstruction : $@convention(thin) () -> () {
|
|
bb0:
|
|
// Construct an OSLogMessageStub instance.
|
|
%0 = string_literal utf8 "animation begins here %d"
|
|
%1 = integer_literal $Builtin.Word, 24
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = metatype $@thin String.Type
|
|
// function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // users: %60, %47
|
|
%6 = function_ref @oslogMessageInit : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
%7 = apply %6(%5) : $@convention(thin) (@owned String) -> @owned OSLogMessageStub
|
|
|
|
// Begin chain of evaluated instructions
|
|
%8 = begin_borrow %7 : $OSLogMessageStub
|
|
|
|
// Construct CVarArgStub
|
|
%11 = integer_literal $Builtin.Word, 1
|
|
// function_ref _allocateUninitializedArray<A>(_:)
|
|
%12 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
%13 = apply %12<CVarArgStub>(%11) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
(%14, %15) = destructure_tuple %13 : $(Array<CVarArgStub>, Builtin.RawPointer)
|
|
%16 = pointer_to_address %15 : $Builtin.RawPointer to [strict] $*CVarArgStub
|
|
%17 = integer_literal $Builtin.IntLiteral, 42
|
|
%18 = builtin "s_to_s_checked_trunc_IntLiteral_Int64"(%17 : $Builtin.IntLiteral) : $(Builtin.Int64, Builtin.Int1)
|
|
(%19, %20) = destructure_tuple %18 : $(Builtin.Int64, Builtin.Int1)
|
|
%21 = struct $Int64 (%19 : $Builtin.Int64)
|
|
%22 = init_existential_addr %16 : $*CVarArgStub, $Int64
|
|
store %21 to [trivial] %22 : $*Int64
|
|
// function_ref _finalizeUninitializedArray<A>(_:)
|
|
%23 = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF : $@convention(thin) <τ_0_0> (@owned Array<τ_0_0>) -> @owned Array<τ_0_0>
|
|
%24 = apply %23<CVarArgStub>(%14) : $@convention(thin) <τ_0_0> (@owned Array<τ_0_0>) -> @owned Array<τ_0_0>
|
|
destroy_value %24 : $Array<CVarArgStub>
|
|
|
|
// End chain of evaluated instructions
|
|
end_borrow %8 : $OSLogMessageStub
|
|
destroy_value %7 : $OSLogMessageStub
|
|
%25 = tuple ()
|
|
return %25 : $()
|
|
}
|