[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 SILUndef : public ValueBase {
SILUndef(SILType Ty)
: ValueBase(ValueKind::SILUndef, Ty, IsRepresentative::Yes) {}
ValueOwnershipKind ownershipKind;
SILUndef(SILType type, SILModule &m);
public:
void operator=(const SILArgument &) = delete;
@@ -33,8 +34,12 @@ public:
static SILUndef *get(SILType ty, SILModule &m);
static SILUndef *get(SILType ty, SILModule *m) { return get(ty, *m); }
template<class OwnerTy>
static SILUndef *getSentinelValue(SILType Ty, OwnerTy Owner) { return new (*Owner) SILUndef(Ty); }
template <class OwnerTy>
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 SILInstruction *) = delete;

View File

@@ -51,12 +51,15 @@ class SILSSAUpdater {
// If not null updated with inserted 'phi' nodes (SILArgument).
SmallVectorImpl<SILPhiArgument *> *InsertedPHIs;
SILModule &M;
// Not copyable.
void operator=(const SILSSAUpdater &) = delete;
SILSSAUpdater(const SILSSAUpdater &) = delete;
public:
explicit SILSSAUpdater(
SILModule &M,
SmallVectorImpl<SILPhiArgument *> *InsertedPHIs = nullptr);
~SILSSAUpdater();

View File

@@ -37,6 +37,7 @@ add_swift_host_library(swiftSIL STATIC
SILProfiler.cpp
SILSuccessor.cpp
SILType.cpp
SILUndef.cpp
SILValue.cpp
SILVerifier.cpp
SILOwnershipVerifier.cpp

View File

@@ -30,14 +30,6 @@
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) {
const DeclContext *fileContext = D->getDeclContext()->getModuleScopeContext();

View File

@@ -669,9 +669,6 @@ void SILInstruction::verifyOperandOwnership() const {
continue;
SILValue opValue = op.get();
// Skip any SILUndef that we see.
if (isa<SILUndef>(opValue))
continue;
auto operandOwnershipKindMap = op.getOwnershipKindMap();
auto valueOwnershipKind = opValue.getOwnershipKind();
if (operandOwnershipKindMap.canAcceptKind(valueOwnershipKind))
@@ -702,11 +699,6 @@ void SILValue::verifyOwnership(SILModule &mod,
if (DisableOwnershipVerification)
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
// a real function. Assert in case this assumption is no longer true.
SILFunction *f = (*this)->getFunction();
@@ -743,11 +735,6 @@ bool OwnershipChecker::checkValue(SILValue value) {
lifetimeEndingUsers.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
// a real function. Assert in case this assumption is no longer true.
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();
}
ValueOwnershipKind ValueOwnershipKindClassifier::visitSILUndef(SILUndef *Arg) {
return ValueOwnershipKind::Any;
ValueOwnershipKind ValueOwnershipKindClassifier::visitSILUndef(SILUndef *arg) {
return arg->getOwnershipKind();
}
ValueOwnershipKind

View File

@@ -1619,7 +1619,7 @@ protected:
}
void updateSSAForm() {
SILSSAUpdater SSAUp;
SILSSAUpdater SSAUp(StartBB->getParent()->getModule());
for (auto *origBB : originalPreorderBlocks()) {
// Update outside used phi values.
for (auto *arg : origBB->getArguments())

View File

@@ -174,7 +174,7 @@ rewriteNewLoopEntryCheckBlock(SILBasicBlock *Header,
SILBasicBlock *EntryCheckBlock,
const llvm::DenseMap<ValueBase *, SILValue> &ValueMap) {
SmallVector<SILPhiArgument *, 4> InsertedPHIs;
SILSSAUpdater Updater(&InsertedPHIs);
SILSSAUpdater Updater(Header->getParent()->getModule(), &InsertedPHIs);
// Fix PHIs (incoming arguments).
for (auto *Arg : Header->getArguments())

View File

@@ -305,9 +305,9 @@ void LoopCloner::collectLoopLiveOutValues(
}
static void
updateSSA(SILLoop *Loop,
updateSSA(SILModule &M, SILLoop *Loop,
DenseMap<SILValue, SmallVector<SILValue, 8>> &LoopLiveOutValues) {
SILSSAUpdater SSAUp;
SILSSAUpdater SSAUp(M);
for (auto &MapEntry : LoopLiveOutValues) {
// Collect out of loop uses of this value.
auto OrigValue = MapEntry.first;
@@ -335,6 +335,7 @@ static bool tryToUnrollLoop(SILLoop *Loop) {
auto *Preheader = Loop->getLoopPreheader();
if (!Preheader)
return false;
SILModule &M = Preheader->getParent()->getModule();
auto *Latch = Loop->getLoopLatch();
if (!Latch)
@@ -409,7 +410,7 @@ static bool tryToUnrollLoop(SILLoop *Loop) {
}
// Fixup SSA form for loop values used outside the loop.
updateSSA(Loop, LoopLiveOutValues);
updateSSA(M, Loop, LoopLiveOutValues);
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
// the borrowed aggregate before each insertion point.
SILSSAUpdater Updater;
SILSSAUpdater Updater(B.getModule());
Updater.Initialize(LoadTy);
for (auto *I : Val.getInsertionPoints()) {
// 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;
}
// For each store location, insert releases.
SILSSAUpdater SSAUp;
SILSSAUpdater SSAUp(ArrayDef->getModule());
ValueLifetimeAnalysis::Frontier ArrayFrontier;
if (!VLA.computeFrontier(ArrayFrontier,
ValueLifetimeAnalysis::UsersMustPostDomDef,

View File

@@ -1191,7 +1191,7 @@ void BlockState::dump(RLEContext &Ctx) {
RLEContext::RLEContext(SILFunction *F, SILPassManager *PM, AliasAnalysis *AA,
TypeExpansionAnalysis *TE, PostOrderFunctionInfo *PO,
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 ?
F->getModule().getASTContext().getArrayDecl() : nullptr)
#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.
void swift::updateSSAAfterCloning(BasicBlockCloner &Cloner,
SILBasicBlock *SrcBB, SILBasicBlock *DestBB) {
SILSSAUpdater SSAUp;
SILSSAUpdater SSAUp(SrcBB->getParent()->getModule());
for (auto AvailValPair : Cloner.AvailVals) {
ValueBase *Inst = AvailValPair.first;
if (Inst->use_empty())

View File

@@ -34,9 +34,9 @@ void SILSSAUpdater::deallocateSentinel(SILUndef *D) {
AlignedFree(D);
}
SILSSAUpdater::SILSSAUpdater(SmallVectorImpl<SILPhiArgument *> *PHIs)
SILSSAUpdater::SILSSAUpdater(SILModule &M, SmallVectorImpl<SILPhiArgument *> *PHIs)
: AV(nullptr), PHISentinel(nullptr, deallocateSentinel),
InsertedPHIs(PHIs) {}
InsertedPHIs(PHIs), M(M) {}
SILSSAUpdater::~SILSSAUpdater() = default;
@@ -44,7 +44,7 @@ void SILSSAUpdater::Initialize(SILType Ty) {
ValType = Ty;
PHISentinel = std::unique_ptr<SILUndef, void (*)(SILUndef *)>(
SILUndef::getSentinelValue(Ty, this), SILSSAUpdater::deallocateSentinel);
SILUndef::getSentinelValue(Ty, M, this), SILSSAUpdater::deallocateSentinel);
if (!AV)
AV.reset(new AvailableValsTy());

View File

@@ -1050,6 +1050,7 @@ sil @class_method_undef_test : $@convention(thin) () -> () {
bb0:
%0 = unchecked_ref_cast undef : $Builtin.NativeObject to $SuperKlass
%1 = class_method %0 : $SuperKlass, #SuperKlass.d!1 : (SuperKlass) -> () -> (), $@convention(method) (@guaranteed SuperKlass) -> ()
destroy_value %0 : $SuperKlass
%9999 = tuple()
return %9999 : $()
}
@@ -1058,6 +1059,7 @@ sil @forwarding_instruction_undef_test : $@convention(thin) () -> () {
bb0:
%0 = unchecked_ref_cast undef : $Builtin.NativeObject to $SuperKlass
%1 = unchecked_ref_cast %0 : $SuperKlass to $Builtin.NativeObject
destroy_value %1 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}