Skip to content

Commit ffa5593

Browse files
authored
Merge pull request swiftlang#35297 from gottesmm/ossa-sil-combine-2
[sil-combine] Fix for Ownership round 2
2 parents 843b25b + cd75a68 commit ffa5593

23 files changed

+1704
-670
lines changed

include/swift/SIL/OwnershipUtils.h

Lines changed: 85 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -82,29 +82,24 @@ class ForwardingOperand {
8282
public:
8383
static Optional<ForwardingOperand> get(Operand *use);
8484

85-
Operand *getUse() const { return use; }
8685
OwnershipConstraint getOwnershipConstraint() const {
8786
// We use a force unwrap since a ForwardingOperand should always have an
8887
// ownership constraint.
8988
return use->getOwnershipConstraint();
9089
}
90+
9191
ValueOwnershipKind getOwnershipKind() const;
9292
void setOwnershipKind(ValueOwnershipKind newKind) const;
9393
void replaceOwnershipKind(ValueOwnershipKind oldKind,
9494
ValueOwnershipKind newKind) const;
9595

96-
const OwnershipForwardingInst *operator->() const {
97-
return cast<OwnershipForwardingInst>(use->getUser());
98-
}
99-
OwnershipForwardingInst *operator->() {
100-
return cast<OwnershipForwardingInst>(use->getUser());
101-
}
102-
const OwnershipForwardingInst &operator*() const {
103-
return *cast<OwnershipForwardingInst>(use->getUser());
104-
}
105-
OwnershipForwardingInst &operator*() {
106-
return *cast<OwnershipForwardingInst>(use->getUser());
107-
}
96+
const Operand *operator->() const { return use; }
97+
98+
Operand *operator->() { return use; }
99+
100+
const Operand &operator*() const { return *use; }
101+
102+
Operand &operator*() { return *use; }
108103

109104
/// Call \p visitor with each value that contains the final forwarded
110105
/// ownership of. E.x.: result of a unchecked_ref_cast, phi arguments of a
@@ -473,6 +468,13 @@ struct BorrowedValue {
473468
return foundAnyReborrows;
474469
}
475470

471+
// Helpers to allow a BorrowedValue to easily be used as a SILValue
472+
// programatically.
473+
SILValue operator->() { return value; }
474+
SILValue operator->() const { return value; }
475+
SILValue operator*() { return value; }
476+
SILValue operator*() const { return value; }
477+
476478
private:
477479
/// Internal constructor for failable static constructor. Please do not expand
478480
/// its usage since it assumes the code passed in is well formed.
@@ -505,6 +507,7 @@ Optional<BorrowedValue> getSingleBorrowIntroducingValue(SILValue inputValue);
505507
class InteriorPointerOperandKind {
506508
public:
507509
enum Kind : uint8_t {
510+
Invalid=0,
508511
RefElementAddr,
509512
RefTailAddr,
510513
OpenExistentialBox,
@@ -516,18 +519,38 @@ class InteriorPointerOperandKind {
516519
public:
517520
InteriorPointerOperandKind(Kind newValue) : value(newValue) {}
518521

519-
operator Kind() const { return value; }
522+
operator Kind() const {
523+
return value;
524+
}
525+
526+
bool isValid() const { return value != Kind::Invalid; }
520527

521-
static Optional<InteriorPointerOperandKind> get(Operand *use) {
528+
static InteriorPointerOperandKind get(Operand *use) {
522529
switch (use->getUser()->getKind()) {
523530
default:
524-
return None;
531+
return Kind::Invalid;
525532
case SILInstructionKind::RefElementAddrInst:
526-
return InteriorPointerOperandKind(RefElementAddr);
533+
return Kind::RefElementAddr;
527534
case SILInstructionKind::RefTailAddrInst:
528-
return InteriorPointerOperandKind(RefTailAddr);
535+
return Kind::RefTailAddr;
529536
case SILInstructionKind::OpenExistentialBoxInst:
530-
return InteriorPointerOperandKind(OpenExistentialBox);
537+
return Kind::OpenExistentialBox;
538+
}
539+
}
540+
541+
/// Given a \p value that is a result of an instruction with an interior
542+
/// pointer operand, return the interior pointer operand kind that would be
543+
/// appropriate for that operand.
544+
static InteriorPointerOperandKind inferFromResult(SILValue value) {
545+
switch (value->getKind()) {
546+
default:
547+
return Kind::Invalid;
548+
case ValueKind::RefElementAddrInst:
549+
return Kind::RefElementAddr;
550+
case ValueKind::RefTailAddrInst:
551+
return Kind::RefTailAddr;
552+
case ValueKind::OpenExistentialBoxInst:
553+
return Kind::OpenExistentialBox;
531554
}
532555
}
533556

@@ -544,14 +567,42 @@ struct InteriorPointerOperand {
544567
InteriorPointerOperandKind kind;
545568

546569
InteriorPointerOperand(Operand *op)
547-
: operand(op), kind(*InteriorPointerOperandKind::get(op)) {}
570+
: operand(op), kind(InteriorPointerOperandKind::get(op)) {
571+
assert(kind.isValid());
572+
}
548573

549-
/// If value is a borrow introducer return it after doing some checks.
574+
/// If \p op has a user that is an interior pointer, return a valid
575+
/// value. Otherwise, return None.
550576
static Optional<InteriorPointerOperand> get(Operand *op) {
551577
auto kind = InteriorPointerOperandKind::get(op);
552578
if (!kind)
553579
return None;
554-
return InteriorPointerOperand(op, *kind);
580+
return InteriorPointerOperand(op, kind);
581+
}
582+
583+
/// If \p val is a result of an instruction that is an interior pointer,
584+
/// return an interor pointer operand based off of the base value operand of
585+
/// the instruction.
586+
static Optional<InteriorPointerOperand>
587+
inferFromResult(SILValue resultValue) {
588+
auto kind = InteriorPointerOperandKind::inferFromResult(resultValue);
589+
590+
// NOTE: We use an exhaustive switch here to allow for further interior
591+
// pointer operand having instructions to make the interior pointer
592+
// operand's argument index arbitrary.
593+
switch (kind) {
594+
case InteriorPointerOperandKind::Invalid:
595+
// We do not have a valid instruction, so return None.
596+
return None;
597+
case InteriorPointerOperandKind::RefElementAddr:
598+
case InteriorPointerOperandKind::RefTailAddr:
599+
case InteriorPointerOperandKind::OpenExistentialBox: {
600+
// Ok, we have a valid instruction. Return the relevant operand.
601+
auto *op =
602+
&cast<SingleValueInstruction>(resultValue)->getAllOperands()[0];
603+
return InteriorPointerOperand(op, kind);
604+
}
605+
}
555606
}
556607

557608
/// Return the end scope of all borrow introducers of the parent value of this
@@ -569,8 +620,15 @@ struct InteriorPointerOperand {
569620
return true;
570621
}
571622

623+
/// Return the base BorrowedValue of the incoming value's operand.
624+
Optional<BorrowedValue> getSingleBaseValue() const {
625+
return getSingleBorrowIntroducingValue(operand->get());
626+
}
627+
572628
SILValue getProjectedAddress() const {
573629
switch (kind) {
630+
case InteriorPointerOperandKind::Invalid:
631+
llvm_unreachable("Calling method on invalid?!");
574632
case InteriorPointerOperandKind::RefElementAddr:
575633
return cast<RefElementAddrInst>(operand->getUser());
576634
case InteriorPointerOperandKind::RefTailAddr:
@@ -591,6 +649,11 @@ struct InteriorPointerOperand {
591649
bool getImplicitUses(SmallVectorImpl<Operand *> &foundUses,
592650
std::function<void(Operand *)> *onError = nullptr);
593651

652+
Operand *operator->() { return operand; }
653+
const Operand *operator->() const { return operand; }
654+
Operand *operator*() { return operand; }
655+
const Operand *operator*() const { return operand; }
656+
594657
private:
595658
/// Internal constructor for failable static constructor. Please do not expand
596659
/// its usage since it assumes the code passed in is well formed.

include/swift/SIL/SILInstruction.h

Lines changed: 62 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,19 @@ class SILInstruction
541541
SILValue getOperand(unsigned Num) const {
542542
return getAllOperands()[Num].get();
543543
}
544-
Operand &getOperandRef(unsigned Num) { return getAllOperands()[Num]; }
544+
545+
/// Return the ith mutable operand of this instruction.
546+
///
547+
/// Equivalent to performing getAllOperands()[index];
548+
Operand &getOperandRef(unsigned index) { return getAllOperands()[index]; }
549+
550+
/// Return the ith operand of this instruction.
551+
///
552+
/// Equivalent to performing getAllOperands()[index];
553+
const Operand &getOperandRef(unsigned index) const {
554+
return getAllOperands()[index];
555+
}
556+
545557
void setOperand(unsigned Num, SILValue V) { getAllOperands()[Num].set(V); }
546558
void swapOperands(unsigned Num1, unsigned Num2) {
547559
getAllOperands()[Num1].swap(getAllOperands()[Num2]);
@@ -917,32 +929,32 @@ inline SingleValueInstruction *SILNode::castToSingleValueInstruction() {
917929
///
918930
/// NOTE: We assume that the constructor for the instruction subclass that
919931
/// initializes the kind field on our object is run before our constructor runs.
920-
class OwnershipForwardingInst {
932+
class OwnershipForwardingMixin {
921933
ValueOwnershipKind ownershipKind;
922934

923935
protected:
924-
OwnershipForwardingInst(SILInstructionKind kind,
925-
ValueOwnershipKind ownershipKind)
936+
OwnershipForwardingMixin(SILInstructionKind kind,
937+
ValueOwnershipKind ownershipKind)
926938
: ownershipKind(ownershipKind) {
927-
assert(classof(kind) && "Invalid subclass?!");
939+
assert(isa(kind) && "Invalid subclass?!");
928940
}
929941

930942
public:
931943
ValueOwnershipKind getOwnershipKind() const { return ownershipKind; }
932944

933945
void setOwnershipKind(ValueOwnershipKind newKind) { ownershipKind = newKind; }
934946

935-
static bool classof(const SILNode *node) {
936-
if (auto *i = dyn_cast<SILInstruction>(node))
937-
return classof(i);
947+
/// Defined inline below due to forward declaration issues.
948+
static OwnershipForwardingMixin *get(SILInstruction *inst);
949+
/// Defined inline below due to forward declaration issues.
950+
static bool isa(SILInstructionKind kind);
951+
static bool isa(const SILInstruction *inst) { return isa(inst->getKind()); }
952+
static bool isa(const SILNode *node) {
953+
node = node->getRepresentativeSILNodeInObject();
954+
if (auto *i = dyn_cast<const SILInstruction>(node))
955+
return isa(i);
938956
return false;
939957
}
940-
941-
// Defined inline below due to forward declaration issues.
942-
static bool classof(const SILInstruction *inst);
943-
944-
/// Define inline below due to forward declaration issues.
945-
static bool classof(SILInstructionKind kind);
946958
};
947959

948960
/// A single value inst that forwards a static ownership from one (or all) of
@@ -952,14 +964,14 @@ class OwnershipForwardingInst {
952964
/// explicitly using setOwnershipKind().
953965
class FirstArgOwnershipForwardingSingleValueInst
954966
: public SingleValueInstruction,
955-
public OwnershipForwardingInst {
967+
public OwnershipForwardingMixin {
956968
protected:
957969
FirstArgOwnershipForwardingSingleValueInst(SILInstructionKind kind,
958970
SILDebugLocation debugLoc,
959971
SILType ty,
960972
ValueOwnershipKind ownershipKind)
961973
: SingleValueInstruction(kind, debugLoc, ty),
962-
OwnershipForwardingInst(kind, ownershipKind) {
974+
OwnershipForwardingMixin(kind, ownershipKind) {
963975
assert(classof(kind) && "classof missing new subclass?!");
964976
}
965977

@@ -1084,14 +1096,14 @@ FirstArgOwnershipForwardingSingleValueInst::classof(SILInstructionKind kind) {
10841096

10851097
class AllArgOwnershipForwardingSingleValueInst
10861098
: public SingleValueInstruction,
1087-
public OwnershipForwardingInst {
1099+
public OwnershipForwardingMixin {
10881100
protected:
10891101
AllArgOwnershipForwardingSingleValueInst(SILInstructionKind kind,
10901102
SILDebugLocation debugLoc,
10911103
SILType ty,
10921104
ValueOwnershipKind ownershipKind)
10931105
: SingleValueInstruction(kind, debugLoc, ty),
1094-
OwnershipForwardingInst(kind, ownershipKind) {
1106+
OwnershipForwardingMixin(kind, ownershipKind) {
10951107
assert(classof(kind) && "classof missing new subclass?!");
10961108
}
10971109

@@ -4668,13 +4680,13 @@ class ConversionInst : public SingleValueInstruction {
46684680
/// A conversion inst that produces a static OwnershipKind set upon the
46694681
/// instruction's construction.
46704682
class OwnershipForwardingConversionInst : public ConversionInst,
4671-
public OwnershipForwardingInst {
4683+
public OwnershipForwardingMixin {
46724684
protected:
46734685
OwnershipForwardingConversionInst(SILInstructionKind kind,
46744686
SILDebugLocation debugLoc, SILType ty,
46754687
ValueOwnershipKind ownershipKind)
46764688
: ConversionInst(kind, debugLoc, ty),
4677-
OwnershipForwardingInst(kind, ownershipKind) {
4689+
OwnershipForwardingMixin(kind, ownershipKind) {
46784690
assert(classof(kind) && "classof missing subclass?!");
46794691
}
46804692

@@ -5872,15 +5884,15 @@ class SelectEnumInstBase
58725884

58735885
/// A select enum inst that produces a static OwnershipKind.
58745886
class OwnershipForwardingSelectEnumInstBase : public SelectEnumInstBase,
5875-
public OwnershipForwardingInst {
5887+
public OwnershipForwardingMixin {
58765888
protected:
58775889
OwnershipForwardingSelectEnumInstBase(
58785890
SILInstructionKind kind, SILDebugLocation debugLoc, SILType type,
58795891
bool defaultValue, Optional<ArrayRef<ProfileCounter>> caseCounts,
58805892
ProfileCounter defaultCount, ValueOwnershipKind ownershipKind)
58815893
: SelectEnumInstBase(kind, debugLoc, type, defaultValue, caseCounts,
58825894
defaultCount),
5883-
OwnershipForwardingInst(kind, ownershipKind) {
5895+
OwnershipForwardingMixin(kind, ownershipKind) {
58845896
assert(classof(kind) && "classof missing subclass");
58855897
}
58865898

@@ -7612,12 +7624,13 @@ class TermInst : public NonValueInstruction {
76127624
};
76137625

76147626
class OwnershipForwardingTermInst : public TermInst,
7615-
public OwnershipForwardingInst {
7627+
public OwnershipForwardingMixin {
76167628
protected:
76177629
OwnershipForwardingTermInst(SILInstructionKind kind,
76187630
SILDebugLocation debugLoc,
76197631
ValueOwnershipKind ownershipKind)
7620-
: TermInst(kind, debugLoc), OwnershipForwardingInst(kind, ownershipKind) {
7632+
: TermInst(kind, debugLoc),
7633+
OwnershipForwardingMixin(kind, ownershipKind) {
76217634
assert(classof(kind));
76227635
}
76237636

@@ -9081,13 +9094,13 @@ SILFunction *ApplyInstBase<Impl, Base, false>::getCalleeFunction() const {
90819094

90829095
class OwnershipForwardingMultipleValueInstruction
90839096
: public MultipleValueInstruction,
9084-
public OwnershipForwardingInst {
9097+
public OwnershipForwardingMixin {
90859098
public:
90869099
OwnershipForwardingMultipleValueInstruction(SILInstructionKind kind,
90879100
SILDebugLocation loc,
90889101
ValueOwnershipKind ownershipKind)
90899102
: MultipleValueInstruction(kind, loc),
9090-
OwnershipForwardingInst(kind, ownershipKind) {
9103+
OwnershipForwardingMixin(kind, ownershipKind) {
90919104
assert(classof(kind) && "Missing subclass from classof?!");
90929105
}
90939106

@@ -9276,16 +9289,7 @@ inline bool Operand::isTypeDependent() const {
92769289
return getUser()->isTypeDependentOperand(*this);
92779290
}
92789291

9279-
inline bool OwnershipForwardingInst::classof(const SILInstruction *inst) {
9280-
return FirstArgOwnershipForwardingSingleValueInst::classof(inst) ||
9281-
AllArgOwnershipForwardingSingleValueInst::classof(inst) ||
9282-
OwnershipForwardingTermInst::classof(inst) ||
9283-
OwnershipForwardingConversionInst::classof(inst) ||
9284-
OwnershipForwardingSelectEnumInstBase::classof(inst) ||
9285-
OwnershipForwardingMultipleValueInstruction::classof(inst);
9286-
}
9287-
9288-
inline bool OwnershipForwardingInst::classof(SILInstructionKind kind) {
9292+
inline bool OwnershipForwardingMixin::isa(SILInstructionKind kind) {
92899293
return FirstArgOwnershipForwardingSingleValueInst::classof(kind) ||
92909294
AllArgOwnershipForwardingSingleValueInst::classof(kind) ||
92919295
OwnershipForwardingTermInst::classof(kind) ||
@@ -9294,6 +9298,28 @@ inline bool OwnershipForwardingInst::classof(SILInstructionKind kind) {
92949298
OwnershipForwardingMultipleValueInstruction::classof(kind);
92959299
}
92969300

9301+
inline OwnershipForwardingMixin *
9302+
OwnershipForwardingMixin::get(SILInstruction *inst) {
9303+
// I am purposely performing this cast in this manner rather than reinterpret
9304+
// casting to OwnershipForwardingMixin to ensure that we offset to the
9305+
// appropriate offset inside of inst instead of converting inst's current
9306+
// location to an OwnershipForwardingMixin which would be incorrect.
9307+
if (auto *result = dyn_cast<FirstArgOwnershipForwardingSingleValueInst>(inst))
9308+
return result;
9309+
if (auto *result = dyn_cast<AllArgOwnershipForwardingSingleValueInst>(inst))
9310+
return result;
9311+
if (auto *result = dyn_cast<OwnershipForwardingTermInst>(inst))
9312+
return result;
9313+
if (auto *result = dyn_cast<OwnershipForwardingConversionInst>(inst))
9314+
return result;
9315+
if (auto *result = dyn_cast<OwnershipForwardingSelectEnumInstBase>(inst))
9316+
return result;
9317+
if (auto *result =
9318+
dyn_cast<OwnershipForwardingMultipleValueInstruction>(inst))
9319+
return result;
9320+
return nullptr;
9321+
}
9322+
92979323
} // end swift namespace
92989324

92999325
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)