1198439Srpaulo//===- PPCMachineScheduler.cpp - MI Scheduler for PowerPC -------------===//
2198439Srpaulo//
3198439Srpaulo// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4198439Srpaulo// See https://llvm.org/LICENSE.txt for license information.
5198439Srpaulo// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6198439Srpaulo//
7198439Srpaulo//===----------------------------------------------------------------------===//
8198439Srpaulo
9198439Srpaulo#include "PPCMachineScheduler.h"
10198439Srpaulo#include "MCTargetDesc/PPCMCTargetDesc.h"
11198439Srpaulo
12208591Srpaulousing namespace llvm;
13208591Srpaulo
14208591Srpaulostatic cl::opt<bool>
15208591SrpauloDisableAddiLoadHeuristic("disable-ppc-sched-addi-load",
16208590Srpaulo                         cl::desc("Disable scheduling addi instruction before"
17198439Srpaulo                                  "load for ppc"), cl::Hidden);
18198439Srpaulo
19bool 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
45void 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
64void PPCPostRASchedStrategy::enterMBB(MachineBasicBlock *MBB) {
65  // Custom PPC PostRA specific behavior here.
66  PostGenericScheduler::enterMBB(MBB);
67}
68
69void PPCPostRASchedStrategy::leaveMBB() {
70  // Custom PPC PostRA specific behavior here.
71  PostGenericScheduler::leaveMBB();
72}
73
74void PPCPostRASchedStrategy::initialize(ScheduleDAGMI *Dag) {
75  // Custom PPC PostRA specific initialization here.
76  PostGenericScheduler::initialize(Dag);
77}
78
79SUnit *PPCPostRASchedStrategy::pickNode(bool &IsTopNode) {
80  // Custom PPC PostRA specific scheduling here.
81  return PostGenericScheduler::pickNode(IsTopNode);
82}
83
84