Skip to content

Commit 36bf1ed

Browse files
committed
Address review feedback
1 parent 2b6ecd7 commit 36bf1ed

File tree

6 files changed

+66
-23
lines changed

6 files changed

+66
-23
lines changed

clang/include/clang/CIR/Dialect/IR/CIRDialect.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ def CIR_Dialect : Dialect {
2727
let useDefaultAttributePrinterParser = 0;
2828
let useDefaultTypePrinterParser = 0;
2929

30+
// Enable constant materialization for the CIR dialect. This generates a
31+
// declaration for the cir::CIRDialect::materializeConstant function. This
32+
// hook is necessary for canonicalization to properly handle attributes
33+
// returned by fold methods, allowing them to be materialized as constant
34+
// operations in the IR.
3035
let hasConstantMaterializer = 1;
3136

3237
let extraClassDeclaration = [{

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,17 @@ def CIRCanonicalize : Pass<"cir-canonicalize"> {
3232
def CIRSimplify : Pass<"cir-simplify"> {
3333
let summary = "Performs CIR simplification and code optimization";
3434
let description = [{
35-
The pass performs code simplification and optimization on CIR.
36-
37-
Unlike the `cir-canonicalize` pass, this pass contains more aggresive code
38-
transformations that could significantly affect CIR-to-source fidelity.
39-
Example transformations performed in this pass include ternary folding,
40-
code hoisting, etc.
35+
The pass performs semantics-preserving code simplifications and optimizations
36+
on CIR while maintaining strict program correctness.
37+
38+
Unlike the `cir-canonicalize` pass, these transformations may reduce the IR's
39+
structural similarity to the original source code as a trade-off for improved
40+
code quality. This can affect debugging fidelity by altering intermediate
41+
representations of folded expressions, hoisted operations, and other
42+
optimized constructs.
43+
44+
Example transformations include ternary expression folding and code hoisting
45+
while preserving program semantics.
4146
}];
4247
let constructor = "mlir::createCIRSimplifyPass()";
4348
let dependentDialects = ["cir::CIRDialect"];

clang/include/clang/CIR/FrontendAction/CIRGenAction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class CIRGenAction : public clang::ASTFrontendAction {
4949
public:
5050
~CIRGenAction() override;
5151

52-
OutputType action;
52+
OutputType Action;
5353
};
5454

5555
class EmitCIRAction : public CIRGenAction {

clang/lib/CIR/Dialect/Transforms/CIRSimplify.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ namespace {
3737
///
3838
/// For example, we will simplify the following ternary operation:
3939
///
40-
/// %0 = cir.ternary (%condition, true {
41-
/// %1 = cir.const ...
42-
/// cir.yield %1
43-
/// } false {
40+
/// %0 = ...
41+
/// %1 = cir.ternary (%condition, true {
42+
/// %2 = cir.const ...
4443
/// cir.yield %2
45-
/// })
44+
/// } false {
45+
/// cir.yield %0
4646
///
4747
/// into the following sequence of operations:
4848
///
@@ -103,6 +103,24 @@ struct SimplifyTernary final : public OpRewritePattern<TernaryOp> {
103103
}
104104
};
105105

106+
/// Simplify select operations with boolean constants into simpler forms.
107+
///
108+
/// This pattern simplifies select operations where both true and false values
109+
/// are boolean constants. Two specific cases are handled:
110+
///
111+
/// 1. When selecting between true and false based on a condition,
112+
/// the operation simplifies to just the condition itself:
113+
///
114+
/// %0 = cir.select if %condition then true else false
115+
/// ->
116+
/// (replaced with %condition directly)
117+
///
118+
/// 2. When selecting between false and true based on a condition,
119+
/// the operation simplifies to the logical negation of the condition:
120+
///
121+
/// %0 = cir.select if %condition then false else true
122+
/// ->
123+
/// %0 = cir.unary not %condition
106124
struct SimplifySelect : public OpRewritePattern<SelectOp> {
107125
using OpRewritePattern<SelectOp>::OpRewritePattern;
108126

clang/lib/CIR/FrontendAction/CIRGenAction.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,16 @@ class CIRGenConsumer : public clang::ASTConsumer {
6262
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
6363
std::unique_ptr<CIRGenerator> Gen;
6464
const FrontendOptions &FEOptions;
65-
CodeGenOptions &codeGenOptions;
65+
CodeGenOptions &CGO;
6666

6767
public:
6868
CIRGenConsumer(CIRGenAction::OutputType Action, CompilerInstance &CI,
69-
CodeGenOptions &codeGenOptions,
70-
std::unique_ptr<raw_pwrite_stream> OS)
69+
CodeGenOptions &CGO, std::unique_ptr<raw_pwrite_stream> OS)
7170
: Action(Action), CI(CI), OutputStream(std::move(OS)),
7271
FS(&CI.getVirtualFileSystem()),
7372
Gen(std::make_unique<CIRGenerator>(CI.getDiagnostics(), std::move(FS),
7473
CI.getCodeGenOpts())),
75-
FEOptions(CI.getFrontendOpts()), codeGenOptions(codeGenOptions) {}
74+
FEOptions(CI.getFrontendOpts()), CGO(CGO) {}
7675

7776
void Initialize(ASTContext &Ctx) override {
7877
assert(!Context && "initialized multiple times");
@@ -105,7 +104,7 @@ class CIRGenConsumer : public clang::ASTConsumer {
105104
// Setup and run CIR pipeline.
106105
if (runCIRToCIRPasses(MlirModule, MlirCtx, C,
107106
!FEOptions.ClangIRDisableCIRVerifier,
108-
codeGenOptions.OptimizationLevel > 0)
107+
CGO.OptimizationLevel > 0)
109108
.failed()) {
110109
CI.getDiagnostics().Report(diag::err_cir_to_cir_transform_failed);
111110
return;
@@ -142,7 +141,7 @@ class CIRGenConsumer : public clang::ASTConsumer {
142141
void CIRGenConsumer::anchor() {}
143142

144143
CIRGenAction::CIRGenAction(OutputType Act, mlir::MLIRContext *MLIRCtx)
145-
: MLIRCtx(MLIRCtx ? MLIRCtx : new mlir::MLIRContext), action(Act) {}
144+
: MLIRCtx(MLIRCtx ? MLIRCtx : new mlir::MLIRContext), Action(Act) {}
146145

147146
CIRGenAction::~CIRGenAction() { MLIRMod.release(); }
148147

@@ -165,14 +164,14 @@ getOutputStream(CompilerInstance &CI, StringRef InFile,
165164
}
166165

167166
std::unique_ptr<ASTConsumer>
168-
CIRGenAction::CreateASTConsumer(CompilerInstance &ci, StringRef inFile) {
169-
std::unique_ptr<llvm::raw_pwrite_stream> out = ci.takeOutputStream();
167+
CIRGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
168+
std::unique_ptr<llvm::raw_pwrite_stream> Out = CI.takeOutputStream();
170169

171-
if (!out)
172-
out = getOutputStream(ci, inFile, action);
170+
if (!Out)
171+
Out = getOutputStream(CI, InFile, Action);
173172

174173
auto Result = std::make_unique<cir::CIRGenConsumer>(
175-
action, ci, ci.getCodeGenOpts(), std::move(out));
174+
Action, CI, CI.getCodeGenOpts(), std::move(Out));
176175

177176
return Result;
178177
}

clang/test/CIR/Transforms/ternary-fold.cir

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,22 @@ module {
3434
// CHECK-NEXT: cir.return %[[#B]] : !s32i
3535
// CHECK-NEXT: }
3636

37+
cir.func @simplify_ternary_false_const(%arg0 : !cir.bool, %arg1 : !s32i) -> !s32i {
38+
%0 = cir.ternary (%arg0, true {
39+
cir.yield %arg1 : !s32i
40+
}, false {
41+
%1 = cir.const #cir.int<24> : !s32i
42+
cir.yield %1 : !s32i
43+
}) : (!cir.bool) -> !s32i
44+
cir.return %0 : !s32i
45+
}
46+
47+
// CHECK: cir.func @simplify_ternary_false_const(%[[ARG0:.+]]: !cir.bool, %[[ARG1:.+]]: !s32i) -> !s32i {
48+
// CHECK-NEXT: %[[#A:]] = cir.const #cir.int<24> : !s32i
49+
// CHECK-NEXT: %[[#B:]] = cir.select if %[[ARG0]] then %[[ARG1]] else %[[#A]] : (!cir.bool, !s32i, !s32i) -> !s32i
50+
// CHECK-NEXT: cir.return %[[#B]] : !s32i
51+
// CHECK-NEXT: }
52+
3753
cir.func @non_simplifiable_ternary(%arg0 : !cir.bool) -> !s32i {
3854
%0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
3955
%1 = cir.ternary (%arg0, true {

0 commit comments

Comments
 (0)