Skip to content

Commit 39ce995

Browse files
authored
[CIR] Upstream cir-canonicalize pass (#131891)
This change introduces the cir-canonicalize pass. This is a simple cir-to-cir transformation that eliminates empty scopes and redundant branches. It will be expanded in future changes to simplify other redundant instruction sequences. MLIR verification and mlir-specific command-line option handling is also introduced here.
1 parent cd26dd5 commit 39ce995

File tree

25 files changed

+455
-5
lines changed

25 files changed

+455
-5
lines changed

clang/include/clang/Basic/DiagnosticFrontendKinds.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,4 +386,12 @@ def warn_hlsl_langstd_minimal :
386386
Warning<"support for HLSL language version %0 is incomplete, "
387387
"recommend using %1 instead">,
388388
InGroup<HLSLDXCCompat>;
389+
390+
// ClangIR frontend errors
391+
def err_cir_to_cir_transform_failed : Error<
392+
"CIR-to-CIR transformation failed">, DefaultFatal;
393+
394+
def err_cir_verification_failed_pre_passes : Error<
395+
"CIR module verification error before running CIR-to-CIR passes">,
396+
DefaultFatal;
389397
}

clang/include/clang/CIR/CIRGenerator.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ class CIRGenerator : public clang::ASTConsumer {
5555
void Initialize(clang::ASTContext &astContext) override;
5656
bool HandleTopLevelDecl(clang::DeclGroupRef group) override;
5757
mlir::ModuleOp getModule() const;
58+
mlir::MLIRContext &getMLIRContext() { return *mlirContext; };
59+
const mlir::MLIRContext &getMLIRContext() const { return *mlirContext; };
60+
61+
bool verifyModule() const;
5862
};
5963

6064
} // namespace cir
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//===----------------------------------------------------------------------===//
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 an interface for running CIR-to-CIR passes.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef CLANG_CIR_CIRTOCIRPASSES_H
14+
#define CLANG_CIR_CIRTOCIRPASSES_H
15+
16+
#include "mlir/Pass/Pass.h"
17+
18+
#include <memory>
19+
20+
namespace clang {
21+
class ASTContext;
22+
}
23+
24+
namespace mlir {
25+
class MLIRContext;
26+
class ModuleOp;
27+
} // namespace mlir
28+
29+
namespace cir {
30+
31+
// Run set of cleanup/prepare/etc passes CIR <-> CIR.
32+
mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp theModule,
33+
mlir::MLIRContext &mlirCtx,
34+
clang::ASTContext &astCtx,
35+
bool enableVerifier);
36+
37+
} // namespace cir
38+
39+
#endif // CLANG_CIR_CIRTOCIRPASSES_H_

clang/include/clang/CIR/Dialect/Passes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class ASTContext;
2020
}
2121
namespace mlir {
2222

23+
std::unique_ptr<Pass> createCIRCanonicalizePass();
2324
std::unique_ptr<Pass> createCIRFlattenCFGPass();
2425

2526
void populateCIRPreLoweringPasses(mlir::OpPassManager &pm);

clang/include/clang/CIR/Dialect/Passes.td

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,24 @@
1111

1212
include "mlir/Pass/PassBase.td"
1313

14+
def CIRCanonicalize : Pass<"cir-canonicalize"> {
15+
let summary = "Performs CIR canonicalization";
16+
let description = [{
17+
Perform canonicalizations on CIR and removes some redundant operations.
18+
19+
This pass performs basic cleanup and canonicalization transformations that
20+
are not intended to affect CIR-to-source fidelity and high-level code
21+
analysis passes. Example transformations performed in this pass include
22+
empty scope cleanup, trivial `try` cleanup, redundant branch cleanup, etc.
23+
Those more "heavyweight" transformations and those transformations that
24+
could significantly affect CIR-to-source fidelity are performed in the
25+
`cir-simplify` pass.
26+
}];
27+
28+
let constructor = "mlir::createCIRCanonicalizePass()";
29+
let dependentDialects = ["cir::CIRDialect"];
30+
}
31+
1432
def CIRFlattenCFG : Pass<"cir-flatten-cfg"> {
1533
let summary = "Produces flatten CFG";
1634
let description = [{

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,18 @@ struct MissingFeatures {
103103
static bool scalableVectors() { return false; }
104104
static bool unsizedTypes() { return false; }
105105
static bool vectorType() { return false; }
106+
107+
// Future CIR operations
108+
static bool labelOp() { return false; }
109+
static bool brCondOp() { return false; }
110+
static bool switchOp() { return false; }
111+
static bool tryOp() { return false; }
112+
static bool unaryOp() { return false; }
113+
static bool selectOp() { return false; }
114+
static bool complexCreateOp() { return false; }
115+
static bool complexRealOp() { return false; }
116+
static bool complexImagOp() { return false; }
117+
static bool callOp() { return false; }
106118
};
107119

108120
} // namespace cir

clang/include/clang/Driver/Options.td

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2978,6 +2978,15 @@ def fapple_link_rtlib : Flag<["-"], "fapple-link-rtlib">, Group<f_Group>,
29782978
HelpText<"Force linking the clang builtins runtime library">;
29792979

29802980
/// ClangIR-specific options - BEGIN
2981+
def clangir_disable_passes : Flag<["-"], "clangir-disable-passes">,
2982+
Visibility<[ClangOption, CC1Option]>,
2983+
HelpText<"Disable CIR transformations pipeline">,
2984+
MarshallingInfoFlag<FrontendOpts<"ClangIRDisablePasses">>;
2985+
def clangir_disable_verifier : Flag<["-"], "clangir-disable-verifier">,
2986+
Visibility<[ClangOption, CC1Option]>,
2987+
HelpText<"ClangIR: Disable MLIR module verifier">,
2988+
MarshallingInfoFlag<FrontendOpts<"ClangIRDisableCIRVerifier">>;
2989+
29812990
defm clangir : BoolFOption<"clangir",
29822991
FrontendOpts<"UseClangIRPipeline">, DefaultFalse,
29832992
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use the ClangIR pipeline to compile">,
@@ -4822,8 +4831,9 @@ def : Joined<["-"], "mllvm=">,
48224831
Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, Alias<mllvm>,
48234832
HelpText<"Alias for -mllvm">, MetaVarName<"<arg>">;
48244833
def mmlir : Separate<["-"], "mmlir">,
4825-
Visibility<[ClangOption, CLOption, FC1Option, FlangOption]>,
4826-
HelpText<"Additional arguments to forward to MLIR's option processing">;
4834+
Visibility<[ClangOption, CC1Option, FC1Option, FlangOption]>,
4835+
HelpText<"Additional arguments to forward to MLIR's option processing">,
4836+
MarshallingInfoStringVector<FrontendOpts<"MLIRArgs">>;
48274837
def ffuchsia_api_level_EQ : Joined<["-"], "ffuchsia-api-level=">,
48284838
Group<m_Group>, Visibility<[ClangOption, CC1Option]>,
48294839
HelpText<"Set Fuchsia API level">,

clang/include/clang/Frontend/FrontendOptions.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,14 @@ class FrontendOptions {
412412
LLVM_PREFERRED_TYPE(bool)
413413
unsigned UseClangIRPipeline : 1;
414414

415+
/// Disable Clang IR specific (CIR) passes
416+
LLVM_PREFERRED_TYPE(bool)
417+
unsigned ClangIRDisablePasses : 1;
418+
419+
/// Disable Clang IR (CIR) verifier
420+
LLVM_PREFERRED_TYPE(bool)
421+
unsigned ClangIRDisableCIRVerifier : 1;
422+
415423
CodeCompleteOptions CodeCompleteOpts;
416424

417425
/// Specifies the output format of the AST.
@@ -488,6 +496,10 @@ class FrontendOptions {
488496
/// should only be used for debugging and experimental features.
489497
std::vector<std::string> LLVMArgs;
490498

499+
/// A list of arguments to forward to MLIR's option processing; this
500+
/// should only be used for debugging and experimental features.
501+
std::vector<std::string> MLIRArgs;
502+
491503
/// File name of the file that will provide record layouts
492504
/// (in the format produced by -fdump-record-layouts).
493505
std::string OverrideRecordLayoutsFile;
@@ -533,7 +545,8 @@ class FrontendOptions {
533545
EmitExtensionSymbolGraphs(false),
534546
EmitSymbolGraphSymbolLabelsForTesting(false),
535547
EmitPrettySymbolGraphs(false), GenReducedBMI(false),
536-
UseClangIRPipeline(false), TimeTraceGranularity(500),
548+
UseClangIRPipeline(false), ClangIRDisablePasses(false),
549+
ClangIRDisableCIRVerifier(false), TimeTraceGranularity(500),
537550
TimeTraceVerbose(false) {}
538551

539552
/// getInputKindForExtension - Return the appropriate input kind for a file

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "mlir/IR/BuiltinOps.h"
2424
#include "mlir/IR/Location.h"
2525
#include "mlir/IR/MLIRContext.h"
26+
#include "mlir/IR/Verifier.h"
2627

2728
using namespace clang;
2829
using namespace clang::CIRGen;
@@ -488,6 +489,13 @@ mlir::Type CIRGenModule::convertType(QualType type) {
488489
return genTypes.convertType(type);
489490
}
490491

492+
bool CIRGenModule::verifyModule() const {
493+
// Verify the module after we have finished constructing it, this will
494+
// check the structural properties of the IR and invoke any specific
495+
// verifiers we have on the CIR operations.
496+
return mlir::verify(theModule).succeeded();
497+
}
498+
491499
DiagnosticBuilder CIRGenModule::errorNYI(SourceLocation loc,
492500
llvm::StringRef feature) {
493501
unsigned diagID = diags.getCustomDiagID(

clang/lib/CIR/CodeGen/CIRGenModule.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ class CIRGenModule : public CIRGenTypeCache {
9191

9292
void emitTopLevelDecl(clang::Decl *decl);
9393

94+
bool verifyModule() const;
95+
9496
/// Return the address of the given function. If funcType is non-null, then
9597
/// this function will use the specified type if it has to create it.
9698
// TODO: this is a bit weird as `GetAddr` given we give back a FuncOp?

0 commit comments

Comments
 (0)