LLVM  4.0.0
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/LLVMContext.h"
25 #include "llvm/IR/Function.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 
59 char &llvm::SILowerI1CopiesID = SILowerI1Copies::ID;
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  .addOperand(Dst)
118  .addImm(Val);
119  MI.eraseFromParent();
120  continue;
121  }
122  }
123 
124  BuildMI(MBB, &MI, DL, TII->get(AMDGPU::V_CNDMASK_B32_e64))
125  .addOperand(Dst)
126  .addImm(0)
127  .addImm(-1)
128  .addOperand(Src);
129  MI.eraseFromParent();
130  } else if (TRI->getCommonSubClass(DstRC, &AMDGPU::SGPR_64RegClass) &&
131  SrcRC == &AMDGPU::VReg_1RegClass) {
132  if (DefInst->getOpcode() == AMDGPU::V_CNDMASK_B32_e64 &&
133  DefInst->getOperand(1).isImm() && DefInst->getOperand(2).isImm() &&
134  DefInst->getOperand(1).getImm() == 0 &&
135  DefInst->getOperand(2).getImm() != 0 &&
136  DefInst->getOperand(3).isReg() &&
138  DefInst->getOperand(3).getReg()) &&
139  TRI->getCommonSubClass(
140  MRI.getRegClass(DefInst->getOperand(3).getReg()),
141  &AMDGPU::SGPR_64RegClass)) {
142  BuildMI(MBB, &MI, DL, TII->get(AMDGPU::S_AND_B64))
143  .addOperand(Dst)
144  .addReg(AMDGPU::EXEC)
145  .addOperand(DefInst->getOperand(3));
146  } else {
147  BuildMI(MBB, &MI, DL, TII->get(AMDGPU::V_CMP_NE_U32_e64))
148  .addOperand(Dst)
149  .addOperand(Src)
150  .addImm(0);
151  }
152  MI.eraseFromParent();
153  }
154  }
155  }
156 
157  for (unsigned Reg : I1Defs)
158  MRI.setRegClass(Reg, &AMDGPU::VGPR_32RegClass);
159 
160  return false;
161 }
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
AMDGPU specific subclass of TargetSubtarget.
#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
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
Reg
All possible values of the reg field in the ModR/M byte.
MachineBasicBlock * MBB
FunctionPass * createSILowerI1CopiesPass()
int64_t getImm() const
char & SILowerI1CopiesID
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:273
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned const MachineRegisterInfo * MRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:279
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
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:36
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:276
MachineInstr * getUniqueVRegDef(unsigned Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:250
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1132
Representation of each machine instruction.
Definition: MachineInstr.h:52
Interface definition for SIInstrInfo.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
#define I(x, y, z)
Definition: MD5.cpp:54
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.
unsigned getReg() const
getReg - Returns the register number.
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:47
void initializeSILowerI1CopiesPass(PassRegistry &)