github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/third_party/mlir/lib/IR/OperationSupport.cpp (about) 1 //===- OperationSupport.cpp -----------------------------------------------===// 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 // This file contains out-of-line implementations of the support types that 19 // Operation and related classes build on top of. 20 // 21 //===----------------------------------------------------------------------===// 22 23 #include "mlir/IR/OperationSupport.h" 24 #include "mlir/IR/Block.h" 25 #include "mlir/IR/Operation.h" 26 using namespace mlir; 27 28 //===----------------------------------------------------------------------===// 29 // OperationState 30 //===----------------------------------------------------------------------===// 31 32 OperationState::OperationState(Location location, StringRef name) 33 : location(location), name(name, location->getContext()) {} 34 35 OperationState::OperationState(Location location, OperationName name) 36 : location(location), name(name) {} 37 38 OperationState::OperationState(Location location, StringRef name, 39 ArrayRef<Value *> operands, ArrayRef<Type> types, 40 ArrayRef<NamedAttribute> attributes, 41 ArrayRef<Block *> successors, 42 MutableArrayRef<std::unique_ptr<Region>> regions, 43 bool resizableOperandList) 44 : location(location), name(name, location->getContext()), 45 operands(operands.begin(), operands.end()), 46 types(types.begin(), types.end()), 47 attributes(attributes.begin(), attributes.end()), 48 successors(successors.begin(), successors.end()) { 49 for (std::unique_ptr<Region> &r : regions) 50 this->regions.push_back(std::move(r)); 51 } 52 53 Region *OperationState::addRegion() { 54 regions.emplace_back(new Region); 55 return regions.back().get(); 56 } 57 58 void OperationState::addRegion(std::unique_ptr<Region> &®ion) { 59 regions.push_back(std::move(region)); 60 } 61 62 //===----------------------------------------------------------------------===// 63 // OperandStorage 64 //===----------------------------------------------------------------------===// 65 66 /// Replace the operands contained in the storage with the ones provided in 67 /// 'operands'. 68 void detail::OperandStorage::setOperands(Operation *owner, 69 ArrayRef<Value *> operands) { 70 // If the number of operands is less than or equal to the current amount, we 71 // can just update in place. 72 if (operands.size() <= numOperands) { 73 auto opOperands = getOperands(); 74 75 // If the number of new operands is less than the current count, then remove 76 // any extra operands. 77 for (unsigned i = operands.size(); i != numOperands; ++i) 78 opOperands[i].~OpOperand(); 79 80 // Set the operands in place. 81 numOperands = operands.size(); 82 for (unsigned i = 0; i != numOperands; ++i) 83 opOperands[i].set(operands[i]); 84 return; 85 } 86 87 // Otherwise, we need to be resizable. 88 assert(resizable && "Only resizable operations may add operands"); 89 90 // Grow the capacity if necessary. 91 auto &resizeUtil = getResizableStorage(); 92 if (resizeUtil.capacity < operands.size()) 93 grow(resizeUtil, operands.size()); 94 95 // Set the operands. 96 OpOperand *opBegin = getRawOperands(); 97 for (unsigned i = 0; i != numOperands; ++i) 98 opBegin[i].set(operands[i]); 99 for (unsigned e = operands.size(); numOperands != e; ++numOperands) 100 new (&opBegin[numOperands]) OpOperand(owner, operands[numOperands]); 101 } 102 103 /// Erase an operand held by the storage. 104 void detail::OperandStorage::eraseOperand(unsigned index) { 105 assert(index < size()); 106 auto operands = getOperands(); 107 --numOperands; 108 109 // Shift all operands down by 1 if the operand to remove is not at the end. 110 auto indexIt = std::next(operands.begin(), index); 111 if (index != numOperands) 112 std::rotate(indexIt, std::next(indexIt), operands.end()); 113 operands[numOperands].~OpOperand(); 114 } 115 116 /// Grow the internal operand storage. 117 void detail::OperandStorage::grow(ResizableStorage &resizeUtil, 118 size_t minSize) { 119 // Allocate a new storage array. 120 resizeUtil.capacity = 121 std::max(size_t(llvm::NextPowerOf2(resizeUtil.capacity + 2)), minSize); 122 OpOperand *newStorage = static_cast<OpOperand *>( 123 llvm::safe_malloc(resizeUtil.capacity * sizeof(OpOperand))); 124 125 // Move the current operands to the new storage. 126 auto operands = getOperands(); 127 std::uninitialized_copy(std::make_move_iterator(operands.begin()), 128 std::make_move_iterator(operands.end()), newStorage); 129 130 // Destroy the original operands and update the resizable storage pointer. 131 for (auto &operand : operands) 132 operand.~OpOperand(); 133 resizeUtil.setDynamicStorage(newStorage); 134 }