1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

Define behavior of "stack-probe-size" attribute when inlining.

Also document the attribute, since "probe-stack" already is.

Reviewed By: majnemer

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

llvm-svn: 306069
This commit is contained in:
whitequark 2017-06-22 23:22:36 +00:00
parent 22acc4c817
commit 539780b2eb
4 changed files with 73 additions and 2 deletions

View File

@ -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.

View File

@ -215,3 +215,4 @@ def : MergeRule<"setOR<NoImplicitFloatAttr>">;
def : MergeRule<"setOR<NoJumpTablesAttr>">;
def : MergeRule<"adjustCallerSSPLevel">;
def : MergeRule<"adjustCallerStackProbes">;
def : MergeRule<"adjustCallerStackProbeSize">;

View File

@ -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

View File

@ -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" }