brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.8 KiB · 4d8fd14 Raw
83 lines · cpp
1//===- AArch64MachineScheduler.cpp - MI Scheduler for AArch64 -------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "AArch64MachineScheduler.h"10#include "AArch64InstrInfo.h"11#include "AArch64Subtarget.h"12#include "MCTargetDesc/AArch64MCTargetDesc.h"13 14using namespace llvm;15 16static bool needReorderStoreMI(const MachineInstr *MI) {17  if (!MI)18    return false;19 20  switch (MI->getOpcode()) {21  default:22    return false;23  case AArch64::STURQi:24  case AArch64::STRQui:25    if (!MI->getMF()->getSubtarget<AArch64Subtarget>().isStoreAddressAscend())26      return false;27    [[fallthrough]];28  case AArch64::STPQi:29    return AArch64InstrInfo::getLdStOffsetOp(*MI).isImm();30  }31 32  return false;33}34 35// Return true if two stores with same base address may overlap writes36static bool mayOverlapWrite(const MachineInstr &MI0, const MachineInstr &MI1,37                            int64_t &Off0, int64_t &Off1) {38  const MachineOperand &Base0 = AArch64InstrInfo::getLdStBaseOp(MI0);39  const MachineOperand &Base1 = AArch64InstrInfo::getLdStBaseOp(MI1);40 41  // May overlapping writes if two store instructions without same base42  if (!Base0.isIdenticalTo(Base1))43    return true;44 45  int StoreSize0 = AArch64InstrInfo::getMemScale(MI0);46  int StoreSize1 = AArch64InstrInfo::getMemScale(MI1);47  Off0 = AArch64InstrInfo::hasUnscaledLdStOffset(MI0.getOpcode())48             ? AArch64InstrInfo::getLdStOffsetOp(MI0).getImm()49             : AArch64InstrInfo::getLdStOffsetOp(MI0).getImm() * StoreSize0;50  Off1 = AArch64InstrInfo::hasUnscaledLdStOffset(MI1.getOpcode())51             ? AArch64InstrInfo::getLdStOffsetOp(MI1).getImm()52             : AArch64InstrInfo::getLdStOffsetOp(MI1).getImm() * StoreSize1;53 54  const MachineInstr &MI = (Off0 < Off1) ? MI0 : MI1;55  int Multiples = AArch64InstrInfo::isPairedLdSt(MI) ? 2 : 1;56  int StoreSize = AArch64InstrInfo::getMemScale(MI) * Multiples;57 58  return llabs(Off0 - Off1) < StoreSize;59}60 61bool AArch64PostRASchedStrategy::tryCandidate(SchedCandidate &Cand,62                                              SchedCandidate &TryCand) {63  bool OriginalResult = PostGenericScheduler::tryCandidate(Cand, TryCand);64 65  if (Cand.isValid()) {66    MachineInstr *Instr0 = TryCand.SU->getInstr();67    MachineInstr *Instr1 = Cand.SU->getInstr();68 69    if (!needReorderStoreMI(Instr0) || !needReorderStoreMI(Instr1))70      return OriginalResult;71 72    int64_t Off0, Off1;73    // With the same base address and non-overlapping writes.74    if (!mayOverlapWrite(*Instr0, *Instr1, Off0, Off1)) {75      TryCand.Reason = NodeOrder;76      // Order them by ascending offsets.77      return Off0 < Off1;78    }79  }80 81  return OriginalResult;82}83