1c4394386SDimitry Andric //===--- AMDGPUMacroFusion.cpp - AMDGPU Macro Fusion ----------------------===// 2c4394386SDimitry Andric // 3c4394386SDimitry Andric // The LLVM Compiler Infrastructure 4c4394386SDimitry Andric // 5c4394386SDimitry Andric // This file is distributed under the University of Illinois Open Source 6c4394386SDimitry Andric // License. See LICENSE.TXT for details. 7c4394386SDimitry Andric // 8c4394386SDimitry Andric //===----------------------------------------------------------------------===// 9c4394386SDimitry Andric // 10c4394386SDimitry Andric /// \file This file contains the AMDGPU implementation of the DAG scheduling 11c4394386SDimitry Andric /// mutation to pair instructions back to back. 12c4394386SDimitry Andric // 13c4394386SDimitry Andric //===----------------------------------------------------------------------===// 14c4394386SDimitry Andric 15c4394386SDimitry Andric #include "AMDGPUMacroFusion.h" 16c4394386SDimitry Andric #include "AMDGPUSubtarget.h" 17c4394386SDimitry Andric #include "SIInstrInfo.h" 18c4394386SDimitry Andric 19c4394386SDimitry Andric #include "llvm/CodeGen/MacroFusion.h" 20c4394386SDimitry Andric 21c4394386SDimitry Andric using namespace llvm; 22c4394386SDimitry Andric 23c4394386SDimitry Andric namespace { 24c4394386SDimitry Andric 25c4394386SDimitry Andric /// \brief Check if the instr pair, FirstMI and SecondMI, should be fused 26c4394386SDimitry Andric /// together. Given SecondMI, when FirstMI is unspecified, then check if 27c4394386SDimitry Andric /// SecondMI may be part of a fused pair at all. 28c4394386SDimitry Andric static bool shouldScheduleAdjacent(const TargetInstrInfo &TII_, 29c4394386SDimitry Andric const TargetSubtargetInfo &TSI, 30c4394386SDimitry Andric const MachineInstr *FirstMI, 31c4394386SDimitry Andric const MachineInstr &SecondMI) { 32c4394386SDimitry Andric const SIInstrInfo &TII = static_cast<const SIInstrInfo&>(TII_); 33c4394386SDimitry Andric 34c4394386SDimitry Andric switch (SecondMI.getOpcode()) { 35c4394386SDimitry Andric case AMDGPU::V_ADDC_U32_e64: 36c4394386SDimitry Andric case AMDGPU::V_SUBB_U32_e64: 37c4394386SDimitry Andric case AMDGPU::V_CNDMASK_B32_e64: { 38c4394386SDimitry Andric // Try to cluster defs of condition registers to their uses. This improves 39c4394386SDimitry Andric // the chance VCC will be available which will allow shrinking to VOP2 40c4394386SDimitry Andric // encodings. 41c4394386SDimitry Andric if (!FirstMI) 42c4394386SDimitry Andric return true; 43c4394386SDimitry Andric 44c4394386SDimitry Andric const MachineOperand *Src2 = TII.getNamedOperand(SecondMI, 45c4394386SDimitry Andric AMDGPU::OpName::src2); 46c4394386SDimitry Andric return FirstMI->definesRegister(Src2->getReg()); 47c4394386SDimitry Andric } 48c4394386SDimitry Andric default: 49c4394386SDimitry Andric return false; 50c4394386SDimitry Andric } 51c4394386SDimitry Andric 52c4394386SDimitry Andric return false; 53c4394386SDimitry Andric } 54c4394386SDimitry Andric 55c4394386SDimitry Andric } // end namespace 56c4394386SDimitry Andric 57c4394386SDimitry Andric 58c4394386SDimitry Andric namespace llvm { 59c4394386SDimitry Andric 60c4394386SDimitry Andric std::unique_ptr<ScheduleDAGMutation> createAMDGPUMacroFusionDAGMutation () { 61c4394386SDimitry Andric return createMacroFusionDAGMutation(shouldScheduleAdjacent); 62c4394386SDimitry Andric } 63c4394386SDimitry Andric 64c4394386SDimitry Andric } // end namespace llvm 65