blob: 0e77e3d22ab9df1a7a767206d05d0f0d12541fe7 [file] [log] [blame]
Tom Stellard1bd80722014-04-30 15:31:33 +00001//===-- 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"
Eric Christopherd9134482014-08-04 21:25:23 +000018#include "AMDGPUSubtarget.h"
Tom Stellard1bd80722014-04-30 15:31:33 +000019#include "SIInstrInfo.h"
20#include "llvm/CodeGen/LiveIntervalAnalysis.h"
21#include "llvm/CodeGen/MachineDominators.h"
22#include "llvm/CodeGen/MachineFunctionPass.h"
23#include "llvm/CodeGen/MachineInstrBuilder.h"
24#include "llvm/CodeGen/MachineRegisterInfo.h"
25#include "llvm/IR/LLVMContext.h"
26#include "llvm/IR/Function.h"
27#include "llvm/Support/Debug.h"
28#include "llvm/Target/TargetMachine.h"
29
30using namespace llvm;
31
32namespace {
33
34class SILowerI1Copies : public MachineFunctionPass {
35public:
36 static char ID;
37
38public:
39 SILowerI1Copies() : MachineFunctionPass(ID) {
40 initializeSILowerI1CopiesPass(*PassRegistry::getPassRegistry());
41 }
42
43 virtual bool runOnMachineFunction(MachineFunction &MF) override;
44
45 virtual const char *getPassName() const override {
46 return "SI Lower il Copies";
47 }
48
49 virtual void getAnalysisUsage(AnalysisUsage &AU) const override {
50 AU.addRequired<MachineDominatorTree>();
51 AU.setPreservesCFG();
52 MachineFunctionPass::getAnalysisUsage(AU);
53 }
54};
55
56} // End anonymous namespace.
57
58INITIALIZE_PASS_BEGIN(SILowerI1Copies, DEBUG_TYPE,
59 "SI Lower il Copies", false, false)
60INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
61INITIALIZE_PASS_END(SILowerI1Copies, DEBUG_TYPE,
62 "SI Lower il Copies", false, false)
63
64char SILowerI1Copies::ID = 0;
65
66char &llvm::SILowerI1CopiesID = SILowerI1Copies::ID;
67
68FunctionPass *llvm::createSILowerI1CopiesPass() {
69 return new SILowerI1Copies();
70}
71
72bool SILowerI1Copies::runOnMachineFunction(MachineFunction &MF) {
73 MachineRegisterInfo &MRI = MF.getRegInfo();
74 const SIInstrInfo *TII = static_cast<const SIInstrInfo *>(
Eric Christopherd9134482014-08-04 21:25:23 +000075 MF.getTarget().getSubtargetImpl()->getInstrInfo());
76 const TargetRegisterInfo *TRI =
77 MF.getTarget().getSubtargetImpl()->getRegisterInfo();
Tom Stellard365a2b42014-05-15 14:41:50 +000078 std::vector<unsigned> I1Defs;
Tom Stellard1bd80722014-04-30 15:31:33 +000079
80 for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
81 BI != BE; ++BI) {
82
83 MachineBasicBlock &MBB = *BI;
84 MachineBasicBlock::iterator I, Next;
85 for (I = MBB.begin(); I != MBB.end(); I = Next) {
86 Next = std::next(I);
87 MachineInstr &MI = *I;
88
89 if (MI.getOpcode() == AMDGPU::V_MOV_I1) {
Tom Stellard365a2b42014-05-15 14:41:50 +000090 I1Defs.push_back(MI.getOperand(0).getReg());
Tom Stellard1bd80722014-04-30 15:31:33 +000091 MI.setDesc(TII->get(AMDGPU::V_MOV_B32_e32));
92 continue;
93 }
94
Tom Stellard365a2b42014-05-15 14:41:50 +000095 if (MI.getOpcode() == AMDGPU::V_AND_I1) {
96 I1Defs.push_back(MI.getOperand(0).getReg());
97 MI.setDesc(TII->get(AMDGPU::V_AND_B32_e32));
98 continue;
99 }
100
101 if (MI.getOpcode() == AMDGPU::V_OR_I1) {
102 I1Defs.push_back(MI.getOperand(0).getReg());
103 MI.setDesc(TII->get(AMDGPU::V_OR_B32_e32));
104 continue;
105 }
106
Tom Stellard54a3b652014-07-21 14:01:10 +0000107 if (MI.getOpcode() == AMDGPU::V_XOR_I1) {
108 I1Defs.push_back(MI.getOperand(0).getReg());
109 MI.setDesc(TII->get(AMDGPU::V_XOR_B32_e32));
110 continue;
111 }
112
Tom Stellard1bd80722014-04-30 15:31:33 +0000113 if (MI.getOpcode() != AMDGPU::COPY ||
114 !TargetRegisterInfo::isVirtualRegister(MI.getOperand(0).getReg()) ||
115 !TargetRegisterInfo::isVirtualRegister(MI.getOperand(1).getReg()))
116 continue;
117
118
119 const TargetRegisterClass *DstRC =
120 MRI.getRegClass(MI.getOperand(0).getReg());
121 const TargetRegisterClass *SrcRC =
122 MRI.getRegClass(MI.getOperand(1).getReg());
123
124 if (DstRC == &AMDGPU::VReg_1RegClass &&
125 TRI->getCommonSubClass(SrcRC, &AMDGPU::SGPR_64RegClass)) {
Tom Stellard365a2b42014-05-15 14:41:50 +0000126 I1Defs.push_back(MI.getOperand(0).getReg());
Tom Stellard1bd80722014-04-30 15:31:33 +0000127 BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(AMDGPU::V_CNDMASK_B32_e64))
128 .addOperand(MI.getOperand(0))
129 .addImm(0)
130 .addImm(-1)
131 .addOperand(MI.getOperand(1))
132 .addImm(0)
133 .addImm(0)
134 .addImm(0)
135 .addImm(0);
136 MI.eraseFromParent();
137 } else if (TRI->getCommonSubClass(DstRC, &AMDGPU::SGPR_64RegClass) &&
138 SrcRC == &AMDGPU::VReg_1RegClass) {
139 BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(AMDGPU::V_CMP_NE_I32_e64))
140 .addOperand(MI.getOperand(0))
Tom Stellard1bd80722014-04-30 15:31:33 +0000141 .addOperand(MI.getOperand(1))
Tom Stellard1bd80722014-04-30 15:31:33 +0000142 .addImm(0);
143 MI.eraseFromParent();
144 }
Tom Stellard1bd80722014-04-30 15:31:33 +0000145 }
146 }
Tom Stellard365a2b42014-05-15 14:41:50 +0000147
148 for (unsigned Reg : I1Defs)
149 MRI.setRegClass(Reg, &AMDGPU::VReg_32RegClass);
150
Tom Stellard1bd80722014-04-30 15:31:33 +0000151 return false;
152}