Import LLVM 74788.

This commit is contained in:
ed 2009-07-04 13:58:26 +00:00
parent cf5cd875b5
commit 72621d11de
476 changed files with 16743 additions and 5595 deletions

View File

@ -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@

View File

@ -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

View File

@ -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);

View File

@ -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
View File

@ -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

View File

@ -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>

View File

@ -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, &quot;mydriver&quot;) == 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>

View File

@ -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>

View File

@ -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>

View File

@ -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&lt;type&gt;(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>

View File

@ -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&lt;DominatorTree&gt;(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&lt;DominatorTree&gt;(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>

View File

@ -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

View File

@ -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 "[]".

View File

@ -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);

View File

@ -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);

View File

@ -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".

View File

@ -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);

View File

@ -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.

View File

@ -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 );

View File

@ -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
}

View File

@ -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

View File

@ -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.
*/

View 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.

View File

@ -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);
/// }

View File

@ -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

View File

@ -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; }

View File

@ -53,7 +53,8 @@ public:
Darwin,
DragonFly,
FreeBSD,
Linux
Linux,
OpenBSD
};
private:

View File

@ -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

View File

@ -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.

View File

@ -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 {

View File

@ -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

View File

@ -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) {

View File

@ -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;
};
}

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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
/// @{

View File

@ -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;

View File

@ -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.

View File

@ -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!

View File

@ -15,6 +15,8 @@
#ifndef LLVM_CODEGEN_BINARYOBJECT_H
#define LLVM_CODEGEN_BINARYOBJECT_H
#include "llvm/Support/DataTypes.h"
#include <string>
#include <vector>

View File

@ -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();

View File

@ -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; }
};
//===--------------------------------------------------------------------===//

View File

@ -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

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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.

View File

@ -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);

View File

@ -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;

View File

@ -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>;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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
View 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

View File

@ -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();

View File

@ -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,"");

View File

@ -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.

View File

@ -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.

View File

@ -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);
}
};

View File

@ -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; }
};

View File

@ -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.

View File

@ -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; }
};

View File

@ -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;

View File

@ -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; }

View File

@ -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.

View File

@ -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

View File

@ -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>

View 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

View File

@ -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> {}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -37,6 +37,7 @@ class Trace;
class CallGraph;
class TargetData;
class LoopInfo;
class LLVMContext;
template<class N> class LoopBase;
typedef LoopBase<BasicBlock> Loop;

View File

@ -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

View 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

View File

@ -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";
}

View File

@ -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(); }

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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 {

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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.

View File

@ -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 ) {

View File

@ -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();
}

View File

@ -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:

View File

@ -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;

View File

@ -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);

View File

@ -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";
}
}

View File

@ -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());

View File

@ -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.

View File

@ -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