19aa45f04SMatt Arsenault //===--- AMDGPUMacroFusion.cpp - AMDGPU Macro Fusion ----------------------===//
29aa45f04SMatt Arsenault //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
69aa45f04SMatt Arsenault //
79aa45f04SMatt Arsenault //===----------------------------------------------------------------------===//
89aa45f04SMatt Arsenault //
99aa45f04SMatt Arsenault /// \file This file contains the AMDGPU implementation of the DAG scheduling
109aa45f04SMatt Arsenault /// mutation to pair instructions back to back.
119aa45f04SMatt Arsenault //
129aa45f04SMatt Arsenault //===----------------------------------------------------------------------===//
139aa45f04SMatt Arsenault
149aa45f04SMatt Arsenault #include "AMDGPUMacroFusion.h"
15*560d7e04Sdfukalov #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
16*560d7e04Sdfukalov #include "SIInstrInfo.h"
179aa45f04SMatt Arsenault #include "llvm/CodeGen/MacroFusion.h"
189aa45f04SMatt Arsenault
199aa45f04SMatt Arsenault using namespace llvm;
209aa45f04SMatt Arsenault
219aa45f04SMatt Arsenault namespace {
229aa45f04SMatt Arsenault
235f8f34e4SAdrian Prantl /// Check if the instr pair, FirstMI and SecondMI, should be fused
249aa45f04SMatt Arsenault /// together. Given SecondMI, when FirstMI is unspecified, then check if
259aa45f04SMatt Arsenault /// SecondMI may be part of a fused pair at all.
shouldScheduleAdjacent(const TargetInstrInfo & TII_,const TargetSubtargetInfo & TSI,const MachineInstr * FirstMI,const MachineInstr & SecondMI)269aa45f04SMatt Arsenault static bool shouldScheduleAdjacent(const TargetInstrInfo &TII_,
279aa45f04SMatt Arsenault const TargetSubtargetInfo &TSI,
289aa45f04SMatt Arsenault const MachineInstr *FirstMI,
299aa45f04SMatt Arsenault const MachineInstr &SecondMI) {
309aa45f04SMatt Arsenault const SIInstrInfo &TII = static_cast<const SIInstrInfo&>(TII_);
319aa45f04SMatt Arsenault
329aa45f04SMatt Arsenault switch (SecondMI.getOpcode()) {
339aa45f04SMatt Arsenault case AMDGPU::V_ADDC_U32_e64:
349aa45f04SMatt Arsenault case AMDGPU::V_SUBB_U32_e64:
35a46dba24SJay Foad case AMDGPU::V_SUBBREV_U32_e64:
369aa45f04SMatt Arsenault case AMDGPU::V_CNDMASK_B32_e64: {
379aa45f04SMatt Arsenault // Try to cluster defs of condition registers to their uses. This improves
389aa45f04SMatt Arsenault // the chance VCC will be available which will allow shrinking to VOP2
399aa45f04SMatt Arsenault // encodings.
409aa45f04SMatt Arsenault if (!FirstMI)
419aa45f04SMatt Arsenault return true;
429aa45f04SMatt Arsenault
4313d3371eSStanislav Mekhanoshin const MachineBasicBlock &MBB = *FirstMI->getParent();
4413d3371eSStanislav Mekhanoshin const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
4513d3371eSStanislav Mekhanoshin const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
469aa45f04SMatt Arsenault const MachineOperand *Src2 = TII.getNamedOperand(SecondMI,
479aa45f04SMatt Arsenault AMDGPU::OpName::src2);
4813d3371eSStanislav Mekhanoshin return FirstMI->definesRegister(Src2->getReg(), TRI);
499aa45f04SMatt Arsenault }
509aa45f04SMatt Arsenault default:
519aa45f04SMatt Arsenault return false;
529aa45f04SMatt Arsenault }
539aa45f04SMatt Arsenault
549aa45f04SMatt Arsenault return false;
559aa45f04SMatt Arsenault }
569aa45f04SMatt Arsenault
579aa45f04SMatt Arsenault } // end namespace
589aa45f04SMatt Arsenault
599aa45f04SMatt Arsenault
609aa45f04SMatt Arsenault namespace llvm {
619aa45f04SMatt Arsenault
createAMDGPUMacroFusionDAGMutation()629aa45f04SMatt Arsenault std::unique_ptr<ScheduleDAGMutation> createAMDGPUMacroFusionDAGMutation () {
639aa45f04SMatt Arsenault return createMacroFusionDAGMutation(shouldScheduleAdjacent);
649aa45f04SMatt Arsenault }
659aa45f04SMatt Arsenault
669aa45f04SMatt Arsenault } // end namespace llvm
67