Skip to content

Commit aaae2e5

Browse files
committed
[CIR] Add code generation options to lowering context
This patch 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 patch 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 41078e9 commit aaae2e5

File tree

10 files changed

+113
-10
lines changed

10 files changed

+113
-10
lines changed

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

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

76+
//===----------------------------------------------------------------------===//
77+
// OptLevelAttr
78+
//===----------------------------------------------------------------------===//
79+
80+
def CIR_OptLevelAttr : CIR_Attr<"OptLevel", "opt_level"> {
81+
let summary = "A module-level attribute that holds the optimization level";
82+
let description = [{
83+
The `#cir.opt_level` attribute holds the optimization level of the module.
84+
This attribute is attached to the module operation during CIRGen.
85+
}];
86+
87+
let parameters = (ins "unsigned":$optLevel, "unsigned":$optSizeLevel);
88+
89+
let assemblyFormat = [{
90+
`<` `opt_level` `=` $optLevel `,` `opt_size` `=` $optSizeLevel `>`
91+
}];
92+
let genVerifyDecl = 1;
93+
}
94+
7695
//===----------------------------------------------------------------------===//
7796
// BoolAttr
7897
//===----------------------------------------------------------------------===//

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 getOptLevelAttrName() { return "cir.opt_level"; }
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
@@ -379,6 +379,11 @@ struct MissingFeatures {
379379
// just yet. Right now, it only instantiates the default lang options.
380380
static bool langOpts() { return false; }
381381

382+
// CodeGenOpts may affect lowering, but we do not carry this information into
383+
// CIR just yet. Right now, it only instantiates the default code generation
384+
// options.
385+
static bool codeGenOpts() { return false; }
386+
382387
// Several type qualifiers are not yet supported in CIR, but important when
383388
// evaluating ABI-specific lowering.
384389
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::getOptLevelAttrName(),
197+
cir::OptLevelAttr::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+
// OptLevelAttr definitions
219+
//===----------------------------------------------------------------------===//
220+
221+
LogicalResult OptLevelAttr::verify(function_ref<InFlightDiagnostic()> emitError,
222+
unsigned optLevel, unsigned optSizeLevel) {
223+
if (optLevel > 3) {
224+
emitError() << "invalid optimization level";
225+
return failure();
226+
}
227+
if (optSizeLevel > 2) {
228+
emitError() << "invalid size optimization level";
229+
return failure();
230+
}
231+
return success();
232+
}
233+
217234
//===----------------------------------------------------------------------===//
218235
// ConstPtrAttr definitions
219236
//===----------------------------------------------------------------------===//

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919
#include "clang/CIR/MissingFeatures.h"
2020
#include "llvm/Support/ErrorHandling.h"
2121
#include <cmath>
22+
#include <utility>
2223

2324
namespace cir {
2425

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

2932
CIRLowerContext::~CIRLowerContext() {}
3033

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: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "mlir/Support/LogicalResult.h"
2727
#include "clang/CIR/Target/AArch64.h"
2828
#include "llvm/Support/ErrorHandling.h"
29+
#include <utility>
2930

3031
using MissingFeatures = cir::MissingFeatures;
3132
using AArch64ABIKind = cir::AArch64ABIKind;
@@ -86,11 +87,14 @@ createTargetLoweringInfo(LowerModule &LM) {
8687
}
8788
}
8889

89-
LowerModule::LowerModule(clang::LangOptions opts, mlir::ModuleOp &module,
90+
LowerModule::LowerModule(clang::LangOptions langOpts,
91+
clang::CodeGenOptions codeGenOpts,
92+
mlir::ModuleOp &module,
9093
std::unique_ptr<clang::TargetInfo> target,
9194
mlir::PatternRewriter &rewriter)
92-
: context(module, opts), module(module), Target(std::move(target)),
93-
ABI(createCXXABI(*this)), types(*this), rewriter(rewriter) {
95+
: context(module, std::move(langOpts), std::move(codeGenOpts)),
96+
module(module), Target(std::move(target)), ABI(createCXXABI(*this)),
97+
types(*this), rewriter(rewriter) {
9498
context.initBuiltinTypes(*Target);
9599
}
96100

@@ -238,8 +242,20 @@ createLowerModule(mlir::ModuleOp module, mlir::PatternRewriter &rewriter) {
238242
cir_cconv_assert(!cir::MissingFeatures::langOpts());
239243
clang::LangOptions langOpts;
240244

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

245261
} // 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_level
18+
19+
// CHECK-O1: module
20+
// CHECK-O1: cir.opt_level = #cir.opt_level<opt_level = 1, opt_size = 0>
21+
22+
// CHECK-O2: module
23+
// CHECK-O2: cir.opt_level = #cir.opt_level<opt_level = 2, opt_size = 0>
24+
25+
// CHECK-O3: module
26+
// CHECK-O3: cir.opt_level = #cir.opt_level<opt_level = 3, opt_size = 0>
27+
28+
// CHECK-Os: module
29+
// CHECK-Os: cir.opt_level = #cir.opt_level<opt_level = 2, opt_size = 1>
30+
31+
// CHECK-Oz: module
32+
// CHECK-Oz: cir.opt_level = #cir.opt_level<opt_level = 2, opt_size = 2>

0 commit comments

Comments
 (0)