| //===- PPCMachineScheduler.cpp - MI Scheduler for PowerPC -------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "PPCMachineScheduler.h" | |
| #include "MCTargetDesc/PPCMCTargetDesc.h" | |
| using namespace llvm; | |
| static cl::opt<bool> | |
| DisableAddiLoadHeuristic("disable-ppc-sched-addi-load", | |
| cl::desc("Disable scheduling addi instruction before" | |
| "load for ppc"), cl::Hidden); | |
| bool PPCPreRASchedStrategy::biasAddiLoadCandidate(SchedCandidate &Cand, | |
| SchedCandidate &TryCand, | |
| SchedBoundary &Zone) const { | |
| if (DisableAddiLoadHeuristic) | |
| return false; | |
| auto isADDIInstr = [&] (const MachineInstr &Inst) { | |
| return Inst.getOpcode() == PPC::ADDI || Inst.getOpcode() == PPC::ADDI8; | |
| }; | |
| SchedCandidate &FirstCand = Zone.isTop() ? TryCand : Cand; | |
| SchedCandidate &SecondCand = Zone.isTop() ? Cand : TryCand; | |
| if (isADDIInstr(*FirstCand.SU->getInstr()) && | |
| SecondCand.SU->getInstr()->mayLoad()) { | |
| TryCand.Reason = Stall; | |
| return true; | |
| } | |
| if (FirstCand.SU->getInstr()->mayLoad() && | |
| isADDIInstr(*SecondCand.SU->getInstr())) { | |
| TryCand.Reason = NoCand; | |
| return true; | |
| } | |
| return false; | |
| } | |
| void PPCPreRASchedStrategy::tryCandidate(SchedCandidate &Cand, | |
| SchedCandidate &TryCand, | |
| SchedBoundary *Zone) const { | |
| GenericScheduler::tryCandidate(Cand, TryCand, Zone); | |
| if (!Cand.isValid() || !Zone) | |
| return; | |
| // Add powerpc specific heuristic only when TryCand isn't selected or | |
| // selected as node order. | |
| if (TryCand.Reason != NodeOrder && TryCand.Reason != NoCand) | |
| return; | |
| // There are some benefits to schedule the ADDI before the load to hide the | |
| // latency, as RA may create a true dependency between the load and addi. | |
| if (biasAddiLoadCandidate(Cand, TryCand, *Zone)) | |
| return; | |
| } | |
| void PPCPostRASchedStrategy::enterMBB(MachineBasicBlock *MBB) { | |
| // Custom PPC PostRA specific behavior here. | |
| PostGenericScheduler::enterMBB(MBB); | |
| } | |
| void PPCPostRASchedStrategy::leaveMBB() { | |
| // Custom PPC PostRA specific behavior here. | |
| PostGenericScheduler::leaveMBB(); | |
| } | |
| void PPCPostRASchedStrategy::initialize(ScheduleDAGMI *Dag) { | |
| // Custom PPC PostRA specific initialization here. | |
| PostGenericScheduler::initialize(Dag); | |
| } | |
| SUnit *PPCPostRASchedStrategy::pickNode(bool &IsTopNode) { | |
| // Custom PPC PostRA specific scheduling here. | |
| return PostGenericScheduler::pickNode(IsTopNode); | |
| } | |