Import LLVM r74383.

This commit is contained in:
Ed Schouten 2009-06-27 10:44:33 +00:00
parent f76359690a
commit f859468f5a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/llvm/dist/; revision=195098
svn path=/vendor/llvm/llvm-r74383/; revision=195100; tag=vendor/llvm/llvm-r74383
373 changed files with 9551 additions and 3588 deletions

View File

@ -236,6 +236,7 @@ add_subdirectory(lib/Transforms/Hello)
add_subdirectory(lib/Linker)
add_subdirectory(lib/Analysis)
add_subdirectory(lib/Analysis/IPA)
add_subdirectory(lib/MC)
set(LLVM_ENUM_ASM_PRINTERS "")
foreach(t ${LLVM_TARGETS_TO_BUILD})

View File

@ -198,6 +198,7 @@ install-bytecode:: install-bytecode-local
ifdef LLVMC_PLUGIN
LIBRARYNAME := $(patsubst %,plugin_llvmc_%,$(LLVMC_PLUGIN))
CPP.Flags += -DLLVMC_PLUGIN_NAME=$(LLVMC_PLUGIN)
REQUIRES_EH := 1
# Build a dynamic library if the user runs `make` directly from the plugin
@ -213,6 +214,49 @@ endif
endif # LLVMC_PLUGIN
ifdef LLVMC_BASED_DRIVER
TOOLNAME = $(LLVMC_BASED_DRIVER)
LLVMLIBS = CompilerDriver.a
LINK_COMPONENTS = support system
REQUIRES_EH := 1
# Preprocessor magic that generates references to static variables in built-in
# plugins.
ifneq ($(LLVMC_BUILTIN_PLUGINS),)
USEDLIBS += $(patsubst %,plugin_llvmc_%.a,$(LLVMC_BUILTIN_PLUGINS))
LLVMC_BUILTIN_PLUGIN_1 = $(word 1, $(LLVMC_BUILTIN_PLUGINS))
LLVMC_BUILTIN_PLUGIN_2 = $(word 2, $(LLVMC_BUILTIN_PLUGINS))
LLVMC_BUILTIN_PLUGIN_3 = $(word 3, $(LLVMC_BUILTIN_PLUGINS))
LLVMC_BUILTIN_PLUGIN_4 = $(word 4, $(LLVMC_BUILTIN_PLUGINS))
LLVMC_BUILTIN_PLUGIN_5 = $(word 5, $(LLVMC_BUILTIN_PLUGINS))
ifneq ($(LLVMC_BUILTIN_PLUGIN_1),)
CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_1=$(LLVMC_BUILTIN_PLUGIN_1)
endif
ifneq ($(LLVMC_BUILTIN_PLUGIN_2),)
CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_2=$(LLVMC_BUILTIN_PLUGIN_2)
endif
ifneq ($(LLVMC_BUILTIN_PLUGIN_3),)
CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_3=$(LLVMC_BUILTIN_PLUGIN_3)
endif
ifneq ($(LLVMC_BUILTIN_PLUGIN_4),)
CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_4=$(LLVMC_BUILTIN_PLUGIN_4)
endif
ifneq ($(LLVMC_BUILTIN_PLUGIN_5),)
CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_5=$(LLVMC_BUILTIN_PLUGIN_5)
endif
endif
endif # LLVMC_BASED_DRIVER
###############################################################################
# VARIABLES: Set up various variables based on configuration data
###############################################################################

View File

@ -829,6 +829,9 @@ if test "$ENABLE_THREADS" -eq 1 ; then
AC_SEARCH_LIBS(pthread_rwlock_init,pthread,
AC_DEFINE([HAVE_PTHREAD_RWLOCK_INIT],[1],
[Have pthread_rwlock_init]))
AC_SEARCH_LIBS(pthread_getspecific,pthread,
AC_DEFINE([HAVE_PTHREAD_GETSPECIFIC],[1],
[Have pthread_getspecific]))
fi
dnl Allow extra x86-disassembler library

View File

@ -13,7 +13,6 @@
LEVEL := ../../..
LIBRARYNAME := llvm_analysis
DONT_BUILD_RELINKED := 1
UsedComponents := analysis
UsedOcamlInterfaces := llvm

View File

@ -13,7 +13,6 @@
LEVEL := ../../..
LIBRARYNAME := llvm_bitreader
DONT_BUILD_RELINKED := 1
UsedComponents := bitreader
UsedOcamlInterfaces := llvm

View File

@ -13,7 +13,6 @@
LEVEL := ../../..
LIBRARYNAME := llvm_bitwriter
DONT_BUILD_RELINKED := 1
UsedComponents := bitwriter
UsedOcamlInterfaces := llvm

View File

@ -13,7 +13,6 @@
LEVEL := ../../..
LIBRARYNAME := llvm_executionengine
DONT_BUILD_RELINKED := 1
UsedComponents := executionengine jit interpreter native
UsedOcamlInterfaces := llvm llvm_target

View File

@ -16,6 +16,7 @@
\*===----------------------------------------------------------------------===*/
#include "llvm-c/ExecutionEngine.h"
#include "llvm-c/Target.h"
#include "caml/alloc.h"
#include "caml/custom.h"
#include "caml/fail.h"
@ -23,6 +24,12 @@
#include <string.h>
#include <assert.h>
/* Force the LLVM interpreter, JIT, and native target to be linked in. */
void llvm_initialize(void) {
LLVMLinkInInterpreter();
LLVMLinkInJIT();
LLVMInitializeNativeTarget();
}
/* Can't use the recommended caml_named_value mechanism for backwards
compatibility reasons. This is largely equivalent. */

View File

@ -13,7 +13,6 @@
LEVEL := ../../..
LIBRARYNAME := llvm
DONT_BUILD_RELINKED := 1
UsedComponents := core
UsedOcamLibs := llvm

View File

@ -13,7 +13,6 @@
LEVEL := ../../..
LIBRARYNAME := llvm_target
DONT_BUILD_RELINKED := 1
UsedComponents := target
UsedOcamlInterfaces := llvm

View File

@ -64,6 +64,8 @@ check_symbol_exists(mallinfo malloc.h HAVE_MALLINFO)
check_symbol_exists(malloc_zone_statistics malloc/malloc.h
HAVE_MALLOC_ZONE_STATISTICS)
check_symbol_exists(pthread_mutex_lock pthread.h HAVE_PTHREAD_MUTEX_LOCK)
check_symbol_exists(pthread_rwlock_init pthread.h HAVE_PTHREAD_RWLOCK_INIT)
check_symbol_exists(pthread_getspecific pthread.h HAVE_PTHREAD_GETSPECIFIC)
check_symbol_exists(strtoll stdlib.h HAVE_STRTOLL)
check_symbol_exists(__GLIBC__ stdio.h LLVM_USING_GLIBC)

View File

@ -58,4 +58,7 @@ macro(add_llvm_target target_name)
endif( TABLEGEN_OUTPUT )
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
add_llvm_library(LLVM${target_name} ${ARGN} ${TABLEGEN_OUTPUT})
if ( TABLEGEN_OUTPUT )
add_dependencies(LLVM${target_name} ${target_name}Table_gen)
endif (TABLEGEN_OUTPUT)
endmacro(add_llvm_target)

View File

@ -20,4 +20,6 @@ macro(tablegen ofn)
COMMENT "Building ${ofn}..."
)
set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn})
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${ofn}
PROPERTIES GENERATED 1)
endmacro(tablegen)

103
configure vendored
View File

@ -28032,6 +28032,109 @@ cat >>confdefs.h <<\_ACEOF
#define HAVE_PTHREAD_RWLOCK_INIT 1
_ACEOF
fi
{ echo "$as_me:$LINENO: checking for library containing pthread_getspecific" >&5
echo $ECHO_N "checking for library containing pthread_getspecific... $ECHO_C" >&6; }
if test "${ac_cv_search_pthread_getspecific+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_func_search_save_LIBS=$LIBS
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char pthread_getspecific ();
int
main ()
{
return pthread_getspecific ();
;
return 0;
}
_ACEOF
for ac_lib in '' pthread; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
{ (case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_try") 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_try") 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_search_pthread_getspecific=$ac_res
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if test "${ac_cv_search_pthread_getspecific+set}" = set; then
break
fi
done
if test "${ac_cv_search_pthread_getspecific+set}" = set; then
:
else
ac_cv_search_pthread_getspecific=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ echo "$as_me:$LINENO: result: $ac_cv_search_pthread_getspecific" >&5
echo "${ECHO_T}$ac_cv_search_pthread_getspecific" >&6; }
ac_res=$ac_cv_search_pthread_getspecific
if test "$ac_res" != no; then
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
cat >>confdefs.h <<\_ACEOF
#define HAVE_PTHREAD_GETSPECIFIC 1
_ACEOF
fi
fi

View File

@ -65,8 +65,11 @@ name. Hidden option, useful for debugging LLVMC plugins.
=item B<--save-temps>
Write temporary files to the current directory and do not delete them
on exit. Hidden option, useful for debugging.
Write temporary files to the current directory and do not delete them on
exit. This option can also take an argument: the I<--save-temps=obj> switch will
write files into the directory specified with the I<-o> option. The
I<--save-temps=cwd> and I<--save-temps> switches are both synonyms for the
default behaviour.
=item B<--help>

View File

@ -109,6 +109,11 @@ until the next -x option.</li>
<li><tt class="docutils literal"><span class="pre">-load</span> <span class="pre">PLUGIN_NAME</span></tt> - Load the specified plugin DLL. Example:
<tt class="docutils literal"><span class="pre">-load</span> <span class="pre">$LLVM_DIR/Release/lib/LLVMCSimple.so</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">-v</span></tt> - Enable verbose mode, i.e. print out all executed commands.</li>
<li><tt class="docutils literal"><span class="pre">--save-temps</span></tt> - Write temporary files to the current directory and do not
delete them on exit. This option can also take an argument: the
<tt class="docutils literal"><span class="pre">--save-temps=obj</span></tt> switch will write files into the directory specified with
the <tt class="docutils literal"><span class="pre">-o</span></tt> option. The <tt class="docutils literal"><span class="pre">--save-temps=cwd</span></tt> and <tt class="docutils literal"><span class="pre">--save-temps</span></tt> switches are
both synonyms for the default behaviour.</li>
<li><tt class="docutils literal"><span class="pre">--check-graph</span></tt> - Check the compilation for common errors like mismatched
output/input language names, multiple default edges and cycles. Because of
plugins, these checks can't be performed at compile-time. Exit with code zero
@ -122,8 +127,6 @@ directory with the compilation graph description in Graphviz format (identical
to the file used by the <tt class="docutils literal"><span class="pre">--view-graph</span></tt> option). The <tt class="docutils literal"><span class="pre">-o</span></tt> option can be
used to set the output file name. Hidden option, useful for debugging LLVMC
plugins.</li>
<li><tt class="docutils literal"><span class="pre">--save-temps</span></tt> - Write temporary files to the current directory
and do not delete them on exit. Hidden option, useful for debugging.</li>
<li><tt class="docutils literal"><span class="pre">--help</span></tt>, <tt class="docutils literal"><span class="pre">--help-hidden</span></tt>, <tt class="docutils literal"><span class="pre">--version</span></tt> - These options have
their standard meaning.</li>
</ul>
@ -642,7 +645,7 @@ errors as its status code.</p>
<a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a><br />
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br />
Last modified: $Date: 2009-06-17 02:56:48 +0000 (Wed, 17 Jun 2009) $
Last modified: $Date: 2009-06-25 20:21:10 +0200 (Thu, 25 Jun 2009) $
</address></div>
</div>
</div>

777
docs/ReleaseNotes-2.6.html Normal file
View File

@ -0,0 +1,777 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="llvm.css" type="text/css">
<title>LLVM 2.6 Release Notes</title>
</head>
<body>
<div class="doc_title">LLVM 2.6 Release Notes</div>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#subproj">Sub-project Status Update</a></li>
<li><a href="#externalproj">External Projects Using LLVM 2.6</a></li>
<li><a href="#whatsnew">What's New in LLVM 2.6?</a></li>
<li><a href="GettingStarted.html">Installation Instructions</a></li>
<li><a href="#portability">Portability and Supported Platforms</a></li>
<li><a href="#knownproblems">Known Problems</a></li>
<li><a href="#additionalinfo">Additional Information</a></li>
</ol>
<div class="doc_author">
<p>Written by the <a href="http://llvm.org">LLVM Team</a></p>
</div>
<!-- *********************************************************************** -->
<div class="doc_section">
<a name="intro">Introduction</a>
</div>
<!-- *********************************************************************** -->
<div class="doc_text">
<p>This document contains the release notes for the LLVM Compiler
Infrastructure, release 2.6. Here we describe the status of LLVM, including
major improvements from the previous release and significant known problems.
All LLVM releases may be downloaded from the <a
href="http://llvm.org/releases/">LLVM releases web site</a>.</p>
<p>For more information about LLVM, including information about the latest
release, please check out the <a href="http://llvm.org/">main LLVM
web site</a>. If you have questions or comments, the <a
href="http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVM Developer's Mailing
List</a> is a good place to send them.</p>
<p>Note that if you are reading this file from a Subversion checkout or the
main LLVM web page, this document applies to the <i>next</i> release, not the
current one. To see the release notes for a specific release, please see the
<a href="http://llvm.org/releases/">releases page</a>.</p>
</div>
<!-- Unfinished features in 2.5:
Machine LICM
Machine Sinking
target-specific intrinsics
gold lto plugin
pre-alloc splitter, strong phi elim
<tt>llc -enable-value-prop</tt>, propagation of value info
(sign/zero ext info) from one MBB to another
debug info for optimized code
interpreter + libffi
postalloc scheduler: anti dependence breaking, hazard recognizer?
initial support for debug line numbers when optimization enabled, not useful in
2.5 but will be for 2.6.
-->
<!-- for announcement email:
-->
<!-- *********************************************************************** -->
<div class="doc_section">
<a name="subproj">Sub-project Status Update</a>
</div>
<!-- *********************************************************************** -->
<div class="doc_text">
<p>
The LLVM 2.6 distribution currently consists of code from the core LLVM
repository &mdash;which roughly includes the LLVM optimizers, code generators
and supporting tools &mdash; and the llvm-gcc repository. In addition to this
code, the LLVM Project includes other sub-projects that are in development. The
two which are the most actively developed are the <a href="#clang">Clang
Project</a> and the <a href="#vmkit">VMKit Project</a>.
</p>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="clang">Clang: C/C++/Objective-C Frontend Toolkit</a>
</div>
<div class="doc_text">
<p>The <a href="http://clang.llvm.org/">Clang project</a> is an effort to build
a set of new 'LLVM native' front-end technologies for the LLVM optimizer and
code generator. While Clang is not included in the LLVM 2.6 release, it is
continuing to make major strides forward in all areas. Its C and Objective-C
parsing and code generation support is now very solid. For example, it is
capable of successfully building many real-world applications for X86-32
and X86-64,
including the <a href="http://wiki.freebsd.org/BuildingFreeBSDWithClang">FreeBSD
kernel</a> and <a href="http://gcc.gnu.org/gcc-4.2/">gcc 4.2</a>. C++ is also
making <a href="http://clang.llvm.org/cxx_status.html">incredible progress</a>,
and work on templates has recently started. If you are
interested in fast compiles and good diagnostics, we encourage you to try it out
by <a href="http://clang.llvm.org/get_started.html">building from mainline</a>
and reporting any issues you hit to the <a
href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">Clang front-end mailing
list</a>.</p>
<p>In the LLVM 2.6 time-frame, the Clang team has made many improvements:</p>
<ul>
<li>Something wonderful!</li>
<li>Many many bugs are fixed and many features have been added.</li>
</ul>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="clangsa">Clang Static Analyzer</a>
</div>
<div class="doc_text">
<p>Previously announced in the 2.4 LLVM release, the Clang project also
includes an early stage static source code analysis tool for <a
href="http://clang.llvm.org/StaticAnalysis.html">automatically finding bugs</a>
in C and Objective-C programs. The tool performs a growing set of checks to find
bugs that occur on a specific path within a program.</p>
<p>In the LLVM 2.6 time-frame there have been many significant improvements to
XYZ.</p>
<p>The set of checks performed by the static analyzer continues to expand, and
future plans for the tool include full source-level inter-procedural analysis
and deeper checks such as buffer overrun detection. There are many opportunities
to extend and enhance the static analyzer, and anyone interested in working on
this project is encouraged to get involved!</p>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="vmkit">VMKit: JVM/CLI Virtual Machine Implementation</a>
</div>
<div class="doc_text">
<p>
The <a href="http://vmkit.llvm.org/">VMKit project</a> is an implementation of
a JVM and a CLI Virtual Machines (Microsoft .NET is an
implementation of the CLI) using the Just-In-Time compiler of LLVM.</p>
<p>Following LLVM 2.6, VMKit has its XYZ release that you can find on its
<a href="http://vmkit.llvm.org/releases/">webpage</a>. The release includes
bug fixes, cleanup and new features. The major changes are:</p>
<ul>
<li>Something wonderful!</li>
</ul>
</div>
<!-- *********************************************************************** -->
<div class="doc_section">
<a name="externalproj">External Projects Using LLVM 2.6</a>
</div>
<!-- *********************************************************************** -->
<!--=========================================================================-->
<div class="doc_subsection">
<a name="pure">Pure</a>
</div>
<div class="doc_text">
<p>
<a href="http://pure-lang.googlecode.com/">Pure</a>
is an algebraic/functional programming language based on term rewriting.
Programs are collections of equations which are used to evaluate expressions in
a symbolic fashion. Pure offers dynamic typing, eager and lazy evaluation,
lexical closures, a hygienic macro system (also based on term rewriting),
built-in list and matrix support (including list and matrix comprehensions) and
an easy-to-use C interface. The interpreter uses LLVM as a backend to
JIT-compile Pure programs to fast native code.</p>
<p>In addition to the usual algebraic data structures, Pure also has
MATLAB-style matrices in order to support numeric computations and signal
processing in an efficient way. Pure is mainly aimed at mathematical
applications right now, but it has been designed as a general purpose language.
The dynamic interpreter environment and the C interface make it possible to use
it as a kind of functional scripting language for many application areas.
</p>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="ldc">LLVM D Compiler</a>
</div>
<div class="doc_text">
<p>
<a href="http://www.dsource.org/projects/ldc">LDC</a> is an implementation of
the D Programming Language using the LLVM optimizer and code generator.
The LDC project works great with the LLVM 2.6 release. General improvements in
this
cycle have included new inline asm constraint handling, better debug info
support, general bugfixes, and better x86-64 support. This has allowed
some major improvements in LDC, getting us much closer to being as
fully featured as the original DMD compiler from DigitalMars.
</p>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="RoadsendPHP">Roadsend PHP</a>
</div>
<div class="doc_text">
<p><a href="http://code.roadsend.com/rphp">Roadsend PHP</a> (rphp) is an open
source implementation of the PHP programming
language that uses LLVM for its optimizer, JIT, and static compiler. This is a
reimplementation of an earlier project that is now based on LLVM.</p>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="Unladen Swallow">Unladen Swallow</a>
</div>
<div class="doc_text">
<p><a href="http://code.google.com/p/unladen-swallow/">Unladen Swallow</a> is a
branch of <a href="http://python.org/">Python</a> intended to be fully
compatible and significantly faster. It uses LLVM's optimization passes and JIT
compiler.</p>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="Rubinius">Rubinius</a>
</div>
<div class="doc_text">
<p><a href="http://github.com/evanphx/rubinius">Rubinius</a> is a new virtual
machine for Ruby. It leverages LLVM to dynamically compile Ruby code down to
machine code using LLVM's JIT.</p>
</div>
<!-- *********************************************************************** -->
<div class="doc_section">
<a name="whatsnew">What's New in LLVM 2.6?</a>
</div>
<!-- *********************************************************************** -->
<div class="doc_text">
<p>This release includes a huge number of bug fixes, performance tweaks, and
minor improvements. Some of the major improvements and new features are listed
in this section.
</p>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="majorfeatures">Major New Features</a>
</div>
<div class="doc_text">
<p>LLVM 2.6 includes several major new capabilities:</p>
<ul>
<li>Something wonderful!</li>
</ul>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="llvm-gcc">llvm-gcc 4.2 Improvements</a>
</div>
<div class="doc_text">
<p>LLVM fully supports the llvm-gcc 4.2 front-end, which marries the GCC
front-ends and driver with the LLVM optimizer and code generator. It currently
includes support for the C, C++, Objective-C, Ada, and Fortran front-ends.</p>
<ul>
<li>Something wonderful!</li>
</ul>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="coreimprovements">LLVM IR and Core Improvements</a>
</div>
<div class="doc_text">
<p>LLVM IR has several new features that are used by our existing front-ends and
can be useful if you are writing a front-end for LLVM:</p>
<ul>
<li>Something wonderful!</li>
</ul>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="optimizer">Optimizer Improvements</a>
</div>
<div class="doc_text">
<p>In addition to a large array of bug fixes and minor performance tweaks, this
release includes a few major enhancements and additions to the optimizers:</p>
<ul>
<li>Something wonderful!</li>
</ul>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="codegen">Target Independent Code Generator Improvements</a>
</div>
<div class="doc_text">
<p>We have put a significant amount of work into the code generator
infrastructure, which allows us to implement more aggressive algorithms and make
it run faster:</p>
<ul>
<li>Something wonderful!</li>
</ul>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="x86">X86-32 and X86-64 Target Improvements</a>
</div>
<div class="doc_text">
<p>New features of the X86 target include:
</p>
<ul>
<li>Something wonderful!</li>
</ul>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="pic16">PIC16 Target Improvements</a>
</div>
<div class="doc_text">
<p>New features of the PIC16 target include:
</p>
<ul>
<li>Something wonderful!</li>
</ul>
<p>Things not yet supported:</p>
<ul>
<li>Floating point.</li>
<li>Passing/returning aggregate types to and from functions.</li>
<li>Variable arguments.</li>
<li>Indirect function calls.</li>
<li>Interrupts/programs.</li>
<li>Debug info.</li>
</ul>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="llvmc">Improvements in LLVMC</a>
</div>
<div class="doc_text">
<p>New features include:</p>
<ul>
<li>Something wonderful!</li>
</ul>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="changes">Major Changes and Removed Features</a>
</div>
<div class="doc_text">
<p>If you're already an LLVM user or developer with out-of-tree changes based
on LLVM 2.4, this section lists some "gotchas" that you may run into upgrading
from the previous release.</p>
<ul>
<li>Something horrible!</li>
</ul>
<p>In addition, many APIs have changed in this release. Some of the major LLVM
API changes are:</p>
<ul>
<li>The <tt>getABITypeSize</tt> methods are now called <tt>getAllocSize</tt>.</li>
</ul>
</div>
<!-- *********************************************************************** -->
<div class="doc_section">
<a name="portability">Portability and Supported Platforms</a>
</div>
<!-- *********************************************************************** -->
<div class="doc_text">
<p>LLVM is known to work on the following platforms:</p>
<ul>
<li>Intel and AMD machines (IA32, X86-64, AMD64, EMT-64) running Red Hat
Linux, Fedora Core and FreeBSD (and probably other unix-like systems).</li>
<li>PowerPC and X86-based Mac OS X systems, running 10.3 and above in 32-bit
and 64-bit modes.</li>
<li>Intel and AMD machines running on Win32 using MinGW libraries (native).</li>
<li>Intel and AMD machines running on Win32 with the Cygwin libraries (limited
support is available for native builds with Visual C++).</li>
<li>Sun UltraSPARC workstations running Solaris 10.</li>
<li>Alpha-based machines running Debian GNU/Linux.</li>
<li>Itanium-based (IA64) machines running Linux and HP-UX.</li>
</ul>
<p>The core LLVM infrastructure uses GNU autoconf to adapt itself
to the machine and operating system on which it is built. However, minor
porting may be required to get LLVM to work on new platforms. We welcome your
portability patches and reports of successful builds or error messages.</p>
</div>
<!-- *********************************************************************** -->
<div class="doc_section">
<a name="knownproblems">Known Problems</a>
</div>
<!-- *********************************************************************** -->
<div class="doc_text">
<p>This section contains significant known problems with the LLVM system,
listed by component. If you run into a problem, please check the <a
href="http://llvm.org/bugs/">LLVM bug database</a> and submit a bug if
there isn't already one.</p>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="experimental">Experimental features included with this release</a>
</div>
<div class="doc_text">
<p>The following components of this LLVM release are either untested, known to
be broken or unreliable, or are in early development. These components should
not be relied on, and bugs should not be filed against them, but they may be
useful to some people. In particular, if you would like to work on one of these
components, please contact us on the <a
href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVMdev list</a>.</p>
<ul>
<li>The MSIL, IA64, Alpha, SPU, MIPS, and PIC16 backends are experimental.</li>
<li>The <tt>llc</tt> "<tt>-filetype=asm</tt>" (the default) is the only
supported value for this option.</li>
</ul>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="x86-be">Known problems with the X86 back-end</a>
</div>
<div class="doc_text">
<ul>
<li>The X86 backend does not yet support
all <a href="http://llvm.org/PR879">inline assembly that uses the X86
floating point stack</a>. It supports the 'f' and 't' constraints, but not
'u'.</li>
<li>The X86 backend generates inefficient floating point code when configured
to generate code for systems that don't have SSE2.</li>
<li>Win64 code generation wasn't widely tested. Everything should work, but we
expect small issues to happen. Also, llvm-gcc cannot build the mingw64
runtime currently due
to <a href="http://llvm.org/PR2255">several</a>
<a href="http://llvm.org/PR2257">bugs</a> and due to lack of support for
the
'u' inline assembly constraint and for X87 floating point inline assembly.</li>
<li>The X86-64 backend does not yet support the LLVM IR instruction
<tt>va_arg</tt>. Currently, the llvm-gcc and front-ends support variadic
argument constructs on X86-64 by lowering them manually.</li>
</ul>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="ppc-be">Known problems with the PowerPC back-end</a>
</div>
<div class="doc_text">
<ul>
<li>The Linux PPC32/ABI support needs testing for the interpreter and static
compilation, and lacks support for debug information.</li>
</ul>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="arm-be">Known problems with the ARM back-end</a>
</div>
<div class="doc_text">
<ul>
<li>Thumb mode works only on ARMv6 or higher processors. On sub-ARMv6
processors, thumb programs can crash or produce wrong
results (<a href="http://llvm.org/PR1388">PR1388</a>).</li>
<li>Compilation for ARM Linux OABI (old ABI) is supported but not fully tested.
</li>
<li>There is a bug in QEMU-ARM (&lt;= 0.9.0) which causes it to incorrectly
execute
programs compiled with LLVM. Please use more recent versions of QEMU.</li>
</ul>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="sparc-be">Known problems with the SPARC back-end</a>
</div>
<div class="doc_text">
<ul>
<li>The SPARC backend only supports the 32-bit SPARC ABI (-m32); it does not
support the 64-bit SPARC ABI (-m64).</li>
</ul>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="mips-be">Known problems with the MIPS back-end</a>
</div>
<div class="doc_text">
<ul>
<li>The O32 ABI is not fully supported.</li>
<li>64-bit MIPS targets are not supported yet.</li>
</ul>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="alpha-be">Known problems with the Alpha back-end</a>
</div>
<div class="doc_text">
<ul>
<li>On 21164s, some rare FP arithmetic sequences which may trap do not have the
appropriate nops inserted to ensure restartability.</li>
</ul>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="ia64-be">Known problems with the IA64 back-end</a>
</div>
<div class="doc_text">
<ul>
<li>The Itanium backend is highly experimental and has a number of known
issues. We are looking for a maintainer for the Itanium backend. If you
are interested, please contact the LLVMdev mailing list.</li>
</ul>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="c-be">Known problems with the C back-end</a>
</div>
<div class="doc_text">
<ul>
<li><a href="http://llvm.org/PR802">The C backend has only basic support for
inline assembly code</a>.</li>
<li><a href="http://llvm.org/PR1658">The C backend violates the ABI of common
C++ programs</a>, preventing intermixing between C++ compiled by the CBE and
C++ code compiled with <tt>llc</tt> or native compilers.</li>
<li>The C backend does not support all exception handling constructs.</li>
<li>The C backend does not support arbitrary precision integers.</li>
</ul>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="c-fe">Known problems with the llvm-gcc C front-end</a>
</div>
<div class="doc_text">
<p>llvm-gcc does not currently support <a href="http://llvm.org/PR869">Link-Time
Optimization</a> on most platforms "out-of-the-box". Please inquire on the
LLVMdev mailing list if you are interested.</p>
<p>The only major language feature of GCC not supported by llvm-gcc is
the <tt>__builtin_apply</tt> family of builtins. However, some extensions
are only supported on some targets. For example, trampolines are only
supported on some targets (these are used when you take the address of a
nested function).</p>
<p>If you run into GCC extensions which are not supported, please let us know.
</p>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="c++-fe">Known problems with the llvm-gcc C++ front-end</a>
</div>
<div class="doc_text">
<p>The C++ front-end is considered to be fully
tested and works for a number of non-trivial programs, including LLVM
itself, Qt, Mozilla, etc.</p>
<ul>
<li>Exception handling works well on the X86 and PowerPC targets. Currently
only Linux and Darwin targets are supported (both 32 and 64 bit).</li>
</ul>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="fortran-fe">Known problems with the llvm-gcc Fortran front-end</a>
</div>
<div class="doc_text">
<ul>
<li>Fortran support generally works, but there are still several unresolved bugs
in Bugzilla. Please see the tools/gfortran component for details.</li>
</ul>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="ada-fe">Known problems with the llvm-gcc Ada front-end</a>
</div>
<div class="doc_text">
The llvm-gcc 4.2 Ada compiler works fairly well; however, this is not a mature
technology, and problems should be expected.
<ul>
<li>The Ada front-end currently only builds on X86-32. This is mainly due
to lack of trampoline support (pointers to nested functions) on other platforms.
However, it <a href="http://llvm.org/PR2006">also fails to build on X86-64</a>
which does support trampolines.</li>
<li>The Ada front-end <a href="http://llvm.org/PR2007">fails to bootstrap</a>.
This is due to lack of LLVM support for <tt>setjmp</tt>/<tt>longjmp</tt> style
exception handling, which is used internally by the compiler.
Workaround: configure with --disable-bootstrap.</li>
<li>The c380004, <a href="http://llvm.org/PR2010">c393010</a>
and <a href="http://llvm.org/PR2421">cxg2021</a> ACATS tests fail
(c380004 also fails with gcc-4.2 mainline).
If the compiler is built with checks disabled then <a href="http://llvm.org/PR2010">c393010</a>
causes the compiler to go into an infinite loop, using up all system memory.</li>
<li>Some GCC specific Ada tests continue to crash the compiler.</li>
<li>The -E binder option (exception backtraces)
<a href="http://llvm.org/PR1982">does not work</a> and will result in programs
crashing if an exception is raised. Workaround: do not use -E.</li>
<li>Only discrete types <a href="http://llvm.org/PR1981">are allowed to start
or finish at a non-byte offset</a> in a record. Workaround: do not pack records
or use representation clauses that result in a field of a non-discrete type
starting or finishing in the middle of a byte.</li>
<li>The <tt>lli</tt> interpreter <a href="http://llvm.org/PR2009">considers
'main' as generated by the Ada binder to be invalid</a>.
Workaround: hand edit the file to use pointers for <tt>argv</tt> and
<tt>envp</tt> rather than integers.</li>
<li>The <tt>-fstack-check</tt> option <a href="http://llvm.org/PR2008">is
ignored</a>.</li>
</ul>
</div>
<!-- *********************************************************************** -->
<div class="doc_section">
<a name="additionalinfo">Additional Information</a>
</div>
<!-- *********************************************************************** -->
<div class="doc_text">
<p>A wide variety of additional information is available on the <a
href="http://llvm.org">LLVM web page</a>, in particular in the <a
href="http://llvm.org/docs/">documentation</a> section. The web page also
contains versions of the API documentation which is up-to-date with the
Subversion version of the source code.
You can access versions of these documents specific to this release by going
into the "<tt>llvm/doc/</tt>" directory in the LLVM tree.</p>
<p>If you have any questions or comments about LLVM, please feel free to contact
us via the <a href="http://llvm.org/docs/#maillist"> mailing
lists</a>.</p>
</div>
<!-- *********************************************************************** -->
<hr>
<address>
<a href="http://jigsaw.w3.org/css-validator/check/referer"><img
src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS"></a>
<a href="http://validator.w3.org/check/referer"><img
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2009-06-24 23:26:42 +0200 (Wed, 24 Jun 2009) $
</address>
</body>
</html>

View File

@ -24,7 +24,6 @@
<ol>
<li><a href="#debug_info_descriptors">Debug information descriptors</a>
<ul>
<li><a href="#format_anchors">Anchor descriptors</a></li>
<li><a href="#format_compile_units">Compile unit descriptors</a></li>
<li><a href="#format_global_variables">Global variable descriptors</a></li>
<li><a href="#format_subprograms">Subprogram descriptors</a></li>
@ -334,58 +333,6 @@ height="369">
</div>
<!-- ======================================================================= -->
<div class="doc_subsubsection">
<a name="format_anchors">Anchor descriptors</a>
</div>
<div class="doc_text">
<div class="doc_code">
<pre>
%<a href="#format_anchors">llvm.dbg.anchor.type</a> = type {
i32, ;; Tag = 0 + <a href="#LLVMDebugVersion">LLVMDebugVersion</a>
i32 ;; Tag of descriptors grouped by the anchor
}
</pre>
</div>
<p>One important aspect of the LLVM debug representation is that it allows the
LLVM debugger to efficiently index all of the global objects without having
to scan the program. To do this, all of the global objects use "anchor"
descriptors with designated names. All of the global objects of a particular
type (e.g., compile units) contain a pointer to the anchor. This pointer
allows a debugger to use def-use chains to find all global objects of that
type.</p>
<p>The following names are recognized as anchors by LLVM:</p>
<div class="doc_code">
<pre>
%<a href="#format_compile_units">llvm.dbg.compile_units</a> = linkonce constant %<a href="#format_anchors">llvm.dbg.anchor.type</a> {
i32 0,
i32 17
} ;; DW_TAG_compile_unit
%<a href="#format_global_variables">llvm.dbg.global_variables</a> = linkonce constant %<a href="#format_anchors">llvm.dbg.anchor.type</a> {
i32 0,
i32 52
} ;; DW_TAG_variable
%<a href="#format_subprograms">llvm.dbg.subprograms</a> = linkonce constant %<a href="#format_anchors">llvm.dbg.anchor.type</a> {
i32 0,
i32 46
} ;; DW_TAG_subprogram
</pre>
</div>
<p>Using anchors in this way (where the compile unit descriptor points to the
anchors, as opposed to having a list of compile unit descriptors) allows for
the standard dead global elimination and merging passes to automatically
remove unused debugging information. If the globals were kept track of
through lists, there would always be an object pointing to the descriptors,
thus would never be deleted.</p>
</div>
<!-- ======================================================================= -->
<div class="doc_subsubsection">
<a name="format_compile_units">Compile unit descriptors</a>
@ -1919,7 +1866,7 @@ enum Trees {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2009-05-29 19:08:57 +0200 (Fri, 29 May 2009) $
Last modified: $Date: 2009-06-26 03:49:18 +0200 (Fri, 26 Jun 2009) $
</address>
</body>

View File

@ -78,27 +78,8 @@ required to build LLVM, plus the following:</p>
<dd>Expect is required by DejaGNU.</dd>
<dt><a href="http://www.tcl.tk/software/tcltk/">tcl</a></dt>
<dd>Tcl is required by DejaGNU. </dd>
<ul>
<li><tt>./configure --with-f2c=$DIR</tt><br>
This will specify a new <tt>$DIR</tt> for the above-described search
process. This will only work if the binary, header, and library are in their
respective subdirectories of <tt>$DIR</tt>.</li>
<li><tt>./configure --with-f2c-bin=/binary/path --with-f2c-inc=/include/path
--with-f2c-lib=/lib/path</tt><br>
This allows you to specify the F2C components separately. Note: if you choose
this route, you MUST specify all three components, and you need to only specify
<em>directories</em> where the files are located; do NOT include the
filenames themselves on the <tt>configure</tt> line.</li>
</ul></dd>
</dl>
<p>Darwin (Mac OS X) developers can simplify the installation of Expect and tcl
by using fink. <tt>fink install expect</tt> will install both. Alternatively,
Darwinports users can use <tt>sudo port install expect</tt> to install Expect
and tcl.</p>
</div>
<!--=========================================================================-->
@ -122,14 +103,17 @@ tests" and are in the <tt>llvm</tt> module in subversion under the
<div class="doc_text">
<p>Code fragments are small pieces of code that test a specific feature of LLVM
or trigger a specific bug in LLVM. They are usually written in LLVM assembly
language, but can be written in other languages if the test targets a particular
language front end. These tests are driven by the DejaGNU testing framework,
which is hidden behind a few simple makefiles.</p>
<p>Code fragments are small pieces of code that test a specific
feature of LLVM or trigger a specific bug in LLVM. They are usually
written in LLVM assembly language, but can be written in other
languages if the test targets a particular language front end (and the
appropriate <tt>--with-llvmgcc</tt> options were used
at <tt>configure</tt> time of the <tt>llvm</tt> module). These tests
are driven by the DejaGNU testing framework, which is hidden behind a
few simple makefiles.</p>
<p>These code fragments are not complete programs. The code generated from them is
never executed to determine correct behavior.</p>
<p>These code fragments are not complete programs. The code generated
from them is never executed to determine correct behavior.</p>
<p>These code fragment tests are located in the <tt>llvm/test</tt>
directory.</p>
@ -251,10 +235,18 @@ programs), first checkout and setup the <tt>test-suite</tt> module:</p>
% cd ..
% ./configure --with-llvmgccdir=$LLVM_GCC_DIR
</pre>
<p>where <tt>$LLVM_GCC_DIR</tt> is the directory where you <em>installed</em>
llvm-gcc, not it's src or obj dir.</p>
</div>
<p>where <tt>$LLVM_GCC_DIR</tt> is the directory where
you <em>installed</em> llvm-gcc, not it's src or obj
dir. The <tt>--with-llvmgccdir</tt> option assumes that
the <tt>llvm-gcc-4.2</tt> module was configured with
<tt>--program-prefix=llvm-</tt>, and therefore that the C and C++
compiler drivers are called <tt>llvm-gcc</tt> and <tt>llvm-g++</tt>
respectively. If this is not the case,
use <tt>--with-llvmgcc</tt>/<tt>--with-llvmgxx</tt> to specify each
executable's location.</p>
<p>Then, run the entire test suite by running make in the <tt>test-suite</tt>
directory:</p>
@ -448,6 +440,11 @@ that subdirectory.</p>
</pre>
</div>
<p>If your system includes GNU <tt>grep</tt>, make sure
that <tt>GREP_OPTIONS</tt> is not set in your environment. Otherwise,
you may get invalid results (both false positives and false
negatives).</p>
</div>
<!-- _______________________________________________________________________ -->
@ -746,6 +743,8 @@ test suite creates temporary files during execution.</p>
have the suite checked out and configured, you don't need to do it again (unless
the test code or configure script changes).</p>
</div>
<!-- _______________________________________________________________________ -->
<div class="doc_subsection">
<a name="testsuiteexternal">Configuring External Tests</a></div>
@ -975,7 +974,7 @@ know. Thanks!</p>
John T. Criswell, Reid Spencer, and Tanya Lattner<br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2009-05-21 22:23:59 +0200 (Thu, 21 May 2009) $
Last modified: $Date: 2009-06-26 07:44:53 +0200 (Fri, 26 Jun 2009) $
</address>
</body>
</html>

View File

@ -26,6 +26,9 @@
extern "C" {
#endif
void LLVMLinkInJIT(void);
void LLVMLinkInInterpreter(void);
typedef struct LLVMOpaqueGenericValue *LLVMGenericValueRef;
typedef struct LLVMOpaqueExecutionEngine *LLVMExecutionEngineRef;

View File

@ -20,6 +20,7 @@
#define LLVM_C_TARGET_H
#include "llvm-c/Core.h"
#include "llvm/Config/config.h"
#ifdef __cplusplus
extern "C" {
@ -31,6 +32,34 @@ typedef int LLVMByteOrdering;
typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef;
typedef struct LLVMStructLayout *LLVMStructLayoutRef;
/* Declare all of the target-initialization functions that are available. */
#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target();
#include "llvm/Config/Targets.def"
/** LLVMInitializeAllTargets - The main program should call this function if it
wants to link in all available targets that LLVM is configured to
support. */
static inline void LLVMInitializeAllTargets() {
#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##Target();
#include "llvm/Config/Targets.def"
}
/** LLVMInitializeNativeTarget - The main program should call this function to
initialize the native target corresponding to the host. This is useful
for JIT applications to ensure that the target gets linked in correctly. */
static inline int LLVMInitializeNativeTarget() {
/* If we have a native target, initialize it to ensure it is linked in. */
#ifdef LLVM_NATIVE_ARCH
#define DoInit2(TARG) LLVMInitialize ## TARG ()
#define DoInit(T) DoInit2(T)
DoInit(LLVM_NATIVE_ARCH);
return 0;
#undef DoInit
#undef DoInit2
#else
return 1;
#endif
}
/*===-- Target Data -------------------------------------------------------===*/

View File

@ -26,14 +26,16 @@
#ifndef LLVM_ADT_STATISTIC_H
#define LLVM_ADT_STATISTIC_H
#include "llvm/System/Atomic.h"
namespace llvm {
class Statistic {
public:
const char *Name;
const char *Desc;
unsigned Value : 31;
bool Initialized : 1;
unsigned Value;
bool Initialized;
unsigned getValue() const { return Value; }
const char *getName() const { return Name; }
@ -47,19 +49,60 @@ class Statistic {
// Allow use of this class as the value itself.
operator unsigned() const { return Value; }
const Statistic &operator=(unsigned Val) { Value = Val; return init(); }
const Statistic &operator++() { ++Value; return init(); }
unsigned operator++(int) { init(); return Value++; }
const Statistic &operator--() { --Value; return init(); }
unsigned operator--(int) { init(); return Value--; }
const Statistic &operator+=(const unsigned &V) { Value += V; return init(); }
const Statistic &operator-=(const unsigned &V) { Value -= V; return init(); }
const Statistic &operator*=(const unsigned &V) { Value *= V; return init(); }
const Statistic &operator/=(const unsigned &V) { Value /= V; return init(); }
const Statistic &operator=(unsigned Val) {
Value = Val;
return init();
}
const Statistic &operator++() {
sys::AtomicIncrement(&Value);
return init();
}
unsigned operator++(int) {
init();
unsigned OldValue = Value;
sys::AtomicIncrement(&Value);
return OldValue;
}
const Statistic &operator--() {
sys::AtomicDecrement(&Value);
return init();
}
unsigned operator--(int) {
init();
unsigned OldValue = Value;
sys::AtomicDecrement(&Value);
return OldValue;
}
const Statistic &operator+=(const unsigned &V) {
sys::AtomicAdd(&Value, V);
return init();
}
const Statistic &operator-=(const unsigned &V) {
sys::AtomicAdd(&Value, -V);
return init();
}
const Statistic &operator*=(const unsigned &V) {
sys::AtomicMul(&Value, V);
return init();
}
const Statistic &operator/=(const unsigned &V) {
sys::AtomicDiv(&Value, V);
return init();
}
protected:
Statistic &init() {
if (!Initialized) RegisterStatistic();
bool tmp = Initialized;
sys::MemoryFence();
if (!tmp) RegisterStatistic();
return *this;
}
void RegisterStatistic();

View File

@ -308,7 +308,8 @@ struct DOTGraphTraits<Trie<Payload> > : public DefaultDOTGraphTraits {
return "Trie";
}
static std::string getNodeLabel(NodeType* Node, const Trie<Payload>& T) {
static std::string getNodeLabel(NodeType* Node, const Trie<Payload>& T,
bool ShortNames) {
if (T.getRoot() == Node)
return "<Root>";
else

View File

@ -20,6 +20,7 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Dwarf.h"
namespace llvm {
@ -36,7 +37,7 @@ namespace llvm {
class DIDescriptor {
protected:
GlobalVariable *GV;
GlobalVariable *DbgGV;
/// DIDescriptor constructor. If the specified GV is non-null, this checks
/// to make sure that the tag in the descriptor matches 'RequiredTag'. If
@ -58,12 +59,12 @@ namespace llvm {
GlobalVariable *getGlobalVariableField(unsigned Elt) const;
public:
explicit DIDescriptor() : GV(0) {}
explicit DIDescriptor(GlobalVariable *gv) : GV(gv) {}
explicit DIDescriptor() : DbgGV(0) {}
explicit DIDescriptor(GlobalVariable *GV) : DbgGV(GV) {}
bool isNull() const { return GV == 0; }
bool isNull() const { return DbgGV == 0; }
GlobalVariable *getGV() const { return GV; }
GlobalVariable *getGV() const { return DbgGV; }
unsigned getVersion() const {
return getUnsignedField(0) & LLVMDebugVersionMask;
@ -80,15 +81,6 @@ namespace llvm {
void dump() const;
};
/// DIAnchor - A wrapper for various anchor descriptors.
class DIAnchor : public DIDescriptor {
public:
explicit DIAnchor(GlobalVariable *GV = 0)
: DIDescriptor(GV, dwarf::DW_TAG_anchor) {}
unsigned getAnchorTag() const { return getUnsignedField(1); }
};
/// DISubrange - This is used to represent ranges, for array bounds.
class DISubrange : public DIDescriptor {
public:
@ -245,7 +237,7 @@ namespace llvm {
explicit DIDerivedType(GlobalVariable *GV)
: DIType(GV, true, true) {
if (GV && !isDerivedType(getTag()))
GV = 0;
DbgGV = 0;
}
DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); }
@ -265,7 +257,7 @@ namespace llvm {
explicit DICompositeType(GlobalVariable *GV)
: DIDerivedType(GV, true, true) {
if (GV && !isCompositeType(getTag()))
GV = 0;
DbgGV = 0;
}
DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
@ -330,6 +322,19 @@ namespace llvm {
DICompositeType getType() const { return getFieldAs<DICompositeType>(8); }
/// getReturnTypeName - Subprogram return types are encoded either as
/// DIType or as DICompositeType.
const std::string &getReturnTypeName(std::string &F) const {
DICompositeType DCT(getFieldAs<DICompositeType>(8));
if (!DCT.isNull()) {
DIArray A = DCT.getTypeArray();
DIType T(A.getElement(0).getGV());
return T.getName(F);
}
DIType T(getFieldAs<DIType>(8));
return T.getName(F);
}
/// Verify - Verify that a subprogram descriptor is well formed.
bool Verify() const;
@ -360,10 +365,10 @@ namespace llvm {
/// global etc).
class DIVariable : public DIDescriptor {
public:
explicit DIVariable(GlobalVariable *gv = 0)
: DIDescriptor(gv) {
if (gv && !isVariable(getTag()))
GV = 0;
explicit DIVariable(GlobalVariable *GV = 0)
: DIDescriptor(GV) {
if (GV && !isVariable(getTag()))
DbgGV = 0;
}
DIDescriptor getContext() const { return getDescriptorField(1); }
@ -398,7 +403,6 @@ namespace llvm {
class DIFactory {
Module &M;
// Cached values for uniquing and faster lookups.
DIAnchor CompileUnitAnchor, SubProgramAnchor, GlobalVariableAnchor;
const Type *EmptyStructPtr; // "{}*".
Function *StopPointFn; // llvm.dbg.stoppoint
Function *FuncStartFn; // llvm.dbg.func.start
@ -413,18 +417,6 @@ namespace llvm {
public:
explicit DIFactory(Module &m);
/// GetOrCreateCompileUnitAnchor - Return the anchor for compile units,
/// creating a new one if there isn't already one in the module.
DIAnchor GetOrCreateCompileUnitAnchor();
/// GetOrCreateSubprogramAnchor - Return the anchor for subprograms,
/// creating a new one if there isn't already one in the module.
DIAnchor GetOrCreateSubprogramAnchor();
/// GetOrCreateGlobalVariableAnchor - Return the anchor for globals,
/// creating a new one if there isn't already one in the module.
DIAnchor GetOrCreateGlobalVariableAnchor();
/// GetOrCreateArray - Create an descriptor for an array of descriptors.
/// This implicitly uniques the arrays created.
DIArray GetOrCreateArray(DIDescriptor *Tys, unsigned NumTys);
@ -527,7 +519,6 @@ namespace llvm {
private:
Constant *GetTagConstant(unsigned TAG);
Constant *GetStringConstant(const std::string &String);
DIAnchor GetOrCreateAnchor(unsigned TAG, const char *Name);
/// getCastToEmpty - Return the descriptor as a Constant* with type '{}*'.
Constant *getCastToEmpty(DIDescriptor D);
@ -550,6 +541,13 @@ namespace llvm {
bool getLocationInfo(const Value *V, std::string &DisplayName, std::string &Type,
unsigned &LineNo, std::string &File, std::string &Dir);
/// CollectDebugInfoAnchors - Collect debugging information anchors.
void CollectDebugInfoAnchors(Module &M,
SmallVector<GlobalVariable *, 2> &CompileUnits,
SmallVector<GlobalVariable *, 4> &GlobalVars,
SmallVector<GlobalVariable *, 4> &Subprograms);
} // end namespace llvm
#endif

View File

@ -0,0 +1,52 @@
//===- llvm/Analysis/LoopDependenceAnalysis.h --------------- -*- C++ -*---===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// LoopDependenceAnalysis is an LLVM pass that analyses dependences in memory
// accesses in loops.
//
// Please note that this is work in progress and the interface is subject to
// change.
//
// TODO: adapt as interface progresses
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H
#define LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H
#include "llvm/Analysis/LoopPass.h"
namespace llvm {
class AnalysisUsage;
class LoopPass;
class ScalarEvolution;
class LoopDependenceAnalysis : public LoopPass {
Loop *L;
ScalarEvolution *SE;
public:
static char ID; // Class identification, replacement for typeinfo
LoopDependenceAnalysis() : LoopPass(&ID) {}
bool runOnLoop(Loop*, LPPassManager&);
virtual void getAnalysisUsage(AnalysisUsage&) const;
}; // class LoopDependenceAnalysis
// createLoopDependenceAnalysisPass - This creates an instance of the
// LoopDependenceAnalysis pass.
//
LoopPass *createLoopDependenceAnalysisPass();
} // namespace llvm
#endif /* LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H */

View File

@ -281,6 +281,16 @@ class LoopBase {
}
}
/// getUniqueExitBlock - If getUniqueExitBlocks would return exactly one
/// block, return that block. Otherwise return null.
BlockT *getUniqueExitBlock() const {
SmallVector<BlockT*, 8> UniqueExitBlocks;
getUniqueExitBlocks(UniqueExitBlocks);
if (UniqueExitBlocks.size() == 1)
return UniqueExitBlocks[0];
return 0;
}
/// getLoopPreheader - If there is a preheader for this loop, return it. A
/// loop has a preheader if there is only one edge to the header of the loop
/// from outside of the loop. If this is the case, the block branching to the

View File

@ -34,9 +34,6 @@ class LoopPass : public Pass {
// runOnLoop - This method should be implemented by the subclass to perform
// whatever action is necessary for the specified Loop.
virtual bool runOnLoop(Loop *L, LPPassManager &LPM) = 0;
virtual bool runOnFunctionBody(Function &F, LPPassManager &LPM) {
return false;
}
// Initialization and finalization hooks.
virtual bool doInitialization(Loop *L, LPPassManager &LPM) {

View File

@ -18,6 +18,7 @@
namespace llvm {
class FunctionPass;
class ImmutablePass;
class LoopPass;
class ModulePass;
class Pass;
class LibCallInfo;
@ -116,6 +117,13 @@ namespace llvm {
// createLiveValuesPass - This creates an instance of the LiveValues pass.
//
FunctionPass *createLiveValuesPass();
//===--------------------------------------------------------------------===//
//
// createLoopDependenceAnalysisPass - This creates an instance of the
// LoopDependenceAnalysis pass.
//
LoopPass *createLoopDependenceAnalysisPass();
// Minor pass prototypes, allowing us to expose them through bugpoint and
// analyze.

View File

@ -33,6 +33,7 @@ class ProfileInfoLoader {
std::vector<unsigned> BlockCounts;
std::vector<unsigned> EdgeCounts;
std::vector<unsigned> BBTrace;
bool Warned;
public:
// ProfileInfoLoader ctor - Read the specified profiling data file, exiting
// the program if the file is invalid or broken.

View File

@ -44,8 +44,8 @@ namespace llvm {
class SCEVUnknown;
/// SCEV - This class represents an analyzed expression in the program. These
/// are reference-counted opaque objects that the client is not allowed to
/// do much with directly.
/// are opaque objects that the client is not allowed to do much with
/// directly.
///
class SCEV {
const unsigned SCEVType; // The SCEV baseclass this node corresponds to
@ -82,6 +82,11 @@ namespace llvm {
///
bool isOne() const;
/// isAllOnesValue - Return true if the expression is a constant
/// all-ones value.
///
bool isAllOnesValue() const;
/// replaceSymbolicValuesWithConcrete - If this SCEV internally references
/// the symbolic value "Sym", construct and return a new SCEV that produces
/// the same value, but which uses the concrete value Conc instead of the
@ -300,8 +305,9 @@ namespace llvm {
/// try to evaluate a few iterations of the loop until we get the exit
/// condition gets a value of ExitWhen (true or false). If we cannot
/// evaluate the trip count of the loop, return CouldNotCompute.
const SCEV* ComputeBackedgeTakenCountExhaustively(const Loop *L, Value *Cond,
bool ExitWhen);
const SCEV* ComputeBackedgeTakenCountExhaustively(const Loop *L,
Value *Cond,
bool ExitWhen);
/// HowFarToZero - Return the number of times a backedge comparing the
/// specified value to zero will execute. If not computable, return
@ -329,6 +335,12 @@ namespace llvm {
/// found.
BasicBlock* getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB);
/// isNecessaryCond - Test whether the given CondValue value is a condition
/// which is at least as strict as the one described by Pred, LHS, and RHS.
bool isNecessaryCond(Value *Cond, ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS,
bool Inverse);
/// getConstantEvolutionLoopExitValue - If we know that the specified Phi is
/// in the header of its containing loop, we know the loop executes a
/// constant number of times, and the PHI node is just a recurrence
@ -457,7 +469,7 @@ namespace llvm {
/// widening.
const SCEV* getTruncateOrNoop(const SCEV* V, const Type *Ty);
/// getIntegerSCEV - Given an integer or FP type, create a constant for the
/// getIntegerSCEV - Given a SCEVable type, create a constant for the
/// specified signed integer value and return a SCEV for the constant.
const SCEV* getIntegerSCEV(int Val, const Type *Ty);
@ -531,10 +543,11 @@ namespace llvm {
/// is deleted.
void forgetLoopBackedgeTakenCount(const Loop *L);
/// GetMinTrailingZeros - Determine the minimum number of zero bits that S is
/// guaranteed to end in (at every loop iteration). It is, at the same time,
/// the minimum number of times S is divisible by 2. For example, given {4,+,8}
/// it returns 2. If S is guaranteed to be 0, it returns the bitwidth of S.
/// GetMinTrailingZeros - Determine the minimum number of zero bits that S
/// is guaranteed to end in (at every loop iteration). It is, at the same
/// time, the minimum number of times S is divisible by 2. For example,
/// given {4,+,8} it returns 2. If S is guaranteed to be 0, it returns the
/// bitwidth of S.
uint32_t GetMinTrailingZeros(const SCEV* S);
/// GetMinLeadingZeros - Determine the minimum number of zero bits that S is

View File

@ -28,7 +28,8 @@ namespace llvm {
/// memory.
struct SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
ScalarEvolution &SE;
std::map<const SCEV*, AssertingVH<Value> > InsertedExpressions;
std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> >
InsertedExpressions;
std::set<Value*> InsertedValues;
BasicBlock::iterator InsertPt;
@ -43,48 +44,18 @@ namespace llvm {
/// different places within the same BasicBlock can do so.
void clear() { InsertedExpressions.clear(); }
/// isInsertedInstruction - Return true if the specified instruction was
/// inserted by the code rewriter. If so, the client should not modify the
/// instruction.
bool isInsertedInstruction(Instruction *I) const {
return InsertedValues.count(I);
}
/// isInsertedExpression - Return true if the the code rewriter has a
/// Value* recorded for the given expression.
bool isInsertedExpression(const SCEV *S) const {
return InsertedExpressions.count(S);
}
/// getOrInsertCanonicalInductionVariable - This method returns the
/// canonical induction variable of the specified type for the specified
/// loop (inserting one if there is none). A canonical induction variable
/// starts at zero and steps by one on each iteration.
Value *getOrInsertCanonicalInductionVariable(const Loop *L, const Type *Ty);
/// addInsertedValue - Remember the specified instruction as being the
/// canonical form for the specified SCEV.
void addInsertedValue(Value *V, const SCEV *S) {
InsertedExpressions[S] = V;
InsertedValues.insert(V);
}
void setInsertionPoint(BasicBlock::iterator NewIP) { InsertPt = NewIP; }
BasicBlock::iterator getInsertionPoint() const { return InsertPt; }
/// expandCodeFor - Insert code to directly compute the specified SCEV
/// expression into the program. The inserted code is inserted into the
/// SCEVExpander's current insertion point. If a type is specified, the
/// result will be expanded to have that type, with a cast if necessary.
Value *expandCodeFor(const SCEV* SH, const Type *Ty = 0);
/// expandCodeFor - Insert code to directly compute the specified SCEV
/// expression into the program. The inserted code is inserted into the
/// specified block.
Value *expandCodeFor(const SCEV* SH, const Type *Ty,
BasicBlock::iterator IP) {
setInsertionPoint(IP);
InsertPt = IP;
return expandCodeFor(SH, Ty);
}
@ -111,6 +82,19 @@ namespace llvm {
Value *expand(const SCEV *S);
/// expandCodeFor - Insert code to directly compute the specified SCEV
/// expression into the program. The inserted code is inserted into the
/// SCEVExpander's current insertion point. If a type is specified, the
/// result will be expanded to have that type, with a cast if necessary.
Value *expandCodeFor(const SCEV* SH, const Type *Ty = 0);
/// isInsertedInstruction - Return true if the specified instruction was
/// inserted by the code rewriter. If so, the client should not modify the
/// instruction.
bool isInsertedInstruction(Instruction *I) const {
return InsertedValues.count(I);
}
Value *visitConstant(const SCEVConstant *S) {
return S->getValue();
}

View File

@ -33,6 +33,7 @@ namespace llvm {
class GlobalVariable;
class MachineConstantPoolEntry;
class MachineConstantPoolValue;
class MachineModuleInfo;
class DwarfWriter;
class Mangler;
class Section;
@ -58,14 +59,12 @@ namespace llvm {
gcp_map_type GCMetadataPrinters;
protected:
/// DW -This is needed because printDeclare() has to insert
/// DbgVariable entries into the dwarf table. This is a short term hack
/// that ought be fixed soon.
/// MMI - If available, this is a pointer to the current MachineModuleInfo.
MachineModuleInfo *MMI;
/// DW - If available, this is a pointer to the current dwarf writer.
DwarfWriter *DW;
// Necessary for external weak linkage support
std::set<const GlobalValue*> ExtWeakSymbols;
/// OptLevel - Generating code at a specific optimization level.
CodeGenOpt::Level OptLevel;
public:
@ -110,6 +109,15 @@ namespace llvm {
///
bool VerboseAsm;
/// Private state for PrintSpecial()
// Assign a unique ID to this machine instruction.
mutable const MachineInstr *LastMI;
mutable const Function *LastFn;
mutable unsigned Counter;
// Private state for processDebugLock()
mutable DebugLocTuple PrevDLT;
protected:
explicit AsmPrinter(raw_ostream &o, TargetMachine &TM,
const TargetAsmInfo *T, CodeGenOpt::Level OL, bool V);

View File

@ -25,8 +25,12 @@ namespace llvm {
class IntrinsicLowering {
const TargetData& TD;
bool Warned;
public:
explicit IntrinsicLowering(const TargetData &td) : TD(td) {}
explicit IntrinsicLowering(const TargetData &td) :
TD(td), Warned(false) {}
/// AddPrototypes - This method, if called, causes all of the prototypes
/// that might be needed by an intrinsic lowering implementation to be

View File

@ -74,8 +74,9 @@ class MachineInstrBuilder {
return *this;
}
const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB) const {
MI->addOperand(MachineOperand::CreateMBB(MBB));
const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB,
unsigned char TargetFlags = 0) const {
MI->addOperand(MachineOperand::CreateMBB(MBB, TargetFlags));
return *this;
}
@ -85,25 +86,29 @@ class MachineInstrBuilder {
}
const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx,
int Offset = 0) const {
MI->addOperand(MachineOperand::CreateCPI(Idx, Offset));
int Offset = 0,
unsigned char TargetFlags = 0) const {
MI->addOperand(MachineOperand::CreateCPI(Idx, Offset, TargetFlags));
return *this;
}
const MachineInstrBuilder &addJumpTableIndex(unsigned Idx) const {
MI->addOperand(MachineOperand::CreateJTI(Idx));
const MachineInstrBuilder &addJumpTableIndex(unsigned Idx,
unsigned char TargetFlags = 0) const {
MI->addOperand(MachineOperand::CreateJTI(Idx, TargetFlags));
return *this;
}
const MachineInstrBuilder &addGlobalAddress(GlobalValue *GV,
int64_t Offset = 0) const {
MI->addOperand(MachineOperand::CreateGA(GV, Offset));
int64_t Offset = 0,
unsigned char TargetFlags = 0) const {
MI->addOperand(MachineOperand::CreateGA(GV, Offset, TargetFlags));
return *this;
}
const MachineInstrBuilder &addExternalSymbol(const char *FnName,
int64_t Offset = 0) const {
MI->addOperand(MachineOperand::CreateES(FnName, Offset));
int64_t Offset = 0,
unsigned char TargetFlags = 0) const {
MI->addOperand(MachineOperand::CreateES(FnName, Offset, TargetFlags));
return *this;
}
@ -113,28 +118,7 @@ class MachineInstrBuilder {
}
const MachineInstrBuilder &addOperand(const MachineOperand &MO) const {
if (MO.isReg())
return addReg(MO.getReg(),
(MO.isDef() ? RegState::Define : 0) |
(MO.isImplicit() ? RegState::Implicit : 0) |
(MO.isKill() ? RegState::Kill : 0) |
(MO.isDead() ? RegState::Dead : 0) |
(MO.isEarlyClobber() ? RegState::EarlyClobber : 0),
MO.getSubReg());
if (MO.isImm())
return addImm(MO.getImm());
if (MO.isFI())
return addFrameIndex(MO.getIndex());
if (MO.isGlobal())
return addGlobalAddress(MO.getGlobal(), MO.getOffset());
if (MO.isCPI())
return addConstantPoolIndex(MO.getIndex(), MO.getOffset());
if (MO.isSymbol())
return addExternalSymbol(MO.getSymbolName());
if (MO.isJTI())
return addJumpTableIndex(MO.getIndex());
assert(0 && "Unknown operand for MachineInstrBuilder::AddOperand!");
MI->addOperand(MO);
return *this;
}
};

View File

@ -47,7 +47,14 @@ class MachineOperand {
private:
/// OpKind - Specify what kind of operand this is. This discriminates the
/// union.
MachineOperandType OpKind : 8;
unsigned char OpKind; // MachineOperandType
/// SubReg - Subregister number, only valid for MO_Register. A value of 0
/// indicates the MO_Register has no subReg.
unsigned char SubReg;
/// TargetFlags - This is a set of target-specific operand flags.
unsigned char TargetFlags;
/// IsDef/IsImp/IsKill/IsDead flags - These are only valid for MO_Register
/// operands.
@ -73,10 +80,6 @@ class MachineOperand {
/// model the GCC inline asm '&' constraint modifier.
bool IsEarlyClobber : 1;
/// SubReg - Subregister number, only valid for MO_Register. A value of 0
/// indicates the MO_Register has no subReg.
unsigned char SubReg;
/// ParentMI - This is the instruction that this operand is embedded into.
/// This is valid for all operand types, when the operand is in an instr.
MachineInstr *ParentMI;
@ -105,7 +108,9 @@ class MachineOperand {
} OffsetedInfo;
} Contents;
explicit MachineOperand(MachineOperandType K) : OpKind(K), ParentMI(0) {}
explicit MachineOperand(MachineOperandType K) : OpKind(K), ParentMI(0) {
TargetFlags = 0;
}
public:
MachineOperand(const MachineOperand &M) {
*this = M;
@ -115,7 +120,12 @@ class MachineOperand {
/// getType - Returns the MachineOperandType for this operand.
///
MachineOperandType getType() const { return OpKind; }
MachineOperandType getType() const { return (MachineOperandType)OpKind; }
unsigned char getTargetFlags() const { return TargetFlags; }
void setTargetFlags(unsigned char F) { TargetFlags = F; }
void addTargetFlag(unsigned char F) { TargetFlags |= F; }
/// getParent - Return the instruction that this operand belongs to.
///
@ -361,9 +371,11 @@ class MachineOperand {
Op.SubReg = SubReg;
return Op;
}
static MachineOperand CreateMBB(MachineBasicBlock *MBB) {
static MachineOperand CreateMBB(MachineBasicBlock *MBB,
unsigned char TargetFlags = 0) {
MachineOperand Op(MachineOperand::MO_MachineBasicBlock);
Op.setMBB(MBB);
Op.setTargetFlags(TargetFlags);
return Op;
}
static MachineOperand CreateFI(unsigned Idx) {
@ -371,27 +383,35 @@ class MachineOperand {
Op.setIndex(Idx);
return Op;
}
static MachineOperand CreateCPI(unsigned Idx, int Offset) {
static MachineOperand CreateCPI(unsigned Idx, int Offset,
unsigned char TargetFlags = 0) {
MachineOperand Op(MachineOperand::MO_ConstantPoolIndex);
Op.setIndex(Idx);
Op.setOffset(Offset);
Op.setTargetFlags(TargetFlags);
return Op;
}
static MachineOperand CreateJTI(unsigned Idx) {
static MachineOperand CreateJTI(unsigned Idx,
unsigned char TargetFlags = 0) {
MachineOperand Op(MachineOperand::MO_JumpTableIndex);
Op.setIndex(Idx);
Op.setTargetFlags(TargetFlags);
return Op;
}
static MachineOperand CreateGA(GlobalValue *GV, int64_t Offset) {
static MachineOperand CreateGA(GlobalValue *GV, int64_t Offset,
unsigned char TargetFlags = 0) {
MachineOperand Op(MachineOperand::MO_GlobalAddress);
Op.Contents.OffsetedInfo.Val.GV = GV;
Op.setOffset(Offset);
Op.setTargetFlags(TargetFlags);
return Op;
}
static MachineOperand CreateES(const char *SymName, int64_t Offset = 0) {
static MachineOperand CreateES(const char *SymName, int64_t Offset = 0,
unsigned char TargetFlags = 0) {
MachineOperand Op(MachineOperand::MO_ExternalSymbol);
Op.Contents.OffsetedInfo.Val.SymbolName = SymName;
Op.setOffset(Offset);
Op.setTargetFlags(TargetFlags);
return Op;
}
const MachineOperand &operator=(const MachineOperand &MO) {
@ -404,6 +424,7 @@ class MachineOperand {
SubReg = MO.SubReg;
ParentMI = MO.ParentMI;
Contents = MO.Contents;
TargetFlags = MO.TargetFlags;
return *this;
}

View File

@ -278,31 +278,37 @@ class SelectionDAG {
return getConstantFP(Val, VT, true);
}
SDValue getGlobalAddress(const GlobalValue *GV, MVT VT,
int64_t offset = 0, bool isTargetGA = false);
int64_t offset = 0, bool isTargetGA = false,
unsigned char TargetFlags = 0);
SDValue getTargetGlobalAddress(const GlobalValue *GV, MVT VT,
int64_t offset = 0) {
return getGlobalAddress(GV, VT, offset, true);
int64_t offset = 0,
unsigned char TargetFlags = 0) {
return getGlobalAddress(GV, VT, offset, true, TargetFlags);
}
SDValue getFrameIndex(int FI, MVT VT, bool isTarget = false);
SDValue getTargetFrameIndex(int FI, MVT VT) {
return getFrameIndex(FI, VT, true);
}
SDValue getJumpTable(int JTI, MVT VT, bool isTarget = false);
SDValue getTargetJumpTable(int JTI, MVT VT) {
return getJumpTable(JTI, VT, true);
SDValue getJumpTable(int JTI, MVT VT, bool isTarget = false,
unsigned char TargetFlags = 0);
SDValue getTargetJumpTable(int JTI, MVT VT, unsigned char TargetFlags = 0) {
return getJumpTable(JTI, VT, true, TargetFlags);
}
SDValue getConstantPool(Constant *C, MVT VT,
unsigned Align = 0, int Offs = 0, bool isT=false);
unsigned Align = 0, int Offs = 0, bool isT=false,
unsigned char TargetFlags = 0);
SDValue getTargetConstantPool(Constant *C, MVT VT,
unsigned Align = 0, int Offset = 0) {
return getConstantPool(C, VT, Align, Offset, true);
unsigned Align = 0, int Offset = 0,
unsigned char TargetFlags = 0) {
return getConstantPool(C, VT, Align, Offset, true, TargetFlags);
}
SDValue getConstantPool(MachineConstantPoolValue *C, MVT VT,
unsigned Align = 0, int Offs = 0, bool isT=false);
unsigned Align = 0, int Offs = 0, bool isT=false,
unsigned char TargetFlags = 0);
SDValue getTargetConstantPool(MachineConstantPoolValue *C,
MVT VT, unsigned Align = 0,
int Offset = 0) {
return getConstantPool(C, VT, Align, Offset, true);
int Offset = 0, unsigned char TargetFlags=0) {
return getConstantPool(C, VT, Align, Offset, true, TargetFlags);
}
// When generating a branch to a BB, we don't in general know enough
// to provide debug info for the BB at that time, so keep this one around.
@ -310,8 +316,8 @@ class SelectionDAG {
SDValue getBasicBlock(MachineBasicBlock *MBB, DebugLoc dl);
SDValue getExternalSymbol(const char *Sym, MVT VT);
SDValue getExternalSymbol(const char *Sym, DebugLoc dl, MVT VT);
SDValue getTargetExternalSymbol(const char *Sym, MVT VT);
SDValue getTargetExternalSymbol(const char *Sym, DebugLoc dl, MVT VT);
SDValue getTargetExternalSymbol(const char *Sym, MVT VT,
unsigned char TargetFlags = 0);
SDValue getArgFlags(ISD::ArgFlagsTy Flags);
SDValue getValueType(MVT);
SDValue getRegister(unsigned Reg, MVT VT);
@ -862,7 +868,8 @@ class SelectionDAG {
std::vector<SDNode*> ValueTypeNodes;
std::map<MVT, SDNode*, MVT::compareRawBits> ExtendedValueTypeNodes;
StringMap<SDNode*> ExternalSymbols;
StringMap<SDNode*> TargetExternalSymbols;
std::map<std::pair<std::string, unsigned char>,SDNode*> TargetExternalSymbols;
};
template <> struct GraphTraits<SelectionDAG*> : public GraphTraits<SDNode*> {

View File

@ -1819,13 +1819,15 @@ class ConstantFPSDNode : public SDNode {
class GlobalAddressSDNode : public SDNode {
GlobalValue *TheGlobal;
int64_t Offset;
unsigned char TargetFlags;
friend class SelectionDAG;
GlobalAddressSDNode(bool isTarget, const GlobalValue *GA, MVT VT,
int64_t o = 0);
GlobalAddressSDNode(unsigned Opc, const GlobalValue *GA, MVT VT,
int64_t o, unsigned char TargetFlags);
public:
GlobalValue *getGlobal() const { return TheGlobal; }
int64_t getOffset() const { return Offset; }
unsigned char getTargetFlags() const { return TargetFlags; }
// Return the address space this GlobalAddress belongs to.
unsigned getAddressSpace() const;
@ -1858,14 +1860,16 @@ class FrameIndexSDNode : public SDNode {
class JumpTableSDNode : public SDNode {
int JTI;
unsigned char TargetFlags;
friend class SelectionDAG;
JumpTableSDNode(int jti, MVT VT, bool isTarg)
JumpTableSDNode(int jti, MVT VT, bool isTarg, unsigned char TF)
: SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable,
DebugLoc::getUnknownLoc(), getSDVTList(VT)), JTI(jti) {
DebugLoc::getUnknownLoc(), getSDVTList(VT)), JTI(jti), TargetFlags(TF) {
}
public:
int getIndex() const { return JTI; }
unsigned char getTargetFlags() const { return TargetFlags; }
static bool classof(const JumpTableSDNode *) { return true; }
static bool classof(const SDNode *N) {
@ -1881,40 +1885,27 @@ class ConstantPoolSDNode : public SDNode {
} Val;
int Offset; // It's a MachineConstantPoolValue if top bit is set.
unsigned Alignment; // Minimum alignment requirement of CP (not log2 value).
unsigned char TargetFlags;
friend class SelectionDAG;
ConstantPoolSDNode(bool isTarget, Constant *c, MVT VT, int o=0)
ConstantPoolSDNode(bool isTarget, Constant *c, MVT VT, int o, unsigned Align,
unsigned char TF)
: SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
DebugLoc::getUnknownLoc(),
getSDVTList(VT)), Offset(o), Alignment(0) {
assert((int)Offset >= 0 && "Offset is too large");
Val.ConstVal = c;
}
ConstantPoolSDNode(bool isTarget, Constant *c, MVT VT, int o, unsigned Align)
: SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
DebugLoc::getUnknownLoc(),
getSDVTList(VT)), Offset(o), Alignment(Align) {
getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) {
assert((int)Offset >= 0 && "Offset is too large");
Val.ConstVal = c;
}
ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
MVT VT, int o=0)
MVT VT, int o, unsigned Align, unsigned char TF)
: SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
DebugLoc::getUnknownLoc(),
getSDVTList(VT)), Offset(o), Alignment(0) {
assert((int)Offset >= 0 && "Offset is too large");
Val.MachineCPVal = v;
Offset |= 1 << (sizeof(unsigned)*CHAR_BIT-1);
}
ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
MVT VT, int o, unsigned Align)
: SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
DebugLoc::getUnknownLoc(),
getSDVTList(VT)), Offset(o), Alignment(Align) {
getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) {
assert((int)Offset >= 0 && "Offset is too large");
Val.MachineCPVal = v;
Offset |= 1 << (sizeof(unsigned)*CHAR_BIT-1);
}
public:
bool isMachineConstantPoolEntry() const {
return (int)Offset < 0;
@ -1937,6 +1928,7 @@ class ConstantPoolSDNode : public SDNode {
// Return the alignment of this constant pool object, which is either 0 (for
// default alignment) or the desired value.
unsigned getAlignment() const { return Alignment; }
unsigned char getTargetFlags() const { return TargetFlags; }
const Type *getType() const;
@ -2101,15 +2093,18 @@ LabelSDNode(unsigned NodeTy, DebugLoc dl, SDValue ch, unsigned id)
class ExternalSymbolSDNode : public SDNode {
const char *Symbol;
unsigned char TargetFlags;
friend class SelectionDAG;
ExternalSymbolSDNode(bool isTarget, const char *Sym, MVT VT)
ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned char TF, MVT VT)
: SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol,
DebugLoc::getUnknownLoc(),
getSDVTList(VT)), Symbol(Sym) {
getSDVTList(VT)), Symbol(Sym), TargetFlags(TF) {
}
public:
const char *getSymbol() const { return Symbol; }
unsigned char getTargetFlags() const { return TargetFlags; }
static bool classof(const ExternalSymbolSDNode *) { return true; }
static bool classof(const SDNode *N) {

View File

@ -1,3 +1,4 @@
//===- CodeGen/ValueTypes.h - Low-Level Target independ. types --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
@ -72,6 +73,12 @@ namespace llvm {
LAST_VALUETYPE = 30, // This always remains at the end of the list.
// This is the current maximum for LAST_VALUETYPE.
// Affects ValueTypeActions in TargetLowering.h.
// MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors
// This value must be a multiple of 32.
MAX_ALLOWED_VALUETYPE = 64,
// iPTRAny - An int value the size of the pointer of the current
// target to any address space. This must only be used internal to
// tblgen. Other than for overloading, we treat iPTRAny the same as iPTR.

View File

@ -0,0 +1,33 @@
//===--- BuiltinOptions.h - The LLVM Compiler Driver ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open
// Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Declarations of all global command-line option variables.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INCLUDE_COMPILER_DRIVER_BUILTIN_OPTIONS_H
#define LLVM_INCLUDE_COMPILER_DRIVER_BUILTIN_OPTIONS_H
#include "llvm/Support/CommandLine.h"
#include <string>
namespace SaveTempsEnum { enum Values { Cwd, Obj, Unset }; }
extern llvm::cl::list<std::string> InputFilenames;
extern llvm::cl::opt<std::string> OutputFilename;
extern llvm::cl::list<std::string> Languages;
extern llvm::cl::opt<bool> DryRun;
extern llvm::cl::opt<bool> VerboseMode;
extern llvm::cl::opt<bool> CheckGraph;
extern llvm::cl::opt<bool> WriteGraph;
extern llvm::cl::opt<bool> ViewGraph;
extern llvm::cl::opt<SaveTempsEnum::Values> SaveTemps;
#endif // LLVM_INCLUDE_COMPILER_DRIVER_BUILTIN_OPTIONS_H

View File

@ -0,0 +1,82 @@
//===--- ForceLinkage.h - The LLVM Compiler Driver --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open
// Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// A bit of preprocessor magic to force references to static libraries. Needed
// because plugin initialization is done via static variables.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_H
#define LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_H
#include "llvm/CompilerDriver/ForceLinkageMacros.h"
namespace llvmc {
// Declare all ForceLinkage$(PluginName) functions.
#ifdef LLVMC_BUILTIN_PLUGIN_1
LLVMC_FORCE_LINKAGE_DECL(LLVMC_BUILTIN_PLUGIN_1);
#endif
#ifdef LLVMC_BUILTIN_PLUGIN_2
LLVMC_FORCE_LINKAGE_DECL(LLVMC_BUILTIN_PLUGIN_2);
#endif
#ifdef LLVMC_BUILTIN_PLUGIN_3
LLVMC_FORCE_LINKAGE_DECL(LLVMC_BUILTIN_PLUGIN_3);
#endif
#ifdef LLVMC_BUILTIN_PLUGIN_4
LLVMC_FORCE_LINKAGE_DECL(LLVMC_BUILTIN_PLUGIN_4);
#endif
#ifdef LLVMC_BUILTIN_PLUGIN_5
LLVMC_FORCE_LINKAGE_DECL(LLVMC_BUILTIN_PLUGIN_5);
#endif
namespace force_linkage {
struct LinkageForcer {
LinkageForcer() {
// Call all ForceLinkage$(PluginName) functions.
#ifdef LLVMC_BUILTIN_PLUGIN_1
LLVMC_FORCE_LINKAGE_CALL(LLVMC_BUILTIN_PLUGIN_1);
#endif
#ifdef LLVMC_BUILTIN_PLUGIN_2
LLVMC_FORCE_LINKAGE_CALL(LLVMC_BUILTIN_PLUGIN_2);
#endif
#ifdef LLVMC_BUILTIN_PLUGIN_3
LLVMC_FORCE_LINKAGE_CALL(LLVMC_BUILTIN_PLUGIN_3);
#endif
#ifdef LLVMC_BUILTIN_PLUGIN_4
LLVMC_FORCE_LINKAGE_CALL(LLVMC_BUILTIN_PLUGIN_4);
#endif
#ifdef LLVMC_BUILTIN_PLUGIN_5
LLVMC_FORCE_LINKAGE_CALL(LLVMC_BUILTIN_PLUGIN_5);
#endif
}
};
} // End namespace force_linkage.
// The only externally used bit.
void ForceLinkage() {
force_linkage::LinkageForcer dummy;
}
} // End namespace llvmc.
#endif // LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_H

View File

@ -0,0 +1,29 @@
//===--- ForceLinkageMacros.h - The LLVM Compiler Driver --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open
// Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Preprocessor magic that forces references to static libraries - common
// macros used by both driver and plugins.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_MACROS_H
#define LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_MACROS_H
#define LLVMC_FORCE_LINKAGE_PREFIX(PluginName) ForceLinkage ## PluginName
#define LLVMC_FORCE_LINKAGE_FUN(PluginName) \
LLVMC_FORCE_LINKAGE_PREFIX(PluginName)
#define LLVMC_FORCE_LINKAGE_DECL(PluginName) \
void LLVMC_FORCE_LINKAGE_FUN(PluginName) ()
#define LLVMC_FORCE_LINKAGE_CALL(PluginName) \
LLVMC_FORCE_LINKAGE_FUN(PluginName) ()
#endif // LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_MACROS_H

View File

@ -12,15 +12,15 @@
// supported please refer to the tools' manual page or run the tool
// with the --help option.
//
// This
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INCLUDE_COMPILER_DRIVER_MAIN_INC
#define LLVM_INCLUDE_COMPILER_DRIVER_MAIN_INC
#include "llvm/CompilerDriver/BuiltinOptions.h"
#include "llvm/CompilerDriver/CompilationGraph.h"
#include "llvm/CompilerDriver/Error.h"
#include "llvm/CompilerDriver/ForceLinkage.h"
#include "llvm/CompilerDriver/Plugin.h"
#include "llvm/System/Path.h"
@ -59,27 +59,56 @@ cl::opt<bool> WriteGraph("write-graph",
cl::opt<bool> ViewGraph("view-graph",
cl::desc("Show compilation graph in GhostView"),
cl::Hidden);
cl::opt<bool> SaveTemps("save-temps",
cl::desc("Keep temporary files"),
cl::Hidden);
cl::opt<SaveTempsEnum::Values> SaveTemps
("save-temps", cl::desc("Keep temporary files"),
cl::init(SaveTempsEnum::Unset),
cl::values(clEnumValN(SaveTempsEnum::Obj, "obj",
"Save files in the directory specified with -o"),
clEnumValN(SaveTempsEnum::Cwd, "cwd",
"Use current working directory"),
clEnumValN(SaveTempsEnum::Obj, "", "Same as 'cwd'"),
clEnumValEnd),
cl::ValueOptional);
namespace {
sys::Path getTempDir() {
sys::Path tempDir;
// GCC 4.5-style -save-temps handling.
if (SaveTemps == SaveTempsEnum::Unset) {
tempDir = sys::Path::GetTemporaryDirectory();
}
else if (SaveTemps == SaveTempsEnum::Obj && !OutputFilename.empty()) {
tempDir = OutputFilename;
if (!tempDir.exists()) {
std::string ErrMsg;
if (tempDir.createDirectoryOnDisk(true, &ErrMsg))
throw std::runtime_error(ErrMsg);
}
}
// else if (SaveTemps == Cwd) -> use current dir (leave tempDir empty)
return tempDir;
}
/// BuildTargets - A small wrapper for CompilationGraph::Build.
int BuildTargets(CompilationGraph& graph, const LanguageMap& langMap) {
int ret;
const sys::Path& tempDir = SaveTemps
? sys::Path("")
: sys::Path(sys::Path::GetTemporaryDirectory());
const sys::Path& tempDir = getTempDir();
try {
ret = graph.Build(tempDir, langMap);
}
catch(...) {
tempDir.eraseFromDisk(true);
if (SaveTemps == SaveTempsEnum::Unset)
tempDir.eraseFromDisk(true);
throw;
}
if (!SaveTemps)
if (SaveTemps == SaveTempsEnum::Unset)
tempDir.eraseFromDisk(true);
return ret;
}
@ -87,6 +116,8 @@ namespace {
int main(int argc, char** argv) {
try {
ForceLinkage();
LanguageMap langMap;
CompilationGraph graph;

View File

@ -1,23 +1,23 @@
//===- llvm/Config/Targets.def - LLVM Target Architectures ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file enumerates all of the target architectures supported by
// this build of LLVM. Clients of this file should define the
// LLVM_TARGET macro to be a function-like macro with a single
// parameter (the name of the target); including this file will then
// enumerate all of the targets.
//
// The set of targets supported by LLVM is generated at configuration
// time, at which point this header is generated. Do not modify this
// header directly.
//
//===----------------------------------------------------------------------===//
/*===- llvm/Config/Targets.def - LLVM Target Architectures ------*- C++ -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
|* This file is distributed under the University of Illinois Open Source *|
|* License. See LICENSE.TXT for details. *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This file enumerates all of the target architectures supported by *|
|* this build of LLVM. Clients of this file should define the *|
|* LLVM_TARGET macro to be a function-like macro with a single *|
|* parameter (the name of the target); including this file will then *|
|* enumerate all of the targets. *|
|* *|
|* The set of targets supported by LLVM is generated at configuration *|
|* time, at which point this header is generated. Do not modify this *|
|* header directly. *|
|* *|
\*===----------------------------------------------------------------------===*/
#ifndef LLVM_TARGET
# error Please define the macro LLVM_TARGET(TargetName)

View File

@ -282,6 +282,12 @@
/* Have pthread_mutex_lock */
#cmakedefine HAVE_PTHREAD_MUTEX_LOCK ${HAVE_PTHREAD_MUTEX_LOCK}
/* Have pthread_rwlock_init */
#cmakedefine HAVE_PTHREAD_RWLOCK_INIT ${HAVE_PTHREAD_RWLOCK_INIT}
/* Have pthread_getspecific */
#cmakedefine HAVE_PTHREAD_GETSPECIFIC ${HAVE_PTHREAD_GETSPECIFIC}
/* Define to 1 if srand48/lrand48/drand48 exist in <stdlib.h> */
#undef HAVE_RAND48

View File

@ -279,6 +279,9 @@
/* Define to have the %a format string */
#undef HAVE_PRINTF_A
/* Have pthread_getspecific */
#undef HAVE_PTHREAD_GETSPECIFIC
/* Define to 1 if you have the <pthread.h> header file. */
#undef HAVE_PTHREAD_H

View File

@ -865,6 +865,7 @@ class MDString : public Constant {
/// get() - Static factory methods - Return objects of the specified value.
///
static MDString *get(const char *StrBegin, const char *StrEnd);
static MDString *get(const std::string &Str);
/// size() - The length of this string.
///

View File

@ -29,13 +29,14 @@ class Constant;
class Function;
class GlobalVariable;
class GlobalValue;
class Module;
class ModuleProvider;
class TargetData;
class Type;
class MutexGuard;
class JITEventListener;
class JITMemoryManager;
class MachineCodeInfo;
class Module;
class ModuleProvider;
class MutexGuard;
class TargetData;
class Type;
class ExecutionEngineState {
private:
@ -276,7 +277,14 @@ class ExecutionEngine {
virtual void *getOrEmitGlobalVariable(const GlobalVariable *GV) {
return getPointerToGlobal((GlobalValue*)GV);
}
/// Registers a listener to be called back on various events within
/// the JIT. See JITEventListener.h for more details. Does not
/// take ownership of the argument. The argument may be NULL, in
/// which case these functions do nothing.
virtual void RegisterJITEventListener(JITEventListener *L) {}
virtual void UnregisterJITEventListener(JITEventListener *L) {}
/// DisableLazyCompilation - If called, the JIT will abort if lazy compilation
/// is ever attempted.
void DisableLazyCompilation(bool Disabled = true) {

View File

@ -18,9 +18,7 @@
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include <cstdlib>
namespace llvm {
extern void LinkInInterpreter();
}
extern "C" void LLVMLinkInInterpreter();
namespace {
struct ForceInterpreterLinking {
@ -32,7 +30,7 @@ namespace {
if (std::getenv("bar") != (char*) -1)
return;
llvm::LinkInInterpreter();
LLVMLinkInInterpreter();
}
} ForceInterpreterLinking;
}

View File

@ -18,9 +18,7 @@
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include <cstdlib>
namespace llvm {
extern void LinkInJIT();
}
extern "C" void LLVMLinkInJIT();
namespace {
struct ForceJITLinking {
@ -32,7 +30,7 @@ namespace {
if (std::getenv("bar") != (char*) -1)
return;
llvm::LinkInJIT();
LLVMLinkInJIT();
}
} ForceJITLinking;
}

View File

@ -0,0 +1,59 @@
//===- JITEventListener.h - Exposes events from JIT compilation -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the JITEventListener interface, which lets users get
// callbacks when significant events happen during the JIT compilation process.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H
#define LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H
#include "llvm/Support/DataTypes.h"
namespace llvm {
class Function;
/// Empty for now, but this object will contain all details about the
/// generated machine code that a Listener might care about.
struct JITEvent_EmittedFunctionDetails {
};
/// JITEventListener - This interface is used by the JIT to notify clients about
/// significant events during compilation. For example, we could have
/// implementations for profilers and debuggers that need to know where
/// functions have been emitted.
///
/// Each method defaults to doing nothing, so you only need to override the ones
/// you care about.
class JITEventListener {
public:
JITEventListener() {}
virtual ~JITEventListener(); // Defined in JIT.cpp.
typedef JITEvent_EmittedFunctionDetails EmittedFunctionDetails;
/// NotifyFunctionEmitted - Called after a function has been successfully
/// emitted to memory. The function still has its MachineFunction attached,
/// if you should happen to need that.
virtual void NotifyFunctionEmitted(const Function &F,
void *Code, size_t Size,
const EmittedFunctionDetails &Details) {}
/// NotifyFreeingMachineCode - This is called inside of
/// freeMachineCodeForFunction(), after the global mapping is removed, but
/// before the machine code is returned to the allocator. OldPtr is the
/// address of the machine code.
virtual void NotifyFreeingMachineCode(const Function &F, void *OldPtr) {}
};
JITEventListener *createMacOSJITEventListener();
} // end namespace llvm.
#endif

View File

@ -302,15 +302,24 @@ let TargetPrefix = "arm" in {
// Interleaving vector stores from N-element structures.
def int_arm_neon_vst3i : Intrinsic<[llvm_void_ty],
[llvm_anyint_ty, llvm_ptr_ty],
[llvm_ptr_ty, llvm_anyint_ty],
[IntrWriteArgMem]>;
def int_arm_neon_vst3f : Intrinsic<[llvm_void_ty],
[llvm_anyfloat_ty, llvm_ptr_ty],
[llvm_ptr_ty, llvm_anyfloat_ty],
[IntrWriteArgMem]>;
def int_arm_neon_vst4i : Intrinsic<[llvm_void_ty],
[llvm_anyint_ty, llvm_ptr_ty],
[llvm_ptr_ty, llvm_anyint_ty],
[IntrWriteArgMem]>;
def int_arm_neon_vst4f : Intrinsic<[llvm_void_ty],
[llvm_anyfloat_ty, llvm_ptr_ty],
[llvm_ptr_ty, llvm_anyfloat_ty],
[IntrWriteArgMem]>;
// Vector Table Lookup
def int_arm_neon_vtbl : Intrinsic<[llvm_v8i8_ty],
[llvm_anyint_ty, llvm_v8i8_ty],
[IntrNoMem]>;
// Vector Table Extension
def int_arm_neon_vtbx : Intrinsic<[llvm_v8i8_ty],
[llvm_v8i8_ty, llvm_anyint_ty,
llvm_v8i8_ty], [IntrNoMem]>;
}

View File

@ -77,6 +77,7 @@ namespace {
(void) llvm::createLCSSAPass();
(void) llvm::createLICMPass();
(void) llvm::createLiveValuesPass();
(void) llvm::createLoopDependenceAnalysisPass();
(void) llvm::createLoopExtractorPass();
(void) llvm::createLoopSimplifyPass();
(void) llvm::createLoopStrengthReducePass();

166
include/llvm/MC/MCContext.h Normal file
View File

@ -0,0 +1,166 @@
//===- MCContext.h - Machine Code Context -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCCONTEXT_H
#define LLVM_MC_MCCONTEXT_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Allocator.h"
namespace llvm {
class MCValue;
class MCSection;
class MCSymbol;
/// MCContext - Context object for machine code objects.
class MCContext {
MCContext(const MCContext&); // DO NOT IMPLEMENT
MCContext &operator=(const MCContext&); // DO NOT IMPLEMENT
/// Sections - Bindings of names to allocated sections.
StringMap<MCSection*> Sections;
/// Symbols - Bindings of names to symbols.
StringMap<MCSymbol*> Symbols;
/// SymbolValues - Bindings of symbols to values.
DenseMap<MCSymbol*, MCValue> SymbolValues;
/// Allocator - Allocator object used for creating machine code objects.
///
/// We use a bump pointer allocator to avoid the need to track all allocated
/// objects.
BumpPtrAllocator Allocator;
public:
MCContext();
~MCContext();
/// GetSection - Get or create a new section with the given @param Name.
MCSection *GetSection(const char *Name);
/// CreateSymbol - Create a new symbol with the specified @param Name.
///
/// @param Name - The symbol name, which must be unique across all symbols.
MCSymbol *CreateSymbol(const char *Name);
/// GetOrCreateSymbol - Lookup the symbol inside with the specified
/// @param Name. If it exists, return it. If not, create a forward
/// reference and return it.
///
/// @param Name - The symbol name, which must be unique across all symbols.
MCSymbol *GetOrCreateSymbol(const char *Name);
/// CreateTemporarySymbol - Create a new temporary symbol with the specified
/// @param Name.
///
/// @param Name - The symbol name, for debugging purposes only, temporary
/// symbols do not surive assembly. If non-empty the name must be unique
/// across all symbols.
MCSymbol *CreateTemporarySymbol(const char *Name = "");
/// LookupSymbol - Get the symbol for @param Name, or null.
MCSymbol *LookupSymbol(const char *Name) const;
/// ClearSymbolValue - Erase a value binding for @param Symbol, if one
/// exists.
void ClearSymbolValue(MCSymbol *Symbol);
/// SetSymbolValue - Set the value binding for @param Symbol to @param
/// Value.
void SetSymbolValue(MCSymbol *Symbol, const MCValue &Value);
/// GetSymbolValue - Return the current value for @param Symbol, or null if
/// none exists.
const MCValue *GetSymbolValue(MCSymbol *Symbol) const;
void *Allocate(unsigned Size, unsigned Align = 8) {
return Allocator.Allocate(Size, Align);
}
void Deallocate(void *Ptr) {
}
};
} // end namespace llvm
// operator new and delete aren't allowed inside namespaces.
// The throw specifications are mandated by the standard.
/// @brief Placement new for using the MCContext's allocator.
///
/// This placement form of operator new uses the MCContext's allocator for
/// obtaining memory. It is a non-throwing new, which means that it returns
/// null on error. (If that is what the allocator does. The current does, so if
/// this ever changes, this operator will have to be changed, too.)
/// Usage looks like this (assuming there's an MCContext 'Context' in scope):
/// @code
/// // Default alignment (16)
/// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments);
/// // Specific alignment
/// IntegerLiteral *Ex2 = new (Context, 8) IntegerLiteral(arguments);
/// @endcode
/// Please note that you cannot use delete on the pointer; it must be
/// deallocated using an explicit destructor call followed by
/// @c Context.Deallocate(Ptr).
///
/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
/// @param C The MCContext that provides the allocator.
/// @param Alignment The alignment of the allocated memory (if the underlying
/// allocator supports it).
/// @return The allocated memory. Could be NULL.
inline void *operator new(size_t Bytes, llvm::MCContext &C,
size_t Alignment = 16) throw () {
return C.Allocate(Bytes, Alignment);
}
/// @brief Placement delete companion to the new above.
///
/// This operator is just a companion to the new above. There is no way of
/// invoking it directly; see the new operator for more details. This operator
/// is called implicitly by the compiler if a placement new expression using
/// the MCContext throws in the object constructor.
inline void operator delete(void *Ptr, llvm::MCContext &C, size_t)
throw () {
C.Deallocate(Ptr);
}
/// This placement form of operator new[] uses the MCContext's allocator for
/// obtaining memory. It is a non-throwing new[], which means that it returns
/// null on error.
/// Usage looks like this (assuming there's an MCContext 'Context' in scope):
/// @code
/// // Default alignment (16)
/// char *data = new (Context) char[10];
/// // Specific alignment
/// char *data = new (Context, 8) char[10];
/// @endcode
/// Please note that you cannot use delete on the pointer; it must be
/// deallocated using an explicit destructor call followed by
/// @c Context.Deallocate(Ptr).
///
/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
/// @param C The MCContext that provides the allocator.
/// @param Alignment The alignment of the allocated memory (if the underlying
/// allocator supports it).
/// @return The allocated memory. Could be NULL.
inline void *operator new[](size_t Bytes, llvm::MCContext& C,
size_t Alignment = 16) throw () {
return C.Allocate(Bytes, Alignment);
}
/// @brief Placement delete[] companion to the new[] above.
///
/// This operator is just a companion to the new[] above. There is no way of
/// invoking it directly; see the new[] operator for more details. This operator
/// is called implicitly by the compiler if a placement new[] expression using
/// the MCContext throws in the object constructor.
inline void operator delete[](void *Ptr, llvm::MCContext &C) throw () {
C.Deallocate(Ptr);
}
#endif

View File

@ -16,7 +16,7 @@
#ifndef LLVM_MC_MCINST_H
#define LLVM_MC_MCINST_H
#include "llvm/MC/MCImm.h"
#include "llvm/MC/MCValue.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/DebugLoc.h"
@ -31,14 +31,14 @@ class MCOperand {
kRegister, ///< Register operand.
kImmediate, ///< Immediate operand.
kMBBLabel, ///< Basic block label.
kMCImm
kMCValue
};
unsigned char Kind;
union {
unsigned RegVal;
int64_t ImmVal;
MCImm MCImmVal;
MCValue MCValueVal;
struct {
unsigned FunctionNo;
unsigned BlockNo;

View File

@ -0,0 +1,28 @@
//===- MCSection.h - Machine Code Sections ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSECTION_H
#define LLVM_MC_MCSECTION_H
#include <string>
namespace llvm {
class MCSection {
std::string Name;
public:
MCSection(const char *_Name) : Name(_Name) {}
const std::string &getName() const { return Name; }
};
} // end namespace llvm
#endif

View File

@ -0,0 +1,191 @@
//===- MCStreamer.h - High-level Streaming Machine Code Output --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSTREAMER_H
#define LLVM_MC_MCSTREAMER_H
#include "llvm/Support/DataTypes.h"
namespace llvm {
class MCContext;
class MCValue;
class MCInst;
class MCSection;
class MCSymbol;
class raw_ostream;
/// MCStreamer - Streaming machine code generation interface.
class MCStreamer {
public:
enum SymbolAttr {
Global, /// .globl
Hidden, /// .hidden (ELF)
IndirectSymbol, /// .indirect_symbol (Apple)
Internal, /// .internal (ELF)
LazyReference, /// .lazy_reference (Apple)
NoDeadStrip, /// .no_dead_strip (Apple)
PrivateExtern, /// .private_extern (Apple)
Protected, /// .protected (ELF)
Reference, /// .reference (Apple)
Weak, /// .weak
WeakDefinition, /// .weak_definition (Apple)
WeakReference, /// .weak_reference (Apple)
SymbolAttrFirst = Global,
SymbolAttrLast = WeakReference
};
private:
MCContext &Context;
MCStreamer(const MCStreamer&); // DO NOT IMPLEMENT
MCStreamer &operator=(const MCStreamer&); // DO NOT IMPLEMENT
protected:
MCStreamer(MCContext &Ctx);
public:
virtual ~MCStreamer();
MCContext &getContext() const { return Context; }
/// @name Symbol & Section Management
/// @{
/// SwitchSection - Set the current section where code is being emitted to
/// @param Section.
///
/// This corresponds to assembler directives like .section, .text, etc.
virtual void SwitchSection(MCSection *Section) = 0;
/// EmitLabel - Emit a label for @param Symbol into the current section.
///
/// This corresponds to an assembler statement such as:
/// foo:
///
/// @param Symbol - The symbol to emit. A given symbol should only be
/// emitted as a label once, and symbols emitted as a label should never be
/// used in an assignment.
//
// FIXME: What to do about the current section? Should we get rid of the
// symbol section in the constructor and initialize it here?
virtual void EmitLabel(MCSymbol *Symbol) = 0;
/// EmitAssignment - Emit an assignment of @param Value to @param Symbol.
///
/// This corresponds to an assembler statement such as:
/// symbol = value
///
/// The assignment generates no code, but has the side effect of binding the
/// value in the current context. For the assembly streamer, this prints the
/// binding into the .s file.
///
/// @param Symbol - The symbol being assigned to.
/// @param Value - The value for the symbol.
/// @param MakeAbsolute - If true, then the symbol should be given the
/// absolute value of @param Value, even if @param Value would be
/// relocatable expression. This corresponds to the ".set" directive.
virtual void EmitAssignment(MCSymbol *Symbol, const MCValue &Value,
bool MakeAbsolute = false) = 0;
/// EmitSymbolAttribute - Add the given @param Attribute to @param Symbol.
//
// FIXME: This doesn't make much sense, could we just have attributes be on
// the symbol and make the printer smart enough to add the right symbols?
// This should work as long as the order of attributes in the file doesn't
// matter.
virtual void EmitSymbolAttribute(MCSymbol *Symbol,
SymbolAttr Attribute) = 0;
/// @}
/// @name Generating Data
/// @{
/// EmitBytes - Emit @param Length bytes starting at @param Data into the
/// output.
///
/// This is used to implement assembler directives such as .byte, .ascii,
/// etc.
virtual void EmitBytes(const char *Data, unsigned Length) = 0;
/// EmitValue - Emit the expression @param Value into the output as a native
/// integer of the given @param Size bytes.
///
/// This is used to implement assembler directives such as .word, .quad,
/// etc.
///
/// @param Value - The value to emit.
/// @param Size - The size of the integer (in bytes) to emit. This must
/// match a native machine width.
virtual void EmitValue(const MCValue &Value, unsigned Size) = 0;
/// EmitValueToAlignment - Emit some number of copies of @param Value until
/// the byte alignment @param ByteAlignment is reached.
///
/// If the number of bytes need to emit for the alignment is not a multiple
/// of @param ValueSize, then the contents of the emitted fill bytes is
/// undefined.
///
/// This used to implement the .align assembler directive.
///
/// @param ByteAlignment - The alignment to reach. This must be a power of
/// two.
/// @param Value - The value to use when filling bytes.
/// @param Size - The size of the integer (in bytes) to emit for @param
/// Value. This must match a native machine width.
/// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
/// the alignment cannot be reached in this many bytes, no bytes are
/// emitted.
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0) = 0;
/// EmitValueToOffset - Emit some number of copies of @param Value until the
/// byte offset @param Offset is reached.
///
/// This is used to implement assembler directives such as .org.
///
/// @param Offset - The offset to reach.This may be an expression, but the
/// expression must be associated with the current section.
/// @param Value - The value to use when filling bytes.
//
// FIXME: How are we going to signal failures out of this?
virtual void EmitValueToOffset(const MCValue &Offset,
unsigned char Value = 0) = 0;
/// @}
/// EmitInstruction - Emit the given @param Instruction into the current
/// section.
virtual void EmitInstruction(const MCInst &Inst) = 0;
/// Finish - Finish emission of machine code and flush any output.
virtual void Finish() = 0;
};
/// createAsmStreamer - Create a machine code streamer which will print out
/// assembly for the native target, suitable for compiling with a native
/// assembler.
MCStreamer *createAsmStreamer(MCContext &Ctx, raw_ostream &OS);
// FIXME: These two may end up getting rolled into a single
// createObjectStreamer interface, which implements the assembler backend, and
// is parameterized on an output object file writer.
/// createMachOStream - Create a machine code streamer which will generative
/// Mach-O format object files.
MCStreamer *createMachOStreamer(MCContext &Ctx, raw_ostream &OS);
/// createELFStreamer - Create a machine code streamer which will generative
/// ELF format object files.
MCStreamer *createELFStreamer(MCContext &Ctx, raw_ostream &OS);
} // end namespace llvm
#endif

View File

@ -0,0 +1,33 @@
//===- MCSymbol.h - Machine Code Symbols ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSYMBOL_H
#define LLVM_MC_MCSYMBOL_H
#include <string>
namespace llvm {
class MCSymbol {
MCSection *Section;
std::string Name;
unsigned IsTemporary : 1;
public:
MCSymbol(const char *_Name, bool _IsTemporary)
: Section(0), Name(_Name), IsTemporary(_IsTemporary) {}
MCSection *getSection() const { return Section; }
void setSection(MCSection *Value) { Section = Value; }
const std::string &getName() const { return Name; }
};
} // end namespace llvm
#endif

View File

@ -1,4 +1,4 @@
//===-- llvm/MC/MCImm.h - MCImm class ---------------------------*- C++ -*-===//
//===-- llvm/MC/MCValue.h - MCValue class -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -7,22 +7,25 @@
//
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of the MCInst and MCOperand classes, which
// is the basic representation used to represent low-level machine code
// instructions.
// This file contains the declaration of the MCValue class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCIMM_H
#define LLVM_MC_MCIMM_H
#ifndef LLVM_MC_MCVALUE_H
#define LLVM_MC_MCVALUE_H
#include "llvm/Support/DataTypes.h"
namespace llvm {
class MCSymbol;
/// MCImm - This represents an "assembler immediate". In its most general form,
/// this can hold "SymbolA - SymbolB + imm64". Not all targets supports
/// MCValue - This represents an "assembler immediate". In its most general
/// form, this can hold "SymbolA - SymbolB + imm64". Not all targets supports
/// relocations of this general form, but we need to represent this anyway.
class MCImm {
///
/// Note that this class must remain a simple POD value class, because we need
/// it to live in unions etc.
class MCValue {
MCSymbol *SymA, *SymB;
int64_t Cst;
public:
@ -32,16 +35,16 @@ class MCImm {
MCSymbol *getSymB() const { return SymB; }
static MCImm get(MCSymbol *SymA, MCSymbol *SymB = 0, int64_t Val = 0) {
MCImm R;
static MCValue get(MCSymbol *SymA, MCSymbol *SymB = 0, int64_t Val = 0) {
MCValue R;
R.Cst = Val;
R.SymA = SymA;
R.SymB = SymB;
return R;
}
static MCImm get(int64_t Val) {
MCImm R;
static MCValue get(int64_t Val) {
MCValue R;
R.Cst = Val;
R.SymA = 0;
R.SymB = 0;

View File

@ -51,7 +51,8 @@ struct DefaultDOTGraphTraits {
/// getNodeLabel - Given a node and a pointer to the top level graph, return
/// the label to print in the node.
template<typename GraphType>
static std::string getNodeLabel(const void *Node, const GraphType& Graph) {
static std::string getNodeLabel(const void *Node,
const GraphType& Graph, bool ShortNames) {
return "";
}

View File

@ -72,6 +72,7 @@ template<typename GraphType>
class GraphWriter {
std::ostream &O;
const GraphType &G;
bool ShortNames;
typedef DOTGraphTraits<GraphType> DOTTraits;
typedef GraphTraits<GraphType> GTraits;
@ -79,7 +80,8 @@ class GraphWriter {
typedef typename GTraits::nodes_iterator node_iterator;
typedef typename GTraits::ChildIteratorType child_iterator;
public:
GraphWriter(std::ostream &o, const GraphType &g) : O(o), G(g) {}
GraphWriter(std::ostream &o, const GraphType &g, bool SN) :
O(o), G(g), ShortNames(SN) {}
void writeHeader(const std::string &Name) {
std::string GraphName = DOTTraits::getGraphName(G);
@ -130,7 +132,7 @@ class GraphWriter {
O << "label=\"{";
if (!DOTTraits::renderGraphFromBottomUp()) {
O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G));
O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G, ShortNames));
// If we should include the address of the node in the label, do so now.
if (DOTTraits::hasNodeAddressLabel(Node, G))
@ -156,7 +158,7 @@ class GraphWriter {
}
if (DOTTraits::renderGraphFromBottomUp()) {
O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G));
O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G, ShortNames));
// If we should include the address of the node in the label, do so now.
if (DOTTraits::hasNodeAddressLabel(Node, G))
@ -250,10 +252,11 @@ class GraphWriter {
template<typename GraphType>
std::ostream &WriteGraph(std::ostream &O, const GraphType &G,
bool ShortNames = false,
const std::string &Name = "",
const std::string &Title = "") {
// Start the graph emission process...
GraphWriter<GraphType> W(O, G);
GraphWriter<GraphType> W(O, G, ShortNames);
// Output the header for the graph...
W.writeHeader(Title);
@ -272,6 +275,7 @@ std::ostream &WriteGraph(std::ostream &O, const GraphType &G,
template<typename GraphType>
sys::Path WriteGraph(const GraphType &G,
const std::string& Name,
bool ShortNames = false,
const std::string& Title = "") {
std::string ErrMsg;
sys::Path Filename = sys::Path::GetTemporaryDirectory(&ErrMsg);
@ -290,7 +294,7 @@ sys::Path WriteGraph(const GraphType &G,
std::ofstream O(Filename.c_str());
if (O.good()) {
WriteGraph(O, G, Name, Title);
WriteGraph(O, G, ShortNames, Name, Title);
cerr << " done. \n";
O.close();
@ -308,8 +312,9 @@ sys::Path WriteGraph(const GraphType &G,
template<typename GraphType>
void ViewGraph(const GraphType& G,
const std::string& Name,
bool ShortNames = false,
const std::string& Title = "") {
sys::Path Filename = WriteGraph(G, Name, Title);
sys::Path Filename = WriteGraph(G, Name, ShortNames, Title);
if (Filename.isEmpty()) {
return;

View File

@ -16,6 +16,7 @@
#define LLVM_SUPPORT_TIMER_H
#include "llvm/Support/DataTypes.h"
#include "llvm/System/Mutex.h"
#include <string>
#include <vector>
#include <iosfwd>
@ -34,28 +35,37 @@ class TimerGroup;
/// if they are never started.
///
class Timer {
int64_t Elapsed; // Wall clock time elapsed in seconds
int64_t UserTime; // User time elapsed
int64_t SystemTime; // System time elapsed
int64_t MemUsed; // Memory allocated (in bytes)
int64_t PeakMem; // Peak memory used
int64_t PeakMemBase; // Temporary for peak calculation...
double Elapsed; // Wall clock time elapsed in seconds
double UserTime; // User time elapsed
double SystemTime; // System time elapsed
ssize_t MemUsed; // Memory allocated (in bytes)
size_t PeakMem; // Peak memory used
size_t PeakMemBase; // Temporary for peak calculation...
std::string Name; // The name of this time variable
bool Started; // Has this time variable ever been started?
TimerGroup *TG; // The TimerGroup this Timer is in.
mutable sys::SmartMutex<true> Lock; // Mutex for the contents of this Timer.
public:
explicit Timer(const std::string &N);
Timer(const std::string &N, TimerGroup &tg);
Timer(const Timer &T);
~Timer();
int64_t getProcessTime() const { return UserTime+SystemTime; }
int64_t getWallTime() const { return Elapsed; }
int64_t getMemUsed() const { return MemUsed; }
int64_t getPeakMem() const { return PeakMem; }
double getProcessTime() const { return UserTime+SystemTime; }
double getWallTime() const { return Elapsed; }
ssize_t getMemUsed() const { return MemUsed; }
size_t getPeakMem() const { return PeakMem; }
std::string getName() const { return Name; }
const Timer &operator=(const Timer &T) {
if (&T < this) {
T.Lock.acquire();
Lock.acquire();
} else {
Lock.acquire();
T.Lock.acquire();
}
Elapsed = T.Elapsed;
UserTime = T.UserTime;
SystemTime = T.SystemTime;
@ -65,6 +75,15 @@ class Timer {
Name = T.Name;
Started = T.Started;
assert(TG == T.TG && "Can only assign timers in the same TimerGroup!");
if (&T < this) {
T.Lock.release();
Lock.release();
} else {
Lock.release();
T.Lock.release();
}
return *this;
}
@ -160,11 +179,9 @@ class TimerGroup {
private:
friend class Timer;
void addTimer() { ++NumTimers; }
void addTimer();
void removeTimer();
void addTimerToPrint(const Timer &T) {
TimersToPrint.push_back(Timer(true, T));
}
void addTimerToPrint(const Timer &T);
};
} // End llvm namespace

View File

@ -20,14 +20,15 @@ namespace llvm {
namespace sys {
void MemoryFence();
uint32_t CompareAndSwap32(volatile uint32_t* ptr,
uint32_t new_value,
uint32_t old_value);
int32_t AtomicIncrement32(volatile int32_t* ptr);
int32_t AtomicDecrement32(volatile int32_t* ptr);
int32_t AtomicAdd32(volatile int32_t* ptr, int32_t val);
int64_t AtomicAdd64(volatile int64_t* ptr, int64_t val);
typedef uint32_t cas_flag;
cas_flag CompareAndSwap(volatile cas_flag* ptr,
cas_flag new_value,
cas_flag old_value);
cas_flag AtomicIncrement(volatile cas_flag* ptr);
cas_flag AtomicDecrement(volatile cas_flag* ptr);
cas_flag AtomicAdd(volatile cas_flag* ptr, cas_flag val);
cas_flag AtomicMul(volatile cas_flag* ptr, cas_flag val);
cas_flag AtomicDiv(volatile cas_flag* ptr, cas_flag val);
}
}

View File

@ -0,0 +1,41 @@
//===- llvm/System/ThreadLocal.h - Thread Local Data ------------*- 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 llvm::sys::ThreadLocal class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SYSTEM_THREAD_LOCAL_H
#define LLVM_SYSTEM_THREAD_LOCAL_H
#include "llvm/System/Threading.h"
#include <cassert>
namespace llvm {
namespace sys {
class ThreadLocalImpl {
void* data;
public:
ThreadLocalImpl();
virtual ~ThreadLocalImpl();
void setInstance(const void* d);
const void* getInstance();
};
template<class T>
class ThreadLocal : public ThreadLocalImpl {
public:
ThreadLocal() : ThreadLocalImpl() { }
T* get() { return static_cast<T*>(getInstance()); }
void set(T* d) { setInstance(d); }
};
}
}
#endif

View File

@ -173,14 +173,18 @@ class TargetLowering {
/// ValueTypeActions - This is a bitvector that contains two bits for each
/// value type, where the two bits correspond to the LegalizeAction enum.
/// This can be queried with "getTypeAction(VT)".
uint32_t ValueTypeActions[2];
/// dimension by (MVT::MAX_ALLOWED_VALUETYPE/32) * 2
uint32_t ValueTypeActions[(MVT::MAX_ALLOWED_VALUETYPE/32)*2];
public:
ValueTypeActionImpl() {
ValueTypeActions[0] = ValueTypeActions[1] = 0;
ValueTypeActions[2] = ValueTypeActions[3] = 0;
}
ValueTypeActionImpl(const ValueTypeActionImpl &RHS) {
ValueTypeActions[0] = RHS.ValueTypeActions[0];
ValueTypeActions[1] = RHS.ValueTypeActions[1];
ValueTypeActions[2] = RHS.ValueTypeActions[2];
ValueTypeActions[3] = RHS.ValueTypeActions[3];
}
LegalizeAction getTypeAction(MVT VT) const {
@ -349,10 +353,13 @@ class TargetLowering {
/// for it.
LegalizeAction getOperationAction(unsigned Op, MVT VT) const {
if (VT.isExtended()) return Expand;
assert(Op < array_lengthof(OpActions) &&
(unsigned)VT.getSimpleVT() < sizeof(OpActions[0])*8 &&
assert(Op < array_lengthof(OpActions[0]) &&
(unsigned)VT.getSimpleVT() < sizeof(OpActions[0][0])*8 &&
"Table isn't big enough!");
return (LegalizeAction)((OpActions[Op] >> (2*VT.getSimpleVT())) & 3);
unsigned I = (unsigned) VT.getSimpleVT();
unsigned J = I & 31;
I = I >> 5;
return (LegalizeAction)((OpActions[I][Op] >> (J*2) ) & 3);
}
/// isOperationLegalOrCustom - Return true if the specified operation is
@ -940,10 +947,13 @@ class TargetLowering {
/// with the specified type and indicate what to do about it.
void setOperationAction(unsigned Op, MVT VT,
LegalizeAction Action) {
assert((unsigned)VT.getSimpleVT() < sizeof(OpActions[0])*8 &&
Op < array_lengthof(OpActions) && "Table isn't big enough!");
OpActions[Op] &= ~(uint64_t(3UL) << VT.getSimpleVT()*2);
OpActions[Op] |= (uint64_t)Action << VT.getSimpleVT()*2;
assert((unsigned)VT.getSimpleVT() < sizeof(OpActions[0][0])*8 &&
Op < array_lengthof(OpActions[0]) && "Table isn't big enough!");
unsigned I = (unsigned) VT.getSimpleVT();
unsigned J = I & 31;
I = I >> 5;
OpActions[I][Op] &= ~(uint64_t(3UL) << (J*2));
OpActions[I][Op] |= (uint64_t)Action << (J*2);
}
/// setLoadExtAction - Indicate that the specified load with extension does
@ -1566,7 +1576,9 @@ class TargetLowering {
/// Most operations are Legal (aka, supported natively by the target), but
/// operations that are not should be described. Note that operations on
/// non-legal value types are not described here.
uint64_t OpActions[ISD::BUILTIN_OP_END];
/// This array is accessed using VT.getSimpleVT(), so it is subject to
/// the MVT::MAX_ALLOWED_VALUETYPE * 2 bits.
uint64_t OpActions[MVT::MAX_ALLOWED_VALUETYPE/(sizeof(uint64_t)*4)][ISD::BUILTIN_OP_END];
/// LoadExtActions - For each load of load extension type and each value type,
/// keep a LegalizeAction that indicates how instruction selection should deal

View File

@ -18,20 +18,21 @@
#include "llvm/Config/config.h"
namespace llvm {
extern "C" {
// Declare all of the target-initialization functions that are available.
#define LLVM_TARGET(TargetName) void Initialize##TargetName##Target();
#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target();
#include "llvm/Config/Targets.def"
// Declare all of the available asm-printer initialization functions.
// Declare all of the target-initialization functions.
#define LLVM_ASM_PRINTER(TargetName) void Initialize##TargetName##AsmPrinter();
#define LLVM_ASM_PRINTER(TargetName) void LLVMInitialize##TargetName##AsmPrinter();
#include "llvm/Config/AsmPrinters.def"
}
namespace llvm {
/// InitializeAllTargets - The main program should call this function if it
/// wants to link in all available targets that LLVM is configured to support.
inline void InitializeAllTargets() {
#define LLVM_TARGET(TargetName) llvm::Initialize##TargetName##Target();
#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##Target();
#include "llvm/Config/Targets.def"
}
@ -39,18 +40,17 @@ namespace llvm {
/// it wants all asm printers that LLVM is configured to support. This will
/// cause them to be linked into its executable.
inline void InitializeAllAsmPrinters() {
#define LLVM_ASM_PRINTER(TargetName) Initialize##TargetName##AsmPrinter();
#define LLVM_ASM_PRINTER(TargetName) LLVMInitialize##TargetName##AsmPrinter();
#include "llvm/Config/AsmPrinters.def"
}
/// InitializeNativeTarget - The main program should call this function to
/// initialize the native target corresponding to the host. This is useful
/// for JIT applications to ensure that the target gets linked in correctly.
inline bool InitializeNativeTarget() {
// If we have a native target, initialize it to ensure it is linked in.
#ifdef LLVM_NATIVE_ARCH
#define DoInit2(TARG) llvm::Initialize ## TARG ()
#define DoInit2(TARG) LLVMInitialize ## TARG ()
#define DoInit(T) DoInit2(T)
DoInit(LLVM_NATIVE_ARCH);
return false;

View File

@ -114,13 +114,6 @@ AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = 0);
bool OnlyUsedByDbgInfoIntrinsics(Instruction *I,
SmallVectorImpl<DbgInfoIntrinsic *> *DbgInUses = 0);
/// UserIsDebugInfo - Return true if U is a constant expr used by
/// llvm.dbg.variable or llvm.dbg.global_variable
bool UserIsDebugInfo(User *U);
/// RemoveDbgInfoUser - Remove an User which is representing debug info.
void RemoveDbgInfoUser(User *U);
} // End llvm namespace
#endif

View File

@ -103,7 +103,7 @@ class Type : public AbstractTypeUser {
/// has no AbstractTypeUsers, the type is deleted. This is only sensical for
/// derived types.
///
mutable int32_t RefCount;
mutable sys::cas_flag RefCount;
const Type *getForwardedTypeInternal() const;
@ -338,7 +338,7 @@ class Type : public AbstractTypeUser {
void addRef() const {
assert(isAbstract() && "Cannot add a reference to a non-abstract type!");
sys::AtomicIncrement32(&RefCount);
sys::AtomicIncrement(&RefCount);
}
void dropRef() const {
@ -347,8 +347,8 @@ class Type : public AbstractTypeUser {
// If this is the last PATypeHolder using this object, and there are no
// PATypeHandles using it, the type is dead, delete it now.
int32_t Count = sys::AtomicDecrement32(&RefCount);
if (Count == 0 && AbstractTypeUsers.empty())
sys::cas_flag OldCount = sys::AtomicDecrement(&RefCount);
if (OldCount == 0 && AbstractTypeUsers.empty())
this->destroy();
}

View File

@ -31,12 +31,6 @@
#include <fstream>
using namespace llvm;
/// CFGOnly flag - This is used to control whether or not the CFG graph printer
/// prints out the contents of basic blocks or not. This is acceptable because
/// this code is only really used for debugging purposes.
///
static bool CFGOnly = false;
namespace llvm {
template<>
struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
@ -45,12 +39,13 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
}
static std::string getNodeLabel(const BasicBlock *Node,
const Function *Graph) {
if (CFGOnly && !Node->getName().empty())
const Function *Graph,
bool ShortNames) {
if (ShortNames && !Node->getName().empty())
return Node->getName() + ":";
std::ostringstream Out;
if (CFGOnly) {
if (ShortNames) {
WriteAsOperand(Out, Node, false);
return Out.str();
}
@ -117,9 +112,7 @@ namespace {
CFGOnlyViewer() : FunctionPass(&ID) {}
virtual bool runOnFunction(Function &F) {
CFGOnly = true;
F.viewCFG();
CFGOnly = false;
return false;
}
@ -168,14 +161,20 @@ static RegisterPass<CFGPrinter>
P1("dot-cfg", "Print CFG of function to 'dot' file", false, true);
namespace {
struct VISIBILITY_HIDDEN CFGOnlyPrinter : public CFGPrinter {
struct VISIBILITY_HIDDEN CFGOnlyPrinter : public FunctionPass {
static char ID; // Pass identification, replacement for typeid
CFGOnlyPrinter() : CFGPrinter(&ID) {}
CFGOnlyPrinter() : FunctionPass(&ID) {}
explicit CFGOnlyPrinter(void *pid) : FunctionPass(pid) {}
virtual bool runOnFunction(Function &F) {
bool OldCFGOnly = CFGOnly;
CFGOnly = true;
CFGPrinter::runOnFunction(F);
CFGOnly = OldCFGOnly;
std::string Filename = "cfg." + F.getName() + ".dot";
cerr << "Writing '" << Filename << "'...";
std::ofstream File(Filename.c_str());
if (File.good())
WriteGraph(File, (const Function*)&F, true);
else
cerr << " error opening file for writing!";
cerr << "\n";
return false;
}
void print(std::ostream &OS, const Module* = 0) const {}
@ -206,9 +205,7 @@ void Function::viewCFG() const {
/// his can make the graph smaller.
///
void Function::viewCFGOnly() const {
CFGOnly = true;
viewCFG();
CFGOnly = false;
ViewGraph(this, "cfg" + getName(), true);
}
FunctionPass *llvm::createCFGPrinterPass () {

View File

@ -18,6 +18,7 @@ add_llvm_library(LLVMAnalysis
LibCallAliasAnalysis.cpp
LibCallSemantics.cpp
LiveValues.cpp
LoopDependenceAnalysis.cpp
LoopInfo.cpp
LoopPass.cpp
LoopVR.cpp
@ -32,3 +33,5 @@ add_llvm_library(LLVMAnalysis
Trace.cpp
ValueTracking.cpp
)
target_link_libraries (LLVMAnalysis LLVMSupport)

View File

@ -93,7 +93,7 @@ void PrintDbgInfo::printFuncStart(const DbgFuncStartInst *FS) {
DISubprogram Subprogram(cast<GlobalVariable>(FS->getSubprogram()));
std::string Res1, Res2;
Out << "; fully qualified function name: " << Subprogram.getDisplayName(Res1)
<< " return type: " << Subprogram.getType().getName(Res2)
<< " return type: " << Subprogram.getReturnTypeName(Res2)
<< " at line " << Subprogram.getLineNumber()
<< "\n\n";
}

View File

@ -73,22 +73,22 @@ bool DIDescriptor::ValidDebugInfo(Value *V, CodeGenOpt::Level OptLevel) {
return true;
}
DIDescriptor::DIDescriptor(GlobalVariable *gv, unsigned RequiredTag) {
GV = gv;
DIDescriptor::DIDescriptor(GlobalVariable *GV, unsigned RequiredTag) {
DbgGV = GV;
// If this is non-null, check to see if the Tag matches. If not, set to null.
if (GV && getTag() != RequiredTag)
GV = 0;
DbgGV = 0;
}
const std::string &
DIDescriptor::getStringField(unsigned Elt, std::string &Result) const {
if (GV == 0) {
if (DbgGV == 0) {
Result.clear();
return Result;
}
Constant *C = GV->getInitializer();
Constant *C = DbgGV->getInitializer();
if (C == 0 || Elt >= C->getNumOperands()) {
Result.clear();
return Result;
@ -102,9 +102,9 @@ DIDescriptor::getStringField(unsigned Elt, std::string &Result) const {
}
uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const {
if (GV == 0) return 0;
if (DbgGV == 0) return 0;
Constant *C = GV->getInitializer();
Constant *C = DbgGV->getInitializer();
if (C == 0 || Elt >= C->getNumOperands())
return 0;
@ -114,9 +114,9 @@ uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const {
}
DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const {
if (GV == 0) return DIDescriptor();
if (DbgGV == 0) return DIDescriptor();
Constant *C = GV->getInitializer();
Constant *C = DbgGV->getInitializer();
if (C == 0 || Elt >= C->getNumOperands())
return DIDescriptor();
@ -125,9 +125,9 @@ DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const {
}
GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const {
if (GV == 0) return 0;
if (DbgGV == 0) return 0;
Constant *C = GV->getInitializer();
Constant *C = DbgGV->getInitializer();
if (C == 0 || Elt >= C->getNumOperands())
return 0;
@ -140,12 +140,12 @@ GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const {
//===----------------------------------------------------------------------===//
// Needed by DIVariable::getType().
DIType::DIType(GlobalVariable *gv) : DIDescriptor(gv) {
if (!gv) return;
DIType::DIType(GlobalVariable *GV) : DIDescriptor(GV) {
if (!GV) return;
unsigned tag = getTag();
if (tag != dwarf::DW_TAG_base_type && !DIDerivedType::isDerivedType(tag) &&
!DICompositeType::isCompositeType(tag))
GV = 0;
DbgGV = 0;
}
/// isDerivedType - Return true if the specified tag is legal for
@ -198,8 +198,8 @@ bool DIVariable::isVariable(unsigned Tag) {
}
unsigned DIArray::getNumElements() const {
assert (GV && "Invalid DIArray");
Constant *C = GV->getInitializer();
assert (DbgGV && "Invalid DIArray");
Constant *C = DbgGV->getInitializer();
assert (C && "Invalid DIArray initializer");
return C->getNumOperands();
}
@ -367,71 +367,10 @@ Constant *DIFactory::GetStringConstant(const std::string &String) {
return Slot = ConstantExpr::getBitCast(StrGV, DestTy);
}
/// GetOrCreateAnchor - Look up an anchor for the specified tag and name. If it
/// already exists, return it. If not, create a new one and return it.
DIAnchor DIFactory::GetOrCreateAnchor(unsigned TAG, const char *Name) {
const Type *EltTy = StructType::get(Type::Int32Ty, Type::Int32Ty, NULL);
// Otherwise, create the global or return it if already in the module.
Constant *C = M.getOrInsertGlobal(Name, EltTy);
assert(isa<GlobalVariable>(C) && "Incorrectly typed anchor?");
GlobalVariable *GV = cast<GlobalVariable>(C);
// If it has an initializer, it is already in the module.
if (GV->hasInitializer())
return SubProgramAnchor = DIAnchor(GV);
GV->setLinkage(GlobalValue::LinkOnceAnyLinkage);
GV->setSection("llvm.metadata");
GV->setConstant(true);
M.addTypeName("llvm.dbg.anchor.type", EltTy);
// Otherwise, set the initializer.
Constant *Elts[] = {
GetTagConstant(dwarf::DW_TAG_anchor),
ConstantInt::get(Type::Int32Ty, TAG)
};
GV->setInitializer(ConstantStruct::get(Elts, 2));
return DIAnchor(GV);
}
//===----------------------------------------------------------------------===//
// DIFactory: Primary Constructors
//===----------------------------------------------------------------------===//
/// GetOrCreateCompileUnitAnchor - Return the anchor for compile units,
/// creating a new one if there isn't already one in the module.
DIAnchor DIFactory::GetOrCreateCompileUnitAnchor() {
// If we already created one, just return it.
if (!CompileUnitAnchor.isNull())
return CompileUnitAnchor;
return CompileUnitAnchor = GetOrCreateAnchor(dwarf::DW_TAG_compile_unit,
"llvm.dbg.compile_units");
}
/// GetOrCreateSubprogramAnchor - Return the anchor for subprograms,
/// creating a new one if there isn't already one in the module.
DIAnchor DIFactory::GetOrCreateSubprogramAnchor() {
// If we already created one, just return it.
if (!SubProgramAnchor.isNull())
return SubProgramAnchor;
return SubProgramAnchor = GetOrCreateAnchor(dwarf::DW_TAG_subprogram,
"llvm.dbg.subprograms");
}
/// GetOrCreateGlobalVariableAnchor - Return the anchor for globals,
/// creating a new one if there isn't already one in the module.
DIAnchor DIFactory::GetOrCreateGlobalVariableAnchor() {
// If we already created one, just return it.
if (!GlobalVariableAnchor.isNull())
return GlobalVariableAnchor;
return GlobalVariableAnchor = GetOrCreateAnchor(dwarf::DW_TAG_variable,
"llvm.dbg.global_variables");
}
/// GetOrCreateArray - Create an descriptor for an array of descriptors.
/// This implicitly uniques the arrays created.
DIArray DIFactory::GetOrCreateArray(DIDescriptor *Tys, unsigned NumTys) {
@ -494,7 +433,7 @@ DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID,
unsigned RunTimeVer) {
Constant *Elts[] = {
GetTagConstant(dwarf::DW_TAG_compile_unit),
getCastToEmpty(GetOrCreateCompileUnitAnchor()),
Constant::getNullValue(EmptyStructPtr),
ConstantInt::get(Type::Int32Ty, LangID),
GetStringConstant(Filename),
GetStringConstant(Directory),
@ -509,7 +448,7 @@ DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID,
M.addTypeName("llvm.dbg.compile_unit.type", Init->getType());
GlobalVariable *GV = new GlobalVariable(Init->getType(), true,
GlobalValue::InternalLinkage,
GlobalValue::LinkOnceAnyLinkage,
Init, "llvm.dbg.compile_unit", &M);
GV->setSection("llvm.metadata");
return DICompileUnit(GV);
@ -655,7 +594,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
Constant *Elts[] = {
GetTagConstant(dwarf::DW_TAG_subprogram),
getCastToEmpty(GetOrCreateSubprogramAnchor()),
Constant::getNullValue(EmptyStructPtr),
getCastToEmpty(Context),
GetStringConstant(Name),
GetStringConstant(DisplayName),
@ -671,7 +610,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
M.addTypeName("llvm.dbg.subprogram.type", Init->getType());
GlobalVariable *GV = new GlobalVariable(Init->getType(), true,
GlobalValue::InternalLinkage,
GlobalValue::LinkOnceAnyLinkage,
Init, "llvm.dbg.subprogram", &M);
GV->setSection("llvm.metadata");
return DISubprogram(GV);
@ -687,7 +626,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name,
bool isDefinition, llvm::GlobalVariable *Val) {
Constant *Elts[] = {
GetTagConstant(dwarf::DW_TAG_variable),
getCastToEmpty(GetOrCreateGlobalVariableAnchor()),
Constant::getNullValue(EmptyStructPtr),
getCastToEmpty(Context),
GetStringConstant(Name),
GetStringConstant(DisplayName),
@ -704,7 +643,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name,
M.addTypeName("llvm.dbg.global_variable.type", Init->getType());
GlobalVariable *GV = new GlobalVariable(Init->getType(), true,
GlobalValue::InternalLinkage,
GlobalValue::LinkOnceAnyLinkage,
Init, "llvm.dbg.global_variable", &M);
GV->setSection("llvm.metadata");
return DIGlobalVariable(GV);
@ -954,12 +893,42 @@ namespace llvm {
Unit.getDirectory(Dir);
return true;
}
/// CollectDebugInfoAnchors - Collect debugging information anchors.
void CollectDebugInfoAnchors(Module &M,
SmallVector<GlobalVariable *, 2> &CUs,
SmallVector<GlobalVariable *, 4> &GVs,
SmallVector<GlobalVariable *, 4> &SPs) {
for (Module::global_iterator GVI = M.global_begin(), E = M.global_end();
GVI != E; GVI++) {
GlobalVariable *GV = GVI;
if (GV->hasName() && strncmp(GV->getNameStart(), "llvm.dbg", 8) == 0
&& GV->isConstant() && GV->hasInitializer()) {
DICompileUnit C(GV);
if (C.isNull() == false) {
CUs.push_back(GV);
continue;
}
DIGlobalVariable G(GV);
if (G.isNull() == false) {
GVs.push_back(GV);
continue;
}
DISubprogram S(GV);
if (S.isNull() == false) {
SPs.push_back(GV);
continue;
}
}
}
}
}
/// dump - Print descriptor.
void DIDescriptor::dump() const {
cerr << "[" << dwarf::TagString(getTag()) << "] ";
cerr << std::hex << "[GV:" << GV << "]" << std::dec;
cerr << std::hex << "[GV:" << DbgGV << "]" << std::dec;
}
/// dump - Print compile unit.
@ -1000,11 +969,11 @@ void DIType::dump() const {
cerr << " [fwd] ";
if (isBasicType(Tag))
DIBasicType(GV).dump();
DIBasicType(DbgGV).dump();
else if (isDerivedType(Tag))
DIDerivedType(GV).dump();
DIDerivedType(DbgGV).dump();
else if (isCompositeType(Tag))
DICompositeType(GV).dump();
DICompositeType(DbgGV).dump();
else {
cerr << "Invalid DIType\n";
return;
@ -1051,7 +1020,7 @@ void DIGlobal::dump() const {
cerr << " [def] ";
if (isGlobalVariable(Tag))
DIGlobalVariable(GV).dump();
DIGlobalVariable(DbgGV).dump();
cerr << "\n";
}
@ -1077,3 +1046,4 @@ void DIVariable::dump() const {
getType().dump();
cerr << "\n";
}

View File

@ -65,6 +65,7 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Support/Debug.h"
#include "llvm/System/Atomic.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/SparseBitVector.h"
#include "llvm/ADT/DenseSet.h"
@ -284,7 +285,8 @@ namespace {
// Timestamp a node (used for work list prioritization)
void Stamp() {
Timestamp = Counter++;
Timestamp = sys::AtomicIncrement(&Counter);
--Timestamp;
}
bool isRep() const {

View File

@ -0,0 +1,47 @@
//===- LoopDependenceAnalysis.cpp - LDA Implementation ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is the (beginning) of an implementation of a loop dependence analysis
// framework, which is used to detect dependences in memory accesses in loops.
//
// Please note that this is work in progress and the interface is subject to
// change.
//
// TODO: adapt as implementation progresses.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "lda"
#include "llvm/Analysis/LoopDependenceAnalysis.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolution.h"
using namespace llvm;
LoopPass *llvm::createLoopDependenceAnalysisPass() {
return new LoopDependenceAnalysis();
}
static RegisterPass<LoopDependenceAnalysis>
R("lda", "Loop Dependence Analysis", false, true);
char LoopDependenceAnalysis::ID = 0;
//===----------------------------------------------------------------------===//
// LoopDependenceAnalysis Implementation
//===----------------------------------------------------------------------===//
bool LoopDependenceAnalysis::runOnLoop(Loop *L, LPPassManager &) {
this->L = L;
SE = &getAnalysis<ScalarEvolution>();
return false;
}
void LoopDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<ScalarEvolution>();
}

View File

@ -73,7 +73,8 @@ static void ReadProfilingBlock(const char *ToolName, FILE *F,
//
ProfileInfoLoader::ProfileInfoLoader(const char *ToolName,
const std::string &Filename,
Module &TheModule) : M(TheModule) {
Module &TheModule) :
M(TheModule), Warned(false) {
FILE *F = fopen(Filename.c_str(), "r");
if (F == 0) {
cerr << ToolName << ": Error opening '" << Filename << "': ";
@ -200,7 +201,6 @@ void ProfileInfoLoader::getBlockCounts(std::vector<std::pair<BasicBlock*,
Counts.back().second += EdgeCounts[i].second;
unsigned SuccNum = EdgeCounts[i].first.second;
if (SuccNum >= TI->getNumSuccessors()) {
static bool Warned = false;
if (!Warned) {
cerr << "WARNING: profile info doesn't seem to match"
<< " the program!\n";

File diff suppressed because it is too large Load Diff

View File

@ -51,21 +51,26 @@ Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V,
if (Argument *A = dyn_cast<Argument>(V)) {
// Check to see if there is already a cast!
for (Value::use_iterator UI = A->use_begin(), E = A->use_end();
UI != E; ++UI) {
UI != E; ++UI)
if ((*UI)->getType() == Ty)
if (CastInst *CI = dyn_cast<CastInst>(cast<Instruction>(*UI)))
if (CI->getOpcode() == opcode) {
// If the cast isn't the first instruction of the function, move it.
if (BasicBlock::iterator(CI) !=
if (BasicBlock::iterator(CI) !=
A->getParent()->getEntryBlock().begin()) {
// If the CastInst is the insert point, change the insert point.
if (CI == InsertPt) ++InsertPt;
// Splice the cast at the beginning of the entry block.
CI->moveBefore(A->getParent()->getEntryBlock().begin());
// Recreate the cast at the beginning of the entry block.
// The old cast is left in place in case it is being used
// as an insert point.
Instruction *NewCI =
CastInst::Create(opcode, V, Ty, "",
A->getParent()->getEntryBlock().begin());
NewCI->takeName(CI);
CI->replaceAllUsesWith(NewCI);
return NewCI;
}
return CI;
}
}
Instruction *I = CastInst::Create(opcode, V, Ty, V->getName(),
A->getParent()->getEntryBlock().begin());
InsertedValues.insert(I);
@ -85,10 +90,13 @@ Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V,
It = cast<InvokeInst>(I)->getNormalDest()->begin();
while (isa<PHINode>(It)) ++It;
if (It != BasicBlock::iterator(CI)) {
// If the CastInst is the insert point, change the insert point.
if (CI == InsertPt) ++InsertPt;
// Splice the cast immediately after the operand in question.
CI->moveBefore(It);
// Recreate the cast at the beginning of the entry block.
// The old cast is left in place in case it is being used
// as an insert point.
Instruction *NewCI = CastInst::Create(opcode, V, Ty, "", It);
NewCI->takeName(CI);
CI->replaceAllUsesWith(NewCI);
return NewCI;
}
return CI;
}
@ -460,13 +468,13 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
const SCEV* Step = SE.getAnyExtendExpr(S->getStepRecurrence(SE),
CanonicalIV->getType());
Value *V = expand(SE.getAddRecExpr(Start, Step, S->getLoop()));
BasicBlock::iterator SaveInsertPt = getInsertionPoint();
BasicBlock::iterator SaveInsertPt = InsertPt;
BasicBlock::iterator NewInsertPt =
next(BasicBlock::iterator(cast<Instruction>(V)));
while (isa<PHINode>(NewInsertPt)) ++NewInsertPt;
V = expandCodeFor(SE.getTruncateExpr(SE.getUnknown(V), Ty), 0,
NewInsertPt);
setInsertionPoint(SaveInsertPt);
InsertPt = SaveInsertPt;
return V;
}
@ -497,8 +505,9 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
}
}
Value *RestV = expand(Rest);
return expand(SE.getAddExpr(S->getStart(), SE.getUnknown(RestV)));
// Just do a normal add. Pre-expand the operands to suppress folding.
return expand(SE.getAddExpr(SE.getUnknown(expand(S->getStart())),
SE.getUnknown(expand(Rest))));
}
// {0,+,1} --> Insert a canonical induction variable into the loop!
@ -546,36 +555,13 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
getOrInsertCanonicalInductionVariable(L, Ty);
// If this is a simple linear addrec, emit it now as a special case.
if (S->isAffine()) { // {0,+,F} --> i*F
Value *F = expandCodeFor(S->getOperand(1), Ty);
// If the insert point is directly inside of the loop, emit the multiply at
// the insert point. Otherwise, L is a loop that is a parent of the insert
// point loop. If we can, move the multiply to the outer most loop that it
// is safe to be in.
BasicBlock::iterator MulInsertPt = getInsertionPoint();
Loop *InsertPtLoop = SE.LI->getLoopFor(MulInsertPt->getParent());
if (InsertPtLoop != L && InsertPtLoop &&
L->contains(InsertPtLoop->getHeader())) {
do {
// If we cannot hoist the multiply out of this loop, don't.
if (!InsertPtLoop->isLoopInvariant(F)) break;
BasicBlock *InsertPtLoopPH = InsertPtLoop->getLoopPreheader();
// If this loop hasn't got a preheader, we aren't able to hoist the
// multiply.
if (!InsertPtLoopPH)
break;
// Otherwise, move the insert point to the preheader.
MulInsertPt = InsertPtLoopPH->getTerminator();
InsertPtLoop = InsertPtLoop->getParentLoop();
} while (InsertPtLoop != L);
}
return InsertBinop(Instruction::Mul, I, F, MulInsertPt);
}
if (S->isAffine()) // {0,+,F} --> i*F
return
expand(SE.getTruncateOrNoop(
SE.getMulExpr(SE.getUnknown(I),
SE.getNoopOrAnyExtend(S->getOperand(1),
I->getType())),
Ty));
// If this is a chain of recurrences, turn it into a closed form, using the
// folders, then expandCodeFor the closed form. This allows the folders to
@ -666,14 +652,42 @@ Value *SCEVExpander::expandCodeFor(const SCEV* SH, const Type *Ty) {
}
Value *SCEVExpander::expand(const SCEV *S) {
// Check to see if we already expanded this.
std::map<const SCEV*, AssertingVH<Value> >::iterator I =
InsertedExpressions.find(S);
if (I != InsertedExpressions.end())
BasicBlock::iterator SaveInsertPt = InsertPt;
// Compute an insertion point for this SCEV object. Hoist the instructions
// as far out in the loop nest as possible.
for (Loop *L = SE.LI->getLoopFor(InsertPt->getParent()); ;
L = L->getParentLoop())
if (S->isLoopInvariant(L)) {
if (!L) break;
if (BasicBlock *Preheader = L->getLoopPreheader())
InsertPt = Preheader->getTerminator();
} else {
// If the SCEV is computable at this level, insert it into the header
// after the PHIs (and after any other instructions that we've inserted
// there) so that it is guaranteed to dominate any user inside the loop.
if (L && S->hasComputableLoopEvolution(L))
InsertPt = L->getHeader()->getFirstNonPHI();
while (isInsertedInstruction(InsertPt)) ++InsertPt;
break;
}
// Check to see if we already expanded this here.
std::map<std::pair<const SCEV *, Instruction *>,
AssertingVH<Value> >::iterator I =
InsertedExpressions.find(std::make_pair(S, InsertPt));
if (I != InsertedExpressions.end()) {
InsertPt = SaveInsertPt;
return I->second;
}
// Expand the expression into instructions.
Value *V = visit(S);
InsertedExpressions[S] = V;
// Remember the expanded value for this SCEV at this location.
InsertedExpressions[std::make_pair(S, InsertPt)] = V;
InsertPt = SaveInsertPt;
return V;
}
@ -686,6 +700,9 @@ SCEVExpander::getOrInsertCanonicalInductionVariable(const Loop *L,
const Type *Ty) {
assert(Ty->isInteger() && "Can only insert integer induction variables!");
const SCEV* H = SE.getAddRecExpr(SE.getIntegerSCEV(0, Ty),
SE.getIntegerSCEV(1, Ty), L);
return expand(H);
SE.getIntegerSCEV(1, Ty), L);
BasicBlock::iterator SaveInsertPt = InsertPt;
Value *V = expandCodeFor(H, 0, L->getHeader()->begin());
InsertPt = SaveInsertPt;
return V;
}

View File

@ -45,8 +45,9 @@ AsmPrinter::AsmPrinter(raw_ostream &o, TargetMachine &tm,
const TargetAsmInfo *T, CodeGenOpt::Level OL, bool VDef)
: MachineFunctionPass(&ID), FunctionNumber(0), OptLevel(OL), O(o),
TM(tm), TAI(T), TRI(tm.getRegisterInfo()),
IsInTextSection(false)
{
IsInTextSection(false), LastMI(0), LastFn(0), Counter(~0U),
PrevDLT(0, ~0U, ~0U) {
DW = 0; MMI = 0;
switch (AsmVerbose) {
case cl::BOU_UNSET: VerboseAsm = VDef; break;
case cl::BOU_TRUE: VerboseAsm = true; break;
@ -177,28 +178,44 @@ bool AsmPrinter::doInitialization(Module &M) {
SwitchToDataSection(""); // Reset back to no section.
if (TAI->doesSupportDebugInformation()
|| TAI->doesSupportExceptionHandling()) {
MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
if (MMI) {
if (TAI->doesSupportDebugInformation() ||
TAI->doesSupportExceptionHandling()) {
MMI = getAnalysisIfAvailable<MachineModuleInfo>();
if (MMI)
MMI->AnalyzeModule(M);
DW = getAnalysisIfAvailable<DwarfWriter>();
if (DW)
DW->BeginModule(&M, MMI, O, this, TAI);
}
DW = getAnalysisIfAvailable<DwarfWriter>();
if (DW)
DW->BeginModule(&M, MMI, O, this, TAI);
}
return false;
}
bool AsmPrinter::doFinalization(Module &M) {
// Emit final debug information.
if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling())
DW->EndModule();
// If the target wants to know about weak references, print them all.
if (TAI->getWeakRefDirective()) {
if (!ExtWeakSymbols.empty())
SwitchToDataSection("");
// FIXME: This is not lazy, it would be nice to only print weak references
// to stuff that is actually used. Note that doing so would require targets
// to notice uses in operands (due to constant exprs etc). This should
// happen with the MC stuff eventually.
SwitchToDataSection("");
for (std::set<const GlobalValue*>::iterator i = ExtWeakSymbols.begin(),
e = ExtWeakSymbols.end(); i != e; ++i)
O << TAI->getWeakRefDirective() << Mang->getValueName(*i) << '\n';
// Print out module-level global variables here.
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) {
if (I->hasExternalWeakLinkage())
O << TAI->getWeakRefDirective() << Mang->getValueName(I) << '\n';
}
for (Module::const_iterator I = M.begin(), E = M.end();
I != E; ++I) {
if (I->hasExternalWeakLinkage())
O << TAI->getWeakRefDirective() << Mang->getValueName(I) << '\n';
}
}
if (TAI->getSetDirective()) {
@ -207,7 +224,7 @@ bool AsmPrinter::doFinalization(Module &M) {
O << '\n';
for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
I!=E; ++I) {
I != E; ++I) {
std::string Name = Mang->getValueName(I);
std::string Target;
@ -235,12 +252,13 @@ bool AsmPrinter::doFinalization(Module &M) {
// If we don't have any trampolines, then we don't require stack memory
// to be executable. Some targets have a directive to declare this.
Function* InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline");
Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline");
if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty())
if (TAI->getNonexecutableStackDirective())
O << TAI->getNonexecutableStackDirective() << '\n';
delete Mang; Mang = 0;
DW = 0; MMI = 0;
return false;
}
@ -1298,20 +1316,15 @@ void AsmPrinter::PrintSpecial(const MachineInstr *MI, const char *Code) const {
if (VerboseAsm)
O << TAI->getCommentString();
} else if (!strcmp(Code, "uid")) {
// Assign a unique ID to this machine instruction.
static const MachineInstr *LastMI = 0;
static const Function *F = 0;
static unsigned Counter = 0U-1;
// Comparing the address of MI isn't sufficient, because machineinstrs may
// be allocated to the same address across functions.
const Function *ThisF = MI->getParent()->getParent()->getFunction();
// If this is a new machine instruction, bump the counter.
if (LastMI != MI || F != ThisF) {
// If this is a new LastFn instruction, bump the counter.
if (LastMI != MI || LastFn != ThisF) {
++Counter;
LastMI = MI;
F = ThisF;
LastFn = ThisF;
}
O << Counter;
} else {
@ -1326,7 +1339,6 @@ void AsmPrinter::PrintSpecial(const MachineInstr *MI, const char *Code) const {
void AsmPrinter::processDebugLoc(DebugLoc DL) {
if (TAI->doesSupportDebugInformation() && DW->ShouldEmitDwarfDebug()) {
if (!DL.isUnknown()) {
static DebugLocTuple PrevDLT(0, ~0U, ~0U);
DebugLocTuple CurDLT = MF->getDebugLocTuple(DL);
if (CurDLT.CompileUnit != 0 && PrevDLT != CurDLT)

View File

@ -126,7 +126,6 @@ void DIE::Profile(FoldingSetNodeID &ID) {
#ifndef NDEBUG
void DIE::print(std::ostream &O, unsigned IncIndent) {
static unsigned IndentCount = 0;
IndentCount += IncIndent;
const std::string Indent(IndentCount, ' ');
bool isBlock = Abbrev.getTag() == 0;

View File

@ -141,9 +141,13 @@ namespace llvm {
/// Abstract compile unit.
CompileUnit *AbstractCU;
// Private data for print()
mutable unsigned IndentCount;
public:
explicit DIE(unsigned Tag)
: Abbrev(Tag, dwarf::DW_CHILDREN_no), Offset(0), Size(0) {}
: Abbrev(Tag, dwarf::DW_CHILDREN_no), Offset(0),
Size(0), IndentCount(0) {}
virtual ~DIE();
// Accessors.

View File

@ -141,9 +141,12 @@ class VISIBILITY_HIDDEN DbgScope {
SmallVector<DbgScope *, 4> Scopes; // Scopes defined in scope.
SmallVector<DbgVariable *, 8> Variables;// Variables declared in scope.
SmallVector<DbgConcreteScope *, 8> ConcreteInsts;// Concrete insts of funcs.
// Private state for dump()
mutable unsigned IndentLevel;
public:
DbgScope(DbgScope *P, DIDescriptor D)
: Parent(P), Desc(D), StartLabelID(0), EndLabelID(0) {}
: Parent(P), Desc(D), StartLabelID(0), EndLabelID(0), IndentLevel(0) {}
virtual ~DbgScope();
// Accessors.
@ -176,7 +179,6 @@ class VISIBILITY_HIDDEN DbgScope {
#ifndef NDEBUG
void DbgScope::dump() const {
static unsigned IndentLevel = 0;
std::string Indent(IndentLevel, ' ');
cerr << Indent; Desc.dump();
@ -1240,27 +1242,7 @@ void DwarfDebug::ConstructCompileUnit(GlobalVariable *GV) {
CompileUnits.push_back(Unit);
}
/// ConstructCompileUnits - Create a compile unit DIEs.
void DwarfDebug::ConstructCompileUnits() {
GlobalVariable *Root = M->getGlobalVariable("llvm.dbg.compile_units");
if (!Root)
return;
assert(Root->hasLinkOnceLinkage() && Root->hasOneUse() &&
"Malformed compile unit descriptor anchor type");
Constant *RootC = cast<Constant>(*Root->use_begin());
assert(RootC->hasNUsesOrMore(1) &&
"Malformed compile unit descriptor anchor type");
for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
UI != UE; ++UI)
for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
UUI != UUE; ++UUI) {
GlobalVariable *GV = cast<GlobalVariable>(*UUI);
ConstructCompileUnit(GV);
}
}
bool DwarfDebug::ConstructGlobalVariableDIE(GlobalVariable *GV) {
void DwarfDebug::ConstructGlobalVariableDIE(GlobalVariable *GV) {
DIGlobalVariable DI_GV(GV);
CompileUnit *DW_Unit = MainCU;
if (!DW_Unit)
@ -1269,7 +1251,7 @@ bool DwarfDebug::ConstructGlobalVariableDIE(GlobalVariable *GV) {
// Check for pre-existence.
DIE *&Slot = DW_Unit->getDieMapSlotFor(DI_GV.getGV());
if (Slot)
return false;
return;
DIE *VariableDie = CreateGlobalVariableDIE(DW_Unit, DI_GV);
@ -1290,33 +1272,10 @@ bool DwarfDebug::ConstructGlobalVariableDIE(GlobalVariable *GV) {
// Expose as global. FIXME - need to check external flag.
std::string Name;
DW_Unit->AddGlobal(DI_GV.getName(Name), VariableDie);
return true;
return;
}
/// ConstructGlobalVariableDIEs - Create DIEs for each of the externally visible
/// global variables. Return true if at least one global DIE is created.
bool DwarfDebug::ConstructGlobalVariableDIEs() {
GlobalVariable *Root = M->getGlobalVariable("llvm.dbg.global_variables");
if (!Root)
return false;
assert(Root->hasLinkOnceLinkage() && Root->hasOneUse() &&
"Malformed global variable descriptor anchor type");
Constant *RootC = cast<Constant>(*Root->use_begin());
assert(RootC->hasNUsesOrMore(1) &&
"Malformed global variable descriptor anchor type");
bool Result = false;
for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
UI != UE; ++UI)
for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
UUI != UUE; ++UUI)
Result |= ConstructGlobalVariableDIE(cast<GlobalVariable>(*UUI));
return Result;
}
bool DwarfDebug::ConstructSubprogram(GlobalVariable *GV) {
void DwarfDebug::ConstructSubprogram(GlobalVariable *GV) {
DISubprogram SP(GV);
CompileUnit *Unit = MainCU;
if (!Unit)
@ -1325,12 +1284,12 @@ bool DwarfDebug::ConstructSubprogram(GlobalVariable *GV) {
// Check for pre-existence.
DIE *&Slot = Unit->getDieMapSlotFor(GV);
if (Slot)
return false;
return;
if (!SP.isDefinition())
// This is a method declaration which will be handled while constructing
// class type.
return false;
return;
DIE *SubprogramDie = CreateSubprogramDIE(Unit, SP);
@ -1343,40 +1302,27 @@ bool DwarfDebug::ConstructSubprogram(GlobalVariable *GV) {
// Expose as global.
std::string Name;
Unit->AddGlobal(SP.getName(Name), SubprogramDie);
return true;
return;
}
/// ConstructSubprograms - Create DIEs for each of the externally visible
/// subprograms. Return true if at least one subprogram DIE is created.
bool DwarfDebug::ConstructSubprograms() {
GlobalVariable *Root = M->getGlobalVariable("llvm.dbg.subprograms");
if (!Root)
return false;
/// BeginModule - Emit all Dwarf sections that should come prior to the
/// content. Create global DIEs and emit initial debug info sections.
/// This is inovked by the target AsmPrinter.
void DwarfDebug::BeginModule(Module *M, MachineModuleInfo *mmi) {
this->M = M;
assert(Root->hasLinkOnceLinkage() && Root->hasOneUse() &&
"Malformed subprogram descriptor anchor type");
Constant *RootC = cast<Constant>(*Root->use_begin());
assert(RootC->hasNUsesOrMore(1) &&
"Malformed subprogram descriptor anchor type");
bool Result = false;
for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
UI != UE; ++UI)
for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
UUI != UUE; ++UUI)
Result |= ConstructSubprogram(cast<GlobalVariable>(*UUI));
return Result;
}
/// SetDebugInfo - Create global DIEs and emit initial debug info sections.
/// This is inovked by the target AsmPrinter.
void DwarfDebug::SetDebugInfo(MachineModuleInfo *mmi) {
if (TimePassesIsEnabled)
DebugTimer->startTimer();
SmallVector<GlobalVariable *, 2> CUs;
SmallVector<GlobalVariable *, 4> GVs;
SmallVector<GlobalVariable *, 4> SPs;
CollectDebugInfoAnchors(*M, CUs, GVs, SPs);
// Create all the compile unit DIEs.
ConstructCompileUnits();
for (SmallVector<GlobalVariable *, 2>::iterator I = CUs.begin(),
E = CUs.end(); I != E; ++I)
ConstructCompileUnit(*I);
if (CompileUnits.empty()) {
if (TimePassesIsEnabled)
@ -1385,21 +1331,25 @@ void DwarfDebug::SetDebugInfo(MachineModuleInfo *mmi) {
return;
}
// Create DIEs for each of the externally visible global variables.
bool globalDIEs = ConstructGlobalVariableDIEs();
// Create DIEs for each of the externally visible subprograms.
bool subprogramDIEs = ConstructSubprograms();
// If there is not any debug info available for any global variables and any
// subprograms then there is not any debug info to emit.
if (!globalDIEs && !subprogramDIEs) {
if (GVs.empty() && SPs.empty()) {
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
return;
}
// Create DIEs for each of the externally visible global variables.
for (SmallVector<GlobalVariable *, 4>::iterator I = GVs.begin(),
E = GVs.end(); I != E; ++I)
ConstructGlobalVariableDIE(*I);
// Create DIEs for each of the externally visible subprograms.
for (SmallVector<GlobalVariable *, 4>::iterator I = SPs.begin(),
E = SPs.end(); I != E; ++I)
ConstructSubprogram(*I);
MMI = mmi;
shouldEmit = true;
MMI->setDebugInfoAvailability(true);

View File

@ -460,21 +460,10 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf {
void ConstructCompileUnit(GlobalVariable *GV);
/// ConstructCompileUnits - Create a compile unit DIEs.
void ConstructCompileUnits();
void ConstructGlobalVariableDIE(GlobalVariable *GV);
bool ConstructGlobalVariableDIE(GlobalVariable *GV);
void ConstructSubprogram(GlobalVariable *GV);
/// ConstructGlobalVariableDIEs - Create DIEs for each of the externally
/// visible global variables. Return true if at least one global DIE is
/// created.
bool ConstructGlobalVariableDIEs();
bool ConstructSubprogram(GlobalVariable *GV);
/// ConstructSubprograms - Create DIEs for each of the externally visible
/// subprograms. Return true if at least one subprogram DIE is created.
bool ConstructSubprograms();
public:
//===--------------------------------------------------------------------===//
// Main entry points.
@ -486,15 +475,9 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf {
/// be emitted.
bool ShouldEmitDwarfDebug() const { return shouldEmit; }
/// SetDebugInfo - Create global DIEs and emit initial debug info sections.
/// This is inovked by the target AsmPrinter.
void SetDebugInfo(MachineModuleInfo *mmi);
/// BeginModule - Emit all Dwarf sections that should come prior to the
/// content.
void BeginModule(Module *M) {
this->M = M;
}
void BeginModule(Module *M, MachineModuleInfo *MMI);
/// EndModule - Emit all Dwarf sections that should come after the content.
///

View File

@ -149,16 +149,11 @@ class VISIBILITY_HIDDEN DwarfException : public Dwarf {
DwarfException(raw_ostream &OS, AsmPrinter *A, const TargetAsmInfo *T);
virtual ~DwarfException();
/// SetModuleInfo - Set machine module information when it's known that pass
/// manager has created it. Set by the target AsmPrinter.
void SetModuleInfo(MachineModuleInfo *mmi) {
MMI = mmi;
}
/// BeginModule - Emit all exception information that should come prior to the
/// content.
void BeginModule(Module *M) {
this->M = M;
void BeginModule(Module *m, MachineModuleInfo *mmi) {
this->M = m;
this->MMI = mmi;
}
/// EndModule - Emit all exception information that should come after the

View File

@ -42,10 +42,8 @@ void DwarfWriter::BeginModule(Module *M,
const TargetAsmInfo *T) {
DE = new DwarfException(OS, A, T);
DD = new DwarfDebug(OS, A, T);
DE->BeginModule(M);
DD->BeginModule(M);
DD->SetDebugInfo(MMI);
DE->SetModuleInfo(MMI);
DE->BeginModule(M, MMI);
DD->BeginModule(M, MMI);
}
/// EndModule - Emit all Dwarf sections that should come after the content.

View File

@ -9,7 +9,5 @@
LEVEL = ../../..
LIBRARYNAME = LLVMAsmPrinter
PARALLEL_DIRS =
BUILD_ARCHIVE = 1
DONT_BUILD_RELINKED = 1
include $(LEVEL)/Makefile.common

View File

@ -63,3 +63,5 @@ add_llvm_library(LLVMCodeGen
VirtRegMap.cpp
VirtRegRewriter.cpp
)
target_link_libraries (LLVMCodeGen LLVMCore)

View File

@ -144,6 +144,9 @@ namespace llvm {
uint8_t Other;
unsigned short SectionIdx;
// Symbol index into the Symbol table
unsigned SymTabIdx;
enum {
STB_LOCAL = 0,
STB_GLOBAL = 1,
@ -168,7 +171,8 @@ namespace llvm {
ELFSym(const GlobalValue *gv) : GV(gv), IsCommon(false), IsBss(false),
IsConstant(false), NameIdx(0), Value(0),
Size(0), Info(0), Other(STV_DEFAULT),
SectionIdx(ELFSection::SHN_UNDEF) {
SectionIdx(ELFSection::SHN_UNDEF),
SymTabIdx(0) {
if (!GV)
return;
@ -191,6 +195,10 @@ namespace llvm {
return (Info >> 4) & 0xf;
}
unsigned getType() {
return Info & 0xf;
}
void setBind(unsigned X) {
assert(X == (X & 0xF) && "Bind value out of range!");
Info = (Info & 0x0F) | (X << 4);

View File

@ -16,6 +16,7 @@
#include "llvm/CodeGen/BinaryObject.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Debug.h"
@ -103,21 +104,28 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
break;
}
// Emit constant pool to appropriate section(s)
emitConstantPool(MF.getConstantPool());
// Relocations
// -----------
// If we have emitted any relocations to function-specific objects such as
// If we have emitted any relocations to function-specific objects such as
// basic blocks, constant pools entries, or jump tables, record their
// addresses now so that we can rewrite them with the correct addresses
// later.
for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
MachineRelocation &MR = Relocations[i];
intptr_t Addr;
if (MR.isBasicBlock()) {
if (MR.isGlobalValue()) {
EW.PendingGlobals.insert(MR.getGlobalValue());
} else if (MR.isBasicBlock()) {
Addr = getMachineBasicBlockAddress(MR.getBasicBlock());
MR.setConstantVal(ES->SectionIdx);
MR.setResultPointer((void*)Addr);
} else if (MR.isGlobalValue()) {
EW.PendingGlobals.insert(MR.getGlobalValue());
} else if (MR.isConstantPoolIndex()) {
Addr = getConstantPoolEntryAddress(MR.getConstantPoolIndex());
MR.setConstantVal(CPSections[MR.getConstantPoolIndex()]);
MR.setResultPointer((void*)Addr);
} else {
assert(0 && "Unhandled relocation type");
}
@ -128,4 +136,36 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
return false;
}
/// emitConstantPool - For each constant pool entry, figure out which section
/// the constant should live in and emit the constant
void ELFCodeEmitter::emitConstantPool(MachineConstantPool *MCP) {
const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();
if (CP.empty()) return;
// TODO: handle PIC codegen
assert(TM.getRelocationModel() != Reloc::PIC_ &&
"PIC codegen not yet handled for elf constant pools!");
const TargetAsmInfo *TAI = TM.getTargetAsmInfo();
for (unsigned i = 0, e = CP.size(); i != e; ++i) {
MachineConstantPoolEntry CPE = CP[i];
// Get the right ELF Section for this constant pool entry
std::string CstPoolName =
TAI->SelectSectionForMachineConst(CPE.getType())->getName();
ELFSection &CstPoolSection =
EW.getConstantPoolSection(CstPoolName, CPE.getAlignment());
// Record the constant pool location and the section index
CPLocations.push_back(CstPoolSection.size());
CPSections.push_back(CstPoolSection.SectionIdx);
if (CPE.isMachineConstantPoolEntry())
assert("CPE.isMachineConstantPoolEntry not supported yet");
// Emit the constant to constant pool section
EW.EmitGlobalConstant(CPE.Val.ConstVal, CstPoolSection);
}
}
} // end namespace llvm

View File

@ -31,6 +31,14 @@ namespace llvm {
/// emitted.
std::vector<MachineRelocation> Relocations;
/// CPLocations - This is a map of constant pool indices to offsets from the
/// start of the section for that constant pool index.
std::vector<uintptr_t> CPLocations;
/// CPSections - This is a map of constant pool indices to the MachOSection
/// containing the constant pool entry for that index.
std::vector<unsigned> CPSections;
/// MBBLocations - This vector is a mapping from MBB ID's to their address.
/// It is filled in by the StartMachineBasicBlock callback and queried by
/// the getMachineBasicBlockAddress callback.
@ -62,9 +70,10 @@ namespace llvm {
}
virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
assert(0 && "CP not implementated yet!");
return 0;
assert(CPLocations.size() > Index && "CP not emitted!");
return CPLocations[Index];
}
virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
assert(0 && "JT not implementated yet!");
return 0;
@ -86,6 +95,10 @@ namespace llvm {
abort();
}
/// emitConstantPool - For each constant pool entry, figure out which section
/// the constant should live in and emit the constant.
void emitConstantPool(MachineConstantPool *MCP);
virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
/// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!

View File

@ -389,6 +389,24 @@ bool ELFWriter::doFinalization(Module &M) {
if (TAI->getNonexecutableStackDirective())
getNonExecStackSection();
// Emit a symbol for each section created until now
for (std::map<std::string, ELFSection*>::iterator I = SectionLookup.begin(),
E = SectionLookup.end(); I != E; ++I) {
ELFSection *ES = I->second;
// Skip null section
if (ES->SectionIdx == 0) continue;
ELFSym SectionSym(0);
SectionSym.SectionIdx = ES->SectionIdx;
SectionSym.Size = 0;
SectionSym.setBind(ELFSym::STB_LOCAL);
SectionSym.setType(ELFSym::STT_SECTION);
// Local symbols go in the list front
SymbolList.push_front(SectionSym);
}
// Emit string table
EmitStringTable();
@ -451,15 +469,25 @@ void ELFWriter::EmitRelocations() {
// Constant addend used to compute the value to be stored
// into the relocatable field
int64_t Addend = TEW->getAddendForRelTy(RelType);
int64_t Addend = 0;
// There are several machine relocations types, and each one of
// them needs a different approach to retrieve the symbol table index.
if (MR.isGlobalValue()) {
const GlobalValue *G = MR.getGlobalValue();
SymIdx = GblSymLookup[G];
Addend = TEW->getAddendForRelTy(RelType);
} else {
assert(0 && "dunno how to handle other relocation types");
unsigned SectionIdx = MR.getConstantVal();
// TODO: use a map for this.
for (std::list<ELFSym>::iterator I = SymbolList.begin(),
E = SymbolList.end(); I != E; ++I)
if ((SectionIdx == I->SectionIdx) &&
(I->getType() == ELFSym::STT_SECTION)) {
SymIdx = I->SymTabIdx;
break;
}
Addend = (uint64_t)MR.getResultPointer();
}
// Get the relocation entry and emit to the relocation section
@ -540,7 +568,8 @@ void ELFWriter::EmitStringTable() {
E = SymbolList.end(); I != E; ++I) {
// Use the name mangler to uniquify the LLVM symbol.
std::string Name = Mang->getValueName(I->GV);
std::string Name;
if (I->GV) Name.append(Mang->getValueName(I->GV));
if (Name.empty()) {
I->NameIdx = 0;
@ -589,7 +618,11 @@ void ELFWriter::EmitSymbolTable() {
EmitSymbol(SymTab, *I);
// Record the symbol table index for each global value
GblSymLookup[I->GV] = Index;
if (I->GV)
GblSymLookup[I->GV] = Index;
// Keep track on the symbol index into the symbol table
I->SymTabIdx = Index;
}
SymTab.Info = FirstNonLocalSymbol;

View File

@ -147,6 +147,12 @@ namespace llvm {
ELFSection::SHF_EXECINSTR | ELFSection::SHF_ALLOC);
}
/// Get a constant pool section based on the section name returned by TAI
ELFSection &getConstantPoolSection(std::string SName, unsigned Align) {
return getSection(SName, ELFSection::SHT_PROGBITS,
ELFSection::SHF_MERGE | ELFSection::SHF_ALLOC, Align);
}
/// Return the relocation section of section 'S'. 'RelA' is true
/// if the relocation section contains entries with addends.
ELFSection &getRelocSection(std::string SName, bool RelA) {

View File

@ -144,9 +144,10 @@ namespace {
const TargetLowering *TLI;
const TargetInstrInfo *TII;
bool MadeChange;
int FnNum;
public:
static char ID;
IfConverter() : MachineFunctionPass(&ID) {}
IfConverter() : MachineFunctionPass(&ID), FnNum(-1) {}
virtual bool runOnMachineFunction(MachineFunction &MF);
virtual const char *getPassName() const { return "If Converter"; }
@ -225,7 +226,6 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
TII = MF.getTarget().getInstrInfo();
if (!TII) return false;
static int FnNum = -1;
DOUT << "\nIfcvt: function (" << ++FnNum << ") \'"
<< MF.getFunction()->getName() << "\'";

View File

@ -61,18 +61,16 @@ static void EnsureFPIntrinsicsExist(Module &M, Function *Fn,
template <class ArgIt>
static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI,
ArgIt ArgBegin, ArgIt ArgEnd,
const Type *RetTy, Constant *&FCache) {
if (!FCache) {
// If we haven't already looked up this function, check to see if the
// program already contains a function with this name.
Module *M = CI->getParent()->getParent()->getParent();
// Get or insert the definition now.
std::vector<const Type *> ParamTys;
for (ArgIt I = ArgBegin; I != ArgEnd; ++I)
ParamTys.push_back((*I)->getType());
FCache = M->getOrInsertFunction(NewFn,
FunctionType::get(RetTy, ParamTys, false));
}
const Type *RetTy) {
// If we haven't already looked up this function, check to see if the
// program already contains a function with this name.
Module *M = CI->getParent()->getParent()->getParent();
// Get or insert the definition now.
std::vector<const Type *> ParamTys;
for (ArgIt I = ArgBegin; I != ArgEnd; ++I)
ParamTys.push_back((*I)->getType());
Constant* FCache = M->getOrInsertFunction(NewFn,
FunctionType::get(RetTy, ParamTys, false));
IRBuilder<> Builder(CI->getParent(), CI);
SmallVector<Value *, 8> Args(ArgBegin, ArgEnd);
@ -624,25 +622,24 @@ static Instruction *LowerPartSet(CallInst *CI) {
return NewCI;
}
static void ReplaceFPIntrinsicWithCall(CallInst *CI, Constant *FCache,
Constant *DCache, Constant *LDCache,
const char *Fname, const char *Dname,
static void ReplaceFPIntrinsicWithCall(CallInst *CI, const char *Fname,
const char *Dname,
const char *LDname) {
switch (CI->getOperand(1)->getType()->getTypeID()) {
default: assert(0 && "Invalid type in intrinsic"); abort();
case Type::FloatTyID:
ReplaceCallWith(Fname, CI, CI->op_begin() + 1, CI->op_end(),
Type::FloatTy, FCache);
Type::FloatTy);
break;
case Type::DoubleTyID:
ReplaceCallWith(Dname, CI, CI->op_begin() + 1, CI->op_end(),
Type::DoubleTy, DCache);
Type::DoubleTy);
break;
case Type::X86_FP80TyID:
case Type::FP128TyID:
case Type::PPC_FP128TyID:
ReplaceCallWith(LDname, CI, CI->op_begin() + 1, CI->op_end(),
CI->getOperand(1)->getType(), LDCache);
CI->getOperand(1)->getType());
break;
}
}
@ -668,9 +665,8 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
// by the lowerinvoke pass. In both cases, the right thing to do is to
// convert the call to an explicit setjmp or longjmp call.
case Intrinsic::setjmp: {
static Constant *SetjmpFCache = 0;
Value *V = ReplaceCallWith("setjmp", CI, CI->op_begin() + 1, CI->op_end(),
Type::Int32Ty, SetjmpFCache);
Type::Int32Ty);
if (CI->getType() != Type::VoidTy)
CI->replaceAllUsesWith(V);
break;
@ -681,17 +677,15 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
break;
case Intrinsic::longjmp: {
static Constant *LongjmpFCache = 0;
ReplaceCallWith("longjmp", CI, CI->op_begin() + 1, CI->op_end(),
Type::VoidTy, LongjmpFCache);
Type::VoidTy);
break;
}
case Intrinsic::siglongjmp: {
// Insert the call to abort
static Constant *AbortFCache = 0;
ReplaceCallWith("abort", CI, CI->op_end(), CI->op_end(),
Type::VoidTy, AbortFCache);
Type::VoidTy);
break;
}
case Intrinsic::ctpop:
@ -728,7 +722,6 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
case Intrinsic::stacksave:
case Intrinsic::stackrestore: {
static bool Warned = false;
if (!Warned)
cerr << "WARNING: this target does not support the llvm.stack"
<< (Callee->getIntrinsicID() == Intrinsic::stacksave ?
@ -783,7 +776,6 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
break; // Strip out annotate intrinsic
case Intrinsic::memcpy: {
static Constant *MemcpyFCache = 0;
const IntegerType *IntPtr = TD.getIntPtrType();
Value *Size = Builder.CreateIntCast(CI->getOperand(3), IntPtr,
/* isSigned */ false);
@ -791,12 +783,10 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
Ops[0] = CI->getOperand(1);
Ops[1] = CI->getOperand(2);
Ops[2] = Size;
ReplaceCallWith("memcpy", CI, Ops, Ops+3, CI->getOperand(1)->getType(),
MemcpyFCache);
ReplaceCallWith("memcpy", CI, Ops, Ops+3, CI->getOperand(1)->getType());
break;
}
case Intrinsic::memmove: {
static Constant *MemmoveFCache = 0;
const IntegerType *IntPtr = TD.getIntPtrType();
Value *Size = Builder.CreateIntCast(CI->getOperand(3), IntPtr,
/* isSigned */ false);
@ -804,12 +794,10 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
Ops[0] = CI->getOperand(1);
Ops[1] = CI->getOperand(2);
Ops[2] = Size;
ReplaceCallWith("memmove", CI, Ops, Ops+3, CI->getOperand(1)->getType(),
MemmoveFCache);
ReplaceCallWith("memmove", CI, Ops, Ops+3, CI->getOperand(1)->getType());
break;
}
case Intrinsic::memset: {
static Constant *MemsetFCache = 0;
const IntegerType *IntPtr = TD.getIntPtrType();
Value *Size = Builder.CreateIntCast(CI->getOperand(3), IntPtr,
/* isSigned */ false);
@ -819,64 +807,35 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
Ops[1] = Builder.CreateIntCast(CI->getOperand(2), Type::Int32Ty,
/* isSigned */ false);
Ops[2] = Size;
ReplaceCallWith("memset", CI, Ops, Ops+3, CI->getOperand(1)->getType(),
MemsetFCache);
ReplaceCallWith("memset", CI, Ops, Ops+3, CI->getOperand(1)->getType());
break;
}
case Intrinsic::sqrt: {
static Constant *sqrtFCache = 0;
static Constant *sqrtDCache = 0;
static Constant *sqrtLDCache = 0;
ReplaceFPIntrinsicWithCall(CI, sqrtFCache, sqrtDCache, sqrtLDCache,
"sqrtf", "sqrt", "sqrtl");
ReplaceFPIntrinsicWithCall(CI, "sqrtf", "sqrt", "sqrtl");
break;
}
case Intrinsic::log: {
static Constant *logFCache = 0;
static Constant *logDCache = 0;
static Constant *logLDCache = 0;
ReplaceFPIntrinsicWithCall(CI, logFCache, logDCache, logLDCache,
"logf", "log", "logl");
ReplaceFPIntrinsicWithCall(CI, "logf", "log", "logl");
break;
}
case Intrinsic::log2: {
static Constant *log2FCache = 0;
static Constant *log2DCache = 0;
static Constant *log2LDCache = 0;
ReplaceFPIntrinsicWithCall(CI, log2FCache, log2DCache, log2LDCache,
"log2f", "log2", "log2l");
ReplaceFPIntrinsicWithCall(CI, "log2f", "log2", "log2l");
break;
}
case Intrinsic::log10: {
static Constant *log10FCache = 0;
static Constant *log10DCache = 0;
static Constant *log10LDCache = 0;
ReplaceFPIntrinsicWithCall(CI, log10FCache, log10DCache, log10LDCache,
"log10f", "log10", "log10l");
ReplaceFPIntrinsicWithCall(CI, "log10f", "log10", "log10l");
break;
}
case Intrinsic::exp: {
static Constant *expFCache = 0;
static Constant *expDCache = 0;
static Constant *expLDCache = 0;
ReplaceFPIntrinsicWithCall(CI, expFCache, expDCache, expLDCache,
"expf", "exp", "expl");
ReplaceFPIntrinsicWithCall(CI, "expf", "exp", "expl");
break;
}
case Intrinsic::exp2: {
static Constant *exp2FCache = 0;
static Constant *exp2DCache = 0;
static Constant *exp2LDCache = 0;
ReplaceFPIntrinsicWithCall(CI, exp2FCache, exp2DCache, exp2LDCache,
"exp2f", "exp2", "exp2l");
ReplaceFPIntrinsicWithCall(CI, "exp2f", "exp2", "exp2l");
break;
}
case Intrinsic::pow: {
static Constant *powFCache = 0;
static Constant *powDCache = 0;
static Constant *powLDCache = 0;
ReplaceFPIntrinsicWithCall(CI, powFCache, powDCache, powLDCache,
"powf", "pow", "powl");
ReplaceFPIntrinsicWithCall(CI, "powf", "pow", "powl");
break;
}
case Intrinsic::flt_rounds:

View File

@ -373,7 +373,8 @@ void LiveInterval::scaleNumbering(unsigned factor) {
for (vni_iterator VNI = vni_begin(), VNIE = vni_end(); VNI != VNIE; ++VNI) {
VNInfo *vni = *VNI;
vni->def = InstrSlots::scale(vni->def, factor);
if (vni->isDefAccurate())
vni->def = InstrSlots::scale(vni->def, factor);
for (unsigned i = 0; i < vni->kills.size(); ++i) {
if (vni->kills[i] != 0)

View File

@ -947,6 +947,10 @@ unsigned LiveIntervals::getReMatImplicitUse(const LiveInterval &li,
unsigned Reg = MO.getReg();
if (Reg == 0 || Reg == li.reg)
continue;
if (TargetRegisterInfo::isPhysicalRegister(Reg) &&
!allocatableRegs_[Reg])
continue;
// FIXME: For now, only remat MI with at most one register operand.
assert(!RegOp &&
"Can't rematerialize instruction with multiple register operand!");

View File

@ -124,25 +124,28 @@ MachineFunction::MachineFunction(const Function *F,
MachineFrameInfo(*TM.getFrameInfo());
ConstantPool = new (Allocator.Allocate<MachineConstantPool>())
MachineConstantPool(TM.getTargetData());
// Set up jump table.
const TargetData &TD = *TM.getTargetData();
bool IsPic = TM.getRelocationModel() == Reloc::PIC_;
unsigned EntrySize = IsPic ? 4 : TD.getPointerSize();
unsigned Alignment = IsPic ? TD.getABITypeAlignment(Type::Int32Ty)
: TD.getPointerABIAlignment();
unsigned TyAlignment = IsPic ? TD.getABITypeAlignment(Type::Int32Ty)
: TD.getPointerABIAlignment();
JumpTableInfo = new (Allocator.Allocate<MachineJumpTableInfo>())
MachineJumpTableInfo(EntrySize, Alignment);
MachineJumpTableInfo(EntrySize, TyAlignment);
}
MachineFunction::~MachineFunction() {
BasicBlocks.clear();
InstructionRecycler.clear(Allocator);
BasicBlockRecycler.clear(Allocator);
if (RegInfo)
RegInfo->~MachineRegisterInfo(); Allocator.Deallocate(RegInfo);
if (RegInfo) {
RegInfo->~MachineRegisterInfo();
Allocator.Deallocate(RegInfo);
}
if (MFInfo) {
MFInfo->~MachineFunctionInfo(); Allocator.Deallocate(MFInfo);
MFInfo->~MachineFunctionInfo();
Allocator.Deallocate(MFInfo);
}
FrameInfo->~MachineFrameInfo(); Allocator.Deallocate(FrameInfo);
ConstantPool->~MachineConstantPool(); Allocator.Deallocate(ConstantPool);
@ -295,12 +298,6 @@ void MachineFunction::print(std::ostream &OS) const {
OS << "\n# End machine code for " << Fn->getName () << "().\n\n";
}
/// CFGOnly flag - This is used to control whether or not the CFG graph printer
/// prints out the contents of basic blocks or not. This is acceptable because
/// this code is only really used for debugging purposes.
///
static bool CFGOnly = false;
namespace llvm {
template<>
struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits {
@ -309,13 +306,14 @@ namespace llvm {
}
static std::string getNodeLabel(const MachineBasicBlock *Node,
const MachineFunction *Graph) {
if (CFGOnly && Node->getBasicBlock() &&
const MachineFunction *Graph,
bool ShortNames) {
if (ShortNames && Node->getBasicBlock() &&
!Node->getBasicBlock()->getName().empty())
return Node->getBasicBlock()->getName() + ":";
std::ostringstream Out;
if (CFGOnly) {
if (ShortNames) {
Out << Node->getNumber() << ':';
return Out.str();
}
@ -348,9 +346,12 @@ void MachineFunction::viewCFG() const
void MachineFunction::viewCFGOnly() const
{
CFGOnly = true;
viewCFG();
CFGOnly = false;
#ifndef NDEBUG
ViewGraph(this, "mf" + getFunction()->getName(), true);
#else
cerr << "SelectionDAG::viewGraph is only available in debug builds on "
<< "systems with Graphviz or gv!\n";
#endif // NDEBUG
}
// The next two methods are used to construct and to retrieve

View File

@ -150,7 +150,9 @@ void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
/// isIdenticalTo - Return true if this operand is identical to the specified
/// operand.
bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
if (getType() != Other.getType()) return false;
if (getType() != Other.getType() ||
getTargetFlags() != Other.getTargetFlags())
return false;
switch (getType()) {
default: assert(0 && "Unrecognized operand type");
@ -205,70 +207,72 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const {
}
if (getSubReg() != 0) {
OS << ":" << getSubReg();
OS << ':' << getSubReg();
}
if (isDef() || isKill() || isDead() || isImplicit() || isEarlyClobber()) {
OS << "<";
OS << '<';
bool NeedComma = false;
if (isImplicit()) {
if (NeedComma) OS << ",";
if (NeedComma) OS << ',';
OS << (isDef() ? "imp-def" : "imp-use");
NeedComma = true;
} else if (isDef()) {
if (NeedComma) OS << ",";
if (NeedComma) OS << ',';
if (isEarlyClobber())
OS << "earlyclobber,";
OS << "def";
NeedComma = true;
}
if (isKill() || isDead()) {
if (NeedComma) OS << ",";
if (NeedComma) OS << ',';
if (isKill()) OS << "kill";
if (isDead()) OS << "dead";
}
OS << ">";
OS << '>';
}
break;
case MachineOperand::MO_Immediate:
OS << getImm();
break;
case MachineOperand::MO_FPImmediate:
if (getFPImm()->getType() == Type::FloatTy) {
if (getFPImm()->getType() == Type::FloatTy)
OS << getFPImm()->getValueAPF().convertToFloat();
} else {
else
OS << getFPImm()->getValueAPF().convertToDouble();
}
break;
case MachineOperand::MO_MachineBasicBlock:
OS << "mbb<"
<< ((Value*)getMBB()->getBasicBlock())->getName()
<< "," << (void*)getMBB() << ">";
<< "," << (void*)getMBB() << '>';
break;
case MachineOperand::MO_FrameIndex:
OS << "<fi#" << getIndex() << ">";
OS << "<fi#" << getIndex() << '>';
break;
case MachineOperand::MO_ConstantPoolIndex:
OS << "<cp#" << getIndex();
if (getOffset()) OS << "+" << getOffset();
OS << ">";
OS << '>';
break;
case MachineOperand::MO_JumpTableIndex:
OS << "<jt#" << getIndex() << ">";
OS << "<jt#" << getIndex() << '>';
break;
case MachineOperand::MO_GlobalAddress:
OS << "<ga:" << ((Value*)getGlobal())->getName();
if (getOffset()) OS << "+" << getOffset();
OS << ">";
OS << '>';
break;
case MachineOperand::MO_ExternalSymbol:
OS << "<es:" << getSymbolName();
if (getOffset()) OS << "+" << getOffset();
OS << ">";
OS << '>';
break;
default:
assert(0 && "Unrecognized operand type");
}
if (unsigned TF = getTargetFlags())
OS << "[TF=" << TF << ']';
}
//===----------------------------------------------------------------------===//
@ -716,31 +720,37 @@ isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx) const {
const MachineOperand &MO = getOperand(DefOpIdx);
if (!MO.isReg() || !MO.isDef() || MO.getReg() == 0)
return false;
// Determine the actual operand no corresponding to this index.
// Determine the actual operand index that corresponds to this index.
unsigned DefNo = 0;
unsigned DefPart = 0;
for (unsigned i = 1, e = getNumOperands(); i < e; ) {
const MachineOperand &FMO = getOperand(i);
assert(FMO.isImm());
// Skip over this def.
i += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1;
if (i > DefOpIdx)
unsigned NumOps = InlineAsm::getNumOperandRegisters(FMO.getImm());
unsigned PrevDef = i + 1;
i = PrevDef + NumOps;
if (i > DefOpIdx) {
DefPart = DefOpIdx - PrevDef;
break;
}
++DefNo;
}
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
for (unsigned i = 1, e = getNumOperands(); i != e; ++i) {
const MachineOperand &FMO = getOperand(i);
if (!FMO.isImm())
continue;
if (i+1 >= e || !getOperand(i+1).isReg() || !getOperand(i+1).isUse())
continue;
unsigned Idx;
if (InlineAsm::isUseOperandTiedToDef(FMO.getImm(), Idx) &&
if (InlineAsm::isUseOperandTiedToDef(FMO.getImm(), Idx) &&
Idx == DefNo) {
if (UseOpIdx)
*UseOpIdx = (unsigned)i + 1;
*UseOpIdx = (unsigned)i + 1 + DefPart;
return true;
}
}
return false;
}
assert(getOperand(DefOpIdx).isDef() && "DefOpIdx is not a def!");
@ -766,10 +776,16 @@ isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx) const {
const MachineOperand &MO = getOperand(UseOpIdx);
if (!MO.isReg() || !MO.isUse() || MO.getReg() == 0)
return false;
assert(UseOpIdx > 0);
const MachineOperand &UFMO = getOperand(UseOpIdx-1);
if (!UFMO.isImm())
return false; // Must be physreg uses.
int FlagIdx = UseOpIdx - 1;
if (FlagIdx < 1)
return false;
while (!getOperand(FlagIdx).isImm()) {
if (--FlagIdx == 0)
return false;
}
const MachineOperand &UFMO = getOperand(FlagIdx);
if (FlagIdx + InlineAsm::getNumOperandRegisters(UFMO.getImm()) < UseOpIdx)
return false;
unsigned DefNo;
if (InlineAsm::isUseOperandTiedToDef(UFMO.getImm(), DefNo)) {
if (!DefOpIdx)
@ -785,7 +801,7 @@ isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx) const {
DefIdx += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1;
--DefNo;
}
*DefOpIdx = DefIdx+1;
*DefOpIdx = DefIdx + UseOpIdx - FlagIdx;
return true;
}
return false;
@ -1092,13 +1108,13 @@ bool MachineInstr::addRegisterDead(unsigned IncomingReg,
// If not found, this means an alias of one of the operands is dead. Add a
// new implicit operand if required.
if (!Found && AddIfNotFound) {
addOperand(MachineOperand::CreateReg(IncomingReg,
true /*IsDef*/,
true /*IsImp*/,
false /*IsKill*/,
true /*IsDead*/));
return true;
}
return Found;
if (Found || !AddIfNotFound)
return Found;
addOperand(MachineOperand::CreateReg(IncomingReg,
true /*IsDef*/,
true /*IsImp*/,
false /*IsKill*/,
true /*IsDead*/));
return true;
}

View File

@ -59,7 +59,8 @@ namespace llvm {
static std::string getNodeLabel(const SUnit *Node,
const ScheduleDAG *Graph);
const ScheduleDAG *Graph,
bool ShortNames);
static std::string getNodeAttributes(const SUnit *N,
const ScheduleDAG *Graph) {
return "shape=Mrecord";
@ -73,7 +74,8 @@ namespace llvm {
}
std::string DOTGraphTraits<ScheduleDAG*>::getNodeLabel(const SUnit *SU,
const ScheduleDAG *G) {
const ScheduleDAG *G,
bool ShortNames) {
return G->getGraphNodeLabel(SU);
}
@ -84,11 +86,11 @@ void ScheduleDAG::viewGraph() {
// This code is only for debugging!
#ifndef NDEBUG
if (BB->getBasicBlock())
ViewGraph(this, "dag." + MF.getFunction()->getName(),
ViewGraph(this, "dag." + MF.getFunction()->getName(), false,
"Scheduling-Units Graph for " + MF.getFunction()->getName() + ':' +
BB->getBasicBlock()->getName());
else
ViewGraph(this, "dag." + MF.getFunction()->getName(),
ViewGraph(this, "dag." + MF.getFunction()->getName(), false,
"Scheduling-Units Graph for " + MF.getFunction()->getName());
#else
cerr << "ScheduleDAG::viewGraph is only available in debug builds on "

View File

@ -211,7 +211,7 @@ SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag,
CodeGenOpt::Level ol)
: TLI(dag.getTargetLoweringInfo()), DAG(dag), OptLevel(ol),
ValueTypeActions(TLI.getValueTypeActions()) {
assert(MVT::LAST_VALUETYPE <= 32 &&
assert(MVT::LAST_VALUETYPE <= MVT::MAX_ALLOWED_VALUETYPE &&
"Too many value types for ValueTypeActions to hold!");
}

View File

@ -159,7 +159,7 @@ class VISIBILITY_HIDDEN DAGTypeLegalizer {
explicit DAGTypeLegalizer(SelectionDAG &dag)
: TLI(dag.getTargetLoweringInfo()), DAG(dag),
ValueTypeActions(TLI.getValueTypeActions()) {
assert(MVT::LAST_VALUETYPE <= 32 &&
assert(MVT::LAST_VALUETYPE <= MVT::MAX_ALLOWED_VALUETYPE &&
"Too many value types for ValueTypeActions to hold!");
}

View File

@ -9,7 +9,5 @@
LEVEL = ../../..
LIBRARYNAME = LLVMSelectionDAG
PARALLEL_DIRS =
BUILD_ARCHIVE = 1
DONT_BUILD_RELINKED = 1
include $(LEVEL)/Makefile.common

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