Chris Lattner | 4c95a50 | 2018-06-23 16:03:42 -0700 | [diff] [blame] | 1 | //===- BasicBlock.h - MLIR BasicBlock Class ---------------------*- C++ -*-===// |
| 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 | #ifndef MLIR_IR_BASICBLOCK_H |
| 19 | #define MLIR_IR_BASICBLOCK_H |
| 20 | |
| 21 | #include "mlir/IR/Instructions.h" |
Chris Lattner | 3a467cc | 2018-07-01 20:28:00 -0700 | [diff] [blame] | 22 | #include <memory> |
Chris Lattner | 4c95a50 | 2018-06-23 16:03:42 -0700 | [diff] [blame] | 23 | |
| 24 | namespace mlir { |
James Molloy | 61a656c | 2018-07-22 15:45:24 -0700 | [diff] [blame] | 25 | class BBArgument; |
Chris Lattner | 4c95a50 | 2018-06-23 16:03:42 -0700 | [diff] [blame] | 26 | |
| 27 | /// Each basic block in a CFG function contains a list of basic block arguments, |
| 28 | /// normal instructions, and a terminator instruction. |
| 29 | /// |
| 30 | /// Basic blocks form a graph (the CFG) which can be traversed through |
| 31 | /// predecessor and successor edges. |
Chris Lattner | 3a467cc | 2018-07-01 20:28:00 -0700 | [diff] [blame] | 32 | class BasicBlock |
| 33 | : public llvm::ilist_node_with_parent<BasicBlock, CFGFunction> { |
Chris Lattner | 4c95a50 | 2018-06-23 16:03:42 -0700 | [diff] [blame] | 34 | public: |
Chris Lattner | 3a467cc | 2018-07-01 20:28:00 -0700 | [diff] [blame] | 35 | explicit BasicBlock(); |
| 36 | ~BasicBlock(); |
Chris Lattner | 4c95a50 | 2018-06-23 16:03:42 -0700 | [diff] [blame] | 37 | |
| 38 | /// Return the function that a BasicBlock is part of. |
| 39 | CFGFunction *getFunction() const { |
| 40 | return function; |
| 41 | } |
| 42 | |
Chris Lattner | 3a467cc | 2018-07-01 20:28:00 -0700 | [diff] [blame] | 43 | /// Unlink this BasicBlock from its CFGFunction and delete it. |
| 44 | void eraseFromFunction(); |
Chris Lattner | 4c95a50 | 2018-06-23 16:03:42 -0700 | [diff] [blame] | 45 | |
Chris Lattner | 3a467cc | 2018-07-01 20:28:00 -0700 | [diff] [blame] | 46 | //===--------------------------------------------------------------------===// |
James Molloy | 61a656c | 2018-07-22 15:45:24 -0700 | [diff] [blame] | 47 | // Block arguments management |
| 48 | //===--------------------------------------------------------------------===// |
| 49 | |
| 50 | // This is the list of arguments to the block. |
| 51 | typedef ArrayRef<BBArgument *> BBArgListType; |
| 52 | BBArgListType getArguments() const { return arguments; } |
| 53 | |
| 54 | using args_iterator = BBArgListType::iterator; |
| 55 | using reverse_args_iterator = BBArgListType::reverse_iterator; |
| 56 | args_iterator args_begin() const { return getArguments().begin(); } |
| 57 | args_iterator args_end() const { return getArguments().end(); } |
| 58 | reverse_args_iterator args_rbegin() const { return getArguments().rbegin(); } |
| 59 | reverse_args_iterator args_rend() const { return getArguments().rend(); } |
| 60 | |
| 61 | bool args_empty() const { return arguments.empty(); } |
Chris Lattner | 1604e47 | 2018-07-23 08:42:19 -0700 | [diff] [blame] | 62 | |
| 63 | /// Add one value to the operand list. |
James Molloy | 61a656c | 2018-07-22 15:45:24 -0700 | [diff] [blame] | 64 | BBArgument *addArgument(Type *type); |
Chris Lattner | 1604e47 | 2018-07-23 08:42:19 -0700 | [diff] [blame] | 65 | |
| 66 | /// Add one argument to the argument list for each type specified in the list. |
| 67 | llvm::iterator_range<args_iterator> addArguments(ArrayRef<Type *> types); |
James Molloy | 61a656c | 2018-07-22 15:45:24 -0700 | [diff] [blame] | 68 | |
| 69 | unsigned getNumArguments() const { return arguments.size(); } |
| 70 | BBArgument *getArgument(unsigned i) { return arguments[i]; } |
| 71 | const BBArgument *getArgument(unsigned i) const { return arguments[i]; } |
| 72 | |
| 73 | //===--------------------------------------------------------------------===// |
Chris Lattner | 3a467cc | 2018-07-01 20:28:00 -0700 | [diff] [blame] | 74 | // Operation list management |
| 75 | //===--------------------------------------------------------------------===// |
| 76 | |
| 77 | /// This is the list of operations in the block. |
| 78 | typedef llvm::iplist<OperationInst> OperationListType; |
| 79 | OperationListType &getOperations() { return operations; } |
| 80 | const OperationListType &getOperations() const { return operations; } |
| 81 | |
| 82 | // Iteration over the operations in the block. |
| 83 | using iterator = OperationListType::iterator; |
| 84 | using const_iterator = OperationListType::const_iterator; |
| 85 | using reverse_iterator = OperationListType::reverse_iterator; |
| 86 | using const_reverse_iterator = OperationListType::const_reverse_iterator; |
| 87 | |
| 88 | iterator begin() { return operations.begin(); } |
| 89 | iterator end() { return operations.end(); } |
| 90 | const_iterator begin() const { return operations.begin(); } |
| 91 | const_iterator end() const { return operations.end(); } |
| 92 | reverse_iterator rbegin() { return operations.rbegin(); } |
| 93 | reverse_iterator rend() { return operations.rend(); } |
| 94 | const_reverse_iterator rbegin() const { return operations.rbegin(); } |
| 95 | const_reverse_iterator rend() const { return operations.rend(); } |
| 96 | |
| 97 | bool empty() const { return operations.empty(); } |
| 98 | void push_back(OperationInst *inst) { operations.push_back(inst); } |
| 99 | void push_front(OperationInst *inst) { operations.push_front(inst); } |
| 100 | |
| 101 | OperationInst &back() { return operations.back(); } |
| 102 | const OperationInst &back() const { |
| 103 | return const_cast<BasicBlock *>(this)->back(); |
Chris Lattner | 4c95a50 | 2018-06-23 16:03:42 -0700 | [diff] [blame] | 104 | } |
Chris Lattner | 3a467cc | 2018-07-01 20:28:00 -0700 | [diff] [blame] | 105 | |
| 106 | OperationInst &front() { return operations.front(); } |
| 107 | const OperationInst &front() const { |
| 108 | return const_cast<BasicBlock*>(this)->front(); |
| 109 | } |
| 110 | |
| 111 | //===--------------------------------------------------------------------===// |
| 112 | // Terminator management |
| 113 | //===--------------------------------------------------------------------===// |
| 114 | |
| 115 | /// Change the terminator of this block to the specified instruction. |
| 116 | void setTerminator(TerminatorInst *inst); |
| 117 | |
Chris Lattner | 4c95a50 | 2018-06-23 16:03:42 -0700 | [diff] [blame] | 118 | TerminatorInst *getTerminator() const { return terminator; } |
| 119 | |
| 120 | void print(raw_ostream &os) const; |
| 121 | void dump() const; |
| 122 | |
Chris Lattner | 3a467cc | 2018-07-01 20:28:00 -0700 | [diff] [blame] | 123 | /// getSublistAccess() - Returns pointer to member of operation list |
| 124 | static OperationListType BasicBlock::*getSublistAccess(OperationInst*) { |
| 125 | return &BasicBlock::operations; |
| 126 | } |
| 127 | |
Chris Lattner | 4c95a50 | 2018-06-23 16:03:42 -0700 | [diff] [blame] | 128 | private: |
Chris Lattner | 3a467cc | 2018-07-01 20:28:00 -0700 | [diff] [blame] | 129 | CFGFunction *function = nullptr; |
| 130 | |
| 131 | /// This is the list of operations in the block. |
| 132 | OperationListType operations; |
| 133 | |
James Molloy | 61a656c | 2018-07-22 15:45:24 -0700 | [diff] [blame] | 134 | /// This is the list of arguments to the block. |
| 135 | std::vector<BBArgument *> arguments; |
| 136 | |
Chris Lattner | 3a467cc | 2018-07-01 20:28:00 -0700 | [diff] [blame] | 137 | /// This is the owning reference to the terminator of the block. |
Chris Lattner | 4c95a50 | 2018-06-23 16:03:42 -0700 | [diff] [blame] | 138 | TerminatorInst *terminator = nullptr; |
Chris Lattner | 3a467cc | 2018-07-01 20:28:00 -0700 | [diff] [blame] | 139 | |
| 140 | BasicBlock(const BasicBlock&) = delete; |
| 141 | void operator=(const BasicBlock&) = delete; |
| 142 | |
| 143 | friend struct llvm::ilist_traits<BasicBlock>; |
Chris Lattner | 4c95a50 | 2018-06-23 16:03:42 -0700 | [diff] [blame] | 144 | }; |
| 145 | |
| 146 | } // end namespace mlir |
| 147 | |
Chris Lattner | 3a467cc | 2018-07-01 20:28:00 -0700 | [diff] [blame] | 148 | //===----------------------------------------------------------------------===// |
Chris Lattner | a8e4767 | 2018-07-25 14:08:16 -0700 | [diff] [blame^] | 149 | // ilist_traits for BasicBlock |
Chris Lattner | 3a467cc | 2018-07-01 20:28:00 -0700 | [diff] [blame] | 150 | //===----------------------------------------------------------------------===// |
| 151 | |
| 152 | namespace llvm { |
| 153 | |
| 154 | template <> |
| 155 | struct ilist_traits<::mlir::BasicBlock> |
| 156 | : public ilist_alloc_traits<::mlir::BasicBlock> { |
| 157 | using BasicBlock = ::mlir::BasicBlock; |
| 158 | using block_iterator = simple_ilist<BasicBlock>::iterator; |
| 159 | |
| 160 | void addNodeToList(BasicBlock *block); |
| 161 | void removeNodeFromList(BasicBlock *block); |
| 162 | void transferNodesFromList(ilist_traits<BasicBlock> &otherList, |
| 163 | block_iterator first, block_iterator last); |
| 164 | private: |
| 165 | mlir::CFGFunction *getContainingFunction(); |
| 166 | }; |
| 167 | } // end namespace llvm |
| 168 | |
| 169 | |
Chris Lattner | 4c95a50 | 2018-06-23 16:03:42 -0700 | [diff] [blame] | 170 | #endif // MLIR_IR_BASICBLOCK_H |