LLVM  3.7.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"
25 #include "llvm/IR/LLVMContext.h"
26 #include "llvm/IR/Function.h"
27 #include "llvm/Support/Debug.h"
29 
30 using namespace llvm;
31 
32 namespace {
33 
34 class SILowerI1Copies : public MachineFunctionPass {
35 public:
36  static char ID;
37 
38 public:
39  SILowerI1Copies() : MachineFunctionPass(ID) {
41  }
42 
43  bool runOnMachineFunction(MachineFunction &MF) override;
44 
45  const char *getPassName() const override {
46  return "SI Lower i1 Copies";
47  }
48 
49  void getAnalysisUsage(AnalysisUsage &AU) const override {
51  AU.setPreservesCFG();
53  }
54 };
55 
56 } // End anonymous namespace.
57 
58 INITIALIZE_PASS_BEGIN(SILowerI1Copies, DEBUG_TYPE,
59  "SI Lower i1 Copies", false, false)
62  "SI Lower i1 Copies", false, false)
63 
64 char SILowerI1Copies::ID = 0;
65 
66 char &llvm::SILowerI1CopiesID = SILowerI1Copies::ID;
67 
69  return new SILowerI1Copies();
70 }
71 
72 bool SILowerI1Copies::runOnMachineFunction(MachineFunction &MF) {
73  MachineRegisterInfo &MRI = MF.getRegInfo();
74  const SIInstrInfo *TII =
75  static_cast<const SIInstrInfo *>(MF.getSubtarget().getInstrInfo());
77  std::vector<unsigned> I1Defs;
78 
79  for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
80  BI != BE; ++BI) {
81 
82  MachineBasicBlock &MBB = *BI;
84  for (I = MBB.begin(); I != MBB.end(); I = Next) {
85  Next = std::next(I);
86  MachineInstr &MI = *I;
87 
88  if (MI.getOpcode() == AMDGPU::IMPLICIT_DEF) {
89  unsigned Reg = MI.getOperand(0).getReg();
90  const TargetRegisterClass *RC = MRI.getRegClass(Reg);
91  if (RC == &AMDGPU::VReg_1RegClass)
92  MRI.setRegClass(Reg, &AMDGPU::SReg_64RegClass);
93  continue;
94  }
95 
96  if (MI.getOpcode() != AMDGPU::COPY)
97  continue;
98 
99  const MachineOperand &Dst = MI.getOperand(0);
100  const MachineOperand &Src = MI.getOperand(1);
101 
104  continue;
105 
106  const TargetRegisterClass *DstRC = MRI.getRegClass(Dst.getReg());
107  const TargetRegisterClass *SrcRC = MRI.getRegClass(Src.getReg());
108 
109  if (DstRC == &AMDGPU::VReg_1RegClass &&
110  TRI->getCommonSubClass(SrcRC, &AMDGPU::SGPR_64RegClass)) {
111  I1Defs.push_back(Dst.getReg());
112  DebugLoc DL = MI.getDebugLoc();
113 
114  MachineInstr *DefInst = MRI.getUniqueVRegDef(Src.getReg());
115  if (DefInst->getOpcode() == AMDGPU::S_MOV_B64) {
116  if (DefInst->getOperand(1).isImm()) {
117  I1Defs.push_back(Dst.getReg());
118 
119  int64_t Val = DefInst->getOperand(1).getImm();
120  assert(Val == 0 || Val == -1);
121 
122  BuildMI(MBB, &MI, DL, TII->get(AMDGPU::V_MOV_B32_e32))
123  .addOperand(Dst)
124  .addImm(Val);
125  MI.eraseFromParent();
126  continue;
127  }
128  }
129 
130  BuildMI(MBB, &MI, DL, TII->get(AMDGPU::V_CNDMASK_B32_e64))
131  .addOperand(Dst)
132  .addImm(0)
133  .addImm(-1)
134  .addOperand(Src);
135  MI.eraseFromParent();
136  } else if (TRI->getCommonSubClass(DstRC, &AMDGPU::SGPR_64RegClass) &&
137  SrcRC == &AMDGPU::VReg_1RegClass) {
138  BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(AMDGPU::V_CMP_NE_I32_e64))
139  .addOperand(Dst)
140  .addOperand(Src)
141  .addImm(0);
142  MI.eraseFromParent();
143  }
144  }
145  }
146 
147  for (unsigned Reg : I1Defs)
148  MRI.setRegClass(Reg, &AMDGPU::VGPR_32RegClass);
149 
150  return false;
151 }
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
AMDGPU specific subclass of TargetSubtarget.
INITIALIZE_PASS_BEGIN(SILowerI1Copies, DEBUG_TYPE,"SI Lower i1 Copies", false, false) INITIALIZE_PASS_END(SILowerI1Copies
#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)
isVirtualRegister - Return true if the specified register number is in the virtual register namespace...
const TargetRegisterClass * getCommonSubClass(const TargetRegisterClass *A, const TargetRegisterClass *B) const
getCommonSubClass - find the largest common subclass of A and B.
A debug info location.
Definition: DebugLoc.h:34
COPY - Target-independent register copy.
Definition: TargetOpcodes.h:86
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:70
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.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:75
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const TargetRegisterClass * getRegClass(unsigned Reg) const
getRegClass - Return the register class of the specified virtual register.
Reg
All possible values of the reg field in the ModR/M byte.
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
FunctionPass * createSILowerI1CopiesPass()
int64_t getImm() const
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:267
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
Definition: TargetOpcodes.h:52
bundle_iterator< MachineInstr, instr_iterator > iterator
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:273
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:294
SI Lower i1 false
char & SILowerI1CopiesID
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
MachineOperand class - Representation of each machine instruction operand.
SI Lower i1 Copies
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:263
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:238
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:51
Interface definition for SIInstrInfo.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
#define I(x, y, z)
Definition: MD5.cpp:54
unsigned getReg() const
getReg - Returns the register number.
virtual const TargetInstrInfo * getInstrInfo() const
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
BasicBlockListType::iterator iterator
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
void setRegClass(unsigned Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
void initializeSILowerI1CopiesPass(PassRegistry &)
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...