未验证 提交 5409d71a 编写于 作者: E Egor Bogatov 提交者: GitHub

ARM64: Avoid LEA for volatile IND (#64354)

Co-authored-by: NKunal Pathak <Kunal.Pathak@microsoft.com>
上级 bd84729d
......@@ -4891,20 +4891,29 @@ bool Lowering::AreSourcesPossiblyModifiedLocals(GenTree* addr, GenTree* base, Ge
// addressing mode and transform them to a GT_LEA
//
// Arguments:
// use - the use of the address we want to transform
// addr - the use of the address we want to transform
// isContainable - true if this addressing mode can be contained
// targetType - on arm we can use "scale" only for appropriate target type
// parent - the node that consumes the given addr (most likely it's an IND)
//
// Returns:
// true if the address node was changed to a LEA, false otherwise.
//
bool Lowering::TryCreateAddrMode(GenTree* addr, bool isContainable, var_types targetType)
bool Lowering::TryCreateAddrMode(GenTree* addr, bool isContainable, GenTree* parent)
{
if (!addr->OperIs(GT_ADD) || addr->gtOverflow())
{
return false;
}
#ifdef TARGET_ARM64
if (parent->OperIsIndir() && parent->AsIndir()->IsVolatile())
{
// For Arm64 we avoid using LEA for volatile INDs
// because we won't be able to use ldar/star
return false;
}
#endif
GenTree* base = nullptr;
GenTree* index = nullptr;
unsigned scale = 0;
......@@ -4920,6 +4929,8 @@ bool Lowering::TryCreateAddrMode(GenTree* addr, bool isContainable, var_types ta
&scale, // scaling
&offset); // displacement
var_types targetType = parent->OperIsIndir() ? parent->TypeGet() : TYP_UNDEF;
#ifdef TARGET_ARMARCH
// Multiplier should be a "natural-scale" power of two number which is equal to target's width.
//
......@@ -5109,7 +5120,7 @@ GenTree* Lowering::LowerAdd(GenTreeOp* node)
GenTree* parent = use.User();
if (!parent->OperIsIndir() && !parent->OperIs(GT_ADD))
{
TryCreateAddrMode(node, false);
TryCreateAddrMode(node, false, parent);
}
}
#endif // !TARGET_ARMARCH
......@@ -6778,7 +6789,7 @@ void Lowering::ContainCheckBitCast(GenTree* node)
void Lowering::LowerStoreIndirCommon(GenTreeStoreInd* ind)
{
assert(ind->TypeGet() != TYP_STRUCT);
TryCreateAddrMode(ind->Addr(), true, ind->TypeGet());
TryCreateAddrMode(ind->Addr(), true, ind);
if (!comp->codeGen->gcInfo.gcIsWriteBarrierStoreIndNode(ind))
{
if (varTypeIsFloating(ind) && ind->Data()->IsCnsFltOrDbl())
......@@ -6846,7 +6857,7 @@ void Lowering::LowerIndir(GenTreeIndir* ind)
// TODO-Cleanup: We're passing isContainable = true but ContainCheckIndir rejects
// address containment in some cases so we end up creating trivial (reg + offfset)
// or (reg + reg) LEAs that are not necessary.
TryCreateAddrMode(ind->Addr(), true, ind->TypeGet());
TryCreateAddrMode(ind->Addr(), true, ind);
ContainCheckIndir(ind);
if (ind->OperIs(GT_NULLCHECK) || ind->IsUnusedValue())
......@@ -6859,7 +6870,7 @@ void Lowering::LowerIndir(GenTreeIndir* ind)
// If the `ADDR` node under `STORE_OBJ(dstAddr, IND(struct(ADDR))`
// is a complex one it could benefit from an `LEA` that is not contained.
const bool isContainable = false;
TryCreateAddrMode(ind->Addr(), isContainable, ind->TypeGet());
TryCreateAddrMode(ind->Addr(), isContainable, ind);
}
}
......
......@@ -307,7 +307,7 @@ private:
void ContainBlockStoreAddress(GenTreeBlk* blkNode, unsigned size, GenTree* addr);
void LowerPutArgStk(GenTreePutArgStk* tree);
bool TryCreateAddrMode(GenTree* addr, bool isContainable, var_types targetType = TYP_UNDEF);
bool TryCreateAddrMode(GenTree* addr, bool isContainable, GenTree* parent);
bool TryTransformStoreObjAsStoreInd(GenTreeBlk* blkNode);
......
......@@ -194,7 +194,7 @@ GenTree* Lowering::LowerBinaryArithmetic(GenTreeOp* binOp)
//
void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
{
TryCreateAddrMode(blkNode->Addr(), false);
TryCreateAddrMode(blkNode->Addr(), false, blkNode);
GenTree* dstAddr = blkNode->Addr();
GenTree* src = blkNode->Data();
......@@ -408,7 +408,7 @@ void Lowering::ContainBlockStoreAddress(GenTreeBlk* blkNode, unsigned size, GenT
return;
}
if (!addr->OperIsAddrMode() && !TryCreateAddrMode(addr, true))
if (!addr->OperIsAddrMode() && !TryCreateAddrMode(addr, true, blkNode))
{
return;
}
......@@ -5799,7 +5799,7 @@ bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode
void Lowering::ContainCheckHWIntrinsicAddr(GenTreeHWIntrinsic* node, GenTree* addr)
{
assert((addr->TypeGet() == TYP_I_IMPL) || (addr->TypeGet() == TYP_BYREF));
TryCreateAddrMode(addr, true);
TryCreateAddrMode(addr, true, node);
if ((addr->OperIs(GT_CLS_VAR_ADDR, GT_LCL_VAR_ADDR, GT_LCL_FLD_ADDR, GT_LEA) ||
(addr->IsCnsIntOrI() && addr->AsIntConCommon()->FitsInAddrBase(comp))) &&
IsSafeToContainMem(node, addr))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册