File: OwnershipPhiOperand.h

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (125 lines) | stat: -rw-r--r-- 3,637 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//===--- OwnershipPhiOperand.h --------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 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
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_SILOPTIMIZER_SEMANTICARC_OWNERSHIPPHIOPERAND_H
#define SWIFT_SILOPTIMIZER_SEMANTICARC_OWNERSHIPPHIOPERAND_H

#include "swift/Basic/STLExtras.h"
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILBasicBlock.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SIL/SILUndef.h"
#include "swift/SIL/SILValue.h"

namespace swift {
namespace semanticarc {

/// The operand of a "phi" in the induced ownership graph of a def-use graph.
///
/// Some examples: br, struct, tuple.
class LLVM_LIBRARY_VISIBILITY OwnershipPhiOperand {
public:
  enum Kind {
    Branch,
    Struct,
    Tuple,
  };

private:
  Operand *op;

  OwnershipPhiOperand(Operand *op) : op(op) {}

public:
  static std::optional<OwnershipPhiOperand> get(const Operand *op) {
    switch (op->getUser()->getKind()) {
    case SILInstructionKind::BranchInst:
    case SILInstructionKind::StructInst:
    case SILInstructionKind::TupleInst:
      return {{const_cast<Operand *>(op)}};
    default:
      return std::nullopt;
    }
  }

  Kind getKind() const {
    switch (op->getUser()->getKind()) {
    case SILInstructionKind::BranchInst:
      return Kind::Branch;
    case SILInstructionKind::StructInst:
      return Kind::Struct;
    case SILInstructionKind::TupleInst:
      return Kind::Tuple;
    default:
      llvm_unreachable("unhandled case?!");
    }
  }

  operator const Operand *() const { return op; }
  operator Operand *() { return op; }

  Operand *getOperand() const { return op; }
  SILValue getValue() const { return op->get(); }
  SILType getType() const { return op->get()->getType(); }

  unsigned getOperandNumber() const { return op->getOperandNumber(); }

  void markUndef() & { op->set(SILUndef::get(getValue())); }

  SILInstruction *getInst() const { return op->getUser(); }

  /// Return true if this phi consumes a borrow.
  ///
  /// If so, we may need to insert an extra begin_borrow to balance the +1 when
  /// converting owned ownership phis to guaranteed ownership phis.
  bool isGuaranteedConsuming() const {
    switch (getKind()) {
    case Kind::Branch:
      return true;
    case Kind::Tuple:
    case Kind::Struct:
      return false;
    }
    llvm_unreachable("unhandled operand kind!");
  }

  bool operator<(const OwnershipPhiOperand &other) const {
    return op < other.op;
  }

  bool operator==(const OwnershipPhiOperand &other) const {
    return op == other.op;
  }

  bool visitResults(function_ref<bool(SILValue)> visitor) const {
    switch (getKind()) {
    case Kind::Struct:
      return visitor(cast<StructInst>(getInst()));
    case Kind::Tuple:
      return visitor(cast<TupleInst>(getInst()));
    case Kind::Branch: {
      auto *br = cast<BranchInst>(getInst());
      unsigned opNum = getOperandNumber();
      return llvm::all_of(
          br->getSuccessorBlocks(), [&](SILBasicBlock *succBlock) {
            return visitor(succBlock->getSILPhiArguments()[opNum]);
          });
    }
    }
    llvm_unreachable("unhandled operand kind!");
  }
};

} // namespace semanticarc
} // namespace swift

#endif // SWIFT_SILOPTIMIZER_SEMANTICARC_OWNERSHIPPHIOPERAND_H