blob: 7114d49c33ec0cea86a6bcd83f49ad2bed06fbe2 [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 Lattnerdd0c2ca2018-07-24 16:07:22 -070020#include "mlir/IR/OpImplementation.h"
Chris Lattnerff0d5902018-07-05 09:12:11 -070021#include "mlir/IR/OperationSet.h"
Chris Lattner9361fb32018-07-24 08:34:58 -070022#include "mlir/IR/SSAValue.h"
23#include "mlir/IR/Types.h"
Chris Lattnerff0d5902018-07-05 09:12:11 -070024#include "llvm/Support/raw_ostream.h"
25using namespace mlir;
26
Chris Lattnerdd0c2ca2018-07-24 16:07:22 -070027void AddFOp::print(OpAsmPrinter *p) const {
28 *p << "addf " << *getOperand(0) << ", " << *getOperand(1) << " : "
29 << *getType();
Chris Lattnerff0d5902018-07-05 09:12:11 -070030}
31
Chris Lattner21e67f62018-07-06 10:46:19 -070032// Return an error message on failure.
33const char *AddFOp::verify() const {
34 // TODO: Check that the types of the LHS and RHS match.
35 // TODO: This should be a refinement of TwoOperands.
36 // TODO: There should also be a OneResultWhoseTypeMatchesFirstOperand.
37 return nullptr;
38}
39
Chris Lattner9361fb32018-07-24 08:34:58 -070040/// The constant op requires an attribute, and furthermore requires that it
41/// matches the return type.
42const char *ConstantOp::verify() const {
43 auto *value = getValue();
44 if (!value)
45 return "requires a 'value' attribute";
46
47 auto *type = this->getType();
Chris Lattner1ec70572018-07-24 10:41:30 -070048 if (isa<IntegerType>(type) || type->isAffineInt()) {
Chris Lattner9361fb32018-07-24 08:34:58 -070049 if (!isa<IntegerAttr>(value))
50 return "requires 'value' to be an integer for an integer result type";
51 return nullptr;
52 }
53
54 if (isa<FunctionType>(type)) {
55 // TODO: Verify a function attr.
56 }
57
58 return "requires a result type that aligns with the 'value' attribute";
59}
60
61/// ConstantIntOp only matches values whose result type is an IntegerType.
62bool ConstantIntOp::isClassFor(const Operation *op) {
63 return ConstantOp::isClassFor(op) &&
64 isa<IntegerType>(op->getResult(0)->getType());
65}
66
Chris Lattnerdd0c2ca2018-07-24 16:07:22 -070067void DimOp::print(OpAsmPrinter *p) const {
68 *p << "dim " << *getOperand() << ", " << getIndex() << " : "
69 << *getOperand()->getType();
Chris Lattnerff0d5902018-07-05 09:12:11 -070070}
71
Chris Lattner21e67f62018-07-06 10:46:19 -070072const char *DimOp::verify() const {
Chris Lattner21e67f62018-07-06 10:46:19 -070073 // Check that we have an integer index operand.
74 auto indexAttr = getAttrOfType<IntegerAttr>("index");
75 if (!indexAttr)
Chris Lattner9361fb32018-07-24 08:34:58 -070076 return "requires an integer attribute named 'index'";
77 uint64_t index = (uint64_t)indexAttr->getValue();
Chris Lattner21e67f62018-07-06 10:46:19 -070078
Chris Lattner9361fb32018-07-24 08:34:58 -070079 auto *type = getOperand()->getType();
80 if (auto *tensorType = dyn_cast<RankedTensorType>(type)) {
81 if (index >= tensorType->getRank())
82 return "index is out of range";
83 } else if (auto *memrefType = dyn_cast<MemRefType>(type)) {
84 if (index >= memrefType->getRank())
85 return "index is out of range";
86
87 } else if (isa<UnrankedTensorType>(type)) {
88 // ok, assumed to be in-range.
89 } else {
90 return "requires an operand with tensor or memref type";
91 }
Chris Lattner21e67f62018-07-06 10:46:19 -070092
93 return nullptr;
94}
95
Chris Lattnerdd0c2ca2018-07-24 16:07:22 -070096void AffineApplyOp::print(OpAsmPrinter *p) const {
97 // TODO: Print operands etc.
98 *p << "affine_apply map: " << *getAffineMap();
MLIR Team3fa00ab2018-07-24 10:13:31 -070099}
100
101const char *AffineApplyOp::verify() const {
102 // TODO: Check input and output dimensions match.
103
104 // Check that affine map attribute was specified
105 auto affineMapAttr = getAttrOfType<AffineMapAttr>("map");
106 if (!affineMapAttr)
107 return "requires an affine map.";
108
109 return nullptr;
110}
111
Chris Lattnerff0d5902018-07-05 09:12:11 -0700112/// Install the standard operations in the specified operation set.
113void mlir::registerStandardOperations(OperationSet &opSet) {
MLIR Team3fa00ab2018-07-24 10:13:31 -0700114 opSet.addOperations<AddFOp, ConstantOp, DimOp, AffineApplyOp>(/*prefix=*/"");
Chris Lattnerff0d5902018-07-05 09:12:11 -0700115}