blob: 90a50160054f4935c5a781a7048c72058d1ef8b2 [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"
Chris Lattner95865062018-08-01 10:18:59 -070019#include "mlir/IR/CFGFunction.h"
Chris Lattner1628fa02018-08-23 14:32:25 -070020#include "mlir/IR/MLIRContext.h"
Chris Lattner4c95a502018-06-23 16:03:42 -070021using namespace mlir;
22
Chris Lattner6119d382018-07-20 18:41:34 -070023/// Replace all uses of 'this' value with the new value, updating anything in
24/// the IR that uses 'this' to use the other value instead. When this returns
25/// there are zero uses of 'this'.
Chris Lattner1e9fd7f2018-07-26 08:56:26 -070026void IRObjectWithUseList::replaceAllUsesWith(IRObjectWithUseList *newValue) {
Chris Lattner6119d382018-07-20 18:41:34 -070027 assert(this != newValue && "cannot RAUW a value with itself");
28 while (!use_empty()) {
29 use_begin()->set(newValue);
30 }
31}
32
33/// Return the result number of this result.
34unsigned InstResult::getResultNumber() const {
35 // Results are always stored consecutively, so use pointer subtraction to
36 // figure out what number this is.
37 return this - &getOwner()->getInstResults()[0];
38}
39
Chris Lattnered65a732018-06-28 20:45:33 -070040//===----------------------------------------------------------------------===//
41// Instruction
42//===----------------------------------------------------------------------===//
43
Chris Lattner3a467cc2018-07-01 20:28:00 -070044// Instructions are deleted through the destroy() member because we don't have
45// a virtual destructor.
46Instruction::~Instruction() {
47 assert(block == nullptr && "instruction destroyed but still in a block");
48}
49
50/// Destroy this instruction or one of its subclasses.
Chris Lattner6119d382018-07-20 18:41:34 -070051void Instruction::destroy() {
52 switch (getKind()) {
Chris Lattner3a467cc2018-07-01 20:28:00 -070053 case Kind::Operation:
Chris Lattner6119d382018-07-20 18:41:34 -070054 cast<OperationInst>(this)->destroy();
Chris Lattner3a467cc2018-07-01 20:28:00 -070055 break;
56 case Kind::Branch:
Chris Lattner6119d382018-07-20 18:41:34 -070057 delete cast<BranchInst>(this);
Chris Lattner3a467cc2018-07-01 20:28:00 -070058 break;
James Molloy4f788372018-07-24 15:01:27 -070059 case Kind::CondBranch:
60 delete cast<CondBranchInst>(this);
61 break;
Chris Lattner3a467cc2018-07-01 20:28:00 -070062 case Kind::Return:
Chris Lattner40746442018-07-21 14:32:09 -070063 cast<ReturnInst>(this)->destroy();
Chris Lattner3a467cc2018-07-01 20:28:00 -070064 break;
65 }
66}
67
Chris Lattner6119d382018-07-20 18:41:34 -070068void OperationInst::destroy() {
69 this->~OperationInst();
70 free(this);
71}
72
Chris Lattner95865062018-08-01 10:18:59 -070073/// Return the context this operation is associated with.
74MLIRContext *Instruction::getContext() const {
Tatiana Shpeismanc335d182018-08-03 11:12:34 -070075 auto *fn = getFunction();
76 return fn ? fn->getContext() : nullptr;
Chris Lattner95865062018-08-01 10:18:59 -070077}
78
Chris Lattnered65a732018-06-28 20:45:33 -070079CFGFunction *Instruction::getFunction() const {
Tatiana Shpeismanc335d182018-08-03 11:12:34 -070080 auto *block = getBlock();
81 return block ? block->getFunction() : nullptr;
Chris Lattner4c95a502018-06-23 16:03:42 -070082}
83
Chris Lattner68a3fd02018-07-23 10:08:00 -070084unsigned Instruction::getNumOperands() const {
85 switch (getKind()) {
86 case Kind::Operation:
87 return cast<OperationInst>(this)->getNumOperands();
88 case Kind::Branch:
89 return cast<BranchInst>(this)->getNumOperands();
James Molloy4f788372018-07-24 15:01:27 -070090 case Kind::CondBranch:
91 return cast<CondBranchInst>(this)->getNumOperands();
Chris Lattner68a3fd02018-07-23 10:08:00 -070092 case Kind::Return:
93 return cast<ReturnInst>(this)->getNumOperands();
94 }
95}
96
97MutableArrayRef<InstOperand> Instruction::getInstOperands() {
98 switch (getKind()) {
99 case Kind::Operation:
100 return cast<OperationInst>(this)->getInstOperands();
101 case Kind::Branch:
102 return cast<BranchInst>(this)->getInstOperands();
James Molloy4f788372018-07-24 15:01:27 -0700103 case Kind::CondBranch:
104 return cast<CondBranchInst>(this)->getInstOperands();
Chris Lattner68a3fd02018-07-23 10:08:00 -0700105 case Kind::Return:
106 return cast<ReturnInst>(this)->getInstOperands();
107 }
108}
109
Chris Lattnera8e47672018-07-25 14:08:16 -0700110/// This drops all operand uses from this instruction, which is an essential
111/// step in breaking cyclic dependences between references when they are to
112/// be deleted.
113void Instruction::dropAllReferences() {
114 for (auto &op : getInstOperands())
115 op.drop();
Chris Lattner1e9fd7f2018-07-26 08:56:26 -0700116
117 if (auto *term = dyn_cast<TerminatorInst>(this))
Chris Lattner548cd7f2018-07-26 11:30:28 -0700118 for (auto &dest : term->getBasicBlockOperands())
Chris Lattner1e9fd7f2018-07-26 08:56:26 -0700119 dest.drop();
Chris Lattnera8e47672018-07-25 14:08:16 -0700120}
121
Chris Lattner1628fa02018-08-23 14:32:25 -0700122/// Emit a note about this instruction, reporting up to any diagnostic
123/// handlers that may be listening.
124void Instruction::emitNote(const Twine &message) const {
125 getContext()->emitDiagnostic(getLoc(), message,
126 MLIRContext::DiagnosticKind::Note);
127}
128
129/// Emit a warning about this operation, reporting up to any diagnostic
130/// handlers that may be listening.
131void Instruction::emitWarning(const Twine &message) const {
132 getContext()->emitDiagnostic(getLoc(), message,
133 MLIRContext::DiagnosticKind::Warning);
134}
135
136/// Emit an error about fatal conditions with this instruction, reporting up to
137/// any diagnostic handlers that may be listening. NOTE: This may terminate
138/// the containing application, only use when the IR is in an inconsistent
139/// state.
140void Instruction::emitError(const Twine &message) const {
141 getContext()->emitDiagnostic(getLoc(), message,
142 MLIRContext::DiagnosticKind::Error);
143}
144
Chris Lattnered65a732018-06-28 20:45:33 -0700145//===----------------------------------------------------------------------===//
146// OperationInst
147//===----------------------------------------------------------------------===//
148
Chris Lattnerfc647d52018-08-27 21:05:16 -0700149/// Create a new OperationInst with the specified fields.
150OperationInst *OperationInst::create(Location *location, Identifier name,
Chris Lattner3b2ef762018-07-18 15:31:25 -0700151 ArrayRef<CFGValue *> operands,
152 ArrayRef<Type *> resultTypes,
153 ArrayRef<NamedAttribute> attributes,
154 MLIRContext *context) {
155 auto byteSize = totalSizeToAlloc<InstOperand, InstResult>(operands.size(),
156 resultTypes.size());
Chris Lattner6119d382018-07-20 18:41:34 -0700157 void *rawMem = malloc(byteSize);
Chris Lattner3b2ef762018-07-18 15:31:25 -0700158
159 // Initialize the OperationInst part of the instruction.
160 auto inst = ::new (rawMem) OperationInst(
Chris Lattner1628fa02018-08-23 14:32:25 -0700161 location, name, operands.size(), resultTypes.size(), attributes, context);
Chris Lattner3b2ef762018-07-18 15:31:25 -0700162
163 // Initialize the operands and results.
Chris Lattnerf8cce872018-07-20 09:28:54 -0700164 auto instOperands = inst->getInstOperands();
Chris Lattner3b2ef762018-07-18 15:31:25 -0700165 for (unsigned i = 0, e = operands.size(); i != e; ++i)
166 new (&instOperands[i]) InstOperand(inst, operands[i]);
167
Chris Lattnerf8cce872018-07-20 09:28:54 -0700168 auto instResults = inst->getInstResults();
Chris Lattner3b2ef762018-07-18 15:31:25 -0700169 for (unsigned i = 0, e = resultTypes.size(); i != e; ++i)
170 new (&instResults[i]) InstResult(resultTypes[i], inst);
171 return inst;
172}
173
Uday Bondhugula15984952018-08-01 22:36:12 -0700174OperationInst *OperationInst::clone() const {
175 SmallVector<CFGValue *, 8> operands;
176 SmallVector<Type *, 8> resultTypes;
177
Uday Bondhugula15984952018-08-01 22:36:12 -0700178 // Put together the operands and results.
Chris Lattner1628fa02018-08-23 14:32:25 -0700179 for (auto *operand : getOperands())
180 operands.push_back(const_cast<CFGValue *>(operand));
Uday Bondhugula15984952018-08-01 22:36:12 -0700181
Chris Lattner1628fa02018-08-23 14:32:25 -0700182 for (auto *result : getResults())
183 resultTypes.push_back(result->getType());
Uday Bondhugula15984952018-08-01 22:36:12 -0700184
Chris Lattner1628fa02018-08-23 14:32:25 -0700185 return create(getLoc(), getName(), operands, resultTypes, getAttrs(),
186 getContext());
Uday Bondhugula15984952018-08-01 22:36:12 -0700187}
188
Chris Lattnerfc647d52018-08-27 21:05:16 -0700189OperationInst::OperationInst(Location *location, Identifier name,
Chris Lattner1628fa02018-08-23 14:32:25 -0700190 unsigned numOperands, unsigned numResults,
Chris Lattner3b2ef762018-07-18 15:31:25 -0700191 ArrayRef<NamedAttribute> attributes,
192 MLIRContext *context)
Chris Lattner1628fa02018-08-23 14:32:25 -0700193 : Operation(/*isInstruction=*/true, name, attributes, context),
194 Instruction(Kind::Operation, location), numOperands(numOperands),
Chris Lattner55315d52018-07-18 19:06:45 -0700195 numResults(numResults) {}
Chris Lattner3b2ef762018-07-18 15:31:25 -0700196
197OperationInst::~OperationInst() {
198 // Explicitly run the destructors for the operands and results.
Chris Lattnerf8cce872018-07-20 09:28:54 -0700199 for (auto &operand : getInstOperands())
Chris Lattner3b2ef762018-07-18 15:31:25 -0700200 operand.~InstOperand();
201
Chris Lattnerf8cce872018-07-20 09:28:54 -0700202 for (auto &result : getInstResults())
Chris Lattner3b2ef762018-07-18 15:31:25 -0700203 result.~InstResult();
204}
205
Chris Lattner3a467cc2018-07-01 20:28:00 -0700206mlir::BasicBlock *
207llvm::ilist_traits<::mlir::OperationInst>::getContainingBlock() {
208 size_t Offset(
209 size_t(&((BasicBlock *)nullptr->*BasicBlock::getSublistAccess(nullptr))));
210 iplist<OperationInst> *Anchor(static_cast<iplist<OperationInst> *>(this));
211 return reinterpret_cast<BasicBlock *>(reinterpret_cast<char *>(Anchor) -
James Molloy4f788372018-07-24 15:01:27 -0700212 Offset);
Chris Lattnered65a732018-06-28 20:45:33 -0700213}
214
Chris Lattner3a467cc2018-07-01 20:28:00 -0700215/// This is a trait method invoked when an instruction is added to a block. We
216/// keep the block pointer up to date.
James Molloy4f788372018-07-24 15:01:27 -0700217void llvm::ilist_traits<::mlir::OperationInst>::addNodeToList(
218 OperationInst *inst) {
Chris Lattner3a467cc2018-07-01 20:28:00 -0700219 assert(!inst->getBlock() && "already in a basic block!");
220 inst->block = getContainingBlock();
221}
222
223/// This is a trait method invoked when an instruction is removed from a block.
224/// We keep the block pointer up to date.
James Molloy4f788372018-07-24 15:01:27 -0700225void llvm::ilist_traits<::mlir::OperationInst>::removeNodeFromList(
226 OperationInst *inst) {
Chris Lattner3a467cc2018-07-01 20:28:00 -0700227 assert(inst->block && "not already in a basic block!");
228 inst->block = nullptr;
229}
230
231/// This is a trait method invoked when an instruction is moved from one block
232/// to another. We keep the block pointer up to date.
James Molloy4f788372018-07-24 15:01:27 -0700233void llvm::ilist_traits<::mlir::OperationInst>::transferNodesFromList(
234 ilist_traits<OperationInst> &otherList, instr_iterator first,
235 instr_iterator last) {
Chris Lattner3a467cc2018-07-01 20:28:00 -0700236 // If we are transferring instructions within the same basic block, the block
237 // pointer doesn't need to be updated.
238 BasicBlock *curParent = getContainingBlock();
239 if (curParent == otherList.getContainingBlock())
240 return;
241
242 // Update the 'block' member of each instruction.
243 for (; first != last; ++first)
244 first->block = curParent;
245}
246
247/// Unlink this instruction from its BasicBlock and delete it.
248void OperationInst::eraseFromBlock() {
249 assert(getBlock() && "Instruction has no parent");
250 getBlock()->getOperations().erase(this);
251}
252
Chris Lattnered65a732018-06-28 20:45:33 -0700253//===----------------------------------------------------------------------===//
Chris Lattner1e9fd7f2018-07-26 08:56:26 -0700254// TerminatorInst
Chris Lattnered65a732018-06-28 20:45:33 -0700255//===----------------------------------------------------------------------===//
256
Chris Lattner3a467cc2018-07-01 20:28:00 -0700257/// Remove this terminator from its BasicBlock and delete it.
258void TerminatorInst::eraseFromBlock() {
259 assert(getBlock() && "Instruction has no parent");
260 getBlock()->setTerminator(nullptr);
Chris Lattner6119d382018-07-20 18:41:34 -0700261 destroy();
Chris Lattner4c95a502018-06-23 16:03:42 -0700262}
263
Chris Lattner1e9fd7f2018-07-26 08:56:26 -0700264/// Return the list of destination entries that this terminator branches to.
Chris Lattner548cd7f2018-07-26 11:30:28 -0700265MutableArrayRef<BasicBlockOperand> TerminatorInst::getBasicBlockOperands() {
Chris Lattner1e9fd7f2018-07-26 08:56:26 -0700266 switch (getKind()) {
267 case Kind::Operation:
MLIR Team6f8692f2018-07-26 09:23:10 -0700268 llvm_unreachable("not a terminator");
Chris Lattner1e9fd7f2018-07-26 08:56:26 -0700269 case Kind::Branch:
Chris Lattner548cd7f2018-07-26 11:30:28 -0700270 return cast<BranchInst>(this)->getBasicBlockOperands();
Chris Lattner1e9fd7f2018-07-26 08:56:26 -0700271 case Kind::CondBranch:
Chris Lattner548cd7f2018-07-26 11:30:28 -0700272 return cast<CondBranchInst>(this)->getBasicBlockOperands();
Chris Lattner1e9fd7f2018-07-26 08:56:26 -0700273 case Kind::Return:
274 // Return has no basic block successors.
275 return {};
276 }
277}
278
279//===----------------------------------------------------------------------===//
280// ReturnInst
281//===----------------------------------------------------------------------===//
282
Chris Lattner40746442018-07-21 14:32:09 -0700283/// Create a new OperationInst with the specific fields.
Chris Lattnerfc647d52018-08-27 21:05:16 -0700284ReturnInst *ReturnInst::create(Location *location,
Chris Lattner1628fa02018-08-23 14:32:25 -0700285 ArrayRef<CFGValue *> operands) {
Chris Lattner40746442018-07-21 14:32:09 -0700286 auto byteSize = totalSizeToAlloc<InstOperand>(operands.size());
287 void *rawMem = malloc(byteSize);
Chris Lattner3a467cc2018-07-01 20:28:00 -0700288
Chris Lattner40746442018-07-21 14:32:09 -0700289 // Initialize the ReturnInst part of the instruction.
Chris Lattner1628fa02018-08-23 14:32:25 -0700290 auto inst = ::new (rawMem) ReturnInst(location, operands.size());
Chris Lattner40746442018-07-21 14:32:09 -0700291
292 // Initialize the operands and results.
293 auto instOperands = inst->getInstOperands();
294 for (unsigned i = 0, e = operands.size(); i != e; ++i)
295 new (&instOperands[i]) InstOperand(inst, operands[i]);
296 return inst;
297}
298
Chris Lattnerfc647d52018-08-27 21:05:16 -0700299ReturnInst::ReturnInst(Location *location, unsigned numOperands)
Chris Lattner1628fa02018-08-23 14:32:25 -0700300 : TerminatorInst(Kind::Return, location), numOperands(numOperands) {}
301
Chris Lattner40746442018-07-21 14:32:09 -0700302void ReturnInst::destroy() {
303 this->~ReturnInst();
304 free(this);
305}
306
307ReturnInst::~ReturnInst() {
308 // Explicitly run the destructors for the operands.
309 for (auto &operand : getInstOperands())
310 operand.~InstOperand();
311}
Chris Lattner1604e472018-07-23 08:42:19 -0700312
Chris Lattner1e9fd7f2018-07-26 08:56:26 -0700313//===----------------------------------------------------------------------===//
314// BranchInst
315//===----------------------------------------------------------------------===//
316
Chris Lattnerfc647d52018-08-27 21:05:16 -0700317BranchInst::BranchInst(Location *location, BasicBlock *dest,
Chris Lattner8a9310a2018-08-24 21:13:19 -0700318 ArrayRef<CFGValue *> operands)
319 : TerminatorInst(Kind::Branch, location), dest(this, dest) {
320 addOperands(operands);
321}
Chris Lattner1e9fd7f2018-07-26 08:56:26 -0700322
323void BranchInst::setDest(BasicBlock *block) { dest.set(block); }
324
Chris Lattner1604e472018-07-23 08:42:19 -0700325/// Add one value to the operand list.
326void BranchInst::addOperand(CFGValue *value) {
327 operands.emplace_back(InstOperand(this, value));
328}
329
330/// Add a list of values to the operand list.
331void BranchInst::addOperands(ArrayRef<CFGValue *> values) {
332 operands.reserve(operands.size() + values.size());
333 for (auto *value : values)
334 addOperand(value);
335}
James Molloy4f788372018-07-24 15:01:27 -0700336
Chris Lattner1e9fd7f2018-07-26 08:56:26 -0700337//===----------------------------------------------------------------------===//
338// CondBranchInst
339//===----------------------------------------------------------------------===//
340
Chris Lattnerfc647d52018-08-27 21:05:16 -0700341CondBranchInst::CondBranchInst(Location *location, CFGValue *condition,
Chris Lattner1628fa02018-08-23 14:32:25 -0700342 BasicBlock *trueDest, BasicBlock *falseDest)
343 : TerminatorInst(Kind::CondBranch, location),
Chris Lattner1e9fd7f2018-07-26 08:56:26 -0700344 condition(condition), dests{{this}, {this}}, numTrueOperands(0) {
345 dests[falseIndex].set(falseDest);
346 dests[trueIndex].set(trueDest);
347}
348
James Molloy4f788372018-07-24 15:01:27 -0700349/// Add one value to the true operand list.
350void CondBranchInst::addTrueOperand(CFGValue *value) {
351 assert(getNumFalseOperands() == 0 &&
352 "Must insert all true operands before false operands!");
353 operands.emplace_back(InstOperand(this, value));
354 ++numTrueOperands;
355}
356
357/// Add a list of values to the true operand list.
358void CondBranchInst::addTrueOperands(ArrayRef<CFGValue *> values) {
359 operands.reserve(operands.size() + values.size());
360 for (auto *value : values)
361 addTrueOperand(value);
362}
363
364/// Add one value to the false operand list.
365void CondBranchInst::addFalseOperand(CFGValue *value) {
366 operands.emplace_back(InstOperand(this, value));
367}
368
369/// Add a list of values to the false operand list.
370void CondBranchInst::addFalseOperands(ArrayRef<CFGValue *> values) {
371 operands.reserve(operands.size() + values.size());
372 for (auto *value : values)
373 addFalseOperand(value);
374}