2 * Copyright (c) 2016 Advanced Micro Devices, Inc.
5 * For use for simulation and test purposes only
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
17 * 3. Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
36 #include "gpu-compute/static_register_manager_policy.hh"
38 #include "config/the_gpu_isa.hh"
39 #include "debug/GPURename.hh"
40 #include "gpu-compute/compute_unit.hh"
41 #include "gpu-compute/pool_manager.hh"
42 #include "gpu-compute/scalar_register_file.hh"
43 #include "gpu-compute/shader.hh"
44 #include "gpu-compute/vector_register_file.hh"
45 #include "gpu-compute/wavefront.hh"
47 StaticRegisterManagerPolicy::StaticRegisterManagerPolicy()
52 StaticRegisterManagerPolicy::exec()
57 StaticRegisterManagerPolicy::mapVgpr(Wavefront
* w
, int vgprIndex
)
59 panic_if((vgprIndex
>= w
->reservedVectorRegs
)
60 || (w
->reservedVectorRegs
< 0),
61 "VGPR index %d is out of range: VGPR range=[0,%d]",
62 vgprIndex
, w
->reservedVectorRegs
);
64 // add the offset from where the VGPRs of the wavefront have been assigned
65 int physicalVgprIndex
= w
->startVgprIndex
+ vgprIndex
;
67 panic_if(!((w
->startVgprIndex
<= physicalVgprIndex
) &&
68 (w
->startVgprIndex
+ w
->reservedVectorRegs
- 1)
69 >= physicalVgprIndex
),
70 "Invalid VGPR index %d\n", physicalVgprIndex
);
72 // calculate physical VGPR index
73 return physicalVgprIndex
% w
->computeUnit
->vrf
[w
->simdId
]->numRegs();
77 StaticRegisterManagerPolicy::mapSgpr(Wavefront
* w
, int sgprIndex
)
79 panic_if(!((sgprIndex
< w
->reservedScalarRegs
)
80 && (w
->reservedScalarRegs
> 0)),
81 "SGPR index %d is out of range: SGPR range=[0,%d]\n",
82 sgprIndex
, w
->reservedScalarRegs
);
84 // add the offset from where the SGPRs of the wavefront have been assigned
85 int physicalSgprIndex
= w
->startSgprIndex
+ sgprIndex
;
87 panic_if(!((w
->startSgprIndex
<= physicalSgprIndex
) &&
88 (w
->startSgprIndex
+ w
->reservedScalarRegs
- 1)
89 >= physicalSgprIndex
),
90 "Invalid SGPR index %d\n", physicalSgprIndex
);
92 // calculate physical SGPR index
93 return physicalSgprIndex
% w
->computeUnit
->srf
[w
->simdId
]->numRegs();
97 StaticRegisterManagerPolicy::canAllocateVgprs(int simdId
, int nWfs
,
100 return cu
->registerManager
->vrfPoolMgrs
[simdId
]->
101 canAllocate(nWfs
, demandPerWf
);
105 StaticRegisterManagerPolicy::canAllocateSgprs(int simdId
, int nWfs
,
108 return cu
->registerManager
->srfPoolMgrs
[simdId
]->
109 canAllocate(nWfs
, demandPerWf
);
113 StaticRegisterManagerPolicy::allocateRegisters(Wavefront
*w
, int vectorDemand
,
116 uint32_t allocatedSize
= 0;
117 w
->startVgprIndex
= cu
->registerManager
->vrfPoolMgrs
[w
->simdId
]->
118 allocateRegion(vectorDemand
, &allocatedSize
);
119 w
->reservedVectorRegs
= allocatedSize
;
120 cu
->vectorRegsReserved
[w
->simdId
] += w
->reservedVectorRegs
;
121 panic_if(cu
->vectorRegsReserved
[w
->simdId
] > cu
->numVecRegsPerSimd
,
122 "VRF[%d] has been overallocated %d > %d\n",
123 w
->simdId
, cu
->vectorRegsReserved
[w
->simdId
],
124 cu
->numVecRegsPerSimd
);
127 w
->startSgprIndex
= cu
->registerManager
->srfPoolMgrs
[w
->simdId
]->
128 allocateRegion(scalarDemand
, &allocatedSize
);
129 w
->reservedScalarRegs
= allocatedSize
;
130 cu
->scalarRegsReserved
[w
->simdId
] += w
->reservedScalarRegs
;
131 panic_if(cu
->scalarRegsReserved
[w
->simdId
] > cu
->numScalarRegsPerSimd
,
132 "SRF[%d] has been overallocated %d > %d\n",
133 w
->simdId
, cu
->scalarRegsReserved
[w
->simdId
],
134 cu
->numScalarRegsPerSimd
);
139 StaticRegisterManagerPolicy::freeRegisters(Wavefront
*w
)
141 // free the vector registers of the completed wavefront
142 w
->computeUnit
->vectorRegsReserved
[w
->simdId
] -= w
->reservedVectorRegs
;
143 // free the scalar registers of the completed wavefront
144 w
->computeUnit
->scalarRegsReserved
[w
->simdId
] -= w
->reservedScalarRegs
;
146 panic_if(w
->computeUnit
->vectorRegsReserved
[w
->simdId
] < 0,
147 "Freeing VRF[%d] registers left %d registers reserved\n",
149 w
->computeUnit
->vectorRegsReserved
[w
->simdId
]);
150 panic_if(w
->computeUnit
->scalarRegsReserved
[w
->simdId
] < 0,
151 "Freeing SRF[%d] registers left %d registers reserved\n",
153 w
->computeUnit
->scalarRegsReserved
[w
->simdId
]);
155 int endIndex
= (w
->startVgprIndex
+ w
->reservedVectorRegs
- 1) %
156 w
->computeUnit
->vrf
[w
->simdId
]->numRegs();
158 w
->computeUnit
->registerManager
->vrfPoolMgrs
[w
->simdId
]->
159 freeRegion(w
->startVgprIndex
, endIndex
);
161 // mark/pre-mark all registers as not busy
162 for (int i
= 0; i
< w
->reservedVectorRegs
; i
++) {
163 uint32_t physVgprIdx
= mapVgpr(w
, i
);
164 w
->computeUnit
->vrf
[w
->simdId
]->markReg(physVgprIdx
, false);
167 w
->reservedVectorRegs
= 0;
168 w
->startVgprIndex
= 0;
170 endIndex
= (w
->startSgprIndex
+ w
->reservedScalarRegs
- 1) %
171 w
->computeUnit
->srf
[w
->simdId
]->numRegs();
172 w
->computeUnit
->registerManager
->srfPoolMgrs
[w
->simdId
]->
173 freeRegion(w
->startSgprIndex
, endIndex
);
175 // mark/pre-mark all registers as not busy
176 for (int i
= 0; i
< w
->reservedScalarRegs
; i
++) {
177 uint32_t physSgprIdx
= mapSgpr(w
, i
);
178 w
->computeUnit
->srf
[w
->simdId
]->markReg(physSgprIdx
, false);
181 w
->reservedScalarRegs
= 0;
182 w
->startSgprIndex
= 0;
186 StaticRegisterManagerPolicy::regStats()