brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.8 KiB · 3bd2705 Raw
111 lines · cpp
1//===- RISCVVectorMaskDAGMutation.cpp - RISC-V Vector Mask DAGMutation ----===//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-exception6//7//===----------------------------------------------------------------------===//8//9// A schedule mutation that adds an artificial dependency between masks producer10// instructions and masked instructions, so that we can reduce the live range11// overlaps of mask registers.12//13// If there are multiple masks producers followed by multiple masked14// instructions, then at each masked instructions add dependency edges between15// every producer and masked instruction.16//17// The reason why we need to do this:18// 1. When tracking register pressure, we don't track physical registers.19// 2. We have a RegisterClass for mask register (which is `VMV0`), but we don't20//    use it by the time we reach scheduling. Instead, we use physical21//    register V0 directly and insert a `$v0 = COPY ...` before the use.22// 3. For mask producers, we are using VR RegisterClass (we can allocate V0-V3123//    to it). So if V0 is not available, there are still 31 available registers24//    out there.25//26// This means that the RegPressureTracker can't track the pressure of mask27// registers correctly.28//29// This schedule mutation is a workaround to fix this issue.30//31//===----------------------------------------------------------------------===//32 33#include "MCTargetDesc/RISCVBaseInfo.h"34#include "MCTargetDesc/RISCVMCTargetDesc.h"35#include "RISCVTargetMachine.h"36#include "llvm/CodeGen/LiveIntervals.h"37#include "llvm/CodeGen/MachineInstr.h"38#include "llvm/CodeGen/ScheduleDAGInstrs.h"39#include "llvm/CodeGen/ScheduleDAGMutation.h"40#include "llvm/TargetParser/RISCVTargetParser.h"41 42#define DEBUG_TYPE "machine-scheduler"43 44namespace llvm {45 46static bool isCopyToV0(const MachineInstr &MI) {47  return MI.isFullCopy() && MI.getOperand(0).getReg() == RISCV::V0 &&48         MI.getOperand(1).getReg().isVirtual();49}50 51static bool isSoleUseCopyToV0(SUnit &SU) {52  if (SU.Succs.size() != 1)53    return false;54  SDep &Dep = SU.Succs[0];55  // Ignore dependencies other than data or strong ordering.56  if (Dep.isWeak())57    return false;58 59  SUnit &DepSU = *Dep.getSUnit();60  if (DepSU.isBoundaryNode())61    return false;62  return isCopyToV0(*DepSU.getInstr());63}64 65class RISCVVectorMaskDAGMutation : public ScheduleDAGMutation {66private:67  const TargetRegisterInfo *TRI;68 69public:70  RISCVVectorMaskDAGMutation(const TargetRegisterInfo *TRI) : TRI(TRI) {}71 72  void apply(ScheduleDAGInstrs *DAG) override {73    SUnit *NearestUseV0SU = nullptr;74    SmallVector<SUnit *, 2> DefMask;75    for (SUnit &SU : DAG->SUnits) {76      const MachineInstr *MI = SU.getInstr();77      bool UseV0 = MI->findRegisterUseOperand(RISCV::V0, TRI);78      if (isSoleUseCopyToV0(SU) && !UseV0)79        DefMask.push_back(&SU);80 81      if (UseV0) {82        NearestUseV0SU = &SU;83 84        // Copy may not be a real use, so skip it here.85        if (DefMask.size() > 1 && !MI->isCopy()) {86          for (SUnit *Def : DefMask)87            if (DAG->canAddEdge(Def, &SU))88              DAG->addEdge(Def, SDep(&SU, SDep::Artificial));89        }90 91        if (!DefMask.empty())92          DefMask.erase(DefMask.begin());93      }94 95      if (NearestUseV0SU && NearestUseV0SU != &SU && isSoleUseCopyToV0(SU) &&96          // For LMUL=8 cases, there will be more possibilities to spill.97          // FIXME: We should use RegPressureTracker to do fine-grained98          // controls.99          RISCVII::getLMul(MI->getDesc().TSFlags) != RISCVVType::LMUL_8)100        DAG->addEdge(&SU, SDep(NearestUseV0SU, SDep::Artificial));101    }102  }103};104 105std::unique_ptr<ScheduleDAGMutation>106createRISCVVectorMaskDAGMutation(const TargetRegisterInfo *TRI) {107  return std::make_unique<RISCVVectorMaskDAGMutation>(TRI);108}109 110} // namespace llvm111