Skip to content

Commit 2eb733b

Browse files
authored
[mlir][tblgen] add concrete create methods (#147168)
Currently `builder.create<...>` does not in any meaningful way hint/show the various builders an op supports (arg names/types) because [`create` forwards the args to `build`](https://github.com/llvm/llvm-project/blob/887222e3526fbe08e748a33f740296ac22bf1ab1/mlir/include/mlir/IR/Builders.h#L503). To improve QoL, this PR adds static create methods to the ops themselves like ```c++ static arith::ConstantIntOp create(OpBuilder& builder, Location location, int64_t value, unsigned width); ``` Now if one types `arith::ConstantIntO::create(builder,...` instead of `builder.create<arith::ConstantIntO>(...` auto-complete/hints will pop up. See https://discourse.llvm.org/t/rfc-building-mlir-operation-observed-caveats-and-proposed-solution/87204/13 for more info.
1 parent e10db15 commit 2eb733b

File tree

6 files changed

+291
-102
lines changed

6 files changed

+291
-102
lines changed

mlir/include/mlir/IR/Builders.h

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,96 @@ class OpBuilder : public Builder {
615615
Block::iterator insertPoint;
616616
};
617617

618+
/// ImplicitLocOpBuilder maintains a 'current location', allowing use of the
619+
/// create<> method without specifying the location. It is otherwise the same
620+
/// as OpBuilder.
621+
class ImplicitLocOpBuilder : public mlir::OpBuilder {
622+
public:
623+
/// OpBuilder has a bunch of convenience constructors - we support them all
624+
/// with the additional Location.
625+
template <typename... T>
626+
ImplicitLocOpBuilder(Location loc, T &&...operands)
627+
: OpBuilder(std::forward<T>(operands)...), curLoc(loc) {}
628+
629+
/// Create a builder and set the insertion point to before the first operation
630+
/// in the block but still inside the block.
631+
static ImplicitLocOpBuilder atBlockBegin(Location loc, Block *block,
632+
Listener *listener = nullptr) {
633+
return ImplicitLocOpBuilder(loc, block, block->begin(), listener);
634+
}
635+
636+
/// Create a builder and set the insertion point to after the last operation
637+
/// in the block but still inside the block.
638+
static ImplicitLocOpBuilder atBlockEnd(Location loc, Block *block,
639+
Listener *listener = nullptr) {
640+
return ImplicitLocOpBuilder(loc, block, block->end(), listener);
641+
}
642+
643+
/// Create a builder and set the insertion point to before the block
644+
/// terminator.
645+
static ImplicitLocOpBuilder atBlockTerminator(Location loc, Block *block,
646+
Listener *listener = nullptr) {
647+
auto *terminator = block->getTerminator();
648+
assert(terminator != nullptr && "the block has no terminator");
649+
return ImplicitLocOpBuilder(loc, block, Block::iterator(terminator),
650+
listener);
651+
}
652+
653+
/// Accessors for the implied location.
654+
Location getLoc() const { return curLoc; }
655+
void setLoc(Location loc) { curLoc = loc; }
656+
657+
// We allow clients to use the explicit-loc version of create as well.
658+
using OpBuilder::create;
659+
using OpBuilder::createOrFold;
660+
661+
/// Create an operation of specific op type at the current insertion point and
662+
/// location.
663+
template <typename OpTy, typename... Args>
664+
OpTy create(Args &&...args) {
665+
return OpBuilder::create<OpTy>(curLoc, std::forward<Args>(args)...);
666+
}
667+
668+
/// Create an operation of specific op type at the current insertion point,
669+
/// and immediately try to fold it. This functions populates 'results' with
670+
/// the results after folding the operation.
671+
template <typename OpTy, typename... Args>
672+
void createOrFold(llvm::SmallVectorImpl<Value> &results, Args &&...args) {
673+
OpBuilder::createOrFold<OpTy>(results, curLoc, std::forward<Args>(args)...);
674+
}
675+
676+
/// Overload to create or fold a single result operation.
677+
template <typename OpTy, typename... Args>
678+
std::enable_if_t<OpTy::template hasTrait<mlir::OpTrait::OneResult>(), Value>
679+
createOrFold(Args &&...args) {
680+
return OpBuilder::createOrFold<OpTy>(curLoc, std::forward<Args>(args)...);
681+
}
682+
683+
/// Overload to create or fold a zero result operation.
684+
template <typename OpTy, typename... Args>
685+
std::enable_if_t<OpTy::template hasTrait<mlir::OpTrait::ZeroResults>(), OpTy>
686+
createOrFold(Args &&...args) {
687+
return OpBuilder::createOrFold<OpTy>(curLoc, std::forward<Args>(args)...);
688+
}
689+
690+
/// This builder can also be used to emit diagnostics to the current location.
691+
mlir::InFlightDiagnostic
692+
emitError(const llvm::Twine &message = llvm::Twine()) {
693+
return mlir::emitError(curLoc, message);
694+
}
695+
mlir::InFlightDiagnostic
696+
emitWarning(const llvm::Twine &message = llvm::Twine()) {
697+
return mlir::emitWarning(curLoc, message);
698+
}
699+
mlir::InFlightDiagnostic
700+
emitRemark(const llvm::Twine &message = llvm::Twine()) {
701+
return mlir::emitRemark(curLoc, message);
702+
}
703+
704+
private:
705+
Location curLoc;
706+
};
707+
618708
} // namespace mlir
619709

620710
#endif

mlir/include/mlir/IR/ImplicitLocOpBuilder.h

Lines changed: 0 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -15,98 +15,4 @@
1515

1616
#include "mlir/IR/Builders.h"
1717

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>
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.
56-
Location getLoc() const { return curLoc; }
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>
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>
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>
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>
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-
11218
#endif // MLIR_IR_IMPLICITLOCOPBUILDER_H

mlir/include/mlir/IR/OpDefinition.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
namespace mlir {
3131
class Builder;
3232
class OpBuilder;
33+
class ImplicitLocOpBuilder;
3334

3435
/// This class implements `Optional` functionality for ParseResult. We don't
3536
/// directly use Optional here, because it provides an implicit conversion

mlir/include/mlir/TableGen/Class.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ class MethodParameter {
7171
StringRef getName() const { return name; }
7272
/// Returns true if the parameter has a default value.
7373
bool hasDefaultValue() const { return !defaultValue.empty(); }
74+
/// Get the default value.
75+
StringRef getDefaultValue() const { return defaultValue; }
76+
/// Returns true if the parameter is optional.
77+
bool isOptional() const { return optional; }
7478

7579
private:
7680
/// The C++ type.

0 commit comments

Comments
 (0)