mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 20:30:14 +01:00
Use the Carbon-computed alignment for allocas, loads, stores, and memcpys. Previously we used whatever LLVM felt like giving us, which would result in ABI mismatches and runtime crashes due to misalignment when creating objects of imported C++ class types, as well as resulting in some surprising choices like `(i32, i32)` and `()` having 8-byte alignment instead of 4 and 1, respectively.
85 lines
3.4 KiB
C++
85 lines
3.4 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#include "toolchain/lower/function_context.h"
|
|
#include "toolchain/sem_ir/expr_info.h"
|
|
#include "toolchain/sem_ir/file.h"
|
|
|
|
namespace Carbon::Lower {
|
|
|
|
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
|
|
SemIR::AcquireValue inst) -> void {
|
|
auto inst_type = context.GetTypeIdOfInst(inst_id);
|
|
switch (context.GetValueRepr(inst_type).repr.kind) {
|
|
case SemIR::ValueRepr::Unknown:
|
|
CARBON_FATAL(
|
|
"Value acquisition for type with incomplete value representation");
|
|
case SemIR::ValueRepr::Dependent:
|
|
CARBON_FATAL(
|
|
"Value acquisition for type with dependent value representation");
|
|
case SemIR::ValueRepr::None:
|
|
// Nothing should use this value, but StubRef needs a value to
|
|
// propagate.
|
|
// TODO: Remove this now the StubRefs are gone.
|
|
context.SetLocal(inst_id,
|
|
llvm::PoisonValue::get(context.GetType(inst_type)));
|
|
break;
|
|
case SemIR::ValueRepr::Copy:
|
|
context.SetLocal(
|
|
inst_id,
|
|
context.LoadObject(inst_type, context.GetValue(inst.value_id)));
|
|
break;
|
|
case SemIR::ValueRepr::Pointer:
|
|
context.SetLocal(inst_id, context.GetValue(inst.value_id));
|
|
break;
|
|
case SemIR::ValueRepr::Custom:
|
|
CARBON_FATAL("TODO: Add support for AcquireValue with custom value rep");
|
|
}
|
|
}
|
|
|
|
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
|
|
SemIR::MarkInPlaceInit inst) -> void {
|
|
context.SetLocal(inst_id, context.GetValue(inst.dest_id));
|
|
}
|
|
|
|
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
|
|
SemIR::Temporary inst) -> void {
|
|
if (SemIR::GetExprCategory(context.sem_ir(), inst.init_id) !=
|
|
SemIR::ExprCategory::InPlaceInitializing) {
|
|
context.InitializeStorage(context.GetTypeIdOfInst(inst_id), inst.storage_id,
|
|
inst.init_id);
|
|
}
|
|
context.SetLocal(inst_id, context.GetValue(inst.storage_id));
|
|
}
|
|
|
|
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
|
|
SemIR::TemporaryStorage /*inst*/) -> void {
|
|
context.SetLocal(
|
|
inst_id, context.CreateAlloca(context.GetTypeIdOfInst(inst_id), "temp"));
|
|
}
|
|
|
|
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
|
|
SemIR::ValueAsRef inst) -> void {
|
|
CARBON_CHECK(SemIR::GetExprCategory(context.sem_ir(), inst.value_id) ==
|
|
SemIR::ExprCategory::Value);
|
|
auto inst_type = context.GetTypeIdOfInst(inst_id);
|
|
auto value_repr = context.GetValueRepr(inst_type);
|
|
CARBON_CHECK(value_repr.repr.kind == SemIR::ValueRepr::Pointer);
|
|
context.SetLocal(inst_id, context.GetValue(inst.value_id));
|
|
}
|
|
|
|
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
|
|
SemIR::ValueOfInitializer inst) -> void {
|
|
CARBON_CHECK(SemIR::GetExprCategory(context.sem_ir(), inst.init_id) ==
|
|
SemIR::ExprCategory::ReprInitializing);
|
|
auto inst_type = context.GetTypeIdOfInst(inst_id);
|
|
auto value_repr = context.GetValueRepr(inst_type);
|
|
auto init_repr = context.GetInitRepr(inst_type);
|
|
CARBON_CHECK(value_repr.repr.kind == SemIR::ValueRepr::Copy);
|
|
CARBON_CHECK(init_repr.kind == SemIR::InitRepr::ByCopy);
|
|
context.SetLocal(inst_id, context.GetValue(inst.init_id));
|
|
}
|
|
|
|
} // namespace Carbon::Lower
|