diff --git a/toolchain/lower/file_context.cpp b/toolchain/lower/file_context.cpp index aa93acf97481..065d3ae312b3 100644 --- a/toolchain/lower/file_context.cpp +++ b/toolchain/lower/file_context.cpp @@ -154,9 +154,9 @@ auto FileContext::GetGlobal(SemIR::InstId inst_id, return const_value; } - // If we want a pointer to the constant, materialize a global to hold it. - // TODO: We could reuse the same global if the constant is used more than - // once. + if (auto result = global_variables().Lookup(const_inst_id)) { + return result.value(); + } // Include both the name of the constant, if any, and the point of use in // the name of the variable. @@ -177,10 +177,13 @@ auto FileContext::GetGlobal(SemIR::InstId inst_id, } llvm::StringRef sep = (use_name[0] == '.') ? "" : "."; - return new llvm::GlobalVariable( + auto* global_variable = new llvm::GlobalVariable( llvm_module(), GetType(sem_ir().GetPointeeType(value_rep.type_id)), /*isConstant=*/true, llvm::GlobalVariable::InternalLinkage, const_value, const_name + sep + use_name); + + global_variables_.Insert(const_inst_id, global_variable); + return global_variable; } auto FileContext::GetOrCreateFunction(SemIR::FunctionId function_id, diff --git a/toolchain/lower/testdata/class/virtual.carbon b/toolchain/lower/testdata/class/virtual.carbon index 11c761d7efd5..58f422765a6a 100644 --- a/toolchain/lower/testdata/class/virtual.carbon +++ b/toolchain/lower/testdata/class/virtual.carbon @@ -110,8 +110,6 @@ fn Use() { // CHECK:STDOUT: @"_CIntermediate.Classes.$vtable" = external unnamed_addr constant ptr // CHECK:STDOUT: @"_CDerived.Classes.$vtable" = external unnamed_addr constant ptr // CHECK:STDOUT: @Base.val.loc7_3.2 = internal constant {} zeroinitializer -// CHECK:STDOUT: @Base.val.loc8_44.6 = internal constant {} zeroinitializer -// CHECK:STDOUT: @Base.val.loc9_48.6 = internal constant {} zeroinitializer // CHECK:STDOUT: // CHECK:STDOUT: define void @_CCreate.Create() !dbg !4 { // CHECK:STDOUT: entry: @@ -125,13 +123,13 @@ fn Use() { // CHECK:STDOUT: %.loc8_44.2.vptr = getelementptr inbounds nuw { ptr, {} }, ptr %i.var, i32 0, i32 0, !dbg !8 // CHECK:STDOUT: store ptr @"_CIntermediate.Classes.$vtable", ptr %.loc8_44.2.vptr, align 8, !dbg !8 // CHECK:STDOUT: %.loc8_44.5.base = getelementptr inbounds nuw { ptr, {} }, ptr %i.var, i32 0, i32 1, !dbg !8 -// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %.loc8_44.5.base, ptr align 1 @Base.val.loc8_44.6, i64 0, i1 false), !dbg !8 +// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %.loc8_44.5.base, ptr align 1 @Base.val.loc7_3.2, i64 0, i1 false), !dbg !8 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %d.var), !dbg !7 // CHECK:STDOUT: %.loc9_49.2.base = getelementptr inbounds nuw { { ptr, {} } }, ptr %d.var, i32 0, i32 0, !dbg !9 // CHECK:STDOUT: %.loc9_48.2.vptr = getelementptr inbounds nuw { ptr, {} }, ptr %.loc9_49.2.base, i32 0, i32 0, !dbg !10 // CHECK:STDOUT: store ptr @"_CDerived.Classes.$vtable", ptr %.loc9_48.2.vptr, align 8, !dbg !10 // CHECK:STDOUT: %.loc9_48.5.base = getelementptr inbounds nuw { ptr, {} }, ptr %.loc9_49.2.base, i32 0, i32 1, !dbg !10 -// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %.loc9_48.5.base, ptr align 1 @Base.val.loc9_48.6, i64 0, i1 false), !dbg !10 +// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %.loc9_48.5.base, ptr align 1 @Base.val.loc7_3.2, i64 0, i1 false), !dbg !10 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %d2.var), !dbg !7 // CHECK:STDOUT: ret void, !dbg !11 // CHECK:STDOUT: } diff --git a/toolchain/lower/testdata/global/class_with_fun.carbon b/toolchain/lower/testdata/global/class_with_fun.carbon index f3246e5dd108..8c9160987e3f 100644 --- a/toolchain/lower/testdata/global/class_with_fun.carbon +++ b/toolchain/lower/testdata/global/class_with_fun.carbon @@ -20,7 +20,6 @@ var a: A = {}; // CHECK:STDOUT: // CHECK:STDOUT: @a = internal global {} zeroinitializer // CHECK:STDOUT: @A.val.loc13_12 = internal constant {} zeroinitializer -// CHECK:STDOUT: @A.val.loc16_1 = internal constant {} zeroinitializer // CHECK:STDOUT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @_C__global_init.Main, ptr null }] // CHECK:STDOUT: // CHECK:STDOUT: define void @_Cret_a.Main(ptr sret({}) %return) !dbg !4 { @@ -31,7 +30,7 @@ var a: A = {}; // CHECK:STDOUT: // CHECK:STDOUT: define void @_C__global_init.Main() !dbg !8 { // CHECK:STDOUT: entry: -// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 @a, ptr align 1 @A.val.loc16_1, i64 0, i1 false), !dbg !9 +// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 @a, ptr align 1 @A.val.loc13_12, i64 0, i1 false), !dbg !9 // CHECK:STDOUT: ret void, !dbg !10 // CHECK:STDOUT: } // CHECK:STDOUT: