void LocalAccessChainConvertPass::ReplaceAccessChainLoad( const Instruction* address_inst, Instruction* original_load) { // Build and append load of variable in ptrInst std::vector<std::unique_ptr<Instruction>> new_inst; uint32_t varId; uint32_t varPteTypeId; const uint32_t ldResultId = BuildAndAppendVarLoad(address_inst, &varId, &varPteTypeId, &new_inst); context()->get_decoration_mgr()->CloneDecorations( original_load->result_id(), ldResultId, {SpvDecorationRelaxedPrecision}); original_load->InsertBefore(std::move(new_inst)); // Rewrite |original_load| into an extract. Instruction::OperandList new_operands; // copy the result id and the type id to the new operand list. new_operands.emplace_back(original_load->GetOperand(0)); new_operands.emplace_back(original_load->GetOperand(1)); new_operands.emplace_back( Operand({spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ldResultId}})); AppendConstantOperands(address_inst, &new_operands); original_load->SetOpcode(SpvOpCompositeExtract); original_load->ReplaceOperands(new_operands); context()->UpdateDefUse(original_load); }
void LocalAccessChainConvertPass::GenAccessChainStoreReplacement( const Instruction* ptrInst, uint32_t valId, std::vector<std::unique_ptr<Instruction>>* newInsts) { // Build and append load of variable in ptrInst uint32_t varId; uint32_t varPteTypeId; const uint32_t ldResultId = BuildAndAppendVarLoad(ptrInst, &varId, &varPteTypeId, newInsts); context()->get_decoration_mgr()->CloneDecorations( varId, ldResultId, {SpvDecorationRelaxedPrecision}); // Build and append Insert const uint32_t insResultId = TakeNextId(); std::vector<Operand> ins_in_opnds = { {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {valId}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ldResultId}}}; AppendConstantOperands(ptrInst, &ins_in_opnds); BuildAndAppendInst(SpvOpCompositeInsert, varPteTypeId, insResultId, ins_in_opnds, newInsts); context()->get_decoration_mgr()->CloneDecorations( varId, insResultId, {SpvDecorationRelaxedPrecision}); // Build and append Store BuildAndAppendInst(SpvOpStore, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {varId}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {insResultId}}}, newInsts); }
uint32_t LocalAccessChainConvertPass::GenAccessChainLoadReplacement( const ir::Instruction* ptrInst, std::vector<std::unique_ptr<ir::Instruction>>* newInsts) { // Build and append load of variable in ptrInst uint32_t varId; uint32_t varPteTypeId; const uint32_t ldResultId = BuildAndAppendVarLoad(ptrInst, &varId, &varPteTypeId, newInsts); // Build and append Extract const uint32_t extResultId = TakeNextId(); const uint32_t ptrPteTypeId = GetPointeeTypeId(ptrInst); std::vector<ir::Operand> ext_in_opnds = {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ldResultId}}}; AppendConstantOperands(ptrInst, &ext_in_opnds); BuildAndAppendInst(SpvOpCompositeExtract, ptrPteTypeId, extResultId, ext_in_opnds, newInsts); return extResultId; }