Skip to content

Commit 5077e12

Browse files
committed
[CIR] Align inline-kind FuncOp attribute with incubator
Switches to more efficient explicit enum property instead of a wrapped storage, simplifying the string representation. The attribute is now placed before the symbol name for consistency with other FuncOp attributes. FileCheck patterns are also simplified to match only the attributes under test.
1 parent 1d3384e commit 5077e12

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+306
-323
lines changed

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

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,44 +1085,10 @@ def CIR_TypeInfoAttr : CIR_Attr<"TypeInfo", "typeinfo", [TypedAttrInterface]> {
10851085
//===----------------------------------------------------------------------===//
10861086

10871087
def CIR_InlineKind : CIR_I32EnumAttr<"InlineKind", "inlineKind", [
1088-
I32EnumAttrCase<"NoInline", 1, "never">,
1089-
I32EnumAttrCase<"AlwaysInline", 2, "always">,
1090-
I32EnumAttrCase<"InlineHint", 3, "hint">
1091-
]> {
1092-
let genSpecializedAttr = 0;
1093-
}
1094-
1095-
def CIR_InlineAttr : CIR_EnumAttr<CIR_InlineKind, "inline"> {
1096-
let summary = "Inline attribute";
1097-
let description = [{
1098-
Inline attribute represents user directives for inlining behavior.
1099-
This attribute is only used by `cir.func` operations.
1100-
1101-
Values:
1102-
- `never`: Prevents the function from being inlined (__attribute__((noinline)))
1103-
- `always`: Forces the function to be inlined (__attribute__((always_inline)))
1104-
- `hint`: Suggests the function should be inlined (inline keyword)
1105-
1106-
Example:
1107-
```
1108-
cir.func @noinline_func(%arg0: !s32i) -> !s32i inline(never) {
1109-
cir.return %arg0 : !s32i
1110-
}
1111-
cir.func @always_inline_func() -> !s32i inline(always) {
1112-
%0 = cir.const #cir.int<42> : !s32i
1113-
cir.return %0 : !s32i
1114-
}
1115-
```
1116-
}];
1117-
1118-
let cppClassName = "InlineAttr";
1119-
1120-
let extraClassDeclaration = [{
1121-
bool isNoInline() const { return getValue() == InlineKind::NoInline; };
1122-
bool isAlwaysInline() const { return getValue() == InlineKind::AlwaysInline; };
1123-
bool isInlineHint() const { return getValue() == InlineKind::InlineHint; };
1124-
}];
1125-
}
1088+
I32EnumAttrCase<"NoInline", 1, "no_inline">,
1089+
I32EnumAttrCase<"AlwaysInline", 2, "always_inline">,
1090+
I32EnumAttrCase<"InlineHint", 3, "inline_hint">
1091+
]>;
11261092

11271093
//===----------------------------------------------------------------------===//
11281094
// CatchAllAttr & UnwindAttr

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

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2564,9 +2564,9 @@ def CIR_FuncOp : CIR_Op<"func", [
25642564
Similarly, for global destructors both `global_dtor` and
25652565
`global_dtor(<priority>)` are available.
25662566

2567-
The `inline(never)` keyword marks a function that should not be inlined.
2568-
The `inline(always)` keyword marks a function that should always be inlined.
2569-
The `inline(hint)` keyword suggests that the function should be inlined.
2567+
The `no_inline` attribute marks a function that should not be inlined.
2568+
The `always_inline` attribute marks a function that should always be inlined.
2569+
The `inline_hint` attribute suggests that the function should be inlined.
25702570

25712571
Example:
25722572

@@ -2580,7 +2580,10 @@ def CIR_FuncOp : CIR_Op<"func", [
25802580

25812581
// Linkage information
25822582
cir.func linkonce_odr @some_method(...)
2583-
```
2583+
2584+
// Inline information
2585+
cir.func no_inline @some_method(...)
2586+
25842587
// Builtin function
25852588
cir.func builtin @__builtin_coro_end(!cir.ptr<i8>, !cir.bool) -> !cir.bool
25862589
// Coroutine
@@ -2592,26 +2595,29 @@ def CIR_FuncOp : CIR_Op<"func", [
25922595
```
25932596
}];
25942597

2595-
let arguments = (ins SymbolNameAttr:$sym_name,
2596-
CIR_VisibilityAttr:$global_visibility,
2597-
TypeAttrOf<CIR_FuncType>:$function_type,
2598-
UnitAttr:$builtin,
2599-
UnitAttr:$coroutine,
2600-
UnitAttr:$lambda,
2601-
UnitAttr:$no_proto,
2602-
UnitAttr:$dso_local,
2603-
DefaultValuedAttr<CIR_GlobalLinkageKind,
2604-
"cir::GlobalLinkageKind::ExternalLinkage">:$linkage,
2605-
OptionalAttr<CIR_InlineAttr>:$inline_kind,
2606-
OptionalAttr<StrAttr>:$sym_visibility,
2607-
UnitAttr:$comdat,
2608-
OptionalAttr<DictArrayAttr>:$arg_attrs,
2609-
OptionalAttr<DictArrayAttr>:$res_attrs,
2610-
OptionalAttr<FlatSymbolRefAttr>:$aliasee,
2611-
CIR_OptionalPriorityAttr:$global_ctor_priority,
2612-
CIR_OptionalPriorityAttr:$global_dtor_priority,
2613-
OptionalAttr<CIR_CXXSpecialMemberAttr>:$cxx_special_member
2614-
);
2598+
let arguments = (ins
2599+
SymbolNameAttr:$sym_name,
2600+
CIR_VisibilityAttr:$global_visibility,
2601+
TypeAttrOf<CIR_FuncType>:$function_type,
2602+
UnitAttr:$builtin,
2603+
UnitAttr:$coroutine,
2604+
OptionalAttr<CIR_InlineKind>:$inline_kind,
2605+
UnitAttr:$lambda,
2606+
UnitAttr:$no_proto,
2607+
UnitAttr:$dso_local,
2608+
DefaultValuedAttr<
2609+
CIR_GlobalLinkageKind,
2610+
"cir::GlobalLinkageKind::ExternalLinkage"
2611+
>:$linkage,
2612+
OptionalAttr<StrAttr>:$sym_visibility,
2613+
UnitAttr:$comdat,
2614+
OptionalAttr<DictArrayAttr>:$arg_attrs,
2615+
OptionalAttr<DictArrayAttr>:$res_attrs,
2616+
OptionalAttr<FlatSymbolRefAttr>:$aliasee,
2617+
CIR_OptionalPriorityAttr:$global_ctor_priority,
2618+
CIR_OptionalPriorityAttr:$global_dtor_priority,
2619+
OptionalAttr<CIR_CXXSpecialMemberAttr>:$cxx_special_member
2620+
);
26152621

26162622
let regions = (region AnyRegion:$body);
26172623

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1870,8 +1870,7 @@ CIRGenCallee CIRGenFunction::emitDirectCallee(const GlobalDecl &gd) {
18701870
clone.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
18711871
&cgm.getMLIRContext(), cir::GlobalLinkageKind::InternalLinkage));
18721872
clone.setSymVisibility("private");
1873-
clone.setInlineKindAttr(cir::InlineAttr::get(
1874-
&cgm.getMLIRContext(), cir::InlineKind::AlwaysInline));
1873+
clone.setInlineKind(cir::InlineKind::AlwaysInline);
18751874
}
18761875
return CIRGenCallee::forDirect(clone, gd);
18771876
}

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,7 +1975,6 @@ void CIRGenModule::setCIRFunctionAttributesForDefinition(
19751975
existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
19761976
bool isAlwaysInline = existingInlineKind &&
19771977
*existingInlineKind == cir::InlineKind::AlwaysInline;
1978-
19791978
if (!decl) {
19801979
assert(!cir::MissingFeatures::hlsl());
19811980

@@ -1984,8 +1983,7 @@ void CIRGenModule::setCIRFunctionAttributesForDefinition(
19841983
// If inlining is disabled and we don't have a declaration to control
19851984
// inlining, mark the function as 'noinline' unless it is explicitly
19861985
// marked as 'alwaysinline'.
1987-
f.setInlineKindAttr(
1988-
cir::InlineAttr::get(&getMLIRContext(), cir::InlineKind::NoInline));
1986+
f.setInlineKind(cir::InlineKind::NoInline);
19891987
}
19901988

19911989
return;
@@ -2002,19 +2000,16 @@ void CIRGenModule::setCIRFunctionAttributesForDefinition(
20022000
// Handle inline attributes
20032001
if (decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) {
20042002
// Add noinline if the function isn't always_inline.
2005-
f.setInlineKindAttr(
2006-
cir::InlineAttr::get(&getMLIRContext(), cir::InlineKind::NoInline));
2003+
f.setInlineKind(cir::InlineKind::NoInline);
20072004
} else if (decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) {
20082005
// Don't override AlwaysInline with NoInline, or vice versa, since we can't
20092006
// specify both in IR.
2010-
f.setInlineKindAttr(
2011-
cir::InlineAttr::get(&getMLIRContext(), cir::InlineKind::AlwaysInline));
2007+
f.setInlineKind(cir::InlineKind::AlwaysInline);
20122008
} else if (codeGenOpts.getInlining() == CodeGenOptions::OnlyAlwaysInlining) {
20132009
// If inlining is disabled, force everything that isn't always_inline
20142010
// to carry an explicit noinline attribute.
20152011
if (!isAlwaysInline) {
2016-
f.setInlineKindAttr(
2017-
cir::InlineAttr::get(&getMLIRContext(), cir::InlineKind::NoInline));
2012+
f.setInlineKind(cir::InlineKind::NoInline);
20182013
}
20192014
} else {
20202015
// Otherwise, propagate the inline hint attribute and potentially use its
@@ -2036,13 +2031,11 @@ void CIRGenModule::setCIRFunctionAttributesForDefinition(
20362031
return any_of(pattern->redecls(), checkRedeclForInline);
20372032
};
20382033
if (checkForInline(fd)) {
2039-
f.setInlineKindAttr(cir::InlineAttr::get(&getMLIRContext(),
2040-
cir::InlineKind::InlineHint));
2034+
f.setInlineKind(cir::InlineKind::InlineHint);
20412035
} else if (codeGenOpts.getInlining() ==
20422036
CodeGenOptions::OnlyHintInlining &&
20432037
!fd->isInlined() && !isAlwaysInline) {
2044-
f.setInlineKindAttr(
2045-
cir::InlineAttr::get(&getMLIRContext(), cir::InlineKind::NoInline));
2038+
f.setInlineKind(cir::InlineKind::NoInline);
20462039
}
20472040
}
20482041
}

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

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,41 @@ void parseVisibilityAttr(OpAsmParser &parser, cir::VisibilityAttr &visibility) {
220220
visibility = cir::VisibilityAttr::get(parser.getContext(), visibilityKind);
221221
}
222222

223+
//===----------------------------------------------------------------------===//
224+
// InlineKindAttr (FIXME: remove once FuncOp uses assembly format)
225+
//===----------------------------------------------------------------------===//
226+
227+
ParseResult parseInlineKindAttr(OpAsmParser &parser,
228+
cir::InlineKindAttr &inlineKindAttr) {
229+
// Static list of possible inline kind keywords
230+
static constexpr llvm::StringRef keywords[] = {"no_inline", "always_inline",
231+
"inline_hint"};
232+
233+
// Parse the inline kind keyword (optional)
234+
llvm::StringRef keyword;
235+
if (parser.parseOptionalKeyword(&keyword, keywords).failed()) {
236+
// Not an inline kind keyword, leave inlineKindAttr empty
237+
return success();
238+
}
239+
240+
// Parse the enum value from the keyword
241+
auto inlineKindResult = ::cir::symbolizeEnum<::cir::InlineKind>(keyword);
242+
if (!inlineKindResult) {
243+
return parser.emitError(parser.getCurrentLocation(), "expected one of [")
244+
<< llvm::join(llvm::ArrayRef(keywords), ", ")
245+
<< "] for inlineKind, got: " << keyword;
246+
}
247+
248+
inlineKindAttr =
249+
::cir::InlineKindAttr::get(parser.getContext(), *inlineKindResult);
250+
return success();
251+
}
252+
253+
void printInlineKindAttr(OpAsmPrinter &p, cir::InlineKindAttr inlineKindAttr) {
254+
if (inlineKindAttr) {
255+
p << " " << stringifyInlineKind(inlineKindAttr.getValue());
256+
}
257+
}
223258
//===----------------------------------------------------------------------===//
224259
// CIR Custom Parsers/Printers
225260
//===----------------------------------------------------------------------===//
@@ -1753,6 +1788,7 @@ ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {
17531788

17541789
mlir::StringAttr builtinNameAttr = getBuiltinAttrName(state.name);
17551790
mlir::StringAttr coroutineNameAttr = getCoroutineAttrName(state.name);
1791+
mlir::StringAttr inlineKindNameAttr = getInlineKindAttrName(state.name);
17561792
mlir::StringAttr lambdaNameAttr = getLambdaAttrName(state.name);
17571793
mlir::StringAttr noProtoNameAttr = getNoProtoAttrName(state.name);
17581794
mlir::StringAttr visNameAttr = getSymVisibilityAttrName(state.name);
@@ -1765,6 +1801,14 @@ ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {
17651801
if (::mlir::succeeded(
17661802
parser.parseOptionalKeyword(coroutineNameAttr.strref())))
17671803
state.addAttribute(coroutineNameAttr, parser.getBuilder().getUnitAttr());
1804+
1805+
// Parse optional inline kind attribute
1806+
cir::InlineKindAttr inlineKindAttr;
1807+
if (failed(parseInlineKindAttr(parser, inlineKindAttr)))
1808+
return failure();
1809+
if (inlineKindAttr)
1810+
state.addAttribute(inlineKindNameAttr, inlineKindAttr);
1811+
17681812
if (::mlir::succeeded(parser.parseOptionalKeyword(lambdaNameAttr.strref())))
17691813
state.addAttribute(lambdaNameAttr, parser.getBuilder().getUnitAttr());
17701814
if (parser.parseOptionalKeyword(noProtoNameAttr).succeeded())
@@ -1890,36 +1934,6 @@ ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {
18901934
}).failed())
18911935
return failure();
18921936

1893-
// Parse optional inline kind: inline(never|always|hint)
1894-
if (parser.parseOptionalKeyword("inline").succeeded()) {
1895-
if (parser.parseLParen().failed())
1896-
return failure();
1897-
1898-
llvm::StringRef inlineKindStr;
1899-
const std::array<llvm::StringRef, cir::getMaxEnumValForInlineKind()>
1900-
allowedInlineKindStrs{
1901-
cir::stringifyInlineKind(cir::InlineKind::NoInline),
1902-
cir::stringifyInlineKind(cir::InlineKind::AlwaysInline),
1903-
cir::stringifyInlineKind(cir::InlineKind::InlineHint),
1904-
};
1905-
if (parser.parseOptionalKeyword(&inlineKindStr, allowedInlineKindStrs)
1906-
.failed())
1907-
return parser.emitError(parser.getCurrentLocation(),
1908-
"expected 'never', 'always', or 'hint'");
1909-
1910-
std::optional<InlineKind> inlineKind =
1911-
cir::symbolizeInlineKind(inlineKindStr);
1912-
if (!inlineKind)
1913-
return parser.emitError(parser.getCurrentLocation(),
1914-
"invalid inline kind");
1915-
1916-
state.addAttribute(getInlineKindAttrName(state.name),
1917-
cir::InlineAttr::get(builder.getContext(), *inlineKind));
1918-
1919-
if (parser.parseRParen().failed())
1920-
return failure();
1921-
}
1922-
19231937
// Parse the rest of the attributes.
19241938
NamedAttrList parsedAttrs;
19251939
if (parser.parseOptionalAttrDictWithKeyword(parsedAttrs))
@@ -2028,6 +2042,8 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
20282042
if (getCoroutine())
20292043
p << " coroutine";
20302044

2045+
printInlineKindAttr(p, getInlineKindAttr());
2046+
20312047
if (getLambda())
20322048
p << " lambda";
20332049

@@ -2083,10 +2099,6 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
20832099
p << "(" << globalDtorPriority.value() << ")";
20842100
}
20852101

2086-
if (cir::InlineAttr inlineAttr = getInlineKindAttr()) {
2087-
p << " inline(" << cir::stringifyInlineKind(inlineAttr.getValue()) << ")";
2088-
}
2089-
20902102
function_interface_impl::printFunctionAttributes(
20912103
p, *this, cir::FuncOp::getAttributeNames());
20922104

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,10 +1978,10 @@ mlir::LogicalResult CIRToLLVMFuncOpLowering::matchAndRewrite(
19781978

19791979
assert(!cir::MissingFeatures::opFuncMultipleReturnVals());
19801980

1981-
if (auto inlineKind = op.getInlineKind()) {
1982-
fn.setNoInline(inlineKind == cir::InlineKind::NoInline);
1983-
fn.setInlineHint(inlineKind == cir::InlineKind::InlineHint);
1984-
fn.setAlwaysInline(inlineKind == cir::InlineKind::AlwaysInline);
1981+
if (std::optional<cir::InlineKind> inlineKind = op.getInlineKind()) {
1982+
fn.setNoInline(*inlineKind == cir::InlineKind::NoInline);
1983+
fn.setInlineHint(*inlineKind == cir::InlineKind::InlineHint);
1984+
fn.setAlwaysInline(*inlineKind == cir::InlineKind::AlwaysInline);
19851985
}
19861986

19871987
fn.setVisibility_Attr(mlir::LLVM::VisibilityAttr::get(

clang/test/CIR/CodeGen/aapcs-volatile-bitfields.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ int check_load(st1 *s1) {
8282
return s1->b;
8383
}
8484

85-
// CIR: cir.func dso_local @check_load
85+
// CIR: cir.func {{.*}} @check_load
8686
// CIR: [[LOAD:%.*]] = cir.load align(8) {{.*}} : !cir.ptr<!cir.ptr<!rec_st1>>, !cir.ptr<!rec_st1>
8787
// CIR: [[MEMBER:%.*]] = cir.get_member [[LOAD]][0] {name = "b"} : !cir.ptr<!rec_st1> -> !cir.ptr<!u16i>
8888
// CIR: [[BITFI:%.*]] = cir.get_bitfield align(4) (#bfi_b, [[MEMBER]] {is_volatile} : !cir.ptr<!u16i>) -> !u32i
@@ -114,7 +114,7 @@ int check_load_exception(st3 *s3) {
114114
return s3->b;
115115
}
116116

117-
// CIR: cir.func dso_local @check_load_exception
117+
// CIR: cir.func {{.*}} @check_load_exception
118118
// CIR: [[LOAD:%.*]] = cir.load align(8) {{.*}} : !cir.ptr<!cir.ptr<!rec_st3>>, !cir.ptr<!rec_st3>
119119
// CIR: [[MEMBER:%.*]] = cir.get_member [[LOAD]][2] {name = "b"} : !cir.ptr<!rec_st3> -> !cir.ptr<!u8i>
120120
// CIR: [[BITFI:%.*]] = cir.get_bitfield align(4) (#bfi_b1, [[MEMBER]] {is_volatile} : !cir.ptr<!u8i>) -> !u32i
@@ -151,7 +151,7 @@ int clip_load_exception2(clip *c) {
151151
return c->a;
152152
}
153153

154-
// CIR: cir.func dso_local @clip_load_exception2
154+
// CIR: cir.func {{.*}} @clip_load_exception2
155155
// CIR: [[LOAD:%.*]] = cir.load align(8) {{.*}} : !cir.ptr<!cir.ptr<!rec_clip>>, !cir.ptr<!rec_clip>
156156
// CIR: [[MEMBER:%.*]] = cir.get_member [[LOAD]][0] {name = "a"} : !cir.ptr<!rec_clip> -> !cir.ptr<!cir.array<!u8i x 3>>
157157
// CIR: [[BITFI:%.*]] = cir.get_bitfield align(4) (#bfi_a1, [[MEMBER]] {is_volatile} : !cir.ptr<!cir.array<!u8i x 3>>) -> !s32i
@@ -178,7 +178,7 @@ void check_store(st2 *s2) {
178178
s2->a = 1;
179179
}
180180

181-
// CIR: cir.func dso_local @check_store
181+
// CIR: cir.func {{.*}} @check_store
182182
// CIR: [[CONST:%.*]] = cir.const #cir.int<1> : !s32i
183183
// CIR: [[CAST:%.*]] = cir.cast integral [[CONST]] : !s32i -> !s16i
184184
// CIR: [[LOAD:%.*]] = cir.load align(8) {{.*}} : !cir.ptr<!cir.ptr<!rec_st2>>, !cir.ptr<!rec_st2>
@@ -209,7 +209,7 @@ void check_store_exception(st3 *s3) {
209209
s3->b = 2;
210210
}
211211

212-
// CIR: cir.func dso_local @check_store_exception
212+
// CIR: cir.func {{.*}} @check_store_exception
213213
// CIR: [[CONST:%.*]] = cir.const #cir.int<2> : !s32i
214214
// CIR: [[CAST:%.*]] = cir.cast integral [[CONST]] : !s32i -> !u32i
215215
// CIR: [[LOAD:%.*]] = cir.load align(8) {{.*}} : !cir.ptr<!cir.ptr<!rec_st3>>, !cir.ptr<!rec_st3>
@@ -239,7 +239,7 @@ void clip_store_exception2(clip *c) {
239239
c->a = 3;
240240
}
241241

242-
// CIR: cir.func dso_local @clip_store_exception2
242+
// CIR: cir.func {{.*}} @clip_store_exception2
243243
// CIR: [[CONST:%.*]] = cir.const #cir.int<3> : !s32i
244244
// CIR: [[LOAD:%.*]] = cir.load align(8) {{.*}} : !cir.ptr<!cir.ptr<!rec_clip>>, !cir.ptr<!rec_clip>
245245
// CIR: [[MEMBER:%.*]] = cir.get_member [[LOAD]][0] {name = "a"} : !cir.ptr<!rec_clip> -> !cir.ptr<!cir.array<!u8i x 3>>
@@ -261,7 +261,7 @@ void check_store_second_member (st4 *s4) {
261261
s4->b = 1;
262262
}
263263

264-
// CIR: cir.func dso_local @check_store_second_member
264+
// CIR: cir.func {{.*}} @check_store_second_member
265265
// CIR: [[ONE:%.*]] = cir.const #cir.int<1> : !s32i
266266
// CIR: [[CAST:%.*]] = cir.cast integral [[ONE]] : !s32i -> !u64i
267267
// CIR: [[LOAD:%.*]] = cir.load align(8) {{.*}} : !cir.ptr<!cir.ptr<!rec_st4>>, !cir.ptr<!rec_st4>

0 commit comments

Comments
 (0)