Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
Original file line number Diff line number Diff line change
Expand Up @@ -1222,10 +1222,6 @@ def CIR_InlineAttr : CIR_EnumAttr<CIR_InlineKind, "inline"> {
// Unit Function Attributes
//===----------------------------------------------------------------------===//

def CIR_OptNoneAttr : CIR_UnitAttr<"OptNone", "optnone"> {
let storageType = [{ OptNoneAttr }];
}

def CIR_NoThrowAttr : CIR_UnitAttr<"NoThrow", "nothrow"> {
let storageType = [{ NoThrowAttr }];
}
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -4101,6 +4101,7 @@ def FuncOp : CIR_Op<"func", [
UnitAttr:$coroutine,
UnitAttr:$lambda,
UnitAttr:$no_proto,
UnitAttr:$opt_none,
UnitAttr:$dso_local,
DefaultValuedAttr<
CIR_GlobalLinkageKind, "GlobalLinkageKind::ExternalLinkage"
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/CIR/CodeGen/CIRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2938,8 +2938,7 @@ void CIRGenModule::setCIRFunctionAttributesForDefinition(const Decl *decl,
} else if ((shouldAddOptNone || decl->hasAttr<OptimizeNoneAttr>()) &&
!isAlwaysInline) {
// Add optnone, but do so only if the function isn't always_inline.
auto optNoneAttr = cir::OptNoneAttr::get(&getMLIRContext());
attrs.set(optNoneAttr.getMnemonic(), optNoneAttr);
f.setOptNone(true);

// OptimizeNone implies noinline; we should not be inlining such functions.
auto noInlineAttr =
Expand Down
10 changes: 8 additions & 2 deletions clang/lib/CIR/Dialect/IR/CIRDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2649,6 +2649,7 @@ ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {
auto lambdaNameAttr = getLambdaAttrName(state.name);
auto visNameAttr = getSymVisibilityAttrName(state.name);
auto noProtoNameAttr = getNoProtoAttrName(state.name);
auto optNoneNameAttr = getOptNoneAttrName(state.name);
auto visibilityNameAttr = getGlobalVisibilityAttrName(state.name);
auto dsoLocalNameAttr = getDsoLocalAttrName(state.name);
auto annotationsNameAttr = getAnnotationsAttrName(state.name);
Expand All @@ -2662,6 +2663,8 @@ ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {
state.addAttribute(lambdaNameAttr, parser.getBuilder().getUnitAttr());
if (parser.parseOptionalKeyword(noProtoNameAttr).succeeded())
state.addAttribute(noProtoNameAttr, parser.getBuilder().getUnitAttr());
if (parser.parseOptionalKeyword("optnone").succeeded())
state.addAttribute(optNoneNameAttr, parser.getBuilder().getUnitAttr());

// TODO: Missing comdat
assert(!cir::MissingFeatures::setComdat());
Expand Down Expand Up @@ -2898,6 +2901,9 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
if (getNoProto())
p << " no_proto";

if (getOptNone())
p << " optnone";

if (getComdat())
p << " comdat";

Expand Down Expand Up @@ -2946,8 +2952,8 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
getFunctionTypeAttrName(), getGlobalCtorPriorityAttrName(),
getGlobalDtorPriorityAttrName(), getLambdaAttrName(),
getLinkageAttrName(), getCallingConvAttrName(), getNoProtoAttrName(),
getSymVisibilityAttrName(), getArgAttrsAttrName(), getResAttrsAttrName(),
getComdatAttrName(), getGlobalVisibilityAttrName(),
getOptNoneAttrName(), getSymVisibilityAttrName(), getArgAttrsAttrName(),
getResAttrsAttrName(), getComdatAttrName(), getGlobalVisibilityAttrName(),
getAnnotationsAttrName(), getCxxSpecialMemberAttrName()});

if (auto aliaseeName = getAliasee()) {
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2370,6 +2370,7 @@ void CIRToLLVMFuncOpLowering::lowerFuncAttributes(
name == func.getFunctionTypeAttrName() ||
name == getLinkageAttrNameString() ||
name == func.getCallingConvAttrName() ||
name == func.getOptNoneAttrName() ||
name == func.getDsoLocalAttrName() ||
(filterArgAndResAttrs && (name == func.getArgAttrsAttrName() ||
name == func.getResAttrsAttrName())))
Expand Down Expand Up @@ -2525,6 +2526,9 @@ mlir::LogicalResult CIRToLLVMFuncOpLowering::matchAndRewrite(
getContext(), lowerCIRVisibilityToLLVMVisibility(
op.getGlobalVisibilityAttr().getValue())));

// Handle optnone attribute
fn.setOptimizeNone(op.getOptNone());

rewriter.inlineRegionBefore(op.getBody(), fn.getBody(), fn.end());
if (failed(rewriter.convertRegionTypes(&fn.getBody(), *typeConverter,
&signatureConversion)))
Expand Down
2 changes: 0 additions & 2 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVMIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,6 @@ class CIRDialectLLVMIRTranslationInterface
llvmFunc->addFnAttr(llvm::Attribute::InlineHint);
else
llvm_unreachable("Unknown inline kind");
} else if (mlir::dyn_cast<cir::OptNoneAttr>(attr.getValue())) {
llvmFunc->addFnAttr(llvm::Attribute::OptimizeNone);
} else if (mlir::dyn_cast<cir::NoThrowAttr>(attr.getValue())) {
llvmFunc->addFnAttr(llvm::Attribute::NoUnwind);
} else if (mlir::dyn_cast<cir::ConvergentAttr>(attr.getValue())) {
Expand Down
8 changes: 4 additions & 4 deletions clang/test/CIR/CodeGen/call-extra-attrs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ int s2(int a, int b) {
return s1(a, b);
}

// CIR: #fn_attr = #cir<extra({inline = #cir.inline<no>, nothrow = #cir.nothrow, optnone = #cir.optnone})>
// CIR: #fn_attr = #cir<extra({inline = #cir.inline<no>, nothrow = #cir.nothrow})>
// CIR: #fn_attr1 = #cir<extra({nothrow = #cir.nothrow})>

// CIR: cir.func {{.*}} @_Z2s0ii(%{{.*}}, %{{.*}}) -> {{.*}} extra(#fn_attr)
// CIR: cir.func {{.*}} @_Z2s1ii(%{{.*}}, %{{.*}}) -> {{.*}} extra(#fn_attr)
// CIR: cir.func optnone {{.*}} @_Z2s0ii(%{{.*}}, %{{.*}}) -> {{.*}} extra(#fn_attr)
// CIR: cir.func optnone {{.*}} @_Z2s1ii(%{{.*}}, %{{.*}}) -> {{.*}} extra(#fn_attr)
// CIR: cir.call @_Z2s0ii(%{{.*}}, %{{.*}}) : ({{.*}}, {{.*}}) -> {{.*}} extra(#fn_attr1)
// CIR: cir.func {{.*}} @_Z2s2ii(%{{.*}}, %{{.*}}) -> {{.*}} extra(#fn_attr)
// CIR: cir.func optnone {{.*}} @_Z2s2ii(%{{.*}}, %{{.*}}) -> {{.*}} extra(#fn_attr)
// CHECK-NOT: cir.call @_Z2s1ii(%{{.*}}, %{{.*}}) : ({{.*}}, {{.*}}) -> {{.*}} extra(#fn_attr{{.*}})

// LLVM: define dso_local i32 @_Z2s0ii(i32 %0, i32 %1) #[[#ATTR1:]]
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CIR/CodeGen/conditional-cleanup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ namespace test7 {

// CIR_EH-DAG: #[[$ATTR_0:.+]] = #cir.bool<false> : !cir.bool
// CIR_EH-DAG: #[[$ATTR_1:.+]] = #cir<extra({nothrow = #cir.nothrow})>
// CIR_EH-DAG: #[[$ATTR_2:.+]] = #cir<extra({inline = #cir.inline<no>, optnone = #cir.optnone})>
// CIR_EH-DAG: #[[$ATTR_2:.+]] = #cir<extra({inline = #cir.inline<no>})>
// CIR_EH-DAG: #[[$ATTR_3:.+]] = #cir.bool<true> : !cir.bool

// CIR_EH-LABEL: @_ZN5test74testEv
Expand Down
6 changes: 3 additions & 3 deletions clang/test/CIR/CodeGen/dynamic-cast.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module @"/Users/henrichlauko/src/clangir/clang/test/CIR/CodeGen/dynamic-cast.cpp
cir.global constant external @_ZTI7Derived = #cir.typeinfo<{#cir.global_view<@_ZTVN10__cxxabiv120__si_class_type_infoE, [2 : i32]> : !cir.ptr<!u8i>, #cir.global_view<@_ZTS7Derived> : !cir.ptr<!u8i>, #cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>}> : !rec_anon_struct {alignment = 8 : i64} loc(#loc28)
cir.func private @__dynamic_cast(!cir.ptr<!void>, !cir.ptr<!u8i>, !cir.ptr<!u8i>, !s64i) -> !cir.ptr<!void> loc(#loc)
cir.func private @__cxa_bad_cast() loc(#loc)
cir.func dso_local @_Z8ptr_castP4Base(%arg0: !cir.ptr<!rec_Base> loc(fused[#loc5, #loc6])) -> !cir.ptr<!rec_Derived> {inline = #cir.inline<no>, nothrow = #cir.nothrow, optnone = #cir.optnone} {
cir.func dso_local optnone @_Z8ptr_castP4Base(%arg0: !cir.ptr<!rec_Base> loc(fused[#loc5, #loc6])) -> !cir.ptr<!rec_Derived> {inline = #cir.inline<no>, nothrow = #cir.nothrow} {
%0 = cir.alloca !cir.ptr<!rec_Base>, !cir.ptr<!cir.ptr<!rec_Base>>, ["b", init] {alignment = 8 : i64} loc(#loc30)
%1 = cir.alloca !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>, ["__retval"] {alignment = 8 : i64} loc(#loc4)
cir.store %arg0, %0 : !cir.ptr<!rec_Base>, !cir.ptr<!cir.ptr<!rec_Base>> loc(#loc7)
Expand All @@ -43,7 +43,7 @@ module @"/Users/henrichlauko/src/clangir/clang/test/CIR/CodeGen/dynamic-cast.cpp
%5 = cir.load %1 : !cir.ptr<!cir.ptr<!rec_Derived>>, !cir.ptr<!rec_Derived> loc(#loc31)
cir.return %5 : !cir.ptr<!rec_Derived> loc(#loc31)
} loc(#loc29)
cir.func dso_local @_Z8ref_castR4Base(%arg0: !cir.ptr<!rec_Base> loc(fused[#loc12, #loc13])) -> !cir.ptr<!rec_Derived> {inline = #cir.inline<no>, nothrow = #cir.nothrow, optnone = #cir.optnone} {
cir.func dso_local optnone @_Z8ref_castR4Base(%arg0: !cir.ptr<!rec_Base> loc(fused[#loc12, #loc13])) -> !cir.ptr<!rec_Derived> {inline = #cir.inline<no>, nothrow = #cir.nothrow} {
%0 = cir.alloca !cir.ptr<!rec_Base>, !cir.ptr<!cir.ptr<!rec_Base>>, ["b", init, const] {alignment = 8 : i64} loc(#loc33)
%1 = cir.alloca !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>, ["__retval"] {alignment = 8 : i64} loc(#loc11)
cir.store %arg0, %0 : !cir.ptr<!rec_Base>, !cir.ptr<!cir.ptr<!rec_Base>> loc(#loc14)
Expand All @@ -64,7 +64,7 @@ module @"/Users/henrichlauko/src/clangir/clang/test/CIR/CodeGen/dynamic-cast.cpp
%11 = cir.load %1 : !cir.ptr<!cir.ptr<!rec_Derived>>, !cir.ptr<!rec_Derived> loc(#loc35)
cir.return %11 : !cir.ptr<!rec_Derived> loc(#loc35)
} loc(#loc32)
cir.func dso_local @_Z20ptr_cast_to_completeP4Base(%arg0: !cir.ptr<!rec_Base> loc(fused[#loc21, #loc22])) -> !cir.ptr<!void> {inline = #cir.inline<no>, nothrow = #cir.nothrow, optnone = #cir.optnone} {
cir.func dso_local optnone @_Z20ptr_cast_to_completeP4Base(%arg0: !cir.ptr<!rec_Base> loc(fused[#loc21, #loc22])) -> !cir.ptr<!void> {inline = #cir.inline<no>, nothrow = #cir.nothrow} {
%0 = cir.alloca !cir.ptr<!rec_Base>, !cir.ptr<!cir.ptr<!rec_Base>>, ["ptr", init] {alignment = 8 : i64} loc(#loc37)
%1 = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["__retval"] {alignment = 8 : i64} loc(#loc20)
cir.store %arg0, %0 : !cir.ptr<!rec_Base>, !cir.ptr<!cir.ptr<!rec_Base>> loc(#loc23)
Expand Down
6 changes: 3 additions & 3 deletions clang/test/CIR/CodeGen/optnone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ int s0(int a, int b) {
return x;
}

// CIR-O0: #fn_attr = #cir<extra({inline = #cir.inline<no>, nothrow = #cir.nothrow, optnone = #cir.optnone})>
// CIR-O0: cir.func {{.*}} @_Z2s0ii(%arg0:{{.*}}, %arg1:{{.*}} -> {{.*}} extra(#fn_attr)
// CIR-O0: #fn_attr = #cir<extra({inline = #cir.inline<no>, nothrow = #cir.nothrow})>
// CIR-O0: cir.func {{.*}}optnone {{.*}} @_Z2s0ii(%arg0:{{.*}}, %arg1:{{.*}} -> {{.*}} extra(#fn_attr)

// CIR-O2-NOT: #fn_attr ={{.*}} optnone
// CIR-O2-NOT: cir.func optnone

// LLVM-O0: define dso_local i32 @_Z2s0ii(i32 %0, i32 %1) #[[#ATTR:]]
// LLVM-O0: attributes #[[#ATTR]] = { noinline nounwind optnone }
Expand Down
6 changes: 3 additions & 3 deletions clang/test/CIR/IR/call.cir
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
!s32i = !cir.int<s, 32>
!fnptr = !cir.ptr<!cir.func<(!s32i) -> !s32i>>

#fn_attr = #cir<extra({inline = #cir.inline<no>, optnone = #cir.optnone})>
#fn_attr = #cir<extra({inline = #cir.inline<no>})>
#fn_attr1 = #cir<extra({nothrow = #cir.nothrow})>

module {
// Excerpt of std::array<int, 8192ul>::operator[](unsigned long)
cir.func linkonce_odr @_ZNSt5arrayIiLm8192EEixEm(%arg0: !s32i) -> !s32i extra(#fn_attr) {
cir.func linkonce_odr optnone @_ZNSt5arrayIiLm8192EEixEm(%arg0: !s32i) -> !s32i extra(#fn_attr) {
cir.return %arg0 : !s32i
}

cir.func private @my_add(%a: !s32i, %b: !s32i) -> !s32i cc(spir_function) extra(#fn_attr)
cir.func private optnone @my_add(%a: !s32i, %b: !s32i) -> !s32i cc(spir_function) extra(#fn_attr)

cir.func @ind(%fnptr: !fnptr, %a : !s32i) {
%r = cir.call %fnptr(%a) : (!fnptr, !s32i) -> !s32i
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CIR/IR/func-dsolocal-parser.cir
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// RUN: cir-opt %s --verify-roundtrip | FileCheck %s

!s32i = !cir.int<s, 32>
#fn_attr = #cir<extra({inline = #cir.inline<no>, nothrow = #cir.nothrow, optnone = #cir.optnone})>
#fn_attr = #cir<extra({inline = #cir.inline<no>, nothrow = #cir.nothrow})>
module {
cir.func dso_local @foo(%arg0: !s32i ) extra(#fn_attr) {
cir.func dso_local optnone @foo(%arg0: !s32i ) extra(#fn_attr) {
%0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init] {alignment = 4 : i64}
cir.store %arg0, %0 : !s32i, !cir.ptr<!s32i>
cir.return
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CIR/Lowering/brcond.cir
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// RUN: cir-translate %s -cir-to-llvmir --disable-cc-lowering | FileCheck %s -check-prefix=LLVM

!s32i = !cir.int<s, 32>
#fn_attr = #cir<extra({inline = #cir.inline<no>, nothrow = #cir.nothrow, optnone = #cir.optnone})>
module { cir.func no_proto @test() -> !cir.bool extra(#fn_attr) {
#fn_attr = #cir<extra({inline = #cir.inline<no>, nothrow = #cir.nothrow})>
module { cir.func no_proto optnone @test() -> !cir.bool extra(#fn_attr) {
%0 = cir.const #cir.int<0> : !s32i
%1 = cir.cast int_to_bool %0 : !s32i -> !cir.bool
cir.br ^bb1
Expand Down
8 changes: 4 additions & 4 deletions clang/test/CIR/Lowering/syncscope.cir
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
// RUN: cir-translate %s -cir-to-llvmir --disable-cc-lowering -o - | FileCheck %s -check-prefix=LLVM

!s32i = !cir.int<s, 32>
#fn_attr = #cir<extra({inline = #cir.inline<no>, nothrow = #cir.nothrow, optnone = #cir.optnone})>
#fn_attr = #cir<extra({inline = #cir.inline<no>, nothrow = #cir.nothrow})>
module {
cir.func @test(%ptr: !cir.ptr<!s32i>, %expected: !s32i, %desired: !s32i) -> !cir.bool extra(#fn_attr) {
cir.func optnone @test(%ptr: !cir.ptr<!s32i>, %expected: !s32i, %desired: !s32i) -> !cir.bool extra(#fn_attr) {
%old, %cmp = cir.atomic.cmp_xchg(%ptr : !cir.ptr<!s32i>, %expected : !s32i, %desired : !s32i, success = acquire, failure = acquire) syncscope(single_thread) align(4) : (!s32i, !cir.bool)
cir.return %cmp: !cir.bool
}

cir.func @load(%ptr: !cir.ptr<!s32i>) -> !s32i extra(#fn_attr) {
cir.func optnone @load(%ptr: !cir.ptr<!s32i>) -> !s32i extra(#fn_attr) {
%val = cir.load syncscope(single_thread) atomic(relaxed) %ptr : !cir.ptr<!s32i>, !s32i
cir.return %val : !s32i
}


// System scope should not materialize a syncscope attribute.
cir.func @system_load(%ptr: !cir.ptr<!s32i>) -> !s32i extra(#fn_attr) {
cir.func optnone @system_load(%ptr: !cir.ptr<!s32i>) -> !s32i extra(#fn_attr) {
%val = cir.load atomic(seq_cst) %ptr : !cir.ptr<!s32i>, !s32i
cir.return %val : !s32i
}
Expand Down
Loading