diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/CodeGen/AsmPrinter.h | 9 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 56 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/alignment.ll | 29 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/unaligned-load.ll | 4 | ||||
| -rw-r--r-- | llvm/test/FrontendC/cstring-align.c | 5 | 
5 files changed, 70 insertions, 33 deletions
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h index b5c287ae90f..243ddbb5da3 100644 --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -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); diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 68e70aae6ab..a694033fa1d 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -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); diff --git a/llvm/test/CodeGen/X86/alignment.ll b/llvm/test/CodeGen/X86/alignment.ll index 06a4f3f8e88..9678e6df740 100644 --- a/llvm/test/CodeGen/X86/alignment.ll +++ b/llvm/test/CodeGen/X86/alignment.ll @@ -6,7 +6,7 @@  ; CHECK:	.bss  ; CHECK:	.globl	GlobalA -; CHECK:	.align	8 +; CHECK:	.align	16  ; CHECK: GlobalA:  ; CHECK:	.zero	384 @@ -15,4 +15,29 @@  ; 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 diff --git a/llvm/test/CodeGen/X86/unaligned-load.ll b/llvm/test/CodeGen/X86/unaligned-load.ll index b26097f31b4..a99af0605b1 100644 --- a/llvm/test/CodeGen/X86/unaligned-load.ll +++ b/llvm/test/CodeGen/X86/unaligned-load.ll @@ -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: diff --git a/llvm/test/FrontendC/cstring-align.c b/llvm/test/FrontendC/cstring-align.c index 715d0f31269..b9ec281f567 100644 --- a/llvm/test/FrontendC/cstring-align.c +++ b/llvm/test/FrontendC/cstring-align.c @@ -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"  | 

