blob: f111d7126b36364d581f65c888eef4746bde775f [file] [log] [blame]
Tatiana Shpeismande8829f2018-08-24 23:38:14 -07001//===- SSAValue.cpp - MLIR SSAValue Classes ------------===//
Chris Lattnerd4964212018-08-01 10:43:18 -07002//
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/SSAValue.h"
Chris Lattnerfdc1f652018-09-05 17:45:19 -070019#include "mlir/IR/CFGFunction.h"
Chris Lattnerd4964212018-08-01 10:43:18 -070020#include "mlir/IR/Instructions.h"
Chris Lattnerfdc1f652018-09-05 17:45:19 -070021#include "mlir/IR/MLFunction.h"
Tatiana Shpeismande8829f2018-08-24 23:38:14 -070022#include "mlir/IR/StandardOps.h"
Chris Lattnerd4964212018-08-01 10:43:18 -070023#include "mlir/IR/Statements.h"
24using namespace mlir;
25
26/// If this value is the result of an OperationInst, return the instruction
27/// that defines it.
28OperationInst *SSAValue::getDefiningInst() {
29 if (auto *result = dyn_cast<InstResult>(this))
30 return result->getOwner();
31 return nullptr;
32}
33
34/// If this value is the result of an OperationStmt, return the statement
35/// that defines it.
36OperationStmt *SSAValue::getDefiningStmt() {
37 if (auto *result = dyn_cast<StmtResult>(this))
38 return result->getOwner();
39 return nullptr;
40}
41
42Operation *SSAValue::getDefiningOperation() {
43 if (auto *inst = getDefiningInst())
44 return inst;
45 if (auto *stmt = getDefiningStmt())
46 return stmt;
47 return nullptr;
48}
Tatiana Shpeismande8829f2018-08-24 23:38:14 -070049
Chris Lattnerfdc1f652018-09-05 17:45:19 -070050/// Return the function that this SSAValue is defined in.
51Function *SSAValue::getFunction() {
52 switch (getKind()) {
53 case SSAValueKind::BBArgument:
54 return cast<BBArgument>(this)->getFunction();
55 case SSAValueKind::InstResult:
56 return getDefiningInst()->getFunction();
57 case SSAValueKind::MLFuncArgument:
58 return cast<MLFuncArgument>(this)->getFunction();
59 case SSAValueKind::StmtResult:
60 return getDefiningStmt()->findFunction();
61 case SSAValueKind::ForStmt:
62 return cast<ForStmt>(this)->findFunction();
63 }
64}
65
66//===----------------------------------------------------------------------===//
67// CFGValue implementation.
68//===----------------------------------------------------------------------===//
69
70/// Return the function that this CFGValue is defined in.
71CFGFunction *CFGValue::getFunction() {
72 return cast<CFGFunction>(static_cast<SSAValue *>(this)->getFunction());
73}
74
75//===----------------------------------------------------------------------===//
76// BBArgument implementation.
77//===----------------------------------------------------------------------===//
78
79/// Return the function that this argument is defined in.
80CFGFunction *BBArgument::getFunction() const {
81 if (auto *owner = getOwner())
82 return owner->getFunction();
83 return nullptr;
84}
85
Tatiana Shpeismande8829f2018-08-24 23:38:14 -070086//===----------------------------------------------------------------------===//
87// MLValue implementation.
88//===----------------------------------------------------------------------===//
89
Chris Lattnerfdc1f652018-09-05 17:45:19 -070090/// Return the function that this MLValue is defined in.
91MLFunction *MLValue::getFunction() {
92 return cast<MLFunction>(static_cast<SSAValue *>(this)->getFunction());
93}
94
Tatiana Shpeismande8829f2018-08-24 23:38:14 -070095// MLValue can be used a a dimension id if it is valid as a symbol, or
96// it is an induction variable, or it is a result of affine apply operation
97// with dimension id arguments.
98bool MLValue::isValidDim() const {
99 if (auto *stmt = getDefiningStmt()) {
100 // Top level statement or constant operation is ok.
101 if (stmt->getParentStmt() == nullptr || stmt->is<ConstantOp>())
102 return true;
103 // Affine apply operation is ok if all of its operands are ok.
104 if (auto op = stmt->getAs<AffineApplyOp>())
105 return op->isValidDim();
106 return false;
107 }
Chris Lattnerfdc1f652018-09-05 17:45:19 -0700108 // This value is either a function argument or an induction variable. Both
109 // are ok.
Tatiana Shpeismande8829f2018-08-24 23:38:14 -0700110 return true;
111}
112
113// MLValue can be used as a symbol if it is a constant, or it is defined at
114// the top level, or it is a result of affine apply operation with symbol
115// arguments.
116bool MLValue::isValidSymbol() const {
117 if (auto *stmt = getDefiningStmt()) {
118 // Top level statement or constant operation is ok.
119 if (stmt->getParentStmt() == nullptr || stmt->is<ConstantOp>())
120 return true;
121 // Affine apply operation is ok if all of its operands are ok.
122 if (auto op = stmt->getAs<AffineApplyOp>())
123 return op->isValidSymbol();
124 return false;
125 }
126 // This value is either a function argument or an induction variable.
127 // Function argument is ok, induction variable is not.
128 return isa<MLFuncArgument>(this);
129}