summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/LangRef.html5
-rw-r--r--include/llvm/Attributes.h29
-rw-r--r--lib/AsmParser/LLParser.cpp28
-rw-r--r--lib/AsmParser/LLParser.h1
-rw-r--r--lib/VMCore/Attributes.cpp5
-rw-r--r--test/Feature/alignment.ll4
6 files changed, 71 insertions, 1 deletions
diff --git a/docs/LangRef.html b/docs/LangRef.html
index fed2f80696..9590609a87 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -1078,6 +1078,11 @@ define void @f() optsize { ... }
</div>
<dl>
+ <dt><tt><b>alignstack(&lt;<em>n</em>&gt;)</b></tt></dt>
+ <dd>This attribute indicates that, when emitting the prologue and epilogue,
+ the backend should forcibly align the stack pointer. Specify the
+ desired alignment, which must be a power of two, in parentheses.
+
<dt><tt><b>alwaysinline</b></tt></dt>
<dd>This attribute indicates that the inliner should attempt to inline this
function into callers whenever possible, ignoring any active inlining size
diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h
index 068f81fc7d..126c290b5a 100644
--- a/include/llvm/Attributes.h
+++ b/include/llvm/Attributes.h
@@ -60,6 +60,11 @@ const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point
const Attributes Naked = 1<<24; ///< Naked function
const Attributes InlineHint = 1<<25; ///< source said inlining was
///desirable
+const Attributes StackAlignment = 31<<26; ///< Alignment of stack for
+ ///function (5 bits) stored as log2
+ ///of alignment with +1 bias
+ ///0 means unaligned (different from
+ ///alignstack(1))
/// @brief Attributes that only apply to function parameters.
const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
@@ -68,7 +73,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
/// be used on return values or function parameters.
const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |
- NoRedZone | NoImplicitFloat | Naked | InlineHint;
+ NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment;
/// @brief Parameter attributes that do not apply to vararg call arguments.
const Attributes VarArgsIncompatible = StructRet;
@@ -105,6 +110,28 @@ inline unsigned getAlignmentFromAttrs(Attributes A) {
return 1U << ((Align >> 16) - 1);
}
+/// This turns an int stack alignment (which must be a power of 2) into
+/// the form used internally in Attributes.
+inline Attributes constructStackAlignmentFromInt(unsigned i) {
+ // Default alignment, allow the target to define how to align it.
+ if (i == 0)
+ return 0;
+
+ assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
+ assert(i <= 0x40000000 && "Alignment too large.");
+ return (Log2_32(i)+1) << 26;
+}
+
+/// This returns the stack alignment field of an attribute as a byte alignment
+/// value.
+inline unsigned getStackAlignmentFromAttrs(Attributes A) {
+ Attributes StackAlign = A & Attribute::StackAlignment;
+ if (StackAlign == 0)
+ return 0;
+
+ return 1U << ((StackAlign >> 26) - 1);
+}
+
/// The set of Attributes set in Attributes is converted to a
/// string of equivalent mnemonics. This is, presumably, for writing out
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 5dd65691a3..4dab11826b 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -956,6 +956,14 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break;
case lltok::kw_naked: Attrs |= Attribute::Naked; break;
+ case lltok::kw_alignstack: {
+ unsigned Alignment;
+ if (ParseOptionalStackAlignment(Alignment))
+ return true;
+ Attrs |= Attribute::constructStackAlignmentFromInt(Alignment);
+ continue;
+ }
+
case lltok::kw_align: {
unsigned Alignment;
if (ParseOptionalAlignment(Alignment))
@@ -963,6 +971,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
Attrs |= Attribute::constructAlignmentFromInt(Alignment);
continue;
}
+
}
Lex.Lex();
}
@@ -1131,6 +1140,25 @@ bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment,
return false;
}
+/// ParseOptionalStackAlignment
+/// ::= /* empty */
+/// ::= 'alignstack' '(' 4 ')'
+bool LLParser::ParseOptionalStackAlignment(unsigned &Alignment) {
+ Alignment = 0;
+ if (!EatIfPresent(lltok::kw_alignstack))
+ return false;
+ LocTy ParenLoc = Lex.getLoc();
+ if (!EatIfPresent(lltok::lparen))
+ return Error(ParenLoc, "expected '('");
+ LocTy AlignLoc = Lex.getLoc();
+ if (ParseUInt32(Alignment)) return true;
+ ParenLoc = Lex.getLoc();
+ if (!EatIfPresent(lltok::rparen))
+ return Error(ParenLoc, "expected ')'");
+ if (!isPowerOf2_32(Alignment))
+ return Error(AlignLoc, "stack alignment is not a power of two");
+ return false;
+}
/// ParseIndexList - This parses the index list for an insert/extractvalue
/// instruction. This sets AteExtraComma in the case where we eat an extra
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index 85c07ffa8f..ed7a1d7117 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -169,6 +169,7 @@ namespace llvm {
bool ParseOptionalVisibility(unsigned &Visibility);
bool ParseOptionalCallingConv(CallingConv::ID &CC);
bool ParseOptionalAlignment(unsigned &Alignment);
+ bool ParseOptionalStackAlignment(unsigned &Alignment);
bool ParseInstructionMetadata(SmallVectorImpl<std::pair<unsigned,
MDNode *> > &);
bool ParseOptionalCommaAlign(unsigned &Alignment, bool &AteExtraComma);
diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp
index a371c6f92e..6fa597e958 100644
--- a/lib/VMCore/Attributes.cpp
+++ b/lib/VMCore/Attributes.cpp
@@ -70,6 +70,11 @@ std::string Attribute::getAsString(Attributes Attrs) {
Result += "noimplicitfloat ";
if (Attrs & Attribute::Naked)
Result += "naked ";
+ if (Attrs & Attribute::StackAlignment) {
+ Result += "alignstack(";
+ Result += utostr(Attribute::getStackAlignmentFromAttrs(Attrs));
+ Result += ") ";
+ }
if (Attrs & Attribute::Alignment) {
Result += "align ";
Result += utostr(Attribute::getAlignmentFromAttrs(Attrs));
diff --git a/test/Feature/alignment.ll b/test/Feature/alignment.ll
index 409efebe84..ef35a1344a 100644
--- a/test/Feature/alignment.ll
+++ b/test/Feature/alignment.ll
@@ -19,3 +19,7 @@ define i32* @test2() {
ret i32* %X
}
+define void @test3() alignstack(16) {
+ ret void
+}
+