summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2012-06-20 12:05:05 +0000
committerBill Wendling <isanbard@gmail.com>2012-06-20 12:05:05 +0000
commit47997e877cf4469e70dcb323542fef7d8ed615fd (patch)
treea460714b4ae29713d6cae15357eba8b780b221e4
parenteef31a5031dfb7770ec1fc3cf207f797005a2f78 (diff)
downloadllvm-47997e877cf4469e70dcb323542fef7d8ed615fd.tar.gz
llvm-47997e877cf4469e70dcb323542fef7d8ed615fd.tar.bz2
llvm-47997e877cf4469e70dcb323542fef7d8ed615fd.tar.xz
Sphinxify the SegmentedStack document.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158819 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--docs/SegmentedStacks.html93
-rw-r--r--docs/SegmentedStacks.rst80
-rw-r--r--docs/subsystems.rst7
3 files changed, 86 insertions, 94 deletions
diff --git a/docs/SegmentedStacks.html b/docs/SegmentedStacks.html
deleted file mode 100644
index 052003bc63..0000000000
--- a/docs/SegmentedStacks.html
+++ /dev/null
@@ -1,93 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
- <head>
- <title>Segmented Stacks in LLVM</title>
- <link rel="stylesheet" href="_static/llvm.css" type="text/css">
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- </head>
-
- <body>
- <h1>Segmented Stacks in LLVM</h1>
- <div class="doc_author">
- <p>Written by <a href="mailto:sanjoy@playingwithpointers.com">Sanjoy Das</a></p>
- </div>
-
- <ol>
- <li><a href="#intro">Introduction</a></li>
- <li><a href="#implementation">Implementation Details</a>
- <ol>
- <li><a href="#morestack">Allocating Stacklets</a></li>
- <li><a href="#alloca">Variable Sized Allocas</a></li>
- </ol>
- </li>
- </ol>
-
- <h2><a name="intro">Introduction</a></h2>
- <div>
- <p>
- Segmented stack allows stack space to be allocated incrementally than as a monolithic chunk (of some worst case size) at thread initialization. This is done by allocating stack blocks (henceforth called <em>stacklets</em>) and linking them into a doubly linked list. The function prologue is responsible for checking if the current stacklet has enough space for the function to execute; and if not, call into the libgcc runtime to allocate more stack space. When using <tt>llc</tt>, segmented stacks can be enabled by adding <tt>-segmented-stacks</tt> to the command line.
- </p>
- <p>
- The runtime functionality is <a href="http://gcc.gnu.org/wiki/SplitStacks">already there in libgcc</a>.
- </p>
- </div>
-
- <h2><a name="implementation">Implementation Details</a></h2>
- <div>
- <h3><a name="morestack">Allocating Stacklets</a></h3>
- <div>
- <p>
- As mentioned above, the function prologue checks if the current stacklet has enough space. The current approach is to use a slot in the TCB to store the current stack limit (minus the amount of space needed to allocate a new block) - this slot's offset is again dictated by <code>libgcc</code>. The generated assembly looks like this on x86-64:
- </p>
- <pre>
- leaq -8(%rsp), %r10
- cmpq %fs:112, %r10
- jg .LBB0_2
-
- # More stack space needs to be allocated
- movabsq $8, %r10 # The amount of space needed
- movabsq $0, %r11 # The total size of arguments passed on stack
- callq __morestack
- ret # The reason for this extra return is explained below
- .LBB0_2:
- # Usual prologue continues here
- </pre>
- <p>
- The size of function arguments on the stack needs to be passed to <code> __morestack</code> (this function is implemented in <code>libgcc</code>) since that number of bytes has to be copied from the previous stacklet to the current one. This is so that SP (and FP) relative addressing of function arguments work as expected.
- </p>
- <p>
- The unusual <code>ret</code> is needed to have the function which made a call to <code>__morestack</code> return correctly. <code>__morestack</code>, instead of returning, calls into <code>.LBB0_2</code>. This is possible since both, the size of the <code>ret</code> instruction and the PC of call to <code>__morestack</code> are known. When the function body returns, control is transferred back to <code>__morestack</code>. <code>__morestack</code> then de-allocates the new stacklet, restores the correct SP value, and does a second return, which returns control to the correct caller.
- </p>
- </div>
-
- <h3><a name="alloca">Variable Sized Allocas</a></h3>
- <div>
- <p>
- The section on <a href="#morestack">allocating stacklets</a> automatically assumes that every stack frame will be of fixed size. However, LLVM allows the use of the <code>llvm.alloca</code> intrinsic to allocate dynamically sized blocks of memory on the stack. When faced with such a variable-sized alloca, code is generated to
- </p>
- <ul>
- <li>Check if the current stacklet has enough space. If yes, just bump the SP, like in the normal case.</li>
- <li>If not, generate a call to <code>libgcc</code>, which allocates the memory from the heap.</li>
- </ul>
- <p>
- The memory allocated from the heap is linked into a list in the current stacklet, and freed along with the same. This prevents a memory leak.
- </p>
- </div>
-
- </div>
-
- <hr>
- <address>
- <a href="http://jigsaw.w3.org/css-validator/check/referer">
- <img src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS">
- </a>
- <a href="http://validator.w3.org/check/referer">
- <img src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01">
- </a>
- <a href="mailto:sanjoy@playingwithpointers.com">Sanjoy Das</a><br>
- <a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date$
- </address>
- </body>
-</html>
-
diff --git a/docs/SegmentedStacks.rst b/docs/SegmentedStacks.rst
new file mode 100644
index 0000000000..f97d62abda
--- /dev/null
+++ b/docs/SegmentedStacks.rst
@@ -0,0 +1,80 @@
+.. _segmented_stacks:
+
+========================
+Segmented Stacks in LLVM
+========================
+
+.. contents::
+ :local:
+
+Introduction
+============
+
+Segmented stack allows stack space to be allocated incrementally than as a
+monolithic chunk (of some worst case size) at thread initialization. This is
+done by allocating stack blocks (henceforth called *stacklets*) and linking them
+into a doubly linked list. The function prologue is responsible for checking if
+the current stacklet has enough space for the function to execute; and if not,
+call into the libgcc runtime to allocate more stack space. When using ``llc``,
+segmented stacks can be enabled by adding ``-segmented-stacks`` to the command
+line.
+
+The runtime functionality is `already there in libgcc
+<http://gcc.gnu.org/wiki/SplitStacks>`_.
+
+Implementation Details
+======================
+
+.. _allocating stacklets:
+
+Allocating Stacklets
+--------------------
+
+As mentioned above, the function prologue checks if the current stacklet has
+enough space. The current approach is to use a slot in the TCB to store the
+current stack limit (minus the amount of space needed to allocate a new block) -
+this slot's offset is again dictated by ``libgcc``. The generated
+assembly looks like this on x86-64:
+
+.. code-block:: nasm
+
+ leaq -8(%rsp), %r10
+ cmpq %fs:112, %r10
+ jg .LBB0_2
+
+ # More stack space needs to be allocated
+ movabsq $8, %r10 # The amount of space needed
+ movabsq $0, %r11 # The total size of arguments passed on stack
+ callq __morestack
+ ret # The reason for this extra return is explained below
+ .LBB0_2:
+ # Usual prologue continues here
+
+The size of function arguments on the stack needs to be passed to
+``__morestack`` (this function is implemented in ``libgcc``) since that number
+of bytes has to be copied from the previous stacklet to the current one. This is
+so that SP (and FP) relative addressing of function arguments work as expected.
+
+The unusual ``ret`` is needed to have the function which made a call to
+``__morestack`` return correctly. ``__morestack``, instead of returning, calls
+into ``.LBB0_2``. This is possible since both, the size of the ``ret``
+instruction and the PC of call to ``__morestack`` are known. When the function
+body returns, control is transferred back to ``__morestack``. ``__morestack``
+then de-allocates the new stacklet, restores the correct SP value, and does a
+second return, which returns control to the correct caller.
+
+Variable Sized Allocas
+----------------------
+
+The section on `allocating stacklets`_ automatically assumes that every stack
+frame will be of fixed size. However, LLVM allows the use of the ``llvm.alloca``
+intrinsic to allocate dynamically sized blocks of memory on the stack. When
+faced with such a variable-sized alloca, code is generated to:
+
+* Check if the current stacklet has enough space. If yes, just bump the SP, like
+ in the normal case.
+* If not, generate a call to ``libgcc``, which allocates the memory from the
+ heap.
+
+The memory allocated from the heap is linked into a list in the current
+stacklet, and freed along with the same. This prevents a memory leak.
diff --git a/docs/subsystems.rst b/docs/subsystems.rst
index 1f9bd7d6ed..9ceb842420 100644
--- a/docs/subsystems.rst
+++ b/docs/subsystems.rst
@@ -9,6 +9,7 @@ Subsystem Documentation
AliasAnalysis
BranchWeightMetadata
LinkTimeOptimization
+ SegmentedStacks
* `Writing an LLVM Pass <WritingAnLLVMPass.html>`_
@@ -38,7 +39,7 @@ Subsystem Documentation
The interfaces source-language compilers should use for compiling GC'd
programs.
-
+
* `Source Level Debugging with LLVM <SourceLevelDebugging.html>`_
This document describes the design and philosophy behind the LLVM
@@ -79,3 +80,7 @@ Subsystem Documentation
* :ref:`branch_weight`
Provides information about Branch Prediction Information.
+
+* :ref:`segmented_stacks`
+
+ This document describes segmented stacks and how they are used in LLVM.