summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Davis <cdavis@mines.edu>2010-02-12 00:31:15 +0000
committerCharles Davis <cdavis@mines.edu>2010-02-12 00:31:15 +0000
commit1e063d14df0f182626ebdd7ac7f32405aa754e03 (patch)
tree13d4b73826e6b511d2776a42af7549b53eed0371
parent4a540f0593f32d928534817b59c4a528e2197e0c (diff)
downloadllvm-1e063d14df0f182626ebdd7ac7f32405aa754e03.tar.gz
llvm-1e063d14df0f182626ebdd7ac7f32405aa754e03.tar.bz2
llvm-1e063d14df0f182626ebdd7ac7f32405aa754e03.tar.xz
Add a new function attribute, 'alignstack'. It will indicate (when the backends
implement support for it) that the stack should be forcibly realigned in the prologue (and the process reversed in the epilogue). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95945 91177308-0d34-0410-b5e6-96231b3b80d8
-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
+}
+