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, Register LaneMaskRegAttrs); 35 36 class PhiLoweringHelper { 37 public: 38 PhiLoweringHelper(MachineFunction *MF, MachineDominatorTree *DT, 39 MachinePostDominatorTree *PDT); 40 virtual ~PhiLoweringHelper() = default; 41 42 protected: 43 bool IsWave32 = false; 44 MachineFunction *MF = nullptr; 45 MachineDominatorTree *DT = nullptr; 46 MachinePostDominatorTree *PDT = nullptr; 47 MachineRegisterInfo *MRI = nullptr; 48 const GCNSubtarget *ST = nullptr; 49 const SIInstrInfo *TII = nullptr; 50 Register LaneMaskRegAttrs; 51 52 #ifndef NDEBUG 53 DenseSet<Register> PhiRegisters; 54 #endif 55 56 Register ExecReg; 57 unsigned MovOp; 58 unsigned AndOp; 59 unsigned OrOp; 60 unsigned XorOp; 61 unsigned AndN2Op; 62 unsigned OrN2Op; 63 64 public: 65 bool lowerPhis(); 66 bool isConstantLaneMask(Register Reg, bool &Val) const; 67 MachineBasicBlock::iterator 68 getSaluInsertionAtEnd(MachineBasicBlock &MBB) const; 69 70 void initializeLaneMaskRegisterAttributes(Register LaneMask) { 71 LaneMaskRegAttrs = LaneMask; 72 } 73 74 bool isLaneMaskReg(Register Reg) const { 75 return TII->getRegisterInfo().isSGPRReg(*MRI, Reg) && 76 TII->getRegisterInfo().getRegSizeInBits(Reg, *MRI) == 77 ST->getWavefrontSize(); 78 } 79 80 // Helpers from lowerPhis that are different between sdag and global-isel. 81 82 virtual void markAsLaneMask(Register DstReg) const = 0; 83 virtual void getCandidatesForLowering( 84 SmallVectorImpl<MachineInstr *> &Vreg1Phis) const = 0; 85 virtual void 86 collectIncomingValuesFromPhi(const MachineInstr *MI, 87 SmallVectorImpl<Incoming> &Incomings) const = 0; 88 virtual void replaceDstReg(Register NewReg, Register OldReg, 89 MachineBasicBlock *MBB) = 0; 90 virtual void buildMergeLaneMasks(MachineBasicBlock &MBB, 91 MachineBasicBlock::iterator I, 92 const DebugLoc &DL, Register DstReg, 93 Register PrevReg, Register CurReg) = 0; 94 virtual void constrainIncomingRegisterTakenAsIs(Incoming &In) = 0; 95 }; 96 97 } // end namespace llvm 98