mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
SimplifyLoad: improve simplification of load of global variable
Inline the initialization code of a global initializer if the load is a global_addr with a builtin "once" dependency.
This commit is contained in:
@@ -98,7 +98,7 @@ extension LoadInst : OnoneSimplifyable, SILCombineSimplifyable {
|
||||
|
||||
/// The load of a global let variable is replaced by its static initializer value.
|
||||
private func replaceLoadOfGlobalLet(_ context: SimplifyContext) -> Bool {
|
||||
guard let globalInitVal = getGlobalInitValue(address: address) else {
|
||||
guard let globalInitVal = getGlobalInitValue(address: address, context) else {
|
||||
return false
|
||||
}
|
||||
if !globalInitVal.canBeCopied(into: parentFunction, context) {
|
||||
@@ -211,30 +211,51 @@ extension LoadInst : OnoneSimplifyable, SILCombineSimplifyable {
|
||||
}
|
||||
|
||||
/// Returns the init value of a global which is loaded from `address`.
|
||||
private func getGlobalInitValue(address: Value) -> Value? {
|
||||
private func getGlobalInitValue(address: Value, _ context: SimplifyContext) -> Value? {
|
||||
switch address {
|
||||
case let gai as GlobalAddrInst:
|
||||
if gai.global.isLet {
|
||||
return gai.global.staticInitValue
|
||||
if let staticInitValue = gai.global.staticInitValue {
|
||||
return staticInitValue
|
||||
}
|
||||
if let staticInitValue = getInitializerFromInitFunction(of: gai, context) {
|
||||
return staticInitValue
|
||||
}
|
||||
}
|
||||
case let pta as PointerToAddressInst:
|
||||
return globalLoadedViaAddressor(pointer: pta.pointer)?.staticInitValue
|
||||
case let sea as StructElementAddrInst:
|
||||
if let structVal = getGlobalInitValue(address: sea.struct) as? StructInst {
|
||||
if let structVal = getGlobalInitValue(address: sea.struct, context) as? StructInst {
|
||||
return structVal.operands[sea.fieldIndex].value
|
||||
}
|
||||
case let tea as TupleElementAddrInst:
|
||||
if let tupleVal = getGlobalInitValue(address: tea.tuple) as? TupleInst {
|
||||
if let tupleVal = getGlobalInitValue(address: tea.tuple, context) as? TupleInst {
|
||||
return tupleVal.operands[tea.fieldIndex].value
|
||||
}
|
||||
case let bai as BeginAccessInst:
|
||||
return getGlobalInitValue(address: bai.address)
|
||||
return getGlobalInitValue(address: bai.address, context)
|
||||
default:
|
||||
break
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
private func getInitializerFromInitFunction(of globalAddr: GlobalAddrInst, _ context: SimplifyContext) -> Value? {
|
||||
guard let dependentOn = globalAddr.dependencyToken,
|
||||
let builtinOnce = dependentOn as? BuiltinInst,
|
||||
builtinOnce.id == .Once,
|
||||
let initFnRef = builtinOnce.operands[1].value as? FunctionRefInst else
|
||||
{
|
||||
return nil
|
||||
}
|
||||
let initFn = initFnRef.referencedFunction
|
||||
context.notifyDependency(onBodyOf: initFn)
|
||||
guard let (_, storeToGlobal) = getGlobalInitialization(of: initFn, allowGlobalValue: true) else {
|
||||
return nil
|
||||
}
|
||||
return storeToGlobal.source
|
||||
}
|
||||
|
||||
private func globalLoadedViaAddressor(pointer: Value) -> GlobalVariable? {
|
||||
if let ai = pointer as? ApplyInst,
|
||||
let callee = ai.referencedFunction,
|
||||
|
||||
Reference in New Issue
Block a user