Files
swift-mirror/SwiftCompilerSources/Sources/Optimizer/PassManager/PassRegistration.swift
Erik Eckstein c89df9ec98 Mandatory optimizations: constant fold boolean literals before the DefiniteInitialization pass
Add a new mandatory BooleanLiteralFolding pass which constant folds conditional branches with boolean literals as operands.

```
  %1 = integer_literal -1
  %2 = apply %bool_init(%1)   // Bool.init(_builtinBooleanLiteral:)
  %3 = struct_extract %2, #Bool._value
  cond_br %3, bb1, bb2
```
->
```
  ...
  br bb1
```

This pass is intended to run before DefiniteInitialization, where mandatory inlining and constant folding didn't run, yet (which would perform this kind of optimization).
This optimization is required to let DefiniteInitialization handle boolean literals correctly.
For example in infinite loops:

```
   init() {
     while true {           // DI need to know that there is no loop exit from this while-statement
       if some_condition {
         member_field = init_value
         break
       }
     }
   }
```
2024-01-10 16:15:57 +01:00

121 lines
5.6 KiB
Swift

//===--- PassRegistration.swift - Register optimization passes -------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2021 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
import OptimizerBridging
@_cdecl("initializeSwiftModules")
public func initializeSwiftModules() {
registerSILClasses()
registerSwiftAnalyses()
registerSwiftPasses()
registerOptimizerTests()
}
private func registerPass(
_ pass: ModulePass,
_ runFn: @escaping (@convention(c) (BridgedPassContext) -> ())) {
pass.name._withBridgedStringRef { nameStr in
SILPassManager_registerModulePass(nameStr, runFn)
}
}
private func registerPass(
_ pass: FunctionPass,
_ runFn: @escaping (@convention(c) (BridgedFunctionPassCtxt) -> ())) {
pass.name._withBridgedStringRef { nameStr in
SILPassManager_registerFunctionPass(nameStr, runFn)
}
}
protocol SILCombineSimplifyable : Instruction {
func simplify(_ context: SimplifyContext)
}
private func run<InstType: SILCombineSimplifyable>(_ instType: InstType.Type,
_ bridgedCtxt: BridgedInstructionPassCtxt) {
let inst = bridgedCtxt.instruction.getAs(instType)
let context = SimplifyContext(_bridged: bridgedCtxt.passContext,
notifyInstructionChanged: {inst in},
preserveDebugInfo: false)
inst.simplify(context)
}
private func registerForSILCombine<InstType: SILCombineSimplifyable>(
_ instType: InstType.Type,
_ runFn: @escaping (@convention(c) (BridgedInstructionPassCtxt) -> ())) {
String(describing: instType)._withBridgedStringRef { instClassStr in
SILCombine_registerInstructionPass(instClassStr, runFn)
}
}
private func registerSwiftPasses() {
// Module passes
registerPass(mandatoryPerformanceOptimizations, { mandatoryPerformanceOptimizations.run($0) })
registerPass(readOnlyGlobalVariablesPass, { readOnlyGlobalVariablesPass.run($0) })
registerPass(stackProtection, { stackProtection.run($0) })
// Function passes
registerPass(allocVectorLowering, { allocVectorLowering.run($0) })
registerPass(asyncDemotion, { asyncDemotion.run($0) })
registerPass(booleanLiteralFolding, { booleanLiteralFolding.run($0) })
registerPass(letPropertyLowering, { letPropertyLowering.run($0) })
registerPass(mergeCondFailsPass, { mergeCondFailsPass.run($0) })
registerPass(computeEscapeEffects, { computeEscapeEffects.run($0) })
registerPass(computeSideEffects, { computeSideEffects.run($0) })
registerPass(initializeStaticGlobalsPass, { initializeStaticGlobalsPass.run($0) })
registerPass(objCBridgingOptimization, { objCBridgingOptimization.run($0) })
registerPass(objectOutliner, { objectOutliner.run($0) })
registerPass(stackPromotion, { stackPromotion.run($0) })
registerPass(functionStackProtection, { functionStackProtection.run($0) })
registerPass(assumeSingleThreadedPass, { assumeSingleThreadedPass.run($0) })
registerPass(releaseDevirtualizerPass, { releaseDevirtualizerPass.run($0) })
registerPass(simplificationPass, { simplificationPass.run($0) })
registerPass(ononeSimplificationPass, { ononeSimplificationPass.run($0) })
registerPass(lateOnoneSimplificationPass, { lateOnoneSimplificationPass.run($0) })
registerPass(cleanupDebugStepsPass, { cleanupDebugStepsPass.run($0) })
registerPass(namedReturnValueOptimization, { namedReturnValueOptimization.run($0) })
registerPass(stripObjectHeadersPass, { stripObjectHeadersPass.run($0) })
registerPass(deadStoreElimination, { deadStoreElimination.run($0) })
registerPass(redundantLoadElimination, { redundantLoadElimination.run($0) })
registerPass(earlyRedundantLoadElimination, { earlyRedundantLoadElimination.run($0) })
registerPass(deinitDevirtualizer, { deinitDevirtualizer.run($0) })
// Instruction passes
registerForSILCombine(BeginCOWMutationInst.self, { run(BeginCOWMutationInst.self, $0) })
registerForSILCombine(GlobalValueInst.self, { run(GlobalValueInst.self, $0) })
registerForSILCombine(StrongRetainInst.self, { run(StrongRetainInst.self, $0) })
registerForSILCombine(StrongReleaseInst.self, { run(StrongReleaseInst.self, $0) })
registerForSILCombine(RetainValueInst.self, { run(RetainValueInst.self, $0) })
registerForSILCombine(ReleaseValueInst.self, { run(ReleaseValueInst.self, $0) })
registerForSILCombine(LoadInst.self, { run(LoadInst.self, $0) })
registerForSILCombine(CopyValueInst.self, { run(CopyValueInst.self, $0) })
registerForSILCombine(DestroyValueInst.self, { run(DestroyValueInst.self, $0) })
// Test passes
registerPass(functionUsesDumper, { functionUsesDumper.run($0) })
registerPass(silPrinterPass, { silPrinterPass.run($0) })
registerPass(escapeInfoDumper, { escapeInfoDumper.run($0) })
registerPass(addressEscapeInfoDumper, { addressEscapeInfoDumper.run($0) })
registerPass(accessDumper, { accessDumper.run($0) })
registerPass(deadEndBlockDumper, { deadEndBlockDumper.run($0) })
registerPass(memBehaviorDumper, { memBehaviorDumper.run($0) })
registerPass(rangeDumper, { rangeDumper.run($0) })
registerPass(runUnitTests, { runUnitTests.run($0) })
registerPass(testInstructionIteration, { testInstructionIteration.run($0) })
}
private func registerSwiftAnalyses() {
AliasAnalysis.register()
CalleeAnalysis.register()
}