Folds an OpcompositeInsert where input is a composite constant.
| 139 | |
| 140 | // Folds an OpcompositeInsert where input is a composite constant. |
| 141 | ConstantFoldingRule FoldInsertWithConstants() { |
| 142 | return [](IRContext* context, Instruction* inst, |
| 143 | const std::vector<const analysis::Constant*>& constants) |
| 144 | -> const analysis::Constant* { |
| 145 | analysis::ConstantManager* const_mgr = context->get_constant_mgr(); |
| 146 | const analysis::Constant* object = constants[0]; |
| 147 | const analysis::Constant* composite = constants[1]; |
| 148 | if (object == nullptr || composite == nullptr) { |
| 149 | return nullptr; |
| 150 | } |
| 151 | |
| 152 | // If there is more than 1 index, then each additional constant used by the |
| 153 | // index will need to be recreated to use the inserted object. |
| 154 | std::vector<const analysis::Constant*> chain; |
| 155 | std::vector<const analysis::Constant*> components; |
| 156 | const analysis::Type* type = nullptr; |
| 157 | const uint32_t final_index = (inst->NumInOperands() - 1); |
| 158 | |
| 159 | // Work down hierarchy of all indexes |
| 160 | for (uint32_t i = 2; i < inst->NumInOperands(); ++i) { |
| 161 | type = composite->type(); |
| 162 | |
| 163 | if (composite->AsNullConstant()) { |
| 164 | // Make new composite so it can be inserted in the index with the |
| 165 | // non-null value |
| 166 | if (const auto new_composite = |
| 167 | const_mgr->GetNullCompositeConstant(type)) { |
| 168 | // Keep track of any indexes along the way to last index |
| 169 | if (i != final_index) { |
| 170 | chain.push_back(new_composite); |
| 171 | } |
| 172 | components = new_composite->AsCompositeConstant()->GetComponents(); |
| 173 | } else { |
| 174 | // Unsupported input type (such as structs) |
| 175 | return nullptr; |
| 176 | } |
| 177 | } else { |
| 178 | // Keep track of any indexes along the way to last index |
| 179 | if (i != final_index) { |
| 180 | chain.push_back(composite); |
| 181 | } |
| 182 | components = composite->AsCompositeConstant()->GetComponents(); |
| 183 | } |
| 184 | const uint32_t index = inst->GetSingleWordInOperand(i); |
| 185 | composite = components[index]; |
| 186 | } |
| 187 | |
| 188 | // Final index in hierarchy is inserted with new object. |
| 189 | const uint32_t final_operand = inst->GetSingleWordInOperand(final_index); |
| 190 | std::vector<uint32_t> ids; |
| 191 | for (size_t i = 0; i < components.size(); i++) { |
| 192 | const analysis::Constant* constant = |
| 193 | (i == final_operand) ? object : components[i]; |
| 194 | Instruction* member_inst = const_mgr->GetDefiningInstruction(constant); |
| 195 | ids.push_back(member_inst->result_id()); |
| 196 | } |
| 197 | const analysis::Constant* new_constant = const_mgr->GetConstant(type, ids); |
| 198 |
no test coverage detected