Skip to content

Commit 7cbfe8e

Browse files
authored
[CIR] Add code generation options to lowering context (#1171)
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_level`. The attribute is a module-level attribute and it holds the optimization level (e.g. -O1, -Oz, etc.). The attribute is consumed when initializing the lowering context to populate the `OptimizationLevel` and the `OptimizeSize` field in the code generation options. CIRGen is updated to attach this attribute to the module op.
1 parent aa7b5c6 commit 7cbfe8e

File tree

10 files changed

+141
-11
lines changed

10 files changed

+141
-11
lines changed

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

+49-1
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

+1
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

+5
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

+4
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

+17
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

+4-2
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

+7-1
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

+20-5
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

+2-2
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

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)