Author: Bruno Cardoso Lopes Date: 2026-10-16T20:31:32-07:00 New Revision: 08b8038d3475001d01d438c836af1c8140c97acd
URL: https://github.com/llvm/llvm-project/commit/08b8038d3475001d01d438c836af1c8140c97acd DIFF: https://github.com/llvm/llvm-project/commit/08b8038d3475001d01d438c836af1c8140c97acd.diff LOG: [CIR] Skip record rebuilds for unchanging types in CXXABI lowering (#232880) CIRABITypeConverter only rewrites data-member and method types, but it did not override typeMayChange, so every named record converted to a renamed copy and every op touching one was illegal, forcing the generic pattern to rebuild them all. Override it to report only those two types as possibly changing, letting records that reach neither convert to themselves and stay legal. Small gains across the more expensive selfhosting TUs (no CIR output changes): - Registry 36.7->35.8, - ASTImporterTest 64.4->63.7, - SLPVectorizer 93.6->91.9, - OpenMPDecomp 39.5->38.1, - SemaExpr 59.3->57.5. Added: clang/test/CIR/Transforms/cxx-abi-lowering-member-record.cir clang/test/CIR/Transforms/cxx-abi-lowering-same-type-cast-fold.cir Modified: clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp Removed: ################################################################################ diff --git a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp index 86c74ce14842b..2bf8bf1677912 100644 --- a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp +++ b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp @@ -846,6 +846,13 @@ class CIRABITypeConverter : public cir::RecordRewritingTypeConverter { return convertType(abiType); }); } + +protected: + // Only member pointer types are rewritten. Records that reach none of them + // are left alone. + bool typeMayChange(mlir::Type type) const override { + return mlir::isa<cir::DataMemberType, cir::MethodType>(type); + } }; } // namespace @@ -885,6 +892,27 @@ populateCXXABIConversionTarget(mlir::ConversionTarget &target, }); }); + // TargetLowering leaves same-type casts behind. Keep them illegal so the + // conversion driver folds them away. + target.addDynamicallyLegalOp<cir::CastOp>([&typeConverter](cir::CastOp op) { + if (op.getSrc().getType() == op.getType()) { + switch (op.getKind()) { + case cir::CastKind::bitcast: + case cir::CastKind::address_space: + case cir::CastKind::float_complex: + case cir::CastKind::int_complex: + return false; + default: + break; + } + } + if (!typeConverter.isLegal(op.getOperation())) + return false; + // CastOp has no regions, so operand/result types and inherent + // attributes are the whole legality check. + return areCXXABIInherentAttrsLegal(op, typeConverter); + }); + // Some CIR ops needs special checking for legality target.addDynamicallyLegalOp<cir::FuncOp>([&typeConverter](cir::FuncOp op) { bool attrs = areCXXABIInherentAttrsLegal(op, typeConverter); diff --git a/clang/test/CIR/Transforms/cxx-abi-lowering-member-record.cir b/clang/test/CIR/Transforms/cxx-abi-lowering-member-record.cir new file mode 100644 index 0000000000000..ee5a0ede7b0bf --- /dev/null +++ b/clang/test/CIR/Transforms/cxx-abi-lowering-member-record.cir @@ -0,0 +1,26 @@ +// RUN: cir-opt %s -cir-cxxabi-lowering -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s + +!s32i = !cir.int<s, 32> +!rec_Foo = !cir.struct<"Foo" {data !s32i}> +!method = !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i)> in !rec_Foo> +!rec_HasMethod = !cir.struct<"HasMethod" {data !method}> +!rec_Plain = !cir.struct<"Plain" {data !s32i}> + +// A record reaching a method type is rebuilt with the Itanium lowered form, +// a {ptr diff _t, ptr diff _t} pair. Dropping MethodType from typeMayChange +// leaves the member unlowered and this check fails. +// CHECK-DAG: !rec_HasMethod = !cir.struct<"HasMethod" {data !rec_anon_struct}> +// CHECK-DAG: !rec_anon_struct = !cir.struct<{data !s64i, data !s64i}> + +// A record reaching no member pointer type converts to itself and passes +// through with its name and members untouched. +// CHECK-DAG: !rec_Plain = !cir.struct<"Plain" {data !s32i}> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + cir.func @method_record() { + %m = cir.const #cir.zero : !rec_HasMethod + %p = cir.const #cir.zero : !rec_Plain + cir.return + } +} diff --git a/clang/test/CIR/Transforms/cxx-abi-lowering-same-type-cast-fold.cir b/clang/test/CIR/Transforms/cxx-abi-lowering-same-type-cast-fold.cir new file mode 100644 index 0000000000000..c0ee9a9b611a4 --- /dev/null +++ b/clang/test/CIR/Transforms/cxx-abi-lowering-same-type-cast-fold.cir @@ -0,0 +1,45 @@ +// RUN: cir-opt %s -cir-cxxabi-lowering -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s + +!u8i = !cir.int<u, 8> +!s32i = !cir.int<s, 32> +!rec_S = !cir.struct<"S" {data !s32i}> +!rec_Other = !cir.struct<"Other" {pad !u8i}> +!rec_Dmp = !cir.struct<"Dmp" {data !cir.data_member<!s32i in !rec_Other>}> +// CHECK: !rec_Dmp = !cir.struct<"Dmp" {data !s64i}> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // Same-type no-op casts stay illegal so the driver folds them away, + // on plain ... + cir.func @cast_plain(%p: !cir.ptr<!s32i>) -> !cir.ptr<!s32i> { + %c = cir.cast bitcast %p : !cir.ptr<!s32i> -> !cir.ptr<!s32i> + cir.return %c : !cir.ptr<!s32i> + } + // CHECK-LABEL: cir.func @cast_plain + // CHECK-NEXT: cir.return %{{.*}} : !cir.ptr<!s32i> + + // ... and record pointers. + cir.func @cast_record(%p: !cir.ptr<!rec_S>) -> !cir.ptr<!rec_S> { + %c = cir.cast bitcast %p : !cir.ptr<!rec_S> -> !cir.ptr<!rec_S> + cir.return %c : !cir.ptr<!rec_S> + } + // CHECK-LABEL: cir.func @cast_record + // CHECK-NEXT: cir.return %{{.*}} : !cir.ptr<!rec_S> + + // Same for the address_space casts TargetLowering leaves behind. + cir.func @cast_addrspace(%p: !cir.ptr<!s32i>) -> !cir.ptr<!s32i> { + %c = cir.cast address_space %p : !cir.ptr<!s32i> -> !cir.ptr<!s32i> + cir.return %c : !cir.ptr<!s32i> + } + // CHECK-LABEL: cir.func @cast_addrspace + // CHECK-NEXT: cir.return %{{.*}} : !cir.ptr<!s32i> + + // Records that reach member pointers are still rewritten. + cir.func @dmp_rewritten() { + %r = cir.const #cir.zero : !rec_Dmp + cir.return + } + // CHECK-LABEL: cir.func @dmp_rewritten + // CHECK-NEXT: %{{.*}} = cir.const #cir.zero : !rec_Dmp + // CHECK-NEXT: cir.return +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
