Skip to content

Commit c1c2ccc

Browse files
committed
[CIR] Add code generation options to lowering context
This PR adds `clang::CodeGenOptions` to the lowering context. Similar to `clang::LangOptions`, the code generation options are currently set to the default values when initializing the lowering context. Besides, this PR also adds a new attribute `#cir.opt_info`. The attribute is a module-level attribute and it holds optimization information such as the optimization level. The attribute is consumed when initializing the lowering context to populate the code generation options. CIRGen is updated to generate and attach this attribute to the module op.
1 parent 888f00c commit c1c2ccc

File tree

10 files changed

+141
-11
lines changed

10 files changed

+141
-11
lines changed

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

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,54 @@ def LangAttr : CIR_Attr<"Lang", "lang"> {
7373
let genVerifyDecl = 0;
7474
}
7575

76+
//===----------------------------------------------------------------------===//
77+
// OptInfoAttr
78+
//===----------------------------------------------------------------------===//
79+
80+
def CIR_OptInfoAttr : CIR_Attr<"OptInfo", "opt_info"> {
81+
let summary =
82+
"A module-level attribute that holds the optimization information";
83+
let description = [{
84+
The `#cir.opt_info` attribute holds the optimization related information.
85+
Currently this attribute is a module-level attribute that gets attached to
86+
the module operation during CIRGen.
87+
88+
The `level` parameter gives the optimization level. It must be an integer
89+
between 0 and 3, inclusive. It corresponds to the `OptimizationLevel` field
90+
within the `clang::CodeGenOptions` structure.
91+
92+
The `size` parameter gives the code size optimization level. It must be an
93+
integer between 0 and 2, inclusive. It corresponds to the `OptimizeSize`
94+
field within the `clang::CodeGenOptions` structure.
95+
96+
The `level` and `size` parameters correspond to the optimization level
97+
command line options passed to clang driver. The table below lists the
98+
current correspondance relationship:
99+
100+
| Flag | `level` | `size` |
101+
|------------------|---------|--------|
102+
| `-O0` or nothing | 0 | 0 |
103+
| `-O1` | 1 | 0 |
104+
| `-O2` | 2 | 0 |
105+
| `-O3` | 3 | 0 |
106+
| `-Os` | 2 | 1 |
107+
| `-Oz` | 2 | 2 |
108+
109+
Examples:
110+
111+
```mlir
112+
#cir.opt_info<level = 2, size = 0> // -O2
113+
```
114+
}];
115+
116+
let parameters = (ins "unsigned":$level, "unsigned":$size);
117+
118+
let assemblyFormat = [{
119+
`<` `level` `=` $level `,` `size` `=` $size `>`
120+
}];
121+
let genVerifyDecl = 1;
122+
}
123+
76124
//===----------------------------------------------------------------------===//
77125
// BoolAttr
78126
//===----------------------------------------------------------------------===//
@@ -311,7 +359,7 @@ def ComplexAttr : CIR_Attr<"Complex", "complex", [TypedAttrInterface]> {
311359
contains values of the same CIR type.
312360
}];
313361

314-
let parameters = (ins
362+
let parameters = (ins
315363
AttributeSelfTypeParameter<"", "cir::ComplexType">:$type,
316364
"mlir::TypedAttr":$real, "mlir::TypedAttr":$imag);
317365

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def CIR_Dialect : Dialect {
3737
static llvm::StringRef getSOBAttrName() { return "cir.sob"; }
3838
static llvm::StringRef getLangAttrName() { return "cir.lang"; }
3939
static llvm::StringRef getTripleAttrName() { return "cir.triple"; }
40+
static llvm::StringRef getOptInfoAttrName() { return "cir.opt_info"; }
4041

4142
static llvm::StringRef getGlobalCtorsAttrName() { return "cir.global_ctors"; }
4243
static llvm::StringRef getGlobalDtorsAttrName() { return "cir.global_dtors"; }

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,11 @@ struct MissingFeatures {
377377
// just yet. Right now, it only instantiates the default lang options.
378378
static bool langOpts() { return false; }
379379

380+
// CodeGenOpts may affect lowering, but we do not carry this information into
381+
// CIR just yet. Right now, it only instantiates the default code generation
382+
// options.
383+
static bool codeGenOpts() { return false; }
384+
380385
// Several type qualifiers are not yet supported in CIR, but important when
381386
// evaluating ABI-specific lowering.
382387
static bool qualifiedTypes() { return false; }

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,10 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &context,
192192
cir::LangAttr::get(&context, lang));
193193
theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
194194
builder.getStringAttr(getTriple().str()));
195+
if (CGO.OptimizationLevel > 0 || CGO.OptimizeSize > 0)
196+
theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
197+
cir::OptInfoAttr::get(&context, CGO.OptimizationLevel,
198+
CGO.OptimizeSize));
195199
// Set the module name to be the name of the main file. TranslationUnitDecl
196200
// often contains invalid source locations and isn't a reliable source for the
197201
// module location.

clang/lib/CIR/Dialect/IR/CIRAttrs.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,23 @@ void LangAttr::print(AsmPrinter &printer) const {
214214
printer << "<" << getLang().getValue() << '>';
215215
}
216216

217+
//===----------------------------------------------------------------------===//
218+
// OptInfoAttr definitions
219+
//===----------------------------------------------------------------------===//
220+
221+
LogicalResult OptInfoAttr::verify(function_ref<InFlightDiagnostic()> emitError,
222+
unsigned level, unsigned size) {
223+
if (level > 3) {
224+
emitError() << "optimization level must be between 0 and 3 inclusive";
225+
return failure();
226+
}
227+
if (size > 2) {
228+
emitError() << "size optimization level must be between 0 and 2 inclusive";
229+
return failure();
230+
}
231+
return success();
232+
}
233+
217234
//===----------------------------------------------------------------------===//
218235
// ConstPtrAttr definitions
219236
//===----------------------------------------------------------------------===//

clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRLowerContext.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
namespace cir {
2424

2525
CIRLowerContext::CIRLowerContext(mlir::ModuleOp module,
26-
clang::LangOptions LOpts)
27-
: MLIRCtx(module.getContext()), LangOpts(LOpts) {}
26+
clang::LangOptions LOpts,
27+
clang::CodeGenOptions CGOpts)
28+
: MLIRCtx(module.getContext()), LangOpts(std::move(LOpts)),
29+
CodeGenOpts(std::move(CGOpts)) {}
2830

2931
CIRLowerContext::~CIRLowerContext() {}
3032

clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRLowerContext.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,18 @@ class CIRLowerContext : public llvm::RefCountedBase<CIRLowerContext> {
4444
/// this ASTContext object.
4545
clang::LangOptions LangOpts;
4646

47+
/// Options for code generation.
48+
clang::CodeGenOptions CodeGenOpts;
49+
4750
//===--------------------------------------------------------------------===//
4851
// Built-in Types
4952
//===--------------------------------------------------------------------===//
5053

5154
mlir::Type CharTy;
5255

5356
public:
54-
CIRLowerContext(mlir::ModuleOp module, clang::LangOptions LOpts);
57+
CIRLowerContext(mlir::ModuleOp module, clang::LangOptions LOpts,
58+
clang::CodeGenOptions CGOpts);
5559
CIRLowerContext(const CIRLowerContext &) = delete;
5660
CIRLowerContext &operator=(const CIRLowerContext &) = delete;
5761
~CIRLowerContext();
@@ -73,6 +77,8 @@ class CIRLowerContext : public llvm::RefCountedBase<CIRLowerContext> {
7377

7478
const clang::LangOptions &getLangOpts() const { return LangOpts; }
7579

80+
const clang::CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; }
81+
7682
mlir::MLIRContext *getMLIRContext() const { return MLIRCtx; }
7783

7884
//===--------------------------------------------------------------------===//

clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,14 @@ createTargetLoweringInfo(LowerModule &LM) {
8686
}
8787
}
8888

89-
LowerModule::LowerModule(clang::LangOptions opts, mlir::ModuleOp &module,
89+
LowerModule::LowerModule(clang::LangOptions langOpts,
90+
clang::CodeGenOptions codeGenOpts,
91+
mlir::ModuleOp &module,
9092
std::unique_ptr<clang::TargetInfo> target,
9193
mlir::PatternRewriter &rewriter)
92-
: context(module, opts), module(module), Target(std::move(target)),
93-
ABI(createCXXABI(*this)), types(*this), rewriter(rewriter) {
94+
: context(module, std::move(langOpts), std::move(codeGenOpts)),
95+
module(module), Target(std::move(target)), ABI(createCXXABI(*this)),
96+
types(*this), rewriter(rewriter) {
9497
context.initBuiltinTypes(*Target);
9598
}
9699

@@ -238,8 +241,20 @@ createLowerModule(mlir::ModuleOp module, mlir::PatternRewriter &rewriter) {
238241
cir_cconv_assert(!cir::MissingFeatures::langOpts());
239242
clang::LangOptions langOpts;
240243

241-
return std::make_unique<LowerModule>(langOpts, module, std::move(targetInfo),
242-
rewriter);
244+
// FIXME(cir): This just uses the default code generation options. We need to
245+
// account for custom options.
246+
cir_cconv_assert(!cir::MissingFeatures::codeGenOpts());
247+
clang::CodeGenOptions codeGenOpts;
248+
249+
if (auto optInfo = mlir::cast_if_present<cir::OptInfoAttr>(
250+
module->getAttr(cir::CIRDialect::getOptInfoAttrName()))) {
251+
codeGenOpts.OptimizationLevel = optInfo.getLevel();
252+
codeGenOpts.OptimizeSize = optInfo.getSize();
253+
}
254+
255+
return std::make_unique<LowerModule>(std::move(langOpts),
256+
std::move(codeGenOpts), module,
257+
std::move(targetInfo), rewriter);
243258
}
244259

245260
} // namespace cir

clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ class LowerModule {
4242
mlir::PatternRewriter &rewriter;
4343

4444
public:
45-
LowerModule(clang::LangOptions opts, mlir::ModuleOp &module,
46-
std::unique_ptr<clang::TargetInfo> target,
45+
LowerModule(clang::LangOptions langOpts, clang::CodeGenOptions codeGenOpts,
46+
mlir::ModuleOp &module, std::unique_ptr<clang::TargetInfo> target,
4747
mlir::PatternRewriter &rewriter);
4848
~LowerModule() = default;
4949

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O0 -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir --check-prefix=CHECK-O0 %s
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O1 -fclangir -emit-cir %s -o %t.cir
4+
// RUN: FileCheck --input-file=%t.cir --check-prefix=CHECK-O1 %s
5+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -fclangir -emit-cir %s -o %t.cir
6+
// RUN: FileCheck --input-file=%t.cir --check-prefix=CHECK-O2 %s
7+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O3 -fclangir -emit-cir %s -o %t.cir
8+
// RUN: FileCheck --input-file=%t.cir --check-prefix=CHECK-O3 %s
9+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Os -fclangir -emit-cir %s -o %t.cir
10+
// RUN: FileCheck --input-file=%t.cir --check-prefix=CHECK-Os %s
11+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Oz -fclangir -emit-cir %s -o %t.cir
12+
// RUN: FileCheck --input-file=%t.cir --check-prefix=CHECK-Oz %s
13+
14+
void foo() {}
15+
16+
// CHECK-O0: module
17+
// CHECK-O0-NOT: cir.opt_info
18+
19+
// CHECK-O1: module
20+
// CHECK-O1: cir.opt_info = #cir.opt_info<level = 1, size = 0>
21+
22+
// CHECK-O2: module
23+
// CHECK-O2: cir.opt_info = #cir.opt_info<level = 2, size = 0>
24+
25+
// CHECK-O3: module
26+
// CHECK-O3: cir.opt_info = #cir.opt_info<level = 3, size = 0>
27+
28+
// CHECK-Os: module
29+
// CHECK-Os: cir.opt_info = #cir.opt_info<level = 2, size = 1>
30+
31+
// CHECK-Oz: module
32+
// CHECK-Oz: cir.opt_info = #cir.opt_info<level = 2, size = 2>

0 commit comments

Comments
 (0)