LLVM 22.0.0git
AArch64MachineScheduler.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "AArch64InstrInfo.h"
11#include "AArch64Subtarget.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:
30 }
31
32 return false;
33}
34
35// Return true if two stores with same base address may overlap writes
36static bool mayOverlapWrite(const MachineInstr &MI0, const MachineInstr &MI1,
37 int64_t &Off0, int64_t &Off1) {
40
41 // May overlapping writes if two store instructions without same base
42 if (!Base0.isIdenticalTo(Base1))
43 return true;
44
45 int StoreSize0 = AArch64InstrInfo::getMemScale(MI0);
46 int StoreSize1 = AArch64InstrInfo::getMemScale(MI1);
49 : AArch64InstrInfo::getLdStOffsetOp(MI0).getImm() * StoreSize0;
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
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}
static bool mayOverlapWrite(const MachineInstr &MI0, const MachineInstr &MI1, int64_t &Off0, int64_t &Off1)
static bool needReorderStoreMI(const MachineInstr *MI)
IRTranslator LLVM IR MI
static const MachineOperand & getLdStOffsetOp(const MachineInstr &MI)
Returns the immediate offset operator of a load/store.
static bool hasUnscaledLdStOffset(unsigned Opc)
Return true if it has an unscaled load/store offset.
static bool isPairedLdSt(const MachineInstr &MI)
Returns whether the instruction is a paired load/store.
static int getMemScale(unsigned Opc)
Scaling factor for (scaled or unscaled) load or store.
static const MachineOperand & getLdStBaseOp(const MachineInstr &MI)
Returns the base register operator of a load/store.
bool tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand) override
Apply a set of heuristics to a new candidate for PostRA scheduling.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
virtual bool tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand)
Apply a set of heuristics to a new candidate for PostRA scheduling.
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
This is an optimization pass for GlobalISel generic memory operations.
Store the state used by GenericScheduler heuristics, required for the lifetime of one invocation of p...