LLVM API Documentation

SILowerI1Copies.cpp
Go to the documentation of this file.
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 }