1 //===-- SILowerI1Copies.h --------------------------------------*- C++ -*--===//
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
7 //===----------------------------------------------------------------------===//
10 /// Interface definition of the PhiLoweringHelper class that implements lane
11 /// mask merging algorithm for divergent i1 phis.
13 //===----------------------------------------------------------------------===//
15 #include "GCNSubtarget.h"
16 #include "llvm/CodeGen/MachineBasicBlock.h"
17 #include "llvm/CodeGen/MachinePostDominators.h"
18 #include "llvm/CodeGen/MachineSSAUpdater.h"
22 /// Incoming for lane maks phi as machine instruction, incoming register \p Reg
23 /// and incoming block \p Block are taken from machine instruction.
24 /// \p UpdatedReg (if valid) is \p Reg lane mask merged with another lane mask.
27 MachineBasicBlock
*Block
;
30 Incoming(Register Reg
, MachineBasicBlock
*Block
, Register UpdatedReg
)
31 : Reg(Reg
), Block(Block
), UpdatedReg(UpdatedReg
) {}
34 Register
createLaneMaskReg(MachineRegisterInfo
*MRI
,
35 MachineRegisterInfo::VRegAttrs LaneMaskRegAttrs
);
37 class PhiLoweringHelper
{
39 PhiLoweringHelper(MachineFunction
*MF
, MachineDominatorTree
*DT
,
40 MachinePostDominatorTree
*PDT
);
41 virtual ~PhiLoweringHelper() = default;
44 bool IsWave32
= false;
45 MachineFunction
*MF
= nullptr;
46 MachineDominatorTree
*DT
= nullptr;
47 MachinePostDominatorTree
*PDT
= nullptr;
48 MachineRegisterInfo
*MRI
= nullptr;
49 const GCNSubtarget
*ST
= nullptr;
50 const SIInstrInfo
*TII
= nullptr;
51 MachineRegisterInfo::VRegAttrs LaneMaskRegAttrs
;
54 DenseSet
<Register
> PhiRegisters
;
67 bool isConstantLaneMask(Register Reg
, bool &Val
) const;
68 MachineBasicBlock::iterator
69 getSaluInsertionAtEnd(MachineBasicBlock
&MBB
) const;
71 void initializeLaneMaskRegisterAttributes(Register LaneMask
) {
72 LaneMaskRegAttrs
= MRI
->getVRegAttrs(LaneMask
);
75 bool isLaneMaskReg(Register Reg
) const {
76 return TII
->getRegisterInfo().isSGPRReg(*MRI
, Reg
) &&
77 TII
->getRegisterInfo().getRegSizeInBits(Reg
, *MRI
) ==
78 ST
->getWavefrontSize();
81 // Helpers from lowerPhis that are different between sdag and global-isel.
83 virtual void markAsLaneMask(Register DstReg
) const = 0;
84 virtual void getCandidatesForLowering(
85 SmallVectorImpl
<MachineInstr
*> &Vreg1Phis
) const = 0;
87 collectIncomingValuesFromPhi(const MachineInstr
*MI
,
88 SmallVectorImpl
<Incoming
> &Incomings
) const = 0;
89 virtual void replaceDstReg(Register NewReg
, Register OldReg
,
90 MachineBasicBlock
*MBB
) = 0;
91 virtual void buildMergeLaneMasks(MachineBasicBlock
&MBB
,
92 MachineBasicBlock::iterator I
,
93 const DebugLoc
&DL
, Register DstReg
,
94 Register PrevReg
, Register CurReg
) = 0;
95 virtual void constrainAsLaneMask(Incoming
&In
) = 0;
98 } // end namespace llvm