Skip to content

Commit

Permalink
Define behavior of "stack-probe-size" attribute when inlining.
Browse files Browse the repository at this point in the history
Also document the attribute, since "probe-stack" already is.

Reviewed By: majnemer

Differential Revision: https://reviews.llvm.org/D34528

llvm-svn: 306069
  • Loading branch information
whitequark committed Jun 22, 2017
1 parent 4b652a5 commit 08b2035
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 2 deletions.
15 changes: 15 additions & 0 deletions llvm/docs/LangRef.rst
Expand Up @@ -1511,6 +1511,21 @@ example:
On an argument, this attribute indicates that the function does not write
through this pointer argument, even though it may write to the memory that
the pointer points to.
``"stack-probe-size"``
This attribute controls the behavior of stack probes: either
the ``"probe-stack"`` attribute, or ABI-required stack probes, if any.
It defines the size of the guard region. It ensures that if the function
may use more stack space than the size of the guard region, stack probing
sequence will be emitted. It takes one required integer value, which
is 4096 by default.

If a function that has a ``"stack-probe-size"`` attribute is inlined into
a function with another ``"stack-probe-size"`` attribute, the resulting
function has the ``"stack-probe-size"`` attribute that has the lower
numeric value. If a function that has a ``"stack-probe-size"`` attribute is
inlined into a function that has no ``"stack-probe-size"`` attribute
at all, the resulting function has the ``"stack-probe-size"`` attribute
of the callee.
``writeonly``
On a function, this attribute indicates that the function may write to but
does not read from memory.
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/IR/Attributes.td
Expand Up @@ -215,3 +215,4 @@ def : MergeRule<"setOR<NoImplicitFloatAttr>">;
def : MergeRule<"setOR<NoJumpTablesAttr>">;
def : MergeRule<"adjustCallerSSPLevel">;
def : MergeRule<"adjustCallerStackProbes">;
def : MergeRule<"adjustCallerStackProbeSize">;
30 changes: 28 additions & 2 deletions llvm/lib/IR/Attributes.cpp
Expand Up @@ -1641,8 +1641,34 @@ static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
/// \brief If the inlined function required stack probes, then ensure that
/// the calling function has those too.
static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
if (!Caller.hasFnAttribute("probe-stack") && Callee.hasFnAttribute("probe-stack"))
Caller.addFnAttr("probe-stack", Callee.getFnAttribute("probe-stack").getValueAsString());
if (!Caller.hasFnAttribute("probe-stack") &&
Callee.hasFnAttribute("probe-stack")) {
Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
}
}

/// \brief If the inlined function defines the size of guard region
/// on the stack, then ensure that the calling function defines a guard region
/// that is no larger.
static void
adjustCallerStackProbeSize(Function &Caller, const Function &Callee) {
if (Callee.hasFnAttribute("stack-probe-size")) {
uint64_t CalleeStackProbeSize;
Callee.getFnAttribute("stack-probe-size")
.getValueAsString()
.getAsInteger(0, CalleeStackProbeSize);
if (Caller.hasFnAttribute("stack-probe-size")) {
uint64_t CallerStackProbeSize;
Caller.getFnAttribute("stack-probe-size")
.getValueAsString()
.getAsInteger(0, CallerStackProbeSize);
if (CallerStackProbeSize > CalleeStackProbeSize) {
Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
}
} else {
Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
}
}
}

#define GET_ATTR_COMPAT_FUNC
Expand Down
29 changes: 29 additions & 0 deletions llvm/test/Transforms/Inline/inline-stack-probe-size.ll
@@ -0,0 +1,29 @@
; RUN: opt %s -inline -S | FileCheck %s

define internal void @innerSmall() "stack-probe-size"="4096" {
ret void
}

define internal void @innerLarge() "stack-probe-size"="8192" {
ret void
}

define void @outerNoAttribute() {
call void @innerSmall()
ret void
}

define void @outerConflictingAttributeSmall() "stack-probe-size"="4096" {
call void @innerLarge()
ret void
}

define void @outerConflictingAttributeLarge() "stack-probe-size"="8192" {
call void @innerSmall()
ret void
}

; CHECK: define void @outerNoAttribute() #0
; CHECK: define void @outerConflictingAttributeSmall() #0
; CHECK: define void @outerConflictingAttributeLarge() #0
; CHECK: attributes #0 = { "stack-probe-size"="4096" }

0 comments on commit 08b2035

Please sign in to comment.