1*9880d681SAndroid Build Coastguard Worker //===-- SILowerI1Copies.cpp - Lower I1 Copies -----------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker /// i1 values are usually inserted by the CFG Structurize pass and they are
9*9880d681SAndroid Build Coastguard Worker /// unique in that they can be copied from VALU to SALU registers.
10*9880d681SAndroid Build Coastguard Worker /// This is not possible for any other value type. Since there are no
11*9880d681SAndroid Build Coastguard Worker /// MOV instructions for i1, we to use V_CMP_* and V_CNDMASK to move the i1.
12*9880d681SAndroid Build Coastguard Worker ///
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker //
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "si-i1-copies"
17*9880d681SAndroid Build Coastguard Worker #include "AMDGPU.h"
18*9880d681SAndroid Build Coastguard Worker #include "AMDGPUSubtarget.h"
19*9880d681SAndroid Build Coastguard Worker #include "SIInstrInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LiveIntervalAnalysis.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Worker using namespace llvm;
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker namespace {
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Worker class SILowerI1Copies : public MachineFunctionPass {
34*9880d681SAndroid Build Coastguard Worker public:
35*9880d681SAndroid Build Coastguard Worker static char ID;
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker public:
SILowerI1Copies()38*9880d681SAndroid Build Coastguard Worker SILowerI1Copies() : MachineFunctionPass(ID) {
39*9880d681SAndroid Build Coastguard Worker initializeSILowerI1CopiesPass(*PassRegistry::getPassRegistry());
40*9880d681SAndroid Build Coastguard Worker }
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker bool runOnMachineFunction(MachineFunction &MF) override;
43*9880d681SAndroid Build Coastguard Worker
getPassName() const44*9880d681SAndroid Build Coastguard Worker const char *getPassName() const override {
45*9880d681SAndroid Build Coastguard Worker return "SI Lower i1 Copies";
46*9880d681SAndroid Build Coastguard Worker }
47*9880d681SAndroid Build Coastguard Worker
getAnalysisUsage(AnalysisUsage & AU) const48*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override {
49*9880d681SAndroid Build Coastguard Worker AU.setPreservesCFG();
50*9880d681SAndroid Build Coastguard Worker MachineFunctionPass::getAnalysisUsage(AU);
51*9880d681SAndroid Build Coastguard Worker }
52*9880d681SAndroid Build Coastguard Worker };
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Worker } // End anonymous namespace.
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(SILowerI1Copies, DEBUG_TYPE,
57*9880d681SAndroid Build Coastguard Worker "SI Lower i1 Copies", false, false)
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Worker char SILowerI1Copies::ID = 0;
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker char &llvm::SILowerI1CopiesID = SILowerI1Copies::ID;
62*9880d681SAndroid Build Coastguard Worker
createSILowerI1CopiesPass()63*9880d681SAndroid Build Coastguard Worker FunctionPass *llvm::createSILowerI1CopiesPass() {
64*9880d681SAndroid Build Coastguard Worker return new SILowerI1Copies();
65*9880d681SAndroid Build Coastguard Worker }
66*9880d681SAndroid Build Coastguard Worker
runOnMachineFunction(MachineFunction & MF)67*9880d681SAndroid Build Coastguard Worker bool SILowerI1Copies::runOnMachineFunction(MachineFunction &MF) {
68*9880d681SAndroid Build Coastguard Worker MachineRegisterInfo &MRI = MF.getRegInfo();
69*9880d681SAndroid Build Coastguard Worker const SISubtarget &ST = MF.getSubtarget<SISubtarget>();
70*9880d681SAndroid Build Coastguard Worker const SIInstrInfo *TII = ST.getInstrInfo();
71*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI = &TII->getRegisterInfo();
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Worker std::vector<unsigned> I1Defs;
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
76*9880d681SAndroid Build Coastguard Worker BI != BE; ++BI) {
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB = *BI;
79*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I, Next;
80*9880d681SAndroid Build Coastguard Worker for (I = MBB.begin(); I != MBB.end(); I = Next) {
81*9880d681SAndroid Build Coastguard Worker Next = std::next(I);
82*9880d681SAndroid Build Coastguard Worker MachineInstr &MI = *I;
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker if (MI.getOpcode() == AMDGPU::IMPLICIT_DEF) {
85*9880d681SAndroid Build Coastguard Worker unsigned Reg = MI.getOperand(0).getReg();
86*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = MRI.getRegClass(Reg);
87*9880d681SAndroid Build Coastguard Worker if (RC == &AMDGPU::VReg_1RegClass)
88*9880d681SAndroid Build Coastguard Worker MRI.setRegClass(Reg, &AMDGPU::SReg_64RegClass);
89*9880d681SAndroid Build Coastguard Worker continue;
90*9880d681SAndroid Build Coastguard Worker }
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Worker if (MI.getOpcode() != AMDGPU::COPY)
93*9880d681SAndroid Build Coastguard Worker continue;
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker const MachineOperand &Dst = MI.getOperand(0);
96*9880d681SAndroid Build Coastguard Worker const MachineOperand &Src = MI.getOperand(1);
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker if (!TargetRegisterInfo::isVirtualRegister(Src.getReg()) ||
99*9880d681SAndroid Build Coastguard Worker !TargetRegisterInfo::isVirtualRegister(Dst.getReg()))
100*9880d681SAndroid Build Coastguard Worker continue;
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *DstRC = MRI.getRegClass(Dst.getReg());
103*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *SrcRC = MRI.getRegClass(Src.getReg());
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Worker if (DstRC == &AMDGPU::VReg_1RegClass &&
106*9880d681SAndroid Build Coastguard Worker TRI->getCommonSubClass(SrcRC, &AMDGPU::SGPR_64RegClass)) {
107*9880d681SAndroid Build Coastguard Worker I1Defs.push_back(Dst.getReg());
108*9880d681SAndroid Build Coastguard Worker DebugLoc DL = MI.getDebugLoc();
109*9880d681SAndroid Build Coastguard Worker
110*9880d681SAndroid Build Coastguard Worker MachineInstr *DefInst = MRI.getUniqueVRegDef(Src.getReg());
111*9880d681SAndroid Build Coastguard Worker if (DefInst->getOpcode() == AMDGPU::S_MOV_B64) {
112*9880d681SAndroid Build Coastguard Worker if (DefInst->getOperand(1).isImm()) {
113*9880d681SAndroid Build Coastguard Worker I1Defs.push_back(Dst.getReg());
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker int64_t Val = DefInst->getOperand(1).getImm();
116*9880d681SAndroid Build Coastguard Worker assert(Val == 0 || Val == -1);
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, &MI, DL, TII->get(AMDGPU::V_MOV_B32_e32))
119*9880d681SAndroid Build Coastguard Worker .addOperand(Dst)
120*9880d681SAndroid Build Coastguard Worker .addImm(Val);
121*9880d681SAndroid Build Coastguard Worker MI.eraseFromParent();
122*9880d681SAndroid Build Coastguard Worker continue;
123*9880d681SAndroid Build Coastguard Worker }
124*9880d681SAndroid Build Coastguard Worker }
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, &MI, DL, TII->get(AMDGPU::V_CNDMASK_B32_e64))
127*9880d681SAndroid Build Coastguard Worker .addOperand(Dst)
128*9880d681SAndroid Build Coastguard Worker .addImm(0)
129*9880d681SAndroid Build Coastguard Worker .addImm(-1)
130*9880d681SAndroid Build Coastguard Worker .addOperand(Src);
131*9880d681SAndroid Build Coastguard Worker MI.eraseFromParent();
132*9880d681SAndroid Build Coastguard Worker } else if (TRI->getCommonSubClass(DstRC, &AMDGPU::SGPR_64RegClass) &&
133*9880d681SAndroid Build Coastguard Worker SrcRC == &AMDGPU::VReg_1RegClass) {
134*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(AMDGPU::V_CMP_NE_I32_e64))
135*9880d681SAndroid Build Coastguard Worker .addOperand(Dst)
136*9880d681SAndroid Build Coastguard Worker .addOperand(Src)
137*9880d681SAndroid Build Coastguard Worker .addImm(0);
138*9880d681SAndroid Build Coastguard Worker MI.eraseFromParent();
139*9880d681SAndroid Build Coastguard Worker }
140*9880d681SAndroid Build Coastguard Worker }
141*9880d681SAndroid Build Coastguard Worker }
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker for (unsigned Reg : I1Defs)
144*9880d681SAndroid Build Coastguard Worker MRI.setRegClass(Reg, &AMDGPU::VGPR_32RegClass);
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker return false;
147*9880d681SAndroid Build Coastguard Worker }
148