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 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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ add_swift_host_library(swiftSIL STATIC
|
||||
SILProfiler.cpp
|
||||
SILSuccessor.cpp
|
||||
SILType.cpp
|
||||
SILUndef.cpp
|
||||
SILValue.cpp
|
||||
SILVerifier.cpp
|
||||
SILOwnershipVerifier.cpp
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
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();
|
||||
}
|
||||
|
||||
ValueOwnershipKind ValueOwnershipKindClassifier::visitSILUndef(SILUndef *Arg) {
|
||||
return ValueOwnershipKind::Any;
|
||||
ValueOwnershipKind ValueOwnershipKindClassifier::visitSILUndef(SILUndef *arg) {
|
||||
return arg->getOwnershipKind();
|
||||
}
|
||||
|
||||
ValueOwnershipKind
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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 : $()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user