Make use of BSS more explicit in global initializers (vs a local .comm).
This reduces the number of conditionals, and will more closely reflect
the structure of the ELF writer's version of the same thing.
Without fdata-sections, the ELF writer version will have to batch all
initializers of a certain type so that they can be contiguous on the file
and the overall alignment can be determined.
A downside of this is that, .s files will be different from llc's output.
The spec .o and executables are identical before/after the change.
BUG=none
R=kschimpf@google.com, stichnot@chromium.org
Review URL: https://codereview.chromium.org/870123003
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index 501cdd7..b092f7f 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -4663,24 +4663,16 @@
Str << "\t.section\t.rodata" << SectionSuffix << ",\"a\",@progbits\n";
else if (HasNonzeroInitializer)
Str << "\t.section\t.data" << SectionSuffix << ",\"aw\",@progbits\n";
- else if (IsExternal)
+ else
Str << "\t.section\t.bss" << SectionSuffix << ",\"aw\",@nobits\n";
- // No .section for non-constant + zeroinitializer + internal
if (IsExternal)
Str << "\t.globl\t" << MangledName << "\n";
- else if (!IsConstant && !HasNonzeroInitializer)
- Str << "\t.local\t" << MangledName << "\n";
- // Internal symbols only get .local when using .comm.
- if ((IsConstant || HasNonzeroInitializer || IsExternal) && Align > 1)
+ if (Align > 1)
Str << "\t.align\t" << Align << "\n";
- // Alignment is part of .comm.
- if (IsConstant || HasNonzeroInitializer || IsExternal)
- Str << MangledName << ":\n";
- else
- Str << "\t.comm\t" << MangledName << "," << Size << "," << Align << "\n";
+ Str << MangledName << ":\n";
if (HasNonzeroInitializer) {
for (VariableDeclaration::Initializer *Init : Initializers) {
@@ -4712,13 +4704,14 @@
}
}
}
- } else if (IsConstant || IsExternal)
+ } else
+ // NOTE: for non-constant zero initializers, this is BSS (no bits),
+ // so an ELF writer would not write to the file, and only track
+ // virtual offsets, but the .s writer still needs this .zero and
+ // cannot simply use the .size to advance offsets.
Str << "\t.zero\t" << Size << "\n";
- // Size is part of .comm.
- if (IsConstant || HasNonzeroInitializer || IsExternal)
- Str << "\t.size\t" << MangledName << ", " << Size << "\n";
- // Size is part of .comm.
+ Str << "\t.size\t" << MangledName << ", " << Size << "\n";
}
} // end of namespace Ice
diff --git a/tests_lit/llvm2ice_tests/globalinit.pnacl.ll b/tests_lit/llvm2ice_tests/globalinit.pnacl.ll
index a4a86b5..68fa144 100644
--- a/tests_lit/llvm2ice_tests/globalinit.pnacl.ll
+++ b/tests_lit/llvm2ice_tests/globalinit.pnacl.ll
@@ -49,18 +49,27 @@
@PrimitiveInitStatic = internal global [4 x i8] zeroinitializer, align 4
; CHECK: .type PrimitiveInitStatic,@object
-; CHECK-NEXT: .local PrimitiveInitStatic
-; CHECK-NEXT: .comm PrimitiveInitStatic,4,4
+; CHECK-NEXT: .section .bss,"aw",@nobits
+; CHECK-NEXT: .align 4
+; CHECK-NEXT: PrimitiveInitStatic:
+; CHECK-NEXT: .zero 4
+; CHECK-NEXT: .size PrimitiveInitStatic, 4
@PrimitiveUninit = internal global [4 x i8] zeroinitializer, align 4
; CHECK: .type PrimitiveUninit,@object
-; CHECK-NEXT: .local PrimitiveUninit
-; CHECK-NEXT: .comm PrimitiveUninit,4,4
+; CHECK-NEXT: .section .bss,"aw",@nobits
+; CHECK-NEXT: .align 4
+; CHECK-NEXT: PrimitiveUninit:
+; CHECK-NEXT: .zero 4
+; CHECK-NEXT: .size PrimitiveUninit, 4
@ArrayUninit = internal global [20 x i8] zeroinitializer, align 4
; CHECK: .type ArrayUninit,@object
-; CHECK-NEXT: .local ArrayUninit
-; CHECK-NEXT: .comm ArrayUninit,20,4
+; CHECK-NEXT: .section .bss,"aw",@nobits
+; CHECK-NEXT: .align 4
+; CHECK-NEXT: ArrayUninit:
+; CHECK-NEXT: .zero 20
+; CHECK-NEXT: .size ArrayUninit, 20
@ArrayUninitConstDouble = internal constant [200 x i8] zeroinitializer, align 8
; CHECK: .type ArrayUninitConstDouble,@object