Skip to content

Commit fd0c839

Browse files
committed
wip: adding --emit-spirv-mlir path
1 parent 3086002 commit fd0c839

File tree

10 files changed

+98
-1
lines changed

10 files changed

+98
-1
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//====- LowerToSPIRV.h- Lowering from CIR to LLVM -------------------------===//
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+
// This file declares an interface for converting MLIR modules to SPIR-V
10+
//
11+
//===----------------------------------------------------------------------===//
12+
#ifndef CLANG_CIR_LOWERTOSPIRV_H
13+
#define CLANG_CIR_LOWERTOSPIRV_H
14+
15+
#include "mlir/Dialect/SPIRV/IR/SPIRVOps.h"
16+
17+
#include <memory>
18+
19+
namespace llvm {
20+
class LLVMContext;
21+
class Module;
22+
} // namespace llvm
23+
24+
namespace mlir {
25+
class MLIRContext;
26+
class ModuleOp;
27+
28+
spirv::ModuleOp lowerFromMLIRToSPIRV(mlir::ModuleOp theModule,
29+
mlir::MLIRContext *mlirCtx);
30+
} // namespace mlir
31+
32+
#endif // CLANG_CIR_LOWERTOSPIRV_H

clang/include/clang/CIR/Passes.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@ namespace cir {
2222
/// `Std`, to the LLVM dialect for codegen.
2323
std::unique_ptr<mlir::Pass> createConvertMLIRToLLVMPass();
2424

25+
/// Create a pass for lowering from MLIR builtin dialects to the SPIRV dialect for codegen.
26+
std::unique_ptr<mlir::Pass> createConvertMLIRToSPIRVPass();
27+
2528
/// Create a pass that fully lowers CIR to the MLIR in-tree dialects.
2629
std::unique_ptr<mlir::Pass> createConvertCIRToMLIRPass();
2730

31+
2832
namespace direct {
2933
/// Create a pass that fully lowers CIR to the LLVMIR dialect.
3034
std::unique_ptr<mlir::Pass> createConvertCIRToLLVMPass();

clang/include/clang/CIRFrontendAction/CIRGenAction.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class CIRGenAction : public clang::ASTFrontendAction {
3434
EmitAssembly,
3535
EmitCIR,
3636
EmitCIRFlat,
37+
EmitSPIRV,
3738
EmitLLVM,
3839
EmitBC,
3940
EmitMLIR,
@@ -101,6 +102,13 @@ class EmitMLIRAction : public CIRGenAction {
101102
EmitMLIRAction(mlir::MLIRContext *mlirCtx = nullptr);
102103
};
103104

105+
class EmitSPIRVAction : public CIRGenAction {
106+
virtual void anchor();
107+
108+
public:
109+
EmitSPIRVAction(mlir::MLIRContext *mlirCtx = nullptr);
110+
};
111+
104112
class EmitLLVMAction : public CIRGenAction {
105113
virtual void anchor();
106114

clang/include/clang/Driver/Options.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3055,6 +3055,8 @@ def emit_cir_flat : Flag<["-"], "emit-cir-flat">, Visibility<[ClangOption, CC1Op
30553055
Group<Action_Group>, HelpText<"Similar to -emit-cir but also lowers structured CFG into basic blocks.">;
30563056
def emit_mlir : Flag<["-"], "emit-mlir">, Visibility<[CC1Option]>, Group<Action_Group>,
30573057
HelpText<"Build ASTs and then lower through ClangIR to MLIR, emit the .milr file">;
3058+
def emit_spirv_mlir : Flag<["-"], "emit-spirv-mlir">, Visibility<[CC1Option]>, Group<Action_Group>,
3059+
HelpText<"Build ASTs and then lower through ClangIR to MLIR to SPIR-V, emit the .spv file">;
30583060
/// ClangIR-specific options - END
30593061

30603062
def flto : Flag<["-"], "flto">,

clang/include/clang/Frontend/FrontendOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ enum ActionKind {
7777
/// Emit a .mlir file
7878
EmitMLIR,
7979

80+
/// Emit a .spv file
81+
EmitSPIRV,
82+
8083
/// Emit a .ll file.
8184
EmitLLVM,
8285

clang/lib/CIR/FrontendAction/CIRGenAction.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "mlir/IR/MLIRContext.h"
1414
#include "mlir/IR/OperationSupport.h"
1515
#include "mlir/Parser/Parser.h"
16+
#include "mlir/Target/SPIRV/Serialization.h"
1617
#include "clang/AST/ASTConsumer.h"
1718
#include "clang/AST/ASTContext.h"
1819
#include "clang/AST/DeclCXX.h"
@@ -26,6 +27,7 @@
2627
#include "clang/CIR/CIRToCIRPasses.h"
2728
#include "clang/CIR/Dialect/IR/CIRDialect.h"
2829
#include "clang/CIR/LowerToLLVM.h"
30+
#include "clang/CIR/LowerToSPIRV.h"
2931
#include "clang/CIR/Passes.h"
3032
#include "clang/CodeGen/BackendUtil.h"
3133
#include "clang/CodeGen/ModuleBuilder.h"
@@ -278,6 +280,20 @@ class CIRGenConsumer : public clang::ASTConsumer {
278280
loweredMlirModule->print(*outputStream, flags);
279281
break;
280282
}
283+
case CIRGenAction::OutputType::EmitSPIRV: {
284+
auto loweredMlirModule = lowerFromCIRToMLIR(mlirMod, mlirCtx.get());
285+
auto spirvModule = ::mlir::lowerFromMLIRToSPIRV(loweredMlirModule, mlirCtx.get());
286+
assert(outputStream && "Why are we here without an output stream?");
287+
// FIXME: we cannot roundtrip prettyForm=true right now.
288+
mlir::OpPrintingFlags flags;
289+
flags.enableDebugInfo(/*enable=*/true, /*prettyForm=*/false);
290+
// loweredMlirModule->print(*outputStream, flags);
291+
SmallVector<uint32_t, 0> words;
292+
::mlir::spirv::SerializationOptions options;
293+
(void) ::mlir::spirv::serialize(spirvModule, words, options);
294+
outputStream->write(reinterpret_cast<char*>(words.data()), words.size_in_bytes());
295+
break;
296+
}
281297
case CIRGenAction::OutputType::EmitLLVM:
282298
case CIRGenAction::OutputType::EmitBC:
283299
case CIRGenAction::OutputType::EmitObj:
@@ -464,6 +480,10 @@ void EmitMLIRAction::anchor() {}
464480
EmitMLIRAction::EmitMLIRAction(mlir::MLIRContext *_MLIRContext)
465481
: CIRGenAction(OutputType::EmitMLIR, _MLIRContext) {}
466482

483+
void EmitSPIRVAction::anchor() {}
484+
EmitSPIRVAction::EmitSPIRVAction(mlir::MLIRContext *_MLIRContext)
485+
: CIRGenAction(OutputType::EmitSPIRV, _MLIRContext) {}
486+
467487
void EmitLLVMAction::anchor() {}
468488
EmitLLVMAction::EmitLLVMAction(mlir::MLIRContext *_MLIRContext)
469489
: CIRGenAction(OutputType::EmitLLVM, _MLIRContext) {}

clang/lib/CIR/Lowering/ThroughMLIR/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ add_clang_library(clangCIRLoweringThroughMLIR
99
LowerCIRLoopToSCF.cpp
1010
LowerCIRToMLIR.cpp
1111
LowerMLIRToLLVM.cpp
12+
LowerMLIRToSPIRV.cpp
1213

1314
DEPENDS
1415
MLIRCIROpsIncGen
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include "mlir/IR/BuiltinOps.h"
2+
#include "mlir/IR/MLIRContext.h"
3+
#include "mlir/Pass/PassManager.h"
4+
#include "clang/CIR/Passes.h"
5+
#include "llvm/Support/TimeProfiler.h"
6+
7+
#include "mlir/Dialect/SPIRV/Transforms/Passes.h"
8+
9+
namespace mlir {
10+
11+
mlir::ModuleOp lowerFromMLIRToSPIRV(mlir::ModuleOp theModule,
12+
mlir::MLIRContext *mlirCtx) {
13+
llvm::TimeTraceScope scope("Lower from MLIR to SPIR-V");
14+
15+
mlir::PassManager pm(mlirCtx);
16+
17+
// TODO
18+
//pm.addPass(cir::createConvertMLIRToSPIRVPass());
19+
20+
//auto result = !mlir::failed(pm.run(theModule));
21+
//if (!result)
22+
// report_fatal_error("The pass manager failed to lower CIR to SPIRV dialect!");
23+
}
24+
25+
} // namespace mlir

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2634,6 +2634,7 @@ static const auto &getFrontendActionTable() {
26342634
{frontend::EmitCIRFlat, OPT_emit_cir_flat},
26352635
{frontend::EmitCIROnly, OPT_emit_cir_only},
26362636
{frontend::EmitMLIR, OPT_emit_mlir},
2637+
{frontend::EmitSPIRV, OPT_emit_spirv_mlir},
26372638
{frontend::EmitHTML, OPT_emit_html},
26382639
{frontend::EmitLLVM, OPT_emit_llvm},
26392640
{frontend::EmitLLVMOnly, OPT_emit_llvm_only},

clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ CreateFrontendBaseAction(CompilerInstance &CI) {
5454
auto UseCIR = CI.getFrontendOpts().UseClangIRPipeline;
5555
auto Act = CI.getFrontendOpts().ProgramAction;
5656
auto CIRAnalysisOnly = CI.getFrontendOpts().ClangIRAnalysisOnly;
57-
auto EmitsCIR = Act == EmitCIR || Act == EmitCIRFlat || Act == EmitCIROnly;
57+
auto EmitsCIR = Act == EmitCIR || Act == EmitCIRFlat || Act == EmitCIROnly || Act == EmitSPIRV;
5858

5959
if (!UseCIR && EmitsCIR)
6060
llvm::report_fatal_error(
@@ -96,6 +96,7 @@ CreateFrontendBaseAction(CompilerInstance &CI) {
9696
return std::make_unique<::cir::EmitCIRFlatAction>();
9797
case EmitCIROnly: return std::make_unique<::cir::EmitCIROnlyAction>();
9898
case EmitMLIR: return std::make_unique<::cir::EmitMLIRAction>();
99+
case EmitSPIRV: return std::make_unique<::cir::EmitSPIRVAction>();
99100
#else
100101
case EmitCIR:
101102
case EmitCIRFlat:

0 commit comments

Comments
 (0)