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

Code before:
    case SemIR::ValueRepr::Custom:
      CARBON_FATAL("TODO: Add support for CopyValue with custom value rep");
  }
}

auto FunctionContext::CopyObject(TypeInFile type, SemIR::InstId source_id,
                                 SemIR::InstId dest_id) -> void {
  const auto& layout = llvm_module().getDataLayout();
  auto* llvm_type = GetType(type);
  // TODO: Compute known alignment of the source and destination, which may
  // be greater than the alignment computed by LLVM.
  auto align = layout.getABITypeAlign(llvm_type);

  // TODO: Attach !tbaa.struct metadata indicating which portions of the
  // type we actually need to copy and which are padding.
  builder().CreateMemCpy(GetValue(dest_id), align, GetValue(source_id), align,
                         layout.getTypeAllocSize(llvm_type));
}

auto FunctionContext::Inserter::InsertHelper(
    llvm::Instruction* inst, const llvm::Twine& name,
    llvm::BasicBlock::iterator insert_pt) const -> void {
  llvm::StringRef base_name;
  llvm::StringRef separator;
  if (inst_namer_ && !inst->getType()->isVoidTy()) {
    base_name = inst_namer_->GetUnscopedNameFor(inst_id_);
  }
  if (!base_name.empty() && !name.isTriviallyEmpty()) {
    separator = ".";
  }

  IRBuilderDefaultInserter::InsertHelper(inst, base_name + separator + name,
                                         insert_pt);
}

auto FunctionContext::AddCallToCurrentFingerprint(SemIR::CheckIRId file_id,
                                                  SemIR::FunctionId function_id,
                                                  SemIR::SpecificId specific_id)
    -> void {
  if (!function_fingerprint_) {
    return;
  }

  RawStringOstream os;
  // TODO: Replace indexes with info that is translation unit independent.
  // Using a string that includes the `FunctionId` string and the index to
  // avoid possible collisions. This needs revisiting.
  os << "file_id" << file_id.index << "\n";
  os << "function_id" << function_id.index << "\n";
  current_fingerprint_.common_fingerprint.update(os.TakeStr());
  // TODO: Replace index with info that is translation unit independent.

Review comment (suggestion):
FWIW, I'm dubious about it... But it's hard to tell...

As long as we're consistent, things like GVN should all be fine.

If there is some other sign extension that the extension here could fold into, that would be better. But if there isn't, the zero extension is likely better.

Hmm... ok, should leave this TODO, I want to think a bit more.

Code after:
}

auto FunctionContext::LoadObject(TypeInFile type, llvm::Value* addr,
                                 llvm::Twine name) -> llvm::Value* {
  auto* llvm_type = GetType(type);
  auto* load_type = GetWidenedMemoryType(llvm_type);

  // TODO: Include alias and alignment information.
  llvm::Value* value = builder().CreateLoad(load_type, addr, name);

  if (load_type != llvm_type) {
    value = builder().CreateTrunc(value, llvm_type);
  }
  return value;
}

auto FunctionContext::StoreObject(TypeInFile type, llvm::Value* value,
                                  llvm::Value* addr) -> void {
  // TODO: Include alias and alignment information.
  auto* llvm_type = GetType(type);
  CARBON_CHECK(value->getType() == llvm_type);

  // Don't emit a store of `iN` if N is not a multiple of 8. See `LoadObject`.
  auto* store_type = GetWidenedMemoryType(llvm_type);
  if (store_type != llvm_type) {
    // TODO: Should we consider creating a sext if the value is signed?
    value = builder().CreateZExt(value, store_type);
  }

  builder().CreateStore(value, addr);
}

auto FunctionContext::CopyValue(TypeInFile type, SemIR::InstId source_id,
                                SemIR::InstId dest_id) -> void {
  switch (GetValueRepr(type).repr.kind) {
    case SemIR::ValueRepr::Unknown:
      CARBON_FATAL("Attempt to copy incomplete type");
    case SemIR::ValueRepr::None:
      break;
    case SemIR::ValueRepr::Copy:
      StoreObject(type, GetValue(source_id), GetValue(dest_id));
      break;
    case SemIR::ValueRepr::Pointer:
      CopyObject(type, source_id, dest_id);
      break;
    case SemIR::ValueRepr::Custom:
      CARBON_FATAL("TODO: Add support for CopyValue with custom value rep");
  }
}

auto FunctionContext::CopyObject(TypeInFile type, SemIR::InstId source_id,