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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306069 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
whitequark committed Jun 22, 2017
1 parent e83d2ec commit e4b1890
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 2 deletions.
15 changes: 15 additions & 0 deletions docs/LangRef.rst
Original file line number Diff line number Diff line change
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 include/llvm/IR/Attributes.td
Original file line number Diff line number Diff line change
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 lib/IR/Attributes.cpp
Original file line number Diff line number Diff line change
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 test/Transforms/Inline/inline-stack-probe-size.ll
Original file line number Diff line number Diff line change
@@ -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 e4b1890

Please sign in to comment.