@@ -263,38 +263,6 @@ auto AllocateFacetTypeImplWitness(Context& context,
263
263
context.inst_blocks ().ReplacePlaceholder (witness_id, empty_table);
264
264
}
265
265
266
- namespace {
267
- // TODO: This class should go away, and we should just use the constant value of
268
- // the ImplWitnessAccess as a key in AccessRewriteValues, but that requires
269
- // changing its API to work with InstId instead of ImplWitnessAccess.
270
- struct FacetTypeConstraintValue {
271
- SemIR::EntityNameId entity_name_id;
272
- SemIR::ElementIndex access_index;
273
- SemIR::SpecificInterfaceId specific_interface_id;
274
-
275
- friend auto operator ==(const FacetTypeConstraintValue& lhs,
276
- const FacetTypeConstraintValue& rhs) -> bool = default ;
277
- };
278
- } // namespace
279
-
280
- static auto GetFacetTypeConstraintValue (Context& context,
281
- SemIR::ImplWitnessAccess access)
282
- -> std::optional<FacetTypeConstraintValue> {
283
- auto lookup =
284
- context.insts ().TryGetAs <SemIR::LookupImplWitness>(access.witness_id );
285
- if (lookup) {
286
- auto self = context.insts ().TryGetAs <SemIR::BindSymbolicName>(
287
- context.constant_values ().GetConstantInstId (
288
- lookup->query_self_inst_id ));
289
- if (self) {
290
- return {{.entity_name_id = self->entity_name_id ,
291
- .access_index = access.index ,
292
- .specific_interface_id = lookup->query_specific_interface_id }};
293
- }
294
- }
295
- return std::nullopt;
296
- }
297
-
298
266
// A mapping of each associated constant (represented as `ImplWitnessAccess`) to
299
267
// its value (represented as an `InstId`). Used to track rewrite constraints,
300
268
// with the LHS mapping to the resolved value of the RHS.
@@ -310,24 +278,24 @@ class AccessRewriteValues {
310
278
SemIR::InstId inst_id;
311
279
};
312
280
313
- auto InsertNotRewritten (Context& context, SemIR::ImplWitnessAccess access,
314
- SemIR::InstId inst_id) -> void {
315
- map_.insert ({*GetKey (context, access), {NotRewritten, inst_id}});
281
+ auto InsertNotRewritten (
282
+ Context& context, SemIR::KnownInstId<SemIR::ImplWitnessAccess> access_id,
283
+ SemIR::InstId inst_id) -> void {
284
+ map_.Insert (context.constant_values ().Get (access_id),
285
+ {NotRewritten, inst_id});
316
286
}
317
287
318
288
// Finds and returns a pointer into the cache for a given ImplWitnessAccess.
319
289
// The pointer will be invalidated by mutating the cache. Returns `nullptr`
320
290
// if `access` is not found.
321
- auto FindRef (Context& context, SemIR::ImplWitnessAccess access) -> Value* {
322
- auto key = GetKey (context, access);
323
- if (!key) {
324
- return nullptr ;
325
- }
326
- auto it = map_.find (*key);
327
- if (it == map_.end ()) {
291
+ auto FindRef (Context& context,
292
+ SemIR::KnownInstId<SemIR::ImplWitnessAccess> access_id)
293
+ -> Value* {
294
+ auto result = map_.Lookup (context.constant_values ().Get (access_id));
295
+ if (!result) {
328
296
return nullptr ;
329
297
}
330
- return &it-> second ;
298
+ return &result. value () ;
331
299
}
332
300
333
301
auto SetBeingRewritten (Value& value) -> void {
@@ -346,54 +314,13 @@ class AccessRewriteValues {
346
314
}
347
315
348
316
private:
349
- using Key = FacetTypeConstraintValue;
350
- struct KeyInfo {
351
- static auto getEmptyKey () -> Key {
352
- return {
353
- .entity_name_id = SemIR::EntityNameId::None,
354
- .access_index = SemIR::ElementIndex (-1 ),
355
- .specific_interface_id = SemIR::SpecificInterfaceId::None,
356
- };
357
- }
358
- static auto getTombstoneKey () -> Key {
359
- return {
360
- .entity_name_id = SemIR::EntityNameId::None,
361
- .access_index = SemIR::ElementIndex (-2 ),
362
- .specific_interface_id = SemIR::SpecificInterfaceId::None,
363
- };
364
- }
365
- static auto getHashValue (Key key) -> unsigned {
366
- // This hash produces the same value if two ImplWitnessAccess are
367
- // pointing to the same associated constant, even if they are different
368
- // instruction ids.
369
- //
370
- // TODO: This truncates the high bits of the hash code which does not
371
- // make for a good hash function.
372
- return static_cast <unsigned >(static_cast <uint64_t >(HashValue (key)));
373
- }
374
- static auto isEqual (Key lhs, Key rhs) -> bool {
375
- // This comparison is true if the two ImplWitnessAccess are pointing to
376
- // the same associated constant, even if they are different instruction
377
- // ids.
378
- return lhs == rhs;
379
- }
380
- };
381
-
382
- // Returns a key for the `access` to an associated context if the access is
383
- // through a facet value. If the access it through another `ImplWitnessAccess`
384
- // then no key is able to be made.
385
- auto GetKey (Context& context, SemIR::ImplWitnessAccess access)
386
- -> std::optional<Key> {
387
- return GetFacetTypeConstraintValue (context, access);
388
- }
389
-
390
317
// Try avoid heap allocations in the common case where there are a small
391
318
// number of rewrite rules referring to each other by keeping up to 16 on
392
319
// the stack.
393
320
//
394
321
// TODO: Revisit if 16 is an appropriate number when we can measure how deep
395
322
// rewrite constraint chains go in practice.
396
- llvm::SmallDenseMap<Key , Value, 16 , KeyInfo > map_;
323
+ Map<SemIR::ConstantId , Value, 16 > map_;
397
324
};
398
325
399
326
// To be used for substituting into the RHS of a rewrite constraint.
@@ -437,7 +364,7 @@ class SubstImplWitnessAccessCallbacks : public SubstInstCallbacks {
437
364
438
365
auto Subst (SemIR::InstId& rhs_inst_id) -> SubstResult override {
439
366
auto rhs_access =
440
- context ().insts ().TryGetAs <SemIR::ImplWitnessAccess>(rhs_inst_id);
367
+ context ().insts ().TryGetAsWithId <SemIR::ImplWitnessAccess>(rhs_inst_id);
441
368
if (!rhs_access) {
442
369
// We only want to substitute ImplWitnessAccesses written directly on the
443
370
// RHS of the rewrite constraint, not when they are nested inside facet
@@ -471,15 +398,16 @@ class SubstImplWitnessAccessCallbacks : public SubstInstCallbacks {
471
398
// access needs to be resolved to a facet value first. If it can't be
472
399
// resolved then the outer one can not be either.
473
400
if (auto lookup = context ().insts ().TryGetAs <SemIR::LookupImplWitness>(
474
- rhs_access->witness_id )) {
401
+ rhs_access->inst . witness_id )) {
475
402
if (context ().insts ().Is <SemIR::ImplWitnessAccess>(
476
403
lookup->query_self_inst_id )) {
477
404
substs_in_progress_.push_back (rhs_inst_id);
478
405
return SubstResult::SubstOperandsAndRetry;
479
406
}
480
407
}
481
408
482
- auto * rewrite_value = rewrite_values_->FindRef (context (), *rhs_access);
409
+ auto * rewrite_value =
410
+ rewrite_values_->FindRef (context (), rhs_access->inst_id );
483
411
if (!rewrite_value) {
484
412
// The RHS refers to an associated constant for which there is no rewrite
485
413
// rule.
@@ -521,9 +449,11 @@ class SubstImplWitnessAccessCallbacks : public SubstInstCallbacks {
521
449
-> SemIR::InstId override {
522
450
auto inst_id = RebuildNewInst (loc_id_, new_inst);
523
451
auto subst_inst_id = substs_in_progress_.pop_back_val ();
524
- if (auto access = context ().insts ().TryGetAs <SemIR::ImplWitnessAccess>(
525
- subst_inst_id)) {
526
- if (auto * rewrite_value = rewrite_values_->FindRef (context (), *access)) {
452
+ if (auto access =
453
+ context ().insts ().TryGetAsWithId <SemIR::ImplWitnessAccess>(
454
+ subst_inst_id)) {
455
+ if (auto * rewrite_value =
456
+ rewrite_values_->FindRef (context (), access->inst_id )) {
527
457
rewrite_values_->SetFullyRewritten (context (), *rewrite_value, inst_id);
528
458
}
529
459
}
@@ -532,9 +462,11 @@ class SubstImplWitnessAccessCallbacks : public SubstInstCallbacks {
532
462
533
463
auto ReuseUnchanged (SemIR::InstId orig_inst_id) -> SemIR::InstId override {
534
464
auto subst_inst_id = substs_in_progress_.pop_back_val ();
535
- if (auto access = context ().insts ().TryGetAs <SemIR::ImplWitnessAccess>(
536
- subst_inst_id)) {
537
- if (auto * rewrite_value = rewrite_values_->FindRef (context (), *access)) {
465
+ if (auto access =
466
+ context ().insts ().TryGetAsWithId <SemIR::ImplWitnessAccess>(
467
+ subst_inst_id)) {
468
+ if (auto * rewrite_value =
469
+ rewrite_values_->FindRef (context (), access->inst_id )) {
538
470
rewrite_values_->SetFullyRewritten (context (), *rewrite_value,
539
471
orig_inst_id);
540
472
}
@@ -580,23 +512,25 @@ auto ResolveFacetTypeRewriteConstraints(
580
512
AccessRewriteValues rewrite_values;
581
513
582
514
for (auto & constraint : rewrites) {
583
- auto lhs_access = context.insts ().TryGetAs <SemIR::ImplWitnessAccess>(
515
+ auto lhs_access = context.insts ().TryGetAsWithId <SemIR::ImplWitnessAccess>(
584
516
GetImplWitnessAccessWithoutSubstitution (context, constraint.lhs_id ));
585
517
if (!lhs_access) {
586
518
continue ;
587
519
}
588
520
589
- rewrite_values.InsertNotRewritten (context, *lhs_access, constraint.rhs_id );
521
+ rewrite_values.InsertNotRewritten (context, lhs_access->inst_id ,
522
+ constraint.rhs_id );
590
523
}
591
524
592
525
for (auto & constraint : rewrites) {
593
- auto lhs_access = context.insts ().TryGetAs <SemIR::ImplWitnessAccess>(
526
+ auto lhs_access = context.insts ().TryGetAsWithId <SemIR::ImplWitnessAccess>(
594
527
GetImplWitnessAccessWithoutSubstitution (context, constraint.lhs_id ));
595
528
if (!lhs_access) {
596
529
continue ;
597
530
}
598
531
599
- auto * lhs_rewrite_value = rewrite_values.FindRef (context, *lhs_access);
532
+ auto * lhs_rewrite_value =
533
+ rewrite_values.FindRef (context, lhs_access->inst_id );
600
534
// Every LHS was added with InsertNotRewritten above.
601
535
CARBON_CHECK (lhs_rewrite_value);
602
536
rewrite_values.SetBeingRewritten (*lhs_rewrite_value);
@@ -658,14 +592,14 @@ auto ResolveFacetTypeRewriteConstraints(
658
592
for (size_t i = 0 ; i < keep_size;) {
659
593
auto & constraint = rewrites[i];
660
594
661
- auto lhs_access = context.insts ().TryGetAs <SemIR::ImplWitnessAccess>(
595
+ auto lhs_access = context.insts ().TryGetAsWithId <SemIR::ImplWitnessAccess>(
662
596
GetImplWitnessAccessWithoutSubstitution (context, constraint.lhs_id ));
663
597
if (!lhs_access) {
664
598
++i;
665
599
continue ;
666
600
}
667
601
668
- auto & rewrite_value = *rewrite_values.FindRef (context, * lhs_access);
602
+ auto & rewrite_value = *rewrite_values.FindRef (context, lhs_access-> inst_id );
669
603
auto rhs_id = std::exchange (rewrite_value.inst_id , SemIR::InstId::None);
670
604
if (rhs_id == SemIR::InstId::None) {
671
605
std::swap (rewrites[i], rewrites[keep_size - 1 ]);
0 commit comments