From debf60a6258f3fa94c58eab28a84ff3eaa3636ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= Date: Tue, 12 Nov 2024 03:06:59 +0100 Subject: [PATCH 1/3] Propagate delegate loads during inlining --- src/coreclr/jit/gentree.h | 3 ++- src/coreclr/jit/importer.cpp | 15 +++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index f72fa678135d22..7da821b6119c80 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -482,13 +482,14 @@ enum GenTreeFlags : unsigned int GTF_IND_REQ_ADDR_IN_REG = 0x08000000, // GT_IND -- requires its addr operand to be evaluated into a register. // This flag is useful in cases where it is required to generate register // indirect addressing mode. One such case is virtual stub calls on xarch. + GTF_IND_DELEGATE = 0x04000000, // GT_IND -- the target is a delegate (used for inlining heuristics) GTF_IND_UNALIGNED = 0x02000000, // OperIsIndir() -- the load or store is unaligned (we assume worst case alignment of 1 byte) GTF_IND_INVARIANT = 0x01000000, // GT_IND -- the target is invariant (a prejit indirection) GTF_IND_NONNULL = 0x00400000, // GT_IND -- the indirection never returns null (zero) GTF_IND_INITCLASS = 0x00200000, // OperIsIndir() -- the indirection requires preceding static cctor GTF_IND_ALLOW_NON_ATOMIC = 0x00100000, // GT_IND -- this memory access does not need to be atomic - GTF_IND_COPYABLE_FLAGS = GTF_IND_VOLATILE | GTF_IND_NONFAULTING | GTF_IND_UNALIGNED | GTF_IND_INITCLASS, + GTF_IND_COPYABLE_FLAGS = GTF_IND_VOLATILE | GTF_IND_NONFAULTING | GTF_IND_UNALIGNED | GTF_IND_DELEGATE | GTF_IND_INITCLASS, GTF_IND_FLAGS = GTF_IND_COPYABLE_FLAGS | GTF_IND_NONNULL | GTF_IND_TGT_NOT_HEAP | GTF_IND_TGT_HEAP | GTF_IND_INVARIANT | GTF_IND_ALLOW_NON_ATOMIC, GTF_ADDRMODE_NO_CSE = 0x80000000, // GT_ADD/GT_MUL/GT_LSH -- Do not CSE this node only, forms complex diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 564d3560109859..137ffe4f1f524d 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4142,10 +4142,15 @@ GenTree* Compiler::impImportStaticFieldAddress(CORINFO_RESOLVED_TOKEN* pResolved ((*pIndirFlags & GTF_IND_VOLATILE) == 0)) { bool isSpeculative = true; - if ((info.compCompHnd->getStaticFieldCurrentClass(pResolvedToken->hField, &isSpeculative) != - NO_CLASS_HANDLE)) + CORINFO_CLASS_HANDLE classHandle = info.compCompHnd->getStaticFieldCurrentClass(pResolvedToken->hField, &isSpeculative); + if (classHandle != NO_CLASS_HANDLE) { isStaticReadOnlyInitedRef = !isSpeculative; + unsigned attribs = info.compCompHnd->getClassAttribs(classHandle); + if ((attribs & CORINFO_FLG_DELEGATE) != 0) + { + indirFlags |= GTF_IND_DELEGATE; + } } } #endif // TARGET_64BIT @@ -4175,7 +4180,7 @@ GenTree* Compiler::impImportStaticFieldAddress(CORINFO_RESOLVED_TOKEN* pResolved } if (isStaticReadOnlyInitedRef) { - indirFlags |= (GTF_IND_INVARIANT | GTF_IND_NONNULL); + indirFlags |= (GTF_IND_NONFAULTING | GTF_IND_INVARIANT | GTF_IND_NONNULL); } break; } @@ -12545,7 +12550,9 @@ void Compiler::impFixPredLists() // bool Compiler::impIsInvariant(const GenTree* tree) { - return tree->OperIsConst() || impIsAddressInLocal(tree) || tree->OperIs(GT_FTN_ADDR); + return tree->OperIsConst() || impIsAddressInLocal(tree) || tree->OperIs(GT_FTN_ADDR) || + (tree->OperIs(GT_IND) && tree->AsIndir()->IsInvariantLoad() && + ((tree->AsIndir()->gtFlags & (GTF_SIDE_EFFECT | GTF_IND_DELEGATE)) == GTF_IND_DELEGATE)); } //------------------------------------------------------------------------ From 2d5739a0e992936b3bf5ddcd6d09f277f39a83a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= Date: Tue, 12 Nov 2024 03:22:07 +0100 Subject: [PATCH 2/3] Format --- src/coreclr/jit/importer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 137ffe4f1f524d..19cd8d3cd25674 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4141,8 +4141,9 @@ GenTree* Compiler::impImportStaticFieldAddress(CORINFO_RESOLVED_TOKEN* pResolved if (!isBoxedStatic && (lclTyp == TYP_REF) && ((access & CORINFO_ACCESS_GET) != 0) && ((*pIndirFlags & GTF_IND_VOLATILE) == 0)) { - bool isSpeculative = true; - CORINFO_CLASS_HANDLE classHandle = info.compCompHnd->getStaticFieldCurrentClass(pResolvedToken->hField, &isSpeculative); + bool isSpeculative = true; + CORINFO_CLASS_HANDLE classHandle = + info.compCompHnd->getStaticFieldCurrentClass(pResolvedToken->hField, &isSpeculative); if (classHandle != NO_CLASS_HANDLE) { isStaticReadOnlyInitedRef = !isSpeculative; From 4910178069350cb0351e6f4621204b9b83b9ca29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Tue, 12 Nov 2024 03:39:31 +0100 Subject: [PATCH 3/3] Revert change --- src/coreclr/jit/importer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 19cd8d3cd25674..876fc5f25691ed 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4181,7 +4181,7 @@ GenTree* Compiler::impImportStaticFieldAddress(CORINFO_RESOLVED_TOKEN* pResolved } if (isStaticReadOnlyInitedRef) { - indirFlags |= (GTF_IND_NONFAULTING | GTF_IND_INVARIANT | GTF_IND_NONNULL); + indirFlags |= (GTF_IND_INVARIANT | GTF_IND_NONNULL); } break; }