//===--- OptimizerBridging.h - header for the OptimizerBridging module ----===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2025 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 // //===----------------------------------------------------------------------===// #ifndef SWIFT_SILOPTIMIZER_OPTIMIZERBRIDGING_H #define SWIFT_SILOPTIMIZER_OPTIMIZERBRIDGING_H /// `OptimizerBridging.h` is imported into Swift. Be *very* careful with what /// you include here and keep these includes minimal! /// /// See include guidelines and caveats in `BasicBridging.h`. #include "swift/AST/ASTBridging.h" #include "swift/SIL/SILBridging.h" #include "swift/SILOptimizer/Analysis/ArrayCallKind.h" #ifndef NOT_COMPILED_WITH_SWIFT_PURE_BRIDGING_MODE // Pure bridging mode does not permit including any C++/llvm/swift headers. // See also the comments for `BRIDGING_MODE` in the top-level CMakeLists.txt file. #ifdef SWIFT_SIL_SILVALUE_H #error "should not include swift headers into bridging header" #endif #ifdef LLVM_SUPPORT_COMPILER_H #error "should not include llvm headers into bridging header" #endif #endif // #ifndef NOT_COMPILED_WITH_SWIFT_PURE_BRIDGING_MODE SWIFT_BEGIN_NULLABILITY_ANNOTATIONS namespace swift { class AliasAnalysis; class ArraySemanticsCall; class BasicCalleeAnalysis; class CalleeList; class DeadEndBlocks; class DominanceInfo; class PostDominanceInfo; class SILLoopInfo; class SILLoop; class SwiftPassInvocation; class SILVTable; } struct BridgedPassContext; struct BridgedAliasAnalysis { swift::AliasAnalysis * _Nonnull aa; // Workaround for a compiler bug. // When this unused function is removed, the compiler gives an error. BRIDGED_INLINE bool unused(BridgedValue address1, BridgedValue address2) const; typedef void (* _Nonnull InitFn)(BridgedAliasAnalysis aliasAnalysis, SwiftInt size); typedef void (* _Nonnull DestroyFn)(BridgedAliasAnalysis aliasAnalysis); typedef BridgedMemoryBehavior (* _Nonnull GetMemEffectFn)( BridgedContext context, BridgedAliasAnalysis aliasAnalysis, BridgedValue, BridgedInstruction); typedef bool (* _Nonnull Escaping2InstFn)( BridgedContext context, BridgedAliasAnalysis aliasAnalysis, BridgedValue, BridgedInstruction); typedef bool (* _Nonnull Escaping2ValIntFn)( BridgedContext context, BridgedAliasAnalysis aliasAnalysis, BridgedValue, BridgedValue); typedef bool (* _Nonnull MayAliasFn)( BridgedContext context, BridgedAliasAnalysis aliasAnalysis, BridgedValue, BridgedValue); static void registerAnalysis(InitFn initFn, DestroyFn destroyFn, GetMemEffectFn getMemEffectsFn, Escaping2InstFn isObjReleasedFn, Escaping2ValIntFn isAddrVisibleFromObjFn, MayAliasFn mayAliasFn); }; struct BridgedCalleeAnalysis { swift::BasicCalleeAnalysis * _Nonnull ca; struct CalleeList { uint64_t storage[3]; BRIDGED_INLINE CalleeList(swift::CalleeList list); BRIDGED_INLINE swift::CalleeList unbridged() const; BRIDGED_INLINE bool isIncomplete() const; BRIDGED_INLINE SwiftInt getCount() const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedFunction getCallee(SwiftInt index) const; }; SWIFT_IMPORT_UNSAFE CalleeList getCallees(BridgedValue callee) const; SWIFT_IMPORT_UNSAFE CalleeList getDestructors(BridgedType type, bool isExactType) const; typedef bool (* _Nonnull IsDeinitBarrierFn)(BridgedInstruction, BridgedCalleeAnalysis bca); typedef BridgedMemoryBehavior (* _Nonnull GetMemBehvaiorFn)( BridgedInstruction apply, bool observeRetains, BridgedCalleeAnalysis bca); static void registerAnalysis(IsDeinitBarrierFn isDeinitBarrierFn, GetMemBehvaiorFn getEffectsFn); }; struct BridgedDeadEndBlocksAnalysis { swift::DeadEndBlocks * _Nonnull deb; BRIDGED_INLINE bool isDeadEnd(BridgedBasicBlock block) const; }; struct BridgedDomTree { swift::DominanceInfo * _Nonnull di; BRIDGED_INLINE bool dominates(BridgedBasicBlock dominating, BridgedBasicBlock dominated) const; BRIDGED_INLINE SwiftInt getNumberOfChildren(BridgedBasicBlock bb) const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedBasicBlock getChildAt(BridgedBasicBlock bb, SwiftInt index) const; }; struct BridgedPostDomTree { swift::PostDominanceInfo * _Nonnull pdi; BRIDGED_INLINE bool postDominates(BridgedBasicBlock dominating, BridgedBasicBlock dominated) const; }; struct BridgedLoopTree { swift::SILLoopInfo * _Nonnull li; BRIDGED_INLINE SwiftInt getTopLevelLoopCount() const; BRIDGED_INLINE BridgedLoop getLoop(SwiftInt index) const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedBasicBlock splitEdge(BridgedBasicBlock bb, SwiftInt edgeIndex, BridgedDomTree domTree) const; }; struct BridgedPassContext { swift::SwiftPassInvocation * _Nonnull invocation; BridgedPassContext(swift::SwiftPassInvocation * _Nonnull invocation) : invocation(invocation) {} BRIDGED_INLINE BridgedPassContext(BridgedContext ctxt); BRIDGED_INLINE bool hadError() const; BRIDGED_INLINE void notifyDependencyOnBodyOf(BridgedFunction otherFunction) const; // Analysis SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedAliasAnalysis getAliasAnalysis() const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedCalleeAnalysis getCalleeAnalysis() const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedDeadEndBlocksAnalysis getDeadEndBlocksAnalysis() const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedDomTree getDomTree() const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedPostDomTree getPostDomTree() const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedDeclObj getSwiftArrayDecl() const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedDeclObj getSwiftMutableSpanDecl() const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedLoopTree getLoopTree() const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedLoop getLoop() const; // Array semantics call static BRIDGED_INLINE ArrayCallKind getArraySemanticsCallKind(BridgedInstruction inst); BRIDGED_INLINE bool canHoistArraySemanticsCall(BridgedInstruction inst, BridgedInstruction toInst) const; BRIDGED_INLINE void hoistArraySemanticsCall(BridgedInstruction inst, BridgedInstruction beforeInst) const; // AST SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedDiagnosticEngine getDiagnosticEngine() const; // SIL modifications struct DevirtResult { OptionalBridgedInstruction newApply; bool cfgChanged; }; bool tryOptimizeApplyOfPartialApply(BridgedInstruction closure) const; bool tryDeleteDeadClosure(BridgedInstruction closure, bool needKeepArgsAlive) const; SWIFT_IMPORT_UNSAFE DevirtResult tryDevirtualizeApply(BridgedInstruction apply, bool isMandatory) const; bool tryOptimizeKeypath(BridgedInstruction apply) const; SWIFT_IMPORT_UNSAFE OptionalBridgedValue constantFoldBuiltin(BridgedInstruction builtin) const; SWIFT_IMPORT_UNSAFE OptionalBridgedFunction specializeFunction(BridgedFunction function, BridgedSubstitutionMap substitutions, bool convertIndirectToDirect, bool isMandatory) const; void deserializeAllCallees(BridgedFunction function, bool deserializeAll) const; bool specializeClassMethodInst(BridgedInstruction cm) const; bool specializeWitnessMethodInst(BridgedInstruction wm) const; bool specializeAppliesInFunction(BridgedFunction function, bool isMandatory) const; BridgedOwnedString mangleOutlinedVariable(BridgedFunction function) const; BridgedOwnedString mangleAsyncRemoved(BridgedFunction function) const; BridgedOwnedString mangleWithDeadArgs(BridgedArrayRef bridgedDeadArgIndices, BridgedFunction function) const; BridgedOwnedString mangleWithClosureArgs(BridgedArrayRef closureArgIndices, BridgedFunction applySiteCallee) const; BridgedOwnedString mangleWithConstCaptureArgs(BridgedArrayRef bridgedConstArgs, BridgedFunction applySiteCallee) const; BridgedOwnedString mangleWithBoxToStackPromotedArgs(BridgedArrayRef bridgedPromotedArgIndices, BridgedFunction bridgedOriginalFunction) const; void inlineFunction(BridgedInstruction apply, bool mandatoryInline) const; BRIDGED_INLINE bool eliminateDeadAllocations(BridgedFunction f) const; void eraseFunction(BridgedFunction function) const; BRIDGED_INLINE bool shouldExpand(BridgedType type) const; // IRGen SwiftInt getStaticSize(BridgedType type) const; SwiftInt getStaticAlignment(BridgedType type) const; SwiftInt getStaticStride(BridgedType type) const; bool canMakeStaticObjectReadOnly(BridgedType type) const; // Stack nesting BRIDGED_INLINE void notifyInvalidatedStackNesting() const; BRIDGED_INLINE bool getNeedFixStackNesting() const; void fixStackNesting(BridgedFunction function) const; // Access SIL module data structures SWIFT_IMPORT_UNSAFE BRIDGED_INLINE OptionalBridgedFunction getFirstFunctionInModule() const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE static OptionalBridgedFunction getNextFunctionInModule(BridgedFunction function); SWIFT_IMPORT_UNSAFE BRIDGED_INLINE OptionalBridgedGlobalVar getFirstGlobalInModule() const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE static OptionalBridgedGlobalVar getNextGlobalInModule(BridgedGlobalVar global); BRIDGED_INLINE SwiftInt getNumVTables() const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedVTable getVTable(SwiftInt index) const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE OptionalBridgedWitnessTable getFirstWitnessTableInModule() const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE static OptionalBridgedWitnessTable getNextWitnessTableInModule( BridgedWitnessTable table); SWIFT_IMPORT_UNSAFE BRIDGED_INLINE OptionalBridgedDefaultWitnessTable getFirstDefaultWitnessTableInModule() const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE static OptionalBridgedDefaultWitnessTable getNextDefaultWitnessTableInModule( BridgedDefaultWitnessTable table); // Passmanager housekeeping BRIDGED_INLINE bool continueWithNextSubpassRun(OptionalBridgedInstruction inst) const; SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedContext initializeNestedPassContext(BridgedFunction newFunction) const; BRIDGED_INLINE void deinitializedNestedPassContext() const; BRIDGED_INLINE void addFunctionToPassManagerWorklist(BridgedFunction newFunction, BridgedFunction oldFunction) const; // Options enum class AssertConfiguration { Debug = 0, Release = 1, Unchecked = 2 }; BRIDGED_INLINE bool useAggressiveReg2MemForCodeSize() const; BRIDGED_INLINE bool enableStackProtection() const; BRIDGED_INLINE bool enableMergeableTraps() const; BRIDGED_INLINE bool hasFeature(BridgedFeature feature) const; BRIDGED_INLINE bool enableMoveInoutStackProtection() const; BRIDGED_INLINE AssertConfiguration getAssertConfiguration() const; bool enableSimplificationFor(BridgedInstruction inst) const; BRIDGED_INLINE bool enableWMORequiredDiagnostics() const; BRIDGED_INLINE bool noAllocations() const; // Temporary for AddressableParameters Bootstrapping. BRIDGED_INLINE bool enableAddressDependencies() const; // Closure specializer SWIFT_IMPORT_UNSAFE BridgedFunction createSpecializedFunctionDeclaration(BridgedStringRef specializedName, const BridgedParameterInfo * _Nullable specializedBridgedParams, SwiftInt paramCount, BridgedFunction bridgedOriginal, bool makeThin, bool makeBare, bool preserveGenericSignature) const; bool completeLifetime(BridgedValue value) const; }; bool BeginApply_canInline(BridgedInstruction beginApply); enum class BridgedDynamicCastResult { willSucceed, maySucceed, willFail }; BridgedDynamicCastResult classifyDynamicCastBridged(BridgedCanType sourceTy, BridgedCanType destTy, BridgedFunction function, bool sourceTypeIsExact); BridgedDynamicCastResult classifyDynamicCastBridged(BridgedInstruction inst); //===----------------------------------------------------------------------===// // Pass registration //===----------------------------------------------------------------------===// struct BridgedFunctionPassCtxt { BridgedFunction function; BridgedContext passContext; } ; struct BridgedInstructionPassCtxt { BridgedInstruction instruction; BridgedContext passContext; }; typedef void (* _Nonnull BridgedModulePassRunFn)(BridgedContext); typedef void (* _Nonnull BridgedFunctionPassRunFn)(BridgedFunctionPassCtxt); typedef void (* _Nonnull BridgedInstructionPassRunFn)(BridgedInstructionPassCtxt); void SILPassManager_registerModulePass(BridgedStringRef name, BridgedModulePassRunFn runFn); void SILPassManager_registerFunctionPass(BridgedStringRef name, BridgedFunctionPassRunFn runFn); void SILCombine_registerInstructionPass(BridgedStringRef instClassName, BridgedInstructionPassRunFn runFn); void registerFunctionTestThunk(SwiftNativeFunctionTestThunk); void registerFunctionTest(BridgedStringRef, void *_Nonnull nativeSwiftContext); #ifndef PURE_BRIDGING_MODE // In _not_ PURE_BRIDGING_MODE, briding functions are inlined and therefore inluded in the header file. #include "OptimizerBridgingImpl.h" #else // For fflush and stdout #include #endif SWIFT_END_NULLABILITY_ANNOTATIONS #endif