mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[ownership] Change SILUndef to return Any ownership for trivial values and owned for non-trivial values.
This is in preparation for verifying that when ownership verification is enabled that only enums and trivial values can have any ownership. I am doing this in preparation for eliminating ValueOwnershipKind::Trivial. rdar://46294760
This commit is contained in:
@@ -23,8 +23,9 @@ class SILInstruction;
|
|||||||
class SILModule;
|
class SILModule;
|
||||||
|
|
||||||
class SILUndef : public ValueBase {
|
class SILUndef : public ValueBase {
|
||||||
SILUndef(SILType Ty)
|
ValueOwnershipKind ownershipKind;
|
||||||
: ValueBase(ValueKind::SILUndef, Ty, IsRepresentative::Yes) {}
|
|
||||||
|
SILUndef(SILType type, SILModule &m);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void operator=(const SILArgument &) = delete;
|
void operator=(const SILArgument &) = delete;
|
||||||
@@ -33,8 +34,12 @@ public:
|
|||||||
static SILUndef *get(SILType ty, SILModule &m);
|
static SILUndef *get(SILType ty, SILModule &m);
|
||||||
static SILUndef *get(SILType ty, SILModule *m) { return get(ty, *m); }
|
static SILUndef *get(SILType ty, SILModule *m) { return get(ty, *m); }
|
||||||
|
|
||||||
template<class OwnerTy>
|
template <class OwnerTy>
|
||||||
static SILUndef *getSentinelValue(SILType Ty, OwnerTy Owner) { return new (*Owner) SILUndef(Ty); }
|
static SILUndef *getSentinelValue(SILType type, SILModule &m, OwnerTy owner) {
|
||||||
|
return new (*owner) SILUndef(type, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueOwnershipKind getOwnershipKind() const { return ownershipKind; }
|
||||||
|
|
||||||
static bool classof(const SILArgument *) = delete;
|
static bool classof(const SILArgument *) = delete;
|
||||||
static bool classof(const SILInstruction *) = delete;
|
static bool classof(const SILInstruction *) = delete;
|
||||||
|
|||||||
@@ -51,12 +51,15 @@ class SILSSAUpdater {
|
|||||||
// If not null updated with inserted 'phi' nodes (SILArgument).
|
// If not null updated with inserted 'phi' nodes (SILArgument).
|
||||||
SmallVectorImpl<SILPhiArgument *> *InsertedPHIs;
|
SmallVectorImpl<SILPhiArgument *> *InsertedPHIs;
|
||||||
|
|
||||||
|
SILModule &M;
|
||||||
|
|
||||||
// Not copyable.
|
// Not copyable.
|
||||||
void operator=(const SILSSAUpdater &) = delete;
|
void operator=(const SILSSAUpdater &) = delete;
|
||||||
SILSSAUpdater(const SILSSAUpdater &) = delete;
|
SILSSAUpdater(const SILSSAUpdater &) = delete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SILSSAUpdater(
|
explicit SILSSAUpdater(
|
||||||
|
SILModule &M,
|
||||||
SmallVectorImpl<SILPhiArgument *> *InsertedPHIs = nullptr);
|
SmallVectorImpl<SILPhiArgument *> *InsertedPHIs = nullptr);
|
||||||
~SILSSAUpdater();
|
~SILSSAUpdater();
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ add_swift_host_library(swiftSIL STATIC
|
|||||||
SILProfiler.cpp
|
SILProfiler.cpp
|
||||||
SILSuccessor.cpp
|
SILSuccessor.cpp
|
||||||
SILType.cpp
|
SILType.cpp
|
||||||
|
SILUndef.cpp
|
||||||
SILValue.cpp
|
SILValue.cpp
|
||||||
SILVerifier.cpp
|
SILVerifier.cpp
|
||||||
SILOwnershipVerifier.cpp
|
SILOwnershipVerifier.cpp
|
||||||
|
|||||||
@@ -30,14 +30,6 @@
|
|||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
|
|
||||||
SILUndef *SILUndef::get(SILType ty, SILModule &m) {
|
|
||||||
// Unique these.
|
|
||||||
SILUndef *&entry = m.UndefValues[ty];
|
|
||||||
if (entry == nullptr)
|
|
||||||
entry = new (m) SILUndef(ty);
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
FormalLinkage swift::getDeclLinkage(const ValueDecl *D) {
|
FormalLinkage swift::getDeclLinkage(const ValueDecl *D) {
|
||||||
const DeclContext *fileContext = D->getDeclContext()->getModuleScopeContext();
|
const DeclContext *fileContext = D->getDeclContext()->getModuleScopeContext();
|
||||||
|
|
||||||
|
|||||||
@@ -669,9 +669,6 @@ void SILInstruction::verifyOperandOwnership() const {
|
|||||||
continue;
|
continue;
|
||||||
SILValue opValue = op.get();
|
SILValue opValue = op.get();
|
||||||
|
|
||||||
// Skip any SILUndef that we see.
|
|
||||||
if (isa<SILUndef>(opValue))
|
|
||||||
continue;
|
|
||||||
auto operandOwnershipKindMap = op.getOwnershipKindMap();
|
auto operandOwnershipKindMap = op.getOwnershipKindMap();
|
||||||
auto valueOwnershipKind = opValue.getOwnershipKind();
|
auto valueOwnershipKind = opValue.getOwnershipKind();
|
||||||
if (operandOwnershipKindMap.canAcceptKind(valueOwnershipKind))
|
if (operandOwnershipKindMap.canAcceptKind(valueOwnershipKind))
|
||||||
@@ -702,11 +699,6 @@ void SILValue::verifyOwnership(SILModule &mod,
|
|||||||
if (DisableOwnershipVerification)
|
if (DisableOwnershipVerification)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If we are SILUndef, just bail. SILUndef can pair with anything. Any uses of
|
|
||||||
// the SILUndef will make sure that the matching checks out.
|
|
||||||
if (isa<SILUndef>(*this))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Since we do not have SILUndef, we now know that getFunction() should return
|
// Since we do not have SILUndef, we now know that getFunction() should return
|
||||||
// a real function. Assert in case this assumption is no longer true.
|
// a real function. Assert in case this assumption is no longer true.
|
||||||
SILFunction *f = (*this)->getFunction();
|
SILFunction *f = (*this)->getFunction();
|
||||||
@@ -743,11 +735,6 @@ bool OwnershipChecker::checkValue(SILValue value) {
|
|||||||
lifetimeEndingUsers.clear();
|
lifetimeEndingUsers.clear();
|
||||||
liveBlocks.clear();
|
liveBlocks.clear();
|
||||||
|
|
||||||
// If we are SILUndef, just bail. SILUndef can pair with anything. Any uses of
|
|
||||||
// the SILUndef will make sure that the matching checks out.
|
|
||||||
if (isa<SILUndef>(value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Since we do not have SILUndef, we now know that getFunction() should return
|
// Since we do not have SILUndef, we now know that getFunction() should return
|
||||||
// a real function. Assert in case this assumption is no longer true.
|
// a real function. Assert in case this assumption is no longer true.
|
||||||
SILFunction *f = value->getFunction();
|
SILFunction *f = value->getFunction();
|
||||||
|
|||||||
34
lib/SIL/SILUndef.cpp
Normal file
34
lib/SIL/SILUndef.cpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
//===--- SILUndef.cpp -----------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This source file is part of the Swift.org open source project
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014 - 2018 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
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "swift/SIL/SILUndef.h"
|
||||||
|
#include "swift/SIL/SILModule.h"
|
||||||
|
|
||||||
|
using namespace swift;
|
||||||
|
|
||||||
|
static ValueOwnershipKind getOwnershipKindForUndef(SILType type, SILModule &m) {
|
||||||
|
if (type.isTrivial(m))
|
||||||
|
return ValueOwnershipKind::Trivial;
|
||||||
|
return ValueOwnershipKind::Owned;
|
||||||
|
}
|
||||||
|
|
||||||
|
SILUndef::SILUndef(SILType type, SILModule &m)
|
||||||
|
: ValueBase(ValueKind::SILUndef, type, IsRepresentative::Yes),
|
||||||
|
ownershipKind(getOwnershipKindForUndef(type, m)) {}
|
||||||
|
|
||||||
|
SILUndef *SILUndef::get(SILType ty, SILModule &m) {
|
||||||
|
// Unique these.
|
||||||
|
SILUndef *&entry = m.UndefValues[ty];
|
||||||
|
if (entry == nullptr)
|
||||||
|
entry = new (m) SILUndef(ty, m);
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
@@ -280,8 +280,8 @@ ValueOwnershipKindClassifier::visitUncheckedOwnershipConversionInst(
|
|||||||
return I->getConversionOwnershipKind();
|
return I->getConversionOwnershipKind();
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueOwnershipKind ValueOwnershipKindClassifier::visitSILUndef(SILUndef *Arg) {
|
ValueOwnershipKind ValueOwnershipKindClassifier::visitSILUndef(SILUndef *arg) {
|
||||||
return ValueOwnershipKind::Any;
|
return arg->getOwnershipKind();
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueOwnershipKind
|
ValueOwnershipKind
|
||||||
|
|||||||
@@ -1619,7 +1619,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateSSAForm() {
|
void updateSSAForm() {
|
||||||
SILSSAUpdater SSAUp;
|
SILSSAUpdater SSAUp(StartBB->getParent()->getModule());
|
||||||
for (auto *origBB : originalPreorderBlocks()) {
|
for (auto *origBB : originalPreorderBlocks()) {
|
||||||
// Update outside used phi values.
|
// Update outside used phi values.
|
||||||
for (auto *arg : origBB->getArguments())
|
for (auto *arg : origBB->getArguments())
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ rewriteNewLoopEntryCheckBlock(SILBasicBlock *Header,
|
|||||||
SILBasicBlock *EntryCheckBlock,
|
SILBasicBlock *EntryCheckBlock,
|
||||||
const llvm::DenseMap<ValueBase *, SILValue> &ValueMap) {
|
const llvm::DenseMap<ValueBase *, SILValue> &ValueMap) {
|
||||||
SmallVector<SILPhiArgument *, 4> InsertedPHIs;
|
SmallVector<SILPhiArgument *, 4> InsertedPHIs;
|
||||||
SILSSAUpdater Updater(&InsertedPHIs);
|
SILSSAUpdater Updater(Header->getParent()->getModule(), &InsertedPHIs);
|
||||||
|
|
||||||
// Fix PHIs (incoming arguments).
|
// Fix PHIs (incoming arguments).
|
||||||
for (auto *Arg : Header->getArguments())
|
for (auto *Arg : Header->getArguments())
|
||||||
|
|||||||
@@ -305,9 +305,9 @@ void LoopCloner::collectLoopLiveOutValues(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
updateSSA(SILLoop *Loop,
|
updateSSA(SILModule &M, SILLoop *Loop,
|
||||||
DenseMap<SILValue, SmallVector<SILValue, 8>> &LoopLiveOutValues) {
|
DenseMap<SILValue, SmallVector<SILValue, 8>> &LoopLiveOutValues) {
|
||||||
SILSSAUpdater SSAUp;
|
SILSSAUpdater SSAUp(M);
|
||||||
for (auto &MapEntry : LoopLiveOutValues) {
|
for (auto &MapEntry : LoopLiveOutValues) {
|
||||||
// Collect out of loop uses of this value.
|
// Collect out of loop uses of this value.
|
||||||
auto OrigValue = MapEntry.first;
|
auto OrigValue = MapEntry.first;
|
||||||
@@ -335,6 +335,7 @@ static bool tryToUnrollLoop(SILLoop *Loop) {
|
|||||||
auto *Preheader = Loop->getLoopPreheader();
|
auto *Preheader = Loop->getLoopPreheader();
|
||||||
if (!Preheader)
|
if (!Preheader)
|
||||||
return false;
|
return false;
|
||||||
|
SILModule &M = Preheader->getParent()->getModule();
|
||||||
|
|
||||||
auto *Latch = Loop->getLoopLatch();
|
auto *Latch = Loop->getLoopLatch();
|
||||||
if (!Latch)
|
if (!Latch)
|
||||||
@@ -409,7 +410,7 @@ static bool tryToUnrollLoop(SILLoop *Loop) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fixup SSA form for loop values used outside the loop.
|
// Fixup SSA form for loop values used outside the loop.
|
||||||
updateSSA(Loop, LoopLiveOutValues);
|
updateSSA(M, Loop, LoopLiveOutValues);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -537,7 +537,7 @@ SILValue AvailableValueAggregator::handlePrimitiveValue(SILType LoadTy,
|
|||||||
|
|
||||||
// If we have an available value, then we want to extract the subelement from
|
// If we have an available value, then we want to extract the subelement from
|
||||||
// the borrowed aggregate before each insertion point.
|
// the borrowed aggregate before each insertion point.
|
||||||
SILSSAUpdater Updater;
|
SILSSAUpdater Updater(B.getModule());
|
||||||
Updater.Initialize(LoadTy);
|
Updater.Initialize(LoadTy);
|
||||||
for (auto *I : Val.getInsertionPoints()) {
|
for (auto *I : Val.getInsertionPoints()) {
|
||||||
// Use the scope and location of the store at the insertion point.
|
// Use the scope and location of the store at the insertion point.
|
||||||
|
|||||||
@@ -595,7 +595,7 @@ static bool removeAndReleaseArray(SingleValueInstruction *NewArrayValue,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// For each store location, insert releases.
|
// For each store location, insert releases.
|
||||||
SILSSAUpdater SSAUp;
|
SILSSAUpdater SSAUp(ArrayDef->getModule());
|
||||||
ValueLifetimeAnalysis::Frontier ArrayFrontier;
|
ValueLifetimeAnalysis::Frontier ArrayFrontier;
|
||||||
if (!VLA.computeFrontier(ArrayFrontier,
|
if (!VLA.computeFrontier(ArrayFrontier,
|
||||||
ValueLifetimeAnalysis::UsersMustPostDomDef,
|
ValueLifetimeAnalysis::UsersMustPostDomDef,
|
||||||
|
|||||||
@@ -1191,7 +1191,7 @@ void BlockState::dump(RLEContext &Ctx) {
|
|||||||
RLEContext::RLEContext(SILFunction *F, SILPassManager *PM, AliasAnalysis *AA,
|
RLEContext::RLEContext(SILFunction *F, SILPassManager *PM, AliasAnalysis *AA,
|
||||||
TypeExpansionAnalysis *TE, PostOrderFunctionInfo *PO,
|
TypeExpansionAnalysis *TE, PostOrderFunctionInfo *PO,
|
||||||
EpilogueARCFunctionInfo *EAFI, bool disableArrayLoads)
|
EpilogueARCFunctionInfo *EAFI, bool disableArrayLoads)
|
||||||
: Fn(F), PM(PM), AA(AA), TE(TE), PO(PO), EAFI(EAFI),
|
: Fn(F), PM(PM), AA(AA), TE(TE), Updater(F->getModule()), PO(PO), EAFI(EAFI),
|
||||||
ArrayType(disableArrayLoads ?
|
ArrayType(disableArrayLoads ?
|
||||||
F->getModule().getASTContext().getArrayDecl() : nullptr)
|
F->getModule().getASTContext().getArrayDecl() : nullptr)
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ static bool isUsedOutsideOfBlock(SILValue V, SILBasicBlock *BB) {
|
|||||||
/// Helper function to perform SSA updates in case of jump threading.
|
/// Helper function to perform SSA updates in case of jump threading.
|
||||||
void swift::updateSSAAfterCloning(BasicBlockCloner &Cloner,
|
void swift::updateSSAAfterCloning(BasicBlockCloner &Cloner,
|
||||||
SILBasicBlock *SrcBB, SILBasicBlock *DestBB) {
|
SILBasicBlock *SrcBB, SILBasicBlock *DestBB) {
|
||||||
SILSSAUpdater SSAUp;
|
SILSSAUpdater SSAUp(SrcBB->getParent()->getModule());
|
||||||
for (auto AvailValPair : Cloner.AvailVals) {
|
for (auto AvailValPair : Cloner.AvailVals) {
|
||||||
ValueBase *Inst = AvailValPair.first;
|
ValueBase *Inst = AvailValPair.first;
|
||||||
if (Inst->use_empty())
|
if (Inst->use_empty())
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ void SILSSAUpdater::deallocateSentinel(SILUndef *D) {
|
|||||||
AlignedFree(D);
|
AlignedFree(D);
|
||||||
}
|
}
|
||||||
|
|
||||||
SILSSAUpdater::SILSSAUpdater(SmallVectorImpl<SILPhiArgument *> *PHIs)
|
SILSSAUpdater::SILSSAUpdater(SILModule &M, SmallVectorImpl<SILPhiArgument *> *PHIs)
|
||||||
: AV(nullptr), PHISentinel(nullptr, deallocateSentinel),
|
: AV(nullptr), PHISentinel(nullptr, deallocateSentinel),
|
||||||
InsertedPHIs(PHIs) {}
|
InsertedPHIs(PHIs), M(M) {}
|
||||||
|
|
||||||
SILSSAUpdater::~SILSSAUpdater() = default;
|
SILSSAUpdater::~SILSSAUpdater() = default;
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ void SILSSAUpdater::Initialize(SILType Ty) {
|
|||||||
ValType = Ty;
|
ValType = Ty;
|
||||||
|
|
||||||
PHISentinel = std::unique_ptr<SILUndef, void (*)(SILUndef *)>(
|
PHISentinel = std::unique_ptr<SILUndef, void (*)(SILUndef *)>(
|
||||||
SILUndef::getSentinelValue(Ty, this), SILSSAUpdater::deallocateSentinel);
|
SILUndef::getSentinelValue(Ty, M, this), SILSSAUpdater::deallocateSentinel);
|
||||||
|
|
||||||
if (!AV)
|
if (!AV)
|
||||||
AV.reset(new AvailableValsTy());
|
AV.reset(new AvailableValsTy());
|
||||||
|
|||||||
@@ -1050,6 +1050,7 @@ sil @class_method_undef_test : $@convention(thin) () -> () {
|
|||||||
bb0:
|
bb0:
|
||||||
%0 = unchecked_ref_cast undef : $Builtin.NativeObject to $SuperKlass
|
%0 = unchecked_ref_cast undef : $Builtin.NativeObject to $SuperKlass
|
||||||
%1 = class_method %0 : $SuperKlass, #SuperKlass.d!1 : (SuperKlass) -> () -> (), $@convention(method) (@guaranteed SuperKlass) -> ()
|
%1 = class_method %0 : $SuperKlass, #SuperKlass.d!1 : (SuperKlass) -> () -> (), $@convention(method) (@guaranteed SuperKlass) -> ()
|
||||||
|
destroy_value %0 : $SuperKlass
|
||||||
%9999 = tuple()
|
%9999 = tuple()
|
||||||
return %9999 : $()
|
return %9999 : $()
|
||||||
}
|
}
|
||||||
@@ -1058,6 +1059,7 @@ sil @forwarding_instruction_undef_test : $@convention(thin) () -> () {
|
|||||||
bb0:
|
bb0:
|
||||||
%0 = unchecked_ref_cast undef : $Builtin.NativeObject to $SuperKlass
|
%0 = unchecked_ref_cast undef : $Builtin.NativeObject to $SuperKlass
|
||||||
%1 = unchecked_ref_cast %0 : $SuperKlass to $Builtin.NativeObject
|
%1 = unchecked_ref_cast %0 : $SuperKlass to $Builtin.NativeObject
|
||||||
|
destroy_value %1 : $Builtin.NativeObject
|
||||||
%9999 = tuple()
|
%9999 = tuple()
|
||||||
return %9999 : $()
|
return %9999 : $()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user