Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/AArch64/AArch64MachineScheduler.cpp
35269 views
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
9
#include "AArch64MachineScheduler.h"
10
#include "AArch64InstrInfo.h"
11
#include "AArch64Subtarget.h"
12
#include "MCTargetDesc/AArch64MCTargetDesc.h"
13
14
using namespace llvm;
15
16
static 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 writes
36
static 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 base
42
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
61
bool 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
84