blob: 428523ee70534abbafd461f43e856225714e1061 [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 Lattnered65a732018-06-28 20:45:33 -070073//===----------------------------------------------------------------------===//
74// OperationInst
75//===----------------------------------------------------------------------===//
76
Chris Lattner3b2ef762018-07-18 15:31:25 -070077/// Create a new OperationInst with the specific fields.
78OperationInst *OperationInst::create(Identifier name,
79 ArrayRef<CFGValue *> operands,
80 ArrayRef<Type *> resultTypes,
81 ArrayRef<NamedAttribute> attributes,
82 MLIRContext *context) {
83 auto byteSize = totalSizeToAlloc<InstOperand, InstResult>(operands.size(),
84 resultTypes.size());
Chris Lattner6119d382018-07-20 18:41:34 -070085 void *rawMem = malloc(byteSize);
Chris Lattner3b2ef762018-07-18 15:31:25 -070086
87 // Initialize the OperationInst part of the instruction.
88 auto inst = ::new (rawMem) OperationInst(
89 name, operands.size(), resultTypes.size(), attributes, context);
90
91 // Initialize the operands and results.
Chris Lattnerf8cce872018-07-20 09:28:54 -070092 auto instOperands = inst->getInstOperands();
Chris Lattner3b2ef762018-07-18 15:31:25 -070093 for (unsigned i = 0, e = operands.size(); i != e; ++i)
94 new (&instOperands[i]) InstOperand(inst, operands[i]);
95
Chris Lattnerf8cce872018-07-20 09:28:54 -070096 auto instResults = inst->getInstResults();
Chris Lattner3b2ef762018-07-18 15:31:25 -070097 for (unsigned i = 0, e = resultTypes.size(); i != e; ++i)
98 new (&instResults[i]) InstResult(resultTypes[i], inst);
99 return inst;
100}
101
102OperationInst::OperationInst(Identifier name, unsigned numOperands,
103 unsigned numResults,
104 ArrayRef<NamedAttribute> attributes,
105 MLIRContext *context)
Chris Lattner55315d52018-07-18 19:06:45 -0700106 : Operation(name, /*isInstruction=*/ true, attributes, context),
107 Instruction(Kind::Operation), numOperands(numOperands),
108 numResults(numResults) {}
Chris Lattner3b2ef762018-07-18 15:31:25 -0700109
110OperationInst::~OperationInst() {
111 // Explicitly run the destructors for the operands and results.
Chris Lattnerf8cce872018-07-20 09:28:54 -0700112 for (auto &operand : getInstOperands())
Chris Lattner3b2ef762018-07-18 15:31:25 -0700113 operand.~InstOperand();
114
Chris Lattnerf8cce872018-07-20 09:28:54 -0700115 for (auto &result : getInstResults())
Chris Lattner3b2ef762018-07-18 15:31:25 -0700116 result.~InstResult();
117}
118
Chris Lattner3a467cc2018-07-01 20:28:00 -0700119mlir::BasicBlock *
120llvm::ilist_traits<::mlir::OperationInst>::getContainingBlock() {
121 size_t Offset(
122 size_t(&((BasicBlock *)nullptr->*BasicBlock::getSublistAccess(nullptr))));
123 iplist<OperationInst> *Anchor(static_cast<iplist<OperationInst> *>(this));
124 return reinterpret_cast<BasicBlock *>(reinterpret_cast<char *>(Anchor) -
125 Offset);
Chris Lattnered65a732018-06-28 20:45:33 -0700126}
127
Chris Lattner3a467cc2018-07-01 20:28:00 -0700128/// This is a trait method invoked when an instruction is added to a block. We
129/// keep the block pointer up to date.
130void llvm::ilist_traits<::mlir::OperationInst>::
131addNodeToList(OperationInst *inst) {
132 assert(!inst->getBlock() && "already in a basic block!");
133 inst->block = getContainingBlock();
134}
135
136/// This is a trait method invoked when an instruction is removed from a block.
137/// We keep the block pointer up to date.
138void llvm::ilist_traits<::mlir::OperationInst>::
139removeNodeFromList(OperationInst *inst) {
140 assert(inst->block && "not already in a basic block!");
141 inst->block = nullptr;
142}
143
144/// This is a trait method invoked when an instruction is moved from one block
145/// to another. We keep the block pointer up to date.
146void llvm::ilist_traits<::mlir::OperationInst>::
147transferNodesFromList(ilist_traits<OperationInst> &otherList,
148 instr_iterator first, instr_iterator last) {
149 // If we are transferring instructions within the same basic block, the block
150 // pointer doesn't need to be updated.
151 BasicBlock *curParent = getContainingBlock();
152 if (curParent == otherList.getContainingBlock())
153 return;
154
155 // Update the 'block' member of each instruction.
156 for (; first != last; ++first)
157 first->block = curParent;
158}
159
160/// Unlink this instruction from its BasicBlock and delete it.
161void OperationInst::eraseFromBlock() {
162 assert(getBlock() && "Instruction has no parent");
163 getBlock()->getOperations().erase(this);
164}
165
Chris Lattner6119d382018-07-20 18:41:34 -0700166/// If this value is the result of an OperationInst, return the instruction
167/// that defines it.
168OperationInst *SSAValue::getDefiningInst() {
169 if (auto *result = dyn_cast<InstResult>(this))
170 return result->getOwner();
171 return nullptr;
172}
173
Chris Lattnered65a732018-06-28 20:45:33 -0700174//===----------------------------------------------------------------------===//
175// Terminators
176//===----------------------------------------------------------------------===//
177
Chris Lattner3a467cc2018-07-01 20:28:00 -0700178/// Remove this terminator from its BasicBlock and delete it.
179void TerminatorInst::eraseFromBlock() {
180 assert(getBlock() && "Instruction has no parent");
181 getBlock()->setTerminator(nullptr);
Chris Lattner6119d382018-07-20 18:41:34 -0700182 destroy();
Chris Lattner4c95a502018-06-23 16:03:42 -0700183}
184
Chris Lattner40746442018-07-21 14:32:09 -0700185/// Create a new OperationInst with the specific fields.
186ReturnInst *ReturnInst::create(ArrayRef<CFGValue *> operands) {
187 auto byteSize = totalSizeToAlloc<InstOperand>(operands.size());
188 void *rawMem = malloc(byteSize);
Chris Lattner3a467cc2018-07-01 20:28:00 -0700189
Chris Lattner40746442018-07-21 14:32:09 -0700190 // Initialize the ReturnInst part of the instruction.
191 auto inst = ::new (rawMem) ReturnInst(operands.size());
192
193 // Initialize the operands and results.
194 auto instOperands = inst->getInstOperands();
195 for (unsigned i = 0, e = operands.size(); i != e; ++i)
196 new (&instOperands[i]) InstOperand(inst, operands[i]);
197 return inst;
198}
199
200void ReturnInst::destroy() {
201 this->~ReturnInst();
202 free(this);
203}
204
205ReturnInst::~ReturnInst() {
206 // Explicitly run the destructors for the operands.
207 for (auto &operand : getInstOperands())
208 operand.~InstOperand();
209}