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*449bfdd1SQingShan Zhang #include "PPC.h" 95321dcd6SQingShan Zhang #include "PPCMachineScheduler.h" 105321dcd6SQingShan Zhang using namespace llvm; 115321dcd6SQingShan Zhang 12*449bfdd1SQingShan Zhang static cl::opt<bool> 13*449bfdd1SQingShan Zhang DisableAddiLoadHeuristic("disable-ppc-sched-addi-load", 14*449bfdd1SQingShan Zhang cl::desc("Disable scheduling addi instruction before" 15*449bfdd1SQingShan Zhang "load for ppc"), cl::Hidden); 16*449bfdd1SQingShan Zhang 17*449bfdd1SQingShan Zhang bool PPCPreRASchedStrategy::biasAddiLoadCandidate(SchedCandidate &Cand, 18*449bfdd1SQingShan Zhang SchedCandidate &TryCand, 19*449bfdd1SQingShan Zhang SchedBoundary &Zone) const { 20*449bfdd1SQingShan Zhang if (DisableAddiLoadHeuristic) 21*449bfdd1SQingShan Zhang return false; 22*449bfdd1SQingShan Zhang 23*449bfdd1SQingShan Zhang auto isADDIInstr = [&] (const MachineInstr &Inst) { 24*449bfdd1SQingShan Zhang return Inst.getOpcode() == PPC::ADDI || Inst.getOpcode() == PPC::ADDI8; 25*449bfdd1SQingShan Zhang }; 26*449bfdd1SQingShan Zhang 27*449bfdd1SQingShan Zhang SchedCandidate &FirstCand = Zone.isTop() ? TryCand : Cand; 28*449bfdd1SQingShan Zhang SchedCandidate &SecondCand = Zone.isTop() ? Cand : TryCand; 29*449bfdd1SQingShan Zhang if (isADDIInstr(*FirstCand.SU->getInstr()) && 30*449bfdd1SQingShan Zhang SecondCand.SU->getInstr()->mayLoad()) { 31*449bfdd1SQingShan Zhang TryCand.Reason = Stall; 32*449bfdd1SQingShan Zhang return true; 33*449bfdd1SQingShan Zhang } 34*449bfdd1SQingShan Zhang if (FirstCand.SU->getInstr()->mayLoad() && 35*449bfdd1SQingShan Zhang isADDIInstr(*SecondCand.SU->getInstr())) { 36*449bfdd1SQingShan Zhang TryCand.Reason = NoCand; 37*449bfdd1SQingShan Zhang return true; 38*449bfdd1SQingShan Zhang } 39*449bfdd1SQingShan Zhang 40*449bfdd1SQingShan Zhang return false; 41*449bfdd1SQingShan Zhang } 42*449bfdd1SQingShan Zhang 43*449bfdd1SQingShan Zhang void PPCPreRASchedStrategy::tryCandidate(SchedCandidate &Cand, 44*449bfdd1SQingShan Zhang SchedCandidate &TryCand, 45*449bfdd1SQingShan Zhang SchedBoundary *Zone) const { 46*449bfdd1SQingShan Zhang GenericScheduler::tryCandidate(Cand, TryCand, Zone); 47*449bfdd1SQingShan Zhang 48*449bfdd1SQingShan Zhang if (!Cand.isValid() || !Zone) 49*449bfdd1SQingShan Zhang return; 50*449bfdd1SQingShan Zhang 51*449bfdd1SQingShan Zhang // Add powerpc specific heuristic only when TryCand isn't selected or 52*449bfdd1SQingShan Zhang // selected as node order. 53*449bfdd1SQingShan Zhang if (TryCand.Reason != NodeOrder && TryCand.Reason != NoCand) 54*449bfdd1SQingShan Zhang return; 55*449bfdd1SQingShan Zhang 56*449bfdd1SQingShan Zhang // There are some benefits to schedule the ADDI before the load to hide the 57*449bfdd1SQingShan Zhang // latency, as RA may create a true dependency between the load and addi. 58*449bfdd1SQingShan Zhang if (biasAddiLoadCandidate(Cand, TryCand, *Zone)) 59*449bfdd1SQingShan Zhang return; 60*449bfdd1SQingShan Zhang } 61*449bfdd1SQingShan Zhang 625321dcd6SQingShan Zhang void PPCPostRASchedStrategy::enterMBB(MachineBasicBlock *MBB) { 635321dcd6SQingShan Zhang // Custom PPC PostRA specific behavior here. 645321dcd6SQingShan Zhang PostGenericScheduler::enterMBB(MBB); 655321dcd6SQingShan Zhang } 665321dcd6SQingShan Zhang 675321dcd6SQingShan Zhang void PPCPostRASchedStrategy::leaveMBB() { 685321dcd6SQingShan Zhang // Custom PPC PostRA specific behavior here. 695321dcd6SQingShan Zhang PostGenericScheduler::leaveMBB(); 705321dcd6SQingShan Zhang } 715321dcd6SQingShan Zhang 725321dcd6SQingShan Zhang void PPCPostRASchedStrategy::initialize(ScheduleDAGMI *Dag) { 735321dcd6SQingShan Zhang // Custom PPC PostRA specific initialization here. 745321dcd6SQingShan Zhang PostGenericScheduler::initialize(Dag); 755321dcd6SQingShan Zhang } 765321dcd6SQingShan Zhang 775321dcd6SQingShan Zhang SUnit *PPCPostRASchedStrategy::pickNode(bool &IsTopNode) { 785321dcd6SQingShan Zhang // Custom PPC PostRA specific scheduling here. 795321dcd6SQingShan Zhang return PostGenericScheduler::pickNode(IsTopNode); 805321dcd6SQingShan Zhang } 815321dcd6SQingShan Zhang 82