1572fc7d2SAndre Vieira //===- AArch64MachineScheduler.cpp - MI Scheduler for AArch64 -------------===// 2572fc7d2SAndre Vieira // 3572fc7d2SAndre Vieira // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4572fc7d2SAndre Vieira // See https://llvm.org/LICENSE.txt for license information. 5572fc7d2SAndre Vieira // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6572fc7d2SAndre Vieira // 7572fc7d2SAndre Vieira //===----------------------------------------------------------------------===// 8572fc7d2SAndre Vieira 9572fc7d2SAndre Vieira #include "AArch64MachineScheduler.h" 10c42a2255Szhongyunde #include "AArch64InstrInfo.h" 11c42a2255Szhongyunde #include "AArch64Subtarget.h" 12572fc7d2SAndre Vieira #include "MCTargetDesc/AArch64MCTargetDesc.h" 13572fc7d2SAndre Vieira 14572fc7d2SAndre Vieira using namespace llvm; 15572fc7d2SAndre Vieira 16c42a2255Szhongyunde static bool needReorderStoreMI(const MachineInstr *MI) { 17c42a2255Szhongyunde if (!MI) 18c42a2255Szhongyunde return false; 19c42a2255Szhongyunde 20c42a2255Szhongyunde switch (MI->getOpcode()) { 21c42a2255Szhongyunde default: 22c42a2255Szhongyunde return false; 23c42a2255Szhongyunde case AArch64::STURQi: 24c42a2255Szhongyunde case AArch64::STRQui: 25c42a2255Szhongyunde if (MI->getMF()->getSubtarget<AArch64Subtarget>().isStoreAddressAscend()) 26c42a2255Szhongyunde return false; 27c42a2255Szhongyunde LLVM_FALLTHROUGH; 28c42a2255Szhongyunde case AArch64::STPQi: 29*0cb33551Szhongyunde return AArch64InstrInfo::getLdStOffsetOp(*MI).isImm(); 30c42a2255Szhongyunde } 31c42a2255Szhongyunde 32c42a2255Szhongyunde return false; 33c42a2255Szhongyunde } 34c42a2255Szhongyunde 35c42a2255Szhongyunde // Return true if two stores with same base address may overlap writes 36c42a2255Szhongyunde static bool mayOverlapWrite(const MachineInstr &MI0, const MachineInstr &MI1, 37c42a2255Szhongyunde int64_t &Off0, int64_t &Off1) { 38c42a2255Szhongyunde const MachineOperand &Base0 = AArch64InstrInfo::getLdStBaseOp(MI0); 39c42a2255Szhongyunde const MachineOperand &Base1 = AArch64InstrInfo::getLdStBaseOp(MI1); 40c42a2255Szhongyunde 41c42a2255Szhongyunde // May overlapping writes if two store instructions without same base 42c42a2255Szhongyunde if (!Base0.isIdenticalTo(Base1)) 43c42a2255Szhongyunde return true; 44c42a2255Szhongyunde 45c42a2255Szhongyunde int StoreSize0 = AArch64InstrInfo::getMemScale(MI0); 46c42a2255Szhongyunde int StoreSize1 = AArch64InstrInfo::getMemScale(MI1); 47c42a2255Szhongyunde Off0 = AArch64InstrInfo::hasUnscaledLdStOffset(MI0.getOpcode()) 48c42a2255Szhongyunde ? AArch64InstrInfo::getLdStOffsetOp(MI0).getImm() 49c42a2255Szhongyunde : AArch64InstrInfo::getLdStOffsetOp(MI0).getImm() * StoreSize0; 50c42a2255Szhongyunde Off1 = AArch64InstrInfo::hasUnscaledLdStOffset(MI1.getOpcode()) 51c42a2255Szhongyunde ? AArch64InstrInfo::getLdStOffsetOp(MI1).getImm() 52c42a2255Szhongyunde : AArch64InstrInfo::getLdStOffsetOp(MI1).getImm() * StoreSize1; 53c42a2255Szhongyunde 54c42a2255Szhongyunde const MachineInstr &MI = (Off0 < Off1) ? MI0 : MI1; 55c42a2255Szhongyunde int Multiples = AArch64InstrInfo::isPairedLdSt(MI) ? 2 : 1; 56c42a2255Szhongyunde int StoreSize = AArch64InstrInfo::getMemScale(MI) * Multiples; 57c42a2255Szhongyunde 58c42a2255Szhongyunde return llabs(Off0 - Off1) < StoreSize; 59c42a2255Szhongyunde } 60c42a2255Szhongyunde 61572fc7d2SAndre Vieira bool AArch64PostRASchedStrategy::tryCandidate(SchedCandidate &Cand, 62572fc7d2SAndre Vieira SchedCandidate &TryCand) { 63572fc7d2SAndre Vieira bool OriginalResult = PostGenericScheduler::tryCandidate(Cand, TryCand); 64572fc7d2SAndre Vieira 65572fc7d2SAndre Vieira if (Cand.isValid()) { 66572fc7d2SAndre Vieira MachineInstr *Instr0 = TryCand.SU->getInstr(); 67572fc7d2SAndre Vieira MachineInstr *Instr1 = Cand.SU->getInstr(); 68c42a2255Szhongyunde 69c42a2255Szhongyunde if (!needReorderStoreMI(Instr0) || !needReorderStoreMI(Instr1)) 70c42a2255Szhongyunde return OriginalResult; 71c42a2255Szhongyunde 72c42a2255Szhongyunde int64_t Off0, Off1; 73572fc7d2SAndre Vieira // With the same base address and non-overlapping writes. 74c42a2255Szhongyunde if (!mayOverlapWrite(*Instr0, *Instr1, Off0, Off1)) { 75572fc7d2SAndre Vieira TryCand.Reason = NodeOrder; 76572fc7d2SAndre Vieira // Order them by ascending offsets. 77572fc7d2SAndre Vieira return Off0 < Off1; 78572fc7d2SAndre Vieira } 79572fc7d2SAndre Vieira } 80572fc7d2SAndre Vieira 81572fc7d2SAndre Vieira return OriginalResult; 82572fc7d2SAndre Vieira } 83