OP_SPEC_CONSTANT_FALSE = 49,
OP_SPEC_CONSTANT = 50,
OP_VARIABLE = 59,
+ OP_LOAD = 61,
+ OP_STORE = 62,
+ OP_ACCESS_CHAIN = 65,
OP_DECORATE = 71,
OP_MEMBER_DECORATE = 72,
+ OP_LABEL = 248,
+ OP_BRANCH = 249,
+ OP_BRANCH_CONDITIONAL = 250,
DECO_SPEC_ID = 1,
DECO_ARRAY_STRIDE = 6,
v = (i!=var_indices.end() ? &variables[i->second] : 0);
}
}
+
+ map<const InstructionBlock *, unsigned> block_indices;
+ blocks.reserve(reflection.blocks.size());
+ for(const auto &kvp: reflection.blocks)
+ {
+ block_indices[&kvp.second] = blocks.size();
+ blocks.push_back(kvp.second);
+ }
+
+ for(InstructionBlock &b: blocks)
+ {
+ auto i = spec_indices.find(b.condition);
+ b.condition = (i!=spec_indices.end() ? &spec_constants[i->second] : 0);
+
+ for(const Variable *&v: b.accessed_variables)
+ {
+ auto j = var_indices.find(v);
+ v = (j!=var_indices.end() ? &variables[j->second] : 0);
+ }
+
+ for(const InstructionBlock *&s: b.successors)
+ {
+ auto j = block_indices.find(s);
+ s = (j!=block_indices.end() ? &blocks[j->second] : 0);
+ }
+ }
}
case OP_SPEC_CONSTANT_FALSE:
case OP_SPEC_CONSTANT: reflect_constant(op); break;
case OP_VARIABLE: reflect_variable(op); break;
+ case OP_LOAD:
+ case OP_STORE: reflect_access(op); break;
+ case OP_ACCESS_CHAIN: reflect_access_chain(op); break;
case OP_DECORATE: reflect_decorate(op); break;
case OP_MEMBER_DECORATE: reflect_member_decorate(op); break;
+ case OP_LABEL: reflect_label(op); break;
+ case OP_BRANCH: reflect_branch(op); break;
+ case OP_BRANCH_CONDITIONAL: reflect_branch_conditional(op); break;
}
op += word_count;
void SpirVModule::Reflection::reflect_constant(CodeIterator op)
{
+ unsigned opcode = get_opcode(*op);
unsigned id = *(op+2);
Constant &cnst = constants[id];
cnst.name = names[id];
cnst.type = types[*(op+1)].type;
- if(*op==OP_CONSTANT_TRUE || *op==OP_SPEC_CONSTANT_TRUE)
+ if(opcode==OP_CONSTANT_TRUE || opcode==OP_SPEC_CONSTANT_TRUE)
cnst.i_value = true;
- else if(*op==OP_CONSTANT_FALSE || *op==OP_SPEC_CONSTANT_FALSE)
+ else if(opcode==OP_CONSTANT_FALSE || opcode==OP_SPEC_CONSTANT_FALSE)
cnst.i_value = false;
else if(cnst.type==INT || cnst.type==UNSIGNED_INT)
cnst.i_value = *(op+3);
var.array_size = type.array_size;
}
+void SpirVModule::Reflection::reflect_access(CodeIterator op)
+{
+ if(current_block)
+ {
+ unsigned id = (get_opcode(*op)==OP_LOAD ? *(op+3) : *(op+1));
+ auto i = access_chain_bases.find(id);
+ if(i!=access_chain_bases.end())
+ id = i->second;
+ Variable &var = variables[id];
+ auto j = find(current_block->accessed_variables, &var);
+ if(j==current_block->accessed_variables.end())
+ current_block->accessed_variables.push_back(&var);
+ }
+}
+
+void SpirVModule::Reflection::reflect_access_chain(CodeIterator op)
+{
+ access_chain_bases[*(op+2)] = *(op+3);
+}
+
void SpirVModule::Reflection::reflect_decorate(CodeIterator op)
{
unsigned id = *(op+1);
}
}
+void SpirVModule::Reflection::reflect_label(CodeIterator op)
+{
+ current_block = &blocks[*(op+1)];
+}
+
+void SpirVModule::Reflection::reflect_branch(CodeIterator op)
+{
+ InstructionBlock &block = blocks[*(op+1)];
+ block.condition = &true_condition;
+ current_block->successors.push_back(&block);
+}
+
+void SpirVModule::Reflection::reflect_branch_conditional(CodeIterator op)
+{
+ InstructionBlock &true_block = blocks[*(op+2)];
+ InstructionBlock &false_block = blocks[*(op+3)];
+
+ auto i = constants.find(*(op+1));
+ if(i!=constants.end() && i->second.constant_id)
+ {
+ if(!true_block.condition)
+ true_block.condition = &i->second;
+ if(!false_block.condition)
+ {
+ false_block.condition = &i->second;
+ false_block.negate_condition = true;
+ }
+ }
+
+ current_block->successors.push_back(&true_block);
+ current_block->successors.push_back(&false_block);
+}
+
} // namespace GL
} // namespace Msp