Update LLVM to 91430.

This commit is contained in:
Roman Divacky 2009-12-15 18:09:07 +00:00
parent 06f9d4012f
commit 571945e6af
371 changed files with 11261 additions and 5671 deletions

View File

@ -191,7 +191,13 @@ set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LLVM_BINARY_DIR}/lib )
add_llvm_definitions( -D__STDC_LIMIT_MACROS )
add_llvm_definitions( -D__STDC_CONSTANT_MACROS )
option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON)
# MSVC has a gazillion warnings with this.
if( MSVC )
option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." OFF)
else( MSVC )
option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON)
endif()
option(LLVM_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
option(LLVM_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)

View File

@ -66,8 +66,7 @@ ifeq ($(MAKECMDGOALS),tools-only)
endif
ifeq ($(MAKECMDGOALS),install-clang)
DIRS := tools/clang/tools/driver tools/clang/tools/clang-cc \
tools/clang/lib/Headers tools/clang/docs
DIRS := tools/clang/tools/driver tools/clang/lib/Headers tools/clang/docs
OPTIONAL_DIRS :=
NO_INSTALL = 1
endif

View File

@ -313,7 +313,7 @@ endif
# Location of the plugin header file for gold.
BINUTILS_INCDIR := @BINUTILS_INCDIR@
C_INCLUDE_DIRS := @C_INCLUDE_DISR@
C_INCLUDE_DIRS := @C_INCLUDE_DIRS@
CXX_INCLUDE_ROOT := @CXX_INCLUDE_ROOT@
CXX_INCLUDE_ARCH := @CXX_INCLUDE_ARCH@
CXX_INCLUDE_32BIT_DIR = @CXX_INCLUDE_32BIT_DIR@

View File

@ -672,7 +672,7 @@ case "$withval" in
*) AC_MSG_ERROR([Invalid path for --with-ocaml-libdir. Provide full path]) ;;
esac
AC_ARG_WITH(c-include-dir,
AC_ARG_WITH(c-include-dirs,
AS_HELP_STRING([--with-c-include-dirs],
[Colon separated list of directories clang will search for headers]),,
withval="")

View File

@ -1,14 +1,25 @@
# atomic builtins are required for threading support.
INCLUDE(CheckCXXSourceCompiles)
CHECK_CXX_SOURCE_COMPILES("
#ifdef _MSC_VER
#include <windows.h>
#endif
int main() {
#ifdef _MSC_VER
volatile LONG val = 1;
MemoryBarrier();
InterlockedCompareExchange(&val, 0, 1);
InterlockedIncrement(&val);
InterlockedDecrement(&val);
#else
volatile unsigned long val = 1;
__sync_synchronize();
__sync_val_compare_and_swap(&val, 1, 0);
__sync_add_and_fetch(&val, 1);
__sync_sub_and_fetch(&val, 1);
#endif
return 0;
}
" LLVM_MULTITHREADED)

6
configure vendored
View File

@ -5286,9 +5286,9 @@ echo "$as_me: error: Invalid path for --with-ocaml-libdir. Provide full path" >&
esac
# Check whether --with-c-include-dir was given.
if test "${with_c_include_dir+set}" = set; then
withval=$with_c_include_dir;
# Check whether --with-c-include-dirs was given.
if test "${with_c_include_dirs+set}" = set; then
withval=$with_c_include_dirs;
else
withval=""
fi

View File

@ -17,28 +17,28 @@ The ReST source lives in the directory 'tools/llvmc/doc'. -->
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#introduction" id="id4">Introduction</a></li>
<li><a class="reference internal" href="#compiling-with-llvmc" id="id5">Compiling with LLVMC</a></li>
<li><a class="reference internal" href="#predefined-options" id="id6">Predefined options</a></li>
<li><a class="reference internal" href="#compiling-llvmc-plugins" id="id7">Compiling LLVMC plugins</a></li>
<li><a class="reference internal" href="#compiling-standalone-llvmc-based-drivers" id="id8">Compiling standalone LLVMC-based drivers</a></li>
<li><a class="reference internal" href="#customizing-llvmc-the-compilation-graph" id="id9">Customizing LLVMC: the compilation graph</a></li>
<li><a class="reference internal" href="#describing-options" id="id10">Describing options</a><ul>
<li><a class="reference internal" href="#external-options" id="id11">External options</a></li>
<li><a class="reference internal" href="#introduction" id="id8">Introduction</a></li>
<li><a class="reference internal" href="#compiling-with-llvmc" id="id9">Compiling with LLVMC</a></li>
<li><a class="reference internal" href="#predefined-options" id="id10">Predefined options</a></li>
<li><a class="reference internal" href="#compiling-llvmc-plugins" id="id11">Compiling LLVMC plugins</a></li>
<li><a class="reference internal" href="#compiling-standalone-llvmc-based-drivers" id="id12">Compiling standalone LLVMC-based drivers</a></li>
<li><a class="reference internal" href="#customizing-llvmc-the-compilation-graph" id="id13">Customizing LLVMC: the compilation graph</a></li>
<li><a class="reference internal" href="#describing-options" id="id14">Describing options</a><ul>
<li><a class="reference internal" href="#external-options" id="id15">External options</a></li>
</ul>
</li>
<li><a class="reference internal" href="#conditional-evaluation" id="id12">Conditional evaluation</a></li>
<li><a class="reference internal" href="#writing-a-tool-description" id="id13">Writing a tool description</a><ul>
<li><a class="reference internal" href="#actions" id="id14">Actions</a></li>
<li><a class="reference internal" href="#conditional-evaluation" id="id16">Conditional evaluation</a></li>
<li><a class="reference internal" href="#writing-a-tool-description" id="id17">Writing a tool description</a><ul>
<li><a class="reference internal" href="#id5" id="id18">Actions</a></li>
</ul>
</li>
<li><a class="reference internal" href="#language-map" id="id15">Language map</a></li>
<li><a class="reference internal" href="#option-preprocessor" id="id16">Option preprocessor</a></li>
<li><a class="reference internal" href="#more-advanced-topics" id="id17">More advanced topics</a><ul>
<li><a class="reference internal" href="#hooks-and-environment-variables" id="id18">Hooks and environment variables</a></li>
<li><a class="reference internal" href="#how-plugins-are-loaded" id="id19">How plugins are loaded</a></li>
<li><a class="reference internal" href="#debugging" id="id20">Debugging</a></li>
<li><a class="reference internal" href="#conditioning-on-the-executable-name" id="id21">Conditioning on the executable name</a></li>
<li><a class="reference internal" href="#language-map" id="id19">Language map</a></li>
<li><a class="reference internal" href="#option-preprocessor" id="id20">Option preprocessor</a></li>
<li><a class="reference internal" href="#more-advanced-topics" id="id21">More advanced topics</a><ul>
<li><a class="reference internal" href="#hooks-and-environment-variables" id="id22">Hooks and environment variables</a></li>
<li><a class="reference internal" href="#how-plugins-are-loaded" id="id23">How plugins are loaded</a></li>
<li><a class="reference internal" href="#debugging" id="id24">Debugging</a></li>
<li><a class="reference internal" href="#conditioning-on-the-executable-name" id="id25">Conditioning on the executable name</a></li>
</ul>
</li>
</ul>
@ -46,7 +46,7 @@ The ReST source lives in the directory 'tools/llvmc/doc'. -->
<div class="doc_author">
<p>Written by <a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a></p>
</div><div class="section" id="introduction">
<h1><a class="toc-backref" href="#id4">Introduction</a></h1>
<h1><a class="toc-backref" href="#id8">Introduction</a></h1>
<p>LLVMC is a generic compiler driver, designed to be customizable and
extensible. It plays the same role for LLVM as the <tt class="docutils literal"><span class="pre">gcc</span></tt> program
does for GCC - LLVMC's job is essentially to transform a set of input
@ -63,7 +63,7 @@ example, as a build tool for game resources.</p>
need to be familiar with it to customize LLVMC.</p>
</div>
<div class="section" id="compiling-with-llvmc">
<h1><a class="toc-backref" href="#id5">Compiling with LLVMC</a></h1>
<h1><a class="toc-backref" href="#id9">Compiling with LLVMC</a></h1>
<p>LLVMC tries hard to be as compatible with <tt class="docutils literal"><span class="pre">gcc</span></tt> as possible,
although there are some small differences. Most of the time, however,
you shouldn't be able to notice them:</p>
@ -100,7 +100,7 @@ hello
possible to choose the <tt class="docutils literal"><span class="pre">clang</span></tt> compiler with the <tt class="docutils literal"><span class="pre">-clang</span></tt> option.</p>
</div>
<div class="section" id="predefined-options">
<h1><a class="toc-backref" href="#id6">Predefined options</a></h1>
<h1><a class="toc-backref" href="#id10">Predefined options</a></h1>
<p>LLVMC has some built-in options that can't be overridden in the
configuration libraries:</p>
<ul class="simple">
@ -137,7 +137,7 @@ their standard meaning.</li>
</ul>
</div>
<div class="section" id="compiling-llvmc-plugins">
<h1><a class="toc-backref" href="#id7">Compiling LLVMC plugins</a></h1>
<h1><a class="toc-backref" href="#id11">Compiling LLVMC plugins</a></h1>
<p>It's easiest to start working on your own LLVMC plugin by copying the
skeleton project which lives under <tt class="docutils literal"><span class="pre">$LLVMC_DIR/plugins/Simple</span></tt>:</p>
<pre class="literal-block">
@ -176,7 +176,7 @@ $ llvmc -load $LLVM_DIR/Release/lib/plugin_llvmc_Simple.so
</pre>
</div>
<div class="section" id="compiling-standalone-llvmc-based-drivers">
<h1><a class="toc-backref" href="#id8">Compiling standalone LLVMC-based drivers</a></h1>
<h1><a class="toc-backref" href="#id12">Compiling standalone LLVMC-based drivers</a></h1>
<p>By default, the <tt class="docutils literal"><span class="pre">llvmc</span></tt> executable consists of a driver core plus several
statically linked plugins (<tt class="docutils literal"><span class="pre">Base</span></tt> and <tt class="docutils literal"><span class="pre">Clang</span></tt> at the moment). You can
produce a standalone LLVMC-based driver executable by linking the core with your
@ -215,7 +215,7 @@ $ make LLVMC_BUILTIN_PLUGINS=&quot;&quot;
</pre>
</div>
<div class="section" id="customizing-llvmc-the-compilation-graph">
<h1><a class="toc-backref" href="#id9">Customizing LLVMC: the compilation graph</a></h1>
<h1><a class="toc-backref" href="#id13">Customizing LLVMC: the compilation graph</a></h1>
<p>Each TableGen configuration file should include the common
definitions:</p>
<pre class="literal-block">
@ -283,7 +283,7 @@ debugging), run <tt class="docutils literal"><span class="pre">llvmc</span> <spa
<tt class="docutils literal"><span class="pre">gsview</span></tt> installed for this to work properly.</p>
</div>
<div class="section" id="describing-options">
<h1><a class="toc-backref" href="#id10">Describing options</a></h1>
<h1><a class="toc-backref" href="#id14">Describing options</a></h1>
<p>Command-line options that the plugin supports are defined by using an
<tt class="docutils literal"><span class="pre">OptionList</span></tt>:</p>
<pre class="literal-block">
@ -342,6 +342,11 @@ the <tt class="docutils literal"><span class="pre">--help</span></tt> output (bu
output).</li>
<li><tt class="docutils literal"><span class="pre">really_hidden</span></tt> - the option will not be mentioned in any help
output.</li>
<li><tt class="docutils literal"><span class="pre">comma_separated</span></tt> - Indicates that any commas specified for an option's
value should be used to split the value up into multiple values for the
option. This property is valid only for list options. In conjunction with
<tt class="docutils literal"><span class="pre">forward_value</span></tt> can be used to implement option forwarding in style of
gcc's <tt class="docutils literal"><span class="pre">-Wa,</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">multi_val</span> <span class="pre">n</span></tt> - this option takes <em>n</em> arguments (can be useful in some
special cases). Usage example: <tt class="docutils literal"><span class="pre">(parameter_list_option</span> <span class="pre">&quot;foo&quot;,</span> <span class="pre">(multi_val</span>
<span class="pre">3))</span></tt>; the command-line syntax is '-foo a b c'. Only list options can have
@ -352,13 +357,13 @@ parameter), or a boolean (if it is a switch; boolean constants are called
<tt class="docutils literal"><span class="pre">true</span></tt> and <tt class="docutils literal"><span class="pre">false</span></tt>). List options can't have this attribute. Usage
examples: <tt class="docutils literal"><span class="pre">(switch_option</span> <span class="pre">&quot;foo&quot;,</span> <span class="pre">(init</span> <span class="pre">true))</span></tt>; <tt class="docutils literal"><span class="pre">(prefix_option</span> <span class="pre">&quot;bar&quot;,</span>
<span class="pre">(init</span> <span class="pre">&quot;baz&quot;))</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">extern</span></tt> - this option is defined in some other plugin, see below.</li>
<li><tt class="docutils literal"><span class="pre">extern</span></tt> - this option is defined in some other plugin, see <a class="reference internal" href="#extern">below</a>.</li>
</ul>
</blockquote>
</li>
</ul>
<div class="section" id="external-options">
<h2><a class="toc-backref" href="#id11">External options</a></h2>
<span id="extern"></span><h2><a class="toc-backref" href="#id15">External options</a></h2>
<p>Sometimes, when linking several plugins together, one plugin needs to
access options defined in some other plugin. Because of the way
options are implemented, such options must be marked as
@ -374,7 +379,7 @@ ignored. See also the section on plugin <a class="reference internal" href="#pri
</div>
</div>
<div class="section" id="conditional-evaluation">
<span id="case"></span><h1><a class="toc-backref" href="#id12">Conditional evaluation</a></h1>
<span id="case"></span><h1><a class="toc-backref" href="#id16">Conditional evaluation</a></h1>
<p>The 'case' construct is the main means by which programmability is
achieved in LLVMC. It can be used to calculate edge weights, program
actions and modify the shell commands to be executed. The 'case'
@ -433,7 +438,7 @@ a given value.
Example: <tt class="docutils literal"><span class="pre">(parameter_equals</span> <span class="pre">&quot;W&quot;,</span> <span class="pre">&quot;all&quot;)</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">element_in_list</span></tt> - Returns true if a command-line parameter
list contains a given value.
Example: <tt class="docutils literal"><span class="pre">(parameter_in_list</span> <span class="pre">&quot;l&quot;,</span> <span class="pre">&quot;pthread&quot;)</span></tt>.</li>
Example: <tt class="docutils literal"><span class="pre">(element_in_list</span> <span class="pre">&quot;l&quot;,</span> <span class="pre">&quot;pthread&quot;)</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">input_languages_contain</span></tt> - Returns true if a given language
belongs to the current input language set.
Example: <tt class="docutils literal"><span class="pre">(input_languages_contain</span> <span class="pre">&quot;c++&quot;)</span></tt>.</li>
@ -475,7 +480,7 @@ argument. Example: <tt class="docutils literal"><span class="pre">(not</span> <s
</ul>
</div>
<div class="section" id="writing-a-tool-description">
<h1><a class="toc-backref" href="#id13">Writing a tool description</a></h1>
<h1><a class="toc-backref" href="#id17">Writing a tool description</a></h1>
<p>As was said earlier, nodes in the compilation graph represent tools,
which are described separately. A tool definition looks like this
(taken from the <tt class="docutils literal"><span class="pre">include/llvm/CompilerDriver/Tools.td</span></tt> file):</p>
@ -512,12 +517,12 @@ list of input files and joins them together. Used for linkers.</li>
tools are passed to this tool.</li>
<li><tt class="docutils literal"><span class="pre">actions</span></tt> - A single big <tt class="docutils literal"><span class="pre">case</span></tt> expression that specifies how
this tool reacts on command-line options (described in more detail
below).</li>
<a class="reference internal" href="#actions">below</a>).</li>
</ul>
</li>
</ul>
<div class="section" id="actions">
<h2><a class="toc-backref" href="#id14">Actions</a></h2>
<div class="section" id="id5">
<span id="actions"></span><h2><a class="toc-backref" href="#id18">Actions</a></h2>
<p>A tool often needs to react to command-line options, and this is
precisely what the <tt class="docutils literal"><span class="pre">actions</span></tt> property is for. The next example
illustrates this feature:</p>
@ -550,28 +555,31 @@ like a linker.</p>
<li><p class="first">Possible actions:</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">append_cmd</span></tt> - append a string to the tool invocation
command.
Example: <tt class="docutils literal"><span class="pre">(case</span> <span class="pre">(switch_on</span> <span class="pre">&quot;pthread&quot;),</span> <span class="pre">(append_cmd</span>
<span class="pre">&quot;-lpthread&quot;))</span></tt></li>
<li><tt class="docutils literal"><span class="pre">error</span></tt> - exit with error.
<li><tt class="docutils literal"><span class="pre">append_cmd</span></tt> - Append a string to the tool invocation command.
Example: <tt class="docutils literal"><span class="pre">(case</span> <span class="pre">(switch_on</span> <span class="pre">&quot;pthread&quot;),</span> <span class="pre">(append_cmd</span> <span class="pre">&quot;-lpthread&quot;))</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">error</span></tt> - Exit with error.
Example: <tt class="docutils literal"><span class="pre">(error</span> <span class="pre">&quot;Mixing</span> <span class="pre">-c</span> <span class="pre">and</span> <span class="pre">-S</span> <span class="pre">is</span> <span class="pre">not</span> <span class="pre">allowed!&quot;)</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">warning</span></tt> - print a warning.
<li><tt class="docutils literal"><span class="pre">warning</span></tt> - Print a warning.
Example: <tt class="docutils literal"><span class="pre">(warning</span> <span class="pre">&quot;Specifying</span> <span class="pre">both</span> <span class="pre">-O1</span> <span class="pre">and</span> <span class="pre">-O2</span> <span class="pre">is</span> <span class="pre">meaningless!&quot;)</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">forward</span></tt> - forward an option unchanged. Example: <tt class="docutils literal"><span class="pre">(forward</span> <span class="pre">&quot;Wall&quot;)</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">forward_as</span></tt> - Change the name of an option, but forward the
argument unchanged.
<li><tt class="docutils literal"><span class="pre">forward</span></tt> - Forward the option unchanged.
Example: <tt class="docutils literal"><span class="pre">(forward</span> <span class="pre">&quot;Wall&quot;)</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">forward_as</span></tt> - Change the option's name, but forward the argument
unchanged.
Example: <tt class="docutils literal"><span class="pre">(forward_as</span> <span class="pre">&quot;O0&quot;,</span> <span class="pre">&quot;--disable-optimization&quot;)</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">output_suffix</span></tt> - modify the output suffix of this
tool.
<li><tt class="docutils literal"><span class="pre">forward_value</span></tt> - Forward only option's value. Cannot be used with switch
options (since they don't have values), but works fine with lists.
Example: <tt class="docutils literal"><span class="pre">(forward_value</span> <span class="pre">&quot;Wa,&quot;)</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">forward_transformed_value</span></tt> - As above, but applies a hook to the
option's value before forwarding (see <a class="reference internal" href="#hooks">below</a>). When
<tt class="docutils literal"><span class="pre">forward_transformed_value</span></tt> is applied to a list
option, the hook must have signature
<tt class="docutils literal"><span class="pre">std::string</span> <span class="pre">hooks::HookName</span> <span class="pre">(const</span> <span class="pre">std::vector&lt;std::string&gt;&amp;)</span></tt>.
Example: <tt class="docutils literal"><span class="pre">(forward_transformed_value</span> <span class="pre">&quot;m&quot;,</span> <span class="pre">&quot;ConvertToMAttr&quot;)</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">output_suffix</span></tt> - Modify the output suffix of this tool.
Example: <tt class="docutils literal"><span class="pre">(output_suffix</span> <span class="pre">&quot;i&quot;)</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">stop_compilation</span></tt> - stop compilation after this tool processes
its input. Used without arguments.</li>
<li><tt class="docutils literal"><span class="pre">unpack_values</span></tt> - used for for splitting and forwarding
comma-separated lists of options, e.g. <tt class="docutils literal"><span class="pre">-Wa,-foo=bar,-baz</span></tt> is
converted to <tt class="docutils literal"><span class="pre">-foo=bar</span> <span class="pre">-baz</span></tt> and appended to the tool invocation
command.
Example: <tt class="docutils literal"><span class="pre">(unpack_values</span> <span class="pre">&quot;Wa,&quot;)</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">stop_compilation</span></tt> - Stop compilation after this tool processes its
input. Used without arguments.
Example: <tt class="docutils literal"><span class="pre">(stop_compilation)</span></tt>.</li>
</ul>
</blockquote>
</li>
@ -579,7 +587,7 @@ Example: <tt class="docutils literal"><span class="pre">(unpack_values</span> <s
</div>
</div>
<div class="section" id="language-map">
<h1><a class="toc-backref" href="#id15">Language map</a></h1>
<h1><a class="toc-backref" href="#id19">Language map</a></h1>
<p>If you are adding support for a new language to LLVMC, you'll need to
modify the language map, which defines mappings from file extensions
to language names. It is used to choose the proper toolchain(s) for a
@ -602,7 +610,7 @@ multiple output languages, for nodes &quot;inside&quot; the graph the input and
output languages should match. This is enforced at compile-time.</p>
</div>
<div class="section" id="option-preprocessor">
<h1><a class="toc-backref" href="#id16">Option preprocessor</a></h1>
<h1><a class="toc-backref" href="#id20">Option preprocessor</a></h1>
<p>It is sometimes useful to run error-checking code before processing the
compilation graph. For example, if optimization options &quot;-O1&quot; and &quot;-O2&quot; are
implemented as switches, we might want to output a warning if the user invokes
@ -629,9 +637,9 @@ in <tt class="docutils literal"><span class="pre">OptionPreprocessor</span></tt>
convenience, <tt class="docutils literal"><span class="pre">unset_option</span></tt> also works on lists.</p>
</div>
<div class="section" id="more-advanced-topics">
<h1><a class="toc-backref" href="#id17">More advanced topics</a></h1>
<h1><a class="toc-backref" href="#id21">More advanced topics</a></h1>
<div class="section" id="hooks-and-environment-variables">
<span id="hooks"></span><h2><a class="toc-backref" href="#id18">Hooks and environment variables</a></h2>
<span id="hooks"></span><h2><a class="toc-backref" href="#id22">Hooks and environment variables</a></h2>
<p>Normally, LLVMC executes programs from the system <tt class="docutils literal"><span class="pre">PATH</span></tt>. Sometimes,
this is not sufficient: for example, we may want to specify tool paths
or names in the configuration file. This can be easily achieved via
@ -664,7 +672,7 @@ the <tt class="docutils literal"><span class="pre">case</span></tt> expression (
</pre>
</div>
<div class="section" id="how-plugins-are-loaded">
<span id="priorities"></span><h2><a class="toc-backref" href="#id19">How plugins are loaded</a></h2>
<span id="priorities"></span><h2><a class="toc-backref" href="#id23">How plugins are loaded</a></h2>
<p>It is possible for LLVMC plugins to depend on each other. For example,
one can create edges between nodes defined in some other plugin. To
make this work, however, that plugin should be loaded first. To
@ -680,7 +688,7 @@ with 0. Therefore, the plugin with the highest priority value will be
loaded last.</p>
</div>
<div class="section" id="debugging">
<h2><a class="toc-backref" href="#id20">Debugging</a></h2>
<h2><a class="toc-backref" href="#id24">Debugging</a></h2>
<p>When writing LLVMC plugins, it can be useful to get a visual view of
the resulting compilation graph. This can be achieved via the command
line option <tt class="docutils literal"><span class="pre">--view-graph</span></tt>. This command assumes that <a class="reference external" href="http://www.graphviz.org/">Graphviz</a> and
@ -696,7 +704,7 @@ perform any compilation tasks and returns the number of encountered
errors as its status code.</p>
</div>
<div class="section" id="conditioning-on-the-executable-name">
<h2><a class="toc-backref" href="#id21">Conditioning on the executable name</a></h2>
<h2><a class="toc-backref" href="#id25">Conditioning on the executable name</a></h2>
<p>For now, the executable name (the value passed to the driver in <tt class="docutils literal"><span class="pre">argv[0]</span></tt>) is
accessible only in the C++ code (i.e. hooks). Use the following code:</p>
<pre class="literal-block">
@ -704,12 +712,16 @@ namespace llvmc {
extern const char* ProgramName;
}
namespace hooks {
std::string MyHook() {
//...
if (strcmp(ProgramName, &quot;mydriver&quot;) == 0) {
//...
}
} // end namespace hooks
</pre>
<p>In general, you're encouraged not to make the behaviour dependent on the
executable file name, and use command-line switches instead. See for example how
@ -727,7 +739,7 @@ the <tt class="docutils literal"><span class="pre">Base</span></tt> plugin behav
<a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a><br />
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br />
Last modified: $Date: 2009-10-26 02:35:46 +0100 (Mon, 26 Oct 2009) $
Last modified: $Date: 2009-12-07 19:26:24 +0100 (Mon, 07 Dec 2009) $
</address></div>
</div>
</div>

View File

@ -252,7 +252,8 @@ software you will need.</p>
</tr>
<tr>
<td>Cygwin/Win32</td>
<td>x86<sup><a href="#pf_1">1</a>,<a href="#pf_8">8</a></sup></td>
<td>x86<sup><a href="#pf_1">1</a>,<a href="#pf_8">8</a>,
<a href="#pf_11">11</a></sup></td>
<td>GCC 3.4.X, binutils 2.15</td>
</tr>
<tr>
@ -331,6 +332,9 @@ up</a></li>
before any Windows-based versions such as Strawberry Perl and
ActivePerl, as these have Windows-specifics that will cause the
build to fail.</a></li>
<li><a name="pf_11">In general, LLVM modules requiring dynamic linking can
not be built on Windows. However, you can build LLVM tools using
<i>"make tools-only"</i>.</li>
</ol>
</div>
@ -1636,7 +1640,7 @@ out:</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.x10sys.com/rspencer/">Reid Spencer</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2009-11-04 07:15:28 +0100 (Wed, 04 Nov 2009) $
Last modified: $Date: 2009-12-09 18:26:02 +0100 (Wed, 09 Dec 2009) $
</address>
</body>
</html>

View File

@ -5,7 +5,7 @@
<title>LLVM Assembly Language Reference Manual</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="author" content="Chris Lattner">
<meta name="description"
<meta name="description"
content="LLVM Assembly Language Reference Manual.">
<link rel="stylesheet" href="llvm.css" type="text/css">
</head>
@ -54,7 +54,7 @@
<li><a href="#typesystem">Type System</a>
<ol>
<li><a href="#t_classifications">Type Classifications</a></li>
<li><a href="#t_primitive">Primitive Types</a>
<li><a href="#t_primitive">Primitive Types</a>
<ol>
<li><a href="#t_integer">Integer Type</a></li>
<li><a href="#t_floating">Floating Point Types</a></li>
@ -576,7 +576,7 @@ define i32 @main() { <i>; i32()* </i>
Symbols with "<tt>common</tt>" linkage are merged in the same way as
<tt>weak symbols</tt>, and they may not be deleted if unreferenced.
<tt>common</tt> symbols may not have an explicit section,
must have a zero initializer, and may not be marked '<a
must have a zero initializer, and may not be marked '<a
href="#globalvars"><tt>constant</tt></a>'. Functions and aliases may not
have common linkage.</dd>
@ -843,7 +843,7 @@ define i32 @main() { <i>; i32()* </i>
<p>LLVM function declarations consist of the "<tt>declare</tt>" keyword, an
optional <a href="#linkage">linkage type</a>, an optional
<a href="#visibility">visibility style</a>, an optional
<a href="#visibility">visibility style</a>, an optional
<a href="#callingconv">calling convention</a>, a return type, an optional
<a href="#paramattrs">parameter attribute</a> for the return type, a function
name, a possibly empty list of arguments, an optional alignment, and an
@ -1192,7 +1192,7 @@ target datalayout = "<i>layout specification</i>"
location.</dd>
<dt><tt>p:<i>size</i>:<i>abi</i>:<i>pref</i></tt></dt>
<dd>This specifies the <i>size</i> of a pointer and its <i>abi</i> and
<dd>This specifies the <i>size</i> of a pointer and its <i>abi</i> and
<i>preferred</i> alignments. All sizes are in bits. Specifying
the <i>pref</i> alignment is optional. If omitted, the
preceding <tt>:</tt> should be omitted too.</dd>
@ -1202,11 +1202,11 @@ target datalayout = "<i>layout specification</i>"
<i>size</i>. The value of <i>size</i> must be in the range [1,2^23).</dd>
<dt><tt>v<i>size</i>:<i>abi</i>:<i>pref</i></tt></dt>
<dd>This specifies the alignment for a vector type of a given bit
<dd>This specifies the alignment for a vector type of a given bit
<i>size</i>.</dd>
<dt><tt>f<i>size</i>:<i>abi</i>:<i>pref</i></tt></dt>
<dd>This specifies the alignment for a floating point type of a given bit
<dd>This specifies the alignment for a floating point type of a given bit
<i>size</i>. The value of <i>size</i> must be either 32 (float) or 64
(double).</dd>
@ -1222,7 +1222,7 @@ target datalayout = "<i>layout specification</i>"
<dd>This specifies a set of native integer widths for the target CPU
in bits. For example, it might contain "n32" for 32-bit PowerPC,
"n32:64" for PowerPC 64, or "n8:16:32:64" for X86-64. Elements of
this set are considered to support most general arithmetic
this set are considered to support most general arithmetic
operations efficiently.</dd>
</dl>
@ -1616,16 +1616,16 @@ Classifications</a> </div>
</tr><tr class="layout">
<td class="left"><tt>float&nbsp;(i16&nbsp;signext,&nbsp;i32&nbsp;*)&nbsp;*
</tt></td>
<td class="left"><a href="#t_pointer">Pointer</a> to a function that takes
an <tt>i16</tt> that should be sign extended and a
<a href="#t_pointer">pointer</a> to <tt>i32</tt>, returning
<td class="left"><a href="#t_pointer">Pointer</a> to a function that takes
an <tt>i16</tt> that should be sign extended and a
<a href="#t_pointer">pointer</a> to <tt>i32</tt>, returning
<tt>float</tt>.
</td>
</tr><tr class="layout">
<td class="left"><tt>i32 (i8*, ...)</tt></td>
<td class="left">A vararg function that takes at least one
<a href="#t_pointer">pointer</a> to <tt>i8 </tt> (char in C),
which returns an integer. This is the signature for <tt>printf</tt> in
<td class="left">A vararg function that takes at least one
<a href="#t_pointer">pointer</a> to <tt>i8 </tt> (char in C),
which returns an integer. This is the signature for <tt>printf</tt> in
LLVM.
</td>
</tr><tr class="layout">
@ -2054,9 +2054,9 @@ Unsafe:
For example, if "%X" has a zero bit, then the output of the 'and' operation will
always be a zero, no matter what the corresponding bit from the undef is. As
such, it is unsafe to optimize or assume that the result of the and is undef.
However, it is safe to assume that all bits of the undef could be 0, and
optimize the and to 0. Likewise, it is safe to assume that all the bits of
the undef operand to the or could be set, allowing the or to be folded to
However, it is safe to assume that all bits of the undef could be 0, and
optimize the and to 0. Likewise, it is safe to assume that all the bits of
the undef operand to the or could be set, allowing the or to be folded to
-1.</p>
<div class="doc_code">
@ -2086,7 +2086,7 @@ the optimizer is allowed to assume that the undef operand could be the same as
<div class="doc_code">
<pre>
%A = xor undef, undef
%B = undef
%C = xor %B, %B
@ -2137,7 +2137,7 @@ does not execute at all. This allows us to delete the divide and all code after
it: since the undefined operation "can't happen", the optimizer can assume that
it occurs in dead code.
</p>
<div class="doc_code">
<pre>
a: store undef -> %X
@ -2149,7 +2149,7 @@ b: unreachable
</div>
<p>These examples reiterate the fdiv example: a store "of" an undefined value
can be assumed to not have any effect: we can assume that the value is
can be assumed to not have any effect: we can assume that the value is
overwritten with bits that happen to match what was already there. However, a
store "to" an undefined location could clobber arbitrary memory, therefore, it
has undefined behavior.</p>
@ -2166,7 +2166,7 @@ has undefined behavior.</p>
<p>The '<tt>blockaddress</tt>' constant computes the address of the specified
basic block in the specified function, and always has an i8* type. Taking
the address of the entry block is illegal.</p>
<p>This value only has defined behavior when used as an operand to the
'<a href="#i_indirectbr"><tt>indirectbr</tt></a>' instruction or for comparisons
against null. Pointer equality tests between labels addresses is undefined
@ -2175,7 +2175,7 @@ has undefined behavior.</p>
pointer sized value as long as the bits are not inspected. This allows
<tt>ptrtoint</tt> and arithmetic to be performed on these values so long as
the original value is reconstituted before the <tt>indirectbr</tt>.</p>
<p>Finally, some targets may provide defined semantics when
using the value as the operand to an inline assembly, but that is target
specific.
@ -2703,7 +2703,7 @@ IfUnequal:
rest of the arguments indicate the full set of possible destinations that the
address may point to. Blocks are allowed to occur multiple times in the
destination list, though this isn't particularly useful.</p>
<p>This destination list is required so that dataflow analysis has an accurate
understanding of the CFG.</p>
@ -3060,7 +3060,7 @@ Instruction</a> </div>
<p>The two arguments to the '<tt>mul</tt>' instruction must
be <a href="#t_integer">integer</a> or <a href="#t_vector">vector</a> of
integer values. Both arguments must have identical types.</p>
<h5>Semantics:</h5>
<p>The value produced is the integer product of the two operands.</p>
@ -3132,7 +3132,7 @@ Instruction</a> </div>
<p>The '<tt>udiv</tt>' instruction returns the quotient of its two operands.</p>
<h5>Arguments:</h5>
<p>The two arguments to the '<tt>udiv</tt>' instruction must be
<p>The two arguments to the '<tt>udiv</tt>' instruction must be
<a href="#t_integer">integer</a> or <a href="#t_vector">vector</a> of integer
values. Both arguments must have identical types.</p>
@ -3167,7 +3167,7 @@ Instruction</a> </div>
<p>The '<tt>sdiv</tt>' instruction returns the quotient of its two operands.</p>
<h5>Arguments:</h5>
<p>The two arguments to the '<tt>sdiv</tt>' instruction must be
<p>The two arguments to the '<tt>sdiv</tt>' instruction must be
<a href="#t_integer">integer</a> or <a href="#t_vector">vector</a> of integer
values. Both arguments must have identical types.</p>
@ -3238,7 +3238,7 @@ Instruction</a> </div>
division of its two arguments.</p>
<h5>Arguments:</h5>
<p>The two arguments to the '<tt>urem</tt>' instruction must be
<p>The two arguments to the '<tt>urem</tt>' instruction must be
<a href="#t_integer">integer</a> or <a href="#t_vector">vector</a> of integer
values. Both arguments must have identical types.</p>
@ -3278,7 +3278,7 @@ Instruction</a> </div>
elements must be integers.</p>
<h5>Arguments:</h5>
<p>The two arguments to the '<tt>srem</tt>' instruction must be
<p>The two arguments to the '<tt>srem</tt>' instruction must be
<a href="#t_integer">integer</a> or <a href="#t_vector">vector</a> of integer
values. Both arguments must have identical types.</p>
@ -3373,7 +3373,7 @@ Instruction</a> </div>
<p>Both arguments to the '<tt>shl</tt>' instruction must be the
same <a href="#t_integer">integer</a> or <a href="#t_vector">vector</a> of
integer type. '<tt>op2</tt>' is treated as an unsigned value.</p>
<h5>Semantics:</h5>
<p>The value produced is <tt>op1</tt> * 2<sup><tt>op2</tt></sup> mod
2<sup>n</sup>, where <tt>n</tt> is the width of the result. If <tt>op2</tt>
@ -3409,7 +3409,7 @@ Instruction</a> </div>
operand shifted to the right a specified number of bits with zero fill.</p>
<h5>Arguments:</h5>
<p>Both arguments to the '<tt>lshr</tt>' instruction must be the same
<p>Both arguments to the '<tt>lshr</tt>' instruction must be the same
<a href="#t_integer">integer</a> or <a href="#t_vector">vector</a> of integer
type. '<tt>op2</tt>' is treated as an unsigned value.</p>
@ -3449,7 +3449,7 @@ Instruction</a> </div>
extension.</p>
<h5>Arguments:</h5>
<p>Both arguments to the '<tt>ashr</tt>' instruction must be the same
<p>Both arguments to the '<tt>ashr</tt>' instruction must be the same
<a href="#t_integer">integer</a> or <a href="#t_vector">vector</a> of integer
type. '<tt>op2</tt>' is treated as an unsigned value.</p>
@ -3489,7 +3489,7 @@ Instruction</a> </div>
operands.</p>
<h5>Arguments:</h5>
<p>The two arguments to the '<tt>and</tt>' instruction must be
<p>The two arguments to the '<tt>and</tt>' instruction must be
<a href="#t_integer">integer</a> or <a href="#t_vector">vector</a> of integer
values. Both arguments must have identical types.</p>
@ -3548,7 +3548,7 @@ Instruction</a> </div>
two operands.</p>
<h5>Arguments:</h5>
<p>The two arguments to the '<tt>or</tt>' instruction must be
<p>The two arguments to the '<tt>or</tt>' instruction must be
<a href="#t_integer">integer</a> or <a href="#t_vector">vector</a> of integer
values. Both arguments must have identical types.</p>
@ -3611,7 +3611,7 @@ Instruction</a> </div>
complement" operation, which is the "~" operator in C.</p>
<h5>Arguments:</h5>
<p>The two arguments to the '<tt>xor</tt>' instruction must be
<p>The two arguments to the '<tt>xor</tt>' instruction must be
<a href="#t_integer">integer</a> or <a href="#t_vector">vector</a> of integer
values. Both arguments must have identical types.</p>
@ -3659,7 +3659,7 @@ Instruction</a> </div>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<div class="doc_subsection">
<a name="vectorops">Vector Operations</a>
</div>
@ -3782,20 +3782,20 @@ Instruction</a> </div>
<h5>Example:</h5>
<pre>
&lt;result&gt; = shufflevector &lt;4 x i32&gt; %v1, &lt;4 x i32&gt; %v2,
&lt;result&gt; = shufflevector &lt;4 x i32&gt; %v1, &lt;4 x i32&gt; %v2,
&lt;4 x i32&gt; &lt;i32 0, i32 4, i32 1, i32 5&gt; <i>; yields &lt;4 x i32&gt;</i>
&lt;result&gt; = shufflevector &lt;4 x i32&gt; %v1, &lt;4 x i32&gt; undef,
&lt;result&gt; = shufflevector &lt;4 x i32&gt; %v1, &lt;4 x i32&gt; undef,
&lt;4 x i32&gt; &lt;i32 0, i32 1, i32 2, i32 3&gt; <i>; yields &lt;4 x i32&gt;</i> - Identity shuffle.
&lt;result&gt; = shufflevector &lt;8 x i32&gt; %v1, &lt;8 x i32&gt; undef,
&lt;result&gt; = shufflevector &lt;8 x i32&gt; %v1, &lt;8 x i32&gt; undef,
&lt;4 x i32&gt; &lt;i32 0, i32 1, i32 2, i32 3&gt; <i>; yields &lt;4 x i32&gt;</i>
&lt;result&gt; = shufflevector &lt;4 x i32&gt; %v1, &lt;4 x i32&gt; %v2,
&lt;result&gt; = shufflevector &lt;4 x i32&gt; %v1, &lt;4 x i32&gt; %v2,
&lt;8 x i32&gt; &lt;i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7 &gt; <i>; yields &lt;8 x i32&gt;</i>
</pre>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<div class="doc_subsection">
<a name="aggregateops">Aggregate Operations</a>
</div>
@ -3880,7 +3880,7 @@ Instruction</a> </div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<div class="doc_subsection">
<a name="memoryops">Memory Access and Addressing Operations</a>
</div>
@ -4243,15 +4243,15 @@ entry:
</pre>
<h5>Overview:</h5>
<p>The '<tt>zext</tt>' instruction zero extends its operand to type
<p>The '<tt>zext</tt>' instruction zero extends its operand to type
<tt>ty2</tt>.</p>
<h5>Arguments:</h5>
<p>The '<tt>zext</tt>' instruction takes a value to cast, which must be of
<p>The '<tt>zext</tt>' instruction takes a value to cast, which must be of
<a href="#t_integer">integer</a> type, and a type to cast it to, which must
also be of <a href="#t_integer">integer</a> type. The bit size of the
<tt>value</tt> must be smaller than the bit size of the destination type,
<tt>value</tt> must be smaller than the bit size of the destination type,
<tt>ty2</tt>.</p>
<h5>Semantics:</h5>
@ -4283,10 +4283,10 @@ entry:
<p>The '<tt>sext</tt>' sign extends <tt>value</tt> to the type <tt>ty2</tt>.</p>
<h5>Arguments:</h5>
<p>The '<tt>sext</tt>' instruction takes a value to cast, which must be of
<p>The '<tt>sext</tt>' instruction takes a value to cast, which must be of
<a href="#t_integer">integer</a> type, and a type to cast it to, which must
also be of <a href="#t_integer">integer</a> type. The bit size of the
<tt>value</tt> must be smaller than the bit size of the destination type,
<tt>value</tt> must be smaller than the bit size of the destination type,
<tt>ty2</tt>.</p>
<h5>Semantics:</h5>
@ -4324,12 +4324,12 @@ entry:
<p>The '<tt>fptrunc</tt>' instruction takes a <a href="#t_floating">floating
point</a> value to cast and a <a href="#t_floating">floating point</a> type
to cast it to. The size of <tt>value</tt> must be larger than the size of
<tt>ty2</tt>. This implies that <tt>fptrunc</tt> cannot be used to make a
<tt>ty2</tt>. This implies that <tt>fptrunc</tt> cannot be used to make a
<i>no-op cast</i>.</p>
<h5>Semantics:</h5>
<p>The '<tt>fptrunc</tt>' instruction truncates a <tt>value</tt> from a larger
<a href="#t_floating">floating point</a> type to a smaller
<a href="#t_floating">floating point</a> type to a smaller
<a href="#t_floating">floating point</a> type. If the value cannot fit
within the destination type, <tt>ty2</tt>, then the results are
undefined.</p>
@ -4358,7 +4358,7 @@ entry:
floating point value.</p>
<h5>Arguments:</h5>
<p>The '<tt>fpext</tt>' instruction takes a
<p>The '<tt>fpext</tt>' instruction takes a
<a href="#t_floating">floating point</a> <tt>value</tt> to cast, and
a <a href="#t_floating">floating point</a> type to cast it to. The source
type must be smaller than the destination type.</p>
@ -4401,7 +4401,7 @@ entry:
vector integer type with the same number of elements as <tt>ty</tt></p>
<h5>Semantics:</h5>
<p>The '<tt>fptoui</tt>' instruction converts its
<p>The '<tt>fptoui</tt>' instruction converts its
<a href="#t_floating">floating point</a> operand into the nearest (rounding
towards zero) unsigned integer value. If the value cannot fit
in <tt>ty2</tt>, the results are undefined.</p>
@ -4427,7 +4427,7 @@ entry:
</pre>
<h5>Overview:</h5>
<p>The '<tt>fptosi</tt>' instruction converts
<p>The '<tt>fptosi</tt>' instruction converts
<a href="#t_floating">floating point</a> <tt>value</tt> to
type <tt>ty2</tt>.</p>
@ -4439,7 +4439,7 @@ entry:
vector integer type with the same number of elements as <tt>ty</tt></p>
<h5>Semantics:</h5>
<p>The '<tt>fptosi</tt>' instruction converts its
<p>The '<tt>fptosi</tt>' instruction converts its
<a href="#t_floating">floating point</a> operand into the nearest (rounding
towards zero) signed integer value. If the value cannot fit in <tt>ty2</tt>,
the results are undefined.</p>
@ -4636,7 +4636,7 @@ entry:
<pre>
%X = bitcast i8 255 to i8 <i>; yields i8 :-1</i>
%Y = bitcast i32* %x to sint* <i>; yields sint*:%x</i>
%Z = bitcast &lt;2 x int&gt; %V to i64; <i>; yields i64: %V</i>
%Z = bitcast &lt;2 x int&gt; %V to i64; <i>; yields i64: %V</i>
</pre>
</div>
@ -4696,11 +4696,11 @@ entry:
result, as follows:</p>
<ol>
<li><tt>eq</tt>: yields <tt>true</tt> if the operands are equal,
<li><tt>eq</tt>: yields <tt>true</tt> if the operands are equal,
<tt>false</tt> otherwise. No sign interpretation is necessary or
performed.</li>
<li><tt>ne</tt>: yields <tt>true</tt> if the operands are unequal,
<li><tt>ne</tt>: yields <tt>true</tt> if the operands are unequal,
<tt>false</tt> otherwise. No sign interpretation is necessary or
performed.</li>
@ -4817,42 +4817,42 @@ entry:
<ol>
<li><tt>false</tt>: always yields <tt>false</tt>, regardless of operands.</li>
<li><tt>oeq</tt>: yields <tt>true</tt> if both operands are not a QNAN and
<li><tt>oeq</tt>: yields <tt>true</tt> if both operands are not a QNAN and
<tt>op1</tt> is equal to <tt>op2</tt>.</li>
<li><tt>ogt</tt>: yields <tt>true</tt> if both operands are not a QNAN and
<tt>op1</tt> is greather than <tt>op2</tt>.</li>
<li><tt>oge</tt>: yields <tt>true</tt> if both operands are not a QNAN and
<li><tt>oge</tt>: yields <tt>true</tt> if both operands are not a QNAN and
<tt>op1</tt> is greater than or equal to <tt>op2</tt>.</li>
<li><tt>olt</tt>: yields <tt>true</tt> if both operands are not a QNAN and
<li><tt>olt</tt>: yields <tt>true</tt> if both operands are not a QNAN and
<tt>op1</tt> is less than <tt>op2</tt>.</li>
<li><tt>ole</tt>: yields <tt>true</tt> if both operands are not a QNAN and
<li><tt>ole</tt>: yields <tt>true</tt> if both operands are not a QNAN and
<tt>op1</tt> is less than or equal to <tt>op2</tt>.</li>
<li><tt>one</tt>: yields <tt>true</tt> if both operands are not a QNAN and
<li><tt>one</tt>: yields <tt>true</tt> if both operands are not a QNAN and
<tt>op1</tt> is not equal to <tt>op2</tt>.</li>
<li><tt>ord</tt>: yields <tt>true</tt> if both operands are not a QNAN.</li>
<li><tt>ueq</tt>: yields <tt>true</tt> if either operand is a QNAN or
<li><tt>ueq</tt>: yields <tt>true</tt> if either operand is a QNAN or
<tt>op1</tt> is equal to <tt>op2</tt>.</li>
<li><tt>ugt</tt>: yields <tt>true</tt> if either operand is a QNAN or
<li><tt>ugt</tt>: yields <tt>true</tt> if either operand is a QNAN or
<tt>op1</tt> is greater than <tt>op2</tt>.</li>
<li><tt>uge</tt>: yields <tt>true</tt> if either operand is a QNAN or
<li><tt>uge</tt>: yields <tt>true</tt> if either operand is a QNAN or
<tt>op1</tt> is greater than or equal to <tt>op2</tt>.</li>
<li><tt>ult</tt>: yields <tt>true</tt> if either operand is a QNAN or
<li><tt>ult</tt>: yields <tt>true</tt> if either operand is a QNAN or
<tt>op1</tt> is less than <tt>op2</tt>.</li>
<li><tt>ule</tt>: yields <tt>true</tt> if either operand is a QNAN or
<li><tt>ule</tt>: yields <tt>true</tt> if either operand is a QNAN or
<tt>op1</tt> is less than or equal to <tt>op2</tt>.</li>
<li><tt>une</tt>: yields <tt>true</tt> if either operand is a QNAN or
<li><tt>une</tt>: yields <tt>true</tt> if either operand is a QNAN or
<tt>op1</tt> is not equal to <tt>op2</tt>.</li>
<li><tt>uno</tt>: yields <tt>true</tt> if either operand is a QNAN.</li>
@ -5144,7 +5144,7 @@ freestanding environments and non-C-based langauges.</p>
suffix is required. Because the argument's type is matched against the return
type, it does not require its own name suffix.</p>
<p>To learn how to add an intrinsic function, please see the
<p>To learn how to add an intrinsic function, please see the
<a href="ExtendingLLVM.html">Extending LLVM Guide</a>.</p>
</div>
@ -6579,11 +6579,11 @@ LLVM</a>.</p>
<ul>
<li><tt>ll</tt>: All loads before the barrier must complete before any load
after the barrier begins.</li>
<li><tt>ls</tt>: All loads before the barrier must complete before any
<li><tt>ls</tt>: All loads before the barrier must complete before any
store after the barrier begins.</li>
<li><tt>ss</tt>: All stores before the barrier must complete before any
<li><tt>ss</tt>: All stores before the barrier must complete before any
store after the barrier begins.</li>
<li><tt>sl</tt>: All stores before the barrier must complete before any
<li><tt>sl</tt>: All stores before the barrier must complete before any
load after the barrier begins.</li>
</ul>
@ -6796,7 +6796,7 @@ LLVM</a>.</p>
</pre>
<h5>Overview:</h5>
<p>This intrinsic subtracts <tt>delta</tt> to the value stored in memory at
<p>This intrinsic subtracts <tt>delta</tt> to the value stored in memory at
<tt>ptr</tt>. It yields the original value at <tt>ptr</tt>.</p>
<h5>Arguments:</h5>
@ -6952,7 +6952,7 @@ LLVM</a>.</p>
</pre>
<h5>Overview:</h5>
<p>These intrinsics takes the signed or unsigned minimum or maximum of
<p>These intrinsics takes the signed or unsigned minimum or maximum of
<tt>delta</tt> and the value stored in memory at <tt>ptr</tt>. It yields the
original value at <tt>ptr</tt>.</p>
@ -7262,24 +7262,44 @@ LLVM</a>.</p>
</pre>
<h5>Overview:</h5>
<p>The <tt>llvm.objectsize</tt> intrinsic returns the constant number of bytes
from <tt>ptr</tt> to the end of the object <tt>ptr</tt> points to if it
can deduce this at compile time. If there are any side-effects in evaluating
the argument or it cannot deduce which objects <tt>ptr</tt> points to at compile
time the intrinsic returns <tt>(size_t) -1</tt> for <tt>type</tt> 0
or 1 and <tt>(size_t) 0</tt> for <tt>type</tt> 2 or 3.</p>
<p>The <tt>llvm.objectsize</tt> intrinsic is designed to provide information
to the optimizers to either discover at compile time either a) when an
operation like memcpy will either overflow a buffer that corresponds to
an object, or b) to determine that a runtime check for overflow isn't
necessary. An object in this context means an allocation of a
specific <a href="#typesystem">type</a>.</p>
<h5>Arguments:</h5>
<p>The <tt>llvm.objectsize</tt> intrinsic takes two arguments. The first
argument is a pointer to the object <tt>ptr</tt> and an integer <tt>type</tt>.
<tt>type</tt> is an integer ranging from 0 to 3. The lsb corresponds to
a return value based on whole objects, the second bit whether or not we
return the maximum or minimum remaining bytes computed.</p>
argument is a pointer to the object <tt>ptr</tt>. The second argument
is an integer <tt>type</tt> which ranges from 0 to 3. The first bit in
the type corresponds to a return value based on whole objects,
and the second bit whether or not we return the maximum or minimum
remaining bytes computed.</p>
<table class="layout">
<tr class="layout">
<td class="left"><tt>00</tt></td>
<td class="left">whole object, maximum number of bytes</td>
</tr>
<tr class="layout">
<td class="left"><tt>01</tt></td>
<td class="left">partial object, maximum number of bytes</td>
</tr>
<tr class="layout">
<td class="left"><tt>10</tt></td>
<td class="left">whole object, minimum number of bytes</td>
</tr>
<tr class="layout">
<td class="left"><tt>11</tt></td>
<td class="left">partial object, minimum number of bytes</td>
</tr>
</table>
<h5>Semantics:</h5>
<p>The <tt>llvm.objectsize</tt> intrinsic is lowered to either a constant
representing the size of the object concerned or <tt>(size_t) -1</tt> if
it cannot be determined at compile time.</p>
representing the size of the object concerned or <tt>i32/i64 -1 or 0</tt>
(depending on the <tt>type</tt> argument if the size cannot be determined
at compile time.</p>
</div>
@ -7293,7 +7313,7 @@ LLVM</a>.</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2009-11-30 09:03:53 +0100 (Mon, 30 Nov 2009) $
Last modified: $Date: 2009-12-05 03:46:03 +0100 (Sat, 05 Dec 2009) $
</address>
</body>

View File

@ -100,7 +100,12 @@ install-ocamldoc: ocamldoc
$(FIND) . -type f -exec \
$(DataInstall) {} $(PROJ_docsdir)/ocamldoc/html \;
ocamldoc: regen-ocamldoc $(PROJ_OBJ_DIR)/ocamldoc.tar.gz
ocamldoc: regen-ocamldoc
$(Echo) Packaging ocamldoc documentation
$(Verb) $(RM) -rf $(PROJ_OBJ_DIR)/ocamldoc.tar*
$(Verb) $(TAR) cf $(PROJ_OBJ_DIR)/ocamldoc.tar ocamldoc
$(Verb) $(GZIP) $(PROJ_OBJ_DIR)/ocamldoc.tar
$(Verb) $(CP) $(PROJ_OBJ_DIR)/ocamldoc.tar.gz $(PROJ_OBJ_DIR)/ocamldoc/html/
regen-ocamldoc:
$(Echo) Building ocamldoc documentation
@ -113,13 +118,6 @@ regen-ocamldoc:
$(OCAMLDOC) -d $(PROJ_OBJ_DIR)/ocamldoc/html -sort -colorize-code -html \
`$(FIND) $(LEVEL)/bindings/ocaml -name "*.odoc" -exec echo -load '{}' ';'`
$(PROJ_OBJ_DIR)/ocamldoc.tar.gz:
$(Echo) Packaging ocamldoc documentation
$(Verb) $(RM) -rf $@ $(PROJ_OBJ_DIR)/ocamldoc.tar
$(Verb) $(TAR) cf $(PROJ_OBJ_DIR)/ocamldoc.tar ocamldoc
$(Verb) $(GZIP) $(PROJ_OBJ_DIR)/ocamldoc.tar
$(Verb) $(CP) $(PROJ_OBJ_DIR)/ocamldoc.tar.gz $(PROJ_OBJ_DIR)/ocamldoc/html/
uninstall-local::
$(Echo) Uninstalling Documentation
$(Verb) $(RM) -rf $(PROJ_docsdir)

View File

@ -0,0 +1,91 @@
//===--- DeltaAlgorithm.h - A Set Minimization Algorithm -------*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_DELTAALGORITHM_H
#define LLVM_ADT_DELTAALGORITHM_H
#include <vector>
#include <set>
namespace llvm {
/// DeltaAlgorithm - Implements the delta debugging algorithm (A. Zeller '99)
/// for minimizing arbitrary sets using a predicate function.
///
/// The result of the algorithm is a subset of the input change set which is
/// guaranteed to satisfy the predicate, assuming that the input set did. For
/// well formed predicates, the result set is guaranteed to be such that
/// removing any single element would falsify the predicate.
///
/// For best results the predicate function *should* (but need not) satisfy
/// certain properties, in particular:
/// (1) The predicate should return false on an empty set and true on the full
/// set.
/// (2) If the predicate returns true for a set of changes, it should return
/// true for all supersets of that set.
///
/// It is not an error to provide a predicate that does not satisfy these
/// requirements, and the algorithm will generally produce reasonable
/// results. However, it may run substantially more tests than with a good
/// predicate.
class DeltaAlgorithm {
public:
typedef unsigned change_ty;
// FIXME: Use a decent data structure.
typedef std::set<change_ty> changeset_ty;
typedef std::vector<changeset_ty> changesetlist_ty;
private:
/// Cache of failed test results. Successful test results are never cached
/// since we always reduce following a success.
std::set<changeset_ty> FailedTestsCache;
/// GetTestResult - Get the test result for the \arg Changes from the
/// cache, executing the test if necessary.
///
/// \param Changes - The change set to test.
/// \return - The test result.
bool GetTestResult(const changeset_ty &Changes);
/// Split - Partition a set of changes \arg Sinto one or two subsets.
void Split(const changeset_ty &S, changesetlist_ty &Res);
/// Delta - Minimize a set of \arg Changes which has been partioned into
/// smaller sets, by attempting to remove individual subsets.
changeset_ty Delta(const changeset_ty &Changes,
const changesetlist_ty &Sets);
/// Search - Search for a subset (or subsets) in \arg Sets which can be
/// removed from \arg Changes while still satisfying the predicate.
///
/// \param Res - On success, a subset of Changes which satisfies the
/// predicate.
/// \return - True on success.
bool Search(const changeset_ty &Changes, const changesetlist_ty &Sets,
changeset_ty &Res);
protected:
/// UpdatedSearchState - Callback used when the search state changes.
virtual void UpdatedSearchState(const changeset_ty &Changes,
const changesetlist_ty &Sets) {}
/// ExecuteOneTest - Execute a single test predicate on the change set \arg S.
virtual bool ExecuteOneTest(const changeset_ty &S) = 0;
public:
virtual ~DeltaAlgorithm();
/// Run - Minimize the set \arg Changes by executing \see ExecuteOneTest() on
/// subsets of changes and returning the smallest set which still satisfies
/// the test predicate.
changeset_ty Run(const changeset_ty &Changes);
};
} // end namespace llvm
#endif

View File

@ -217,7 +217,8 @@ class DenseMap {
private:
void CopyFrom(const DenseMap& other) {
if (NumBuckets != 0 && (!KeyInfoT::isPod() || !ValueInfoT::isPod())) {
if (NumBuckets != 0 &&
(!isPodLike<KeyInfoT>::value || !isPodLike<ValueInfoT>::value)) {
const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
@ -239,7 +240,7 @@ class DenseMap {
Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) *
other.NumBuckets));
if (KeyInfoT::isPod() && ValueInfoT::isPod())
if (isPodLike<KeyInfoT>::value && isPodLike<ValueInfoT>::value)
memcpy(Buckets, other.Buckets, other.NumBuckets * sizeof(BucketT));
else
for (size_t i = 0; i < other.NumBuckets; ++i) {

View File

@ -15,7 +15,7 @@
#define LLVM_ADT_DENSEMAPINFO_H
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <utility>
#include "llvm/Support/type_traits.h"
namespace llvm {
@ -25,7 +25,6 @@ struct DenseMapInfo {
//static inline T getTombstoneKey();
//static unsigned getHashValue(const T &Val);
//static bool isEqual(const T &LHS, const T &RHS);
//static bool isPod()
};
// Provide DenseMapInfo for all pointers.
@ -46,7 +45,6 @@ struct DenseMapInfo<T*> {
(unsigned((uintptr_t)PtrVal) >> 9);
}
static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
static bool isPod() { return true; }
};
// Provide DenseMapInfo for chars.
@ -54,7 +52,6 @@ template<> struct DenseMapInfo<char> {
static inline char getEmptyKey() { return ~0; }
static inline char getTombstoneKey() { return ~0 - 1; }
static unsigned getHashValue(const char& Val) { return Val * 37; }
static bool isPod() { return true; }
static bool isEqual(const char &LHS, const char &RHS) {
return LHS == RHS;
}
@ -65,7 +62,6 @@ template<> struct DenseMapInfo<unsigned> {
static inline unsigned getEmptyKey() { return ~0; }
static inline unsigned getTombstoneKey() { return ~0U - 1; }
static unsigned getHashValue(const unsigned& Val) { return Val * 37; }
static bool isPod() { return true; }
static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
return LHS == RHS;
}
@ -78,7 +74,6 @@ template<> struct DenseMapInfo<unsigned long> {
static unsigned getHashValue(const unsigned long& Val) {
return (unsigned)(Val * 37UL);
}
static bool isPod() { return true; }
static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) {
return LHS == RHS;
}
@ -91,7 +86,6 @@ template<> struct DenseMapInfo<unsigned long long> {
static unsigned getHashValue(const unsigned long long& Val) {
return (unsigned)(Val * 37ULL);
}
static bool isPod() { return true; }
static bool isEqual(const unsigned long long& LHS,
const unsigned long long& RHS) {
return LHS == RHS;
@ -127,7 +121,6 @@ struct DenseMapInfo<std::pair<T, U> > {
return (unsigned)key;
}
static bool isEqual(const Pair& LHS, const Pair& RHS) { return LHS == RHS; }
static bool isPod() { return FirstInfo::isPod() && SecondInfo::isPod(); }
};
} // end namespace llvm

View File

@ -60,7 +60,7 @@ class DenseSet {
ValueT& operator*() { return I->first; }
ValueT* operator->() { return &I->first; }
Iterator& operator++() { ++I; return *this; };
Iterator& operator++() { ++I; return *this; }
bool operator==(const Iterator& X) const { return I == X.I; }
bool operator!=(const Iterator& X) const { return I != X.I; }
};
@ -73,7 +73,7 @@ class DenseSet {
const ValueT& operator*() { return I->first; }
const ValueT* operator->() { return &I->first; }
ConstIterator& operator++() { ++I; return *this; };
ConstIterator& operator++() { ++I; return *this; }
bool operator==(const ConstIterator& X) const { return I == X.I; }
bool operator!=(const ConstIterator& X) const { return I != X.I; }
};

View File

@ -211,9 +211,12 @@ template<typename T> struct DenseMapInfo<ImmutableList<T> > {
static bool isEqual(ImmutableList<T> X1, ImmutableList<T> X2) {
return X1 == X2;
}
static bool isPod() { return true; }
};
template <typename T> struct isPodLike;
template <typename T>
struct isPodLike<ImmutableList<T> > { static const bool value = true; };
} // end llvm namespace
#endif

View File

@ -106,6 +106,12 @@ class PointerIntPair {
bool operator>=(const PointerIntPair &RHS) const {return Value >= RHS.Value;}
};
template <typename T> struct isPodLike;
template<typename PointerTy, unsigned IntBits, typename IntType>
struct isPodLike<PointerIntPair<PointerTy, IntBits, IntType> > {
static const bool value = true;
};
// Provide specialization of DenseMapInfo for PointerIntPair.
template<typename PointerTy, unsigned IntBits, typename IntType>
struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
@ -125,7 +131,6 @@ struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
return unsigned(IV) ^ unsigned(IV >> 9);
}
static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
static bool isPod() { return true; }
};
// Teach SmallPtrSet that PointerIntPair is "basically a pointer".

View File

@ -46,20 +46,17 @@ namespace std {
namespace llvm {
/// SmallVectorImpl - This class consists of common code factored out of the
/// SmallVector class to reduce code duplication based on the SmallVector 'N'
/// template parameter.
template <typename T>
class SmallVectorImpl {
/// SmallVectorBase - This is all the non-templated stuff common to all
/// SmallVectors.
class SmallVectorBase {
protected:
T *Begin, *End, *Capacity;
void *BeginX, *EndX, *CapacityX;
// Allocate raw space for N elements of type T. If T has a ctor or dtor, we
// don't want it to be automatically run, so we need to represent the space as
// something else. An array of char would work great, but might not be
// aligned sufficiently. Instead, we either use GCC extensions, or some
// number of union instances for the space, which guarantee maximal alignment.
protected:
#ifdef __GNUC__
typedef char U;
U FirstEl __attribute__((aligned));
@ -72,46 +69,65 @@ class SmallVectorImpl {
} FirstEl;
#endif
// Space after 'FirstEl' is clobbered, do not add any instance vars after it.
protected:
SmallVectorBase(size_t Size)
: BeginX(&FirstEl), EndX(&FirstEl), CapacityX((char*)&FirstEl+Size) {}
/// isSmall - Return true if this is a smallvector which has not had dynamic
/// memory allocated for it.
bool isSmall() const {
return BeginX == static_cast<const void*>(&FirstEl);
}
public:
bool empty() const { return BeginX == EndX; }
};
/// SmallVectorImpl - This class consists of common code factored out of the
/// SmallVector class to reduce code duplication based on the SmallVector 'N'
/// template parameter.
template <typename T>
class SmallVectorImpl : public SmallVectorBase {
void setEnd(T *P) { EndX = P; }
public:
// Default ctor - Initialize to empty.
explicit SmallVectorImpl(unsigned N)
: Begin(reinterpret_cast<T*>(&FirstEl)),
End(reinterpret_cast<T*>(&FirstEl)),
Capacity(reinterpret_cast<T*>(&FirstEl)+N) {
explicit SmallVectorImpl(unsigned N) : SmallVectorBase(N*sizeof(T)) {
}
~SmallVectorImpl() {
// Destroy the constructed elements in the vector.
destroy_range(Begin, End);
destroy_range(begin(), end());
// If this wasn't grown from the inline copy, deallocate the old space.
if (!isSmall())
operator delete(Begin);
operator delete(begin());
}
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
typedef T *iterator;
typedef const T *const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
bool empty() const { return Begin == End; }
size_type size() const { return End-Begin; }
size_type max_size() const { return size_type(-1) / sizeof(T); }
typedef T &reference;
typedef const T &const_reference;
typedef T *pointer;
typedef const T *const_pointer;
// forward iterator creation methods.
iterator begin() { return Begin; }
const_iterator begin() const { return Begin; }
iterator end() { return End; }
const_iterator end() const { return End; }
iterator begin() { return (iterator)BeginX; }
const_iterator begin() const { return (const_iterator)BeginX; }
iterator end() { return (iterator)EndX; }
const_iterator end() const { return (const_iterator)EndX; }
private:
iterator capacity_ptr() { return (iterator)CapacityX; }
const_iterator capacity_ptr() const { return (const_iterator)CapacityX; }
public:
// reverse iterator creation methods.
reverse_iterator rbegin() { return reverse_iterator(end()); }
@ -119,14 +135,25 @@ class SmallVectorImpl {
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
size_type size() const { return end()-begin(); }
size_type max_size() const { return size_type(-1) / sizeof(T); }
/// capacity - Return the total number of elements in the currently allocated
/// buffer.
size_t capacity() const { return capacity_ptr() - begin(); }
/// data - Return a pointer to the vector's buffer, even if empty().
pointer data() { return pointer(begin()); }
/// data - Return a pointer to the vector's buffer, even if empty().
const_pointer data() const { return const_pointer(begin()); }
reference operator[](unsigned idx) {
assert(Begin + idx < End);
return Begin[idx];
assert(begin() + idx < end());
return begin()[idx];
}
const_reference operator[](unsigned idx) const {
assert(Begin + idx < End);
return Begin[idx];
assert(begin() + idx < end());
return begin()[idx];
}
reference front() {
@ -144,10 +171,10 @@ class SmallVectorImpl {
}
void push_back(const_reference Elt) {
if (End < Capacity) {
if (EndX < CapacityX) {
Retry:
new (End) T(Elt);
++End;
new (end()) T(Elt);
setEnd(end()+1);
return;
}
grow();
@ -155,8 +182,8 @@ class SmallVectorImpl {
}
void pop_back() {
--End;
End->~T();
setEnd(end()-1);
end()->~T();
}
T pop_back_val() {
@ -166,36 +193,36 @@ class SmallVectorImpl {
}
void clear() {
destroy_range(Begin, End);
End = Begin;
destroy_range(begin(), end());
EndX = BeginX;
}
void resize(unsigned N) {
if (N < size()) {
destroy_range(Begin+N, End);
End = Begin+N;
destroy_range(begin()+N, end());
setEnd(begin()+N);
} else if (N > size()) {
if (unsigned(Capacity-Begin) < N)
if (capacity() < N)
grow(N);
construct_range(End, Begin+N, T());
End = Begin+N;
construct_range(end(), begin()+N, T());
setEnd(begin()+N);
}
}
void resize(unsigned N, const T &NV) {
if (N < size()) {
destroy_range(Begin+N, End);
End = Begin+N;
destroy_range(begin()+N, end());
setEnd(begin()+N);
} else if (N > size()) {
if (unsigned(Capacity-Begin) < N)
if (capacity() < N)
grow(N);
construct_range(End, Begin+N, NV);
End = Begin+N;
construct_range(end(), begin()+N, NV);
setEnd(begin()+N);
}
}
void reserve(unsigned N) {
if (unsigned(Capacity-Begin) < N)
if (capacity() < N)
grow(N);
}
@ -207,38 +234,38 @@ class SmallVectorImpl {
void append(in_iter in_start, in_iter in_end) {
size_type NumInputs = std::distance(in_start, in_end);
// Grow allocated space if needed.
if (NumInputs > size_type(Capacity-End))
if (NumInputs > size_type(capacity_ptr()-end()))
grow(size()+NumInputs);
// Copy the new elements over.
std::uninitialized_copy(in_start, in_end, End);
End += NumInputs;
std::uninitialized_copy(in_start, in_end, end());
setEnd(end() + NumInputs);
}
/// append - Add the specified range to the end of the SmallVector.
///
void append(size_type NumInputs, const T &Elt) {
// Grow allocated space if needed.
if (NumInputs > size_type(Capacity-End))
if (NumInputs > size_type(capacity_ptr()-end()))
grow(size()+NumInputs);
// Copy the new elements over.
std::uninitialized_fill_n(End, NumInputs, Elt);
End += NumInputs;
std::uninitialized_fill_n(end(), NumInputs, Elt);
setEnd(end() + NumInputs);
}
void assign(unsigned NumElts, const T &Elt) {
clear();
if (unsigned(Capacity-Begin) < NumElts)
if (capacity() < NumElts)
grow(NumElts);
End = Begin+NumElts;
construct_range(Begin, End, Elt);
setEnd(begin()+NumElts);
construct_range(begin(), end(), Elt);
}
iterator erase(iterator I) {
iterator N = I;
// Shift all elts down one.
std::copy(I+1, End, I);
std::copy(I+1, end(), I);
// Drop the last elt.
pop_back();
return(N);
@ -247,36 +274,36 @@ class SmallVectorImpl {
iterator erase(iterator S, iterator E) {
iterator N = S;
// Shift all elts down.
iterator I = std::copy(E, End, S);
iterator I = std::copy(E, end(), S);
// Drop the last elts.
destroy_range(I, End);
End = I;
destroy_range(I, end());
setEnd(I);
return(N);
}
iterator insert(iterator I, const T &Elt) {
if (I == End) { // Important special case for empty vector.
if (I == end()) { // Important special case for empty vector.
push_back(Elt);
return end()-1;
}
if (End < Capacity) {
if (EndX < CapacityX) {
Retry:
new (End) T(back());
++End;
new (end()) T(back());
setEnd(end()+1);
// Push everything else over.
std::copy_backward(I, End-1, End);
std::copy_backward(I, end()-1, end());
*I = Elt;
return I;
}
size_t EltNo = I-Begin;
size_t EltNo = I-begin();
grow();
I = Begin+EltNo;
I = begin()+EltNo;
goto Retry;
}
iterator insert(iterator I, size_type NumToInsert, const T &Elt) {
if (I == End) { // Important special case for empty vector.
if (I == end()) { // Important special case for empty vector.
append(NumToInsert, Elt);
return end()-1;
}
@ -295,8 +322,8 @@ class SmallVectorImpl {
// insertion. Since we already reserved space, we know that this won't
// reallocate the vector.
if (size_t(end()-I) >= NumToInsert) {
T *OldEnd = End;
append(End-NumToInsert, End);
T *OldEnd = end();
append(end()-NumToInsert, end());
// Copy the existing elements that get replaced.
std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
@ -309,10 +336,10 @@ class SmallVectorImpl {
// not inserting at the end.
// Copy over the elements that we're about to overwrite.
T *OldEnd = End;
End += NumToInsert;
T *OldEnd = end();
setEnd(end() + NumToInsert);
size_t NumOverwritten = OldEnd-I;
std::uninitialized_copy(I, OldEnd, End-NumOverwritten);
std::uninitialized_copy(I, OldEnd, end()-NumOverwritten);
// Replace the overwritten part.
std::fill_n(I, NumOverwritten, Elt);
@ -324,7 +351,7 @@ class SmallVectorImpl {
template<typename ItTy>
iterator insert(iterator I, ItTy From, ItTy To) {
if (I == End) { // Important special case for empty vector.
if (I == end()) { // Important special case for empty vector.
append(From, To);
return end()-1;
}
@ -344,8 +371,8 @@ class SmallVectorImpl {
// insertion. Since we already reserved space, we know that this won't
// reallocate the vector.
if (size_t(end()-I) >= NumToInsert) {
T *OldEnd = End;
append(End-NumToInsert, End);
T *OldEnd = end();
append(end()-NumToInsert, end());
// Copy the existing elements that get replaced.
std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
@ -358,10 +385,10 @@ class SmallVectorImpl {
// not inserting at the end.
// Copy over the elements that we're about to overwrite.
T *OldEnd = End;
End += NumToInsert;
T *OldEnd = end();
setEnd(end() + NumToInsert);
size_t NumOverwritten = OldEnd-I;
std::uninitialized_copy(I, OldEnd, End-NumOverwritten);
std::uninitialized_copy(I, OldEnd, end()-NumOverwritten);
// Replace the overwritten part.
std::copy(From, From+NumOverwritten, I);
@ -371,25 +398,11 @@ class SmallVectorImpl {
return I;
}
/// data - Return a pointer to the vector's buffer, even if empty().
pointer data() {
return pointer(Begin);
}
/// data - Return a pointer to the vector's buffer, even if empty().
const_pointer data() const {
return const_pointer(Begin);
}
const SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
bool operator==(const SmallVectorImpl &RHS) const {
if (size() != RHS.size()) return false;
for (T *This = Begin, *That = RHS.Begin, *E = Begin+size();
This != E; ++This, ++That)
if (*This != *That)
return false;
return true;
return std::equal(begin(), end(), RHS.begin());
}
bool operator!=(const SmallVectorImpl &RHS) const { return !(*this == RHS); }
@ -398,10 +411,6 @@ class SmallVectorImpl {
RHS.begin(), RHS.end());
}
/// capacity - Return the total number of elements in the currently allocated
/// buffer.
size_t capacity() const { return Capacity - Begin; }
/// set_size - Set the array size to \arg N, which the current array must have
/// enough capacity for.
///
@ -413,17 +422,10 @@ class SmallVectorImpl {
/// which will only be overwritten.
void set_size(unsigned N) {
assert(N <= capacity());
End = Begin + N;
setEnd(begin() + N);
}
private:
/// isSmall - Return true if this is a smallvector which has not had dynamic
/// memory allocated for it.
bool isSmall() const {
return static_cast<const void*>(Begin) ==
static_cast<const void*>(&FirstEl);
}
/// grow - double the size of the allocated memory, guaranteeing space for at
/// least one more element or MinSize if specified.
void grow(size_type MinSize = 0);
@ -434,6 +436,9 @@ class SmallVectorImpl {
}
void destroy_range(T *S, T *E) {
// No need to do a destroy loop for POD's.
if (isPodLike<T>::value) return;
while (S != E) {
--E;
E->~T();
@ -444,7 +449,7 @@ class SmallVectorImpl {
// Define this out-of-line to dissuade the C++ compiler from inlining it.
template <typename T>
void SmallVectorImpl<T>::grow(size_t MinSize) {
size_t CurCapacity = Capacity-Begin;
size_t CurCapacity = capacity();
size_t CurSize = size();
size_t NewCapacity = 2*CurCapacity;
if (NewCapacity < MinSize)
@ -452,22 +457,22 @@ void SmallVectorImpl<T>::grow(size_t MinSize) {
T *NewElts = static_cast<T*>(operator new(NewCapacity*sizeof(T)));
// Copy the elements over.
if (is_class<T>::value)
std::uninitialized_copy(Begin, End, NewElts);
if (isPodLike<T>::value)
// Use memcpy for PODs: std::uninitialized_copy optimizes to memmove.
memcpy(NewElts, begin(), CurSize * sizeof(T));
else
// Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
memcpy(NewElts, Begin, CurSize * sizeof(T));
std::uninitialized_copy(begin(), end(), NewElts);
// Destroy the original elements.
destroy_range(Begin, End);
destroy_range(begin(), end());
// If this wasn't grown from the inline copy, deallocate the old space.
if (!isSmall())
operator delete(Begin);
operator delete(begin());
Begin = NewElts;
End = NewElts+CurSize;
Capacity = Begin+NewCapacity;
setEnd(NewElts+CurSize);
BeginX = NewElts;
CapacityX = begin()+NewCapacity;
}
template <typename T>
@ -476,35 +481,35 @@ void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
// We can only avoid copying elements if neither vector is small.
if (!isSmall() && !RHS.isSmall()) {
std::swap(Begin, RHS.Begin);
std::swap(End, RHS.End);
std::swap(Capacity, RHS.Capacity);
std::swap(BeginX, RHS.BeginX);
std::swap(EndX, RHS.EndX);
std::swap(CapacityX, RHS.CapacityX);
return;
}
if (RHS.size() > size_type(Capacity-Begin))
if (RHS.size() > capacity())
grow(RHS.size());
if (size() > size_type(RHS.Capacity-RHS.begin()))
if (size() > RHS.capacity())
RHS.grow(size());
// Swap the shared elements.
size_t NumShared = size();
if (NumShared > RHS.size()) NumShared = RHS.size();
for (unsigned i = 0; i != static_cast<unsigned>(NumShared); ++i)
std::swap(Begin[i], RHS[i]);
std::swap((*this)[i], RHS[i]);
// Copy over the extra elts.
if (size() > RHS.size()) {
size_t EltDiff = size() - RHS.size();
std::uninitialized_copy(Begin+NumShared, End, RHS.End);
RHS.End += EltDiff;
destroy_range(Begin+NumShared, End);
End = Begin+NumShared;
std::uninitialized_copy(begin()+NumShared, end(), RHS.end());
RHS.setEnd(RHS.end()+EltDiff);
destroy_range(begin()+NumShared, end());
setEnd(begin()+NumShared);
} else if (RHS.size() > size()) {
size_t EltDiff = RHS.size() - size();
std::uninitialized_copy(RHS.Begin+NumShared, RHS.End, End);
End += EltDiff;
destroy_range(RHS.Begin+NumShared, RHS.End);
RHS.End = RHS.Begin+NumShared;
std::uninitialized_copy(RHS.begin()+NumShared, RHS.end(), end());
setEnd(end() + EltDiff);
destroy_range(RHS.begin()+NumShared, RHS.end());
RHS.setEnd(RHS.begin()+NumShared);
}
}
@ -516,42 +521,42 @@ SmallVectorImpl<T>::operator=(const SmallVectorImpl<T> &RHS) {
// If we already have sufficient space, assign the common elements, then
// destroy any excess.
unsigned RHSSize = unsigned(RHS.size());
unsigned CurSize = unsigned(size());
size_t RHSSize = RHS.size();
size_t CurSize = size();
if (CurSize >= RHSSize) {
// Assign common elements.
iterator NewEnd;
if (RHSSize)
NewEnd = std::copy(RHS.Begin, RHS.Begin+RHSSize, Begin);
NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, begin());
else
NewEnd = Begin;
NewEnd = begin();
// Destroy excess elements.
destroy_range(NewEnd, End);
destroy_range(NewEnd, end());
// Trim.
End = NewEnd;
setEnd(NewEnd);
return *this;
}
// If we have to grow to have enough elements, destroy the current elements.
// This allows us to avoid copying them during the grow.
if (unsigned(Capacity-Begin) < RHSSize) {
if (capacity() < RHSSize) {
// Destroy current elements.
destroy_range(Begin, End);
End = Begin;
destroy_range(begin(), end());
setEnd(begin());
CurSize = 0;
grow(RHSSize);
} else if (CurSize) {
// Otherwise, use assignment for the already-constructed elements.
std::copy(RHS.Begin, RHS.Begin+CurSize, Begin);
std::copy(RHS.begin(), RHS.begin()+CurSize, begin());
}
// Copy construct the new elements in place.
std::uninitialized_copy(RHS.Begin+CurSize, RHS.End, Begin+CurSize);
std::uninitialized_copy(RHS.begin()+CurSize, RHS.end(), begin()+CurSize);
// Set end.
End = Begin+RHSSize;
setEnd(begin()+RHSSize);
return *this;
}

View File

@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===/
//
// This file implements the StringSwitch template, which mimics a switch()
// statements whose cases are string literals.
// statement whose cases are string literals.
//
//===----------------------------------------------------------------------===/
#ifndef LLVM_ADT_STRINGSWITCH_H
@ -18,7 +18,7 @@
#include <cstring>
namespace llvm {
/// \brief A switch()-like statement whose cases are string literals.
///
/// The StringSwitch class is a simple form of a switch() statement that
@ -35,48 +35,44 @@ namespace llvm {
/// .Case("green", Green)
/// .Case("blue", Blue)
/// .Case("indigo", Indigo)
/// .Case("violet", Violet)
/// .Cases("violet", "purple", Violet)
/// .Default(UnknownColor);
/// \endcode
template<typename T>
template<typename T, typename R = T>
class StringSwitch {
/// \brief The string we are matching.
StringRef Str;
/// \brief The result of this switch statement, once known.
T Result;
/// \brief Set true when the result of this switch is already known; in this
/// case, Result is valid.
bool ResultKnown;
/// \brief The pointer to the result of this switch statement, once known,
/// null before that.
const T *Result;
public:
explicit StringSwitch(StringRef Str)
: Str(Str), ResultKnown(false) { }
explicit StringSwitch(StringRef Str)
: Str(Str), Result(0) { }
template<unsigned N>
StringSwitch& Case(const char (&S)[N], const T& Value) {
if (!ResultKnown && N-1 == Str.size() &&
if (!Result && N-1 == Str.size() &&
(std::memcmp(S, Str.data(), N-1) == 0)) {
Result = Value;
ResultKnown = true;
Result = &Value;
}
return *this;
}
template<unsigned N0, unsigned N1>
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
const T& Value) {
return Case(S0, Value).Case(S1, Value);
}
template<unsigned N0, unsigned N1, unsigned N2>
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
const char (&S2)[N2], const T& Value) {
return Case(S0, Value).Case(S1, Value).Case(S2, Value);
}
template<unsigned N0, unsigned N1, unsigned N2, unsigned N3>
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
const char (&S2)[N2], const char (&S3)[N3],
@ -87,21 +83,21 @@ class StringSwitch {
template<unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4>
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
const char (&S2)[N2], const char (&S3)[N3],
const char (&S4)[N4], const T& Value) {
const char (&S4)[N4], const T& Value) {
return Case(S0, Value).Case(S1, Value).Case(S2, Value).Case(S3, Value)
.Case(S4, Value);
}
T Default(const T& Value) {
if (ResultKnown)
return Result;
R Default(const T& Value) const {
if (Result)
return *Result;
return Value;
}
operator T() {
assert(ResultKnown && "Fell off the end of a string-switch");
return Result;
operator R() const {
assert(Result && "Fell off the end of a string-switch");
return *Result;
}
};

View File

@ -250,6 +250,12 @@ class ValueMapCallbackVH : public CallbackVH {
}
};
template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT>
struct isPodLike<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > {
static const bool value = true;
};
template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT>
struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > {
typedef ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> VH;
@ -267,7 +273,6 @@ struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > {
static bool isEqual(const VH &LHS, const VH &RHS) {
return LHS == RHS;
}
static bool isPod() { return false; }
};

View File

@ -643,7 +643,7 @@ struct ilist : public iplist<NodeTy> {
// Main implementation here - Insert for a node passed by value...
iterator insert(iterator where, const NodeTy &val) {
return insert(where, createNode(val));
return insert(where, this->createNode(val));
}

View File

@ -259,11 +259,9 @@ class AliasSetTracker {
ASTCallbackVH(Value *V, AliasSetTracker *AST = 0);
ASTCallbackVH &operator=(Value *V);
};
/// ASTCallbackVHDenseMapInfo - Traits to tell DenseMap that ASTCallbackVH
/// is not a POD (it needs its destructor called).
struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {
static bool isPod() { return false; }
};
/// ASTCallbackVHDenseMapInfo - Traits to tell DenseMap that tell us how to
/// compare and hash the value handle.
struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {};
AliasAnalysis &AA;
ilist<AliasSet> AliasSets;

View File

@ -197,7 +197,8 @@ namespace llvm {
FlagProtected = 1 << 1,
FlagFwdDecl = 1 << 2,
FlagAppleBlock = 1 << 3,
FlagBlockByrefStruct = 1 << 4
FlagBlockByrefStruct = 1 << 4,
FlagVirtual = 1 << 5
};
protected:
@ -242,6 +243,9 @@ namespace llvm {
bool isBlockByrefStruct() const {
return (getFlags() & FlagBlockByrefStruct) != 0;
}
bool isVirtual() const {
return (getFlags() & FlagVirtual) != 0;
}
/// dump - print type.
void dump() const;
@ -366,6 +370,24 @@ namespace llvm {
/// compile unit, like 'static' in C.
unsigned isLocalToUnit() const { return getUnsignedField(9); }
unsigned isDefinition() const { return getUnsignedField(10); }
unsigned getVirtuality() const {
if (DbgNode->getNumElements() < 14)
return 0;
return getUnsignedField(11);
}
unsigned getVirtualIndex() const {
if (DbgNode->getNumElements() < 14)
return 0;
return getUnsignedField(12);
}
DICompositeType getContainingType() const {
assert (DbgNode->getNumElements() >= 14 && "Invalid type!");
return getFieldAs<DICompositeType>(13);
}
StringRef getFilename() const { return getCompileUnit().getFilename();}
StringRef getDirectory() const { return getCompileUnit().getDirectory();}
@ -470,6 +492,7 @@ namespace llvm {
const Type *EmptyStructPtr; // "{}*".
Function *DeclareFn; // llvm.dbg.declare
Function *ValueFn; // llvm.dbg.value
DIFactory(const DIFactory &); // DO NOT IMPLEMENT
void operator=(const DIFactory&); // DO NOT IMPLEMENT
@ -565,7 +588,14 @@ namespace llvm {
StringRef LinkageName,
DICompileUnit CompileUnit, unsigned LineNo,
DIType Type, bool isLocalToUnit,
bool isDefinition);
bool isDefinition,
unsigned VK = 0,
unsigned VIndex = 0,
DIType = DIType());
/// CreateSubprogramDefinition - Create new subprogram descriptor for the
/// given declaration.
DISubprogram CreateSubprogramDefinition(DISubprogram &SPDeclaration);
/// CreateGlobalVariable - Create a new descriptor for the specified global.
DIGlobalVariable
@ -610,6 +640,13 @@ namespace llvm {
Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D,
Instruction *InsertBefore);
/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
Instruction *InsertDbgValueIntrinsic(llvm::Value *V, llvm::Value *Offset,
DIVariable D, BasicBlock *InsertAtEnd);
/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
Instruction *InsertDbgValueIntrinsic(llvm::Value *V, llvm::Value *Offset,
DIVariable D, Instruction *InsertBefore);
private:
Constant *GetTagConstant(unsigned TAG);
};

View File

@ -175,11 +175,11 @@ class IVUsers : public LoopPass {
ScalarEvolution *SE;
SmallPtrSet<Instruction*,16> Processed;
public:
/// IVUses - A list of all tracked IV uses of induction variable expressions
/// we are interested in.
ilist<IVUsersOfOneStride> IVUses;
public:
/// IVUsesByStride - A mapping from the strides in StrideOrder to the
/// uses in IVUses.
std::map<const SCEV *, IVUsersOfOneStride*> IVUsesByStride;

View File

@ -67,17 +67,17 @@ class LoopDependenceAnalysis : public LoopPass {
/// created. The third argument is set to the pair found or created.
bool findOrInsertDependencePair(Value*, Value*, DependencePair*&);
/// getLoops - Collect all loops of the loop-nest L a given SCEV is variant
/// in.
/// getLoops - Collect all loops of the loop nest L in which
/// a given SCEV is variant.
void getLoops(const SCEV*, DenseSet<const Loop*>*) const;
/// isLoopInvariant - True if a given SCEV is invariant in all loops of the
/// loop-nest starting at the innermost loop L.
/// loop nest starting at the innermost loop L.
bool isLoopInvariant(const SCEV*) const;
/// isAffine - An SCEV is affine with respect to the loop-nest starting at
/// isAffine - An SCEV is affine with respect to the loop nest starting at
/// the innermost loop L if it is of the form A+B*X where A, B are invariant
/// in the loop-nest and X is a induction variable in the loop-nest.
/// in the loop nest and X is a induction variable in the loop nest.
bool isAffine(const SCEV*) const;
/// TODO: doc
@ -93,8 +93,8 @@ class LoopDependenceAnalysis : public LoopPass {
static char ID; // Class identification, replacement for typeinfo
LoopDependenceAnalysis() : LoopPass(&ID) {}
/// isDependencePair - Check wether two values can possibly give rise to a
/// data dependence: that is the case if both are instructions accessing
/// isDependencePair - Check whether two values can possibly give rise to
/// a data dependence: that is the case if both are instructions accessing
/// memory and at least one of those accesses is a write.
bool isDependencePair(const Value*, const Value*) const;

View File

@ -568,7 +568,7 @@ class Loop : public LoopBase<BasicBlock, Loop> {
/// getUniqueExitBlocks - Return all unique successor blocks of this loop.
/// These are the blocks _outside of the current loop_ which are branched to.
/// This assumes that loop is in canonical form.
/// This assumes that loop exits are in canonical form.
///
void getUniqueExitBlocks(SmallVectorImpl<BasicBlock *> &ExitBlocks) const;
@ -976,13 +976,6 @@ class LoopInfo : public FunctionPass {
void removeBlock(BasicBlock *BB) {
LI.removeBlock(BB);
}
static bool isNotAlreadyContainedIn(const Loop *SubLoop,
const Loop *ParentLoop) {
return
LoopInfoBase<BasicBlock, Loop>::isNotAlreadyContainedIn(SubLoop,
ParentLoop);
}
};

View File

@ -52,7 +52,7 @@ class LoopPass : public Pass {
// LPPassManger as expected.
void preparePassManager(PMStack &PMS);
/// Assign pass manager to manager this pass
/// Assign pass manager to manage this pass
virtual void assignPassManager(PMStack &PMS,
PassManagerType PMT = PMT_LoopPassManager);
@ -73,7 +73,7 @@ class LoopPass : public Pass {
/// cloneBasicBlockAnalysis - Clone analysis info associated with basic block.
virtual void cloneBasicBlockAnalysis(BasicBlock *F, BasicBlock *T, Loop *L) {}
/// deletekAnalysisValue - Delete analysis info associated with value V.
/// deleteAnalysisValue - Delete analysis info associated with value V.
virtual void deleteAnalysisValue(Value *V, Loop *L) {}
};

View File

@ -16,6 +16,7 @@
#include "llvm/BasicBlock.h"
#include "llvm/Pass.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/OwningPtr.h"
@ -31,6 +32,7 @@ namespace llvm {
class MemoryDependenceAnalysis;
class PredIteratorCache;
class DominatorTree;
class PHITransAddr;
/// MemDepResult - A memory dependence query can return one of three different
/// answers, described below.
@ -60,9 +62,9 @@ namespace llvm {
/// this case, the load is loading an undef value or a store is the
/// first store to (that part of) the allocation.
/// 3. Dependence queries on calls return Def only when they are
/// readonly calls with identical callees and no intervening
/// clobbers. No validation is done that the operands to the calls
/// are the same.
/// readonly calls or memory use intrinsics with identical callees
/// and no intervening clobbers. No validation is done that the
/// operands to the calls are the same.
Def,
/// NonLocal - This marker indicates that the query has no dependency in
@ -130,6 +132,45 @@ namespace llvm {
}
};
/// NonLocalDepEntry - This is an entry in the NonLocalDepInfo cache, and an
/// entry in the results set for a non-local query. For each BasicBlock (the
/// BB entry) it keeps a MemDepResult and the (potentially phi translated)
/// address that was live in the block.
class NonLocalDepEntry {
BasicBlock *BB;
MemDepResult Result;
WeakVH Address;
public:
NonLocalDepEntry(BasicBlock *bb, MemDepResult result, Value *address)
: BB(bb), Result(result), Address(address) {}
// This is used for searches.
NonLocalDepEntry(BasicBlock *bb) : BB(bb) {}
// BB is the sort key, it can't be changed.
BasicBlock *getBB() const { return BB; }
void setResult(const MemDepResult &R, Value *Addr) {
Result = R;
Address = Addr;
}
const MemDepResult &getResult() const { return Result; }
/// getAddress - Return the address of this pointer in this block. This can
/// be different than the address queried for the non-local result because
/// of phi translation. This returns null if the address was not available
/// in a block (i.e. because phi translation failed) or if this is a cached
/// result and that address was deleted.
///
/// The address is always null for a non-local 'call' dependence.
Value *getAddress() const { return Address; }
bool operator<(const NonLocalDepEntry &RHS) const {
return BB < RHS.BB;
}
};
/// MemoryDependenceAnalysis - This is an analysis that determines, for a
/// given memory operation, what preceding memory operations it depends on.
/// It builds on alias analysis information, and tries to provide a lazy,
@ -151,7 +192,6 @@ namespace llvm {
LocalDepMapType LocalDeps;
public:
typedef std::pair<BasicBlock*, MemDepResult> NonLocalDepEntry;
typedef std::vector<NonLocalDepEntry> NonLocalDepInfo;
private:
/// ValueIsLoadPair - This is a pair<Value*, bool> where the bool is true if
@ -245,29 +285,6 @@ namespace llvm {
BasicBlock *BB,
SmallVectorImpl<NonLocalDepEntry> &Result);
/// GetPHITranslatedValue - Find an available version of the specified value
/// PHI translated across the specified edge. If MemDep isn't able to
/// satisfy this request, it returns null.
Value *GetPHITranslatedValue(Value *V,
BasicBlock *CurBB, BasicBlock *PredBB,
const TargetData *TD) const;
/// GetAvailablePHITranslatedValue - Return the value computed by
/// PHITranslatePointer if it dominates PredBB, otherwise return null.
Value *GetAvailablePHITranslatedValue(Value *V,
BasicBlock *CurBB, BasicBlock *PredBB,
const TargetData *TD,
const DominatorTree &DT) const;
/// InsertPHITranslatedPointer - Insert a computation of the PHI translated
/// version of 'V' for the edge PredBB->CurBB into the end of the PredBB
/// block. All newly created instructions are added to the NewInsts list.
Value *InsertPHITranslatedPointer(Value *V,
BasicBlock *CurBB, BasicBlock *PredBB,
const TargetData *TD,
const DominatorTree &DT,
SmallVectorImpl<Instruction*> &NewInsts) const;
/// removeInstruction - Remove an instruction from the dependence analysis,
/// updating the dependence of instructions that previously depended on it.
void removeInstruction(Instruction *InstToRemove);
@ -288,7 +305,7 @@ namespace llvm {
MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
BasicBlock::iterator ScanIt,
BasicBlock *BB);
bool getNonLocalPointerDepFromBB(Value *Pointer, uint64_t Size,
bool getNonLocalPointerDepFromBB(const PHITransAddr &Pointer, uint64_t Size,
bool isLoad, BasicBlock *BB,
SmallVectorImpl<NonLocalDepEntry> &Result,
DenseMap<BasicBlock*, Value*> &Visited,

View File

@ -0,0 +1,121 @@
//===- PHITransAddr.h - PHI Translation for Addresses -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the PHITransAddr class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_PHITRANSADDR_H
#define LLVM_ANALYSIS_PHITRANSADDR_H
#include "llvm/Instruction.h"
#include "llvm/ADT/SmallVector.h"
namespace llvm {
class DominatorTree;
class TargetData;
/// PHITransAddr - An address value which tracks and handles phi translation.
/// As we walk "up" the CFG through predecessors, we need to ensure that the
/// address we're tracking is kept up to date. For example, if we're analyzing
/// an address of "&A[i]" and walk through the definition of 'i' which is a PHI
/// node, we *must* phi translate i to get "&A[j]" or else we will analyze an
/// incorrect pointer in the predecessor block.
///
/// This is designed to be a relatively small object that lives on the stack and
/// is copyable.
///
class PHITransAddr {
/// Addr - The actual address we're analyzing.
Value *Addr;
/// TD - The target data we are playing with if known, otherwise null.
const TargetData *TD;
/// InstInputs - The inputs for our symbolic address.
SmallVector<Instruction*, 4> InstInputs;
public:
PHITransAddr(Value *addr, const TargetData *td) : Addr(addr), TD(td) {
// If the address is an instruction, the whole thing is considered an input.
if (Instruction *I = dyn_cast<Instruction>(Addr))
InstInputs.push_back(I);
}
Value *getAddr() const { return Addr; }
/// NeedsPHITranslationFromBlock - Return true if moving from the specified
/// BasicBlock to its predecessors requires PHI translation.
bool NeedsPHITranslationFromBlock(BasicBlock *BB) const {
// We do need translation if one of our input instructions is defined in
// this block.
for (unsigned i = 0, e = InstInputs.size(); i != e; ++i)
if (InstInputs[i]->getParent() == BB)
return true;
return false;
}
/// IsPotentiallyPHITranslatable - If this needs PHI translation, return true
/// if we have some hope of doing it. This should be used as a filter to
/// avoid calling PHITranslateValue in hopeless situations.
bool IsPotentiallyPHITranslatable() const;
/// PHITranslateValue - PHI translate the current address up the CFG from
/// CurBB to Pred, updating our state the reflect any needed changes. This
/// returns true on failure and sets Addr to null.
bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB);
/// PHITranslateWithInsertion - PHI translate this value into the specified
/// predecessor block, inserting a computation of the value if it is
/// unavailable.
///
/// All newly created instructions are added to the NewInsts list. This
/// returns null on failure.
///
Value *PHITranslateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB,
const DominatorTree &DT,
SmallVectorImpl<Instruction*> &NewInsts);
void dump() const;
/// Verify - Check internal consistency of this data structure. If the
/// structure is valid, it returns true. If invalid, it prints errors and
/// returns false.
bool Verify() const;
private:
Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB);
/// GetAvailablePHITranslatedSubExpr - Return the value computed by
/// PHITranslateSubExpr if it dominates PredBB, otherwise return null.
Value *GetAvailablePHITranslatedSubExpr(Value *V,
BasicBlock *CurBB, BasicBlock *PredBB,
const DominatorTree &DT) const;
/// InsertPHITranslatedSubExpr - Insert a computation of the PHI translated
/// version of 'V' for the edge PredBB->CurBB into the end of the PredBB
/// block. All newly created instructions are added to the NewInsts list.
/// This returns null on failure.
///
Value *InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB,
BasicBlock *PredBB, const DominatorTree &DT,
SmallVectorImpl<Instruction*> &NewInsts);
/// AddAsInput - If the specified value is an instruction, add it as an input.
Value *AddAsInput(Value *V) {
// If V is an instruction, it is now an input.
if (Instruction *VI = dyn_cast<Instruction>(V))
InstInputs.push_back(VI);
return V;
}
};
} // end namespace llvm
#endif

View File

@ -92,6 +92,7 @@ namespace llvm {
// file.
//
ModulePass *createProfileLoaderPass();
extern const PassInfo *ProfileLoaderPassID;
//===--------------------------------------------------------------------===//
//

View File

@ -21,116 +21,228 @@
#ifndef LLVM_ANALYSIS_PROFILEINFO_H
#define LLVM_ANALYSIS_PROFILEINFO_H
#include "llvm/BasicBlock.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <string>
#include <map>
#include <set>
namespace llvm {
class Function;
class Pass;
class raw_ostream;
class BasicBlock;
class Function;
class MachineBasicBlock;
class MachineFunction;
// Helper for dumping edges to errs().
raw_ostream& operator<<(raw_ostream &O, std::pair<const BasicBlock *, const BasicBlock *> E);
raw_ostream& operator<<(raw_ostream &O, std::pair<const MachineBasicBlock *, const MachineBasicBlock *> E);
raw_ostream& operator<<(raw_ostream &O, const BasicBlock *BB);
raw_ostream& operator<<(raw_ostream &O, const MachineBasicBlock *MBB);
raw_ostream& operator<<(raw_ostream &O, const Function *F);
raw_ostream& operator<<(raw_ostream &O, const MachineFunction *MF);
/// ProfileInfo Class - This class holds and maintains profiling
/// information for some unit of code.
class ProfileInfo {
template<class FType, class BType>
class ProfileInfoT {
public:
// Types for handling profiling information.
typedef std::pair<const BasicBlock*, const BasicBlock*> Edge;
typedef std::pair<const BType*, const BType*> Edge;
typedef std::pair<Edge, double> EdgeWeight;
typedef std::map<Edge, double> EdgeWeights;
typedef std::map<const BasicBlock*, double> BlockCounts;
typedef std::map<const BType*, double> BlockCounts;
typedef std::map<const BType*, const BType*> Path;
protected:
// EdgeInformation - Count the number of times a transition between two
// blocks is executed. As a special case, we also hold an edge from the
// null BasicBlock to the entry block to indicate how many times the
// function was entered.
std::map<const Function*, EdgeWeights> EdgeInformation;
std::map<const FType*, EdgeWeights> EdgeInformation;
// BlockInformation - Count the number of times a block is executed.
std::map<const Function*, BlockCounts> BlockInformation;
std::map<const FType*, BlockCounts> BlockInformation;
// FunctionInformation - Count the number of times a function is executed.
std::map<const Function*, double> FunctionInformation;
std::map<const FType*, double> FunctionInformation;
ProfileInfoT<MachineFunction, MachineBasicBlock> *MachineProfile;
public:
static char ID; // Class identification, replacement for typeinfo
virtual ~ProfileInfo(); // We want to be subclassed
ProfileInfoT();
~ProfileInfoT(); // We want to be subclassed
// MissingValue - The value that is returned for execution counts in case
// no value is available.
static const double MissingValue;
// getFunction() - Returns the Function for an Edge, checking for validity.
static const Function* getFunction(Edge e) {
static const FType* getFunction(Edge e) {
if (e.first) {
return e.first->getParent();
} else if (e.second) {
return e.second->getParent();
}
assert(0 && "Invalid ProfileInfo::Edge");
return (const Function*)0;
return (const FType*)0;
}
// getEdge() - Creates an Edge from two BasicBlocks.
static Edge getEdge(const BasicBlock *Src, const BasicBlock *Dest) {
static Edge getEdge(const BType *Src, const BType *Dest) {
return std::make_pair(Src, Dest);
}
//===------------------------------------------------------------------===//
/// Profile Information Queries
///
double getExecutionCount(const Function *F);
double getExecutionCount(const FType *F);
double getExecutionCount(const BasicBlock *BB);
double getExecutionCount(const BType *BB);
void setExecutionCount(const BType *BB, double w);
void addExecutionCount(const BType *BB, double w);
double getEdgeWeight(Edge e) const {
std::map<const Function*, EdgeWeights>::const_iterator J =
typename std::map<const FType*, EdgeWeights>::const_iterator J =
EdgeInformation.find(getFunction(e));
if (J == EdgeInformation.end()) return MissingValue;
EdgeWeights::const_iterator I = J->second.find(e);
typename EdgeWeights::const_iterator I = J->second.find(e);
if (I == J->second.end()) return MissingValue;
return I->second;
}
EdgeWeights &getEdgeWeights (const Function *F) {
void setEdgeWeight(Edge e, double w) {
DEBUG_WITH_TYPE("profile-info",
errs() << "Creating Edge " << e
<< " (weight: " << format("%.20g",w) << ")\n");
EdgeInformation[getFunction(e)][e] = w;
}
void addEdgeWeight(Edge e, double w);
EdgeWeights &getEdgeWeights (const FType *F) {
return EdgeInformation[F];
}
//===------------------------------------------------------------------===//
/// Analysis Update Methods
///
void removeBlock(const BasicBlock *BB) {
std::map<const Function*, BlockCounts>::iterator J =
BlockInformation.find(BB->getParent());
if (J == BlockInformation.end()) return;
void removeBlock(const BType *BB);
J->second.erase(BB);
void removeEdge(Edge e);
void replaceEdge(const Edge &, const Edge &);
enum GetPathMode {
GetPathToExit = 1,
GetPathToValue = 2,
GetPathToDest = 4,
GetPathWithNewEdges = 8
};
const BType *GetPath(const BType *Src, const BType *Dest,
Path &P, unsigned Mode);
void divertFlow(const Edge &, const Edge &);
void splitEdge(const BType *FirstBB, const BType *SecondBB,
const BType *NewBB, bool MergeIdenticalEdges = false);
void splitBlock(const BType *Old, const BType* New);
void splitBlock(const BType *BB, const BType* NewBB,
BType *const *Preds, unsigned NumPreds);
void replaceAllUses(const BType *RmBB, const BType *DestBB);
void transfer(const FType *Old, const FType *New);
void repair(const FType *F);
void dump(FType *F = 0, bool real = true) {
errs() << "**** This is ProfileInfo " << this << " speaking:\n";
if (!real) {
typename std::set<const FType*> Functions;
errs() << "Functions: \n";
if (F) {
errs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n";
Functions.insert(F);
} else {
for (typename std::map<const FType*, double>::iterator fi = FunctionInformation.begin(),
fe = FunctionInformation.end(); fi != fe; ++fi) {
errs() << fi->first << "@" << format("%p",fi->first) << ": " << format("%.20g",fi->second) << "\n";
Functions.insert(fi->first);
}
}
for (typename std::set<const FType*>::iterator FI = Functions.begin(), FE = Functions.end();
FI != FE; ++FI) {
const FType *F = *FI;
typename std::map<const FType*, BlockCounts>::iterator bwi = BlockInformation.find(F);
errs() << "BasicBlocks for Function " << F << ":\n";
for (typename BlockCounts::const_iterator bi = bwi->second.begin(), be = bwi->second.end(); bi != be; ++bi) {
errs() << bi->first << "@" << format("%p", bi->first) << ": " << format("%.20g",bi->second) << "\n";
}
}
for (typename std::set<const FType*>::iterator FI = Functions.begin(), FE = Functions.end();
FI != FE; ++FI) {
typename std::map<const FType*, EdgeWeights>::iterator ei = EdgeInformation.find(*FI);
errs() << "Edges for Function " << ei->first << ":\n";
for (typename EdgeWeights::iterator ewi = ei->second.begin(), ewe = ei->second.end();
ewi != ewe; ++ewi) {
errs() << ewi->first << ": " << format("%.20g",ewi->second) << "\n";
}
}
} else {
assert(F && "No function given, this is not supported!");
errs() << "Functions: \n";
errs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n";
errs() << "BasicBlocks for Function " << F << ":\n";
for (typename FType::const_iterator BI = F->begin(), BE = F->end();
BI != BE; ++BI) {
const BType *BB = &(*BI);
errs() << BB << "@" << format("%p", BB) << ": " << format("%.20g",getExecutionCount(BB)) << "\n";
}
}
errs() << "**** ProfileInfo " << this << ", over and out.\n";
}
void removeEdge(Edge e) {
std::map<const Function*, EdgeWeights>::iterator J =
EdgeInformation.find(getFunction(e));
if (J == EdgeInformation.end()) return;
bool CalculateMissingEdge(const BType *BB, Edge &removed, bool assumeEmptyExit = false);
J->second.erase(e);
bool EstimateMissingEdges(const BType *BB);
ProfileInfoT<MachineFunction, MachineBasicBlock> *MI() {
if (MachineProfile == 0)
MachineProfile = new ProfileInfoT<MachineFunction, MachineBasicBlock>();
return MachineProfile;
}
void splitEdge(const BasicBlock *FirstBB, const BasicBlock *SecondBB,
const BasicBlock *NewBB, bool MergeIdenticalEdges = false);
void replaceAllUses(const BasicBlock *RmBB, const BasicBlock *DestBB);
bool hasMI() const {
return (MachineProfile != 0);
}
};
typedef ProfileInfoT<Function, BasicBlock> ProfileInfo;
typedef ProfileInfoT<MachineFunction, MachineBasicBlock> MachineProfileInfo;
/// createProfileLoaderPass - This function returns a Pass that loads the
/// profiling information for the module from the specified filename, making
/// it available to the optimizers.
Pass *createProfileLoaderPass(const std::string &Filename);
raw_ostream& operator<<(raw_ostream &O, ProfileInfo::Edge E);
} // End llvm namespace
#endif

View File

@ -51,6 +51,10 @@ class Argument : public Value, public ilist_node<Argument> {
/// in its containing function.
bool hasByValAttr() const;
/// hasNestAttr - Return true if this argument has the nest attribute on
/// it in its containing function.
bool hasNestAttr() const;
/// hasNoAliasAttr - Return true if this argument has the noalias attribute on
/// it in its containing function.
bool hasNoAliasAttr() const;

View File

@ -25,53 +25,52 @@
namespace llvm {
struct BPNode {
BPNode* Next;
uintptr_t& PtrRef;
BPNode(BPNode* n, uintptr_t& pref)
: Next(n), PtrRef(pref) {
PtrRef = 0;
}
};
struct BPEntry {
union { BPNode* Head; void* Ptr; };
BPEntry() : Head(NULL) {}
void SetPtr(BPNode*& FreeList, void* P);
};
class BPKey {
unsigned Raw;
public:
BPKey(SerializedPtrID PtrId) : Raw(PtrId << 1) { assert (PtrId > 0); }
BPKey(unsigned code, unsigned) : Raw(code) {}
void MarkFinal() { Raw |= 0x1; }
bool hasFinalPtr() const { return Raw & 0x1 ? true : false; }
SerializedPtrID getID() const { return Raw >> 1; }
static inline BPKey getEmptyKey() { return BPKey(0,0); }
static inline BPKey getTombstoneKey() { return BPKey(1,0); }
static inline unsigned getHashValue(const BPKey& K) { return K.Raw & ~0x1; }
static bool isEqual(const BPKey& K1, const BPKey& K2) {
return (K1.Raw ^ K2.Raw) & ~0x1 ? false : true;
}
};
template <>
struct isPodLike<BPKey> { static const bool value = true; };
template <>
struct isPodLike<BPEntry> { static const bool value = true; };
class Deserializer {
//===----------------------------------------------------------===//
// Internal type definitions.
//===----------------------------------------------------------===//
struct BPNode {
BPNode* Next;
uintptr_t& PtrRef;
BPNode(BPNode* n, uintptr_t& pref)
: Next(n), PtrRef(pref) {
PtrRef = 0;
}
};
struct BPEntry {
union { BPNode* Head; void* Ptr; };
BPEntry() : Head(NULL) {}
static inline bool isPod() { return true; }
void SetPtr(BPNode*& FreeList, void* P);
};
class BPKey {
unsigned Raw;
public:
BPKey(SerializedPtrID PtrId) : Raw(PtrId << 1) { assert (PtrId > 0); }
BPKey(unsigned code, unsigned) : Raw(code) {}
void MarkFinal() { Raw |= 0x1; }
bool hasFinalPtr() const { return Raw & 0x1 ? true : false; }
SerializedPtrID getID() const { return Raw >> 1; }
static inline BPKey getEmptyKey() { return BPKey(0,0); }
static inline BPKey getTombstoneKey() { return BPKey(1,0); }
static inline unsigned getHashValue(const BPKey& K) { return K.Raw & ~0x1; }
static bool isEqual(const BPKey& K1, const BPKey& K2) {
return (K1.Raw ^ K2.Raw) & ~0x1 ? false : true;
}
static bool isPod() { return true; }
};
typedef llvm::DenseMap<BPKey,BPEntry,BPKey,BPEntry> MapTy;

View File

@ -68,7 +68,10 @@ namespace CallingConv {
ARM_AAPCS = 67,
/// ARM_AAPCS_VFP - Same as ARM_AAPCS, but uses hard floating point ABI.
ARM_AAPCS_VFP = 68
ARM_AAPCS_VFP = 68,
/// MSP430_INTR - Calling convention used for MSP430 interrupt routines.
MSP430_INTR = 69
};
} // End CallingConv namespace

View File

@ -1,108 +0,0 @@
//===--------- BreakCriticalMachineEdge.h - Break critical edges ---------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
//
// Helper function to break a critical machine edge.
//
//===---------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_BREAKCRITICALMACHINEEDGE_H
#define LLVM_CODEGEN_BREAKCRITICALMACHINEEDGE_H
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
MachineBasicBlock* SplitCriticalMachineEdge(MachineBasicBlock* src,
MachineBasicBlock* dst) {
MachineFunction &MF = *src->getParent();
const BasicBlock* srcBB = src->getBasicBlock();
MachineBasicBlock* crit_mbb = MF.CreateMachineBasicBlock(srcBB);
// modify the llvm control flow graph
src->removeSuccessor(dst);
src->addSuccessor(crit_mbb);
crit_mbb->addSuccessor(dst);
// insert the new block into the machine function.
MF.push_back(crit_mbb);
// insert a unconditional branch linking the new block to dst
const TargetMachine& TM = MF.getTarget();
const TargetInstrInfo* TII = TM.getInstrInfo();
std::vector<MachineOperand> emptyConditions;
TII->InsertBranch(*crit_mbb, dst, (MachineBasicBlock*)0,
emptyConditions);
// modify every branch in src that points to dst to point to the new
// machine basic block instead:
MachineBasicBlock::iterator mii = src->end();
bool found_branch = false;
while (mii != src->begin()) {
mii--;
// if there are no more branches, finish the loop
if (!mii->getDesc().isTerminator()) {
break;
}
// Scan the operands of this branch, replacing any uses of dst with
// crit_mbb.
for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) {
MachineOperand & mo = mii->getOperand(i);
if (mo.isMBB() && mo.getMBB() == dst) {
found_branch = true;
mo.setMBB(crit_mbb);
}
}
}
// TODO: This is tentative. It may be necessary to fix this code. Maybe
// I am inserting too many gotos, but I am trusting that the asm printer
// will optimize the unnecessary gotos.
if(!found_branch) {
TII->InsertBranch(*src, crit_mbb, (MachineBasicBlock*)0,
emptyConditions);
}
/// Change all the phi functions in dst, so that the incoming block be
/// crit_mbb, instead of src
for(mii = dst->begin(); mii != dst->end(); mii++) {
/// the first instructions are always phi functions.
if(mii->getOpcode() != TargetInstrInfo::PHI)
break;
// Find the operands corresponding to the source block
std::vector<unsigned> toRemove;
unsigned reg = 0;
for (unsigned u = 0; u != mii->getNumOperands(); ++u)
if (mii->getOperand(u).isMBB() &&
mii->getOperand(u).getMBB() == src) {
reg = mii->getOperand(u-1).getReg();
toRemove.push_back(u-1);
}
// Remove all uses of this MBB
for (std::vector<unsigned>::reverse_iterator I = toRemove.rbegin(),
E = toRemove.rend(); I != E; ++I) {
mii->RemoveOperand(*I+1);
mii->RemoveOperand(*I);
}
// Add a single use corresponding to the new MBB
mii->addOperand(MachineOperand::CreateReg(reg, false));
mii->addOperand(MachineOperand::CreateMBB(crit_mbb));
}
return crit_mbb;
}
}
#endif

View File

@ -0,0 +1,39 @@
//===---------------- lib/CodeGen/CalcSpillWeights.h ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H
#define LLVM_CODEGEN_CALCSPILLWEIGHTS_H
#include "llvm/CodeGen/MachineFunctionPass.h"
namespace llvm {
class LiveInterval;
/// CalculateSpillWeights - Compute spill weights for all virtual register
/// live intervals.
class CalculateSpillWeights : public MachineFunctionPass {
public:
static char ID;
CalculateSpillWeights() : MachineFunctionPass(&ID) {}
virtual void getAnalysisUsage(AnalysisUsage &au) const;
virtual bool runOnMachineFunction(MachineFunction &fn);
private:
/// Returns true if the given live interval is zero length.
bool isZeroLengthInterval(LiveInterval *li) const;
};
}
#endif // LLVM_CODEGEN_CALCSPILLWEIGHTS_H

View File

@ -93,7 +93,7 @@ void SelectRoot(SelectionDAG &DAG) {
// a reference to the root node, preventing it from being deleted,
// and tracking any changes of the root.
HandleSDNode Dummy(CurDAG->getRoot());
ISelPosition = next(SelectionDAG::allnodes_iterator(CurDAG->getRoot().getNode()));
ISelPosition = llvm::next(SelectionDAG::allnodes_iterator(CurDAG->getRoot().getNode()));
// The AllNodes list is now topological-sorted. Visit the
// nodes by starting at the end of the list (the root of the
@ -110,8 +110,7 @@ void SelectRoot(SelectionDAG &DAG) {
DAG.setSubgraphColor(Node, "red");
#endif
SDNode *ResNode = Select(SDValue(Node, 0));
// If node should not be replaced,
// continue with the next one.
// If node should not be replaced, continue with the next one.
if (ResNode == Node)
continue;
// Replace node.

View File

@ -98,14 +98,6 @@ class FastISel {
///
bool SelectOperator(User *I, unsigned Opcode);
/// TargetSelectInstruction - This method is called by target-independent
/// code when the normal FastISel process fails to select an instruction.
/// This gives targets a chance to emit code for anything that doesn't
/// fit into FastISel's framework. It returns true if it was successful.
///
virtual bool
TargetSelectInstruction(Instruction *I) = 0;
/// getRegForValue - Create a virtual register and arrange for it to
/// be assigned the value for the given LLVM value.
unsigned getRegForValue(Value *V);
@ -134,6 +126,14 @@ class FastISel {
#endif
);
/// TargetSelectInstruction - This method is called by target-independent
/// code when the normal FastISel process fails to select an instruction.
/// This gives targets a chance to emit code for anything that doesn't
/// fit into FastISel's framework. It returns true if it was successful.
///
virtual bool
TargetSelectInstruction(Instruction *I) = 0;
/// FastEmit_r - This method is called by target-independent code
/// to request that an instruction with the given type and opcode
/// be emitted.

View File

@ -19,6 +19,7 @@
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/CodeGen/GCs.h"
#include "llvm/Target/TargetMachine.h"
#include <cstdlib>
namespace {
struct ForceCodegenLinking {

View File

@ -112,10 +112,13 @@ namespace llvm {
return (unsigned)(IntervalPercentage * indexes_->getFunctionSize());
}
/// conflictsWithPhysRegDef - Returns true if the specified register
/// is defined during the duration of the specified interval.
bool conflictsWithPhysRegDef(const LiveInterval &li, VirtRegMap &vrm,
unsigned reg);
/// conflictsWithPhysReg - Returns true if the specified register is used or
/// defined during the duration of the specified interval. Copies to and
/// from li.reg are allowed. This method is only able to analyze simple
/// ranges that stay within a single basic block. Anything else is
/// considered a conflict.
bool conflictsWithPhysReg(const LiveInterval &li, VirtRegMap &vrm,
unsigned reg);
/// conflictsWithPhysRegRef - Similar to conflictsWithPhysRegRef except
/// it can check use as well.
@ -186,6 +189,10 @@ namespace llvm {
return indexes_->getMBBFromIndex(index);
}
SlotIndex getMBBTerminatorGap(const MachineBasicBlock *mbb) {
return indexes_->getTerminatorGap(mbb);
}
SlotIndex InsertMachineInstrInMaps(MachineInstr *MI) {
return indexes_->insertMachineInstrInMaps(MI);
}

View File

@ -283,6 +283,11 @@ class LiveVariables : public MachineFunctionPass {
return getVarInfo(Reg).isLiveIn(MBB, Reg, *MRI);
}
/// isLiveOut - Determine if Reg is live out from MBB, when not considering
/// PHI nodes. This means that Reg is either killed by a successor block or
/// passed through one.
bool isLiveOut(unsigned Reg, const MachineBasicBlock &MBB);
/// addNewBlock - Add a new basic block BB between DomBB and SuccBB. All
/// variables that are live out of DomBB and live into SuccBB will be marked
/// as passing live through BB. This method assumes that the machine code is

View File

@ -327,7 +327,20 @@ class MachineFrameInfo {
/// setMaxAlignment - Set the preferred alignment.
///
void setMaxAlignment(unsigned Align) { MaxAlignment = Align; }
/// calculateMaxStackAlignment() - If there is a local object which requires
/// greater alignment than the current max alignment, adjust accordingly.
void calculateMaxStackAlignment() {
for (int i = getObjectIndexBegin(),
e = getObjectIndexEnd(); i != e; ++i) {
if (isDeadObjectIndex(i))
continue;
unsigned Align = getObjectAlignment(i);
MaxAlignment = std::max(MaxAlignment, Align);
}
}
/// hasCalls - Return true if the current function has no function calls.
/// This is only valid during or after prolog/epilog code emission.
///

View File

@ -320,6 +320,11 @@ class MachineInstr : public ilist_node<MachineInstr> {
/// loads the instruction does are invariant (if it does multiple loads).
bool isInvariantLoad(AliasAnalysis *AA) const;
/// isConstantValuePHI - If the specified instruction is a PHI that always
/// merges together the same virtual register, return the register, otherwise
/// return 0.
unsigned isConstantValuePHI() const;
//
// Debugging support
//

View File

@ -0,0 +1,115 @@
//===-- MachineSSAUpdater.h - Unstructured SSA Update Tool ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the MachineSSAUpdater class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_MACHINESSAUPDATER_H
#define LLVM_CODEGEN_MACHINESSAUPDATER_H
namespace llvm {
class MachineBasicBlock;
class MachineFunction;
class MachineInstr;
class MachineOperand;
class MachineRegisterInfo;
class TargetInstrInfo;
class TargetRegisterClass;
template<typename T> class SmallVectorImpl;
/// MachineSSAUpdater - This class updates SSA form for a set of virtual
/// registers defined in multiple blocks. This is used when code duplication
/// or another unstructured transformation wants to rewrite a set of uses of one
/// vreg with uses of a set of vregs.
class MachineSSAUpdater {
/// AvailableVals - This keeps track of which value to use on a per-block
/// basis. When we insert PHI nodes, we keep track of them here.
//typedef DenseMap<MachineBasicBlock*, unsigned > AvailableValsTy;
void *AV;
/// IncomingPredInfo - We use this as scratch space when doing our recursive
/// walk. This should only be used in GetValueInBlockInternal, normally it
/// should be empty.
//std::vector<std::pair<MachineBasicBlock*, unsigned > > IncomingPredInfo;
void *IPI;
/// VR - Current virtual register whose uses are being updated.
unsigned VR;
/// VRC - Register class of the current virtual register.
const TargetRegisterClass *VRC;
/// InsertedPHIs - If this is non-null, the MachineSSAUpdater adds all PHI
/// nodes that it creates to the vector.
SmallVectorImpl<MachineInstr*> *InsertedPHIs;
const TargetInstrInfo *TII;
MachineRegisterInfo *MRI;
public:
/// MachineSSAUpdater constructor. If InsertedPHIs is specified, it will be
/// filled in with all PHI Nodes created by rewriting.
explicit MachineSSAUpdater(MachineFunction &MF,
SmallVectorImpl<MachineInstr*> *InsertedPHIs = 0);
~MachineSSAUpdater();
/// Initialize - Reset this object to get ready for a new set of SSA
/// updates.
void Initialize(unsigned V);
/// AddAvailableValue - Indicate that a rewritten value is available at the
/// end of the specified block with the specified value.
void AddAvailableValue(MachineBasicBlock *BB, unsigned V);
/// HasValueForBlock - Return true if the MachineSSAUpdater already has a
/// value for the specified block.
bool HasValueForBlock(MachineBasicBlock *BB) const;
/// GetValueAtEndOfBlock - Construct SSA form, materializing a value that is
/// live at the end of the specified block.
unsigned GetValueAtEndOfBlock(MachineBasicBlock *BB);
/// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that
/// is live in the middle of the specified block.
///
/// GetValueInMiddleOfBlock is the same as GetValueAtEndOfBlock except in one
/// important case: if there is a definition of the rewritten value after the
/// 'use' in BB. Consider code like this:
///
/// X1 = ...
/// SomeBB:
/// use(X)
/// X2 = ...
/// br Cond, SomeBB, OutBB
///
/// In this case, there are two values (X1 and X2) added to the AvailableVals
/// set by the client of the rewriter, and those values are both live out of
/// their respective blocks. However, the use of X happens in the *middle* of
/// a block. Because of this, we need to insert a new PHI node in SomeBB to
/// merge the appropriate values, and this value isn't live out of the block.
///
unsigned GetValueInMiddleOfBlock(MachineBasicBlock *BB);
/// RewriteUse - Rewrite a use of the symbolic value. This handles PHI nodes,
/// which use their value in the corresponding predecessor. Note that this
/// will not work if the use is supposed to be rewritten to a value defined in
/// the same block as the use, but above it. Any 'AddAvailableValue's added
/// for the use's block will be considered to be below it.
void RewriteUse(MachineOperand &U);
private:
void ReplaceRegWith(unsigned OldReg, unsigned NewReg);
unsigned GetValueAtEndOfBlockInternal(MachineBasicBlock *BB);
void operator=(const MachineSSAUpdater&); // DO NOT IMPLEMENT
MachineSSAUpdater(const MachineSSAUpdater&); // DO NOT IMPLEMENT
};
} // End llvm namespace
#endif

View File

@ -131,7 +131,7 @@ namespace llvm {
/// TailDuplicate Pass - Duplicate blocks with unconditional branches
/// into tails of their predecessors.
FunctionPass *createTailDuplicatePass();
FunctionPass *createTailDuplicatePass(bool PreRegAlloc = false);
/// IfConverter Pass - This pass performs machine code if conversion.
FunctionPass *createIfConverterPass();
@ -191,6 +191,10 @@ namespace llvm {
/// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.
FunctionPass *createSjLjEHPass(const TargetLowering *tli);
/// createMaxStackAlignmentCalculatorPass() - Determine the maximum required
/// alignment for a function.
FunctionPass* createMaxStackAlignmentCalculatorPass();
} // End llvm namespace
#endif

View File

@ -110,6 +110,46 @@ class SelectionDAG {
/// SelectionDAG.
BumpPtrAllocator Allocator;
/// NodeOrdering - Assigns a "line number" value to each SDNode that
/// corresponds to the "line number" of the original LLVM instruction. This
/// used for turning off scheduling, because we'll forgo the normal scheduling
/// algorithm and output the instructions according to this ordering.
class NodeOrdering {
/// LineNo - The line of the instruction the node corresponds to. A value of
/// `0' means it's not assigned.
unsigned LineNo;
std::map<const SDNode*, unsigned> Order;
void operator=(const NodeOrdering&); // Do not implement.
NodeOrdering(const NodeOrdering&); // Do not implement.
public:
NodeOrdering() : LineNo(0) {}
void add(const SDNode *Node) {
assert(LineNo && "Invalid line number!");
Order[Node] = LineNo;
}
void remove(const SDNode *Node) {
std::map<const SDNode*, unsigned>::iterator Itr = Order.find(Node);
if (Itr != Order.end())
Order.erase(Itr);
}
void clear() {
Order.clear();
LineNo = 1;
}
unsigned getLineNo(const SDNode *Node) {
unsigned LN = Order[Node];
assert(LN && "Node isn't in ordering map!");
return LN;
}
void newInst() {
++LineNo;
}
void dump() const;
} *Ordering;
/// VerifyNode - Sanity check the given node. Aborts if it is invalid.
void VerifyNode(SDNode *N);
@ -120,6 +160,9 @@ class SelectionDAG {
DenseSet<SDNode *> &visited,
int level, bool &printed);
void operator=(const SelectionDAG&); // Do not implement.
SelectionDAG(const SelectionDAG&); // Do not implement.
public:
SelectionDAG(TargetLowering &tli, FunctionLoweringInfo &fli);
~SelectionDAG();
@ -199,6 +242,13 @@ class SelectionDAG {
return Root = N;
}
/// NewInst - Tell the ordering object that we're processing a new
/// instruction.
void NewInst() {
if (Ordering)
Ordering->newInst();
}
/// Combine - This iterates over the nodes in the SelectionDAG, folding
/// certain types of nodes together, or eliminating superfluous nodes. The
/// Level argument controls whether Combine is allowed to produce nodes and
@ -220,7 +270,7 @@ class SelectionDAG {
///
/// Note that this is an involved process that may invalidate pointers into
/// the graph.
void Legalize(bool TypesNeedLegalizing, CodeGenOpt::Level OptLevel);
void Legalize(CodeGenOpt::Level OptLevel);
/// LegalizeVectors - This transforms the SelectionDAG into a SelectionDAG
/// that only uses vector math operations supported by the target. This is
@ -890,6 +940,16 @@ class SelectionDAG {
/// vector op and fill the end of the resulting vector with UNDEFS.
SDValue UnrollVectorOp(SDNode *N, unsigned ResNE = 0);
/// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a
/// location that is 'Dist' units away from the location that the 'Base' load
/// is loading from.
bool isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base,
unsigned Bytes, int Dist) const;
/// InferPtrAlignment - Infer alignment of a load / store address. Return 0 if
/// it cannot be inferred.
unsigned InferPtrAlignment(SDValue Ptr) const;
private:
bool RemoveNodeFromCSEMaps(SDNode *N);
void AddModifiedNodeToCSEMaps(SDNode *N, DAGUpdateListener *UpdateListener);

View File

@ -113,7 +113,6 @@ class SelectionDAGISel : public MachineFunctionPass {
// Calls to these functions are generated by tblgen.
SDNode *Select_INLINEASM(SDValue N);
SDNode *Select_UNDEF(const SDValue &N);
SDNode *Select_DBG_LABEL(const SDValue &N);
SDNode *Select_EH_LABEL(const SDValue &N);
void CannotYetSelect(SDValue N);
void CannotYetSelectIntrinsic(SDValue N);

View File

@ -891,8 +891,9 @@ template<> struct DenseMapInfo<SDValue> {
static bool isEqual(const SDValue &LHS, const SDValue &RHS) {
return LHS == RHS;
}
static bool isPod() { return true; }
};
template <> struct isPodLike<SDValue> { static const bool value = true; };
/// simplify_type specializations - Allow casting operators to work directly on
/// SDValues as if they were SDNode*'s.
@ -1095,7 +1096,7 @@ class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
/// hasOneUse - Return true if there is exactly one use of this node.
///
bool hasOneUse() const {
return !use_empty() && next(use_begin()) == use_end();
return !use_empty() && llvm::next(use_begin()) == use_end();
}
/// use_size - Return the number of uses of this node. This method takes
@ -2397,6 +2398,11 @@ class SDNodeIterator : public std::iterator<std::forward_iterator_tag,
SDNodeIterator operator++(int) { // Postincrement
SDNodeIterator tmp = *this; ++*this; return tmp;
}
size_t operator-(SDNodeIterator Other) const {
assert(Node == Other.Node &&
"Cannot compare iterators of two different nodes!");
return Operand - Other.Operand;
}
static SDNodeIterator begin(SDNode *N) { return SDNodeIterator(N, 0); }
static SDNodeIterator end (SDNode *N) {

View File

@ -343,8 +343,10 @@ namespace llvm {
static inline bool isEqual(const SlotIndex &LHS, const SlotIndex &RHS) {
return (LHS == RHS);
}
static inline bool isPod() { return false; }
};
template <> struct isPodLike<SlotIndex> { static const bool value = true; };
inline raw_ostream& operator<<(raw_ostream &os, SlotIndex li) {
li.print(os);

View File

@ -47,35 +47,36 @@ namespace llvm {
f80 = 9, // This is a 80 bit floating point value
f128 = 10, // This is a 128 bit floating point value
ppcf128 = 11, // This is a PPC 128-bit floating point value
Flag = 12, // This is a condition code or machine flag.
isVoid = 13, // This has no value
v2i8 = 12, // 2 x i8
v4i8 = 13, // 4 x i8
v8i8 = 14, // 8 x i8
v16i8 = 15, // 16 x i8
v32i8 = 16, // 32 x i8
v2i16 = 17, // 2 x i16
v4i16 = 18, // 4 x i16
v8i16 = 19, // 8 x i16
v16i16 = 20, // 16 x i16
v2i32 = 21, // 2 x i32
v4i32 = 22, // 4 x i32
v8i32 = 23, // 8 x i32
v1i64 = 24, // 1 x i64
v2i64 = 25, // 2 x i64
v4i64 = 26, // 4 x i64
v2i8 = 14, // 2 x i8
v4i8 = 15, // 4 x i8
v8i8 = 16, // 8 x i8
v16i8 = 17, // 16 x i8
v32i8 = 18, // 32 x i8
v2i16 = 19, // 2 x i16
v4i16 = 20, // 4 x i16
v8i16 = 21, // 8 x i16
v16i16 = 22, // 16 x i16
v2i32 = 23, // 2 x i32
v4i32 = 24, // 4 x i32
v8i32 = 25, // 8 x i32
v1i64 = 26, // 1 x i64
v2i64 = 27, // 2 x i64
v4i64 = 28, // 4 x i64
v2f32 = 29, // 2 x f32
v4f32 = 30, // 4 x f32
v8f32 = 31, // 8 x f32
v2f64 = 32, // 2 x f64
v4f64 = 33, // 4 x f64
v2f32 = 27, // 2 x f32
v4f32 = 28, // 4 x f32
v8f32 = 29, // 8 x f32
v2f64 = 30, // 2 x f64
v4f64 = 31, // 4 x f64
FIRST_VECTOR_VALUETYPE = v2i8,
LAST_VECTOR_VALUETYPE = v4f64,
Flag = 32, // This glues nodes together during pre-RA sched
isVoid = 33, // This has no value
LAST_VALUETYPE = 34, // This always remains at the end of the list.
// This is the current maximum for LAST_VALUETYPE.
@ -166,6 +167,12 @@ namespace llvm {
return *this;
}
}
/// getScalarType - If this is a vector type, return the element type,
/// otherwise return this.
MVT getScalarType() const {
return isVector() ? getVectorElementType() : *this;
}
MVT getVectorElementType() const {
switch (SimpleTy) {
@ -524,6 +531,12 @@ namespace llvm {
return V;
}
/// getScalarType - If this is a vector type, return the element type,
/// otherwise return this.
EVT getScalarType() const {
return isVector() ? getVectorElementType() : *this;
}
/// getVectorElementType - Given a vector type, return the type of
/// each element.
EVT getVectorElementType() const {

View File

@ -31,30 +31,31 @@ def f64 : ValueType<64 , 8>; // 64-bit floating point value
def f80 : ValueType<80 , 9>; // 80-bit floating point value
def f128 : ValueType<128, 10>; // 128-bit floating point value
def ppcf128: ValueType<128, 11>; // PPC 128-bit floating point value
def FlagVT : ValueType<0 , 12>; // Condition code or machine flag
def isVoid : ValueType<0 , 13>; // Produces no value
def v2i8 : ValueType<16 , 14>; // 2 x i8 vector value
def v4i8 : ValueType<32 , 15>; // 4 x i8 vector value
def v8i8 : ValueType<64 , 16>; // 8 x i8 vector value
def v16i8 : ValueType<128, 17>; // 16 x i8 vector value
def v32i8 : ValueType<256, 18>; // 32 x i8 vector value
def v2i16 : ValueType<32 , 19>; // 2 x i16 vector value
def v4i16 : ValueType<64 , 20>; // 4 x i16 vector value
def v8i16 : ValueType<128, 21>; // 8 x i16 vector value
def v16i16 : ValueType<256, 22>; // 16 x i16 vector value
def v2i32 : ValueType<64 , 23>; // 2 x i32 vector value
def v4i32 : ValueType<128, 24>; // 4 x i32 vector value
def v8i32 : ValueType<256, 25>; // 8 x i32 vector value
def v1i64 : ValueType<64 , 26>; // 1 x i64 vector value
def v2i64 : ValueType<128, 27>; // 2 x i64 vector value
def v4i64 : ValueType<256, 28>; // 4 x f64 vector value
def v2i8 : ValueType<16 , 12>; // 2 x i8 vector value
def v4i8 : ValueType<32 , 13>; // 4 x i8 vector value
def v8i8 : ValueType<64 , 14>; // 8 x i8 vector value
def v16i8 : ValueType<128, 15>; // 16 x i8 vector value
def v32i8 : ValueType<256, 16>; // 32 x i8 vector value
def v2i16 : ValueType<32 , 17>; // 2 x i16 vector value
def v4i16 : ValueType<64 , 18>; // 4 x i16 vector value
def v8i16 : ValueType<128, 19>; // 8 x i16 vector value
def v16i16 : ValueType<256, 20>; // 16 x i16 vector value
def v2i32 : ValueType<64 , 21>; // 2 x i32 vector value
def v4i32 : ValueType<128, 22>; // 4 x i32 vector value
def v8i32 : ValueType<256, 23>; // 8 x i32 vector value
def v1i64 : ValueType<64 , 24>; // 1 x i64 vector value
def v2i64 : ValueType<128, 25>; // 2 x i64 vector value
def v4i64 : ValueType<256, 26>; // 4 x f64 vector value
def v2f32 : ValueType<64, 29>; // 2 x f32 vector value
def v4f32 : ValueType<128, 30>; // 4 x f32 vector value
def v8f32 : ValueType<256, 31>; // 8 x f32 vector value
def v2f64 : ValueType<128, 32>; // 2 x f64 vector value
def v4f64 : ValueType<256, 33>; // 4 x f64 vector value
def v2f32 : ValueType<64, 27>; // 2 x f32 vector value
def v4f32 : ValueType<128, 28>; // 4 x f32 vector value
def v8f32 : ValueType<256, 29>; // 8 x f32 vector value
def v2f64 : ValueType<128, 30>; // 2 x f64 vector value
def v4f64 : ValueType<256, 31>; // 4 x f64 vector value
def FlagVT : ValueType<0 , 32>; // Pre-RA sched glue
def isVoid : ValueType<0 , 33>; // Produces no value
def MetadataVT: ValueType<0, 250>; // Metadata

View File

@ -42,9 +42,10 @@ def hidden;
def init;
def multi_val;
def one_or_more;
def optional;
def really_hidden;
def required;
def zero_or_one;
def comma_separated;
// The 'case' construct.
def case;
@ -77,6 +78,8 @@ def any_empty;
def append_cmd;
def forward;
def forward_as;
def forward_value;
def forward_transformed_value;
def stop_compilation;
def unpack_values;
def warning;

View File

@ -70,6 +70,7 @@ namespace llvm {
case Intrinsic::dbg_region_start:
case Intrinsic::dbg_region_end:
case Intrinsic::dbg_declare:
case Intrinsic::dbg_value:
return true;
default: return false;
}
@ -171,6 +172,25 @@ namespace llvm {
}
};
/// DbgValueInst - This represents the llvm.dbg.value instruction.
///
struct DbgValueInst : public DbgInfoIntrinsic {
Value *getValue() const {
return cast<MDNode>(getOperand(1))->getElement(0);
}
Value *getOffset() const { return getOperand(2); }
MDNode *getVariable() const { return cast<MDNode>(getOperand(3)); }
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const DbgValueInst *) { return true; }
static inline bool classof(const IntrinsicInst *I) {
return I->getIntrinsicID() == Intrinsic::dbg_value;
}
static inline bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
/// MemIntrinsic - This is the common base class for memset/memcpy/memmove.
///
struct MemIntrinsic : public IntrinsicInst {

View File

@ -290,6 +290,9 @@ let Properties = [IntrNoMem] in {
def int_dbg_func_start : Intrinsic<[llvm_void_ty], [llvm_metadata_ty]>;
def int_dbg_declare : Intrinsic<[llvm_void_ty],
[llvm_descriptor_ty, llvm_metadata_ty]>;
def int_dbg_value : Intrinsic<[llvm_void_ty],
[llvm_metadata_ty, llvm_i64_ty,
llvm_metadata_ty]>;
}
//===------------------ Exception Handling Intrinsics----------------------===//

View File

@ -35,6 +35,7 @@
#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/SlowOperationInformer.h"
#include <cstdlib>
namespace {
struct ForceVMCoreLinking {

View File

@ -111,12 +111,10 @@ class Pass {
virtual void assignPassManager(PMStack &,
PassManagerType = PMT_Unknown) {}
/// Check if available pass managers are suitable for this pass or not.
virtual void preparePassManager(PMStack &) {}
virtual void preparePassManager(PMStack &);
/// Return what kind of Pass Manager can manage this pass.
virtual PassManagerType getPotentialPassManagerType() const {
return PMT_Unknown;
}
virtual PassManagerType getPotentialPassManagerType() const;
// Access AnalysisResolver
inline void setResolver(AnalysisResolver *AR) {
@ -132,9 +130,7 @@ class Pass {
/// particular analysis result to this function, it can then use the
/// getAnalysis<AnalysisType>() function, below.
///
virtual void getAnalysisUsage(AnalysisUsage &) const {
// By default, no analysis results are used, all are invalidated.
}
virtual void getAnalysisUsage(AnalysisUsage &) const;
/// releaseMemory() - This member can be implemented by a pass if it wants to
/// be able to release its memory when it is no longer needed. The default
@ -147,11 +143,11 @@ class Pass {
/// Optionally implement this function to release pass memory when it is no
/// longer used.
///
virtual void releaseMemory() {}
virtual void releaseMemory();
/// verifyAnalysis() - This member can be implemented by a analysis pass to
/// check state of analysis information.
virtual void verifyAnalysis() const {}
virtual void verifyAnalysis() const;
// dumpPassStructure - Implement the -debug-passes=PassStructure option
virtual void dumpPassStructure(unsigned Offset = 0);
@ -221,9 +217,7 @@ class ModulePass : public Pass {
PassManagerType T = PMT_ModulePassManager);
/// Return what kind of Pass Manager can manage this pass.
virtual PassManagerType getPotentialPassManagerType() const {
return PMT_ModulePassManager;
}
virtual PassManagerType getPotentialPassManagerType() const;
explicit ModulePass(intptr_t pid) : Pass(pid) {}
explicit ModulePass(const void *pid) : Pass(pid) {}
@ -245,7 +239,7 @@ class ImmutablePass : public ModulePass {
/// and if it does, the overloaded version of initializePass may get access to
/// these passes with getAnalysis<>.
///
virtual void initializePass() {}
virtual void initializePass();
/// ImmutablePasses are never run.
///
@ -276,7 +270,7 @@ class FunctionPass : public Pass {
/// doInitialization - Virtual method overridden by subclasses to do
/// any necessary per-module initialization.
///
virtual bool doInitialization(Module &) { return false; }
virtual bool doInitialization(Module &);
/// runOnFunction - Virtual method overriden by subclasses to do the
/// per-function processing of the pass.
@ -286,7 +280,7 @@ class FunctionPass : public Pass {
/// doFinalization - Virtual method overriden by subclasses to do any post
/// processing needed after all passes have run.
///
virtual bool doFinalization(Module &) { return false; }
virtual bool doFinalization(Module &);
/// runOnModule - On a module, we run this pass by initializing,
/// ronOnFunction'ing once for every function in the module, then by
@ -303,9 +297,7 @@ class FunctionPass : public Pass {
PassManagerType T = PMT_FunctionPassManager);
/// Return what kind of Pass Manager can manage this pass.
virtual PassManagerType getPotentialPassManagerType() const {
return PMT_FunctionPassManager;
}
virtual PassManagerType getPotentialPassManagerType() const;
};
@ -328,12 +320,12 @@ class BasicBlockPass : public Pass {
/// doInitialization - Virtual method overridden by subclasses to do
/// any necessary per-module initialization.
///
virtual bool doInitialization(Module &) { return false; }
virtual bool doInitialization(Module &);
/// doInitialization - Virtual method overridden by BasicBlockPass subclasses
/// to do any necessary per-function initialization.
///
virtual bool doInitialization(Function &) { return false; }
virtual bool doInitialization(Function &);
/// runOnBasicBlock - Virtual method overriden by subclasses to do the
/// per-basicblock processing of the pass.
@ -343,12 +335,12 @@ class BasicBlockPass : public Pass {
/// doFinalization - Virtual method overriden by BasicBlockPass subclasses to
/// do any post processing needed after all passes have run.
///
virtual bool doFinalization(Function &) { return false; }
virtual bool doFinalization(Function &);
/// doFinalization - Virtual method overriden by subclasses to do any post
/// processing needed after all passes have run.
///
virtual bool doFinalization(Module &) { return false; }
virtual bool doFinalization(Module &);
// To run this pass on a function, we simply call runOnBasicBlock once for
@ -360,9 +352,7 @@ class BasicBlockPass : public Pass {
PassManagerType T = PMT_BasicBlockPassManager);
/// Return what kind of Pass Manager can manage this pass.
virtual PassManagerType getPotentialPassManagerType() const {
return PMT_BasicBlockPassManager;
}
virtual PassManagerType getPotentialPassManagerType() const;
};
/// If the user specifies the -time-passes argument on an LLVM tool command line

View File

@ -986,7 +986,7 @@ template<class DataType>
class list_storage<DataType, bool> : public std::vector<DataType> {
public:
template<class T>
void addValue(const T &V) { push_back(V); }
void addValue(const T &V) { std::vector<DataType>::push_back(V); }
};
@ -1011,7 +1011,7 @@ class list : public Option, public list_storage<DataType, Storage> {
typename ParserClass::parser_data_type();
if (Parser.parse(*this, ArgName, Arg, Val))
return true; // Parse Error!
addValue(Val);
list_storage<DataType, Storage>::addValue(Val);
setPosition(pos);
Positions.push_back(pos);
return false;

View File

@ -70,6 +70,16 @@
#define DISABLE_INLINE
#endif
// ALWAYS_INLINE - On compilers where we have a directive to do so, mark a
// method "always inline" because it is performance sensitive.
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
#define ALWAYS_INLINE __attribute__((always_inline))
#else
// TODO: No idea how to do this with MSVC.
#define ALWAYS_INLINE
#endif
#ifdef __GNUC__
#define NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)

View File

@ -63,7 +63,8 @@ void SetCurrentDebugType(const char *Type);
/// This will emit the debug information if -debug is present, and -debug-only
/// is not specified, or is specified as "bitset".
#define DEBUG_WITH_TYPE(TYPE, X) \
do { if (DebugFlag && isCurrentDebugType(TYPE)) { X; } } while (0)
do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType(TYPE)) { X; } \
} while (0)
#else
#define isCurrentDebugType(X) (false)

View File

@ -66,7 +66,7 @@ namespace llvm {
};
// Specialize DenseMapInfo for DebugLocTuple.
template<> struct DenseMapInfo<DebugLocTuple> {
template<> struct DenseMapInfo<DebugLocTuple> {
static inline DebugLocTuple getEmptyKey() {
return DebugLocTuple(0, 0, ~0U, ~0U);
}
@ -85,9 +85,9 @@ namespace llvm {
LHS.Line == RHS.Line &&
LHS.Col == RHS.Col;
}
static bool isPod() { return true; }
};
template <> struct isPodLike<DebugLocTuple> {static const bool value = true;};
/// DebugLocTracker - This class tracks debug location information.
///

View File

@ -79,9 +79,10 @@ namespace llvm {
/// Use this instead of assert(0), so that the compiler knows this path
/// is not reachable even for NDEBUG builds.
#ifndef NDEBUG
#define llvm_unreachable(msg) llvm_unreachable_internal(msg, __FILE__, __LINE__)
#define llvm_unreachable(msg) \
::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__)
#else
#define llvm_unreachable(msg) llvm_unreachable_internal()
#define llvm_unreachable(msg) ::llvm::llvm_unreachable_internal()
#endif
#endif

View File

@ -84,7 +84,7 @@ namespace llvm {
inline gep_type_iterator gep_type_begin(const User *GEP) {
return gep_type_iterator::begin(GEP->getOperand(0)->getType(),
GEP->op_begin()+1);
GEP->op_begin()+1);
}
inline gep_type_iterator gep_type_end(const User *GEP) {
return gep_type_iterator::end(GEP->op_end());

View File

@ -269,6 +269,27 @@ class IRBuilder : public Inserter {
return Insert(IndirectBrInst::Create(Addr, NumDests));
}
InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
BasicBlock *UnwindDest, const Twine &Name = "") {
Value *Args[] = { 0 };
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args,
Args), Name);
}
InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
BasicBlock *UnwindDest, Value *Arg1,
const Twine &Name = "") {
Value *Args[] = { Arg1 };
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args,
Args+1), Name);
}
InvokeInst *CreateInvoke3(Value *Callee, BasicBlock *NormalDest,
BasicBlock *UnwindDest, Value *Arg1,
Value *Arg2, Value *Arg3,
const Twine &Name = "") {
Value *Args[] = { Arg1, Arg2, Arg3 };
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args,
Args+3), Name);
}
/// CreateInvoke - Create an invoke instruction.
template<typename InputIterator>
InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
@ -386,18 +407,39 @@ class IRBuilder : public Inserter {
return Folder.CreateShl(LC, RC);
return Insert(BinaryOperator::CreateShl(LHS, RHS), Name);
}
Value *CreateShl(Value *LHS, uint64_t RHS, const Twine &Name = "") {
Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
if (Constant *LC = dyn_cast<Constant>(LHS))
return Folder.CreateShl(LC, RHSC);
return Insert(BinaryOperator::CreateShl(LHS, RHSC), Name);
}
Value *CreateLShr(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateLShr(LC, RC);
return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name);
}
Value *CreateLShr(Value *LHS, uint64_t RHS, const Twine &Name = "") {
Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
if (Constant *LC = dyn_cast<Constant>(LHS))
return Folder.CreateLShr(LC, RHSC);
return Insert(BinaryOperator::CreateLShr(LHS, RHSC), Name);
}
Value *CreateAShr(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateAShr(LC, RC);
return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name);
}
Value *CreateAShr(Value *LHS, uint64_t RHS, const Twine &Name = "") {
Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
if (Constant *LC = dyn_cast<Constant>(LHS))
return Folder.CreateSShr(LC, RHSC);
return Insert(BinaryOperator::CreateAShr(LHS, RHSC), Name);
}
Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *RC = dyn_cast<Constant>(RHS)) {
if (isa<ConstantInt>(RC) && cast<ConstantInt>(RC)->isAllOnesValue())

View File

@ -254,14 +254,17 @@ struct DenseMapInfo<AssertingVH<T> > {
static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) {
return LHS == RHS;
}
static bool isPod() {
#ifdef NDEBUG
return true;
#else
return false;
#endif
}
};
template <typename T>
struct isPodLike<AssertingVH<T> > {
#ifdef NDEBUG
static const bool value = true;
#else
static const bool value = false;
#endif
};
/// TrackingVH - This is a value handle that tracks a Value (or Value subclass),
/// even across RAUW operations.

View File

@ -186,14 +186,12 @@ class raw_ostream {
// Inline fast path, particulary for constant strings where a sufficiently
// smart compiler will simplify strlen.
this->operator<<(StringRef(Str));
return *this;
return this->operator<<(StringRef(Str));
}
raw_ostream &operator<<(const std::string &Str) {
// Avoid the fast path, it would only increase code size for a marginal win.
write(Str.data(), Str.length());
return *this;
return write(Str.data(), Str.length());
}
raw_ostream &operator<<(unsigned long N);
@ -202,13 +200,11 @@ class raw_ostream {
raw_ostream &operator<<(long long N);
raw_ostream &operator<<(const void *P);
raw_ostream &operator<<(unsigned int N) {
this->operator<<(static_cast<unsigned long>(N));
return *this;
return this->operator<<(static_cast<unsigned long>(N));
}
raw_ostream &operator<<(int N) {
this->operator<<(static_cast<long>(N));
return *this;
return this->operator<<(static_cast<long>(N));
}
raw_ostream &operator<<(double N);

View File

@ -17,13 +17,15 @@
#ifndef LLVM_SUPPORT_TYPE_TRAITS_H
#define LLVM_SUPPORT_TYPE_TRAITS_H
#include <utility>
// This is actually the conforming implementation which works with abstract
// classes. However, enough compilers have trouble with it that most will use
// the one in boost/type_traits/object_traits.hpp. This implementation actually
// works with VC7.0, but other interactions seem to fail when we use it.
namespace llvm {
namespace dont_use
{
// These two functions should never be used. They are helpers to
@ -48,6 +50,23 @@ struct is_class
public:
enum { value = sizeof(char) == sizeof(dont_use::is_class_helper<T>(0)) };
};
/// isPodLike - This is a type trait that is used to determine whether a given
/// type can be copied around with memcpy instead of running ctors etc.
template <typename T>
struct isPodLike {
// If we don't know anything else, we can (at least) assume that all non-class
// types are PODs.
static const bool value = !is_class<T>::value;
};
// std::pair's are pod-like if their elements are.
template<typename T, typename U>
struct isPodLike<std::pair<T, U> > {
static const bool value = isPodLike<T>::value & isPodLike<U>::value;
};
/// \brief Metafunction that determines whether the two given types are
/// equivalent.

View File

@ -20,7 +20,11 @@ namespace llvm {
namespace sys {
void MemoryFence();
#ifdef _MSC_VER
typedef long cas_flag;
#else
typedef uint32_t cas_flag;
#endif
cas_flag CompareAndSwap(volatile cas_flag* ptr,
cas_flag new_value,
cas_flag old_value);

View File

@ -118,14 +118,33 @@ typedef signed int ssize_t;
#define INT32_MAX 2147483647
#define INT32_MIN -2147483648
#define UINT32_MAX 4294967295U
#define INT8_C(C) C
#define UINT8_C(C) C
#define INT16_C(C) C
#define UINT16_C(C) C
#define INT32_C(C) C
#define UINT32_C(C) C ## U
#define INT64_C(C) ((int64_t) C ## LL)
#define UINT64_C(C) ((uint64_t) C ## ULL)
/* Certain compatibility updates to VC++ introduce the `cstdint'
* header, which defines the INT*_C macros. On default installs they
* are absent. */
#ifndef INT8_C
# define INT8_C(C) C
#endif
#ifndef UINT8_C
# define UINT8_C(C) C
#endif
#ifndef INT16_C
# define INT16_C(C) C
#endif
#ifndef UINT16_C
# define UINT16_C(C) C
#endif
#ifndef INT32_C
# define INT32_C(C) C
#endif
#ifndef UINT32_C
# define UINT32_C(C) C ## U
#endif
#ifndef INT64_C
# define INT64_C(C) ((int64_t) C ## LL)
#endif
#ifndef UINT64_C
# define UINT64_C(C) ((uint64_t) C ## ULL)
#endif
#endif /* _MSC_VER */
/* Set defaults for constants which we cannot find. */

View File

@ -36,8 +36,6 @@
#include <math.h>
#endif
#ifndef _MSC_VER
/* Note that this header's correct operation depends on __STDC_LIMIT_MACROS
being defined. We would define it here, but in order to prevent Bad Things
happening when system headers or C++ STL headers include stdint.h before we
@ -89,40 +87,6 @@ typedef u_int64_t uint64_t;
#define UINT32_MAX 4294967295U
#endif
#else /* _MSC_VER */
/* Visual C++ doesn't provide standard integer headers, but it does provide
built-in data types. */
#include <stdlib.h>
#include <stddef.h>
#include <sys/types.h>
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
typedef signed int int32_t;
typedef unsigned int uint32_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed int ssize_t;
#define INT8_MAX 127
#define INT8_MIN -128
#define UINT8_MAX 255
#define INT16_MAX 32767
#define INT16_MIN -32768
#define UINT16_MAX 65535
#define INT32_MAX 2147483647
#define INT32_MIN -2147483648
#define UINT32_MAX 4294967295U
#define INT8_C(C) C
#define UINT8_C(C) C
#define INT16_C(C) C
#define UINT16_C(C) C
#define INT32_C(C) C
#define UINT32_C(C) C ## U
#define INT64_C(C) ((int64_t) C ## LL)
#define UINT64_C(C) ((uint64_t) C ## ULL)
#endif /* _MSC_VER */
/* Set defaults for constants which we cannot find. */
#if !defined(INT64_MAX)
# define INT64_MAX 9223372036854775807LL

View File

@ -30,7 +30,6 @@ class Type;
class IntegerType;
class StructType;
class StructLayout;
class StructLayoutMap;
class GlobalVariable;
class LLVMContext;
@ -60,8 +59,6 @@ struct TargetAlignElem {
unsigned char pref_align, uint32_t bit_width);
/// Equality predicate
bool operator==(const TargetAlignElem &rhs) const;
/// output stream operator
std::ostream &dump(std::ostream &os) const;
};
class TargetData : public ImmutablePass {
@ -86,7 +83,7 @@ class TargetData : public ImmutablePass {
static const TargetAlignElem InvalidAlignmentElem;
// The StructType -> StructLayout map.
mutable StructLayoutMap *LayoutMap;
mutable void *LayoutMap;
//! Set/initialize target alignments
void setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
@ -153,7 +150,7 @@ class TargetData : public ImmutablePass {
/// The width is specified in bits.
///
bool isLegalInteger(unsigned Width) const {
for (unsigned i = 0, e = LegalIntWidths.size(); i != e; ++i)
for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i)
if (LegalIntWidths[i] == Width)
return true;
return false;

View File

@ -26,6 +26,7 @@ class LiveVariables;
class CalleeSavedInfo;
class SDNode;
class SelectionDAG;
class MachineMemOperand;
template<class T> class SmallVectorImpl;
@ -182,11 +183,13 @@ class TargetInstrInfo {
/// hasLoadFromStackSlot - If the specified machine instruction has
/// a load from a stack slot, return true along with the FrameIndex
/// of the loaded stack slot. If not, return false. Unlike
/// of the loaded stack slot and the machine mem operand containing
/// the reference. If not, return false. Unlike
/// isLoadFromStackSlot, this returns true for any instructions that
/// loads from the stack. This is just a hint, as some cases may be
/// missed.
virtual bool hasLoadFromStackSlot(const MachineInstr *MI,
const MachineMemOperand *&MMO,
int &FrameIndex) const {
return 0;
}
@ -205,17 +208,18 @@ class TargetInstrInfo {
/// stack locations as well. This uses a heuristic so it isn't
/// reliable for correctness.
virtual unsigned isStoreToStackSlotPostFE(const MachineInstr *MI,
int &FrameIndex) const {
int &FrameIndex) const {
return 0;
}
/// hasStoreToStackSlot - If the specified machine instruction has a
/// store to a stack slot, return true along with the FrameIndex of
/// the loaded stack slot. If not, return false. Unlike
/// isStoreToStackSlot, this returns true for any instructions that
/// loads from the stack. This is just a hint, as some cases may be
/// missed.
/// the loaded stack slot and the machine mem operand containing the
/// reference. If not, return false. Unlike isStoreToStackSlot,
/// this returns true for any instructions that loads from the
/// stack. This is just a hint, as some cases may be missed.
virtual bool hasStoreToStackSlot(const MachineInstr *MI,
const MachineMemOperand *&MMO,
int &FrameIndex) const {
return 0;
}
@ -282,11 +286,10 @@ class TargetInstrInfo {
/// just return false, leaving TBB/FBB null.
/// 2. If this block ends with only an unconditional branch, it sets TBB to be
/// the destination block.
/// 3. If this block ends with an conditional branch and it falls through to
/// a successor block, it sets TBB to be the branch destination block and
/// a list of operands that evaluate the condition. These
/// operands can be passed to other TargetInstrInfo methods to create new
/// branches.
/// 3. If this block ends with a conditional branch and it falls through to a
/// successor block, it sets TBB to be the branch destination block and a
/// list of operands that evaluate the condition. These operands can be
/// passed to other TargetInstrInfo methods to create new branches.
/// 4. If this block ends with a conditional branch followed by an
/// unconditional branch, it returns the 'true' destination in TBB, the
/// 'false' destination in FBB, and a list of operands that evaluate the
@ -461,14 +464,6 @@ class TargetInstrInfo {
return 0;
}
/// BlockHasNoFallThrough - Return true if the specified block does not
/// fall-through into its successor block. This is primarily used when a
/// branch is unanalyzable. It is useful for things like unconditional
/// indirect branches (jump tables).
virtual bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const {
return false;
}
/// ReverseBranchCondition - Reverses the branch condition of the specified
/// condition list, returning false on success and true if it cannot be
/// reversed.

View File

@ -857,12 +857,6 @@ class TargetLowering {
virtual bool
isGAPlusOffset(SDNode *N, GlobalValue* &GA, int64_t &Offset) const;
/// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a
/// location that is 'Dist' units away from the location that the 'Base' load
/// is loading from.
bool isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes,
int Dist, const MachineFrameInfo *MFI) const;
/// PerformDAGCombine - This method will be invoked for all target nodes and
/// for any target-independent nodes that the target has registered with
/// invoke it for.
@ -978,7 +972,7 @@ class TargetLowering {
/// not work with the with specified type and indicate what to do about it.
void setLoadExtAction(unsigned ExtType, MVT VT,
LegalizeAction Action) {
assert((unsigned)VT.SimpleTy < MVT::LAST_VALUETYPE &&
assert((unsigned)VT.SimpleTy*2 < 63 &&
ExtType < array_lengthof(LoadExtActions) &&
"Table isn't big enough!");
LoadExtActions[ExtType] &= ~(uint64_t(3UL) << VT.SimpleTy*2);
@ -990,7 +984,7 @@ class TargetLowering {
void setTruncStoreAction(MVT ValVT, MVT MemVT,
LegalizeAction Action) {
assert((unsigned)ValVT.SimpleTy < array_lengthof(TruncStoreActions) &&
(unsigned)MemVT.SimpleTy < MVT::LAST_VALUETYPE &&
(unsigned)MemVT.SimpleTy*2 < 63 &&
"Table isn't big enough!");
TruncStoreActions[ValVT.SimpleTy] &= ~(uint64_t(3UL) << MemVT.SimpleTy*2);
TruncStoreActions[ValVT.SimpleTy] |= (uint64_t)Action << MemVT.SimpleTy*2;

View File

@ -299,7 +299,7 @@ class TargetRegisterInfo {
/// FirstVirtualRegister - This is the first register number that is
/// considered to be a 'virtual' register, which is part of the SSA
/// namespace. This must be the same for all targets, which means that each
/// target is limited to 1024 registers.
/// target is limited to this fixed number of registers.
FirstVirtualRegister = 1024
};

View File

@ -27,6 +27,7 @@ add_llvm_library(LLVMAnalysis
LoopPass.cpp
MemoryBuiltins.cpp
MemoryDependenceAnalysis.cpp
PHITransAddr.cpp
PointerTracking.cpp
PostDominators.cpp
ProfileEstimatorPass.cpp

View File

@ -25,6 +25,16 @@
#include "llvm/Support/CallSite.h"
using namespace llvm;
/// As its comment mentions, PointerMayBeCaptured can be expensive.
/// However, it's not easy for BasicAA to cache the result, because
/// it's an ImmutablePass. To work around this, bound queries at a
/// fixed number of uses.
///
/// TODO: Write a new FunctionPass AliasAnalysis so that it can keep
/// a cache. Then we can move the code from BasicAliasAnalysis into
/// that path, and remove this threshold.
static int const Threshold = 20;
/// PointerMayBeCaptured - Return true if this pointer value may be captured
/// by the enclosing function (which is required to exist). This routine can
/// be expensive, so consider caching the results. The boolean ReturnCaptures
@ -35,11 +45,17 @@ using namespace llvm;
bool llvm::PointerMayBeCaptured(const Value *V,
bool ReturnCaptures, bool StoreCaptures) {
assert(isa<PointerType>(V->getType()) && "Capture is for pointers only!");
SmallVector<Use*, 16> Worklist;
SmallSet<Use*, 16> Visited;
SmallVector<Use*, Threshold> Worklist;
SmallSet<Use*, Threshold> Visited;
int Count = 0;
for (Value::use_const_iterator UI = V->use_begin(), UE = V->use_end();
UI != UE; ++UI) {
// If there are lots of uses, conservatively say that the value
// is captured to avoid taking too much compile time.
if (Count++ >= Threshold)
return true;
Use *U = &UI.getUse();
Visited.insert(U);
Worklist.push_back(U);

View File

@ -432,7 +432,7 @@ Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C,
// Instead of loading constant c string, use corresponding integer value
// directly if string length is small enough.
std::string Str;
if (TD && GetConstantStringInfo(CE->getOperand(0), Str) && !Str.empty()) {
if (TD && GetConstantStringInfo(CE, Str) && !Str.empty()) {
unsigned StrLen = Str.length();
const Type *Ty = cast<PointerType>(CE->getType())->getElementType();
unsigned NumBits = Ty->getPrimitiveSizeInBits();
@ -569,9 +569,16 @@ static Constant *SymbolicallyEvaluateGEP(Constant *const *Ops, unsigned NumOps,
SmallVector<Constant*, 32> NewIdxs;
do {
if (const SequentialType *ATy = dyn_cast<SequentialType>(Ty)) {
// The only pointer indexing we'll do is on the first index of the GEP.
if (isa<PointerType>(ATy) && !NewIdxs.empty())
break;
if (isa<PointerType>(ATy)) {
// The only pointer indexing we'll do is on the first index of the GEP.
if (!NewIdxs.empty())
break;
// Only handle pointers to sized types, not pointers to functions.
if (!ATy->getElementType()->isSized())
return 0;
}
// Determine which element of the array the offset points into.
APInt ElemSize(BitWidth, TD->getTypeAllocSize(ATy->getElementType()));
if (ElemSize == 0)

View File

@ -866,7 +866,9 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
DICompileUnit CompileUnit,
unsigned LineNo, DIType Type,
bool isLocalToUnit,
bool isDefinition) {
bool isDefinition,
unsigned VK, unsigned VIndex,
DIType ContainingType) {
Value *Elts[] = {
GetTagConstant(dwarf::DW_TAG_subprogram),
@ -879,9 +881,38 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
Type.getNode(),
ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit),
ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition)
ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition),
ConstantInt::get(Type::getInt32Ty(VMContext), (unsigned)VK),
ConstantInt::get(Type::getInt32Ty(VMContext), VIndex),
ContainingType.getNode()
};
return DISubprogram(MDNode::get(VMContext, &Elts[0], 11));
return DISubprogram(MDNode::get(VMContext, &Elts[0], 14));
}
/// CreateSubprogramDefinition - Create new subprogram descriptor for the
/// given declaration.
DISubprogram DIFactory::CreateSubprogramDefinition(DISubprogram &SPDeclaration) {
if (SPDeclaration.isDefinition())
return DISubprogram(SPDeclaration.getNode());
MDNode *DeclNode = SPDeclaration.getNode();
Value *Elts[] = {
GetTagConstant(dwarf::DW_TAG_subprogram),
llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)),
DeclNode->getElement(2), // Context
DeclNode->getElement(3), // Name
DeclNode->getElement(4), // DisplayName
DeclNode->getElement(5), // LinkageName
DeclNode->getElement(6), // CompileUnit
DeclNode->getElement(7), // LineNo
DeclNode->getElement(8), // Type
DeclNode->getElement(9), // isLocalToUnit
ConstantInt::get(Type::getInt1Ty(VMContext), true),
DeclNode->getElement(11), // Virtuality
DeclNode->getElement(12), // VIndex
DeclNode->getElement(13) // Containting Type
};
return DISubprogram(MDNode::get(VMContext, &Elts[0], 14));
}
/// CreateGlobalVariable - Create a new descriptor for the specified global.
@ -1019,6 +1050,37 @@ Instruction *DIFactory::InsertDeclare(Value *Storage, DIVariable D,
return CallInst::Create(DeclareFn, Args, Args+2, "", InsertAtEnd);
}
/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, Value *Offset,
DIVariable D,
Instruction *InsertBefore) {
assert(V && "no value passed to dbg.value");
assert(Offset->getType() == Type::getInt64Ty(V->getContext()) &&
"offset must be i64");
if (!ValueFn)
ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);
Value *Elts[] = { V };
Value *Args[] = { MDNode::get(V->getContext(), Elts, 1), Offset,
D.getNode() };
return CallInst::Create(ValueFn, Args, Args+3, "", InsertBefore);
}
/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, Value *Offset,
DIVariable D,
BasicBlock *InsertAtEnd) {
assert(V && "no value passed to dbg.value");
assert(Offset->getType() == Type::getInt64Ty(V->getContext()) &&
"offset must be i64");
if (!ValueFn)
ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);
Value *Elts[] = { V };
Value *Args[] = { MDNode::get(V->getContext(), Elts, 1), Offset,
D.getNode() };
return CallInst::Create(ValueFn, Args, Args+3, "", InsertAtEnd);
}
//===----------------------------------------------------------------------===//
// DebugInfoFinder implementations.

View File

@ -121,8 +121,6 @@ namespace {
return *LHS == *RHS;
}
static bool isPod() { return true; }
};
class Andersens : public ModulePass, public AliasAnalysis,

View File

@ -53,7 +53,7 @@ static bool containsAddRecFromDifferentLoop(const SCEV *S, Loop *L) {
if (newLoop == L)
return false;
// if newLoop is an outer loop of L, this is OK.
if (!LoopInfo::isNotAlreadyContainedIn(L, newLoop))
if (newLoop->contains(L->getHeader()))
return false;
}
return true;
@ -307,6 +307,7 @@ bool IVUsers::runOnLoop(Loop *l, LPPassManager &LPM) {
for (BasicBlock::iterator I = L->getHeader()->begin(); isa<PHINode>(I); ++I)
AddUsersIfInteresting(I);
Processed.clear();
return false;
}
@ -369,7 +370,7 @@ void IVUsers::dump() const {
void IVUsers::releaseMemory() {
IVUsesByStride.clear();
StrideOrder.clear();
Processed.clear();
IVUses.clear();
}
void IVStrideUse::deleted() {

View File

@ -316,12 +316,12 @@ bool Loop::hasDedicatedExits() const {
/// getUniqueExitBlocks - Return all unique successor blocks of this loop.
/// These are the blocks _outside of the current loop_ which are branched to.
/// This assumes that loop is in canonical form.
/// This assumes that loop exits are in canonical form.
///
void
Loop::getUniqueExitBlocks(SmallVectorImpl<BasicBlock *> &ExitBlocks) const {
assert(isLoopSimplifyForm() &&
"getUniqueExitBlocks assumes the loop is in canonical form!");
assert(hasDedicatedExits() &&
"getUniqueExitBlocks assumes the loop has canonical form exits!");
// Sort the blocks vector so that we can use binary search to do quick
// lookups.

View File

@ -23,6 +23,7 @@
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/PHITransAddr.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/PredIteratorCache.h"
@ -172,7 +173,7 @@ MemDepResult MemoryDependenceAnalysis::
getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad,
BasicBlock::iterator ScanIt, BasicBlock *BB) {
Value *invariantTag = 0;
Value *InvariantTag = 0;
// Walk backwards through the basic block, looking for dependencies.
while (ScanIt != BB->begin()) {
@ -180,34 +181,36 @@ getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad,
// If we're in an invariant region, no dependencies can be found before
// we pass an invariant-begin marker.
if (invariantTag == Inst) {
invariantTag = 0;
if (InvariantTag == Inst) {
InvariantTag = 0;
continue;
} else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
}
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
// Debug intrinsics don't cause dependences.
if (isa<DbgInfoIntrinsic>(Inst)) continue;
// If we pass an invariant-end marker, then we've just entered an
// invariant region and can start ignoring dependencies.
if (II->getIntrinsicID() == Intrinsic::invariant_end) {
uint64_t invariantSize = ~0ULL;
if (ConstantInt *CI = dyn_cast<ConstantInt>(II->getOperand(2)))
invariantSize = CI->getZExtValue();
AliasAnalysis::AliasResult R =
AA->alias(II->getOperand(3), invariantSize, MemPtr, MemSize);
// FIXME: This only considers queries directly on the invariant-tagged
// pointer, not on query pointers that are indexed off of them. It'd
// be nice to handle that at some point.
AliasAnalysis::AliasResult R =
AA->alias(II->getOperand(3), ~0U, MemPtr, ~0U);
if (R == AliasAnalysis::MustAlias) {
invariantTag = II->getOperand(1);
InvariantTag = II->getOperand(1);
continue;
}
// If we reach a lifetime begin or end marker, then the query ends here
// because the value is undefined.
} else if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
II->getIntrinsicID() == Intrinsic::lifetime_end) {
uint64_t invariantSize = ~0ULL;
if (ConstantInt *CI = dyn_cast<ConstantInt>(II->getOperand(1)))
invariantSize = CI->getZExtValue();
} else if (II->getIntrinsicID() == Intrinsic::lifetime_start) {
// FIXME: This only considers queries directly on the invariant-tagged
// pointer, not on query pointers that are indexed off of them. It'd
// be nice to handle that at some point.
AliasAnalysis::AliasResult R =
AA->alias(II->getOperand(2), invariantSize, MemPtr, MemSize);
AA->alias(II->getOperand(2), ~0U, MemPtr, ~0U);
if (R == AliasAnalysis::MustAlias)
return MemDepResult::getDef(II);
}
@ -215,10 +218,7 @@ getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad,
// If we're querying on a load and we're in an invariant region, we're done
// at this point. Nothing a load depends on can live in an invariant region.
if (isLoad && invariantTag) continue;
// Debug intrinsics don't cause dependences.
if (isa<DbgInfoIntrinsic>(Inst)) continue;
if (isLoad && InvariantTag) continue;
// Values depend on loads if the pointers are must aliased. This means that
// a load depends on another must aliased load from the same value.
@ -243,7 +243,7 @@ getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad,
if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
// There can't be stores to the value we care about inside an
// invariant region.
if (invariantTag) continue;
if (InvariantTag) continue;
// If alias analysis can tell that this store is guaranteed to not modify
// the query pointer, ignore it. Use getModRefInfo to handle cases where
@ -292,7 +292,7 @@ getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad,
case AliasAnalysis::Mod:
// If we're in an invariant region, we can ignore calls that ONLY
// modify the pointer.
if (invariantTag) continue;
if (InvariantTag) continue;
return MemDepResult::getClobber(Inst);
case AliasAnalysis::Ref:
// If the call is known to never store to the pointer, and if this is a
@ -374,21 +374,22 @@ MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *QueryInst) {
IntrinsicID = II->getIntrinsicID();
switch (IntrinsicID) {
case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end:
case Intrinsic::invariant_start:
MemPtr = QueryInst->getOperand(2);
MemSize = cast<ConstantInt>(QueryInst->getOperand(1))->getZExtValue();
break;
case Intrinsic::invariant_end:
MemPtr = QueryInst->getOperand(3);
MemSize = cast<ConstantInt>(QueryInst->getOperand(2))->getZExtValue();
break;
default:
CallSite QueryCS = CallSite::get(QueryInst);
bool isReadOnly = AA->onlyReadsMemory(QueryCS);
LocalCache = getCallSiteDependencyFrom(QueryCS, isReadOnly, ScanPos,
QueryParent);
case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end:
case Intrinsic::invariant_start:
MemPtr = QueryInst->getOperand(2);
MemSize = cast<ConstantInt>(QueryInst->getOperand(1))->getZExtValue();
break;
case Intrinsic::invariant_end:
MemPtr = QueryInst->getOperand(3);
MemSize = cast<ConstantInt>(QueryInst->getOperand(2))->getZExtValue();
break;
default:
CallSite QueryCS = CallSite::get(QueryInst);
bool isReadOnly = AA->onlyReadsMemory(QueryCS);
LocalCache = getCallSiteDependencyFrom(QueryCS, isReadOnly, ScanPos,
QueryParent);
break;
}
} else {
// Non-memory instruction.
@ -421,7 +422,7 @@ static void AssertSorted(MemoryDependenceAnalysis::NonLocalDepInfo &Cache,
if (Count == 0) return;
for (unsigned i = 1; i != unsigned(Count); ++i)
assert(Cache[i-1] <= Cache[i] && "Cache isn't sorted!");
assert(!(Cache[i] < Cache[i-1]) && "Cache isn't sorted!");
}
#endif
@ -462,8 +463,8 @@ MemoryDependenceAnalysis::getNonLocalCallDependency(CallSite QueryCS) {
// determine what is dirty, seeding our initial DirtyBlocks worklist.
for (NonLocalDepInfo::iterator I = Cache.begin(), E = Cache.end();
I != E; ++I)
if (I->second.isDirty())
DirtyBlocks.push_back(I->first);
if (I->getResult().isDirty())
DirtyBlocks.push_back(I->getBB());
// Sort the cache so that we can do fast binary search lookups below.
std::sort(Cache.begin(), Cache.end());
@ -501,27 +502,27 @@ MemoryDependenceAnalysis::getNonLocalCallDependency(CallSite QueryCS) {
DEBUG(AssertSorted(Cache, NumSortedEntries));
NonLocalDepInfo::iterator Entry =
std::upper_bound(Cache.begin(), Cache.begin()+NumSortedEntries,
std::make_pair(DirtyBB, MemDepResult()));
if (Entry != Cache.begin() && prior(Entry)->first == DirtyBB)
NonLocalDepEntry(DirtyBB));
if (Entry != Cache.begin() && prior(Entry)->getBB() == DirtyBB)
--Entry;
MemDepResult *ExistingResult = 0;
NonLocalDepEntry *ExistingResult = 0;
if (Entry != Cache.begin()+NumSortedEntries &&
Entry->first == DirtyBB) {
Entry->getBB() == DirtyBB) {
// If we already have an entry, and if it isn't already dirty, the block
// is done.
if (!Entry->second.isDirty())
if (!Entry->getResult().isDirty())
continue;
// Otherwise, remember this slot so we can update the value.
ExistingResult = &Entry->second;
ExistingResult = &*Entry;
}
// If the dirty entry has a pointer, start scanning from it so we don't have
// to rescan the entire block.
BasicBlock::iterator ScanPos = DirtyBB->end();
if (ExistingResult) {
if (Instruction *Inst = ExistingResult->getInst()) {
if (Instruction *Inst = ExistingResult->getResult().getInst()) {
ScanPos = Inst;
// We're removing QueryInst's use of Inst.
RemoveFromReverseMap(ReverseNonLocalDeps, Inst,
@ -545,9 +546,9 @@ MemoryDependenceAnalysis::getNonLocalCallDependency(CallSite QueryCS) {
// If we had a dirty entry for the block, update it. Otherwise, just add
// a new entry.
if (ExistingResult)
*ExistingResult = Dep;
ExistingResult->setResult(Dep, 0);
else
Cache.push_back(std::make_pair(DirtyBB, Dep));
Cache.push_back(NonLocalDepEntry(DirtyBB, Dep, 0));
// If the block has a dependency (i.e. it isn't completely transparent to
// the value), remember the association!
@ -587,17 +588,20 @@ getNonLocalPointerDependency(Value *Pointer, bool isLoad, BasicBlock *FromBB,
const Type *EltTy = cast<PointerType>(Pointer->getType())->getElementType();
uint64_t PointeeSize = AA->getTypeStoreSize(EltTy);
PHITransAddr Address(Pointer, TD);
// This is the set of blocks we've inspected, and the pointer we consider in
// each block. Because of critical edges, we currently bail out if querying
// a block with multiple different pointers. This can happen during PHI
// translation.
DenseMap<BasicBlock*, Value*> Visited;
if (!getNonLocalPointerDepFromBB(Pointer, PointeeSize, isLoad, FromBB,
if (!getNonLocalPointerDepFromBB(Address, PointeeSize, isLoad, FromBB,
Result, Visited, true))
return;
Result.clear();
Result.push_back(std::make_pair(FromBB,
MemDepResult::getClobber(FromBB->begin())));
Result.push_back(NonLocalDepEntry(FromBB,
MemDepResult::getClobber(FromBB->begin()),
Pointer));
}
/// GetNonLocalInfoForBlock - Compute the memdep value for BB with
@ -613,30 +617,30 @@ GetNonLocalInfoForBlock(Value *Pointer, uint64_t PointeeSize,
// the cache set. If so, find it.
NonLocalDepInfo::iterator Entry =
std::upper_bound(Cache->begin(), Cache->begin()+NumSortedEntries,
std::make_pair(BB, MemDepResult()));
if (Entry != Cache->begin() && prior(Entry)->first == BB)
NonLocalDepEntry(BB));
if (Entry != Cache->begin() && (Entry-1)->getBB() == BB)
--Entry;
MemDepResult *ExistingResult = 0;
if (Entry != Cache->begin()+NumSortedEntries && Entry->first == BB)
ExistingResult = &Entry->second;
NonLocalDepEntry *ExistingResult = 0;
if (Entry != Cache->begin()+NumSortedEntries && Entry->getBB() == BB)
ExistingResult = &*Entry;
// If we have a cached entry, and it is non-dirty, use it as the value for
// this dependency.
if (ExistingResult && !ExistingResult->isDirty()) {
if (ExistingResult && !ExistingResult->getResult().isDirty()) {
++NumCacheNonLocalPtr;
return *ExistingResult;
return ExistingResult->getResult();
}
// Otherwise, we have to scan for the value. If we have a dirty cache
// entry, start scanning from its position, otherwise we scan from the end
// of the block.
BasicBlock::iterator ScanPos = BB->end();
if (ExistingResult && ExistingResult->getInst()) {
assert(ExistingResult->getInst()->getParent() == BB &&
if (ExistingResult && ExistingResult->getResult().getInst()) {
assert(ExistingResult->getResult().getInst()->getParent() == BB &&
"Instruction invalidated?");
++NumCacheDirtyNonLocalPtr;
ScanPos = ExistingResult->getInst();
ScanPos = ExistingResult->getResult().getInst();
// Eliminating the dirty entry from 'Cache', so update the reverse info.
ValueIsLoadPair CacheKey(Pointer, isLoad);
@ -652,9 +656,9 @@ GetNonLocalInfoForBlock(Value *Pointer, uint64_t PointeeSize,
// If we had a dirty entry for the block, update it. Otherwise, just add
// a new entry.
if (ExistingResult)
*ExistingResult = Dep;
ExistingResult->setResult(Dep, Pointer);
else
Cache->push_back(std::make_pair(BB, Dep));
Cache->push_back(NonLocalDepEntry(BB, Dep, Pointer));
// If the block has a dependency (i.e. it isn't completely transparent to
// the value), remember the reverse association because we just added it
@ -683,7 +687,7 @@ SortNonLocalDepInfoCache(MemoryDependenceAnalysis::NonLocalDepInfo &Cache,
break;
case 2: {
// Two new entries, insert the last one into place.
MemoryDependenceAnalysis::NonLocalDepEntry Val = Cache.back();
NonLocalDepEntry Val = Cache.back();
Cache.pop_back();
MemoryDependenceAnalysis::NonLocalDepInfo::iterator Entry =
std::upper_bound(Cache.begin(), Cache.end()-1, Val);
@ -693,7 +697,7 @@ SortNonLocalDepInfoCache(MemoryDependenceAnalysis::NonLocalDepInfo &Cache,
case 1:
// One new entry, Just insert the new value at the appropriate position.
if (Cache.size() != 1) {
MemoryDependenceAnalysis::NonLocalDepEntry Val = Cache.back();
NonLocalDepEntry Val = Cache.back();
Cache.pop_back();
MemoryDependenceAnalysis::NonLocalDepInfo::iterator Entry =
std::upper_bound(Cache.begin(), Cache.end(), Val);
@ -707,275 +711,6 @@ SortNonLocalDepInfoCache(MemoryDependenceAnalysis::NonLocalDepInfo &Cache,
}
}
/// isPHITranslatable - Return true if the specified computation is derived from
/// a PHI node in the current block and if it is simple enough for us to handle.
static bool isPHITranslatable(Instruction *Inst) {
if (isa<PHINode>(Inst))
return true;
// We can handle bitcast of a PHI, but the PHI needs to be in the same block
// as the bitcast.
if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
Instruction *OpI = dyn_cast<Instruction>(BC->getOperand(0));
if (OpI == 0 || OpI->getParent() != Inst->getParent())
return true;
return isPHITranslatable(OpI);
}
// We can translate a GEP if all of its operands defined in this block are phi
// translatable.
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
Instruction *OpI = dyn_cast<Instruction>(GEP->getOperand(i));
if (OpI == 0 || OpI->getParent() != Inst->getParent())
continue;
if (!isPHITranslatable(OpI))
return false;
}
return true;
}
if (Inst->getOpcode() == Instruction::Add &&
isa<ConstantInt>(Inst->getOperand(1))) {
Instruction *OpI = dyn_cast<Instruction>(Inst->getOperand(0));
if (OpI == 0 || OpI->getParent() != Inst->getParent())
return true;
return isPHITranslatable(OpI);
}
// cerr << "MEMDEP: Could not PHI translate: " << *Pointer;
// if (isa<BitCastInst>(PtrInst) || isa<GetElementPtrInst>(PtrInst))
// cerr << "OP:\t\t\t\t" << *PtrInst->getOperand(0);
return false;
}
/// GetPHITranslatedValue - Given a computation that satisfied the
/// isPHITranslatable predicate, see if we can translate the computation into
/// the specified predecessor block. If so, return that value.
Value *MemoryDependenceAnalysis::
GetPHITranslatedValue(Value *InVal, BasicBlock *CurBB, BasicBlock *Pred,
const TargetData *TD) const {
// If the input value is not an instruction, or if it is not defined in CurBB,
// then we don't need to phi translate it.
Instruction *Inst = dyn_cast<Instruction>(InVal);
if (Inst == 0 || Inst->getParent() != CurBB)
return InVal;
if (PHINode *PN = dyn_cast<PHINode>(Inst))
return PN->getIncomingValueForBlock(Pred);
// Handle bitcast of PHI.
if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
// PHI translate the input operand.
Value *PHIIn = GetPHITranslatedValue(BC->getOperand(0), CurBB, Pred, TD);
if (PHIIn == 0) return 0;
// Constants are trivial to phi translate.
if (Constant *C = dyn_cast<Constant>(PHIIn))
return ConstantExpr::getBitCast(C, BC->getType());
// Otherwise we have to see if a bitcasted version of the incoming pointer
// is available. If so, we can use it, otherwise we have to fail.
for (Value::use_iterator UI = PHIIn->use_begin(), E = PHIIn->use_end();
UI != E; ++UI) {
if (BitCastInst *BCI = dyn_cast<BitCastInst>(*UI))
if (BCI->getType() == BC->getType())
return BCI;
}
return 0;
}
// Handle getelementptr with at least one PHI translatable operand.
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
SmallVector<Value*, 8> GEPOps;
BasicBlock *CurBB = GEP->getParent();
for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
Value *GEPOp = GEP->getOperand(i);
// No PHI translation is needed of operands whose values are live in to
// the predecessor block.
if (!isa<Instruction>(GEPOp) ||
cast<Instruction>(GEPOp)->getParent() != CurBB) {
GEPOps.push_back(GEPOp);
continue;
}
// If the operand is a phi node, do phi translation.
Value *InOp = GetPHITranslatedValue(GEPOp, CurBB, Pred, TD);
if (InOp == 0) return 0;
GEPOps.push_back(InOp);
}
// Simplify the GEP to handle 'gep x, 0' -> x etc.
if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD))
return V;
// Scan to see if we have this GEP available.
Value *APHIOp = GEPOps[0];
for (Value::use_iterator UI = APHIOp->use_begin(), E = APHIOp->use_end();
UI != E; ++UI) {
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*UI))
if (GEPI->getType() == GEP->getType() &&
GEPI->getNumOperands() == GEPOps.size() &&
GEPI->getParent()->getParent() == CurBB->getParent()) {
bool Mismatch = false;
for (unsigned i = 0, e = GEPOps.size(); i != e; ++i)
if (GEPI->getOperand(i) != GEPOps[i]) {
Mismatch = true;
break;
}
if (!Mismatch)
return GEPI;
}
}
return 0;
}
// Handle add with a constant RHS.
if (Inst->getOpcode() == Instruction::Add &&
isa<ConstantInt>(Inst->getOperand(1))) {
// PHI translate the LHS.
Value *LHS;
Constant *RHS = cast<ConstantInt>(Inst->getOperand(1));
Instruction *OpI = dyn_cast<Instruction>(Inst->getOperand(0));
bool isNSW = cast<BinaryOperator>(Inst)->hasNoSignedWrap();
bool isNUW = cast<BinaryOperator>(Inst)->hasNoUnsignedWrap();
if (OpI == 0 || OpI->getParent() != Inst->getParent())
LHS = Inst->getOperand(0);
else {
LHS = GetPHITranslatedValue(Inst->getOperand(0), CurBB, Pred, TD);
if (LHS == 0)
return 0;
}
// If the PHI translated LHS is an add of a constant, fold the immediates.
if (BinaryOperator *BOp = dyn_cast<BinaryOperator>(LHS))
if (BOp->getOpcode() == Instruction::Add)
if (ConstantInt *CI = dyn_cast<ConstantInt>(BOp->getOperand(1))) {
LHS = BOp->getOperand(0);
RHS = ConstantExpr::getAdd(RHS, CI);
isNSW = isNUW = false;
}
// See if the add simplifies away.
if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD))
return Res;
// Otherwise, see if we have this add available somewhere.
for (Value::use_iterator UI = LHS->use_begin(), E = LHS->use_end();
UI != E; ++UI) {
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(*UI))
if (BO->getOperand(0) == LHS && BO->getOperand(1) == RHS &&
BO->getParent()->getParent() == CurBB->getParent())
return BO;
}
return 0;
}
return 0;
}
/// GetAvailablePHITranslatePointer - Return the value computed by
/// PHITranslatePointer if it dominates PredBB, otherwise return null.
Value *MemoryDependenceAnalysis::
GetAvailablePHITranslatedValue(Value *V,
BasicBlock *CurBB, BasicBlock *PredBB,
const TargetData *TD,
const DominatorTree &DT) const {
// See if PHI translation succeeds.
V = GetPHITranslatedValue(V, CurBB, PredBB, TD);
if (V == 0) return 0;
// Make sure the value is live in the predecessor.
if (Instruction *Inst = dyn_cast_or_null<Instruction>(V))
if (!DT.dominates(Inst->getParent(), PredBB))
return 0;
return V;
}
/// InsertPHITranslatedPointer - Insert a computation of the PHI translated
/// version of 'V' for the edge PredBB->CurBB into the end of the PredBB
/// block. All newly created instructions are added to the NewInsts list.
///
Value *MemoryDependenceAnalysis::
InsertPHITranslatedPointer(Value *InVal, BasicBlock *CurBB,
BasicBlock *PredBB, const TargetData *TD,
const DominatorTree &DT,
SmallVectorImpl<Instruction*> &NewInsts) const {
// See if we have a version of this value already available and dominating
// PredBB. If so, there is no need to insert a new copy.
if (Value *Res = GetAvailablePHITranslatedValue(InVal, CurBB, PredBB, TD, DT))
return Res;
// If we don't have an available version of this value, it must be an
// instruction.
Instruction *Inst = cast<Instruction>(InVal);
// Handle bitcast of PHI translatable value.
if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
Value *OpVal = InsertPHITranslatedPointer(BC->getOperand(0),
CurBB, PredBB, TD, DT, NewInsts);
if (OpVal == 0) return 0;
// Otherwise insert a bitcast at the end of PredBB.
BitCastInst *New = new BitCastInst(OpVal, InVal->getType(),
InVal->getName()+".phi.trans.insert",
PredBB->getTerminator());
NewInsts.push_back(New);
return New;
}
// Handle getelementptr with at least one PHI operand.
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
SmallVector<Value*, 8> GEPOps;
BasicBlock *CurBB = GEP->getParent();
for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
Value *OpVal = InsertPHITranslatedPointer(GEP->getOperand(i),
CurBB, PredBB, TD, DT, NewInsts);
if (OpVal == 0) return 0;
GEPOps.push_back(OpVal);
}
GetElementPtrInst *Result =
GetElementPtrInst::Create(GEPOps[0], GEPOps.begin()+1, GEPOps.end(),
InVal->getName()+".phi.trans.insert",
PredBB->getTerminator());
Result->setIsInBounds(GEP->isInBounds());
NewInsts.push_back(Result);
return Result;
}
#if 0
// FIXME: This code works, but it is unclear that we actually want to insert
// a big chain of computation in order to make a value available in a block.
// This needs to be evaluated carefully to consider its cost trade offs.
// Handle add with a constant RHS.
if (Inst->getOpcode() == Instruction::Add &&
isa<ConstantInt>(Inst->getOperand(1))) {
// PHI translate the LHS.
Value *OpVal = InsertPHITranslatedPointer(Inst->getOperand(0),
CurBB, PredBB, TD, DT, NewInsts);
if (OpVal == 0) return 0;
BinaryOperator *Res = BinaryOperator::CreateAdd(OpVal, Inst->getOperand(1),
InVal->getName()+".phi.trans.insert",
PredBB->getTerminator());
Res->setHasNoSignedWrap(cast<BinaryOperator>(Inst)->hasNoSignedWrap());
Res->setHasNoUnsignedWrap(cast<BinaryOperator>(Inst)->hasNoUnsignedWrap());
NewInsts.push_back(Res);
return Res;
}
#endif
return 0;
}
/// getNonLocalPointerDepFromBB - Perform a dependency query based on
/// pointer/pointeesize starting at the end of StartBB. Add any clobber/def
/// results to the results vector and keep track of which blocks are visited in
@ -989,14 +724,14 @@ InsertPHITranslatedPointer(Value *InVal, BasicBlock *CurBB,
/// not compute dependence information for some reason. This should be treated
/// as a clobber dependence on the first instruction in the predecessor block.
bool MemoryDependenceAnalysis::
getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize,
getNonLocalPointerDepFromBB(const PHITransAddr &Pointer, uint64_t PointeeSize,
bool isLoad, BasicBlock *StartBB,
SmallVectorImpl<NonLocalDepEntry> &Result,
DenseMap<BasicBlock*, Value*> &Visited,
bool SkipFirstBlock) {
// Look up the cached info for Pointer.
ValueIsLoadPair CacheKey(Pointer, isLoad);
ValueIsLoadPair CacheKey(Pointer.getAddr(), isLoad);
std::pair<BBSkipFirstBlockPair, NonLocalDepInfo> *CacheInfo =
&NonLocalPointerDeps[CacheKey];
@ -1013,8 +748,9 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize,
if (!Visited.empty()) {
for (NonLocalDepInfo::iterator I = Cache->begin(), E = Cache->end();
I != E; ++I) {
DenseMap<BasicBlock*, Value*>::iterator VI = Visited.find(I->first);
if (VI == Visited.end() || VI->second == Pointer) continue;
DenseMap<BasicBlock*, Value*>::iterator VI = Visited.find(I->getBB());
if (VI == Visited.end() || VI->second == Pointer.getAddr())
continue;
// We have a pointer mismatch in a block. Just return clobber, saying
// that something was clobbered in this result. We could also do a
@ -1025,8 +761,8 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize,
for (NonLocalDepInfo::iterator I = Cache->begin(), E = Cache->end();
I != E; ++I) {
Visited.insert(std::make_pair(I->first, Pointer));
if (!I->second.isNonLocal())
Visited.insert(std::make_pair(I->getBB(), Pointer.getAddr()));
if (!I->getResult().isNonLocal())
Result.push_back(*I);
}
++NumCacheCompleteNonLocalPtr;
@ -1065,30 +801,27 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize,
// Get the dependency info for Pointer in BB. If we have cached
// information, we will use it, otherwise we compute it.
DEBUG(AssertSorted(*Cache, NumSortedEntries));
MemDepResult Dep = GetNonLocalInfoForBlock(Pointer, PointeeSize, isLoad,
BB, Cache, NumSortedEntries);
MemDepResult Dep = GetNonLocalInfoForBlock(Pointer.getAddr(), PointeeSize,
isLoad, BB, Cache,
NumSortedEntries);
// If we got a Def or Clobber, add this to the list of results.
if (!Dep.isNonLocal()) {
Result.push_back(NonLocalDepEntry(BB, Dep));
Result.push_back(NonLocalDepEntry(BB, Dep, Pointer.getAddr()));
continue;
}
}
// If 'Pointer' is an instruction defined in this block, then we need to do
// phi translation to change it into a value live in the predecessor block.
// If phi translation fails, then we can't continue dependence analysis.
Instruction *PtrInst = dyn_cast<Instruction>(Pointer);
bool NeedsPHITranslation = PtrInst && PtrInst->getParent() == BB;
// If no PHI translation is needed, just add all the predecessors of this
// block to scan them as well.
if (!NeedsPHITranslation) {
// If not, we just add the predecessors to the worklist and scan them with
// the same Pointer.
if (!Pointer.NeedsPHITranslationFromBlock(BB)) {
SkipFirstBlock = false;
for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI) {
// Verify that we haven't looked at this block yet.
std::pair<DenseMap<BasicBlock*,Value*>::iterator, bool>
InsertRes = Visited.insert(std::make_pair(*PI, Pointer));
InsertRes = Visited.insert(std::make_pair(*PI, Pointer.getAddr()));
if (InsertRes.second) {
// First time we've looked at *PI.
Worklist.push_back(*PI);
@ -1098,16 +831,17 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize,
// If we have seen this block before, but it was with a different
// pointer then we have a phi translation failure and we have to treat
// this as a clobber.
if (InsertRes.first->second != Pointer)
if (InsertRes.first->second != Pointer.getAddr())
goto PredTranslationFailure;
}
continue;
}
// If we do need to do phi translation, then there are a bunch of different
// cases, because we have to find a Value* live in the predecessor block. We
// know that PtrInst is defined in this block at least.
// We do need to do phi translation, if we know ahead of time we can't phi
// translate this value, don't even try.
if (!Pointer.IsPotentiallyPHITranslatable())
goto PredTranslationFailure;
// We may have added values to the cache list before this PHI translation.
// If so, we haven't done anything to ensure that the cache remains sorted.
// Sort it now (if needed) so that recursive invocations of
@ -1117,19 +851,17 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize,
SortNonLocalDepInfoCache(*Cache, NumSortedEntries);
NumSortedEntries = Cache->size();
}
// If this is a computation derived from a PHI node, use the suitably
// translated incoming values for each pred as the phi translated version.
if (!isPHITranslatable(PtrInst))
goto PredTranslationFailure;
Cache = 0;
for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI) {
BasicBlock *Pred = *PI;
// Get the PHI translated pointer in this predecessor. This can fail and
// return null if not translatable.
Value *PredPtr = GetPHITranslatedValue(PtrInst, BB, Pred, TD);
// Get the PHI translated pointer in this predecessor. This can fail if
// not translatable, in which case the getAddr() returns null.
PHITransAddr PredPointer(Pointer);
PredPointer.PHITranslateValue(BB, Pred);
Value *PredPtrVal = PredPointer.getAddr();
// Check to see if we have already visited this pred block with another
// pointer. If so, we can't do this lookup. This failure can occur
@ -1137,12 +869,12 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize,
// the successor translates to a pointer value different than the
// pointer the block was first analyzed with.
std::pair<DenseMap<BasicBlock*,Value*>::iterator, bool>
InsertRes = Visited.insert(std::make_pair(Pred, PredPtr));
InsertRes = Visited.insert(std::make_pair(Pred, PredPtrVal));
if (!InsertRes.second) {
// If the predecessor was visited with PredPtr, then we already did
// the analysis and can ignore it.
if (InsertRes.first->second == PredPtr)
if (InsertRes.first->second == PredPtrVal)
continue;
// Otherwise, the block was previously analyzed with a different
@ -1155,10 +887,11 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize,
// predecessor, then we have to assume that the pointer is clobbered in
// that predecessor. We can still do PRE of the load, which would insert
// a computation of the pointer in this predecessor.
if (PredPtr == 0) {
if (PredPtrVal == 0) {
// Add the entry to the Result list.
NonLocalDepEntry Entry(Pred,
MemDepResult::getClobber(Pred->getTerminator()));
MemDepResult::getClobber(Pred->getTerminator()),
PredPtrVal);
Result.push_back(Entry);
// Add it to the cache for this CacheKey so that subsequent queries get
@ -1167,27 +900,27 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize,
MemoryDependenceAnalysis::NonLocalDepInfo::iterator It =
std::upper_bound(Cache->begin(), Cache->end(), Entry);
if (It != Cache->begin() && prior(It)->first == Pred)
if (It != Cache->begin() && (It-1)->getBB() == Pred)
--It;
if (It == Cache->end() || It->first != Pred) {
if (It == Cache->end() || It->getBB() != Pred) {
Cache->insert(It, Entry);
// Add it to the reverse map.
ReverseNonLocalPtrDeps[Pred->getTerminator()].insert(CacheKey);
} else if (!It->second.isDirty()) {
} else if (!It->getResult().isDirty()) {
// noop
} else if (It->second.getInst() == Pred->getTerminator()) {
} else if (It->getResult().getInst() == Pred->getTerminator()) {
// Same instruction, clear the dirty marker.
It->second = Entry.second;
} else if (It->second.getInst() == 0) {
It->setResult(Entry.getResult(), PredPtrVal);
} else if (It->getResult().getInst() == 0) {
// Dirty, with no instruction, just add this.
It->second = Entry.second;
It->setResult(Entry.getResult(), PredPtrVal);
ReverseNonLocalPtrDeps[Pred->getTerminator()].insert(CacheKey);
} else {
// Otherwise, dirty with a different instruction.
RemoveFromReverseMap(ReverseNonLocalPtrDeps, It->second.getInst(),
CacheKey);
It->second = Entry.second;
RemoveFromReverseMap(ReverseNonLocalPtrDeps,
It->getResult().getInst(), CacheKey);
It->setResult(Entry.getResult(),PredPtrVal);
ReverseNonLocalPtrDeps[Pred->getTerminator()].insert(CacheKey);
}
Cache = 0;
@ -1201,7 +934,7 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize,
// If we have a problem phi translating, fall through to the code below
// to handle the failure condition.
if (getNonLocalPointerDepFromBB(PredPtr, PointeeSize, isLoad, Pred,
if (getNonLocalPointerDepFromBB(PredPointer, PointeeSize, isLoad, Pred,
Result, Visited))
goto PredTranslationFailure;
}
@ -1245,12 +978,12 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize,
for (NonLocalDepInfo::reverse_iterator I = Cache->rbegin(); ; ++I) {
assert(I != Cache->rend() && "Didn't find current block??");
if (I->first != BB)
if (I->getBB() != BB)
continue;
assert(I->second.isNonLocal() &&
assert(I->getResult().isNonLocal() &&
"Should only be here with transparent block");
I->second = MemDepResult::getClobber(BB->begin());
I->setResult(MemDepResult::getClobber(BB->begin()), Pointer.getAddr());
ReverseNonLocalPtrDeps[BB->begin()].insert(CacheKey);
Result.push_back(*I);
break;
@ -1276,9 +1009,9 @@ RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P) {
NonLocalDepInfo &PInfo = It->second.second;
for (unsigned i = 0, e = PInfo.size(); i != e; ++i) {
Instruction *Target = PInfo[i].second.getInst();
Instruction *Target = PInfo[i].getResult().getInst();
if (Target == 0) continue; // Ignore non-local dep results.
assert(Target->getParent() == PInfo[i].first);
assert(Target->getParent() == PInfo[i].getBB());
// Eliminating the dirty entry from 'Cache', so update the reverse info.
RemoveFromReverseMap(ReverseNonLocalPtrDeps, Target, P);
@ -1315,7 +1048,7 @@ void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) {
NonLocalDepInfo &BlockMap = NLDI->second.first;
for (NonLocalDepInfo::iterator DI = BlockMap.begin(), DE = BlockMap.end();
DI != DE; ++DI)
if (Instruction *Inst = DI->second.getInst())
if (Instruction *Inst = DI->getResult().getInst())
RemoveFromReverseMap(ReverseNonLocalDeps, Inst, RemInst);
NonLocalDeps.erase(NLDI);
}
@ -1403,10 +1136,10 @@ void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) {
for (NonLocalDepInfo::iterator DI = INLD.first.begin(),
DE = INLD.first.end(); DI != DE; ++DI) {
if (DI->second.getInst() != RemInst) continue;
if (DI->getResult().getInst() != RemInst) continue;
// Convert to a dirty entry for the subsequent instruction.
DI->second = NewDirtyVal;
DI->setResult(NewDirtyVal, DI->getAddress());
if (Instruction *NextI = NewDirtyVal.getInst())
ReverseDepsToAdd.push_back(std::make_pair(NextI, *I));
@ -1445,10 +1178,10 @@ void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) {
// Update any entries for RemInst to use the instruction after it.
for (NonLocalDepInfo::iterator DI = NLPDI.begin(), DE = NLPDI.end();
DI != DE; ++DI) {
if (DI->second.getInst() != RemInst) continue;
if (DI->getResult().getInst() != RemInst) continue;
// Convert to a dirty entry for the subsequent instruction.
DI->second = NewDirtyVal;
DI->setResult(NewDirtyVal, DI->getAddress());
if (Instruction *NewDirtyInst = NewDirtyVal.getInst())
ReversePtrDepsToAdd.push_back(std::make_pair(NewDirtyInst, P));
@ -1489,7 +1222,7 @@ void MemoryDependenceAnalysis::verifyRemoved(Instruction *D) const {
const NonLocalDepInfo &Val = I->second.second;
for (NonLocalDepInfo::const_iterator II = Val.begin(), E = Val.end();
II != E; ++II)
assert(II->second.getInst() != D && "Inst occurs as NLPD value");
assert(II->getResult().getInst() != D && "Inst occurs as NLPD value");
}
for (NonLocalDepMapType::const_iterator I = NonLocalDeps.begin(),
@ -1498,7 +1231,7 @@ void MemoryDependenceAnalysis::verifyRemoved(Instruction *D) const {
const PerInstNLInfo &INLD = I->second;
for (NonLocalDepInfo::const_iterator II = INLD.first.begin(),
EE = INLD.first.end(); II != EE; ++II)
assert(II->second.getInst() != D && "Inst occurs in data structures");
assert(II->getResult().getInst() != D && "Inst occurs in data structures");
}
for (ReverseDepMapType::const_iterator I = ReverseLocalDeps.begin(),

View File

@ -0,0 +1,432 @@
//===- PHITransAddr.cpp - PHI Translation for Addresses -------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the PHITransAddr class.
//
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/PHITransAddr.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
static bool CanPHITrans(Instruction *Inst) {
if (isa<PHINode>(Inst) ||
isa<BitCastInst>(Inst) ||
isa<GetElementPtrInst>(Inst))
return true;
if (Inst->getOpcode() == Instruction::Add &&
isa<ConstantInt>(Inst->getOperand(1)))
return true;
// cerr << "MEMDEP: Could not PHI translate: " << *Pointer;
// if (isa<BitCastInst>(PtrInst) || isa<GetElementPtrInst>(PtrInst))
// cerr << "OP:\t\t\t\t" << *PtrInst->getOperand(0);
return false;
}
void PHITransAddr::dump() const {
if (Addr == 0) {
errs() << "PHITransAddr: null\n";
return;
}
errs() << "PHITransAddr: " << *Addr << "\n";
for (unsigned i = 0, e = InstInputs.size(); i != e; ++i)
errs() << " Input #" << i << " is " << *InstInputs[i] << "\n";
}
static bool VerifySubExpr(Value *Expr,
SmallVectorImpl<Instruction*> &InstInputs) {
// If this is a non-instruction value, there is nothing to do.
Instruction *I = dyn_cast<Instruction>(Expr);
if (I == 0) return true;
// If it's an instruction, it is either in Tmp or its operands recursively
// are.
SmallVectorImpl<Instruction*>::iterator Entry =
std::find(InstInputs.begin(), InstInputs.end(), I);
if (Entry != InstInputs.end()) {
InstInputs.erase(Entry);
return true;
}
// If it isn't in the InstInputs list it is a subexpr incorporated into the
// address. Sanity check that it is phi translatable.
if (!CanPHITrans(I)) {
errs() << "Non phi translatable instruction found in PHITransAddr, either "
"something is missing from InstInputs or CanPHITrans is wrong:\n";
errs() << *I << '\n';
return false;
}
// Validate the operands of the instruction.
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
if (!VerifySubExpr(I->getOperand(i), InstInputs))
return false;
return true;
}
/// Verify - Check internal consistency of this data structure. If the
/// structure is valid, it returns true. If invalid, it prints errors and
/// returns false.
bool PHITransAddr::Verify() const {
if (Addr == 0) return true;
SmallVector<Instruction*, 8> Tmp(InstInputs.begin(), InstInputs.end());
if (!VerifySubExpr(Addr, Tmp))
return false;
if (!Tmp.empty()) {
errs() << "PHITransAddr inconsistent, contains extra instructions:\n";
for (unsigned i = 0, e = InstInputs.size(); i != e; ++i)
errs() << " InstInput #" << i << " is " << *InstInputs[i] << "\n";
return false;
}
// a-ok.
return true;
}
/// IsPotentiallyPHITranslatable - If this needs PHI translation, return true
/// if we have some hope of doing it. This should be used as a filter to
/// avoid calling PHITranslateValue in hopeless situations.
bool PHITransAddr::IsPotentiallyPHITranslatable() const {
// If the input value is not an instruction, or if it is not defined in CurBB,
// then we don't need to phi translate it.
Instruction *Inst = dyn_cast<Instruction>(Addr);
return Inst == 0 || CanPHITrans(Inst);
}
static void RemoveInstInputs(Value *V,
SmallVectorImpl<Instruction*> &InstInputs) {
Instruction *I = dyn_cast<Instruction>(V);
if (I == 0) return;
// If the instruction is in the InstInputs list, remove it.
SmallVectorImpl<Instruction*>::iterator Entry =
std::find(InstInputs.begin(), InstInputs.end(), I);
if (Entry != InstInputs.end()) {
InstInputs.erase(Entry);
return;
}
assert(!isa<PHINode>(I) && "Error, removing something that isn't an input");
// Otherwise, it must have instruction inputs itself. Zap them recursively.
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
if (Instruction *Op = dyn_cast<Instruction>(I->getOperand(i)))
RemoveInstInputs(Op, InstInputs);
}
}
Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB,
BasicBlock *PredBB) {
// If this is a non-instruction value, it can't require PHI translation.
Instruction *Inst = dyn_cast<Instruction>(V);
if (Inst == 0) return V;
// Determine whether 'Inst' is an input to our PHI translatable expression.
bool isInput = std::count(InstInputs.begin(), InstInputs.end(), Inst);
// Handle inputs instructions if needed.
if (isInput) {
if (Inst->getParent() != CurBB) {
// If it is an input defined in a different block, then it remains an
// input.
return Inst;
}
// If 'Inst' is defined in this block and is an input that needs to be phi
// translated, we need to incorporate the value into the expression or fail.
// In either case, the instruction itself isn't an input any longer.
InstInputs.erase(std::find(InstInputs.begin(), InstInputs.end(), Inst));
// If this is a PHI, go ahead and translate it.
if (PHINode *PN = dyn_cast<PHINode>(Inst))
return AddAsInput(PN->getIncomingValueForBlock(PredBB));
// If this is a non-phi value, and it is analyzable, we can incorporate it
// into the expression by making all instruction operands be inputs.
if (!CanPHITrans(Inst))
return 0;
// All instruction operands are now inputs (and of course, they may also be
// defined in this block, so they may need to be phi translated themselves.
for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i)
if (Instruction *Op = dyn_cast<Instruction>(Inst->getOperand(i)))
InstInputs.push_back(Op);
}
// Ok, it must be an intermediate result (either because it started that way
// or because we just incorporated it into the expression). See if its
// operands need to be phi translated, and if so, reconstruct it.
if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
Value *PHIIn = PHITranslateSubExpr(BC->getOperand(0), CurBB, PredBB);
if (PHIIn == 0) return 0;
if (PHIIn == BC->getOperand(0))
return BC;
// Find an available version of this cast.
// Constants are trivial to find.
if (Constant *C = dyn_cast<Constant>(PHIIn))
return AddAsInput(ConstantExpr::getBitCast(C, BC->getType()));
// Otherwise we have to see if a bitcasted version of the incoming pointer
// is available. If so, we can use it, otherwise we have to fail.
for (Value::use_iterator UI = PHIIn->use_begin(), E = PHIIn->use_end();
UI != E; ++UI) {
if (BitCastInst *BCI = dyn_cast<BitCastInst>(*UI))
if (BCI->getType() == BC->getType())
return BCI;
}
return 0;
}
// Handle getelementptr with at least one PHI translatable operand.
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
SmallVector<Value*, 8> GEPOps;
bool AnyChanged = false;
for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
Value *GEPOp = PHITranslateSubExpr(GEP->getOperand(i), CurBB, PredBB);
if (GEPOp == 0) return 0;
AnyChanged |= GEPOp != GEP->getOperand(i);
GEPOps.push_back(GEPOp);
}
if (!AnyChanged)
return GEP;
// Simplify the GEP to handle 'gep x, 0' -> x etc.
if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD)) {
for (unsigned i = 0, e = GEPOps.size(); i != e; ++i)
RemoveInstInputs(GEPOps[i], InstInputs);
return AddAsInput(V);
}
// Scan to see if we have this GEP available.
Value *APHIOp = GEPOps[0];
for (Value::use_iterator UI = APHIOp->use_begin(), E = APHIOp->use_end();
UI != E; ++UI) {
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*UI))
if (GEPI->getType() == GEP->getType() &&
GEPI->getNumOperands() == GEPOps.size() &&
GEPI->getParent()->getParent() == CurBB->getParent()) {
bool Mismatch = false;
for (unsigned i = 0, e = GEPOps.size(); i != e; ++i)
if (GEPI->getOperand(i) != GEPOps[i]) {
Mismatch = true;
break;
}
if (!Mismatch)
return GEPI;
}
}
return 0;
}
// Handle add with a constant RHS.
if (Inst->getOpcode() == Instruction::Add &&
isa<ConstantInt>(Inst->getOperand(1))) {
// PHI translate the LHS.
Constant *RHS = cast<ConstantInt>(Inst->getOperand(1));
bool isNSW = cast<BinaryOperator>(Inst)->hasNoSignedWrap();
bool isNUW = cast<BinaryOperator>(Inst)->hasNoUnsignedWrap();
Value *LHS = PHITranslateSubExpr(Inst->getOperand(0), CurBB, PredBB);
if (LHS == 0) return 0;
// If the PHI translated LHS is an add of a constant, fold the immediates.
if (BinaryOperator *BOp = dyn_cast<BinaryOperator>(LHS))
if (BOp->getOpcode() == Instruction::Add)
if (ConstantInt *CI = dyn_cast<ConstantInt>(BOp->getOperand(1))) {
LHS = BOp->getOperand(0);
RHS = ConstantExpr::getAdd(RHS, CI);
isNSW = isNUW = false;
// If the old 'LHS' was an input, add the new 'LHS' as an input.
if (std::count(InstInputs.begin(), InstInputs.end(), BOp)) {
RemoveInstInputs(BOp, InstInputs);
AddAsInput(LHS);
}
}
// See if the add simplifies away.
if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD)) {
// If we simplified the operands, the LHS is no longer an input, but Res
// is.
RemoveInstInputs(LHS, InstInputs);
return AddAsInput(Res);
}
// If we didn't modify the add, just return it.
if (LHS == Inst->getOperand(0) && RHS == Inst->getOperand(1))
return Inst;
// Otherwise, see if we have this add available somewhere.
for (Value::use_iterator UI = LHS->use_begin(), E = LHS->use_end();
UI != E; ++UI) {
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(*UI))
if (BO->getOpcode() == Instruction::Add &&
BO->getOperand(0) == LHS && BO->getOperand(1) == RHS &&
BO->getParent()->getParent() == CurBB->getParent())
return BO;
}
return 0;
}
// Otherwise, we failed.
return 0;
}
/// PHITranslateValue - PHI translate the current address up the CFG from
/// CurBB to Pred, updating our state the reflect any needed changes. This
/// returns true on failure and sets Addr to null.
bool PHITransAddr::PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB) {
assert(Verify() && "Invalid PHITransAddr!");
Addr = PHITranslateSubExpr(Addr, CurBB, PredBB);
assert(Verify() && "Invalid PHITransAddr!");
return Addr == 0;
}
/// GetAvailablePHITranslatedSubExpr - Return the value computed by
/// PHITranslateSubExpr if it dominates PredBB, otherwise return null.
Value *PHITransAddr::
GetAvailablePHITranslatedSubExpr(Value *V, BasicBlock *CurBB,BasicBlock *PredBB,
const DominatorTree &DT) const {
PHITransAddr Tmp(V, TD);
Tmp.PHITranslateValue(CurBB, PredBB);
// See if PHI translation succeeds.
V = Tmp.getAddr();
// Make sure the value is live in the predecessor.
if (Instruction *Inst = dyn_cast_or_null<Instruction>(V))
if (!DT.dominates(Inst->getParent(), PredBB))
return 0;
return V;
}
/// PHITranslateWithInsertion - PHI translate this value into the specified
/// predecessor block, inserting a computation of the value if it is
/// unavailable.
///
/// All newly created instructions are added to the NewInsts list. This
/// returns null on failure.
///
Value *PHITransAddr::
PHITranslateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB,
const DominatorTree &DT,
SmallVectorImpl<Instruction*> &NewInsts) {
unsigned NISize = NewInsts.size();
// Attempt to PHI translate with insertion.
Addr = InsertPHITranslatedSubExpr(Addr, CurBB, PredBB, DT, NewInsts);
// If successful, return the new value.
if (Addr) return Addr;
// If not, destroy any intermediate instructions inserted.
while (NewInsts.size() != NISize)
NewInsts.pop_back_val()->eraseFromParent();
return 0;
}
/// InsertPHITranslatedPointer - Insert a computation of the PHI translated
/// version of 'V' for the edge PredBB->CurBB into the end of the PredBB
/// block. All newly created instructions are added to the NewInsts list.
/// This returns null on failure.
///
Value *PHITransAddr::
InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB,
BasicBlock *PredBB, const DominatorTree &DT,
SmallVectorImpl<Instruction*> &NewInsts) {
// See if we have a version of this value already available and dominating
// PredBB. If so, there is no need to insert a new instance of it.
if (Value *Res = GetAvailablePHITranslatedSubExpr(InVal, CurBB, PredBB, DT))
return Res;
// If we don't have an available version of this value, it must be an
// instruction.
Instruction *Inst = cast<Instruction>(InVal);
// Handle bitcast of PHI translatable value.
if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
Value *OpVal = InsertPHITranslatedSubExpr(BC->getOperand(0),
CurBB, PredBB, DT, NewInsts);
if (OpVal == 0) return 0;
// Otherwise insert a bitcast at the end of PredBB.
BitCastInst *New = new BitCastInst(OpVal, InVal->getType(),
InVal->getName()+".phi.trans.insert",
PredBB->getTerminator());
NewInsts.push_back(New);
return New;
}
// Handle getelementptr with at least one PHI operand.
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
SmallVector<Value*, 8> GEPOps;
BasicBlock *CurBB = GEP->getParent();
for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
Value *OpVal = InsertPHITranslatedSubExpr(GEP->getOperand(i),
CurBB, PredBB, DT, NewInsts);
if (OpVal == 0) return 0;
GEPOps.push_back(OpVal);
}
GetElementPtrInst *Result =
GetElementPtrInst::Create(GEPOps[0], GEPOps.begin()+1, GEPOps.end(),
InVal->getName()+".phi.trans.insert",
PredBB->getTerminator());
Result->setIsInBounds(GEP->isInBounds());
NewInsts.push_back(Result);
return Result;
}
#if 0
// FIXME: This code works, but it is unclear that we actually want to insert
// a big chain of computation in order to make a value available in a block.
// This needs to be evaluated carefully to consider its cost trade offs.
// Handle add with a constant RHS.
if (Inst->getOpcode() == Instruction::Add &&
isa<ConstantInt>(Inst->getOperand(1))) {
// PHI translate the LHS.
Value *OpVal = InsertPHITranslatedSubExpr(Inst->getOperand(0),
CurBB, PredBB, DT, NewInsts);
if (OpVal == 0) return 0;
BinaryOperator *Res = BinaryOperator::CreateAdd(OpVal, Inst->getOperand(1),
InVal->getName()+".phi.trans.insert",
PredBB->getTerminator());
Res->setHasNoSignedWrap(cast<BinaryOperator>(Inst)->hasNoSignedWrap());
Res->setHasNoUnsignedWrap(cast<BinaryOperator>(Inst)->hasNoUnsignedWrap());
NewInsts.push_back(Res);
return Res;
}
#endif
return 0;
}

View File

@ -35,6 +35,7 @@ namespace {
LoopInfo *LI;
std::set<BasicBlock*> BBToVisit;
std::map<Loop*,double> LoopExitWeights;
std::map<Edge,double> MinimalWeight;
public:
static char ID; // Class identification, replacement for typeinfo
explicit ProfileEstimatorPass(const double execcount = 0)
@ -91,7 +92,7 @@ static void inline printEdgeError(ProfileInfo::Edge e, const char *M) {
void inline ProfileEstimatorPass::printEdgeWeight(Edge E) {
DEBUG(errs() << "-- Weight of Edge " << E << ":"
<< format("%g", getEdgeWeight(E)) << "\n");
<< format("%20.20g", getEdgeWeight(E)) << "\n");
}
// recurseBasicBlock() - This calculates the ProfileInfo estimation for a
@ -174,6 +175,12 @@ void ProfileEstimatorPass::recurseBasicBlock(BasicBlock *BB) {
double w = getEdgeWeight(*ei);
if (w == MissingValue) {
Edges.push_back(*ei);
// Check if there is a necessary minimal weight, if yes, subtract it
// from weight.
if (MinimalWeight.find(*ei) != MinimalWeight.end()) {
incoming -= MinimalWeight[*ei];
DEBUG(errs() << "Reserving " << format("%.20g",MinimalWeight[*ei]) << " at " << (*ei) << "\n");
}
} else {
incoming -= w;
}
@ -191,11 +198,43 @@ void ProfileEstimatorPass::recurseBasicBlock(BasicBlock *BB) {
printEdgeWeight(edge);
}
}
// Distribute remaining weight onto the exit edges.
// Distribute remaining weight to the exting edges. To prevent fractions
// from building up and provoking precision problems the weight which is to
// be distributed is split and the rounded, the last edge gets a somewhat
// bigger value, but we are close enough for an estimation.
double fraction = floor(incoming/Edges.size());
for (SmallVector<Edge, 8>::iterator ei = Edges.begin(), ee = Edges.end();
ei != ee; ++ei) {
EdgeInformation[BB->getParent()][*ei] += incoming/Edges.size();
double w = 0;
if (ei != (ee-1)) {
w = fraction;
incoming -= fraction;
} else {
w = incoming;
}
EdgeInformation[BB->getParent()][*ei] += w;
// Read necessary minimal weight.
if (MinimalWeight.find(*ei) != MinimalWeight.end()) {
EdgeInformation[BB->getParent()][*ei] += MinimalWeight[*ei];
DEBUG(errs() << "Additionally " << format("%.20g",MinimalWeight[*ei]) << " at " << (*ei) << "\n");
}
printEdgeWeight(*ei);
// Add minimal weight to paths to all exit edges, this is used to ensure
// that enough flow is reaching this edges.
Path p;
const BasicBlock *Dest = GetPath(BB, (*ei).first, p, GetPathToDest);
while (Dest != BB) {
const BasicBlock *Parent = p.find(Dest)->second;
Edge e = getEdge(Parent, Dest);
if (MinimalWeight.find(e) == MinimalWeight.end()) {
MinimalWeight[e] = 0;
}
MinimalWeight[e] += w;
DEBUG(errs() << "Minimal Weight for " << e << ": " << format("%.20g",MinimalWeight[e]) << "\n");
Dest = Parent;
}
}
// Increase flow into the loop.
BBWeight *= (ExecCount+1);
@ -203,7 +242,7 @@ void ProfileEstimatorPass::recurseBasicBlock(BasicBlock *BB) {
BlockInformation[BB->getParent()][BB] = BBWeight;
// Up until now we considered only the loop exiting edges, now we have a
// definite block weight and must ditribute this onto the outgoing edges.
// definite block weight and must distribute this onto the outgoing edges.
// Since there may be already flow attached to some of the edges, read this
// flow first and remember the edges that have still now flow attached.
Edges.clear();
@ -225,15 +264,32 @@ void ProfileEstimatorPass::recurseBasicBlock(BasicBlock *BB) {
BBWeight -= getEdgeWeight(edge);
} else {
Edges.push_back(edge);
// If minimal weight is necessary, reserve weight by subtracting weight
// from block weight, this is readded later on.
if (MinimalWeight.find(edge) != MinimalWeight.end()) {
BBWeight -= MinimalWeight[edge];
DEBUG(errs() << "Reserving " << format("%.20g",MinimalWeight[edge]) << " at " << edge << "\n");
}
}
}
}
double fraction = floor(BBWeight/Edges.size());
// Finally we know what flow is still not leaving the block, distribute this
// flow onto the empty edges.
for (SmallVector<Edge, 8>::iterator ei = Edges.begin(), ee = Edges.end();
ei != ee; ++ei) {
EdgeInformation[BB->getParent()][*ei] += BBWeight/Edges.size();
if (ei != (ee-1)) {
EdgeInformation[BB->getParent()][*ei] += fraction;
BBWeight -= fraction;
} else {
EdgeInformation[BB->getParent()][*ei] += BBWeight;
}
// Readd minial necessary weight.
if (MinimalWeight.find(*ei) != MinimalWeight.end()) {
EdgeInformation[BB->getParent()][*ei] += MinimalWeight[*ei];
DEBUG(errs() << "Additionally " << format("%.20g",MinimalWeight[*ei]) << " at " << (*ei) << "\n");
}
printEdgeWeight(*ei);
}
@ -260,20 +316,24 @@ bool ProfileEstimatorPass::runOnFunction(Function &F) {
for (Function::iterator bi = F.begin(), be = F.end(); bi != be; ++bi)
BBToVisit.insert(bi);
// Clear Minimal Edges.
MinimalWeight.clear();
DEBUG(errs() << "Working on function " << F.getNameStr() << "\n");
// Since the entry block is the first one and has no predecessors, the edge
// (0,entry) is inserted with the starting weight of 1.
BasicBlock *entry = &F.getEntryBlock();
BlockInformation[&F][entry] = 1;
BlockInformation[&F][entry] = pow(2.0, 32.0);
Edge edge = getEdge(0,entry);
EdgeInformation[&F][edge] = 1;
EdgeInformation[&F][edge] = BlockInformation[&F][entry];
printEdgeWeight(edge);
// Since recurseBasicBlock() maybe returns with a block which was not fully
// estimated, use recurseBasicBlock() until everything is calculated.
// estimated, use recurseBasicBlock() until everything is calculated.
bool cleanup = false;
recurseBasicBlock(entry);
while (BBToVisit.size() > 0) {
while (BBToVisit.size() > 0 && !cleanup) {
// Remember number of open blocks, this is later used to check if progress
// was made.
unsigned size = BBToVisit.size();
@ -287,21 +347,65 @@ bool ProfileEstimatorPass::runOnFunction(Function &F) {
if (BBToVisit.size() < size) break;
}
// If there was not a single block resovled, make some assumptions.
// If there was not a single block resolved, make some assumptions.
if (BBToVisit.size() == size) {
BasicBlock *BB = *(BBToVisit.begin());
// Since this BB was not calculated because of missing incoming edges,
// set these edges to zero.
for (pred_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
bbi != bbe; ++bbi) {
Edge e = getEdge(*bbi,BB);
double w = getEdgeWeight(e);
if (w == MissingValue) {
EdgeInformation[&F][e] = 0;
DEBUG(errs() << "Assuming edge weight: ");
printEdgeWeight(e);
bool found = false;
for (std::set<BasicBlock*>::iterator BBI = BBToVisit.begin(), BBE = BBToVisit.end();
(BBI != BBE) && (!found); ++BBI) {
BasicBlock *BB = *BBI;
// Try each predecessor if it can be assumend.
for (pred_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
(bbi != bbe) && (!found); ++bbi) {
Edge e = getEdge(*bbi,BB);
double w = getEdgeWeight(e);
// Check that edge from predecessor is still free.
if (w == MissingValue) {
// Check if there is a circle from this block to predecessor.
Path P;
const BasicBlock *Dest = GetPath(BB, *bbi, P, GetPathToDest);
if (Dest != *bbi) {
// If there is no circle, just set edge weight to 0
EdgeInformation[&F][e] = 0;
DEBUG(errs() << "Assuming edge weight: ");
printEdgeWeight(e);
found = true;
}
}
}
}
if (!found) {
cleanup = true;
DEBUG(errs() << "No assumption possible in Fuction "<<F.getName()<<", setting all to zero\n");
}
}
}
// In case there was no safe way to assume edges, set as a last measure,
// set _everything_ to zero.
if (cleanup) {
FunctionInformation[&F] = 0;
BlockInformation[&F].clear();
EdgeInformation[&F].clear();
for (Function::const_iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) {
const BasicBlock *BB = &(*FI);
BlockInformation[&F][BB] = 0;
pred_const_iterator predi = pred_begin(BB), prede = pred_end(BB);
if (predi == prede) {
Edge e = getEdge(0,BB);
setEdgeWeight(e,0);
}
for (;predi != prede; ++predi) {
Edge e = getEdge(*predi,BB);
setEdgeWeight(e,0);
}
succ_const_iterator succi = succ_begin(BB), succe = succ_end(BB);
if (succi == succe) {
Edge e = getEdge(BB,0);
setEdgeWeight(e,0);
}
for (;succi != succe; ++succi) {
Edge e = getEdge(*succi,BB);
setEdgeWeight(e,0);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -74,6 +74,8 @@ X("profile-loader", "Load profile information from llvmprof.out", false, true);
static RegisterAnalysisGroup<ProfileInfo> Y(X);
const PassInfo *llvm::ProfileLoaderPassID = &X;
ModulePass *llvm::createProfileLoaderPass() { return new LoaderPass(); }
/// createProfileLoaderPass - This function returns a Pass that loads the
@ -112,46 +114,9 @@ void LoaderPass::recurseBasicBlock(const BasicBlock *BB) {
recurseBasicBlock(*bbi);
}
Edge edgetocalc;
unsigned uncalculated = 0;
// collect weights of all incoming and outgoing edges, rememer edges that
// have no value
double incount = 0;
SmallSet<const BasicBlock*,8> pred_visited;
pred_const_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
if (bbi==bbe) {
readEdgeOrRemember(getEdge(0, BB),edgetocalc,uncalculated,incount);
}
for (;bbi != bbe; ++bbi) {
if (pred_visited.insert(*bbi)) {
readEdgeOrRemember(getEdge(*bbi, BB),edgetocalc,uncalculated,incount);
}
}
double outcount = 0;
SmallSet<const BasicBlock*,8> succ_visited;
succ_const_iterator sbbi = succ_begin(BB), sbbe = succ_end(BB);
if (sbbi==sbbe) {
readEdgeOrRemember(getEdge(BB, 0),edgetocalc,uncalculated,outcount);
}
for (;sbbi != sbbe; ++sbbi) {
if (succ_visited.insert(*sbbi)) {
readEdgeOrRemember(getEdge(BB, *sbbi),edgetocalc,uncalculated,outcount);
}
}
// if exactly one edge weight was missing, calculate it and remove it from
// spanning tree
if (uncalculated == 1) {
if (incount < outcount) {
EdgeInformation[BB->getParent()][edgetocalc] = outcount-incount;
} else {
EdgeInformation[BB->getParent()][edgetocalc] = incount-outcount;
}
DEBUG(errs() << "--Calc Edge Counter for " << edgetocalc << ": "
<< format("%g", getEdgeWeight(edgetocalc)) << "\n");
SpanningTree.erase(edgetocalc);
Edge tocalc;
if (CalculateMissingEdge(BB, tocalc)) {
SpanningTree.erase(tocalc);
}
}
@ -219,9 +184,9 @@ bool LoaderPass::runOnModule(Module &M) {
}
}
while (SpanningTree.size() > 0) {
#if 0
unsigned size = SpanningTree.size();
#endif
BBisUnvisited.clear();
for (std::set<Edge>::iterator ei = SpanningTree.begin(),
ee = SpanningTree.end(); ei != ee; ++ei) {
@ -231,17 +196,16 @@ bool LoaderPass::runOnModule(Module &M) {
while (BBisUnvisited.size() > 0) {
recurseBasicBlock(*BBisUnvisited.begin());
}
#if 0
if (SpanningTree.size() == size) {
DEBUG(errs()<<"{");
for (std::set<Edge>::iterator ei = SpanningTree.begin(),
ee = SpanningTree.end(); ei != ee; ++ei) {
DEBUG(errs()<<"("<<(ei->first?ei->first->getName():"0")<<","
<<(ei->second?ei->second->getName():"0")<<"),");
DEBUG(errs()<< *ei <<",");
}
assert(0 && "No edge calculated!");
}
#endif
}
}
if (ReadCount != Counters.size()) {

View File

@ -21,6 +21,7 @@
#include "llvm/Support/CFG.h"
#include "llvm/Support/InstIterator.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Debug.h"
#include <set>
using namespace llvm;
@ -29,44 +30,45 @@ static cl::opt<bool,false>
ProfileVerifierDisableAssertions("profile-verifier-noassert",
cl::desc("Disable assertions"));
namespace {
class ProfileVerifierPass : public FunctionPass {
namespace llvm {
template<class FType, class BType>
class ProfileVerifierPassT : public FunctionPass {
struct DetailedBlockInfo {
const BasicBlock *BB;
double BBWeight;
double inWeight;
int inCount;
double outWeight;
int outCount;
const BType *BB;
double BBWeight;
double inWeight;
int inCount;
double outWeight;
int outCount;
};
ProfileInfo *PI;
std::set<const BasicBlock*> BBisVisited;
std::set<const Function*> FisVisited;
ProfileInfoT<FType, BType> *PI;
std::set<const BType*> BBisVisited;
std::set<const FType*> FisVisited;
bool DisableAssertions;
// When debugging is enabled, the verifier prints a whole slew of debug
// information, otherwise its just the assert. These are all the helper
// functions.
bool PrintedDebugTree;
std::set<const BasicBlock*> BBisPrinted;
std::set<const BType*> BBisPrinted;
void debugEntry(DetailedBlockInfo*);
void printDebugInfo(const BasicBlock *BB);
void printDebugInfo(const BType *BB);
public:
static char ID; // Class identification, replacement for typeinfo
explicit ProfileVerifierPass () : FunctionPass(&ID) {
explicit ProfileVerifierPassT () : FunctionPass(&ID) {
DisableAssertions = ProfileVerifierDisableAssertions;
}
explicit ProfileVerifierPass (bool da) : FunctionPass(&ID),
DisableAssertions(da) {
explicit ProfileVerifierPassT (bool da) : FunctionPass(&ID),
DisableAssertions(da) {
}
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<ProfileInfo>();
AU.addRequired<ProfileInfoT<FType, BType> >();
}
const char *getPassName() const {
@ -74,16 +76,296 @@ namespace {
}
/// run - Verify the profile information.
bool runOnFunction(Function &F);
void recurseBasicBlock(const BasicBlock*);
bool runOnFunction(FType &F);
void recurseBasicBlock(const BType*);
bool exitReachable(const Function*);
double ReadOrAssert(ProfileInfo::Edge);
bool exitReachable(const FType*);
double ReadOrAssert(typename ProfileInfoT<FType, BType>::Edge);
void CheckValue(bool, const char*, DetailedBlockInfo*);
};
} // End of anonymous namespace
char ProfileVerifierPass::ID = 0;
typedef ProfileVerifierPassT<Function, BasicBlock> ProfileVerifierPass;
template<class FType, class BType>
void ProfileVerifierPassT<FType, BType>::printDebugInfo(const BType *BB) {
if (BBisPrinted.find(BB) != BBisPrinted.end()) return;
double BBWeight = PI->getExecutionCount(BB);
if (BBWeight == ProfileInfoT<FType, BType>::MissingValue) { BBWeight = 0; }
double inWeight = 0;
int inCount = 0;
std::set<const BType*> ProcessedPreds;
for ( pred_const_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
bbi != bbe; ++bbi ) {
if (ProcessedPreds.insert(*bbi).second) {
typename ProfileInfoT<FType, BType>::Edge E = PI->getEdge(*bbi,BB);
double EdgeWeight = PI->getEdgeWeight(E);
if (EdgeWeight == ProfileInfoT<FType, BType>::MissingValue) { EdgeWeight = 0; }
errs() << "calculated in-edge " << E << ": "
<< format("%20.20g",EdgeWeight) << "\n";
inWeight += EdgeWeight;
inCount++;
}
}
double outWeight = 0;
int outCount = 0;
std::set<const BType*> ProcessedSuccs;
for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
bbi != bbe; ++bbi ) {
if (ProcessedSuccs.insert(*bbi).second) {
typename ProfileInfoT<FType, BType>::Edge E = PI->getEdge(BB,*bbi);
double EdgeWeight = PI->getEdgeWeight(E);
if (EdgeWeight == ProfileInfoT<FType, BType>::MissingValue) { EdgeWeight = 0; }
errs() << "calculated out-edge " << E << ": "
<< format("%20.20g",EdgeWeight) << "\n";
outWeight += EdgeWeight;
outCount++;
}
}
errs() << "Block " << BB->getNameStr() << " in "
<< BB->getParent()->getNameStr() << ":"
<< "BBWeight=" << format("%20.20g",BBWeight) << ","
<< "inWeight=" << format("%20.20g",inWeight) << ","
<< "inCount=" << inCount << ","
<< "outWeight=" << format("%20.20g",outWeight) << ","
<< "outCount" << outCount << "\n";
// mark as visited and recurse into subnodes
BBisPrinted.insert(BB);
for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
bbi != bbe; ++bbi ) {
printDebugInfo(*bbi);
}
}
template<class FType, class BType>
void ProfileVerifierPassT<FType, BType>::debugEntry (DetailedBlockInfo *DI) {
errs() << "TROUBLE: Block " << DI->BB->getNameStr() << " in "
<< DI->BB->getParent()->getNameStr() << ":"
<< "BBWeight=" << format("%20.20g",DI->BBWeight) << ","
<< "inWeight=" << format("%20.20g",DI->inWeight) << ","
<< "inCount=" << DI->inCount << ","
<< "outWeight=" << format("%20.20g",DI->outWeight) << ","
<< "outCount=" << DI->outCount << "\n";
if (!PrintedDebugTree) {
PrintedDebugTree = true;
printDebugInfo(&(DI->BB->getParent()->getEntryBlock()));
}
}
// This compares A and B for equality.
static bool Equals(double A, double B) {
return A == B;
}
// This checks if the function "exit" is reachable from an given function
// via calls, this is necessary to check if a profile is valid despite the
// counts not fitting exactly.
template<class FType, class BType>
bool ProfileVerifierPassT<FType, BType>::exitReachable(const FType *F) {
if (!F) return false;
if (FisVisited.count(F)) return false;
FType *Exit = F->getParent()->getFunction("exit");
if (Exit == F) {
return true;
}
FisVisited.insert(F);
bool exits = false;
for (const_inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
if (const CallInst *CI = dyn_cast<CallInst>(&*I)) {
FType *F = CI->getCalledFunction();
if (F) {
exits |= exitReachable(F);
} else {
// This is a call to a pointer, all bets are off...
exits = true;
}
if (exits) break;
}
}
return exits;
}
#define ASSERTMESSAGE(M) \
{ errs() << "ASSERT:" << (M) << "\n"; \
if (!DisableAssertions) assert(0 && (M)); }
template<class FType, class BType>
double ProfileVerifierPassT<FType, BType>::ReadOrAssert(typename ProfileInfoT<FType, BType>::Edge E) {
double EdgeWeight = PI->getEdgeWeight(E);
if (EdgeWeight == ProfileInfoT<FType, BType>::MissingValue) {
errs() << "Edge " << E << " in Function "
<< ProfileInfoT<FType, BType>::getFunction(E)->getNameStr() << ": ";
ASSERTMESSAGE("Edge has missing value");
return 0;
} else {
if (EdgeWeight < 0) {
errs() << "Edge " << E << " in Function "
<< ProfileInfoT<FType, BType>::getFunction(E)->getNameStr() << ": ";
ASSERTMESSAGE("Edge has negative value");
}
return EdgeWeight;
}
}
template<class FType, class BType>
void ProfileVerifierPassT<FType, BType>::CheckValue(bool Error,
const char *Message,
DetailedBlockInfo *DI) {
if (Error) {
DEBUG(debugEntry(DI));
errs() << "Block " << DI->BB->getNameStr() << " in Function "
<< DI->BB->getParent()->getNameStr() << ": ";
ASSERTMESSAGE(Message);
}
return;
}
// This calculates the Information for a block and then recurses into the
// successors.
template<class FType, class BType>
void ProfileVerifierPassT<FType, BType>::recurseBasicBlock(const BType *BB) {
// Break the recursion by remembering all visited blocks.
if (BBisVisited.find(BB) != BBisVisited.end()) return;
// Use a data structure to store all the information, this can then be handed
// to debug printers.
DetailedBlockInfo DI;
DI.BB = BB;
DI.outCount = DI.inCount = 0;
DI.inWeight = DI.outWeight = 0;
// Read predecessors.
std::set<const BType*> ProcessedPreds;
pred_const_iterator bpi = pred_begin(BB), bpe = pred_end(BB);
// If there are none, check for (0,BB) edge.
if (bpi == bpe) {
DI.inWeight += ReadOrAssert(PI->getEdge(0,BB));
DI.inCount++;
}
for (;bpi != bpe; ++bpi) {
if (ProcessedPreds.insert(*bpi).second) {
DI.inWeight += ReadOrAssert(PI->getEdge(*bpi,BB));
DI.inCount++;
}
}
// Read successors.
std::set<const BType*> ProcessedSuccs;
succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
// If there is an (0,BB) edge, consider it too. (This is done not only when
// there are no successors, but every time; not every function contains
// return blocks with no successors (think loop latch as return block)).
double w = PI->getEdgeWeight(PI->getEdge(BB,0));
if (w != ProfileInfoT<FType, BType>::MissingValue) {
DI.outWeight += w;
DI.outCount++;
}
for (;bbi != bbe; ++bbi) {
if (ProcessedSuccs.insert(*bbi).second) {
DI.outWeight += ReadOrAssert(PI->getEdge(BB,*bbi));
DI.outCount++;
}
}
// Read block weight.
DI.BBWeight = PI->getExecutionCount(BB);
CheckValue(DI.BBWeight == ProfileInfoT<FType, BType>::MissingValue,
"BasicBlock has missing value", &DI);
CheckValue(DI.BBWeight < 0,
"BasicBlock has negative value", &DI);
// Check if this block is a setjmp target.
bool isSetJmpTarget = false;
if (DI.outWeight > DI.inWeight) {
for (typename BType::const_iterator i = BB->begin(), ie = BB->end();
i != ie; ++i) {
if (const CallInst *CI = dyn_cast<CallInst>(&*i)) {
FType *F = CI->getCalledFunction();
if (F && (F->getNameStr() == "_setjmp")) {
isSetJmpTarget = true; break;
}
}
}
}
// Check if this block is eventually reaching exit.
bool isExitReachable = false;
if (DI.inWeight > DI.outWeight) {
for (typename BType::const_iterator i = BB->begin(), ie = BB->end();
i != ie; ++i) {
if (const CallInst *CI = dyn_cast<CallInst>(&*i)) {
FType *F = CI->getCalledFunction();
if (F) {
FisVisited.clear();
isExitReachable |= exitReachable(F);
} else {
// This is a call to a pointer, all bets are off...
isExitReachable = true;
}
if (isExitReachable) break;
}
}
}
if (DI.inCount > 0 && DI.outCount == 0) {
// If this is a block with no successors.
if (!isSetJmpTarget) {
CheckValue(!Equals(DI.inWeight,DI.BBWeight),
"inWeight and BBWeight do not match", &DI);
}
} else if (DI.inCount == 0 && DI.outCount > 0) {
// If this is a block with no predecessors.
if (!isExitReachable)
CheckValue(!Equals(DI.BBWeight,DI.outWeight),
"BBWeight and outWeight do not match", &DI);
} else {
// If this block has successors and predecessors.
if (DI.inWeight > DI.outWeight && !isExitReachable)
CheckValue(!Equals(DI.inWeight,DI.outWeight),
"inWeight and outWeight do not match", &DI);
if (DI.inWeight < DI.outWeight && !isSetJmpTarget)
CheckValue(!Equals(DI.inWeight,DI.outWeight),
"inWeight and outWeight do not match", &DI);
}
// Mark this block as visited, rescurse into successors.
BBisVisited.insert(BB);
for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
bbi != bbe; ++bbi ) {
recurseBasicBlock(*bbi);
}
}
template<class FType, class BType>
bool ProfileVerifierPassT<FType, BType>::runOnFunction(FType &F) {
PI = getAnalysisIfAvailable<ProfileInfoT<FType, BType> >();
if (!PI)
ASSERTMESSAGE("No ProfileInfo available");
// Prepare global variables.
PrintedDebugTree = false;
BBisVisited.clear();
// Fetch entry block and recurse into it.
const BType *entry = &F.getEntryBlock();
recurseBasicBlock(entry);
if (PI->getExecutionCount(&F) != PI->getExecutionCount(entry))
ASSERTMESSAGE("Function count and entry block count do not match");
return false;
}
template<class FType, class BType>
char ProfileVerifierPassT<FType, BType>::ID = 0;
}
static RegisterPass<ProfileVerifierPass>
X("profile-verifier", "Verify profiling information", false, true);
@ -93,252 +375,3 @@ namespace llvm {
}
}
void ProfileVerifierPass::printDebugInfo(const BasicBlock *BB) {
if (BBisPrinted.find(BB) != BBisPrinted.end()) return;
double BBWeight = PI->getExecutionCount(BB);
if (BBWeight == ProfileInfo::MissingValue) { BBWeight = 0; }
double inWeight = 0;
int inCount = 0;
std::set<const BasicBlock*> ProcessedPreds;
for ( pred_const_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
bbi != bbe; ++bbi ) {
if (ProcessedPreds.insert(*bbi).second) {
ProfileInfo::Edge E = PI->getEdge(*bbi,BB);
double EdgeWeight = PI->getEdgeWeight(E);
if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; }
errs() << "calculated in-edge " << E << ": " << EdgeWeight << "\n";
inWeight += EdgeWeight;
inCount++;
}
}
double outWeight = 0;
int outCount = 0;
std::set<const BasicBlock*> ProcessedSuccs;
for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
bbi != bbe; ++bbi ) {
if (ProcessedSuccs.insert(*bbi).second) {
ProfileInfo::Edge E = PI->getEdge(BB,*bbi);
double EdgeWeight = PI->getEdgeWeight(E);
if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; }
errs() << "calculated out-edge " << E << ": " << EdgeWeight << "\n";
outWeight += EdgeWeight;
outCount++;
}
}
errs()<<"Block "<<BB->getNameStr()<<" in "<<BB->getParent()->getNameStr()
<<",BBWeight="<<BBWeight<<",inWeight="<<inWeight<<",inCount="<<inCount
<<",outWeight="<<outWeight<<",outCount"<<outCount<<"\n";
// mark as visited and recurse into subnodes
BBisPrinted.insert(BB);
for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
bbi != bbe; ++bbi ) {
printDebugInfo(*bbi);
}
}
void ProfileVerifierPass::debugEntry (DetailedBlockInfo *DI) {
errs() << "TROUBLE: Block " << DI->BB->getNameStr() << " in "
<< DI->BB->getParent()->getNameStr() << ":";
errs() << "BBWeight=" << DI->BBWeight << ",";
errs() << "inWeight=" << DI->inWeight << ",";
errs() << "inCount=" << DI->inCount << ",";
errs() << "outWeight=" << DI->outWeight << ",";
errs() << "outCount=" << DI->outCount << "\n";
if (!PrintedDebugTree) {
PrintedDebugTree = true;
printDebugInfo(&(DI->BB->getParent()->getEntryBlock()));
}
}
// This compares A and B but considering maybe small differences.
static bool Equals(double A, double B) {
double maxRelativeError = 0.0000001;
if (A == B)
return true;
double relativeError;
if (fabs(B) > fabs(A))
relativeError = fabs((A - B) / B);
else
relativeError = fabs((A - B) / A);
if (relativeError <= maxRelativeError) return true;
return false;
}
// This checks if the function "exit" is reachable from an given function
// via calls, this is necessary to check if a profile is valid despite the
// counts not fitting exactly.
bool ProfileVerifierPass::exitReachable(const Function *F) {
if (!F) return false;
if (FisVisited.count(F)) return false;
Function *Exit = F->getParent()->getFunction("exit");
if (Exit == F) {
return true;
}
FisVisited.insert(F);
bool exits = false;
for (const_inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
if (const CallInst *CI = dyn_cast<CallInst>(&*I)) {
exits |= exitReachable(CI->getCalledFunction());
if (exits) break;
}
}
return exits;
}
#define ASSERTMESSAGE(M) \
errs() << (M) << "\n"; \
if (!DisableAssertions) assert(0 && (M));
double ProfileVerifierPass::ReadOrAssert(ProfileInfo::Edge E) {
double EdgeWeight = PI->getEdgeWeight(E);
if (EdgeWeight == ProfileInfo::MissingValue) {
errs() << "Edge " << E << " in Function "
<< ProfileInfo::getFunction(E)->getNameStr() << ": ";
ASSERTMESSAGE("ASSERT:Edge has missing value");
return 0;
} else {
return EdgeWeight;
}
}
void ProfileVerifierPass::CheckValue(bool Error, const char *Message,
DetailedBlockInfo *DI) {
if (Error) {
DEBUG(debugEntry(DI));
errs() << "Block " << DI->BB->getNameStr() << " in Function "
<< DI->BB->getParent()->getNameStr() << ": ";
ASSERTMESSAGE(Message);
}
return;
}
// This calculates the Information for a block and then recurses into the
// successors.
void ProfileVerifierPass::recurseBasicBlock(const BasicBlock *BB) {
// Break the recursion by remembering all visited blocks.
if (BBisVisited.find(BB) != BBisVisited.end()) return;
// Use a data structure to store all the information, this can then be handed
// to debug printers.
DetailedBlockInfo DI;
DI.BB = BB;
DI.outCount = DI.inCount = 0;
DI.inWeight = DI.outWeight = 0.0;
// Read predecessors.
std::set<const BasicBlock*> ProcessedPreds;
pred_const_iterator bpi = pred_begin(BB), bpe = pred_end(BB);
// If there are none, check for (0,BB) edge.
if (bpi == bpe) {
DI.inWeight += ReadOrAssert(PI->getEdge(0,BB));
DI.inCount++;
}
for (;bpi != bpe; ++bpi) {
if (ProcessedPreds.insert(*bpi).second) {
DI.inWeight += ReadOrAssert(PI->getEdge(*bpi,BB));
DI.inCount++;
}
}
// Read successors.
std::set<const BasicBlock*> ProcessedSuccs;
succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
// If there is an (0,BB) edge, consider it too. (This is done not only when
// there are no successors, but every time; not every function contains
// return blocks with no successors (think loop latch as return block)).
double w = PI->getEdgeWeight(PI->getEdge(BB,0));
if (w != ProfileInfo::MissingValue) {
DI.outWeight += w;
DI.outCount++;
}
for (;bbi != bbe; ++bbi) {
if (ProcessedSuccs.insert(*bbi).second) {
DI.outWeight += ReadOrAssert(PI->getEdge(BB,*bbi));
DI.outCount++;
}
}
// Read block weight.
DI.BBWeight = PI->getExecutionCount(BB);
CheckValue(DI.BBWeight == ProfileInfo::MissingValue,
"ASSERT:BasicBlock has missing value", &DI);
// Check if this block is a setjmp target.
bool isSetJmpTarget = false;
if (DI.outWeight > DI.inWeight) {
for (BasicBlock::const_iterator i = BB->begin(), ie = BB->end();
i != ie; ++i) {
if (const CallInst *CI = dyn_cast<CallInst>(&*i)) {
Function *F = CI->getCalledFunction();
if (F && (F->getNameStr() == "_setjmp")) {
isSetJmpTarget = true; break;
}
}
}
}
// Check if this block is eventually reaching exit.
bool isExitReachable = false;
if (DI.inWeight > DI.outWeight) {
for (BasicBlock::const_iterator i = BB->begin(), ie = BB->end();
i != ie; ++i) {
if (const CallInst *CI = dyn_cast<CallInst>(&*i)) {
FisVisited.clear();
isExitReachable |= exitReachable(CI->getCalledFunction());
if (isExitReachable) break;
}
}
}
if (DI.inCount > 0 && DI.outCount == 0) {
// If this is a block with no successors.
if (!isSetJmpTarget) {
CheckValue(!Equals(DI.inWeight,DI.BBWeight),
"ASSERT:inWeight and BBWeight do not match", &DI);
}
} else if (DI.inCount == 0 && DI.outCount > 0) {
// If this is a block with no predecessors.
if (!isExitReachable)
CheckValue(!Equals(DI.BBWeight,DI.outWeight),
"ASSERT:BBWeight and outWeight do not match", &DI);
} else {
// If this block has successors and predecessors.
if (DI.inWeight > DI.outWeight && !isExitReachable)
CheckValue(!Equals(DI.inWeight,DI.outWeight),
"ASSERT:inWeight and outWeight do not match", &DI);
if (DI.inWeight < DI.outWeight && !isSetJmpTarget)
CheckValue(!Equals(DI.inWeight,DI.outWeight),
"ASSERT:inWeight and outWeight do not match", &DI);
}
// Mark this block as visited, rescurse into successors.
BBisVisited.insert(BB);
for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
bbi != bbe; ++bbi ) {
recurseBasicBlock(*bbi);
}
}
bool ProfileVerifierPass::runOnFunction(Function &F) {
PI = &getAnalysis<ProfileInfo>();
// Prepare global variables.
PrintedDebugTree = false;
BBisVisited.clear();
// Fetch entry block and recurse into it.
const BasicBlock *entry = &F.getEntryBlock();
recurseBasicBlock(entry);
if (!DisableAssertions)
assert((PI->getExecutionCount(&F)==PI->getExecutionCount(entry)) &&
"Function count and entry block count do not match");
return false;
}

View File

@ -357,7 +357,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
// without the other.
SplitAddRecs(Ops, Ty, SE);
// Decend down the pointer's type and attempt to convert the other
// Descend down the pointer's type and attempt to convert the other
// operands into GEP indices, at each level. The first index in a GEP
// indexes into the array implied by the pointer operand; the rest of
// the indices index into the element or field type selected by the
@ -628,7 +628,7 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
BasicBlock *SaveInsertBB = Builder.GetInsertBlock();
BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint();
BasicBlock::iterator NewInsertPt =
next(BasicBlock::iterator(cast<Instruction>(V)));
llvm::next(BasicBlock::iterator(cast<Instruction>(V)));
while (isa<PHINode>(NewInsertPt)) ++NewInsertPt;
V = expandCodeFor(SE.getTruncateExpr(SE.getUnknown(V), Ty), 0,
NewInsertPt);
@ -844,7 +844,7 @@ Value *SCEVExpander::expand(const SCEV *S) {
if (L && S->hasComputableLoopEvolution(L))
InsertPt = L->getHeader()->getFirstNonPHI();
while (isInsertedInstruction(InsertPt))
InsertPt = next(BasicBlock::iterator(InsertPt));
InsertPt = llvm::next(BasicBlock::iterator(InsertPt));
break;
}

View File

@ -659,7 +659,7 @@ unsigned llvm::ComputeNumSignBits(Value *V, const TargetData *TD,
switch (Operator::getOpcode(V)) {
default: break;
case Instruction::SExt:
Tmp = TyBits-cast<IntegerType>(U->getOperand(0)->getType())->getBitWidth();
Tmp = TyBits - U->getOperand(0)->getType()->getScalarSizeInBits();
return ComputeNumSignBits(U->getOperand(0), TD, Depth+1) + Tmp;
case Instruction::AShr:

View File

@ -540,6 +540,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(arm_apcscc);
KEYWORD(arm_aapcscc);
KEYWORD(arm_aapcs_vfpcc);
KEYWORD(msp430_intrcc);
KEYWORD(cc);
KEYWORD(c);

View File

@ -581,6 +581,37 @@ bool LLParser::ParseStandaloneMetadata() {
return false;
}
/// ParseInlineMetadata:
/// !{type %instr}
/// !{...} MDNode
/// !"foo" MDString
bool LLParser::ParseInlineMetadata(Value *&V, PerFunctionState &PFS) {
assert(Lex.getKind() == lltok::Metadata && "Only for Metadata");
V = 0;
Lex.Lex();
if (Lex.getKind() == lltok::lbrace) {
Lex.Lex();
if (ParseTypeAndValue(V, PFS) ||
ParseToken(lltok::rbrace, "expected end of metadata node"))
return true;
Value *Vals[] = { V };
V = MDNode::get(Context, Vals, 1);
return false;
}
// Standalone metadata reference
// !{ ..., !42, ... }
if (!ParseMDNode((MetadataBase *&)V))
return false;
// MDString:
// '!' STRINGCONSTANT
if (ParseMDString((MetadataBase *&)V)) return true;
return false;
}
/// ParseAlias:
/// ::= GlobalVar '=' OptionalVisibility 'alias' OptionalLinkage Aliasee
/// Aliasee
@ -1043,6 +1074,7 @@ bool LLParser::ParseOptionalVisibility(unsigned &Res) {
/// ::= 'arm_apcscc'
/// ::= 'arm_aapcscc'
/// ::= 'arm_aapcs_vfpcc'
/// ::= 'msp430_intrcc'
/// ::= 'cc' UINT
///
bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
@ -1056,6 +1088,7 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
case lltok::kw_arm_apcscc: CC = CallingConv::ARM_APCS; break;
case lltok::kw_arm_aapcscc: CC = CallingConv::ARM_AAPCS; break;
case lltok::kw_arm_aapcs_vfpcc:CC = CallingConv::ARM_AAPCS_VFP; break;
case lltok::kw_msp430_intrcc: CC = CallingConv::MSP430_INTR; break;
case lltok::kw_cc: {
unsigned ArbitraryCC;
Lex.Lex();
@ -1377,15 +1410,23 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
// Parse the argument.
LocTy ArgLoc;
PATypeHolder ArgTy(Type::getVoidTy(Context));
unsigned ArgAttrs1, ArgAttrs2;
unsigned ArgAttrs1 = Attribute::None;
unsigned ArgAttrs2 = Attribute::None;
Value *V;
if (ParseType(ArgTy, ArgLoc) ||
ParseOptionalAttrs(ArgAttrs1, 0) ||
ParseValue(ArgTy, V, PFS) ||
// FIXME: Should not allow attributes after the argument, remove this in
// LLVM 3.0.
ParseOptionalAttrs(ArgAttrs2, 3))
if (ParseType(ArgTy, ArgLoc))
return true;
if (Lex.getKind() == lltok::Metadata) {
if (ParseInlineMetadata(V, PFS))
return true;
} else {
if (ParseOptionalAttrs(ArgAttrs1, 0) ||
ParseValue(ArgTy, V, PFS) ||
// FIXME: Should not allow attributes after the argument, remove this
// in LLVM 3.0.
ParseOptionalAttrs(ArgAttrs2, 3))
return true;
}
ArgList.push_back(ParamInfo(ArgLoc, V, ArgAttrs1|ArgAttrs2));
}

View File

@ -279,7 +279,9 @@ namespace llvm {
LocTy Loc;
return ParseTypeAndBasicBlock(BB, Loc, PFS);
}
bool ParseInlineMetadata(Value *&V, PerFunctionState &PFS);
struct ParamInfo {
LocTy Loc;
Value *V;

View File

@ -69,6 +69,7 @@ namespace lltok {
kw_cc, kw_ccc, kw_fastcc, kw_coldcc,
kw_x86_stdcallcc, kw_x86_fastcallcc,
kw_arm_apcscc, kw_arm_aapcscc, kw_arm_aapcs_vfpcc,
kw_msp430_intrcc,
kw_signext,
kw_zeroext,

View File

@ -413,7 +413,7 @@ uintptr_t Deserializer::ReadInternalRefPtr() {
return GetFinalPtr(E);
}
void Deserializer::BPEntry::SetPtr(BPNode*& FreeList, void* P) {
void BPEntry::SetPtr(BPNode*& FreeList, void* P) {
BPNode* Last = NULL;
for (BPNode* N = Head; N != NULL; N=N->Next) {

View File

@ -38,16 +38,19 @@ DebugMod("agg-antidep-debugmod",
cl::desc("Debug control for aggressive anti-dep breaker"),
cl::init(0), cl::Hidden);
AggressiveAntiDepState::AggressiveAntiDepState(MachineBasicBlock *BB) :
GroupNodes(TargetRegisterInfo::FirstVirtualRegister, 0) {
// Initialize all registers to be in their own group. Initially we
// assign the register to the same-indexed GroupNode.
for (unsigned i = 0; i < TargetRegisterInfo::FirstVirtualRegister; ++i)
GroupNodeIndices[i] = i;
AggressiveAntiDepState::AggressiveAntiDepState(const unsigned TargetRegs,
MachineBasicBlock *BB) :
NumTargetRegs(TargetRegs), GroupNodes(TargetRegs, 0) {
// Initialize the indices to indicate that no registers are live.
std::fill(KillIndices, array_endof(KillIndices), ~0u);
std::fill(DefIndices, array_endof(DefIndices), BB->size());
const unsigned BBSize = BB->size();
for (unsigned i = 0; i < NumTargetRegs; ++i) {
// Initialize all registers to be in their own group. Initially we
// assign the register to the same-indexed GroupNode.
GroupNodeIndices[i] = i;
// Initialize the indices to indicate that no registers are live.
KillIndices[i] = ~0u;
DefIndices[i] = BBSize;
}
}
unsigned AggressiveAntiDepState::GetGroup(unsigned Reg)
@ -64,7 +67,7 @@ void AggressiveAntiDepState::GetGroupRegs(
std::vector<unsigned> &Regs,
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference> *RegRefs)
{
for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) {
for (unsigned Reg = 0; Reg != NumTargetRegs; ++Reg) {
if ((GetGroup(Reg) == Group) && (RegRefs->count(Reg) > 0))
Regs.push_back(Reg);
}
@ -137,7 +140,7 @@ AggressiveAntiDepBreaker::~AggressiveAntiDepBreaker() {
void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) {
assert(State == NULL);
State = new AggressiveAntiDepState(BB);
State = new AggressiveAntiDepState(TRI->getNumRegs(), BB);
bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn());
unsigned *KillIndices = State->GetKillIndices();
@ -220,7 +223,7 @@ void AggressiveAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count,
DEBUG(errs() << "\tRegs:");
unsigned *DefIndices = State->GetDefIndices();
for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) {
for (unsigned Reg = 0; Reg != TRI->getNumRegs(); ++Reg) {
// If Reg is current live, then mark that it can't be renamed as
// we don't know the extent of its live-range anymore (now that it
// has been scheduled). If it is not live but was defined in the

View File

@ -44,6 +44,10 @@ namespace llvm {
} RegisterReference;
private:
/// NumTargetRegs - Number of non-virtual target registers
/// (i.e. TRI->getNumRegs()).
const unsigned NumTargetRegs;
/// GroupNodes - Implements a disjoint-union data structure to
/// form register groups. A node is represented by an index into
/// the vector. A node can "point to" itself to indicate that it
@ -69,7 +73,7 @@ namespace llvm {
unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister];
public:
AggressiveAntiDepState(MachineBasicBlock *BB);
AggressiveAntiDepState(const unsigned TargetRegs, MachineBasicBlock *BB);
/// GetKillIndices - Return the kill indices.
unsigned *GetKillIndices() { return KillIndices; }

View File

@ -1374,6 +1374,7 @@ void AsmPrinter::processDebugLoc(const MachineInstr *MI,
unsigned L = DW->RecordSourceLine(CurDLT.Line, CurDLT.Col,
CurDLT.Scope);
printLabel(L);
O << '\n';
DW->BeginScope(MI, L);
PrevDLT = CurDLT;
}
@ -1837,15 +1838,16 @@ void AsmPrinter::EmitComments(const MachineInstr &MI) const {
// Print source line info.
O.PadToColumn(MAI->getCommentColumn());
O << MAI->getCommentString() << " SrcLine ";
if (DLT.Scope) {
DICompileUnit CU(DLT.Scope);
if (!CU.isNull())
O << CU.getFilename() << " ";
}
O << DLT.Line;
O << MAI->getCommentString() << ' ';
DIScope Scope(DLT.Scope);
// Omit the directory, because it's likely to be long and uninteresting.
if (!Scope.isNull())
O << Scope.getFilename();
else
O << "<unknown>";
O << ':' << DLT.Line;
if (DLT.Col != 0)
O << ":" << DLT.Col;
O << ':' << DLT.Col;
Newline = true;
}
@ -1857,35 +1859,40 @@ void AsmPrinter::EmitComments(const MachineInstr &MI) const {
// We assume a single instruction only has a spill or reload, not
// both.
const MachineMemOperand *MMO;
if (TM.getInstrInfo()->isLoadFromStackSlotPostFE(&MI, FI)) {
if (FrameInfo->isSpillSlotObjectIndex(FI)) {
MMO = *MI.memoperands_begin();
if (Newline) O << '\n';
O.PadToColumn(MAI->getCommentColumn());
O << MAI->getCommentString() << " Reload";
O << MAI->getCommentString() << ' ' << MMO->getSize() << "-byte Reload";
Newline = true;
}
}
else if (TM.getInstrInfo()->hasLoadFromStackSlot(&MI, FI)) {
else if (TM.getInstrInfo()->hasLoadFromStackSlot(&MI, MMO, FI)) {
if (FrameInfo->isSpillSlotObjectIndex(FI)) {
if (Newline) O << '\n';
O.PadToColumn(MAI->getCommentColumn());
O << MAI->getCommentString() << " Folded Reload";
O << MAI->getCommentString() << ' '
<< MMO->getSize() << "-byte Folded Reload";
Newline = true;
}
}
else if (TM.getInstrInfo()->isStoreToStackSlotPostFE(&MI, FI)) {
if (FrameInfo->isSpillSlotObjectIndex(FI)) {
MMO = *MI.memoperands_begin();
if (Newline) O << '\n';
O.PadToColumn(MAI->getCommentColumn());
O << MAI->getCommentString() << " Spill";
O << MAI->getCommentString() << ' ' << MMO->getSize() << "-byte Spill";
Newline = true;
}
}
else if (TM.getInstrInfo()->hasStoreToStackSlot(&MI, FI)) {
else if (TM.getInstrInfo()->hasStoreToStackSlot(&MI, MMO, FI)) {
if (FrameInfo->isSpillSlotObjectIndex(FI)) {
if (Newline) O << '\n';
O.PadToColumn(MAI->getCommentColumn());
O << MAI->getCommentString() << " Folded Spill";
O << MAI->getCommentString() << ' '
<< MMO->getSize() << "-byte Folded Spill";
Newline = true;
}
}

View File

@ -274,7 +274,7 @@ namespace llvm {
};
//===--------------------------------------------------------------------===//
/// DIEString - A string value DIE.
/// DIEString - A string value DIE. This DIE keeps string reference only.
///
class DIEString : public DIEValue {
const StringRef Str;

View File

@ -330,8 +330,8 @@ void DwarfDebug::addSInt(DIE *Die, unsigned Attribute,
Die->addValue(Attribute, Form, Value);
}
/// addString - Add a string attribute data and value.
///
/// addString - Add a string attribute data and value. DIEString only
/// keeps string reference.
void DwarfDebug::addString(DIE *Die, unsigned Attribute, unsigned Form,
const StringRef String) {
DIEValue *Value = new DIEString(String);
@ -393,7 +393,7 @@ void DwarfDebug::addSourceLine(DIE *Die, const DIVariable *V) {
return;
unsigned Line = V->getLineNumber();
unsigned FileID = findCompileUnit(V->getCompileUnit()).getID();
unsigned FileID = findCompileUnit(V->getCompileUnit())->getID();
assert(FileID && "Invalid file id");
addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@ -407,7 +407,7 @@ void DwarfDebug::addSourceLine(DIE *Die, const DIGlobal *G) {
return;
unsigned Line = G->getLineNumber();
unsigned FileID = findCompileUnit(G->getCompileUnit()).getID();
unsigned FileID = findCompileUnit(G->getCompileUnit())->getID();
assert(FileID && "Invalid file id");
addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@ -425,7 +425,7 @@ void DwarfDebug::addSourceLine(DIE *Die, const DISubprogram *SP) {
unsigned Line = SP->getLineNumber();
unsigned FileID = findCompileUnit(SP->getCompileUnit()).getID();
unsigned FileID = findCompileUnit(SP->getCompileUnit())->getID();
assert(FileID && "Invalid file id");
addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@ -440,7 +440,7 @@ void DwarfDebug::addSourceLine(DIE *Die, const DIType *Ty) {
return;
unsigned Line = Ty->getLineNumber();
unsigned FileID = findCompileUnit(CU).getID();
unsigned FileID = findCompileUnit(CU)->getID();
assert(FileID && "Invalid file id");
addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@ -738,13 +738,49 @@ void DwarfDebug::addAddress(DIE *Die, unsigned Attribute,
addBlock(Die, Attribute, 0, Block);
}
/// addToContextOwner - Add Die into the list of its context owner's children.
void DwarfDebug::addToContextOwner(DIE *Die, DIDescriptor Context) {
if (Context.isNull())
ModuleCU->addDie(Die);
else if (Context.isType()) {
DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context.getNode()));
ContextDIE->addChild(Die);
} else if (DIE *ContextDIE = ModuleCU->getDIE(Context.getNode()))
ContextDIE->addChild(Die);
else
ModuleCU->addDie(Die);
}
/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
/// given DIType.
DIE *DwarfDebug::getOrCreateTypeDIE(DIType Ty) {
DIE *TyDIE = ModuleCU->getDIE(Ty.getNode());
if (TyDIE)
return TyDIE;
// Create new type.
TyDIE = new DIE(dwarf::DW_TAG_base_type);
ModuleCU->insertDIE(Ty.getNode(), TyDIE);
if (Ty.isBasicType())
constructTypeDIE(*TyDIE, DIBasicType(Ty.getNode()));
else if (Ty.isCompositeType())
constructTypeDIE(*TyDIE, DICompositeType(Ty.getNode()));
else {
assert(Ty.isDerivedType() && "Unknown kind of DIType");
constructTypeDIE(*TyDIE, DIDerivedType(Ty.getNode()));
}
addToContextOwner(TyDIE, Ty.getContext());
return TyDIE;
}
/// addType - Add a new type attribute to the specified entity.
void DwarfDebug::addType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) {
void DwarfDebug::addType(DIE *Entity, DIType Ty) {
if (Ty.isNull())
return;
// Check for pre-existence.
DIEEntry *Entry = DW_Unit->getDIEEntry(Ty.getNode());
DIEEntry *Entry = ModuleCU->getDIEEntry(Ty.getNode());
// If it exists then use the existing value.
if (Entry) {
@ -754,36 +790,17 @@ void DwarfDebug::addType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) {
// Set up proxy.
Entry = createDIEEntry();
DW_Unit->insertDIEEntry(Ty.getNode(), Entry);
ModuleCU->insertDIEEntry(Ty.getNode(), Entry);
// Construct type.
DIE *Buffer = new DIE(dwarf::DW_TAG_base_type);
if (Ty.isBasicType())
constructTypeDIE(DW_Unit, *Buffer, DIBasicType(Ty.getNode()));
else if (Ty.isCompositeType())
constructTypeDIE(DW_Unit, *Buffer, DICompositeType(Ty.getNode()));
else {
assert(Ty.isDerivedType() && "Unknown kind of DIType");
constructTypeDIE(DW_Unit, *Buffer, DIDerivedType(Ty.getNode()));
}
DIE *Buffer = getOrCreateTypeDIE(Ty);
// Add debug information entry to entity and appropriate context.
DIE *Die = NULL;
DIDescriptor Context = Ty.getContext();
if (!Context.isNull())
Die = DW_Unit->getDIE(Context.getNode());
if (Die)
Die->addChild(Buffer);
else
DW_Unit->addDie(Buffer);
Entry->setEntry(Buffer);
Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
}
/// constructTypeDIE - Construct basic type die from DIBasicType.
void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
DIBasicType BTy) {
void DwarfDebug::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
// Get core information.
StringRef Name = BTy.getName();
Buffer.setTag(dwarf::DW_TAG_base_type);
@ -798,8 +815,7 @@ void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
}
/// constructTypeDIE - Construct derived type die from DIDerivedType.
void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
DIDerivedType DTy) {
void DwarfDebug::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
// Get core information.
StringRef Name = DTy.getName();
uint64_t Size = DTy.getSizeInBits() >> 3;
@ -812,7 +828,7 @@ void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
// Map to main type, void will not have a type.
DIType FromTy = DTy.getTypeDerivedFrom();
addType(DW_Unit, &Buffer, FromTy);
addType(&Buffer, FromTy);
// Add name if not anonymous or intermediate type.
if (!Name.empty())
@ -828,8 +844,7 @@ void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
}
/// constructTypeDIE - Construct type DIE from DICompositeType.
void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
DICompositeType CTy) {
void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
// Get core information.
StringRef Name = CTy.getName();
@ -840,7 +855,7 @@ void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
switch (Tag) {
case dwarf::DW_TAG_vector_type:
case dwarf::DW_TAG_array_type:
constructArrayTypeDIE(DW_Unit, Buffer, &CTy);
constructArrayTypeDIE(Buffer, &CTy);
break;
case dwarf::DW_TAG_enumeration_type: {
DIArray Elements = CTy.getTypeArray();
@ -850,7 +865,7 @@ void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
DIE *ElemDie = NULL;
DIEnumerator Enum(Elements.getElement(i).getNode());
if (!Enum.isNull()) {
ElemDie = constructEnumTypeDIE(DW_Unit, &Enum);
ElemDie = constructEnumTypeDIE(&Enum);
Buffer.addChild(ElemDie);
}
}
@ -860,7 +875,7 @@ void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
// Add return type.
DIArray Elements = CTy.getTypeArray();
DIDescriptor RTy = Elements.getElement(0);
addType(DW_Unit, &Buffer, DIType(RTy.getNode()));
addType(&Buffer, DIType(RTy.getNode()));
// Add prototype flag.
addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
@ -869,7 +884,7 @@ void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
DIDescriptor Ty = Elements.getElement(i);
addType(DW_Unit, Arg, DIType(Ty.getNode()));
addType(Arg, DIType(Ty.getNode()));
Buffer.addChild(Arg);
}
}
@ -891,11 +906,9 @@ void DwarfDebug::constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
continue;
DIE *ElemDie = NULL;
if (Element.getTag() == dwarf::DW_TAG_subprogram)
ElemDie = createSubprogramDIE(DW_Unit,
DISubprogram(Element.getNode()));
ElemDie = createSubprogramDIE(DISubprogram(Element.getNode()));
else
ElemDie = createMemberDIE(DW_Unit,
DIDerivedType(Element.getNode()));
ElemDie = createMemberDIE(DIDerivedType(Element.getNode()));
Buffer.addChild(ElemDie);
}
@ -944,33 +957,32 @@ void DwarfDebug::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
if (L)
addSInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, L);
if (H)
addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H);
addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H);
Buffer.addChild(DW_Subrange);
}
/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
void DwarfDebug::constructArrayTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
void DwarfDebug::constructArrayTypeDIE(DIE &Buffer,
DICompositeType *CTy) {
Buffer.setTag(dwarf::DW_TAG_array_type);
if (CTy->getTag() == dwarf::DW_TAG_vector_type)
addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1);
// Emit derived type.
addType(DW_Unit, &Buffer, CTy->getTypeDerivedFrom());
addType(&Buffer, CTy->getTypeDerivedFrom());
DIArray Elements = CTy->getTypeArray();
// Get an anonymous type for index type.
DIE *IdxTy = DW_Unit->getIndexTyDie();
DIE *IdxTy = ModuleCU->getIndexTyDie();
if (!IdxTy) {
// Construct an anonymous type for index type.
IdxTy = new DIE(dwarf::DW_TAG_base_type);
addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
dwarf::DW_ATE_signed);
DW_Unit->addDie(IdxTy);
DW_Unit->setIndexTyDie(IdxTy);
ModuleCU->addDie(IdxTy);
ModuleCU->setIndexTyDie(IdxTy);
}
// Add subranges to array type.
@ -982,7 +994,7 @@ void DwarfDebug::constructArrayTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
}
/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
DIE *DwarfDebug::constructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy) {
DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator *ETy) {
DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
StringRef Name = ETy->getName();
addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
@ -992,8 +1004,7 @@ DIE *DwarfDebug::constructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy) {
}
/// createGlobalVariableDIE - Create new DIE using GV.
DIE *DwarfDebug::createGlobalVariableDIE(CompileUnit *DW_Unit,
const DIGlobalVariable &GV) {
DIE *DwarfDebug::createGlobalVariableDIE(const DIGlobalVariable &GV) {
// If the global variable was optmized out then no need to create debug info
// entry.
if (!GV.getGlobal()) return NULL;
@ -1014,7 +1025,7 @@ DIE *DwarfDebug::createGlobalVariableDIE(CompileUnit *DW_Unit,
addString(GVDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
LinkageName);
}
addType(DW_Unit, GVDie, GV.getType());
addType(GVDie, GV.getType());
if (!GV.isLocalToUnit())
addUInt(GVDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
addSourceLine(GVDie, &GV);
@ -1030,13 +1041,13 @@ DIE *DwarfDebug::createGlobalVariableDIE(CompileUnit *DW_Unit,
}
/// createMemberDIE - Create new member DIE.
DIE *DwarfDebug::createMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT){
DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) {
DIE *MemberDie = new DIE(DT.getTag());
StringRef Name = DT.getName();
if (!Name.empty())
addString(MemberDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
addType(DW_Unit, MemberDie, DT.getTypeDerivedFrom());
addType(MemberDie, DT.getTypeDerivedFrom());
addSourceLine(MemberDie, &DT);
@ -1073,21 +1084,27 @@ DIE *DwarfDebug::createMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT){
addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
if (DT.isProtected())
addUInt(MemberDie, dwarf::DW_AT_accessibility, 0,
addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
dwarf::DW_ACCESS_protected);
else if (DT.isPrivate())
addUInt(MemberDie, dwarf::DW_AT_accessibility, 0,
addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
dwarf::DW_ACCESS_private);
else if (DT.getTag() == dwarf::DW_TAG_inheritance)
addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
dwarf::DW_ACCESS_public);
if (DT.isVirtual())
addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag,
dwarf::DW_VIRTUALITY_virtual);
return MemberDie;
}
/// createSubprogramDIE - Create new DIE using SP.
DIE *DwarfDebug::createSubprogramDIE(CompileUnit *DW_Unit,
const DISubprogram &SP,
bool IsConstructor,
bool IsInlined) {
DIE *SPDie = new DIE(dwarf::DW_TAG_subprogram);
DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
DIE *SPDie = ModuleCU->getDIE(SP.getNode());
if (SPDie)
return SPDie;
SPDie = new DIE(dwarf::DW_TAG_subprogram);
addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName());
StringRef LinkageName = SP.getLinkageName();
@ -1103,9 +1120,6 @@ DIE *DwarfDebug::createSubprogramDIE(CompileUnit *DW_Unit,
}
addSourceLine(SPDie, &SP);
DICompositeType SPTy = SP.getType();
DIArray Args = SPTy.getTypeArray();
// Add prototyped tag, if C or ObjC.
unsigned Lang = SP.getCompileUnit().getLanguage();
if (Lang == dwarf::DW_LANG_C99 || Lang == dwarf::DW_LANG_C89 ||
@ -1113,98 +1127,56 @@ DIE *DwarfDebug::createSubprogramDIE(CompileUnit *DW_Unit,
addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
// Add Return Type.
DICompositeType SPTy = SP.getType();
DIArray Args = SPTy.getTypeArray();
unsigned SPTag = SPTy.getTag();
if (!IsConstructor) {
if (Args.isNull() || SPTag != dwarf::DW_TAG_subroutine_type)
addType(DW_Unit, SPDie, SPTy);
else
addType(DW_Unit, SPDie, DIType(Args.getElement(0).getNode()));
if (Args.isNull() || SPTag != dwarf::DW_TAG_subroutine_type)
addType(SPDie, SPTy);
else
addType(SPDie, DIType(Args.getElement(0).getNode()));
unsigned VK = SP.getVirtuality();
if (VK) {
addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK);
DIEBlock *Block = new DIEBlock();
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
addUInt(Block, 0, dwarf::DW_FORM_data1, SP.getVirtualIndex());
addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
ContainingTypeMap.insert(std::make_pair(SPDie, WeakVH(SP.getContainingType().getNode())));
}
if (!SP.isDefinition()) {
if (MakeDecl || !SP.isDefinition()) {
addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
// Add arguments. Do not add arguments for subprogram definition. They will
// be handled through RecordVariable.
// be handled while processing variables.
DICompositeType SPTy = SP.getType();
DIArray Args = SPTy.getTypeArray();
unsigned SPTag = SPTy.getTag();
if (SPTag == dwarf::DW_TAG_subroutine_type)
for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
addType(DW_Unit, Arg, DIType(Args.getElement(i).getNode()));
addType(Arg, DIType(Args.getElement(i).getNode()));
addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); // ??
SPDie->addChild(Arg);
}
}
// DW_TAG_inlined_subroutine may refer to this DIE.
DW_Unit->insertDIE(SP.getNode(), SPDie);
ModuleCU->insertDIE(SP.getNode(), SPDie);
return SPDie;
}
/// findCompileUnit - Get the compile unit for the given descriptor.
///
CompileUnit &DwarfDebug::findCompileUnit(DICompileUnit Unit) const {
CompileUnit *DwarfDebug::findCompileUnit(DICompileUnit Unit) {
DenseMap<Value *, CompileUnit *>::const_iterator I =
CompileUnitMap.find(Unit.getNode());
assert(I != CompileUnitMap.end() && "Missing compile unit.");
return *I->second;
}
/// createDbgScopeVariable - Create a new scope variable.
///
DIE *DwarfDebug::createDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) {
// Get the descriptor.
const DIVariable &VD = DV->getVariable();
StringRef Name = VD.getName();
if (Name.empty())
return NULL;
// Translate tag to proper Dwarf tag. The result variable is dropped for
// now.
unsigned Tag;
switch (VD.getTag()) {
case dwarf::DW_TAG_return_variable:
return NULL;
case dwarf::DW_TAG_arg_variable:
Tag = dwarf::DW_TAG_formal_parameter;
break;
case dwarf::DW_TAG_auto_variable: // fall thru
default:
Tag = dwarf::DW_TAG_variable;
break;
}
// Define variable debug information entry.
DIE *VariableDie = new DIE(Tag);
addString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
// Add source line info if available.
addSourceLine(VariableDie, &VD);
// Add variable type.
// FIXME: isBlockByrefVariable should be reformulated in terms of complex
// addresses instead.
if (VD.isBlockByrefVariable())
addType(Unit, VariableDie, getBlockByrefType(VD.getType(), Name));
else
addType(Unit, VariableDie, VD.getType());
// Add variable address.
// Variables for abstract instances of inlined functions don't get a
// location.
MachineLocation Location;
unsigned FrameReg;
int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(), FrameReg);
Location.set(FrameReg, Offset);
if (VD.hasComplexAddress())
addComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
else if (VD.isBlockByrefVariable())
addBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
else
addAddress(VariableDie, dwarf::DW_AT_location, Location);
return VariableDie;
if (I == CompileUnitMap.end())
return constructCompileUnit(Unit.getNode());
return I->second;
}
/// getUpdatedDbgScope - Find or create DbgScope assicated with the instruction.
@ -1295,6 +1267,28 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
DIE *SPDie = ModuleCU->getDIE(SPNode);
assert (SPDie && "Unable to find subprogram DIE!");
DISubprogram SP(SPNode);
if (SP.isDefinition() && !SP.getContext().isCompileUnit()) {
addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
// Add arguments.
DICompositeType SPTy = SP.getType();
DIArray Args = SPTy.getTypeArray();
unsigned SPTag = SPTy.getTag();
if (SPTag == dwarf::DW_TAG_subroutine_type)
for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
addType(Arg, DIType(Args.getElement(i).getNode()));
addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); // ??
SPDie->addChild(Arg);
}
DIE *SPDeclDie = SPDie;
SPDie = new DIE(dwarf::DW_TAG_subprogram);
addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
SPDeclDie);
ModuleCU->addDie(SPDie);
}
addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
DWLabel("func_begin", SubprogramCount));
addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
@ -1305,19 +1299,6 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
if (!DISubprogram(SPNode).isLocalToUnit())
addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
// If there are global variables at this scope then add their dies.
for (SmallVector<WeakVH, 4>::iterator SGI = ScopedGVs.begin(),
SGE = ScopedGVs.end(); SGI != SGE; ++SGI) {
MDNode *N = dyn_cast_or_null<MDNode>(*SGI);
if (!N) continue;
DIGlobalVariable GV(N);
if (GV.getContext().getNode() == SPNode) {
DIE *ScopedGVDie = createGlobalVariableDIE(ModuleCU, GV);
if (ScopedGVDie)
SPDie->addChild(ScopedGVDie);
}
}
return SPDie;
}
@ -1401,8 +1382,7 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
/// constructVariableDIE - Construct a DIE for the given DbgVariable.
DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV,
DbgScope *Scope, CompileUnit *Unit) {
DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
// Get the descriptor.
const DIVariable &VD = DV->getVariable();
StringRef Name = VD.getName();
@ -1451,9 +1431,9 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV,
// FIXME: isBlockByrefVariable should be reformulated in terms of complex
// addresses instead.
if (VD.isBlockByrefVariable())
addType(Unit, VariableDie, getBlockByrefType(VD.getType(), Name));
addType(VariableDie, getBlockByrefType(VD.getType(), Name));
else
addType(Unit, VariableDie, VD.getType());
addType(VariableDie, VD.getType());
}
// Add variable address.
@ -1522,7 +1502,7 @@ DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {
// Add variables to scope.
SmallVector<DbgVariable *, 8> &Variables = Scope->getVariables();
for (unsigned i = 0, N = Variables.size(); i < N; ++i) {
DIE *VariableDIE = constructVariableDIE(Variables[i], Scope, ModuleCU);
DIE *VariableDIE = constructVariableDIE(Variables[i], Scope);
if (VariableDIE)
ScopeDIE->addChild(VariableDIE);
}
@ -1579,7 +1559,7 @@ unsigned DwarfDebug::GetOrCreateSourceID(StringRef DirName, StringRef FileName)
return SrcId;
}
void DwarfDebug::constructCompileUnit(MDNode *N) {
CompileUnit *DwarfDebug::constructCompileUnit(MDNode *N) {
DICompileUnit DIUnit(N);
StringRef FN = DIUnit.getFilename();
StringRef Dir = DIUnit.getDirectory();
@ -1618,6 +1598,7 @@ void DwarfDebug::constructCompileUnit(MDNode *N) {
CompileUnitMap[DIUnit.getNode()] = Unit;
CompileUnits.push_back(Unit);
return Unit;
}
void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
@ -1631,14 +1612,16 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
if (ModuleCU->getDIE(DI_GV.getNode()))
return;
DIE *VariableDie = createGlobalVariableDIE(ModuleCU, DI_GV);
DIE *VariableDie = createGlobalVariableDIE(DI_GV);
if (!VariableDie)
return;
// Add to map.
ModuleCU->insertDIE(N, VariableDie);
// Add to context owner.
ModuleCU->getCUDie()->addChild(VariableDie);
addToContextOwner(VariableDie, DI_GV.getContext());
// Expose as global. FIXME - need to check external flag.
ModuleCU->addGlobal(DI_GV.getName(), VariableDie);
@ -1663,13 +1646,15 @@ void DwarfDebug::constructSubprogramDIE(MDNode *N) {
// class type.
return;
DIE *SubprogramDie = createSubprogramDIE(ModuleCU, SP);
DIE *SubprogramDie = createSubprogramDIE(SP);
// Add to map.
ModuleCU->insertDIE(N, SubprogramDie);
// Add to context owner.
ModuleCU->getCUDie()->addChild(SubprogramDie);
if (SP.getContext().getNode() == SP.getCompileUnit().getNode())
if (TopLevelDIEs.insert(SubprogramDie))
TopLevelDIEsVector.push_back(SubprogramDie);
// Expose as global.
ModuleCU->addGlobal(SP.getName(), SubprogramDie);
@ -1709,21 +1694,16 @@ void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) {
if (!ModuleCU)
ModuleCU = CompileUnits[0];
// Create DIEs for each of the externally visible global variables.
for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(),
E = DbgFinder.global_variable_end(); I != E; ++I) {
DIGlobalVariable GV(*I);
if (GV.getContext().getNode() != GV.getCompileUnit().getNode())
ScopedGVs.push_back(*I);
else
constructGlobalVariableDIE(*I);
}
// Create DIEs for each subprogram.
for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(),
E = DbgFinder.subprogram_end(); I != E; ++I)
constructSubprogramDIE(*I);
// Create DIEs for each global variable.
for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(),
E = DbgFinder.global_variable_end(); I != E; ++I)
constructGlobalVariableDIE(*I);
MMI = mmi;
shouldEmit = true;
MMI->setDebugInfoAvailability(true);
@ -1770,6 +1750,22 @@ void DwarfDebug::endModule() {
addUInt(ISP, dwarf::DW_AT_inline, 0, dwarf::DW_INL_inlined);
}
// Insert top level DIEs.
for (SmallVector<DIE *, 4>::iterator TI = TopLevelDIEsVector.begin(),
TE = TopLevelDIEsVector.end(); TI != TE; ++TI)
ModuleCU->getCUDie()->addChild(*TI);
for (DenseMap<DIE *, WeakVH>::iterator CI = ContainingTypeMap.begin(),
CE = ContainingTypeMap.end(); CI != CE; ++CI) {
DIE *SPDie = CI->first;
MDNode *N = dyn_cast_or_null<MDNode>(CI->second);
if (!N) continue;
DIE *NDie = ModuleCU->getDIE(N);
if (!NDie) continue;
addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
addDIEEntry(NDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
}
// Standard sections final addresses.
Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getTextSection());
EmitLabel("text_end", 0);
@ -1898,6 +1894,7 @@ void DwarfDebug::endScope(const MachineInstr *MI) {
unsigned Label = MMI->NextLabelID();
Asm->printLabel(Label);
O << '\n';
SmallVector<DbgScope *, 2> &SD = I->second;
for (SmallVector<DbgScope *, 2>::iterator SDI = SD.begin(), SDE = SD.end();
@ -2092,17 +2089,15 @@ void DwarfDebug::endFunction(MachineFunction *MF) {
MMI->getFrameMoves()));
// Clear debug info
if (CurrentFnDbgScope) {
CurrentFnDbgScope = NULL;
DbgScopeMap.clear();
DbgScopeBeginMap.clear();
DbgScopeEndMap.clear();
ConcreteScopes.clear();
AbstractScopesList.clear();
}
CurrentFnDbgScope = NULL;
DbgScopeMap.clear();
DbgScopeBeginMap.clear();
DbgScopeEndMap.clear();
ConcreteScopes.clear();
AbstractScopesList.clear();
Lines.clear();
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
}
@ -2337,13 +2332,16 @@ void DwarfDebug::emitDIE(DIE *Die) {
}
}
/// emitDebugInfo / emitDebugInfoPerCU - Emit the debug info section.
/// emitDebugInfo - Emit the debug info section.
///
void DwarfDebug::emitDebugInfoPerCU(CompileUnit *Unit) {
DIE *Die = Unit->getCUDie();
void DwarfDebug::emitDebugInfo() {
// Start debug info section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfInfoSection());
DIE *Die = ModuleCU->getCUDie();
// Emit the compile units header.
EmitLabel("info_begin", Unit->getID());
EmitLabel("info_begin", ModuleCU->getID());
// Emit size of content not including length itself
unsigned ContentSize = Die->getSize() +
@ -2364,17 +2362,10 @@ void DwarfDebug::emitDebugInfoPerCU(CompileUnit *Unit) {
Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
EmitLabel("info_end", Unit->getID());
EmitLabel("info_end", ModuleCU->getID());
Asm->EOL();
}
void DwarfDebug::emitDebugInfo() {
// Start debug info section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfInfoSection());
emitDebugInfoPerCU(ModuleCU);
}
/// emitAbbreviations - Emit the abbreviation section.
@ -2534,9 +2525,9 @@ void DwarfDebug::emitDebugLines() {
std::pair<unsigned, unsigned> SourceID =
getSourceDirectoryAndFileIds(LineInfo.getSourceID());
O << '\t' << MAI->getCommentString() << ' '
<< getSourceDirectoryName(SourceID.first) << ' '
<< getSourceDirectoryName(SourceID.first) << '/'
<< getSourceFileName(SourceID.second)
<<" :" << utostr_32(LineInfo.getLine()) << '\n';
<< ':' << utostr_32(LineInfo.getLine()) << '\n';
}
// Define the line address.
@ -2672,24 +2663,30 @@ DwarfDebug::emitFunctionDebugFrame(const FunctionDebugFrameInfo&DebugFrameInfo){
Asm->EOL();
}
void DwarfDebug::emitDebugPubNamesPerCU(CompileUnit *Unit) {
EmitDifference("pubnames_end", Unit->getID(),
"pubnames_begin", Unit->getID(), true);
/// emitDebugPubNames - Emit visible names into a debug pubnames section.
///
void DwarfDebug::emitDebugPubNames() {
// Start the dwarf pubnames section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfPubNamesSection());
EmitDifference("pubnames_end", ModuleCU->getID(),
"pubnames_begin", ModuleCU->getID(), true);
Asm->EOL("Length of Public Names Info");
EmitLabel("pubnames_begin", Unit->getID());
EmitLabel("pubnames_begin", ModuleCU->getID());
Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF Version");
EmitSectionOffset("info_begin", "section_info",
Unit->getID(), 0, true, false);
ModuleCU->getID(), 0, true, false);
Asm->EOL("Offset of Compilation Unit Info");
EmitDifference("info_end", Unit->getID(), "info_begin", Unit->getID(),
EmitDifference("info_end", ModuleCU->getID(), "info_begin", ModuleCU->getID(),
true);
Asm->EOL("Compilation Unit Length");
const StringMap<DIE*> &Globals = Unit->getGlobals();
const StringMap<DIE*> &Globals = ModuleCU->getGlobals();
for (StringMap<DIE*>::const_iterator
GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) {
const char *Name = GI->getKeyData();
@ -2700,21 +2697,11 @@ void DwarfDebug::emitDebugPubNamesPerCU(CompileUnit *Unit) {
}
Asm->EmitInt32(0); Asm->EOL("End Mark");
EmitLabel("pubnames_end", Unit->getID());
EmitLabel("pubnames_end", ModuleCU->getID());
Asm->EOL();
}
/// emitDebugPubNames - Emit visible names into a debug pubnames section.
///
void DwarfDebug::emitDebugPubNames() {
// Start the dwarf pubnames section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfPubNamesSection());
emitDebugPubNamesPerCU(ModuleCU);
}
void DwarfDebug::emitDebugPubTypes() {
// Start the dwarf pubnames section.
Asm->OutStreamer.SwitchSection(

View File

@ -154,12 +154,14 @@ class DwarfDebug : public Dwarf {
/// (at the end of the module) as DW_AT_inline.
SmallPtrSet<DIE *, 4> InlinedSubprogramDIEs;
DenseMap<DIE *, WeakVH> ContainingTypeMap;
/// AbstractSubprogramDIEs - Collection of abstruct subprogram DIEs.
SmallPtrSet<DIE *, 4> AbstractSubprogramDIEs;
/// ScopedGVs - Tracks global variables that are not at file scope.
/// For example void f() { static int b = 42; }
SmallVector<WeakVH, 4> ScopedGVs;
/// TopLevelDIEs - Collection of top level DIEs.
SmallPtrSet<DIE *, 4> TopLevelDIEs;
SmallVector<DIE *, 4> TopLevelDIEsVector;
typedef SmallVector<DbgScope *, 2> ScopeVector;
typedef DenseMap<const MachineInstr *, ScopeVector>
@ -307,53 +309,52 @@ class DwarfDebug : public Dwarf {
void addBlockByrefAddress(DbgVariable *&DV, DIE *Die, unsigned Attribute,
const MachineLocation &Location);
/// addToContextOwner - Add Die into the list of its context owner's children.
void addToContextOwner(DIE *Die, DIDescriptor Context);
/// addType - Add a new type attribute to the specified entity.
void addType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty);
void addType(DIE *Entity, DIType Ty);
/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
/// given DIType.
DIE *getOrCreateTypeDIE(DIType Ty);
void addPubTypes(DISubprogram SP);
/// constructTypeDIE - Construct basic type die from DIBasicType.
void constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
void constructTypeDIE(DIE &Buffer,
DIBasicType BTy);
/// constructTypeDIE - Construct derived type die from DIDerivedType.
void constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
void constructTypeDIE(DIE &Buffer,
DIDerivedType DTy);
/// constructTypeDIE - Construct type DIE from DICompositeType.
void constructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
void constructTypeDIE(DIE &Buffer,
DICompositeType CTy);
/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
void constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy);
/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
void constructArrayTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
void constructArrayTypeDIE(DIE &Buffer,
DICompositeType *CTy);
/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
DIE *constructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy);
DIE *constructEnumTypeDIE(DIEnumerator *ETy);
/// createGlobalVariableDIE - Create new DIE using GV.
DIE *createGlobalVariableDIE(CompileUnit *DW_Unit,
const DIGlobalVariable &GV);
DIE *createGlobalVariableDIE(const DIGlobalVariable &GV);
/// createMemberDIE - Create new member DIE.
DIE *createMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT);
DIE *createMemberDIE(const DIDerivedType &DT);
/// createSubprogramDIE - Create new DIE using SP.
DIE *createSubprogramDIE(CompileUnit *DW_Unit,
const DISubprogram &SP,
bool IsConstructor = false,
bool IsInlined = false);
DIE *createSubprogramDIE(const DISubprogram &SP, bool MakeDecl = false);
/// findCompileUnit - Get the compile unit for the given descriptor.
///
CompileUnit &findCompileUnit(DICompileUnit Unit) const;
/// createDbgScopeVariable - Create a new scope variable.
///
DIE *createDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit);
CompileUnit *findCompileUnit(DICompileUnit Unit);
/// getUpdatedDbgScope - Find or create DbgScope assicated with
/// the instruction. Initialize scope and update scope hierarchy.
@ -384,7 +385,7 @@ class DwarfDebug : public Dwarf {
DIE *constructInlinedScopeDIE(DbgScope *Scope);
/// constructVariableDIE - Construct a DIE for the given DbgVariable.
DIE *constructVariableDIE(DbgVariable *DV, DbgScope *S, CompileUnit *Unit);
DIE *constructVariableDIE(DbgVariable *DV, DbgScope *S);
/// constructScopeDIE - Construct a DIE for this scope.
DIE *constructScopeDIE(DbgScope *Scope);
@ -405,10 +406,8 @@ class DwarfDebug : public Dwarf {
///
void computeSizeAndOffsets();
/// EmitDebugInfo / emitDebugInfoPerCU - Emit the debug info section.
/// EmitDebugInfo - Emit the debug info section.
///
void emitDebugInfoPerCU(CompileUnit *Unit);
void emitDebugInfo();
/// emitAbbreviations - Emit the abbreviation section.
@ -432,8 +431,6 @@ class DwarfDebug : public Dwarf {
/// section.
void emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo);
void emitDebugPubNamesPerCU(CompileUnit *Unit);
/// emitDebugPubNames - Emit visible names into a debug pubnames section.
///
void emitDebugPubNames();
@ -488,7 +485,7 @@ class DwarfDebug : public Dwarf {
/// as well.
unsigned GetOrCreateSourceID(StringRef DirName, StringRef FileName);
void constructCompileUnit(MDNode *N);
CompileUnit *constructCompileUnit(MDNode *N);
void constructGlobalVariableDIE(MDNode *N);

View File

@ -292,14 +292,13 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
Asm->EmitULEB128Bytes(is4Byte ? 4 : 8);
Asm->EOL("Augmentation size");
// We force 32-bits here because we've encoded our LSDA in the CIE with
// `dwarf::DW_EH_PE_sdata4'. And the CIE and FDE should agree.
if (EHFrameInfo.hasLandingPads)
EmitReference("exception", EHFrameInfo.Number, true, false);
else {
if (is4Byte)
Asm->EmitInt32((int)0);
else
Asm->EmitInt64((int)0);
}
EmitReference("exception", EHFrameInfo.Number, true, true);
else
Asm->EmitInt32((int)0);
Asm->EOL("Language Specific Data Area");
} else {
Asm->EmitULEB128Bytes(0);

View File

@ -119,7 +119,6 @@ class DwarfException : public Dwarf {
static inline unsigned getTombstoneKey() { return -2U; }
static unsigned getHashValue(const unsigned &Key) { return Key; }
static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; }
static bool isPod() { return true; }
};
/// PadRange - Structure holding a try-range and the associated landing pad.

Some files were not shown because too many files have changed in this diff Show More