1 | //===--- AMDGPUMacroFusion.cpp - AMDGPU Macro Fusion ----------------------===// |
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-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | /// \file This file contains the AMDGPU implementation of the DAG scheduling |
10 | /// mutation to pair instructions back to back. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "AMDGPUMacroFusion.h" |
15 | #include "MCTargetDesc/AMDGPUMCTargetDesc.h" |
16 | #include "SIInstrInfo.h" |
17 | #include "llvm/CodeGen/MacroFusion.h" |
18 | |
19 | using namespace llvm; |
20 | |
21 | namespace { |
22 | |
23 | /// Check if the instr pair, FirstMI and SecondMI, should be fused |
24 | /// together. Given SecondMI, when FirstMI is unspecified, then check if |
25 | /// SecondMI may be part of a fused pair at all. |
26 | static bool shouldScheduleAdjacent(const TargetInstrInfo &TII_, |
27 | const TargetSubtargetInfo &TSI, |
28 | const MachineInstr *FirstMI, |
29 | const MachineInstr &SecondMI) { |
30 | const SIInstrInfo &TII = static_cast<const SIInstrInfo&>(TII_); |
31 | |
32 | switch (SecondMI.getOpcode()) { |
33 | case AMDGPU::V_ADDC_U32_e64: |
34 | case AMDGPU::V_SUBB_U32_e64: |
35 | case AMDGPU::V_SUBBREV_U32_e64: |
36 | case AMDGPU::V_CNDMASK_B32_e64: { |
37 | // Try to cluster defs of condition registers to their uses. This improves |
38 | // the chance VCC will be available which will allow shrinking to VOP2 |
39 | // encodings. |
40 | if (!FirstMI) |
41 | return true; |
42 | |
43 | const MachineBasicBlock &MBB = *FirstMI->getParent(); |
44 | const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); |
45 | const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo(); |
46 | const MachineOperand *Src2 = TII.getNamedOperand(MI: SecondMI, |
47 | OpName: AMDGPU::OpName::src2); |
48 | return FirstMI->definesRegister(Reg: Src2->getReg(), TRI); |
49 | } |
50 | default: |
51 | return false; |
52 | } |
53 | |
54 | return false; |
55 | } |
56 | |
57 | } // end namespace |
58 | |
59 | |
60 | namespace llvm { |
61 | |
62 | std::unique_ptr<ScheduleDAGMutation> createAMDGPUMacroFusionDAGMutation() { |
63 | return createMacroFusionDAGMutation(Predicates: shouldScheduleAdjacent); |
64 | } |
65 | |
66 | } // end namespace llvm |
67 | |