Bill's change in r95336 broke empty aggregates embedded

in other types.  fix this by only bumping zero-byte globals
up to a single byte if the *entire global* is zero size,
fixing PR6340.

This also fixes empty arrays etc to be handled correctly,
and only does this on subsection-via-symbols targets (aka
darwin) which is the only place where this matters.

llvm-svn: 101879
This commit is contained in:
Chris Lattner 2010-04-20 06:20:21 +00:00
parent 52c28fe61a
commit 5100367ff3
2 changed files with 52 additions and 25 deletions

View File

@ -1155,6 +1155,10 @@ void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV,
OutStreamer.EmitValueToAlignment(1 << NumBits, 0, 1, 0); OutStreamer.EmitValueToAlignment(1 << NumBits, 0, 1, 0);
} }
//===----------------------------------------------------------------------===//
// Constant emission.
//===----------------------------------------------------------------------===//
/// LowerConstant - Lower the specified LLVM Constant to an MCExpr. /// LowerConstant - Lower the specified LLVM Constant to an MCExpr.
/// ///
static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) { static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) {
@ -1282,12 +1286,15 @@ static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) {
} }
} }
static void EmitGlobalConstantImpl(const Constant *C, unsigned AddrSpace,
AsmPrinter &AP);
static void EmitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace, static void EmitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace,
AsmPrinter &AP) { AsmPrinter &AP) {
if (AddrSpace != 0 || !CA->isString()) { if (AddrSpace != 0 || !CA->isString()) {
// Not a string. Print the values in successive locations // Not a string. Print the values in successive locations
for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
AP.EmitGlobalConstant(CA->getOperand(i), AddrSpace); EmitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP);
return; return;
} }
@ -1303,7 +1310,7 @@ static void EmitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace,
static void EmitGlobalConstantVector(const ConstantVector *CV, static void EmitGlobalConstantVector(const ConstantVector *CV,
unsigned AddrSpace, AsmPrinter &AP) { unsigned AddrSpace, AsmPrinter &AP) {
for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i) for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i)
AP.EmitGlobalConstant(CV->getOperand(i), AddrSpace); EmitGlobalConstantImpl(CV->getOperand(i), AddrSpace, AP);
} }
static void EmitGlobalConstantStruct(const ConstantStruct *CS, static void EmitGlobalConstantStruct(const ConstantStruct *CS,
@ -1323,7 +1330,7 @@ static void EmitGlobalConstantStruct(const ConstantStruct *CS,
SizeSoFar += FieldSize + PadSize; SizeSoFar += FieldSize + PadSize;
// Now print the actual field value. // Now print the actual field value.
AP.EmitGlobalConstant(Field, AddrSpace); EmitGlobalConstantImpl(Field, AddrSpace, AP);
// Insert padding - this may include padding to increase the size of the // Insert padding - this may include padding to increase the size of the
// current field up to the ABI size (if the struct is not packed) as well // current field up to the ABI size (if the struct is not packed) as well
@ -1343,7 +1350,7 @@ static void EmitGlobalConstantUnion(const ConstantUnion *CU,
unsigned FilledSize = TD->getTypeAllocSize(Contents->getType()); unsigned FilledSize = TD->getTypeAllocSize(Contents->getType());
// Print the actually filled part // Print the actually filled part
AP.EmitGlobalConstant(Contents, AddrSpace); EmitGlobalConstantImpl(Contents, AddrSpace, AP);
// And pad with enough zeroes // And pad with enough zeroes
AP.OutStreamer.EmitZeros(Size-FilledSize, AddrSpace); AP.OutStreamer.EmitZeros(Size-FilledSize, AddrSpace);
@ -1435,59 +1442,70 @@ static void EmitGlobalConstantLargeInt(const ConstantInt *CI,
} }
} }
/// EmitGlobalConstant - Print a general LLVM constant to the .s file. static void EmitGlobalConstantImpl(const Constant *CV, unsigned AddrSpace,
void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) { AsmPrinter &AP) {
if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV)) { if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV)) {
uint64_t Size = TM.getTargetData()->getTypeAllocSize(CV->getType()); uint64_t Size = AP.TM.getTargetData()->getTypeAllocSize(CV->getType());
if (Size == 0) Size = 1; // An empty "_foo:" followed by a section is undef. return AP.OutStreamer.EmitZeros(Size, AddrSpace);
return OutStreamer.EmitZeros(Size, AddrSpace);
} }
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
unsigned Size = TM.getTargetData()->getTypeAllocSize(CV->getType()); unsigned Size = AP.TM.getTargetData()->getTypeAllocSize(CV->getType());
switch (Size) { switch (Size) {
case 1: case 1:
case 2: case 2:
case 4: case 4:
case 8: case 8:
if (isVerbose()) if (AP.isVerbose())
OutStreamer.GetCommentOS() << format("0x%llx\n", CI->getZExtValue()); AP.OutStreamer.GetCommentOS() << format("0x%llx\n", CI->getZExtValue());
OutStreamer.EmitIntValue(CI->getZExtValue(), Size, AddrSpace); AP.OutStreamer.EmitIntValue(CI->getZExtValue(), Size, AddrSpace);
return; return;
default: default:
EmitGlobalConstantLargeInt(CI, AddrSpace, *this); EmitGlobalConstantLargeInt(CI, AddrSpace, AP);
return; return;
} }
} }
if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV))
return EmitGlobalConstantArray(CVA, AddrSpace, *this); return EmitGlobalConstantArray(CVA, AddrSpace, AP);
if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
return EmitGlobalConstantStruct(CVS, AddrSpace, *this); return EmitGlobalConstantStruct(CVS, AddrSpace, AP);
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))
return EmitGlobalConstantFP(CFP, AddrSpace, *this); return EmitGlobalConstantFP(CFP, AddrSpace, AP);
if (isa<ConstantPointerNull>(CV)) { if (isa<ConstantPointerNull>(CV)) {
unsigned Size = TM.getTargetData()->getTypeAllocSize(CV->getType()); unsigned Size = AP.TM.getTargetData()->getTypeAllocSize(CV->getType());
OutStreamer.EmitIntValue(0, Size, AddrSpace); AP.OutStreamer.EmitIntValue(0, Size, AddrSpace);
return; return;
} }
if (const ConstantUnion *CVU = dyn_cast<ConstantUnion>(CV)) if (const ConstantUnion *CVU = dyn_cast<ConstantUnion>(CV))
return EmitGlobalConstantUnion(CVU, AddrSpace, *this); return EmitGlobalConstantUnion(CVU, AddrSpace, AP);
if (const ConstantVector *V = dyn_cast<ConstantVector>(CV)) if (const ConstantVector *V = dyn_cast<ConstantVector>(CV))
return EmitGlobalConstantVector(V, AddrSpace, *this); return EmitGlobalConstantVector(V, AddrSpace, AP);
// Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it // Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it
// thread the streamer with EmitValue. // thread the streamer with EmitValue.
OutStreamer.EmitValue(LowerConstant(CV, *this), AP.OutStreamer.EmitValue(LowerConstant(CV, AP),
TM.getTargetData()->getTypeAllocSize(CV->getType()), AP.TM.getTargetData()->getTypeAllocSize(CV->getType()),
AddrSpace); AddrSpace);
} }
/// EmitGlobalConstant - Print a general LLVM constant to the .s file.
void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) {
uint64_t Size = TM.getTargetData()->getTypeAllocSize(CV->getType());
if (Size)
EmitGlobalConstantImpl(CV, AddrSpace, *this);
else if (MAI->hasSubsectionsViaSymbols()) {
// If the global has zero size, emit a single byte so that two labels don't
// look like they are at the same location.
OutStreamer.EmitIntValue(0, 1, AddrSpace);
}
}
void AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { void AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
// Target doesn't support this yet! // Target doesn't support this yet!
llvm_unreachable("Target does not support EmitMachineConstantPoolValue"); llvm_unreachable("Target does not support EmitMachineConstantPoolValue");

View File

@ -8,4 +8,13 @@
; CHECK: .globl __cmd ; CHECK: .globl __cmd
; CHECK-NEXT: .align 3 ; CHECK-NEXT: .align 3
; CHECK-NEXT: __cmd: ; CHECK-NEXT: __cmd:
; CHECK-NEXT: .space 1 ; CHECK-NEXT: .byte 0
; PR6340
%Ty = type { i32, {}, i32 }
@k = global %Ty { i32 1, {} zeroinitializer, i32 3 }
; CHECK: _k:
; CHECK-NEXT: .long 1
; CHECK-NEXT: .long 3