Skip to content

[ownership] Ban ValueOwnershipKind::Any in preparation for eliminated ValueOwnershipKind::Trivial #20819

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions include/swift/SIL/SILUndef.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,29 @@
#include "swift/SIL/SILValue.h"

namespace swift {

class SILArgument;
class SILInstruction;
class SILModule;

class SILUndef : public ValueBase {
void operator=(const SILArgument &) = delete;

void operator delete(void *Ptr, size_t) SWIFT_DELETE_OPERATOR_DELETED;
ValueOwnershipKind ownershipKind;

SILUndef(SILType Ty)
: ValueBase(ValueKind::SILUndef, Ty, IsRepresentative::Yes) {}
SILUndef(SILType type, SILModule &m);

public:
void operator=(const SILArgument &) = delete;
void operator delete(void *, size_t) SWIFT_DELETE_OPERATOR_DELETED;

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);
static SILUndef *get(SILType Ty, SILModule &M) { return get(Ty, &M); }
template <class OwnerTy>
static SILUndef *getSentinelValue(SILType type, SILModule &m, OwnerTy owner) {
return new (*owner) SILUndef(type, m);
}

template<class OwnerTy>
static SILUndef *getSentinelValue(SILType Ty, OwnerTy Owner) { return new (*Owner) SILUndef(Ty); }
ValueOwnershipKind getOwnershipKind() const { return ownershipKind; }

static bool classof(const SILArgument *) = delete;
static bool classof(const SILInstruction *) = delete;
Expand Down
3 changes: 3 additions & 0 deletions include/swift/SILOptimizer/Utils/SILSSAUpdater.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
1 change: 1 addition & 0 deletions lib/SIL/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ add_swift_host_library(swiftSIL STATIC
SILProfiler.cpp
SILSuccessor.cpp
SILType.cpp
SILUndef.cpp
SILValue.cpp
SILVerifier.cpp
SILOwnershipVerifier.cpp
Expand Down
8 changes: 0 additions & 8 deletions lib/SIL/SIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
15 changes: 2 additions & 13 deletions lib/SIL/SILOwnershipVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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();
Expand All @@ -717,6 +709,8 @@ void SILValue::verifyOwnership(SILModule &mod,
if (!f->hasQualifiedOwnership() || !f->shouldVerifyOwnership())
return;

assert(getOwnershipKind() != ValueOwnershipKind::Any &&
"No values should have any ownership anymore");
ErrorBehaviorKind errorBehavior;
if (IsSILOwnershipVerifierTestingEnabled) {
errorBehavior = ErrorBehaviorKind::PrintMessageAndReturnFalse;
Expand All @@ -743,11 +737,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();
Expand Down
34 changes: 34 additions & 0 deletions lib/SIL/SILUndef.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
4 changes: 2 additions & 2 deletions lib/SIL/ValueOwnership.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/LoopTransforms/COWArrayOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1619,7 +1619,7 @@ class RegionCloner : public SILCloner<RegionCloner> {
}

void updateSSAForm() {
SILSSAUpdater SSAUp;
SILSSAUpdater SSAUp(StartBB->getParent()->getModule());
for (auto *origBB : originalPreorderBlocks()) {
// Update outside used phi values.
for (auto *arg : origBB->getArguments())
Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/LoopTransforms/LoopRotate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
7 changes: 4 additions & 3 deletions lib/SILOptimizer/LoopTransforms/LoopUnroll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/Transforms/DeadObjectElimination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/Transforms/SimplifyCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
6 changes: 3 additions & 3 deletions lib/SILOptimizer/Utils/SILSSAUpdater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,17 @@ 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;

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());
Expand Down
2 changes: 2 additions & 0 deletions test/SIL/ownership-verifier/use_verifier.sil
Original file line number Diff line number Diff line change
Expand Up @@ -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 : $()
}
Expand All @@ -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 : $()
}
Expand Down