aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorAndy Kaylor <akaylor@nvidia.com>2025-02-19 09:08:37 -0800
committerGitHub <noreply@github.com>2025-02-19 09:08:37 -0800
commit75ea7aed93ec8afa43634a41c2e94380ba0d671e (patch)
tree6cbda8cde083a6441b515a668117c066d228cb73 /clang/lib
parentddf24086f119cacf2a0fc489773f8af302f4a489 (diff)
downloadllvm-75ea7aed93ec8afa43634a41c2e94380ba0d671e.zip
llvm-75ea7aed93ec8afa43634a41c2e94380ba0d671e.tar.gz
llvm-75ea7aed93ec8afa43634a41c2e94380ba0d671e.tar.bz2
[CIR] Add additional frontend actions (#127249)
Add frontend actions to support emitting assembly, bitcode, and object files when compiling with ClangIR. This change also correctly sets and propagates the target triple in the MLIR and LLVM modules, which was a necessary prerequisite for emitting assembly and object files.
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenModule.cpp3
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenModule.h4
-rw-r--r--clang/lib/CIR/FrontendAction/CIRGenAction.cpp29
-rw-r--r--clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp11
-rw-r--r--clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp21
5 files changed, 64 insertions, 4 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 2615ae3..cbecdf9 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -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(),
+ builder.getStringAttr(getTriple().str()));
}
mlir::Location CIRGenModule::getLoc(SourceLocation cLoc) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h
index 1c7ed63..29bb403 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -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;
@@ -88,6 +90,8 @@ public:
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);
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index eab6958..0f686a3 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -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
@@ -84,7 +90,10 @@ public:
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);
@@ -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");
}
@@ -132,6 +147,10 @@ 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) {}
@@ -139,3 +158,11 @@ EmitCIRAction::EmitCIRAction(mlir::MLIRContext *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) {}
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 74ff893..235b5a057 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -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";
}
@@ -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");
@@ -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>();
diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index c8d0041..bb3bb0a 100644
--- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -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>();
@@ -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>();