Commit 2a063e2b by Jim Stichnoth

Subzero: Fix emission of global initializers.

Also changes the szbuild.py script to add -fdata-sections, and entirely removes the -disable-globals option. The global initializer emission basically copies what llc does, based on 3 properties of the global: constant vs non-constant, internal vs external, and full zero-initializer vs non-trivial initializer. BUG= none R=jvoung@chromium.org, kschimpf@google.com Review URL: https://codereview.chromium.org/631383003
parent 645aa1a9
...@@ -174,6 +174,7 @@ def ProcessPexe(args, pexe, exe): ...@@ -174,6 +174,7 @@ def ProcessPexe(args, pexe, exe):
NewerThanOrNotThere(llcbin, obj_llc): NewerThanOrNotThere(llcbin, obj_llc):
shellcmd(['pnacl-translate', shellcmd(['pnacl-translate',
'-ffunction-sections', '-ffunction-sections',
'-fdata-sections',
'-c', '-c',
'-arch', 'x86-32-linux', '-arch', 'x86-32-linux',
'-O' + opt_level_map[opt_level], '-O' + opt_level_map[opt_level],
...@@ -193,9 +194,9 @@ def ProcessPexe(args, pexe, exe): ...@@ -193,9 +194,9 @@ def ProcessPexe(args, pexe, exe):
shellcmd([llvm2ice, shellcmd([llvm2ice,
'-O' + opt_level, '-O' + opt_level,
'-bitcode-format=pnacl', '-bitcode-format=pnacl',
'-disable-globals',
'-externalize', '-externalize',
'-ffunction-sections', '-ffunction-sections',
'-fdata-sections',
'-o', asm_sz] + '-o', asm_sz] +
args.sz_args + args.sz_args +
[pexe], [pexe],
......
...@@ -23,16 +23,14 @@ class ClFlags { ...@@ -23,16 +23,14 @@ class ClFlags {
public: public:
ClFlags() ClFlags()
: DisableInternal(false), SubzeroTimingEnabled(false), : DisableInternal(false), SubzeroTimingEnabled(false),
DisableTranslation(false), DisableGlobals(false), DisableTranslation(false), FunctionSections(false), DataSections(false),
FunctionSections(false), DataSections(false),
UseIntegratedAssembler(false), UseSandboxing(false), DumpStats(false), UseIntegratedAssembler(false), UseSandboxing(false), DumpStats(false),
AllowUninitializedGlobals(false), TimeEachFunction(false), AllowUninitializedGlobals(false), TimeEachFunction(false),
DefaultGlobalPrefix(""), DefaultFunctionPrefix(""),TimingFocusOn(""), DefaultGlobalPrefix(""), DefaultFunctionPrefix(""), TimingFocusOn(""),
VerboseFocusOn("") {} VerboseFocusOn("") {}
bool DisableInternal; bool DisableInternal;
bool SubzeroTimingEnabled; bool SubzeroTimingEnabled;
bool DisableTranslation; bool DisableTranslation;
bool DisableGlobals;
bool FunctionSections; bool FunctionSections;
bool DataSections; bool DataSections;
bool UseIntegratedAssembler; bool UseIntegratedAssembler;
......
...@@ -801,8 +801,7 @@ void Converter::convertToIce() { ...@@ -801,8 +801,7 @@ void Converter::convertToIce() {
TimerMarker T(TimerStack::TT_convertToIce, Ctx); TimerMarker T(TimerStack::TT_convertToIce, Ctx);
nameUnnamedGlobalAddresses(Mod); nameUnnamedGlobalAddresses(Mod);
nameUnnamedFunctions(Mod); nameUnnamedFunctions(Mod);
if (!Ctx->getFlags().DisableGlobals) convertGlobals(Mod);
convertGlobals(Mod);
convertFunctions(); convertFunctions();
} }
......
...@@ -4437,70 +4437,52 @@ void TargetGlobalInitX8632::lower(const GlobalAddress &Global, ...@@ -4437,70 +4437,52 @@ void TargetGlobalInitX8632::lower(const GlobalAddress &Global,
return; return;
Ostream &Str = Ctx->getStrEmit(); Ostream &Str = Ctx->getStrEmit();
// constant:
// .section .rodata,"a",@progbits
// .align ALIGN
// .byte ...
// .size NAME, SIZE
// non-constant:
// .data
// .align ALIGN
// .byte ...
// .size NAME, SIZE
// zeroinitializer (constant):
// (.section or .data as above)
// .align ALIGN
// .zero SIZE
// .size NAME, SIZE
// zeroinitializer (non-constant):
// (.section or .data as above)
// .local NAME
// .comm NAME, SIZE, ALIGN
// TODO(kschimpf): Don't mangle name if external and uninitialized. This // TODO(kschimpf): Don't mangle name if external and uninitialized. This
// will allow us to cross test relocations for references to external // will allow us to cross test relocations for references to external
// global variables. // global variables.
IceString MangledName = Ctx->mangleName(Global.getName());
// Start a new section.
if (Ctx->getFlags().DataSections) {
Str << "\t.section\t.rodata." << MangledName << ",\"a\",@progbits\n";
} else if (Global.getIsConstant()) {
Str << "\t.section\t.rodata,\"a\",@progbits\n";
} else {
Str << "\t.type\t" << MangledName << ",@object\n";
Str << "\t.data\n";
}
Str << "\t" << (Global.getIsInternal() ? ".local" : ".global") << "\t"
<< MangledName << "\n";
const GlobalAddress::InitializerListType &Initializers = const GlobalAddress::InitializerListType &Initializers =
Global.getInitializers(); Global.getInitializers();
assert(Initializers.size());
// Note: Handle zero initializations specially when lowering, since bool HasInitializer =
// we may be able to reduce object size. !(Initializers.size() == 1 &&
GlobalAddress::ZeroInitializer *SimpleZeroInit = nullptr; llvm::isa<GlobalAddress::ZeroInitializer>(Initializers[0]));
if (Initializers.size() == 1) { bool IsConstant = Global.getIsConstant();
GlobalAddress::Initializer *Init = Initializers[0]; bool IsExternal = !Global.getIsInternal();
if (const auto ZeroInit = uint32_t Align = Global.getAlignment();
llvm::dyn_cast<GlobalAddress::ZeroInitializer>(Init)) { SizeT Size = Global.getNumBytes();
SimpleZeroInit = ZeroInit; IceString MangledName = Ctx->mangleName(Global.getName());
} IceString SectionSuffix = "";
} if (Ctx->getFlags().DataSections)
SectionSuffix = "." + MangledName;
if (SimpleZeroInit && !Global.getIsConstant()) {
// TODO(stichnot): Put the appropriate non-constant Str << "\t.type\t" << MangledName << ",@object\n";
// zeroinitializers in a .bss section to reduce object size.
Str << "\t.comm\t" << MangledName << ", " << Global.getNumBytes() << ", " if (IsConstant)
<< Global.getAlignment() << "\n"; Str << "\t.section\t.rodata" << SectionSuffix << ",\"a\",@progbits\n";
// } else if (HasInitializer)
} else { Str << "\t.section\t.data" << SectionSuffix << ",\"aw\",@progbits\n";
Str << "\t.align\t" << Global.getAlignment() << "\n"; else if (IsExternal)
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 && !HasInitializer)
Str << "\t.local\t" << MangledName << "\n";
// Internal symbols only get .local when using .comm.
if ((IsConstant || HasInitializer || IsExternal) && Align > 1)
Str << "\t.align\t" << Align << "\n";
// Alignment is part of .comm.
if (IsConstant || HasInitializer || IsExternal)
Str << MangledName << ":\n"; Str << MangledName << ":\n";
else
Str << "\t.comm\t" << MangledName << "," << Size << "," << Align << "\n";
if (HasInitializer) {
for (GlobalAddress::Initializer *Init : Initializers) { for (GlobalAddress::Initializer *Init : Initializers) {
switch (Init->getKind()) { switch (Init->getKind()) {
case GlobalAddress::Initializer::DataInitializerKind: { case GlobalAddress::Initializer::DataInitializerKind: {
...@@ -4539,8 +4521,13 @@ void TargetGlobalInitX8632::lower(const GlobalAddress &Global, ...@@ -4539,8 +4521,13 @@ void TargetGlobalInitX8632::lower(const GlobalAddress &Global,
} }
} }
} }
Str << "\t.size\t" << MangledName << ", " << Global.getNumBytes() << "\n"; } else if (IsConstant || IsExternal)
} Str << "\t.zero\t" << Size << "\n";
// Size is part of .comm.
if (IsConstant || HasInitializer || IsExternal)
Str << "\t.size\t" << MangledName << ", " << Size << "\n";
// Size is part of .comm.
} }
} // end of namespace Ice } // end of namespace Ice
...@@ -2369,8 +2369,7 @@ private: ...@@ -2369,8 +2369,7 @@ private:
} }
} }
Trans.nameUnnamedFunctions(Context->getModule()); Trans.nameUnnamedFunctions(Context->getModule());
if (!getFlags().DisableGlobals) getTranslator().lowerGlobals(Context->getGlobalIDAddresses());
getTranslator().lowerGlobals(Context->getGlobalIDAddresses());
GlobalAddressNamesAndInitializersInstalled = true; GlobalAddressNamesAndInitializersInstalled = true;
} }
} }
......
...@@ -111,10 +111,6 @@ static cl::opt<std::string> VerboseFocusOn( ...@@ -111,10 +111,6 @@ static cl::opt<std::string> VerboseFocusOn(
cl::desc("Temporarily enable full verbosity for a specific function"), cl::desc("Temporarily enable full verbosity for a specific function"),
cl::init("")); cl::init(""));
static cl::opt<bool>
DisableGlobals("disable-globals",
cl::desc("Disable global initializer translation"));
// This is currently unused, and is a placeholder for lit tests. // This is currently unused, and is a placeholder for lit tests.
static cl::opt<bool> static cl::opt<bool>
DisablePhiEdgeSplit("no-phi-edge-split", DisablePhiEdgeSplit("no-phi-edge-split",
...@@ -197,7 +193,6 @@ int main(int argc, char **argv) { ...@@ -197,7 +193,6 @@ int main(int argc, char **argv) {
Flags.DisableInternal = DisableInternal; Flags.DisableInternal = DisableInternal;
Flags.SubzeroTimingEnabled = SubzeroTimingEnabled; Flags.SubzeroTimingEnabled = SubzeroTimingEnabled;
Flags.DisableTranslation = DisableTranslation; Flags.DisableTranslation = DisableTranslation;
Flags.DisableGlobals = DisableGlobals;
Flags.FunctionSections = FunctionSections; Flags.FunctionSections = FunctionSections;
Flags.DataSections = DataSections; Flags.DataSections = DataSections;
Flags.UseIntegratedAssembler = UseIntegratedAssembler; Flags.UseIntegratedAssembler = UseIntegratedAssembler;
......
...@@ -6,63 +6,63 @@ ...@@ -6,63 +6,63 @@
; RUN: %p2i -i %s --args --verbose none | FileCheck --check-prefix=ERRORS %s ; RUN: %p2i -i %s --args --verbose none | FileCheck --check-prefix=ERRORS %s
@PrimitiveInit = internal global [4 x i8] c"\1B\00\00\00", align 4 @PrimitiveInit = internal global [4 x i8] c"\1B\00\00\00", align 4
; CHECK: .data ; CHECK: .type PrimitiveInit,@object
; CHECK-NEXT: .local ; CHECK-NEXT: .section .data,"aw",@progbits
; CHECK-NEXT: .align 4 ; CHECK-NEXT: .align 4
; CHECK-NEXT: PrimitiveInit: ; CHECK-NEXT: PrimitiveInit:
; CHECK-NEXT: .byte ; CHECK-NEXT: .byte
; CHECK: .size PrimitiveInit, 4 ; CHECK: .size PrimitiveInit, 4
@PrimitiveInitConst = internal constant [4 x i8] c"\0D\00\00\00", align 4 @PrimitiveInitConst = internal constant [4 x i8] c"\0D\00\00\00", align 4
; CHECK: .section .rodata,"a",@progbits ; CHECK: .type PrimitiveInitConst,@object
; CHECK-NEXT: .local ; CHECK-NEXT: .section .rodata,"a",@progbits
; CHECK-NEXT: .align 4 ; CHECK-NEXT: .align 4
; CHECK-NEXT: PrimitiveInitConst: ; CHECK-NEXT: PrimitiveInitConst:
; CHECK-NEXT: .byte ; CHECK-NEXT: .byte
; CHECK: .size PrimitiveInitConst, 4 ; CHECK: .size PrimitiveInitConst, 4
@ArrayInit = internal global [20 x i8] c"\0A\00\00\00\14\00\00\00\1E\00\00\00(\00\00\002\00\00\00", align 4 @ArrayInit = internal global [20 x i8] c"\0A\00\00\00\14\00\00\00\1E\00\00\00(\00\00\002\00\00\00", align 4
; CHECK: .data ; CHECK: .type ArrayInit,@object
; CHECK-NEXT: .local ; CHECK-NEXT: .section .data,"aw",@progbits
; CHECK-NEXT: .align 4 ; CHECK-NEXT: .align 4
; CHECK-NEXT: ArrayInit: ; CHECK-NEXT: ArrayInit:
; CHECK-NEXT: .byte ; CHECK-NEXT: .byte
; CHECK: .size ArrayInit, 20 ; CHECK: .size ArrayInit, 20
@ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4 @ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4
; CHECK: .data ; CHECK: .type ArrayInitPartial,@object
; CHECK-NEXT: .local ; CHECK-NEXT: .section .data,"aw",@progbits
; CHECK-NEXT: .align 4 ; CHECK-NEXT: .align 4
; CHECK-NEXT: ArrayInitPartial: ; CHECK-NEXT: ArrayInitPartial:
; CHECK-NEXT: .byte ; CHECK-NEXT: .byte
; CHECK: .size ArrayInitPartial, 40 ; CHECK: .size ArrayInitPartial, 40
@PrimitiveInitStatic = internal global [4 x i8] zeroinitializer, align 4 @PrimitiveInitStatic = internal global [4 x i8] zeroinitializer, align 4
; CHECK: .data ; CHECK: .type PrimitiveInitStatic,@object
; CHECK-NEXT: .local PrimitiveInitStatic ; CHECK-NEXT: .local PrimitiveInitStatic
; CHECK-NEXT: .comm PrimitiveInitStatic, 4, 4 ; CHECK-NEXT: .comm PrimitiveInitStatic,4,4
@PrimitiveUninit = internal global [4 x i8] zeroinitializer, align 4 @PrimitiveUninit = internal global [4 x i8] zeroinitializer, align 4
; CHECK: .data ; CHECK: .type PrimitiveUninit,@object
; CHECK-NEXT: .local PrimitiveUninit ; CHECK-NEXT: .local PrimitiveUninit
; CHECK-NEXT: .comm PrimitiveUninit, 4, 4 ; CHECK-NEXT: .comm PrimitiveUninit,4,4
@ArrayUninit = internal global [20 x i8] zeroinitializer, align 4 @ArrayUninit = internal global [20 x i8] zeroinitializer, align 4
; CHECK: .data ; CHECK: .type ArrayUninit,@object
; CHECK-NEXT: .local ArrayUninit ; CHECK-NEXT: .local ArrayUninit
; CHECK-NEXT: .comm ArrayUninit, 20, 4 ; CHECK-NEXT: .comm ArrayUninit,20,4
@ArrayUninitConstDouble = internal constant [200 x i8] zeroinitializer, align 8 @ArrayUninitConstDouble = internal constant [200 x i8] zeroinitializer, align 8
; CHECK: .section .rodata,"a",@progbits ; CHECK: .type ArrayUninitConstDouble,@object
; CHECK-NEXT: .local ; CHECK-NEXT: .section .rodata,"a",@progbits
; CHECK-NEXT: .align 8 ; CHECK-NEXT: .align 8
; CHECK-NEXT: ArrayUninitConstDouble: ; CHECK-NEXT: ArrayUninitConstDouble:
; CHECK-NEXT: .zero 200 ; CHECK-NEXT: .zero 200
; CHECK-NEXT: .size ArrayUninitConstDouble, 200 ; CHECK-NEXT: .size ArrayUninitConstDouble, 200
@ArrayUninitConstInt = internal constant [20 x i8] zeroinitializer, align 4 @ArrayUninitConstInt = internal constant [20 x i8] zeroinitializer, align 4
; CHECK: .type ArrayUninitConstInt,@object
; CHECK: .section .rodata,"a",@progbits ; CHECK: .section .rodata,"a",@progbits
; CHECK-NEXT: .local
; CHECK-NEXT: .align 4 ; CHECK-NEXT: .align 4
; CHECK-NEXT: ArrayUninitConstInt: ; CHECK-NEXT: ArrayUninitConstInt:
; CHECK-NEXT: .zero 20 ; CHECK-NEXT: .zero 20
......
...@@ -11,63 +11,63 @@ ...@@ -11,63 +11,63 @@
; RUN: %p2i -i %s --args -verbose none | FileCheck --check-prefix=ERRORS %s ; RUN: %p2i -i %s --args -verbose none | FileCheck --check-prefix=ERRORS %s
@PrimitiveInit = internal global [4 x i8] c"\1B\00\00\00", align 4 @PrimitiveInit = internal global [4 x i8] c"\1B\00\00\00", align 4
; CHECK: .data ; CHECK: .type PrimitiveInit,@object
; CHECK-NEXT: .local ; CHECK-NEXT: .section .data,"aw",@progbits
; CHECK-NEXT: .align 4 ; CHECK-NEXT: .align 4
; CHECK-NEXT: PrimitiveInit: ; CHECK-NEXT: PrimitiveInit:
; CHECK-NEXT: .byte ; CHECK-NEXT: .byte
; CHECK: .size PrimitiveInit, 4 ; CHECK: .size PrimitiveInit, 4
@PrimitiveInitConst = internal constant [4 x i8] c"\0D\00\00\00", align 4 @PrimitiveInitConst = internal constant [4 x i8] c"\0D\00\00\00", align 4
; CHECK: .section .rodata,"a",@progbits ; CHECK: .type PrimitiveInitConst,@object
; CHECK-NEXT: .local ; CHECK-NEXT: .section .rodata,"a",@progbits
; CHECK-NEXT: .align 4 ; CHECK-NEXT: .align 4
; CHECK-NEXT: PrimitiveInitConst: ; CHECK-NEXT: PrimitiveInitConst:
; CHECK-NEXT: .byte ; CHECK-NEXT: .byte
; CHECK: .size PrimitiveInitConst, 4 ; CHECK: .size PrimitiveInitConst, 4
@ArrayInit = internal global [20 x i8] c"\0A\00\00\00\14\00\00\00\1E\00\00\00(\00\00\002\00\00\00", align 4 @ArrayInit = internal global [20 x i8] c"\0A\00\00\00\14\00\00\00\1E\00\00\00(\00\00\002\00\00\00", align 4
; CHECK: .data ; CHECK: .type ArrayInit,@object
; CHECK-NEXT: .local ; CHECK-NEXT: .section .data,"aw",@progbits
; CHECK-NEXT: .align 4 ; CHECK-NEXT: .align 4
; CHECK-NEXT: ArrayInit: ; CHECK-NEXT: ArrayInit:
; CHECK-NEXT: .byte ; CHECK-NEXT: .byte
; CHECK: .size ArrayInit, 20 ; CHECK: .size ArrayInit, 20
@ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4 @ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4
; CHECK: .data ; CHECK: .type ArrayInitPartial,@object
; CHECK-NEXT: .local ; CHECK-NEXT: .section .data,"aw",@progbits
; CHECK-NEXT: .align 4 ; CHECK-NEXT: .align 4
; CHECK-NEXT: ArrayInitPartial: ; CHECK-NEXT: ArrayInitPartial:
; CHECK-NEXT: .byte ; CHECK-NEXT: .byte
; CHECK: .size ArrayInitPartial, 40 ; CHECK: .size ArrayInitPartial, 40
@PrimitiveInitStatic = internal global [4 x i8] zeroinitializer, align 4 @PrimitiveInitStatic = internal global [4 x i8] zeroinitializer, align 4
; CHECK: .data ; CHECK: .type PrimitiveInitStatic,@object
; CHECK-NEXT: .local PrimitiveInitStatic ; CHECK-NEXT: .local PrimitiveInitStatic
; CHECK-NEXT: .comm PrimitiveInitStatic, 4, 4 ; CHECK-NEXT: .comm PrimitiveInitStatic,4,4
@PrimitiveUninit = internal global [4 x i8] zeroinitializer, align 4 @PrimitiveUninit = internal global [4 x i8] zeroinitializer, align 4
; CHECK: .data ; CHECK: .type PrimitiveUninit,@object
; CHECK-NEXT: .local PrimitiveUninit ; CHECK-NEXT: .local PrimitiveUninit
; CHECK-NEXT: .comm PrimitiveUninit, 4, 4 ; CHECK-NEXT: .comm PrimitiveUninit,4,4
@ArrayUninit = internal global [20 x i8] zeroinitializer, align 4 @ArrayUninit = internal global [20 x i8] zeroinitializer, align 4
; CHECK: .data ; CHECK: .type ArrayUninit,@object
; CHECK-NEXT: .local ArrayUninit ; CHECK-NEXT: .local ArrayUninit
; CHECK-NEXT: .comm ArrayUninit, 20, 4 ; CHECK-NEXT: .comm ArrayUninit,20,4
@ArrayUninitConstDouble = internal constant [200 x i8] zeroinitializer, align 8 @ArrayUninitConstDouble = internal constant [200 x i8] zeroinitializer, align 8
; CHECK: .section .rodata,"a",@progbits ; CHECK: .type ArrayUninitConstDouble,@object
; CHECK-NEXT: .local ; CHECK-NEXT: .section .rodata,"a",@progbits
; CHECK-NEXT: .align 8 ; CHECK-NEXT: .align 8
; CHECK-NEXT: ArrayUninitConstDouble: ; CHECK-NEXT: ArrayUninitConstDouble:
; CHECK-NEXT: .zero 200 ; CHECK-NEXT: .zero 200
; CHECK-NEXT: .size ArrayUninitConstDouble, 200 ; CHECK-NEXT: .size ArrayUninitConstDouble, 200
@ArrayUninitConstInt = internal constant [20 x i8] zeroinitializer, align 4 @ArrayUninitConstInt = internal constant [20 x i8] zeroinitializer, align 4
; CHECK: .type ArrayUninitConstInt,@object
; CHECK: .section .rodata,"a",@progbits ; CHECK: .section .rodata,"a",@progbits
; CHECK-NEXT: .local
; CHECK-NEXT: .align 4 ; CHECK-NEXT: .align 4
; CHECK-NEXT: ArrayUninitConstInt: ; CHECK-NEXT: ArrayUninitConstInt:
; CHECK-NEXT: .zero 20 ; CHECK-NEXT: .zero 20
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment