[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:
Michael Gottesman
2018-11-26 16:39:22 -08:00
parent 83c4266e18
commit c9bb5161a1
16 changed files with 64 additions and 39 deletions

View File

@@ -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;

View File

@@ -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();

View File

@@ -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

View File

@@ -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();

View File

@@ -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
View 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;
}

View File

@@ -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

View File

@@ -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())

View File

@@ -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())

View File

@@ -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;
} }

View File

@@ -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.

View File

@@ -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,

View File

@@ -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

View File

@@ -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())

View File

@@ -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());

View File

@@ -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 : $()
} }