Skip to content

Commit

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

See the issue for details.
  • Loading branch information
ChuanqiXu9 committed May 29, 2024
1 parent b5f3862 commit d2e0959
Show file tree
Hide file tree
Showing 24 changed files with 72 additions and 6 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.
4 changes: 4 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -2955,6 +2955,10 @@ 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_pipeline : BoolFOption<"clangir-analysis-only",
FrontendOpts<"ClangIRAnalysisOnlyPipeline">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable CIR analysis for the traditional code gen pipeline">,
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
6 changes: 5 additions & 1 deletion clang/include/clang/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,10 @@ class FrontendOptions {
// Enable Clang IR library optimizations
unsigned ClangIRLibOpt : 1;

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

CodeCompleteOptions CodeCompleteOpts;

/// Specifies the output format of the AST.
Expand Down Expand Up @@ -638,7 +642,7 @@ class FrontendOptions {
ClangIRDisablePasses(false), ClangIRDisableCIRVerifier(false),
ClangIRDisableEmitCXXDefault(false), ClangIRLifetimeCheck(false),
ClangIRIdiomRecognizer(false), ClangIRLibOpt(false),
TimeTraceGranularity(500) {}
ClangIRAnalysisOnlyPipeline(false), TimeTraceGranularity(500) {}

/// 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 @@ -470,3 +470,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);
}
20 changes: 15 additions & 5 deletions clang/lib/CodeGen/CodeGenAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "clang/Basic/LangStandard.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CIRFrontendAction/CIRGenAction.h"
#include "clang/CodeGen/BackendUtil.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Driver/DriverDiagnostic.h"
Expand Down Expand Up @@ -1070,14 +1071,23 @@ 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 (CI.getFrontendOpts().ClangIRAnalysisOnlyPipeline)
AdditionalConsumers.push_back(cir::createCIRAnalysisOnlyConsumer(CI));

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 @@ -4979,6 +4979,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fclangir-idiom-recognizer");
}

if (Args.hasArg(options::OPT_fclangir_analysis_only_pipeline)) {
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: 4 additions & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2932,6 +2932,10 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
if (Args.hasArg(OPT_clangir_verify_diagnostics))
Opts.ClangIRVerifyDiags = true;

if (Args.hasArg(OPT_fclangir_analysis_only_pipeline)) {
Opts.ClangIRAnalysisOnlyPipeline = true;
}

if (const Arg *A = Args.getLastArg(OPT_fclangir_lifetime_check,
OPT_fclangir_lifetime_check_EQ)) {
Opts.ClangIRLifetimeCheck = true;
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
1 change: 1 addition & 0 deletions clang/test/CIR/Transforms/lifetime-check-coro-task.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -I%S/Inputs -fclangir -fclangir-lifetime-check="history=all;remarks=all;history_limit=1" -clangir-verify-diagnostics -emit-cir %s -o %t.cir
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -I%S/Inputs -fclangir-analysis-only -fclangir-lifetime-check="history=all;remarks=all;history_limit=1" -clangir-verify-diagnostics -emit-obj %s -o /dev/null

#include "folly-coro.h"

Expand Down
1 change: 1 addition & 0 deletions clang/test/CIR/Transforms/lifetime-check-lambda.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -I%S/Inputs -Wno-return-stack-address -fclangir -fclangir-lifetime-check="history=all;history_limit=1" -clangir-verify-diagnostics -emit-cir %s -o %t.cir
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -I%S/Inputs -Wno-return-stack-address -fclangir-analysis-only -fclangir-lifetime-check="history=all;history_limit=1" -clangir-verify-diagnostics -emit-obj %s -o /dev/null

// Check also implements:
// EXP61-CPP. A lambda object must not outlive any of its reference captured objects
Expand Down
1 change: 1 addition & 0 deletions clang/test/CIR/Transforms/lifetime-check-owner.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fclangir-lifetime-check="history=all;remarks=all;history_limit=1" -clangir-verify-diagnostics -emit-cir %s -o %t.cir
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir-analysis-only -fclangir-lifetime-check="history=all;remarks=all;history_limit=1" -clangir-verify-diagnostics -emit-obj %s -o /dev/null

struct [[gsl::Owner(int)]] MyIntOwner {
int val;
Expand Down
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 -I%S/../Inputs -mconstructor-aliases -fclangir -clangir-disable-emit-cxx-default -fclangir-lifetime-check="history=all" -fclangir-skip-system-headers -clangir-verify-diagnostics -emit-cir %s -o %t.cir
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -I%S/../Inputs -mconstructor-aliases -fclangir-analysis-only -fclangir-lifetime-check="history=all" -fclangir-skip-system-headers -clangir-verify-diagnostics -emit-obj %s -o /dev/null

#include "std-cxx.h"

Expand Down
1 change: 1 addition & 0 deletions clang/test/CIR/Transforms/lifetime-check-remarks.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -fclangir-lifetime-check="remarks=pset-invalid" -clangir-verify-diagnostics -emit-cir %s -o %t.cir
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir-analysis-only -fclangir-lifetime-check="remarks=pset-invalid" -clangir-verify-diagnostics -emit-obj %s -o /dev/null

int *p0() {
int *p = nullptr;
Expand Down
1 change: 1 addition & 0 deletions clang/test/CIR/Transforms/lifetime-check-string.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=c++17 -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++17 -triple x86_64-unknown-linux-gnu -mconstructor-aliases -fclangir-analysis-only -fclangir-lifetime-check="history=all;remarks=all" -clangir-verify-diagnostics -emit-obj %s -o /dev/null

int strlen(char const *);

Expand Down
1 change: 1 addition & 0 deletions clang/test/CIR/Transforms/lifetime-check.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fclangir-lifetime-check="history=invalid,null" -clangir-verify-diagnostics -emit-cir %s -o %t.cir
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir-analysis-only -fclangir-lifetime-check="history=invalid,null" -clangir-verify-diagnostics -emit-obj %s -o /dev/null

int *p0() {
int *p = nullptr;
Expand Down
1 change: 1 addition & 0 deletions clang/test/CIR/Transforms/lifetime-fn-args.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" -clangir-verify-diagnostics -emit-obj %s -o /dev/null

struct A {
void* ctx;
Expand Down
1 change: 1 addition & 0 deletions clang/test/CIR/Transforms/lifetime-loop-valid.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -fclangir-lifetime-check="history=invalid,null;remarks=pset-always" -clangir-verify-diagnostics -emit-cir %s -o %t.cir
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir-analysis-only -fclangir-lifetime-check="history=invalid,null;remarks=pset-always" -clangir-verify-diagnostics -emit-obj %s -o /dev/null

// Loops that do not change psets

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

void loop_basic_for() {
int *p = nullptr; // expected-note {{invalidated here}}
Expand Down
1 change: 1 addition & 0 deletions clang/test/CIR/Transforms/lifetime-null-passing.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" -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" -clangir-verify-diagnostics -emit-obj %s -o /dev/null

class _j {};
typedef _j* jobj;
Expand Down
1 change: 1 addition & 0 deletions clang/test/CIR/Transforms/lifetime-switch.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -fclangir-lifetime-check="history=invalid,null" -clangir-verify-diagnostics -emit-cir %s -o %t.cir
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir-analysis-only -fclangir-lifetime-check="history=invalid,null" -clangir-verify-diagnostics -emit-obj %s -o /dev/null

void s0(int b) {
int *p = nullptr;
Expand Down
1 change: 1 addition & 0 deletions clang/test/CIR/Transforms/lifetime-this.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 -I%S/../Inputs -mconstructor-aliases -fclangir -clangir-disable-emit-cxx-default -fclangir-lifetime-check="history=all;remarks=all" -fclangir-skip-system-headers -clangir-verify-diagnostics -emit-cir %s -o %t.cir
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -I%S/../Inputs -mconstructor-aliases -fclangir-analysis-only -fclangir-lifetime-check="history=all;remarks=all" -fclangir-skip-system-headers -clangir-verify-diagnostics -emit-obj %s -o /dev/null

#include "std-cxx.h"

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 d2e0959

Please sign in to comment.