1 //===- PPCMachineScheduler.cpp - MI Scheduler for PowerPC -------------===//
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 "PPCMachineScheduler.h"
10 #include "MCTargetDesc/PPCMCTargetDesc.h"
11
12 using namespace llvm;
13
14 static cl::opt<bool>
15 DisableAddiLoadHeuristic("disable-ppc-sched-addi-load",
16 cl::desc("Disable scheduling addi instruction before"
17 "load for ppc"), cl::Hidden);
18
biasAddiLoadCandidate(SchedCandidate & Cand,SchedCandidate & TryCand,SchedBoundary & Zone) const19 bool PPCPreRASchedStrategy::biasAddiLoadCandidate(SchedCandidate &Cand,
20 SchedCandidate &TryCand,
21 SchedBoundary &Zone) const {
22 if (DisableAddiLoadHeuristic)
23 return false;
24
25 auto isADDIInstr = [&] (const MachineInstr &Inst) {
26 return Inst.getOpcode() == PPC::ADDI || Inst.getOpcode() == PPC::ADDI8;
27 };
28
29 SchedCandidate &FirstCand = Zone.isTop() ? TryCand : Cand;
30 SchedCandidate &SecondCand = Zone.isTop() ? Cand : TryCand;
31 if (isADDIInstr(*FirstCand.SU->getInstr()) &&
32 SecondCand.SU->getInstr()->mayLoad()) {
33 TryCand.Reason = Stall;
34 return true;
35 }
36 if (FirstCand.SU->getInstr()->mayLoad() &&
37 isADDIInstr(*SecondCand.SU->getInstr())) {
38 TryCand.Reason = NoCand;
39 return true;
40 }
41
42 return false;
43 }
44
tryCandidate(SchedCandidate & Cand,SchedCandidate & TryCand,SchedBoundary * Zone) const45 void PPCPreRASchedStrategy::tryCandidate(SchedCandidate &Cand,
46 SchedCandidate &TryCand,
47 SchedBoundary *Zone) const {
48 GenericScheduler::tryCandidate(Cand, TryCand, Zone);
49
50 if (!Cand.isValid() || !Zone)
51 return;
52
53 // Add powerpc specific heuristic only when TryCand isn't selected or
54 // selected as node order.
55 if (TryCand.Reason != NodeOrder && TryCand.Reason != NoCand)
56 return;
57
58 // There are some benefits to schedule the ADDI before the load to hide the
59 // latency, as RA may create a true dependency between the load and addi.
60 if (biasAddiLoadCandidate(Cand, TryCand, *Zone))
61 return;
62 }
63
enterMBB(MachineBasicBlock * MBB)64 void PPCPostRASchedStrategy::enterMBB(MachineBasicBlock *MBB) {
65 // Custom PPC PostRA specific behavior here.
66 PostGenericScheduler::enterMBB(MBB);
67 }
68
leaveMBB()69 void PPCPostRASchedStrategy::leaveMBB() {
70 // Custom PPC PostRA specific behavior here.
71 PostGenericScheduler::leaveMBB();
72 }
73
initialize(ScheduleDAGMI * Dag)74 void PPCPostRASchedStrategy::initialize(ScheduleDAGMI *Dag) {
75 // Custom PPC PostRA specific initialization here.
76 PostGenericScheduler::initialize(Dag);
77 }
78
pickNode(bool & IsTopNode)79 SUnit *PPCPostRASchedStrategy::pickNode(bool &IsTopNode) {
80 // Custom PPC PostRA specific scheduling here.
81 return PostGenericScheduler::pickNode(IsTopNode);
82 }
83
84