|
10 | 10 | #include "common/check.h"
|
11 | 11 | #include "llvm/ADT/STLExtras.h"
|
12 | 12 | #include "toolchain/check/context.h"
|
| 13 | +#include "toolchain/sem_ir/copy_on_write_block.h" |
13 | 14 | #include "toolchain/sem_ir/file.h"
|
14 | 15 | #include "toolchain/sem_ir/inst.h"
|
15 | 16 |
|
@@ -194,47 +195,6 @@ static auto ConvertAggregateElement(
|
194 | 195 | return Convert(context, node_id, src_elem_id, target);
|
195 | 196 | }
|
196 | 197 |
|
197 |
| -namespace { |
198 |
| -// A handle to a new block that may be modified, with copy-on-write semantics. |
199 |
| -// |
200 |
| -// The constructor is given the ID of an existing block that provides the |
201 |
| -// initial contents of the new block. The new block is lazily allocated; if no |
202 |
| -// modifications have been made, the `id()` function will return the original |
203 |
| -// block ID. |
204 |
| -// |
205 |
| -// This is intended to avoid an unnecessary block allocation in the case where |
206 |
| -// the new block ends up being exactly the same as the original block. |
207 |
| -class CopyOnWriteBlock { |
208 |
| - public: |
209 |
| - // Constructs the block. If `source_id` is valid, it is used as the initial |
210 |
| - // value of the block. Otherwise, uninitialized storage for `size` elements |
211 |
| - // is allocated. |
212 |
| - CopyOnWriteBlock(SemIR::File& file, SemIR::InstBlockId source_id, size_t size) |
213 |
| - : file_(file), source_id_(source_id) { |
214 |
| - if (!source_id_.is_valid()) { |
215 |
| - id_ = file_.inst_blocks().AddUninitialized(size); |
216 |
| - } |
217 |
| - } |
218 |
| - |
219 |
| - auto id() const -> SemIR::InstBlockId { return id_; } |
220 |
| - |
221 |
| - auto Set(int i, SemIR::InstId value) -> void { |
222 |
| - if (source_id_.is_valid() && file_.inst_blocks().Get(id_)[i] == value) { |
223 |
| - return; |
224 |
| - } |
225 |
| - if (id_ == source_id_) { |
226 |
| - id_ = file_.inst_blocks().Add(file_.inst_blocks().Get(source_id_)); |
227 |
| - } |
228 |
| - file_.inst_blocks().Get(id_)[i] = value; |
229 |
| - } |
230 |
| - |
231 |
| - private: |
232 |
| - SemIR::File& file_; |
233 |
| - SemIR::InstBlockId source_id_; |
234 |
| - SemIR::InstBlockId id_ = source_id_; |
235 |
| -}; |
236 |
| -} // namespace |
237 |
| - |
238 | 198 | // Performs a conversion from a tuple to an array type. This function only
|
239 | 199 | // converts the type, and does not perform a final conversion to the requested
|
240 | 200 | // expression category.
|
@@ -370,7 +330,12 @@ static auto ConvertTupleToTuple(Context& context, SemIR::TupleType src_type,
|
370 | 330 | // Initialize each element of the destination from the corresponding element
|
371 | 331 | // of the source.
|
372 | 332 | // TODO: Annotate diagnostics coming from here with the element index.
|
373 |
| - CopyOnWriteBlock new_block(sem_ir, literal_elems_id, src_elem_types.size()); |
| 333 | + auto new_block = |
| 334 | + literal_elems_id.is_valid() |
| 335 | + ? SemIR::CopyOnWriteInstBlock(sem_ir, literal_elems_id) |
| 336 | + : SemIR::CopyOnWriteInstBlock( |
| 337 | + sem_ir, SemIR::CopyOnWriteInstBlock::UninitializedBlock{ |
| 338 | + src_elem_types.size()}); |
374 | 339 | for (auto [i, src_type_id, dest_type_id] :
|
375 | 340 | llvm::enumerate(src_elem_types, dest_elem_types)) {
|
376 | 341 | // TODO: This call recurses back into conversion. Switch to an iterative
|
@@ -463,7 +428,12 @@ static auto ConvertStructToStructOrClass(Context& context,
|
463 | 428 | // Initialize each element of the destination from the corresponding element
|
464 | 429 | // of the source.
|
465 | 430 | // TODO: Annotate diagnostics coming from here with the element index.
|
466 |
| - CopyOnWriteBlock new_block(sem_ir, literal_elems_id, src_elem_fields.size()); |
| 431 | + auto new_block = |
| 432 | + literal_elems_id.is_valid() |
| 433 | + ? SemIR::CopyOnWriteInstBlock(sem_ir, literal_elems_id) |
| 434 | + : SemIR::CopyOnWriteInstBlock( |
| 435 | + sem_ir, SemIR::CopyOnWriteInstBlock::UninitializedBlock{ |
| 436 | + src_elem_fields.size()}); |
467 | 437 | for (auto [i, dest_field_id] : llvm::enumerate(dest_elem_fields)) {
|
468 | 438 | auto dest_field =
|
469 | 439 | sem_ir.insts().GetAs<SemIR::StructTypeField>(dest_field_id);
|
|
0 commit comments