1*0b57cec5SDimitry Andric //===- PPCMachineScheduler.cpp - MI Scheduler for PowerPC -------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #include "PPCMachineScheduler.h" 10*0b57cec5SDimitry Andric #include "MCTargetDesc/PPCMCTargetDesc.h" 11*0b57cec5SDimitry Andric 12*0b57cec5SDimitry Andric using namespace llvm; 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric static cl::opt<bool> 15*0b57cec5SDimitry Andric DisableAddiLoadHeuristic("disable-ppc-sched-addi-load", 16*0b57cec5SDimitry Andric cl::desc("Disable scheduling addi instruction before" 17*0b57cec5SDimitry Andric "load for ppc"), cl::Hidden); 18*0b57cec5SDimitry Andric 19*0b57cec5SDimitry Andric bool PPCPreRASchedStrategy::biasAddiLoadCandidate(SchedCandidate &Cand, 20*0b57cec5SDimitry Andric SchedCandidate &TryCand, 21*0b57cec5SDimitry Andric SchedBoundary &Zone) const { 22*0b57cec5SDimitry Andric if (DisableAddiLoadHeuristic) 23*0b57cec5SDimitry Andric return false; 24*0b57cec5SDimitry Andric 25*0b57cec5SDimitry Andric auto isADDIInstr = [&] (const MachineInstr &Inst) { 26*0b57cec5SDimitry Andric return Inst.getOpcode() == PPC::ADDI || Inst.getOpcode() == PPC::ADDI8; 27*0b57cec5SDimitry Andric }; 28*0b57cec5SDimitry Andric 29*0b57cec5SDimitry Andric SchedCandidate &FirstCand = Zone.isTop() ? TryCand : Cand; 30*0b57cec5SDimitry Andric SchedCandidate &SecondCand = Zone.isTop() ? Cand : TryCand; 31*0b57cec5SDimitry Andric if (isADDIInstr(*FirstCand.SU->getInstr()) && 32*0b57cec5SDimitry Andric SecondCand.SU->getInstr()->mayLoad()) { 33*0b57cec5SDimitry Andric TryCand.Reason = Stall; 34*0b57cec5SDimitry Andric return true; 35*0b57cec5SDimitry Andric } 36*0b57cec5SDimitry Andric if (FirstCand.SU->getInstr()->mayLoad() && 37*0b57cec5SDimitry Andric isADDIInstr(*SecondCand.SU->getInstr())) { 38*0b57cec5SDimitry Andric TryCand.Reason = NoCand; 39*0b57cec5SDimitry Andric return true; 40*0b57cec5SDimitry Andric } 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric return false; 43*0b57cec5SDimitry Andric } 44*0b57cec5SDimitry Andric 45*0b57cec5SDimitry Andric void PPCPreRASchedStrategy::tryCandidate(SchedCandidate &Cand, 46*0b57cec5SDimitry Andric SchedCandidate &TryCand, 47*0b57cec5SDimitry Andric SchedBoundary *Zone) const { 48*0b57cec5SDimitry Andric GenericScheduler::tryCandidate(Cand, TryCand, Zone); 49*0b57cec5SDimitry Andric 50*0b57cec5SDimitry Andric if (!Cand.isValid() || !Zone) 51*0b57cec5SDimitry Andric return; 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry Andric // Add powerpc specific heuristic only when TryCand isn't selected or 54*0b57cec5SDimitry Andric // selected as node order. 55*0b57cec5SDimitry Andric if (TryCand.Reason != NodeOrder && TryCand.Reason != NoCand) 56*0b57cec5SDimitry Andric return; 57*0b57cec5SDimitry Andric 58*0b57cec5SDimitry Andric // There are some benefits to schedule the ADDI before the load to hide the 59*0b57cec5SDimitry Andric // latency, as RA may create a true dependency between the load and addi. 60*0b57cec5SDimitry Andric if (biasAddiLoadCandidate(Cand, TryCand, *Zone)) 61*0b57cec5SDimitry Andric return; 62*0b57cec5SDimitry Andric } 63*0b57cec5SDimitry Andric 64*0b57cec5SDimitry Andric void PPCPostRASchedStrategy::enterMBB(MachineBasicBlock *MBB) { 65*0b57cec5SDimitry Andric // Custom PPC PostRA specific behavior here. 66*0b57cec5SDimitry Andric PostGenericScheduler::enterMBB(MBB); 67*0b57cec5SDimitry Andric } 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric void PPCPostRASchedStrategy::leaveMBB() { 70*0b57cec5SDimitry Andric // Custom PPC PostRA specific behavior here. 71*0b57cec5SDimitry Andric PostGenericScheduler::leaveMBB(); 72*0b57cec5SDimitry Andric } 73*0b57cec5SDimitry Andric 74*0b57cec5SDimitry Andric void PPCPostRASchedStrategy::initialize(ScheduleDAGMI *Dag) { 75*0b57cec5SDimitry Andric // Custom PPC PostRA specific initialization here. 76*0b57cec5SDimitry Andric PostGenericScheduler::initialize(Dag); 77*0b57cec5SDimitry Andric } 78*0b57cec5SDimitry Andric 79*0b57cec5SDimitry Andric SUnit *PPCPostRASchedStrategy::pickNode(bool &IsTopNode) { 80*0b57cec5SDimitry Andric // Custom PPC PostRA specific scheduling here. 81*0b57cec5SDimitry Andric return PostGenericScheduler::pickNode(IsTopNode); 82*0b57cec5SDimitry Andric } 83*0b57cec5SDimitry Andric 84