blob: e9e28cb969fe714d6d07bd65c3953706e7ff609c [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 Lattnered65a732018-06-28 20:45:33 -070022//===----------------------------------------------------------------------===//
23// Instruction
24//===----------------------------------------------------------------------===//
25
Chris Lattner3a467cc2018-07-01 20:28:00 -070026// Instructions are deleted through the destroy() member because we don't have
27// a virtual destructor.
28Instruction::~Instruction() {
29 assert(block == nullptr && "instruction destroyed but still in a block");
30}
31
32/// Destroy this instruction or one of its subclasses.
33void Instruction::destroy(Instruction *inst) {
34 switch (inst->getKind()) {
35 case Kind::Operation:
36 delete cast<OperationInst>(inst);
37 break;
38 case Kind::Branch:
39 delete cast<BranchInst>(inst);
40 break;
41 case Kind::Return:
42 delete cast<ReturnInst>(inst);
43 break;
44 }
45}
46
Chris Lattnered65a732018-06-28 20:45:33 -070047CFGFunction *Instruction::getFunction() const {
Chris Lattner4c95a502018-06-23 16:03:42 -070048 return getBlock()->getFunction();
49}
50
Chris Lattnered65a732018-06-28 20:45:33 -070051//===----------------------------------------------------------------------===//
52// OperationInst
53//===----------------------------------------------------------------------===//
54
Chris Lattner3b2ef762018-07-18 15:31:25 -070055/// Create a new OperationInst with the specific fields.
56OperationInst *OperationInst::create(Identifier name,
57 ArrayRef<CFGValue *> operands,
58 ArrayRef<Type *> resultTypes,
59 ArrayRef<NamedAttribute> attributes,
60 MLIRContext *context) {
61 auto byteSize = totalSizeToAlloc<InstOperand, InstResult>(operands.size(),
62 resultTypes.size());
63 void *rawMem = ::operator new(byteSize);
64
65 // Initialize the OperationInst part of the instruction.
66 auto inst = ::new (rawMem) OperationInst(
67 name, operands.size(), resultTypes.size(), attributes, context);
68
69 // Initialize the operands and results.
70 auto instOperands = inst->getOperands();
71 for (unsigned i = 0, e = operands.size(); i != e; ++i)
72 new (&instOperands[i]) InstOperand(inst, operands[i]);
73
74 auto instResults = inst->getResults();
75 for (unsigned i = 0, e = resultTypes.size(); i != e; ++i)
76 new (&instResults[i]) InstResult(resultTypes[i], inst);
77 return inst;
78}
79
80OperationInst::OperationInst(Identifier name, unsigned numOperands,
81 unsigned numResults,
82 ArrayRef<NamedAttribute> attributes,
83 MLIRContext *context)
84 : Operation(name, attributes, context), Instruction(Kind::Operation),
85 numOperands(numOperands), numResults(numResults) {}
86
87OperationInst::~OperationInst() {
88 // Explicitly run the destructors for the operands and results.
89 for (auto &operand : getOperands())
90 operand.~InstOperand();
91
92 for (auto &result : getResults())
93 result.~InstResult();
94}
95
Chris Lattner3a467cc2018-07-01 20:28:00 -070096mlir::BasicBlock *
97llvm::ilist_traits<::mlir::OperationInst>::getContainingBlock() {
98 size_t Offset(
99 size_t(&((BasicBlock *)nullptr->*BasicBlock::getSublistAccess(nullptr))));
100 iplist<OperationInst> *Anchor(static_cast<iplist<OperationInst> *>(this));
101 return reinterpret_cast<BasicBlock *>(reinterpret_cast<char *>(Anchor) -
102 Offset);
Chris Lattnered65a732018-06-28 20:45:33 -0700103}
104
Chris Lattner3a467cc2018-07-01 20:28:00 -0700105/// This is a trait method invoked when an instruction is added to a block. We
106/// keep the block pointer up to date.
107void llvm::ilist_traits<::mlir::OperationInst>::
108addNodeToList(OperationInst *inst) {
109 assert(!inst->getBlock() && "already in a basic block!");
110 inst->block = getContainingBlock();
111}
112
113/// This is a trait method invoked when an instruction is removed from a block.
114/// We keep the block pointer up to date.
115void llvm::ilist_traits<::mlir::OperationInst>::
116removeNodeFromList(OperationInst *inst) {
117 assert(inst->block && "not already in a basic block!");
118 inst->block = nullptr;
119}
120
121/// This is a trait method invoked when an instruction is moved from one block
122/// to another. We keep the block pointer up to date.
123void llvm::ilist_traits<::mlir::OperationInst>::
124transferNodesFromList(ilist_traits<OperationInst> &otherList,
125 instr_iterator first, instr_iterator last) {
126 // If we are transferring instructions within the same basic block, the block
127 // pointer doesn't need to be updated.
128 BasicBlock *curParent = getContainingBlock();
129 if (curParent == otherList.getContainingBlock())
130 return;
131
132 // Update the 'block' member of each instruction.
133 for (; first != last; ++first)
134 first->block = curParent;
135}
136
137/// Unlink this instruction from its BasicBlock and delete it.
138void OperationInst::eraseFromBlock() {
139 assert(getBlock() && "Instruction has no parent");
140 getBlock()->getOperations().erase(this);
141}
142
Chris Lattnered65a732018-06-28 20:45:33 -0700143//===----------------------------------------------------------------------===//
144// Terminators
145//===----------------------------------------------------------------------===//
146
Chris Lattner3a467cc2018-07-01 20:28:00 -0700147/// Remove this terminator from its BasicBlock and delete it.
148void TerminatorInst::eraseFromBlock() {
149 assert(getBlock() && "Instruction has no parent");
150 getBlock()->setTerminator(nullptr);
151 TerminatorInst::destroy(this);
Chris Lattner4c95a502018-06-23 16:03:42 -0700152}
153
Chris Lattner3a467cc2018-07-01 20:28:00 -0700154