[llvm] [RISCV][PoC] Schedule RVV instructions with same type first (PR #95924)
Michael Maitland via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 19 20:02:24 PDT 2024
================
@@ -0,0 +1,118 @@
+//===- RISCVMachineScheduler.cpp - MI Scheduler for RISC-V ----------------===//
+//
+// 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 "RISCVMachineScheduler.h"
+#include "MCTargetDesc/RISCVBaseInfo.h"
+#include "MCTargetDesc/RISCVMCTargetDesc.h"
+#include "RISCVInstrInfo.h"
+#include "RISCVSubtarget.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/MachineScheduler.h"
+#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/TargetParser/RISCVTargetParser.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "riscv-prera-sched-strategy"
+
+static cl::opt<bool> EnableScheduleSameVType(
+ "riscv-enable-schedule-same-vtype", cl::init(false), cl::Hidden,
+ cl::desc("Enable scheduling RVV instructions with same vtype first"));
+
+SUnit *RISCVPreRAMachineSchedStrategy::pickNode(bool &IsTopNode) {
+ auto FindPotentialRVVInstructionInQueue =
+ [&](SchedBoundary &Boundary, ReadyQueue Q, bool ShouldBeTop) -> SUnit * {
+ for (SUnit *SU : Q) {
+ if (SU->isScheduled)
+ continue;
+
+ MachineInstr *MI = SU->getInstr();
+ const MCInstrDesc &Desc = MI->getDesc();
+ if (RISCVII::hasSEWOp(Desc.TSFlags)) {
+ unsigned CurVSEW = MI->getOperand(RISCVII::getSEWOpNum(Desc)).getImm();
+ RISCVII::VLMUL CurVLMUL = RISCVII::getLMul(Desc.TSFlags);
+ // FIXME: We should consider vl and policy here.
+ if (CurVSEW == PrevVSEW && CurVLMUL == PrevVLMUL) {
+ IsTopNode = ShouldBeTop;
+ // Boundary.removeReady(SU);
+ if (SU->isTopReady())
+ Top.removeReady(SU);
+ if (SU->isBottomReady())
+ Bot.removeReady(SU);
+ LLVM_DEBUG(dbgs() << "Scheduling SU(" << SU->NodeNum << ") "
+ << *SU->getInstr());
+ return SU;
+ }
+ }
+ }
+ return nullptr;
+ };
+
+ auto FindPotentialRVVInstruction = [&](SchedBoundary &Boundary,
+ bool ShouldBeTop) -> SUnit * {
+ if (SUnit *Available = FindPotentialRVVInstructionInQueue(
+ Boundary, Boundary.Available, ShouldBeTop))
+ return Available;
+ if (SUnit *Pending = FindPotentialRVVInstructionInQueue(
+ Boundary, Boundary.Pending, ShouldBeTop))
+ return Pending;
+ return nullptr;
+ };
+
+ if (EnableScheduleSameVType) {
+ if (RegionPolicy.OnlyBottomUp) {
+ if (SUnit *SU = FindPotentialRVVInstruction(Bot, false))
+ return SU;
+ } else if (RegionPolicy.OnlyTopDown) {
+ if (SUnit *SU = FindPotentialRVVInstruction(Top, true))
+ return SU;
+ } else {
+ if (SUnit *SU =
----------------
michaelmaitland wrote:
In the `GenericScheduler`, we tend not to pick from the `Pending` queues. It is usually better to move the node to `Available` and keep `pick` functions to take from `Available`. Otherwise, there are two cases we run into:
1. HazardRecognizers try and keep nodes on the `Pending` queue and this code here will ignore that. It will be really hard to keep the intended functionality of HazardRecognizers if we pick from `Pending`.
2. A node is `Pending` because it will lead to stalls. Picking from it ignores the scheduler model.
Do we really need to pick from `Pending` here?
https://github.com/llvm/llvm-project/pull/95924
More information about the llvm-commits
mailing list