Repository: carbon-language/carbon-lang
File: toolchain/lower/file_context.cpp (C++)

Code before:
  }

  llvm::SmallVector<SemIR::SpecificId> stack;
  SemIR::SpecificId specific_to_update = specific_id;
  while (equivalent_specifics_.Get(
             equivalent_specifics_.Get(specific_to_update)) !=
         equivalent_specifics_.Get(specific_to_update)) {
    stack.push_back(specific_to_update);
    specific_to_update = equivalent_specifics_.Get(specific_to_update);
  }
  for (auto specific : llvm::reverse(stack)) {
    equivalent_specifics_.Set(
        specific,
        equivalent_specifics_.Get(equivalent_specifics_.Get(specific)));
  }
}

auto FileContext::UpdateAndDeleteLLVMFunction(SemIR::SpecificId specific_id)
    -> void {
  specific_functions_.Get(specific_id)
      ->replaceAllUsesWith(
          specific_functions_.Get(equivalent_specifics_.Get(specific_id)));
  specific_functions_.Get(specific_id)->eraseFromParent();
  specific_functions_.Set(
      specific_id,
      specific_functions_.Get(equivalent_specifics_.Get(specific_id)));
}

auto FileContext::IsKnownEquivalence(SemIR::SpecificId specific_id1,
                                     SemIR::SpecificId specific_id2) -> bool {
  if (!equivalent_specifics_.Get(specific_id1).has_value() ||
      !equivalent_specifics_.Get(specific_id2).has_value()) {
    return false;
  }

  UpdateEquivalentSpecific(specific_id1);
  UpdateEquivalentSpecific(specific_id2);

  return equivalent_specifics_.Get(specific_id1) ==
         equivalent_specifics_.Get(specific_id2);
}

auto FileContext::AreFunctionTypesEquivalent(SemIR::SpecificId specific_id1,
                                             SemIR::SpecificId specific_id2)
    -> bool {
  CARBON_CHECK(specific_id1.has_value() && specific_id2.has_value());
  return lowered_specifics_type_fingerprint_.Get(specific_id1) ==
         lowered_specifics_type_fingerprint_.Get(specific_id2);
}

auto FileContext::AreFunctionBodiesEquivalent(

Review comment (suggestion):
Just suggesting locals to reuse `Get` results

```suggestion
  auto* old_function = specific_functions_.Get(specific_id);
  auto* new_function = specific_functions_.Get(equivalent_specifics_.Get(specific_id));
  old_function->replaceAllUsesWith(new_function);
  old_function->eraseFromParent();
  specific_functions_.Set(specific_id, new_function);
```

Code after:
  llvm::SmallVector<SemIR::SpecificId> stack;
  SemIR::SpecificId specific_to_update = specific_id;
  SemIR::SpecificId equivalent = equivalent_specifics_.Get(specific_to_update);
  SemIR::SpecificId equivalent_next = equivalent_specifics_.Get(equivalent);
  while (equivalent != equivalent_next) {
    stack.push_back(specific_to_update);
    specific_to_update = equivalent;
    equivalent = equivalent_next;
    equivalent_next = equivalent_specifics_.Get(equivalent_next);
  }

  for (auto specific : stack) {
    equivalent_specifics_.Set(specific, equivalent);
  }
}

auto FileContext::UpdateAndDeleteLLVMFunction(SemIR::SpecificId specific_id)
    -> void {
  UpdateEquivalentSpecific(specific_id);
  auto* old_function = specific_functions_.Get(specific_id);
  auto* new_function =
      specific_functions_.Get(equivalent_specifics_.Get(specific_id));
  old_function->replaceAllUsesWith(new_function);
  old_function->eraseFromParent();
  specific_functions_.Set(specific_id, new_function);
}

auto FileContext::IsKnownEquivalence(SemIR::SpecificId specific_id1,
                                     SemIR::SpecificId specific_id2) -> bool {
  if (!equivalent_specifics_.Get(specific_id1).has_value() ||
      !equivalent_specifics_.Get(specific_id2).has_value()) {
    return false;
  }

  UpdateEquivalentSpecific(specific_id1);
  UpdateEquivalentSpecific(specific_id2);

  return equivalent_specifics_.Get(specific_id1) ==
         equivalent_specifics_.Get(specific_id2);
}

auto FileContext::AreFunctionTypesEquivalent(SemIR::SpecificId specific_id1,
                                             SemIR::SpecificId specific_id2)
    -> bool {
  CARBON_CHECK(specific_id1.has_value() && specific_id2.has_value());
  return lowered_specifics_type_fingerprint_.Get(specific_id1) ==
         lowered_specifics_type_fingerprint_.Get(specific_id2);
}

auto FileContext::AreFunctionBodiesEquivalent(
    SemIR::SpecificId specific_id1, SemIR::SpecificId specific_id2,