Files
swift-mirror/include/swift/SILOptimizer/OptimizerBridgingImpl.h
2025-08-28 21:00:09 +01:00

396 lines
15 KiB
C++

//===--- OptimizerBridgingImpl.h ------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file contains the implementation of bridging functions, which are either
// - depending on if PURE_BRIDGING_MODE is set - included in the cpp file or
// in the header file.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SILOPTIMIZER_OPTIMIZERBRIDGING_IMPL_H
#define SWIFT_SILOPTIMIZER_OPTIMIZERBRIDGING_IMPL_H
#include "swift/Demangling/Demangle.h"
#include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
#include "swift/SILOptimizer/Analysis/ArraySemantic.h"
#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h"
#include "swift/SILOptimizer/Analysis/DeadEndBlocksAnalysis.h"
#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h"
#include "swift/SILOptimizer/Analysis/LoopAnalysis.h"
#include "swift/SILOptimizer/OptimizerBridging.h"
#include "swift/SILOptimizer/PassManager/PassManager.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
#include "swift/SILOptimizer/Utils/DebugOptUtils.h"
SWIFT_BEGIN_NULLABILITY_ANNOTATIONS
//===----------------------------------------------------------------------===//
// BridgedAliasAnalysis
//===----------------------------------------------------------------------===//
bool BridgedAliasAnalysis::unused(BridgedValue address1, BridgedValue address2) const {
return true;
}
//===----------------------------------------------------------------------===//
// BridgedCalleeAnalysis
//===----------------------------------------------------------------------===//
static_assert(sizeof(BridgedCalleeAnalysis::CalleeList) >= sizeof(swift::CalleeList),
"BridgedCalleeAnalysis::CalleeList has wrong size");
BridgedCalleeAnalysis::CalleeList::CalleeList(swift::CalleeList list) {
*reinterpret_cast<swift::CalleeList *>(&storage) = list;
}
swift::CalleeList BridgedCalleeAnalysis::CalleeList::unbridged() const {
return *reinterpret_cast<const swift::CalleeList *>(&storage);
}
bool BridgedCalleeAnalysis::CalleeList::isIncomplete() const {
return unbridged().isIncomplete();
}
SwiftInt BridgedCalleeAnalysis::CalleeList::getCount() const {
return unbridged().getCount();
}
BridgedFunction BridgedCalleeAnalysis::CalleeList::getCallee(SwiftInt index) const {
return {unbridged().get((unsigned)index)};
}
//===----------------------------------------------------------------------===//
// BridgedDeadEndBlocksAnalysis
//===----------------------------------------------------------------------===//
bool BridgedDeadEndBlocksAnalysis::isDeadEnd(BridgedBasicBlock block) const {
return deb->isDeadEnd(block.unbridged());
}
//===----------------------------------------------------------------------===//
// BridgedDomTree, BridgedPostDomTree
//===----------------------------------------------------------------------===//
bool BridgedDomTree::dominates(BridgedBasicBlock dominating, BridgedBasicBlock dominated) const {
return di->dominates(dominating.unbridged(), dominated.unbridged());
}
SwiftInt BridgedDomTree::getNumberOfChildren(BridgedBasicBlock bb) const {
return di->getNode(bb.unbridged())->getNumChildren();
}
BridgedBasicBlock BridgedDomTree::getChildAt(BridgedBasicBlock bb, SwiftInt index) const {
return {di->getNode(bb.unbridged())->begin()[index]->getBlock()};
}
bool BridgedPostDomTree::postDominates(BridgedBasicBlock dominating, BridgedBasicBlock dominated) const {
return pdi->dominates(dominating.unbridged(), dominated.unbridged());
}
//===----------------------------------------------------------------------===//
// BridgedLoopTree, BridgedLoop
//===----------------------------------------------------------------------===//
SwiftInt BridgedLoopTree::getTopLevelLoopCount() const {
return li->end() - li->begin();
}
BridgedLoop BridgedLoopTree::getLoop(SwiftInt index) const {
return {li->begin()[index]};
}
BridgedBasicBlock BridgedLoopTree::splitEdge(BridgedBasicBlock bb, SwiftInt edgeIndex, BridgedDomTree domTree) const {
return {swift::splitEdge(bb.unbridged()->getTerminator(), edgeIndex, domTree.di, li)};
}
SwiftInt BridgedLoop::getInnerLoopCount() const {
return l->end() - l->begin();
}
BridgedLoop BridgedLoop::getInnerLoop(SwiftInt index) const {
return {l->begin()[index]};
}
SwiftInt BridgedLoop::getBasicBlockCount() const {
return l->getBlocks().size();
}
BridgedBasicBlock BridgedLoop::getBasicBlock(SwiftInt index) const {
return {l->getBlocks()[index]};
}
OptionalBridgedBasicBlock BridgedLoop::getPreheader() const {
return {l->getLoopPreheader()};
}
BridgedBasicBlock BridgedLoop::getHeader() const {
return {l->getHeader()};
}
bool BridgedLoop::contains(BridgedBasicBlock block) const {
return l->contains(block.unbridged());
}
//===----------------------------------------------------------------------===//
// BridgedPassContext
//===----------------------------------------------------------------------===//
static_assert((int)swift::SILAnalysis::InvalidationKind::Instructions ==
(int)swift::SILContext::NotificationKind::Instructions);
static_assert((int)swift::SILAnalysis::InvalidationKind::Calls ==
(int)swift::SILContext::NotificationKind::Calls);
static_assert((int)swift::SILAnalysis::InvalidationKind::Branches ==
(int)swift::SILContext::NotificationKind::Branches);
static_assert((int)swift::SILAnalysis::InvalidationKind::Effects ==
(int)swift::SILContext::NotificationKind::Effects);
BridgedPassContext::BridgedPassContext(BridgedContext ctxt) :
invocation(static_cast<swift::SwiftPassInvocation *>(ctxt.context)) {}
void BridgedPassContext::notifyDependencyOnBodyOf(BridgedFunction otherFunction) const {
// Currently `otherFunction` is ignored. We could design a more accurate dependency system
// in the pass manager, which considers the actual function. But it's probaboly not worth the effort.
invocation->getPassManager()->setDependingOnCalleeBodies();
}
bool BridgedPassContext::hadError() const {
return invocation->getPassManager()->getModule()->getASTContext().hadError();
}
BridgedAliasAnalysis BridgedPassContext::getAliasAnalysis() const {
return {invocation->getPassManager()->getAnalysis<swift::AliasAnalysis>(invocation->getFunction())};
}
BridgedCalleeAnalysis BridgedPassContext::getCalleeAnalysis() const {
return {invocation->getPassManager()->getAnalysis<swift::BasicCalleeAnalysis>()};
}
BridgedDeadEndBlocksAnalysis BridgedPassContext::getDeadEndBlocksAnalysis() const {
auto *dba = invocation->getPassManager()->getAnalysis<swift::DeadEndBlocksAnalysis>();
return {dba->get(invocation->getFunction())};
}
BridgedDomTree BridgedPassContext::getDomTree() const {
auto *da = invocation->getPassManager()->getAnalysis<swift::DominanceAnalysis>();
return {da->get(invocation->getFunction())};
}
BridgedPostDomTree BridgedPassContext::getPostDomTree() const {
auto *pda = invocation->getPassManager()->getAnalysis<swift::PostDominanceAnalysis>();
return {pda->get(invocation->getFunction())};
}
BridgedLoopTree BridgedPassContext::getLoopTree() const {
auto *lt = invocation->getPassManager()->getAnalysis<swift::SILLoopAnalysis>();
return {lt->get(invocation->getFunction())};
}
BridgedDeclObj BridgedPassContext::getSwiftArrayDecl() const {
swift::SILModule *mod = invocation->getPassManager()->getModule();
return {mod->getASTContext().getArrayDecl()};
}
BridgedDeclObj BridgedPassContext::getSwiftMutableSpanDecl() const {
swift::SILModule *mod = invocation->getPassManager()->getModule();
return {mod->getASTContext().getMutableSpanDecl()};
}
// Array semantics call
ArrayCallKind BridgedPassContext::getArraySemanticsCallKind(BridgedInstruction inst) {
swift::ArraySemanticsCall semCall(inst.unbridged());
return semCall.getKind();
}
bool BridgedPassContext::canHoistArraySemanticsCall(BridgedInstruction inst, BridgedInstruction toInst) const {
swift::ArraySemanticsCall semCall(inst.unbridged());
return semCall.canHoist(toInst.unbridged(), getDomTree().di);
}
void BridgedPassContext::hoistArraySemanticsCall(BridgedInstruction inst, BridgedInstruction beforeInst) const {
swift::ArraySemanticsCall semCall(inst.unbridged());
semCall.hoist(beforeInst.unbridged(), getDomTree().di);
}
// AST
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE
BridgedDiagnosticEngine BridgedPassContext::getDiagnosticEngine() const {
swift::SILModule *mod = invocation->getPassManager()->getModule();
return {&mod->getASTContext().Diags};
}
// SIL modifications
bool BridgedPassContext::eliminateDeadAllocations(BridgedFunction f) const {
return swift::eliminateDeadAllocations(f.getFunction(),
this->getDomTree().di);
}
OptionalBridgedFunction BridgedPassContext::getFirstFunctionInModule() const {
swift::SILModule *mod = invocation->getPassManager()->getModule();
if (mod->getFunctions().empty())
return {nullptr};
return {&*mod->getFunctions().begin()};
}
OptionalBridgedFunction BridgedPassContext::getNextFunctionInModule(BridgedFunction function) {
auto *f = function.getFunction();
auto nextIter = std::next(f->getIterator());
if (nextIter == f->getModule().getFunctions().end())
return {nullptr};
return {&*nextIter};
}
OptionalBridgedGlobalVar BridgedPassContext::getFirstGlobalInModule() const {
swift::SILModule *mod = invocation->getPassManager()->getModule();
if (mod->getSILGlobals().empty())
return {nullptr};
return {&*mod->getSILGlobals().begin()};
}
OptionalBridgedGlobalVar BridgedPassContext::getNextGlobalInModule(BridgedGlobalVar global) {
auto *g = global.getGlobal();
auto nextIter = std::next(g->getIterator());
if (nextIter == g->getModule().getSILGlobals().end())
return {nullptr};
return {&*nextIter};
}
SwiftInt BridgedPassContext::getNumVTables() const {
return (SwiftInt)(invocation->getPassManager()->getModule()->getVTables().size());
}
BridgedVTable BridgedPassContext::getVTable(SwiftInt index) const {
return {invocation->getPassManager()->getModule()->getVTables()[index]};
}
OptionalBridgedWitnessTable BridgedPassContext::getFirstWitnessTableInModule() const {
swift::SILModule *mod = invocation->getPassManager()->getModule();
if (mod->getWitnessTables().empty())
return {nullptr};
return {&*mod->getWitnessTables().begin()};
}
OptionalBridgedWitnessTable BridgedPassContext::getNextWitnessTableInModule(BridgedWitnessTable table) {
auto *t = table.table;
auto nextIter = std::next(t->getIterator());
if (nextIter == t->getModule().getWitnessTables().end())
return {nullptr};
return {&*nextIter};
}
OptionalBridgedDefaultWitnessTable BridgedPassContext::getFirstDefaultWitnessTableInModule() const {
swift::SILModule *mod = invocation->getPassManager()->getModule();
if (mod->getDefaultWitnessTables().empty())
return {nullptr};
return {&*mod->getDefaultWitnessTables().begin()};
}
OptionalBridgedDefaultWitnessTable BridgedPassContext::
getNextDefaultWitnessTableInModule(BridgedDefaultWitnessTable table) {
auto *t = table.table;
auto nextIter = std::next(t->getIterator());
if (nextIter == t->getModule().getDefaultWitnessTables().end())
return {nullptr};
return {&*nextIter};
}
void BridgedPassContext::notifyInvalidatedStackNesting() const {
invocation->setNeedFixStackNesting(true);
}
bool BridgedPassContext::getNeedFixStackNesting() const {
return invocation->getNeedFixStackNesting();
}
bool BridgedPassContext::continueWithNextSubpassRun(OptionalBridgedInstruction inst) const {
swift::SILPassManager *pm = invocation->getPassManager();
return pm->continueWithNextSubpassRun(
inst.unbridged(), invocation->getFunction(), invocation->getTransform());
}
BridgedContext BridgedPassContext::initializeNestedPassContext(BridgedFunction newFunction) const {
return { invocation->initializeNestedSwiftPassInvocation(newFunction.getFunction()) };
}
void BridgedPassContext::deinitializedNestedPassContext() const {
invocation->deinitializeNestedSwiftPassInvocation();
}
void BridgedPassContext::addFunctionToPassManagerWorklist(
BridgedFunction newFunction, BridgedFunction oldFunction) const {
swift::SILPassManager *pm = invocation->getPassManager();
if (llvm::isa<swift::SILFunctionTransform>(invocation->getTransform())) {
pm->addFunctionToWorklist(newFunction.getFunction(), oldFunction.getFunction());
}
}
bool BridgedPassContext::enableStackProtection() const {
swift::SILModule *mod = invocation->getPassManager()->getModule();
return mod->getOptions().EnableStackProtection;
}
bool BridgedPassContext::enableMergeableTraps() const {
swift::SILModule *mod = invocation->getPassManager()->getModule();
return mod->getOptions().MergeableTraps;
}
bool BridgedPassContext::hasFeature(BridgedFeature feature) const {
swift::SILModule *mod = invocation->getPassManager()->getModule();
return mod->getASTContext().LangOpts.hasFeature(swift::Feature(feature));
}
bool BridgedPassContext::enableMoveInoutStackProtection() const {
swift::SILModule *mod = invocation->getPassManager()->getModule();
return mod->getOptions().EnableMoveInoutStackProtection;
}
bool BridgedPassContext::useAggressiveReg2MemForCodeSize() const {
swift::SILModule *mod = invocation->getPassManager()->getModule();
return mod->getOptions().UseAggressiveReg2MemForCodeSize;
}
BridgedPassContext::AssertConfiguration BridgedPassContext::getAssertConfiguration() const {
swift::SILModule *mod = invocation->getPassManager()->getModule();
return (AssertConfiguration)mod->getOptions().AssertConfig;
}
bool BridgedPassContext::shouldExpand(BridgedType ty) const {
swift::SILModule &mod = *invocation->getPassManager()->getModule();
return swift::shouldExpand(mod, ty.unbridged());
}
bool BridgedPassContext::enableWMORequiredDiagnostics() const {
swift::SILModule *mod = invocation->getPassManager()->getModule();
return mod->getOptions().EnableWMORequiredDiagnostics;
}
bool BridgedPassContext::noAllocations() const {
swift::SILModule *mod = invocation->getPassManager()->getModule();
return mod->getOptions().NoAllocations;
}
bool BridgedPassContext::enableAddressDependencies() const {
swift::SILModule *mod = invocation->getPassManager()->getModule();
return mod->getOptions().EnableAddressDependencies;
}
static_assert((int)BridgedPassContext::AssertConfiguration::Debug == (int)swift::SILOptions::Debug);
static_assert((int)BridgedPassContext::AssertConfiguration::Release == (int)swift::SILOptions::Release);
static_assert((int)BridgedPassContext::AssertConfiguration::Unchecked == (int)swift::SILOptions::Unchecked);
SWIFT_END_NULLABILITY_ANNOTATIONS
#endif