blob: 729936a6a8d77ff457c9708db9b82830b187910d [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 Lattner3a467cc2018-07-01 20:28:00 -070055mlir::BasicBlock *
56llvm::ilist_traits<::mlir::OperationInst>::getContainingBlock() {
57 size_t Offset(
58 size_t(&((BasicBlock *)nullptr->*BasicBlock::getSublistAccess(nullptr))));
59 iplist<OperationInst> *Anchor(static_cast<iplist<OperationInst> *>(this));
60 return reinterpret_cast<BasicBlock *>(reinterpret_cast<char *>(Anchor) -
61 Offset);
Chris Lattnered65a732018-06-28 20:45:33 -070062}
63
Chris Lattner3a467cc2018-07-01 20:28:00 -070064/// This is a trait method invoked when an instruction is added to a block. We
65/// keep the block pointer up to date.
66void llvm::ilist_traits<::mlir::OperationInst>::
67addNodeToList(OperationInst *inst) {
68 assert(!inst->getBlock() && "already in a basic block!");
69 inst->block = getContainingBlock();
70}
71
72/// This is a trait method invoked when an instruction is removed from a block.
73/// We keep the block pointer up to date.
74void llvm::ilist_traits<::mlir::OperationInst>::
75removeNodeFromList(OperationInst *inst) {
76 assert(inst->block && "not already in a basic block!");
77 inst->block = nullptr;
78}
79
80/// This is a trait method invoked when an instruction is moved from one block
81/// to another. We keep the block pointer up to date.
82void llvm::ilist_traits<::mlir::OperationInst>::
83transferNodesFromList(ilist_traits<OperationInst> &otherList,
84 instr_iterator first, instr_iterator last) {
85 // If we are transferring instructions within the same basic block, the block
86 // pointer doesn't need to be updated.
87 BasicBlock *curParent = getContainingBlock();
88 if (curParent == otherList.getContainingBlock())
89 return;
90
91 // Update the 'block' member of each instruction.
92 for (; first != last; ++first)
93 first->block = curParent;
94}
95
96/// Unlink this instruction from its BasicBlock and delete it.
97void OperationInst::eraseFromBlock() {
98 assert(getBlock() && "Instruction has no parent");
99 getBlock()->getOperations().erase(this);
100}
101
102
103
Chris Lattnered65a732018-06-28 20:45:33 -0700104//===----------------------------------------------------------------------===//
105// Terminators
106//===----------------------------------------------------------------------===//
107
Chris Lattner3a467cc2018-07-01 20:28:00 -0700108/// Remove this terminator from its BasicBlock and delete it.
109void TerminatorInst::eraseFromBlock() {
110 assert(getBlock() && "Instruction has no parent");
111 getBlock()->setTerminator(nullptr);
112 TerminatorInst::destroy(this);
Chris Lattner4c95a502018-06-23 16:03:42 -0700113}
114
Chris Lattner3a467cc2018-07-01 20:28:00 -0700115