From d123f2ea1697cab8d0fbf8ee62c298059e62946c Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 5 Apr 2023 22:23:11 -0700 Subject: [PATCH 1/4] Perform ldr to ldp peephole optimization --- src/coreclr/jit/emitarm64.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/jit/emitarm64.h b/src/coreclr/jit/emitarm64.h index 7c8fac3e772c35..319b45d6a11751 100644 --- a/src/coreclr/jit/emitarm64.h +++ b/src/coreclr/jit/emitarm64.h @@ -162,8 +162,7 @@ inline bool OptimizeLdrStr(instruction ins, // If the previous instruction was a matching load/store, then try to replace it instead of emitting. // Don't do this if either instruction had a local variable. - if ((emitLastIns->idIns() == ins) && !localVar && !emitLastIns->idIsLclVar() && - ReplaceLdrStrWithPairInstr(ins, reg1Attr, reg1, reg2, imm, size, fmt)) + if ((emitLastIns->idIns() == ins) && ((ins == INS_ldr) || (!localVar && !emitLastIns->idIsLclVar())) && ReplaceLdrStrWithPairInstr(ins, reg1Attr, reg1, reg2, imm, size, fmt)) { return true; } From ecf152749f79525f873ca874353318b043997bb4 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Thu, 6 Apr 2023 10:10:09 -0700 Subject: [PATCH 2/4] jit format --- src/coreclr/jit/emitarm64.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/emitarm64.h b/src/coreclr/jit/emitarm64.h index 319b45d6a11751..4d7926f2478096 100644 --- a/src/coreclr/jit/emitarm64.h +++ b/src/coreclr/jit/emitarm64.h @@ -162,7 +162,8 @@ inline bool OptimizeLdrStr(instruction ins, // If the previous instruction was a matching load/store, then try to replace it instead of emitting. // Don't do this if either instruction had a local variable. - if ((emitLastIns->idIns() == ins) && ((ins == INS_ldr) || (!localVar && !emitLastIns->idIsLclVar())) && ReplaceLdrStrWithPairInstr(ins, reg1Attr, reg1, reg2, imm, size, fmt)) + if ((emitLastIns->idIns() == ins) && ((ins == INS_ldr) || (!localVar && !emitLastIns->idIsLclVar())) && + ReplaceLdrStrWithPairInstr(ins, reg1Attr, reg1, reg2, imm, size, fmt)) { return true; } From 7c5541baf30b4a27e3bac5f92125791193d7de43 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 7 Apr 2023 15:19:17 -0700 Subject: [PATCH 3/4] handle non-gc str cases --- src/coreclr/jit/emitarm64.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/emitarm64.h b/src/coreclr/jit/emitarm64.h index 4d7926f2478096..095afde701eefc 100644 --- a/src/coreclr/jit/emitarm64.h +++ b/src/coreclr/jit/emitarm64.h @@ -146,7 +146,7 @@ inline bool OptimizeLdrStr(instruction ins, { assert(ins == INS_ldr || ins == INS_str); - if (!emitCanPeepholeLastIns()) + if (!emitCanPeepholeLastIns() || (emitLastIns->idIns() != ins)) { return false; } @@ -161,9 +161,18 @@ inline bool OptimizeLdrStr(instruction ins, reg2 = encodingZRtoSP(reg2); // If the previous instruction was a matching load/store, then try to replace it instead of emitting. - // Don't do this if either instruction had a local variable. - if ((emitLastIns->idIns() == ins) && ((ins == INS_ldr) || (!localVar && !emitLastIns->idIsLclVar())) && - ReplaceLdrStrWithPairInstr(ins, reg1Attr, reg1, reg2, imm, size, fmt)) + // + bool canReplaceWithPair = true; + if (ins == INS_str) + { + // For INS_str, don't do this if either instruction had a local GC variable. + if ((localVar && EA_IS_GCREF_OR_BYREF(reg1Attr)) || (emitLastIns->idIsLclVar() && (emitLastIns->idGCref() != GCT_NONE))) + { + canReplaceWithPair = false; + } + } + + if (canReplaceWithPair && ReplaceLdrStrWithPairInstr(ins, reg1Attr, reg1, reg2, imm, size, fmt)) { return true; } From d2fc334960f8205f28aa388702afa28a070a6260 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 7 Apr 2023 15:22:12 -0700 Subject: [PATCH 4/4] Add the comment --- src/coreclr/jit/emitarm64.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/emitarm64.h b/src/coreclr/jit/emitarm64.h index 095afde701eefc..ee0e029c84b68c 100644 --- a/src/coreclr/jit/emitarm64.h +++ b/src/coreclr/jit/emitarm64.h @@ -166,7 +166,10 @@ inline bool OptimizeLdrStr(instruction ins, if (ins == INS_str) { // For INS_str, don't do this if either instruction had a local GC variable. - if ((localVar && EA_IS_GCREF_OR_BYREF(reg1Attr)) || (emitLastIns->idIsLclVar() && (emitLastIns->idGCref() != GCT_NONE))) + // For INS_ldr, it is fine to perform this optimization because the output code already handles the code of + // updating the gc refs. We do not need offset tracking for load cases. + if ((localVar && EA_IS_GCREF_OR_BYREF(reg1Attr)) || + (emitLastIns->idIsLclVar() && (emitLastIns->idGCref() != GCT_NONE))) { canReplaceWithPair = false; }