LLVM API Documentation
00001 //===-- SILowerI1Copies.cpp - Lower I1 Copies -----------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 /// i1 values are usually inserted by the CFG Structurize pass and they are 00009 /// unique in that they can be copied from VALU to SALU registers. 00010 /// This is not possible for any other value type. Since there are no 00011 /// MOV instructions for i1, we to use V_CMP_* and V_CNDMASK to move the i1. 00012 /// 00013 //===----------------------------------------------------------------------===// 00014 // 00015 00016 #define DEBUG_TYPE "si-i1-copies" 00017 #include "AMDGPU.h" 00018 #include "AMDGPUSubtarget.h" 00019 #include "SIInstrInfo.h" 00020 #include "llvm/CodeGen/LiveIntervalAnalysis.h" 00021 #include "llvm/CodeGen/MachineDominators.h" 00022 #include "llvm/CodeGen/MachineFunctionPass.h" 00023 #include "llvm/CodeGen/MachineInstrBuilder.h" 00024 #include "llvm/CodeGen/MachineRegisterInfo.h" 00025 #include "llvm/IR/LLVMContext.h" 00026 #include "llvm/IR/Function.h" 00027 #include "llvm/Support/Debug.h" 00028 #include "llvm/Target/TargetMachine.h" 00029 00030 using namespace llvm; 00031 00032 namespace { 00033 00034 class SILowerI1Copies : public MachineFunctionPass { 00035 public: 00036 static char ID; 00037 00038 public: 00039 SILowerI1Copies() : MachineFunctionPass(ID) { 00040 initializeSILowerI1CopiesPass(*PassRegistry::getPassRegistry()); 00041 } 00042 00043 bool runOnMachineFunction(MachineFunction &MF) override; 00044 00045 const char *getPassName() const override { 00046 return "SI Lower il Copies"; 00047 } 00048 00049 void getAnalysisUsage(AnalysisUsage &AU) const override { 00050 AU.addRequired<MachineDominatorTree>(); 00051 AU.setPreservesCFG(); 00052 MachineFunctionPass::getAnalysisUsage(AU); 00053 } 00054 }; 00055 00056 } // End anonymous namespace. 00057 00058 INITIALIZE_PASS_BEGIN(SILowerI1Copies, DEBUG_TYPE, 00059 "SI Lower il Copies", false, false) 00060 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) 00061 INITIALIZE_PASS_END(SILowerI1Copies, DEBUG_TYPE, 00062 "SI Lower il Copies", false, false) 00063 00064 char SILowerI1Copies::ID = 0; 00065 00066 char &llvm::SILowerI1CopiesID = SILowerI1Copies::ID; 00067 00068 FunctionPass *llvm::createSILowerI1CopiesPass() { 00069 return new SILowerI1Copies(); 00070 } 00071 00072 bool SILowerI1Copies::runOnMachineFunction(MachineFunction &MF) { 00073 MachineRegisterInfo &MRI = MF.getRegInfo(); 00074 const SIInstrInfo *TII = 00075 static_cast<const SIInstrInfo *>(MF.getSubtarget().getInstrInfo()); 00076 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 00077 std::vector<unsigned> I1Defs; 00078 00079 for (MachineFunction::iterator BI = MF.begin(), BE = MF.end(); 00080 BI != BE; ++BI) { 00081 00082 MachineBasicBlock &MBB = *BI; 00083 MachineBasicBlock::iterator I, Next; 00084 for (I = MBB.begin(); I != MBB.end(); I = Next) { 00085 Next = std::next(I); 00086 MachineInstr &MI = *I; 00087 00088 if (MI.getOpcode() == AMDGPU::V_MOV_I1) { 00089 I1Defs.push_back(MI.getOperand(0).getReg()); 00090 MI.setDesc(TII->get(AMDGPU::V_MOV_B32_e32)); 00091 continue; 00092 } 00093 00094 if (MI.getOpcode() == AMDGPU::V_AND_I1) { 00095 I1Defs.push_back(MI.getOperand(0).getReg()); 00096 MI.setDesc(TII->get(AMDGPU::V_AND_B32_e32)); 00097 continue; 00098 } 00099 00100 if (MI.getOpcode() == AMDGPU::V_OR_I1) { 00101 I1Defs.push_back(MI.getOperand(0).getReg()); 00102 MI.setDesc(TII->get(AMDGPU::V_OR_B32_e32)); 00103 continue; 00104 } 00105 00106 if (MI.getOpcode() == AMDGPU::V_XOR_I1) { 00107 I1Defs.push_back(MI.getOperand(0).getReg()); 00108 MI.setDesc(TII->get(AMDGPU::V_XOR_B32_e32)); 00109 continue; 00110 } 00111 00112 if (MI.getOpcode() != AMDGPU::COPY || 00113 !TargetRegisterInfo::isVirtualRegister(MI.getOperand(0).getReg()) || 00114 !TargetRegisterInfo::isVirtualRegister(MI.getOperand(1).getReg())) 00115 continue; 00116 00117 00118 const TargetRegisterClass *DstRC = 00119 MRI.getRegClass(MI.getOperand(0).getReg()); 00120 const TargetRegisterClass *SrcRC = 00121 MRI.getRegClass(MI.getOperand(1).getReg()); 00122 00123 if (DstRC == &AMDGPU::VReg_1RegClass && 00124 TRI->getCommonSubClass(SrcRC, &AMDGPU::SGPR_64RegClass)) { 00125 I1Defs.push_back(MI.getOperand(0).getReg()); 00126 BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(AMDGPU::V_CNDMASK_B32_e64)) 00127 .addOperand(MI.getOperand(0)) 00128 .addImm(0) 00129 .addImm(-1) 00130 .addOperand(MI.getOperand(1)) 00131 .addImm(0) 00132 .addImm(0) 00133 .addImm(0) 00134 .addImm(0); 00135 MI.eraseFromParent(); 00136 } else if (TRI->getCommonSubClass(DstRC, &AMDGPU::SGPR_64RegClass) && 00137 SrcRC == &AMDGPU::VReg_1RegClass) { 00138 BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(AMDGPU::V_CMP_NE_I32_e64)) 00139 .addOperand(MI.getOperand(0)) 00140 .addOperand(MI.getOperand(1)) 00141 .addImm(0); 00142 MI.eraseFromParent(); 00143 } 00144 } 00145 } 00146 00147 for (unsigned Reg : I1Defs) 00148 MRI.setRegClass(Reg, &AMDGPU::VReg_32RegClass); 00149 00150 return false; 00151 }