#include "mlir/AffineOps/AffineOps.h"
#include "mlir/IR/Builders.h"
#include "mlir/StandardOps/Ops.h"
+#include "mlir/Transforms/FoldUtils.h"
#include "mlir/VectorOps/VectorOps.h"
namespace mlir {
template <typename Op, typename... Args>
static ValueHandle create(Args... args);
+ /// Generic mlir::Op create. This is the key to being extensible to the whole
+ /// of MLIR without duplicating the type system or the op definitions.
+ template <typename Op, typename... Args>
+ static ValueHandle create(OperationFolder &folder, Args... args);
+
/// Special case to build composed AffineApply operations.
// TODO: createOrFold when available and move inside of the `create` method.
static ValueHandle createComposedAffineApply(AffineMap map,
llvm_unreachable("unsupported operation, use an OperationHandle instead");
}
+template <typename Op, typename... Args>
+ValueHandle ValueHandle::create(OperationFolder &folder, Args... args) {
+ return ValueHandle(folder.create<Op>(ScopedContext::getBuilder(),
+ ScopedContext::getLocation(), args...));
+}
+
namespace op {
ValueHandle operator+(ValueHandle lhs, ValueHandle rhs);
/// Without subclassing, implicit conversion to Value* would fail when composing
/// in patterns such as: `select(a, b, select(c, d, e))`.
template <typename Op> struct ValueBuilder : public ValueHandle {
+ // Builder-based
template <typename... Args>
ValueBuilder(Args... args)
: ValueHandle(ValueHandle::create<Op>(detail::unpack(args)...)) {}
: ValueHandle(ValueHandle::create<Op>(
detail::unpack(t1), detail::unpack(t2), detail::unpack(vs),
detail::unpack(args)...)) {}
+
+ /// Folder-based
+ template <typename... Args>
+ ValueBuilder(OperationFolder &folder, Args... args)
+ : ValueHandle(ValueHandle::create<Op>(folder, detail::unpack(args)...)) {}
+ ValueBuilder(OperationFolder &folder, ArrayRef<ValueHandle> vs)
+ : ValueBuilder(ValueBuilder::create<Op>(folder, detail::unpack(vs))) {}
+ template <typename... Args>
+ ValueBuilder(OperationFolder &folder, ArrayRef<ValueHandle> vs, Args... args)
+ : ValueHandle(ValueHandle::create<Op>(folder, detail::unpack(vs),
+ detail::unpack(args)...)) {}
+ template <typename T, typename... Args>
+ ValueBuilder(OperationFolder &folder, T t, ArrayRef<ValueHandle> vs,
+ Args... args)
+ : ValueHandle(ValueHandle::create<Op>(folder, detail::unpack(t),
+ detail::unpack(vs),
+ detail::unpack(args)...)) {}
+ template <typename T1, typename T2, typename... Args>
+ ValueBuilder(OperationFolder &folder, T1 t1, T2 t2, ArrayRef<ValueHandle> vs,
+ Args... args)
+ : ValueHandle(ValueHandle::create<Op>(
+ folder, detail::unpack(t1), detail::unpack(t2), detail::unpack(vs),
+ detail::unpack(args)...)) {}
+
ValueBuilder() : ValueHandle(ValueHandle::create<Op>()) {}
};
};
using alloc = ValueBuilder<AllocOp>;
+using affine_apply = ValueBuilder<AffineApplyOp>;
using constant_float = ValueBuilder<ConstantFloatOp>;
using constant_index = ValueBuilder<ConstantIndexOp>;
using constant_int = ValueBuilder<ConstantIntOp>;
using dealloc = OperationBuilder<DeallocOp>;
using dim = ValueBuilder<DimOp>;
using load = ValueBuilder<LoadOp>;
+using muli = ValueBuilder<MulIOp>;
using ret = OperationBuilder<ReturnOp>;
using select = ValueBuilder<SelectOp>;
using store = OperationBuilder<StoreOp>;
+using subi = ValueBuilder<SubIOp>;
using vector_type_cast = ValueBuilder<VectorTypeCastOp>;
/// Branches into the mlir::Block* captured by BlockHandle `b` with `operands`.