From c8612b72575e68b8b898d0c5eca6c5a92c5773e1 Mon Sep 17 00:00:00 2001 From: William Chen Date: Tue, 27 Apr 2021 09:02:25 -0700 Subject: [PATCH] Add dependence edge for overlapping stack memory accesses --- .../include/cg/aarch64/aarch64_dependence.h | 4 +- .../include/cg/aarch64/aarch64_insn.h | 2 + .../include/cg/aarch64/aarch64_operand.h | 2 + src/mapleall/maple_be/include/cg/insn.h | 4 + src/mapleall/maple_be/include/cg/operand.h | 9 ++ .../src/cg/aarch64/aarch64_dependence.cpp | 11 ++- .../maple_be/src/cg/aarch64/aarch64_insn.cpp | 84 +++++++++++++++++++ .../src/cg/aarch64/aarch64_operand.cpp | 17 ++++ 8 files changed, 129 insertions(+), 4 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_dependence.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_dependence.h index 0470eece41..2c0c1766cf 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_dependence.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_dependence.h @@ -49,8 +49,8 @@ class AArch64DepAnalysis : public DepAnalysis { bool NeedBuildDepsMem(const AArch64MemOperand &memOpnd, const AArch64MemOperand *nextMemOpnd, Insn &memInsn) const; void BuildDepsUseMem(Insn &insn, MemOperand &memOpnd) override; void BuildDepsDefMem(Insn &insn, MemOperand &memOpnd) override; - void BuildAntiDepsDefStackMem(Insn &insn, const AArch64MemOperand &memOpnd, const AArch64MemOperand *nextMemOpnd); - void BuildOutputDepsDefStackMem(Insn &insn, const AArch64MemOperand &memOpnd, const AArch64MemOperand *nextMemOpnd); + void BuildAntiDepsDefStackMem(Insn &insn, AArch64MemOperand &memOpnd, const AArch64MemOperand *nextMemOpnd); + void BuildOutputDepsDefStackMem(Insn &insn, AArch64MemOperand &memOpnd, const AArch64MemOperand *nextMemOpnd); void BuildDepsMemBar(Insn &insn) override; void BuildDepsSeparator(DepNode &newSepNode, MapleVector &nodes) override; void BuildDepsControlAll(DepNode &depNode, const MapleVector &nodes) override; diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h index a6d3512233..787d4d14ec 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h @@ -163,6 +163,8 @@ class AArch64Insn : public Insn { bool CheckRefField(size_t opndIndex, bool isEmit) const; + uint8 GetLoadStoreSize(); + private: void CheckOpnd(Operand &opnd, OpndProp &mopd) const; void EmitClinit(const CG&, Emitter&) const; diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h index 02f9a7e1f2..4aefac121f 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h @@ -739,6 +739,8 @@ class AArch64MemOperand : public MemOperand { bool NoAlias(AArch64MemOperand &rightOpnd) const; + bool NoOverlap(AArch64MemOperand &rightOpnd) const; + VaryType GetMemVaryType() override { Operand *ofstOpnd = GetOffsetOperand(); if (ofstOpnd != nullptr) { diff --git a/src/mapleall/maple_be/include/cg/insn.h b/src/mapleall/maple_be/include/cg/insn.h index 50f24668f5..2a17b56f26 100644 --- a/src/mapleall/maple_be/include/cg/insn.h +++ b/src/mapleall/maple_be/include/cg/insn.h @@ -285,6 +285,10 @@ class Insn { return false; } + virtual bool NoOverlap() const { + return false; + } + virtual bool IsVolatile() const { return false; } diff --git a/src/mapleall/maple_be/include/cg/operand.h b/src/mapleall/maple_be/include/cg/operand.h index 5c9e47337f..bbe9efc4e3 100644 --- a/src/mapleall/maple_be/include/cg/operand.h +++ b/src/mapleall/maple_be/include/cg/operand.h @@ -555,6 +555,14 @@ class MemOperand : public Operand { return kNotVary; } + void SetAccessSize(uint8 size) { + accessSize = size; + } + + const uint8 GetAccessSize() const { + return accessSize; + } + bool Less(const Operand &right) const override = 0; MemOperand(uint32 size, const MIRSymbol &mirSymbol) @@ -591,6 +599,7 @@ class MemOperand : public Operand { Operand *scaleOpnd = nullptr; const MIRSymbol *symbol; /* AddrMode_Literal */ uint32 memoryOrder = 0; + uint8 accessSize = 0; /* temp, must be set right before use everytime. */ }; class LabelOperand : public Operand { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_dependence.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_dependence.cpp index b4e38bf683..d14cec8513 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_dependence.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_dependence.cpp @@ -408,6 +408,7 @@ void AArch64DepAnalysis::BuildDepsUseMem(Insn &insn, MemOperand &memOpnd) { AArch64MemOperand &aarchMemOpnd = static_cast(memOpnd); AArch64MemOperand *nextMemOpnd = GetNextMemOperand(insn, aarchMemOpnd); + memOpnd.SetAccessSize(static_cast(insn).GetLoadStoreSize()); /* Stack memory address */ for (auto defInsn : stackDefs) { if (defInsn->IsCall() || NeedBuildDepsMem(aarchMemOpnd, nextMemOpnd, *defInsn)) { @@ -434,6 +435,10 @@ bool AArch64DepAnalysis::NeedBuildDepsMem(const AArch64MemOperand &memOpnd, cons if (!memOpnd.NoAlias(*memOpndOfmemInsn) || ((nextMemOpnd != nullptr) && !nextMemOpnd->NoAlias(*memOpndOfmemInsn))) { return true; } + if (cgFunc.GetMirModule().GetSrcLang() == kSrcLangC && memInsn.IsCall() == false) { + static_cast(memInsn.GetMemOpnd())->SetAccessSize(static_cast(memInsn).GetLoadStoreSize()); + return (memOpnd.NoOverlap(*memOpndOfmemInsn) == false); + } AArch64MemOperand *nextMemOpndOfmemInsn = GetNextMemOperand(memInsn, *memOpndOfmemInsn); if (nextMemOpndOfmemInsn != nullptr) { if (!memOpnd.NoAlias(*nextMemOpndOfmemInsn) || @@ -450,8 +455,9 @@ bool AArch64DepAnalysis::NeedBuildDepsMem(const AArch64MemOperand &memOpnd, cons * memOpnd : insn's memOpnd * nextMemOpnd : some memory pair operator instruction (like ldp/stp) defines two memory. */ -void AArch64DepAnalysis::BuildAntiDepsDefStackMem(Insn &insn, const AArch64MemOperand &memOpnd, +void AArch64DepAnalysis::BuildAntiDepsDefStackMem(Insn &insn, AArch64MemOperand &memOpnd, const AArch64MemOperand *nextMemOpnd) { + memOpnd.SetAccessSize(static_cast(insn).GetLoadStoreSize()); for (auto *useInsn : stackUses) { if (NeedBuildDepsMem(memOpnd, nextMemOpnd, *useInsn)) { AddDependence(*useInsn->GetDepNode(), *insn.GetDepNode(), kDependenceTypeAnti); @@ -465,8 +471,9 @@ void AArch64DepAnalysis::BuildAntiDepsDefStackMem(Insn &insn, const AArch64MemOp * memOpnd : insn's memOpnd * nextMemOpnd : some memory pair operator instruction (like ldp/stp) defines two memory. */ -void AArch64DepAnalysis::BuildOutputDepsDefStackMem(Insn &insn, const AArch64MemOperand &memOpnd, +void AArch64DepAnalysis::BuildOutputDepsDefStackMem(Insn &insn, AArch64MemOperand &memOpnd, const AArch64MemOperand *nextMemOpnd) { + memOpnd.SetAccessSize(static_cast(insn).GetLoadStoreSize()); for (auto defInsn : stackDefs) { if (defInsn->IsCall() || NeedBuildDepsMem(memOpnd, nextMemOpnd, *defInsn)) { AddDependence(*defInsn->GetDepNode(), *insn.GetDepNode(), kDependenceTypeOutput); diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp index 7488ed7a7c..a0de344123 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp @@ -1129,6 +1129,90 @@ bool AArch64Insn::CheckRefField(size_t opndIndex, bool isEmit) const { return false; } +uint8 AArch64Insn::GetLoadStoreSize() { + if (IsLoadStorePair()) { + return k16ByteSize; + } + /* These are the loads and stores possible from PickLdStInsn() */ + switch (mOp) { + case MOP_wldrb: + return k1ByteSize; + case MOP_wldrh: + return k2ByteSize; + + case MOP_wldrsb: + return k1ByteSize; + case MOP_wldrsh: + return k2ByteSize; + case MOP_wldr: + return k4ByteSize; + case MOP_xldr: + return k8ByteSize; + + case MOP_wstrb: + return k1ByteSize; + case MOP_wstrh: + return k2ByteSize; + case MOP_wstr: + return k4ByteSize; + case MOP_xstr: + return k8ByteSize; + + case MOP_wldarb: + return k1ByteSize; + case MOP_wldarh: + return k2ByteSize; + case MOP_wldar: + return k4ByteSize; + case MOP_xldar: + return k8ByteSize; + + case MOP_wstlrb: + return k1ByteSize; + case MOP_wstlrh: + return k2ByteSize; + case MOP_wstlr: + return k4ByteSize; + case MOP_xstlr: + return k8ByteSize; + + case MOP_sldr: + return k4ByteSize; + case MOP_dldr: + return k8ByteSize; + + case MOP_sstr: + return k4ByteSize; + case MOP_dstr: + return k8ByteSize; + + case MOP_wldp: + return k8ByteSize; + case MOP_xldp: + return k16ByteSize; + case MOP_xldpsw: + return k16ByteSize; + + case MOP_sldp: + return k8ByteSize; + case MOP_dldp: + return k16ByteSize; + + case MOP_wstp: + return k8ByteSize; + case MOP_xstp: + return k16ByteSize; + + case MOP_sstp: + return k8ByteSize; + case MOP_dstp: + return k16ByteSize; + + default: + CHECK_FATAL(false, "Unsupported load/store op"); + } +} + Operand *AArch64Insn::GetResult(uint32 id) const { ASSERT(id < GetResultNum(), "index out of range"); const AArch64MD *md = &AArch64CG::kMd[mOp]; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp index ed22795ad9..8b9d23d6fc 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp @@ -490,6 +490,23 @@ bool AArch64MemOperand::NoAlias(AArch64MemOperand &rightOpnd) const { return false; } +bool AArch64MemOperand::NoOverlap(AArch64MemOperand &rightOpnd) const { + if (addrMode != kAddrModeBOi || rightOpnd.addrMode != kAddrModeBOi || idxOpt != kIntact || + rightOpnd.idxOpt != kIntact) { + return false; + } + if (GetBaseRegister()->GetRegisterNumber() != RFP || rightOpnd.GetBaseRegister()->GetRegisterNumber() != RFP) { + return false; + } + int64 ofset1 = GetOffsetOperand()->GetValue(); + int64 ofset2 = rightOpnd.GetOffsetOperand()->GetValue(); + if (ofset1 < ofset2) { + return ((ofset1 + GetAccessSize()) <= ofset2); + } else { + return ((ofset2 + rightOpnd.GetAccessSize()) <= ofset1); + } +} + /* sort the register operand according to their number */ void AArch64ListOperand::Emit(Emitter &emitter, const OpndProp *opndProp) const { (void)opndProp; -- Gitee