blob: f2f9eb4191f868e944152e9e5ed46eaf018fa168 [file] [log] [blame]
Chris Lattner7121b802018-07-04 20:45:39 -07001//===- Operation.cpp - MLIR Operation Class -------------------------------===//
2//
3// Copyright 2019 The MLIR Authors.
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16// =============================================================================
17
18#include "mlir/IR/Operation.h"
Chris Lattnerdf1a2fc2018-07-05 21:20:59 -070019#include "AttributeListStorage.h"
Chris Lattnerac591f12018-07-22 21:02:26 -070020#include "mlir/IR/Instructions.h"
21#include "mlir/IR/Statements.h"
Chris Lattner7121b802018-07-04 20:45:39 -070022using namespace mlir;
23
Chris Lattner55315d52018-07-18 19:06:45 -070024Operation::Operation(Identifier name, bool isInstruction,
25 ArrayRef<NamedAttribute> attrs, MLIRContext *context)
26 : nameAndIsInstruction(name, isInstruction) {
Chris Lattnerdf1a2fc2018-07-05 21:20:59 -070027 this->attrs = AttributeListStorage::get(attrs, context);
28
Chris Lattner7121b802018-07-04 20:45:39 -070029#ifndef NDEBUG
30 for (auto elt : attrs)
31 assert(elt.second != nullptr && "Attributes cannot have null entries");
32#endif
33}
34
Chris Lattnerac591f12018-07-22 21:02:26 -070035Operation::~Operation() {}
36
37/// Return the number of operands this operation has.
38unsigned Operation::getNumOperands() const {
39 if (auto *inst = dyn_cast<OperationInst>(this)) {
40 return inst->getNumOperands();
41 } else {
Tatiana Shpeisman60bf7be2018-07-26 18:09:20 -070042 return cast<OperationStmt>(this)->getNumOperands();
Chris Lattnerac591f12018-07-22 21:02:26 -070043 }
44}
45
46SSAValue *Operation::getOperand(unsigned idx) {
47 if (auto *inst = dyn_cast<OperationInst>(this)) {
48 return inst->getOperand(idx);
49 } else {
50 auto *stmt = cast<OperationStmt>(this);
Tatiana Shpeisman60bf7be2018-07-26 18:09:20 -070051 return stmt->getOperand(idx);
Chris Lattnerac591f12018-07-22 21:02:26 -070052 }
53}
54
Chris Lattner68a3fd02018-07-23 10:08:00 -070055void Operation::setOperand(unsigned idx, SSAValue *value) {
56 if (auto *inst = dyn_cast<OperationInst>(this)) {
57 inst->setOperand(idx, cast<CFGValue>(value));
58 } else {
59 auto *stmt = cast<OperationStmt>(this);
Tatiana Shpeisman60bf7be2018-07-26 18:09:20 -070060 stmt->setOperand(idx, cast<MLValue>(value));
Chris Lattner68a3fd02018-07-23 10:08:00 -070061 }
62}
63
Chris Lattnerac591f12018-07-22 21:02:26 -070064/// Return the number of results this operation has.
65unsigned Operation::getNumResults() const {
66 if (auto *inst = dyn_cast<OperationInst>(this)) {
67 return inst->getNumResults();
68 } else {
69 auto *stmt = cast<OperationStmt>(this);
Tatiana Shpeisman60bf7be2018-07-26 18:09:20 -070070 return stmt->getNumResults();
Chris Lattnerac591f12018-07-22 21:02:26 -070071 }
72}
73
74/// Return the indicated result.
75SSAValue *Operation::getResult(unsigned idx) {
76 if (auto *inst = dyn_cast<OperationInst>(this)) {
77 return inst->getResult(idx);
78 } else {
79 auto *stmt = cast<OperationStmt>(this);
Tatiana Shpeisman60bf7be2018-07-26 18:09:20 -070080 return stmt->getResult(idx);
Chris Lattnerac591f12018-07-22 21:02:26 -070081 }
Chris Lattner7121b802018-07-04 20:45:39 -070082}
83
Chris Lattnerdf1a2fc2018-07-05 21:20:59 -070084ArrayRef<NamedAttribute> Operation::getAttrs() const {
85 if (!attrs)
86 return {};
87 return attrs->getElements();
88}
89
Chris Lattnerff0d5902018-07-05 09:12:11 -070090/// If an attribute exists with the specified name, change it to the new
91/// value. Otherwise, add a new attribute with the specified name/value.
Chris Lattnerdf1a2fc2018-07-05 21:20:59 -070092void Operation::setAttr(Identifier name, Attribute *value,
93 MLIRContext *context) {
Chris Lattnerff0d5902018-07-05 09:12:11 -070094 assert(value && "attributes may never be null");
Chris Lattnerdf1a2fc2018-07-05 21:20:59 -070095 auto origAttrs = getAttrs();
96
97 SmallVector<NamedAttribute, 8> newAttrs(origAttrs.begin(), origAttrs.end());
98
Chris Lattnerff0d5902018-07-05 09:12:11 -070099 // If we already have this attribute, replace it.
Chris Lattnerdf1a2fc2018-07-05 21:20:59 -0700100 for (auto &elt : newAttrs)
Chris Lattnerff0d5902018-07-05 09:12:11 -0700101 if (elt.first == name) {
102 elt.second = value;
Chris Lattnerdf1a2fc2018-07-05 21:20:59 -0700103 attrs = AttributeListStorage::get(newAttrs, context);
Chris Lattnerff0d5902018-07-05 09:12:11 -0700104 return;
105 }
106
107 // Otherwise, add it.
Chris Lattnerdf1a2fc2018-07-05 21:20:59 -0700108 newAttrs.push_back({name, value});
109 attrs = AttributeListStorage::get(newAttrs, context);
Chris Lattnerff0d5902018-07-05 09:12:11 -0700110}
111
112/// Remove the attribute with the specified name if it exists. The return
113/// value indicates whether the attribute was present or not.
Chris Lattnerdf1a2fc2018-07-05 21:20:59 -0700114auto Operation::removeAttr(Identifier name, MLIRContext *context)
115 -> RemoveResult {
116 auto origAttrs = getAttrs();
117 for (unsigned i = 0, e = origAttrs.size(); i != e; ++i) {
118 if (origAttrs[i].first == name) {
119 SmallVector<NamedAttribute, 8> newAttrs;
120 newAttrs.reserve(origAttrs.size() - 1);
121 newAttrs.append(origAttrs.begin(), origAttrs.begin() + i);
122 newAttrs.append(origAttrs.begin() + i + 1, origAttrs.end());
123 attrs = AttributeListStorage::get(newAttrs, context);
Chris Lattner7121b802018-07-04 20:45:39 -0700124 return RemoveResult::Removed;
125 }
126 }
127 return RemoveResult::NotFound;
128}