blob: 92a01baadf2f75fbe3b679fa2c271c8b6ef0eb16 [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 {
42 auto *stmt = cast<OperationStmt>(this);
43 (void)stmt;
44 // TODO: Add operands to OperationStmt.
45 return 0;
46 }
47}
48
49SSAValue *Operation::getOperand(unsigned idx) {
50 if (auto *inst = dyn_cast<OperationInst>(this)) {
51 return inst->getOperand(idx);
52 } else {
53 auto *stmt = cast<OperationStmt>(this);
54 (void)stmt;
55 // TODO: Add operands to OperationStmt.
56 abort();
57 }
58}
59
Chris Lattner68a3fd02018-07-23 10:08:00 -070060void Operation::setOperand(unsigned idx, SSAValue *value) {
61 if (auto *inst = dyn_cast<OperationInst>(this)) {
62 inst->setOperand(idx, cast<CFGValue>(value));
63 } else {
64 auto *stmt = cast<OperationStmt>(this);
65 (void)stmt;
66 // TODO: Add operands to OperationStmt.
67 abort();
68 }
69}
70
Chris Lattnerac591f12018-07-22 21:02:26 -070071/// Return the number of results this operation has.
72unsigned Operation::getNumResults() const {
73 if (auto *inst = dyn_cast<OperationInst>(this)) {
74 return inst->getNumResults();
75 } else {
76 auto *stmt = cast<OperationStmt>(this);
77 (void)stmt;
78 // TODO: Add results to OperationStmt.
79 return 0;
80 }
81}
82
83/// Return the indicated result.
84SSAValue *Operation::getResult(unsigned idx) {
85 if (auto *inst = dyn_cast<OperationInst>(this)) {
86 return inst->getResult(idx);
87 } else {
88 auto *stmt = cast<OperationStmt>(this);
89 (void)stmt;
90 // TODO: Add operands to OperationStmt.
91 abort();
92 }
Chris Lattner7121b802018-07-04 20:45:39 -070093}
94
Chris Lattnerdf1a2fc2018-07-05 21:20:59 -070095ArrayRef<NamedAttribute> Operation::getAttrs() const {
96 if (!attrs)
97 return {};
98 return attrs->getElements();
99}
100
Chris Lattnerff0d5902018-07-05 09:12:11 -0700101/// If an attribute exists with the specified name, change it to the new
102/// value. Otherwise, add a new attribute with the specified name/value.
Chris Lattnerdf1a2fc2018-07-05 21:20:59 -0700103void Operation::setAttr(Identifier name, Attribute *value,
104 MLIRContext *context) {
Chris Lattnerff0d5902018-07-05 09:12:11 -0700105 assert(value && "attributes may never be null");
Chris Lattnerdf1a2fc2018-07-05 21:20:59 -0700106 auto origAttrs = getAttrs();
107
108 SmallVector<NamedAttribute, 8> newAttrs(origAttrs.begin(), origAttrs.end());
109
Chris Lattnerff0d5902018-07-05 09:12:11 -0700110 // If we already have this attribute, replace it.
Chris Lattnerdf1a2fc2018-07-05 21:20:59 -0700111 for (auto &elt : newAttrs)
Chris Lattnerff0d5902018-07-05 09:12:11 -0700112 if (elt.first == name) {
113 elt.second = value;
Chris Lattnerdf1a2fc2018-07-05 21:20:59 -0700114 attrs = AttributeListStorage::get(newAttrs, context);
Chris Lattnerff0d5902018-07-05 09:12:11 -0700115 return;
116 }
117
118 // Otherwise, add it.
Chris Lattnerdf1a2fc2018-07-05 21:20:59 -0700119 newAttrs.push_back({name, value});
120 attrs = AttributeListStorage::get(newAttrs, context);
Chris Lattnerff0d5902018-07-05 09:12:11 -0700121}
122
123/// Remove the attribute with the specified name if it exists. The return
124/// value indicates whether the attribute was present or not.
Chris Lattnerdf1a2fc2018-07-05 21:20:59 -0700125auto Operation::removeAttr(Identifier name, MLIRContext *context)
126 -> RemoveResult {
127 auto origAttrs = getAttrs();
128 for (unsigned i = 0, e = origAttrs.size(); i != e; ++i) {
129 if (origAttrs[i].first == name) {
130 SmallVector<NamedAttribute, 8> newAttrs;
131 newAttrs.reserve(origAttrs.size() - 1);
132 newAttrs.append(origAttrs.begin(), origAttrs.begin() + i);
133 newAttrs.append(origAttrs.begin() + i + 1, origAttrs.end());
134 attrs = AttributeListStorage::get(newAttrs, context);
Chris Lattner7121b802018-07-04 20:45:39 -0700135 return RemoveResult::Removed;
136 }
137 }
138 return RemoveResult::NotFound;
139}