Import LLVM 74788.
This commit is contained in:
parent
cf5cd875b5
commit
72621d11de
@ -223,7 +223,7 @@ RDYNAMIC := @RDYNAMIC@
|
||||
#ENABLE_PROFILING = 1
|
||||
@ENABLE_PROFILING@
|
||||
|
||||
# When DISABLE_ASSERTIONS is enabled, builds of all of the LLVM code will
|
||||
# When DISABLE_ASSERTIONS is enabled, builds of all of the LLVM code will
|
||||
# exclude assertion checks, otherwise they are included.
|
||||
#DISABLE_ASSERTIONS = 1
|
||||
@DISABLE_ASSERTIONS@
|
||||
@ -297,3 +297,14 @@ endif
|
||||
|
||||
# Location of the plugin header file for gold.
|
||||
BINUTILS_INCDIR := @BINUTILS_INCDIR@
|
||||
|
||||
# When ENABLE_LLVMC_DYNAMIC is enabled, LLVMC will link libCompilerDriver
|
||||
# dynamically. This is needed to make dynamic plugins work on some targets
|
||||
# (Windows).
|
||||
ENABLE_LLVMC_DYNAMIC = 0
|
||||
#@ENABLE_LLVMC_DYNAMIC@
|
||||
|
||||
# When ENABLE_LLVMC_DYNAMIC_PLUGINS is enabled, LLVMC will have dynamic plugin
|
||||
# support (via the -load option).
|
||||
ENABLE_LLVMC_DYNAMIC_PLUGINS = 1
|
||||
#@ENABLE_LLVMC_DYNAMIC_PLUGINS@
|
||||
|
@ -201,15 +201,19 @@ LIBRARYNAME := $(patsubst %,plugin_llvmc_%,$(LLVMC_PLUGIN))
|
||||
CPP.Flags += -DLLVMC_PLUGIN_NAME=$(LLVMC_PLUGIN)
|
||||
REQUIRES_EH := 1
|
||||
|
||||
ifeq ($(ENABLE_LLVMC_DYNAMIC),1)
|
||||
LD.Flags += -lCompilerDriver
|
||||
endif
|
||||
|
||||
# Build a dynamic library if the user runs `make` directly from the plugin
|
||||
# directory.
|
||||
ifndef LLVMC_BUILTIN_PLUGIN
|
||||
LOADABLE_MODULE = 1
|
||||
LOADABLE_MODULE = 1
|
||||
endif
|
||||
|
||||
# TableGen stuff...
|
||||
ifneq ($(BUILT_SOURCES),)
|
||||
LLVMC_BUILD_AUTOGENERATED_INC=1
|
||||
LLVMC_BUILD_AUTOGENERATED_INC=1
|
||||
endif
|
||||
|
||||
endif # LLVMC_PLUGIN
|
||||
@ -217,10 +221,16 @@ endif # LLVMC_PLUGIN
|
||||
ifdef LLVMC_BASED_DRIVER
|
||||
|
||||
TOOLNAME = $(LLVMC_BASED_DRIVER)
|
||||
LLVMLIBS = CompilerDriver.a
|
||||
LINK_COMPONENTS = support system
|
||||
|
||||
REQUIRES_EH := 1
|
||||
|
||||
ifeq ($(ENABLE_LLVMC_DYNAMIC),1)
|
||||
LD.Flags += -lCompilerDriver
|
||||
else
|
||||
LLVMLIBS = CompilerDriver.a
|
||||
LINK_COMPONENTS = support system
|
||||
endif
|
||||
|
||||
# Preprocessor magic that generates references to static variables in built-in
|
||||
# plugins.
|
||||
ifneq ($(LLVMC_BUILTIN_PLUGINS),)
|
||||
@ -502,8 +512,7 @@ ifeq ($(OS),Darwin)
|
||||
else
|
||||
ifeq ($(OS),Cygwin)
|
||||
SharedLinkOptions=-shared -nostdlib -Wl,--export-all-symbols \
|
||||
-Wl,--enable-auto-import -Wl,--enable-auto-image-base \
|
||||
-Wl,--enable-runtime-pseudo-relocs
|
||||
-Wl,--enable-auto-import -Wl,--enable-auto-image-base
|
||||
else
|
||||
SharedLinkOptions=-shared
|
||||
endif
|
||||
|
@ -240,7 +240,7 @@ case "$llvm_cv_target_arch" in
|
||||
x86_64) LLVM_NATIVE_ARCH="X86" ;;
|
||||
*) LLVM_NATIVE_ARCH="$llvm_cv_target_arch" ;;
|
||||
esac
|
||||
|
||||
|
||||
dnl Define a substitution, ARCH, for the target architecture
|
||||
AC_SUBST(ARCH,$llvm_cv_target_arch)
|
||||
|
||||
@ -453,7 +453,7 @@ for a_target in $TARGETS_TO_BUILD; do
|
||||
fi
|
||||
done
|
||||
|
||||
# Build the LLVM_TARGET and LLVM_ASM_PRINTER macro uses for
|
||||
# Build the LLVM_TARGET and LLVM_ASM_PRINTER macro uses for
|
||||
# Targets.def and AsmPrinters.def.
|
||||
LLVM_ENUM_TARGETS=""
|
||||
LLVM_ENUM_ASM_PRINTERS=""
|
||||
@ -593,6 +593,35 @@ case "$enableval" in
|
||||
*) AC_MSG_ERROR([Invalid setting for --enable-libffi. Use "yes" or "no"]) ;;
|
||||
esac
|
||||
|
||||
dnl Only Windows needs dynamic libCompilerDriver to support plugins.
|
||||
if test "$llvm_cv_os_type" = "Win32" ; then
|
||||
llvmc_dynamic="yes"
|
||||
else
|
||||
llvmc_dynamic="no"
|
||||
fi
|
||||
|
||||
dnl --enable-llvmc-dynamic : should LLVMC link libCompilerDriver dynamically?
|
||||
AC_ARG_ENABLE(llvmc-dynamic,AS_HELP_STRING(
|
||||
--enable-llvmc-dynamic,
|
||||
[Link LLVMC dynamically (default is NO, unless on Win32)]),,
|
||||
enableval=$llvmc_dynamic)
|
||||
if test ${enableval} = "yes" && test "$ENABLE_PIC" -eq 1 ; then
|
||||
AC_SUBST(ENABLE_LLVMC_DYNAMIC,[[ENABLE_LLVMC_DYNAMIC=1]])
|
||||
else
|
||||
AC_SUBST(ENABLE_LLVMC_DYNAMIC,[[]])
|
||||
fi
|
||||
|
||||
dnl --enable-llvmc-dynamic-plugins : should LLVMC support dynamic plugins?
|
||||
AC_ARG_ENABLE(llvmc-dynamic-plugins,AS_HELP_STRING(
|
||||
--enable-llvmc-dynamic-plugins,
|
||||
[Enable dynamic LLVMC plugins (default is YES)]),,
|
||||
enableval=yes)
|
||||
if test ${enableval} = "yes" ; then
|
||||
AC_SUBST(ENABLE_LLVMC_DYNAMIC_PLUGINS,[[ENABLE_LLVMC_DYNAMIC_PLUGINS=1]])
|
||||
else
|
||||
AC_SUBST(ENABLE_LLVMC_DYNAMIC_PLUGINS,[[]])
|
||||
fi
|
||||
|
||||
dnl===-----------------------------------------------------------------------===
|
||||
dnl===
|
||||
dnl=== SECTION 4: Check for programs we need and that they are the right version
|
||||
@ -914,7 +943,8 @@ AC_CHECK_FUNCS([backtrace ceilf floorf roundf rintf nearbyintf getcwd ])
|
||||
AC_CHECK_FUNCS([powf fmodf strtof round ])
|
||||
AC_CHECK_FUNCS([getpagesize getrusage getrlimit setrlimit gettimeofday ])
|
||||
AC_CHECK_FUNCS([isatty mkdtemp mkstemp ])
|
||||
AC_CHECK_FUNCS([mktemp realpath sbrk setrlimit strdup strerror strerror_r ])
|
||||
AC_CHECK_FUNCS([mktemp realpath sbrk setrlimit strdup ])
|
||||
AC_CHECK_FUNCS([strerror strerror_r strerror_s ])
|
||||
AC_CHECK_FUNCS([strtoll strtoq sysconf malloc_zone_statistics ])
|
||||
AC_CHECK_FUNCS([setjmp longjmp sigsetjmp siglongjmp])
|
||||
AC_C_PRINTF_A
|
||||
@ -951,7 +981,7 @@ dnl atomic builtins are required for threading support.
|
||||
AC_MSG_CHECKING(for GCC atomic builtins)
|
||||
AC_LINK_IFELSE(
|
||||
AC_LANG_SOURCE(
|
||||
[[int main() {
|
||||
[[int main() {
|
||||
volatile unsigned long val = 1;
|
||||
__sync_synchronize();
|
||||
__sync_val_compare_and_swap(&val, 1, 0);
|
||||
|
@ -44,6 +44,8 @@ check_include_file(windows.h HAVE_WINDOWS_H)
|
||||
# library checks
|
||||
include(CheckLibraryExists)
|
||||
check_library_exists(pthread pthread_create "" HAVE_LIBPTHREAD)
|
||||
check_library_exists(pthread pthread_getspecific "" HAVE_PTHREAD_GETSPECIFIC)
|
||||
check_library_exists(pthread pthread_rwlock_init "" HAVE_PTHREAD_RWLOCK_INIT)
|
||||
check_library_exists(dl dlopen "" HAVE_LIBDL)
|
||||
|
||||
# function checks
|
||||
@ -64,9 +66,10 @@ 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(strerror string.h HAVE_STRERROR)
|
||||
check_symbol_exists(strerror_r string.h HAVE_STRERROR_R)
|
||||
check_symbol_exists(strerror_s string.h HAVE_STRERROR_S)
|
||||
|
||||
check_symbol_exists(__GLIBC__ stdio.h LLVM_USING_GLIBC)
|
||||
if( LLVM_USING_GLIBC )
|
||||
|
112
configure
vendored
112
configure
vendored
@ -31356,9 +31356,119 @@ done
|
||||
|
||||
|
||||
|
||||
for ac_func in mktemp realpath sbrk setrlimit strdup
|
||||
do
|
||||
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
|
||||
if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
|
||||
For example, HP-UX 11i <limits.h> declares gettimeofday. */
|
||||
#define $ac_func innocuous_$ac_func
|
||||
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char $ac_func (); below.
|
||||
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
|
||||
<limits.h> exists even on freestanding compilers. */
|
||||
|
||||
#ifdef __STDC__
|
||||
# include <limits.h>
|
||||
#else
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#undef $ac_func
|
||||
|
||||
/* 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 $ac_func ();
|
||||
/* The GNU C library defines this for functions which it implements
|
||||
to always fail with ENOSYS. Some functions are actually named
|
||||
something starting with __ and the normal name is an alias. */
|
||||
#if defined __stub_$ac_func || defined __stub___$ac_func
|
||||
choke me
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return $ac_func ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
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
|
||||
eval "$as_ac_var=yes"
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
eval "$as_ac_var=no"
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
ac_res=`eval echo '${'$as_ac_var'}'`
|
||||
{ echo "$as_me:$LINENO: result: $ac_res" >&5
|
||||
echo "${ECHO_T}$ac_res" >&6; }
|
||||
if test `eval echo '${'$as_ac_var'}'` = yes; then
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
for ac_func in mktemp realpath sbrk setrlimit strdup strerror strerror_r
|
||||
|
||||
|
||||
for ac_func in strerror strerror_r strerror_s
|
||||
do
|
||||
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||
|
@ -50,6 +50,8 @@
|
||||
<li><a href="#ll_ns_std">Do not use 'using namespace std'</a></li>
|
||||
<li><a href="#ll_virtual_anch">Provide a virtual method anchor for
|
||||
classes in headers</a></li>
|
||||
<li><a href="#ll_end">Don't evaluate end() every time through a
|
||||
loop</a></li>
|
||||
<li><a href="#ll_preincrement">Prefer Preincrement</a></li>
|
||||
<li><a href="#ll_avoidendl">Avoid <tt>std::endl</tt></a></li>
|
||||
</ol></li>
|
||||
@ -661,6 +663,67 @@ increasing link times.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="ll_end">Don't evaluate end() every time through a loop</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>Because C++ doesn't have a standard "foreach" loop (though it can be emulated
|
||||
with macros and may be coming in C++'0x) we end up writing a lot of loops that
|
||||
manually iterate from begin to end on a variety of containers or through other
|
||||
data structures. One common mistake is to write a loop in this style:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
BasicBlock *BB = ...
|
||||
for (BasicBlock::iterator I = BB->begin(); I != <b>BB->end()</b>; ++I)
|
||||
... use I ...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>The problem with this construct is that it evaluates "<tt>BB->end()</tt>"
|
||||
every time through the loop. Instead of writing the loop like this, we strongly
|
||||
prefer loops to be written so that they evaluate it once before the loop starts.
|
||||
A convenient way to do this is like so:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
BasicBlock *BB = ...
|
||||
for (BasicBlock::iterator I = BB->begin(), E = <b>BB->end()</b>; I != E; ++I)
|
||||
... use I ...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>The observant may quickly point out that these two loops may have different
|
||||
semantics: if the container (a basic block in this case) is being mutated, then
|
||||
"<tt>BB->end()</tt>" may change its value every time through the loop and the
|
||||
second loop may not in fact be correct. If you actually do depend on this
|
||||
behavior, please write the loop in the first form and add a comment indicating
|
||||
that you did it intentionally.</p>
|
||||
|
||||
<p>Why do we prefer the second form (when correct)? Writing the loop in the
|
||||
first form has two problems: First it may be less efficient than evaluating it
|
||||
at the start of the loop. In this case, the cost is probably minor: a few extra
|
||||
loads every time through the loop. However, if the base expression is more
|
||||
complex, then the cost can rise quickly. I've seen loops where the end
|
||||
expression was actually something like: "<tt>SomeMap[x]->end()</tt>" and map
|
||||
lookups really aren't cheap. By writing it in the second form consistently, you
|
||||
eliminate the issue entirely and don't even have to think about it.</p>
|
||||
|
||||
<p>The second (even bigger) issue is that writing the loop in the first form
|
||||
hints to the reader that the loop is mutating the container (a fact that a
|
||||
comment would handily confirm!). If you write the loop in the second form, it
|
||||
is immediately obvious without even looking at the body of the loop that the
|
||||
container isn't being modified, which makes it easier to read the code and
|
||||
understand what it does.</p>
|
||||
|
||||
<p>While the second form of the loop is a few extra keystrokes, we do strongly
|
||||
prefer it.</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
@ -744,7 +807,7 @@ something.</p>
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-03-23 05:53:34 +0100 (Mon, 23 Mar 2009) $
|
||||
Last modified: $Date: 2009-06-30 08:27:54 +0200 (Tue, 30 Jun 2009) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -37,6 +37,7 @@ The ReST source lives in the directory 'tools/llvmc/doc'. -->
|
||||
<li><a class="reference internal" href="#hooks-and-environment-variables" id="id17">Hooks and environment variables</a></li>
|
||||
<li><a class="reference internal" href="#how-plugins-are-loaded" id="id18">How plugins are loaded</a></li>
|
||||
<li><a class="reference internal" href="#debugging" id="id19">Debugging</a></li>
|
||||
<li><a class="reference internal" href="#conditioning-on-the-executable-name" id="id20">Conditioning on the executable name</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@ -94,9 +95,8 @@ $ llvmc --linker=c++ hello.o
|
||||
$ ./a.out
|
||||
hello
|
||||
</pre>
|
||||
<p>By default, LLVMC uses <tt class="docutils literal"><span class="pre">llvm-gcc</span></tt> to compile the source code. It is
|
||||
also possible to choose the work-in-progress <tt class="docutils literal"><span class="pre">clang</span></tt> compiler with
|
||||
the <tt class="docutils literal"><span class="pre">-clang</span></tt> option.</p>
|
||||
<p>By default, LLVMC uses <tt class="docutils literal"><span class="pre">llvm-gcc</span></tt> to compile the source code. It is also
|
||||
possible to choose the <tt class="docutils literal"><span class="pre">clang</span></tt> compiler with the <tt class="docutils literal"><span class="pre">-clang</span></tt> option.</p>
|
||||
</div>
|
||||
<div class="section" id="predefined-options">
|
||||
<h1><a class="toc-backref" href="#id6">Predefined options</a></h1>
|
||||
@ -633,6 +633,27 @@ be performed at compile-time because the plugins can load code
|
||||
dynamically. When invoked with <tt class="docutils literal"><span class="pre">--check-graph</span></tt>, <tt class="docutils literal"><span class="pre">llvmc</span></tt> doesn't
|
||||
perform any compilation tasks and returns the number of encountered
|
||||
errors as its status code.</p>
|
||||
</div>
|
||||
<div class="section" id="conditioning-on-the-executable-name">
|
||||
<h2><a class="toc-backref" href="#id20">Conditioning on the executable name</a></h2>
|
||||
<p>For now, the executable name (the value passed to the driver in <tt class="docutils literal"><span class="pre">argv[0]</span></tt>) is
|
||||
accessible only in the C++ code (i.e. hooks). Use the following code:</p>
|
||||
<pre class="literal-block">
|
||||
namespace llvmc {
|
||||
extern const char* ProgramName;
|
||||
}
|
||||
|
||||
std::string MyHook() {
|
||||
//...
|
||||
if (strcmp(ProgramName, "mydriver") == 0) {
|
||||
//...
|
||||
|
||||
}
|
||||
</pre>
|
||||
<p>In general, you're encouraged not to make the behaviour dependent on the
|
||||
executable file name, and use command-line switches instead. See for example how
|
||||
the <tt class="docutils literal"><span class="pre">Base</span></tt> plugin behaves when it needs to choose the correct linker options
|
||||
(think <tt class="docutils literal"><span class="pre">g++</span></tt> vs. <tt class="docutils literal"><span class="pre">gcc</span></tt>).</p>
|
||||
<hr />
|
||||
<address>
|
||||
<a href="http://jigsaw.w3.org/css-validator/check/referer">
|
||||
@ -645,7 +666,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-25 20:21:10 +0200 (Thu, 25 Jun 2009) $
|
||||
Last modified: $Date: 2009-06-30 02:16:43 +0200 (Tue, 30 Jun 2009) $
|
||||
</address></div>
|
||||
</div>
|
||||
</div>
|
||||
|
143
docs/FAQ.html
143
docs/FAQ.html
@ -124,6 +124,10 @@
|
||||
|
||||
<li><a href="#undef">What is this "<tt>undef</tt>" thing that shows up in
|
||||
my code?</a></li>
|
||||
|
||||
<li><a href="#callconvwrong">Why does instcombine + simplifycfg turn
|
||||
a call to a function with a mismatched calling convention into "unreachable"?
|
||||
Why not make the verifier reject it?</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
</ol>
|
||||
@ -780,6 +784,143 @@ int X() { int i; return i; }
|
||||
value specified for it.</p>
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
|
||||
<div class="question">
|
||||
<p><a name="callconvwrong">Why does instcombine + simplifycfg turn
|
||||
a call to a function with a mismatched calling convention into "unreachable"?
|
||||
Why not make the verifier reject it?</a></p>
|
||||
</div>
|
||||
|
||||
<div class="answer">
|
||||
<p>This is a common problem run into by authors of front-ends that are using
|
||||
custom calling conventions: you need to make sure to set the right calling
|
||||
convention on both the function and on each call to the function. For example,
|
||||
this code:</p>
|
||||
|
||||
<pre class="doc_code">
|
||||
define fastcc void @foo() {
|
||||
ret void
|
||||
}
|
||||
define void @bar() {
|
||||
call void @foo( )
|
||||
ret void
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Is optimized to:</p>
|
||||
|
||||
<pre class="doc_code">
|
||||
define fastcc void @foo() {
|
||||
ret void
|
||||
}
|
||||
define void @bar() {
|
||||
unreachable
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>... with "opt -instcombine -simplifycfg". This often bites people because
|
||||
"all their code disappears". Setting the calling convention on the caller and
|
||||
callee is required for indirect calls to work, so people often ask why not make
|
||||
the verifier reject this sort of thing.</p>
|
||||
|
||||
<p>The answer is that this code has undefined behavior, but it is not illegal.
|
||||
If we made it illegal, then every transformation that could potentially create
|
||||
this would have to ensure that it doesn't, and there is valid code that can
|
||||
create this sort of construct (in dead code). The sorts of things that can
|
||||
cause this to happen are fairly contrived, but we still need to accept them.
|
||||
Here's an example:</p>
|
||||
|
||||
<pre class="doc_code">
|
||||
define fastcc void @foo() {
|
||||
ret void
|
||||
}
|
||||
define internal void @bar(void()* %FP, i1 %cond) {
|
||||
br i1 %cond, label %T, label %F
|
||||
T:
|
||||
call void %FP()
|
||||
ret void
|
||||
F:
|
||||
call fastcc void %FP()
|
||||
ret void
|
||||
}
|
||||
define void @test() {
|
||||
%X = or i1 false, false
|
||||
call void @bar(void()* @foo, i1 %X)
|
||||
ret void
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>In this example, "test" always passes @foo/false into bar, which ensures that
|
||||
it is dynamically called with the right calling conv (thus, the code is
|
||||
perfectly well defined). If you run this through the inliner, you get this
|
||||
(the explicit "or" is there so that the inliner doesn't dead code eliminate
|
||||
a bunch of stuff):
|
||||
</p>
|
||||
|
||||
<pre class="doc_code">
|
||||
define fastcc void @foo() {
|
||||
ret void
|
||||
}
|
||||
define void @test() {
|
||||
%X = or i1 false, false
|
||||
br i1 %X, label %T.i, label %F.i
|
||||
T.i:
|
||||
call void @foo()
|
||||
br label %bar.exit
|
||||
F.i:
|
||||
call fastcc void @foo()
|
||||
br label %bar.exit
|
||||
bar.exit:
|
||||
ret void
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Here you can see that the inlining pass made an undefined call to @foo with
|
||||
the wrong calling convention. We really don't want to make the inliner have
|
||||
to know about this sort of thing, so it needs to be valid code. In this case,
|
||||
dead code elimination can trivially remove the undefined code. However, if %X
|
||||
was an input argument to @test, the inliner would produce this:
|
||||
</p>
|
||||
|
||||
<pre class="doc_code">
|
||||
define fastcc void @foo() {
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test(i1 %X) {
|
||||
br i1 %X, label %T.i, label %F.i
|
||||
T.i:
|
||||
call void @foo()
|
||||
br label %bar.exit
|
||||
F.i:
|
||||
call fastcc void @foo()
|
||||
br label %bar.exit
|
||||
bar.exit:
|
||||
ret void
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>The interesting thing about this is that %X <em>must</em> be false for the
|
||||
code to be well-defined, but no amount of dead code elimination will be able to
|
||||
delete the broken call as unreachable. However, since instcombine/simplifycfg
|
||||
turns the undefined call into unreachable, we end up with a branch on a
|
||||
condition that goes to unreachable: a branch to unreachable can never happen, so
|
||||
"-inline -instcombine -simplifycfg" is able to produce:</p>
|
||||
|
||||
<pre class="doc_code">
|
||||
define fastcc void @foo() {
|
||||
ret void
|
||||
}
|
||||
define void @test(i1 %X) {
|
||||
F.i:
|
||||
call fastcc void @foo()
|
||||
ret void
|
||||
}
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<hr>
|
||||
@ -790,7 +931,7 @@ int X() { int i; return i; }
|
||||
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-04-10 22:48:27 +0200 (Fri, 10 Apr 2009) $
|
||||
Last modified: $Date: 2009-06-30 19:10:19 +0200 (Tue, 30 Jun 2009) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -419,7 +419,7 @@ it run faster:</p>
|
||||
<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
|
||||
on LLVM 2.5, this section lists some "gotchas" that you may run into upgrading
|
||||
from the previous release.</p>
|
||||
|
||||
<ul>
|
||||
@ -433,6 +433,13 @@ from the previous release.</p>
|
||||
API changes are:</p>
|
||||
|
||||
<ul>
|
||||
<li>LLVM's global uniquing tables for <tt>Type</tt>s and <tt>Constant</tt>s have
|
||||
been privatized into members of an <tt>LLVMContext</tt>. A number of APIs
|
||||
now take an <tt>LLVMContext</tt> as a parameter. To smooth the transition
|
||||
for clients that will only ever use a single context, the new
|
||||
<tt>getGlobalContext()</tt> API can be used to access a default global
|
||||
context which can be passed in any and all cases where a context is
|
||||
required.
|
||||
<li>The <tt>getABITypeSize</tt> methods are now called <tt>getAllocSize</tt>.</li>
|
||||
</ul>
|
||||
|
||||
@ -770,7 +777,7 @@ lists</a>.</p>
|
||||
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) $
|
||||
Last modified: $Date: 2009-07-02 18:48:38 +0200 (Thu, 02 Jul 2009) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -411,7 +411,8 @@ which case the user must specify it explicitly.</dd>
|
||||
<dt><tt>!cast<type>(a)</tt></dt>
|
||||
<dd>A symbol of type <em>type</em> obtained by looking up the string 'a' in
|
||||
the symbol table. If the type of 'a' does not match <em>type</em>, TableGen
|
||||
aborts with an error. </dd>
|
||||
aborts with an error. !cast<string> is a special case in that the argument must
|
||||
be an object defined by a 'def' construct.</dd>
|
||||
<dt><tt>!nameconcat<type>(a, b)</tt></dt>
|
||||
<dd>Shorthand for !cast<type>(!strconcat(a, b))</dd>
|
||||
<dt><tt>!subst(a, b, c)</tt></dt>
|
||||
@ -781,7 +782,7 @@ This should highlight the APIs in <tt>TableGen/Record.h</tt>.</p>
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-06-09 20:31:17 +0200 (Tue, 09 Jun 2009) $
|
||||
Last modified: $Date: 2009-06-29 22:05:29 +0200 (Mon, 29 Jun 2009) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -491,10 +491,15 @@ class is the most general of all superclasses that you can use. Deriving from
|
||||
<tt>ModulePass</tt> indicates that your pass uses the entire program as a unit,
|
||||
refering to function bodies in no predictable order, or adding and removing
|
||||
functions. Because nothing is known about the behavior of <tt>ModulePass</tt>
|
||||
subclasses, no optimization can be done for their execution. A module pass
|
||||
can use function level passes (e.g. dominators) using getAnalysis interface
|
||||
<tt> getAnalysis<DominatorTree>(Function)</tt>, if the function pass
|
||||
does not require any module passes. </p>
|
||||
subclasses, no optimization can be done for their execution.</p>
|
||||
|
||||
<p>A module pass can use function level passes (e.g. dominators) using
|
||||
the getAnalysis interface
|
||||
<tt>getAnalysis<DominatorTree>(llvm::Function *)</tt> to provide the
|
||||
function to retrieve analysis result for, if the function pass does not require
|
||||
any module passes. Note that this can only be done for functions for which the
|
||||
analysis ran, e.g. in the case of dominators you should only ask for the
|
||||
DominatorTree for function definitions, not declarations.</p>
|
||||
|
||||
<p>To write a correct <tt>ModulePass</tt> subclass, derive from
|
||||
<tt>ModulePass</tt> and overload the <tt>runOnModule</tt> method with the
|
||||
@ -1821,7 +1826,7 @@ Despite that, we have kept the LLVM passes SMP ready, and you should too.</p>
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-06-15 18:22:49 +0000 (Mon, 15 Jun 2009) $
|
||||
Last modified: $Date: 2009-07-02 01:38:44 +0200 (Thu, 02 Jul 2009) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -36,19 +36,20 @@ const char *BrainF::headreg = "head";
|
||||
const char *BrainF::label = "brainf";
|
||||
const char *BrainF::testreg = "test";
|
||||
|
||||
Module *BrainF::parse(std::istream *in1, int mem, CompileFlags cf) {
|
||||
Module *BrainF::parse(std::istream *in1, int mem, CompileFlags cf,
|
||||
LLVMContext& Context) {
|
||||
in = in1;
|
||||
memtotal = mem;
|
||||
comflag = cf;
|
||||
|
||||
header();
|
||||
header(Context);
|
||||
readloop(0, 0, 0);
|
||||
delete builder;
|
||||
return module;
|
||||
}
|
||||
|
||||
void BrainF::header() {
|
||||
module = new Module("BrainF");
|
||||
void BrainF::header(LLVMContext& C) {
|
||||
module = new Module("BrainF", C);
|
||||
|
||||
//Function prototypes
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#ifndef BRAINF_H
|
||||
#define BRAINF_H
|
||||
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Support/IRBuilder.h"
|
||||
|
||||
@ -38,7 +39,8 @@ class BrainF {
|
||||
/// containing the resulting code.
|
||||
/// On error, it calls abort.
|
||||
/// The caller must delete the returned module.
|
||||
Module *parse(std::istream *in1, int mem, CompileFlags cf);
|
||||
Module *parse(std::istream *in1, int mem, CompileFlags cf,
|
||||
LLVMContext& C);
|
||||
|
||||
protected:
|
||||
/// The different symbols in the BrainF language
|
||||
@ -64,7 +66,7 @@ class BrainF {
|
||||
static const char *testreg;
|
||||
|
||||
/// Put the brainf function preamble and other fixed pieces of code
|
||||
void header();
|
||||
void header(LLVMContext& C);
|
||||
|
||||
/// The main loop for parsing. It calls itself recursively
|
||||
/// to handle the depth of nesting of "[]".
|
||||
|
@ -86,6 +86,8 @@ void addMainFunction(Module *mod) {
|
||||
int main(int argc, char **argv) {
|
||||
cl::ParseCommandLineOptions(argc, argv, " BrainF compiler\n");
|
||||
|
||||
LLVMContext Context;
|
||||
|
||||
if (InputFilename == "") {
|
||||
std::cerr<<"Error: You must specify the filename of the program to "
|
||||
"be compiled. Use --help to see the options.\n";
|
||||
@ -124,7 +126,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
//Read the BrainF program
|
||||
BrainF bf;
|
||||
Module *mod = bf.parse(in, 65536, cf); //64 KiB
|
||||
Module *mod = bf.parse(in, 65536, cf, Context); //64 KiB
|
||||
if (in != &std::cin) {delete in;}
|
||||
addMainFunction(mod);
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Constants.h"
|
||||
@ -90,8 +91,10 @@ static Function *CreateFibFunction(Module *M) {
|
||||
int main(int argc, char **argv) {
|
||||
int n = argc > 1 ? atol(argv[1]) : 24;
|
||||
|
||||
LLVMContext Context;
|
||||
|
||||
// Create some module to put our function into it.
|
||||
Module *M = new Module("test");
|
||||
Module *M = new Module("test", Context);
|
||||
|
||||
// We are about to create the "fib" function:
|
||||
Function *FibF = CreateFibFunction(M);
|
||||
|
@ -34,6 +34,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
@ -50,9 +51,11 @@ using namespace llvm;
|
||||
int main() {
|
||||
|
||||
InitializeNativeTarget();
|
||||
|
||||
LLVMContext Context;
|
||||
|
||||
// Create some module to put our function into it.
|
||||
Module *M = new Module("test");
|
||||
Module *M = new Module("test", Context);
|
||||
|
||||
// Create the add1 function entry and insert this entry into module M. The
|
||||
// function will have a return type of "int" and take an argument of "int".
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/ModuleProvider.h"
|
||||
#include "llvm/PassManager.h"
|
||||
@ -1083,6 +1084,7 @@ double printd(double X) {
|
||||
|
||||
int main() {
|
||||
InitializeNativeTarget();
|
||||
LLVMContext Context;
|
||||
|
||||
// Install standard binary operators.
|
||||
// 1 is lowest precedence.
|
||||
@ -1097,7 +1099,7 @@ int main() {
|
||||
getNextToken();
|
||||
|
||||
// Make the module, which holds all the code.
|
||||
TheModule = new Module("my cool jit");
|
||||
TheModule = new Module("my cool jit", Context);
|
||||
|
||||
// Create the JIT.
|
||||
TheExecutionEngine = ExecutionEngine::create(TheModule);
|
||||
|
@ -13,6 +13,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Constants.h"
|
||||
@ -22,13 +23,14 @@
|
||||
using namespace llvm;
|
||||
|
||||
int main() {
|
||||
LLVMContext Context;
|
||||
|
||||
// Create the "module" or "program" or "translation unit" to hold the
|
||||
// function
|
||||
Module *M = new Module("test");
|
||||
Module *M = new Module("test", Context);
|
||||
|
||||
// Create the main function: first create the type 'int ()'
|
||||
FunctionType *FT = FunctionType::get(Type::Int32Ty, std::vector<const Type*>(),
|
||||
/*not vararg*/false);
|
||||
FunctionType *FT = FunctionType::get(Type::Int32Ty, /*not vararg*/false);
|
||||
|
||||
// By passing a module as the last parameter to the Function constructor,
|
||||
// it automatically gets appended to the Module.
|
||||
|
@ -18,6 +18,7 @@
|
||||
// same time). This test had assertion errors until I got the locking right.
|
||||
|
||||
#include <pthread.h>
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
@ -232,9 +233,10 @@ void* callFunc( void* param )
|
||||
|
||||
int main() {
|
||||
InitializeNativeTarget();
|
||||
LLVMContext Context;
|
||||
|
||||
// Create some module to put our function into it.
|
||||
Module *M = new Module("test");
|
||||
Module *M = new Module("test", Context);
|
||||
|
||||
Function* add1F = createAdd1( M );
|
||||
Function* fibF = CreateFibFunction( M );
|
||||
|
@ -32,6 +32,10 @@ extern "C" {
|
||||
int LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleRef *OutModule, char **OutMessage);
|
||||
|
||||
int LLVMParseBitcodeInContext(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMContextRef ContextRef,
|
||||
LLVMModuleRef *OutModule, char **OutMessage);
|
||||
|
||||
/* Reads a module from the specified path, returning via the OutMP parameter
|
||||
a module provider which performs lazy deserialization. Returns 0 on success.
|
||||
Optionally returns a human-readable error message via OutMessage. */
|
||||
@ -39,6 +43,11 @@ int LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleProviderRef *OutMP,
|
||||
char **OutMessage);
|
||||
|
||||
int LLVMGetBitcodeModuleProviderInContext(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMContextRef ContextRef,
|
||||
LLVMModuleProviderRef *OutMP,
|
||||
char **OutMessage);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -46,6 +46,11 @@ extern "C" {
|
||||
|
||||
/* Opaque types. */
|
||||
|
||||
/**
|
||||
* The top-level container for all LLVM global data. See the LLVMContext class.
|
||||
*/
|
||||
typedef struct LLVMCtxt *LLVMContextRef;
|
||||
|
||||
/**
|
||||
* The top-level container for all other LLVM Intermediate Representation (IR)
|
||||
* objects. See the llvm::Module class.
|
||||
@ -188,9 +193,16 @@ void LLVMDisposeMessage(char *Message);
|
||||
|
||||
/*===-- Modules -----------------------------------------------------------===*/
|
||||
|
||||
/* Create and destroy contexts. */
|
||||
LLVMContextRef LLVMContextCreate();
|
||||
LLVMContextRef LLVMGetGlobalContext();
|
||||
void LLVMContextDispose(LLVMContextRef C);
|
||||
|
||||
/* Create and destroy modules. */
|
||||
/** See llvm::Module::Module. */
|
||||
LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID);
|
||||
LLVMModuleRef LLVMModuleCreateWithNameInContext(const char *ModuleID,
|
||||
LLVMContextRef C);
|
||||
|
||||
/** See llvm::Module::~Module. */
|
||||
void LLVMDisposeModule(LLVMModuleRef M);
|
||||
@ -815,6 +827,7 @@ namespace llvm {
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(PATypeHolder, LLVMTypeHandleRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ModuleProvider, LLVMModuleProviderRef)
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef )
|
||||
DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBase, LLVMPassManagerRef )
|
||||
|
||||
#undef DEFINE_STDCXX_CONVERSION_FUNCTIONS
|
||||
|
@ -16,6 +16,7 @@
|
||||
#ifndef LTO_H
|
||||
#define LTO_H 1
|
||||
|
||||
#include "llvm-c/Core.h"
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
@ -58,7 +59,6 @@ typedef struct LTOModule* lto_module_t;
|
||||
/** opaque reference to a code generator */
|
||||
typedef struct LTOCodeGenerator* lto_code_gen_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -76,7 +76,6 @@ lto_get_version(void);
|
||||
extern const char*
|
||||
lto_get_error_message(void);
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a file is a loadable object file.
|
||||
*/
|
||||
|
@ -1426,6 +1426,8 @@ inline raw_ostream &operator<<(raw_ostream &OS, const APInt &I) {
|
||||
return OS;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &o, const APInt &I);
|
||||
|
||||
namespace APIntOps {
|
||||
|
||||
/// @brief Determine the smaller of two APInts considered to be signed.
|
||||
|
@ -51,7 +51,7 @@ namespace llvm {
|
||||
/// public:
|
||||
/// MyNode(const char *N, unsigned V) : Name(N), Value(V) {}
|
||||
/// ...
|
||||
/// void Profile(FoldingSetNodeID &ID) {
|
||||
/// void Profile(FoldingSetNodeID &ID) const {
|
||||
/// ID.AddString(Name);
|
||||
/// ID.AddInteger(Value);
|
||||
/// }
|
||||
|
@ -89,7 +89,7 @@ namespace llvm {
|
||||
int is() const {
|
||||
int TyNo = ::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0);
|
||||
assert(TyNo != -1 && "Type query could never succeed on PointerUnion!");
|
||||
return Val.getInt() == TyNo;
|
||||
return static_cast<int>(Val.getInt()) == TyNo;
|
||||
}
|
||||
|
||||
/// get<T>() - Return the value of the specified pointer type. If the
|
||||
|
@ -34,10 +34,10 @@ class Statistic {
|
||||
public:
|
||||
const char *Name;
|
||||
const char *Desc;
|
||||
unsigned Value;
|
||||
volatile llvm::sys::cas_flag Value;
|
||||
bool Initialized;
|
||||
|
||||
unsigned getValue() const { return Value; }
|
||||
llvm::sys::cas_flag getValue() const { return Value; }
|
||||
const char *getName() const { return Name; }
|
||||
const char *getDesc() const { return Desc; }
|
||||
|
||||
|
@ -53,7 +53,8 @@ public:
|
||||
Darwin,
|
||||
DragonFly,
|
||||
FreeBSD,
|
||||
Linux
|
||||
Linux,
|
||||
OpenBSD
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -33,6 +33,11 @@ namespace llvm {
|
||||
class Value;
|
||||
struct DbgStopPointInst;
|
||||
struct DbgDeclareInst;
|
||||
struct DbgFuncStartInst;
|
||||
struct DbgRegionStartInst;
|
||||
struct DbgRegionEndInst;
|
||||
class DebugLoc;
|
||||
class DebugLocTracker;
|
||||
class Instruction;
|
||||
|
||||
class DIDescriptor {
|
||||
@ -548,6 +553,47 @@ namespace llvm {
|
||||
SmallVector<GlobalVariable *, 4> &GlobalVars,
|
||||
SmallVector<GlobalVariable *, 4> &Subprograms);
|
||||
|
||||
/// isValidDebugInfoIntrinsic - Return true if SPI is a valid debug
|
||||
/// info intrinsic.
|
||||
bool isValidDebugInfoIntrinsic(DbgStopPointInst &SPI,
|
||||
CodeGenOpt::Level OptLev);
|
||||
|
||||
/// isValidDebugInfoIntrinsic - Return true if FSI is a valid debug
|
||||
/// info intrinsic.
|
||||
bool isValidDebugInfoIntrinsic(DbgFuncStartInst &FSI,
|
||||
CodeGenOpt::Level OptLev);
|
||||
|
||||
/// isValidDebugInfoIntrinsic - Return true if RSI is a valid debug
|
||||
/// info intrinsic.
|
||||
bool isValidDebugInfoIntrinsic(DbgRegionStartInst &RSI,
|
||||
CodeGenOpt::Level OptLev);
|
||||
|
||||
/// isValidDebugInfoIntrinsic - Return true if REI is a valid debug
|
||||
/// info intrinsic.
|
||||
bool isValidDebugInfoIntrinsic(DbgRegionEndInst &REI,
|
||||
CodeGenOpt::Level OptLev);
|
||||
|
||||
/// isValidDebugInfoIntrinsic - Return true if DI is a valid debug
|
||||
/// info intrinsic.
|
||||
bool isValidDebugInfoIntrinsic(DbgDeclareInst &DI,
|
||||
CodeGenOpt::Level OptLev);
|
||||
|
||||
/// ExtractDebugLocation - Extract debug location information
|
||||
/// from llvm.dbg.stoppoint intrinsic.
|
||||
DebugLoc ExtractDebugLocation(DbgStopPointInst &SPI,
|
||||
DebugLocTracker &DebugLocInfo);
|
||||
|
||||
/// ExtractDebugLocation - Extract debug location information
|
||||
/// from llvm.dbg.func_start intrinsic.
|
||||
DebugLoc ExtractDebugLocation(DbgFuncStartInst &FSI,
|
||||
DebugLocTracker &DebugLocInfo);
|
||||
|
||||
/// isInlinedFnStart - Return true if FSI is starting an inlined function.
|
||||
bool isInlinedFnStart(DbgFuncStartInst &FSI, const Function *CurrentFn);
|
||||
|
||||
/// isInlinedFnEnd - Return true if REI is ending an inlined function.
|
||||
bool isInlinedFnEnd(DbgRegionEndInst &REI, const Function *CurrentFn);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -618,8 +618,9 @@ protected:
|
||||
}
|
||||
|
||||
DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB) {
|
||||
if (DomTreeNodeBase<NodeT> *BBNode = this->DomTreeNodes[BB])
|
||||
return BBNode;
|
||||
typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.find(BB);
|
||||
if (I != this->DomTreeNodes.end() && I->second)
|
||||
return I->second;
|
||||
|
||||
// Haven't calculated this node yet? Get or calculate the node for the
|
||||
// immediate dominator.
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#include "llvm/Analysis/LoopPass.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include <llvm/ADT/SmallVector.h>
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <map>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -21,24 +21,35 @@
|
||||
#define LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H
|
||||
|
||||
#include "llvm/Analysis/LoopPass.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <iosfwd>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class AliasAnalysis;
|
||||
class AnalysisUsage;
|
||||
class LoopPass;
|
||||
class ScalarEvolution;
|
||||
class Value;
|
||||
|
||||
class LoopDependenceAnalysis : public LoopPass {
|
||||
Loop *L;
|
||||
AliasAnalysis *AA;
|
||||
ScalarEvolution *SE;
|
||||
|
||||
public:
|
||||
static char ID; // Class identification, replacement for typeinfo
|
||||
LoopDependenceAnalysis() : LoopPass(&ID) {}
|
||||
|
||||
/// TODO: docs
|
||||
bool isDependencePair(const Value*, const Value*) const;
|
||||
bool depends(Value*, Value*);
|
||||
|
||||
bool runOnLoop(Loop*, LPPassManager&);
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage&) const;
|
||||
|
||||
void print(raw_ostream&, const Module* = 0) const;
|
||||
virtual void print(std::ostream&, const Module* = 0) const;
|
||||
}; // class LoopDependenceAnalysis
|
||||
|
||||
|
||||
|
@ -662,7 +662,9 @@ class LoopInfoBase {
|
||||
std::map<BlockT*, LoopBase<BlockT>*> BBMap;
|
||||
std::vector<LoopBase<BlockT>*> TopLevelLoops;
|
||||
friend class LoopBase<BlockT>;
|
||||
|
||||
|
||||
void operator=(const LoopInfoBase &); // do not implement
|
||||
LoopInfoBase(const LoopInfo &); // do not implement
|
||||
public:
|
||||
LoopInfoBase() { }
|
||||
~LoopInfoBase() { releaseMemory(); }
|
||||
@ -962,61 +964,59 @@ public:
|
||||
};
|
||||
|
||||
class LoopInfo : public FunctionPass {
|
||||
LoopInfoBase<BasicBlock>* LI;
|
||||
LoopInfoBase<BasicBlock> LI;
|
||||
friend class LoopBase<BasicBlock>;
|
||||
|
||||
|
||||
void operator=(const LoopInfo &); // do not implement
|
||||
LoopInfo(const LoopInfo &); // do not implement
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
|
||||
LoopInfo() : FunctionPass(&ID) {
|
||||
LI = new LoopInfoBase<BasicBlock>();
|
||||
}
|
||||
|
||||
~LoopInfo() { delete LI; }
|
||||
LoopInfo() : FunctionPass(&ID) {}
|
||||
|
||||
LoopInfoBase<BasicBlock>& getBase() { return *LI; }
|
||||
LoopInfoBase<BasicBlock>& getBase() { return LI; }
|
||||
|
||||
/// iterator/begin/end - The interface to the top-level loops in the current
|
||||
/// function.
|
||||
///
|
||||
typedef std::vector<Loop*>::const_iterator iterator;
|
||||
inline iterator begin() const { return LI->begin(); }
|
||||
inline iterator end() const { return LI->end(); }
|
||||
bool empty() const { return LI->empty(); }
|
||||
typedef LoopInfoBase<BasicBlock>::iterator iterator;
|
||||
inline iterator begin() const { return LI.begin(); }
|
||||
inline iterator end() const { return LI.end(); }
|
||||
bool empty() const { return LI.empty(); }
|
||||
|
||||
/// getLoopFor - Return the inner most loop that BB lives in. If a basic
|
||||
/// block is in no loop (for example the entry node), null is returned.
|
||||
///
|
||||
inline Loop *getLoopFor(const BasicBlock *BB) const {
|
||||
return LI->getLoopFor(BB);
|
||||
return LI.getLoopFor(BB);
|
||||
}
|
||||
|
||||
/// operator[] - same as getLoopFor...
|
||||
///
|
||||
inline const Loop *operator[](const BasicBlock *BB) const {
|
||||
return LI->getLoopFor(BB);
|
||||
return LI.getLoopFor(BB);
|
||||
}
|
||||
|
||||
/// getLoopDepth - Return the loop nesting level of the specified block. A
|
||||
/// depth of 0 means the block is not inside any loop.
|
||||
///
|
||||
inline unsigned getLoopDepth(const BasicBlock *BB) const {
|
||||
return LI->getLoopDepth(BB);
|
||||
return LI.getLoopDepth(BB);
|
||||
}
|
||||
|
||||
// isLoopHeader - True if the block is a loop header node
|
||||
inline bool isLoopHeader(BasicBlock *BB) const {
|
||||
return LI->isLoopHeader(BB);
|
||||
return LI.isLoopHeader(BB);
|
||||
}
|
||||
|
||||
/// runOnFunction - Calculate the natural loop information.
|
||||
///
|
||||
virtual bool runOnFunction(Function &F);
|
||||
|
||||
virtual void releaseMemory() { LI->releaseMemory(); }
|
||||
virtual void releaseMemory() { LI.releaseMemory(); }
|
||||
|
||||
virtual void print(std::ostream &O, const Module* M = 0) const {
|
||||
if (O) LI->print(O, M);
|
||||
LI.print(O, M);
|
||||
}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
@ -1024,32 +1024,32 @@ public:
|
||||
/// removeLoop - This removes the specified top-level loop from this loop info
|
||||
/// object. The loop is not deleted, as it will presumably be inserted into
|
||||
/// another loop.
|
||||
inline Loop *removeLoop(iterator I) { return LI->removeLoop(I); }
|
||||
inline Loop *removeLoop(iterator I) { return LI.removeLoop(I); }
|
||||
|
||||
/// changeLoopFor - Change the top-level loop that contains BB to the
|
||||
/// specified loop. This should be used by transformations that restructure
|
||||
/// the loop hierarchy tree.
|
||||
inline void changeLoopFor(BasicBlock *BB, Loop *L) {
|
||||
LI->changeLoopFor(BB, L);
|
||||
LI.changeLoopFor(BB, L);
|
||||
}
|
||||
|
||||
/// changeTopLevelLoop - Replace the specified loop in the top-level loops
|
||||
/// list with the indicated loop.
|
||||
inline void changeTopLevelLoop(Loop *OldLoop, Loop *NewLoop) {
|
||||
LI->changeTopLevelLoop(OldLoop, NewLoop);
|
||||
LI.changeTopLevelLoop(OldLoop, NewLoop);
|
||||
}
|
||||
|
||||
/// addTopLevelLoop - This adds the specified loop to the collection of
|
||||
/// top-level loops.
|
||||
inline void addTopLevelLoop(Loop *New) {
|
||||
LI->addTopLevelLoop(New);
|
||||
LI.addTopLevelLoop(New);
|
||||
}
|
||||
|
||||
/// removeBlock - This method completely removes BB from all data structures,
|
||||
/// including all of the Loop objects it is nested in and our mapping from
|
||||
/// BasicBlocks to loops.
|
||||
void removeBlock(BasicBlock *BB) {
|
||||
LI->removeBlock(BB);
|
||||
LI.removeBlock(BB);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1057,7 +1057,7 @@ public:
|
||||
// Allow clients to walk the list of nested loops...
|
||||
template <> struct GraphTraits<const Loop*> {
|
||||
typedef const Loop NodeType;
|
||||
typedef std::vector<Loop*>::const_iterator ChildIteratorType;
|
||||
typedef LoopInfo::iterator ChildIteratorType;
|
||||
|
||||
static NodeType *getEntryNode(const Loop *L) { return L; }
|
||||
static inline ChildIteratorType child_begin(NodeType *N) {
|
||||
@ -1070,7 +1070,7 @@ template <> struct GraphTraits<const Loop*> {
|
||||
|
||||
template <> struct GraphTraits<Loop*> {
|
||||
typedef Loop NodeType;
|
||||
typedef std::vector<Loop*>::const_iterator ChildIteratorType;
|
||||
typedef LoopInfo::iterator ChildIteratorType;
|
||||
|
||||
static NodeType *getEntryNode(Loop *L) { return L; }
|
||||
static inline ChildIteratorType child_begin(NodeType *N) {
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include <iosfwd>
|
||||
|
||||
@ -34,20 +36,12 @@ namespace llvm {
|
||||
class Type;
|
||||
class ScalarEvolution;
|
||||
class TargetData;
|
||||
class SCEVConstant;
|
||||
class SCEVTruncateExpr;
|
||||
class SCEVZeroExtendExpr;
|
||||
class SCEVCommutativeExpr;
|
||||
class SCEVUDivExpr;
|
||||
class SCEVSignExtendExpr;
|
||||
class SCEVAddRecExpr;
|
||||
class SCEVUnknown;
|
||||
|
||||
/// SCEV - This class represents an analyzed expression in the program. These
|
||||
/// are opaque objects that the client is not allowed to do much with
|
||||
/// directly.
|
||||
///
|
||||
class SCEV {
|
||||
class SCEV : public FoldingSetNode {
|
||||
const unsigned SCEVType; // The SCEV baseclass this node corresponds to
|
||||
|
||||
SCEV(const SCEV &); // DO NOT IMPLEMENT
|
||||
@ -58,6 +52,8 @@ namespace llvm {
|
||||
explicit SCEV(unsigned SCEVTy) :
|
||||
SCEVType(SCEVTy) {}
|
||||
|
||||
virtual void Profile(FoldingSetNodeID &ID) const = 0;
|
||||
|
||||
unsigned getSCEVType() const { return SCEVType; }
|
||||
|
||||
/// isLoopInvariant - Return true if the value of this SCEV is unchanging in
|
||||
@ -132,6 +128,7 @@ namespace llvm {
|
||||
SCEVCouldNotCompute();
|
||||
|
||||
// None of these methods are valid for this object.
|
||||
virtual void Profile(FoldingSetNodeID &ID) const;
|
||||
virtual bool isLoopInvariant(const Loop *L) const;
|
||||
virtual const Type *getType() const;
|
||||
virtual bool hasComputableLoopEvolution(const Loop *L) const;
|
||||
@ -182,7 +179,7 @@ namespace llvm {
|
||||
|
||||
/// CouldNotCompute - This SCEV is used to represent unknown trip
|
||||
/// counts and things.
|
||||
const SCEV* CouldNotCompute;
|
||||
SCEVCouldNotCompute CouldNotCompute;
|
||||
|
||||
/// Scalars - This is a cache of the scalars we have analyzed so far.
|
||||
///
|
||||
@ -566,23 +563,10 @@ namespace llvm {
|
||||
void print(std::ostream *OS, const Module* M = 0) const {
|
||||
if (OS) print(*OS, M);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
// Uniquing tables.
|
||||
std::map<ConstantInt*, SCEVConstant*> SCEVConstants;
|
||||
std::map<std::pair<const SCEV*, const Type*>,
|
||||
SCEVTruncateExpr*> SCEVTruncates;
|
||||
std::map<std::pair<const SCEV*, const Type*>,
|
||||
SCEVZeroExtendExpr*> SCEVZeroExtends;
|
||||
std::map<std::pair<unsigned, std::vector<const SCEV*> >,
|
||||
SCEVCommutativeExpr*> SCEVCommExprs;
|
||||
std::map<std::pair<const SCEV*, const SCEV*>,
|
||||
SCEVUDivExpr*> SCEVUDivs;
|
||||
std::map<std::pair<const SCEV*, const Type*>,
|
||||
SCEVSignExtendExpr*> SCEVSignExtends;
|
||||
std::map<std::pair<const Loop *, std::vector<const SCEV*> >,
|
||||
SCEVAddRecExpr*> SCEVAddRecExprs;
|
||||
std::map<Value*, SCEVUnknown*> SCEVUnknowns;
|
||||
FoldingSet<SCEV> UniqueSCEVs;
|
||||
BumpPtrAllocator SCEVAllocator;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,9 @@
|
||||
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
|
||||
#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
|
||||
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||
#include "llvm/Support/IRBuilder.h"
|
||||
#include "llvm/Support/TargetFolder.h"
|
||||
|
||||
namespace llvm {
|
||||
/// SCEVExpander - This class uses information about analyze scalars to
|
||||
@ -32,12 +31,13 @@ namespace llvm {
|
||||
InsertedExpressions;
|
||||
std::set<Value*> InsertedValues;
|
||||
|
||||
BasicBlock::iterator InsertPt;
|
||||
typedef IRBuilder<true, TargetFolder> BuilderType;
|
||||
BuilderType Builder;
|
||||
|
||||
friend struct SCEVVisitor<SCEVExpander, Value*>;
|
||||
public:
|
||||
explicit SCEVExpander(ScalarEvolution &se)
|
||||
: SE(se) {}
|
||||
: SE(se), Builder(TargetFolder(se.TD)) {}
|
||||
|
||||
/// clear - Erase the contents of the InsertedExpressions map so that users
|
||||
/// trying to expand the same expression into multiple BasicBlocks or
|
||||
@ -53,27 +53,21 @@ namespace llvm {
|
||||
/// 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) {
|
||||
InsertPt = IP;
|
||||
Value *expandCodeFor(const SCEV* SH, const Type *Ty, Instruction *IP) {
|
||||
Builder.SetInsertPoint(IP->getParent(), IP);
|
||||
return expandCodeFor(SH, Ty);
|
||||
}
|
||||
|
||||
/// InsertCastOfTo - Insert a cast of V to the specified type, doing what
|
||||
/// we can to share the casts.
|
||||
Value *InsertCastOfTo(Instruction::CastOps opcode, Value *V,
|
||||
const Type *Ty);
|
||||
|
||||
/// InsertNoopCastOfTo - Insert a cast of V to the specified type,
|
||||
/// which must be possible with a noop cast.
|
||||
Value *InsertNoopCastOfTo(Value *V, const Type *Ty);
|
||||
|
||||
private:
|
||||
/// InsertBinop - Insert the specified binary operator, doing a small amount
|
||||
/// of work to avoid inserting an obviously redundant operation.
|
||||
Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS,
|
||||
Value *RHS, BasicBlock::iterator InsertPt);
|
||||
Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS);
|
||||
|
||||
/// InsertNoopCastOfTo - Insert a cast of V to the specified type,
|
||||
/// which must be possible with a noop cast, doing what we can to
|
||||
/// share the casts.
|
||||
Value *InsertNoopCastOfTo(Value *V, const Type *Ty);
|
||||
|
||||
private:
|
||||
/// expandAddToGEP - Expand a SCEVAddExpr with a pointer type into a GEP
|
||||
/// instead of using ptrtoint+arithmetic+inttoptr.
|
||||
Value *expandAddToGEP(const SCEV* const *op_begin,
|
||||
|
@ -39,6 +39,8 @@ namespace llvm {
|
||||
explicit SCEVConstant(ConstantInt *v) :
|
||||
SCEV(scConstant), V(v) {}
|
||||
public:
|
||||
virtual void Profile(FoldingSetNodeID &ID) const;
|
||||
|
||||
ConstantInt *getValue() const { return V; }
|
||||
|
||||
virtual bool isLoopInvariant(const Loop *L) const {
|
||||
@ -81,6 +83,8 @@ namespace llvm {
|
||||
SCEVCastExpr(unsigned SCEVTy, const SCEV* op, const Type *ty);
|
||||
|
||||
public:
|
||||
virtual void Profile(FoldingSetNodeID &ID) const;
|
||||
|
||||
const SCEV* getOperand() const { return Op; }
|
||||
virtual const Type *getType() const { return Ty; }
|
||||
|
||||
@ -200,6 +204,8 @@ namespace llvm {
|
||||
: SCEV(T), Operands(ops.begin(), ops.end()) {}
|
||||
|
||||
public:
|
||||
virtual void Profile(FoldingSetNodeID &ID) const;
|
||||
|
||||
unsigned getNumOperands() const { return (unsigned)Operands.size(); }
|
||||
const SCEV* getOperand(unsigned i) const {
|
||||
assert(i < Operands.size() && "Operand index out of range!");
|
||||
@ -330,6 +336,8 @@ namespace llvm {
|
||||
: SCEV(scUDivExpr), LHS(lhs), RHS(rhs) {}
|
||||
|
||||
public:
|
||||
virtual void Profile(FoldingSetNodeID &ID) const;
|
||||
|
||||
const SCEV* getLHS() const { return LHS; }
|
||||
const SCEV* getRHS() const { return RHS; }
|
||||
|
||||
@ -389,6 +397,8 @@ namespace llvm {
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void Profile(FoldingSetNodeID &ID) const;
|
||||
|
||||
const SCEV* getStart() const { return Operands[0]; }
|
||||
const Loop *getLoop() const { return L; }
|
||||
|
||||
@ -505,6 +515,8 @@ namespace llvm {
|
||||
SCEV(scUnknown), V(v) {}
|
||||
|
||||
public:
|
||||
virtual void Profile(FoldingSetNodeID &ID) const;
|
||||
|
||||
Value *getValue() const { return V; }
|
||||
|
||||
virtual bool isLoopInvariant(const Loop *L) const;
|
||||
|
@ -19,8 +19,9 @@
|
||||
namespace llvm {
|
||||
|
||||
class Module;
|
||||
class ParseError;
|
||||
class SMDiagnostic;
|
||||
class raw_ostream;
|
||||
class LLVMContext;
|
||||
|
||||
/// This function is the main interface to the LLVM Assembly Parser. It parses
|
||||
/// an ASCII file that (presumably) contains LLVM Assembly code. It returns a
|
||||
@ -30,7 +31,8 @@ class raw_ostream;
|
||||
/// @brief Parse LLVM Assembly from a file
|
||||
Module *ParseAssemblyFile(
|
||||
const std::string &Filename, ///< The name of the file to parse
|
||||
ParseError &Error ///< If not null, an object to return errors in.
|
||||
SMDiagnostic &Error, ///< Error result info.
|
||||
LLVMContext &Context ///< Context in which to allocate globals info.
|
||||
);
|
||||
|
||||
/// The function is a secondary interface to the LLVM Assembly Parser. It parses
|
||||
@ -42,60 +44,10 @@ Module *ParseAssemblyFile(
|
||||
Module *ParseAssemblyString(
|
||||
const char *AsmString, ///< The string containing assembly
|
||||
Module *M, ///< A module to add the assembly too.
|
||||
ParseError &Error ///< If not null, an object to return errors in.
|
||||
SMDiagnostic &Error, ///< Error result info.
|
||||
LLVMContext &Context
|
||||
);
|
||||
|
||||
//===------------------------------------------------------------------------===
|
||||
// Helper Classes
|
||||
//===------------------------------------------------------------------------===
|
||||
|
||||
/// An instance of this class can be passed to ParseAssemblyFile or
|
||||
/// ParseAssemblyString functions in order to capture error information from
|
||||
/// the parser. It provides a standard way to print out the error message
|
||||
/// including the file name and line number where the error occurred.
|
||||
/// @brief An LLVM Assembly Parsing Error Object
|
||||
class ParseError {
|
||||
public:
|
||||
ParseError() : Filename("unknown"), Message("none"), LineNo(0), ColumnNo(0) {}
|
||||
ParseError(const ParseError &E);
|
||||
|
||||
void setFilename(const std::string &F) { Filename = F; }
|
||||
|
||||
inline const std::string &getRawMessage() const { // Just the raw message.
|
||||
return Message;
|
||||
}
|
||||
|
||||
inline const std::string &getFilename() const {
|
||||
return Filename;
|
||||
}
|
||||
|
||||
void setError(const std::string &message, int lineNo = -1, int ColNo = -1,
|
||||
const std::string &FileContents = "") {
|
||||
Message = message;
|
||||
LineNo = lineNo; ColumnNo = ColNo;
|
||||
LineContents = FileContents;
|
||||
}
|
||||
|
||||
// getErrorLocation - Return the line and column number of the error in the
|
||||
// input source file. The source filename can be derived from the
|
||||
// ParserOptions in effect. If positional information is not applicable,
|
||||
// these will return a value of -1.
|
||||
//
|
||||
inline void getErrorLocation(int &Line, int &Column) const {
|
||||
Line = LineNo; Column = ColumnNo;
|
||||
}
|
||||
|
||||
void PrintError(const char *ProgName, raw_ostream &S);
|
||||
|
||||
private :
|
||||
std::string Filename;
|
||||
std::string Message;
|
||||
int LineNo, ColumnNo; // -1 if not relevant
|
||||
std::string LineContents;
|
||||
|
||||
void operator=(const ParseError &E); // DO NOT IMPLEMENT
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -32,6 +32,7 @@ class ModuleProvider; // From VMCore
|
||||
class Module; // From VMCore
|
||||
class Archive; // Declared below
|
||||
class ArchiveMemberHeader; // Internal implementation class
|
||||
class LLVMContext; // Global data
|
||||
|
||||
/// This class is the main class manipulated by users of the Archive class. It
|
||||
/// holds information about one member of the Archive. It is also the element
|
||||
@ -278,7 +279,8 @@ class Archive {
|
||||
/// @returns An Archive* that represents the new archive file.
|
||||
/// @brief Create an empty Archive.
|
||||
static Archive* CreateEmpty(
|
||||
const sys::Path& Filename ///< Name of the archive to (eventually) create.
|
||||
const sys::Path& Filename,///< Name of the archive to (eventually) create.
|
||||
LLVMContext& C ///< Context to use for global information
|
||||
);
|
||||
|
||||
/// Open an existing archive and load its contents in preparation for
|
||||
@ -289,6 +291,7 @@ class Archive {
|
||||
/// @brief Open and load an archive file
|
||||
static Archive* OpenAndLoad(
|
||||
const sys::Path& filePath, ///< The file path to open and load
|
||||
LLVMContext& C, ///< The context to use for global information
|
||||
std::string* ErrorMessage ///< An optional error string
|
||||
);
|
||||
|
||||
@ -310,6 +313,7 @@ class Archive {
|
||||
/// @brief Open an existing archive and load its symbols.
|
||||
static Archive* OpenAndLoadSymbols(
|
||||
const sys::Path& Filename, ///< Name of the archive file to open
|
||||
LLVMContext& C, ///< The context to use for global info
|
||||
std::string* ErrorMessage=0 ///< An optional error string
|
||||
);
|
||||
|
||||
@ -449,7 +453,7 @@ class Archive {
|
||||
protected:
|
||||
/// @brief Construct an Archive for \p filename and optionally map it
|
||||
/// into memory.
|
||||
explicit Archive(const sys::Path& filename);
|
||||
explicit Archive(const sys::Path& filename, LLVMContext& C);
|
||||
|
||||
/// @param data The symbol table data to be parsed
|
||||
/// @param len The length of the symbol table data
|
||||
@ -530,6 +534,7 @@ class Archive {
|
||||
unsigned firstFileOffset; ///< Offset to first normal file.
|
||||
ModuleMap modules; ///< The modules loaded via symbol lookup.
|
||||
ArchiveMember* foreignST; ///< This holds the foreign symbol table.
|
||||
LLVMContext& Context; ///< This holds global data.
|
||||
/// @}
|
||||
/// @name Hidden
|
||||
/// @{
|
||||
|
@ -324,7 +324,7 @@ public:
|
||||
|
||||
uint64_t ReadVBR64(unsigned NumBits) {
|
||||
uint64_t Piece = Read(NumBits);
|
||||
if ((Piece & (1U << (NumBits-1))) == 0)
|
||||
if ((Piece & (uint64_t(1) << (NumBits-1))) == 0)
|
||||
return Piece;
|
||||
|
||||
uint64_t Result = 0;
|
||||
@ -332,7 +332,7 @@ public:
|
||||
while (1) {
|
||||
Result |= (Piece & ((1U << (NumBits-1))-1)) << NextBit;
|
||||
|
||||
if ((Piece & (1U << (NumBits-1))) == 0)
|
||||
if ((Piece & (uint64_t(1) << (NumBits-1))) == 0)
|
||||
return Result;
|
||||
|
||||
NextBit += NumBits-1;
|
||||
|
@ -23,6 +23,7 @@ namespace llvm {
|
||||
class MemoryBuffer;
|
||||
class ModulePass;
|
||||
class BitstreamWriter;
|
||||
class LLVMContext;
|
||||
class raw_ostream;
|
||||
|
||||
/// getBitcodeModuleProvider - Read the header of the specified bitcode buffer
|
||||
@ -31,12 +32,14 @@ namespace llvm {
|
||||
/// error, this returns null, *does not* take ownership of Buffer, and fills
|
||||
/// in *ErrMsg with an error description if ErrMsg is non-null.
|
||||
ModuleProvider *getBitcodeModuleProvider(MemoryBuffer *Buffer,
|
||||
LLVMContext& Context,
|
||||
std::string *ErrMsg = 0);
|
||||
|
||||
/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
|
||||
/// If an error occurs, this returns null and fills in *ErrMsg if it is
|
||||
/// non-null. This method *never* takes ownership of Buffer.
|
||||
Module *ParseBitcodeFile(MemoryBuffer *Buffer, std::string *ErrMsg = 0);
|
||||
Module *ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context,
|
||||
std::string *ErrMsg = 0);
|
||||
|
||||
/// WriteBitcodeToFile - Write the specified module to the specified output
|
||||
/// stream.
|
||||
|
@ -65,8 +65,6 @@ namespace llvm {
|
||||
/// DW - If available, this is a pointer to the current dwarf writer.
|
||||
DwarfWriter *DW;
|
||||
|
||||
/// OptLevel - Generating code at a specific optimization level.
|
||||
CodeGenOpt::Level OptLevel;
|
||||
public:
|
||||
/// Output stream on which we're printing assembly code.
|
||||
///
|
||||
@ -120,7 +118,7 @@ namespace llvm {
|
||||
|
||||
protected:
|
||||
explicit AsmPrinter(raw_ostream &o, TargetMachine &TM,
|
||||
const TargetAsmInfo *T, CodeGenOpt::Level OL, bool V);
|
||||
const TargetAsmInfo *T, bool V);
|
||||
|
||||
public:
|
||||
virtual ~AsmPrinter();
|
||||
@ -139,7 +137,8 @@ namespace llvm {
|
||||
///
|
||||
/// This method is used when about to emit executable code.
|
||||
///
|
||||
void SwitchToTextSection(const char *NewSection, const GlobalValue *GV = NULL);
|
||||
void SwitchToTextSection(const char *NewSection,
|
||||
const GlobalValue *GV = NULL);
|
||||
|
||||
/// SwitchToDataSection - Switch to the specified section of the executable
|
||||
/// if we are not already in it! If GV is non-null and if the global has an
|
||||
@ -153,7 +152,8 @@ namespace llvm {
|
||||
/// is the same as the SwitchToTextSection method, but not all assemblers
|
||||
/// are the same.
|
||||
///
|
||||
void SwitchToDataSection(const char *NewSection, const GlobalValue *GV = NULL);
|
||||
void SwitchToDataSection(const char *NewSection,
|
||||
const GlobalValue *GV = NULL);
|
||||
|
||||
/// SwitchToSection - Switch to the specified section of the executable if
|
||||
/// we are not already in it!
|
||||
|
@ -15,6 +15,8 @@
|
||||
#ifndef LLVM_CODEGEN_BINARYOBJECT_H
|
||||
#define LLVM_CODEGEN_BINARYOBJECT_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -390,6 +390,10 @@ namespace llvm {
|
||||
unsigned getNumConflictsWithPhysReg(const LiveInterval &li,
|
||||
unsigned PhysReg) const;
|
||||
|
||||
/// processImplicitDefs - Process IMPLICIT_DEF instructions. Add isUndef
|
||||
/// marker to implicit_def defs and their uses.
|
||||
void processImplicitDefs();
|
||||
|
||||
/// computeNumbering - Compute the index numbering.
|
||||
void computeNumbering();
|
||||
|
||||
|
@ -111,6 +111,9 @@ class MachineFunction : private Annotation {
|
||||
// Tracks debug locations.
|
||||
DebugLocTracker DebugLocInfo;
|
||||
|
||||
// The alignment of the function.
|
||||
unsigned Alignment;
|
||||
|
||||
public:
|
||||
MachineFunction(const Function *Fn, const TargetMachine &TM);
|
||||
~MachineFunction();
|
||||
@ -148,6 +151,14 @@ public:
|
||||
MachineConstantPool *getConstantPool() { return ConstantPool; }
|
||||
const MachineConstantPool *getConstantPool() const { return ConstantPool; }
|
||||
|
||||
/// getAlignment - Return the alignment (log2, not bytes) of the function.
|
||||
///
|
||||
unsigned getAlignment() const { return Alignment; }
|
||||
|
||||
/// setAlignment - Set the alignment (log2, not bytes) of the function.
|
||||
///
|
||||
void setAlignment(unsigned A) { Alignment = A; }
|
||||
|
||||
/// MachineFunctionInfo - Keep track of various per-function pieces of
|
||||
/// information for backends that would like to do so.
|
||||
///
|
||||
@ -345,6 +356,9 @@ public:
|
||||
/// setDefaultDebugLoc - Get the default debug location for the machine
|
||||
/// function.
|
||||
void setDefaultDebugLoc(DebugLoc DL) { DefaultDebugLoc = DL; }
|
||||
|
||||
/// getDebugLocInfo - Get the debug info location tracker.
|
||||
DebugLocTracker &getDebugLocInfo() { return DebugLocInfo; }
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -29,7 +29,8 @@ namespace RegState {
|
||||
Implicit = 0x4,
|
||||
Kill = 0x8,
|
||||
Dead = 0x10,
|
||||
EarlyClobber = 0x20,
|
||||
Undef = 0x20,
|
||||
EarlyClobber = 0x40,
|
||||
ImplicitDefine = Implicit | Define,
|
||||
ImplicitKill = Implicit | Kill
|
||||
};
|
||||
@ -57,8 +58,9 @@ public:
|
||||
flags & RegState::Implicit,
|
||||
flags & RegState::Kill,
|
||||
flags & RegState::Dead,
|
||||
SubReg,
|
||||
flags & RegState::EarlyClobber));
|
||||
flags & RegState::Undef,
|
||||
flags & RegState::EarlyClobber,
|
||||
SubReg));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -105,6 +107,13 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
const MachineInstrBuilder &addMetadata(MDNode *N,
|
||||
int64_t Offset = 0,
|
||||
unsigned char TargetFlags = 0) const {
|
||||
MI->addOperand(MachineOperand::CreateMDNode(N, Offset, TargetFlags));
|
||||
return *this;
|
||||
}
|
||||
|
||||
const MachineInstrBuilder &addExternalSymbol(const char *FnName,
|
||||
int64_t Offset = 0,
|
||||
unsigned char TargetFlags = 0) const {
|
||||
@ -203,6 +212,9 @@ inline unsigned getKillRegState(bool B) {
|
||||
inline unsigned getDeadRegState(bool B) {
|
||||
return B ? RegState::Dead : 0;
|
||||
}
|
||||
inline unsigned getUndefRegState(bool B) {
|
||||
return B ? RegState::Undef : 0;
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
|
@ -70,88 +70,88 @@ inline bool LoopBase<MachineBasicBlock>::isLCSSAForm() const {
|
||||
typedef LoopBase<MachineBasicBlock> MachineLoop;
|
||||
|
||||
class MachineLoopInfo : public MachineFunctionPass {
|
||||
LoopInfoBase<MachineBasicBlock>* LI;
|
||||
LoopInfoBase<MachineBasicBlock> LI;
|
||||
friend class LoopBase<MachineBasicBlock>;
|
||||
|
||||
LoopInfoBase<MachineBasicBlock>& getBase() { return *LI; }
|
||||
|
||||
void operator=(const MachineLoopInfo &); // do not implement
|
||||
MachineLoopInfo(const MachineLoopInfo &); // do not implement
|
||||
|
||||
LoopInfoBase<MachineBasicBlock>& getBase() { return LI; }
|
||||
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
|
||||
MachineLoopInfo() : MachineFunctionPass(&ID) {
|
||||
LI = new LoopInfoBase<MachineBasicBlock>();
|
||||
}
|
||||
|
||||
~MachineLoopInfo() { delete LI; }
|
||||
MachineLoopInfo() : MachineFunctionPass(&ID) {}
|
||||
|
||||
/// iterator/begin/end - The interface to the top-level loops in the current
|
||||
/// function.
|
||||
///
|
||||
typedef std::vector<MachineLoop*>::const_iterator iterator;
|
||||
inline iterator begin() const { return LI->begin(); }
|
||||
inline iterator end() const { return LI->end(); }
|
||||
bool empty() const { return LI->empty(); }
|
||||
typedef LoopInfoBase<MachineBasicBlock>::iterator iterator;
|
||||
inline iterator begin() const { return LI.begin(); }
|
||||
inline iterator end() const { return LI.end(); }
|
||||
bool empty() const { return LI.empty(); }
|
||||
|
||||
/// getLoopFor - Return the inner most loop that BB lives in. If a basic
|
||||
/// block is in no loop (for example the entry node), null is returned.
|
||||
///
|
||||
inline MachineLoop *getLoopFor(const MachineBasicBlock *BB) const {
|
||||
return LI->getLoopFor(BB);
|
||||
return LI.getLoopFor(BB);
|
||||
}
|
||||
|
||||
/// operator[] - same as getLoopFor...
|
||||
///
|
||||
inline const MachineLoop *operator[](const MachineBasicBlock *BB) const {
|
||||
return LI->getLoopFor(BB);
|
||||
return LI.getLoopFor(BB);
|
||||
}
|
||||
|
||||
/// getLoopDepth - Return the loop nesting level of the specified block...
|
||||
///
|
||||
inline unsigned getLoopDepth(const MachineBasicBlock *BB) const {
|
||||
return LI->getLoopDepth(BB);
|
||||
return LI.getLoopDepth(BB);
|
||||
}
|
||||
|
||||
// isLoopHeader - True if the block is a loop header node
|
||||
inline bool isLoopHeader(MachineBasicBlock *BB) const {
|
||||
return LI->isLoopHeader(BB);
|
||||
return LI.isLoopHeader(BB);
|
||||
}
|
||||
|
||||
/// runOnFunction - Calculate the natural loop information.
|
||||
///
|
||||
virtual bool runOnMachineFunction(MachineFunction &F);
|
||||
|
||||
virtual void releaseMemory() { LI->releaseMemory(); }
|
||||
virtual void releaseMemory() { LI.releaseMemory(); }
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
|
||||
/// removeLoop - This removes the specified top-level loop from this loop info
|
||||
/// object. The loop is not deleted, as it will presumably be inserted into
|
||||
/// another loop.
|
||||
inline MachineLoop *removeLoop(iterator I) { return LI->removeLoop(I); }
|
||||
inline MachineLoop *removeLoop(iterator I) { return LI.removeLoop(I); }
|
||||
|
||||
/// changeLoopFor - Change the top-level loop that contains BB to the
|
||||
/// specified loop. This should be used by transformations that restructure
|
||||
/// the loop hierarchy tree.
|
||||
inline void changeLoopFor(MachineBasicBlock *BB, MachineLoop *L) {
|
||||
LI->changeLoopFor(BB, L);
|
||||
LI.changeLoopFor(BB, L);
|
||||
}
|
||||
|
||||
/// changeTopLevelLoop - Replace the specified loop in the top-level loops
|
||||
/// list with the indicated loop.
|
||||
inline void changeTopLevelLoop(MachineLoop *OldLoop, MachineLoop *NewLoop) {
|
||||
LI->changeTopLevelLoop(OldLoop, NewLoop);
|
||||
LI.changeTopLevelLoop(OldLoop, NewLoop);
|
||||
}
|
||||
|
||||
/// addTopLevelLoop - This adds the specified loop to the collection of
|
||||
/// top-level loops.
|
||||
inline void addTopLevelLoop(MachineLoop *New) {
|
||||
LI->addTopLevelLoop(New);
|
||||
LI.addTopLevelLoop(New);
|
||||
}
|
||||
|
||||
/// removeBlock - This method completely removes BB from all data structures,
|
||||
/// including all of the Loop objects it is nested in and our mapping from
|
||||
/// MachineBasicBlocks to loops.
|
||||
void removeBlock(MachineBasicBlock *BB) {
|
||||
LI->removeBlock(BB);
|
||||
LI.removeBlock(BB);
|
||||
}
|
||||
};
|
||||
|
||||
@ -159,7 +159,7 @@ public:
|
||||
// Allow clients to walk the list of nested loops...
|
||||
template <> struct GraphTraits<const MachineLoop*> {
|
||||
typedef const MachineLoop NodeType;
|
||||
typedef std::vector<MachineLoop*>::const_iterator ChildIteratorType;
|
||||
typedef MachineLoopInfo::iterator ChildIteratorType;
|
||||
|
||||
static NodeType *getEntryNode(const MachineLoop *L) { return L; }
|
||||
static inline ChildIteratorType child_begin(NodeType *N) {
|
||||
@ -172,7 +172,7 @@ template <> struct GraphTraits<const MachineLoop*> {
|
||||
|
||||
template <> struct GraphTraits<MachineLoop*> {
|
||||
typedef MachineLoop NodeType;
|
||||
typedef std::vector<MachineLoop*>::const_iterator ChildIteratorType;
|
||||
typedef MachineLoopInfo::iterator ChildIteratorType;
|
||||
|
||||
static NodeType *getEntryNode(MachineLoop *L) { return L; }
|
||||
static inline ChildIteratorType child_begin(NodeType *N) {
|
||||
|
@ -23,6 +23,7 @@ namespace llvm {
|
||||
class ConstantFP;
|
||||
class MachineBasicBlock;
|
||||
class GlobalValue;
|
||||
class MDNode;
|
||||
class MachineInstr;
|
||||
class TargetMachine;
|
||||
class MachineRegisterInfo;
|
||||
@ -41,7 +42,8 @@ public:
|
||||
MO_ConstantPoolIndex, ///< Address of indexed Constant in Constant Pool
|
||||
MO_JumpTableIndex, ///< Address of indexed Jump Table for switch
|
||||
MO_ExternalSymbol, ///< Name of external global symbol
|
||||
MO_GlobalAddress ///< Address of a global value
|
||||
MO_GlobalAddress, ///< Address of a global value
|
||||
MO_Metadata ///< Metadata info
|
||||
};
|
||||
|
||||
private:
|
||||
@ -75,6 +77,10 @@ private:
|
||||
/// This is only valid on definitions of registers.
|
||||
bool IsDead : 1;
|
||||
|
||||
/// IsUndef - True if this is a register def / use of "undef", i.e. register
|
||||
/// defined by an IMPLICIT_DEF. This is only valid on registers.
|
||||
bool IsUndef : 1;
|
||||
|
||||
/// IsEarlyClobber - True if this MO_Register 'def' operand is written to
|
||||
/// by the MachineInstr before all input registers are read. This is used to
|
||||
/// model the GCC inline asm '&' constraint modifier.
|
||||
@ -103,6 +109,7 @@ private:
|
||||
int Index; // For MO_*Index - The index itself.
|
||||
const char *SymbolName; // For MO_ExternalSymbol.
|
||||
GlobalValue *GV; // For MO_GlobalAddress.
|
||||
MDNode *Node; // For MO_Metadata.
|
||||
} Val;
|
||||
int64_t Offset; // An offset from the object.
|
||||
} OffsetedInfo;
|
||||
@ -198,6 +205,11 @@ public:
|
||||
return IsKill;
|
||||
}
|
||||
|
||||
bool isUndef() const {
|
||||
assert(isReg() && "Wrong MachineOperand accessor");
|
||||
return IsUndef;
|
||||
}
|
||||
|
||||
bool isEarlyClobber() const {
|
||||
assert(isReg() && "Wrong MachineOperand accessor");
|
||||
return IsEarlyClobber;
|
||||
@ -248,6 +260,11 @@ public:
|
||||
IsDead = Val;
|
||||
}
|
||||
|
||||
void setIsUndef(bool Val = true) {
|
||||
assert(isReg() && "Wrong MachineOperand accessor");
|
||||
IsUndef = Val;
|
||||
}
|
||||
|
||||
void setIsEarlyClobber(bool Val = true) {
|
||||
assert(isReg() && IsDef && "Wrong MachineOperand accessor");
|
||||
IsEarlyClobber = Val;
|
||||
@ -283,6 +300,10 @@ public:
|
||||
return Contents.OffsetedInfo.Val.GV;
|
||||
}
|
||||
|
||||
MDNode *getMDNode() const {
|
||||
return Contents.OffsetedInfo.Val.Node;
|
||||
}
|
||||
|
||||
int64_t getOffset() const {
|
||||
assert((isGlobal() || isSymbol() || isCPI()) &&
|
||||
"Wrong MachineOperand accessor");
|
||||
@ -337,7 +358,8 @@ public:
|
||||
/// the specified value. If an operand is known to be an register already,
|
||||
/// the setReg method should be used.
|
||||
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
|
||||
bool isKill = false, bool isDead = false);
|
||||
bool isKill = false, bool isDead = false,
|
||||
bool isUndef = false);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Construction methods.
|
||||
@ -357,13 +379,15 @@ public:
|
||||
|
||||
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp = false,
|
||||
bool isKill = false, bool isDead = false,
|
||||
unsigned SubReg = 0,
|
||||
bool isEarlyClobber = false) {
|
||||
bool isUndef = false,
|
||||
bool isEarlyClobber = false,
|
||||
unsigned SubReg = 0) {
|
||||
MachineOperand Op(MachineOperand::MO_Register);
|
||||
Op.IsDef = isDef;
|
||||
Op.IsImp = isImp;
|
||||
Op.IsKill = isKill;
|
||||
Op.IsDead = isDead;
|
||||
Op.IsUndef = isUndef;
|
||||
Op.IsEarlyClobber = isEarlyClobber;
|
||||
Op.Contents.Reg.RegNo = Reg;
|
||||
Op.Contents.Reg.Prev = 0;
|
||||
@ -406,6 +430,14 @@ public:
|
||||
Op.setTargetFlags(TargetFlags);
|
||||
return Op;
|
||||
}
|
||||
static MachineOperand CreateMDNode(MDNode *N, int64_t Offset,
|
||||
unsigned char TargetFlags = 0) {
|
||||
MachineOperand Op(MachineOperand::MO_Metadata);
|
||||
Op.Contents.OffsetedInfo.Val.Node = N;
|
||||
Op.setOffset(Offset);
|
||||
Op.setTargetFlags(TargetFlags);
|
||||
return Op;
|
||||
}
|
||||
static MachineOperand CreateES(const char *SymName, int64_t Offset = 0,
|
||||
unsigned char TargetFlags = 0) {
|
||||
MachineOperand Op(MachineOperand::MO_ExternalSymbol);
|
||||
@ -420,6 +452,7 @@ public:
|
||||
IsImp = MO.IsImp;
|
||||
IsKill = MO.IsKill;
|
||||
IsDead = MO.IsDead;
|
||||
IsUndef = MO.IsUndef;
|
||||
IsEarlyClobber = MO.IsEarlyClobber;
|
||||
SubReg = MO.SubReg;
|
||||
ParentMI = MO.ParentMI;
|
||||
|
@ -69,10 +69,6 @@ class RegScavenger {
|
||||
/// available, unset means the register is currently being used.
|
||||
BitVector RegsAvailable;
|
||||
|
||||
/// ImplicitDefed - If bit is set that means the register is defined by an
|
||||
/// implicit_def instructions. That means it can be clobbered at will.
|
||||
BitVector ImplicitDefed;
|
||||
|
||||
/// CurrDist - Distance from MBB entry to the current instruction MBBI.
|
||||
///
|
||||
unsigned CurrDist;
|
||||
@ -117,25 +113,18 @@ public:
|
||||
bool isUsed(unsigned Reg) const { return !RegsAvailable[Reg]; }
|
||||
bool isUnused(unsigned Reg) const { return RegsAvailable[Reg]; }
|
||||
|
||||
bool isImplicitlyDefined(unsigned Reg) const { return ImplicitDefed[Reg]; }
|
||||
|
||||
/// getRegsUsed - return all registers currently in use in used.
|
||||
void getRegsUsed(BitVector &used, bool includeReserved);
|
||||
|
||||
/// setUsed / setUnused - Mark the state of one or a number of registers.
|
||||
///
|
||||
void setUsed(unsigned Reg, bool ImpDef = false);
|
||||
void setUsed(BitVector &Regs, bool ImpDef = false) {
|
||||
void setUsed(unsigned Reg);
|
||||
void setUsed(BitVector &Regs) {
|
||||
RegsAvailable &= ~Regs;
|
||||
if (ImpDef)
|
||||
ImplicitDefed |= Regs;
|
||||
else
|
||||
ImplicitDefed &= ~Regs;
|
||||
}
|
||||
void setUnused(unsigned Reg, const MachineInstr *MI);
|
||||
void setUnused(BitVector &Regs) {
|
||||
RegsAvailable |= Regs;
|
||||
ImplicitDefed &= ~Regs;
|
||||
}
|
||||
|
||||
/// FindUnusedReg - Find a unused register of the specified register class
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
#include "llvm/ADT/ilist.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/CodeGen/SelectionDAGNodes.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
@ -537,7 +536,8 @@ public:
|
||||
///
|
||||
SDValue getCall(unsigned CallingConv, DebugLoc dl, bool IsVarArgs,
|
||||
bool IsTailCall, bool isInreg, SDVTList VTs,
|
||||
const SDValue *Operands, unsigned NumOperands);
|
||||
const SDValue *Operands, unsigned NumOperands,
|
||||
unsigned NumFixedArgs);
|
||||
|
||||
/// getLoad - Loads are not normal binary operators: their result type is not
|
||||
/// determined by their operands, and they produce a value AND a token chain.
|
||||
|
@ -2257,6 +2257,7 @@ class CallSDNode : public SDNode {
|
||||
unsigned CallingConv;
|
||||
bool IsVarArg;
|
||||
bool IsTailCall;
|
||||
unsigned NumFixedArgs;
|
||||
// We might eventually want a full-blown Attributes for the result; that
|
||||
// will expand the size of the representation. At the moment we only
|
||||
// need Inreg.
|
||||
@ -2264,10 +2265,10 @@ class CallSDNode : public SDNode {
|
||||
friend class SelectionDAG;
|
||||
CallSDNode(unsigned cc, DebugLoc dl, bool isvararg, bool istailcall,
|
||||
bool isinreg, SDVTList VTs, const SDValue *Operands,
|
||||
unsigned numOperands)
|
||||
unsigned numOperands, unsigned numFixedArgs)
|
||||
: SDNode(ISD::CALL, dl, VTs, Operands, numOperands),
|
||||
CallingConv(cc), IsVarArg(isvararg), IsTailCall(istailcall),
|
||||
Inreg(isinreg) {}
|
||||
NumFixedArgs(numFixedArgs), Inreg(isinreg) {}
|
||||
public:
|
||||
unsigned getCallingConv() const { return CallingConv; }
|
||||
unsigned isVarArg() const { return IsVarArg; }
|
||||
@ -2284,6 +2285,12 @@ public:
|
||||
SDValue getCallee() const { return getOperand(1); }
|
||||
|
||||
unsigned getNumArgs() const { return (getNumOperands() - 2) / 2; }
|
||||
unsigned getNumFixedArgs() const {
|
||||
if (isVarArg())
|
||||
return NumFixedArgs;
|
||||
else
|
||||
return getNumArgs();
|
||||
}
|
||||
SDValue getArg(unsigned i) const { return getOperand(2+2*i); }
|
||||
SDValue getArgFlagsVal(unsigned i) const {
|
||||
return getOperand(3+2*i);
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
//===- CodeGen/ValueTypes.h - Low-Level Target independ. types --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
@ -52,29 +51,34 @@ namespace llvm {
|
||||
|
||||
v2i8 = 14, // 2 x i8
|
||||
v4i8 = 15, // 4 x i8
|
||||
v2i16 = 16, // 2 x i16
|
||||
v8i8 = 17, // 8 x i8
|
||||
v4i16 = 18, // 4 x i16
|
||||
v2i32 = 19, // 2 x i32
|
||||
v1i64 = 20, // 1 x i64
|
||||
v16i8 = 21, // 16 x i8
|
||||
v8i16 = 22, // 8 x i16
|
||||
v3i32 = 23, // 3 x i32
|
||||
v4i32 = 24, // 4 x i32
|
||||
v2i64 = 25, // 2 x i64
|
||||
|
||||
v2f32 = 26, // 2 x f32
|
||||
v3f32 = 27, // 3 x f32
|
||||
v4f32 = 28, // 4 x f32
|
||||
v2f64 = 29, // 2 x f64
|
||||
v8i8 = 16, // 8 x i8
|
||||
v16i8 = 17, // 16 x i8
|
||||
v32i8 = 18, // 32 x i8
|
||||
v2i16 = 19, // 2 x i16
|
||||
v4i16 = 20, // 4 x i16
|
||||
v8i16 = 21, // 8 x i16
|
||||
v16i16 = 22, // 16 x i16
|
||||
v2i32 = 23, // 2 x i32
|
||||
v3i32 = 24, // 3 x i32
|
||||
v4i32 = 25, // 4 x i32
|
||||
v8i32 = 26, // 8 x i32
|
||||
v1i64 = 27, // 1 x i64
|
||||
v2i64 = 28, // 2 x i64
|
||||
v4i64 = 29, // 4 x i64
|
||||
|
||||
v2f32 = 30, // 2 x f32
|
||||
v3f32 = 31, // 3 x f32
|
||||
v4f32 = 32, // 4 x f32
|
||||
v8f32 = 33, // 8 x f32
|
||||
v2f64 = 34, // 2 x f64
|
||||
v4f64 = 35, // 4 x f64
|
||||
|
||||
FIRST_VECTOR_VALUETYPE = v2i8,
|
||||
LAST_VECTOR_VALUETYPE = v2f64,
|
||||
LAST_VECTOR_VALUETYPE = v4f64,
|
||||
|
||||
LAST_VALUETYPE = 30, // This always remains at the end of the list.
|
||||
LAST_VALUETYPE = 36, // 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,
|
||||
@ -179,28 +183,34 @@ namespace llvm {
|
||||
if (NumElements == 4) return v4i8;
|
||||
if (NumElements == 8) return v8i8;
|
||||
if (NumElements == 16) return v16i8;
|
||||
if (NumElements == 32) return v32i8;
|
||||
break;
|
||||
case i16:
|
||||
if (NumElements == 2) return v2i16;
|
||||
if (NumElements == 4) return v4i16;
|
||||
if (NumElements == 8) return v8i16;
|
||||
if (NumElements == 16) return v16i16;
|
||||
break;
|
||||
case i32:
|
||||
if (NumElements == 2) return v2i32;
|
||||
if (NumElements == 3) return v3i32;
|
||||
if (NumElements == 4) return v4i32;
|
||||
if (NumElements == 8) return v8i32;
|
||||
break;
|
||||
case i64:
|
||||
if (NumElements == 1) return v1i64;
|
||||
if (NumElements == 2) return v2i64;
|
||||
if (NumElements == 4) return v4i64;
|
||||
break;
|
||||
case f32:
|
||||
if (NumElements == 2) return v2f32;
|
||||
if (NumElements == 3) return v3f32;
|
||||
if (NumElements == 4) return v4f32;
|
||||
if (NumElements == 8) return v8f32;
|
||||
break;
|
||||
case f64:
|
||||
if (NumElements == 2) return v2f64;
|
||||
if (NumElements == 4) return v4f64;
|
||||
break;
|
||||
}
|
||||
return getExtendedVectorVT(VT, NumElements);
|
||||
@ -235,15 +245,15 @@ namespace llvm {
|
||||
/// isFloatingPoint - Return true if this is a FP, or a vector FP type.
|
||||
bool isFloatingPoint() const {
|
||||
return isSimple() ?
|
||||
((V >= f32 && V <= ppcf128) || (V >= v2f32 && V <= v2f64)) :
|
||||
isExtendedFloatingPoint();
|
||||
((V >= f32 && V <= ppcf128) ||
|
||||
(V >= v2f32 && V <= v4f64)) : isExtendedFloatingPoint();
|
||||
}
|
||||
|
||||
/// isInteger - Return true if this is an integer, or a vector integer type.
|
||||
bool isInteger() const {
|
||||
return isSimple() ?
|
||||
((V >= FIRST_INTEGER_VALUETYPE && V <= LAST_INTEGER_VALUETYPE) ||
|
||||
(V >= v2i8 && V <= v2i64)) : isExtendedInteger();
|
||||
(V >= v2i8 && V <= v4i64)) : isExtendedInteger();
|
||||
}
|
||||
|
||||
/// isVector - Return true if this is a vector value type.
|
||||
@ -268,6 +278,13 @@ namespace llvm {
|
||||
isExtended128BitVector();
|
||||
}
|
||||
|
||||
/// is256BitVector - Return true if this is a 256-bit vector type.
|
||||
inline bool is256BitVector() const {
|
||||
return isSimple() ?
|
||||
(V==v8f32 || V==v4f64 || V==v32i8 || V==v16i16 || V==v8i32 ||
|
||||
V==v4i64) : isExtended256BitVector();
|
||||
}
|
||||
|
||||
/// isByteSized - Return true if the bit size is a multiple of 8.
|
||||
bool isByteSized() const {
|
||||
return (getSizeInBits() & 7) == 0;
|
||||
@ -322,19 +339,25 @@ namespace llvm {
|
||||
case v2i8 :
|
||||
case v4i8 :
|
||||
case v8i8 :
|
||||
case v16i8: return i8;
|
||||
case v16i8:
|
||||
case v32i8: return i8;
|
||||
case v2i16:
|
||||
case v4i16:
|
||||
case v8i16: return i16;
|
||||
case v8i16:
|
||||
case v16i16: return i16;
|
||||
case v2i32:
|
||||
case v3i32:
|
||||
case v4i32: return i32;
|
||||
case v4i32:
|
||||
case v8i32: return i32;
|
||||
case v1i64:
|
||||
case v2i64: return i64;
|
||||
case v2i64:
|
||||
case v4i64: return i64;
|
||||
case v2f32:
|
||||
case v3f32:
|
||||
case v4f32: return f32;
|
||||
case v2f64: return f64;
|
||||
case v4f32:
|
||||
case v8f32: return f32;
|
||||
case v2f64:
|
||||
case v4f64: return f64;
|
||||
}
|
||||
}
|
||||
|
||||
@ -345,13 +368,19 @@ namespace llvm {
|
||||
switch (V) {
|
||||
default:
|
||||
return getExtendedVectorNumElements();
|
||||
case v16i8: return 16;
|
||||
case v32i8: return 32;
|
||||
case v16i8:
|
||||
case v16i16: return 16;
|
||||
case v8i8 :
|
||||
case v8i16: return 8;
|
||||
case v8i16:
|
||||
case v8i32:
|
||||
case v8f32: return 8;
|
||||
case v4i8:
|
||||
case v4i16:
|
||||
case v4i32:
|
||||
case v4f32: return 4;
|
||||
case v4i64:
|
||||
case v4f32:
|
||||
case v4f64: return 4;
|
||||
case v3i32:
|
||||
case v3f32: return 3;
|
||||
case v2i8:
|
||||
@ -402,6 +431,12 @@ namespace llvm {
|
||||
case v2i64:
|
||||
case v4f32:
|
||||
case v2f64: return 128;
|
||||
case v32i8:
|
||||
case v16i16:
|
||||
case v8i32:
|
||||
case v4i64:
|
||||
case v8f32:
|
||||
case v4f64: return 256;
|
||||
}
|
||||
}
|
||||
|
||||
@ -478,6 +513,7 @@ namespace llvm {
|
||||
bool isExtendedVector() const;
|
||||
bool isExtended64BitVector() const;
|
||||
bool isExtended128BitVector() const;
|
||||
bool isExtended256BitVector() const;
|
||||
MVT getExtendedVectorElementType() const;
|
||||
unsigned getExtendedVectorNumElements() const;
|
||||
unsigned getExtendedSizeInBits() const;
|
||||
|
@ -33,25 +33,31 @@ def f128 : ValueType<128, 10>; // 128-bit floating point value
|
||||
def ppcf128: ValueType<128, 11>; // PPC 128-bit floating point value
|
||||
def FlagVT : ValueType<0 , 12>; // Condition code or machine flag
|
||||
def isVoid : ValueType<0 , 13>; // Produces no value
|
||||
|
||||
def v2i8 : ValueType<16 , 14>; // 2 x i8 vector value
|
||||
def v4i8 : ValueType<32 , 15>; // 4 x i8 vector value
|
||||
def v2i16 : ValueType<32 , 16>; // 2 x i16 vector value
|
||||
def v8i8 : ValueType<64 , 17>; // 8 x i8 vector value
|
||||
def v4i16 : ValueType<64 , 18>; // 4 x i16 vector value
|
||||
def v2i32 : ValueType<64 , 19>; // 2 x i32 vector value
|
||||
def v1i64 : ValueType<64 , 20>; // 1 x i64 vector value
|
||||
|
||||
def v16i8 : ValueType<128, 21>; // 16 x i8 vector value
|
||||
def v8i16 : ValueType<128, 22>; // 8 x i16 vector value
|
||||
def v3i32 : ValueType<96 , 23>; // 3 x i32 vector value
|
||||
def v4i32 : ValueType<128, 24>; // 4 x i32 vector value
|
||||
def v2i64 : ValueType<128, 25>; // 2 x i64 vector value
|
||||
|
||||
def v2f32 : ValueType<64, 26>; // 2 x f32 vector value
|
||||
def v3f32 : ValueType<96 , 27>; // 3 x f32 vector value
|
||||
def v4f32 : ValueType<128, 28>; // 4 x f32 vector value
|
||||
def v2f64 : ValueType<128, 29>; // 2 x f64 vector value
|
||||
def v8i8 : ValueType<64 , 16>; // 8 x i8 vector value
|
||||
def v16i8 : ValueType<128, 17>; // 16 x i8 vector value
|
||||
def v32i8 : ValueType<256, 18>; // 32 x i8 vector value
|
||||
def v2i16 : ValueType<32 , 19>; // 2 x i16 vector value
|
||||
def v4i16 : ValueType<64 , 20>; // 4 x i16 vector value
|
||||
def v8i16 : ValueType<128, 21>; // 8 x i16 vector value
|
||||
def v16i16 : ValueType<256, 22>; // 16 x i16 vector value
|
||||
def v2i32 : ValueType<64 , 23>; // 2 x i32 vector value
|
||||
def v3i32 : ValueType<96 , 24>; // 3 x i32 vector value
|
||||
def v4i32 : ValueType<128, 25>; // 4 x i32 vector value
|
||||
def v8i32 : ValueType<256, 26>; // 8 x f32 vector value
|
||||
def v1i64 : ValueType<64 , 27>; // 1 x i64 vector value
|
||||
def v2i64 : ValueType<128, 28>; // 2 x i64 vector value
|
||||
def v4i64 : ValueType<256, 29>; // 4 x f64 vector value
|
||||
|
||||
def v2f32 : ValueType<64, 30>; // 2 x f32 vector value
|
||||
def v3f32 : ValueType<96 , 31>; // 3 x f32 vector value
|
||||
def v4f32 : ValueType<128, 32>; // 4 x f32 vector value
|
||||
def v8f32 : ValueType<256, 33>; // 8 x f32 vector value
|
||||
def v2f64 : ValueType<128, 34>; // 2 x f64 vector value
|
||||
def v4f64 : ValueType<256, 35>; // 4 x f64 vector value
|
||||
|
||||
// Pseudo valuetype mapped to the current pointer size to any address space.
|
||||
// Should only be used in TableGen.
|
||||
def iPTRAny : ValueType<0, 252>;
|
||||
|
@ -12,159 +12,22 @@
|
||||
// supported please refer to the tools' manual page or run the tool
|
||||
// with the --help option.
|
||||
//
|
||||
// This file provides the default entry point for the driver executable.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#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"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/PluginLoader.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace cl = llvm::cl;
|
||||
namespace sys = llvm::sys;
|
||||
using namespace llvmc;
|
||||
|
||||
// Built-in command-line options.
|
||||
// External linkage here is intentional.
|
||||
|
||||
cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input file>"),
|
||||
cl::ZeroOrMore);
|
||||
cl::opt<std::string> OutputFilename("o", cl::desc("Output file name"),
|
||||
cl::value_desc("file"), cl::Prefix);
|
||||
cl::list<std::string> Languages("x",
|
||||
cl::desc("Specify the language of the following input files"),
|
||||
cl::ZeroOrMore);
|
||||
cl::opt<bool> DryRun("dry-run",
|
||||
cl::desc("Only pretend to run commands"));
|
||||
cl::opt<bool> VerboseMode("v",
|
||||
cl::desc("Enable verbose mode"));
|
||||
|
||||
cl::opt<bool> CheckGraph("check-graph",
|
||||
cl::desc("Check the compilation graph for errors"),
|
||||
cl::Hidden);
|
||||
cl::opt<bool> WriteGraph("write-graph",
|
||||
cl::desc("Write compilation-graph.dot file"),
|
||||
cl::Hidden);
|
||||
cl::opt<bool> ViewGraph("view-graph",
|
||||
cl::desc("Show compilation graph in GhostView"),
|
||||
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 = getTempDir();
|
||||
|
||||
try {
|
||||
ret = graph.Build(tempDir, langMap);
|
||||
}
|
||||
catch(...) {
|
||||
if (SaveTemps == SaveTempsEnum::Unset)
|
||||
tempDir.eraseFromDisk(true);
|
||||
throw;
|
||||
}
|
||||
|
||||
if (SaveTemps == SaveTempsEnum::Unset)
|
||||
tempDir.eraseFromDisk(true);
|
||||
return ret;
|
||||
}
|
||||
namespace llvmc {
|
||||
int Main(int argc, char** argv);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
try {
|
||||
ForceLinkage();
|
||||
|
||||
LanguageMap langMap;
|
||||
CompilationGraph graph;
|
||||
|
||||
cl::ParseCommandLineOptions
|
||||
(argc, argv, "LLVM Compiler Driver (Work In Progress)", true);
|
||||
|
||||
PluginLoader Plugins;
|
||||
Plugins.PopulateLanguageMap(langMap);
|
||||
Plugins.PopulateCompilationGraph(graph);
|
||||
|
||||
if (CheckGraph) {
|
||||
int ret = graph.Check();
|
||||
if (!ret)
|
||||
std::cerr << "check-graph: no errors found.\n";
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ViewGraph) {
|
||||
graph.viewGraph();
|
||||
if (!WriteGraph)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (WriteGraph) {
|
||||
graph.writeGraph(OutputFilename.empty()
|
||||
? std::string("compilation-graph.dot")
|
||||
: OutputFilename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (InputFilenames.empty()) {
|
||||
throw std::runtime_error("no input files");
|
||||
}
|
||||
|
||||
return BuildTargets(graph, langMap);
|
||||
}
|
||||
catch(llvmc::error_code& ec) {
|
||||
return ec.code();
|
||||
}
|
||||
catch(const std::exception& ex) {
|
||||
std::cerr << argv[0] << ": " << ex.what() << '\n';
|
||||
}
|
||||
catch(...) {
|
||||
std::cerr << argv[0] << ": unknown error!\n";
|
||||
}
|
||||
return 1;
|
||||
llvmc::ForceLinkage();
|
||||
return llvmc::Main(argc, argv);
|
||||
}
|
||||
|
||||
#endif // LLVM_INCLUDE_COMPILER_DRIVER_MAIN_INC
|
||||
|
@ -364,10 +364,13 @@
|
||||
#undef HAVE_STRDUP
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#undef HAVE_STRERROR
|
||||
#cmakedefine HAVE_STRERROR
|
||||
|
||||
/* Define to 1 if you have the `strerror_r' function. */
|
||||
#undef HAVE_STRERROR_R
|
||||
#cmakedefine HAVE_STRERROR_R
|
||||
|
||||
/* Define to 1 if you have the `strerror_s' function. */
|
||||
#cmakedefine HAVE_STRERROR_S
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
@ -369,6 +369,9 @@
|
||||
/* Define to 1 if you have the `strerror_r' function. */
|
||||
#undef HAVE_STRERROR_R
|
||||
|
||||
/* Define to 1 if you have the `strerror_s' function. */
|
||||
#undef HAVE_STRERROR_S
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
namespace llvm {
|
||||
class Module;
|
||||
class InferiorProcess;
|
||||
class LLVMContext;
|
||||
|
||||
/// Debugger class - This class implements the LLVM source-level debugger.
|
||||
/// This allows clients to handle the user IO processing without having to
|
||||
@ -95,7 +96,7 @@ namespace llvm {
|
||||
/// the PATH for the specified program, loading it when found. If the
|
||||
/// specified program cannot be found, an exception is thrown to indicate
|
||||
/// the error.
|
||||
void loadProgram(const std::string &Path);
|
||||
void loadProgram(const std::string &Path, LLVMContext& Context);
|
||||
|
||||
/// unloadProgram - If a program is running, kill it, then unload all traces
|
||||
/// of the current program. If no program is loaded, this method silently
|
||||
|
@ -159,6 +159,15 @@ public:
|
||||
bool isVarArg ///< Whether this is a variable argument length function
|
||||
);
|
||||
|
||||
/// FunctionType::get - Create a FunctionType taking no parameters.
|
||||
///
|
||||
static FunctionType *get(
|
||||
const Type *Result, ///< The result type
|
||||
bool isVarArg ///< Whether this is a variable argument length function
|
||||
) {
|
||||
return get(Result, std::vector<const Type *>(), isVarArg);
|
||||
}
|
||||
|
||||
/// isValidReturnType - Return true if the specified type is valid as a return
|
||||
/// type.
|
||||
static bool isValidReturnType(const Type *RetTy);
|
||||
@ -234,6 +243,12 @@ public:
|
||||
static StructType *get(const std::vector<const Type*> &Params,
|
||||
bool isPacked=false);
|
||||
|
||||
/// StructType::get - Create an empty structure type.
|
||||
///
|
||||
static StructType *get(bool isPacked=false) {
|
||||
return get(std::vector<const Type*>(), isPacked);
|
||||
}
|
||||
|
||||
/// StructType::get - This static method is a convenience method for
|
||||
/// creating structure types by specifying the elements as arguments.
|
||||
/// Note that this method always returns a non-packed struct. To get
|
||||
|
@ -27,6 +27,7 @@
|
||||
namespace llvm {
|
||||
|
||||
class FunctionType;
|
||||
class LLVMContext;
|
||||
|
||||
// Traits for intrusive list of basic blocks...
|
||||
template<> struct ilist_traits<BasicBlock>
|
||||
@ -126,6 +127,10 @@ public:
|
||||
const Type *getReturnType() const; // Return the type of the ret val
|
||||
const FunctionType *getFunctionType() const; // Return the FunctionType for me
|
||||
|
||||
/// getContext - Return a pointer to the LLVMContext associated with this
|
||||
/// function, or NULL if this function is not bound to a context yet.
|
||||
LLVMContext* getContext();
|
||||
|
||||
/// isVarArg - Return true if this function takes a variable number of
|
||||
/// arguments.
|
||||
bool isVarArg() const;
|
||||
|
@ -110,22 +110,32 @@ def llvm_anyptr_ty : LLVMAnyPointerType<llvm_i8_ty>; // (space)i8*
|
||||
def llvm_empty_ty : LLVMType<OtherVT>; // { }
|
||||
def llvm_descriptor_ty : LLVMPointerType<llvm_empty_ty>; // { }*
|
||||
|
||||
def llvm_v16i8_ty : LLVMType<v16i8>; // 16 x i8
|
||||
def llvm_v8i16_ty : LLVMType<v8i16>; // 8 x i16
|
||||
def llvm_v2i64_ty : LLVMType<v2i64>; // 2 x i64
|
||||
def llvm_v2i32_ty : LLVMType<v2i32>; // 2 x i32
|
||||
def llvm_v1i64_ty : LLVMType<v1i64>; // 1 x i64
|
||||
def llvm_v4i32_ty : LLVMType<v4i32>; // 4 x i32
|
||||
def llvm_v2f32_ty : LLVMType<v2f32>; // 2 x float
|
||||
def llvm_v4f32_ty : LLVMType<v4f32>; // 4 x float
|
||||
def llvm_v2f64_ty : LLVMType<v2f64>; // 2 x double
|
||||
|
||||
// MMX Vector Types
|
||||
def llvm_v2i8_ty : LLVMType<v2i8>; // 2 x i8
|
||||
def llvm_v4i8_ty : LLVMType<v4i8>; // 4 x i8
|
||||
def llvm_v8i8_ty : LLVMType<v8i8>; // 8 x i8
|
||||
def llvm_v16i8_ty : LLVMType<v16i8>; // 16 x i8
|
||||
def llvm_v32i8_ty : LLVMType<v32i8>; // 32 x i8
|
||||
def llvm_v2i16_ty : LLVMType<v2i16>; // 4 x i16
|
||||
def llvm_v4i16_ty : LLVMType<v4i16>; // 4 x i16
|
||||
def llvm_v8i16_ty : LLVMType<v8i16>; // 8 x i16
|
||||
def llvm_v16i16_ty : LLVMType<v16i16>; // 16 x i16
|
||||
def llvm_v2i32_ty : LLVMType<v2i32>; // 2 x i32
|
||||
def llvm_v4i32_ty : LLVMType<v4i32>; // 4 x i32
|
||||
def llvm_v8i32_ty : LLVMType<v8i32>; // 8 x i32
|
||||
def llvm_v1i64_ty : LLVMType<v1i64>; // 1 x i64
|
||||
def llvm_v2i64_ty : LLVMType<v2i64>; // 2 x i64
|
||||
def llvm_v4i64_ty : LLVMType<v4i64>; // 4 x i64
|
||||
|
||||
def llvm_v2f32_ty : LLVMType<v2f32>; // 2 x float
|
||||
def llvm_v3f32_ty : LLVMType<v3f32>; // 3 x float
|
||||
def llvm_v4f32_ty : LLVMType<v4f32>; // 4 x float
|
||||
def llvm_v8f32_ty : LLVMType<v8f32>; // 8 x float
|
||||
def llvm_v2f64_ty : LLVMType<v2f64>; // 2 x double
|
||||
def llvm_v4f64_ty : LLVMType<v4f64>; // 4 x double
|
||||
|
||||
def llvm_vararg_ty : LLVMType<isVoid>; // this means vararg here
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Intrinsic Definitions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
225
include/llvm/LLVMContext.h
Normal file
225
include/llvm/LLVMContext.h
Normal file
@ -0,0 +1,225 @@
|
||||
//===-- llvm/LLVMContext.h - Class for managing "global" state --*- 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 LLVMContext, a container of "global" state in LLVM, such
|
||||
// as the global type and constant uniquing tables.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LLVMCONTEXT_H
|
||||
#define LLVM_LLVMCONTEXT_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class LLVMContextImpl;
|
||||
class Constant;
|
||||
class ConstantInt;
|
||||
class ConstantPointerNull;
|
||||
class ConstantStruct;
|
||||
class ConstantAggregateZero;
|
||||
class ConstantArray;
|
||||
class ConstantFP;
|
||||
class ConstantVector;
|
||||
class UndefValue;
|
||||
class MDNode;
|
||||
class MDString;
|
||||
class IntegerType;
|
||||
class PointerType;
|
||||
class StructType;
|
||||
class ArrayType;
|
||||
class VectorType;
|
||||
class OpaqueType;
|
||||
class FunctionType;
|
||||
class Type;
|
||||
class APInt;
|
||||
class APFloat;
|
||||
class Value;
|
||||
|
||||
/// This is an important class for using LLVM in a threaded context. It
|
||||
/// (opaquely) owns and manages the core "global" data of LLVM's core
|
||||
/// infrastructure, including the type and constant uniquing tables.
|
||||
/// LLVMContext itself provides no locking guarantees, so you should be careful
|
||||
/// to have one context per thread.
|
||||
class LLVMContext {
|
||||
LLVMContextImpl* pImpl;
|
||||
public:
|
||||
LLVMContext();
|
||||
~LLVMContext();
|
||||
|
||||
// Constant accessors
|
||||
Constant* getNullValue(const Type* Ty);
|
||||
Constant* getAllOnesValue(const Type* Ty);
|
||||
|
||||
// UndefValue accessors
|
||||
UndefValue* getUndef(const Type* Ty);
|
||||
|
||||
// ConstantInt accessors
|
||||
ConstantInt* getConstantIntTrue();
|
||||
ConstantInt* getConstantIntFalse();
|
||||
Constant* getConstantInt(const Type* Ty, uint64_t V,
|
||||
bool isSigned = false);
|
||||
ConstantInt* getConstantInt(const IntegerType* Ty, uint64_t V,
|
||||
bool isSigned = false);
|
||||
ConstantInt* getConstantIntSigned(const IntegerType* Ty, int64_t V);
|
||||
ConstantInt* getConstantInt(const APInt& V);
|
||||
Constant* getConstantInt(const Type* Ty, const APInt& V);
|
||||
ConstantInt* getConstantIntAllOnesValue(const Type* Ty);
|
||||
|
||||
// ConstantPointerNull accessors
|
||||
ConstantPointerNull* getConstantPointerNull(const PointerType* T);
|
||||
|
||||
// ConstantStruct accessors
|
||||
Constant* getConstantStruct(const StructType* T,
|
||||
const std::vector<Constant*>& V);
|
||||
Constant* getConstantStruct(const std::vector<Constant*>& V,
|
||||
bool Packed = false);
|
||||
Constant* getConstantStruct(Constant* const *Vals, unsigned NumVals,
|
||||
bool Packed = false);
|
||||
|
||||
// ConstantAggregateZero accessors
|
||||
ConstantAggregateZero* getConstantAggregateZero(const Type* Ty);
|
||||
|
||||
// ConstantArray accessors
|
||||
Constant* getConstantArray(const ArrayType* T,
|
||||
const std::vector<Constant*>& V);
|
||||
Constant* getConstantArray(const ArrayType* T, Constant* const* Vals,
|
||||
unsigned NumVals);
|
||||
Constant* getConstantArray(const std::string& Initializer,
|
||||
bool AddNull = false);
|
||||
|
||||
// ConstantExpr accessors
|
||||
Constant* getConstantExpr(unsigned Opcode, Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprTrunc(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprSExt(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprZExt(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprFPTrunc(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprFPExtend(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprUIToFP(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprSIToFP(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprFPToUI(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprFPToSI(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprPtrToInt(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprIntToPtr(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprBitCast(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprCast(unsigned ops, Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprZExtOrBitCast(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprSExtOrBitCast(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprTruncOrBitCast(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprPointerCast(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprIntegerCast(Constant* C, const Type* Ty,
|
||||
bool isSigned);
|
||||
Constant* getConstantExprFPCast(Constant* C, const Type* Ty);
|
||||
Constant* getConstantExprSelect(Constant* C, Constant* V1, Constant* V2);
|
||||
Constant* getConstantExprAlignOf(const Type* Ty);
|
||||
Constant* getConstantExprCompare(unsigned short pred,
|
||||
Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprNeg(Constant* C);
|
||||
Constant* getConstantExprFNeg(Constant* C);
|
||||
Constant* getConstantExprNot(Constant* C);
|
||||
Constant* getConstantExprAdd(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprFAdd(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprSub(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprFSub(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprMul(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprFMul(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprUDiv(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprSDiv(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprFDiv(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprURem(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprSRem(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprFRem(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprAnd(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprOr(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprXor(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprICmp(unsigned short pred, Constant* LHS,
|
||||
Constant* RHS);
|
||||
Constant* getConstantExprFCmp(unsigned short pred, Constant* LHS,
|
||||
Constant* RHS);
|
||||
Constant* getConstantExprVICmp(unsigned short pred, Constant* LHS,
|
||||
Constant* RHS);
|
||||
Constant* getConstantExprVFCmp(unsigned short pred, Constant* LHS,
|
||||
Constant* RHS);
|
||||
Constant* getConstantExprShl(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprLShr(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprAShr(Constant* C1, Constant* C2);
|
||||
Constant* getConstantExprGetElementPtr(Constant* C, Constant* const* IdxList,
|
||||
unsigned NumIdx);
|
||||
Constant* getConstantExprGetElementPtr(Constant* C, Value* const* IdxList,
|
||||
unsigned NumIdx);
|
||||
Constant* getConstantExprExtractElement(Constant* Vec, Constant* Idx);
|
||||
Constant* getConstantExprInsertElement(Constant* Vec, Constant* Elt,
|
||||
Constant* Idx);
|
||||
Constant* getConstantExprShuffleVector(Constant* V1, Constant* V2,
|
||||
Constant* Mask);
|
||||
Constant* getConstantExprExtractValue(Constant* Agg, const unsigned* IdxList,
|
||||
unsigned NumIdx);
|
||||
Constant* getConstantExprInsertValue(Constant* Agg, Constant* Val,
|
||||
const unsigned* IdxList,
|
||||
unsigned NumIdx);
|
||||
Constant* getZeroValueForNegation(const Type* Ty);
|
||||
|
||||
// ConstantFP accessors
|
||||
ConstantFP* getConstantFP(const APFloat& V);
|
||||
Constant* getConstantFP(const Type* Ty, double V);
|
||||
ConstantFP* getConstantFPNegativeZero(const Type* Ty);
|
||||
|
||||
// ConstantVector accessors
|
||||
Constant* getConstantVector(const VectorType* T,
|
||||
const std::vector<Constant*>& V);
|
||||
Constant* getConstantVector(const std::vector<Constant*>& V);
|
||||
Constant* getConstantVector(Constant* const* Vals, unsigned NumVals);
|
||||
ConstantVector* getConstantVectorAllOnesValue(const VectorType* Ty);
|
||||
|
||||
// MDNode accessors
|
||||
MDNode* getMDNode(Value* const* Vals, unsigned NumVals);
|
||||
|
||||
// MDString accessors
|
||||
MDString* getMDString(const char *StrBegin, const char *StrEnd);
|
||||
MDString* getMDString(const std::string &Str);
|
||||
|
||||
// FunctionType accessors
|
||||
FunctionType* getFunctionType(const Type* Result,
|
||||
const std::vector<const Type*>& Params,
|
||||
bool isVarArg);
|
||||
|
||||
// IntegerType accessors
|
||||
const IntegerType* getIntegerType(unsigned NumBits);
|
||||
|
||||
// OpaqueType accessors
|
||||
OpaqueType* getOpaqueType();
|
||||
|
||||
// StructType accessors
|
||||
StructType* getStructType(bool isPacked=false);
|
||||
StructType* getStructType(const std::vector<const Type*>& Params,
|
||||
bool isPacked = false);
|
||||
|
||||
// ArrayType accessors
|
||||
ArrayType* getArrayType(const Type* ElementType, uint64_t NumElements);
|
||||
|
||||
// PointerType accessors
|
||||
PointerType* getPointerType(const Type* ElementType, unsigned AddressSpace);
|
||||
PointerType* getPointerTypeUnqual(const Type* ElementType);
|
||||
|
||||
// VectorType accessors
|
||||
VectorType* getVectorType(const Type* ElementType, unsigned NumElements);
|
||||
VectorType* getVectorTypeInteger(const VectorType* VTy);
|
||||
VectorType* getVectorTypeExtendedElement(const VectorType* VTy);
|
||||
VectorType* getVectorTypeTruncatedElement(const VectorType* VTy);
|
||||
};
|
||||
|
||||
/// FOR BACKWARDS COMPATIBILITY - Returns a global context.
|
||||
extern LLVMContext& getGlobalContext();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -129,6 +129,7 @@ namespace {
|
||||
(void) llvm::createPrintFunctionPass("", 0);
|
||||
(void) llvm::createDbgInfoPrinterPass();
|
||||
(void) llvm::createPartialInliningPass();
|
||||
(void) llvm::createSSIPass();
|
||||
|
||||
(void)new llvm::IntervalPartition();
|
||||
(void)new llvm::FindUsedTypes();
|
||||
|
@ -16,6 +16,7 @@
|
||||
#ifndef LLVM_LINKALLVMCORE_H
|
||||
#define LLVM_LINKALLVMCORE_H
|
||||
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/IntrinsicInst.h"
|
||||
@ -44,7 +45,7 @@ namespace {
|
||||
// to know that getenv() never returns -1, this will do the job.
|
||||
if (std::getenv("bar") != (char*) -1)
|
||||
return;
|
||||
llvm::Module* M = new llvm::Module("");
|
||||
llvm::Module* M = new llvm::Module("", llvm::getGlobalContext());
|
||||
(void)new llvm::UnreachableInst();
|
||||
(void) llvm::createVerifierPass();
|
||||
(void) new llvm::Mangler(*M,"");
|
||||
|
@ -21,6 +21,7 @@
|
||||
namespace llvm {
|
||||
|
||||
class Module;
|
||||
class LLVMContext;
|
||||
|
||||
/// This class provides the core functionality of linking in LLVM. It retains a
|
||||
/// Module object which is the composite of the modules and libraries linked
|
||||
@ -66,6 +67,7 @@ class Linker {
|
||||
Linker(
|
||||
const std::string& progname, ///< name of tool running linker
|
||||
const std::string& modulename, ///< name of linker's end-result module
|
||||
LLVMContext& C, ///< Context for global info
|
||||
unsigned Flags = 0 ///< ControlFlags (one or more |'d together)
|
||||
);
|
||||
|
||||
@ -283,6 +285,7 @@ class Linker {
|
||||
/// @name Data
|
||||
/// @{
|
||||
private:
|
||||
LLVMContext& Context; ///< The context for global information
|
||||
Module* Composite; ///< The composite module linked together
|
||||
std::vector<sys::Path> LibPaths; ///< The library search paths
|
||||
unsigned Flags; ///< Flags to control optional behavior.
|
||||
|
@ -31,6 +31,8 @@ namespace llvm {
|
||||
StringMap<MCSymbol*> Symbols;
|
||||
|
||||
/// SymbolValues - Bindings of symbols to values.
|
||||
//
|
||||
// FIXME: Is there a good reason to not just put this in the MCSymbol?
|
||||
DenseMap<MCSymbol*, MCValue> SymbolValues;
|
||||
|
||||
/// Allocator - Allocator object used for creating machine code objects.
|
||||
|
@ -31,7 +31,7 @@ class MCOperand {
|
||||
kRegister, ///< Register operand.
|
||||
kImmediate, ///< Immediate operand.
|
||||
kMBBLabel, ///< Basic block label.
|
||||
kMCValue
|
||||
kMCValue ///< Relocatable immediate operand.
|
||||
};
|
||||
unsigned char Kind;
|
||||
|
||||
@ -49,9 +49,11 @@ public:
|
||||
MCOperand() : Kind(kInvalid) {}
|
||||
MCOperand(const MCOperand &RHS) { *this = RHS; }
|
||||
|
||||
bool isValid() const { return Kind != kInvalid; }
|
||||
bool isReg() const { return Kind == kRegister; }
|
||||
bool isImm() const { return Kind == kImmediate; }
|
||||
bool isMBBLabel() const { return Kind == kMBBLabel; }
|
||||
bool isMCValue() const { return Kind == kMCValue; }
|
||||
|
||||
/// getReg - Returns the register number.
|
||||
unsigned getReg() const {
|
||||
@ -82,6 +84,15 @@ public:
|
||||
assert(isMBBLabel() && "Wrong accessor");
|
||||
return MBBLabel.BlockNo;
|
||||
}
|
||||
|
||||
const MCValue &getMCValue() const {
|
||||
assert(isMCValue() && "This is not an MCValue");
|
||||
return MCValueVal;
|
||||
}
|
||||
void setMCValue(const MCValue &Val) {
|
||||
assert(isMCValue() && "This is not an MCValue");
|
||||
MCValueVal = Val;
|
||||
}
|
||||
|
||||
void MakeReg(unsigned Reg) {
|
||||
Kind = kRegister;
|
||||
@ -96,6 +107,10 @@ public:
|
||||
MBBLabel.FunctionNo = Fn;
|
||||
MBBLabel.BlockNo = MBB;
|
||||
}
|
||||
void MakeMCValue(const MCValue &Val) {
|
||||
Kind = kMCValue;
|
||||
MCValueVal = Val;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -119,7 +134,6 @@ public:
|
||||
void addOperand(const MCOperand &Op) {
|
||||
Operands.push_back(Op);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -6,6 +6,10 @@
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the MCSection class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_MC_MCSECTION_H
|
||||
#define LLVM_MC_MCSECTION_H
|
||||
@ -14,11 +18,18 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// MCSection - Instances of this class represent a uniqued identifier for a
|
||||
/// section in the current translation unit. The MCContext class uniques and
|
||||
/// creates these.
|
||||
class MCSection {
|
||||
std::string Name;
|
||||
|
||||
public:
|
||||
private:
|
||||
friend class MCContext;
|
||||
MCSection(const char *_Name) : Name(_Name) {}
|
||||
|
||||
MCSection(const MCSection&); // DO NOT IMPLEMENT
|
||||
void operator=(const MCSection&); // DO NOT IMPLEMENT
|
||||
public:
|
||||
|
||||
const std::string &getName() const { return Name; }
|
||||
};
|
||||
|
@ -6,6 +6,10 @@
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the MCStreamer class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_MC_MCSTREAMER_H
|
||||
#define LLVM_MC_MCSTREAMER_H
|
||||
@ -20,7 +24,15 @@ namespace llvm {
|
||||
class MCSymbol;
|
||||
class raw_ostream;
|
||||
|
||||
/// MCStreamer - Streaming machine code generation interface.
|
||||
/// MCStreamer - Streaming machine code generation interface. This interface
|
||||
/// is intended to provide a programatic interface that is very similar to the
|
||||
/// level that an assembler .s file provides. It has callbacks to emit bytes,
|
||||
/// "emit directives", etc. The implementation of this interface retains
|
||||
/// state to know what the current section is etc.
|
||||
///
|
||||
/// There are multiple implementations of this interface: one for writing out
|
||||
/// a .s file, and implementations that write out .o files of various formats.
|
||||
///
|
||||
class MCStreamer {
|
||||
public:
|
||||
enum SymbolAttr {
|
||||
@ -135,7 +147,7 @@ namespace llvm {
|
||||
/// This used to implement the .align assembler directive.
|
||||
///
|
||||
/// @param ByteAlignment - The alignment to reach. This must be a power of
|
||||
/// two.
|
||||
/// two on some targets.
|
||||
/// @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.
|
||||
|
@ -6,6 +6,10 @@
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the declaration of the MCSymbol class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_MC_MCSYMBOL_H
|
||||
#define LLVM_MC_MCSYMBOL_H
|
||||
@ -13,18 +17,48 @@
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
class MCSection;
|
||||
class MCContext;
|
||||
|
||||
/// MCSymbol - Instances of this class represent a symbol name in the MC file,
|
||||
/// and MCSymbols are created and unique'd by the MCContext class.
|
||||
///
|
||||
/// If the symbol is defined/emitted into the current translation unit, the
|
||||
/// Section member is set to indicate what section it lives in. Otherwise, if
|
||||
/// it is a reference to an external entity, it has a null section.
|
||||
///
|
||||
class MCSymbol {
|
||||
MCSection *Section;
|
||||
/// Name - The name of the symbol.
|
||||
std::string Name;
|
||||
/// Section - The section the symbol is defined in, or null if the symbol
|
||||
/// has not been defined in the associated translation unit.
|
||||
MCSection *Section;
|
||||
|
||||
/// IsTemporary - True if this is an assembler temporary label, which
|
||||
/// typically does not survive in the .o file's symbol table. Usually
|
||||
/// "Lfoo" or ".foo".
|
||||
unsigned IsTemporary : 1;
|
||||
|
||||
/// IsExternal - True if this symbol has been implicitly defined as an
|
||||
/// external, for example by using it in an expression without ever emitting
|
||||
/// it as a label. The @var Section for an external symbol is always null.
|
||||
unsigned IsExternal : 1;
|
||||
|
||||
public:
|
||||
private: // MCContext creates and uniques these.
|
||||
friend class MCContext;
|
||||
MCSymbol(const char *_Name, bool _IsTemporary)
|
||||
: Section(0), Name(_Name), IsTemporary(_IsTemporary) {}
|
||||
|
||||
: Name(_Name), Section(0), IsTemporary(_IsTemporary), IsExternal(false) {}
|
||||
|
||||
MCSymbol(const MCSymbol&); // DO NOT IMPLEMENT
|
||||
void operator=(const MCSymbol&); // DO NOT IMPLEMENT
|
||||
public:
|
||||
|
||||
MCSection *getSection() const { return Section; }
|
||||
void setSection(MCSection *Value) { Section = Value; }
|
||||
|
||||
bool isExternal() const { return IsExternal; }
|
||||
void setExternal(bool Value) { IsExternal = Value; }
|
||||
|
||||
const std::string &getName() const { return Name; }
|
||||
};
|
||||
|
||||
|
@ -15,6 +15,8 @@
|
||||
#define LLVM_MC_MCVALUE_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
class MCSymbol;
|
||||
@ -23,6 +25,10 @@ class MCSymbol;
|
||||
/// form, this can hold "SymbolA - SymbolB + imm64". Not all targets supports
|
||||
/// relocations of this general form, but we need to represent this anyway.
|
||||
///
|
||||
/// In the general form, SymbolB can only be defined if SymbolA is, and both
|
||||
/// must be in the same (non-external) section. The latter constraint is not
|
||||
/// enforced, since a symbol's section may not be known at construction.
|
||||
///
|
||||
/// Note that this class must remain a simple POD value class, because we need
|
||||
/// it to live in unions etc.
|
||||
class MCValue {
|
||||
@ -30,13 +36,25 @@ class MCValue {
|
||||
int64_t Cst;
|
||||
public:
|
||||
|
||||
int64_t getCst() const { return Cst; }
|
||||
int64_t getConstant() const { return Cst; }
|
||||
MCSymbol *getSymA() const { return SymA; }
|
||||
MCSymbol *getSymB() const { return SymB; }
|
||||
|
||||
|
||||
|
||||
/// isAbsolute - Is this an absolute (as opposed to relocatable) value.
|
||||
bool isAbsolute() const { return !SymA && !SymB; }
|
||||
|
||||
/// getAssociatedSection - For relocatable values, return the section the
|
||||
/// value is associated with.
|
||||
///
|
||||
/// @result - The value's associated section, or null for external or constant
|
||||
/// values.
|
||||
MCSection *getAssociatedSection() const {
|
||||
return SymA ? SymA->getSection() : 0;
|
||||
}
|
||||
|
||||
static MCValue get(MCSymbol *SymA, MCSymbol *SymB = 0, int64_t Val = 0) {
|
||||
MCValue R;
|
||||
assert((!SymB || SymA) && "Invalid relocatable MCValue!");
|
||||
R.Cst = Val;
|
||||
R.SymA = SymA;
|
||||
R.SymB = SymB;
|
||||
|
@ -25,6 +25,7 @@ namespace llvm {
|
||||
|
||||
class GlobalValueRefMap; // Used by ConstantVals.cpp
|
||||
class FunctionType;
|
||||
class LLVMContext;
|
||||
|
||||
template<> struct ilist_traits<Function>
|
||||
: public SymbolTableListTraits<Function, Module> {
|
||||
@ -109,6 +110,8 @@ public:
|
||||
/// @name Member Variables
|
||||
/// @{
|
||||
private:
|
||||
LLVMContext& Context; ///< The LLVMContext from which types and
|
||||
///< constants are allocated.
|
||||
GlobalListType GlobalList; ///< The Global Variables in the module
|
||||
FunctionListType FunctionList; ///< The Functions in the module
|
||||
AliasListType AliasList; ///< The Aliases in the module
|
||||
@ -128,7 +131,7 @@ private:
|
||||
public:
|
||||
/// The Module constructor. Note that there is no default constructor. You
|
||||
/// must provide a name for the module upon construction.
|
||||
explicit Module(const std::string &ModuleID);
|
||||
explicit Module(const std::string &ModuleID, LLVMContext& C);
|
||||
/// The module destructor. This will dropAllReferences.
|
||||
~Module();
|
||||
|
||||
@ -157,6 +160,10 @@ public:
|
||||
/// @returns PointerSize - an enumeration for the size of the target's pointer
|
||||
PointerSize getPointerSize() const;
|
||||
|
||||
/// Get the global data context.
|
||||
/// @returns LLVMContext - a container for LLVM's global information
|
||||
LLVMContext& getContext() const { return Context; }
|
||||
|
||||
/// Get any module-scope inline assembly blocks.
|
||||
/// @returns a string containing the module-scope inline assembly blocks.
|
||||
const std::string &getModuleInlineAsm() const { return GlobalScopeAsm; }
|
||||
|
@ -29,6 +29,7 @@
|
||||
#ifndef LLVM_PASS_H
|
||||
#define LLVM_PASS_H
|
||||
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/Streams.h"
|
||||
#include <cassert>
|
||||
@ -47,6 +48,7 @@ class ImmutablePass;
|
||||
class PMStack;
|
||||
class AnalysisResolver;
|
||||
class PMDataManager;
|
||||
class LLVMContext;
|
||||
|
||||
// AnalysisID - Use the PassInfo to identify a pass...
|
||||
typedef const PassInfo* AnalysisID;
|
||||
@ -75,6 +77,10 @@ class Pass {
|
||||
|
||||
void operator=(const Pass&); // DO NOT IMPLEMENT
|
||||
Pass(const Pass &); // DO NOT IMPLEMENT
|
||||
|
||||
protected:
|
||||
LLVMContext* Context;
|
||||
|
||||
public:
|
||||
explicit Pass(intptr_t pid) : Resolver(0), PassID(pid) {
|
||||
assert(pid && "pid cannot be 0");
|
||||
@ -275,7 +281,10 @@ public:
|
||||
/// doInitialization - Virtual method overridden by subclasses to do
|
||||
/// any necessary per-module initialization.
|
||||
///
|
||||
virtual bool doInitialization(Module &) { return false; }
|
||||
virtual bool doInitialization(Module &M) {
|
||||
Context = &M.getContext();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// runOnFunction - Virtual method overriden by subclasses to do the
|
||||
/// per-function processing of the pass.
|
||||
@ -327,7 +336,10 @@ public:
|
||||
/// doInitialization - Virtual method overridden by subclasses to do
|
||||
/// any necessary per-module initialization.
|
||||
///
|
||||
virtual bool doInitialization(Module &) { return false; }
|
||||
virtual bool doInitialization(Module &M) {
|
||||
Context = &M.getContext();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// doInitialization - Virtual method overridden by BasicBlockPass subclasses
|
||||
/// to do any necessary per-function initialization.
|
||||
|
@ -7,9 +7,9 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the SourceMgr class. This class is used as a simple
|
||||
// substrate for diagnostics, #include handling, and other low level things for
|
||||
// simple parsers.
|
||||
// This file declares the SMLoc, SMDiagnostic and SourceMgr classes. This
|
||||
// provides a simple substrate for diagnostics, #include handling, and other low
|
||||
// level things for simple parsers.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@ -23,6 +23,8 @@
|
||||
namespace llvm {
|
||||
class MemoryBuffer;
|
||||
class SourceMgr;
|
||||
class SMDiagnostic;
|
||||
class raw_ostream;
|
||||
|
||||
class SMLoc {
|
||||
const char *Ptr;
|
||||
@ -30,6 +32,8 @@ public:
|
||||
SMLoc() : Ptr(0) {}
|
||||
SMLoc(const SMLoc &RHS) : Ptr(RHS.Ptr) {}
|
||||
|
||||
bool isValid() const { return Ptr != 0; }
|
||||
|
||||
bool operator==(const SMLoc &RHS) const { return RHS.Ptr == Ptr; }
|
||||
bool operator!=(const SMLoc &RHS) const { return RHS.Ptr != Ptr; }
|
||||
|
||||
@ -42,8 +46,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// SourceMgr - This owns the files read by tblgen, handles include stacks,
|
||||
/// and handles printing of diagnostics.
|
||||
/// SourceMgr - This owns the files read by a parser, handles include stacks,
|
||||
/// and handles diagnostic wrangling.
|
||||
class SourceMgr {
|
||||
struct SrcBuffer {
|
||||
/// Buffer - The memory buffer for the file.
|
||||
@ -109,10 +113,51 @@ public:
|
||||
|
||||
/// PrintMessage - Emit a message about the specified location with the
|
||||
/// specified string.
|
||||
void PrintMessage(SMLoc Loc, const std::string &Msg) const;
|
||||
///
|
||||
/// @param Type - If non-null, the kind of message (e.g., "error") which is
|
||||
/// prefixed to the message.
|
||||
void PrintMessage(SMLoc Loc, const std::string &Msg, const char *Type) const;
|
||||
|
||||
|
||||
/// GetMessage - Return an SMDiagnostic at the specified location with the
|
||||
/// specified string.
|
||||
///
|
||||
/// @param Type - If non-null, the kind of message (e.g., "error") which is
|
||||
/// prefixed to the message.
|
||||
SMDiagnostic GetMessage(SMLoc Loc,
|
||||
const std::string &Msg, const char *Type) const;
|
||||
|
||||
|
||||
private:
|
||||
void PrintIncludeStack(SMLoc IncludeLoc) const;
|
||||
void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const;
|
||||
};
|
||||
|
||||
|
||||
/// SMDiagnostic - Instances of this class encapsulate one diagnostic report,
|
||||
/// allowing printing to a raw_ostream as a caret diagnostic.
|
||||
class SMDiagnostic {
|
||||
std::string Filename;
|
||||
int LineNo, ColumnNo;
|
||||
std::string Message, LineContents;
|
||||
public:
|
||||
SMDiagnostic() : LineNo(0), ColumnNo(0) {}
|
||||
SMDiagnostic(const std::string &FN, int Line, int Col,
|
||||
const std::string &Msg, const std::string &LineStr)
|
||||
: Filename(FN), LineNo(Line), ColumnNo(Col), Message(Msg),
|
||||
LineContents(LineStr) {}
|
||||
SMDiagnostic(const SMDiagnostic &RHS) {
|
||||
operator=(RHS);
|
||||
}
|
||||
|
||||
void operator=(const SMDiagnostic &E) {
|
||||
Filename = E.Filename;
|
||||
LineNo = E.LineNo;
|
||||
ColumnNo = E.ColumnNo;
|
||||
Message = E.Message;
|
||||
LineContents = E.LineContents;
|
||||
}
|
||||
|
||||
void Print(const char *ProgName, raw_ostream &S);
|
||||
};
|
||||
|
||||
} // end llvm namespace
|
||||
|
@ -253,8 +253,7 @@ public:
|
||||
|
||||
private:
|
||||
static const FunctionType *create() {
|
||||
std::vector<const Type*> params;
|
||||
return FunctionType::get(TypeBuilder<R, cross>::get(), params, false);
|
||||
return FunctionType::get(TypeBuilder<R, cross>::get(), false);
|
||||
}
|
||||
};
|
||||
template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> {
|
||||
@ -360,8 +359,7 @@ public:
|
||||
|
||||
private:
|
||||
static const FunctionType *create() {
|
||||
std::vector<const Type*> params;
|
||||
return FunctionType::get(TypeBuilder<R, cross>::get(), params, true);
|
||||
return FunctionType::get(TypeBuilder<R, cross>::get(), true);
|
||||
}
|
||||
};
|
||||
template<typename R, typename A1, bool cross>
|
||||
|
34
include/llvm/System/Errno.h
Normal file
34
include/llvm/System/Errno.h
Normal file
@ -0,0 +1,34 @@
|
||||
//===- llvm/System/Errno.h - Portable+convenient errno handling -*- 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 some portable and convenient functions to deal with errno.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SYSTEM_ERRNO_H
|
||||
#define LLVM_SYSTEM_ERRNO_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
|
||||
/// Returns a string representation of the errno value, using whatever
|
||||
/// thread-safe variant of strerror() is available. Be sure to call this
|
||||
/// immediately after the function that set errno, or errno may have been
|
||||
/// overwritten by an intervening call.
|
||||
std::string StrError();
|
||||
|
||||
/// Like the no-argument version above, but uses \p errnum instead of errno.
|
||||
std::string StrError(int errnum);
|
||||
|
||||
} // namespace sys
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_SYSTEM_ERRNO_H
|
@ -54,6 +54,10 @@ class CCIfInReg<CCAction A> : CCIf<"ArgFlags.isInReg()", A> {}
|
||||
/// the specified action.
|
||||
class CCIfNest<CCAction A> : CCIf<"ArgFlags.isNest()", A> {}
|
||||
|
||||
/// CCIfSplit - If this argument is marked with the 'split' attribute, apply
|
||||
/// the specified action.
|
||||
class CCIfSplit<CCAction A> : CCIf<"ArgFlags.isSplit()", A> {}
|
||||
|
||||
/// CCIfNotVarArg - If the current function is not vararg - apply the action
|
||||
class CCIfNotVarArg<CCAction A> : CCIf<"!State.isVarArg()", A> {}
|
||||
|
||||
|
@ -89,10 +89,6 @@ namespace llvm {
|
||||
: (hasRelocationAddend() ? 12 : 8);
|
||||
}
|
||||
|
||||
/// getFunctionAlignment - Returns the alignment for function 'F', targets
|
||||
/// with different alignment constraints should overload this method
|
||||
virtual unsigned getFunctionAlignment(const Function *F) const;
|
||||
|
||||
/// getRelocationType - Returns the target specific ELF Relocation type.
|
||||
/// 'MachineRelTy' contains the object code independent relocation type
|
||||
virtual unsigned getRelocationType(unsigned MachineRelTy) const = 0;
|
||||
|
@ -256,7 +256,7 @@ public:
|
||||
return getTypeAction(NVT) == Promote ? getTypeToTransformTo(NVT) : NVT;
|
||||
}
|
||||
assert(0 && "Unsupported extended type!");
|
||||
return MVT(); // Not reached
|
||||
return MVT(MVT::Other); // Not reached
|
||||
}
|
||||
|
||||
/// getTypeToExpandTo - For types supported by the target, this is an
|
||||
@ -557,7 +557,7 @@ public:
|
||||
return getRegisterType(getTypeToTransformTo(VT));
|
||||
}
|
||||
assert(0 && "Unsupported extended type!");
|
||||
return MVT(); // Not reached
|
||||
return MVT(MVT::Other); // Not reached
|
||||
}
|
||||
|
||||
/// getNumRegisters - Return the number of registers that this ValueType will
|
||||
@ -736,6 +736,9 @@ public:
|
||||
/// PIC relocation models.
|
||||
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
|
||||
|
||||
/// getFunctionAlignment - Return the Log2 alignment of this function.
|
||||
virtual unsigned getFunctionAlignment(const Function *) const = 0;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// TargetLowering Optimization Methods
|
||||
//
|
||||
@ -1119,9 +1122,9 @@ public:
|
||||
typedef std::vector<ArgListEntry> ArgListTy;
|
||||
virtual std::pair<SDValue, SDValue>
|
||||
LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt,
|
||||
bool isVarArg, bool isInreg, unsigned CallingConv,
|
||||
bool isTailCall, SDValue Callee, ArgListTy &Args,
|
||||
SelectionDAG &DAG, DebugLoc dl);
|
||||
bool isVarArg, bool isInreg, unsigned NumFixedArgs,
|
||||
unsigned CallingConv, bool isTailCall, SDValue Callee,
|
||||
ArgListTy &Args, SelectionDAG &DAG, DebugLoc dl);
|
||||
|
||||
/// EmitTargetCodeForMemcpy - Emit target-specific code that performs a
|
||||
/// memcpy. This can be used by targets to provide code sequences for cases
|
||||
|
@ -337,6 +337,12 @@ FunctionPass *createCodeGenPreparePass(const TargetLowering *TLI = 0);
|
||||
FunctionPass *createInstructionNamerPass();
|
||||
extern const PassInfo *const InstructionNamerID;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// SSI - This pass converts to Static Single Information form.
|
||||
//
|
||||
FunctionPass *createSSIPass();
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -37,6 +37,7 @@ class Trace;
|
||||
class CallGraph;
|
||||
class TargetData;
|
||||
class LoopInfo;
|
||||
class LLVMContext;
|
||||
template<class N> class LoopBase;
|
||||
typedef LoopBase<BasicBlock> Loop;
|
||||
|
||||
|
@ -19,6 +19,7 @@ namespace llvm {
|
||||
|
||||
class User;
|
||||
class BasicBlock;
|
||||
class BranchInst;
|
||||
class Instruction;
|
||||
class Value;
|
||||
class Pass;
|
||||
@ -94,6 +95,12 @@ void MergeBasicBlockIntoOnlyPred(BasicBlock *BB);
|
||||
///
|
||||
bool SimplifyCFG(BasicBlock *BB);
|
||||
|
||||
/// FoldBranchToCommonDest - If this basic block is ONLY a setcc and a branch,
|
||||
/// and if a predecessor branches to us and one of our successors, fold the
|
||||
/// setcc into the predecessor and use logical operations to pick the right
|
||||
/// destination.
|
||||
bool FoldBranchToCommonDest(BranchInst *BI);
|
||||
|
||||
/// DemoteRegToStack - This function takes a virtual register computed by an
|
||||
/// Instruction and replaces it with a slot in the stack frame, allocated via
|
||||
/// alloca. This allows the CFG to be changed around without fear of
|
||||
|
102
include/llvm/Transforms/Utils/SSI.h
Normal file
102
include/llvm/Transforms/Utils/SSI.h
Normal file
@ -0,0 +1,102 @@
|
||||
//===------------------- SSI.h - Creates SSI Representation -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This pass converts a list of variables to the Static Single Information
|
||||
// form. This is a program representation described by Scott Ananian in his
|
||||
// Master Thesis: "The Static Single Information Form (1999)".
|
||||
// We are building an on-demand representation, that is, we do not convert
|
||||
// every single variable in the target function to SSI form. Rather, we receive
|
||||
// a list of target variables that must be converted. We also do not
|
||||
// completely convert a target variable to the SSI format. Instead, we only
|
||||
// change the variable in the points where new information can be attached
|
||||
// to its live range, that is, at branch points.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TRANSFORMS_UTILS_SSI_H
|
||||
#define LLVM_TRANSFORMS_UTILS_SSI_H
|
||||
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class DominatorTree;
|
||||
class PHINode;
|
||||
class Instruction;
|
||||
class CmpInst;
|
||||
|
||||
class SSI : public FunctionPass {
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid.
|
||||
SSI() :
|
||||
FunctionPass(&ID) {
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
|
||||
/// runOnMachineFunction - pass entry point
|
||||
bool runOnFunction(Function&);
|
||||
|
||||
void createSSI(SmallVectorImpl<Instruction *> &value);
|
||||
|
||||
private:
|
||||
// Variables always live
|
||||
DominatorTree *DT_;
|
||||
|
||||
// Stores variables created by SSI
|
||||
SmallPtrSet<Instruction *, 16> created;
|
||||
|
||||
// These variables are only live for each creation
|
||||
unsigned num_values;
|
||||
|
||||
// Has a bit for each variable, true if it needs to be created
|
||||
// and false otherwise
|
||||
BitVector needConstruction;
|
||||
|
||||
// Phis created by SSI
|
||||
DenseMap<PHINode *, unsigned> phis;
|
||||
|
||||
// Sigmas created by SSI
|
||||
DenseMap<PHINode *, unsigned> sigmas;
|
||||
|
||||
// Phi nodes that have a phi as operand and has to be fixed
|
||||
SmallPtrSet<PHINode *, 1> phisToFix;
|
||||
|
||||
// List of definition points for every variable
|
||||
SmallVector<SmallVector<BasicBlock *, 1>, 0> defsites;
|
||||
|
||||
// Basic Block of the original definition of each variable
|
||||
SmallVector<BasicBlock *, 0> value_original;
|
||||
|
||||
// Stack of last seen definition of a variable
|
||||
SmallVector<SmallVector<Instruction *, 1>, 0> value_stack;
|
||||
|
||||
void insertSigmaFunctions(SmallVectorImpl<Instruction *> &value);
|
||||
void insertPhiFunctions(SmallVectorImpl<Instruction *> &value);
|
||||
void renameInit(SmallVectorImpl<Instruction *> &value);
|
||||
void rename(BasicBlock *BB);
|
||||
|
||||
void substituteUse(Instruction *I);
|
||||
bool dominateAny(BasicBlock *BB, Instruction *value);
|
||||
void fixPhis();
|
||||
|
||||
unsigned getPositionPhi(PHINode *PN);
|
||||
unsigned getPositionSigma(PHINode *PN);
|
||||
|
||||
unsigned isUsedInTerminator(CmpInst *CI);
|
||||
|
||||
void init(SmallVectorImpl<Instruction *> &value);
|
||||
void clean();
|
||||
};
|
||||
} // end namespace
|
||||
#endif
|
@ -21,6 +21,7 @@
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
#include "llvm/Support/Dwarf.h"
|
||||
#include "llvm/Support/DebugLoc.h"
|
||||
#include "llvm/Support/Streams.h"
|
||||
|
||||
using namespace llvm;
|
||||
@ -320,6 +321,133 @@ bool DISubprogram::describes(const Function *F) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DIDescriptor: dump routines for all descriptors.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
/// dump - Print descriptor.
|
||||
void DIDescriptor::dump() const {
|
||||
cerr << "[" << dwarf::TagString(getTag()) << "] ";
|
||||
cerr << std::hex << "[GV:" << DbgGV << "]" << std::dec;
|
||||
}
|
||||
|
||||
/// dump - Print compile unit.
|
||||
void DICompileUnit::dump() const {
|
||||
if (getLanguage())
|
||||
cerr << " [" << dwarf::LanguageString(getLanguage()) << "] ";
|
||||
|
||||
std::string Res1, Res2;
|
||||
cerr << " [" << getDirectory(Res1) << "/" << getFilename(Res2) << " ]";
|
||||
}
|
||||
|
||||
/// dump - Print type.
|
||||
void DIType::dump() const {
|
||||
if (isNull()) return;
|
||||
|
||||
std::string Res;
|
||||
if (!getName(Res).empty())
|
||||
cerr << " [" << Res << "] ";
|
||||
|
||||
unsigned Tag = getTag();
|
||||
cerr << " [" << dwarf::TagString(Tag) << "] ";
|
||||
|
||||
// TODO : Print context
|
||||
getCompileUnit().dump();
|
||||
cerr << " ["
|
||||
<< getLineNumber() << ", "
|
||||
<< getSizeInBits() << ", "
|
||||
<< getAlignInBits() << ", "
|
||||
<< getOffsetInBits()
|
||||
<< "] ";
|
||||
|
||||
if (isPrivate())
|
||||
cerr << " [private] ";
|
||||
else if (isProtected())
|
||||
cerr << " [protected] ";
|
||||
|
||||
if (isForwardDecl())
|
||||
cerr << " [fwd] ";
|
||||
|
||||
if (isBasicType(Tag))
|
||||
DIBasicType(DbgGV).dump();
|
||||
else if (isDerivedType(Tag))
|
||||
DIDerivedType(DbgGV).dump();
|
||||
else if (isCompositeType(Tag))
|
||||
DICompositeType(DbgGV).dump();
|
||||
else {
|
||||
cerr << "Invalid DIType\n";
|
||||
return;
|
||||
}
|
||||
|
||||
cerr << "\n";
|
||||
}
|
||||
|
||||
/// dump - Print basic type.
|
||||
void DIBasicType::dump() const {
|
||||
cerr << " [" << dwarf::AttributeEncodingString(getEncoding()) << "] ";
|
||||
}
|
||||
|
||||
/// dump - Print derived type.
|
||||
void DIDerivedType::dump() const {
|
||||
cerr << "\n\t Derived From: "; getTypeDerivedFrom().dump();
|
||||
}
|
||||
|
||||
/// dump - Print composite type.
|
||||
void DICompositeType::dump() const {
|
||||
DIArray A = getTypeArray();
|
||||
if (A.isNull())
|
||||
return;
|
||||
cerr << " [" << A.getNumElements() << " elements]";
|
||||
}
|
||||
|
||||
/// dump - Print global.
|
||||
void DIGlobal::dump() const {
|
||||
std::string Res;
|
||||
if (!getName(Res).empty())
|
||||
cerr << " [" << Res << "] ";
|
||||
|
||||
unsigned Tag = getTag();
|
||||
cerr << " [" << dwarf::TagString(Tag) << "] ";
|
||||
|
||||
// TODO : Print context
|
||||
getCompileUnit().dump();
|
||||
cerr << " [" << getLineNumber() << "] ";
|
||||
|
||||
if (isLocalToUnit())
|
||||
cerr << " [local] ";
|
||||
|
||||
if (isDefinition())
|
||||
cerr << " [def] ";
|
||||
|
||||
if (isGlobalVariable(Tag))
|
||||
DIGlobalVariable(DbgGV).dump();
|
||||
|
||||
cerr << "\n";
|
||||
}
|
||||
|
||||
/// dump - Print subprogram.
|
||||
void DISubprogram::dump() const {
|
||||
DIGlobal::dump();
|
||||
}
|
||||
|
||||
/// dump - Print global variable.
|
||||
void DIGlobalVariable::dump() const {
|
||||
cerr << " ["; getGlobal()->dump(); cerr << "] ";
|
||||
}
|
||||
|
||||
/// dump - Print variable.
|
||||
void DIVariable::dump() const {
|
||||
std::string Res;
|
||||
if (!getName(Res).empty())
|
||||
cerr << " [" << Res << "] ";
|
||||
|
||||
getCompileUnit().dump();
|
||||
cerr << " [" << getLineNumber() << "] ";
|
||||
getType().dump();
|
||||
cerr << "\n";
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DIFactory: Basic Helpers
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -327,7 +455,7 @@ bool DISubprogram::describes(const Function *F) {
|
||||
DIFactory::DIFactory(Module &m)
|
||||
: M(m), StopPointFn(0), FuncStartFn(0), RegionStartFn(0), RegionEndFn(0),
|
||||
DeclareFn(0) {
|
||||
EmptyStructPtr = PointerType::getUnqual(StructType::get(NULL, NULL));
|
||||
EmptyStructPtr = PointerType::getUnqual(StructType::get());
|
||||
}
|
||||
|
||||
/// getCastToEmpty - Return this descriptor as a Constant* with type '{}*'.
|
||||
@ -923,127 +1051,108 @@ namespace llvm {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// dump - Print descriptor.
|
||||
void DIDescriptor::dump() const {
|
||||
cerr << "[" << dwarf::TagString(getTag()) << "] ";
|
||||
cerr << std::hex << "[GV:" << DbgGV << "]" << std::dec;
|
||||
}
|
||||
|
||||
/// dump - Print compile unit.
|
||||
void DICompileUnit::dump() const {
|
||||
if (getLanguage())
|
||||
cerr << " [" << dwarf::LanguageString(getLanguage()) << "] ";
|
||||
|
||||
std::string Res1, Res2;
|
||||
cerr << " [" << getDirectory(Res1) << "/" << getFilename(Res2) << " ]";
|
||||
}
|
||||
|
||||
/// dump - Print type.
|
||||
void DIType::dump() const {
|
||||
if (isNull()) return;
|
||||
|
||||
std::string Res;
|
||||
if (!getName(Res).empty())
|
||||
cerr << " [" << Res << "] ";
|
||||
|
||||
unsigned Tag = getTag();
|
||||
cerr << " [" << dwarf::TagString(Tag) << "] ";
|
||||
|
||||
// TODO : Print context
|
||||
getCompileUnit().dump();
|
||||
cerr << " ["
|
||||
<< getLineNumber() << ", "
|
||||
<< getSizeInBits() << ", "
|
||||
<< getAlignInBits() << ", "
|
||||
<< getOffsetInBits()
|
||||
<< "] ";
|
||||
|
||||
if (isPrivate())
|
||||
cerr << " [private] ";
|
||||
else if (isProtected())
|
||||
cerr << " [protected] ";
|
||||
|
||||
if (isForwardDecl())
|
||||
cerr << " [fwd] ";
|
||||
|
||||
if (isBasicType(Tag))
|
||||
DIBasicType(DbgGV).dump();
|
||||
else if (isDerivedType(Tag))
|
||||
DIDerivedType(DbgGV).dump();
|
||||
else if (isCompositeType(Tag))
|
||||
DICompositeType(DbgGV).dump();
|
||||
else {
|
||||
cerr << "Invalid DIType\n";
|
||||
return;
|
||||
/// isValidDebugInfoIntrinsic - Return true if SPI is a valid debug
|
||||
/// info intrinsic.
|
||||
bool isValidDebugInfoIntrinsic(DbgStopPointInst &SPI,
|
||||
CodeGenOpt::Level OptLev) {
|
||||
return DIDescriptor::ValidDebugInfo(SPI.getContext(), OptLev);
|
||||
}
|
||||
|
||||
/// isValidDebugInfoIntrinsic - Return true if FSI is a valid debug
|
||||
/// info intrinsic.
|
||||
bool isValidDebugInfoIntrinsic(DbgFuncStartInst &FSI,
|
||||
CodeGenOpt::Level OptLev) {
|
||||
return DIDescriptor::ValidDebugInfo(FSI.getSubprogram(), OptLev);
|
||||
}
|
||||
|
||||
/// isValidDebugInfoIntrinsic - Return true if RSI is a valid debug
|
||||
/// info intrinsic.
|
||||
bool isValidDebugInfoIntrinsic(DbgRegionStartInst &RSI,
|
||||
CodeGenOpt::Level OptLev) {
|
||||
return DIDescriptor::ValidDebugInfo(RSI.getContext(), OptLev);
|
||||
}
|
||||
|
||||
/// isValidDebugInfoIntrinsic - Return true if REI is a valid debug
|
||||
/// info intrinsic.
|
||||
bool isValidDebugInfoIntrinsic(DbgRegionEndInst &REI,
|
||||
CodeGenOpt::Level OptLev) {
|
||||
return DIDescriptor::ValidDebugInfo(REI.getContext(), OptLev);
|
||||
}
|
||||
|
||||
|
||||
/// isValidDebugInfoIntrinsic - Return true if DI is a valid debug
|
||||
/// info intrinsic.
|
||||
bool isValidDebugInfoIntrinsic(DbgDeclareInst &DI,
|
||||
CodeGenOpt::Level OptLev) {
|
||||
return DIDescriptor::ValidDebugInfo(DI.getVariable(), OptLev);
|
||||
}
|
||||
|
||||
/// ExtractDebugLocation - Extract debug location information
|
||||
/// from llvm.dbg.stoppoint intrinsic.
|
||||
DebugLoc ExtractDebugLocation(DbgStopPointInst &SPI,
|
||||
DebugLocTracker &DebugLocInfo) {
|
||||
DebugLoc DL;
|
||||
Value *Context = SPI.getContext();
|
||||
|
||||
// If this location is already tracked then use it.
|
||||
DebugLocTuple Tuple(cast<GlobalVariable>(Context), SPI.getLine(),
|
||||
SPI.getColumn());
|
||||
DenseMap<DebugLocTuple, unsigned>::iterator II
|
||||
= DebugLocInfo.DebugIdMap.find(Tuple);
|
||||
if (II != DebugLocInfo.DebugIdMap.end())
|
||||
return DebugLoc::get(II->second);
|
||||
|
||||
// Add a new location entry.
|
||||
unsigned Id = DebugLocInfo.DebugLocations.size();
|
||||
DebugLocInfo.DebugLocations.push_back(Tuple);
|
||||
DebugLocInfo.DebugIdMap[Tuple] = Id;
|
||||
|
||||
return DebugLoc::get(Id);
|
||||
}
|
||||
|
||||
/// ExtractDebugLocation - Extract debug location information
|
||||
/// from llvm.dbg.func_start intrinsic.
|
||||
DebugLoc ExtractDebugLocation(DbgFuncStartInst &FSI,
|
||||
DebugLocTracker &DebugLocInfo) {
|
||||
DebugLoc DL;
|
||||
Value *SP = FSI.getSubprogram();
|
||||
|
||||
DISubprogram Subprogram(cast<GlobalVariable>(SP));
|
||||
unsigned Line = Subprogram.getLineNumber();
|
||||
DICompileUnit CU(Subprogram.getCompileUnit());
|
||||
|
||||
// If this location is already tracked then use it.
|
||||
DebugLocTuple Tuple(CU.getGV(), Line, /* Column */ 0);
|
||||
DenseMap<DebugLocTuple, unsigned>::iterator II
|
||||
= DebugLocInfo.DebugIdMap.find(Tuple);
|
||||
if (II != DebugLocInfo.DebugIdMap.end())
|
||||
return DebugLoc::get(II->second);
|
||||
|
||||
// Add a new location entry.
|
||||
unsigned Id = DebugLocInfo.DebugLocations.size();
|
||||
DebugLocInfo.DebugLocations.push_back(Tuple);
|
||||
DebugLocInfo.DebugIdMap[Tuple] = Id;
|
||||
|
||||
return DebugLoc::get(Id);
|
||||
}
|
||||
|
||||
/// isInlinedFnStart - Return true if FSI is starting an inlined function.
|
||||
bool isInlinedFnStart(DbgFuncStartInst &FSI, const Function *CurrentFn) {
|
||||
DISubprogram Subprogram(cast<GlobalVariable>(FSI.getSubprogram()));
|
||||
if (Subprogram.describes(CurrentFn))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// isInlinedFnEnd - Return true if REI is ending an inlined function.
|
||||
bool isInlinedFnEnd(DbgRegionEndInst &REI, const Function *CurrentFn) {
|
||||
DISubprogram Subprogram(cast<GlobalVariable>(REI.getContext()));
|
||||
if (Subprogram.isNull() || Subprogram.describes(CurrentFn))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
cerr << "\n";
|
||||
}
|
||||
|
||||
/// dump - Print basic type.
|
||||
void DIBasicType::dump() const {
|
||||
cerr << " [" << dwarf::AttributeEncodingString(getEncoding()) << "] ";
|
||||
}
|
||||
|
||||
/// dump - Print derived type.
|
||||
void DIDerivedType::dump() const {
|
||||
cerr << "\n\t Derived From: "; getTypeDerivedFrom().dump();
|
||||
}
|
||||
|
||||
/// dump - Print composite type.
|
||||
void DICompositeType::dump() const {
|
||||
DIArray A = getTypeArray();
|
||||
if (A.isNull())
|
||||
return;
|
||||
cerr << " [" << A.getNumElements() << " elements]";
|
||||
}
|
||||
|
||||
/// dump - Print global.
|
||||
void DIGlobal::dump() const {
|
||||
std::string Res;
|
||||
if (!getName(Res).empty())
|
||||
cerr << " [" << Res << "] ";
|
||||
|
||||
unsigned Tag = getTag();
|
||||
cerr << " [" << dwarf::TagString(Tag) << "] ";
|
||||
|
||||
// TODO : Print context
|
||||
getCompileUnit().dump();
|
||||
cerr << " [" << getLineNumber() << "] ";
|
||||
|
||||
if (isLocalToUnit())
|
||||
cerr << " [local] ";
|
||||
|
||||
if (isDefinition())
|
||||
cerr << " [def] ";
|
||||
|
||||
if (isGlobalVariable(Tag))
|
||||
DIGlobalVariable(DbgGV).dump();
|
||||
|
||||
cerr << "\n";
|
||||
}
|
||||
|
||||
/// dump - Print subprogram.
|
||||
void DISubprogram::dump() const {
|
||||
DIGlobal::dump();
|
||||
}
|
||||
|
||||
/// dump - Print global variable.
|
||||
void DIGlobalVariable::dump() const {
|
||||
cerr << " ["; getGlobal()->dump(); cerr << "] ";
|
||||
}
|
||||
|
||||
/// dump - Print variable.
|
||||
void DIVariable::dump() const {
|
||||
std::string Res;
|
||||
if (!getName(Res).empty())
|
||||
cerr << " [" << Res << "] ";
|
||||
|
||||
getCompileUnit().dump();
|
||||
cerr << " [" << getLineNumber() << "] ";
|
||||
getType().dump();
|
||||
cerr << "\n";
|
||||
}
|
||||
|
||||
|
@ -211,7 +211,7 @@ namespace {
|
||||
// for each location equivalent Node.
|
||||
struct Node {
|
||||
private:
|
||||
static unsigned Counter;
|
||||
static volatile sys::cas_flag Counter;
|
||||
|
||||
public:
|
||||
Value *Val;
|
||||
@ -618,7 +618,7 @@ X("anders-aa", "Andersen's Interprocedural Alias Analysis", false, true);
|
||||
static RegisterAnalysisGroup<AliasAnalysis> Y(X);
|
||||
|
||||
// Initialize Timestamp Counter (static).
|
||||
unsigned Andersens::Node::Counter = 0;
|
||||
volatile llvm::sys::cas_flag Andersens::Node::Counter = 0;
|
||||
|
||||
ModulePass *llvm::createAndersensPass() { return new Andersens(); }
|
||||
|
||||
|
@ -18,9 +18,13 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "lda"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/LoopDependenceAnalysis.h"
|
||||
#include "llvm/Analysis/LoopPass.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
using namespace llvm;
|
||||
|
||||
LoopPass *llvm::createLoopDependenceAnalysisPass() {
|
||||
@ -31,17 +35,133 @@ static RegisterPass<LoopDependenceAnalysis>
|
||||
R("lda", "Loop Dependence Analysis", false, true);
|
||||
char LoopDependenceAnalysis::ID = 0;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Utility Functions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static inline bool IsMemRefInstr(const Value *V) {
|
||||
const Instruction *I = dyn_cast<const Instruction>(V);
|
||||
return I && (I->mayReadFromMemory() || I->mayWriteToMemory());
|
||||
}
|
||||
|
||||
static void GetMemRefInstrs(
|
||||
const Loop *L, SmallVectorImpl<Instruction*> &memrefs) {
|
||||
for (Loop::block_iterator b = L->block_begin(), be = L->block_end();
|
||||
b != be; ++b)
|
||||
for (BasicBlock::iterator i = (*b)->begin(), ie = (*b)->end();
|
||||
i != ie; ++i)
|
||||
if (IsMemRefInstr(i))
|
||||
memrefs.push_back(i);
|
||||
}
|
||||
|
||||
static bool IsLoadOrStoreInst(Value *I) {
|
||||
return isa<LoadInst>(I) || isa<StoreInst>(I);
|
||||
}
|
||||
|
||||
static Value *GetPointerOperand(Value *I) {
|
||||
if (LoadInst *i = dyn_cast<LoadInst>(I))
|
||||
return i->getPointerOperand();
|
||||
if (StoreInst *i = dyn_cast<StoreInst>(I))
|
||||
return i->getPointerOperand();
|
||||
assert(0 && "Value is no load or store instruction!");
|
||||
// Never reached.
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Dependence Testing
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool LoopDependenceAnalysis::isDependencePair(const Value *x,
|
||||
const Value *y) const {
|
||||
return IsMemRefInstr(x) &&
|
||||
IsMemRefInstr(y) &&
|
||||
(cast<const Instruction>(x)->mayWriteToMemory() ||
|
||||
cast<const Instruction>(y)->mayWriteToMemory());
|
||||
}
|
||||
|
||||
bool LoopDependenceAnalysis::depends(Value *src, Value *dst) {
|
||||
assert(isDependencePair(src, dst) && "Values form no dependence pair!");
|
||||
DOUT << "== LDA test ==\n" << *src << *dst;
|
||||
|
||||
// We only analyse loads and stores; for possible memory accesses by e.g.
|
||||
// free, call, or invoke instructions we conservatively assume dependence.
|
||||
if (!IsLoadOrStoreInst(src) || !IsLoadOrStoreInst(dst))
|
||||
return true;
|
||||
|
||||
Value *srcPtr = GetPointerOperand(src);
|
||||
Value *dstPtr = GetPointerOperand(dst);
|
||||
const Value *srcObj = srcPtr->getUnderlyingObject();
|
||||
const Value *dstObj = dstPtr->getUnderlyingObject();
|
||||
AliasAnalysis::AliasResult alias = AA->alias(
|
||||
srcObj, AA->getTargetData().getTypeStoreSize(srcObj->getType()),
|
||||
dstObj, AA->getTargetData().getTypeStoreSize(dstObj->getType()));
|
||||
|
||||
// If we don't know whether or not the two objects alias, assume dependence.
|
||||
if (alias == AliasAnalysis::MayAlias)
|
||||
return true;
|
||||
|
||||
// If the objects noalias, they are distinct, accesses are independent.
|
||||
if (alias == AliasAnalysis::NoAlias)
|
||||
return false;
|
||||
|
||||
// TODO: the underlying objects MustAlias, test for dependence
|
||||
|
||||
// We couldn't establish a more precise result, so we have to conservatively
|
||||
// assume full dependence.
|
||||
return true;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// LoopDependenceAnalysis Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool LoopDependenceAnalysis::runOnLoop(Loop *L, LPPassManager &) {
|
||||
this->L = L;
|
||||
AA = &getAnalysis<AliasAnalysis>();
|
||||
SE = &getAnalysis<ScalarEvolution>();
|
||||
return false;
|
||||
}
|
||||
|
||||
void LoopDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
AU.addRequired<ScalarEvolution>();
|
||||
AU.addRequiredTransitive<AliasAnalysis>();
|
||||
AU.addRequiredTransitive<ScalarEvolution>();
|
||||
}
|
||||
|
||||
static void PrintLoopInfo(
|
||||
raw_ostream &OS, LoopDependenceAnalysis *LDA, const Loop *L) {
|
||||
if (!L->empty()) return; // ignore non-innermost loops
|
||||
|
||||
SmallVector<Instruction*, 8> memrefs;
|
||||
GetMemRefInstrs(L, memrefs);
|
||||
|
||||
OS << "Loop at depth " << L->getLoopDepth() << ", header block: ";
|
||||
WriteAsOperand(OS, L->getHeader(), false);
|
||||
OS << "\n";
|
||||
|
||||
OS << " Load/store instructions: " << memrefs.size() << "\n";
|
||||
for (SmallVector<Instruction*, 8>::const_iterator x = memrefs.begin(),
|
||||
end = memrefs.end(); x != end; ++x)
|
||||
OS << "\t" << (x - memrefs.begin()) << ": " << **x;
|
||||
|
||||
OS << " Pairwise dependence results:\n";
|
||||
for (SmallVector<Instruction*, 8>::const_iterator x = memrefs.begin(),
|
||||
end = memrefs.end(); x != end; ++x)
|
||||
for (SmallVector<Instruction*, 8>::const_iterator y = x + 1;
|
||||
y != end; ++y)
|
||||
if (LDA->isDependencePair(*x, *y))
|
||||
OS << "\t" << (x - memrefs.begin()) << "," << (y - memrefs.begin())
|
||||
<< ": " << (LDA->depends(*x, *y) ? "dependent" : "independent")
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
void LoopDependenceAnalysis::print(raw_ostream &OS, const Module*) const {
|
||||
// TODO: doc why const_cast is safe
|
||||
PrintLoopInfo(OS, const_cast<LoopDependenceAnalysis*>(this), this->L);
|
||||
}
|
||||
|
||||
void LoopDependenceAnalysis::print(std::ostream &OS, const Module *M) const {
|
||||
raw_os_ostream os(OS);
|
||||
print(os, M);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ X("loops", "Natural Loop Information", true, true);
|
||||
//
|
||||
bool LoopInfo::runOnFunction(Function &) {
|
||||
releaseMemory();
|
||||
LI->Calculate(getAnalysis<DominatorTree>().getBase()); // Update
|
||||
LI.Calculate(getAnalysis<DominatorTree>().getBase()); // Update
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -195,6 +195,9 @@ bool LPPassManager::runOnFunction(Function &F) {
|
||||
for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I)
|
||||
addLoopIntoQueue(*I, LQ);
|
||||
|
||||
if (LQ.empty()) // No loops, skip calling finalizers
|
||||
return false;
|
||||
|
||||
// Initialization
|
||||
for (std::deque<Loop *>::const_iterator I = LQ.begin(), E = LQ.end();
|
||||
I != E; ++I) {
|
||||
|
@ -110,7 +110,9 @@ char ScalarEvolution::ID = 0;
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Implementation of the SCEV class.
|
||||
//
|
||||
|
||||
SCEV::~SCEV() {}
|
||||
|
||||
void SCEV::dump() const {
|
||||
print(errs());
|
||||
errs() << '\n';
|
||||
@ -142,6 +144,10 @@ bool SCEV::isAllOnesValue() const {
|
||||
SCEVCouldNotCompute::SCEVCouldNotCompute() :
|
||||
SCEV(scCouldNotCompute) {}
|
||||
|
||||
void SCEVCouldNotCompute::Profile(FoldingSetNodeID &ID) const {
|
||||
assert(0 && "Attempt to use a SCEVCouldNotCompute object!");
|
||||
}
|
||||
|
||||
bool SCEVCouldNotCompute::isLoopInvariant(const Loop *L) const {
|
||||
assert(0 && "Attempt to use a SCEVCouldNotCompute object!");
|
||||
return false;
|
||||
@ -174,9 +180,15 @@ bool SCEVCouldNotCompute::classof(const SCEV *S) {
|
||||
}
|
||||
|
||||
const SCEV* ScalarEvolution::getConstant(ConstantInt *V) {
|
||||
SCEVConstant *&R = SCEVConstants[V];
|
||||
if (R == 0) R = new SCEVConstant(V);
|
||||
return R;
|
||||
FoldingSetNodeID ID;
|
||||
ID.AddInteger(scConstant);
|
||||
ID.AddPointer(V);
|
||||
void *IP = 0;
|
||||
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
|
||||
SCEV *S = SCEVAllocator.Allocate<SCEVConstant>();
|
||||
new (S) SCEVConstant(V);
|
||||
UniqueSCEVs.InsertNode(S, IP);
|
||||
return S;
|
||||
}
|
||||
|
||||
const SCEV* ScalarEvolution::getConstant(const APInt& Val) {
|
||||
@ -188,6 +200,11 @@ ScalarEvolution::getConstant(const Type *Ty, uint64_t V, bool isSigned) {
|
||||
return getConstant(ConstantInt::get(cast<IntegerType>(Ty), V, isSigned));
|
||||
}
|
||||
|
||||
void SCEVConstant::Profile(FoldingSetNodeID &ID) const {
|
||||
ID.AddInteger(scConstant);
|
||||
ID.AddPointer(V);
|
||||
}
|
||||
|
||||
const Type *SCEVConstant::getType() const { return V->getType(); }
|
||||
|
||||
void SCEVConstant::print(raw_ostream &OS) const {
|
||||
@ -198,6 +215,12 @@ SCEVCastExpr::SCEVCastExpr(unsigned SCEVTy,
|
||||
const SCEV* op, const Type *ty)
|
||||
: SCEV(SCEVTy), Op(op), Ty(ty) {}
|
||||
|
||||
void SCEVCastExpr::Profile(FoldingSetNodeID &ID) const {
|
||||
ID.AddInteger(getSCEVType());
|
||||
ID.AddPointer(Op);
|
||||
ID.AddPointer(Ty);
|
||||
}
|
||||
|
||||
bool SCEVCastExpr::dominates(BasicBlock *BB, DominatorTree *DT) const {
|
||||
return Op->dominates(BB, DT);
|
||||
}
|
||||
@ -277,6 +300,13 @@ SCEVCommutativeExpr::replaceSymbolicValuesWithConcrete(
|
||||
return this;
|
||||
}
|
||||
|
||||
void SCEVNAryExpr::Profile(FoldingSetNodeID &ID) const {
|
||||
ID.AddInteger(getSCEVType());
|
||||
ID.AddInteger(Operands.size());
|
||||
for (unsigned i = 0, e = Operands.size(); i != e; ++i)
|
||||
ID.AddPointer(Operands[i]);
|
||||
}
|
||||
|
||||
bool SCEVNAryExpr::dominates(BasicBlock *BB, DominatorTree *DT) const {
|
||||
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
|
||||
if (!getOperand(i)->dominates(BB, DT))
|
||||
@ -285,6 +315,12 @@ bool SCEVNAryExpr::dominates(BasicBlock *BB, DominatorTree *DT) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void SCEVUDivExpr::Profile(FoldingSetNodeID &ID) const {
|
||||
ID.AddInteger(scUDivExpr);
|
||||
ID.AddPointer(LHS);
|
||||
ID.AddPointer(RHS);
|
||||
}
|
||||
|
||||
bool SCEVUDivExpr::dominates(BasicBlock *BB, DominatorTree *DT) const {
|
||||
return LHS->dominates(BB, DT) && RHS->dominates(BB, DT);
|
||||
}
|
||||
@ -302,6 +338,14 @@ const Type *SCEVUDivExpr::getType() const {
|
||||
return RHS->getType();
|
||||
}
|
||||
|
||||
void SCEVAddRecExpr::Profile(FoldingSetNodeID &ID) const {
|
||||
ID.AddInteger(scAddRecExpr);
|
||||
ID.AddInteger(Operands.size());
|
||||
for (unsigned i = 0, e = Operands.size(); i != e; ++i)
|
||||
ID.AddPointer(Operands[i]);
|
||||
ID.AddPointer(L);
|
||||
}
|
||||
|
||||
const SCEV *
|
||||
SCEVAddRecExpr::replaceSymbolicValuesWithConcrete(const SCEV *Sym,
|
||||
const SCEV *Conc,
|
||||
@ -345,7 +389,6 @@ bool SCEVAddRecExpr::isLoopInvariant(const Loop *QueryLoop) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SCEVAddRecExpr::print(raw_ostream &OS) const {
|
||||
OS << "{" << *Operands[0];
|
||||
for (unsigned i = 1, e = Operands.size(); i != e; ++i)
|
||||
@ -353,6 +396,11 @@ void SCEVAddRecExpr::print(raw_ostream &OS) const {
|
||||
OS << "}<" << L->getHeader()->getName() + ">";
|
||||
}
|
||||
|
||||
void SCEVUnknown::Profile(FoldingSetNodeID &ID) const {
|
||||
ID.AddInteger(scUnknown);
|
||||
ID.AddPointer(V);
|
||||
}
|
||||
|
||||
bool SCEVUnknown::isLoopInvariant(const Loop *L) const {
|
||||
// All non-instruction values are loop invariant. All instructions are loop
|
||||
// invariant if they are not contained in the specified loop.
|
||||
@ -696,6 +744,7 @@ const SCEV* ScalarEvolution::getTruncateExpr(const SCEV* Op,
|
||||
"This is not a conversion to a SCEVable type!");
|
||||
Ty = getEffectiveSCEVType(Ty);
|
||||
|
||||
// Fold if the operand is constant.
|
||||
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(Op))
|
||||
return getConstant(
|
||||
cast<ConstantInt>(ConstantExpr::getTrunc(SC->getValue(), Ty)));
|
||||
@ -720,9 +769,16 @@ const SCEV* ScalarEvolution::getTruncateExpr(const SCEV* Op,
|
||||
return getAddRecExpr(Operands, AddRec->getLoop());
|
||||
}
|
||||
|
||||
SCEVTruncateExpr *&Result = SCEVTruncates[std::make_pair(Op, Ty)];
|
||||
if (Result == 0) Result = new SCEVTruncateExpr(Op, Ty);
|
||||
return Result;
|
||||
FoldingSetNodeID ID;
|
||||
ID.AddInteger(scTruncate);
|
||||
ID.AddPointer(Op);
|
||||
ID.AddPointer(Ty);
|
||||
void *IP = 0;
|
||||
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
|
||||
SCEV *S = SCEVAllocator.Allocate<SCEVTruncateExpr>();
|
||||
new (S) SCEVTruncateExpr(Op, Ty);
|
||||
UniqueSCEVs.InsertNode(S, IP);
|
||||
return S;
|
||||
}
|
||||
|
||||
const SCEV* ScalarEvolution::getZeroExtendExpr(const SCEV* Op,
|
||||
@ -733,6 +789,7 @@ const SCEV* ScalarEvolution::getZeroExtendExpr(const SCEV* Op,
|
||||
"This is not a conversion to a SCEVable type!");
|
||||
Ty = getEffectiveSCEVType(Ty);
|
||||
|
||||
// Fold if the operand is constant.
|
||||
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(Op)) {
|
||||
const Type *IntTy = getEffectiveSCEVType(Ty);
|
||||
Constant *C = ConstantExpr::getZExt(SC->getValue(), IntTy);
|
||||
@ -808,9 +865,16 @@ const SCEV* ScalarEvolution::getZeroExtendExpr(const SCEV* Op,
|
||||
}
|
||||
}
|
||||
|
||||
SCEVZeroExtendExpr *&Result = SCEVZeroExtends[std::make_pair(Op, Ty)];
|
||||
if (Result == 0) Result = new SCEVZeroExtendExpr(Op, Ty);
|
||||
return Result;
|
||||
FoldingSetNodeID ID;
|
||||
ID.AddInteger(scZeroExtend);
|
||||
ID.AddPointer(Op);
|
||||
ID.AddPointer(Ty);
|
||||
void *IP = 0;
|
||||
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
|
||||
SCEV *S = SCEVAllocator.Allocate<SCEVZeroExtendExpr>();
|
||||
new (S) SCEVZeroExtendExpr(Op, Ty);
|
||||
UniqueSCEVs.InsertNode(S, IP);
|
||||
return S;
|
||||
}
|
||||
|
||||
const SCEV* ScalarEvolution::getSignExtendExpr(const SCEV* Op,
|
||||
@ -821,6 +885,7 @@ const SCEV* ScalarEvolution::getSignExtendExpr(const SCEV* Op,
|
||||
"This is not a conversion to a SCEVable type!");
|
||||
Ty = getEffectiveSCEVType(Ty);
|
||||
|
||||
// Fold if the operand is constant.
|
||||
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(Op)) {
|
||||
const Type *IntTy = getEffectiveSCEVType(Ty);
|
||||
Constant *C = ConstantExpr::getSExt(SC->getValue(), IntTy);
|
||||
@ -880,9 +945,16 @@ const SCEV* ScalarEvolution::getSignExtendExpr(const SCEV* Op,
|
||||
}
|
||||
}
|
||||
|
||||
SCEVSignExtendExpr *&Result = SCEVSignExtends[std::make_pair(Op, Ty)];
|
||||
if (Result == 0) Result = new SCEVSignExtendExpr(Op, Ty);
|
||||
return Result;
|
||||
FoldingSetNodeID ID;
|
||||
ID.AddInteger(scSignExtend);
|
||||
ID.AddPointer(Op);
|
||||
ID.AddPointer(Ty);
|
||||
void *IP = 0;
|
||||
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
|
||||
SCEV *S = SCEVAllocator.Allocate<SCEVSignExtendExpr>();
|
||||
new (S) SCEVSignExtendExpr(Op, Ty);
|
||||
UniqueSCEVs.InsertNode(S, IP);
|
||||
return S;
|
||||
}
|
||||
|
||||
/// getAnyExtendExpr - Return a SCEV for the given operand extended with
|
||||
@ -980,9 +1052,8 @@ CollectAddOperandsWithScales(DenseMap<const SCEV*, APInt> &M,
|
||||
SmallVector<const SCEV*, 4> MulOps(Mul->op_begin()+1, Mul->op_end());
|
||||
const SCEV* Key = SE.getMulExpr(MulOps);
|
||||
std::pair<DenseMap<const SCEV*, APInt>::iterator, bool> Pair =
|
||||
M.insert(std::make_pair(Key, APInt()));
|
||||
M.insert(std::make_pair(Key, NewScale));
|
||||
if (Pair.second) {
|
||||
Pair.first->second = NewScale;
|
||||
NewOps.push_back(Pair.first->first);
|
||||
} else {
|
||||
Pair.first->second += NewScale;
|
||||
@ -999,9 +1070,8 @@ CollectAddOperandsWithScales(DenseMap<const SCEV*, APInt> &M,
|
||||
} else {
|
||||
// An ordinary operand. Update the map.
|
||||
std::pair<DenseMap<const SCEV*, APInt>::iterator, bool> Pair =
|
||||
M.insert(std::make_pair(Ops[i], APInt()));
|
||||
M.insert(std::make_pair(Ops[i], Scale));
|
||||
if (Pair.second) {
|
||||
Pair.first->second = Scale;
|
||||
NewOps.push_back(Pair.first->first);
|
||||
} else {
|
||||
Pair.first->second += Scale;
|
||||
@ -1343,11 +1413,17 @@ const SCEV* ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV*> &Ops) {
|
||||
|
||||
// Okay, it looks like we really DO need an add expr. Check to see if we
|
||||
// already have one, otherwise create a new one.
|
||||
std::vector<const SCEV*> SCEVOps(Ops.begin(), Ops.end());
|
||||
SCEVCommutativeExpr *&Result = SCEVCommExprs[std::make_pair(scAddExpr,
|
||||
SCEVOps)];
|
||||
if (Result == 0) Result = new SCEVAddExpr(Ops);
|
||||
return Result;
|
||||
FoldingSetNodeID ID;
|
||||
ID.AddInteger(scAddExpr);
|
||||
ID.AddInteger(Ops.size());
|
||||
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
|
||||
ID.AddPointer(Ops[i]);
|
||||
void *IP = 0;
|
||||
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
|
||||
SCEV *S = SCEVAllocator.Allocate<SCEVAddExpr>();
|
||||
new (S) SCEVAddExpr(Ops);
|
||||
UniqueSCEVs.InsertNode(S, IP);
|
||||
return S;
|
||||
}
|
||||
|
||||
|
||||
@ -1508,12 +1584,17 @@ const SCEV* ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV*> &Ops) {
|
||||
|
||||
// Okay, it looks like we really DO need an mul expr. Check to see if we
|
||||
// already have one, otherwise create a new one.
|
||||
std::vector<const SCEV*> SCEVOps(Ops.begin(), Ops.end());
|
||||
SCEVCommutativeExpr *&Result = SCEVCommExprs[std::make_pair(scMulExpr,
|
||||
SCEVOps)];
|
||||
if (Result == 0)
|
||||
Result = new SCEVMulExpr(Ops);
|
||||
return Result;
|
||||
FoldingSetNodeID ID;
|
||||
ID.AddInteger(scMulExpr);
|
||||
ID.AddInteger(Ops.size());
|
||||
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
|
||||
ID.AddPointer(Ops[i]);
|
||||
void *IP = 0;
|
||||
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
|
||||
SCEV *S = SCEVAllocator.Allocate<SCEVMulExpr>();
|
||||
new (S) SCEVMulExpr(Ops);
|
||||
UniqueSCEVs.InsertNode(S, IP);
|
||||
return S;
|
||||
}
|
||||
|
||||
/// getUDivExpr - Get a canonical multiply expression, or something simpler if
|
||||
@ -1603,9 +1684,16 @@ const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS,
|
||||
}
|
||||
}
|
||||
|
||||
SCEVUDivExpr *&Result = SCEVUDivs[std::make_pair(LHS, RHS)];
|
||||
if (Result == 0) Result = new SCEVUDivExpr(LHS, RHS);
|
||||
return Result;
|
||||
FoldingSetNodeID ID;
|
||||
ID.AddInteger(scUDivExpr);
|
||||
ID.AddPointer(LHS);
|
||||
ID.AddPointer(RHS);
|
||||
void *IP = 0;
|
||||
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
|
||||
SCEV *S = SCEVAllocator.Allocate<SCEVUDivExpr>();
|
||||
new (S) SCEVUDivExpr(LHS, RHS);
|
||||
UniqueSCEVs.InsertNode(S, IP);
|
||||
return S;
|
||||
}
|
||||
|
||||
|
||||
@ -1677,10 +1765,18 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV*> &Operands,
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<const SCEV*> SCEVOps(Operands.begin(), Operands.end());
|
||||
SCEVAddRecExpr *&Result = SCEVAddRecExprs[std::make_pair(L, SCEVOps)];
|
||||
if (Result == 0) Result = new SCEVAddRecExpr(Operands, L);
|
||||
return Result;
|
||||
FoldingSetNodeID ID;
|
||||
ID.AddInteger(scAddRecExpr);
|
||||
ID.AddInteger(Operands.size());
|
||||
for (unsigned i = 0, e = Operands.size(); i != e; ++i)
|
||||
ID.AddPointer(Operands[i]);
|
||||
ID.AddPointer(L);
|
||||
void *IP = 0;
|
||||
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
|
||||
SCEV *S = SCEVAllocator.Allocate<SCEVAddRecExpr>();
|
||||
new (S) SCEVAddRecExpr(Operands, L);
|
||||
UniqueSCEVs.InsertNode(S, IP);
|
||||
return S;
|
||||
}
|
||||
|
||||
const SCEV *ScalarEvolution::getSMaxExpr(const SCEV *LHS,
|
||||
@ -1767,11 +1863,17 @@ ScalarEvolution::getSMaxExpr(SmallVectorImpl<const SCEV*> &Ops) {
|
||||
|
||||
// Okay, it looks like we really DO need an smax expr. Check to see if we
|
||||
// already have one, otherwise create a new one.
|
||||
std::vector<const SCEV*> SCEVOps(Ops.begin(), Ops.end());
|
||||
SCEVCommutativeExpr *&Result = SCEVCommExprs[std::make_pair(scSMaxExpr,
|
||||
SCEVOps)];
|
||||
if (Result == 0) Result = new SCEVSMaxExpr(Ops);
|
||||
return Result;
|
||||
FoldingSetNodeID ID;
|
||||
ID.AddInteger(scSMaxExpr);
|
||||
ID.AddInteger(Ops.size());
|
||||
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
|
||||
ID.AddPointer(Ops[i]);
|
||||
void *IP = 0;
|
||||
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
|
||||
SCEV *S = SCEVAllocator.Allocate<SCEVSMaxExpr>();
|
||||
new (S) SCEVSMaxExpr(Ops);
|
||||
UniqueSCEVs.InsertNode(S, IP);
|
||||
return S;
|
||||
}
|
||||
|
||||
const SCEV *ScalarEvolution::getUMaxExpr(const SCEV *LHS,
|
||||
@ -1858,11 +1960,17 @@ ScalarEvolution::getUMaxExpr(SmallVectorImpl<const SCEV*> &Ops) {
|
||||
|
||||
// Okay, it looks like we really DO need a umax expr. Check to see if we
|
||||
// already have one, otherwise create a new one.
|
||||
std::vector<const SCEV*> SCEVOps(Ops.begin(), Ops.end());
|
||||
SCEVCommutativeExpr *&Result = SCEVCommExprs[std::make_pair(scUMaxExpr,
|
||||
SCEVOps)];
|
||||
if (Result == 0) Result = new SCEVUMaxExpr(Ops);
|
||||
return Result;
|
||||
FoldingSetNodeID ID;
|
||||
ID.AddInteger(scUMaxExpr);
|
||||
ID.AddInteger(Ops.size());
|
||||
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
|
||||
ID.AddPointer(Ops[i]);
|
||||
void *IP = 0;
|
||||
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
|
||||
SCEV *S = SCEVAllocator.Allocate<SCEVUMaxExpr>();
|
||||
new (S) SCEVUMaxExpr(Ops);
|
||||
UniqueSCEVs.InsertNode(S, IP);
|
||||
return S;
|
||||
}
|
||||
|
||||
const SCEV *ScalarEvolution::getSMinExpr(const SCEV *LHS,
|
||||
@ -1883,9 +1991,15 @@ const SCEV* ScalarEvolution::getUnknown(Value *V) {
|
||||
// interesting possibilities, and any other code that calls getUnknown
|
||||
// is doing so in order to hide a value from SCEV canonicalization.
|
||||
|
||||
SCEVUnknown *&Result = SCEVUnknowns[V];
|
||||
if (Result == 0) Result = new SCEVUnknown(V);
|
||||
return Result;
|
||||
FoldingSetNodeID ID;
|
||||
ID.AddInteger(scUnknown);
|
||||
ID.AddPointer(V);
|
||||
void *IP = 0;
|
||||
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
|
||||
SCEV *S = SCEVAllocator.Allocate<SCEVUnknown>();
|
||||
new (S) SCEVUnknown(V);
|
||||
UniqueSCEVs.InsertNode(S, IP);
|
||||
return S;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -1939,7 +2053,7 @@ const Type *ScalarEvolution::getEffectiveSCEVType(const Type *Ty) const {
|
||||
}
|
||||
|
||||
const SCEV* ScalarEvolution::getCouldNotCompute() {
|
||||
return CouldNotCompute;
|
||||
return &CouldNotCompute;
|
||||
}
|
||||
|
||||
/// hasSCEV - Return true if the SCEV for this value has already been
|
||||
@ -2750,7 +2864,7 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
|
||||
BackedgeTakenCounts.insert(std::make_pair(L, getCouldNotCompute()));
|
||||
if (Pair.second) {
|
||||
BackedgeTakenInfo ItCount = ComputeBackedgeTakenCount(L);
|
||||
if (ItCount.Exact != CouldNotCompute) {
|
||||
if (ItCount.Exact != getCouldNotCompute()) {
|
||||
assert(ItCount.Exact->isLoopInvariant(L) &&
|
||||
ItCount.Max->isLoopInvariant(L) &&
|
||||
"Computed trip count isn't loop invariant for loop!");
|
||||
@ -2759,7 +2873,7 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
|
||||
// Update the value in the map.
|
||||
Pair.first->second = ItCount;
|
||||
} else {
|
||||
if (ItCount.Max != CouldNotCompute)
|
||||
if (ItCount.Max != getCouldNotCompute())
|
||||
// Update the value in the map.
|
||||
Pair.first->second = ItCount;
|
||||
if (isa<PHINode>(L->getHeader()->begin()))
|
||||
@ -2825,27 +2939,27 @@ ScalarEvolution::ComputeBackedgeTakenCount(const Loop *L) {
|
||||
L->getExitingBlocks(ExitingBlocks);
|
||||
|
||||
// Examine all exits and pick the most conservative values.
|
||||
const SCEV* BECount = CouldNotCompute;
|
||||
const SCEV* MaxBECount = CouldNotCompute;
|
||||
const SCEV* BECount = getCouldNotCompute();
|
||||
const SCEV* MaxBECount = getCouldNotCompute();
|
||||
bool CouldNotComputeBECount = false;
|
||||
for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) {
|
||||
BackedgeTakenInfo NewBTI =
|
||||
ComputeBackedgeTakenCountFromExit(L, ExitingBlocks[i]);
|
||||
|
||||
if (NewBTI.Exact == CouldNotCompute) {
|
||||
if (NewBTI.Exact == getCouldNotCompute()) {
|
||||
// We couldn't compute an exact value for this exit, so
|
||||
// we won't be able to compute an exact value for the loop.
|
||||
CouldNotComputeBECount = true;
|
||||
BECount = CouldNotCompute;
|
||||
BECount = getCouldNotCompute();
|
||||
} else if (!CouldNotComputeBECount) {
|
||||
if (BECount == CouldNotCompute)
|
||||
if (BECount == getCouldNotCompute())
|
||||
BECount = NewBTI.Exact;
|
||||
else
|
||||
BECount = getUMinFromMismatchedTypes(BECount, NewBTI.Exact);
|
||||
}
|
||||
if (MaxBECount == CouldNotCompute)
|
||||
if (MaxBECount == getCouldNotCompute())
|
||||
MaxBECount = NewBTI.Max;
|
||||
else if (NewBTI.Max != CouldNotCompute)
|
||||
else if (NewBTI.Max != getCouldNotCompute())
|
||||
MaxBECount = getUMinFromMismatchedTypes(MaxBECount, NewBTI.Max);
|
||||
}
|
||||
|
||||
@ -2863,7 +2977,7 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExit(const Loop *L,
|
||||
//
|
||||
// FIXME: we should be able to handle switch instructions (with a single exit)
|
||||
BranchInst *ExitBr = dyn_cast<BranchInst>(ExitingBlock->getTerminator());
|
||||
if (ExitBr == 0) return CouldNotCompute;
|
||||
if (ExitBr == 0) return getCouldNotCompute();
|
||||
assert(ExitBr->isConditional() && "If unconditional, it can't be in loop!");
|
||||
|
||||
// At this point, we know we have a conditional branch that determines whether
|
||||
@ -2892,7 +3006,7 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExit(const Loop *L,
|
||||
for (BasicBlock *BB = ExitBr->getParent(); BB; ) {
|
||||
BasicBlock *Pred = BB->getUniquePredecessor();
|
||||
if (!Pred)
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
TerminatorInst *PredTerm = Pred->getTerminator();
|
||||
for (unsigned i = 0, e = PredTerm->getNumSuccessors(); i != e; ++i) {
|
||||
BasicBlock *PredSucc = PredTerm->getSuccessor(i);
|
||||
@ -2901,7 +3015,7 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExit(const Loop *L,
|
||||
// If the predecessor has a successor that isn't BB and isn't
|
||||
// outside the loop, assume the worst.
|
||||
if (L->contains(PredSucc))
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
}
|
||||
if (Pred == L->getHeader()) {
|
||||
Ok = true;
|
||||
@ -2910,7 +3024,7 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExit(const Loop *L,
|
||||
BB = Pred;
|
||||
}
|
||||
if (!Ok)
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
}
|
||||
|
||||
// Procede to the next level to examine the exit condition expression.
|
||||
@ -2935,27 +3049,30 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExitCond(const Loop *L,
|
||||
ComputeBackedgeTakenCountFromExitCond(L, BO->getOperand(0), TBB, FBB);
|
||||
BackedgeTakenInfo BTI1 =
|
||||
ComputeBackedgeTakenCountFromExitCond(L, BO->getOperand(1), TBB, FBB);
|
||||
const SCEV* BECount = CouldNotCompute;
|
||||
const SCEV* MaxBECount = CouldNotCompute;
|
||||
const SCEV* BECount = getCouldNotCompute();
|
||||
const SCEV* MaxBECount = getCouldNotCompute();
|
||||
if (L->contains(TBB)) {
|
||||
// Both conditions must be true for the loop to continue executing.
|
||||
// Choose the less conservative count.
|
||||
if (BTI0.Exact == CouldNotCompute || BTI1.Exact == CouldNotCompute)
|
||||
BECount = CouldNotCompute;
|
||||
if (BTI0.Exact == getCouldNotCompute() ||
|
||||
BTI1.Exact == getCouldNotCompute())
|
||||
BECount = getCouldNotCompute();
|
||||
else
|
||||
BECount = getUMinFromMismatchedTypes(BTI0.Exact, BTI1.Exact);
|
||||
if (BTI0.Max == CouldNotCompute)
|
||||
if (BTI0.Max == getCouldNotCompute())
|
||||
MaxBECount = BTI1.Max;
|
||||
else if (BTI1.Max == CouldNotCompute)
|
||||
else if (BTI1.Max == getCouldNotCompute())
|
||||
MaxBECount = BTI0.Max;
|
||||
else
|
||||
MaxBECount = getUMinFromMismatchedTypes(BTI0.Max, BTI1.Max);
|
||||
} else {
|
||||
// Both conditions must be true for the loop to exit.
|
||||
assert(L->contains(FBB) && "Loop block has no successor in loop!");
|
||||
if (BTI0.Exact != CouldNotCompute && BTI1.Exact != CouldNotCompute)
|
||||
if (BTI0.Exact != getCouldNotCompute() &&
|
||||
BTI1.Exact != getCouldNotCompute())
|
||||
BECount = getUMaxFromMismatchedTypes(BTI0.Exact, BTI1.Exact);
|
||||
if (BTI0.Max != CouldNotCompute && BTI1.Max != CouldNotCompute)
|
||||
if (BTI0.Max != getCouldNotCompute() &&
|
||||
BTI1.Max != getCouldNotCompute())
|
||||
MaxBECount = getUMaxFromMismatchedTypes(BTI0.Max, BTI1.Max);
|
||||
}
|
||||
|
||||
@ -2967,27 +3084,30 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExitCond(const Loop *L,
|
||||
ComputeBackedgeTakenCountFromExitCond(L, BO->getOperand(0), TBB, FBB);
|
||||
BackedgeTakenInfo BTI1 =
|
||||
ComputeBackedgeTakenCountFromExitCond(L, BO->getOperand(1), TBB, FBB);
|
||||
const SCEV* BECount = CouldNotCompute;
|
||||
const SCEV* MaxBECount = CouldNotCompute;
|
||||
const SCEV* BECount = getCouldNotCompute();
|
||||
const SCEV* MaxBECount = getCouldNotCompute();
|
||||
if (L->contains(FBB)) {
|
||||
// Both conditions must be false for the loop to continue executing.
|
||||
// Choose the less conservative count.
|
||||
if (BTI0.Exact == CouldNotCompute || BTI1.Exact == CouldNotCompute)
|
||||
BECount = CouldNotCompute;
|
||||
if (BTI0.Exact == getCouldNotCompute() ||
|
||||
BTI1.Exact == getCouldNotCompute())
|
||||
BECount = getCouldNotCompute();
|
||||
else
|
||||
BECount = getUMinFromMismatchedTypes(BTI0.Exact, BTI1.Exact);
|
||||
if (BTI0.Max == CouldNotCompute)
|
||||
if (BTI0.Max == getCouldNotCompute())
|
||||
MaxBECount = BTI1.Max;
|
||||
else if (BTI1.Max == CouldNotCompute)
|
||||
else if (BTI1.Max == getCouldNotCompute())
|
||||
MaxBECount = BTI0.Max;
|
||||
else
|
||||
MaxBECount = getUMinFromMismatchedTypes(BTI0.Max, BTI1.Max);
|
||||
} else {
|
||||
// Both conditions must be false for the loop to exit.
|
||||
assert(L->contains(TBB) && "Loop block has no successor in loop!");
|
||||
if (BTI0.Exact != CouldNotCompute && BTI1.Exact != CouldNotCompute)
|
||||
if (BTI0.Exact != getCouldNotCompute() &&
|
||||
BTI1.Exact != getCouldNotCompute())
|
||||
BECount = getUMaxFromMismatchedTypes(BTI0.Exact, BTI1.Exact);
|
||||
if (BTI0.Max != CouldNotCompute && BTI1.Max != CouldNotCompute)
|
||||
if (BTI0.Max != getCouldNotCompute() &&
|
||||
BTI1.Max != getCouldNotCompute())
|
||||
MaxBECount = getUMaxFromMismatchedTypes(BTI0.Max, BTI1.Max);
|
||||
}
|
||||
|
||||
@ -3164,11 +3284,11 @@ ScalarEvolution::ComputeLoadConstantCompareBackedgeTakenCount(
|
||||
Constant *RHS,
|
||||
const Loop *L,
|
||||
ICmpInst::Predicate predicate) {
|
||||
if (LI->isVolatile()) return CouldNotCompute;
|
||||
if (LI->isVolatile()) return getCouldNotCompute();
|
||||
|
||||
// Check to see if the loaded pointer is a getelementptr of a global.
|
||||
GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(LI->getOperand(0));
|
||||
if (!GEP) return CouldNotCompute;
|
||||
if (!GEP) return getCouldNotCompute();
|
||||
|
||||
// Make sure that it is really a constant global we are gepping, with an
|
||||
// initializer, and make sure the first IDX is really 0.
|
||||
@ -3176,7 +3296,7 @@ ScalarEvolution::ComputeLoadConstantCompareBackedgeTakenCount(
|
||||
if (!GV || !GV->isConstant() || !GV->hasInitializer() ||
|
||||
GEP->getNumOperands() < 3 || !isa<Constant>(GEP->getOperand(1)) ||
|
||||
!cast<Constant>(GEP->getOperand(1))->isNullValue())
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
|
||||
// Okay, we allow one non-constant index into the GEP instruction.
|
||||
Value *VarIdx = 0;
|
||||
@ -3186,7 +3306,7 @@ ScalarEvolution::ComputeLoadConstantCompareBackedgeTakenCount(
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(i))) {
|
||||
Indexes.push_back(CI);
|
||||
} else if (!isa<ConstantInt>(GEP->getOperand(i))) {
|
||||
if (VarIdx) return CouldNotCompute; // Multiple non-constant idx's.
|
||||
if (VarIdx) return getCouldNotCompute(); // Multiple non-constant idx's.
|
||||
VarIdx = GEP->getOperand(i);
|
||||
VarIdxNum = i-2;
|
||||
Indexes.push_back(0);
|
||||
@ -3203,7 +3323,7 @@ ScalarEvolution::ComputeLoadConstantCompareBackedgeTakenCount(
|
||||
if (!IdxExpr || !IdxExpr->isAffine() || IdxExpr->isLoopInvariant(L) ||
|
||||
!isa<SCEVConstant>(IdxExpr->getOperand(0)) ||
|
||||
!isa<SCEVConstant>(IdxExpr->getOperand(1)))
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
|
||||
unsigned MaxSteps = MaxBruteForceIterations;
|
||||
for (unsigned IterationNum = 0; IterationNum != MaxSteps; ++IterationNum) {
|
||||
@ -3230,7 +3350,7 @@ ScalarEvolution::ComputeLoadConstantCompareBackedgeTakenCount(
|
||||
return getConstant(ItCst); // Found terminating iteration!
|
||||
}
|
||||
}
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
}
|
||||
|
||||
|
||||
@ -3371,13 +3491,13 @@ ScalarEvolution::getConstantEvolutionLoopExitValue(PHINode *PN,
|
||||
/// constant number of times (the condition evolves only from constants),
|
||||
/// 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.
|
||||
/// evaluate the trip count of the loop, return getCouldNotCompute().
|
||||
const SCEV *
|
||||
ScalarEvolution::ComputeBackedgeTakenCountExhaustively(const Loop *L,
|
||||
Value *Cond,
|
||||
bool ExitWhen) {
|
||||
PHINode *PN = getConstantEvolvingPHI(Cond, L);
|
||||
if (PN == 0) return CouldNotCompute;
|
||||
if (PN == 0) return getCouldNotCompute();
|
||||
|
||||
// Since the loop is canonicalized, the PHI node must have two entries. One
|
||||
// entry must be a constant (coming in from outside of the loop), and the
|
||||
@ -3385,11 +3505,11 @@ ScalarEvolution::ComputeBackedgeTakenCountExhaustively(const Loop *L,
|
||||
bool SecondIsBackedge = L->contains(PN->getIncomingBlock(1));
|
||||
Constant *StartCST =
|
||||
dyn_cast<Constant>(PN->getIncomingValue(!SecondIsBackedge));
|
||||
if (StartCST == 0) return CouldNotCompute; // Must be a constant.
|
||||
if (StartCST == 0) return getCouldNotCompute(); // Must be a constant.
|
||||
|
||||
Value *BEValue = PN->getIncomingValue(SecondIsBackedge);
|
||||
PHINode *PN2 = getConstantEvolvingPHI(BEValue, L);
|
||||
if (PN2 != PN) return CouldNotCompute; // Not derived from same PHI.
|
||||
if (PN2 != PN) return getCouldNotCompute(); // Not derived from same PHI.
|
||||
|
||||
// Okay, we find a PHI node that defines the trip count of this loop. Execute
|
||||
// the loop symbolically to determine when the condition gets a value of
|
||||
@ -3402,10 +3522,9 @@ ScalarEvolution::ComputeBackedgeTakenCountExhaustively(const Loop *L,
|
||||
dyn_cast_or_null<ConstantInt>(EvaluateExpression(Cond, PHIVal));
|
||||
|
||||
// Couldn't symbolically evaluate.
|
||||
if (!CondVal) return CouldNotCompute;
|
||||
if (!CondVal) return getCouldNotCompute();
|
||||
|
||||
if (CondVal->getValue() == uint64_t(ExitWhen)) {
|
||||
ConstantEvolutionLoopExitValue[PN] = PHIVal;
|
||||
++NumBruteForceTripCountsComputed;
|
||||
return getConstant(Type::Int32Ty, IterationNum);
|
||||
}
|
||||
@ -3413,12 +3532,12 @@ ScalarEvolution::ComputeBackedgeTakenCountExhaustively(const Loop *L,
|
||||
// Compute the value of the PHI node for the next iteration.
|
||||
Constant *NextPHI = EvaluateExpression(BEValue, PHIVal);
|
||||
if (NextPHI == 0 || NextPHI == PHIVal)
|
||||
return CouldNotCompute; // Couldn't evaluate or not making progress...
|
||||
return getCouldNotCompute();// Couldn't evaluate or not making progress...
|
||||
PHIVal = NextPHI;
|
||||
}
|
||||
|
||||
// Too many iterations were needed to evaluate.
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
}
|
||||
|
||||
/// getSCEVAtScope - Return a SCEV expression handle for the specified value
|
||||
@ -3457,7 +3576,7 @@ const SCEV* ScalarEvolution::getSCEVAtScope(const SCEV *V, const Loop *L) {
|
||||
Constant *RV = getConstantEvolutionLoopExitValue(PN,
|
||||
BTCC->getValue()->getValue(),
|
||||
LI);
|
||||
if (RV) return getUnknown(RV);
|
||||
if (RV) return getSCEV(RV);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3471,7 +3590,7 @@ const SCEV* ScalarEvolution::getSCEVAtScope(const SCEV *V, const Loop *L) {
|
||||
std::pair<std::map<const Loop *, Constant *>::iterator, bool> Pair =
|
||||
Values.insert(std::make_pair(L, static_cast<Constant *>(0)));
|
||||
if (!Pair.second)
|
||||
return Pair.first->second ? &*getUnknown(Pair.first->second) : V;
|
||||
return Pair.first->second ? &*getSCEV(Pair.first->second) : V;
|
||||
|
||||
std::vector<Constant*> Operands;
|
||||
Operands.reserve(I->getNumOperands());
|
||||
@ -3520,7 +3639,7 @@ const SCEV* ScalarEvolution::getSCEVAtScope(const SCEV *V, const Loop *L) {
|
||||
C = ConstantFoldInstOperands(I->getOpcode(), I->getType(),
|
||||
&Operands[0], Operands.size());
|
||||
Pair.first->second = C;
|
||||
return getUnknown(C);
|
||||
return getSCEV(C);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3574,7 +3693,7 @@ const SCEV* ScalarEvolution::getSCEVAtScope(const SCEV *V, const Loop *L) {
|
||||
// To evaluate this recurrence, we need to know how many times the AddRec
|
||||
// loop iterates. Compute this now.
|
||||
const SCEV* BackedgeTakenCount = getBackedgeTakenCount(AddRec->getLoop());
|
||||
if (BackedgeTakenCount == CouldNotCompute) return AddRec;
|
||||
if (BackedgeTakenCount == getCouldNotCompute()) return AddRec;
|
||||
|
||||
// Then, evaluate the AddRec.
|
||||
return AddRec->evaluateAtIteration(BackedgeTakenCount, *this);
|
||||
@ -3729,12 +3848,12 @@ const SCEV* ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) {
|
||||
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(V)) {
|
||||
// If the value is already zero, the branch will execute zero times.
|
||||
if (C->getValue()->isZero()) return C;
|
||||
return CouldNotCompute; // Otherwise it will loop infinitely.
|
||||
return getCouldNotCompute(); // Otherwise it will loop infinitely.
|
||||
}
|
||||
|
||||
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(V);
|
||||
if (!AddRec || AddRec->getLoop() != L)
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
|
||||
if (AddRec->isAffine()) {
|
||||
// If this is an affine expression, the execution count of this branch is
|
||||
@ -3798,7 +3917,7 @@ const SCEV* ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) {
|
||||
}
|
||||
}
|
||||
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
}
|
||||
|
||||
/// HowFarToNonZero - Return the number of times a backedge checking the
|
||||
@ -3814,12 +3933,12 @@ const SCEV* ScalarEvolution::HowFarToNonZero(const SCEV *V, const Loop *L) {
|
||||
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(V)) {
|
||||
if (!C->getValue()->isNullValue())
|
||||
return getIntegerSCEV(0, C->getType());
|
||||
return CouldNotCompute; // Otherwise it will loop infinitely.
|
||||
return getCouldNotCompute(); // Otherwise it will loop infinitely.
|
||||
}
|
||||
|
||||
// We could implement others, but I really doubt anyone writes loops like
|
||||
// this, and if they did, they would already be constant folded.
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
}
|
||||
|
||||
/// getLoopPredecessor - If the given loop's header has exactly one unique
|
||||
@ -4037,7 +4156,7 @@ const SCEV* ScalarEvolution::getBECount(const SCEV* Start,
|
||||
getAddExpr(getZeroExtendExpr(Diff, WideTy),
|
||||
getZeroExtendExpr(RoundUp, WideTy));
|
||||
if (getZeroExtendExpr(Add, WideTy) != OperandExtendedAdd)
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
|
||||
return getUDivExpr(Add, Step);
|
||||
}
|
||||
@ -4049,11 +4168,11 @@ ScalarEvolution::BackedgeTakenInfo
|
||||
ScalarEvolution::HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
|
||||
const Loop *L, bool isSigned) {
|
||||
// Only handle: "ADDREC < LoopInvariant".
|
||||
if (!RHS->isLoopInvariant(L)) return CouldNotCompute;
|
||||
if (!RHS->isLoopInvariant(L)) return getCouldNotCompute();
|
||||
|
||||
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(LHS);
|
||||
if (!AddRec || AddRec->getLoop() != L)
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
|
||||
if (AddRec->isAffine()) {
|
||||
// FORNOW: We only support unit strides.
|
||||
@ -4063,7 +4182,7 @@ ScalarEvolution::HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
|
||||
// TODO: handle non-constant strides.
|
||||
const SCEVConstant *CStep = dyn_cast<SCEVConstant>(Step);
|
||||
if (!CStep || CStep->isZero())
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
if (CStep->isOne()) {
|
||||
// With unit stride, the iteration never steps past the limit value.
|
||||
} else if (CStep->getValue()->getValue().isStrictlyPositive()) {
|
||||
@ -4074,19 +4193,19 @@ ScalarEvolution::HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
|
||||
APInt Max = APInt::getSignedMaxValue(BitWidth);
|
||||
if ((Max - CStep->getValue()->getValue())
|
||||
.slt(CLimit->getValue()->getValue()))
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
} else {
|
||||
APInt Max = APInt::getMaxValue(BitWidth);
|
||||
if ((Max - CStep->getValue()->getValue())
|
||||
.ult(CLimit->getValue()->getValue()))
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
}
|
||||
} else
|
||||
// TODO: handle non-constant limit values below.
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
} else
|
||||
// TODO: handle negative strides below.
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
|
||||
// We know the LHS is of the form {n,+,s} and the RHS is some loop-invariant
|
||||
// m. So, we count the number of iterations in which {n,+,s} < m is true.
|
||||
@ -4126,12 +4245,12 @@ ScalarEvolution::HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
|
||||
|
||||
// The maximum backedge count is similar, except using the minimum start
|
||||
// value and the maximum end value.
|
||||
const SCEV* MaxBECount = getBECount(MinStart, MaxEnd, Step);;
|
||||
const SCEV* MaxBECount = getBECount(MinStart, MaxEnd, Step);
|
||||
|
||||
return BackedgeTakenInfo(BECount, MaxBECount);
|
||||
}
|
||||
|
||||
return CouldNotCompute;
|
||||
return getCouldNotCompute();
|
||||
}
|
||||
|
||||
/// getNumIterationsInRange - Return the number of iterations of this loop that
|
||||
@ -4319,7 +4438,7 @@ ScalarEvolution::SCEVCallbackVH::SCEVCallbackVH(Value *V, ScalarEvolution *se)
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
ScalarEvolution::ScalarEvolution()
|
||||
: FunctionPass(&ID), CouldNotCompute(new SCEVCouldNotCompute()) {
|
||||
: FunctionPass(&ID) {
|
||||
}
|
||||
|
||||
bool ScalarEvolution::runOnFunction(Function &F) {
|
||||
@ -4334,45 +4453,8 @@ void ScalarEvolution::releaseMemory() {
|
||||
BackedgeTakenCounts.clear();
|
||||
ConstantEvolutionLoopExitValue.clear();
|
||||
ValuesAtScopes.clear();
|
||||
|
||||
for (std::map<ConstantInt*, SCEVConstant*>::iterator
|
||||
I = SCEVConstants.begin(), E = SCEVConstants.end(); I != E; ++I)
|
||||
delete I->second;
|
||||
for (std::map<std::pair<const SCEV*, const Type*>,
|
||||
SCEVTruncateExpr*>::iterator I = SCEVTruncates.begin(),
|
||||
E = SCEVTruncates.end(); I != E; ++I)
|
||||
delete I->second;
|
||||
for (std::map<std::pair<const SCEV*, const Type*>,
|
||||
SCEVZeroExtendExpr*>::iterator I = SCEVZeroExtends.begin(),
|
||||
E = SCEVZeroExtends.end(); I != E; ++I)
|
||||
delete I->second;
|
||||
for (std::map<std::pair<unsigned, std::vector<const SCEV*> >,
|
||||
SCEVCommutativeExpr*>::iterator I = SCEVCommExprs.begin(),
|
||||
E = SCEVCommExprs.end(); I != E; ++I)
|
||||
delete I->second;
|
||||
for (std::map<std::pair<const SCEV*, const SCEV*>, SCEVUDivExpr*>::iterator
|
||||
I = SCEVUDivs.begin(), E = SCEVUDivs.end(); I != E; ++I)
|
||||
delete I->second;
|
||||
for (std::map<std::pair<const SCEV*, const Type*>,
|
||||
SCEVSignExtendExpr*>::iterator I = SCEVSignExtends.begin(),
|
||||
E = SCEVSignExtends.end(); I != E; ++I)
|
||||
delete I->second;
|
||||
for (std::map<std::pair<const Loop *, std::vector<const SCEV*> >,
|
||||
SCEVAddRecExpr*>::iterator I = SCEVAddRecExprs.begin(),
|
||||
E = SCEVAddRecExprs.end(); I != E; ++I)
|
||||
delete I->second;
|
||||
for (std::map<Value*, SCEVUnknown*>::iterator I = SCEVUnknowns.begin(),
|
||||
E = SCEVUnknowns.end(); I != E; ++I)
|
||||
delete I->second;
|
||||
|
||||
SCEVConstants.clear();
|
||||
SCEVTruncates.clear();
|
||||
SCEVZeroExtends.clear();
|
||||
SCEVCommExprs.clear();
|
||||
SCEVUDivs.clear();
|
||||
SCEVSignExtends.clear();
|
||||
SCEVAddRecExprs.clear();
|
||||
SCEVUnknowns.clear();
|
||||
UniqueSCEVs.clear();
|
||||
SCEVAllocator.Reset();
|
||||
}
|
||||
|
||||
void ScalarEvolution::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
|
@ -19,16 +19,24 @@
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
using namespace llvm;
|
||||
|
||||
/// InsertCastOfTo - Insert a cast of V to the specified type, doing what
|
||||
/// we can to share the casts.
|
||||
Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V,
|
||||
const Type *Ty) {
|
||||
/// InsertNoopCastOfTo - Insert a cast of V to the specified type,
|
||||
/// which must be possible with a noop cast, doing what we can to share
|
||||
/// the casts.
|
||||
Value *SCEVExpander::InsertNoopCastOfTo(Value *V, const Type *Ty) {
|
||||
Instruction::CastOps Op = CastInst::getCastOpcode(V, false, Ty, false);
|
||||
assert((Op == Instruction::BitCast ||
|
||||
Op == Instruction::PtrToInt ||
|
||||
Op == Instruction::IntToPtr) &&
|
||||
"InsertNoopCastOfTo cannot perform non-noop casts!");
|
||||
assert(SE.getTypeSizeInBits(V->getType()) == SE.getTypeSizeInBits(Ty) &&
|
||||
"InsertNoopCastOfTo cannot change sizes!");
|
||||
|
||||
// Short-circuit unnecessary bitcasts.
|
||||
if (opcode == Instruction::BitCast && V->getType() == Ty)
|
||||
if (Op == Instruction::BitCast && V->getType() == Ty)
|
||||
return V;
|
||||
|
||||
// Short-circuit unnecessary inttoptr<->ptrtoint casts.
|
||||
if ((opcode == Instruction::PtrToInt || opcode == Instruction::IntToPtr) &&
|
||||
if ((Op == Instruction::PtrToInt || Op == Instruction::IntToPtr) &&
|
||||
SE.getTypeSizeInBits(Ty) == SE.getTypeSizeInBits(V->getType())) {
|
||||
if (CastInst *CI = dyn_cast<CastInst>(V))
|
||||
if ((CI->getOpcode() == Instruction::PtrToInt ||
|
||||
@ -46,7 +54,7 @@ Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V,
|
||||
|
||||
// FIXME: keep track of the cast instruction.
|
||||
if (Constant *C = dyn_cast<Constant>(V))
|
||||
return ConstantExpr::getCast(opcode, C, Ty);
|
||||
return ConstantExpr::getCast(Op, C, Ty);
|
||||
|
||||
if (Argument *A = dyn_cast<Argument>(V)) {
|
||||
// Check to see if there is already a cast!
|
||||
@ -54,7 +62,7 @@ Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V,
|
||||
UI != E; ++UI)
|
||||
if ((*UI)->getType() == Ty)
|
||||
if (CastInst *CI = dyn_cast<CastInst>(cast<Instruction>(*UI)))
|
||||
if (CI->getOpcode() == opcode) {
|
||||
if (CI->getOpcode() == Op) {
|
||||
// If the cast isn't the first instruction of the function, move it.
|
||||
if (BasicBlock::iterator(CI) !=
|
||||
A->getParent()->getEntryBlock().begin()) {
|
||||
@ -62,7 +70,7 @@ Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V,
|
||||
// The old cast is left in place in case it is being used
|
||||
// as an insert point.
|
||||
Instruction *NewCI =
|
||||
CastInst::Create(opcode, V, Ty, "",
|
||||
CastInst::Create(Op, V, Ty, "",
|
||||
A->getParent()->getEntryBlock().begin());
|
||||
NewCI->takeName(CI);
|
||||
CI->replaceAllUsesWith(NewCI);
|
||||
@ -71,7 +79,7 @@ Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V,
|
||||
return CI;
|
||||
}
|
||||
|
||||
Instruction *I = CastInst::Create(opcode, V, Ty, V->getName(),
|
||||
Instruction *I = CastInst::Create(Op, V, Ty, V->getName(),
|
||||
A->getParent()->getEntryBlock().begin());
|
||||
InsertedValues.insert(I);
|
||||
return I;
|
||||
@ -84,7 +92,7 @@ Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V,
|
||||
UI != E; ++UI) {
|
||||
if ((*UI)->getType() == Ty)
|
||||
if (CastInst *CI = dyn_cast<CastInst>(cast<Instruction>(*UI)))
|
||||
if (CI->getOpcode() == opcode) {
|
||||
if (CI->getOpcode() == Op) {
|
||||
BasicBlock::iterator It = I; ++It;
|
||||
if (isa<InvokeInst>(I))
|
||||
It = cast<InvokeInst>(I)->getNormalDest()->begin();
|
||||
@ -93,7 +101,7 @@ Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V,
|
||||
// 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);
|
||||
Instruction *NewCI = CastInst::Create(Op, V, Ty, "", It);
|
||||
NewCI->takeName(CI);
|
||||
CI->replaceAllUsesWith(NewCI);
|
||||
return NewCI;
|
||||
@ -105,28 +113,15 @@ Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V,
|
||||
if (InvokeInst *II = dyn_cast<InvokeInst>(I))
|
||||
IP = II->getNormalDest()->begin();
|
||||
while (isa<PHINode>(IP)) ++IP;
|
||||
Instruction *CI = CastInst::Create(opcode, V, Ty, V->getName(), IP);
|
||||
Instruction *CI = CastInst::Create(Op, V, Ty, V->getName(), IP);
|
||||
InsertedValues.insert(CI);
|
||||
return CI;
|
||||
}
|
||||
|
||||
/// InsertNoopCastOfTo - Insert a cast of V to the specified type,
|
||||
/// which must be possible with a noop cast.
|
||||
Value *SCEVExpander::InsertNoopCastOfTo(Value *V, const Type *Ty) {
|
||||
Instruction::CastOps Op = CastInst::getCastOpcode(V, false, Ty, false);
|
||||
assert((Op == Instruction::BitCast ||
|
||||
Op == Instruction::PtrToInt ||
|
||||
Op == Instruction::IntToPtr) &&
|
||||
"InsertNoopCastOfTo cannot perform non-noop casts!");
|
||||
assert(SE.getTypeSizeInBits(V->getType()) == SE.getTypeSizeInBits(Ty) &&
|
||||
"InsertNoopCastOfTo cannot change sizes!");
|
||||
return InsertCastOfTo(Op, V, Ty);
|
||||
}
|
||||
|
||||
/// InsertBinop - Insert the specified binary operator, doing a small amount
|
||||
/// of work to avoid inserting an obviously redundant operation.
|
||||
Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode, Value *LHS,
|
||||
Value *RHS, BasicBlock::iterator InsertPt) {
|
||||
Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode,
|
||||
Value *LHS, Value *RHS) {
|
||||
// Fold a binop with constant operands.
|
||||
if (Constant *CLHS = dyn_cast<Constant>(LHS))
|
||||
if (Constant *CRHS = dyn_cast<Constant>(RHS))
|
||||
@ -134,10 +129,10 @@ Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode, Value *LHS,
|
||||
|
||||
// Do a quick scan to see if we have this binop nearby. If so, reuse it.
|
||||
unsigned ScanLimit = 6;
|
||||
BasicBlock::iterator BlockBegin = InsertPt->getParent()->begin();
|
||||
if (InsertPt != BlockBegin) {
|
||||
// Scanning starts from the last instruction before InsertPt.
|
||||
BasicBlock::iterator IP = InsertPt;
|
||||
BasicBlock::iterator BlockBegin = Builder.GetInsertBlock()->begin();
|
||||
// Scanning starts from the last instruction before the insertion point.
|
||||
BasicBlock::iterator IP = Builder.GetInsertPoint();
|
||||
if (IP != BlockBegin) {
|
||||
--IP;
|
||||
for (; ScanLimit; --IP, --ScanLimit) {
|
||||
if (IP->getOpcode() == (unsigned)Opcode && IP->getOperand(0) == LHS &&
|
||||
@ -146,9 +141,9 @@ Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode, Value *LHS,
|
||||
if (IP == BlockBegin) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If we haven't found this binop, insert it.
|
||||
Instruction *BO = BinaryOperator::Create(Opcode, LHS, RHS, "tmp", InsertPt);
|
||||
Value *BO = Builder.CreateBinOp(Opcode, LHS, RHS, "tmp");
|
||||
InsertedValues.insert(BO);
|
||||
return BO;
|
||||
}
|
||||
@ -190,8 +185,9 @@ static bool FactorOutConstant(const SCEV* &S,
|
||||
if (const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(S))
|
||||
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(M->getOperand(0)))
|
||||
if (!C->getValue()->getValue().srem(Factor)) {
|
||||
const SmallVectorImpl<const SCEV*> &MOperands = M->getOperands();
|
||||
SmallVector<const SCEV*, 4> NewMulOps(MOperands.begin(), MOperands.end());
|
||||
const SmallVectorImpl<const SCEV *> &MOperands = M->getOperands();
|
||||
SmallVector<const SCEV *, 4> NewMulOps(MOperands.begin(),
|
||||
MOperands.end());
|
||||
NewMulOps[0] =
|
||||
SE.getConstant(C->getValue()->getValue().sdiv(Factor));
|
||||
S = SE.getMulExpr(NewMulOps);
|
||||
@ -336,10 +332,10 @@ Value *SCEVExpander::expandAddToGEP(const SCEV* const *op_begin,
|
||||
|
||||
// Do a quick scan to see if we have this GEP nearby. If so, reuse it.
|
||||
unsigned ScanLimit = 6;
|
||||
BasicBlock::iterator BlockBegin = InsertPt->getParent()->begin();
|
||||
if (InsertPt != BlockBegin) {
|
||||
// Scanning starts from the last instruction before InsertPt.
|
||||
BasicBlock::iterator IP = InsertPt;
|
||||
BasicBlock::iterator BlockBegin = Builder.GetInsertBlock()->begin();
|
||||
// Scanning starts from the last instruction before the insertion point.
|
||||
BasicBlock::iterator IP = Builder.GetInsertPoint();
|
||||
if (IP != BlockBegin) {
|
||||
--IP;
|
||||
for (; ScanLimit; --IP, --ScanLimit) {
|
||||
if (IP->getOpcode() == Instruction::GetElementPtr &&
|
||||
@ -349,16 +345,16 @@ Value *SCEVExpander::expandAddToGEP(const SCEV* const *op_begin,
|
||||
}
|
||||
}
|
||||
|
||||
Value *GEP = GetElementPtrInst::Create(V, Idx, "scevgep", InsertPt);
|
||||
Value *GEP = Builder.CreateGEP(V, Idx, "scevgep");
|
||||
InsertedValues.insert(GEP);
|
||||
return GEP;
|
||||
}
|
||||
|
||||
// Insert a pretty getelementptr.
|
||||
Value *GEP = GetElementPtrInst::Create(V,
|
||||
GepIndices.begin(),
|
||||
GepIndices.end(),
|
||||
"scevgep", InsertPt);
|
||||
Value *GEP = Builder.CreateGEP(V,
|
||||
GepIndices.begin(),
|
||||
GepIndices.end(),
|
||||
"scevgep");
|
||||
Ops.push_back(SE.getUnknown(GEP));
|
||||
InsertedValues.insert(GEP);
|
||||
return expand(SE.getAddExpr(Ops));
|
||||
@ -373,8 +369,7 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) {
|
||||
if (SE.TD)
|
||||
if (const PointerType *PTy = dyn_cast<PointerType>(V->getType())) {
|
||||
const SmallVectorImpl<const SCEV*> &Ops = S->getOperands();
|
||||
return expandAddToGEP(&Ops[0], &Ops[Ops.size() - 1],
|
||||
PTy, Ty, V);
|
||||
return expandAddToGEP(&Ops[0], &Ops[Ops.size() - 1], PTy, Ty, V);
|
||||
}
|
||||
|
||||
V = InsertNoopCastOfTo(V, Ty);
|
||||
@ -382,7 +377,7 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) {
|
||||
// Emit a bunch of add instructions
|
||||
for (int i = S->getNumOperands()-2; i >= 0; --i) {
|
||||
Value *W = expandCodeFor(S->getOperand(i), Ty);
|
||||
V = InsertBinop(Instruction::Add, V, W, InsertPt);
|
||||
V = InsertBinop(Instruction::Add, V, W);
|
||||
}
|
||||
return V;
|
||||
}
|
||||
@ -400,12 +395,12 @@ Value *SCEVExpander::visitMulExpr(const SCEVMulExpr *S) {
|
||||
// Emit a bunch of multiply instructions
|
||||
for (; i >= FirstOp; --i) {
|
||||
Value *W = expandCodeFor(S->getOperand(i), Ty);
|
||||
V = InsertBinop(Instruction::Mul, V, W, InsertPt);
|
||||
V = InsertBinop(Instruction::Mul, V, W);
|
||||
}
|
||||
|
||||
// -1 * ... ---> 0 - ...
|
||||
if (FirstOp == 1)
|
||||
V = InsertBinop(Instruction::Sub, Constant::getNullValue(Ty), V, InsertPt);
|
||||
V = InsertBinop(Instruction::Sub, Constant::getNullValue(Ty), V);
|
||||
return V;
|
||||
}
|
||||
|
||||
@ -417,12 +412,11 @@ Value *SCEVExpander::visitUDivExpr(const SCEVUDivExpr *S) {
|
||||
const APInt &RHS = SC->getValue()->getValue();
|
||||
if (RHS.isPowerOf2())
|
||||
return InsertBinop(Instruction::LShr, LHS,
|
||||
ConstantInt::get(Ty, RHS.logBase2()),
|
||||
InsertPt);
|
||||
ConstantInt::get(Ty, RHS.logBase2()));
|
||||
}
|
||||
|
||||
Value *RHS = expandCodeFor(S->getRHS(), Ty);
|
||||
return InsertBinop(Instruction::UDiv, LHS, RHS, InsertPt);
|
||||
return InsertBinop(Instruction::UDiv, LHS, RHS);
|
||||
}
|
||||
|
||||
/// Move parts of Base into Rest to leave Base with the minimal
|
||||
@ -463,18 +457,19 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
|
||||
if (CanonicalIV &&
|
||||
SE.getTypeSizeInBits(CanonicalIV->getType()) >
|
||||
SE.getTypeSizeInBits(Ty)) {
|
||||
const SCEV* Start = SE.getAnyExtendExpr(S->getStart(),
|
||||
const SCEV *Start = SE.getAnyExtendExpr(S->getStart(),
|
||||
CanonicalIV->getType());
|
||||
const SCEV *Step = SE.getAnyExtendExpr(S->getStepRecurrence(SE),
|
||||
CanonicalIV->getType());
|
||||
const SCEV* Step = SE.getAnyExtendExpr(S->getStepRecurrence(SE),
|
||||
CanonicalIV->getType());
|
||||
Value *V = expand(SE.getAddRecExpr(Start, Step, S->getLoop()));
|
||||
BasicBlock::iterator SaveInsertPt = InsertPt;
|
||||
BasicBlock *SaveInsertBB = Builder.GetInsertBlock();
|
||||
BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint();
|
||||
BasicBlock::iterator NewInsertPt =
|
||||
next(BasicBlock::iterator(cast<Instruction>(V)));
|
||||
while (isa<PHINode>(NewInsertPt)) ++NewInsertPt;
|
||||
V = expandCodeFor(SE.getTruncateExpr(SE.getUnknown(V), Ty), 0,
|
||||
NewInsertPt);
|
||||
InsertPt = SaveInsertPt;
|
||||
Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt);
|
||||
return V;
|
||||
}
|
||||
|
||||
@ -524,9 +519,10 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
|
||||
// Create and insert the PHI node for the induction variable in the
|
||||
// specified loop.
|
||||
BasicBlock *Header = L->getHeader();
|
||||
BasicBlock *Preheader = L->getLoopPreheader();
|
||||
PHINode *PN = PHINode::Create(Ty, "indvar", Header->begin());
|
||||
InsertedValues.insert(PN);
|
||||
PN->addIncoming(Constant::getNullValue(Ty), L->getLoopPreheader());
|
||||
PN->addIncoming(Constant::getNullValue(Ty), Preheader);
|
||||
|
||||
pred_iterator HPI = pred_begin(Header);
|
||||
assert(HPI != pred_end(Header) && "Loop with zero preds???");
|
||||
@ -542,7 +538,7 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
|
||||
InsertedValues.insert(Add);
|
||||
|
||||
pred_iterator PI = pred_begin(Header);
|
||||
if (*PI == L->getLoopPreheader())
|
||||
if (*PI == Preheader)
|
||||
++PI;
|
||||
PN->addIncoming(Add, *PI);
|
||||
return PN;
|
||||
@ -587,7 +583,7 @@ Value *SCEVExpander::visitTruncateExpr(const SCEVTruncateExpr *S) {
|
||||
const Type *Ty = SE.getEffectiveSCEVType(S->getType());
|
||||
Value *V = expandCodeFor(S->getOperand(),
|
||||
SE.getEffectiveSCEVType(S->getOperand()->getType()));
|
||||
Instruction *I = new TruncInst(V, Ty, "tmp.", InsertPt);
|
||||
Value *I = Builder.CreateTrunc(V, Ty, "tmp");
|
||||
InsertedValues.insert(I);
|
||||
return I;
|
||||
}
|
||||
@ -596,7 +592,7 @@ Value *SCEVExpander::visitZeroExtendExpr(const SCEVZeroExtendExpr *S) {
|
||||
const Type *Ty = SE.getEffectiveSCEVType(S->getType());
|
||||
Value *V = expandCodeFor(S->getOperand(),
|
||||
SE.getEffectiveSCEVType(S->getOperand()->getType()));
|
||||
Instruction *I = new ZExtInst(V, Ty, "tmp.", InsertPt);
|
||||
Value *I = Builder.CreateZExt(V, Ty, "tmp");
|
||||
InsertedValues.insert(I);
|
||||
return I;
|
||||
}
|
||||
@ -605,7 +601,7 @@ Value *SCEVExpander::visitSignExtendExpr(const SCEVSignExtendExpr *S) {
|
||||
const Type *Ty = SE.getEffectiveSCEVType(S->getType());
|
||||
Value *V = expandCodeFor(S->getOperand(),
|
||||
SE.getEffectiveSCEVType(S->getOperand()->getType()));
|
||||
Instruction *I = new SExtInst(V, Ty, "tmp.", InsertPt);
|
||||
Value *I = Builder.CreateSExt(V, Ty, "tmp");
|
||||
InsertedValues.insert(I);
|
||||
return I;
|
||||
}
|
||||
@ -615,10 +611,9 @@ Value *SCEVExpander::visitSMaxExpr(const SCEVSMaxExpr *S) {
|
||||
Value *LHS = expandCodeFor(S->getOperand(0), Ty);
|
||||
for (unsigned i = 1; i < S->getNumOperands(); ++i) {
|
||||
Value *RHS = expandCodeFor(S->getOperand(i), Ty);
|
||||
Instruction *ICmp =
|
||||
new ICmpInst(ICmpInst::ICMP_SGT, LHS, RHS, "tmp", InsertPt);
|
||||
Value *ICmp = Builder.CreateICmpSGT(LHS, RHS, "tmp");
|
||||
InsertedValues.insert(ICmp);
|
||||
Instruction *Sel = SelectInst::Create(ICmp, LHS, RHS, "smax", InsertPt);
|
||||
Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "smax");
|
||||
InsertedValues.insert(Sel);
|
||||
LHS = Sel;
|
||||
}
|
||||
@ -630,10 +625,9 @@ Value *SCEVExpander::visitUMaxExpr(const SCEVUMaxExpr *S) {
|
||||
Value *LHS = expandCodeFor(S->getOperand(0), Ty);
|
||||
for (unsigned i = 1; i < S->getNumOperands(); ++i) {
|
||||
Value *RHS = expandCodeFor(S->getOperand(i), Ty);
|
||||
Instruction *ICmp =
|
||||
new ICmpInst(ICmpInst::ICMP_UGT, LHS, RHS, "tmp", InsertPt);
|
||||
Value *ICmp = Builder.CreateICmpUGT(LHS, RHS, "tmp");
|
||||
InsertedValues.insert(ICmp);
|
||||
Instruction *Sel = SelectInst::Create(ICmp, LHS, RHS, "umax", InsertPt);
|
||||
Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "umax");
|
||||
InsertedValues.insert(Sel);
|
||||
LHS = Sel;
|
||||
}
|
||||
@ -652,11 +646,10 @@ Value *SCEVExpander::expandCodeFor(const SCEV* SH, const Type *Ty) {
|
||||
}
|
||||
|
||||
Value *SCEVExpander::expand(const SCEV *S) {
|
||||
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()); ;
|
||||
Instruction *InsertPt = Builder.GetInsertPoint();
|
||||
for (Loop *L = SE.LI->getLoopFor(Builder.GetInsertBlock()); ;
|
||||
L = L->getParentLoop())
|
||||
if (S->isLoopInvariant(L)) {
|
||||
if (!L) break;
|
||||
@ -668,7 +661,8 @@ Value *SCEVExpander::expand(const SCEV *S) {
|
||||
// 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;
|
||||
while (isInsertedInstruction(InsertPt))
|
||||
InsertPt = next(BasicBlock::iterator(InsertPt));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -676,10 +670,12 @@ Value *SCEVExpander::expand(const SCEV *S) {
|
||||
std::map<std::pair<const SCEV *, Instruction *>,
|
||||
AssertingVH<Value> >::iterator I =
|
||||
InsertedExpressions.find(std::make_pair(S, InsertPt));
|
||||
if (I != InsertedExpressions.end()) {
|
||||
InsertPt = SaveInsertPt;
|
||||
if (I != InsertedExpressions.end())
|
||||
return I->second;
|
||||
}
|
||||
|
||||
BasicBlock *SaveInsertBB = Builder.GetInsertBlock();
|
||||
BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint();
|
||||
Builder.SetInsertPoint(InsertPt->getParent(), InsertPt);
|
||||
|
||||
// Expand the expression into instructions.
|
||||
Value *V = visit(S);
|
||||
@ -687,7 +683,7 @@ Value *SCEVExpander::expand(const SCEV *S) {
|
||||
// Remember the expanded value for this SCEV at this location.
|
||||
InsertedExpressions[std::make_pair(S, InsertPt)] = V;
|
||||
|
||||
InsertPt = SaveInsertPt;
|
||||
Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt);
|
||||
return V;
|
||||
}
|
||||
|
||||
@ -701,8 +697,10 @@ SCEVExpander::getOrInsertCanonicalInductionVariable(const Loop *L,
|
||||
assert(Ty->isInteger() && "Can only insert integer induction variables!");
|
||||
const SCEV* H = SE.getAddRecExpr(SE.getIntegerSCEV(0, Ty),
|
||||
SE.getIntegerSCEV(1, Ty), L);
|
||||
BasicBlock::iterator SaveInsertPt = InsertPt;
|
||||
BasicBlock *SaveInsertBB = Builder.GetInsertBlock();
|
||||
BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint();
|
||||
Value *V = expandCodeFor(H, 0, L->getHeader()->begin());
|
||||
InsertPt = SaveInsertPt;
|
||||
if (SaveInsertBB)
|
||||
Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt);
|
||||
return V;
|
||||
}
|
||||
|
@ -249,7 +249,10 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
|
||||
}
|
||||
case Instruction::BitCast: {
|
||||
const Type *SrcTy = I->getOperand(0)->getType();
|
||||
if (SrcTy->isInteger() || isa<PointerType>(SrcTy)) {
|
||||
if ((SrcTy->isInteger() || isa<PointerType>(SrcTy)) &&
|
||||
// TODO: For now, not handling conversions like:
|
||||
// (bitcast i64 %x to <2 x i32>)
|
||||
!isa<VectorType>(I->getType())) {
|
||||
ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, TD,
|
||||
Depth+1);
|
||||
return;
|
||||
|
@ -138,9 +138,9 @@ bool ArchiveMember::replaceWith(const sys::Path& newFile, std::string* ErrMsg) {
|
||||
// Archive constructor - this is the only constructor that gets used for the
|
||||
// Archive class. Everything else (default,copy) is deprecated. This just
|
||||
// initializes and maps the file into memory, if requested.
|
||||
Archive::Archive(const sys::Path& filename)
|
||||
Archive::Archive(const sys::Path& filename, LLVMContext& C)
|
||||
: archPath(filename), members(), mapfile(0), base(0), symTab(), strtab(),
|
||||
symTabSize(0), firstFileOffset(0), modules(), foreignST(0) {
|
||||
symTabSize(0), firstFileOffset(0), modules(), foreignST(0), Context(C) {
|
||||
}
|
||||
|
||||
bool
|
||||
@ -208,6 +208,7 @@ static void getSymbols(Module*M, std::vector<std::string>& symbols) {
|
||||
|
||||
// Get just the externally visible defined symbols from the bitcode
|
||||
bool llvm::GetBitcodeSymbols(const sys::Path& fName,
|
||||
LLVMContext& Context,
|
||||
std::vector<std::string>& symbols,
|
||||
std::string* ErrMsg) {
|
||||
std::auto_ptr<MemoryBuffer> Buffer(
|
||||
@ -217,7 +218,7 @@ bool llvm::GetBitcodeSymbols(const sys::Path& fName,
|
||||
return true;
|
||||
}
|
||||
|
||||
ModuleProvider *MP = getBitcodeModuleProvider(Buffer.get(), ErrMsg);
|
||||
ModuleProvider *MP = getBitcodeModuleProvider(Buffer.get(), Context, ErrMsg);
|
||||
if (!MP)
|
||||
return true;
|
||||
|
||||
@ -239,13 +240,14 @@ bool llvm::GetBitcodeSymbols(const sys::Path& fName,
|
||||
ModuleProvider*
|
||||
llvm::GetBitcodeSymbols(const unsigned char *BufPtr, unsigned Length,
|
||||
const std::string& ModuleID,
|
||||
LLVMContext& Context,
|
||||
std::vector<std::string>& symbols,
|
||||
std::string* ErrMsg) {
|
||||
// Get the module provider
|
||||
MemoryBuffer *Buffer =MemoryBuffer::getNewMemBuffer(Length, ModuleID.c_str());
|
||||
memcpy((char*)Buffer->getBufferStart(), BufPtr, Length);
|
||||
|
||||
ModuleProvider *MP = getBitcodeModuleProvider(Buffer, ErrMsg);
|
||||
ModuleProvider *MP = getBitcodeModuleProvider(Buffer, Context, ErrMsg);
|
||||
if (!MP)
|
||||
return 0;
|
||||
|
||||
|
@ -31,6 +31,8 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class LLVMContext;
|
||||
|
||||
/// The ArchiveMemberHeader structure is used internally for bitcode
|
||||
/// archives.
|
||||
/// The header precedes each file member in the archive. This structure is
|
||||
@ -71,11 +73,13 @@ namespace llvm {
|
||||
|
||||
// Get just the externally visible defined symbols from the bitcode
|
||||
bool GetBitcodeSymbols(const sys::Path& fName,
|
||||
LLVMContext& Context,
|
||||
std::vector<std::string>& symbols,
|
||||
std::string* ErrMsg);
|
||||
|
||||
ModuleProvider* GetBitcodeSymbols(const unsigned char*Buffer,unsigned Length,
|
||||
const std::string& ModuleID,
|
||||
LLVMContext& Context,
|
||||
std::vector<std::string>& symbols,
|
||||
std::string* ErrMsg);
|
||||
}
|
||||
|
@ -327,9 +327,9 @@ Archive::loadArchive(std::string* error) {
|
||||
|
||||
// Open and completely load the archive file.
|
||||
Archive*
|
||||
Archive::OpenAndLoad(const sys::Path& file, std::string* ErrorMessage)
|
||||
{
|
||||
std::auto_ptr<Archive> result ( new Archive(file));
|
||||
Archive::OpenAndLoad(const sys::Path& file, LLVMContext& C,
|
||||
std::string* ErrorMessage) {
|
||||
std::auto_ptr<Archive> result ( new Archive(file, C));
|
||||
if (result->mapToMemory(ErrorMessage))
|
||||
return 0;
|
||||
if (!result->loadArchive(ErrorMessage))
|
||||
@ -339,7 +339,8 @@ Archive::OpenAndLoad(const sys::Path& file, std::string* ErrorMessage)
|
||||
|
||||
// Get all the bitcode modules from the archive
|
||||
bool
|
||||
Archive::getAllModules(std::vector<Module*>& Modules, std::string* ErrMessage) {
|
||||
Archive::getAllModules(std::vector<Module*>& Modules,
|
||||
std::string* ErrMessage) {
|
||||
|
||||
for (iterator I=begin(), E=end(); I != E; ++I) {
|
||||
if (I->isBitcode()) {
|
||||
@ -349,7 +350,7 @@ Archive::getAllModules(std::vector<Module*>& Modules, std::string* ErrMessage) {
|
||||
MemoryBuffer::getNewMemBuffer(I->getSize(), FullMemberName.c_str());
|
||||
memcpy((char*)Buffer->getBufferStart(), I->getData(), I->getSize());
|
||||
|
||||
Module *M = ParseBitcodeFile(Buffer, ErrMessage);
|
||||
Module *M = ParseBitcodeFile(Buffer, Context, ErrMessage);
|
||||
delete Buffer;
|
||||
if (!M)
|
||||
return true;
|
||||
@ -440,9 +441,10 @@ Archive::loadSymbolTable(std::string* ErrorMsg) {
|
||||
}
|
||||
|
||||
// Open the archive and load just the symbol tables
|
||||
Archive*
|
||||
Archive::OpenAndLoadSymbols(const sys::Path& file, std::string* ErrorMessage) {
|
||||
std::auto_ptr<Archive> result ( new Archive(file) );
|
||||
Archive* Archive::OpenAndLoadSymbols(const sys::Path& file,
|
||||
LLVMContext& C,
|
||||
std::string* ErrorMessage) {
|
||||
std::auto_ptr<Archive> result ( new Archive(file, C) );
|
||||
if (result->mapToMemory(ErrorMessage))
|
||||
return 0;
|
||||
if (!result->loadSymbolTable(ErrorMessage))
|
||||
@ -488,7 +490,7 @@ Archive::findModuleDefiningSymbol(const std::string& symbol,
|
||||
FullMemberName.c_str());
|
||||
memcpy((char*)Buffer->getBufferStart(), mbr->getData(), mbr->getSize());
|
||||
|
||||
ModuleProvider *mp = getBitcodeModuleProvider(Buffer, ErrMsg);
|
||||
ModuleProvider *mp = getBitcodeModuleProvider(Buffer, Context, ErrMsg);
|
||||
if (!mp)
|
||||
return 0;
|
||||
|
||||
@ -536,7 +538,7 @@ Archive::findModulesDefiningSymbols(std::set<std::string>& symbols,
|
||||
mbr->getPath().toString() + ")";
|
||||
ModuleProvider* MP =
|
||||
GetBitcodeSymbols((const unsigned char*)At, mbr->getSize(),
|
||||
FullMemberName, symbols, error);
|
||||
FullMemberName, Context, symbols, error);
|
||||
|
||||
if (MP) {
|
||||
// Insert the module's symbols into the symbol table
|
||||
@ -615,7 +617,7 @@ bool Archive::isBitcodeArchive() {
|
||||
MemoryBuffer *Buffer =
|
||||
MemoryBuffer::getNewMemBuffer(I->getSize(), FullMemberName.c_str());
|
||||
memcpy((char*)Buffer->getBufferStart(), I->getData(), I->getSize());
|
||||
Module *M = ParseBitcodeFile(Buffer);
|
||||
Module *M = ParseBitcodeFile(Buffer, Context);
|
||||
delete Buffer;
|
||||
if (!M)
|
||||
return false; // Couldn't parse bitcode, not a bitcode archive.
|
||||
|
@ -64,9 +64,8 @@ static inline unsigned numVbrBytes(unsigned num) {
|
||||
}
|
||||
|
||||
// Create an empty archive.
|
||||
Archive*
|
||||
Archive::CreateEmpty(const sys::Path& FilePath ) {
|
||||
Archive* result = new Archive(FilePath);
|
||||
Archive* Archive::CreateEmpty(const sys::Path& FilePath, LLVMContext& C) {
|
||||
Archive* result = new Archive(FilePath, C);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -229,7 +228,7 @@ Archive::writeMember(
|
||||
+ ")";
|
||||
ModuleProvider* MP =
|
||||
GetBitcodeSymbols((const unsigned char*)data,fSize,
|
||||
FullMemberName, symbols, ErrMsg);
|
||||
FullMemberName, Context, symbols, ErrMsg);
|
||||
|
||||
// If the bitcode parsed successfully
|
||||
if ( MP ) {
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "llvm/Instruction.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Assembly/Parser.h"
|
||||
#include <cstdlib>
|
||||
@ -23,23 +24,7 @@
|
||||
using namespace llvm;
|
||||
|
||||
bool LLLexer::Error(LocTy ErrorLoc, const std::string &Msg) const {
|
||||
// Scan backward to find the start of the line.
|
||||
const char *LineStart = ErrorLoc;
|
||||
while (LineStart != CurBuf->getBufferStart() &&
|
||||
LineStart[-1] != '\n' && LineStart[-1] != '\r')
|
||||
--LineStart;
|
||||
// Get the end of the line.
|
||||
const char *LineEnd = ErrorLoc;
|
||||
while (LineEnd != CurBuf->getBufferEnd() &&
|
||||
LineEnd[0] != '\n' && LineEnd[0] != '\r')
|
||||
++LineEnd;
|
||||
|
||||
unsigned LineNo = 1;
|
||||
for (const char *FP = CurBuf->getBufferStart(); FP != ErrorLoc; ++FP)
|
||||
if (*FP == '\n') ++LineNo;
|
||||
|
||||
std::string LineContents(LineStart, LineEnd);
|
||||
ErrorInfo.setError(Msg, LineNo, ErrorLoc-LineStart, LineContents);
|
||||
ErrorInfo = SM.GetMessage(ErrorLoc, Msg, "error");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -195,8 +180,8 @@ static const char *isLabelTail(const char *CurPtr) {
|
||||
// Lexer definition.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
LLLexer::LLLexer(MemoryBuffer *StartBuf, ParseError &Err)
|
||||
: CurBuf(StartBuf), ErrorInfo(Err), APFloatVal(0.0) {
|
||||
LLLexer::LLLexer(MemoryBuffer *StartBuf, SourceMgr &sm, SMDiagnostic &Err)
|
||||
: CurBuf(StartBuf), ErrorInfo(Err), SM(sm), APFloatVal(0.0) {
|
||||
CurPtr = CurBuf->getBufferStart();
|
||||
}
|
||||
|
||||
|
@ -17,17 +17,19 @@
|
||||
#include "LLToken.h"
|
||||
#include "llvm/ADT/APSInt.h"
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
class MemoryBuffer;
|
||||
class Type;
|
||||
class ParseError;
|
||||
class SMDiagnostic;
|
||||
|
||||
class LLLexer {
|
||||
const char *CurPtr;
|
||||
MemoryBuffer *CurBuf;
|
||||
ParseError &ErrorInfo;
|
||||
SMDiagnostic &ErrorInfo;
|
||||
SourceMgr &SM;
|
||||
|
||||
// Information about the current token.
|
||||
const char *TokStart;
|
||||
@ -40,15 +42,15 @@ namespace llvm {
|
||||
|
||||
std::string TheError;
|
||||
public:
|
||||
explicit LLLexer(MemoryBuffer *StartBuf, ParseError &);
|
||||
explicit LLLexer(MemoryBuffer *StartBuf, SourceMgr &SM, SMDiagnostic &);
|
||||
~LLLexer() {}
|
||||
|
||||
lltok::Kind Lex() {
|
||||
return CurKind = LexToken();
|
||||
}
|
||||
|
||||
typedef const char* LocTy;
|
||||
LocTy getLoc() const { return TokStart; }
|
||||
typedef SMLoc LocTy;
|
||||
LocTy getLoc() const { return SMLoc::getFromPointer(TokStart); }
|
||||
lltok::Kind getKind() const { return CurKind; }
|
||||
const std::string getStrVal() const { return StrVal; }
|
||||
const Type *getTyVal() const { return TyVal; }
|
||||
@ -58,7 +60,7 @@ namespace llvm {
|
||||
|
||||
|
||||
bool Error(LocTy L, const std::string &Msg) const;
|
||||
bool Error(const std::string &Msg) const { return Error(CurPtr, Msg); }
|
||||
bool Error(const std::string &Msg) const { return Error(getLoc(), Msg); }
|
||||
std::string getFilename() const;
|
||||
|
||||
private:
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/InlineAsm.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/MDNode.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/ValueSymbolTable.h"
|
||||
@ -109,6 +110,7 @@ bool LLParser::ParseTopLevelEntities() {
|
||||
case lltok::StringConstant: // FIXME: REMOVE IN LLVM 3.0
|
||||
case lltok::LocalVar: if (ParseNamedType()) return true; break;
|
||||
case lltok::GlobalVar: if (ParseNamedGlobal()) return true; break;
|
||||
case lltok::Metadata: if (ParseStandaloneMetadata()) return true; break;
|
||||
|
||||
// The Global variable production with no name can have many different
|
||||
// optional leading prefixes, the production is:
|
||||
@ -129,7 +131,7 @@ bool LLParser::ParseTopLevelEntities() {
|
||||
unsigned Linkage, Visibility;
|
||||
if (ParseOptionalLinkage(Linkage) ||
|
||||
ParseOptionalVisibility(Visibility) ||
|
||||
ParseGlobal("", 0, Linkage, true, Visibility))
|
||||
ParseGlobal("", SMLoc(), Linkage, true, Visibility))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
@ -138,7 +140,7 @@ bool LLParser::ParseTopLevelEntities() {
|
||||
case lltok::kw_protected: { // OptionalVisibility
|
||||
unsigned Visibility;
|
||||
if (ParseOptionalVisibility(Visibility) ||
|
||||
ParseGlobal("", 0, 0, false, Visibility))
|
||||
ParseGlobal("", SMLoc(), 0, false, Visibility))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
@ -147,7 +149,7 @@ bool LLParser::ParseTopLevelEntities() {
|
||||
case lltok::kw_addrspace: // OptionalAddrSpace
|
||||
case lltok::kw_constant: // GlobalType
|
||||
case lltok::kw_global: // GlobalType
|
||||
if (ParseGlobal("", 0, 0, false, 0)) return true;
|
||||
if (ParseGlobal("", SMLoc(), 0, false, 0)) return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -355,6 +357,34 @@ bool LLParser::ParseNamedGlobal() {
|
||||
return ParseAlias(Name, NameLoc, Visibility);
|
||||
}
|
||||
|
||||
/// ParseStandaloneMetadata:
|
||||
/// !42 = !{...}
|
||||
bool LLParser::ParseStandaloneMetadata() {
|
||||
assert(Lex.getKind() == lltok::Metadata);
|
||||
Lex.Lex();
|
||||
unsigned MetadataID = 0;
|
||||
if (ParseUInt32(MetadataID))
|
||||
return true;
|
||||
if (MetadataCache.find(MetadataID) != MetadataCache.end())
|
||||
return TokError("Metadata id is already used");
|
||||
if (ParseToken(lltok::equal, "expected '=' here"))
|
||||
return true;
|
||||
|
||||
LocTy TyLoc;
|
||||
bool IsConstant;
|
||||
PATypeHolder Ty(Type::VoidTy);
|
||||
if (ParseGlobalType(IsConstant) ||
|
||||
ParseType(Ty, TyLoc))
|
||||
return true;
|
||||
|
||||
Constant *Init = 0;
|
||||
if (ParseGlobalValue(Ty, Init))
|
||||
return true;
|
||||
|
||||
MetadataCache[MetadataID] = Init;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ParseAlias:
|
||||
/// ::= GlobalVar '=' OptionalVisibility 'alias' OptionalLinkage Aliasee
|
||||
/// Aliasee
|
||||
@ -968,7 +998,7 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
|
||||
break;
|
||||
case lltok::kw_opaque:
|
||||
// TypeRec ::= 'opaque'
|
||||
Result = OpaqueType::get();
|
||||
Result = Context.getOpaqueType();
|
||||
Lex.Lex();
|
||||
break;
|
||||
case lltok::lbrace:
|
||||
@ -998,7 +1028,7 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
|
||||
if (const Type *T = M->getTypeByName(Lex.getStrVal())) {
|
||||
Result = T;
|
||||
} else {
|
||||
Result = OpaqueType::get();
|
||||
Result = Context.getOpaqueType();
|
||||
ForwardRefTypes.insert(std::make_pair(Lex.getStrVal(),
|
||||
std::make_pair(Result,
|
||||
Lex.getLoc())));
|
||||
@ -1017,7 +1047,7 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
|
||||
if (I != ForwardRefTypeIDs.end())
|
||||
Result = I->second.first;
|
||||
else {
|
||||
Result = OpaqueType::get();
|
||||
Result = Context.getOpaqueType();
|
||||
ForwardRefTypeIDs.insert(std::make_pair(Lex.getUIntVal(),
|
||||
std::make_pair(Result,
|
||||
Lex.getLoc())));
|
||||
@ -1030,7 +1060,7 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
|
||||
Lex.Lex();
|
||||
unsigned Val;
|
||||
if (ParseUInt32(Val)) return true;
|
||||
OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder.
|
||||
OpaqueType *OT = Context.getOpaqueType(); //Use temporary placeholder.
|
||||
UpRefs.push_back(UpRefRecord(Lex.getLoc(), Val, OT));
|
||||
Result = OT;
|
||||
break;
|
||||
@ -1051,7 +1081,7 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
|
||||
return TokError("pointers to void are invalid; use i8* instead");
|
||||
if (!PointerType::isValidElementType(Result.get()))
|
||||
return TokError("pointer to this type is invalid");
|
||||
Result = HandleUpRefs(PointerType::getUnqual(Result.get()));
|
||||
Result = HandleUpRefs(Context.getPointerTypeUnqual(Result.get()));
|
||||
Lex.Lex();
|
||||
break;
|
||||
|
||||
@ -1068,7 +1098,7 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
|
||||
ParseToken(lltok::star, "expected '*' in address space"))
|
||||
return true;
|
||||
|
||||
Result = HandleUpRefs(PointerType::get(Result.get(), AddrSpace));
|
||||
Result = HandleUpRefs(Context.getPointerType(Result.get(), AddrSpace));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1229,7 +1259,8 @@ bool LLParser::ParseFunctionType(PATypeHolder &Result) {
|
||||
for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
|
||||
ArgListTy.push_back(ArgList[i].Type);
|
||||
|
||||
Result = HandleUpRefs(FunctionType::get(Result.get(), ArgListTy, isVarArg));
|
||||
Result = HandleUpRefs(Context.getFunctionType(Result.get(),
|
||||
ArgListTy, isVarArg));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1244,7 +1275,7 @@ bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) {
|
||||
Lex.Lex(); // Consume the '{'
|
||||
|
||||
if (EatIfPresent(lltok::rbrace)) {
|
||||
Result = StructType::get(std::vector<const Type*>(), Packed);
|
||||
Result = Context.getStructType(Packed);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1276,7 +1307,7 @@ bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) {
|
||||
std::vector<const Type*> ParamsListTy;
|
||||
for (unsigned i = 0, e = ParamsList.size(); i != e; ++i)
|
||||
ParamsListTy.push_back(ParamsList[i].get());
|
||||
Result = HandleUpRefs(StructType::get(ParamsListTy, Packed));
|
||||
Result = HandleUpRefs(Context.getStructType(ParamsListTy, Packed));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1315,11 +1346,11 @@ bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) {
|
||||
return Error(SizeLoc, "size too large for vector");
|
||||
if (!VectorType::isValidElementType(EltTy))
|
||||
return Error(TypeLoc, "vector element type must be fp or integer");
|
||||
Result = VectorType::get(EltTy, unsigned(Size));
|
||||
Result = Context.getVectorType(EltTy, unsigned(Size));
|
||||
} else {
|
||||
if (!ArrayType::isValidElementType(EltTy))
|
||||
return Error(TypeLoc, "invalid array element type");
|
||||
Result = HandleUpRefs(ArrayType::get(EltTy, Size));
|
||||
Result = HandleUpRefs(Context.getArrayType(EltTy, Size));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -1343,8 +1374,8 @@ LLParser::PerFunctionState::~PerFunctionState() {
|
||||
for (std::map<std::string, std::pair<Value*, LocTy> >::iterator
|
||||
I = ForwardRefVals.begin(), E = ForwardRefVals.end(); I != E; ++I)
|
||||
if (!isa<BasicBlock>(I->second.first)) {
|
||||
I->second.first->replaceAllUsesWith(UndefValue::get(I->second.first
|
||||
->getType()));
|
||||
I->second.first->replaceAllUsesWith(
|
||||
P.getContext().getUndef(I->second.first->getType()));
|
||||
delete I->second.first;
|
||||
I->second.first = 0;
|
||||
}
|
||||
@ -1352,8 +1383,8 @@ LLParser::PerFunctionState::~PerFunctionState() {
|
||||
for (std::map<unsigned, std::pair<Value*, LocTy> >::iterator
|
||||
I = ForwardRefValIDs.begin(), E = ForwardRefValIDs.end(); I != E; ++I)
|
||||
if (!isa<BasicBlock>(I->second.first)) {
|
||||
I->second.first->replaceAllUsesWith(UndefValue::get(I->second.first
|
||||
->getType()));
|
||||
I->second.first->replaceAllUsesWith(
|
||||
P.getContext().getUndef(I->second.first->getType()));
|
||||
delete I->second.first;
|
||||
I->second.first = 0;
|
||||
}
|
||||
@ -1592,16 +1623,27 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
ParseToken(lltok::rbrace, "expected end of metadata node"))
|
||||
return true;
|
||||
|
||||
ID.ConstantVal = MDNode::get(Elts.data(), Elts.size());
|
||||
ID.ConstantVal = Context.getMDNode(Elts.data(), Elts.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Standalone metadata reference
|
||||
// !{ ..., !42, ... }
|
||||
unsigned MID = 0;
|
||||
if (!ParseUInt32(MID)) {
|
||||
std::map<unsigned, Constant *>::iterator I = MetadataCache.find(MID);
|
||||
if (I == MetadataCache.end())
|
||||
return TokError("Unknown metadata reference");
|
||||
ID.ConstantVal = I->second;
|
||||
return false;
|
||||
}
|
||||
|
||||
// MDString:
|
||||
// ::= '!' STRINGCONSTANT
|
||||
std::string Str;
|
||||
if (ParseStringConstant(Str)) return true;
|
||||
|
||||
ID.ConstantVal = MDString::get(Str.data(), Str.data() + Str.size());
|
||||
ID.ConstantVal = Context.getMDString(Str.data(), Str.data() + Str.size());
|
||||
return false;
|
||||
}
|
||||
case lltok::APSInt:
|
||||
@ -1613,11 +1655,11 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
ID.Kind = ValID::t_APFloat;
|
||||
break;
|
||||
case lltok::kw_true:
|
||||
ID.ConstantVal = ConstantInt::getTrue();
|
||||
ID.ConstantVal = Context.getConstantIntTrue();
|
||||
ID.Kind = ValID::t_Constant;
|
||||
break;
|
||||
case lltok::kw_false:
|
||||
ID.ConstantVal = ConstantInt::getFalse();
|
||||
ID.ConstantVal = Context.getConstantIntFalse();
|
||||
ID.Kind = ValID::t_Constant;
|
||||
break;
|
||||
case lltok::kw_null: ID.Kind = ValID::t_Null; break;
|
||||
@ -1632,7 +1674,7 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
ParseToken(lltok::rbrace, "expected end of struct constant"))
|
||||
return true;
|
||||
|
||||
ID.ConstantVal = ConstantStruct::get(Elts.data(), Elts.size(), false);
|
||||
ID.ConstantVal = Context.getConstantStruct(Elts.data(), Elts.size(), false);
|
||||
ID.Kind = ValID::t_Constant;
|
||||
return false;
|
||||
}
|
||||
@ -1651,7 +1693,8 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
return true;
|
||||
|
||||
if (isPackedStruct) {
|
||||
ID.ConstantVal = ConstantStruct::get(Elts.data(), Elts.size(), true);
|
||||
ID.ConstantVal =
|
||||
Context.getConstantStruct(Elts.data(), Elts.size(), true);
|
||||
ID.Kind = ValID::t_Constant;
|
||||
return false;
|
||||
}
|
||||
@ -1671,7 +1714,7 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
"vector element #" + utostr(i) +
|
||||
" is not of type '" + Elts[0]->getType()->getDescription());
|
||||
|
||||
ID.ConstantVal = ConstantVector::get(Elts.data(), Elts.size());
|
||||
ID.ConstantVal = Context.getConstantVector(Elts.data(), Elts.size());
|
||||
ID.Kind = ValID::t_Constant;
|
||||
return false;
|
||||
}
|
||||
@ -1695,7 +1738,7 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
return Error(FirstEltLoc, "invalid array element type: " +
|
||||
Elts[0]->getType()->getDescription());
|
||||
|
||||
ArrayType *ATy = ArrayType::get(Elts[0]->getType(), Elts.size());
|
||||
ArrayType *ATy = Context.getArrayType(Elts[0]->getType(), Elts.size());
|
||||
|
||||
// Verify all elements are correct type!
|
||||
for (unsigned i = 0, e = Elts.size(); i != e; ++i) {
|
||||
@ -1705,13 +1748,13 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
" is not of type '" +Elts[0]->getType()->getDescription());
|
||||
}
|
||||
|
||||
ID.ConstantVal = ConstantArray::get(ATy, Elts.data(), Elts.size());
|
||||
ID.ConstantVal = Context.getConstantArray(ATy, Elts.data(), Elts.size());
|
||||
ID.Kind = ValID::t_Constant;
|
||||
return false;
|
||||
}
|
||||
case lltok::kw_c: // c "foo"
|
||||
Lex.Lex();
|
||||
ID.ConstantVal = ConstantArray::get(Lex.getStrVal(), false);
|
||||
ID.ConstantVal = Context.getConstantArray(Lex.getStrVal(), false);
|
||||
if (ParseToken(lltok::StringConstant, "expected string")) return true;
|
||||
ID.Kind = ValID::t_Constant;
|
||||
return false;
|
||||
@ -1757,8 +1800,8 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
return Error(ID.Loc, "invalid cast opcode for cast from '" +
|
||||
SrcVal->getType()->getDescription() + "' to '" +
|
||||
DestTy->getDescription() + "'");
|
||||
ID.ConstantVal = ConstantExpr::getCast((Instruction::CastOps)Opc, SrcVal,
|
||||
DestTy);
|
||||
ID.ConstantVal = Context.getConstantExprCast((Instruction::CastOps)Opc,
|
||||
SrcVal, DestTy);
|
||||
ID.Kind = ValID::t_Constant;
|
||||
return false;
|
||||
}
|
||||
@ -1777,7 +1820,7 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
Indices.end()))
|
||||
return Error(ID.Loc, "invalid indices for extractvalue");
|
||||
ID.ConstantVal =
|
||||
ConstantExpr::getExtractValue(Val, Indices.data(), Indices.size());
|
||||
Context.getConstantExprExtractValue(Val, Indices.data(), Indices.size());
|
||||
ID.Kind = ValID::t_Constant;
|
||||
return false;
|
||||
}
|
||||
@ -1797,8 +1840,8 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(),
|
||||
Indices.end()))
|
||||
return Error(ID.Loc, "invalid indices for insertvalue");
|
||||
ID.ConstantVal =
|
||||
ConstantExpr::getInsertValue(Val0, Val1, Indices.data(), Indices.size());
|
||||
ID.ConstantVal = Context.getConstantExprInsertValue(Val0, Val1,
|
||||
Indices.data(), Indices.size());
|
||||
ID.Kind = ValID::t_Constant;
|
||||
return false;
|
||||
}
|
||||
@ -1825,24 +1868,24 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
if (Opc == Instruction::FCmp) {
|
||||
if (!Val0->getType()->isFPOrFPVector())
|
||||
return Error(ID.Loc, "fcmp requires floating point operands");
|
||||
ID.ConstantVal = ConstantExpr::getFCmp(Pred, Val0, Val1);
|
||||
ID.ConstantVal = Context.getConstantExprFCmp(Pred, Val0, Val1);
|
||||
} else if (Opc == Instruction::ICmp) {
|
||||
if (!Val0->getType()->isIntOrIntVector() &&
|
||||
!isa<PointerType>(Val0->getType()))
|
||||
return Error(ID.Loc, "icmp requires pointer or integer operands");
|
||||
ID.ConstantVal = ConstantExpr::getICmp(Pred, Val0, Val1);
|
||||
ID.ConstantVal = Context.getConstantExprICmp(Pred, Val0, Val1);
|
||||
} else if (Opc == Instruction::VFCmp) {
|
||||
// FIXME: REMOVE VFCMP Support
|
||||
if (!Val0->getType()->isFPOrFPVector() ||
|
||||
!isa<VectorType>(Val0->getType()))
|
||||
return Error(ID.Loc, "vfcmp requires vector floating point operands");
|
||||
ID.ConstantVal = ConstantExpr::getVFCmp(Pred, Val0, Val1);
|
||||
ID.ConstantVal = Context.getConstantExprVFCmp(Pred, Val0, Val1);
|
||||
} else if (Opc == Instruction::VICmp) {
|
||||
// FIXME: REMOVE VICMP Support
|
||||
if (!Val0->getType()->isIntOrIntVector() ||
|
||||
!isa<VectorType>(Val0->getType()))
|
||||
return Error(ID.Loc, "vicmp requires vector floating point operands");
|
||||
ID.ConstantVal = ConstantExpr::getVICmp(Pred, Val0, Val1);
|
||||
ID.ConstantVal = Context.getConstantExprVICmp(Pred, Val0, Val1);
|
||||
}
|
||||
ID.Kind = ValID::t_Constant;
|
||||
return false;
|
||||
@ -1875,7 +1918,7 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
if (!Val0->getType()->isIntOrIntVector() &&
|
||||
!Val0->getType()->isFPOrFPVector())
|
||||
return Error(ID.Loc,"constexpr requires integer, fp, or vector operands");
|
||||
ID.ConstantVal = ConstantExpr::get(Opc, Val0, Val1);
|
||||
ID.ConstantVal = Context.getConstantExpr(Opc, Val0, Val1);
|
||||
ID.Kind = ValID::t_Constant;
|
||||
return false;
|
||||
}
|
||||
@ -1901,7 +1944,7 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
if (!Val0->getType()->isIntOrIntVector())
|
||||
return Error(ID.Loc,
|
||||
"constexpr requires integer or integer vector operands");
|
||||
ID.ConstantVal = ConstantExpr::get(Opc, Val0, Val1);
|
||||
ID.ConstantVal = Context.getConstantExpr(Opc, Val0, Val1);
|
||||
ID.Kind = ValID::t_Constant;
|
||||
return false;
|
||||
}
|
||||
@ -1926,7 +1969,7 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
if (!GetElementPtrInst::getIndexedType(Elts[0]->getType(),
|
||||
(Value**)&Elts[1], Elts.size()-1))
|
||||
return Error(ID.Loc, "invalid indices for getelementptr");
|
||||
ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0],
|
||||
ID.ConstantVal = Context.getConstantExprGetElementPtr(Elts[0],
|
||||
&Elts[1], Elts.size()-1);
|
||||
} else if (Opc == Instruction::Select) {
|
||||
if (Elts.size() != 3)
|
||||
@ -1934,26 +1977,28 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
if (const char *Reason = SelectInst::areInvalidOperands(Elts[0], Elts[1],
|
||||
Elts[2]))
|
||||
return Error(ID.Loc, Reason);
|
||||
ID.ConstantVal = ConstantExpr::getSelect(Elts[0], Elts[1], Elts[2]);
|
||||
ID.ConstantVal = Context.getConstantExprSelect(Elts[0], Elts[1], Elts[2]);
|
||||
} else if (Opc == Instruction::ShuffleVector) {
|
||||
if (Elts.size() != 3)
|
||||
return Error(ID.Loc, "expected three operands to shufflevector");
|
||||
if (!ShuffleVectorInst::isValidOperands(Elts[0], Elts[1], Elts[2]))
|
||||
return Error(ID.Loc, "invalid operands to shufflevector");
|
||||
ID.ConstantVal = ConstantExpr::getShuffleVector(Elts[0], Elts[1],Elts[2]);
|
||||
ID.ConstantVal =
|
||||
Context.getConstantExprShuffleVector(Elts[0], Elts[1],Elts[2]);
|
||||
} else if (Opc == Instruction::ExtractElement) {
|
||||
if (Elts.size() != 2)
|
||||
return Error(ID.Loc, "expected two operands to extractelement");
|
||||
if (!ExtractElementInst::isValidOperands(Elts[0], Elts[1]))
|
||||
return Error(ID.Loc, "invalid extractelement operands");
|
||||
ID.ConstantVal = ConstantExpr::getExtractElement(Elts[0], Elts[1]);
|
||||
ID.ConstantVal = Context.getConstantExprExtractElement(Elts[0], Elts[1]);
|
||||
} else {
|
||||
assert(Opc == Instruction::InsertElement && "Unknown opcode");
|
||||
if (Elts.size() != 3)
|
||||
return Error(ID.Loc, "expected three operands to insertelement");
|
||||
if (!InsertElementInst::isValidOperands(Elts[0], Elts[1], Elts[2]))
|
||||
return Error(ID.Loc, "invalid insertelement operands");
|
||||
ID.ConstantVal = ConstantExpr::getInsertElement(Elts[0], Elts[1],Elts[2]);
|
||||
ID.ConstantVal =
|
||||
Context.getConstantExprInsertElement(Elts[0], Elts[1],Elts[2]);
|
||||
}
|
||||
|
||||
ID.Kind = ValID::t_Constant;
|
||||
@ -1997,7 +2042,7 @@ bool LLParser::ConvertGlobalValIDToValue(const Type *Ty, ValID &ID,
|
||||
if (!isa<IntegerType>(Ty))
|
||||
return Error(ID.Loc, "integer constant must have integer type");
|
||||
ID.APSIntVal.extOrTrunc(Ty->getPrimitiveSizeInBits());
|
||||
V = ConstantInt::get(ID.APSIntVal);
|
||||
V = Context.getConstantInt(ID.APSIntVal);
|
||||
return false;
|
||||
case ValID::t_APFloat:
|
||||
if (!Ty->isFloatingPoint() ||
|
||||
@ -2012,7 +2057,7 @@ bool LLParser::ConvertGlobalValIDToValue(const Type *Ty, ValID &ID,
|
||||
ID.APFloatVal.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven,
|
||||
&Ignored);
|
||||
}
|
||||
V = ConstantFP::get(ID.APFloatVal);
|
||||
V = Context.getConstantFP(ID.APFloatVal);
|
||||
|
||||
if (V->getType() != Ty)
|
||||
return Error(ID.Loc, "floating point constant does not have type '" +
|
||||
@ -2022,25 +2067,25 @@ bool LLParser::ConvertGlobalValIDToValue(const Type *Ty, ValID &ID,
|
||||
case ValID::t_Null:
|
||||
if (!isa<PointerType>(Ty))
|
||||
return Error(ID.Loc, "null must be a pointer type");
|
||||
V = ConstantPointerNull::get(cast<PointerType>(Ty));
|
||||
V = Context.getConstantPointerNull(cast<PointerType>(Ty));
|
||||
return false;
|
||||
case ValID::t_Undef:
|
||||
// FIXME: LabelTy should not be a first-class type.
|
||||
if ((!Ty->isFirstClassType() || Ty == Type::LabelTy) &&
|
||||
!isa<OpaqueType>(Ty))
|
||||
return Error(ID.Loc, "invalid type for undef constant");
|
||||
V = UndefValue::get(Ty);
|
||||
V = Context.getUndef(Ty);
|
||||
return false;
|
||||
case ValID::t_EmptyArray:
|
||||
if (!isa<ArrayType>(Ty) || cast<ArrayType>(Ty)->getNumElements() != 0)
|
||||
return Error(ID.Loc, "invalid empty array initializer");
|
||||
V = UndefValue::get(Ty);
|
||||
V = Context.getUndef(Ty);
|
||||
return false;
|
||||
case ValID::t_Zero:
|
||||
// FIXME: LabelTy should not be a first-class type.
|
||||
if (!Ty->isFirstClassType() || Ty == Type::LabelTy)
|
||||
return Error(ID.Loc, "invalid type for null constant");
|
||||
V = Constant::getNullValue(Ty);
|
||||
V = Context.getNullValue(Ty);
|
||||
return false;
|
||||
case ValID::t_Constant:
|
||||
if (ID.ConstantVal->getType() != Ty)
|
||||
@ -2242,8 +2287,9 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
|
||||
RetType != Type::VoidTy)
|
||||
return Error(RetTypeLoc, "functions with 'sret' argument must return void");
|
||||
|
||||
const FunctionType *FT = FunctionType::get(RetType, ParamTypeList, isVarArg);
|
||||
const PointerType *PFT = PointerType::getUnqual(FT);
|
||||
const FunctionType *FT =
|
||||
Context.getFunctionType(RetType, ParamTypeList, isVarArg);
|
||||
const PointerType *PFT = Context.getPointerTypeUnqual(FT);
|
||||
|
||||
Fn = 0;
|
||||
if (!FunctionName.empty()) {
|
||||
@ -2558,7 +2604,7 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
|
||||
RVs.push_back(RV);
|
||||
}
|
||||
|
||||
RV = UndefValue::get(PFS.getFunction().getReturnType());
|
||||
RV = Context.getUndef(PFS.getFunction().getReturnType());
|
||||
for (unsigned i = 0, e = RVs.size(); i != e; ++i) {
|
||||
Instruction *I = InsertValueInst::Create(RV, RVs[i], i, "mrv");
|
||||
BB->getInstList().push_back(I);
|
||||
@ -2696,8 +2742,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
|
||||
if (!FunctionType::isValidReturnType(RetType))
|
||||
return Error(RetTypeLoc, "Invalid result type for LLVM function");
|
||||
|
||||
Ty = FunctionType::get(RetType, ParamTypes, false);
|
||||
PFTy = PointerType::getUnqual(Ty);
|
||||
Ty = Context.getFunctionType(RetType, ParamTypes, false);
|
||||
PFTy = Context.getPointerTypeUnqual(Ty);
|
||||
}
|
||||
|
||||
// Look up the callee.
|
||||
@ -3045,8 +3091,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
|
||||
if (!FunctionType::isValidReturnType(RetType))
|
||||
return Error(RetTypeLoc, "Invalid result type for LLVM function");
|
||||
|
||||
Ty = FunctionType::get(RetType, ParamTypes, false);
|
||||
PFTy = PointerType::getUnqual(Ty);
|
||||
Ty = Context.getFunctionType(RetType, ParamTypes, false);
|
||||
PFTy = Context.getPointerTypeUnqual(Ty);
|
||||
}
|
||||
|
||||
// Look up the callee.
|
||||
@ -3116,7 +3162,7 @@ bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
|
||||
unsigned Opc) {
|
||||
PATypeHolder Ty(Type::VoidTy);
|
||||
Value *Size = 0;
|
||||
LocTy SizeLoc = 0;
|
||||
LocTy SizeLoc;
|
||||
unsigned Alignment = 0;
|
||||
if (ParseType(Ty)) return true;
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define LLVM_ASMPARSER_LLPARSER_H
|
||||
|
||||
#include "LLLexer.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Type.h"
|
||||
#include <map>
|
||||
|
||||
@ -35,7 +36,7 @@ namespace llvm {
|
||||
public:
|
||||
typedef LLLexer::LocTy LocTy;
|
||||
private:
|
||||
|
||||
LLVMContext& Context;
|
||||
LLLexer Lex;
|
||||
Module *M;
|
||||
|
||||
@ -43,7 +44,8 @@ namespace llvm {
|
||||
std::map<std::string, std::pair<PATypeHolder, LocTy> > ForwardRefTypes;
|
||||
std::map<unsigned, std::pair<PATypeHolder, LocTy> > ForwardRefTypeIDs;
|
||||
std::vector<PATypeHolder> NumberedTypes;
|
||||
|
||||
/// MetadataCache - This map keeps track of parsed metadata constants.
|
||||
std::map<unsigned, Constant *> MetadataCache;
|
||||
struct UpRefRecord {
|
||||
/// Loc - This is the location of the upref.
|
||||
LocTy Loc;
|
||||
@ -71,9 +73,12 @@ namespace llvm {
|
||||
std::map<unsigned, std::pair<GlobalValue*, LocTy> > ForwardRefValIDs;
|
||||
std::vector<GlobalValue*> NumberedVals;
|
||||
public:
|
||||
LLParser(MemoryBuffer *F, ParseError &Err, Module *m) : Lex(F, Err), M(m) {}
|
||||
LLParser(MemoryBuffer *F, SourceMgr &SM, SMDiagnostic &Err, Module *m) :
|
||||
Context(m->getContext()), Lex(F, SM, Err), M(m) {}
|
||||
bool Run();
|
||||
|
||||
LLVMContext& getContext() { return Context; }
|
||||
|
||||
private:
|
||||
|
||||
bool Error(LocTy L, const std::string &Msg) const {
|
||||
@ -139,6 +144,7 @@ namespace llvm {
|
||||
bool ParseGlobal(const std::string &Name, LocTy Loc, unsigned Linkage,
|
||||
bool HasLinkage, unsigned Visibility);
|
||||
bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Visibility);
|
||||
bool ParseStandaloneMetadata();
|
||||
|
||||
// Type Parsing.
|
||||
bool ParseType(PATypeHolder &Result, bool AllowVoid = false);
|
||||
|
@ -15,73 +15,47 @@
|
||||
#include "LLParser.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cstring>
|
||||
using namespace llvm;
|
||||
|
||||
Module *llvm::ParseAssemblyFile(const std::string &Filename, ParseError &Err) {
|
||||
Err.setFilename(Filename);
|
||||
|
||||
Module *llvm::ParseAssemblyFile(const std::string &Filename, SMDiagnostic &Err,
|
||||
LLVMContext &Context) {
|
||||
std::string ErrorStr;
|
||||
OwningPtr<MemoryBuffer>
|
||||
F(MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrorStr));
|
||||
MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrorStr);
|
||||
if (F == 0) {
|
||||
Err.setError("Could not open input file '" + Filename + "'");
|
||||
Err = SMDiagnostic("", -1, -1,
|
||||
"Could not open input file '" + Filename + "'", "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
OwningPtr<Module> M(new Module(Filename));
|
||||
if (LLParser(F.get(), Err, M.get()).Run())
|
||||
SourceMgr SM;
|
||||
SM.AddNewSourceBuffer(F, SMLoc());
|
||||
|
||||
OwningPtr<Module> M(new Module(Filename, Context));
|
||||
if (LLParser(F, SM, Err, M.get()).Run())
|
||||
return 0;
|
||||
return M.take();
|
||||
}
|
||||
|
||||
Module *llvm::ParseAssemblyString(const char *AsmString, Module *M,
|
||||
ParseError &Err) {
|
||||
Err.setFilename("<string>");
|
||||
|
||||
OwningPtr<MemoryBuffer>
|
||||
F(MemoryBuffer::getMemBuffer(AsmString, AsmString+strlen(AsmString),
|
||||
"<string>"));
|
||||
SMDiagnostic &Err, LLVMContext &Context) {
|
||||
MemoryBuffer *F =
|
||||
MemoryBuffer::getMemBuffer(AsmString, AsmString+strlen(AsmString),
|
||||
"<string>");
|
||||
|
||||
SourceMgr SM;
|
||||
SM.AddNewSourceBuffer(F, SMLoc());
|
||||
|
||||
// If we are parsing into an existing module, do it.
|
||||
if (M)
|
||||
return LLParser(F.get(), Err, M).Run() ? 0 : M;
|
||||
return LLParser(F, SM, Err, M).Run() ? 0 : M;
|
||||
|
||||
// Otherwise create a new module.
|
||||
OwningPtr<Module> M2(new Module("<string>"));
|
||||
if (LLParser(F.get(), Err, M2.get()).Run())
|
||||
OwningPtr<Module> M2(new Module("<string>", Context));
|
||||
if (LLParser(F, SM, Err, M2.get()).Run())
|
||||
return 0;
|
||||
return M2.take();
|
||||
}
|
||||
|
||||
|
||||
//===------------------------------------------------------------------------===
|
||||
// ParseError Class
|
||||
//===------------------------------------------------------------------------===
|
||||
|
||||
void ParseError::PrintError(const char *ProgName, raw_ostream &S) {
|
||||
errs() << ProgName << ": ";
|
||||
if (Filename == "-")
|
||||
errs() << "<stdin>";
|
||||
else
|
||||
errs() << Filename;
|
||||
|
||||
if (LineNo != -1) {
|
||||
errs() << ':' << LineNo;
|
||||
if (ColumnNo != -1)
|
||||
errs() << ':' << (ColumnNo+1);
|
||||
}
|
||||
|
||||
errs() << ": " << Message << '\n';
|
||||
|
||||
if (LineNo != -1 && ColumnNo != -1) {
|
||||
errs() << LineContents << '\n';
|
||||
|
||||
// Print out spaces/tabs before the caret.
|
||||
for (unsigned i = 0; i != unsigned(ColumnNo); ++i)
|
||||
errs() << (LineContents[i] == '\t' ? '\t' : ' ');
|
||||
errs() << "^\n";
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "llvm-c/BitReader.h"
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
@ -22,7 +23,24 @@ int LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleRef *OutModule, char **OutMessage) {
|
||||
std::string Message;
|
||||
|
||||
*OutModule = wrap(ParseBitcodeFile(unwrap(MemBuf), &Message));
|
||||
*OutModule = wrap(ParseBitcodeFile(unwrap(MemBuf), getGlobalContext(),
|
||||
&Message));
|
||||
if (!*OutModule) {
|
||||
if (OutMessage)
|
||||
*OutMessage = strdup(Message.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LLVMParseBitcodeInContext(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMContextRef ContextRef,
|
||||
LLVMModuleRef *OutModule, char **OutMessage) {
|
||||
std::string Message;
|
||||
|
||||
*OutModule = wrap(ParseBitcodeFile(unwrap(MemBuf), *unwrap(ContextRef),
|
||||
&Message));
|
||||
if (!*OutModule) {
|
||||
if (OutMessage)
|
||||
*OutMessage = strdup(Message.c_str());
|
||||
@ -37,10 +55,29 @@ int LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
|
||||
Optionally returns a human-readable error message via OutMessage. */
|
||||
int LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleProviderRef *OutMP,
|
||||
char **OutMessage) {
|
||||
char **OutMessage) {
|
||||
std::string Message;
|
||||
|
||||
*OutMP = wrap(getBitcodeModuleProvider(unwrap(MemBuf), getGlobalContext(),
|
||||
&Message));
|
||||
|
||||
if (!*OutMP) {
|
||||
if (OutMessage)
|
||||
*OutMessage = strdup(Message.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LLVMGetBitcodeModuleProviderInContext(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMContextRef ContextRef,
|
||||
LLVMModuleProviderRef *OutMP,
|
||||
char **OutMessage) {
|
||||
std::string Message;
|
||||
|
||||
*OutMP = wrap(getBitcodeModuleProvider(unwrap(MemBuf), &Message));
|
||||
*OutMP = wrap(getBitcodeModuleProvider(unwrap(MemBuf), *unwrap(ContextRef),
|
||||
&Message));
|
||||
if (!*OutMP) {
|
||||
if (OutMessage)
|
||||
*OutMessage = strdup(Message.c_str());
|
||||
|
@ -1087,7 +1087,7 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) {
|
||||
return Error("Malformed block record");
|
||||
|
||||
// Otherwise, create the module.
|
||||
TheModule = new Module(ModuleID);
|
||||
TheModule = new Module(ModuleID, Context);
|
||||
|
||||
SmallVector<uint64_t, 64> Record;
|
||||
std::vector<std::string> SectionTable;
|
||||
@ -2090,8 +2090,9 @@ Module *BitcodeReader::releaseModule(std::string *ErrInfo) {
|
||||
/// getBitcodeModuleProvider - lazy function-at-a-time loading from a file.
|
||||
///
|
||||
ModuleProvider *llvm::getBitcodeModuleProvider(MemoryBuffer *Buffer,
|
||||
LLVMContext& Context,
|
||||
std::string *ErrMsg) {
|
||||
BitcodeReader *R = new BitcodeReader(Buffer);
|
||||
BitcodeReader *R = new BitcodeReader(Buffer, Context);
|
||||
if (R->ParseBitcode()) {
|
||||
if (ErrMsg)
|
||||
*ErrMsg = R->getErrorString();
|
||||
@ -2106,9 +2107,11 @@ ModuleProvider *llvm::getBitcodeModuleProvider(MemoryBuffer *Buffer,
|
||||
|
||||
/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
|
||||
/// If an error occurs, return null and fill in *ErrMsg if non-null.
|
||||
Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, std::string *ErrMsg){
|
||||
Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context,
|
||||
std::string *ErrMsg){
|
||||
BitcodeReader *R;
|
||||
R = static_cast<BitcodeReader*>(getBitcodeModuleProvider(Buffer, ErrMsg));
|
||||
R = static_cast<BitcodeReader*>(getBitcodeModuleProvider(Buffer, Context,
|
||||
ErrMsg));
|
||||
if (!R) return 0;
|
||||
|
||||
// Read in the entire module.
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
namespace llvm {
|
||||
class MemoryBuffer;
|
||||
class LLVMContext;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// BitcodeReaderValueList Class
|
||||
@ -85,6 +86,7 @@ public:
|
||||
};
|
||||
|
||||
class BitcodeReader : public ModuleProvider {
|
||||
LLVMContext& Context;
|
||||
MemoryBuffer *Buffer;
|
||||
BitstreamReader StreamFile;
|
||||
BitstreamCursor Stream;
|
||||
@ -123,8 +125,8 @@ class BitcodeReader : public ModuleProvider {
|
||||
/// stream) and what linkage the original function had.
|
||||
DenseMap<Function*, std::pair<uint64_t, unsigned> > DeferredFunctionInfo;
|
||||
public:
|
||||
explicit BitcodeReader(MemoryBuffer *buffer)
|
||||
: Buffer(buffer), ErrorString(0) {
|
||||
explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext& C)
|
||||
: Context(C), Buffer(buffer), ErrorString(0) {
|
||||
HasReversedFunctionsWithBodies = false;
|
||||
}
|
||||
~BitcodeReader() {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user