blob: 67e87a4079288930eecacb88f7c9d67295318e96 [file] [log] [blame]
Chris Lattner4c95a502018-06-23 16:03:42 -07001//===- Instructions.cpp - MLIR CFGFunction Instruction Classes ------------===//
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/Instructions.h"
19#include "mlir/IR/BasicBlock.h"
20using namespace mlir;
21
Chris Lattner6119d382018-07-20 18:41:34 -070022/// Replace all uses of 'this' value with the new value, updating anything in
23/// the IR that uses 'this' to use the other value instead. When this returns
24/// there are zero uses of 'this'.
25void SSAValue::replaceAllUsesWith(SSAValue *newValue) {
26 assert(this != newValue && "cannot RAUW a value with itself");
27 while (!use_empty()) {
28 use_begin()->set(newValue);
29 }
30}
31
32/// Return the result number of this result.
33unsigned InstResult::getResultNumber() const {
34 // Results are always stored consecutively, so use pointer subtraction to
35 // figure out what number this is.
36 return this - &getOwner()->getInstResults()[0];
37}
38
Chris Lattnered65a732018-06-28 20:45:33 -070039//===----------------------------------------------------------------------===//
40// Instruction
41//===----------------------------------------------------------------------===//
42
Chris Lattner3a467cc2018-07-01 20:28:00 -070043// Instructions are deleted through the destroy() member because we don't have
44// a virtual destructor.
45Instruction::~Instruction() {
46 assert(block == nullptr && "instruction destroyed but still in a block");
47}
48
49/// Destroy this instruction or one of its subclasses.
Chris Lattner6119d382018-07-20 18:41:34 -070050void Instruction::destroy() {
51 switch (getKind()) {
Chris Lattner3a467cc2018-07-01 20:28:00 -070052 case Kind::Operation:
Chris Lattner6119d382018-07-20 18:41:34 -070053 cast<OperationInst>(this)->destroy();
Chris Lattner3a467cc2018-07-01 20:28:00 -070054 break;
55 case Kind::Branch:
Chris Lattner6119d382018-07-20 18:41:34 -070056 delete cast<BranchInst>(this);
Chris Lattner3a467cc2018-07-01 20:28:00 -070057 break;
58 case Kind::Return:
Chris Lattner40746442018-07-21 14:32:09 -070059 cast<ReturnInst>(this)->destroy();
Chris Lattner3a467cc2018-07-01 20:28:00 -070060 break;
61 }
62}
63
Chris Lattner6119d382018-07-20 18:41:34 -070064void OperationInst::destroy() {
65 this->~OperationInst();
66 free(this);
67}
68
Chris Lattnered65a732018-06-28 20:45:33 -070069CFGFunction *Instruction::getFunction() const {
Chris Lattner4c95a502018-06-23 16:03:42 -070070 return getBlock()->getFunction();
71}
72
Chris Lattner68a3fd02018-07-23 10:08:00 -070073unsigned Instruction::getNumOperands() const {
74 switch (getKind()) {
75 case Kind::Operation:
76 return cast<OperationInst>(this)->getNumOperands();
77 case Kind::Branch:
78 return cast<BranchInst>(this)->getNumOperands();
79 case Kind::Return:
80 return cast<ReturnInst>(this)->getNumOperands();
81 }
82}
83
84MutableArrayRef<InstOperand> Instruction::getInstOperands() {
85 switch (getKind()) {
86 case Kind::Operation:
87 return cast<OperationInst>(this)->getInstOperands();
88 case Kind::Branch:
89 return cast<BranchInst>(this)->getInstOperands();
90 case Kind::Return:
91 return cast<ReturnInst>(this)->getInstOperands();
92 }
93}
94
Chris Lattnered65a732018-06-28 20:45:33 -070095//===----------------------------------------------------------------------===//
96// OperationInst
97//===----------------------------------------------------------------------===//
98
Chris Lattner3b2ef762018-07-18 15:31:25 -070099/// Create a new OperationInst with the specific fields.
100OperationInst *OperationInst::create(Identifier name,
101 ArrayRef<CFGValue *> operands,
102 ArrayRef<Type *> resultTypes,
103 ArrayRef<NamedAttribute> attributes,
104 MLIRContext *context) {
105 auto byteSize = totalSizeToAlloc<InstOperand, InstResult>(operands.size(),
106 resultTypes.size());
Chris Lattner6119d382018-07-20 18:41:34 -0700107 void *rawMem = malloc(byteSize);
Chris Lattner3b2ef762018-07-18 15:31:25 -0700108
109 // Initialize the OperationInst part of the instruction.
110 auto inst = ::new (rawMem) OperationInst(
111 name, operands.size(), resultTypes.size(), attributes, context);
112
113 // Initialize the operands and results.
Chris Lattnerf8cce872018-07-20 09:28:54 -0700114 auto instOperands = inst->getInstOperands();
Chris Lattner3b2ef762018-07-18 15:31:25 -0700115 for (unsigned i = 0, e = operands.size(); i != e; ++i)
116 new (&instOperands[i]) InstOperand(inst, operands[i]);
117
Chris Lattnerf8cce872018-07-20 09:28:54 -0700118 auto instResults = inst->getInstResults();
Chris Lattner3b2ef762018-07-18 15:31:25 -0700119 for (unsigned i = 0, e = resultTypes.size(); i != e; ++i)
120 new (&instResults[i]) InstResult(resultTypes[i], inst);
121 return inst;
122}
123
124OperationInst::OperationInst(Identifier name, unsigned numOperands,
125 unsigned numResults,
126 ArrayRef<NamedAttribute> attributes,
127 MLIRContext *context)
Chris Lattner55315d52018-07-18 19:06:45 -0700128 : Operation(name, /*isInstruction=*/ true, attributes, context),
129 Instruction(Kind::Operation), numOperands(numOperands),
130 numResults(numResults) {}
Chris Lattner3b2ef762018-07-18 15:31:25 -0700131
132OperationInst::~OperationInst() {
133 // Explicitly run the destructors for the operands and results.
Chris Lattnerf8cce872018-07-20 09:28:54 -0700134 for (auto &operand : getInstOperands())
Chris Lattner3b2ef762018-07-18 15:31:25 -0700135 operand.~InstOperand();
136
Chris Lattnerf8cce872018-07-20 09:28:54 -0700137 for (auto &result : getInstResults())
Chris Lattner3b2ef762018-07-18 15:31:25 -0700138 result.~InstResult();
139}
140
Chris Lattner3a467cc2018-07-01 20:28:00 -0700141mlir::BasicBlock *
142llvm::ilist_traits<::mlir::OperationInst>::getContainingBlock() {
143 size_t Offset(
144 size_t(&((BasicBlock *)nullptr->*BasicBlock::getSublistAccess(nullptr))));
145 iplist<OperationInst> *Anchor(static_cast<iplist<OperationInst> *>(this));
146 return reinterpret_cast<BasicBlock *>(reinterpret_cast<char *>(Anchor) -
147 Offset);
Chris Lattnered65a732018-06-28 20:45:33 -0700148}
149
Chris Lattner3a467cc2018-07-01 20:28:00 -0700150/// This is a trait method invoked when an instruction is added to a block. We
151/// keep the block pointer up to date.
152void llvm::ilist_traits<::mlir::OperationInst>::
153addNodeToList(OperationInst *inst) {
154 assert(!inst->getBlock() && "already in a basic block!");
155 inst->block = getContainingBlock();
156}
157
158/// This is a trait method invoked when an instruction is removed from a block.
159/// We keep the block pointer up to date.
160void llvm::ilist_traits<::mlir::OperationInst>::
161removeNodeFromList(OperationInst *inst) {
162 assert(inst->block && "not already in a basic block!");
163 inst->block = nullptr;
164}
165
166/// This is a trait method invoked when an instruction is moved from one block
167/// to another. We keep the block pointer up to date.
168void llvm::ilist_traits<::mlir::OperationInst>::
169transferNodesFromList(ilist_traits<OperationInst> &otherList,
170 instr_iterator first, instr_iterator last) {
171 // If we are transferring instructions within the same basic block, the block
172 // pointer doesn't need to be updated.
173 BasicBlock *curParent = getContainingBlock();
174 if (curParent == otherList.getContainingBlock())
175 return;
176
177 // Update the 'block' member of each instruction.
178 for (; first != last; ++first)
179 first->block = curParent;
180}
181
182/// Unlink this instruction from its BasicBlock and delete it.
183void OperationInst::eraseFromBlock() {
184 assert(getBlock() && "Instruction has no parent");
185 getBlock()->getOperations().erase(this);
186}
187
Chris Lattner6119d382018-07-20 18:41:34 -0700188/// If this value is the result of an OperationInst, return the instruction
189/// that defines it.
190OperationInst *SSAValue::getDefiningInst() {
191 if (auto *result = dyn_cast<InstResult>(this))
192 return result->getOwner();
193 return nullptr;
194}
195
Chris Lattnered65a732018-06-28 20:45:33 -0700196//===----------------------------------------------------------------------===//
197// Terminators
198//===----------------------------------------------------------------------===//
199
Chris Lattner3a467cc2018-07-01 20:28:00 -0700200/// Remove this terminator from its BasicBlock and delete it.
201void TerminatorInst::eraseFromBlock() {
202 assert(getBlock() && "Instruction has no parent");
203 getBlock()->setTerminator(nullptr);
Chris Lattner6119d382018-07-20 18:41:34 -0700204 destroy();
Chris Lattner4c95a502018-06-23 16:03:42 -0700205}
206
Chris Lattner40746442018-07-21 14:32:09 -0700207/// Create a new OperationInst with the specific fields.
208ReturnInst *ReturnInst::create(ArrayRef<CFGValue *> operands) {
209 auto byteSize = totalSizeToAlloc<InstOperand>(operands.size());
210 void *rawMem = malloc(byteSize);
Chris Lattner3a467cc2018-07-01 20:28:00 -0700211
Chris Lattner40746442018-07-21 14:32:09 -0700212 // Initialize the ReturnInst part of the instruction.
213 auto inst = ::new (rawMem) ReturnInst(operands.size());
214
215 // Initialize the operands and results.
216 auto instOperands = inst->getInstOperands();
217 for (unsigned i = 0, e = operands.size(); i != e; ++i)
218 new (&instOperands[i]) InstOperand(inst, operands[i]);
219 return inst;
220}
221
222void ReturnInst::destroy() {
223 this->~ReturnInst();
224 free(this);
225}
226
227ReturnInst::~ReturnInst() {
228 // Explicitly run the destructors for the operands.
229 for (auto &operand : getInstOperands())
230 operand.~InstOperand();
231}
Chris Lattner1604e472018-07-23 08:42:19 -0700232
233/// Add one value to the operand list.
234void BranchInst::addOperand(CFGValue *value) {
235 operands.emplace_back(InstOperand(this, value));
236}
237
238/// Add a list of values to the operand list.
239void BranchInst::addOperands(ArrayRef<CFGValue *> values) {
240 operands.reserve(operands.size() + values.size());
241 for (auto *value : values)
242 addOperand(value);
243}