xref: /llvm-project/llvm/lib/Target/PowerPC/PPCMachineScheduler.cpp (revision 067a17b51dcf00cc738e86e923bdaaa9464516ff)
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*067a17b5SDmitri Gribenko 
95321dcd6SQingShan Zhang #include "PPCMachineScheduler.h"
10*067a17b5SDmitri Gribenko #include "MCTargetDesc/PPCMCTargetDesc.h"
11*067a17b5SDmitri Gribenko 
125321dcd6SQingShan Zhang using namespace llvm;
135321dcd6SQingShan Zhang 
14449bfdd1SQingShan Zhang static cl::opt<bool>
15449bfdd1SQingShan Zhang DisableAddiLoadHeuristic("disable-ppc-sched-addi-load",
16449bfdd1SQingShan Zhang                          cl::desc("Disable scheduling addi instruction before"
17449bfdd1SQingShan Zhang                                   "load for ppc"), cl::Hidden);
18449bfdd1SQingShan Zhang 
19449bfdd1SQingShan Zhang bool PPCPreRASchedStrategy::biasAddiLoadCandidate(SchedCandidate &Cand,
20449bfdd1SQingShan Zhang                                                   SchedCandidate &TryCand,
21449bfdd1SQingShan Zhang                                                   SchedBoundary &Zone) const {
22449bfdd1SQingShan Zhang   if (DisableAddiLoadHeuristic)
23449bfdd1SQingShan Zhang     return false;
24449bfdd1SQingShan Zhang 
25449bfdd1SQingShan Zhang   auto isADDIInstr = [&] (const MachineInstr &Inst) {
26449bfdd1SQingShan Zhang     return Inst.getOpcode() == PPC::ADDI || Inst.getOpcode() == PPC::ADDI8;
27449bfdd1SQingShan Zhang   };
28449bfdd1SQingShan Zhang 
29449bfdd1SQingShan Zhang   SchedCandidate &FirstCand = Zone.isTop() ? TryCand : Cand;
30449bfdd1SQingShan Zhang   SchedCandidate &SecondCand = Zone.isTop() ? Cand : TryCand;
31449bfdd1SQingShan Zhang   if (isADDIInstr(*FirstCand.SU->getInstr()) &&
32449bfdd1SQingShan Zhang       SecondCand.SU->getInstr()->mayLoad()) {
33449bfdd1SQingShan Zhang     TryCand.Reason = Stall;
34449bfdd1SQingShan Zhang     return true;
35449bfdd1SQingShan Zhang   }
36449bfdd1SQingShan Zhang   if (FirstCand.SU->getInstr()->mayLoad() &&
37449bfdd1SQingShan Zhang       isADDIInstr(*SecondCand.SU->getInstr())) {
38449bfdd1SQingShan Zhang     TryCand.Reason = NoCand;
39449bfdd1SQingShan Zhang     return true;
40449bfdd1SQingShan Zhang   }
41449bfdd1SQingShan Zhang 
42449bfdd1SQingShan Zhang   return false;
43449bfdd1SQingShan Zhang }
44449bfdd1SQingShan Zhang 
45449bfdd1SQingShan Zhang void PPCPreRASchedStrategy::tryCandidate(SchedCandidate &Cand,
46449bfdd1SQingShan Zhang                                          SchedCandidate &TryCand,
47449bfdd1SQingShan Zhang                                          SchedBoundary *Zone) const {
48449bfdd1SQingShan Zhang   GenericScheduler::tryCandidate(Cand, TryCand, Zone);
49449bfdd1SQingShan Zhang 
50449bfdd1SQingShan Zhang   if (!Cand.isValid() || !Zone)
51449bfdd1SQingShan Zhang     return;
52449bfdd1SQingShan Zhang 
53449bfdd1SQingShan Zhang   // Add powerpc specific heuristic only when TryCand isn't selected or
54449bfdd1SQingShan Zhang   // selected as node order.
55449bfdd1SQingShan Zhang   if (TryCand.Reason != NodeOrder && TryCand.Reason != NoCand)
56449bfdd1SQingShan Zhang     return;
57449bfdd1SQingShan Zhang 
58449bfdd1SQingShan Zhang   // There are some benefits to schedule the ADDI before the load to hide the
59449bfdd1SQingShan Zhang   // latency, as RA may create a true dependency between the load and addi.
60449bfdd1SQingShan Zhang   if (biasAddiLoadCandidate(Cand, TryCand, *Zone))
61449bfdd1SQingShan Zhang     return;
62449bfdd1SQingShan Zhang }
63449bfdd1SQingShan Zhang 
645321dcd6SQingShan Zhang void PPCPostRASchedStrategy::enterMBB(MachineBasicBlock *MBB) {
655321dcd6SQingShan Zhang   // Custom PPC PostRA specific behavior here.
665321dcd6SQingShan Zhang   PostGenericScheduler::enterMBB(MBB);
675321dcd6SQingShan Zhang }
685321dcd6SQingShan Zhang 
695321dcd6SQingShan Zhang void PPCPostRASchedStrategy::leaveMBB() {
705321dcd6SQingShan Zhang   // Custom PPC PostRA specific behavior here.
715321dcd6SQingShan Zhang   PostGenericScheduler::leaveMBB();
725321dcd6SQingShan Zhang }
735321dcd6SQingShan Zhang 
745321dcd6SQingShan Zhang void PPCPostRASchedStrategy::initialize(ScheduleDAGMI *Dag) {
755321dcd6SQingShan Zhang   // Custom PPC PostRA specific initialization here.
765321dcd6SQingShan Zhang   PostGenericScheduler::initialize(Dag);
775321dcd6SQingShan Zhang }
785321dcd6SQingShan Zhang 
795321dcd6SQingShan Zhang SUnit *PPCPostRASchedStrategy::pickNode(bool &IsTopNode) {
805321dcd6SQingShan Zhang   // Custom PPC PostRA specific scheduling here.
815321dcd6SQingShan Zhang   return PostGenericScheduler::pickNode(IsTopNode);
825321dcd6SQingShan Zhang }
835321dcd6SQingShan Zhang 
84