Import LLVM r74383.
This commit is contained in:
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
@ -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})
|
||||
|
@ -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
|
||||
###############################################################################
|
||||
|
@ -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
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
LEVEL := ../../..
|
||||
LIBRARYNAME := llvm_analysis
|
||||
DONT_BUILD_RELINKED := 1
|
||||
UsedComponents := analysis
|
||||
UsedOcamlInterfaces := llvm
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
LEVEL := ../../..
|
||||
LIBRARYNAME := llvm_bitreader
|
||||
DONT_BUILD_RELINKED := 1
|
||||
UsedComponents := bitreader
|
||||
UsedOcamlInterfaces := llvm
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
LEVEL := ../../..
|
||||
LIBRARYNAME := llvm_bitwriter
|
||||
DONT_BUILD_RELINKED := 1
|
||||
UsedComponents := bitwriter
|
||||
UsedOcamlInterfaces := llvm
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
LEVEL := ../../..
|
||||
LIBRARYNAME := llvm_executionengine
|
||||
DONT_BUILD_RELINKED := 1
|
||||
UsedComponents := executionengine jit interpreter native
|
||||
UsedOcamlInterfaces := llvm llvm_target
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
LEVEL := ../../..
|
||||
LIBRARYNAME := llvm
|
||||
DONT_BUILD_RELINKED := 1
|
||||
UsedComponents := core
|
||||
UsedOcamLibs := llvm
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
LEVEL := ../../..
|
||||
LIBRARYNAME := llvm_target
|
||||
DONT_BUILD_RELINKED := 1
|
||||
UsedComponents := target
|
||||
UsedOcamlInterfaces := llvm
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
103
configure
vendored
@ -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
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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
777
docs/ReleaseNotes-2.6.html
Normal 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 —which roughly includes the LLVM optimizers, code generators
|
||||
and supporting tools — 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 (<= 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>
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -26,6 +26,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void LLVMLinkInJIT(void);
|
||||
void LLVMLinkInInterpreter(void);
|
||||
|
||||
typedef struct LLVMOpaqueGenericValue *LLVMGenericValueRef;
|
||||
typedef struct LLVMOpaqueExecutionEngine *LLVMExecutionEngineRef;
|
||||
|
||||
|
@ -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 -------------------------------------------------------===*/
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
52
include/llvm/Analysis/LoopDependenceAnalysis.h
Normal file
52
include/llvm/Analysis/LoopDependenceAnalysis.h
Normal 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 */
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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*> {
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
33
include/llvm/CompilerDriver/BuiltinOptions.h
Normal file
33
include/llvm/CompilerDriver/BuiltinOptions.h
Normal 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
|
82
include/llvm/CompilerDriver/ForceLinkage.h
Normal file
82
include/llvm/CompilerDriver/ForceLinkage.h
Normal 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
|
29
include/llvm/CompilerDriver/ForceLinkageMacros.h
Normal file
29
include/llvm/CompilerDriver/ForceLinkageMacros.h
Normal 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
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
59
include/llvm/ExecutionEngine/JITEventListener.h
Normal file
59
include/llvm/ExecutionEngine/JITEventListener.h
Normal 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
|
@ -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]>;
|
||||
}
|
||||
|
@ -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
166
include/llvm/MC/MCContext.h
Normal 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
|
@ -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;
|
||||
|
28
include/llvm/MC/MCSection.h
Normal file
28
include/llvm/MC/MCSection.h
Normal 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
|
191
include/llvm/MC/MCStreamer.h
Normal file
191
include/llvm/MC/MCStreamer.h
Normal 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
|
33
include/llvm/MC/MCSymbol.h
Normal file
33
include/llvm/MC/MCSymbol.h
Normal 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
|
@ -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;
|
@ -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 "";
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
41
include/llvm/System/ThreadLocal.h
Normal file
41
include/llvm/System/ThreadLocal.h
Normal 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
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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 () {
|
||||
|
@ -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)
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
47
lib/Analysis/LoopDependenceAnalysis.cpp
Normal file
47
lib/Analysis/LoopDependenceAnalysis.cpp
Normal 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>();
|
||||
}
|
@ -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
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -9,7 +9,5 @@
|
||||
LEVEL = ../../..
|
||||
LIBRARYNAME = LLVMAsmPrinter
|
||||
PARALLEL_DIRS =
|
||||
BUILD_ARCHIVE = 1
|
||||
DONT_BUILD_RELINKED = 1
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
@ -63,3 +63,5 @@ add_llvm_library(LLVMCodeGen
|
||||
VirtRegMap.cpp
|
||||
VirtRegRewriter.cpp
|
||||
)
|
||||
|
||||
target_link_libraries (LLVMCodeGen LLVMCore)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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!
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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() << "\'";
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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!");
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 "
|
||||
|
@ -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!");
|
||||
}
|
||||
|
||||
|
@ -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!");
|
||||
}
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user