operation.h 4.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// Copyright (c) 2023 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

17
#include <ostream>
18
#include <vector>
19
#include "paddle/ir/core/block.h"
20 21 22
#include "paddle/ir/core/op_info.h"
#include "paddle/ir/core/operation_utils.h"
#include "paddle/ir/core/type.h"
23 24

namespace ir {
25
class OpBase;
26
class Program;
27 28
class OpOperand;
class OpResult;
29

30
class IR_API alignas(8) Operation final {
31 32 33 34
 public:
  ///
  /// \brief Malloc memory and construct objects in the following order:
  /// OpResultImpls|Operation|OpOperandImpls.
35 36
  /// NOTE: Similar to new and delete, the destroy() and the create() need to be
  /// used in conjunction.
37
  ///
38
  static Operation *Create(const std::vector<ir::OpResult> &inputs,
39
                           const AttributeMap &attributes,
40 41 42
                           const std::vector<ir::Type> &output_types,
                           ir::OpInfo op_info,
                           size_t num_regions = 0);
43
  static Operation *Create(OperationArgument &&op_argument);
44

45
  ///
C
co63oc 已提交
46
  /// \brief Destroy the operation objects and free memory by create().
47
  ///
48
  void Destroy();
49

50
  IrContext *ir_context() const;
51

52
  Dialect *dialect() const;
53

54 55
  OpResult result(uint32_t index) const;

56 57 58
  OpOperand op_operand(uint32_t index) const;

  Value operand(uint32_t index) const;
59

60 61 62
  /// Returns the region held by this operation at position 'index'.
  Region &region(unsigned index);

63
  void Print(std::ostream &os);
64

65 66
  const AttributeMap &attributes() const { return attributes_; }

67
  void set_attribute(const std::string &key, Attribute value) {
68 69
    attributes_[key] = value;
  }
70

71 72 73 74 75 76
  Attribute attribute(const std::string &key) const;

  bool HasAttribute(const std::string &key) const {
    return attributes_.find(key) != attributes_.end();
  }

77
  ir::OpInfo info() const { return info_; }
78

79 80 81 82
  uint32_t num_results() const { return num_results_; }

  uint32_t num_operands() const { return num_operands_; }

83 84
  uint32_t num_regions() const { return num_regions_; }

85
  std::string name() const;
86

87
  template <typename T>
Z
zhangbo9674 已提交
88
  T dyn_cast() {
89 90 91 92 93
    return CastUtil<T>::call(this);
  }

  template <typename Trait>
  bool HasTrait() const {
94
    return info_.HasTrait<Trait>();
95 96 97 98
  }

  template <typename Interface>
  bool HasInterface() const {
99
    return info_.HasInterface<Interface>();
100
  }
101

102
  Block *GetParent() const { return parent_; }
103

104 105 106 107 108
  Region *GetParentRegion() const;

  Operation *GetParentOp() const;

  Program *GetParentProgram();
109

110 111
  operator Block::iterator() { return position_; }

112 113
  operator Block::const_iterator() const { return position_; }

114 115 116 117 118 119 120
  /// Replace all uses of results of this operation with the provided 'values'.
  void ReplaceAllUsesWith(const std::vector<Value> &values);

  inline void ReplaceAllUsesWith(Value value) {
    ReplaceAllUsesWith(std::vector<Value>{value});
  }

121 122
  void Verify();

123
 private:
124 125 126
  Operation(const AttributeMap &attribute,
            ir::OpInfo op_info,
            uint32_t num_results,
127
            uint32_t num_operands,
128
            uint32_t num_regions);
129 130 131

  template <typename T, typename Enabler = void>
  struct CastUtil {
Z
zhangbo9674 已提交
132
    static T call(Operation *op) {
133
      throw("Can't dyn_cast to T, T should be a Op or Trait or Interface");
134
    }
135
  };
136

137
  // Allow access to 'SetParent'.
138
  friend class Block;
139
  void SetParent(Block *parent, const Block::iterator &position);
140

141
  template <typename T>
142 143 144
  struct CastUtil<
      T,
      typename std::enable_if<std::is_base_of<OpBase, T>::value>::type> {
Z
zhangbo9674 已提交
145
    static T call(Operation *op) { return T::dyn_cast(op); }
146
  };
147

148
  AttributeMap attributes_;
149

150
  OpInfo info_;
151

152 153 154
  const uint32_t num_results_ = 0;
  const uint32_t num_operands_ = 0;
  const uint32_t num_regions_ = 0;
155

156 157
  Region *regions_{nullptr};
  Block *parent_{nullptr};
158
  Block::iterator position_;
159 160 161
};

}  // namespace ir