Files
swift-mirror/test/SILOptimizer/OSLogMandatoryOptTest.sil
Michael Gottesman 7b55cbc669 [sil-optimizer] Make InstructionDeleter and related APIs to use an InstModCallback instead of a notification callback.
I recently have been running into the issue that many of these APIs perform the
deletion operation themselves and notify the caller it is going to delete
instead of allowing the caller to specify how the instruction is deleted. This
causes interesting semantic issues (see the loop in deleteInstruction I
simplified) and breaks composition since many parts of the optimizer use
InstModCallbacks for this purpose.

To fix this, I added a notify will be deleted construct to InstModCallback. In a
similar way to the rest of it, if the notify is not set, we do not call any code
implying that we should have good predictable performance in loops since we will
always skip the function call.

I also changed InstModCallback::deleteInst() to notify before deleting so we
have a default safe behavior. All previous use sites of this API do not care
about being notified and the only new use sites of this API are in
InstructionDeleter that perform special notification behavior (it notifies for
certain sets of instructions it is going to delete before it deletes any of
them). To work around this, I added a bool to deleteInst to control this
behavior and defaulted to notifying. This should ensure that all other use sites
still compose correctly.
2021-04-26 16:37:43 -07:00

1114 lines
60 KiB
Plaintext

// RUN: %target-sil-opt -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] [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 utf8 "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 : $()
}
/// 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
store_borrow %10 to %11 : $*String
%13 = function_ref @useFormatStringIndirect : $@convention(thin) (@in_guaranteed String) -> ()
%14 = apply %13(%11) : $@convention(thin) (@in_guaranteed String) -> ()
end_borrow %8 : $OSLogMessageStub
destroy_value %7 : $OSLogMessageStub
dealloc_stack %11 : $*String
%15 = tuple ()
return %15 : $()
// CHECK: [[LIT:%[0-9]+]] = string_literal utf8 "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 utf8 "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 utf8 "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 utf8 "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 destorys of the literals at the end of the borrow scope.
// CHECK: [[LIT:%[0-9]+]] = string_literal utf8 "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 utf8 "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 utf8 "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] [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: [[STORAGEADDR:%[0-9]+]] = pointer_to_address [[STORAGEPTR]] : $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 utf8 "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: [[STORAGEADDR:%[0-9]+]] = pointer_to_address [[STORAGEPTR]] : $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 evaulating 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_external [serialized] [_semantics "array.finalize_intrinsic"] @$ss27_finalizeUninitializedArrayySayxGABnlF : $@convention(thin) <Element> (@owned Array<Element>) -> @owned 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 : $()
}