mirror of
https://github.com/apple/swift.git
synced 2026-03-04 18:24:35 +01:00
Pass-invocations can be nested if a module pass creates an inner context for a specific function to modify. This change * removes the SwiftPassInvocation instance from SILCombine and let SILCombine use the current SwiftPassInvocation * correctly use the innermost SwiftPassInvocation in various bridged utilities
144 lines
5.1 KiB
C++
144 lines
5.1 KiB
C++
//===--- AliasAnalysis.cpp - SIL Alias Analysis ---------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#define DEBUG_TYPE "sil-aa"
|
|
#include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
|
|
#include "swift/Basic/Assertions.h"
|
|
#include "swift/SIL/SILFunction.h"
|
|
#include "swift/SILOptimizer/PassManager/PassManager.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "swift/SILOptimizer/OptimizerBridging.h"
|
|
|
|
using namespace swift;
|
|
|
|
// Bridging functions.
|
|
static BridgedAliasAnalysis::InitFn initFunction = nullptr;
|
|
static BridgedAliasAnalysis::DestroyFn destroyFunction = nullptr;
|
|
static BridgedAliasAnalysis::GetMemEffectFn getMemEffectsFunction = nullptr;
|
|
static BridgedAliasAnalysis::Escaping2InstFn isObjReleasedFunction = nullptr;
|
|
static BridgedAliasAnalysis::Escaping2ValIntFn isAddrVisibleFromObjFunction = nullptr;
|
|
static BridgedAliasAnalysis::MayAliasFn mayAliasFunction = nullptr;
|
|
|
|
void AliasAnalysis::initSwiftSpecificData() {
|
|
if (initFunction)
|
|
initFunction({this}, sizeof(swiftSpecificData));
|
|
}
|
|
|
|
AliasAnalysis::~AliasAnalysis() {
|
|
if (destroyFunction)
|
|
destroyFunction({this});
|
|
}
|
|
|
|
bool AliasAnalysis::canApplyDecrementRefCount(FullApplySite FAS, SILValue Ptr) {
|
|
// Treat applications of no-return functions as decrementing ref counts. This
|
|
// causes the apply to become a sink barrier for ref count increments.
|
|
if (FAS.isCalleeNoReturn())
|
|
return true;
|
|
|
|
/// If the pointer cannot escape to the function we are done.
|
|
bool result = isObjectReleasedByInst(Ptr, FAS.getInstruction());
|
|
return result;
|
|
}
|
|
|
|
bool AliasAnalysis::canBuiltinDecrementRefCount(BuiltinInst *BI, SILValue Ptr) {
|
|
return isObjectReleasedByInst(Ptr, BI);
|
|
}
|
|
|
|
namespace {
|
|
|
|
class AliasAnalysisContainer : public FunctionAnalysisBase<AliasAnalysis> {
|
|
SILPassManager *PM = nullptr;
|
|
|
|
public:
|
|
AliasAnalysisContainer() : FunctionAnalysisBase(SILAnalysisKind::Alias) {}
|
|
|
|
virtual bool shouldInvalidate(SILAnalysis::InvalidationKind K) override {
|
|
return K & InvalidationKind::Instructions;
|
|
}
|
|
|
|
virtual void invalidate(SILFunction *f,
|
|
SILAnalysis::InvalidationKind k) override {
|
|
if (k & InvalidationKind::Effects) {
|
|
FunctionAnalysisBase::invalidate();
|
|
} else {
|
|
FunctionAnalysisBase::invalidate(f, k);
|
|
}
|
|
}
|
|
|
|
// Computes loop information for the given function using dominance
|
|
// information.
|
|
virtual std::unique_ptr<AliasAnalysis>
|
|
newFunctionAnalysis(SILFunction *F) override {
|
|
assert(PM && "dependent analysis not initialized");
|
|
return std::make_unique<AliasAnalysis>(PM);
|
|
}
|
|
|
|
virtual void initialize(SILPassManager *PM) override {
|
|
this->PM = PM;
|
|
}
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
SILAnalysis *swift::createAliasAnalysis(SILModule *M) {
|
|
return new AliasAnalysisContainer();
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Swift Bridging
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void BridgedAliasAnalysis::registerAnalysis(InitFn initFn,
|
|
DestroyFn destroyFn,
|
|
GetMemEffectFn getMemEffectsFn,
|
|
Escaping2InstFn isObjReleasedFn,
|
|
Escaping2ValIntFn isAddrVisibleFromObjFn,
|
|
MayAliasFn mayAliasFn) {
|
|
initFunction = initFn;
|
|
destroyFunction = destroyFn;
|
|
getMemEffectsFunction = getMemEffectsFn;
|
|
isObjReleasedFunction = isObjReleasedFn;
|
|
isAddrVisibleFromObjFunction = isAddrVisibleFromObjFn;
|
|
mayAliasFunction = mayAliasFn;
|
|
}
|
|
|
|
MemoryBehavior AliasAnalysis::computeMemoryBehavior(SILInstruction *toInst, SILValue addr) {
|
|
if (getMemEffectsFunction) {
|
|
return (MemoryBehavior)getMemEffectsFunction({PM->getSwiftPassInvocation()->getCurrent()},
|
|
{this},
|
|
{addr},
|
|
{toInst->asSILNode()});
|
|
}
|
|
return MemoryBehavior::MayHaveSideEffects;
|
|
}
|
|
|
|
bool AliasAnalysis::isObjectReleasedByInst(SILValue obj, SILInstruction *inst) {
|
|
if (isObjReleasedFunction) {
|
|
return isObjReleasedFunction({PM->getSwiftPassInvocation()->getCurrent()}, {this}, {obj}, {inst->asSILNode()});
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool AliasAnalysis::isAddrVisibleFromObject(SILValue addr, SILValue obj) {
|
|
if (isAddrVisibleFromObjFunction) {
|
|
return isAddrVisibleFromObjFunction({PM->getSwiftPassInvocation()->getCurrent()}, {this}, {addr}, {obj});
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool AliasAnalysis::mayAlias(SILValue lhs, SILValue rhs) {
|
|
if (mayAliasFunction) {
|
|
return mayAliasFunction({PM->getSwiftPassInvocation()->getCurrent()}, {this}, {lhs}, {rhs});
|
|
}
|
|
return true;
|
|
}
|