Skip to content

[mlir][EmitC] Refactor MLIR Translate To Cpp #84973

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions mlir/include/mlir/Target/Cpp/CppEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,15 @@
#define MLIR_TARGET_CPP_CPPEMITTER_H

#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Value.h"
#include "llvm/ADT/ScopedHashTable.h"
#include "llvm/Support/raw_ostream.h"
#include <stack>

namespace mlir {
namespace emitc {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why losing the namespace here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh I thought it might be good to let translateToCpp be shared with other dialects (not "owned" by emitc). But now a second thought appears that emitc is the end goal for the cpp translation so I could also add it back to keep it original.


/// Translates the given operation to C++ code. The operation or operations in
/// the region of 'op' need almost all be in EmitC dialect. The parameter
/// 'declareVariablesAtTop' enforces that all variables for op results and block
/// arguments are declared at the beginning of the function.
LogicalResult translateToCpp(Operation *op, raw_ostream &os,
bool declareVariablesAtTop = false);
} // namespace emitc
} // namespace mlir

#endif // MLIR_TARGET_CPP_CPPEMITTER_H
55 changes: 55 additions & 0 deletions mlir/include/mlir/Target/Cpp/CppTranslationInterface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//===--- CppTranslationInterface.h - Translation to Cpp iface ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This header file defines dialect interfaces for translation to Cpp.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_TARGET_CPP_CPPTRANSLATIONINTERFACE_H
#define MLIR_TARGET_CPP_CPPTRANSLATIONINTERFACE_H

#include "mlir/IR/DialectInterface.h"
#include "mlir/Support/LogicalResult.h"

namespace mlir {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all part of EmitC still right? If so let's keep the namespace.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, using emitc namespace also makes sense to me

struct CppEmitter;

/// Base class for dialect interfaces providing translation to Cpp. Dialects
/// should implement this interface with supported operation translations to
/// be registered and used with translate-to-cpp.
class CppTranslationDialectInterface
: public DialectInterface::Base<CppTranslationDialectInterface> {
public:
CppTranslationDialectInterface(Dialect *dialect) : Base(dialect) {}

/// Hook for derived dialect interface to provide op translation to Cpp.
virtual LogicalResult emitOperation(Operation *op, CppEmitter &cppEmitter,
bool trailingSemicolon) const {
return failure();
}
};

/// Interface collection for translation to Cpp, dispatches to a concrete
/// interface implementation based on the dialect to which the given op belongs.
class CppTranslationInterface
: public DialectInterfaceCollection<CppTranslationDialectInterface> {
public:
using Base::Base;

/// Translates the given operation to Cpp using the derived dialect interface.
virtual LogicalResult emitOperation(Operation *op, CppEmitter &cppEmitter,
bool trailingSemicolon) const {
if (const CppTranslationDialectInterface *iface = getInterfaceFor(op))
return iface->emitOperation(op, cppEmitter, trailingSemicolon);
return failure();
}
};

} // namespace mlir

#endif // MLIR_TARGET_CPP_CPPTRANSLATIONINTERFACE_H
85 changes: 85 additions & 0 deletions mlir/include/mlir/Target/Cpp/CppTranslationUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//===- CppTranslationUtils.h - Helpers to used in C++ emitter ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines common helper functions used across different dialects
// during the Cpp translation.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_TARGET_CPP_CPPTRANSLATIONUTILS_H
#define MLIR_TARGET_CPP_CPPTRANSLATIONUTILS_H

#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/Target/Cpp/TranslateToCpp.h"

using namespace mlir;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should be in any header.


/// Convenience functions to produce interleaved output with functions returning
/// a LogicalResult. This is different than those in STLExtras as functions used
/// on each element doesn't return a string.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get this comment, the interleaveComma in STLExtras takes a functor that does not return a string either

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part actually comes from the original EmitC code, I tried to keep most of the code as original as possible but I could double check.

template <typename ForwardIterator, typename UnaryFunctor,
typename NullaryFunctor>
inline LogicalResult
interleaveWithError(ForwardIterator begin, ForwardIterator end,
UnaryFunctor eachFn, NullaryFunctor betweenFn) {
if (begin == end)
return success();
if (failed(eachFn(*begin)))
return failure();
++begin;
for (; begin != end; ++begin) {
betweenFn();
if (failed(eachFn(*begin)))
return failure();
}
return success();
}

template <typename Container, typename UnaryFunctor, typename NullaryFunctor>
inline LogicalResult interleaveWithError(const Container &c,
UnaryFunctor eachFn,
NullaryFunctor betweenFn) {
return interleaveWithError(c.begin(), c.end(), eachFn, betweenFn);
}

template <typename Container, typename UnaryFunctor>
inline LogicalResult interleaveCommaWithError(const Container &c,
raw_ostream &os,
UnaryFunctor eachFn) {
return interleaveWithError(c.begin(), c.end(), eachFn, [&]() { os << ", "; });
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not belong here, it seems like a generic MLIR utility.


/// Determine whether expression \p expressionOp should be emitted inline, i.e.
/// as part of its user. This function recommends inlining of any expressions
/// that can be inlined unless it is used by another expression, under the
/// assumption that any expression fusion/re-materialization was taken care of
/// by transformations run by the backend.
bool shouldBeInlined(emitc::ExpressionOp expressionOp);

LogicalResult printConstantOp(CppEmitter &emitter, Operation *operation,
Attribute value);

LogicalResult printBinaryOperation(CppEmitter &emitter, Operation *operation,
StringRef binaryOperator);

LogicalResult printUnaryOperation(CppEmitter &emitter, Operation *operation,
StringRef unaryOperator);

LogicalResult printCallOperation(CppEmitter &emitter, Operation *callOp,
StringRef callee);

LogicalResult printFunctionArgs(CppEmitter &emitter, Operation *functionOp,
ArrayRef<Type> arguments);

LogicalResult printFunctionArgs(CppEmitter &emitter, Operation *functionOp,
Region::BlockArgListType arguments);

LogicalResult printFunctionBody(CppEmitter &emitter, Operation *functionOp,
Region::BlockListType &blocks);

#endif // MLIR_TARGET_CPP_CPPTRANSLATIONUTILS_H
35 changes: 35 additions & 0 deletions mlir/include/mlir/Target/Cpp/Dialect/All.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//===----- All.h - MLIR To Cpp Translation Registration ---------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines a helper to register the all dialect translations to Cpp.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_TARGET_CPP_DIALECT_ALL_H
#define MLIR_TARGET_CPP_DIALECT_ALL_H

#include "mlir/Target/Cpp/Dialect/Builtin/BuiltinToCppTranslation.h"
#include "mlir/Target/Cpp/Dialect/ControlFlow/ControlFlowToCppTranslation.h"
#include "mlir/Target/Cpp/Dialect/EmitC/EmitCToCppTranslation.h"
#include "mlir/Target/Cpp/Dialect/Func/FuncToCppTranslation.h"

namespace mlir {
class DialectRegistry;

/// Registers all dialects that can be translated to Cpp and the
/// corresponding translation interfaces.
static inline void registerAllToCppTranslations(DialectRegistry &registry) {
registerBuiltinDialectCppTranslation(registry);
registerControlFlowDialectCppTranslation(registry);
registerEmitCDialectCppTranslation(registry);
registerFuncDialectCppTranslation(registry);
}

} // namespace mlir

#endif // MLIR_TARGET_CPP_DIALECT_ALL_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===---- BuiltinToCppTranslation.h - Builtin Dialect to Cpp ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This provides registration calls for Builtin dialect to Cpp translation.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_TARGET_CPP_DIALECT_BUILTIN_BUILTINTOCPPTRANSLATION_H
#define MLIR_TARGET_CPP_DIALECT_BUILTIN_BUILTINTOCPPTRANSLATION_H

namespace mlir {

class DialectRegistry;
class MLIRContext;

/// Register the Builtin dialect and the translation from it to the Cpp in the
/// given registry;
void registerBuiltinDialectCppTranslation(DialectRegistry &registry);

/// Register the Builtin dialect and the translation from it in the registry
/// associated with the given context.
void registerBuiltinDialectCppTranslation(MLIRContext &context);

} // namespace mlir

#endif // MLIR_TARGET_CPP_DIALECT_BUILTIN_BUILTINTOCPPTRANSLATION_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===- ControlFlowToCppTranslation.h - ControlFlow Dialect to Cpp -*-C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This provides registration calls for ControlFlow dialect to Cpp translation.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_TARGET_CPP_DIALECT_CONTROLFLOW_CONTROLFLOWTOCPPTRANSLATION_H
#define MLIR_TARGET_CPP_DIALECT_CONTROLFLOW_CONTROLFLOWTOCPPTRANSLATION_H

namespace mlir {

class DialectRegistry;
class MLIRContext;

/// Register the ControlFlow dialect and the translation from it to the Cpp in
/// the given registry;
void registerControlFlowDialectCppTranslation(DialectRegistry &registry);

/// Register the ControlFlow dialect and the translation from it in the registry
/// associated with the given context.
void registerControlFlowDialectCppTranslation(MLIRContext &context);

} // namespace mlir

#endif // MLIR_TARGET_CPP_DIALECT_CONTROLFLOW_CONTROLFLOWTOCPPTRANSLATION_H
31 changes: 31 additions & 0 deletions mlir/include/mlir/Target/Cpp/Dialect/EmitC/EmitCToCppTranslation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===------ EmitCToCppTranslation.h - EmitC Dialect to Cpp-------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This provides registration calls for EmitC dialect to Cpp translation.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_TARGET_CPP_DIALECT_EMITC_EMITCTOCPPTRANSLATION_H
#define MLIR_TARGET_CPP_DIALECT_EMITC_EMITCTOCPPTRANSLATION_H

namespace mlir {

class DialectRegistry;
class MLIRContext;

/// Register the EmitC dialect and the translation from it to the Cpp in the
/// given registry;
void registerEmitCDialectCppTranslation(DialectRegistry &registry);

/// Register the EmitC dialect and the translation from it in the registry
/// associated with the given context.
void registerEmitCDialectCppTranslation(MLIRContext &context);

} // namespace mlir

#endif // MLIR_TARGET_CPP_DIALECT_EMITC_EMITCTOCPPTRANSLATION_H
31 changes: 31 additions & 0 deletions mlir/include/mlir/Target/Cpp/Dialect/Func/FuncToCppTranslation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===------- FuncToCppTranslation.h - Func Dialect to Cpp -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This provides registration calls for Func dialect to Cpp translation.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_TARGET_CPP_DIALECT_FUNC_FUNCTOCPPTRANSLATION_H
#define MLIR_TARGET_CPP_DIALECT_FUNC_FUNCTOCPPTRANSLATION_H

namespace mlir {

class DialectRegistry;
class MLIRContext;

/// Register the Func dialect and the translation from it to the Cpp in the
/// given registry;
void registerFuncDialectCppTranslation(DialectRegistry &registry);

/// Register the Func dialect and the translation from it in the registry
/// associated with the given context.
void registerFuncDialectCppTranslation(MLIRContext &context);

} // namespace mlir

#endif // MLIR_TARGET_CPP_DIALECT_FUNC_FUNCTOCPPTRANSLATION_H
Loading