Path: blob/main/contrib/llvm-project/llvm/lib/Target/AArch64/AArch64MachineScheduler.cpp
35269 views
//===- AArch64MachineScheduler.cpp - MI Scheduler for AArch64 -------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "AArch64MachineScheduler.h"9#include "AArch64InstrInfo.h"10#include "AArch64Subtarget.h"11#include "MCTargetDesc/AArch64MCTargetDesc.h"1213using namespace llvm;1415static bool needReorderStoreMI(const MachineInstr *MI) {16if (!MI)17return false;1819switch (MI->getOpcode()) {20default:21return false;22case AArch64::STURQi:23case AArch64::STRQui:24if (!MI->getMF()->getSubtarget<AArch64Subtarget>().isStoreAddressAscend())25return false;26[[fallthrough]];27case AArch64::STPQi:28return AArch64InstrInfo::getLdStOffsetOp(*MI).isImm();29}3031return false;32}3334// Return true if two stores with same base address may overlap writes35static bool mayOverlapWrite(const MachineInstr &MI0, const MachineInstr &MI1,36int64_t &Off0, int64_t &Off1) {37const MachineOperand &Base0 = AArch64InstrInfo::getLdStBaseOp(MI0);38const MachineOperand &Base1 = AArch64InstrInfo::getLdStBaseOp(MI1);3940// May overlapping writes if two store instructions without same base41if (!Base0.isIdenticalTo(Base1))42return true;4344int StoreSize0 = AArch64InstrInfo::getMemScale(MI0);45int StoreSize1 = AArch64InstrInfo::getMemScale(MI1);46Off0 = AArch64InstrInfo::hasUnscaledLdStOffset(MI0.getOpcode())47? AArch64InstrInfo::getLdStOffsetOp(MI0).getImm()48: AArch64InstrInfo::getLdStOffsetOp(MI0).getImm() * StoreSize0;49Off1 = AArch64InstrInfo::hasUnscaledLdStOffset(MI1.getOpcode())50? AArch64InstrInfo::getLdStOffsetOp(MI1).getImm()51: AArch64InstrInfo::getLdStOffsetOp(MI1).getImm() * StoreSize1;5253const MachineInstr &MI = (Off0 < Off1) ? MI0 : MI1;54int Multiples = AArch64InstrInfo::isPairedLdSt(MI) ? 2 : 1;55int StoreSize = AArch64InstrInfo::getMemScale(MI) * Multiples;5657return llabs(Off0 - Off1) < StoreSize;58}5960bool AArch64PostRASchedStrategy::tryCandidate(SchedCandidate &Cand,61SchedCandidate &TryCand) {62bool OriginalResult = PostGenericScheduler::tryCandidate(Cand, TryCand);6364if (Cand.isValid()) {65MachineInstr *Instr0 = TryCand.SU->getInstr();66MachineInstr *Instr1 = Cand.SU->getInstr();6768if (!needReorderStoreMI(Instr0) || !needReorderStoreMI(Instr1))69return OriginalResult;7071int64_t Off0, Off1;72// With the same base address and non-overlapping writes.73if (!mayOverlapWrite(*Instr0, *Instr1, Off0, Off1)) {74TryCand.Reason = NodeOrder;75// Order them by ascending offsets.76return Off0 < Off1;77}78}7980return OriginalResult;81}828384