xref: /llvm-project/mlir/include/mlir/IR/ImplicitLocOpBuilder.h (revision f11925e0f0c49737509216403136204624dc2a29)
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