MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / AnalyzeAccessChainLoc

Method AnalyzeAccessChainLoc

source/opt/liveness.cpp:172–241  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

170}
171
172uint32_t LivenessManager::AnalyzeAccessChainLoc(const Instruction* ac,
173 uint32_t curr_type_id,
174 uint32_t* offset, bool* no_loc,
175 bool is_patch, bool input) {
176 analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
177 analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr();
178 // For tesc, tese and geom input variables, and tesc output variables,
179 // first array index does not contribute to offset.
180 auto stage = context()->GetStage();
181 bool skip_first_index = false;
182 if ((input && (stage == spv::ExecutionModel::TessellationControl ||
183 stage == spv::ExecutionModel::TessellationEvaluation ||
184 stage == spv::ExecutionModel::Geometry)) ||
185 (!input && stage == spv::ExecutionModel::TessellationControl))
186 skip_first_index = !is_patch;
187 uint32_t ocnt = 0;
188 ac->WhileEachInOperand([this, &ocnt, def_use_mgr, deco_mgr, &curr_type_id,
189 offset, no_loc,
190 skip_first_index](const uint32_t* opnd) {
191 if (ocnt >= 1) {
192 // Skip first index's contribution to offset if indicated
193 Instruction* curr_type_inst = def_use_mgr->GetDef(curr_type_id);
194 if (ocnt == 1 && skip_first_index) {
195 assert(curr_type_inst->opcode() == spv::Op::OpTypeArray &&
196 "unexpected wrapper type");
197 const uint32_t kArrayElementTypeInIdx = 0;
198 curr_type_id =
199 curr_type_inst->GetSingleWordInOperand(kArrayElementTypeInIdx);
200 ocnt++;
201 return true;
202 }
203 // If any non-constant index, mark the entire current object and return.
204 auto idx_inst = def_use_mgr->GetDef(*opnd);
205 if (idx_inst->opcode() != spv::Op::OpConstant) return false;
206 // If current type is struct, look for location decoration on member and
207 // reset offset if found.
208 auto index = idx_inst->GetSingleWordInOperand(0);
209 if (curr_type_inst->opcode() == spv::Op::OpTypeStruct) {
210 uint32_t loc = 0;
211 bool no_mem_loc = deco_mgr->WhileEachDecoration(
212 curr_type_id, uint32_t(spv::Decoration::Location),
213 [&loc, index, no_loc](const Instruction& deco) {
214 assert(deco.opcode() == spv::Op::OpMemberDecorate &&
215 "unexpected decoration");
216 if (deco.GetSingleWordInOperand(kOpDecorateMemberMemberInIdx) ==
217 index) {
218 loc =
219 deco.GetSingleWordInOperand(kOpDecorateMemberLocationInIdx);
220 *no_loc = false;
221 return false;
222 }
223 return true;
224 });
225 if (!no_mem_loc) {
226 *offset = loc;
227 curr_type_id = curr_type_inst->GetSingleWordInOperand(index);
228 ocnt++;
229 return true;

Callers 1

Calls 8

GetStageMethod · 0.80
WhileEachInOperandMethod · 0.80
WhileEachDecorationMethod · 0.80
get_def_use_mgrMethod · 0.45
get_decoration_mgrMethod · 0.45
GetDefMethod · 0.45
opcodeMethod · 0.45

Tested by

no test coverage detected