blob: 23aaa4a6b14ea9df91ac31d465a0c04c1310f5db [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)
Chris Lattner55315d52018-07-18 19:06:45 -070084 : Operation(name, /*isInstruction=*/ true, attributes, context),
85 Instruction(Kind::Operation), numOperands(numOperands),
86 numResults(numResults) {}
Chris Lattner3b2ef762018-07-18 15:31:25 -070087
88OperationInst::~OperationInst() {
89 // Explicitly run the destructors for the operands and results.
90 for (auto &operand : getOperands())
91 operand.~InstOperand();
92
93 for (auto &result : getResults())
94 result.~InstResult();
95}
96
Chris Lattner3a467cc2018-07-01 20:28:00 -070097mlir::BasicBlock *
98llvm::ilist_traits<::mlir::OperationInst>::getContainingBlock() {
99 size_t Offset(
100 size_t(&((BasicBlock *)nullptr->*BasicBlock::getSublistAccess(nullptr))));
101 iplist<OperationInst> *Anchor(static_cast<iplist<OperationInst> *>(this));
102 return reinterpret_cast<BasicBlock *>(reinterpret_cast<char *>(Anchor) -
103 Offset);
Chris Lattnered65a732018-06-28 20:45:33 -0700104}
105
Chris Lattner3a467cc2018-07-01 20:28:00 -0700106/// This is a trait method invoked when an instruction is added to a block. We
107/// keep the block pointer up to date.
108void llvm::ilist_traits<::mlir::OperationInst>::
109addNodeToList(OperationInst *inst) {
110 assert(!inst->getBlock() && "already in a basic block!");
111 inst->block = getContainingBlock();
112}
113
114/// This is a trait method invoked when an instruction is removed from a block.
115/// We keep the block pointer up to date.
116void llvm::ilist_traits<::mlir::OperationInst>::
117removeNodeFromList(OperationInst *inst) {
118 assert(inst->block && "not already in a basic block!");
119 inst->block = nullptr;
120}
121
122/// This is a trait method invoked when an instruction is moved from one block
123/// to another. We keep the block pointer up to date.
124void llvm::ilist_traits<::mlir::OperationInst>::
125transferNodesFromList(ilist_traits<OperationInst> &otherList,
126 instr_iterator first, instr_iterator last) {
127 // If we are transferring instructions within the same basic block, the block
128 // pointer doesn't need to be updated.
129 BasicBlock *curParent = getContainingBlock();
130 if (curParent == otherList.getContainingBlock())
131 return;
132
133 // Update the 'block' member of each instruction.
134 for (; first != last; ++first)
135 first->block = curParent;
136}
137
138/// Unlink this instruction from its BasicBlock and delete it.
139void OperationInst::eraseFromBlock() {
140 assert(getBlock() && "Instruction has no parent");
141 getBlock()->getOperations().erase(this);
142}
143
Chris Lattnered65a732018-06-28 20:45:33 -0700144//===----------------------------------------------------------------------===//
145// Terminators
146//===----------------------------------------------------------------------===//
147
Chris Lattner3a467cc2018-07-01 20:28:00 -0700148/// Remove this terminator from its BasicBlock and delete it.
149void TerminatorInst::eraseFromBlock() {
150 assert(getBlock() && "Instruction has no parent");
151 getBlock()->setTerminator(nullptr);
152 TerminatorInst::destroy(this);
Chris Lattner4c95a502018-06-23 16:03:42 -0700153}
154
Chris Lattner3a467cc2018-07-01 20:28:00 -0700155