blob: cb03db79c7d976fde3ce6d5fb127c109933bdf55 [file] [log] [blame]
Chris Lattnerff0d5902018-07-05 09:12:11 -07001//===- StandardOps.cpp - Standard MLIR Operations -------------------------===//
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/StandardOps.h"
MLIR Team3fa00ab2018-07-24 10:13:31 -070019#include "mlir/IR/AffineMap.h"
Chris Lattnerff0d5902018-07-05 09:12:11 -070020#include "mlir/IR/OperationSet.h"
Chris Lattner9361fb32018-07-24 08:34:58 -070021#include "mlir/IR/SSAValue.h"
22#include "mlir/IR/Types.h"
Chris Lattnerff0d5902018-07-05 09:12:11 -070023#include "llvm/Support/raw_ostream.h"
24using namespace mlir;
25
26void AddFOp::print(raw_ostream &os) const {
Jacques Pienaarb020c542018-07-15 00:06:54 -070027 os << "addf xx, yy : sometype";
Chris Lattnerff0d5902018-07-05 09:12:11 -070028}
29
Chris Lattner21e67f62018-07-06 10:46:19 -070030// Return an error message on failure.
31const char *AddFOp::verify() const {
32 // TODO: Check that the types of the LHS and RHS match.
33 // TODO: This should be a refinement of TwoOperands.
34 // TODO: There should also be a OneResultWhoseTypeMatchesFirstOperand.
35 return nullptr;
36}
37
Chris Lattner9361fb32018-07-24 08:34:58 -070038/// The constant op requires an attribute, and furthermore requires that it
39/// matches the return type.
40const char *ConstantOp::verify() const {
41 auto *value = getValue();
42 if (!value)
43 return "requires a 'value' attribute";
44
45 auto *type = this->getType();
46 if (isa<IntegerType>(type)) {
47 if (!isa<IntegerAttr>(value))
48 return "requires 'value' to be an integer for an integer result type";
49 return nullptr;
50 }
51
52 if (isa<FunctionType>(type)) {
53 // TODO: Verify a function attr.
54 }
55
56 return "requires a result type that aligns with the 'value' attribute";
57}
58
59/// ConstantIntOp only matches values whose result type is an IntegerType.
60bool ConstantIntOp::isClassFor(const Operation *op) {
61 return ConstantOp::isClassFor(op) &&
62 isa<IntegerType>(op->getResult(0)->getType());
63}
64
Chris Lattnerff0d5902018-07-05 09:12:11 -070065void DimOp::print(raw_ostream &os) const {
Jacques Pienaarb020c542018-07-15 00:06:54 -070066 os << "dim xxx, " << getIndex() << " : sometype";
Chris Lattnerff0d5902018-07-05 09:12:11 -070067}
68
Chris Lattner21e67f62018-07-06 10:46:19 -070069const char *DimOp::verify() const {
Chris Lattner21e67f62018-07-06 10:46:19 -070070 // Check that we have an integer index operand.
71 auto indexAttr = getAttrOfType<IntegerAttr>("index");
72 if (!indexAttr)
Chris Lattner9361fb32018-07-24 08:34:58 -070073 return "requires an integer attribute named 'index'";
74 uint64_t index = (uint64_t)indexAttr->getValue();
Chris Lattner21e67f62018-07-06 10:46:19 -070075
Chris Lattner9361fb32018-07-24 08:34:58 -070076 auto *type = getOperand()->getType();
77 if (auto *tensorType = dyn_cast<RankedTensorType>(type)) {
78 if (index >= tensorType->getRank())
79 return "index is out of range";
80 } else if (auto *memrefType = dyn_cast<MemRefType>(type)) {
81 if (index >= memrefType->getRank())
82 return "index is out of range";
83
84 } else if (isa<UnrankedTensorType>(type)) {
85 // ok, assumed to be in-range.
86 } else {
87 return "requires an operand with tensor or memref type";
88 }
Chris Lattner21e67f62018-07-06 10:46:19 -070089
90 return nullptr;
91}
92
MLIR Team3fa00ab2018-07-24 10:13:31 -070093void AffineApplyOp::print(raw_ostream &os) const {
94 os << "affine_apply map: ";
95 getAffineMap()->print(os);
96}
97
98const char *AffineApplyOp::verify() const {
99 // TODO: Check input and output dimensions match.
100
101 // Check that affine map attribute was specified
102 auto affineMapAttr = getAttrOfType<AffineMapAttr>("map");
103 if (!affineMapAttr)
104 return "requires an affine map.";
105
106 return nullptr;
107}
108
Chris Lattnerff0d5902018-07-05 09:12:11 -0700109/// Install the standard operations in the specified operation set.
110void mlir::registerStandardOperations(OperationSet &opSet) {
MLIR Team3fa00ab2018-07-24 10:13:31 -0700111 opSet.addOperations<AddFOp, ConstantOp, DimOp, AffineApplyOp>(/*prefix=*/"");
Chris Lattnerff0d5902018-07-05 09:12:11 -0700112}