OSDN Git Service

Rework global alignment computation again. Now we do round up
authorChris Lattner <sabre@nondot.org>
Wed, 28 Apr 2010 19:58:07 +0000 (19:58 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 28 Apr 2010 19:58:07 +0000 (19:58 +0000)
alignment of globals to the preferred alignment, but only when
there is no section specified on the global (by far the common
case).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102515 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/AsmPrinter.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
test/CodeGen/X86/alignment.ll
test/CodeGen/X86/unaligned-load.ll
test/FrontendC/cstring-align.c

index b5c287a..243ddbb 100644 (file)
@@ -204,12 +204,8 @@ namespace llvm {
     /// EmitAlignment - Emit an alignment directive to the specified power of
     /// two boundary.  For example, if you pass in 3 here, you will get an 8
     /// byte alignment.  If a global value is specified, and if that global has
-    /// an explicit alignment requested, it will unconditionally override the
-    /// alignment request.
-    ///
-    /// The algorithm is:
-    ///     Align = NumBits;
-    ///     if (GV && GV->hasalignment) Align = GV->getAlignment();
+    /// an explicit alignment requested, it will override the alignment request
+    /// if required for correctness.
     ///
     void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0) const;
     
@@ -218,7 +214,6 @@ namespace llvm {
     /// it if appropriate.
     void EmitBasicBlockStart(const MachineBasicBlock *MBB) const;
     
-    
     /// EmitGlobalConstant - Print a general LLVM constant to the .s file.
     void EmitGlobalConstant(const Constant *CV, unsigned AddrSpace = 0);
     
index 68e70aa..a694033 100644 (file)
@@ -61,6 +61,35 @@ static gcp_map_type &getGCMap(void *&P) {
 }
 
 
+/// getGVAlignmentLog2 - Return the alignment to use for the specified global
+/// value in log2 form.  This rounds up to the preferred alignment if possible
+/// and legal.
+static unsigned getGVAlignmentLog2(const GlobalValue *GV, const TargetData &TD,
+                                   unsigned InBits = 0) {
+  unsigned NumBits = 0;
+  if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
+    NumBits = TD.getPreferredAlignmentLog(GVar);
+  
+  // If InBits is specified, round it to it.
+  if (InBits > NumBits)
+    NumBits = InBits;
+  
+  // If the GV has a specified alignment, take it into account.
+  if (GV->getAlignment() == 0)
+    return NumBits;
+  
+  unsigned GVAlign = Log2_32(GV->getAlignment());
+  
+  // If the GVAlign is larger than NumBits, or if we are required to obey
+  // NumBits because the GV has an assigned section, obey it.
+  if (GVAlign > NumBits || GV->hasSection())
+    NumBits = GVAlign;
+  return NumBits;
+}
+
+
+
+
 AsmPrinter::AsmPrinter(TargetMachine &tm, MCStreamer &Streamer)
   : MachineFunctionPass(&ID),
     TM(tm), MAI(tm.getMCAsmInfo()),
@@ -227,16 +256,12 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
   SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM);
 
   const TargetData *TD = TM.getTargetData();
-  unsigned Size = TD->getTypeAllocSize(GV->getType()->getElementType());
+  uint64_t Size = TD->getTypeAllocSize(GV->getType()->getElementType());
   
   // If the alignment is specified, we *must* obey it.  Overaligning a global
   // with a specified alignment is a prompt way to break globals emitted to
   // sections and expected to be contiguous (e.g. ObjC metadata).
-  unsigned AlignLog;
-  if (unsigned GVAlign = GV->getAlignment())
-    AlignLog = Log2_32(GVAlign);
-  else
-    AlignLog = TD->getPreferredAlignmentLog(GV);
+  unsigned AlignLog = getGVAlignmentLog2(GV, *TD);
   
   // Handle common and BSS local symbols (.lcomm).
   if (GVKind.isCommon() || GVKind.isBSSLocal()) {
@@ -1010,7 +1035,7 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
   unsigned Align = Log2_32(TD->getPointerPrefAlignment());
   if (GV->getName() == "llvm.global_ctors") {
     OutStreamer.SwitchSection(getObjFileLowering().getStaticCtorSection());
-    EmitAlignment(Align, 0);
+    EmitAlignment(Align);
     EmitXXStructorList(GV->getInitializer());
     
     if (TM.getRelocationModel() == Reloc::Static &&
@@ -1024,7 +1049,7 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
   
   if (GV->getName() == "llvm.global_dtors") {
     OutStreamer.SwitchSection(getObjFileLowering().getStaticDtorSection());
-    EmitAlignment(Align, 0);
+    EmitAlignment(Align);
     EmitXXStructorList(GV->getInitializer());
 
     if (TM.getRelocationModel() == Reloc::Static &&
@@ -1153,20 +1178,13 @@ void AsmPrinter::EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset,
 // EmitAlignment - Emit an alignment directive to the specified power of
 // two boundary.  For example, if you pass in 3 here, you will get an 8
 // byte alignment.  If a global value is specified, and if that global has
-// an explicit alignment requested, it will unconditionally override the
-// alignment request.  However, if ForcedAlignBits is specified, this value
-// has final say: the ultimate alignment will be the max of ForcedAlignBits
-// and the alignment computed with NumBits and the global.
-//
-// The algorithm is:
-//     Align = NumBits;
-//     if (GV && GV->hasalignment) Align = GV->getAlignment();
+// an explicit alignment requested, it will override the alignment request
+// if required for correctness.
 //
 void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV) const {
-  if (GV && GV->getAlignment())
-    NumBits = Log2_32(GV->getAlignment());
+  if (GV) NumBits = getGVAlignmentLog2(GV, *TM.getTargetData(), NumBits);
   
-  if (NumBits == 0) return;   // No need to emit alignment.
+  if (NumBits == 0) return;   // 1-byte aligned: no need to emit alignment.
   
   if (getCurrentSection()->getKind().isText())
     OutStreamer.EmitCodeAlignment(1 << NumBits);
index 06a4f3f..9678e6d 100644 (file)
@@ -6,7 +6,7 @@
 
 ; CHECK:       .bss
 ; CHECK:       .globl  GlobalA
-; CHECK:       .align  8
+; CHECK:       .align  16
 ; CHECK: GlobalA:
 ; CHECK:       .zero   384
 
 ; PR6921
 @GlobalB = common global { [384 x i8] } zeroinitializer, align 8
 
-; CHECK:       .comm   GlobalB,384,8
\ No newline at end of file
+; CHECK:       .comm   GlobalB,384,16
+
+
+@GlobalC = common global { [384 x i8] } zeroinitializer, align 2
+
+; CHECK:       .comm   GlobalC,384,16
+
+
+
+; This cannot get rounded up to the preferred alignment (16) if they have an
+; explicit alignment specified *and* a section specified.
+@GlobalAS = global { [384 x i8] } zeroinitializer, align 8, section "foo"
+
+; CHECK:       .globl  GlobalAS
+; CHECK:       .align  8
+; CHECK: GlobalAS:
+; CHECK:       .zero   384
+
+; Common variables should not get rounded up to the preferred alignment (16) if
+; they have an explicit alignment specified and a section specified.
+; PR6921
+@GlobalBS = common global { [384 x i8] } zeroinitializer, align 8, section "foo"
+; CHECK:       .comm   GlobalBS,384,8
+
+@GlobalCS = common global { [384 x i8] } zeroinitializer, align 2, section "foo"
+; CHECK:       .comm   GlobalCS,384,2
\ No newline at end of file
index b26097f..a99af06 100644 (file)
@@ -29,8 +29,8 @@ return:
 declare void @llvm.memcpy.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind
 
 ; CORE2: .section
-; CORE2: .align  3
+; CORE2: .align  4
 ; CORE2-NEXT: _.str1:
 ; CORE2-NEXT: .asciz "DHRYSTONE PROGRAM, SOME STRING"
-; CORE2: .align 3
+; CORE2: .align 4
 ; CORE2-NEXT: _.str3:
index 715d0f3..b9ec281 100644 (file)
@@ -1,6 +1,5 @@
 // RUN: %llvmgcc %s -c -Os -m32 -emit-llvm -o - | llc -march=x86 -mtriple=i386-apple-darwin10 | FileCheck %s -check-prefix=DARWIN32
 // RUN: %llvmgcc %s -c -Os -m64 -emit-llvm -o - | llc -march=x86-64 -mtriple=x86_64-apple-darwin10 | FileCheck %s -check-prefix=DARWIN64
-// XFAIL: *
 // XTARGET: darwin
 
 extern void func(const char *, const char *);
@@ -9,10 +8,10 @@ void long_function_name() {
   func("%s: the function name", __func__);
 }
 
-// DARWIN64: .align 3
+// DARWIN64: .align 4
 // DARWIN64: ___func__.
 // DARWIN64: .asciz "long_function_name"
 
-// DARWIN32: .align 2
+// DARWIN32: .align 4
 // DARWIN32: ___func__.
 // DARWIN32: .asciz "long_function_name"