Skip to content

Commit

Permalink
[CIR][Pipeline] Support -fclangir-analysis-only (llvm#638)
Browse files Browse the repository at this point in the history
Close llvm#633.

This patch introduces `-fclangir-analysis-only` option to allow the
users to consume the AST to the CIR (and potential analysis passes, this
can be done by specifying `-Xclang -fclangir-lifetime-check=""` now or
some default value in following patches) and also generating the LLVM IR
by the traditional code gen path. This will be helpful to use CIR with
real world projects without worrying the correctness and completeness of
CIR CodeGen part.
  • Loading branch information
ChuanqiXu9 authored and lanza committed Oct 1, 2024
1 parent 5518148 commit 686fd0b
Show file tree
Hide file tree
Showing 12 changed files with 72 additions and 8 deletions.
3 changes: 3 additions & 0 deletions clang/include/clang/CIRFrontendAction/CIRGenAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ class EmitObjAction : public CIRGenAction {
EmitObjAction(mlir::MLIRContext *mlirCtx = nullptr);
};

std::unique_ptr<clang::ASTConsumer>
createCIRAnalysisOnlyConsumer(clang::CompilerInstance &);

} // namespace cir

#endif
Empty file.
5 changes: 5 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -3037,6 +3037,11 @@ defm clangir_direct_lowering : BoolFOption<"clangir-direct-lowering",
FrontendOpts<"ClangIRDirectLowering">, DefaultTrue,
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Lower directly from ClangIR to LLVM">,
NegFlag<SetFalse, [], [ClangOption, CC1Option], "Lower through MLIR to LLVM">>;
defm clangir_analysis_only : BoolFOption<"clangir-analysis-only",
FrontendOpts<"ClangIRAnalysisOnly">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Enable CIR analysis but keep traditional LLVM codegen (not through CIR)">,
NegFlag<SetFalse, [], [ClangOption, CC1Option], "">>;

def emit_cir : Flag<["-"], "emit-cir">, Visibility<[CC1Option]>,
Group<Action_Group>, HelpText<"Build ASTs and then lower to ClangIR, emit the .cir file">;
Expand Down
7 changes: 6 additions & 1 deletion clang/include/clang/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,10 @@ class FrontendOptions {
// Enable Clang IR call conv lowering pass.
unsigned ClangIREnableCallConvLowering : 1;

// Enable Clang IR analysis only pipeline that uses tranditional code gen
// pipeline.
unsigned ClangIRAnalysisOnly : 1;

CodeCompleteOptions CodeCompleteOpts;

/// Specifies the output format of the AST.
Expand Down Expand Up @@ -650,7 +654,8 @@ class FrontendOptions {
ClangIRDisablePasses(false), ClangIRDisableCIRVerifier(false),
ClangIRDisableEmitCXXDefault(false), ClangIRLifetimeCheck(false),
ClangIRIdiomRecognizer(false), ClangIRLibOpt(false),
TimeTraceGranularity(500), TimeTraceVerbose(false) {}
ClangIRAnalysisOnly(false), TimeTraceGranularity(500),
TimeTraceVerbose(false) {}

/// getInputKindForExtension - Return the appropriate input kind for a file
/// extension. For example, "c" would return Language::C.
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/CIR/FrontendAction/CIRGenAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,3 +471,11 @@ EmitLLVMAction::EmitLLVMAction(mlir::MLIRContext *_MLIRContext)
void EmitObjAction::anchor() {}
EmitObjAction::EmitObjAction(mlir::MLIRContext *_MLIRContext)
: CIRGenAction(OutputType::EmitObj, _MLIRContext) {}

std::unique_ptr<clang::ASTConsumer>
cir::createCIRAnalysisOnlyConsumer(clang::CompilerInstance &ci) {
return std::make_unique<cir::CIRGenConsumer>(
CIRGenAction::OutputType::None, ci.getDiagnostics(),
&ci.getVirtualFileSystem(), ci.getHeaderSearchOpts(), ci.getCodeGenOpts(),
ci.getTargetOpts(), ci.getLangOpts(), ci.getFrontendOpts(), nullptr);
}
8 changes: 8 additions & 0 deletions clang/lib/CodeGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ if(MSVC AND NOT CMAKE_CXX_COMPILER_ID MATCHES Clang
endif()
endif()

set(conditional_link_libs)
if(CLANG_ENABLE_CIR)
list(APPEND conditional_link_libs
clangCIRFrontendAction
)
endif()

add_clang_library(clangCodeGen
ABIInfo.cpp
ABIInfoImpl.cpp
Expand Down Expand Up @@ -156,4 +163,5 @@ add_clang_library(clangCodeGen
clangFrontend
clangLex
clangSerialization
${conditional_link_libs}
)
25 changes: 20 additions & 5 deletions clang/lib/CodeGen/CodeGenAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
#include "clang/Basic/LangStandard.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Config/config.h"
#if CLANG_ENABLE_CIR
#include "clang/CIRFrontendAction/CIRGenAction.h"
#endif
#include "clang/CodeGen/BackendUtil.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Driver/DriverDiagnostic.h"
Expand Down Expand Up @@ -1032,14 +1036,25 @@ CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
CI.getPreprocessor().addPPCallbacks(std::move(Callbacks));
}

std::vector<std::unique_ptr<ASTConsumer>> AdditionalConsumers;
AdditionalConsumers.reserve(2);

if (CI.getFrontendOpts().GenReducedBMI &&
!CI.getFrontendOpts().ModuleOutputPath.empty()) {
std::vector<std::unique_ptr<ASTConsumer>> Consumers(2);
Consumers[0] = std::make_unique<ReducedBMIGenerator>(

AdditionalConsumers.push_back(std::make_unique<ReducedBMIGenerator>(
CI.getPreprocessor(), CI.getModuleCache(),
CI.getFrontendOpts().ModuleOutputPath);
Consumers[1] = std::move(Result);
return std::make_unique<MultiplexConsumer>(std::move(Consumers));
CI.getFrontendOpts().ModuleOutputPath));
}

#if CLANG_ENABLE_CIR
if (CI.getFrontendOpts().ClangIRAnalysisOnly)
AdditionalConsumers.push_back(cir::createCIRAnalysisOnlyConsumer(CI));
#endif

if (!AdditionalConsumers.empty()) {
AdditionalConsumers.push_back(std::move(Result));
return std::make_unique<MultiplexConsumer>(std::move(AdditionalConsumers));
}

return std::move(Result);
Expand Down
9 changes: 9 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5149,6 +5149,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fclangir-idiom-recognizer");
}

if (Args.hasArg(options::OPT_fclangir_analysis_only)) {
CmdArgs.push_back("-fclangir-analysis-only");

// TODO: We should pass some default analysis configuration here.

// TODO2: Should we emit some diagnostics if the configurations conflict
// with each other?
}

if (IsOpenMPDevice) {
// We have to pass the triple of the host if compiling for an OpenMP device.
std::string NormalizedTriple =
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3030,8 +3030,8 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
if (Args.hasArg(OPT_clangir_verify_diagnostics))
Opts.ClangIRVerifyDiags = true;

if (Args.hasArg(OPT_fclangir_call_conv_lowering))
Opts.ClangIREnableCallConvLowering = true;
if (Args.hasArg(OPT_fclangir_analysis_only))
Opts.ClangIRAnalysisOnly = true;

if (const Arg *A = Args.getLastArg(OPT_fclangir_lifetime_check,
OPT_fclangir_lifetime_check_EQ)) {
Expand Down
8 changes: 8 additions & 0 deletions clang/test/CIR/CodeGen/analysis-only.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Check `-fclangir-analysis-only` would generate code correctly.
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir-analysis-only -std=c++20 \
// RUN: -O2 -emit-llvm %s -o - | FileCheck %s

extern "C" void foo() {}

// CHECK: define{{.*}} @foo(

1 change: 1 addition & 0 deletions clang/test/CIR/Transforms/lifetime-check-agg.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -mconstructor-aliases -fclangir -clangir-disable-emit-cxx-default -fclangir-lifetime-check="history=all;remarks=all" -clangir-verify-diagnostics -emit-cir %s -o %t.cir
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -mconstructor-aliases -fclangir-analysis-only -fclangir-lifetime-check="history=all;remarks=all" %s -clangir-verify-diagnostics -emit-obj -o /dev/null

typedef enum SType {
INFO_ENUM_0 = 9,
Expand Down
2 changes: 2 additions & 0 deletions clang/test/CIR/analysis-only.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// RUN: %clang %s -fclangir-analysis-only -### -c %s 2>&1 | FileCheck %s
// CHECK: "-fclangir-analysis-only"

0 comments on commit 686fd0b

Please sign in to comment.