Skip to content

[CIR] Add additional frontend actions #127249

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

Merged
merged 1 commit into from
Feb 19, 2025
Merged
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
2 changes: 2 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIRDialect.td
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ def CIR_Dialect : Dialect {
let useDefaultTypePrinterParser = 0;

let extraClassDeclaration = [{
static llvm::StringRef getTripleAttrName() { return "cir.triple"; }

void registerAttributes();
void registerTypes();

Expand Down
24 changes: 24 additions & 0 deletions clang/include/clang/CIR/FrontendAction/CIRGenAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@ class CIRGenConsumer;
class CIRGenAction : public clang::ASTFrontendAction {
public:
enum class OutputType {
EmitAssembly,
EmitCIR,
EmitLLVM,
EmitBC,
EmitObj,
};

private:
Expand Down Expand Up @@ -63,6 +66,27 @@ class EmitLLVMAction : public CIRGenAction {
EmitLLVMAction(mlir::MLIRContext *MLIRCtx = nullptr);
};

class EmitBCAction : public CIRGenAction {
virtual void anchor();

public:
EmitBCAction(mlir::MLIRContext *MLIRCtx = nullptr);
};

class EmitAssemblyAction : public CIRGenAction {
virtual void anchor();

public:
EmitAssemblyAction(mlir::MLIRContext *MLIRCtx = nullptr);
};

class EmitObjAction : public CIRGenAction {
virtual void anchor();

public:
EmitObjAction(mlir::MLIRContext *MLIRCtx = nullptr);
};

} // namespace cir

#endif
3 changes: 3 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
DoubleTy = cir::DoubleType::get(&getMLIRContext());
FP80Ty = cir::FP80Type::get(&getMLIRContext());
FP128Ty = cir::FP128Type::get(&getMLIRContext());

theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you mention that this is ALSO setting the module 'triple' correctly in the commit message?

builder.getStringAttr(getTriple().str()));
}

mlir::Location CIRGenModule::getLoc(SourceLocation cLoc) {
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/MLIRContext.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/TargetParser/Triple.h"

namespace clang {
class ASTContext;
Expand Down Expand Up @@ -88,6 +90,8 @@ class CIRGenModule : public CIRGenTypeCache {
void emitGlobalVarDefinition(const clang::VarDecl *vd,
bool isTentative = false);

const llvm::Triple &getTriple() const { return target.getTriple(); }

/// Helpers to emit "not yet implemented" error diagnostics
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef);

Expand Down
29 changes: 28 additions & 1 deletion clang/lib/CIR/FrontendAction/CIRGenAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,14 @@ getBackendActionFromOutputType(CIRGenAction::OutputType Action) {
assert(false &&
"Unsupported output type for getBackendActionFromOutputType!");
break; // Unreachable, but fall through to report that
case CIRGenAction::OutputType::EmitAssembly:
return BackendAction::Backend_EmitAssembly;
case CIRGenAction::OutputType::EmitBC:
return BackendAction::Backend_EmitBC;
case CIRGenAction::OutputType::EmitLLVM:
return BackendAction::Backend_EmitLL;
case CIRGenAction::OutputType::EmitObj:
return BackendAction::Backend_EmitObj;
}
// We should only get here if a non-enum value is passed in or we went through
// the assert(false) case above
Expand Down Expand Up @@ -84,7 +90,10 @@ class CIRGenConsumer : public clang::ASTConsumer {
MlirModule->print(*OutputStream, Flags);
}
break;
case CIRGenAction::OutputType::EmitLLVM: {
case CIRGenAction::OutputType::EmitLLVM:
case CIRGenAction::OutputType::EmitBC:
case CIRGenAction::OutputType::EmitObj:
case CIRGenAction::OutputType::EmitAssembly: {
llvm::LLVMContext LLVMCtx;
std::unique_ptr<llvm::Module> LLVMModule =
lowerFromCIRToLLVMIR(MlirModule, LLVMCtx);
Expand All @@ -111,10 +120,16 @@ static std::unique_ptr<raw_pwrite_stream>
getOutputStream(CompilerInstance &CI, StringRef InFile,
CIRGenAction::OutputType Action) {
switch (Action) {
case CIRGenAction::OutputType::EmitAssembly:
return CI.createDefaultOutputFile(false, InFile, "s");
case CIRGenAction::OutputType::EmitCIR:
return CI.createDefaultOutputFile(false, InFile, "cir");
case CIRGenAction::OutputType::EmitLLVM:
return CI.createDefaultOutputFile(false, InFile, "ll");
case CIRGenAction::OutputType::EmitBC:
return CI.createDefaultOutputFile(true, InFile, "bc");
case CIRGenAction::OutputType::EmitObj:
return CI.createDefaultOutputFile(true, InFile, "o");
}
llvm_unreachable("Invalid CIRGenAction::OutputType");
}
Expand All @@ -132,10 +147,22 @@ CIRGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
return Result;
}

void EmitAssemblyAction::anchor() {}
EmitAssemblyAction::EmitAssemblyAction(mlir::MLIRContext *MLIRCtx)
: CIRGenAction(OutputType::EmitAssembly, MLIRCtx) {}

void EmitCIRAction::anchor() {}
EmitCIRAction::EmitCIRAction(mlir::MLIRContext *MLIRCtx)
: CIRGenAction(OutputType::EmitCIR, MLIRCtx) {}

void EmitLLVMAction::anchor() {}
EmitLLVMAction::EmitLLVMAction(mlir::MLIRContext *MLIRCtx)
: CIRGenAction(OutputType::EmitLLVM, MLIRCtx) {}

void EmitBCAction::anchor() {}
EmitBCAction::EmitBCAction(mlir::MLIRContext *MLIRCtx)
: CIRGenAction(OutputType::EmitBC, MLIRCtx) {}

void EmitObjAction::anchor() {}
EmitObjAction::EmitObjAction(mlir::MLIRContext *MLIRCtx)
: CIRGenAction(OutputType::EmitObj, MLIRCtx) {}
11 changes: 11 additions & 0 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ struct ConvertCIRToLLVMPass
}
void runOnOperation() final;

void processCIRAttrs(mlir::ModuleOp module);

StringRef getDescription() const override {
return "Convert the prepared CIR dialect module to LLVM dialect";
}
Expand Down Expand Up @@ -271,6 +273,13 @@ static void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
});
}

void ConvertCIRToLLVMPass::processCIRAttrs(mlir::ModuleOp module) {
// Lower the module attributes to LLVM equivalents.
if (auto tripleAttr = module->getAttr(cir::CIRDialect::getTripleAttrName()))
module->setAttr(mlir::LLVM::LLVMDialect::getTargetTripleAttrName(),
tripleAttr);
}

void ConvertCIRToLLVMPass::runOnOperation() {
llvm::TimeTraceScope scope("Convert CIR to LLVM Pass");

Expand All @@ -283,6 +292,8 @@ void ConvertCIRToLLVMPass::runOnOperation() {

patterns.add<CIRToLLVMGlobalOpLowering>(converter, patterns.getContext(), dl);

processCIRAttrs(module);

mlir::ConversionTarget target(getContext());
target.addLegalOp<mlir::ModuleOp>();
target.addLegalDialect<mlir::LLVM::LLVMDialect>();
Expand Down
21 changes: 18 additions & 3 deletions clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,18 @@ CreateFrontendBaseAction(CompilerInstance &CI) {
return std::make_unique<DumpCompilerOptionsAction>();
case DumpRawTokens: return std::make_unique<DumpRawTokensAction>();
case DumpTokens: return std::make_unique<DumpTokensAction>();
case EmitAssembly: return std::make_unique<EmitAssemblyAction>();
case EmitBC: return std::make_unique<EmitBCAction>();
case EmitAssembly:
#if CLANG_ENABLE_CIR
if (UseCIR)
return std::make_unique<cir::EmitAssemblyAction>();
#endif
return std::make_unique<EmitAssemblyAction>();
case EmitBC:
#if CLANG_ENABLE_CIR
if (UseCIR)
return std::make_unique<cir::EmitBCAction>();
#endif
return std::make_unique<EmitBCAction>();
case EmitCIR:
#if CLANG_ENABLE_CIR
return std::make_unique<cir::EmitCIRAction>();
Expand All @@ -80,7 +90,12 @@ CreateFrontendBaseAction(CompilerInstance &CI) {
}
case EmitLLVMOnly: return std::make_unique<EmitLLVMOnlyAction>();
case EmitCodeGenOnly: return std::make_unique<EmitCodeGenOnlyAction>();
case EmitObj: return std::make_unique<EmitObjAction>();
case EmitObj:
#if CLANG_ENABLE_CIR
if (UseCIR)
return std::make_unique<cir::EmitObjAction>();
#endif
return std::make_unique<EmitObjAction>();
case ExtractAPI:
return std::make_unique<ExtractAPIAction>();
case FixIt: return std::make_unique<FixItAction>();
Expand Down
21 changes: 21 additions & 0 deletions clang/test/CIR/emit-actions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -S %s -o - | FileCheck %s -check-prefix=ASM

// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm-bc %s -o %t.bc
// RUN: llvm-dis %t.bc -o - | FileCheck %s -check-prefix=BC

// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-obj %s -o %t.o
// RUN: llvm-objdump -t %t.o | FileCheck %s -check-prefix=OBJ

// TODO: Make this test target-independent
// REQUIRES: x86-registered-target

int x = 1;

// BC: @x = dso_local global i32 1

// ASM: x:
// ASM: .long 1
// ASM: .size x, 4

// OBJ: .data
// OBJ-SAME: x