Files
swift-mirror/SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyLoad.swift
Erik Eckstein 88a4a9769e Swift Optimizer: add simplification for load
Replace loads of global let variables with there static initializer values.
2023-05-08 21:23:36 +02:00

80 lines
2.5 KiB
Swift

//===--- SimplifyLoad.swift -----------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import SIL
extension LoadInst : OnoneSimplifyable {
func simplify(_ context: SimplifyContext) {
replaceLoadOfGlobalLet(context)
}
private func replaceLoadOfGlobalLet(_ context: SimplifyContext) {
guard let globalInitVal = getGlobalInitValue(address: address) else {
return
}
let builder = Builder(before: self, context)
guard let initVal = context.copyStaticInitializer(fromInitValue: globalInitVal, to: builder) else {
return
}
uses.replaceAll(with: initVal, context)
transitivelyErase(load: self, context)
}
}
/// Returns the init value of a global which is loaded from `address`.
private func getGlobalInitValue(address: Value) -> Value? {
switch address {
case let gai as GlobalAddrInst:
if gai.global.isLet {
return gai.global.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 {
return structVal.operands[sea.fieldIndex].value
}
case let tea as TupleElementAddrInst:
if let tupleVal = getGlobalInitValue(address: tea.tuple) as? TupleInst {
return tupleVal.operands[tea.fieldIndex].value
}
case let bai as BeginAccessInst:
return getGlobalInitValue(address: bai.address)
default:
break
}
return nil
}
private func globalLoadedViaAddressor(pointer: Value) -> GlobalVariable? {
if let ai = pointer as? ApplyInst,
let callee = ai.referencedFunction,
let global = callee.globalOfGlobalInitFunction,
global.isLet {
return global
}
return nil
}
private func transitivelyErase(load: LoadInst, _ context: SimplifyContext) {
var inst: SingleValueInstruction = load
while inst.uses.isEmpty {
if inst.operands.count != 1 {
context.erase(instruction: inst)
return
}
let operandInst = inst.operands[0].value as! SingleValueInstruction
context.erase(instruction: inst)
inst = operandInst
}
}