mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
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.
1114 lines
60 KiB
Plaintext
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 : $()
|
|
}
|