OSDN Git Service

radeonsi: initial WIP SI code
[android-x86/external-mesa.git] / src / gallium / drivers / radeon / AMDILMachinePeephole.cpp
1 //===-- AMDILMachinePeephole.cpp - AMDIL Machine Peephole Pass -*- C++ -*-===//
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 //==-----------------------------------------------------------------------===//
9
10
11 #define DEBUG_TYPE "machine_peephole"
12 #if !defined(NDEBUG)
13 #define DEBUGME (DebugFlag && isCurrentDebugType(DEBUG_TYPE))
14 #else
15 #define DEBUGME (false)
16 #endif
17
18 #include "AMDIL.h"
19 #include "AMDILSubtarget.h"
20 #include "AMDILUtilityFunctions.h"
21 #include "llvm/CodeGen/MachineFunctionPass.h"
22 #include "llvm/CodeGen/MachineRegisterInfo.h"
23 #include "llvm/Support/Debug.h"
24 #include "llvm/Target/TargetMachine.h"
25
26 using namespace llvm;
27 namespace
28 {
29   class AMDILMachinePeephole : public MachineFunctionPass
30   {
31     public:
32       static char ID;
33       AMDILMachinePeephole(TargetMachine &tm AMDIL_OPT_LEVEL_DECL);
34       //virtual ~AMDILMachinePeephole();
35       virtual const char*
36         getPassName() const;
37       virtual bool
38         runOnMachineFunction(MachineFunction &MF);
39     private:
40       void insertFence(MachineBasicBlock::iterator &MIB);
41       TargetMachine &TM;
42       bool mDebug;
43   }; // AMDILMachinePeephole
44   char AMDILMachinePeephole::ID = 0;
45 } // anonymous namespace
46
47 namespace llvm
48 {
49   FunctionPass*
50     createAMDILMachinePeephole(TargetMachine &tm AMDIL_OPT_LEVEL_DECL)
51     {
52       return new AMDILMachinePeephole(tm AMDIL_OPT_LEVEL_VAR);
53     }
54 } // llvm namespace
55
56 AMDILMachinePeephole::AMDILMachinePeephole(TargetMachine &tm AMDIL_OPT_LEVEL_DECL)
57   : MachineFunctionPass(ID), TM(tm)
58 {
59   mDebug = DEBUGME;
60 }
61
62 bool
63 AMDILMachinePeephole::runOnMachineFunction(MachineFunction &MF)
64 {
65   bool Changed = false;
66   const AMDILSubtarget *STM = &TM.getSubtarget<AMDILSubtarget>();
67   for (MachineFunction::iterator MBB = MF.begin(), MBE = MF.end();
68       MBB != MBE; ++MBB) {
69     MachineBasicBlock *mb = MBB;
70     for (MachineBasicBlock::iterator MIB = mb->begin(), MIE = mb->end();
71         MIB != MIE; ++MIB) {
72       MachineInstr *mi = MIB;
73       const char * name;
74       name = TM.getInstrInfo()->getName(mi->getOpcode());
75       switch (mi->getOpcode()) {
76         default:
77           if (isAtomicInst(TM.getInstrInfo(), mi)) {
78             // If we don't support the hardware accellerated address spaces,
79             // then the atomic needs to be transformed to the global atomic.
80             if (strstr(name, "_L_")
81                 && STM->device()->usesSoftware(AMDILDeviceInfo::LocalMem)) {
82               BuildMI(*mb, MIB, mi->getDebugLoc(), 
83                   TM.getInstrInfo()->get(AMDIL::ADD_i32), AMDIL::R1011)
84                 .addReg(mi->getOperand(1).getReg())
85                 .addReg(AMDIL::T2);
86               mi->getOperand(1).setReg(AMDIL::R1011);
87               mi->setDesc(
88                   TM.getInstrInfo()->get(
89                     (mi->getOpcode() - AMDIL::ATOM_L_ADD) + AMDIL::ATOM_G_ADD));
90             } else if (strstr(name, "_R_")
91                 && STM->device()->usesSoftware(AMDILDeviceInfo::RegionMem)) {
92               assert(!"Software region memory is not supported!");
93               mi->setDesc(
94                   TM.getInstrInfo()->get(
95                     (mi->getOpcode() - AMDIL::ATOM_R_ADD) + AMDIL::ATOM_G_ADD));
96             }
97           } else if ((isLoadInst(TM.getInstrInfo(), mi) || isStoreInst(TM.getInstrInfo(), mi)) && isVolatileInst(TM.getInstrInfo(), mi)) {
98             insertFence(MIB);
99           }
100           continue;
101           break;
102         case AMDIL::USHR_i16:
103         case AMDIL::USHR_v2i16:
104         case AMDIL::USHR_v4i16:
105         case AMDIL::USHRVEC_i16:
106         case AMDIL::USHRVEC_v2i16:
107         case AMDIL::USHRVEC_v4i16:
108           if (TM.getSubtarget<AMDILSubtarget>()
109               .device()->usesSoftware(AMDILDeviceInfo::ShortOps)) {
110             unsigned lReg = MF.getRegInfo()
111               .createVirtualRegister(&AMDIL::GPRI32RegClass);
112             unsigned Reg = MF.getRegInfo()
113               .createVirtualRegister(&AMDIL::GPRV4I32RegClass);
114             BuildMI(*mb, MIB, mi->getDebugLoc(),
115                 TM.getInstrInfo()->get(AMDIL::LOADCONST_i32),
116                 lReg).addImm(0xFFFF);
117             BuildMI(*mb, MIB, mi->getDebugLoc(),
118                 TM.getInstrInfo()->get(AMDIL::BINARY_AND_v4i32),
119                 Reg)
120               .addReg(mi->getOperand(1).getReg())
121               .addReg(lReg);
122             mi->getOperand(1).setReg(Reg);
123           }
124           break;
125         case AMDIL::USHR_i8:
126         case AMDIL::USHR_v2i8:
127         case AMDIL::USHR_v4i8:
128         case AMDIL::USHRVEC_i8:
129         case AMDIL::USHRVEC_v2i8:
130         case AMDIL::USHRVEC_v4i8:
131           if (TM.getSubtarget<AMDILSubtarget>()
132               .device()->usesSoftware(AMDILDeviceInfo::ByteOps)) {
133             unsigned lReg = MF.getRegInfo()
134               .createVirtualRegister(&AMDIL::GPRI32RegClass);
135             unsigned Reg = MF.getRegInfo()
136               .createVirtualRegister(&AMDIL::GPRV4I32RegClass);
137             BuildMI(*mb, MIB, mi->getDebugLoc(),
138                 TM.getInstrInfo()->get(AMDIL::LOADCONST_i32),
139                 lReg).addImm(0xFF);
140             BuildMI(*mb, MIB, mi->getDebugLoc(),
141                 TM.getInstrInfo()->get(AMDIL::BINARY_AND_v4i32),
142                 Reg)
143               .addReg(mi->getOperand(1).getReg())
144               .addReg(lReg);
145             mi->getOperand(1).setReg(Reg);
146           }
147           break;
148       }
149     }
150   }
151   return Changed;
152 }
153
154 const char*
155 AMDILMachinePeephole::getPassName() const
156 {
157   return "AMDIL Generic Machine Peephole Optimization Pass";
158 }
159
160 void
161 AMDILMachinePeephole::insertFence(MachineBasicBlock::iterator &MIB)
162 {
163   MachineInstr *MI = MIB;
164   MachineInstr *fence = BuildMI(*(MI->getParent()->getParent()),
165         MI->getDebugLoc(),
166         TM.getInstrInfo()->get(AMDIL::FENCE)).addReg(1);
167
168   MI->getParent()->insert(MIB, fence);
169   fence = BuildMI(*(MI->getParent()->getParent()),
170         MI->getDebugLoc(),
171         TM.getInstrInfo()->get(AMDIL::FENCE)).addReg(1);
172   MIB = MI->getParent()->insertAfter(MIB, fence);
173 }