LLVM  7.0.0svn
SILowerI1Copies.cpp
Go to the documentation of this file.
1 //===-- SILowerI1Copies.cpp - Lower I1 Copies -----------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 /// i1 values are usually inserted by the CFG Structurize pass and they are
9 /// unique in that they can be copied from VALU to SALU registers.
10 /// This is not possible for any other value type. Since there are no
11 /// MOV instructions for i1, we to use V_CMP_* and V_CNDMASK to move the i1.
12 ///
13 //===----------------------------------------------------------------------===//
14 //
15 
16 #define DEBUG_TYPE "si-i1-copies"
17 #include "AMDGPU.h"
18 #include "AMDGPUSubtarget.h"
19 #include "SIInstrInfo.h"
26 #include "llvm/IR/Function.h"
27 #include "llvm/IR/LLVMContext.h"
28 #include "llvm/Support/Debug.h"
30 
31 using namespace llvm;
32 
33 namespace {
34 
35 class SILowerI1Copies : public MachineFunctionPass {
36 public:
37  static char ID;
38 
39 public:
40  SILowerI1Copies() : MachineFunctionPass(ID) {
42  }
43 
44  bool runOnMachineFunction(MachineFunction &MF) override;
45 
46  StringRef getPassName() const override { return "SI Lower i1 Copies"; }
47 
48  void getAnalysisUsage(AnalysisUsage &AU) const override {
49  AU.setPreservesCFG();
51  }
52 };
53 
54 } // End anonymous namespace.
55 
56 INITIALIZE_PASS(SILowerI1Copies, DEBUG_TYPE,
57  "SI Lower i1 Copies", false, false)
58 
59 char SILowerI1Copies::ID = 0;
60 
62 
64  return new SILowerI1Copies();
65 }
66 
67 bool SILowerI1Copies::runOnMachineFunction(MachineFunction &MF) {
70  const SIInstrInfo *TII = ST.getInstrInfo();
71  const TargetRegisterInfo *TRI = &TII->getRegisterInfo();
72 
73  std::vector<unsigned> I1Defs;
74 
75  for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
76  BI != BE; ++BI) {
77 
78  MachineBasicBlock &MBB = *BI;
80  for (I = MBB.begin(); I != MBB.end(); I = Next) {
81  Next = std::next(I);
82  MachineInstr &MI = *I;
83 
84  if (MI.getOpcode() == AMDGPU::IMPLICIT_DEF) {
85  unsigned Reg = MI.getOperand(0).getReg();
86  const TargetRegisterClass *RC = MRI.getRegClass(Reg);
87  if (RC == &AMDGPU::VReg_1RegClass)
88  MRI.setRegClass(Reg, &AMDGPU::SReg_64RegClass);
89  continue;
90  }
91 
92  if (MI.getOpcode() != AMDGPU::COPY)
93  continue;
94 
95  const MachineOperand &Dst = MI.getOperand(0);
96  const MachineOperand &Src = MI.getOperand(1);
97 
100  continue;
101 
102  const TargetRegisterClass *DstRC = MRI.getRegClass(Dst.getReg());
103  const TargetRegisterClass *SrcRC = MRI.getRegClass(Src.getReg());
104 
105  DebugLoc DL = MI.getDebugLoc();
106  MachineInstr *DefInst = MRI.getUniqueVRegDef(Src.getReg());
107  if (DstRC == &AMDGPU::VReg_1RegClass &&
108  TRI->getCommonSubClass(SrcRC, &AMDGPU::SGPR_64RegClass)) {
109  I1Defs.push_back(Dst.getReg());
110 
111  if (DefInst->getOpcode() == AMDGPU::S_MOV_B64) {
112  if (DefInst->getOperand(1).isImm()) {
113  I1Defs.push_back(Dst.getReg());
114 
115  int64_t Val = DefInst->getOperand(1).getImm();
116  assert(Val == 0 || Val == -1);
117 
118  BuildMI(MBB, &MI, DL, TII->get(AMDGPU::V_MOV_B32_e32))
119  .add(Dst)
120  .addImm(Val);
121  MI.eraseFromParent();
122  continue;
123  }
124  }
125 
126  unsigned int TmpSrc = MRI.createVirtualRegister(&AMDGPU::SReg_64_XEXECRegClass);
127  BuildMI(MBB, &MI, DL, TII->get(AMDGPU::COPY), TmpSrc)
128  .add(Src);
129  BuildMI(MBB, &MI, DL, TII->get(AMDGPU::V_CNDMASK_B32_e64))
130  .add(Dst)
131  .addImm(0)
132  .addImm(-1)
133  .addReg(TmpSrc);
134  MI.eraseFromParent();
135  } else if (TRI->getCommonSubClass(DstRC, &AMDGPU::SGPR_64RegClass) &&
136  SrcRC == &AMDGPU::VReg_1RegClass) {
137  if (DefInst->getOpcode() == AMDGPU::V_CNDMASK_B32_e64 &&
138  DefInst->getOperand(1).isImm() && DefInst->getOperand(2).isImm() &&
139  DefInst->getOperand(1).getImm() == 0 &&
140  DefInst->getOperand(2).getImm() != 0 &&
141  DefInst->getOperand(3).isReg() &&
143  DefInst->getOperand(3).getReg()) &&
144  TRI->getCommonSubClass(
145  MRI.getRegClass(DefInst->getOperand(3).getReg()),
146  &AMDGPU::SGPR_64RegClass) &&
147  AMDGPU::laneDominates(DefInst->getParent(), &MBB)) {
148  BuildMI(MBB, &MI, DL, TII->get(AMDGPU::S_AND_B64))
149  .add(Dst)
150  .addReg(AMDGPU::EXEC)
151  .add(DefInst->getOperand(3));
152  } else {
153  BuildMI(MBB, &MI, DL, TII->get(AMDGPU::V_CMP_NE_U32_e64))
154  .add(Dst)
155  .add(Src)
156  .addImm(0);
157  }
158  MI.eraseFromParent();
159  }
160  }
161  }
162 
163  for (unsigned Reg : I1Defs)
164  MRI.setRegClass(Reg, &AMDGPU::VGPR_32RegClass);
165 
166  return false;
167 }
const TargetRegisterClass * getCommonSubClass(const TargetRegisterClass *A, const TargetRegisterClass *B, const MVT::SimpleValueType SVT=MVT::SimpleValueType::Any) const
Find the largest common subclass of A and B.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
AMDGPU specific subclass of TargetSubtarget.
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:285
unsigned getReg() const
getReg - Returns the register number.
#define DEBUG_TYPE
i1 values are usually inserted by the CFG Structurize pass and they are unique in that they can be co...
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
unsigned Reg
const SIInstrInfo * getInstrInfo() const override
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:34
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:311
FunctionPass * createSILowerI1CopiesPass()
char & SILowerI1CopiesID
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata *> MDs)
Definition: Metadata.h:1164
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:285
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool laneDominates(MachineBasicBlock *A, MachineBasicBlock *B)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:34
Iterator for intrusive lists based on ilist_node.
MachineOperand class - Representation of each machine instruction operand.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:286
int64_t getImm() const
MachineInstr * getUniqueVRegDef(unsigned Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:156
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Provides AMDGPU specific target descriptions.
Representation of each machine instruction.
Definition: MachineInstr.h:60
Interface definition for SIInstrInfo.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
#define I(x, y, z)
Definition: MD5.cpp:58
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IRTranslator LLVM IR MI
void setRegClass(unsigned Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
void initializeSILowerI1CopiesPass(PassRegistry &)
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:316
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...