AMDGPU: Check feature attributes in SIMachineFunctionInfo
[oota-llvm.git] / lib / Target / AMDGPU / SIMachineFunctionInfo.cpp
1 //===-- SIMachineFunctionInfo.cpp - SI Machine Function Info -------===//
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 /// \file
9 //===----------------------------------------------------------------------===//
10
11
12 #include "SIMachineFunctionInfo.h"
13 #include "AMDGPUSubtarget.h"
14 #include "SIInstrInfo.h"
15 #include "llvm/CodeGen/MachineInstrBuilder.h"
16 #include "llvm/CodeGen/MachineFrameInfo.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18 #include "llvm/IR/Function.h"
19 #include "llvm/IR/LLVMContext.h"
20
21 #define MAX_LANES 64
22
23 using namespace llvm;
24
25
26 // Pin the vtable to this file.
27 void SIMachineFunctionInfo::anchor() {}
28
29 SIMachineFunctionInfo::SIMachineFunctionInfo(const MachineFunction &MF)
30   : AMDGPUMachineFunction(MF),
31     TIDReg(AMDGPU::NoRegister),
32     ScratchRSrcReg(AMDGPU::NoRegister),
33     LDSWaveSpillSize(0),
34     PSInputAddr(0),
35     NumUserSGPRs(0),
36     HasSpilledSGPRs(false),
37     HasSpilledVGPRs(false),
38     DispatchPtr(false),
39     QueuePtr(false),
40     DispatchID(false),
41     KernargSegmentPtr(true),
42     FlatScratchInit(false),
43     GridWorkgroupCountX(false),
44     GridWorkgroupCountY(false),
45     GridWorkgroupCountZ(false),
46     WorkGroupIDX(true),
47     WorkGroupIDY(false),
48     WorkGroupIDZ(false),
49     WorkGroupInfo(false),
50     WorkItemIDX(true),
51     WorkItemIDY(false),
52     WorkItemIDZ(false) {
53   const Function *F = MF.getFunction();
54
55   if (F->hasFnAttribute("amdgpu-dispatch-ptr"))
56     DispatchPtr = true;
57
58   if (F->hasFnAttribute("amdgpu-work-group-id-y"))
59     WorkGroupIDY = true;
60
61   if (F->hasFnAttribute("amdgpu-work-group-id-z"))
62     WorkGroupIDZ = true;
63
64   if (F->hasFnAttribute("amdgpu-work-item-id-y"))
65     WorkItemIDY = true;
66
67   if (F->hasFnAttribute("amdgpu-work-item-id-z"))
68     WorkItemIDZ = true;
69 }
70
71 SIMachineFunctionInfo::SpilledReg SIMachineFunctionInfo::getSpilledReg(
72                                                        MachineFunction *MF,
73                                                        unsigned FrameIndex,
74                                                        unsigned SubIdx) {
75   const MachineFrameInfo *FrameInfo = MF->getFrameInfo();
76   const SIRegisterInfo *TRI = static_cast<const SIRegisterInfo *>(
77       MF->getSubtarget<AMDGPUSubtarget>().getRegisterInfo());
78   MachineRegisterInfo &MRI = MF->getRegInfo();
79   int64_t Offset = FrameInfo->getObjectOffset(FrameIndex);
80   Offset += SubIdx * 4;
81
82   unsigned LaneVGPRIdx = Offset / (64 * 4);
83   unsigned Lane = (Offset / 4) % 64;
84
85   struct SpilledReg Spill;
86
87   if (!LaneVGPRs.count(LaneVGPRIdx)) {
88     unsigned LaneVGPR = TRI->findUnusedRegister(MRI, &AMDGPU::VGPR_32RegClass);
89     LaneVGPRs[LaneVGPRIdx] = LaneVGPR;
90
91     // Add this register as live-in to all blocks to avoid machine verifer
92     // complaining about use of an undefined physical register.
93     for (MachineFunction::iterator BI = MF->begin(), BE = MF->end();
94          BI != BE; ++BI) {
95       BI->addLiveIn(LaneVGPR);
96     }
97   }
98
99   Spill.VGPR = LaneVGPRs[LaneVGPRIdx];
100   Spill.Lane = Lane;
101   return Spill;
102 }
103
104 unsigned SIMachineFunctionInfo::getMaximumWorkGroupSize(
105                                               const MachineFunction &MF) const {
106   const AMDGPUSubtarget &ST = MF.getSubtarget<AMDGPUSubtarget>();
107   // FIXME: We should get this information from kernel attributes if it
108   // is available.
109   return getShaderType() == ShaderType::COMPUTE ? 256 : ST.getWavefrontSize();
110 }