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 0470eece41dd53a3fdb55195c6c1868406d3d20b..2c0c1766cff697ed4a44ef3f67b45b5683d2a123 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 a6d3512233a787c549f23a843b22fb22344ac4ae..787d4d14ec0abb2e586b51cf5e50159ef979222d 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 02f9a7e1f28b2e635f77f4c9b99c6b100ef5e07c..4aefac121fefb086dcd55a622de41a161aabe658 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 50f24668f5f06f0449981385ebbf93c940a70ac2..2a17b56f268cdabeecd52e02b4f8ac7f7cd019b2 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 5c9e47337f4dc36ec47fd467b6c05662e30df83e..bbe9efc4e31ea277ef3dfd6725220e0c65758834 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 b4e38bf6834bd6b40a407d682af8747298411d71..d14cec8513b56379f14331c0e03353e375fc3034 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 7488ed7a7c6d3e45b5521561960d197767843095..a0de3441239d3bdfb34f41f97f5c51a65ff1dcae 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 ed22795ad93ec655c8dd085b806cdf27fd0849f5..8b9d23d6fcf958badd8301d085649f575517377c 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;