Refactor: Inline global init function lowering (#7302)

This removes the need to support a function without a declaration in
these codepaths.
This commit is contained in:
David Blaikie
2026-06-04 19:13:18 +00:00
committed by GitHub
parent cefa0397bb
commit 2f9bbd067a
2 changed files with 69 additions and 3 deletions
+36 -3
View File
@@ -139,12 +139,45 @@ auto FileContext::LowerDefinitions() -> void {
// variables.
if (auto global_ctor_id = sem_ir().global_ctor_id();
global_ctor_id.has_value()) {
auto llvm_function = BuildFunctionDecl(global_ctor_id);
functions_.Set(global_ctor_id, llvm_function);
// This is basically an inlined and specialized version of
// `BuildFunctionDecl` because global_ctor is a bit special (it has no
// declarations, for one thing).
// TODO: Consider making the global ctor not a function at all, but a
// special block.
auto function_type_info = BuildFunctionTypeInfo(
{{this, global_ctor_id, SemIR::SpecificId::None}});
std::string mangled_name = "_C__global_init.";
auto package_id = sem_ir().package_id();
if (auto ident_id = package_id.AsIdentifierId(); ident_id.has_value()) {
mangled_name += sem_ir().identifiers().Get(ident_id);
} else {
mangled_name += package_id.AsSpecialName();
}
auto* llvm_function = llvm_module().getFunction(mangled_name);
if (!llvm_function) {
llvm_function = llvm::Function::Create(function_type_info.type,
llvm::Function::InternalLinkage,
mangled_name, llvm_module());
CARBON_CHECK(llvm_function->getName() == mangled_name,
"Mangled name collision: {0}", mangled_name);
}
FunctionInfo function_info = {
.type = function_type_info.type,
.di_type = function_type_info.di_type,
.lowered_param_indices =
std::move(function_type_info.lowered_param_indices),
.unused_param_indices =
std::move(function_type_info.unused_param_indices),
.llvm_function = llvm_function,
.inexact = function_type_info.inexact};
functions_.Set(global_ctor_id, function_info);
const auto& global_ctor = sem_ir().functions().Get(global_ctor_id);
BuildFunctionBody(global_ctor_id, SemIR::SpecificId::None, global_ctor,
*this, global_ctor);
llvm::appendToGlobalCtors(llvm_module(), llvm_function->llvm_function,
llvm::appendToGlobalCtors(llvm_module(), llvm_function,
/*Priority=*/0);
}
}
+33
View File
@@ -44,6 +44,12 @@ library "[[@TEST_NAME]]";
var (_: i32, x: i32) = (1, 2);
var (_: i32, _: i32) = (3, 4);
// --- not_main_package.carbon
package Other;
var a: i32 = 1;
// CHECK:STDOUT: ; ModuleID = 'simple.carbon'
// CHECK:STDOUT: source_filename = "simple.carbon"
// CHECK:STDOUT:
@@ -224,3 +230,30 @@ var (_: i32, _: i32) = (3, 4);
// CHECK:STDOUT: !7 = !DILocation(line: 4, column: 1, scope: !4)
// CHECK:STDOUT: !8 = !DILocation(line: 5, column: 1, scope: !4)
// CHECK:STDOUT: !9 = !DILocation(line: 0, scope: !4)
// CHECK:STDOUT: ; ModuleID = 'not_main_package.carbon'
// CHECK:STDOUT: source_filename = "not_main_package.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: @_Ca.Other = global i32 0
// CHECK:STDOUT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @_C__global_init.Other, ptr null }]
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define internal void @_C__global_init.Other() #0 !dbg !4 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: store i32 1, ptr @_Ca.Other, align 4, !dbg !7
// CHECK:STDOUT: ret void, !dbg !8
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: attributes #0 = { nounwind }
// CHECK:STDOUT:
// CHECK:STDOUT: !llvm.module.flags = !{!0, !1}
// CHECK:STDOUT: !llvm.dbg.cu = !{!2}
// CHECK:STDOUT:
// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
// CHECK:STDOUT: !3 = !DIFile(filename: "not_main_package.carbon", directory: "")
// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "__global_init", linkageName: "_C__global_init.Other", scope: null, file: !3, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
// CHECK:STDOUT: !6 = !{null}
// CHECK:STDOUT: !7 = !DILocation(line: 4, column: 1, scope: !4)
// CHECK:STDOUT: !8 = !DILocation(line: 0, scope: !4)