From ba834699c89a838859e9f07aae37dc4f4bd589c5 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Fri, 12 May 2017 15:38:56 -0400 Subject: [PATCH] [Arm64] Use Load Acquire when practical for genCodeForIndir Commit migrated from https://github.com/dotnet/coreclr/commit/0d8bba38b3a74314c19164661eac641815eba68f --- src/coreclr/src/jit/codegenarmarch.cpp | 52 ++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp index 37b9026..9b83a65 100644 --- a/src/coreclr/src/jit/codegenarmarch.cpp +++ b/src/coreclr/src/jit/codegenarmarch.cpp @@ -1333,24 +1333,60 @@ void CodeGen::genCodeForIndir(GenTreeIndir* tree) { assert(tree->OperIs(GT_IND)); - var_types targetType = tree->TypeGet(); - regNumber targetReg = tree->gtRegNum; - emitter* emit = getEmitter(); + var_types targetType = tree->TypeGet(); + regNumber targetReg = tree->gtRegNum; + emitter* emit = getEmitter(); + emitAttr attr = emitTypeSize(tree); + instruction ins = ins_Load(targetType); genConsumeAddress(tree->Addr()); - emit->emitInsLoadStoreOp(ins_Load(targetType), emitTypeSize(tree), targetReg, tree); - genProduceReg(tree); - if (tree->gtFlags & GTF_IND_VOLATILE) { #ifdef _TARGET_ARM64_ - // issue a INS_BARRIER_LD after a volatile LdInd operation - instGen_MemoryBarrier(INS_BARRIER_LD); + GenTree* addr = tree->Addr(); + bool useLoadAcquire = (targetReg >= REG_INT_FIRST) && (targetReg <= REG_ZR) && !addr->isContained() && + varTypeIsUnsigned(targetType) && + ((attr == EA_1BYTE) || !(tree->gtFlags & GTF_IND_UNALIGNED)); + + if (useLoadAcquire) + { + switch (EA_SIZE(attr)) + { + case EA_1BYTE: + assert(ins == INS_ldrb); + ins = INS_ldarb; + break; + case EA_2BYTE: + assert(ins == INS_ldrh); + ins = INS_ldarh; + break; + case EA_4BYTE: + case EA_8BYTE: + assert(ins == INS_ldr); + ins = INS_ldar; + break; + default: + assert(false); // We should not get here + } + } + + emit->emitInsLoadStoreOp(ins, attr, targetReg, tree); + + if (!useLoadAcquire) // issue a INS_BARRIER_OSHLD after a volatile LdInd operation + instGen_MemoryBarrier(INS_BARRIER_OSHLD); #else + emit->emitInsLoadStoreOp(ins, attr, targetReg, tree); + // issue a full memory barrier after a volatile LdInd operation instGen_MemoryBarrier(); #endif // _TARGET_ARM64_ } + else + { + emit->emitInsLoadStoreOp(ins, attr, targetReg, tree); + } + + genProduceReg(tree); } // Generate code for a CpBlk node by the means of the VM memcpy helper call -- 2.7.4