xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMachineScheduler.cpp (revision f4beb2edcde327a49f034da26bb2e5aadcec922a)
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  
19  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  
45  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  
64  void PPCPostRASchedStrategy::enterMBB(MachineBasicBlock *MBB) {
65    // Custom PPC PostRA specific behavior here.
66    PostGenericScheduler::enterMBB(MBB);
67  }
68  
69  void PPCPostRASchedStrategy::leaveMBB() {
70    // Custom PPC PostRA specific behavior here.
71    PostGenericScheduler::leaveMBB();
72  }
73  
74  void PPCPostRASchedStrategy::initialize(ScheduleDAGMI *Dag) {
75    // Custom PPC PostRA specific initialization here.
76    PostGenericScheduler::initialize(Dag);
77  }
78  
79  SUnit *PPCPostRASchedStrategy::pickNode(bool &IsTopNode) {
80    // Custom PPC PostRA specific scheduling here.
81    return PostGenericScheduler::pickNode(IsTopNode);
82  }
83  
84