1 //===- ImplicitLocOpBuilder.h - Convenience OpBuilder -----------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Helper class to create ops with a modally set location. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef MLIR_IR_IMPLICITLOCOPBUILDER_H 14 #define MLIR_IR_IMPLICITLOCOPBUILDER_H 15 16 #include "mlir/IR/Builders.h" 17 18 namespace mlir { 19 20 /// ImplicitLocOpBuilder maintains a 'current location', allowing use of the 21 /// create<> method without specifying the location. It is otherwise the same 22 /// as OpBuilder. 23 class ImplicitLocOpBuilder : public mlir::OpBuilder { 24 public: 25 /// OpBuilder has a bunch of convenience constructors - we support them all 26 /// with the additional Location. 27 template <typename... T> ImplicitLocOpBuilder(Location loc,T &&...operands)28 ImplicitLocOpBuilder(Location loc, T &&...operands) 29 : OpBuilder(std::forward<T>(operands)...), curLoc(loc) {} 30 31 /// Create a builder and set the insertion point to before the first operation 32 /// in the block but still inside the block. 33 static ImplicitLocOpBuilder atBlockBegin(Location loc, Block *block, 34 Listener *listener = nullptr) { 35 return ImplicitLocOpBuilder(loc, block, block->begin(), listener); 36 } 37 38 /// Create a builder and set the insertion point to after the last operation 39 /// in the block but still inside the block. 40 static ImplicitLocOpBuilder atBlockEnd(Location loc, Block *block, 41 Listener *listener = nullptr) { 42 return ImplicitLocOpBuilder(loc, block, block->end(), listener); 43 } 44 45 /// Create a builder and set the insertion point to before the block 46 /// terminator. 47 static ImplicitLocOpBuilder atBlockTerminator(Location loc, Block *block, 48 Listener *listener = nullptr) { 49 auto *terminator = block->getTerminator(); 50 assert(terminator != nullptr && "the block has no terminator"); 51 return ImplicitLocOpBuilder(loc, block, Block::iterator(terminator), 52 listener); 53 } 54 55 /// Accessors for the implied location. getLoc()56 Location getLoc() const { return curLoc; } setLoc(Location loc)57 void setLoc(Location loc) { curLoc = loc; } 58 59 // We allow clients to use the explicit-loc version of create as well. 60 using OpBuilder::create; 61 using OpBuilder::createOrFold; 62 63 /// Create an operation of specific op type at the current insertion point and 64 /// location. 65 template <typename OpTy, typename... Args> create(Args &&...args)66 OpTy create(Args &&...args) { 67 return OpBuilder::create<OpTy>(curLoc, std::forward<Args>(args)...); 68 } 69 70 /// Create an operation of specific op type at the current insertion point, 71 /// and immediately try to fold it. This functions populates 'results' with 72 /// the results after folding the operation. 73 template <typename OpTy, typename... Args> createOrFold(llvm::SmallVectorImpl<Value> & results,Args &&...args)74 void createOrFold(llvm::SmallVectorImpl<Value> &results, Args &&...args) { 75 OpBuilder::createOrFold<OpTy>(results, curLoc, std::forward<Args>(args)...); 76 } 77 78 /// Overload to create or fold a single result operation. 79 template <typename OpTy, typename... Args> 80 std::enable_if_t<OpTy::template hasTrait<mlir::OpTrait::OneResult>(), Value> createOrFold(Args &&...args)81 createOrFold(Args &&...args) { 82 return OpBuilder::createOrFold<OpTy>(curLoc, std::forward<Args>(args)...); 83 } 84 85 /// Overload to create or fold a zero result operation. 86 template <typename OpTy, typename... Args> 87 std::enable_if_t<OpTy::template hasTrait<mlir::OpTrait::ZeroResults>(), OpTy> createOrFold(Args &&...args)88 createOrFold(Args &&...args) { 89 return OpBuilder::createOrFold<OpTy>(curLoc, std::forward<Args>(args)...); 90 } 91 92 /// This builder can also be used to emit diagnostics to the current location. 93 mlir::InFlightDiagnostic 94 emitError(const llvm::Twine &message = llvm::Twine()) { 95 return mlir::emitError(curLoc, message); 96 } 97 mlir::InFlightDiagnostic 98 emitWarning(const llvm::Twine &message = llvm::Twine()) { 99 return mlir::emitWarning(curLoc, message); 100 } 101 mlir::InFlightDiagnostic 102 emitRemark(const llvm::Twine &message = llvm::Twine()) { 103 return mlir::emitRemark(curLoc, message); 104 } 105 106 private: 107 Location curLoc; 108 }; 109 110 } // namespace mlir 111 112 #endif // MLIR_IR_IMPLICITLOCOPBUILDER_H 113