llvm.org GIT mirror llvm / 04c5595
R600: Simplify handling of private address space The AMDGPUIndirectAddressing pass was previously responsible for lowering private loads and stores to indirect addressing instructions. However, this pass was buggy and way too complicated. The only advantage it had over the new simplified code was that it saved one instruction per direct write to private memory. This optimization likely has a minimal impact on performance, and we may be able to duplicate it using some other transformation. For the private address space, we now: 1. Lower private loads/store to Register(Load|Store) instructions 2. Reserve part of the register file as 'private memory' 3. After regalloc lower the Register(Load|Store) instructions to MOV instructions that use indirect addressing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193179 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 6 years ago
14 changed file(s) with 134 addition(s) and 436 deletion(s). Raw diff Collapse all Expand all
4444 // Passes common to R600 and SI
4545 Pass *createAMDGPUStructurizeCFGPass();
4646 FunctionPass *createAMDGPUConvertToISAPass(TargetMachine &tm);
47 FunctionPass *createAMDGPUIndirectAddressingPass(TargetMachine &tm);
4847 FunctionPass *createAMDGPUISelDag(TargetMachine &tm);
4948
5049 /// \brief Creates an AMDGPU-specific Target Transformation Info pass.
+0
-345
lib/Target/R600/AMDGPUIndirectAddressing.cpp less more
None //===-- AMDGPUIndirectAddressing.cpp - Indirect Adressing Support ---------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 ///
11 /// Instructions can use indirect addressing to index the register file as if it
12 /// were memory. This pass lowers RegisterLoad and RegisterStore instructions
13 /// to either a COPY or a MOV that uses indirect addressing.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #include "AMDGPU.h"
18 #include "R600InstrInfo.h"
19 #include "R600MachineFunctionInfo.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineFunctionPass.h"
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/Support/Debug.h"
25
26 using namespace llvm;
27
28 namespace {
29
30 class AMDGPUIndirectAddressingPass : public MachineFunctionPass {
31
32 private:
33 static char ID;
34 const AMDGPUInstrInfo *TII;
35
36 bool regHasExplicitDef(MachineRegisterInfo &MRI, unsigned Reg) const;
37
38 public:
39 AMDGPUIndirectAddressingPass(TargetMachine &tm) :
40 MachineFunctionPass(ID),
41 TII(0)
42 { }
43
44 virtual bool runOnMachineFunction(MachineFunction &MF);
45
46 const char *getPassName() const { return "R600 Handle indirect addressing"; }
47
48 };
49
50 } // End anonymous namespace
51
52 char AMDGPUIndirectAddressingPass::ID = 0;
53
54 FunctionPass *llvm::createAMDGPUIndirectAddressingPass(TargetMachine &tm) {
55 return new AMDGPUIndirectAddressingPass(tm);
56 }
57
58 bool AMDGPUIndirectAddressingPass::runOnMachineFunction(MachineFunction &MF) {
59 MachineRegisterInfo &MRI = MF.getRegInfo();
60
61 TII = static_cast(MF.getTarget().getInstrInfo());
62
63 int IndirectBegin = TII->getIndirectIndexBegin(MF);
64 int IndirectEnd = TII->getIndirectIndexEnd(MF);
65
66 if (IndirectBegin == -1) {
67 // No indirect addressing, we can skip this pass
68 assert(IndirectEnd == -1);
69 return false;
70 }
71
72 // The map keeps track of the indirect address that is represented by
73 // each virtual register. The key is the register and the value is the
74 // indirect address it uses.
75 std::map RegisterAddressMap;
76
77 // First pass - Lower all of the RegisterStore instructions and track which
78 // registers are live.
79 for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
80 BB != BB_E; ++BB) {
81 // This map keeps track of the current live indirect registers.
82 // The key is the address and the value is the register
83 std::map LiveAddressRegisterMap;
84 MachineBasicBlock &MBB = *BB;
85
86 for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I);
87 I != MBB.end(); I = Next) {
88 Next = llvm::next(I);
89 MachineInstr &MI = *I;
90
91 if (!TII->isRegisterStore(MI)) {
92 continue;
93 }
94
95 // Lower RegisterStore
96
97 unsigned RegIndex = MI.getOperand(2).getImm();
98 unsigned Channel = MI.getOperand(3).getImm();
99 unsigned Address = TII->calculateIndirectAddress(RegIndex, Channel);
100 const TargetRegisterClass *IndirectStoreRegClass =
101 TII->getIndirectAddrStoreRegClass(MI.getOperand(0).getReg());
102
103 if (MI.getOperand(1).getReg() == AMDGPU::INDIRECT_BASE_ADDR) {
104 // Direct register access.
105 unsigned DstReg = MRI.createVirtualRegister(IndirectStoreRegClass);
106
107 BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY), DstReg)
108 .addOperand(MI.getOperand(0));
109
110 RegisterAddressMap[DstReg] = Address;
111 LiveAddressRegisterMap[Address] = DstReg;
112 } else {
113 // Indirect register access.
114 MachineInstrBuilder MOV = TII->buildIndirectWrite(BB, I,
115 MI.getOperand(0).getReg(), // Value
116 Address,
117 MI.getOperand(1).getReg()); // Offset
118 for (int i = IndirectBegin; i <= IndirectEnd; ++i) {
119 unsigned Addr = TII->calculateIndirectAddress(i, Channel);
120 unsigned DstReg = MRI.createVirtualRegister(IndirectStoreRegClass);
121 MOV.addReg(DstReg, RegState::Define | RegState::Implicit);
122 RegisterAddressMap[DstReg] = Addr;
123 LiveAddressRegisterMap[Addr] = DstReg;
124 }
125 }
126 MI.eraseFromParent();
127 }
128
129 // Update the live-ins of the succesor blocks
130 for (MachineBasicBlock::succ_iterator Succ = MBB.succ_begin(),
131 SuccEnd = MBB.succ_end();
132 SuccEnd != Succ; ++Succ) {
133 std::map::const_iterator Key, KeyEnd;
134 for (Key = LiveAddressRegisterMap.begin(),
135 KeyEnd = LiveAddressRegisterMap.end(); KeyEnd != Key; ++Key) {
136 (*Succ)->addLiveIn(Key->second);
137 }
138 }
139 }
140
141 // Second pass - Lower the RegisterLoad instructions
142 for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
143 BB != BB_E; ++BB) {
144 // Key is the address and the value is the register
145 std::map LiveAddressRegisterMap;
146 MachineBasicBlock &MBB = *BB;
147
148 MachineBasicBlock::livein_iterator LI = MBB.livein_begin();
149 while (LI != MBB.livein_end()) {
150 std::vector PhiRegisters;
151
152 // Make sure this live in is used for indirect addressing
153 if (RegisterAddressMap.find(*LI) == RegisterAddressMap.end()) {
154 ++LI;
155 continue;
156 }
157
158 unsigned Address = RegisterAddressMap[*LI];
159 LiveAddressRegisterMap[Address] = *LI;
160 PhiRegisters.push_back(*LI);
161
162 // Check if there are other live in registers which map to the same
163 // indirect address.
164 for (MachineBasicBlock::livein_iterator LJ = llvm::next(LI),
165 LE = MBB.livein_end();
166 LJ != LE; ++LJ) {
167 unsigned Reg = *LJ;
168 if (RegisterAddressMap.find(Reg) == RegisterAddressMap.end()) {
169 continue;
170 }
171
172 if (RegisterAddressMap[Reg] == Address) {
173 PhiRegisters.push_back(Reg);
174 }
175 }
176
177 if (PhiRegisters.size() == 1) {
178 // We don't need to insert a Phi instruction, so we can just add the
179 // registers to the live list for the block.
180 LiveAddressRegisterMap[Address] = *LI;
181 MBB.removeLiveIn(*LI);
182 } else {
183 // We need to insert a PHI, because we have the same address being
184 // written in multiple predecessor blocks.
185 const TargetRegisterClass *PhiDstClass =
186 TII->getIndirectAddrStoreRegClass(*(PhiRegisters.begin()));
187 unsigned PhiDstReg = MRI.createVirtualRegister(PhiDstClass);
188 MachineInstrBuilder Phi = BuildMI(MBB, MBB.begin(),
189 MBB.findDebugLoc(MBB.begin()),
190 TII->get(AMDGPU::PHI), PhiDstReg);
191
192 for (std::vector::const_iterator RI = PhiRegisters.begin(),
193 RE = PhiRegisters.end();
194 RI != RE; ++RI) {
195 unsigned Reg = *RI;
196 MachineInstr *DefInst = MRI.getVRegDef(Reg);
197 assert(DefInst);
198 MachineBasicBlock *RegBlock = DefInst->getParent();
199 Phi.addReg(Reg);
200 Phi.addMBB(RegBlock);
201 MBB.removeLiveIn(Reg);
202 }
203 RegisterAddressMap[PhiDstReg] = Address;
204 LiveAddressRegisterMap[Address] = PhiDstReg;
205 }
206 LI = MBB.livein_begin();
207 }
208
209 for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I);
210 I != MBB.end(); I = Next) {
211 Next = llvm::next(I);
212 MachineInstr &MI = *I;
213
214 if (!TII->isRegisterLoad(MI)) {
215 if (MI.getOpcode() == AMDGPU::PHI) {
216 continue;
217 }
218 // Check for indirect register defs
219 for (unsigned OpIdx = 0, NumOperands = MI.getNumOperands();
220 OpIdx < NumOperands; ++OpIdx) {
221 MachineOperand &MO = MI.getOperand(OpIdx);
222 if (MO.isReg() && MO.isDef() &&
223 RegisterAddressMap.find(MO.getReg()) != RegisterAddressMap.end()) {
224 unsigned Reg = MO.getReg();
225 unsigned LiveAddress = RegisterAddressMap[Reg];
226 // Chain the live-ins
227 if (LiveAddressRegisterMap.find(LiveAddress) !=
228 LiveAddressRegisterMap.end()) {
229 MI.addOperand(MachineOperand::CreateReg(
230 LiveAddressRegisterMap[LiveAddress],
231 false, // isDef
232 true, // isImp
233 true)); // isKill
234 }
235 LiveAddressRegisterMap[LiveAddress] = Reg;
236 }
237 }
238 continue;
239 }
240
241 const TargetRegisterClass *SuperIndirectRegClass =
242 TII->getSuperIndirectRegClass();
243 const TargetRegisterClass *IndirectLoadRegClass =
244 TII->getIndirectAddrLoadRegClass();
245 unsigned IndirectReg = MRI.createVirtualRegister(SuperIndirectRegClass);
246
247 unsigned RegIndex = MI.getOperand(2).getImm();
248 unsigned Channel = MI.getOperand(3).getImm();
249 unsigned Address = TII->calculateIndirectAddress(RegIndex, Channel);
250
251 if (MI.getOperand(1).getReg() == AMDGPU::INDIRECT_BASE_ADDR) {
252 // Direct register access
253 unsigned Reg = LiveAddressRegisterMap[Address];
254 unsigned AddrReg = IndirectLoadRegClass->getRegister(Address);
255
256 if (regHasExplicitDef(MRI, Reg)) {
257 // If the register we are reading from has an explicit def, then that
258 // means it was written via a direct register access (i.e. COPY
259 // or other instruction that doesn't use indirect addressing). In
260 // this case we know where the value has been stored, so we can just
261 // issue a copy.
262 BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY),
263 MI.getOperand(0).getReg())
264 .addReg(Reg);
265 } else {
266 // If the register we are reading has an implicit def, then that
267 // means it was written by an indirect register access (i.e. An
268 // instruction that uses indirect addressing.
269 BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY),
270 MI.getOperand(0).getReg())
271 .addReg(AddrReg)
272 .addReg(Reg, RegState::Implicit);
273 }
274 } else {
275 // Indirect register access
276
277 // Note on REQ_SEQUENCE instructions: You can't actually use the register
278 // it defines unless you have an instruction that takes the defined
279 // register class as an operand.
280
281 MachineInstrBuilder Sequence = BuildMI(MBB, I, MBB.findDebugLoc(I),
282 TII->get(AMDGPU::REG_SEQUENCE),
283 IndirectReg);
284 for (int i = IndirectBegin; i <= IndirectEnd; ++i) {
285 unsigned Addr = TII->calculateIndirectAddress(i, Channel);
286 if (LiveAddressRegisterMap.find(Addr) == LiveAddressRegisterMap.end()) {
287 continue;
288 }
289 unsigned Reg = LiveAddressRegisterMap[Addr];
290
291 // We only need to use REG_SEQUENCE for explicit defs, since the
292 // register coalescer won't do anything with the implicit defs.
293 if (!regHasExplicitDef(MRI, Reg)) {
294 continue;
295 }
296
297 // Insert a REQ_SEQUENCE instruction to force the register allocator
298 // to allocate the virtual register to the correct physical register.
299 Sequence.addReg(LiveAddressRegisterMap[Addr]);
300 Sequence.addImm(TII->getRegisterInfo().getIndirectSubReg(Addr));
301 }
302 MachineInstrBuilder Mov = TII->buildIndirectRead(BB, I,
303 MI.getOperand(0).getReg(), // Value
304 Address,
305 MI.getOperand(1).getReg()); // Offset
306
307
308
309 Mov.addReg(IndirectReg, RegState::Implicit | RegState::Kill);
310 Mov.addReg(LiveAddressRegisterMap[Address], RegState::Implicit);
311
312 }
313 MI.eraseFromParent();
314 }
315 }
316 return false;
317 }
318
319 bool AMDGPUIndirectAddressingPass::regHasExplicitDef(MachineRegisterInfo &MRI,
320 unsigned Reg) const {
321 MachineInstr *DefInstr = MRI.getVRegDef(Reg);
322
323 if (!DefInstr) {
324 return false;
325 }
326
327 if (DefInstr->getOpcode() == AMDGPU::PHI) {
328 bool Explicit = false;
329 for (MachineInstr::const_mop_iterator I = DefInstr->operands_begin(),
330 E = DefInstr->operands_end();
331 I != E; ++I) {
332 const MachineOperand &MO = *I;
333 if (!MO.isReg() || MO.isDef()) {
334 continue;
335 }
336
337 Explicit = Explicit || regHasExplicitDef(MRI, MO.getReg());
338 }
339 return Explicit;
340 }
341
342 return DefInstr->getOperand(0).isReg() &&
343 DefInstr->getOperand(0).getReg() == Reg;
344 }
117117 assert(!"Not Implemented");
118118 }
119119
120 bool AMDGPUInstrInfo::expandPostRAPseudo (MachineBasicBlock::iterator MI) const {
121 MachineBasicBlock *MBB = MI->getParent();
122
123 switch(MI->getOpcode()) {
124 default:
125 if (isRegisterLoad(*MI)) {
126 unsigned RegIndex = MI->getOperand(2).getImm();
127 unsigned Channel = MI->getOperand(3).getImm();
128 unsigned Address = calculateIndirectAddress(RegIndex, Channel);
129 unsigned OffsetReg = MI->getOperand(1).getReg();
130 if (OffsetReg == AMDGPU::INDIRECT_BASE_ADDR) {
131 buildMovInstr(MBB, MI, MI->getOperand(0).getReg(),
132 getIndirectAddrRegClass()->getRegister(Address));
133 } else {
134 buildIndirectRead(MBB, MI, MI->getOperand(0).getReg(),
135 Address, OffsetReg);
136 }
137 } else if (isRegisterStore(*MI)) {
138 unsigned RegIndex = MI->getOperand(2).getImm();
139 unsigned Channel = MI->getOperand(3).getImm();
140 unsigned Address = calculateIndirectAddress(RegIndex, Channel);
141 unsigned OffsetReg = MI->getOperand(1).getReg();
142 if (OffsetReg == AMDGPU::INDIRECT_BASE_ADDR) {
143 buildMovInstr(MBB, MI, getIndirectAddrRegClass()->getRegister(Address),
144 MI->getOperand(0).getReg());
145 } else {
146 buildIndirectWrite(MBB, MI, MI->getOperand(0).getReg(),
147 calculateIndirectAddress(RegIndex, Channel),
148 OffsetReg);
149 }
150 } else {
151 return false;
152 }
153 }
154
155 MBB->erase(MI);
156 return true;
157 }
158
159
120160 MachineInstr *
121161 AMDGPUInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
122162 MachineInstr *MI,
8686 unsigned DestReg, int FrameIndex,
8787 const TargetRegisterClass *RC,
8888 const TargetRegisterInfo *TRI) const;
89 virtual bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const;
90
8991
9092 protected:
9193 MachineInstr *foldMemoryOperandImpl(MachineFunction &MF,
159161 virtual unsigned calculateIndirectAddress(unsigned RegIndex,
160162 unsigned Channel) const = 0;
161163
162 /// \returns The register class to be used for storing values to an
163 /// "Indirect Address" .
164 virtual const TargetRegisterClass *getIndirectAddrStoreRegClass(
165 unsigned SourceReg) const = 0;
166
167 /// \returns The register class to be used for loading values from
168 /// an "Indirect Address" .
169 virtual const TargetRegisterClass *getIndirectAddrLoadRegClass() const = 0;
164 /// \returns The register class to be used for loading and storing values
165 /// from an "Indirect Address" .
166 virtual const TargetRegisterClass *getIndirectAddrRegClass() const = 0;
170167
171168 /// \brief Build instruction(s) for an indirect register write.
172169 ///
184181 unsigned ValueReg, unsigned Address,
185182 unsigned OffsetReg) const = 0;
186183
187 /// \returns the register class whose sub registers are the set of all
188 /// possible registers that can be used for indirect addressing.
189 virtual const TargetRegisterClass *getSuperIndirectRegClass() const = 0;
190
191184
192185 /// \brief Convert the AMDIL MachineInstr to a supported ISA
193186 /// MachineInstr
194187 virtual void convertToISA(MachineInstr & MI, MachineFunction &MF,
195188 DebugLoc DL) const;
196189
190 /// \brief Build a MOV instruction.
191 virtual MachineInstr *buildMovInstr(MachineBasicBlock *MBB,
192 MachineBasicBlock::iterator I,
193 unsigned DstReg, unsigned SrcReg) const = 0;
194
197195 /// \brief Given a MIMG \p Opcode that writes all 4 channels, return the
198196 /// equivalent opcode that writes \p Channels Channels.
199197 int getMaskedMIMGOp(uint16_t Opcode, unsigned Channels) const;
198
200199 };
201200
202201 namespace AMDGPU {
138138
139139 bool AMDGPUPassConfig::addInstSelector() {
140140 addPass(createAMDGPUISelDag(getAMDGPUTargetMachine()));
141
142 const AMDGPUSubtarget &ST = TM->getSubtarget();
143 if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) {
144 // This callbacks this pass uses are not implemented yet on SI.
145 addPass(createAMDGPUIndirectAddressingPass(*TM));
146 }
147141 return false;
148142 }
149143
1616 AMDILISelLowering.cpp
1717 AMDGPUAsmPrinter.cpp
1818 AMDGPUFrameLowering.cpp
19 AMDGPUIndirectAddressing.cpp
2019 AMDGPUISelDAGToDAG.cpp
2120 AMDGPUMCInstLower.cpp
2221 AMDGPUMachineFunction.cpp
207207 default:
208208 return false;
209209 }
210 }
211
212 bool R600InstrInfo::usesAddressRegister(MachineInstr *MI) const {
213 return MI->findRegisterUseOperandIdx(AMDGPU::AR_X) != -1;
214 }
215
216 bool R600InstrInfo::definesAddressRegister(MachineInstr *MI) const {
217 return MI->findRegisterDefOperandIdx(AMDGPU::AR_X) != -1;
210218 }
211219
212220 bool R600InstrInfo::readsLDSSrcReg(const MachineInstr *MI) const {
10851093 return RegIndex;
10861094 }
10871095
1088 const TargetRegisterClass * R600InstrInfo::getIndirectAddrStoreRegClass(
1089 unsigned SourceReg) const {
1090 return &AMDGPU::R600_TReg32RegClass;
1091 }
1092
1093 const TargetRegisterClass *R600InstrInfo::getIndirectAddrLoadRegClass() const {
1094 return &AMDGPU::TRegMemRegClass;
1096 const TargetRegisterClass *R600InstrInfo::getIndirectAddrRegClass() const {
1097 return &AMDGPU::R600_TReg32_XRegClass;
10951098 }
10961099
10971100 MachineInstrBuilder R600InstrInfo::buildIndirectWrite(MachineBasicBlock *MBB,
11281131 setImmOperand(Mov, AMDGPU::OpName::src0_rel, 1);
11291132
11301133 return Mov;
1131 }
1132
1133 const TargetRegisterClass *R600InstrInfo::getSuperIndirectRegClass() const {
1134 return &AMDGPU::IndirectRegRegClass;
11351134 }
11361135
11371136 unsigned R600InstrInfo::getMaxAlusPerClause() const {
12711270 return MovImm;
12721271 }
12731272
1273 MachineInstr *R600InstrInfo::buildMovInstr(MachineBasicBlock *MBB,
1274 MachineBasicBlock::iterator I,
1275 unsigned DstReg, unsigned SrcReg) const {
1276 return buildDefaultInstruction(*MBB, I, AMDGPU::MOV, DstReg, SrcReg);
1277 }
1278
12741279 int R600InstrInfo::getOperandIdx(const MachineInstr &MI, unsigned Op) const {
12751280 return getOperandIdx(MI.getOpcode(), Op);
12761281 }
8181 bool usesTextureCache(const MachineInstr *MI) const;
8282
8383 bool mustBeLastInClause(unsigned Opcode) const;
84 bool usesAddressRegister(MachineInstr *MI) const;
85 bool definesAddressRegister(MachineInstr *MI) const;
8486 bool readsLDSSrcReg(const MachineInstr *MI) const;
8587
8688 /// \returns The operand index for the given source number. Legal values
202204 virtual unsigned calculateIndirectAddress(unsigned RegIndex,
203205 unsigned Channel) const;
204206
205 virtual const TargetRegisterClass *getIndirectAddrStoreRegClass(
206 unsigned SourceReg) const;
207
208 virtual const TargetRegisterClass *getIndirectAddrLoadRegClass() const;
207 virtual const TargetRegisterClass *getIndirectAddrRegClass() const;
209208
210209 virtual MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB,
211210 MachineBasicBlock::iterator I,
216215 MachineBasicBlock::iterator I,
217216 unsigned ValueReg, unsigned Address,
218217 unsigned OffsetReg) const;
219
220 virtual const TargetRegisterClass *getSuperIndirectRegClass() const;
221218
222219 unsigned getMaxAlusPerClause() const;
223220
245242 unsigned DstReg,
246243 uint64_t Imm) const;
247244
245 MachineInstr *buildMovInstr(MachineBasicBlock *MBB,
246 MachineBasicBlock::iterator I,
247 unsigned DstReg, unsigned SrcReg) const;
248
248249 /// \brief Get the index of Op in the MachineInstr.
249250 ///
250251 /// \returns -1 if the Instruction does not contain the specified \p Op.
205205 return false;
206206 }
207207 }
208
209 bool ARDef = TII->definesAddressRegister(MII) ||
210 TII->definesAddressRegister(MIJ);
211 bool ARUse = TII->usesAddressRegister(MII) ||
212 TII->usesAddressRegister(MIJ);
213 if (ARDef && ARUse)
214 return false;
215
208216 return true;
209217 }
210218
4040 Reserved.set(AMDGPU::PRED_SEL_OFF);
4141 Reserved.set(AMDGPU::PRED_SEL_ZERO);
4242 Reserved.set(AMDGPU::PRED_SEL_ONE);
43 Reserved.set(AMDGPU::INDIRECT_BASE_ADDR);
4344
4445 for (TargetRegisterClass::iterator I = AMDGPU::R600_AddrRegClass.begin(),
4546 E = AMDGPU::R600_AddrRegClass.end(); I != E; ++I) {
46 Reserved.set(*I);
47 }
48
49 for (TargetRegisterClass::iterator I = AMDGPU::TRegMemRegClass.begin(),
50 E = AMDGPU::TRegMemRegClass.end();
51 I != E; ++I) {
5247 Reserved.set(*I);
5348 }
5449
3838 // Indirect addressing offset registers
3939 def Addr#Index#_#Chan : R600RegWithChan <"T("#Index#" + AR.x)."#Chan,
4040 Index, Chan>;
41 def TRegMem#Index#_#Chan : R600RegWithChan <"T"#Index#"."#Chan, Index,
42 Chan>;
4341 }
4442 // 128-bit Temporary Registers
4543 def T#Index#_XYZW : R600Reg_128 <"T"#Index#"",
209207
210208 def R600_Reg64 : RegisterClass<"AMDGPU", [v2f32, v2i32], 64,
211209 (add (sequence "T%u_XY", 0, 63))>;
212
213 //===----------------------------------------------------------------------===//
214 // Register classes for indirect addressing
215 //===----------------------------------------------------------------------===//
216
217 // Super register for all the Indirect Registers. This register class is used
218 // by the REG_SEQUENCE instruction to specify the registers to use for direct
219 // reads / writes which may be written / read by an indirect address.
220 class IndirectSuper subregs> :
221 RegisterWithSubRegs {
222 let Namespace = "AMDGPU";
223 let SubRegIndices =
224 [sub0, sub1, sub2, sub3, sub4, sub5, sub6, sub7,
225 sub8, sub9, sub10, sub11, sub12, sub13, sub14, sub15];
226 }
227
228 def IndirectSuperReg : IndirectSuper<"Indirect",
229 [TRegMem0_X, TRegMem1_X, TRegMem2_X, TRegMem3_X, TRegMem4_X, TRegMem5_X,
230 TRegMem6_X, TRegMem7_X, TRegMem8_X, TRegMem9_X, TRegMem10_X, TRegMem11_X,
231 TRegMem12_X, TRegMem13_X, TRegMem14_X, TRegMem15_X]
232 >;
233
234 def IndirectReg : RegisterClass<"AMDGPU", [f32, i32], 32, (add IndirectSuperReg)>;
235
236 // This register class defines the registers that are the storage units for
237 // the "Indirect Addressing" pseudo memory space.
238 // XXX: Only use the X channel, until we support wider stack widths
239 def TRegMem : RegisterClass<"AMDGPU", [f32, i32], 32,
240 (add (sequence "TRegMem%u_X", 0, 16))
241 >;
194194 MI->setDesc(get(commuteOpcode(MI->getOpcode())));
195195
196196 return MI;
197 }
198
199 MachineInstr *SIInstrInfo::buildMovInstr(MachineBasicBlock *MBB,
200 MachineBasicBlock::iterator I,
201 unsigned DstReg,
202 unsigned SrcReg) const {
203 assert(!"Not Implemented");
197204 }
198205
199206 bool SIInstrInfo::isMov(unsigned Opcode) const {
345352 llvm_unreachable("Unimplemented");
346353 }
347354
348 const TargetRegisterClass *SIInstrInfo::getIndirectAddrStoreRegClass(
349 unsigned SourceReg) const {
350 llvm_unreachable("Unimplemented");
351 }
352
353 const TargetRegisterClass *SIInstrInfo::getIndirectAddrLoadRegClass() const {
355 const TargetRegisterClass *SIInstrInfo::getIndirectAddrRegClass() const {
354356 llvm_unreachable("Unimplemented");
355357 }
356358
369371 unsigned Address, unsigned OffsetReg) const {
370372 llvm_unreachable("Unimplemented");
371373 }
372
373 const TargetRegisterClass *SIInstrInfo::getSuperIndirectRegClass() const {
374 llvm_unreachable("Unimplemented");
375 }
4040 bool NewMI=false) const;
4141
4242 virtual unsigned getIEQOpcode() const { assert(!"Implement"); return 0;}
43 MachineInstr *buildMovInstr(MachineBasicBlock *MBB,
44 MachineBasicBlock::iterator I,
45 unsigned DstReg, unsigned SrcReg) const;
4346 virtual bool isMov(unsigned Opcode) const;
4447
4548 virtual bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const;
6164 virtual unsigned calculateIndirectAddress(unsigned RegIndex,
6265 unsigned Channel) const;
6366
64 virtual const TargetRegisterClass *getIndirectAddrStoreRegClass(
65 unsigned SourceReg) const;
66
67 virtual const TargetRegisterClass *getIndirectAddrLoadRegClass() const;
67 virtual const TargetRegisterClass *getIndirectAddrRegClass() const;
6868
6969 virtual MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB,
7070 MachineBasicBlock::iterator I,
7777 unsigned ValueReg,
7878 unsigned Address,
7979 unsigned OffsetReg) const;
80
81 virtual const TargetRegisterClass *getSuperIndirectRegClass() const;
8280 };
8381
8482 namespace AMDGPU {
6262 store i32 %0, i32 addrspace(1)* %out
6363 ret void
6464 }
65
66 ; Test direct access of a private array inside a loop. The private array
67 ; loads and stores should be lowered to copies, so there shouldn't be any
68 ; MOVA instructions.
69
70 ; CHECK: @direct_loop
71 ; CHECK-NOT: MOVA_INT
72
73 define void @direct_loop(i32 addrspace(1)* %out, i32 addrspace(1)* %in) {
74 entry:
75 %prv_array_const = alloca [2 x i32]
76 %prv_array = alloca [2 x i32]
77 %a = load i32 addrspace(1)* %in
78 %b_src_ptr = getelementptr i32 addrspace(1)* %in, i32 1
79 %b = load i32 addrspace(1)* %b_src_ptr
80 %a_dst_ptr = getelementptr [2 x i32]* %prv_array_const, i32 0, i32 0
81 store i32 %a, i32* %a_dst_ptr
82 %b_dst_ptr = getelementptr [2 x i32]* %prv_array_const, i32 0, i32 1
83 store i32 %b, i32* %b_dst_ptr
84 br label %for.body
85
86 for.body:
87 %inc = phi i32 [0, %entry], [%count, %for.body]
88 %x_ptr = getelementptr [2 x i32]* %prv_array_const, i32 0, i32 0
89 %x = load i32* %x_ptr
90 %y_ptr = getelementptr [2 x i32]* %prv_array, i32 0, i32 0
91 %y = load i32* %y_ptr
92 %xy = add i32 %x, %y
93 store i32 %xy, i32* %y_ptr
94 %count = add i32 %inc, 1
95 %done = icmp eq i32 %count, 4095
96 br i1 %done, label %for.end, label %for.body
97
98 for.end:
99 %value_ptr = getelementptr [2 x i32]* %prv_array, i32 0, i32 0
100 %value = load i32* %value_ptr
101 store i32 %value, i32 addrspace(1)* %out
102 ret void
103 }