15321dcd6SQingShan Zhang //===- PPCMachineScheduler.cpp - MI Scheduler for PowerPC -------------===//
25321dcd6SQingShan Zhang //
35321dcd6SQingShan Zhang // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45321dcd6SQingShan Zhang // See https://llvm.org/LICENSE.txt for license information.
55321dcd6SQingShan Zhang // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65321dcd6SQingShan Zhang //
75321dcd6SQingShan Zhang //===----------------------------------------------------------------------===//
8*449bfdd1SQingShan Zhang #include "PPC.h"
95321dcd6SQingShan Zhang #include "PPCMachineScheduler.h"
105321dcd6SQingShan Zhang using namespace llvm;
115321dcd6SQingShan Zhang 
12*449bfdd1SQingShan Zhang static cl::opt<bool>
13*449bfdd1SQingShan Zhang DisableAddiLoadHeuristic("disable-ppc-sched-addi-load",
14*449bfdd1SQingShan Zhang                          cl::desc("Disable scheduling addi instruction before"
15*449bfdd1SQingShan Zhang                                   "load for ppc"), cl::Hidden);
16*449bfdd1SQingShan Zhang 
17*449bfdd1SQingShan Zhang bool PPCPreRASchedStrategy::biasAddiLoadCandidate(SchedCandidate &Cand,
18*449bfdd1SQingShan Zhang                                                   SchedCandidate &TryCand,
19*449bfdd1SQingShan Zhang                                                   SchedBoundary &Zone) const {
20*449bfdd1SQingShan Zhang   if (DisableAddiLoadHeuristic)
21*449bfdd1SQingShan Zhang     return false;
22*449bfdd1SQingShan Zhang 
23*449bfdd1SQingShan Zhang   auto isADDIInstr = [&] (const MachineInstr &Inst) {
24*449bfdd1SQingShan Zhang     return Inst.getOpcode() == PPC::ADDI || Inst.getOpcode() == PPC::ADDI8;
25*449bfdd1SQingShan Zhang   };
26*449bfdd1SQingShan Zhang 
27*449bfdd1SQingShan Zhang   SchedCandidate &FirstCand = Zone.isTop() ? TryCand : Cand;
28*449bfdd1SQingShan Zhang   SchedCandidate &SecondCand = Zone.isTop() ? Cand : TryCand;
29*449bfdd1SQingShan Zhang   if (isADDIInstr(*FirstCand.SU->getInstr()) &&
30*449bfdd1SQingShan Zhang       SecondCand.SU->getInstr()->mayLoad()) {
31*449bfdd1SQingShan Zhang     TryCand.Reason = Stall;
32*449bfdd1SQingShan Zhang     return true;
33*449bfdd1SQingShan Zhang   }
34*449bfdd1SQingShan Zhang   if (FirstCand.SU->getInstr()->mayLoad() &&
35*449bfdd1SQingShan Zhang       isADDIInstr(*SecondCand.SU->getInstr())) {
36*449bfdd1SQingShan Zhang     TryCand.Reason = NoCand;
37*449bfdd1SQingShan Zhang     return true;
38*449bfdd1SQingShan Zhang   }
39*449bfdd1SQingShan Zhang 
40*449bfdd1SQingShan Zhang   return false;
41*449bfdd1SQingShan Zhang }
42*449bfdd1SQingShan Zhang 
43*449bfdd1SQingShan Zhang void PPCPreRASchedStrategy::tryCandidate(SchedCandidate &Cand,
44*449bfdd1SQingShan Zhang                                          SchedCandidate &TryCand,
45*449bfdd1SQingShan Zhang                                          SchedBoundary *Zone) const {
46*449bfdd1SQingShan Zhang   GenericScheduler::tryCandidate(Cand, TryCand, Zone);
47*449bfdd1SQingShan Zhang 
48*449bfdd1SQingShan Zhang   if (!Cand.isValid() || !Zone)
49*449bfdd1SQingShan Zhang     return;
50*449bfdd1SQingShan Zhang 
51*449bfdd1SQingShan Zhang   // Add powerpc specific heuristic only when TryCand isn't selected or
52*449bfdd1SQingShan Zhang   // selected as node order.
53*449bfdd1SQingShan Zhang   if (TryCand.Reason != NodeOrder && TryCand.Reason != NoCand)
54*449bfdd1SQingShan Zhang     return;
55*449bfdd1SQingShan Zhang 
56*449bfdd1SQingShan Zhang   // There are some benefits to schedule the ADDI before the load to hide the
57*449bfdd1SQingShan Zhang   // latency, as RA may create a true dependency between the load and addi.
58*449bfdd1SQingShan Zhang   if (biasAddiLoadCandidate(Cand, TryCand, *Zone))
59*449bfdd1SQingShan Zhang     return;
60*449bfdd1SQingShan Zhang }
61*449bfdd1SQingShan Zhang 
625321dcd6SQingShan Zhang void PPCPostRASchedStrategy::enterMBB(MachineBasicBlock *MBB) {
635321dcd6SQingShan Zhang   // Custom PPC PostRA specific behavior here.
645321dcd6SQingShan Zhang   PostGenericScheduler::enterMBB(MBB);
655321dcd6SQingShan Zhang }
665321dcd6SQingShan Zhang 
675321dcd6SQingShan Zhang void PPCPostRASchedStrategy::leaveMBB() {
685321dcd6SQingShan Zhang   // Custom PPC PostRA specific behavior here.
695321dcd6SQingShan Zhang   PostGenericScheduler::leaveMBB();
705321dcd6SQingShan Zhang }
715321dcd6SQingShan Zhang 
725321dcd6SQingShan Zhang void PPCPostRASchedStrategy::initialize(ScheduleDAGMI *Dag) {
735321dcd6SQingShan Zhang   // Custom PPC PostRA specific initialization here.
745321dcd6SQingShan Zhang   PostGenericScheduler::initialize(Dag);
755321dcd6SQingShan Zhang }
765321dcd6SQingShan Zhang 
775321dcd6SQingShan Zhang SUnit *PPCPostRASchedStrategy::pickNode(bool &IsTopNode) {
785321dcd6SQingShan Zhang   // Custom PPC PostRA specific scheduling here.
795321dcd6SQingShan Zhang   return PostGenericScheduler::pickNode(IsTopNode);
805321dcd6SQingShan Zhang }
815321dcd6SQingShan Zhang 
82