LLVM  6.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"
24 #include "llvm/IR/Function.h"
25 #include "llvm/IR/LLVMContext.h"
26 #include "llvm/Support/Debug.h"
28 
29 using namespace llvm;
30 
31 namespace {
32 
33 class SILowerI1Copies : public MachineFunctionPass {
34 public:
35  static char ID;
36 
37 public:
38  SILowerI1Copies() : MachineFunctionPass(ID) {
40  }
41 
42  bool runOnMachineFunction(MachineFunction &MF) override;
43 
44  StringRef getPassName() const override { return "SI Lower i1 Copies"; }
45 
46  void getAnalysisUsage(AnalysisUsage &AU) const override {
47  AU.setPreservesCFG();
49  }
50 };
51 
52 } // End anonymous namespace.
53 
54 INITIALIZE_PASS(SILowerI1Copies, DEBUG_TYPE,
55  "SI Lower i1 Copies", false, false)
56 
57 char SILowerI1Copies::ID = 0;
58 
60 
62  return new SILowerI1Copies();
63 }
64 
65 bool SILowerI1Copies::runOnMachineFunction(MachineFunction &MF) {
67  const SISubtarget &ST = MF.getSubtarget<SISubtarget>();
68  const SIInstrInfo *TII = ST.getInstrInfo();
69  const TargetRegisterInfo *TRI = &TII->getRegisterInfo();
70 
71  std::vector<unsigned> I1Defs;
72 
73  for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
74  BI != BE; ++BI) {
75 
76  MachineBasicBlock &MBB = *BI;
78  for (I = MBB.begin(); I != MBB.end(); I = Next) {
79  Next = std::next(I);
80  MachineInstr &MI = *I;
81 
82  if (MI.getOpcode() == AMDGPU::IMPLICIT_DEF) {
83  unsigned Reg = MI.getOperand(0).getReg();
84  const TargetRegisterClass *RC = MRI.getRegClass(Reg);
85  if (RC == &AMDGPU::VReg_1RegClass)
86  MRI.setRegClass(Reg, &AMDGPU::SReg_64RegClass);
87  continue;
88  }
89 
90  if (MI.getOpcode() != AMDGPU::COPY)
91  continue;
92 
93  const MachineOperand &Dst = MI.getOperand(0);
94  const MachineOperand &Src = MI.getOperand(1);
95 
98  continue;
99 
100  const TargetRegisterClass *DstRC = MRI.getRegClass(Dst.getReg());
101  const TargetRegisterClass *SrcRC = MRI.getRegClass(Src.getReg());
102 
103  DebugLoc DL = MI.getDebugLoc();
104  MachineInstr *DefInst = MRI.getUniqueVRegDef(Src.getReg());
105  if (DstRC == &AMDGPU::VReg_1RegClass &&
106  TRI->getCommonSubClass(SrcRC, &AMDGPU::SGPR_64RegClass)) {
107  I1Defs.push_back(Dst.getReg());
108 
109  if (DefInst->getOpcode() == AMDGPU::S_MOV_B64) {
110  if (DefInst->getOperand(1).isImm()) {
111  I1Defs.push_back(Dst.getReg());
112 
113  int64_t Val = DefInst->getOperand(1).getImm();
114  assert(Val == 0 || Val == -1);
115 
116  BuildMI(MBB, &MI, DL, TII->get(AMDGPU::V_MOV_B32_e32))
117  .add(Dst)
118  .addImm(Val);
119  MI.eraseFromParent();
120  continue;
121  }
122  }
123 
124  unsigned int TmpSrc = MRI.createVirtualRegister(&AMDGPU::SReg_64_XEXECRegClass);
125  BuildMI(MBB, &MI, DL, TII->get(AMDGPU::COPY), TmpSrc)
126  .add(Src);
127  BuildMI(MBB, &MI, DL, TII->get(AMDGPU::V_CNDMASK_B32_e64))
128  .add(Dst)
129  .addImm(0)
130  .addImm(-1)
131  .addReg(TmpSrc);
132  MI.eraseFromParent();
133  } else if (TRI->getCommonSubClass(DstRC, &AMDGPU::SGPR_64RegClass) &&
134  SrcRC == &AMDGPU::VReg_1RegClass) {
135  if (DefInst->getOpcode() == AMDGPU::V_CNDMASK_B32_e64 &&
136  DefInst->getOperand(1).isImm() && DefInst->getOperand(2).isImm() &&
137  DefInst->getOperand(1).getImm() == 0 &&
138  DefInst->getOperand(2).getImm() != 0 &&
139  DefInst->getOperand(3).isReg() &&
141  DefInst->getOperand(3).getReg()) &&
142  TRI->getCommonSubClass(
143  MRI.getRegClass(DefInst->getOperand(3).getReg()),
144  &AMDGPU::SGPR_64RegClass)) {
145  BuildMI(MBB, &MI, DL, TII->get(AMDGPU::S_AND_B64))
146  .add(Dst)
147  .addReg(AMDGPU::EXEC)
148  .add(DefInst->getOperand(3));
149  } else {
150  BuildMI(MBB, &MI, DL, TII->get(AMDGPU::V_CMP_NE_U32_e64))
151  .add(Dst)
152  .add(Src)
153  .addImm(0);
154  }
155  MI.eraseFromParent();
156  }
157  }
158  }
159 
160  for (unsigned Reg : I1Defs)
161  MRI.setRegClass(Reg, &AMDGPU::VGPR_32RegClass);
162 
163  return false;
164 }
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
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:268
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.
const SIInstrInfo * getInstrInfo() const override
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.
Reg
All possible values of the reg field in the ModR/M byte.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:290
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...
#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:285
int64_t getImm() const
MachineInstr * getUniqueVRegDef(unsigned Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:59
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:295