Skip to content

Commit 1bb52e9

Browse files
authoredOct 9, 2024··
[CIR] Build out AST consumer patterns to reach the entry point into CIRGen
Build out the necessary infrastructure for the main entry point into ClangIR generation -- CIRGenModule. A set of boilerplate classes exist to facilitate this -- CIRGenerator, CIRGenAction, EmitCIRAction and CIRGenConsumer. These all mirror the corresponding types from LLVM generation by Clang's CodeGen. The main entry point to CIR generation is `CIRGenModule::buildTopLevelDecl`. It is currently just an empty function. We've added a test to ensure that the pipeline reaches this point and doesn't fail, but does nothing else. This will be removed in one of the subsequent patches that'll add basic `cir.func` emission. This patch also re-adds `-emit-cir` to the driver. lib/Driver/Driver.cpp requires that a driver flag exists to facilirate the selection of the right actions for the driver to create. Without a driver flag you get the standard behaviors of `-S`, `-c`, etc. If we want to emit CIR IR and, eventually, bytecode we'll need a driver flag to force this. This is why `-emit-llvm` is a driver flag. Notably, `-emit-llvm-bc` as a cc1 flag doesn't ever do the right thing. Without a driver flag it is incorrectly ignored and an executable is emitted. With `-S` a file named `something.s` is emitted which actually contains bitcode. Reviewers: AaronBallman, MaskRay, bcardosolopes Reviewed By: bcardosolopes, AaronBallman Pull Request: #91007
1 parent 208584d commit 1bb52e9

16 files changed

+440
-1
lines changed
 
+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//===- CIRGenerator.h - CIR Generation from Clang AST ---------------------===//
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 a simple interface to perform CIR generation from Clang
10+
// AST
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_CLANG_CIR_CIRGENERATOR_H
15+
#define LLVM_CLANG_CIR_CIRGENERATOR_H
16+
17+
#include "clang/AST/ASTConsumer.h"
18+
#include "clang/Basic/CodeGenOptions.h"
19+
20+
#include "llvm/ADT/IntrusiveRefCntPtr.h"
21+
#include "llvm/Support/VirtualFileSystem.h"
22+
23+
#include <memory>
24+
25+
namespace clang {
26+
class DeclGroupRef;
27+
class DiagnosticsEngine;
28+
} // namespace clang
29+
30+
namespace mlir {
31+
class MLIRContext;
32+
} // namespace mlir
33+
namespace cir {
34+
class CIRGenModule;
35+
36+
class CIRGenerator : public clang::ASTConsumer {
37+
virtual void anchor();
38+
clang::DiagnosticsEngine &diags;
39+
clang::ASTContext *astCtx;
40+
// Only used for debug info.
41+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs;
42+
43+
const clang::CodeGenOptions &codeGenOpts;
44+
45+
protected:
46+
std::unique_ptr<mlir::MLIRContext> mlirCtx;
47+
std::unique_ptr<CIRGenModule> cgm;
48+
49+
public:
50+
CIRGenerator(clang::DiagnosticsEngine &diags,
51+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs,
52+
const clang::CodeGenOptions &cgo);
53+
~CIRGenerator() override;
54+
void Initialize(clang::ASTContext &astCtx) override;
55+
bool HandleTopLevelDecl(clang::DeclGroupRef group) override;
56+
};
57+
58+
} // namespace cir
59+
60+
#endif // LLVM_CLANG_CIR_CIRGENERATOR_H
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//===---- CIRGenAction.h - CIR Code Generation Frontend Action -*- C++ -*--===//
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+
#ifndef LLVM_CLANG_CIR_CIRGENACTION_H
10+
#define LLVM_CLANG_CIR_CIRGENACTION_H
11+
12+
#include "clang/Frontend/FrontendAction.h"
13+
14+
#include "mlir/IR/BuiltinOps.h"
15+
#include "mlir/IR/OwningOpRef.h"
16+
17+
namespace mlir {
18+
class MLIRContext;
19+
class ModuleOp;
20+
} // namespace mlir
21+
22+
namespace cir {
23+
class CIRGenConsumer;
24+
25+
class CIRGenAction : public clang::ASTFrontendAction {
26+
public:
27+
enum class OutputType {
28+
EmitCIR,
29+
};
30+
31+
private:
32+
friend class CIRGenConsumer;
33+
34+
mlir::OwningOpRef<mlir::ModuleOp> MLIRMod;
35+
36+
mlir::MLIRContext *MLIRCtx;
37+
38+
protected:
39+
CIRGenAction(OutputType Action, mlir::MLIRContext *MLIRCtx = nullptr);
40+
41+
std::unique_ptr<clang::ASTConsumer>
42+
CreateASTConsumer(clang::CompilerInstance &CI,
43+
llvm::StringRef InFile) override;
44+
45+
public:
46+
~CIRGenAction() override;
47+
48+
OutputType Action;
49+
};
50+
51+
class EmitCIRAction : public CIRGenAction {
52+
virtual void anchor();
53+
54+
public:
55+
EmitCIRAction(mlir::MLIRContext *MLIRCtx = nullptr);
56+
};
57+
58+
} // namespace cir
59+
60+
#endif

‎clang/include/clang/Driver/Options.td

+1-1
Original file line numberDiff line numberDiff line change
@@ -2996,7 +2996,7 @@ defm clangir : BoolFOption<"clangir",
29962996
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use the ClangIR pipeline to compile">,
29972997
NegFlag<SetFalse, [], [ClangOption, CC1Option], "Use the AST -> LLVM pipeline to compile">,
29982998
BothFlags<[], [ClangOption, CC1Option], "">>;
2999-
def emit_cir : Flag<["-"], "emit-cir">, Visibility<[CC1Option]>,
2999+
def emit_cir : Flag<["-"], "emit-cir">, Visibility<[ClangOption, CC1Option]>,
30003000
Group<Action_Group>, HelpText<"Build ASTs and then lower to ClangIR">;
30013001
/// ClangIR-specific options - END
30023002

‎clang/lib/CIR/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ include_directories(${LLVM_MAIN_SRC_DIR}/../mlir/include)
22
include_directories(${CMAKE_BINARY_DIR}/tools/mlir/include)
33

44
add_subdirectory(Dialect)
5+
add_subdirectory(CodeGen)
6+
add_subdirectory(FrontendAction)
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===- CIRGenModule.cpp - Per-Module state for CIR generation -------------===//
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 is the internal per-translation-unit state used for CIR translation.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "CIRGenModule.h"
14+
15+
#include "clang/AST/ASTContext.h"
16+
#include "clang/AST/DeclBase.h"
17+
18+
#include "mlir/IR/BuiltinOps.h"
19+
#include "mlir/IR/Location.h"
20+
#include "mlir/IR/MLIRContext.h"
21+
22+
using namespace cir;
23+
CIRGenModule::CIRGenModule(mlir::MLIRContext &context,
24+
clang::ASTContext &astctx,
25+
const clang::CodeGenOptions &cgo,
26+
DiagnosticsEngine &diags)
27+
: astCtx(astctx), langOpts(astctx.getLangOpts()),
28+
theModule{mlir::ModuleOp::create(mlir::UnknownLoc())},
29+
target(astCtx.getTargetInfo()) {}
30+
31+
// Emit code for a single top level declaration.
32+
void CIRGenModule::buildTopLevelDecl(Decl *decl) {}

‎clang/lib/CIR/CodeGen/CIRGenModule.h

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//===--- CIRGenModule.h - Per-Module state for CIR gen ----------*- C++ -*-===//
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 is the internal per-translation-unit state used for CIR translation.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H
14+
#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H
15+
16+
#include "CIRGenTypeCache.h"
17+
18+
#include "mlir/IR/BuiltinOps.h"
19+
#include "mlir/IR/MLIRContext.h"
20+
21+
namespace clang {
22+
class ASTContext;
23+
class CodeGenOptions;
24+
class Decl;
25+
class DiagnosticsEngine;
26+
class LangOptions;
27+
class TargetInfo;
28+
} // namespace clang
29+
30+
using namespace clang;
31+
namespace cir {
32+
33+
/// This class organizes the cross-function state that is used while generating
34+
/// CIR code.
35+
class CIRGenModule : public CIRGenTypeCache {
36+
CIRGenModule(CIRGenModule &) = delete;
37+
CIRGenModule &operator=(CIRGenModule &) = delete;
38+
39+
public:
40+
CIRGenModule(mlir::MLIRContext &context, clang::ASTContext &astctx,
41+
const clang::CodeGenOptions &cgo,
42+
clang::DiagnosticsEngine &diags);
43+
44+
~CIRGenModule() = default;
45+
46+
private:
47+
/// Hold Clang AST information.
48+
clang::ASTContext &astCtx;
49+
50+
const clang::LangOptions &langOpts;
51+
52+
/// A "module" matches a c/cpp source file: containing a list of functions.
53+
mlir::ModuleOp theModule;
54+
55+
const clang::TargetInfo &target;
56+
57+
public:
58+
void buildTopLevelDecl(clang::Decl *decl);
59+
};
60+
} // namespace cir
61+
62+
#endif // LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===--- CIRGenTypeCache.h - Commonly used LLVM types and info -*- C++ --*-===//
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 structure provides a set of common types useful during CIR emission.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_CLANG_LIB_CIR_CIRGENTYPECACHE_H
14+
#define LLVM_CLANG_LIB_CIR_CIRGENTYPECACHE_H
15+
16+
namespace cir {
17+
18+
/// This structure provides a set of types that are commonly used
19+
/// during IR emission. It's initialized once in CodeGenModule's
20+
/// constructor and then copied around into new CIRGenFunction's.
21+
struct CIRGenTypeCache {
22+
CIRGenTypeCache() = default;
23+
};
24+
25+
} // namespace cir
26+
27+
#endif // LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENTYPECACHE_H
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//===--- CIRGenerator.cpp - Emit CIR from ASTs ----------------------------===//
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 builds an AST and converts it to CIR.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "CIRGenModule.h"
14+
15+
#include "clang/AST/DeclGroup.h"
16+
#include "clang/CIR/CIRGenerator.h"
17+
18+
using namespace cir;
19+
using namespace clang;
20+
21+
void CIRGenerator::anchor() {}
22+
23+
CIRGenerator::CIRGenerator(clang::DiagnosticsEngine &diags,
24+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,
25+
const CodeGenOptions &cgo)
26+
: diags(diags), fs(std::move(vfs)), codeGenOpts{cgo} {}
27+
CIRGenerator::~CIRGenerator() = default;
28+
29+
void CIRGenerator::Initialize(ASTContext &astCtx) {
30+
using namespace llvm;
31+
32+
this->astCtx = &astCtx;
33+
34+
cgm = std::make_unique<CIRGenModule>(*mlirCtx, astCtx, codeGenOpts, diags);
35+
}
36+
37+
bool CIRGenerator::HandleTopLevelDecl(DeclGroupRef group) {
38+
39+
for (Decl *decl : group)
40+
cgm->buildTopLevelDecl(decl);
41+
42+
return true;
43+
}

‎clang/lib/CIR/CodeGen/CMakeLists.txt

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
set(
2+
LLVM_LINK_COMPONENTS
3+
Core
4+
Support
5+
)
6+
7+
get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
8+
9+
add_clang_library(clangCIR
10+
CIRGenerator.cpp
11+
CIRGenModule.cpp
12+
13+
DEPENDS
14+
MLIRCIR
15+
${dialect_libs}
16+
17+
LINK_LIBS
18+
clangAST
19+
clangBasic
20+
clangLex
21+
${dialect_libs}
22+
MLIRCIR
23+
)

0 commit comments

Comments
 (0)
Please sign in to comment.