Including user header files in ODS file?

Hi,

When trying to include a user header file in a .td (ODS) file, this error appears after trying to compile : error: Unexpected input at top level

Is my understanding correct that .td files can only include other .td files or mlir files? If not, how to enable inclusion of user header files?

Thank you

You can include the necessary header files in the C++ header file that includes the .h.inc automatically generated from the td file so that the .h.inc sees those includes. Eg:

#ifndef MLIR_DIALECT_STANDARDOPS_IR_OPS_H
#define MLIR_DIALECT_STANDARDOPS_IR_OPS_H

#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/Interfaces/CallInterfaces.h"
#include "mlir/Interfaces/CastInterfaces.h"
#include "mlir/Interfaces/ControlFlowInterfaces.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
#include "mlir/Interfaces/VectorInterfaces.h"
#include "mlir/Interfaces/ViewLikeInterface.h"

// Pull in all enum type definitions and utility function declarations.
#include "mlir/Dialect/StandardOps/IR/OpsEnums.h.inc"

namespace mlir {
class AffineMap;
class Builder;
class FuncOp;
class OpBuilder;
class PatternRewriter;

/// Return the list of Range (i.e. offset, size, stride). Each Range
/// entry contains either the dynamic value or a ConstantIndexOp constructed
/// with `b` at location `loc`.
SmallVector<Range, 8> getOrCreateRanges(OffsetSizeAndStrideOpInterface op,
                                        OpBuilder &b, Location loc);

#define GET_OP_CLASSES
#include "mlir/Dialect/StandardOps/IR/Ops.h.inc"

But there is no way to add them into the .td file directly?

What problem are you trying to solve exactly? Including a c++ header in a tablegen file wouldn’t make much sense because they’re different languages

To give more specific details, I am trying to do a TypeInference pass on a large set of operations, however, for most operations the type inference logic is the same (and/or, mul/add/sub/idiv, etc.) so I would like to factorize this type inference logic by defining an interface for operations that share the same type inference logic. In this interface, I also defined in c++ (in the .td file) the method that does the type inference, but I simply need to include some c++ header files.

It looks like @bondhugula’s solutions is what you want. There is absolutely no way possible to include a C++ file into a tablegen file, no more than to include a Java file into a C++ file… We use Tablegen to generate C++, so inclusion should happen there.

Hello,

I think I have a similar problem. I defined for some ops in ODS with extra C++ methods (thanks to the extraClassDeclaration statement) that require to include some extra C++ headers.

Reading the discussion here, the suggested approach is to request the include of the extra C++ headers in the C++ source file that will include the generated .h.inc file.

I would find more elegant to have the ability to request the include directly from the ODS file (where we put the code that uses what is defined in the header).

My question is then: couldn’t we add a top level declaration, maybe at the dialect level, that would allows us to put some extra C++ code ?
Something like :

def My_Dialect : Dialect {
  let extraDeclaration = [{
   #include "myHeader.h"
   int myGlobalVariable;
  }];
}

In general, extraClassDeclaration will generate code in the .h.inc which isn’t included in a .cpp file but in a header file where we put the includes in order to make the .h.inc “standalone”, like https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/Dialect/AMX/AMXDialect.h#L21 for example. I think that is what @bondhugula was also referring to in his answer.

We could yes and the topic of generating self-contained headers have come up a few times. Adding an include could also mean changing cmake or bazel build file (which of course won’t happen automatically, I just mean it adds an additional layer of indirection of cause). Today it’s more direct: missing class definition, add forwarding decl/include header & update build files, all of these have tooling support (e.g., one can use your editor with C++ LSP to suggest missing headers etc) while inside the .td file these are just strings. It may be more cumbersome, but it’s all regular C++ development flow, so should be less surprising.

Being able to generate a .h instead of a .h.inc (textual include, partial header) is appealing though. The .h files are quite small at the moment and feels a little wasteful dev setup wise (well and folks new to the system often get them wrong). When straddling the languages barrier one often ends up with surprising failure modes. For the simple case we could automate. I am worried about transparency of the system when things fail and developer experience, which is where it is good to hear from users.