diff options
-rw-r--r-- | docs/LangRef.html | 6 | ||||
-rw-r--r-- | include/llvm/Target/TargetData.h | 6 | ||||
-rw-r--r-- | lib/Target/ARM/ARMTargetMachine.cpp | 15 | ||||
-rw-r--r-- | lib/Target/TargetData.cpp | 12 | ||||
-rw-r--r-- | lib/Target/X86/README-SSE.txt | 2 | ||||
-rw-r--r-- | lib/Target/X86/README.txt | 2 | ||||
-rw-r--r-- | lib/Target/X86/X86TargetMachine.cpp | 8 | ||||
-rw-r--r-- | lib/Transforms/Utils/Local.cpp | 8 |
8 files changed, 45 insertions, 14 deletions
diff --git a/docs/LangRef.html b/docs/LangRef.html index 1392db6e60..a28d92efa1 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -1319,6 +1319,12 @@ target datalayout = "<i>layout specification</i>" the bits with the least significance have the lowest address location.</dd> + <dt><tt>S<i>size</i></tt></dt> + <dd>Specifies the natural alignment of the stack in bits. Alignment promotion + of stack variables is limited to the natural stack alignment to avoid + dynamic stack realignment. The stack alignment must be a multiple of + 8-bits, and currently defaults to 128 bits if unspecified.</dd> + <dt><tt>p:<i>size</i>:<i>abi</i>:<i>pref</i></tt></dt> <dd>This specifies the <i>size</i> of a pointer and its <i>abi</i> and <i>preferred</i> alignments. All sizes are in bits. Specifying diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h index 315bee96ba..e34094ddb7 100644 --- a/include/llvm/Target/TargetData.h +++ b/include/llvm/Target/TargetData.h @@ -70,6 +70,7 @@ private: unsigned PointerMemSize; ///< Pointer size in bytes unsigned PointerABIAlign; ///< Pointer ABI alignment unsigned PointerPrefAlign; ///< Pointer preferred alignment + unsigned StackNaturalAlign; ///< Stack natural alignment SmallVector<unsigned char, 8> LegalIntWidths; ///< Legal Integers. @@ -163,6 +164,11 @@ public: return !isLegalInteger(Width); } + /// Returns true if the given alignment exceeds the natural stack alignment. + bool exceedsNaturalStackAlignment(unsigned Align) const { + return (StackNaturalAlign != 0) && (Align > StackNaturalAlign); + } + /// fitsInLegalInteger - This function returns true if the specified type fits /// in a native integer type supported by the CPU. For example, if the CPU /// only supports i32 as a native integer type, then i27 fits in a legal diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp index f779ede3e3..96b1e89b0d 100644 --- a/lib/Target/ARM/ARMTargetMachine.cpp +++ b/lib/Target/ARM/ARMTargetMachine.cpp @@ -53,9 +53,12 @@ ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT, : ARMBaseTargetMachine(T, TT, CPU, FS, RM, CM), InstrInfo(Subtarget), DataLayout(Subtarget.isAPCS_ABI() ? std::string("e-p:32:32-f64:32:64-i64:32:64-" - "v128:32:128-v64:32:64-n32") : + "v128:32:128-v64:32:64-n32-S32") : + Subtarget.isAAPCS_ABI() ? std::string("e-p:32:32-f64:64:64-i64:64:64-" - "v128:64:128-v64:64:64-n32")), + "v128:64:128-v64:64:64-n32-S64") : + std::string("e-p:32:32-f64:64:64-i64:64:64-" + "v128:64:128-v64:64:64-n32-S32")), ELFWriterInfo(*this), TLInfo(*this), TSInfo(*this), @@ -75,10 +78,14 @@ ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT, DataLayout(Subtarget.isAPCS_ABI() ? std::string("e-p:32:32-f64:32:64-i64:32:64-" "i16:16:32-i8:8:32-i1:8:32-" - "v128:32:128-v64:32:64-a:0:32-n32") : + "v128:32:128-v64:32:64-a:0:32-n32-S32") : + Subtarget.isAAPCS_ABI() ? + std::string("e-p:32:32-f64:64:64-i64:64:64-" + "i16:16:32-i8:8:32-i1:8:32-" + "v128:64:128-v64:64:64-a:0:32-n32-S64") : std::string("e-p:32:32-f64:64:64-i64:64:64-" "i16:16:32-i8:8:32-i1:8:32-" - "v128:64:128-v64:64:64-a:0:32-n32")), + "v128:64:128-v64:64:64-a:0:32-n32-S32")), ELFWriterInfo(*this), TLInfo(*this), TSInfo(*this), diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp index 1dfd9a83da..bd6a6b67be 100644 --- a/lib/Target/TargetData.cpp +++ b/lib/Target/TargetData.cpp @@ -139,6 +139,7 @@ void TargetData::init(StringRef Desc) { PointerMemSize = 8; PointerABIAlign = 8; PointerPrefAlign = PointerABIAlign; + StackNaturalAlign = 0; // Default alignments setAlignment(INTEGER_ALIGN, 1, 1, 1); // i1 @@ -218,7 +219,12 @@ void TargetData::init(StringRef Desc) { Token = Split.second; } while (!Specifier.empty() || !Token.empty()); break; - + case 'S': // Stack natural alignment. + StackNaturalAlign = getInt(Specifier.substr(1)); + StackNaturalAlign /= 8; + // FIXME: Should we really be truncating these alingments and + // sizes silently? + break; default: break; } @@ -372,7 +378,9 @@ std::string TargetData::getStringRepresentation() const { OS << (LittleEndian ? "e" : "E") << "-p:" << PointerMemSize*8 << ':' << PointerABIAlign*8 - << ':' << PointerPrefAlign*8; + << ':' << PointerPrefAlign*8 + << "-S" << StackNaturalAlign*8; + for (unsigned i = 0, e = Alignments.size(); i != e; ++i) { const TargetAlignElem &AI = Alignments[i]; OS << '-' << (char)AI.AlignType << AI.TypeBitWidth << ':' diff --git a/lib/Target/X86/README-SSE.txt b/lib/Target/X86/README-SSE.txt index f16ec029e9..7d901afae4 100644 --- a/lib/Target/X86/README-SSE.txt +++ b/lib/Target/X86/README-SSE.txt @@ -862,7 +862,7 @@ define float @bar(float %x) nounwind { This IR (from PR6194): -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-apple-darwin10.0.0" %0 = type { double, double } diff --git a/lib/Target/X86/README.txt b/lib/Target/X86/README.txt index b98f5fbb99..b407955060 100644 --- a/lib/Target/X86/README.txt +++ b/lib/Target/X86/README.txt @@ -1217,7 +1217,7 @@ Also check why xmm7 is not used at all in the function. Take the following: -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-S128" target triple = "i386-apple-darwin8" @in_exit.4870.b = internal global i1 false ; <i1*> [#uses=2] define fastcc void @abort_gzip() noreturn nounwind { diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp index 683d6aa0dd..1dcad35c2e 100644 --- a/lib/Target/X86/X86TargetMachine.cpp +++ b/lib/Target/X86/X86TargetMachine.cpp @@ -34,11 +34,11 @@ X86_32TargetMachine::X86_32TargetMachine(const Target &T, StringRef TT, Reloc::Model RM, CodeModel::Model CM) : X86TargetMachine(T, TT, CPU, FS, RM, CM, false), DataLayout(getSubtargetImpl()->isTargetDarwin() ? - "e-p:32:32-f64:32:64-i64:32:64-f80:128:128-f128:128:128-n8:16:32" : + "e-p:32:32-f64:32:64-i64:32:64-f80:128:128-f128:128:128-n8:16:32-S128" : (getSubtargetImpl()->isTargetCygMing() || getSubtargetImpl()->isTargetWindows()) ? - "e-p:32:32-f64:64:64-i64:64:64-f80:32:32-f128:128:128-n8:16:32" : - "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-f128:128:128-n8:16:32"), + "e-p:32:32-f64:64:64-i64:64:64-f80:32:32-f128:128:128-n8:16:32-S32" : + "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-f128:128:128-n8:16:32-S32"), InstrInfo(*this), TSInfo(*this), TLInfo(*this), @@ -50,7 +50,7 @@ X86_64TargetMachine::X86_64TargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, Reloc::Model RM, CodeModel::Model CM) : X86TargetMachine(T, TT, CPU, FS, RM, CM, true), - DataLayout("e-p:64:64-s:64-f64:64:64-i64:64:64-f80:128:128-f128:128:128-n8:16:32:64"), + DataLayout("e-p:64:64-s:64-f64:64:64-i64:64:64-f80:128:128-f128:128:128-n8:16:32:64-S128"), InstrInfo(*this), TSInfo(*this), TLInfo(*this), diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index be0aa82500..7034feb227 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -721,10 +721,14 @@ bool llvm::EliminateDuplicatePHINodes(BasicBlock *BB) { /// their preferred alignment from the beginning. /// static unsigned enforceKnownAlignment(Value *V, unsigned Align, - unsigned PrefAlign) { + unsigned PrefAlign, const TargetData *TD) { V = V->stripPointerCasts(); if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) { + // If the preferred alignment is greater than the natural stack alignment + // then don't round up. This avoids dynamic stack realignment. + if (TD && TD->exceedsNaturalStackAlignment(PrefAlign)) + return Align; // If there is a requested alignment and if this is an alloca, round up. if (AI->getAlignment() >= PrefAlign) return AI->getAlignment(); @@ -775,7 +779,7 @@ unsigned llvm::getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign, Align = std::min(Align, +Value::MaximumAlignment); if (PrefAlign > Align) - Align = enforceKnownAlignment(V, Align, PrefAlign); + Align = enforceKnownAlignment(V, Align, PrefAlign, TD); // We don't need to make any adjustment. return Align; |