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:
Erik Eckstein
2024-01-02 16:28:02 +01:00
parent 3229749257
commit cee4505840
2 changed files with 115 additions and 6 deletions

View File

@@ -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,