1 //===-- SILowerI1Copies.h --------------------------------------*- C++ -*--===// 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 10 /// Interface definition of the PhiLoweringHelper class that implements lane 11 /// mask merging algorithm for divergent i1 phis. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "GCNSubtarget.h" 16 #include "llvm/CodeGen/MachineBasicBlock.h" 17 #include "llvm/CodeGen/MachinePostDominators.h" 18 #include "llvm/CodeGen/MachineSSAUpdater.h" 19 20 namespace llvm { 21 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. 25 struct Incoming { 26 Register Reg; 27 MachineBasicBlock *Block; 28 Register UpdatedReg; 29 30 Incoming(Register Reg, MachineBasicBlock *Block, Register UpdatedReg) 31 : Reg(Reg), Block(Block), UpdatedReg(UpdatedReg) {} 32 }; 33 34 Register createLaneMaskReg(MachineRegisterInfo *MRI, 35 MachineRegisterInfo::VRegAttrs LaneMaskRegAttrs); 36 37 class PhiLoweringHelper { 38 public: 39 PhiLoweringHelper(MachineFunction *MF, MachineDominatorTree *DT, 40 MachinePostDominatorTree *PDT); 41 virtual ~PhiLoweringHelper() = default; 42 43 protected: 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; 52 53 #ifndef NDEBUG 54 DenseSet<Register> PhiRegisters; 55 #endif 56 57 Register ExecReg; 58 unsigned MovOp; 59 unsigned AndOp; 60 unsigned OrOp; 61 unsigned XorOp; 62 unsigned AndN2Op; 63 unsigned OrN2Op; 64 65 public: 66 bool lowerPhis(); 67 bool isConstantLaneMask(Register Reg, bool &Val) const; 68 MachineBasicBlock::iterator 69 getSaluInsertionAtEnd(MachineBasicBlock &MBB) const; 70 71 void initializeLaneMaskRegisterAttributes(Register LaneMask) { 72 LaneMaskRegAttrs = MRI->getVRegAttrs(LaneMask); 73 } 74 75 bool isLaneMaskReg(Register Reg) const { 76 return TII->getRegisterInfo().isSGPRReg(*MRI, Reg) && 77 TII->getRegisterInfo().getRegSizeInBits(Reg, *MRI) == 78 ST->getWavefrontSize(); 79 } 80 81 // Helpers from lowerPhis that are different between sdag and global-isel. 82 83 virtual void markAsLaneMask(Register DstReg) const = 0; 84 virtual void getCandidatesForLowering( 85 SmallVectorImpl<MachineInstr *> &Vreg1Phis) const = 0; 86 virtual void 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; 96 }; 97 98 } // end namespace llvm 99