Update LLVM to r96341.
This commit is contained in:
parent
3fd58f91dd
commit
f25ddd991a
@ -365,9 +365,18 @@ endif
|
||||
# CXX.Flags += -fvisibility-inlines-hidden
|
||||
#endif
|
||||
|
||||
ifdef ENABLE_EXPENSIVE_CHECKS
|
||||
# GNU libstdc++ uses RTTI if you define _GLIBCXX_DEBUG, which we did above.
|
||||
# See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40160
|
||||
REQUIRES_RTTI := 1
|
||||
endif
|
||||
|
||||
# IF REQUIRES_EH=1 is specified then don't disable exceptions
|
||||
ifndef REQUIRES_EH
|
||||
CXX.Flags += -fno-exceptions
|
||||
else
|
||||
# If the library requires EH, it also requires RTTI.
|
||||
REQUIRES_RTTI := 1
|
||||
endif
|
||||
|
||||
ifdef REQUIRES_FRAME_POINTER
|
||||
@ -377,9 +386,9 @@ ifdef REQUIRES_FRAME_POINTER
|
||||
endif
|
||||
|
||||
# If REQUIRES_RTTI=1 is specified then don't disable run-time type id.
|
||||
ifeq ($(REQUIRES_RTTI), 1)
|
||||
CXX.Flags := $(filter-out -fno-rtti,$(CXX.Flags))
|
||||
CXXFLAGS := $(filter-out -fno-rtti,$(CXXFLAGS))
|
||||
ifneq ($(REQUIRES_RTTI), 1)
|
||||
CXX.Flags += -fno-rtti
|
||||
CXXFLAGS += -fno-rtti
|
||||
endif
|
||||
|
||||
ifdef ENABLE_COVERAGE
|
||||
@ -468,13 +477,6 @@ ifeq ($(ARCH),Alpha)
|
||||
LD.Flags += -Wl,--no-relax
|
||||
endif
|
||||
|
||||
ifdef ENABLE_EXPENSIVE_CHECKS
|
||||
# GNU libstdc++ uses RTTI if you define _GLIBCXX_DEBUG, which we did above.
|
||||
# See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40160
|
||||
CXX.Flags := $(filter-out -fno-rtti,$(CXX.Flags))
|
||||
CXXFLAGS := $(filter-out -fno-rtti,$(CXXFLAGS))
|
||||
endif
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Directory locations
|
||||
#--------------------------------------------------------------------
|
||||
@ -1572,6 +1574,11 @@ $(ObjDir)/%GenDisassemblerTables.inc.tmp : %.td $(ObjDir)/.dir
|
||||
$(Echo) "Building $(<F) disassembly tables with tblgen"
|
||||
$(Verb) $(TableGen) -gen-disassembler -o $(call SYSPATH, $@) $<
|
||||
|
||||
$(TARGET:%=$(ObjDir)/%GenEDInfo.inc.tmp): \
|
||||
$(ObjDir)/%GenEDInfo.inc.tmp : %.td $(ObjDir)/.dir
|
||||
$(Echo) "Building $(<F) enhanced disassembly information with tblgen"
|
||||
$(Verb) $(TableGen) -gen-enhanced-disassembly-info -o $(call SYSPATH, $@) $<
|
||||
|
||||
$(TARGET:%=$(ObjDir)/%GenFastISel.inc.tmp): \
|
||||
$(ObjDir)/%GenFastISel.inc.tmp : %.td $(ObjDir)/.dir
|
||||
$(Echo) "Building $(<F) \"fast\" instruction selector implementation with tblgen"
|
||||
|
@ -10,4 +10,3 @@ the license agreement found in LICENSE.txt.
|
||||
|
||||
Please see the HTML documentation provided in docs/index.html for further
|
||||
assistance with LLVM.
|
||||
|
||||
|
@ -727,13 +727,13 @@ fi
|
||||
|
||||
dnl --enable-libffi : check whether the user wants to turn off libffi:
|
||||
AC_ARG_ENABLE(libffi,AS_HELP_STRING(
|
||||
--enable-libffi,[Check for the presence of libffi (default is YES)]),,
|
||||
enableval=yes)
|
||||
case "$enableval" in
|
||||
yes) llvm_cv_enable_libffi="yes" ;;
|
||||
no) llvm_cv_enable_libffi="no" ;;
|
||||
*) AC_MSG_ERROR([Invalid setting for --enable-libffi. Use "yes" or "no"]) ;;
|
||||
esac
|
||||
--enable-libffi,[Check for the presence of libffi (default is NO)]),
|
||||
[case "$enableval" in
|
||||
yes) llvm_cv_enable_libffi="yes" ;;
|
||||
no) llvm_cv_enable_libffi="no" ;;
|
||||
*) AC_MSG_ERROR([Invalid setting for --enable-libffi. Use "yes" or "no"]) ;;
|
||||
esac],
|
||||
llvm_cv_enable_libffi=no)
|
||||
|
||||
dnl Only Windows needs dynamic libCompilerDriver to support plugins.
|
||||
if test "$llvm_cv_os_type" = "Win32" ; then
|
||||
@ -789,6 +789,7 @@ AC_PATH_PROG(GREP, [grep], [grep])
|
||||
AC_PATH_PROG(MKDIR,[mkdir],[mkdir])
|
||||
AC_PATH_PROG(MV, [mv], [mv])
|
||||
AC_PROG_RANLIB
|
||||
AC_CHECK_TOOL(AR, ar, false)
|
||||
AC_PATH_PROG(RM, [rm], [rm])
|
||||
AC_PATH_PROG(SED, [sed], [sed])
|
||||
AC_PATH_PROG(TAR, [tar], [gtar])
|
||||
@ -919,13 +920,6 @@ dnl before the AC_PROG_LIBTOOL check in order to enable dlopening libraries with
|
||||
dnl libtool).
|
||||
AC_LIBTOOL_DLOPEN
|
||||
AC_LIB_LTDL
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
if test "$lt_cv_dlopen_self" = "yes" ; then
|
||||
AC_DEFINE([CAN_DLOPEN_SELF],[1],
|
||||
[Define if dlopen(0) will open the symbols of the program])
|
||||
fi
|
||||
|
||||
|
||||
if test "$WITH_LLVMGCCDIR" = "default" ; then
|
||||
LLVMGCC="llvm-gcc${EXEEXT}"
|
||||
@ -1027,7 +1021,7 @@ dnl libffi is optional; used to call external functions from the interpreter
|
||||
if test "$llvm_cv_enable_libffi" = "yes" ; then
|
||||
AC_SEARCH_LIBS(ffi_call,ffi,AC_DEFINE([HAVE_FFI_CALL],[1],
|
||||
[Define if libffi is available on this platform.]),
|
||||
AC_MSG_WARN([libffi not found - disabling external calls from interpreter]))
|
||||
AC_MSG_ERROR([libffi not found - configure without --enable-libffi to compile without it]))
|
||||
fi
|
||||
|
||||
dnl mallinfo is optional; the code can compile (minus features) without it
|
||||
@ -1148,7 +1142,7 @@ dnl===-----------------------------------------------------------------------===
|
||||
AC_HUGE_VAL_CHECK
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_SIGNAL
|
||||
AC_DEFINE_UNQUOTED([RETSIGTYPE],[void],[Define as the return type of signal handlers (`int' or `void').])
|
||||
AC_STRUCT_TM
|
||||
AC_CHECK_TYPES([int64_t],,AC_MSG_ERROR([Type int64_t required but not found]))
|
||||
AC_CHECK_TYPES([uint64_t],,
|
||||
@ -1170,15 +1164,10 @@ AC_CHECK_FUNCS([strerror strerror_r strerror_s setenv ])
|
||||
AC_CHECK_FUNCS([strtoll strtoq sysconf malloc_zone_statistics ])
|
||||
AC_CHECK_FUNCS([setjmp longjmp sigsetjmp siglongjmp])
|
||||
AC_C_PRINTF_A
|
||||
dnl FIXME: This is no longer used, please remove (but test)!!!
|
||||
AC_FUNC_ALLOCA
|
||||
AC_FUNC_RAND48
|
||||
|
||||
dnl Check for variations in the Standard C++ library and STL. These macros are
|
||||
dnl provided by LLVM in the autoconf/m4 directory.
|
||||
AC_CXX_HAVE_STD_ITERATOR
|
||||
AC_CXX_HAVE_BI_ITERATOR
|
||||
AC_CXX_HAVE_FWD_ITERATOR
|
||||
AC_FUNC_ISNAN
|
||||
AC_FUNC_ISINF
|
||||
|
||||
|
@ -19,7 +19,7 @@ if test x"${with_tclinclude}" != x ; then
|
||||
else
|
||||
AC_MSG_ERROR([${with_tclinclude} directory doesn't contain tclsh])
|
||||
fi
|
||||
fi
|
||||
fi])
|
||||
|
||||
dnl see if one is installed
|
||||
if test x"${ac_cv_path_tclsh}" = x ; then
|
||||
@ -35,5 +35,5 @@ else
|
||||
TCLSH="${ac_cv_path_tclsh}"
|
||||
AC_SUBST(TCLSH)
|
||||
fi
|
||||
])])
|
||||
])
|
||||
|
||||
|
@ -93,6 +93,7 @@ module Attribute = struct
|
||||
| Noredzone
|
||||
| Noimplicitfloat
|
||||
| Naked
|
||||
| Inlinehint
|
||||
end
|
||||
|
||||
module Icmp = struct
|
||||
@ -144,7 +145,7 @@ type ('a, 'b) llrev_pos =
|
||||
|
||||
(*===-- Contexts ----------------------------------------------------------===*)
|
||||
external create_context : unit -> llcontext = "llvm_create_context"
|
||||
external dispose_context : unit -> llcontext = "llvm_dispose_context"
|
||||
external dispose_context : llcontext -> unit = "llvm_dispose_context"
|
||||
external global_context : unit -> llcontext = "llvm_global_context"
|
||||
|
||||
(*===-- Modules -----------------------------------------------------------===*)
|
||||
|
@ -143,6 +143,7 @@ module Attribute : sig
|
||||
| Noredzone
|
||||
| Noimplicitfloat
|
||||
| Naked
|
||||
| Inlinehint
|
||||
end
|
||||
|
||||
(** The predicate for an integer comparison ([icmp]) instruction.
|
||||
@ -214,7 +215,7 @@ external create_context : unit -> llcontext = "llvm_create_context"
|
||||
|
||||
(** [destroy_context ()] destroys a context. See the destructor
|
||||
[llvm::LLVMContext::~LLVMContext]. *)
|
||||
external dispose_context : unit -> llcontext = "llvm_dispose_context"
|
||||
external dispose_context : llcontext -> unit = "llvm_dispose_context"
|
||||
|
||||
(** See the function [llvm::getGlobalContext]. *)
|
||||
external global_context : unit -> llcontext = "llvm_global_context"
|
||||
@ -1419,13 +1420,13 @@ external build_aggregate_ret : llvalue array -> llbuilder -> llvalue
|
||||
= "llvm_build_aggregate_ret"
|
||||
|
||||
(** [build_br bb b] creates a
|
||||
[b %bb]
|
||||
[br %bb]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
See the method [llvm::LLVMBuilder::CreateBr]. *)
|
||||
external build_br : llbasicblock -> llbuilder -> llvalue = "llvm_build_br"
|
||||
|
||||
(** [build_cond_br cond tbb fbb b] creates a
|
||||
[b %cond, %tbb, %fbb]
|
||||
[br %cond, %tbb, %fbb]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
See the method [llvm::LLVMBuilder::CreateCondBr]. *)
|
||||
external build_cond_br : llvalue -> llbasicblock -> llbasicblock -> llbuilder ->
|
||||
@ -1475,7 +1476,7 @@ external build_unreachable : llbuilder -> llvalue = "llvm_build_unreachable"
|
||||
external build_add : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_add"
|
||||
|
||||
(** [build_nswadd x y name b] creates a
|
||||
(** [build_nsw_add x y name b] creates a
|
||||
[%name = nsw add %x, %y]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
See the method [llvm::LLVMBuilder::CreateNSWAdd]. *)
|
||||
|
@ -1031,8 +1031,8 @@ CAMLprim LLVMValueRef llvm_build_switch(LLVMValueRef Of,
|
||||
return LLVMBuildSwitch(Builder_val(B), Of, Else, Int_val(EstimatedCount));
|
||||
}
|
||||
|
||||
CAMLprim value llvm_add_case(LLVMValueRef Switch,
|
||||
LLVMValueRef OnVal,
|
||||
/* llvalue -> llvalue -> llbasicblock -> unit */
|
||||
CAMLprim value llvm_add_case(LLVMValueRef Switch, LLVMValueRef OnVal,
|
||||
LLVMBasicBlockRef Dest) {
|
||||
LLVMAddCase(Switch, OnVal, Dest);
|
||||
return Val_unit;
|
||||
@ -1263,11 +1263,10 @@ CAMLprim LLVMValueRef llvm_build_in_bounds_gep(LLVMValueRef Pointer,
|
||||
|
||||
/* llvalue -> int -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_struct_gep(LLVMValueRef Pointer,
|
||||
value Indices, value Name,
|
||||
value Index, value Name,
|
||||
value B) {
|
||||
return LLVMBuildInBoundsGEP(Builder_val(B), Pointer,
|
||||
(LLVMValueRef *) Op_val(Indices),
|
||||
Wosize_val(Indices), String_val(Name));
|
||||
return LLVMBuildStructGEP(Builder_val(B), Pointer,
|
||||
Int_val(Index), String_val(Name));
|
||||
}
|
||||
|
||||
/* string -> string -> llbuilder -> llvalue */
|
||||
|
@ -49,13 +49,13 @@ Show the B<lit> help message.
|
||||
|
||||
=item B<-j> I<N>, B<--threads>=I<N>
|
||||
|
||||
Run I<N> tests in parallel. By default, this is automatically chose to match the
|
||||
number of detected available CPUs.
|
||||
Run I<N> tests in parallel. By default, this is automatically chosen to match
|
||||
the number of detected available CPUs.
|
||||
|
||||
=item B<--config-prefix>=I<NAME>
|
||||
|
||||
Search for I<NAME.cfg> and I<NAME.site.cfg> when searching for test suites,
|
||||
instead I<lit.cfg> and I<lit.site.cfg>.
|
||||
instead of I<lit.cfg> and I<lit.site.cfg>.
|
||||
|
||||
=item B<--param> I<NAME>, B<--param> I<NAME>=I<VALUE>
|
||||
|
||||
@ -237,7 +237,7 @@ creating a new B<lit> testing implementation, or extending an existing one.
|
||||
|
||||
B<lit> proper is primarily an infrastructure for discovering and running
|
||||
arbitrary tests, and to expose a single convenient interface to these
|
||||
tests. B<lit> itself doesn't contain know how to run tests, rather this logic is
|
||||
tests. B<lit> itself doesn't know how to run tests, rather this logic is
|
||||
defined by I<test suites>.
|
||||
|
||||
=head2 TEST SUITES
|
||||
|
@ -34,7 +34,13 @@ B<llvm-extract> will write raw bitcode regardless of the output device.
|
||||
|
||||
=item B<--func> I<function-name>
|
||||
|
||||
Extract the function named I<function-name> from the LLVM bitcode.
|
||||
Extract the function named I<function-name> from the LLVM bitcode. May be
|
||||
specified multiple times to extract multiple functions at once.
|
||||
|
||||
=item B<--glob> I<global-name>
|
||||
|
||||
Extract the global variable named I<global-name> from the LLVM bitcode. May be
|
||||
specified multiple times to extract multiple global variables at once.
|
||||
|
||||
=item B<--help>
|
||||
|
||||
|
@ -39,6 +39,7 @@
|
||||
<li><a href="#llvm_eh_sjlj_setjmp"><tt>llvm.eh.sjlj.setjmp</tt></a></li>
|
||||
<li><a href="#llvm_eh_sjlj_longjmp"><tt>llvm.eh.sjlj.longjmp</tt></a></li>
|
||||
<li><a href="#llvm_eh_sjlj_lsda"><tt>llvm.eh.sjlj.lsda</tt></a></li>
|
||||
<li><a href="#llvm_eh_sjlj_callsite"><tt>llvm.eh.sjlj.callsite</tt></a></li>
|
||||
</ol></li>
|
||||
<li><a href="#asm">Asm Table Formats</a>
|
||||
<ol>
|
||||
@ -508,6 +509,24 @@
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="llvm_eh_sjlj_callsite">llvm.eh.sjlj.callsite</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<pre>
|
||||
void %<a href="#llvm_eh_sjlj_callsite">llvm.eh.sjlj.callsite</a>(i32)
|
||||
</pre>
|
||||
|
||||
<p>For SJLJ based exception handling, the <a href="#llvm_eh_sjlj_callsite">
|
||||
<tt>llvm.eh.sjlj.callsite</tt></a> intrinsic identifies the callsite value
|
||||
associated with the following invoke instruction. This is used to ensure
|
||||
that landing pad entries in the LSDA are generated in the matching order.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_section">
|
||||
<a name="asm">Asm Table Formats</a>
|
||||
@ -580,7 +599,7 @@
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-10-14 18:11:37 +0200 (Wed, 14 Oct 2009) $
|
||||
Last modified: $Date: 2010-01-28 02:45:32 +0100 (Thu, 28 Jan 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -256,13 +256,13 @@ software you will need.</p>
|
||||
<td>Cygwin/Win32</td>
|
||||
<td>x86<sup><a href="#pf_1">1</a>,<a href="#pf_8">8</a>,
|
||||
<a href="#pf_11">11</a></sup></td>
|
||||
<td>GCC 3.4.X, binutils 2.15</td>
|
||||
<td>GCC 3.4.X, binutils 2.20</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MinGW/Win32</td>
|
||||
<td>x86<sup><a href="#pf_1">1</a>,<a href="#pf_6">6</a>,
|
||||
<a href="#pf_8">8</a>, <a href="#pf_10">10</a></sup></td>
|
||||
<td>GCC 3.4.X, binutils 2.15</td>
|
||||
<td>GCC 3.4.X, binutils 2.20</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@ -318,12 +318,8 @@ up</a></li>
|
||||
<li><a name="pf_5">The GCC-based C/C++ frontend does not build</a></li>
|
||||
<li><a name="pf_6">The port is done using the MSYS shell.</a></li>
|
||||
<li><a name="pf_7">Native code generation exists but is not complete.</a></li>
|
||||
<li><a name="pf_8">Binutils</a> up to post-2.17 has bug in bfd/cofflink.c
|
||||
preventing LLVM from building correctly. Several workarounds have been
|
||||
introduced into LLVM build system, but the bug can occur anytime in the
|
||||
future. We highly recommend that you rebuild your current binutils with the
|
||||
patch from <a href="http://sourceware.org/bugzilla/show_bug.cgi?id=2659">
|
||||
Binutils bugzilla</a>, if it wasn't already applied.</li>
|
||||
<li><a name="pf_8">Binutils 2.20 or later is required to build the assembler
|
||||
generated by LLVM properly.</a></li>
|
||||
<li><a name="pf_9">XCode 2.5 and gcc 4.0.1</a> (Apple Build 5370) will trip
|
||||
internal LLVM assert messages when compiled for Release at optimization
|
||||
levels greater than 0 (i.e., <i>"-O1"</i> and higher).
|
||||
@ -1671,7 +1667,7 @@ out:</p>
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.x10sys.com/rspencer/">Reid Spencer</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-12-17 18:18:11 +0100 (Thu, 17 Dec 2009) $
|
||||
Last modified: $Date: 2010-02-11 22:51:51 +0100 (Thu, 11 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -66,12 +66,17 @@
|
||||
</li>
|
||||
<li><a href="#t_derived">Derived Types</a>
|
||||
<ol>
|
||||
<li><a href="#t_array">Array Type</a></li>
|
||||
<li><a href="#t_aggregate">Aggregate Types</a>
|
||||
<ol>
|
||||
<li><a href="#t_array">Array Type</a></li>
|
||||
<li><a href="#t_struct">Structure Type</a></li>
|
||||
<li><a href="#t_pstruct">Packed Structure Type</a></li>
|
||||
<li><a href="#t_union">Union Type</a></li>
|
||||
<li><a href="#t_vector">Vector Type</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="#t_function">Function Type</a></li>
|
||||
<li><a href="#t_pointer">Pointer Type</a></li>
|
||||
<li><a href="#t_struct">Structure Type</a></li>
|
||||
<li><a href="#t_pstruct">Packed Structure Type</a></li>
|
||||
<li><a href="#t_vector">Vector Type</a></li>
|
||||
<li><a href="#t_opaque">Opaque Type</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
@ -1078,11 +1083,21 @@ define void @f() optsize { ... }
|
||||
</div>
|
||||
|
||||
<dl>
|
||||
<dt><tt><b>alignstack(<<em>n</em>>)</b></tt></dt>
|
||||
<dd>This attribute indicates that, when emitting the prologue and epilogue,
|
||||
the backend should forcibly align the stack pointer. Specify the
|
||||
desired alignment, which must be a power of two, in parentheses.
|
||||
|
||||
<dt><tt><b>alwaysinline</b></tt></dt>
|
||||
<dd>This attribute indicates that the inliner should attempt to inline this
|
||||
function into callers whenever possible, ignoring any active inlining size
|
||||
threshold for this caller.</dd>
|
||||
|
||||
<dt><tt><b>inlinehint</b></tt></dt>
|
||||
<dd>This attribute indicates that the source code contained a hint that inlining
|
||||
this function is desirable (such as the "inline" keyword in C/C++). It
|
||||
is just a hint; it imposes no requirements on the inliner.</dd>
|
||||
|
||||
<dt><tt><b>noinline</b></tt></dt>
|
||||
<dd>This attribute indicates that the inliner should never inline this
|
||||
function in any situation. This attribute may not be used together with
|
||||
@ -1394,6 +1409,7 @@ Classifications</a> </div>
|
||||
<a href="#t_pointer">pointer</a>,
|
||||
<a href="#t_vector">vector</a>,
|
||||
<a href="#t_struct">structure</a>,
|
||||
<a href="#t_union">union</a>,
|
||||
<a href="#t_array">array</a>,
|
||||
<a href="#t_label">label</a>,
|
||||
<a href="#t_metadata">metadata</a>.
|
||||
@ -1408,12 +1424,12 @@ Classifications</a> </div>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="#t_derived">derived</a></td>
|
||||
<td><a href="#t_integer">integer</a>,
|
||||
<a href="#t_array">array</a>,
|
||||
<td><a href="#t_array">array</a>,
|
||||
<a href="#t_function">function</a>,
|
||||
<a href="#t_pointer">pointer</a>,
|
||||
<a href="#t_struct">structure</a>,
|
||||
<a href="#t_pstruct">packed structure</a>,
|
||||
<a href="#t_union">union</a>,
|
||||
<a href="#t_vector">vector</a>,
|
||||
<a href="#t_opaque">opaque</a>.
|
||||
</td>
|
||||
@ -1551,6 +1567,21 @@ Classifications</a> </div>
|
||||
possible to have a two dimensional array, using an array as the element type
|
||||
of another array.</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"> <a name="t_aggregate">Aggregate Types</a> </div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>Aggregate Types are a subset of derived types that can contain multiple
|
||||
member types. <a href="#t_array">Arrays</a>,
|
||||
<a href="#t_struct">structs</a>, <a href="#t_vector">vectors</a> and
|
||||
<a href="#t_union">unions</a> are aggregate types.</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
@ -1619,9 +1650,9 @@ Classifications</a> </div>
|
||||
<h5>Overview:</h5>
|
||||
<p>The function type can be thought of as a function signature. It consists of
|
||||
a return type and a list of formal parameter types. The return type of a
|
||||
function type is a scalar type, a void type, or a struct type. If the return
|
||||
type is a struct type then all struct elements must be of first class types,
|
||||
and the struct must have at least one element.</p>
|
||||
function type is a scalar type, a void type, a struct type, or a union
|
||||
type. If the return type is a struct type then all struct elements must be
|
||||
of first class types, and the struct must have at least one element.</p>
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<pre>
|
||||
@ -1743,6 +1774,53 @@ Classifications</a> </div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"> <a name="t_union">Union Type</a> </div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>A union type describes an object with size and alignment suitable for
|
||||
an object of any one of a given set of types (also known as an "untagged"
|
||||
union). It is similar in concept and usage to a
|
||||
<a href="#t_struct">struct</a>, except that all members of the union
|
||||
have an offset of zero. The elements of a union may be any type that has a
|
||||
size. Unions must have at least one member - empty unions are not allowed.
|
||||
</p>
|
||||
|
||||
<p>The size of the union as a whole will be the size of its largest member,
|
||||
and the alignment requirements of the union as a whole will be the largest
|
||||
alignment requirement of any member.</p>
|
||||
|
||||
<p>Unions members are accessed using '<tt><a href="#i_load">load</a></tt> and
|
||||
'<tt><a href="#i_store">store</a></tt>' by getting a pointer to a field with
|
||||
the '<tt><a href="#i_getelementptr">getelementptr</a></tt>' instruction.
|
||||
Since all members are at offset zero, the getelementptr instruction does
|
||||
not affect the address, only the type of the resulting pointer.</p>
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<pre>
|
||||
union { <type list> }
|
||||
</pre>
|
||||
|
||||
<h5>Examples:</h5>
|
||||
<table class="layout">
|
||||
<tr class="layout">
|
||||
<td class="left"><tt>union { i32, i32*, float }</tt></td>
|
||||
<td class="left">A union of three types: an <tt>i32</tt>, a pointer to
|
||||
an <tt>i32</tt>, and a <tt>float</tt>.</td>
|
||||
</tr><tr class="layout">
|
||||
<td class="left">
|
||||
<tt>union { float, i32 (i32) * }</tt></td>
|
||||
<td class="left">A union, where the first element is a <tt>float</tt> and the
|
||||
second element is a <a href="#t_pointer">pointer</a> to a
|
||||
<a href="#t_function">function</a> that takes an <tt>i32</tt>, returning
|
||||
an <tt>i32</tt>.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"> <a name="t_pointer">Pointer Type</a> </div>
|
||||
|
||||
@ -1981,6 +2059,14 @@ Classifications</a> </div>
|
||||
the number and types of elements must match those specified by the
|
||||
type.</dd>
|
||||
|
||||
<dt><b>Union constants</b></dt>
|
||||
<dd>Union constants are represented with notation similar to a structure with
|
||||
a single element - that is, a single typed element surrounded
|
||||
by braces (<tt>{}</tt>)). For example: "<tt>{ i32 4 }</tt>". The
|
||||
<a href="#t_union">union type</a> can be initialized with a single-element
|
||||
struct as long as the type of the struct element matches the type of
|
||||
one of the union members.</dd>
|
||||
|
||||
<dt><b>Array constants</b></dt>
|
||||
<dd>Array constants are represented with notation similar to array type
|
||||
definitions (a comma separated list of elements, surrounded by square
|
||||
@ -1999,7 +2085,8 @@ Classifications</a> </div>
|
||||
|
||||
<dt><b>Zero initialization</b></dt>
|
||||
<dd>The string '<tt>zeroinitializer</tt>' can be used to zero initialize a
|
||||
value to zero of <em>any</em> type, including scalar and aggregate types.
|
||||
value to zero of <em>any</em> type, including scalar and
|
||||
<a href="#t_aggregate">aggregate</a> types.
|
||||
This is often used to avoid having to print large zero initializers
|
||||
(e.g. for large arrays) and is always exactly equivalent to using explicit
|
||||
zero initializers.</dd>
|
||||
@ -3835,7 +3922,8 @@ Instruction</a> </div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>LLVM supports several instructions for working with aggregate values.</p>
|
||||
<p>LLVM supports several instructions for working with
|
||||
<a href="#t_aggregate">aggregate</a> values.</p>
|
||||
|
||||
</div>
|
||||
|
||||
@ -3852,14 +3940,14 @@ Instruction</a> </div>
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>The '<tt>extractvalue</tt>' instruction extracts the value of a struct field
|
||||
or array element from an aggregate value.</p>
|
||||
<p>The '<tt>extractvalue</tt>' instruction extracts the value of a member field
|
||||
from an <a href="#t_aggregate">aggregate</a> value.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>The first operand of an '<tt>extractvalue</tt>' instruction is a value
|
||||
of <a href="#t_struct">struct</a> or <a href="#t_array">array</a> type. The
|
||||
operands are constant indices to specify which value to extract in a similar
|
||||
manner as indices in a
|
||||
of <a href="#t_struct">struct</a>, <a href="#t_union">union</a> or
|
||||
<a href="#t_array">array</a> type. The operands are constant indices to
|
||||
specify which value to extract in a similar manner as indices in a
|
||||
'<tt><a href="#i_getelementptr">getelementptr</a></tt>' instruction.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
@ -3886,16 +3974,15 @@ Instruction</a> </div>
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>The '<tt>insertvalue</tt>' instruction inserts a value into a struct field or
|
||||
array element in an aggregate.</p>
|
||||
|
||||
<p>The '<tt>insertvalue</tt>' instruction inserts a value into a member field
|
||||
in an <a href="#t_aggregate">aggregate</a> value.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>The first operand of an '<tt>insertvalue</tt>' instruction is a value
|
||||
of <a href="#t_struct">struct</a> or <a href="#t_array">array</a> type. The
|
||||
second operand is a first-class value to insert. The following operands are
|
||||
constant indices indicating the position at which to insert the value in a
|
||||
similar manner as indices in a
|
||||
of <a href="#t_struct">struct</a>, <a href="#t_union">union</a> or
|
||||
<a href="#t_array">array</a> type. The second operand is a first-class
|
||||
value to insert. The following operands are constant indices indicating
|
||||
the position at which to insert the value in a similar manner as indices in a
|
||||
'<tt><a href="#i_getelementptr">getelementptr</a></tt>' instruction. The
|
||||
value to insert must have the same type as the value identified by the
|
||||
indices.</p>
|
||||
@ -4097,8 +4184,8 @@ Instruction</a> </div>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>The '<tt>getelementptr</tt>' instruction is used to get the address of a
|
||||
subelement of an aggregate data structure. It performs address calculation
|
||||
only and does not access memory.</p>
|
||||
subelement of an <a href="#t_aggregate">aggregate</a> data structure.
|
||||
It performs address calculation only and does not access memory.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>The first argument is always a pointer, and forms the basis of the
|
||||
@ -4108,15 +4195,15 @@ Instruction</a> </div>
|
||||
indexes the pointer value given as the first argument, the second index
|
||||
indexes a value of the type pointed to (not necessarily the value directly
|
||||
pointed to, since the first index can be non-zero), etc. The first type
|
||||
indexed into must be a pointer value, subsequent types can be arrays, vectors
|
||||
and structs. Note that subsequent types being indexed into can never be
|
||||
pointers, since that would require loading the pointer before continuing
|
||||
calculation.</p>
|
||||
indexed into must be a pointer value, subsequent types can be arrays,
|
||||
vectors, structs and unions. Note that subsequent types being indexed into
|
||||
can never be pointers, since that would require loading the pointer before
|
||||
continuing calculation.</p>
|
||||
|
||||
<p>The type of each index argument depends on the type it is indexing into.
|
||||
When indexing into a (optionally packed) structure, only <tt>i32</tt> integer
|
||||
<b>constants</b> are allowed. When indexing into an array, pointer or
|
||||
vector, integers of any width are allowed, and they are not required to be
|
||||
When indexing into a (optionally packed) structure or union, only <tt>i32</tt>
|
||||
integer <b>constants</b> are allowed. When indexing into an array, pointer
|
||||
or vector, integers of any width are allowed, and they are not required to be
|
||||
constant.</p>
|
||||
|
||||
<p>For example, let's consider a C code fragment and how it gets compiled to
|
||||
@ -7345,7 +7432,7 @@ LLVM</a>.</p>
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2010-01-15 22:50:19 +0100 (Fri, 15 Jan 2010) $
|
||||
Last modified: $Date: 2010-02-12 21:49:41 +0100 (Fri, 12 Feb 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -150,6 +150,7 @@ with another <tt>Value</tt></a> </li>
|
||||
<li><a href="#shutdown">Ending execution with <tt>llvm_shutdown()</tt></a></li>
|
||||
<li><a href="#managedstatic">Lazy initialization with <tt>ManagedStatic</tt></a></li>
|
||||
<li><a href="#llvmcontext">Achieving Isolation with <tt>LLVMContext</tt></a></li>
|
||||
<li><a href="#jitthreading">Threads and the JIT</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@ -2386,9 +2387,9 @@ failure of the initialization. Failure typically indicates that your copy of
|
||||
LLVM was built without multithreading support, typically because GCC atomic
|
||||
intrinsics were not found in your system compiler. In this case, the LLVM API
|
||||
will not be safe for concurrent calls. However, it <em>will</em> be safe for
|
||||
hosting threaded applications in the JIT, though care must be taken to ensure
|
||||
that side exits and the like do not accidentally result in concurrent LLVM API
|
||||
calls.
|
||||
hosting threaded applications in the JIT, though <a href="#jitthreading">care
|
||||
must be taken</a> to ensure that side exits and the like do not accidentally
|
||||
result in concurrent LLVM API calls.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -2485,6 +2486,34 @@ isolation is not a concern.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
<a name="jitthreading">Threads and the JIT</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<p>
|
||||
LLVM's "eager" JIT compiler is safe to use in threaded programs. Multiple
|
||||
threads can call <tt>ExecutionEngine::getPointerToFunction()</tt> or
|
||||
<tt>ExecutionEngine::runFunction()</tt> concurrently, and multiple threads can
|
||||
run code output by the JIT concurrently. The user must still ensure that only
|
||||
one thread accesses IR in a given <tt>LLVMContext</tt> while another thread
|
||||
might be modifying it. One way to do that is to always hold the JIT lock while
|
||||
accessing IR outside the JIT (the JIT <em>modifies</em> the IR by adding
|
||||
<tt>CallbackVH</tt>s). Another way is to only
|
||||
call <tt>getPointerToFunction()</tt> from the <tt>LLVMContext</tt>'s thread.
|
||||
</p>
|
||||
|
||||
<p>When the JIT is configured to compile lazily (using
|
||||
<tt>ExecutionEngine::DisableLazyCompilation(false)</tt>), there is currently a
|
||||
<a href="http://llvm.org/bugs/show_bug.cgi?id=5184">race condition</a> in
|
||||
updating call sites after a function is lazily-jitted. It's still possible to
|
||||
use the lazy JIT in a threaded program if you ensure that only one thread at a
|
||||
time can call any particular lazy stub and that the JIT lock guards any IR
|
||||
access, but we suggest using only the eager JIT in threaded programs.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section">
|
||||
<a name="advanced">Advanced Topics</a>
|
||||
@ -2970,9 +2999,9 @@ the <tt>lib/VMCore</tt> directory.</p>
|
||||
<div class="doc_text">
|
||||
|
||||
<ul>
|
||||
<li><tt>bool isInteger() const</tt>: Returns true for any integer type.</li>
|
||||
<li><tt>bool isIntegerTy() const</tt>: Returns true for any integer type.</li>
|
||||
|
||||
<li><tt>bool isFloatingPoint()</tt>: Return true if this is one of the two
|
||||
<li><tt>bool isFloatingPointTy()</tt>: Return true if this is one of the five
|
||||
floating point types.</li>
|
||||
|
||||
<li><tt>bool isAbstract()</tt>: Return true if the type is abstract (contains
|
||||
@ -3892,7 +3921,7 @@ arguments. An argument has a pointer to the parent Function.</p>
|
||||
<a href="mailto:dhurjati@cs.uiuc.edu">Dinakar Dhurjati</a> and
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2010-01-05 19:24:00 +0100 (Tue, 05 Jan 2010) $
|
||||
Last modified: $Date: 2010-02-15 17:12:20 +0100 (Mon, 15 Feb 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -4,17 +4,17 @@
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
<title>LLVM 2.6 Release Notes</title>
|
||||
<title>LLVM 2.7 Release Notes</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="doc_title">LLVM 2.6 Release Notes</div>
|
||||
<div class="doc_title">LLVM 2.7 Release Notes</div>
|
||||
|
||||
<ol>
|
||||
<li><a href="#intro">Introduction</a></li>
|
||||
<li><a href="#subproj">Sub-project Status Update</a></li>
|
||||
<li><a href="#externalproj">External Projects Using LLVM 2.6</a></li>
|
||||
<li><a href="#whatsnew">What's New in LLVM 2.6?</a></li>
|
||||
<li><a href="#externalproj">External Projects Using LLVM 2.7</a></li>
|
||||
<li><a href="#whatsnew">What's New in LLVM 2.7?</a></li>
|
||||
<li><a href="GettingStarted.html">Installation Instructions</a></li>
|
||||
<li><a href="#portability">Portability and Supported Platforms</a></li>
|
||||
<li><a href="#knownproblems">Known Problems</a></li>
|
||||
@ -25,6 +25,12 @@
|
||||
<p>Written by the <a href="http://llvm.org">LLVM Team</a></p>
|
||||
</div>
|
||||
|
||||
<h1 style="color:red">These are in-progress notes for the upcoming LLVM 2.7
|
||||
release.<br>
|
||||
You may prefer the
|
||||
<a href="http://llvm.org/releases/2.6/docs/ReleaseNotes.html">LLVM 2.6
|
||||
Release Notes</a>.</h1>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section">
|
||||
<a name="intro">Introduction</a>
|
||||
@ -34,7 +40,7 @@
|
||||
<div class="doc_text">
|
||||
|
||||
<p>This document contains the release notes for the LLVM Compiler
|
||||
Infrastructure, release 2.6. Here we describe the status of LLVM, including
|
||||
Infrastructure, release 2.7. Here we describe the status of LLVM, including
|
||||
major improvements from the previous release and significant known problems.
|
||||
All LLVM releases may be downloaded from the <a
|
||||
href="http://llvm.org/releases/">LLVM releases web site</a>.</p>
|
||||
@ -63,7 +69,7 @@ Almost dead code.
|
||||
-->
|
||||
|
||||
|
||||
<!-- Unfinished features in 2.6:
|
||||
<!-- Features that need text if they're finished for 2.7:
|
||||
gcc plugin.
|
||||
strong phi elim
|
||||
variable debug info for optimized code
|
||||
@ -94,7 +100,7 @@ Almost dead code.
|
||||
|
||||
<div class="doc_text">
|
||||
<p>
|
||||
The LLVM 2.6 distribution currently consists of code from the core LLVM
|
||||
The LLVM 2.7 distribution currently consists of code from the core LLVM
|
||||
repository (which roughly includes the LLVM optimizers, code generators
|
||||
and supporting tools), the Clang repository and the llvm-gcc repository. In
|
||||
addition to this code, the LLVM Project includes other sub-projects that are in
|
||||
@ -111,31 +117,12 @@ development. Here we include updates on these subprojects.
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The <a href="http://clang.llvm.org/">Clang project</a> is an effort to build
|
||||
a set of new 'LLVM native' front-end technologies for the C family of languages.
|
||||
LLVM 2.6 is the first release to officially include Clang, and it provides a
|
||||
production quality C and Objective-C compiler. If you are interested in <a
|
||||
href="http://clang.llvm.org/performance.html">fast compiles</a> and
|
||||
<a href="http://clang.llvm.org/diagnostics.html">good diagnostics</a>, we
|
||||
encourage you to try it out. Clang currently compiles typical Objective-C code
|
||||
3x faster than GCC and compiles C code about 30% faster than GCC at -O0 -g
|
||||
(which is when the most pressure is on the frontend).</p>
|
||||
<p>The <a href="http://clang.llvm.org/">Clang project</a> is ...</p>
|
||||
|
||||
<p>In addition to supporting these languages, C++ support is also <a
|
||||
href="http://clang.llvm.org/cxx_status.html">well under way</a>, and mainline
|
||||
Clang is able to parse the libstdc++ 4.2 headers and even codegen simple apps.
|
||||
If you are interested in Clang C++ support or any other Clang feature, we
|
||||
strongly encourage you to get involved on the <a
|
||||
href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">Clang front-end mailing
|
||||
list</a>.</p>
|
||||
|
||||
<p>In the LLVM 2.6 time-frame, the Clang team has made many improvements:</p>
|
||||
<p>In the LLVM 2.7 time-frame, the Clang team has made many improvements:</p>
|
||||
|
||||
<ul>
|
||||
<li>C and Objective-C support are now considered production quality.</li>
|
||||
<li>AuroraUX, FreeBSD and OpenBSD are now supported.</li>
|
||||
<li>Most of Objective-C 2.0 is now supported with the GNU runtime.</li>
|
||||
<li>Many many bugs are fixed and lots of features have been added.</li>
|
||||
<li>...</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -146,24 +133,13 @@ list</a>.</p>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>Previously announced in the 2.4 and 2.5 LLVM releases, the Clang project also
|
||||
<p>Previously announced in the 2.4, 2.5, and 2.6 LLVM releases, the Clang project also
|
||||
includes an early stage static source code analysis tool for <a
|
||||
href="http://clang.llvm.org/StaticAnalysis.html">automatically finding bugs</a>
|
||||
in C and Objective-C programs. The tool performs checks to find
|
||||
bugs that occur on a specific path within a program.</p>
|
||||
|
||||
<p>In the LLVM 2.6 time-frame, the analyzer core has undergone several important
|
||||
improvements and cleanups and now includes a new <em>Checker</em> interface that
|
||||
is intended to eventually serve as a basis for domain-specific checks. Further,
|
||||
in addition to generating HTML files for reporting analysis results, the
|
||||
analyzer can now also emit bug reports in a structured XML format that is
|
||||
intended to be easily readable by other programs.</p>
|
||||
|
||||
<p>The set of checks performed by the static analyzer continues to expand, and
|
||||
future plans for the tool include full source-level inter-procedural analysis
|
||||
and deeper checks such as buffer overrun detection. There are many opportunities
|
||||
to extend and enhance the static analyzer, and anyone interested in working on
|
||||
this project is encouraged to get involved!</p>
|
||||
<p>In the LLVM 2.7 time-frame, the analyzer core has ...</p>
|
||||
|
||||
</div>
|
||||
|
||||
@ -180,20 +156,13 @@ implementation of the CLI) using LLVM for static and just-in-time
|
||||
compilation.</p>
|
||||
|
||||
<p>
|
||||
VMKit version 0.26 builds with LLVM 2.6 and you can find it on its
|
||||
VMKit version ?? builds with LLVM 2.7 and you can find it on its
|
||||
<a href="http://vmkit.llvm.org/releases/">web page</a>. The release includes
|
||||
bug fixes, cleanup and new features. The major changes are:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>A new llcj tool to generate shared libraries or executables of Java
|
||||
files.</li>
|
||||
<li>Cooperative garbage collection. </li>
|
||||
<li>Fast subtype checking (paper from Click et al [JGI'02]). </li>
|
||||
<li>Implementation of a two-word header for Java objects instead of the original
|
||||
three-word header. </li>
|
||||
<li>Better Java specification-compliance: division by zero checks, stack
|
||||
overflow checks, finalization and references support. </li>
|
||||
<li>...</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
@ -249,22 +218,7 @@ KLEE.</p>
|
||||
The goal of <a href="http://dragonegg.llvm.org/">DragonEgg</a> is to make
|
||||
gcc-4.5 act like llvm-gcc without requiring any gcc modifications whatsoever.
|
||||
<a href="http://dragonegg.llvm.org/">DragonEgg</a> is a shared library (dragonegg.so)
|
||||
that is loaded by gcc at runtime. It uses the new gcc plugin architecture to
|
||||
disable the GCC optimizers and code generators, and schedule the LLVM optimizers
|
||||
and code generators (or direct output of LLVM IR) instead. Currently only Linux
|
||||
and Darwin are supported, and only on x86-32 and x86-64. It should be easy to
|
||||
add additional unix-like architectures and other processor families. In theory
|
||||
it should be possible to use <a href="http://dragonegg.llvm.org/">DragonEgg</a>
|
||||
with any language supported by gcc, however only C and Fortran work well for the
|
||||
moment. Ada and C++ work to some extent, while Java, Obj-C and Obj-C++ are so
|
||||
far entirely untested. Since gcc-4.5 has not yet been released, neither has
|
||||
<a href="http://dragonegg.llvm.org/">DragonEgg</a>. To build
|
||||
<a href="http://dragonegg.llvm.org/">DragonEgg</a> you will need to check out the
|
||||
development versions of <a href="http://gcc.gnu.org/svn.html/"> gcc</a>,
|
||||
<a href="http://llvm.org/docs/GettingStarted.html#checkout">llvm</a> and
|
||||
<a href="http://dragonegg.llvm.org/">DragonEgg</a> from their respective
|
||||
subversion repositories, and follow the instructions in the
|
||||
<a href="http://dragonegg.llvm.org/">DragonEgg</a> README.
|
||||
that is loaded by gcc at runtime. It ...
|
||||
</p>
|
||||
|
||||
</div>
|
||||
@ -277,29 +231,7 @@ subversion repositories, and follow the instructions in the
|
||||
|
||||
<div class="doc_text">
|
||||
<p>
|
||||
The LLVM Machine Code (MC) Toolkit project is a (very early) effort to build
|
||||
better tools for dealing with machine code, object file formats, etc. The idea
|
||||
is to be able to generate most of the target specific details of assemblers and
|
||||
disassemblers from existing LLVM target .td files (with suitable enhancements),
|
||||
and to build infrastructure for reading and writing common object file formats.
|
||||
One of the first deliverables is to build a full assembler and integrate it into
|
||||
the compiler, which is predicted to substantially reduce compile time in some
|
||||
scenarios.
|
||||
</p>
|
||||
|
||||
<p>In the LLVM 2.6 timeframe, the MC framework has grown to the point where it
|
||||
can reliably parse and pretty print (with some encoding information) a
|
||||
darwin/x86 .s file successfully, and has the very early phases of a Mach-O
|
||||
assembler in progress. Beyond the MC framework itself, major refactoring of the
|
||||
LLVM code generator has started. The idea is to make the code generator reason
|
||||
about the code it is producing in a much more semantic way, rather than a
|
||||
textual way. For example, the code generator now uses MCSection objects to
|
||||
represent section assignments, instead of text strings that print to .section
|
||||
directives.</p>
|
||||
|
||||
<p>MC is an early and ongoing project that will hopefully continue to lead to
|
||||
many improvements in the code generator and build infrastructure useful for many
|
||||
other situations.
|
||||
The LLVM Machine Code (MC) Toolkit project is ...
|
||||
</p>
|
||||
|
||||
</div>
|
||||
@ -307,7 +239,7 @@ other situations.
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section">
|
||||
<a name="externalproj">External Open Source Projects Using LLVM 2.6</a>
|
||||
<a name="externalproj">External Open Source Projects Using LLVM 2.7</a>
|
||||
</div>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
@ -315,7 +247,7 @@ other situations.
|
||||
|
||||
<p>An exciting aspect of LLVM is that it is used as an enabling technology for
|
||||
a lot of other language and tools projects. This section lists some of the
|
||||
projects that have already been updated to work with LLVM 2.6.</p>
|
||||
projects that have already been updated to work with LLVM 2.7.</p>
|
||||
</div>
|
||||
|
||||
|
||||
@ -376,8 +308,8 @@ built-in list and matrix support (including list and matrix comprehensions) and
|
||||
an easy-to-use C interface. The interpreter uses LLVM as a backend to
|
||||
JIT-compile Pure programs to fast native code.</p>
|
||||
|
||||
<p>Pure versions 0.31 and later have been tested and are known to work with
|
||||
LLVM 2.6 (and continue to work with older LLVM releases >= 2.3 as well).
|
||||
<p>Pure versions ??? and later have been tested and are known to work with
|
||||
LLVM 2.7 (and continue to work with older LLVM releases >= 2.3 as well).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -460,7 +392,7 @@ code.
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section">
|
||||
<a name="whatsnew">What's New in LLVM 2.6?</a>
|
||||
<a name="whatsnew">What's New in LLVM 2.7?</a>
|
||||
</div>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
@ -480,28 +412,10 @@ in this section.
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>LLVM 2.6 includes several major new capabilities:</p>
|
||||
<p>LLVM 2.7 includes several major new capabilities:</p>
|
||||
|
||||
<ul>
|
||||
<li>New <a href="#compiler-rt">compiler-rt</a>, <A href="#klee">KLEE</a>
|
||||
and <a href="#mc">machine code toolkit</a> sub-projects.</li>
|
||||
<li>Debug information now includes line numbers when optimizations are enabled.
|
||||
This allows statistical sampling tools like OProfile and Shark to map
|
||||
samples back to source lines.</li>
|
||||
<li>LLVM now includes new experimental backends to support the MSP430, SystemZ
|
||||
and BlackFin architectures.</li>
|
||||
<li>LLVM supports a new <a href="GoldPlugin.html">Gold Linker Plugin</a> which
|
||||
enables support for <a href="LinkTimeOptimization.html">transparent
|
||||
link-time optimization</a> on ELF targets when used with the Gold binutils
|
||||
linker.</li>
|
||||
<li>LLVM now supports doing optimization and code generation on multiple
|
||||
threads. Please see the <a href="ProgrammersManual.html#threading">LLVM
|
||||
Programmer's Manual</a> for more information.</li>
|
||||
<li>LLVM now has experimental support for <a
|
||||
href="http://nondot.org/~sabre/LLVMNotes/EmbeddedMetadata.txt">embedded
|
||||
metadata</a> in LLVM IR, though the implementation is not guaranteed to be
|
||||
final and the .bc file format may change in future releases. Debug info
|
||||
does not yet use this format in LLVM 2.6.</li>
|
||||
<li>...</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@ -516,50 +430,7 @@ in this section.
|
||||
expose new optimization opportunities:</p>
|
||||
|
||||
<ul>
|
||||
<li>The <a href="LangRef.html#i_add">add</a>, <a
|
||||
href="LangRef.html#i_sub">sub</a> and <a href="LangRef.html#i_mul">mul</a>
|
||||
instructions have been split into integer and floating point versions (like
|
||||
divide and remainder), introducing new <a
|
||||
href="LangRef.html#i_fadd">fadd</a>, <a href="LangRef.html#i_fsub">fsub</a>,
|
||||
and <a href="LangRef.html#i_fmul">fmul</a> instructions.</li>
|
||||
<li>The <a href="LangRef.html#i_add">add</a>, <a
|
||||
href="LangRef.html#i_sub">sub</a> and <a href="LangRef.html#i_mul">mul</a>
|
||||
instructions now support optional "nsw" and "nuw" bits which indicate that
|
||||
the operation is guaranteed to not overflow (in the signed or
|
||||
unsigned case, respectively). This gives the optimizer more information and
|
||||
can be used for things like C signed integer values, which are undefined on
|
||||
overflow.</li>
|
||||
<li>The <a href="LangRef.html#i_sdiv">sdiv</a> instruction now supports an
|
||||
optional "exact" flag which indicates that the result of the division is
|
||||
guaranteed to have a remainder of zero. This is useful for optimizing pointer
|
||||
subtraction in C.</li>
|
||||
<li>The <a href="LangRef.html#i_getelementptr">getelementptr</a> instruction now
|
||||
supports arbitrary integer index values for array/pointer indices. This
|
||||
allows for better code generation on 16-bit pointer targets like PIC16.</li>
|
||||
<li>The <a href="LangRef.html#i_getelementptr">getelementptr</a> instruction now
|
||||
supports an "inbounds" optimization hint that tells the optimizer that the
|
||||
pointer is guaranteed to be within its allocated object.</li>
|
||||
<li>LLVM now support a series of new linkage types for global values which allow
|
||||
for better optimization and new capabilities:
|
||||
<ul>
|
||||
<li><a href="LangRef.html#linkage_linkonce">linkonce_odr</a> and
|
||||
<a href="LangRef.html#linkage_weak">weak_odr</a> have the same linkage
|
||||
semantics as the non-"odr" linkage types. The difference is that these
|
||||
linkage types indicate that all definitions of the specified function
|
||||
are guaranteed to have the same semantics. This allows inlining
|
||||
templates functions in C++ but not inlining weak functions in C,
|
||||
which previously both got the same linkage type.</li>
|
||||
<li><a href="LangRef.html#linkage_available_externally">available_externally
|
||||
</a> is a new linkage type that gives the optimizer visibility into the
|
||||
definition of a function (allowing inlining and side effect analysis)
|
||||
but that does not cause code to be generated. This allows better
|
||||
optimization of "GNU inline" functions, extern templates, etc.</li>
|
||||
<li><a href="LangRef.html#linkage_linker_private">linker_private</a> is a
|
||||
new linkage type (which is only useful on Mac OS X) that is used for
|
||||
some metadata generation and other obscure things.</li>
|
||||
</ul></li>
|
||||
<li>Finally, target-specific intrinsics can now return multiple values, which
|
||||
is useful for modeling target operations with multiple results.</li>
|
||||
<li>...</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@ -576,23 +447,7 @@ release includes a few major enhancements and additions to the optimizers:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>The <a href="Passes.html#scalarrepl">Scalar Replacement of Aggregates</a>
|
||||
pass has many improvements that allow it to better promote vector unions,
|
||||
variables which are memset, and much more strange code that can happen to
|
||||
do bitfield accesses to register operations. An interesting change is that
|
||||
it now produces "unusual" integer sizes (like i1704) in some cases and lets
|
||||
other optimizers clean things up.</li>
|
||||
<li>The <a href="Passes.html#loop-reduce">Loop Strength Reduction</a> pass now
|
||||
promotes small integer induction variables to 64-bit on 64-bit targets,
|
||||
which provides a major performance boost for much numerical code. It also
|
||||
promotes shorts to int on 32-bit hosts, etc. LSR now also analyzes pointer
|
||||
expressions (e.g. getelementptrs), as well as integers.</li>
|
||||
<li>The <a href="Passes.html#gvn">GVN</a> pass now eliminates partial
|
||||
redundancies of loads in simple cases.</li>
|
||||
<li>The <a href="Passes.html#inline">Inliner</a> now reuses stack space when
|
||||
inlining similar arrays from multiple callees into one caller.</li>
|
||||
<li>LLVM includes a new experimental Static Single Information (SSI)
|
||||
construction pass.</li>
|
||||
<li>...</li>
|
||||
|
||||
</ul>
|
||||
|
||||
@ -607,17 +462,15 @@ release includes a few major enhancements and additions to the optimizers:</p>
|
||||
<div class="doc_text">
|
||||
|
||||
<ul>
|
||||
<li>LLVM has a new "EngineBuilder" class which makes it more obvious how to
|
||||
set up and configure an ExecutionEngine (a JIT or interpreter).</li>
|
||||
<li>The JIT now supports generating more than 16M of code.</li>
|
||||
<li>When configured with <tt>--with-oprofile</tt>, the JIT can now inform
|
||||
OProfile about JIT'd code, allowing OProfile to get line number and function
|
||||
name information for JIT'd functions.</li>
|
||||
<li>When "libffi" is available, the LLVM interpreter now uses it, which supports
|
||||
calling almost arbitrary external (natively compiled) functions.</li>
|
||||
<li>Clients of the JIT can now register a 'JITEventListener' object to receive
|
||||
callbacks when the JIT emits or frees machine code. The OProfile support
|
||||
uses this mechanism.</li>
|
||||
<li>The JIT now <a
|
||||
href="http://llvm.org/viewvc/llvm-project?view=rev&revision=85295">defaults
|
||||
to compiling eagerly</a> to avoid a race condition in the lazy JIT.
|
||||
Clients that still want the lazy JIT can switch it on by calling
|
||||
<tt>ExecutionEngine::DisableLazyCompilation(false)</tt>.</li>
|
||||
<li>It is now possible to create more than one JIT instance in the same process.
|
||||
These JITs can generate machine code in parallel,
|
||||
although <a href="http://llvm.org/docs/ProgrammersManual.html#jitthreading">you
|
||||
still have to obey the other threading restrictions</a>.</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@ -635,54 +488,7 @@ it run faster:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>The <tt>llc -asm-verbose</tt> option (exposed from llvm-gcc as <tt>-dA</tt>
|
||||
and clang as <tt>-fverbose-asm</tt> or <tt>-dA</tt>) now adds a lot of
|
||||
useful information in comments to
|
||||
the generated .s file. This information includes location information (if
|
||||
built with <tt>-g</tt>) and loop nest information.</li>
|
||||
<li>The code generator now supports a new MachineVerifier pass which is useful
|
||||
for finding bugs in targets and codegen passes.</li>
|
||||
<li>The Machine LICM is now enabled by default. It hoists instructions out of
|
||||
loops (such as constant pool loads, loads from read-only stubs, vector
|
||||
constant synthesization code, etc.) and is currently configured to only do
|
||||
so when the hoisted operation can be rematerialized.</li>
|
||||
<li>The Machine Sinking pass is now enabled by default. This pass moves
|
||||
side-effect free operations down the CFG so that they are executed on fewer
|
||||
paths through a function.</li>
|
||||
<li>The code generator now performs "stack slot coloring" of register spills,
|
||||
which allows spill slots to be reused. This leads to smaller stack frames
|
||||
in cases where there are lots of register spills.</li>
|
||||
<li>The register allocator has many improvements to take better advantage of
|
||||
commutable operations, various spiller peephole optimizations, and can now
|
||||
coalesce cross-register-class copies.</li>
|
||||
<li>Tblgen now supports multiclass inheritance and a number of new string and
|
||||
list operations like <tt>!(subst)</tt>, <tt>!(foreach)</tt>, <tt>!car</tt>,
|
||||
<tt>!cdr</tt>, <tt>!null</tt>, <tt>!if</tt>, <tt>!cast</tt>.
|
||||
These make the .td files more expressive and allow more aggressive factoring
|
||||
of duplication across instruction patterns.</li>
|
||||
<li>Target-specific intrinsics can now be added without having to hack VMCore to
|
||||
add them. This makes it easier to maintain out-of-tree targets.</li>
|
||||
<li>The instruction selector is better at propagating information about values
|
||||
(such as whether they are sign/zero extended etc.) across basic block
|
||||
boundaries.</li>
|
||||
<li>The SelectionDAG datastructure has new nodes for representing buildvector
|
||||
and <a href="http://llvm.org/PR2957">vector shuffle</a> operations. This
|
||||
makes operations and pattern matching more efficient and easier to get
|
||||
right.</li>
|
||||
<li>The Prolog/Epilog Insertion Pass now has experimental support for performing
|
||||
the "shrink wrapping" optimization, which moves spills and reloads around in
|
||||
the CFG to avoid doing saves on paths that don't need them.</li>
|
||||
<li>LLVM includes new experimental support for writing ELF .o files directly
|
||||
from the compiler. It works well for many simple C testcases, but doesn't
|
||||
support exception handling, debug info, inline assembly, etc.</li>
|
||||
<li>Targets can now specify register allocation hints through
|
||||
<tt>MachineRegisterInfo::setRegAllocationHint</tt>. A regalloc hint consists
|
||||
of hint type and physical register number. A hint type of zero specifies a
|
||||
register allocation preference. Other hint type values are target specific
|
||||
which are resolved by <tt>TargetRegisterInfo::ResolveRegAllocHint</tt>. An
|
||||
example is the ARM target which uses register hints to request that the
|
||||
register allocator provide an even / odd register pair to two virtual
|
||||
registers.</li>
|
||||
<li>...</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -697,31 +503,7 @@ it run faster:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>SSE 4.2 builtins are now supported.</li>
|
||||
<li>GCC-compatible soft float modes are now supported, which are typically used
|
||||
by OS kernels.</li>
|
||||
<li>X86-64 now models implicit zero extensions better, which allows the code
|
||||
generator to remove a lot of redundant zexts. It also models the 8-bit "H"
|
||||
registers as subregs, which allows them to be used in some tricky
|
||||
situations.</li>
|
||||
<li>X86-64 now supports the "local exec" and "initial exec" thread local storage
|
||||
model.</li>
|
||||
<li>The vector forms of the <a href="LangRef.html#i_icmp">icmp</a> and <a
|
||||
href="LangRef.html#i_fcmp">fcmp</a> instructions now select to efficient
|
||||
SSE operations.</li>
|
||||
<li>Support for the win64 calling conventions have improved. The primary
|
||||
missing feature is support for varargs function definitions. It seems to
|
||||
work well for many win64 JIT purposes.</li>
|
||||
<li>The X86 backend has preliminary support for <a
|
||||
href="CodeGenerator.html#x86_memory">mapping address spaces to segment
|
||||
register references</a>. This allows you to write GS or FS relative memory
|
||||
accesses directly in LLVM IR for cases where you know exactly what you're
|
||||
doing (such as in an OS kernel). There are some known problems with this
|
||||
support, but it works in simple cases.</li>
|
||||
<li>The X86 code generator has been refactored to move all global variable
|
||||
reference logic to one place
|
||||
(<tt>X86Subtarget::ClassifyGlobalReference</tt>) which
|
||||
makes it easier to reason about.</li>
|
||||
<li>...</li>
|
||||
|
||||
</ul>
|
||||
|
||||
@ -737,11 +519,7 @@ it run faster:</p>
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Support for floating-point, indirect function calls, and
|
||||
passing/returning aggregate types to functions.
|
||||
<li>The code generator is able to generate debug info into output COFF files.
|
||||
<li>Support for placing an object into a specific section or at a specific
|
||||
address in memory.</li>
|
||||
<li>...</li>
|
||||
</ul>
|
||||
|
||||
<p>Things not yet supported:</p>
|
||||
@ -764,22 +542,9 @@ it run faster:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>Preliminary support for processors, such as the Cortex-A8 and Cortex-A9,
|
||||
that implement version v7-A of the ARM architecture. The ARM backend now
|
||||
supports both the Thumb2 and Advanced SIMD (Neon) instruction sets.</li>
|
||||
|
||||
<li>The AAPCS-VFP "hard float" calling conventions are also supported with the
|
||||
<tt>-float-abi=hard</tt> flag.</li>
|
||||
|
||||
<li>The ARM calling convention code is now tblgen generated instead of resorting
|
||||
to C++ code.</li>
|
||||
<li>...</li>
|
||||
</ul>
|
||||
|
||||
<p>These features are still somewhat experimental
|
||||
and subject to change. The Neon intrinsics, in particular, may change in future
|
||||
releases of LLVM. ARMv7 support has progressed a lot on top of tree since 2.6
|
||||
branched.</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@ -793,11 +558,7 @@ branched.</p>
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Mips now supports O32 Calling Convention.</li>
|
||||
<li>Many improvements to the 32-bit PowerPC SVR4 ABI (used on powerpc-linux)
|
||||
support, lots of bugs fixed.</li>
|
||||
<li>Added support for the 64-bit PowerPC SVR4 ABI (used on powerpc64-linux).
|
||||
Needs more testing.</li>
|
||||
<li>...</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@ -814,40 +575,7 @@ branched.</p>
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>New <a href="http://llvm.org/doxygen/PrettyStackTrace_8h-source.html">
|
||||
<tt>PrettyStackTrace</tt> class</a> allows crashes of llvm tools (and applications
|
||||
that integrate them) to provide more detailed indication of what the
|
||||
compiler was doing at the time of the crash (e.g. running a pass).
|
||||
At the top level for each LLVM tool, it includes the command line arguments.
|
||||
</li>
|
||||
<li>New <a href="http://llvm.org/doxygen/StringRef_8h-source.html">StringRef</a>
|
||||
and <a href="http://llvm.org/doxygen/Twine_8h-source.html">Twine</a> classes
|
||||
make operations on character ranges and
|
||||
string concatenation to be more efficient. <tt>StringRef</tt> is just a <tt>const
|
||||
char*</tt> with a length, <tt>Twine</tt> is a light-weight rope.</li>
|
||||
<li>LLVM has new <tt>WeakVH</tt>, <tt>AssertingVH</tt> and <tt>CallbackVH</tt>
|
||||
classes, which make it easier to write LLVM IR transformations. <tt>WeakVH</tt>
|
||||
is automatically drops to null when the referenced <tt>Value</tt> is deleted,
|
||||
and is updated across a <tt>replaceAllUsesWith</tt> operation.
|
||||
<tt>AssertingVH</tt> aborts the program if the
|
||||
referenced value is destroyed while it is being referenced. <tt>CallbackVH</tt>
|
||||
is a customizable class for handling value references. See <a
|
||||
href="http://llvm.org/doxygen/ValueHandle_8h-source.html">ValueHandle.h</a>
|
||||
for more information.</li>
|
||||
<li>The new '<a href="http://llvm.org/doxygen/Triple_8h-source.html">Triple
|
||||
</a>' class centralizes a lot of logic that reasons about target
|
||||
triples.</li>
|
||||
<li>The new '<a href="http://llvm.org/doxygen/ErrorHandling_8h-source.html">
|
||||
llvm_report_error()</a>' set of APIs allows tools to embed the LLVM
|
||||
optimizer and backend and recover from previously unrecoverable errors.</li>
|
||||
<li>LLVM has new abstractions for <a
|
||||
href="http://llvm.org/doxygen/Atomic_8h-source.html">atomic operations</a>
|
||||
and <a href="http://llvm.org/doxygen/RWMutex_8h-source.html">reader/writer
|
||||
locks</a>.</li>
|
||||
<li>LLVM has new <a href="http://llvm.org/doxygen/SourceMgr_8h-source.html">
|
||||
<tt>SourceMgr</tt> and <tt>SMLoc</tt> classes</a> which implement caret
|
||||
diagnostics and basic include stack processing for simple parsers. It is
|
||||
used by tablegen, llvm-mc, the .ll parser and FileCheck.</li>
|
||||
<li>...</li>
|
||||
</ul>
|
||||
|
||||
|
||||
@ -862,32 +590,7 @@ branched.</p>
|
||||
<p>Other miscellaneous features include:</p>
|
||||
|
||||
<ul>
|
||||
<li>LLVM now includes a new internal '<a
|
||||
href="http://llvm.org/cmds/FileCheck.html">FileCheck</a>' tool which allows
|
||||
writing much more accurate regression tests that run faster. Please see the
|
||||
<a href="TestingGuide.html#FileCheck">FileCheck section of the Testing
|
||||
Guide</a> for more information.</li>
|
||||
<li>LLVM profile information support has been significantly improved to produce
|
||||
correct use counts, and has support for edge profiling with reduced runtime
|
||||
overhead. Combined, the generated profile information is both more correct and
|
||||
imposes about half as much overhead (2.6. from 12% to 6% overhead on SPEC
|
||||
CPU2000).</li>
|
||||
<li>The C bindings (in the llvm/include/llvm-c directory) include many newly
|
||||
supported APIs.</li>
|
||||
<li>LLVM 2.6 includes a brand new experimental LLVM bindings to the Ada2005
|
||||
programming language.</li>
|
||||
|
||||
<li>The LLVMC driver has several new features:
|
||||
<ul>
|
||||
<li>Dynamic plugins now work on Windows.</li>
|
||||
<li>New option property: init. Makes possible to provide default values for
|
||||
options defined in plugins (interface to <tt>cl::init</tt>).</li>
|
||||
<li>New example: Skeleton, shows how to create a standalone LLVMC-based
|
||||
driver.</li>
|
||||
<li>New example: mcc16, a driver for the PIC16 toolchain.</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>...</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@ -901,24 +604,15 @@ CPU2000).</li>
|
||||
<div class="doc_text">
|
||||
|
||||
<p>If you're already an LLVM user or developer with out-of-tree changes based
|
||||
on LLVM 2.5, this section lists some "gotchas" that you may run into upgrading
|
||||
on LLVM 2.6, this section lists some "gotchas" that you may run into upgrading
|
||||
from the previous release.</p>
|
||||
|
||||
<ul>
|
||||
<li>The Itanium (IA64) backend has been removed. It was not actively supported
|
||||
and had bitrotted.</li>
|
||||
<li>The BigBlock register allocator has been removed, it had also bitrotted.</li>
|
||||
<li>The C Backend (<tt>-march=c</tt>) is no longer considered part of the LLVM release
|
||||
criteria. We still want it to work, but no one is maintaining it and it lacks
|
||||
support for arbitrary precision integers and other important IR features.</li>
|
||||
|
||||
<li>All LLVM tools now default to overwriting their output file, behaving more
|
||||
like standard unix tools. Previously, this only happened with the '<tt>-f</tt>'
|
||||
option.</li>
|
||||
<li>LLVM build now builds all libraries as .a files instead of some
|
||||
libraries as relinked .o files. This requires some APIs like
|
||||
InitializeAllTargets.h.
|
||||
</li>
|
||||
<li>The LLVM interpreter now defaults to <em>not</em> using <tt>libffi</tt> even
|
||||
if you have it installed. This makes it more likely that an LLVM built on one
|
||||
system will work when copied to a similar system. To use <tt>libffi</tt>,
|
||||
configure with <tt>--enable-libffi</tt>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
@ -926,82 +620,30 @@ support for arbitrary precision integers and other important IR features.</li>
|
||||
API changes are:</p>
|
||||
|
||||
<ul>
|
||||
<li>All uses of <tt>hash_set</tt> and <tt>hash_map</tt> have been removed from
|
||||
the LLVM tree and the wrapper headers have been removed.</li>
|
||||
<li>The llvm/Streams.h and <tt>DOUT</tt> member of Debug.h have been removed. The
|
||||
<tt>llvm::Ostream</tt> class has been completely removed and replaced with
|
||||
uses of <tt>raw_ostream</tt>.</li>
|
||||
<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>
|
||||
<li>The <tt>Add</tt>, <tt>Sub</tt> and <tt>Mul</tt> operators are no longer
|
||||
overloaded for floating-point types. Floating-point addition, subtraction
|
||||
and multiplication are now represented with new operators <tt>FAdd</tt>,
|
||||
<tt>FSub</tt> and <tt>FMul</tt>. In the <tt>IRBuilder</tt> API,
|
||||
<tt>CreateAdd</tt>, <tt>CreateSub</tt>, <tt>CreateMul</tt> and
|
||||
<tt>CreateNeg</tt> should only be used for integer arithmetic now;
|
||||
<tt>CreateFAdd</tt>, <tt>CreateFSub</tt>, <tt>CreateFMul</tt> and
|
||||
<tt>CreateFNeg</tt> should now be used for floating-point arithmetic.</li>
|
||||
<li>The <tt>DynamicLibrary</tt> class can no longer be constructed, its functionality has
|
||||
moved to static member functions.</li>
|
||||
<li><tt>raw_fd_ostream</tt>'s constructor for opening a given filename now
|
||||
takes an extra <tt>Force</tt> argument. If <tt>Force</tt> is set to
|
||||
<tt>false</tt>, an error will be reported if a file with the given name
|
||||
already exists. If <tt>Force</tt> is set to <tt>true</tt>, the file will
|
||||
be silently truncated (which is the behavior before this flag was
|
||||
added).</li>
|
||||
<li><tt>SCEVHandle</tt> no longer exists, because reference counting is no
|
||||
longer done for <tt>SCEV*</tt> objects, instead <tt>const SCEV*</tt>
|
||||
should be used.</li>
|
||||
<li><tt>ModuleProvider</tt> has been <a
|
||||
href="http://llvm.org/viewvc/llvm-project?view=rev&revision=94686">removed</a>
|
||||
and its methods moved to <tt>Module</tt> and <tt>GlobalValue</tt>.
|
||||
Most clients can remove uses of <tt>ExistingModuleProvider</tt>,
|
||||
replace <tt>getBitcodeModuleProvider</tt> with
|
||||
<tt>getLazyBitcodeModule</tt>, and pass their <tt>Module</tt> to
|
||||
functions that used to accept <tt>ModuleProvider</tt>. Clients who
|
||||
wrote their own <tt>ModuleProvider</tt>s will need to derive from
|
||||
<tt>GVMaterializer</tt> instead and use
|
||||
<tt>Module::setMaterializer</tt> to attach it to a
|
||||
<tt>Module</tt>.</li>
|
||||
|
||||
<li>Many APIs, notably <tt>llvm::Value</tt>, now use the <tt>StringRef</tt>
|
||||
and <tt>Twine</tt> classes instead of passing <tt>const char*</tt>
|
||||
or <tt>std::string</tt>, as described in
|
||||
the <a href="ProgrammersManual.html#string_apis">Programmer's Manual</a>. Most
|
||||
clients should be unaffected by this transition, unless they are used to
|
||||
<tt>Value::getName()</tt> returning a string. Here are some tips on updating to
|
||||
2.6:
|
||||
<ul>
|
||||
<li><tt>getNameStr()</tt> is still available, and matches the old
|
||||
behavior. Replacing <tt>getName()</tt> calls with this is an safe option,
|
||||
although more efficient alternatives are now possible.</li>
|
||||
<li><tt>GhostLinkage</tt> has given up the ghost.
|
||||
<tt>GlobalValue</tt>s that have not yet been read from their backing
|
||||
storage have the same linkage they will have after being read in.
|
||||
Clients must replace calls to
|
||||
<tt>GlobalValue::hasNotBeenReadFromBitcode</tt> with
|
||||
<tt>GlobalValue::isMaterializable</tt>.</li>
|
||||
|
||||
<li>If you were just relying on <tt>getName()</tt> being able to be sent to
|
||||
a <tt>std::ostream</tt>, consider migrating
|
||||
to <tt>llvm::raw_ostream</tt>.</li>
|
||||
|
||||
<li>If you were using <tt>getName().c_str()</tt> to get a <tt>const
|
||||
char*</tt> pointer to the name, you can use <tt>getName().data()</tt>.
|
||||
Note that this string (as before), may not be the entire name if the
|
||||
name contains embedded null characters.</li>
|
||||
<li>FIXME: Debug info has been totally redone. Add pointers to new APIs. Substantial caveats about compatibility of .ll and .bc files.</li>
|
||||
|
||||
<li>If you were using <tt>operator +</tt> on the result of <tt>getName()</tt> and
|
||||
treating the result as an <tt>std::string</tt>, you can either
|
||||
use <tt>Twine::str</tt> to get the result as an <tt>std::string</tt>, or
|
||||
could move to a <tt>Twine</tt> based design.</li>
|
||||
<li>The <tt>llvm/Support/DataTypes.h</tt> header has moved
|
||||
to <tt>llvm/System/DataTypes.h</tt>.</li>
|
||||
|
||||
<li><tt>isName()</tt> should be replaced with comparison
|
||||
against <tt>getName()</tt> (this is now efficient).
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>The registration interfaces for backend Targets has changed (what was
|
||||
previously <tt>TargetMachineRegistry</tt>). For backend authors, see the <a
|
||||
href="WritingAnLLVMBackend.html#TargetRegistration">Writing An LLVM Backend</a>
|
||||
guide. For clients, the notable API changes are:
|
||||
<ul>
|
||||
<li><tt>TargetMachineRegistry</tt> has been renamed
|
||||
to <tt>TargetRegistry</tt>.</li>
|
||||
|
||||
<li>Clients should move to using the <tt>TargetRegistry::lookupTarget()</tt>
|
||||
function to find targets.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@ -1055,8 +697,8 @@ there isn't already one.</p>
|
||||
<li>The llvm-gcc bootstrap will fail with some versions of binutils (e.g. 2.15)
|
||||
with a message of "<tt><a href="http://llvm.org/PR5004">Error: can not do 8
|
||||
byte pc-relative relocation</a></tt>" when building C++ code. We intend to
|
||||
fix this on mainline, but a workaround for 2.6 is to upgrade to binutils
|
||||
2.17 or later.</li>
|
||||
fix this on mainline, but a workaround is to upgrade to binutils 2.17 or
|
||||
later.</li>
|
||||
|
||||
<li>LLVM will not correctly compile on Solaris and/or OpenSolaris
|
||||
using the stock GCC 3.x.x series 'out the box',
|
||||
@ -1350,7 +992,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: 2010-01-16 22:25:13 +0100 (Sat, 16 Jan 2010) $
|
||||
Last modified: $Date: 2010-02-14 02:47:19 +0100 (Sun, 14 Feb 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -354,8 +354,6 @@ public:
|
||||
// Pass Pipeline Configuration
|
||||
virtual bool addInstSelector(PassManagerBase &PM, bool Fast);
|
||||
virtual bool addPreEmitPass(PassManagerBase &PM, bool Fast);
|
||||
virtual bool addAssemblyEmitter(PassManagerBase &PM, bool Fast,
|
||||
std::ostream &Out);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
@ -2152,12 +2150,6 @@ in <tt>XXXGenAsmWriter.inc</tt> contains an implementation of the
|
||||
<li><tt>printImplicitDef</tt></li>
|
||||
|
||||
<li><tt>printInlineAsm</tt></li>
|
||||
|
||||
<li><tt>printLabel</tt></li>
|
||||
|
||||
<li><tt>printPICJumpTableEntry</tt></li>
|
||||
|
||||
<li><tt>printPICJumpTableSetLabel</tt></li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
@ -2563,7 +2555,7 @@ with assembler.
|
||||
<a href="http://www.woo.com">Mason Woo</a> and <a href="http://misha.brukman.net">Misha Brukman</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a>
|
||||
<br>
|
||||
Last modified: $Date: 2009-09-13 00:57:37 +0200 (Sun, 13 Sep 2009) $
|
||||
Last modified: $Date: 2010-02-02 19:44:12 +0100 (Tue, 02 Feb 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -2,12 +2,16 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Documentation for the LLVM System</title>
|
||||
<title>Documentation for the LLVM System at SVN head</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="doc_title">Documentation for the LLVM System</div>
|
||||
<div class="doc_title">Documentation for the LLVM System at SVN head</div>
|
||||
|
||||
<p class="doc_warning">If you are using a released version of LLVM,
|
||||
see <a href="http://llvm.org/releases/">the download page</a> to find
|
||||
your documentation.</p>
|
||||
|
||||
<div class="doc_text">
|
||||
<table class="layout" width="95%"><tr class="layout"><td class="left">
|
||||
@ -281,7 +285,7 @@ times each day, making it a high volume list.</li>
|
||||
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-09-21 04:34:59 +0200 (Mon, 21 Sep 2009) $
|
||||
Last modified: $Date: 2010-02-03 19:49:55 +0100 (Wed, 03 Feb 2010) $
|
||||
</address>
|
||||
</body></html>
|
||||
|
||||
|
@ -342,7 +342,7 @@ so that you can use the lexer and parser together.
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
|
||||
Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1227,7 +1227,7 @@ int main() {
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
|
||||
Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1263,7 +1263,7 @@ int main() {
|
||||
|
||||
<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-07-21 11:05:13 -0700 (Tue, 21 Jul 2009) $
|
||||
Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -171,10 +171,7 @@ add a set of optimizations to run. The code looks like this:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
ExistingModuleProvider *OurModuleProvider =
|
||||
new ExistingModuleProvider(TheModule);
|
||||
|
||||
FunctionPassManager OurFPM(OurModuleProvider);
|
||||
FunctionPassManager OurFPM(TheModule);
|
||||
|
||||
// Set up the optimizer pipeline. Start with registering info about how the
|
||||
// target lays out data structures.
|
||||
@ -198,19 +195,13 @@ add a set of optimizations to run. The code looks like this:</p>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>This code defines two objects, an <tt>ExistingModuleProvider</tt> and a
|
||||
<tt>FunctionPassManager</tt>. The former is basically a wrapper around our
|
||||
<tt>Module</tt> that the PassManager requires. It provides certain flexibility
|
||||
that we're not going to take advantage of here, so I won't dive into any details
|
||||
about it.</p>
|
||||
|
||||
<p>The meat of the matter here, is the definition of "<tt>OurFPM</tt>". It
|
||||
requires a pointer to the <tt>Module</tt> (through the <tt>ModuleProvider</tt>)
|
||||
to construct itself. Once it is set up, we use a series of "add" calls to add
|
||||
a bunch of LLVM passes. The first pass is basically boilerplate, it adds a pass
|
||||
so that later optimizations know how the data structures in the program are
|
||||
laid out. The "<tt>TheExecutionEngine</tt>" variable is related to the JIT,
|
||||
which we will get to in the next section.</p>
|
||||
<p>This code defines a <tt>FunctionPassManager</tt>, "<tt>OurFPM</tt>". It
|
||||
requires a pointer to the <tt>Module</tt> to construct itself. Once it is set
|
||||
up, we use a series of "add" calls to add a bunch of LLVM passes. The first
|
||||
pass is basically boilerplate, it adds a pass so that later optimizations know
|
||||
how the data structures in the program are laid out. The
|
||||
"<tt>TheExecutionEngine</tt>" variable is related to the JIT, which we will get
|
||||
to in the next section.</p>
|
||||
|
||||
<p>In this case, we choose to add 4 optimization passes. The passes we chose
|
||||
here are a pretty standard set of "cleanup" optimizations that are useful for
|
||||
@ -302,8 +293,8 @@ by adding a global variable and a call in <tt>main</tt>:</p>
|
||||
...
|
||||
int main() {
|
||||
..
|
||||
<b>// Create the JIT. This takes ownership of the module and module provider.
|
||||
TheExecutionEngine = EngineBuilder(OurModuleProvider).create();</b>
|
||||
<b>// Create the JIT. This takes ownership of the module.
|
||||
TheExecutionEngine = EngineBuilder(TheModule).create();</b>
|
||||
..
|
||||
}
|
||||
</pre>
|
||||
@ -494,7 +485,7 @@ LLVM JIT and optimizer. To build this example, use:
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
# Compile
|
||||
g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit interpreter native` -O3 -o toy
|
||||
g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
|
||||
# Run
|
||||
./toy
|
||||
</pre>
|
||||
@ -511,11 +502,9 @@ at runtime.</p>
|
||||
<pre>
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/Interpreter.h"
|
||||
#include "llvm/ExecutionEngine/JIT.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/ModuleProvider.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Analysis/Verifier.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
@ -1084,13 +1073,15 @@ int main() {
|
||||
// Make the module, which holds all the code.
|
||||
TheModule = new Module("my cool jit", Context);
|
||||
|
||||
ExistingModuleProvider *OurModuleProvider =
|
||||
new ExistingModuleProvider(TheModule);
|
||||
// Create the JIT. This takes ownership of the module.
|
||||
std::string ErrStr;
|
||||
TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
|
||||
if (!TheExecutionEngine) {
|
||||
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create the JIT. This takes ownership of the module and module provider.
|
||||
TheExecutionEngine = EngineBuilder(OurModuleProvider).create();
|
||||
|
||||
FunctionPassManager OurFPM(OurModuleProvider);
|
||||
FunctionPassManager OurFPM(TheModule);
|
||||
|
||||
// Set up the optimizer pipeline. Start with registering info about how the
|
||||
// target lays out data structures.
|
||||
@ -1135,7 +1126,7 @@ int main() {
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
|
||||
Last modified: $Date: 2010-02-11 20:15:20 +0100 (Thu, 11 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -902,11 +902,9 @@ if/then/else and for expressions.. To build this example, use:
|
||||
<pre>
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/Interpreter.h"
|
||||
#include "llvm/ExecutionEngine/JIT.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/ModuleProvider.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Analysis/Verifier.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
@ -1720,13 +1718,15 @@ int main() {
|
||||
// Make the module, which holds all the code.
|
||||
TheModule = new Module("my cool jit", Context);
|
||||
|
||||
ExistingModuleProvider *OurModuleProvider =
|
||||
new ExistingModuleProvider(TheModule);
|
||||
// Create the JIT. This takes ownership of the module.
|
||||
std::string ErrStr;
|
||||
TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
|
||||
if (!TheExecutionEngine) {
|
||||
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create the JIT. This takes ownership of the module and module provider.
|
||||
TheExecutionEngine = EngineBuilder(OurModuleProvider).create();
|
||||
|
||||
FunctionPassManager OurFPM(OurModuleProvider);
|
||||
FunctionPassManager OurFPM(TheModule);
|
||||
|
||||
// Set up the optimizer pipeline. Start with registering info about how the
|
||||
// target lays out data structures.
|
||||
@ -1771,7 +1771,7 @@ int main() {
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
|
||||
Last modified: $Date: 2010-02-11 20:15:20 +0100 (Thu, 11 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -821,11 +821,9 @@ if/then/else and for expressions.. To build this example, use:
|
||||
<pre>
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/Interpreter.h"
|
||||
#include "llvm/ExecutionEngine/JIT.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/ModuleProvider.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Analysis/Verifier.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
@ -1757,13 +1755,15 @@ int main() {
|
||||
// Make the module, which holds all the code.
|
||||
TheModule = new Module("my cool jit", Context);
|
||||
|
||||
ExistingModuleProvider *OurModuleProvider =
|
||||
new ExistingModuleProvider(TheModule);
|
||||
// Create the JIT. This takes ownership of the module.
|
||||
std::string ErrStr;
|
||||
TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
|
||||
if (!TheExecutionEngine) {
|
||||
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create the JIT. This takes ownership of the module and module provider.
|
||||
TheExecutionEngine = EngineBuilder(OurModuleProvider).create();
|
||||
|
||||
FunctionPassManager OurFPM(OurModuleProvider);
|
||||
FunctionPassManager OurFPM(TheModule);
|
||||
|
||||
// Set up the optimizer pipeline. Start with registering info about how the
|
||||
// target lays out data structures.
|
||||
@ -1808,7 +1808,7 @@ int main() {
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
|
||||
Last modified: $Date: 2010-02-11 20:15:20 +0100 (Thu, 11 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1004,11 +1004,9 @@ variables and var/in support. To build this example, use:
|
||||
<pre>
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/Interpreter.h"
|
||||
#include "llvm/ExecutionEngine/JIT.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/ModuleProvider.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Analysis/Verifier.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
@ -2105,13 +2103,15 @@ int main() {
|
||||
// Make the module, which holds all the code.
|
||||
TheModule = new Module("my cool jit", Context);
|
||||
|
||||
ExistingModuleProvider *OurModuleProvider =
|
||||
new ExistingModuleProvider(TheModule);
|
||||
// Create the JIT. This takes ownership of the module.
|
||||
std::string ErrStr;
|
||||
TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
|
||||
if (!TheExecutionEngine) {
|
||||
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create the JIT. This takes ownership of the module and module provider.
|
||||
TheExecutionEngine = EngineBuilder(OurModuleProvider).create();
|
||||
|
||||
FunctionPassManager OurFPM(OurModuleProvider);
|
||||
FunctionPassManager OurFPM(TheModule);
|
||||
|
||||
// Set up the optimizer pipeline. Start with registering info about how the
|
||||
// target lays out data structures.
|
||||
@ -2158,7 +2158,7 @@ int main() {
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
|
||||
Last modified: $Date: 2010-02-11 20:15:20 +0100 (Thu, 11 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -359,7 +359,7 @@ Passing Style</a> and the use of tail calls (which LLVM also supports).</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: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
|
||||
Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -359,7 +359,7 @@ include a driver so that you can use the lexer and parser together.
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
|
||||
Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1039,7 +1039,7 @@ main ()
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a>
|
||||
<a href="mailto:erickt@users.sourceforge.net">Erick Tryzelaar</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
|
||||
Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1085,7 +1085,7 @@ main ()
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
|
||||
Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1032,7 +1032,7 @@ extern double putchard(double X) {
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
|
||||
Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1563,7 +1563,7 @@ operators</a>
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
|
||||
Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1568,7 +1568,7 @@ SSA construction</a>
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
|
||||
Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1901,7 +1901,7 @@ extern double printd(double X) {
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
|
||||
Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
|
||||
Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -27,7 +27,6 @@
|
||||
|
||||
#include "BrainF.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/ModuleProvider.h"
|
||||
#include "llvm/Analysis/Verifier.h"
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/ExecutionEngine/GenericValue.h"
|
||||
|
@ -4,6 +4,10 @@ add_subdirectory(HowToUseJIT)
|
||||
add_subdirectory(Kaleidoscope)
|
||||
add_subdirectory(ModuleMaker)
|
||||
|
||||
if( NOT WIN32 )
|
||||
add_subdirectory(ExceptionDemo)
|
||||
endif()
|
||||
|
||||
include(CheckIncludeFile)
|
||||
check_include_file(pthread.h HAVE_PTHREAD_H)
|
||||
|
||||
|
5
examples/ExceptionDemo/CMakeLists.txt
Normal file
5
examples/ExceptionDemo/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
set(LLVM_LINK_COMPONENTS jit nativecodegen)
|
||||
|
||||
add_llvm_example(ExceptionDemo
|
||||
ExceptionDemo.cpp
|
||||
)
|
2028
examples/ExceptionDemo/ExceptionDemo.cpp
Normal file
2028
examples/ExceptionDemo/ExceptionDemo.cpp
Normal file
File diff suppressed because it is too large
Load Diff
17
examples/ExceptionDemo/Makefile
Normal file
17
examples/ExceptionDemo/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
##===- examples/ExceptionDemo/Makefile --------------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
##===---------------------------------------------------------------------===##
|
||||
LEVEL = ../..
|
||||
TOOLNAME = ExceptionDemo
|
||||
EXAMPLE_TOOL = 1
|
||||
|
||||
LINK_COMPONENTS := jit interpreter nativecodegen
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
||||
CXXFLAGS += -fexceptions
|
@ -28,7 +28,6 @@
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/ModuleProvider.h"
|
||||
#include "llvm/Analysis/Verifier.h"
|
||||
#include "llvm/ExecutionEngine/JIT.h"
|
||||
#include "llvm/ExecutionEngine/Interpreter.h"
|
||||
|
@ -12,7 +12,7 @@
|
||||
//
|
||||
// Goal:
|
||||
// The goal of this snippet is to create in the memory
|
||||
// the LLVM module consisting of two functions as follow:
|
||||
// the LLVM module consisting of two functions as follow:
|
||||
//
|
||||
// int add1(int x) {
|
||||
// return x+1;
|
||||
@ -39,7 +39,6 @@
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/ModuleProvider.h"
|
||||
#include "llvm/ExecutionEngine/JIT.h"
|
||||
#include "llvm/ExecutionEngine/Interpreter.h"
|
||||
#include "llvm/ExecutionEngine/GenericValue.h"
|
||||
|
@ -10,6 +10,6 @@ LEVEL = ../../..
|
||||
TOOLNAME = Kaleidoscope-Ch4
|
||||
EXAMPLE_TOOL = 1
|
||||
|
||||
LINK_COMPONENTS := core jit interpreter native
|
||||
LINK_COMPONENTS := core jit native
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
@ -1,10 +1,8 @@
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/Interpreter.h"
|
||||
#include "llvm/ExecutionEngine/JIT.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/ModuleProvider.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Analysis/Verifier.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
@ -573,13 +571,15 @@ int main() {
|
||||
// Make the module, which holds all the code.
|
||||
TheModule = new Module("my cool jit", Context);
|
||||
|
||||
ExistingModuleProvider *OurModuleProvider =
|
||||
new ExistingModuleProvider(TheModule);
|
||||
// Create the JIT. This takes ownership of the module.
|
||||
std::string ErrStr;
|
||||
TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
|
||||
if (!TheExecutionEngine) {
|
||||
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create the JIT. This takes ownership of the module and module provider.
|
||||
TheExecutionEngine = EngineBuilder(OurModuleProvider).create();
|
||||
|
||||
FunctionPassManager OurFPM(OurModuleProvider);
|
||||
FunctionPassManager OurFPM(TheModule);
|
||||
|
||||
// Set up the optimizer pipeline. Start with registering info about how the
|
||||
// target lays out data structures.
|
||||
|
@ -10,6 +10,6 @@ LEVEL = ../../..
|
||||
TOOLNAME = Kaleidoscope-Ch5
|
||||
EXAMPLE_TOOL = 1
|
||||
|
||||
LINK_COMPONENTS := core jit interpreter native
|
||||
LINK_COMPONENTS := core jit native
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
@ -1,10 +1,8 @@
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/Interpreter.h"
|
||||
#include "llvm/ExecutionEngine/JIT.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/ModuleProvider.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Analysis/Verifier.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
@ -818,13 +816,15 @@ int main() {
|
||||
// Make the module, which holds all the code.
|
||||
TheModule = new Module("my cool jit", Context);
|
||||
|
||||
ExistingModuleProvider *OurModuleProvider =
|
||||
new ExistingModuleProvider(TheModule);
|
||||
// Create the JIT. This takes ownership of the module.
|
||||
std::string ErrStr;
|
||||
TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
|
||||
if (!TheExecutionEngine) {
|
||||
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create the JIT. This takes ownership of the module and module provider.
|
||||
TheExecutionEngine = EngineBuilder(OurModuleProvider).create();
|
||||
|
||||
FunctionPassManager OurFPM(OurModuleProvider);
|
||||
FunctionPassManager OurFPM(TheModule);
|
||||
|
||||
// Set up the optimizer pipeline. Start with registering info about how the
|
||||
// target lays out data structures.
|
||||
|
@ -10,6 +10,6 @@ LEVEL = ../../..
|
||||
TOOLNAME = Kaleidoscope-Ch6
|
||||
EXAMPLE_TOOL = 1
|
||||
|
||||
LINK_COMPONENTS := core jit interpreter native
|
||||
LINK_COMPONENTS := core jit native
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
@ -1,10 +1,8 @@
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/Interpreter.h"
|
||||
#include "llvm/ExecutionEngine/JIT.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/ModuleProvider.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Analysis/Verifier.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
@ -936,13 +934,15 @@ int main() {
|
||||
// Make the module, which holds all the code.
|
||||
TheModule = new Module("my cool jit", Context);
|
||||
|
||||
ExistingModuleProvider *OurModuleProvider =
|
||||
new ExistingModuleProvider(TheModule);
|
||||
// Create the JIT. This takes ownership of the module.
|
||||
std::string ErrStr;
|
||||
TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
|
||||
if (!TheExecutionEngine) {
|
||||
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create the JIT. This takes ownership of the module and module provider.
|
||||
TheExecutionEngine = EngineBuilder(OurModuleProvider).create();
|
||||
|
||||
FunctionPassManager OurFPM(OurModuleProvider);
|
||||
FunctionPassManager OurFPM(TheModule);
|
||||
|
||||
// Set up the optimizer pipeline. Start with registering info about how the
|
||||
// target lays out data structures.
|
||||
|
@ -9,7 +9,8 @@
|
||||
LEVEL = ../../..
|
||||
TOOLNAME = Kaleidoscope-Ch7
|
||||
EXAMPLE_TOOL = 1
|
||||
REQUIRES_RTTI := 1
|
||||
|
||||
LINK_COMPONENTS := core jit interpreter native
|
||||
LINK_COMPONENTS := core jit native
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
@ -1,10 +1,8 @@
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/Interpreter.h"
|
||||
#include "llvm/ExecutionEngine/JIT.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/ModuleProvider.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Analysis/Verifier.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
@ -1100,13 +1098,15 @@ int main() {
|
||||
// Make the module, which holds all the code.
|
||||
TheModule = new Module("my cool jit", Context);
|
||||
|
||||
ExistingModuleProvider *OurModuleProvider =
|
||||
new ExistingModuleProvider(TheModule);
|
||||
// Create the JIT. This takes ownership of the module.
|
||||
std::string ErrStr;
|
||||
TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
|
||||
if (!TheExecutionEngine) {
|
||||
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create the JIT. This takes ownership of the module and module provider.
|
||||
TheExecutionEngine = EngineBuilder(OurModuleProvider).create();
|
||||
|
||||
FunctionPassManager OurFPM(OurModuleProvider);
|
||||
FunctionPassManager OurFPM(TheModule);
|
||||
|
||||
// Set up the optimizer pipeline. Start with registering info about how the
|
||||
// target lays out data structures.
|
||||
|
@ -16,4 +16,8 @@ ifeq ($(HAVE_PTHREAD),1)
|
||||
PARALLEL_DIRS += ParallelJIT
|
||||
endif
|
||||
|
||||
ifeq ($(LLVM_ON_UNIX),1)
|
||||
PARALLEL_DIRS += ExceptionDemo
|
||||
endif
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/ModuleProvider.h"
|
||||
#include "llvm/ExecutionEngine/JIT.h"
|
||||
#include "llvm/ExecutionEngine/Interpreter.h"
|
||||
#include "llvm/ExecutionEngine/GenericValue.h"
|
||||
|
@ -78,8 +78,9 @@ typedef struct LLVMOpaqueValue *LLVMValueRef;
|
||||
typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef;
|
||||
typedef struct LLVMOpaqueBuilder *LLVMBuilderRef;
|
||||
|
||||
/* Used to provide a module to JIT or interpreter.
|
||||
* See the llvm::ModuleProvider class.
|
||||
/* Interface used to provide a module to JIT or interpreter. This is now just a
|
||||
* synonym for llvm::Module, but we have to keep using the different type to
|
||||
* keep binary compatibility.
|
||||
*/
|
||||
typedef struct LLVMOpaqueModuleProvider *LLVMModuleProviderRef;
|
||||
|
||||
@ -117,63 +118,76 @@ typedef enum {
|
||||
LLVMNoCaptureAttribute = 1<<21,
|
||||
LLVMNoRedZoneAttribute = 1<<22,
|
||||
LLVMNoImplicitFloatAttribute = 1<<23,
|
||||
LLVMNakedAttribute = 1<<24
|
||||
LLVMNakedAttribute = 1<<24,
|
||||
LLVMInlineHintAttribute = 1<<25
|
||||
} LLVMAttribute;
|
||||
|
||||
typedef enum {
|
||||
/* Terminator Instructions */
|
||||
LLVMRet = 1,
|
||||
LLVMBr = 2,
|
||||
LLVMSwitch = 3,
|
||||
LLVMInvoke = 4,
|
||||
LLVMUnwind = 5,
|
||||
LLVMUnreachable = 6,
|
||||
LLVMAdd = 7,
|
||||
LLVMFAdd = 8,
|
||||
LLVMSub = 9,
|
||||
LLVMFSub = 10,
|
||||
LLVMMul = 11,
|
||||
LLVMFMul = 12,
|
||||
LLVMUDiv = 13,
|
||||
LLVMSDiv = 14,
|
||||
LLVMFDiv = 15,
|
||||
LLVMURem = 16,
|
||||
LLVMSRem = 17,
|
||||
LLVMFRem = 18,
|
||||
LLVMShl = 19,
|
||||
LLVMLShr = 20,
|
||||
LLVMAShr = 21,
|
||||
LLVMAnd = 22,
|
||||
LLVMOr = 23,
|
||||
LLVMXor = 24,
|
||||
LLVMMalloc = 25,
|
||||
LLVMFree = 26,
|
||||
LLVMAlloca = 27,
|
||||
LLVMLoad = 28,
|
||||
LLVMStore = 29,
|
||||
LLVMGetElementPtr = 30,
|
||||
LLVMTrunk = 31,
|
||||
LLVMZExt = 32,
|
||||
LLVMSExt = 33,
|
||||
LLVMFPToUI = 34,
|
||||
LLVMFPToSI = 35,
|
||||
LLVMUIToFP = 36,
|
||||
LLVMSIToFP = 37,
|
||||
LLVMFPTrunc = 38,
|
||||
LLVMFPExt = 39,
|
||||
LLVMPtrToInt = 40,
|
||||
LLVMIntToPtr = 41,
|
||||
LLVMBitCast = 42,
|
||||
LLVMICmp = 43,
|
||||
LLVMFCmp = 44,
|
||||
LLVMPHI = 45,
|
||||
LLVMCall = 46,
|
||||
LLVMSelect = 47,
|
||||
LLVMVAArg = 50,
|
||||
LLVMExtractElement = 51,
|
||||
LLVMInsertElement = 52,
|
||||
LLVMShuffleVector = 53,
|
||||
LLVMExtractValue = 54,
|
||||
LLVMInsertValue = 55
|
||||
LLVMIndirectBr = 4,
|
||||
LLVMInvoke = 5,
|
||||
LLVMUnwind = 6,
|
||||
LLVMUnreachable = 7,
|
||||
|
||||
/* Standard Binary Operators */
|
||||
LLVMAdd = 8,
|
||||
LLVMFAdd = 9,
|
||||
LLVMSub = 10,
|
||||
LLVMFSub = 11,
|
||||
LLVMMul = 12,
|
||||
LLVMFMul = 13,
|
||||
LLVMUDiv = 14,
|
||||
LLVMSDiv = 15,
|
||||
LLVMFDiv = 16,
|
||||
LLVMURem = 17,
|
||||
LLVMSRem = 18,
|
||||
LLVMFRem = 19,
|
||||
|
||||
/* Logical Operators */
|
||||
LLVMShl = 20,
|
||||
LLVMLShr = 21,
|
||||
LLVMAShr = 22,
|
||||
LLVMAnd = 23,
|
||||
LLVMOr = 24,
|
||||
LLVMXor = 25,
|
||||
|
||||
/* Memory Operators */
|
||||
LLVMAlloca = 26,
|
||||
LLVMLoad = 27,
|
||||
LLVMStore = 28,
|
||||
LLVMGetElementPtr = 29,
|
||||
|
||||
/* Cast Operators */
|
||||
LLVMTrunc = 30,
|
||||
LLVMZExt = 31,
|
||||
LLVMSExt = 32,
|
||||
LLVMFPToUI = 33,
|
||||
LLVMFPToSI = 34,
|
||||
LLVMUIToFP = 35,
|
||||
LLVMSIToFP = 36,
|
||||
LLVMFPTrunc = 37,
|
||||
LLVMFPExt = 38,
|
||||
LLVMPtrToInt = 39,
|
||||
LLVMIntToPtr = 40,
|
||||
LLVMBitCast = 41,
|
||||
|
||||
/* Other Operators */
|
||||
LLVMICmp = 42,
|
||||
LLVMFCmp = 43,
|
||||
LLVMPHI = 44,
|
||||
LLVMCall = 45,
|
||||
LLVMSelect = 46,
|
||||
/* UserOp1 */
|
||||
/* UserOp2 */
|
||||
LLVMVAArg = 49,
|
||||
LLVMExtractElement = 50,
|
||||
LLVMInsertElement = 51,
|
||||
LLVMShuffleVector = 52,
|
||||
LLVMExtractValue = 53,
|
||||
LLVMInsertValue = 54
|
||||
} LLVMOpcode;
|
||||
|
||||
typedef enum {
|
||||
@ -191,7 +205,8 @@ typedef enum {
|
||||
LLVMPointerTypeKind, /**< Pointers */
|
||||
LLVMOpaqueTypeKind, /**< Opaque: type with unknown structure */
|
||||
LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */
|
||||
LLVMMetadataTypeKind /**< Metadata */
|
||||
LLVMMetadataTypeKind, /**< Metadata */
|
||||
LLVMUnionTypeKind /**< Unions */
|
||||
} LLVMTypeKind;
|
||||
|
||||
typedef enum {
|
||||
@ -210,8 +225,7 @@ typedef enum {
|
||||
LLVMDLLImportLinkage, /**< Function to be imported from DLL */
|
||||
LLVMDLLExportLinkage, /**< Function to be accessible from DLL */
|
||||
LLVMExternalWeakLinkage,/**< ExternalWeak linkage description */
|
||||
LLVMGhostLinkage, /**< Stand-in functions for streaming fns from
|
||||
bitcode */
|
||||
LLVMGhostLinkage, /**< Obsolete */
|
||||
LLVMCommonLinkage, /**< Tentative definitions */
|
||||
LLVMLinkerPrivateLinkage /**< Like Private, but linker removes. */
|
||||
} LLVMLinkage;
|
||||
@ -371,6 +385,13 @@ unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy);
|
||||
void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest);
|
||||
LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy);
|
||||
|
||||
/* Operations on union types */
|
||||
LLVMTypeRef LLVMUnionTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes,
|
||||
unsigned ElementCount);
|
||||
LLVMTypeRef LLVMUnionType(LLVMTypeRef *ElementTypes, unsigned ElementCount);
|
||||
unsigned LLVMCountUnionElementTypes(LLVMTypeRef UnionTy);
|
||||
void LLVMGetUnionElementTypes(LLVMTypeRef UnionTy, LLVMTypeRef *Dest);
|
||||
|
||||
/* Operations on array, pointer, and vector types (sequence types) */
|
||||
LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount);
|
||||
LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace);
|
||||
@ -914,17 +935,15 @@ LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef, LLVMValueRef LHS,
|
||||
|
||||
/*===-- Module providers --------------------------------------------------===*/
|
||||
|
||||
/* Encapsulates the module M in a module provider, taking ownership of the
|
||||
* module.
|
||||
* See the constructor llvm::ExistingModuleProvider::ExistingModuleProvider.
|
||||
/* Changes the type of M so it can be passed to FunctionPassManagers and the
|
||||
* JIT. They take ModuleProviders for historical reasons.
|
||||
*/
|
||||
LLVMModuleProviderRef
|
||||
LLVMCreateModuleProviderForExistingModule(LLVMModuleRef M);
|
||||
|
||||
/* Destroys the module provider MP as well as the contained module.
|
||||
* See the destructor llvm::ModuleProvider::~ModuleProvider.
|
||||
/* Destroys the module M.
|
||||
*/
|
||||
void LLVMDisposeModuleProvider(LLVMModuleProviderRef MP);
|
||||
void LLVMDisposeModuleProvider(LLVMModuleProviderRef M);
|
||||
|
||||
|
||||
/*===-- Memory buffers ----------------------------------------------------===*/
|
||||
@ -981,7 +1000,6 @@ void LLVMDisposePassManager(LLVMPassManagerRef PM);
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
class ModuleProvider;
|
||||
class MemoryBuffer;
|
||||
class PassManagerBase;
|
||||
|
||||
@ -1018,11 +1036,16 @@ namespace llvm {
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef )
|
||||
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_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseIteratorRef )
|
||||
DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBase, LLVMPassManagerRef )
|
||||
/* LLVMModuleProviderRef exists for historical reasons, but now just holds a
|
||||
* Module.
|
||||
*/
|
||||
inline Module *unwrap(LLVMModuleProviderRef MP) {
|
||||
return reinterpret_cast<Module*>(MP);
|
||||
}
|
||||
|
||||
#undef DEFINE_STDCXX_CONVERSION_FUNCTIONS
|
||||
#undef DEFINE_ISA_CONVERSION_FUNCTIONS
|
||||
|
515
include/llvm-c/EnhancedDisassembly.h
Normal file
515
include/llvm-c/EnhancedDisassembly.h
Normal file
@ -0,0 +1,515 @@
|
||||
/*===-- llvm-c/EnhancedDisassembly.h - Disassembler C Interface ---*- C -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This header declares the C interface to EnhancedDisassembly.so, which *|
|
||||
|* implements a disassembler with the ability to extract operand values and *|
|
||||
|* individual tokens from assembly instructions. *|
|
||||
|* *|
|
||||
|* The header declares additional interfaces if the host compiler supports *|
|
||||
|* the blocks API. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef LLVM_C_ENHANCEDDISASSEMBLY_H
|
||||
#define LLVM_C_ENHANCEDDISASSEMBLY_H
|
||||
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@typedef EDByteReaderCallback
|
||||
Interface to memory from which instructions may be read.
|
||||
@param byte A pointer whose target should be filled in with the data returned.
|
||||
@param address The address of the byte to be read.
|
||||
@param arg An anonymous argument for client use.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
typedef int (*EDByteReaderCallback)(uint8_t *byte, uint64_t address, void *arg);
|
||||
|
||||
/*!
|
||||
@typedef EDRegisterReaderCallback
|
||||
Interface to registers from which registers may be read.
|
||||
@param value A pointer whose target should be filled in with the value of the
|
||||
register.
|
||||
@param regID The LLVM register identifier for the register to read.
|
||||
@param arg An anonymous argument for client use.
|
||||
@result 0 if the register could be read; -1 otherwise.
|
||||
*/
|
||||
typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID,
|
||||
void* arg);
|
||||
|
||||
/*!
|
||||
@typedef EDAssemblySyntax_t
|
||||
An assembly syntax for use in tokenizing instructions.
|
||||
*/
|
||||
typedef enum {
|
||||
/*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */
|
||||
kEDAssemblySyntaxX86Intel = 0,
|
||||
/*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */
|
||||
kEDAssemblySyntaxX86ATT = 1
|
||||
} EDAssemblySyntax_t;
|
||||
|
||||
/*!
|
||||
@typedef EDDisassemblerRef
|
||||
Encapsulates a disassembler for a single CPU architecture.
|
||||
*/
|
||||
struct EDDisassembler;
|
||||
typedef struct EDDisassembler *EDDisassemblerRef;
|
||||
|
||||
/*!
|
||||
@typedef EDInstRef
|
||||
Encapsulates a single disassembled instruction in one assembly syntax.
|
||||
*/
|
||||
struct EDInst;
|
||||
typedef struct EDInst *EDInstRef;
|
||||
|
||||
/*!
|
||||
@typedef EDTokenRef
|
||||
Encapsulates a token from the disassembly of an instruction.
|
||||
*/
|
||||
struct EDToken;
|
||||
typedef struct EDToken *EDTokenRef;
|
||||
|
||||
/*!
|
||||
@typedef EDOperandRef
|
||||
Encapsulates an operand of an instruction.
|
||||
*/
|
||||
struct EDOperand;
|
||||
typedef struct EDOperand *EDOperandRef;
|
||||
|
||||
/*!
|
||||
@functiongroup Getting a disassembler
|
||||
*/
|
||||
|
||||
/*!
|
||||
@function EDGetDisassembler
|
||||
Gets the disassembler for a given target.
|
||||
@param disassembler A pointer whose target will be filled in with the
|
||||
disassembler.
|
||||
@param triple Identifies the target. Example: "x86_64-apple-darwin10"
|
||||
@param syntax The assembly syntax to use when decoding instructions.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetDisassembler(EDDisassemblerRef *disassembler,
|
||||
const char *triple,
|
||||
EDAssemblySyntax_t syntax);
|
||||
|
||||
/*!
|
||||
@functiongroup Generic architectural queries
|
||||
*/
|
||||
|
||||
/*!
|
||||
@function EDGetRegisterName
|
||||
Gets the human-readable name for a given register.
|
||||
@param regName A pointer whose target will be pointed at the name of the
|
||||
register. The name does not need to be deallocated and will be
|
||||
@param disassembler The disassembler to query for the name.
|
||||
@param regID The register identifier, as returned by EDRegisterTokenValue.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetRegisterName(const char** regName,
|
||||
EDDisassemblerRef disassembler,
|
||||
unsigned regID);
|
||||
|
||||
/*!
|
||||
@function EDRegisterIsStackPointer
|
||||
Determines if a register is one of the platform's stack-pointer registers.
|
||||
@param disassembler The disassembler to query.
|
||||
@param regID The register identifier, as returned by EDRegisterTokenValue.
|
||||
@result 1 if true; 0 otherwise.
|
||||
*/
|
||||
int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
|
||||
unsigned regID);
|
||||
|
||||
/*!
|
||||
@function EDRegisterIsProgramCounter
|
||||
Determines if a register is one of the platform's stack-pointer registers.
|
||||
@param disassembler The disassembler to query.
|
||||
@param regID The register identifier, as returned by EDRegisterTokenValue.
|
||||
@result 1 if true; 0 otherwise.
|
||||
*/
|
||||
int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
|
||||
unsigned regID);
|
||||
|
||||
/*!
|
||||
@functiongroup Creating and querying instructions
|
||||
*/
|
||||
|
||||
/*!
|
||||
@function EDCreateInst
|
||||
Gets a set of contiguous instructions from a disassembler.
|
||||
@param insts A pointer to an array that will be filled in with the
|
||||
instructions. Must have at least count entries. Entries not filled in will
|
||||
be set to NULL.
|
||||
@param count The maximum number of instructions to fill in.
|
||||
@param disassembler The disassembler to use when decoding the instructions.
|
||||
@param byteReader The function to use when reading the instruction's machine
|
||||
code.
|
||||
@param address The address of the first byte of the instruction.
|
||||
@param arg An anonymous argument to be passed to byteReader.
|
||||
@result The number of instructions read on success; 0 otherwise.
|
||||
*/
|
||||
unsigned int EDCreateInsts(EDInstRef *insts,
|
||||
unsigned int count,
|
||||
EDDisassemblerRef disassembler,
|
||||
EDByteReaderCallback byteReader,
|
||||
uint64_t address,
|
||||
void *arg);
|
||||
|
||||
/*!
|
||||
@function EDReleaseInst
|
||||
Frees the memory for an instruction. The instruction can no longer be accessed
|
||||
after this call.
|
||||
@param inst The instruction to be freed.
|
||||
*/
|
||||
void EDReleaseInst(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDInstByteSize
|
||||
@param inst The instruction to be queried.
|
||||
@result The number of bytes in the instruction's machine-code representation.
|
||||
*/
|
||||
int EDInstByteSize(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDGetInstString
|
||||
Gets the disassembled text equivalent of the instruction.
|
||||
@param buf A pointer whose target will be filled in with a pointer to the
|
||||
string. (The string becomes invalid when the instruction is released.)
|
||||
@param inst The instruction to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetInstString(const char **buf,
|
||||
EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDInstID
|
||||
@param instID A pointer whose target will be filled in with the LLVM identifier
|
||||
for the instruction.
|
||||
@param inst The instruction to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDInstID(unsigned *instID, EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDInstIsBranch
|
||||
@param inst The instruction to be queried.
|
||||
@result 1 if the instruction is a branch instruction; 0 if it is some other
|
||||
type of instruction; -1 if there was an error.
|
||||
*/
|
||||
int EDInstIsBranch(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDInstIsMove
|
||||
@param inst The instruction to be queried.
|
||||
@result 1 if the instruction is a move instruction; 0 if it is some other
|
||||
type of instruction; -1 if there was an error.
|
||||
*/
|
||||
int EDInstIsMove(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDBranchTargetID
|
||||
@param inst The instruction to be queried.
|
||||
@result The ID of the branch target operand, suitable for use with
|
||||
EDCopyOperand. -1 if no such operand exists.
|
||||
*/
|
||||
int EDBranchTargetID(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDMoveSourceID
|
||||
@param inst The instruction to be queried.
|
||||
@result The ID of the move source operand, suitable for use with
|
||||
EDCopyOperand. -1 if no such operand exists.
|
||||
*/
|
||||
int EDMoveSourceID(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDMoveTargetID
|
||||
@param inst The instruction to be queried.
|
||||
@result The ID of the move source operand, suitable for use with
|
||||
EDCopyOperand. -1 if no such operand exists.
|
||||
*/
|
||||
int EDMoveTargetID(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@functiongroup Creating and querying tokens
|
||||
*/
|
||||
|
||||
/*!
|
||||
@function EDNumTokens
|
||||
@param inst The instruction to be queried.
|
||||
@result The number of tokens in the instruction, or -1 on error.
|
||||
*/
|
||||
int EDNumTokens(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDGetToken
|
||||
Retrieves a token from an instruction. The token is valid until the
|
||||
instruction is released.
|
||||
@param token A pointer to be filled in with the token.
|
||||
@param inst The instruction to be queried.
|
||||
@param index The index of the token in the instruction.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetToken(EDTokenRef *token,
|
||||
EDInstRef inst,
|
||||
int index);
|
||||
|
||||
/*!
|
||||
@function EDGetTokenString
|
||||
Gets the disassembled text for a token.
|
||||
@param buf A pointer whose target will be filled in with a pointer to the
|
||||
string. (The string becomes invalid when the token is released.)
|
||||
@param token The token to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetTokenString(const char **buf,
|
||||
EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDOperandIndexForToken
|
||||
Returns the index of the operand to which a token belongs.
|
||||
@param token The token to be queried.
|
||||
@result The operand index on success; -1 otherwise
|
||||
*/
|
||||
int EDOperandIndexForToken(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsWhitespace
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token is whitespace; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsWhitespace(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsPunctuation
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token is punctuation; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsPunctuation(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsOpcode
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token is opcode; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsOpcode(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsLiteral
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token is a numeric literal; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsLiteral(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsRegister
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token identifies a register; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsRegister(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsNegativeLiteral
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token is a negative signed literal; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsNegativeLiteral(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDLiteralTokenAbsoluteValue
|
||||
@param value A pointer whose target will be filled in with the absolute value
|
||||
of the literal.
|
||||
@param token The token to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDLiteralTokenAbsoluteValue(uint64_t *value,
|
||||
EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDRegisterTokenValue
|
||||
@param registerID A pointer whose target will be filled in with the LLVM
|
||||
register identifier for the token.
|
||||
@param token The token to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDRegisterTokenValue(unsigned *registerID,
|
||||
EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@functiongroup Creating and querying operands
|
||||
*/
|
||||
|
||||
/*!
|
||||
@function EDNumOperands
|
||||
@param inst The instruction to be queried.
|
||||
@result The number of operands in the instruction, or -1 on error.
|
||||
*/
|
||||
int EDNumOperands(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDGetOperand
|
||||
Retrieves an operand from an instruction. The operand is valid until the
|
||||
instruction is released.
|
||||
@param operand A pointer to be filled in with the operand.
|
||||
@param inst The instruction to be queried.
|
||||
@param index The index of the operand in the instruction.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetOperand(EDOperandRef *operand,
|
||||
EDInstRef inst,
|
||||
int index);
|
||||
|
||||
/*!
|
||||
@function EDOperandIsRegister
|
||||
@param operand The operand to be queried.
|
||||
@result 1 if the operand names a register; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDOperandIsRegister(EDOperandRef operand);
|
||||
|
||||
/*!
|
||||
@function EDOperandIsImmediate
|
||||
@param operand The operand to be queried.
|
||||
@result 1 if the operand specifies an immediate value; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDOperandIsImmediate(EDOperandRef operand);
|
||||
|
||||
/*!
|
||||
@function EDOperandIsMemory
|
||||
@param operand The operand to be queried.
|
||||
@result 1 if the operand specifies a location in memory; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDOperandIsMemory(EDOperandRef operand);
|
||||
|
||||
/*!
|
||||
@function EDRegisterOperandValue
|
||||
@param value A pointer whose target will be filled in with the LLVM register ID
|
||||
of the register named by the operand.
|
||||
@param operand The operand to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDRegisterOperandValue(unsigned *value,
|
||||
EDOperandRef operand);
|
||||
|
||||
/*!
|
||||
@function EDImmediateOperandValue
|
||||
@param value A pointer whose target will be filled in with the value of the
|
||||
immediate.
|
||||
@param operand The operand to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDImmediateOperandValue(uint64_t *value,
|
||||
EDOperandRef operand);
|
||||
|
||||
/*!
|
||||
@function EDEvaluateOperand
|
||||
Evaluates an operand using a client-supplied register state accessor. Register
|
||||
operands are evaluated by reading the value of the register; immediate operands
|
||||
are evaluated by reporting the immediate value; memory operands are evaluated
|
||||
by computing the target address (with only those relocations applied that were
|
||||
already applied to the original bytes).
|
||||
@param result A pointer whose target is to be filled with the result of
|
||||
evaluating the operand.
|
||||
@param operand The operand to be evaluated.
|
||||
@param regReader The function to use when reading registers from the register
|
||||
state.
|
||||
@param arg An anonymous argument for client use.
|
||||
@result 0 if the operand could be evaluated; -1 otherwise.
|
||||
*/
|
||||
int EDEvaluateOperand(uint64_t *result,
|
||||
EDOperandRef operand,
|
||||
EDRegisterReaderCallback regReader,
|
||||
void *arg);
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
|
||||
/*!
|
||||
@typedef EDByteBlock_t
|
||||
Block-based interface to memory from which instructions may be read.
|
||||
@param byte A pointer whose target should be filled in with the data returned.
|
||||
@param address The address of the byte to be read.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
typedef int (^EDByteBlock_t)(uint8_t *byte, uint64_t address);
|
||||
|
||||
/*!
|
||||
@typedef EDRegisterBlock_t
|
||||
Block-based interface to registers from which registers may be read.
|
||||
@param value A pointer whose target should be filled in with the value of the
|
||||
register.
|
||||
@param regID The LLVM register identifier for the register to read.
|
||||
@result 0 if the register could be read; -1 otherwise.
|
||||
*/
|
||||
typedef int (^EDRegisterBlock_t)(uint64_t *value, unsigned regID);
|
||||
|
||||
/*!
|
||||
@typedef EDTokenVisitor_t
|
||||
Block-based handler for individual tokens.
|
||||
@param token The current token being read.
|
||||
@result 0 to continue; 1 to stop normally; -1 on error.
|
||||
*/
|
||||
typedef int (^EDTokenVisitor_t)(EDTokenRef token);
|
||||
|
||||
/*! @functiongroup Block-based interfaces */
|
||||
|
||||
/*!
|
||||
@function EDBlockCreateInsts
|
||||
Gets a set of contiguous instructions from a disassembler, using a block to
|
||||
read memory.
|
||||
@param insts A pointer to an array that will be filled in with the
|
||||
instructions. Must have at least count entries. Entries not filled in will
|
||||
be set to NULL.
|
||||
@param count The maximum number of instructions to fill in.
|
||||
@param disassembler The disassembler to use when decoding the instructions.
|
||||
@param byteBlock The block to use when reading the instruction's machine
|
||||
code.
|
||||
@param address The address of the first byte of the instruction.
|
||||
@result The number of instructions read on success; 0 otherwise.
|
||||
*/
|
||||
unsigned int EDBlockCreateInsts(EDInstRef *insts,
|
||||
int count,
|
||||
EDDisassemblerRef disassembler,
|
||||
EDByteBlock_t byteBlock,
|
||||
uint64_t address);
|
||||
|
||||
/*!
|
||||
@function EDBlockEvaluateOperand
|
||||
Evaluates an operand using a block to read registers.
|
||||
@param result A pointer whose target is to be filled with the result of
|
||||
evaluating the operand.
|
||||
@param operand The operand to be evaluated.
|
||||
@param regBlock The block to use when reading registers from the register
|
||||
state.
|
||||
@result 0 if the operand could be evaluated; -1 otherwise.
|
||||
*/
|
||||
int EDBlockEvaluateOperand(uint64_t *result,
|
||||
EDOperandRef operand,
|
||||
EDRegisterBlock_t regBlock);
|
||||
|
||||
/*!
|
||||
@function EDBlockVisitTokens
|
||||
Visits every token with a visitor.
|
||||
@param inst The instruction with the tokens to be visited.
|
||||
@param visitor The visitor.
|
||||
@result 0 if the visit ended normally; -1 if the visitor encountered an error
|
||||
or there was some other error.
|
||||
*/
|
||||
int EDBlockVisitTokens(EDInstRef inst,
|
||||
EDTokenVisitor_t visitor);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -307,15 +307,17 @@ class BitVector {
|
||||
}
|
||||
|
||||
BitVector &operator|=(const BitVector &RHS) {
|
||||
assert(Size == RHS.Size && "Illegal operation!");
|
||||
for (unsigned i = 0; i < NumBitWords(size()); ++i)
|
||||
if (size() < RHS.size())
|
||||
resize(RHS.size());
|
||||
for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
|
||||
Bits[i] |= RHS.Bits[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVector &operator^=(const BitVector &RHS) {
|
||||
assert(Size == RHS.Size && "Illegal operation!");
|
||||
for (unsigned i = 0; i < NumBitWords(size()); ++i)
|
||||
if (size() < RHS.size())
|
||||
resize(RHS.size());
|
||||
for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
|
||||
Bits[i] ^= RHS.Bits[i];
|
||||
return *this;
|
||||
}
|
||||
|
@ -359,7 +359,7 @@ class DenseMap {
|
||||
BucketT *OldBuckets = Buckets;
|
||||
|
||||
// Double the number of buckets.
|
||||
while (NumBuckets <= AtLeast)
|
||||
while (NumBuckets < AtLeast)
|
||||
NumBuckets <<= 1;
|
||||
NumTombstones = 0;
|
||||
Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets));
|
||||
|
@ -41,8 +41,8 @@ class DenseSet {
|
||||
return TheMap.count(V);
|
||||
}
|
||||
|
||||
void erase(const ValueT &V) {
|
||||
TheMap.erase(V);
|
||||
bool erase(const ValueT &V) {
|
||||
return TheMap.erase(V);
|
||||
}
|
||||
|
||||
DenseSet &operator=(const DenseSet &RHS) {
|
||||
|
238
include/llvm/ADT/ImmutableIntervalMap.h
Normal file
238
include/llvm/ADT/ImmutableIntervalMap.h
Normal file
@ -0,0 +1,238 @@
|
||||
//===--- ImmutableIntervalMap.h - Immutable (functional) map ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the ImmutableIntervalMap class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "llvm/ADT/ImmutableMap.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Interval {
|
||||
private:
|
||||
uint64_t Start;
|
||||
uint64_t End;
|
||||
|
||||
public:
|
||||
Interval(uint64_t S, uint64_t E) : Start(S), End(E) {}
|
||||
|
||||
uint64_t getStart() const { return Start; }
|
||||
uint64_t getEnd() const { return End; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ImutIntervalInfo {
|
||||
typedef const std::pair<Interval, T> value_type;
|
||||
typedef const value_type &value_type_ref;
|
||||
typedef const Interval key_type;
|
||||
typedef const Interval &key_type_ref;
|
||||
typedef const T data_type;
|
||||
typedef const T &data_type_ref;
|
||||
|
||||
static key_type_ref KeyOfValue(value_type_ref V) {
|
||||
return V.first;
|
||||
}
|
||||
|
||||
static data_type_ref DataOfValue(value_type_ref V) {
|
||||
return V.second;
|
||||
}
|
||||
|
||||
static bool isEqual(key_type_ref L, key_type_ref R) {
|
||||
return L.getStart() == R.getStart() && L.getEnd() == R.getEnd();
|
||||
}
|
||||
|
||||
static bool isDataEqual(data_type_ref L, data_type_ref R) {
|
||||
return ImutContainerInfo<T>::isEqual(L,R);
|
||||
}
|
||||
|
||||
static bool isLess(key_type_ref L, key_type_ref R) {
|
||||
// Assume L and R does not overlap.
|
||||
if (L.getStart() < R.getStart()) {
|
||||
assert(L.getEnd() < R.getStart());
|
||||
return true;
|
||||
} else if (L.getStart() == R.getStart()) {
|
||||
assert(L.getEnd() == R.getEnd());
|
||||
return false;
|
||||
} else {
|
||||
assert(L.getStart() > R.getEnd());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool isContainedIn(key_type_ref K, key_type_ref L) {
|
||||
if (K.getStart() >= L.getStart() && K.getEnd() <= L.getEnd())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static void Profile(FoldingSetNodeID &ID, value_type_ref V) {
|
||||
ID.AddInteger(V.first.getStart());
|
||||
ID.AddInteger(V.first.getEnd());
|
||||
ImutProfileInfo<T>::Profile(ID, V.second);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ImutInfo>
|
||||
class ImutIntervalAVLFactory : public ImutAVLFactory<ImutInfo> {
|
||||
typedef ImutAVLTree<ImutInfo> TreeTy;
|
||||
typedef typename ImutInfo::value_type value_type;
|
||||
typedef typename ImutInfo::value_type_ref value_type_ref;
|
||||
typedef typename ImutInfo::key_type key_type;
|
||||
typedef typename ImutInfo::key_type_ref key_type_ref;
|
||||
typedef typename ImutInfo::data_type data_type;
|
||||
typedef typename ImutInfo::data_type_ref data_type_ref;
|
||||
|
||||
public:
|
||||
ImutIntervalAVLFactory(BumpPtrAllocator &Alloc)
|
||||
: ImutAVLFactory<ImutInfo>(Alloc) {}
|
||||
|
||||
TreeTy *Add(TreeTy *T, value_type_ref V) {
|
||||
T = Add_internal(V,T);
|
||||
this->MarkImmutable(T);
|
||||
return T;
|
||||
}
|
||||
|
||||
TreeTy *Find(TreeTy *T, key_type_ref K) {
|
||||
if (!T)
|
||||
return NULL;
|
||||
|
||||
key_type_ref CurrentKey = ImutInfo::KeyOfValue(this->Value(T));
|
||||
|
||||
if (ImutInfo::isContainedIn(K, CurrentKey))
|
||||
return T;
|
||||
else if (ImutInfo::isLess(K, CurrentKey))
|
||||
return Find(this->Left(T), K);
|
||||
else
|
||||
return Find(this->Right(T), K);
|
||||
}
|
||||
|
||||
private:
|
||||
TreeTy *Add_internal(value_type_ref V, TreeTy *T) {
|
||||
key_type_ref K = ImutInfo::KeyOfValue(V);
|
||||
T = RemoveAllOverlaps(T, K);
|
||||
if (this->isEmpty(T))
|
||||
return this->CreateNode(NULL, V, NULL);
|
||||
|
||||
assert(!T->isMutable());
|
||||
|
||||
key_type_ref KCurrent = ImutInfo::KeyOfValue(this->Value(T));
|
||||
|
||||
if (ImutInfo::isLess(K, KCurrent))
|
||||
return this->Balance(Add_internal(V, this->Left(T)), this->Value(T), this->Right(T));
|
||||
else
|
||||
return this->Balance(this->Left(T), this->Value(T), Add_internal(V, this->Right(T)));
|
||||
}
|
||||
|
||||
// Remove all overlaps from T.
|
||||
TreeTy *RemoveAllOverlaps(TreeTy *T, key_type_ref K) {
|
||||
bool Changed;
|
||||
do {
|
||||
Changed = false;
|
||||
T = RemoveOverlap(T, K, Changed);
|
||||
this->MarkImmutable(T);
|
||||
} while (Changed);
|
||||
|
||||
return T;
|
||||
}
|
||||
|
||||
// Remove one overlap from T.
|
||||
TreeTy *RemoveOverlap(TreeTy *T, key_type_ref K, bool &Changed) {
|
||||
if (!T)
|
||||
return NULL;
|
||||
Interval CurrentK = ImutInfo::KeyOfValue(this->Value(T));
|
||||
|
||||
// If current key does not overlap the inserted key.
|
||||
if (CurrentK.getStart() > K.getEnd())
|
||||
return this->Balance(RemoveOverlap(this->Left(T), K, Changed), this->Value(T), this->Right(T));
|
||||
else if (CurrentK.getEnd() < K.getStart())
|
||||
return this->Balance(this->Left(T), this->Value(T), RemoveOverlap(this->Right(T), K, Changed));
|
||||
|
||||
// Current key overlaps with the inserted key.
|
||||
// Remove the current key.
|
||||
Changed = true;
|
||||
data_type_ref OldData = ImutInfo::DataOfValue(this->Value(T));
|
||||
T = this->Remove_internal(CurrentK, T);
|
||||
// Add back the unoverlapped part of the current key.
|
||||
if (CurrentK.getStart() < K.getStart()) {
|
||||
if (CurrentK.getEnd() <= K.getEnd()) {
|
||||
Interval NewK(CurrentK.getStart(), K.getStart()-1);
|
||||
return Add_internal(std::make_pair(NewK, OldData), T);
|
||||
} else {
|
||||
Interval NewK1(CurrentK.getStart(), K.getStart()-1);
|
||||
T = Add_internal(std::make_pair(NewK1, OldData), T);
|
||||
|
||||
Interval NewK2(K.getEnd()+1, CurrentK.getEnd());
|
||||
return Add_internal(std::make_pair(NewK2, OldData), T);
|
||||
}
|
||||
} else {
|
||||
if (CurrentK.getEnd() > K.getEnd()) {
|
||||
Interval NewK(K.getEnd()+1, CurrentK.getEnd());
|
||||
return Add_internal(std::make_pair(NewK, OldData), T);
|
||||
} else
|
||||
return T;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// ImmutableIntervalMap maps an interval [start, end] to a value. The intervals
|
||||
/// in the map are guaranteed to be disjoint.
|
||||
template <typename ValT>
|
||||
class ImmutableIntervalMap
|
||||
: public ImmutableMap<Interval, ValT, ImutIntervalInfo<ValT> > {
|
||||
|
||||
typedef typename ImutIntervalInfo<ValT>::value_type value_type;
|
||||
typedef typename ImutIntervalInfo<ValT>::value_type_ref value_type_ref;
|
||||
typedef typename ImutIntervalInfo<ValT>::key_type key_type;
|
||||
typedef typename ImutIntervalInfo<ValT>::key_type_ref key_type_ref;
|
||||
typedef typename ImutIntervalInfo<ValT>::data_type data_type;
|
||||
typedef typename ImutIntervalInfo<ValT>::data_type_ref data_type_ref;
|
||||
typedef ImutAVLTree<ImutIntervalInfo<ValT> > TreeTy;
|
||||
|
||||
public:
|
||||
explicit ImmutableIntervalMap(TreeTy *R)
|
||||
: ImmutableMap<Interval, ValT, ImutIntervalInfo<ValT> >(R) {}
|
||||
|
||||
class Factory {
|
||||
ImutIntervalAVLFactory<ImutIntervalInfo<ValT> > F;
|
||||
|
||||
public:
|
||||
Factory(BumpPtrAllocator& Alloc) : F(Alloc) {}
|
||||
|
||||
ImmutableIntervalMap GetEmptyMap() {
|
||||
return ImmutableIntervalMap(F.GetEmptyTree());
|
||||
}
|
||||
|
||||
ImmutableIntervalMap Add(ImmutableIntervalMap Old,
|
||||
key_type_ref K, data_type_ref D) {
|
||||
TreeTy *T = F.Add(Old.Root, std::make_pair<key_type, data_type>(K, D));
|
||||
return ImmutableIntervalMap(F.GetCanonicalTree(T));
|
||||
}
|
||||
|
||||
ImmutableIntervalMap Remove(ImmutableIntervalMap Old, key_type_ref K) {
|
||||
TreeTy *T = F.Remove(Old.Root, K);
|
||||
return ImmutableIntervalMap(F.GetCanonicalTree(T));
|
||||
}
|
||||
|
||||
data_type *Lookup(ImmutableIntervalMap M, key_type_ref K) {
|
||||
TreeTy *T = F.Find(M.getRoot(), K);
|
||||
if (T)
|
||||
return &T->getValue().second;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
// For ImmutableIntervalMap, the lookup operation has to be done by the
|
||||
// factory.
|
||||
data_type* lookup(key_type_ref K) const;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
@ -68,7 +68,7 @@ class ImmutableMap {
|
||||
typedef typename ValInfo::data_type_ref data_type_ref;
|
||||
typedef ImutAVLTree<ValInfo> TreeTy;
|
||||
|
||||
private:
|
||||
protected:
|
||||
TreeTy* Root;
|
||||
|
||||
public:
|
||||
@ -106,13 +106,10 @@ class ImmutableMap {
|
||||
void operator=(const Factory& RHS); // DO NOT IMPLEMENT
|
||||
};
|
||||
|
||||
friend class Factory;
|
||||
|
||||
bool contains(key_type_ref K) const {
|
||||
return Root ? Root->contains(K) : false;
|
||||
}
|
||||
|
||||
|
||||
bool operator==(ImmutableMap RHS) const {
|
||||
return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ namespace llvm {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
template <typename ImutInfo> class ImutAVLFactory;
|
||||
template <typename ImutInfo> class ImutIntervalAVLFactory;
|
||||
template <typename ImutInfo> class ImutAVLTreeInOrderIterator;
|
||||
template <typename ImutInfo> class ImutAVLTreeGenericIterator;
|
||||
|
||||
@ -39,6 +40,7 @@ class ImutAVLTree : public FoldingSetNode {
|
||||
|
||||
typedef ImutAVLFactory<ImutInfo> Factory;
|
||||
friend class ImutAVLFactory<ImutInfo>;
|
||||
friend class ImutIntervalAVLFactory<ImutInfo>;
|
||||
|
||||
friend class ImutAVLTreeGenericIterator<ImutInfo>;
|
||||
friend class FoldingSet<ImutAVLTree>;
|
||||
@ -389,7 +391,7 @@ class ImutAVLFactory {
|
||||
// These have succinct names so that the balancing code
|
||||
// is as terse (and readable) as possible.
|
||||
//===--------------------------------------------------===//
|
||||
private:
|
||||
protected:
|
||||
|
||||
bool isEmpty(TreeTy* T) const { return !T; }
|
||||
unsigned Height(TreeTy* T) const { return T ? T->getHeight() : 0; }
|
||||
@ -581,25 +583,14 @@ class ImutAVLFactory {
|
||||
continue;
|
||||
|
||||
// We found a collision. Perform a comparison of Contents('T')
|
||||
// with Contents('L')+'V'+Contents('R').
|
||||
// with Contents('TNew')
|
||||
typename TreeTy::iterator TI = T->begin(), TE = T->end();
|
||||
|
||||
// First compare Contents('L') with the (initial) contents of T.
|
||||
if (!CompareTreeWithSection(TNew->getLeft(), TI, TE))
|
||||
continue;
|
||||
|
||||
// Now compare the new data element.
|
||||
if (TI == TE || !TI->ElementEqual(TNew->getValue()))
|
||||
continue;
|
||||
|
||||
++TI;
|
||||
|
||||
// Now compare the remainder of 'T' with 'R'.
|
||||
if (!CompareTreeWithSection(TNew->getRight(), TI, TE))
|
||||
if (!CompareTreeWithSection(TNew, TI, TE))
|
||||
continue;
|
||||
|
||||
if (TI != TE)
|
||||
continue; // Contents('R') did not match suffix of 'T'.
|
||||
continue; // T has more contents than TNew.
|
||||
|
||||
// Trees did match! Return 'T'.
|
||||
return T;
|
||||
|
@ -310,11 +310,47 @@ class SmallBitVector {
|
||||
}
|
||||
|
||||
// Intersection, union, disjoint union.
|
||||
BitVector &operator&=(const SmallBitVector &RHS); // TODO: implement
|
||||
SmallBitVector &operator&=(const SmallBitVector &RHS) {
|
||||
resize(std::max(size(), RHS.size()));
|
||||
if (isSmall())
|
||||
setSmallBits(getSmallBits() & RHS.getSmallBits());
|
||||
else if (!RHS.isSmall())
|
||||
X.getPointer()->operator&=(*RHS.X.getPointer());
|
||||
else {
|
||||
SmallBitVector Copy = RHS;
|
||||
Copy.resize(size());
|
||||
X.getPointer()->operator&=(*Copy.X.getPointer());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVector &operator|=(const SmallBitVector &RHS); // TODO: implement
|
||||
SmallBitVector &operator|=(const SmallBitVector &RHS) {
|
||||
resize(std::max(size(), RHS.size()));
|
||||
if (isSmall())
|
||||
setSmallBits(getSmallBits() | RHS.getSmallBits());
|
||||
else if (!RHS.isSmall())
|
||||
X.getPointer()->operator|=(*RHS.X.getPointer());
|
||||
else {
|
||||
SmallBitVector Copy = RHS;
|
||||
Copy.resize(size());
|
||||
X.getPointer()->operator|=(*Copy.X.getPointer());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVector &operator^=(const SmallBitVector &RHS); // TODO: implement
|
||||
SmallBitVector &operator^=(const SmallBitVector &RHS) {
|
||||
resize(std::max(size(), RHS.size()));
|
||||
if (isSmall())
|
||||
setSmallBits(getSmallBits() ^ RHS.getSmallBits());
|
||||
else if (!RHS.isSmall())
|
||||
X.getPointer()->operator^=(*RHS.X.getPointer());
|
||||
else {
|
||||
SmallBitVector Copy = RHS;
|
||||
Copy.resize(size());
|
||||
X.getPointer()->operator^=(*Copy.X.getPointer());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assignment operator.
|
||||
const SmallBitVector &operator=(const SmallBitVector &RHS) {
|
||||
|
@ -225,7 +225,7 @@ struct NextPowerOfTwo {
|
||||
};
|
||||
|
||||
|
||||
/// SmallPtrSet - This class implements a set which is optimizer for holding
|
||||
/// SmallPtrSet - This class implements a set which is optimized for holding
|
||||
/// SmallSize or less elements. This internally rounds up SmallSize to the next
|
||||
/// power of two if it is not already a power of two. See the comments above
|
||||
/// SmallPtrSetImpl for details of the algorithm.
|
||||
|
@ -66,6 +66,7 @@ class Triple {
|
||||
ppc, // PPC: powerpc
|
||||
ppc64, // PPC64: powerpc64, ppu
|
||||
sparc, // Sparc: sparc
|
||||
sparcv9, // Sparcv9: Sparcv9
|
||||
systemz, // SystemZ: s390x
|
||||
tce, // TCE (http://tce.cs.tut.fi/): tce
|
||||
thumb, // Thumb: thumb, thumbv.*
|
||||
|
@ -37,7 +37,7 @@ Constant *ConstantFoldInstruction(Instruction *I, const TargetData *TD = 0);
|
||||
/// ConstantFoldConstantExpression - Attempt to fold the constant expression
|
||||
/// using the specified TargetData. If successful, the constant result is
|
||||
/// result is returned, if not, null is returned.
|
||||
Constant *ConstantFoldConstantExpression(ConstantExpr *CE,
|
||||
Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
|
||||
const TargetData *TD = 0);
|
||||
|
||||
/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
|
||||
|
@ -193,7 +193,9 @@ namespace llvm {
|
||||
FlagFwdDecl = 1 << 2,
|
||||
FlagAppleBlock = 1 << 3,
|
||||
FlagBlockByrefStruct = 1 << 4,
|
||||
FlagVirtual = 1 << 5
|
||||
FlagVirtual = 1 << 5,
|
||||
FlagArtificial = 1 << 6 // To identify artificial arguments in
|
||||
// a subroutine type. e.g. "this" in c++.
|
||||
};
|
||||
|
||||
protected:
|
||||
@ -241,6 +243,9 @@ namespace llvm {
|
||||
bool isVirtual() const {
|
||||
return (getFlags() & FlagVirtual) != 0;
|
||||
}
|
||||
bool isArtificial() const {
|
||||
return (getFlags() & FlagArtificial) != 0;
|
||||
}
|
||||
|
||||
/// dump - print type.
|
||||
void dump() const;
|
||||
@ -298,6 +303,9 @@ namespace llvm {
|
||||
|
||||
DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
|
||||
unsigned getRunTimeLang() const { return getUnsignedField(11); }
|
||||
DICompositeType getContainingType() const {
|
||||
return getFieldAs<DICompositeType>(12);
|
||||
}
|
||||
|
||||
/// Verify - Verify that a composite type descriptor is well formed.
|
||||
bool Verify() const;
|
||||
@ -372,6 +380,7 @@ namespace llvm {
|
||||
DICompositeType getContainingType() const {
|
||||
return getFieldAs<DICompositeType>(13);
|
||||
}
|
||||
unsigned isArtificial() const { return getUnsignedField(14); }
|
||||
|
||||
StringRef getFilename() const { return getCompileUnit().getFilename();}
|
||||
StringRef getDirectory() const { return getCompileUnit().getDirectory();}
|
||||
@ -567,7 +576,11 @@ namespace llvm {
|
||||
uint64_t OffsetInBits, unsigned Flags,
|
||||
DIType DerivedFrom,
|
||||
DIArray Elements,
|
||||
unsigned RunTimeLang = 0);
|
||||
unsigned RunTimeLang = 0,
|
||||
MDNode *ContainingType = 0);
|
||||
|
||||
/// CreateArtificialType - Create a new DIType with "artificial" flag set.
|
||||
DIType CreateArtificialType(DIType Ty);
|
||||
|
||||
/// CreateCompositeType - Create a composite type like array, struct, etc.
|
||||
DICompositeType CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context,
|
||||
@ -591,7 +604,8 @@ namespace llvm {
|
||||
bool isDefinition,
|
||||
unsigned VK = 0,
|
||||
unsigned VIndex = 0,
|
||||
DIType = DIType());
|
||||
DIType = DIType(),
|
||||
bool isArtificial = 0);
|
||||
|
||||
/// CreateSubprogramDefinition - Create new subprogram descriptor for the
|
||||
/// given declaration.
|
||||
|
@ -16,29 +16,27 @@
|
||||
#define LLVM_ANALYSIS_IVUSERS_H
|
||||
|
||||
#include "llvm/Analysis/LoopPass.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <map>
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class DominatorTree;
|
||||
class Instruction;
|
||||
class Value;
|
||||
struct IVUsersOfOneStride;
|
||||
class IVUsers;
|
||||
class ScalarEvolution;
|
||||
class SCEV;
|
||||
|
||||
/// IVStrideUse - Keep track of one use of a strided induction variable, where
|
||||
/// the stride is stored externally. The Offset member keeps track of the
|
||||
/// offset from the IV, User is the actual user of the operand, and
|
||||
/// 'OperandValToReplace' is the operand of the User that is the use.
|
||||
/// IVStrideUse - Keep track of one use of a strided induction variable.
|
||||
/// The Expr member keeps track of the expression, User is the actual user
|
||||
/// instruction of the operand, and 'OperandValToReplace' is the operand of
|
||||
/// the User that is the use.
|
||||
class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
|
||||
public:
|
||||
IVStrideUse(IVUsersOfOneStride *parent,
|
||||
const SCEV *offset,
|
||||
IVStrideUse(IVUsers *P, const SCEV *S, const SCEV *Off,
|
||||
Instruction* U, Value *O)
|
||||
: CallbackVH(U), Parent(parent), Offset(offset),
|
||||
OperandValToReplace(O),
|
||||
IsUseOfPostIncrementedValue(false) {
|
||||
: CallbackVH(U), Parent(P), Stride(S), Offset(Off),
|
||||
OperandValToReplace(O), IsUseOfPostIncrementedValue(false) {
|
||||
}
|
||||
|
||||
/// getUser - Return the user instruction for this use.
|
||||
@ -51,9 +49,17 @@ class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
|
||||
setValPtr(NewUser);
|
||||
}
|
||||
|
||||
/// getParent - Return a pointer to the IVUsersOfOneStride that owns
|
||||
/// getParent - Return a pointer to the IVUsers that owns
|
||||
/// this IVStrideUse.
|
||||
IVUsersOfOneStride *getParent() const { return Parent; }
|
||||
IVUsers *getParent() const { return Parent; }
|
||||
|
||||
/// getStride - Return the expression for the stride for the use.
|
||||
const SCEV *getStride() const { return Stride; }
|
||||
|
||||
/// setStride - Assign a new stride to this use.
|
||||
void setStride(const SCEV *Val) {
|
||||
Stride = Val;
|
||||
}
|
||||
|
||||
/// getOffset - Return the offset to add to a theoeretical induction
|
||||
/// variable that starts at zero and counts up by the stride to compute
|
||||
@ -92,8 +98,11 @@ class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
|
||||
}
|
||||
|
||||
private:
|
||||
/// Parent - a pointer to the IVUsersOfOneStride that owns this IVStrideUse.
|
||||
IVUsersOfOneStride *Parent;
|
||||
/// Parent - a pointer to the IVUsers that owns this IVStrideUse.
|
||||
IVUsers *Parent;
|
||||
|
||||
/// Stride - The stride for this use.
|
||||
const SCEV *Stride;
|
||||
|
||||
/// Offset - The offset to add to the base induction expression.
|
||||
const SCEV *Offset;
|
||||
@ -138,37 +147,8 @@ template<> struct ilist_traits<IVStrideUse>
|
||||
mutable ilist_node<IVStrideUse> Sentinel;
|
||||
};
|
||||
|
||||
/// IVUsersOfOneStride - This structure keeps track of all instructions that
|
||||
/// have an operand that is based on the trip count multiplied by some stride.
|
||||
struct IVUsersOfOneStride : public ilist_node<IVUsersOfOneStride> {
|
||||
private:
|
||||
IVUsersOfOneStride(const IVUsersOfOneStride &I); // do not implement
|
||||
void operator=(const IVUsersOfOneStride &I); // do not implement
|
||||
|
||||
public:
|
||||
IVUsersOfOneStride() : Stride(0) {}
|
||||
|
||||
explicit IVUsersOfOneStride(const SCEV *stride) : Stride(stride) {}
|
||||
|
||||
/// Stride - The stride for all the contained IVStrideUses. This is
|
||||
/// a constant for affine strides.
|
||||
const SCEV *Stride;
|
||||
|
||||
/// Users - Keep track of all of the users of this stride as well as the
|
||||
/// initial value and the operand that uses the IV.
|
||||
ilist<IVStrideUse> Users;
|
||||
|
||||
void addUser(const SCEV *Offset, Instruction *User, Value *Operand) {
|
||||
Users.push_back(new IVStrideUse(this, Offset, User, Operand));
|
||||
}
|
||||
|
||||
void removeUser(IVStrideUse *User) {
|
||||
Users.erase(User);
|
||||
}
|
||||
};
|
||||
|
||||
class IVUsers : public LoopPass {
|
||||
friend class IVStrideUserVH;
|
||||
friend class IVStrideUse;
|
||||
Loop *L;
|
||||
LoopInfo *LI;
|
||||
DominatorTree *DT;
|
||||
@ -177,19 +157,8 @@ class IVUsers : public LoopPass {
|
||||
|
||||
/// IVUses - A list of all tracked IV uses of induction variable expressions
|
||||
/// we are interested in.
|
||||
ilist<IVUsersOfOneStride> IVUses;
|
||||
ilist<IVStrideUse> IVUses;
|
||||
|
||||
public:
|
||||
/// IVUsesByStride - A mapping from the strides in StrideOrder to the
|
||||
/// uses in IVUses.
|
||||
std::map<const SCEV *, IVUsersOfOneStride*> IVUsesByStride;
|
||||
|
||||
/// StrideOrder - An ordering of the keys in IVUsesByStride that is stable:
|
||||
/// We use this to iterate over the IVUsesByStride collection without being
|
||||
/// dependent on random ordering of pointers in the process.
|
||||
SmallVector<const SCEV *, 16> StrideOrder;
|
||||
|
||||
private:
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
|
||||
virtual bool runOnLoop(Loop *L, LPPassManager &LPM);
|
||||
@ -205,8 +174,8 @@ class IVUsers : public LoopPass {
|
||||
/// return true. Otherwise, return false.
|
||||
bool AddUsersIfInteresting(Instruction *I);
|
||||
|
||||
void AddUser(const SCEV *Stride, const SCEV *Offset,
|
||||
Instruction *User, Value *Operand);
|
||||
IVStrideUse &AddUser(const SCEV *Stride, const SCEV *Offset,
|
||||
Instruction *User, Value *Operand);
|
||||
|
||||
/// getReplacementExpr - Return a SCEV expression which computes the
|
||||
/// value of the OperandValToReplace of the given IVStrideUse.
|
||||
@ -217,6 +186,14 @@ class IVUsers : public LoopPass {
|
||||
/// isUseOfPostIncrementedValue flag.
|
||||
const SCEV *getCanonicalExpr(const IVStrideUse &U) const;
|
||||
|
||||
typedef ilist<IVStrideUse>::iterator iterator;
|
||||
typedef ilist<IVStrideUse>::const_iterator const_iterator;
|
||||
iterator begin() { return IVUses.begin(); }
|
||||
iterator end() { return IVUses.end(); }
|
||||
const_iterator begin() const { return IVUses.begin(); }
|
||||
const_iterator end() const { return IVUses.end(); }
|
||||
bool empty() const { return IVUses.empty(); }
|
||||
|
||||
void print(raw_ostream &OS, const Module* = 0) const;
|
||||
|
||||
/// dump - This method is used for debugging.
|
||||
|
@ -34,7 +34,7 @@ namespace llvm {
|
||||
/// NeverInline - True if this callee should never be inlined into a
|
||||
/// caller.
|
||||
bool NeverInline;
|
||||
|
||||
|
||||
/// usesDynamicAlloca - True if this function calls alloca (in the C sense).
|
||||
bool usesDynamicAlloca;
|
||||
|
||||
@ -42,17 +42,20 @@ namespace llvm {
|
||||
/// is used to estimate the code size cost of inlining it.
|
||||
unsigned NumInsts, NumBlocks;
|
||||
|
||||
/// NumCalls - Keep track of the number of calls to 'big' functions.
|
||||
unsigned NumCalls;
|
||||
|
||||
/// NumVectorInsts - Keep track of how many instructions produce vector
|
||||
/// values. The inliner is being more aggressive with inlining vector
|
||||
/// kernels.
|
||||
unsigned NumVectorInsts;
|
||||
|
||||
|
||||
/// NumRets - Keep track of how many Ret instructions the block contains.
|
||||
unsigned NumRets;
|
||||
|
||||
CodeMetrics() : NeverInline(false), usesDynamicAlloca(false), NumInsts(0),
|
||||
NumBlocks(0), NumVectorInsts(0), NumRets(0) {}
|
||||
|
||||
NumBlocks(0), NumCalls(0), NumVectorInsts(0), NumRets(0) {}
|
||||
|
||||
/// analyzeBasicBlock - Add information about the specified basic block
|
||||
/// to the current structure.
|
||||
void analyzeBasicBlock(const BasicBlock *BB);
|
||||
@ -64,7 +67,9 @@ namespace llvm {
|
||||
|
||||
namespace InlineConstants {
|
||||
// Various magic constants used to adjust heuristics.
|
||||
const int CallPenalty = 5;
|
||||
const int InstrCost = 5;
|
||||
const int IndirectCallBonus = 500;
|
||||
const int CallPenalty = 25;
|
||||
const int LastCallToStaticBonus = -15000;
|
||||
const int ColdccPenalty = 2000;
|
||||
const int NoreturnPenalty = 10000;
|
||||
@ -119,18 +124,18 @@ namespace llvm {
|
||||
return getCost();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// InlineCostAnalyzer - Cost analyzer used by inliner.
|
||||
class InlineCostAnalyzer {
|
||||
struct ArgInfo {
|
||||
public:
|
||||
unsigned ConstantWeight;
|
||||
unsigned AllocaWeight;
|
||||
|
||||
|
||||
ArgInfo(unsigned CWeight, unsigned AWeight)
|
||||
: ConstantWeight(CWeight), AllocaWeight(AWeight) {}
|
||||
};
|
||||
|
||||
|
||||
struct FunctionInfo {
|
||||
CodeMetrics Metrics;
|
||||
|
||||
@ -139,12 +144,12 @@ namespace llvm {
|
||||
/// would reduce the code size. If so, we add some value to the argument
|
||||
/// entry here.
|
||||
std::vector<ArgInfo> ArgumentWeights;
|
||||
|
||||
|
||||
/// CountCodeReductionForConstant - Figure out an approximation for how
|
||||
/// many instructions will be constant folded if the specified value is
|
||||
/// constant.
|
||||
unsigned CountCodeReductionForConstant(Value *V);
|
||||
|
||||
|
||||
/// CountCodeReductionForAlloca - Figure out an approximation of how much
|
||||
/// smaller the function will be if it is inlined into a context where an
|
||||
/// argument becomes an alloca.
|
||||
|
@ -553,6 +553,10 @@ class Loop : public LoopBase<BasicBlock, Loop> {
|
||||
/// normal unsigned value, if possible. Returns 0 if the trip count is unknown
|
||||
/// of not constant. Will also return 0 if the trip count is very large
|
||||
/// (>= 2^32)
|
||||
///
|
||||
/// The IndVarSimplify pass transforms loops to have a form that this
|
||||
/// function easily understands.
|
||||
///
|
||||
unsigned getSmallConstantTripCount() const;
|
||||
|
||||
/// getSmallConstantTripMultiple - Returns the largest constant divisor of the
|
||||
|
@ -72,7 +72,7 @@ Value *getMallocArraySize(CallInst *CI, const TargetData *TD,
|
||||
// free Call Utility Functions.
|
||||
//
|
||||
|
||||
/// isFreeCall - Returns true if the the value is a call to the builtin free()
|
||||
/// isFreeCall - Returns true if the value is a call to the builtin free()
|
||||
bool isFreeCall(const Value *I);
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -452,11 +452,25 @@ namespace llvm {
|
||||
const SCEV *getUMaxExpr(SmallVectorImpl<const SCEV *> &Operands);
|
||||
const SCEV *getSMinExpr(const SCEV *LHS, const SCEV *RHS);
|
||||
const SCEV *getUMinExpr(const SCEV *LHS, const SCEV *RHS);
|
||||
const SCEV *getFieldOffsetExpr(const StructType *STy, unsigned FieldNo);
|
||||
const SCEV *getAllocSizeExpr(const Type *AllocTy);
|
||||
const SCEV *getUnknown(Value *V);
|
||||
const SCEV *getCouldNotCompute();
|
||||
|
||||
/// getSizeOfExpr - Return an expression for sizeof on the given type.
|
||||
///
|
||||
const SCEV *getSizeOfExpr(const Type *AllocTy);
|
||||
|
||||
/// getAlignOfExpr - Return an expression for alignof on the given type.
|
||||
///
|
||||
const SCEV *getAlignOfExpr(const Type *AllocTy);
|
||||
|
||||
/// getOffsetOfExpr - Return an expression for offsetof on the given field.
|
||||
///
|
||||
const SCEV *getOffsetOfExpr(const StructType *STy, unsigned FieldNo);
|
||||
|
||||
/// getOffsetOfExpr - Return an expression for offsetof on the given field.
|
||||
///
|
||||
const SCEV *getOffsetOfExpr(const Type *CTy, Constant *FieldNo);
|
||||
|
||||
/// getNegativeSCEV - Return the SCEV object corresponding to -V.
|
||||
///
|
||||
const SCEV *getNegativeSCEV(const SCEV *V);
|
||||
@ -503,7 +517,7 @@ namespace llvm {
|
||||
|
||||
/// getIntegerSCEV - Given a SCEVable type, create a constant for the
|
||||
/// specified signed integer value and return a SCEV for the constant.
|
||||
const SCEV *getIntegerSCEV(int Val, const Type *Ty);
|
||||
const SCEV *getIntegerSCEV(int64_t Val, const Type *Ty);
|
||||
|
||||
/// getUMaxFromMismatchedTypes - Promote the operands to the wider of
|
||||
/// the types using zero-extension, and then perform a umax operation
|
||||
|
@ -27,10 +27,7 @@ namespace llvm {
|
||||
/// and destroy it when finished to allow the release of the associated
|
||||
/// memory.
|
||||
class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
|
||||
public:
|
||||
ScalarEvolution &SE;
|
||||
|
||||
private:
|
||||
std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> >
|
||||
InsertedExpressions;
|
||||
std::set<Value*> InsertedValues;
|
||||
@ -57,11 +54,11 @@ namespace llvm {
|
||||
/// in a more literal form.
|
||||
bool CanonicalMode;
|
||||
|
||||
protected:
|
||||
typedef IRBuilder<true, TargetFolder> BuilderType;
|
||||
BuilderType Builder;
|
||||
|
||||
friend struct SCEVVisitor<SCEVExpander, Value*>;
|
||||
|
||||
public:
|
||||
/// SCEVExpander - Construct a SCEVExpander in "canonical" mode.
|
||||
explicit SCEVExpander(ScalarEvolution &se)
|
||||
@ -167,17 +164,13 @@ namespace llvm {
|
||||
|
||||
Value *visitUMaxExpr(const SCEVUMaxExpr *S);
|
||||
|
||||
Value *visitFieldOffsetExpr(const SCEVFieldOffsetExpr *S);
|
||||
|
||||
Value *visitAllocSizeExpr(const SCEVAllocSizeExpr *S);
|
||||
|
||||
Value *visitUnknown(const SCEVUnknown *S) {
|
||||
return S->getValue();
|
||||
}
|
||||
|
||||
void rememberInstruction(Value *I) {
|
||||
if (!PostIncLoop) InsertedValues.insert(I);
|
||||
}
|
||||
void rememberInstruction(Value *I);
|
||||
|
||||
void restoreInsertPoint(BasicBlock *BB, BasicBlock::iterator I);
|
||||
|
||||
Value *expandAddRecExprLiterally(const SCEVAddRecExpr *);
|
||||
PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
|
||||
|
@ -27,7 +27,7 @@ namespace llvm {
|
||||
// folders simpler.
|
||||
scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr,
|
||||
scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr,
|
||||
scFieldOffset, scAllocSize, scUnknown, scCouldNotCompute
|
||||
scUnknown, scCouldNotCompute
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
@ -412,12 +412,15 @@ namespace llvm {
|
||||
}
|
||||
|
||||
virtual bool hasComputableLoopEvolution(const Loop *QL) const {
|
||||
if (L == QL) return true;
|
||||
return false;
|
||||
return L == QL;
|
||||
}
|
||||
|
||||
virtual bool isLoopInvariant(const Loop *QueryLoop) const;
|
||||
|
||||
bool dominates(BasicBlock *BB, DominatorTree *DT) const;
|
||||
|
||||
bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const;
|
||||
|
||||
/// isAffine - Return true if this is an affine AddRec (i.e., it represents
|
||||
/// an expressions A+B*x where A and B are loop invariant values.
|
||||
bool isAffine() const {
|
||||
@ -511,95 +514,6 @@ namespace llvm {
|
||||
}
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// SCEVTargetDataConstant - This node is the base class for representing
|
||||
/// target-dependent values in a target-independent way.
|
||||
///
|
||||
class SCEVTargetDataConstant : public SCEV {
|
||||
protected:
|
||||
const Type *Ty;
|
||||
SCEVTargetDataConstant(const FoldingSetNodeID &ID, enum SCEVTypes T,
|
||||
const Type *ty) :
|
||||
SCEV(ID, T), Ty(ty) {}
|
||||
|
||||
public:
|
||||
virtual bool isLoopInvariant(const Loop *) const { return true; }
|
||||
virtual bool hasComputableLoopEvolution(const Loop *) const {
|
||||
return false; // not computable
|
||||
}
|
||||
|
||||
virtual bool hasOperand(const SCEV *) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dominates(BasicBlock *, DominatorTree *) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool properlyDominates(BasicBlock *, DominatorTree *) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual const Type *getType() const { return Ty; }
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const SCEVTargetDataConstant *S) { return true; }
|
||||
static inline bool classof(const SCEV *S) {
|
||||
return S->getSCEVType() == scFieldOffset ||
|
||||
S->getSCEVType() == scAllocSize;
|
||||
}
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// SCEVFieldOffsetExpr - This node represents an offsetof expression.
|
||||
///
|
||||
class SCEVFieldOffsetExpr : public SCEVTargetDataConstant {
|
||||
friend class ScalarEvolution;
|
||||
|
||||
const StructType *STy;
|
||||
unsigned FieldNo;
|
||||
SCEVFieldOffsetExpr(const FoldingSetNodeID &ID, const Type *ty,
|
||||
const StructType *sty, unsigned fieldno) :
|
||||
SCEVTargetDataConstant(ID, scFieldOffset, ty),
|
||||
STy(sty), FieldNo(fieldno) {}
|
||||
|
||||
public:
|
||||
const StructType *getStructType() const { return STy; }
|
||||
unsigned getFieldNo() const { return FieldNo; }
|
||||
|
||||
virtual void print(raw_ostream &OS) const;
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const SCEVFieldOffsetExpr *S) { return true; }
|
||||
static inline bool classof(const SCEV *S) {
|
||||
return S->getSCEVType() == scFieldOffset;
|
||||
}
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// SCEVAllocSize - This node represents a sizeof expression.
|
||||
///
|
||||
class SCEVAllocSizeExpr : public SCEVTargetDataConstant {
|
||||
friend class ScalarEvolution;
|
||||
|
||||
const Type *AllocTy;
|
||||
SCEVAllocSizeExpr(const FoldingSetNodeID &ID,
|
||||
const Type *ty, const Type *allocty) :
|
||||
SCEVTargetDataConstant(ID, scAllocSize, ty),
|
||||
AllocTy(allocty) {}
|
||||
|
||||
public:
|
||||
const Type *getAllocType() const { return AllocTy; }
|
||||
|
||||
virtual void print(raw_ostream &OS) const;
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const SCEVAllocSizeExpr *S) { return true; }
|
||||
static inline bool classof(const SCEV *S) {
|
||||
return S->getSCEVType() == scAllocSize;
|
||||
}
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// SCEVUnknown - This means that we are dealing with an entirely unknown SCEV
|
||||
/// value, and only represent it as its LLVM Value. This is the "bottom"
|
||||
@ -615,6 +529,16 @@ namespace llvm {
|
||||
public:
|
||||
Value *getValue() const { return V; }
|
||||
|
||||
/// isSizeOf, isAlignOf, isOffsetOf - Test whether this is a special
|
||||
/// constant representing a type size, alignment, or field offset in
|
||||
/// a target-independent manner, and hasn't happened to have been
|
||||
/// folded with other operations into something unrecognizable. This
|
||||
/// is mainly only useful for pretty-printing and other situations
|
||||
/// where it isn't absolutely required for these to succeed.
|
||||
bool isSizeOf(const Type *&AllocTy) const;
|
||||
bool isAlignOf(const Type *&AllocTy) const;
|
||||
bool isOffsetOf(const Type *&STy, Constant *&FieldNo) const;
|
||||
|
||||
virtual bool isLoopInvariant(const Loop *L) const;
|
||||
virtual bool hasComputableLoopEvolution(const Loop *QL) const {
|
||||
return false; // not computable
|
||||
@ -665,10 +589,6 @@ namespace llvm {
|
||||
return ((SC*)this)->visitSMaxExpr((const SCEVSMaxExpr*)S);
|
||||
case scUMaxExpr:
|
||||
return ((SC*)this)->visitUMaxExpr((const SCEVUMaxExpr*)S);
|
||||
case scFieldOffset:
|
||||
return ((SC*)this)->visitFieldOffsetExpr((const SCEVFieldOffsetExpr*)S);
|
||||
case scAllocSize:
|
||||
return ((SC*)this)->visitAllocSizeExpr((const SCEVAllocSizeExpr*)S);
|
||||
case scUnknown:
|
||||
return ((SC*)this)->visitUnknown((const SCEVUnknown*)S);
|
||||
case scCouldNotCompute:
|
||||
|
@ -23,29 +23,34 @@ class Function;
|
||||
class BasicBlock;
|
||||
class Instruction;
|
||||
class raw_ostream;
|
||||
class formatted_raw_ostream;
|
||||
|
||||
class AssemblyAnnotationWriter {
|
||||
public:
|
||||
|
||||
virtual ~AssemblyAnnotationWriter();
|
||||
|
||||
// emitFunctionAnnot - This may be implemented to emit a string right before
|
||||
// the start of a function.
|
||||
/// emitFunctionAnnot - This may be implemented to emit a string right before
|
||||
/// the start of a function.
|
||||
virtual void emitFunctionAnnot(const Function *F, raw_ostream &OS) {}
|
||||
|
||||
// emitBasicBlockStartAnnot - This may be implemented to emit a string right
|
||||
// after the basic block label, but before the first instruction in the block.
|
||||
/// emitBasicBlockStartAnnot - This may be implemented to emit a string right
|
||||
/// after the basic block label, but before the first instruction in the block.
|
||||
virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, raw_ostream &OS){
|
||||
}
|
||||
|
||||
// emitBasicBlockEndAnnot - This may be implemented to emit a string right
|
||||
// after the basic block.
|
||||
/// emitBasicBlockEndAnnot - This may be implemented to emit a string right
|
||||
/// after the basic block.
|
||||
virtual void emitBasicBlockEndAnnot(const BasicBlock *BB, raw_ostream &OS){
|
||||
}
|
||||
|
||||
// emitInstructionAnnot - This may be implemented to emit a string right
|
||||
// before an instruction is emitted.
|
||||
/// emitInstructionAnnot - This may be implemented to emit a string right
|
||||
/// before an instruction is emitted.
|
||||
virtual void emitInstructionAnnot(const Instruction *I, raw_ostream &OS) {}
|
||||
|
||||
/// printInfoComment - This may be implemented to emit a comment to the
|
||||
/// right of an instruction or global value.
|
||||
virtual void printInfoComment(const Value &V, formatted_raw_ostream &OS) {}
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -58,6 +58,13 @@ const Attributes NoRedZone = 1<<22; /// disable redzone
|
||||
const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point
|
||||
/// instructions.
|
||||
const Attributes Naked = 1<<24; ///< Naked function
|
||||
const Attributes InlineHint = 1<<25; ///< source said inlining was
|
||||
///desirable
|
||||
const Attributes StackAlignment = 31<<26; ///< Alignment of stack for
|
||||
///function (5 bits) stored as log2
|
||||
///of alignment with +1 bias
|
||||
///0 means unaligned (different from
|
||||
///alignstack(1))
|
||||
|
||||
/// @brief Attributes that only apply to function parameters.
|
||||
const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
|
||||
@ -66,7 +73,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
|
||||
/// be used on return values or function parameters.
|
||||
const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
|
||||
NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |
|
||||
NoRedZone | NoImplicitFloat | Naked;
|
||||
NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment;
|
||||
|
||||
/// @brief Parameter attributes that do not apply to vararg call arguments.
|
||||
const Attributes VarArgsIncompatible = StructRet;
|
||||
@ -103,6 +110,28 @@ inline unsigned getAlignmentFromAttrs(Attributes A) {
|
||||
return 1U << ((Align >> 16) - 1);
|
||||
}
|
||||
|
||||
/// This turns an int stack alignment (which must be a power of 2) into
|
||||
/// the form used internally in Attributes.
|
||||
inline Attributes constructStackAlignmentFromInt(unsigned i) {
|
||||
// Default alignment, allow the target to define how to align it.
|
||||
if (i == 0)
|
||||
return 0;
|
||||
|
||||
assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
|
||||
assert(i <= 0x40000000 && "Alignment too large.");
|
||||
return (Log2_32(i)+1) << 26;
|
||||
}
|
||||
|
||||
/// This returns the stack alignment field of an attribute as a byte alignment
|
||||
/// value.
|
||||
inline unsigned getStackAlignmentFromAttrs(Attributes A) {
|
||||
Attributes StackAlign = A & Attribute::StackAlignment;
|
||||
if (StackAlign == 0)
|
||||
return 0;
|
||||
|
||||
return 1U << ((StackAlign >> 26) - 1);
|
||||
}
|
||||
|
||||
|
||||
/// The set of Attributes set in Attributes is converted to a
|
||||
/// string of equivalent mnemonics. This is, presumably, for writing out
|
||||
|
@ -27,7 +27,6 @@ namespace llvm {
|
||||
class MemoryBuffer;
|
||||
|
||||
// Forward declare classes
|
||||
class ModuleProvider; // From VMCore
|
||||
class Module; // From VMCore
|
||||
class Archive; // Declared below
|
||||
class ArchiveMemberHeader; // Internal implementation class
|
||||
@ -374,14 +373,14 @@ class Archive {
|
||||
/// returns the associated module that defines that symbol. This method can
|
||||
/// be called as many times as necessary. This is handy for linking the
|
||||
/// archive into another module based on unresolved symbols. Note that the
|
||||
/// ModuleProvider returned by this accessor should not be deleted by the
|
||||
/// caller. It is managed internally by the Archive class. It is possible
|
||||
/// that multiple calls to this accessor will return the same ModuleProvider
|
||||
/// instance because the associated module defines multiple symbols.
|
||||
/// @returns The ModuleProvider* found or null if the archive does not
|
||||
/// contain a module that defines the \p symbol.
|
||||
/// Module returned by this accessor should not be deleted by the caller. It
|
||||
/// is managed internally by the Archive class. It is possible that multiple
|
||||
/// calls to this accessor will return the same Module instance because the
|
||||
/// associated module defines multiple symbols.
|
||||
/// @returns The Module* found or null if the archive does not contain a
|
||||
/// module that defines the \p symbol.
|
||||
/// @brief Look up a module by symbol name.
|
||||
ModuleProvider* findModuleDefiningSymbol(
|
||||
Module* findModuleDefiningSymbol(
|
||||
const std::string& symbol, ///< Symbol to be sought
|
||||
std::string* ErrMessage ///< Error message storage, if non-zero
|
||||
);
|
||||
@ -397,7 +396,7 @@ class Archive {
|
||||
/// @brief Look up multiple symbols in the archive.
|
||||
bool findModulesDefiningSymbols(
|
||||
std::set<std::string>& symbols, ///< Symbols to be sought
|
||||
std::set<ModuleProvider*>& modules, ///< The modules matching \p symbols
|
||||
std::set<Module*>& modules, ///< The modules matching \p symbols
|
||||
std::string* ErrMessage ///< Error msg storage, if non-zero
|
||||
);
|
||||
|
||||
@ -513,9 +512,9 @@ class Archive {
|
||||
|
||||
/// This type is used to keep track of bitcode modules loaded from the
|
||||
/// symbol table. It maps the file offset to a pair that consists of the
|
||||
/// associated ArchiveMember and the ModuleProvider.
|
||||
/// associated ArchiveMember and the Module.
|
||||
/// @brief Module mapping type
|
||||
typedef std::map<unsigned,std::pair<ModuleProvider*,ArchiveMember*> >
|
||||
typedef std::map<unsigned,std::pair<Module*,ArchiveMember*> >
|
||||
ModuleMap;
|
||||
|
||||
|
||||
|
@ -291,7 +291,7 @@ class BitstreamWriter {
|
||||
/// EmitRecordWithAbbrevImpl - This is the core implementation of the record
|
||||
/// emission code. If BlobData is non-null, then it specifies an array of
|
||||
/// data that should be emitted as part of the Blob or Array operand that is
|
||||
/// known to exist at the end of the the record.
|
||||
/// known to exist at the end of the record.
|
||||
template<typename uintty>
|
||||
void EmitRecordWithAbbrevImpl(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
|
||||
StringRef Blob) {
|
||||
|
@ -94,7 +94,8 @@ namespace bitc {
|
||||
TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa)
|
||||
TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles)
|
||||
|
||||
TYPE_CODE_METADATA = 16 // METADATA
|
||||
TYPE_CODE_METADATA = 16, // METADATA
|
||||
TYPE_CODE_UNION = 17 // UNION: [eltty x N]
|
||||
};
|
||||
|
||||
// The type symbol table only has one code (TST_ENTRY_CODE).
|
||||
|
@ -18,21 +18,20 @@
|
||||
|
||||
namespace llvm {
|
||||
class Module;
|
||||
class ModuleProvider;
|
||||
class MemoryBuffer;
|
||||
class ModulePass;
|
||||
class BitstreamWriter;
|
||||
class LLVMContext;
|
||||
class raw_ostream;
|
||||
|
||||
/// getBitcodeModuleProvider - Read the header of the specified bitcode buffer
|
||||
/// getLazyBitcodeModule - Read the header of the specified bitcode buffer
|
||||
/// and prepare for lazy deserialization of function bodies. If successful,
|
||||
/// this takes ownership of 'buffer' and returns a non-null pointer. On
|
||||
/// 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);
|
||||
Module *getLazyBitcodeModule(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
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/Support/DebugLoc.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
||||
namespace llvm {
|
||||
class BlockAddress;
|
||||
@ -62,13 +61,6 @@ namespace llvm {
|
||||
class AsmPrinter : public MachineFunctionPass {
|
||||
static char ID;
|
||||
|
||||
/// FunctionNumber - This provides a unique ID for each function emitted in
|
||||
/// this translation unit. It is autoincremented by SetupMachineFunction,
|
||||
/// and can be accessed with getFunctionNumber() and
|
||||
/// IncrementFunctionNumber().
|
||||
///
|
||||
unsigned FunctionNumber;
|
||||
|
||||
// GCMetadataPrinters - The garbage collection metadata printer table.
|
||||
typedef DenseMap<GCStrategy*,GCMetadataPrinter*> gcp_map_type;
|
||||
typedef gcp_map_type::iterator gcp_iterator;
|
||||
@ -88,13 +80,6 @@ namespace llvm {
|
||||
DwarfWriter *DW;
|
||||
|
||||
public:
|
||||
/// Flags to specify different kinds of comments to output in
|
||||
/// assembly code. These flags carry semantic information not
|
||||
/// otherwise easily derivable from the IR text.
|
||||
///
|
||||
enum CommentFlag {
|
||||
ReloadReuse = 0x1
|
||||
};
|
||||
|
||||
/// Output stream on which we're printing assembly code.
|
||||
///
|
||||
@ -157,7 +142,8 @@ namespace llvm {
|
||||
|
||||
protected:
|
||||
explicit AsmPrinter(formatted_raw_ostream &o, TargetMachine &TM,
|
||||
const MCAsmInfo *T, bool V);
|
||||
MCContext &Ctx, MCStreamer &Streamer,
|
||||
const MCAsmInfo *T);
|
||||
|
||||
public:
|
||||
virtual ~AsmPrinter();
|
||||
@ -168,7 +154,7 @@ namespace llvm {
|
||||
|
||||
/// getFunctionNumber - Return a unique ID for the current function.
|
||||
///
|
||||
unsigned getFunctionNumber() const { return FunctionNumber; }
|
||||
unsigned getFunctionNumber() const;
|
||||
|
||||
protected:
|
||||
/// getAnalysisUsage - Record analysis usage.
|
||||
@ -215,26 +201,51 @@ namespace llvm {
|
||||
unsigned AsmVariant,
|
||||
const char *ExtraCode);
|
||||
|
||||
/// runOnMachineFunction - Emit the specified function out to the
|
||||
/// OutStreamer.
|
||||
virtual bool runOnMachineFunction(MachineFunction &MF) {
|
||||
SetupMachineFunction(MF);
|
||||
EmitFunctionHeader();
|
||||
EmitFunctionBody();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// SetupMachineFunction - This should be called when a new MachineFunction
|
||||
/// is being processed from runOnMachineFunction.
|
||||
void SetupMachineFunction(MachineFunction &MF);
|
||||
|
||||
/// IncrementFunctionNumber - Increase Function Number. AsmPrinters should
|
||||
/// not normally call this, as the counter is automatically bumped by
|
||||
/// SetupMachineFunction.
|
||||
void IncrementFunctionNumber() { FunctionNumber++; }
|
||||
/// EmitFunctionHeader - This method emits the header for the current
|
||||
/// function.
|
||||
void EmitFunctionHeader();
|
||||
|
||||
/// EmitFunctionBody - This method emits the body and trailer for a
|
||||
/// function.
|
||||
void EmitFunctionBody();
|
||||
|
||||
/// EmitInstruction - Targets should implement this to emit instructions.
|
||||
virtual void EmitInstruction(const MachineInstr *MI) {
|
||||
assert(0 && "EmitInstruction not implemented");
|
||||
}
|
||||
|
||||
/// EmitFunctionBodyStart - Targets can override this to emit stuff before
|
||||
/// the first basic block in the function.
|
||||
virtual void EmitFunctionBodyStart() {}
|
||||
|
||||
/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
|
||||
/// the last basic block in the function.
|
||||
virtual void EmitFunctionBodyEnd() {}
|
||||
|
||||
/// EmitConstantPool - Print to the current output stream assembly
|
||||
/// representations of the constants in the constant pool MCP. This is
|
||||
/// used to print out constants which have been "spilled to memory" by
|
||||
/// the code generator.
|
||||
///
|
||||
void EmitConstantPool(MachineConstantPool *MCP);
|
||||
|
||||
virtual void EmitConstantPool();
|
||||
|
||||
/// EmitJumpTableInfo - Print assembly representations of the jump tables
|
||||
/// used by the current function to the current output stream.
|
||||
///
|
||||
void EmitJumpTableInfo(MachineJumpTableInfo *MJTI, MachineFunction &MF);
|
||||
void EmitJumpTableInfo();
|
||||
|
||||
/// EmitGlobalVariable - Emit the specified global variable to the .s file.
|
||||
virtual void EmitGlobalVariable(const GlobalVariable *GV);
|
||||
@ -265,9 +276,6 @@ namespace llvm {
|
||||
///
|
||||
void EmitInt64(uint64_t Value) const;
|
||||
|
||||
/// EmitFile - Emit a .file directive.
|
||||
void EmitFile(unsigned Number, StringRef Name) const;
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
|
||||
/// EmitAlignment - Emit an alignment directive to the specified power of
|
||||
@ -292,19 +300,15 @@ namespace llvm {
|
||||
|
||||
/// printLabel - This method prints a local label used by debug and
|
||||
/// exception handling tables.
|
||||
void printLabel(const MachineInstr *MI) const;
|
||||
void printLabel(unsigned Id) const;
|
||||
|
||||
/// printDeclare - This method prints a local variable declaration used by
|
||||
/// debug tables.
|
||||
void printDeclare(const MachineInstr *MI) const;
|
||||
|
||||
/// EmitComments - Pretty-print comments for instructions
|
||||
void EmitComments(const MachineInstr &MI) const;
|
||||
|
||||
/// GetGlobalValueSymbol - Return the MCSymbol for the specified global
|
||||
/// value.
|
||||
MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const;
|
||||
virtual MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const;
|
||||
|
||||
/// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with
|
||||
/// global value name as its base, with the specified suffix, and where the
|
||||
@ -317,23 +321,21 @@ namespace llvm {
|
||||
/// ExternalSymbol.
|
||||
MCSymbol *GetExternalSymbolSymbol(StringRef Sym) const;
|
||||
|
||||
/// GetMBBSymbol - Return the MCSymbol corresponding to the specified basic
|
||||
/// block label.
|
||||
MCSymbol *GetMBBSymbol(unsigned MBBID) const;
|
||||
|
||||
/// GetCPISymbol - Return the symbol for the specified constant pool entry.
|
||||
MCSymbol *GetCPISymbol(unsigned CPID) const;
|
||||
|
||||
/// GetJTISymbol - Return the symbol for the specified jump table entry.
|
||||
MCSymbol *GetJTISymbol(unsigned JTID, bool isLinkerPrivate = false) const;
|
||||
|
||||
/// GetJTSetSymbol - Return the symbol for the specified jump table .set
|
||||
/// FIXME: privatize to AsmPrinter.
|
||||
MCSymbol *GetJTSetSymbol(unsigned UID, unsigned MBBID) const;
|
||||
|
||||
/// GetBlockAddressSymbol - Return the MCSymbol used to satisfy BlockAddress
|
||||
/// uses of the specified basic block.
|
||||
MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA,
|
||||
const char *Suffix = "") const;
|
||||
MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const;
|
||||
MCSymbol *GetBlockAddressSymbol(const Function *F,
|
||||
const BasicBlock *BB,
|
||||
const char *Suffix = "") const;
|
||||
const BasicBlock *BB) const;
|
||||
|
||||
/// EmitBasicBlockStart - This method prints the label for the specified
|
||||
/// MachineBasicBlock, an alignment (if present) and a comment describing
|
||||
@ -347,12 +349,21 @@ namespace llvm {
|
||||
void EmitGlobalConstant(const Constant* CV, unsigned AddrSpace = 0);
|
||||
|
||||
protected:
|
||||
virtual void EmitFunctionEntryLabel();
|
||||
|
||||
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
|
||||
|
||||
/// printOffset - This is just convenient handler for printing offsets.
|
||||
void printOffset(int64_t Offset) const;
|
||||
|
||||
private:
|
||||
|
||||
/// processDebugLoc - Processes the debug information of each machine
|
||||
/// instruction's DebugLoc.
|
||||
void processDebugLoc(const MachineInstr *MI, bool BeforePrintingInsn);
|
||||
|
||||
void printLabelInst(const MachineInstr *MI) const;
|
||||
|
||||
/// printInlineAsm - This method formats and prints the specified machine
|
||||
/// instruction that is an inline asm.
|
||||
void printInlineAsm(const MachineInstr *MI) const;
|
||||
@ -364,24 +375,15 @@ namespace llvm {
|
||||
/// printKill - This method prints the specified kill machine instruction.
|
||||
void printKill(const MachineInstr *MI) const;
|
||||
|
||||
/// printPICJumpTableSetLabel - This method prints a set label for the
|
||||
/// specified MachineBasicBlock for a jumptable entry.
|
||||
virtual void printPICJumpTableSetLabel(unsigned uid,
|
||||
const MachineBasicBlock *MBB) const;
|
||||
virtual void printPICJumpTableSetLabel(unsigned uid, unsigned uid2,
|
||||
const MachineBasicBlock *MBB) const;
|
||||
virtual void printPICJumpTableEntry(const MachineJumpTableInfo *MJTI,
|
||||
const MachineBasicBlock *MBB,
|
||||
unsigned uid) const;
|
||||
|
||||
/// printVisibility - This prints visibility information about symbol, if
|
||||
/// EmitVisibility - This emits visibility information about symbol, if
|
||||
/// this is suported by the target.
|
||||
void printVisibility(MCSymbol *Sym, unsigned Visibility) const;
|
||||
void EmitVisibility(MCSymbol *Sym, unsigned Visibility) const;
|
||||
|
||||
/// printOffset - This is just convenient handler for printing offsets.
|
||||
void printOffset(int64_t Offset) const;
|
||||
|
||||
private:
|
||||
void EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const;
|
||||
|
||||
void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
|
||||
const MachineBasicBlock *MBB,
|
||||
unsigned uid) const;
|
||||
void EmitLLVMUsedList(Constant *List);
|
||||
void EmitXXStructorList(Constant *List);
|
||||
GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C);
|
||||
|
@ -132,4 +132,283 @@ void SelectRoot(SelectionDAG &DAG) {
|
||||
CurDAG->setRoot(Dummy.getValue());
|
||||
}
|
||||
|
||||
|
||||
/// CheckInteger - Return true if the specified node is not a ConstantSDNode or
|
||||
/// if it doesn't have the specified value.
|
||||
static bool CheckInteger(SDValue V, int64_t Val) {
|
||||
ConstantSDNode *C = dyn_cast<ConstantSDNode>(V);
|
||||
return C == 0 || C->getSExtValue() != Val;
|
||||
}
|
||||
|
||||
/// CheckAndImmediate - Check to see if the specified node is an and with an
|
||||
/// immediate returning true on failure.
|
||||
///
|
||||
/// FIXME: Inline this gunk into CheckAndMask.
|
||||
bool CheckAndImmediate(SDValue V, int64_t Val) {
|
||||
if (V->getOpcode() == ISD::AND)
|
||||
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(V->getOperand(1)))
|
||||
if (CheckAndMask(V.getOperand(0), C, Val))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// CheckOrImmediate - Check to see if the specified node is an or with an
|
||||
/// immediate returning true on failure.
|
||||
///
|
||||
/// FIXME: Inline this gunk into CheckOrMask.
|
||||
bool CheckOrImmediate(SDValue V, int64_t Val) {
|
||||
if (V->getOpcode() == ISD::OR)
|
||||
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(V->getOperand(1)))
|
||||
if (CheckOrMask(V.getOperand(0), C, Val))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// These functions are marked always inline so that Idx doesn't get pinned to
|
||||
// the stack.
|
||||
ALWAYS_INLINE static int8_t
|
||||
GetInt1(const unsigned char *MatcherTable, unsigned &Idx) {
|
||||
return MatcherTable[Idx++];
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static int16_t
|
||||
GetInt2(const unsigned char *MatcherTable, unsigned &Idx) {
|
||||
int16_t Val = GetInt1(MatcherTable, Idx);
|
||||
Val |= int16_t(GetInt1(MatcherTable, Idx)) << 8;
|
||||
return Val;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static int32_t
|
||||
GetInt4(const unsigned char *MatcherTable, unsigned &Idx) {
|
||||
int32_t Val = GetInt2(MatcherTable, Idx);
|
||||
Val |= int32_t(GetInt2(MatcherTable, Idx)) << 16;
|
||||
return Val;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static int64_t
|
||||
GetInt8(const unsigned char *MatcherTable, unsigned &Idx) {
|
||||
int64_t Val = GetInt4(MatcherTable, Idx);
|
||||
Val |= int64_t(GetInt4(MatcherTable, Idx)) << 32;
|
||||
return Val;
|
||||
}
|
||||
|
||||
enum BuiltinOpcodes {
|
||||
OPC_Emit,
|
||||
OPC_Push,
|
||||
OPC_Record,
|
||||
OPC_MoveChild,
|
||||
OPC_MoveParent,
|
||||
OPC_CheckSame,
|
||||
OPC_CheckPatternPredicate,
|
||||
OPC_CheckPredicate,
|
||||
OPC_CheckOpcode,
|
||||
OPC_CheckType,
|
||||
OPC_CheckInteger1, OPC_CheckInteger2, OPC_CheckInteger4, OPC_CheckInteger8,
|
||||
OPC_CheckCondCode,
|
||||
OPC_CheckValueType,
|
||||
OPC_CheckComplexPat,
|
||||
OPC_CheckAndImm1, OPC_CheckAndImm2, OPC_CheckAndImm4, OPC_CheckAndImm8,
|
||||
OPC_CheckOrImm1, OPC_CheckOrImm2, OPC_CheckOrImm4, OPC_CheckOrImm8,
|
||||
OPC_IsProfitableToFold,
|
||||
OPC_IsLegalToFold
|
||||
};
|
||||
|
||||
struct MatchScope {
|
||||
/// FailIndex - If this match fails, this is the index to continue with.
|
||||
unsigned FailIndex;
|
||||
|
||||
/// NodeStackSize - The size of the node stack when the scope was formed.
|
||||
unsigned NodeStackSize;
|
||||
|
||||
/// NumRecordedNodes - The number of recorded nodes when the scope was formed.
|
||||
unsigned NumRecordedNodes;
|
||||
};
|
||||
|
||||
SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
|
||||
unsigned TableSize) {
|
||||
switch (NodeToMatch->getOpcode()) {
|
||||
default:
|
||||
break;
|
||||
case ISD::EntryToken: // These nodes remain the same.
|
||||
case ISD::BasicBlock:
|
||||
case ISD::Register:
|
||||
case ISD::HANDLENODE:
|
||||
case ISD::TargetConstant:
|
||||
case ISD::TargetConstantFP:
|
||||
case ISD::TargetConstantPool:
|
||||
case ISD::TargetFrameIndex:
|
||||
case ISD::TargetExternalSymbol:
|
||||
case ISD::TargetBlockAddress:
|
||||
case ISD::TargetJumpTable:
|
||||
case ISD::TargetGlobalTLSAddress:
|
||||
case ISD::TargetGlobalAddress:
|
||||
case ISD::TokenFactor:
|
||||
case ISD::CopyFromReg:
|
||||
case ISD::CopyToReg:
|
||||
return 0;
|
||||
case ISD::AssertSext:
|
||||
case ISD::AssertZext:
|
||||
ReplaceUses(SDValue(NodeToMatch, 0), NodeToMatch->getOperand(0));
|
||||
return 0;
|
||||
case ISD::INLINEASM: return Select_INLINEASM(NodeToMatch);
|
||||
case ISD::EH_LABEL: return Select_EH_LABEL(NodeToMatch);
|
||||
case ISD::UNDEF: return Select_UNDEF(NodeToMatch);
|
||||
}
|
||||
|
||||
assert(!NodeToMatch->isMachineOpcode() && "Node already selected!");
|
||||
|
||||
SmallVector<MatchScope, 8> MatchScopes;
|
||||
|
||||
// RecordedNodes - This is the set of nodes that have been recorded by the
|
||||
// state machine.
|
||||
SmallVector<SDValue, 8> RecordedNodes;
|
||||
|
||||
// Set up the node stack with NodeToMatch as the only node on the stack.
|
||||
SmallVector<SDValue, 8> NodeStack;
|
||||
SDValue N = SDValue(NodeToMatch, 0);
|
||||
NodeStack.push_back(N);
|
||||
|
||||
// Interpreter starts at opcode #0.
|
||||
unsigned MatcherIndex = 0;
|
||||
while (1) {
|
||||
assert(MatcherIndex < TableSize && "Invalid index");
|
||||
switch ((BuiltinOpcodes)MatcherTable[MatcherIndex++]) {
|
||||
case OPC_Emit: {
|
||||
errs() << "EMIT NODE\n";
|
||||
return 0;
|
||||
}
|
||||
case OPC_Push: {
|
||||
unsigned NumToSkip = MatcherTable[MatcherIndex++];
|
||||
MatchScope NewEntry;
|
||||
NewEntry.FailIndex = MatcherIndex+NumToSkip;
|
||||
NewEntry.NodeStackSize = NodeStack.size();
|
||||
NewEntry.NumRecordedNodes = RecordedNodes.size();
|
||||
MatchScopes.push_back(NewEntry);
|
||||
continue;
|
||||
}
|
||||
case OPC_Record:
|
||||
// Remember this node, it may end up being an operand in the pattern.
|
||||
RecordedNodes.push_back(N);
|
||||
continue;
|
||||
|
||||
case OPC_MoveChild: {
|
||||
unsigned Child = MatcherTable[MatcherIndex++];
|
||||
if (Child >= N.getNumOperands())
|
||||
break; // Match fails if out of range child #.
|
||||
N = N.getOperand(Child);
|
||||
NodeStack.push_back(N);
|
||||
continue;
|
||||
}
|
||||
|
||||
case OPC_MoveParent:
|
||||
// Pop the current node off the NodeStack.
|
||||
NodeStack.pop_back();
|
||||
assert(!NodeStack.empty() && "Node stack imbalance!");
|
||||
N = NodeStack.back();
|
||||
continue;
|
||||
|
||||
case OPC_CheckSame: {
|
||||
// Accept if it is exactly the same as a previously recorded node.
|
||||
unsigned RecNo = MatcherTable[MatcherIndex++];
|
||||
assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
|
||||
if (N != RecordedNodes[RecNo]) break;
|
||||
continue;
|
||||
}
|
||||
case OPC_CheckPatternPredicate:
|
||||
if (!CheckPatternPredicate(MatcherTable[MatcherIndex++])) break;
|
||||
continue;
|
||||
case OPC_CheckPredicate:
|
||||
if (!CheckNodePredicate(N.getNode(), MatcherTable[MatcherIndex++])) break;
|
||||
continue;
|
||||
case OPC_CheckComplexPat: {
|
||||
unsigned PatNo = MatcherTable[MatcherIndex++];
|
||||
(void)PatNo;
|
||||
// FIXME: CHECK IT.
|
||||
continue;
|
||||
}
|
||||
|
||||
case OPC_CheckOpcode:
|
||||
if (N->getOpcode() != MatcherTable[MatcherIndex++]) break;
|
||||
continue;
|
||||
case OPC_CheckType:
|
||||
if (N.getValueType() !=
|
||||
(MVT::SimpleValueType)MatcherTable[MatcherIndex++]) break;
|
||||
continue;
|
||||
case OPC_CheckCondCode:
|
||||
if (cast<CondCodeSDNode>(N)->get() !=
|
||||
(ISD::CondCode)MatcherTable[MatcherIndex++]) break;
|
||||
continue;
|
||||
case OPC_CheckValueType:
|
||||
if (cast<VTSDNode>(N)->getVT() !=
|
||||
(MVT::SimpleValueType)MatcherTable[MatcherIndex++]) break;
|
||||
continue;
|
||||
|
||||
case OPC_CheckInteger1:
|
||||
if (CheckInteger(N, GetInt1(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckInteger2:
|
||||
if (CheckInteger(N, GetInt2(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckInteger4:
|
||||
if (CheckInteger(N, GetInt4(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckInteger8:
|
||||
if (CheckInteger(N, GetInt8(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
|
||||
case OPC_CheckAndImm1:
|
||||
if (CheckAndImmediate(N, GetInt1(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckAndImm2:
|
||||
if (CheckAndImmediate(N, GetInt2(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckAndImm4:
|
||||
if (CheckAndImmediate(N, GetInt4(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckAndImm8:
|
||||
if (CheckAndImmediate(N, GetInt8(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
|
||||
case OPC_CheckOrImm1:
|
||||
if (CheckOrImmediate(N, GetInt1(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckOrImm2:
|
||||
if (CheckOrImmediate(N, GetInt2(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckOrImm4:
|
||||
if (CheckOrImmediate(N, GetInt4(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckOrImm8:
|
||||
if (CheckOrImmediate(N, GetInt8(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
|
||||
case OPC_IsProfitableToFold:
|
||||
assert(!NodeStack.size() == 1 && "No parent node");
|
||||
if (!IsProfitableToFold(N, NodeStack[NodeStack.size()-2].getNode(),
|
||||
NodeToMatch))
|
||||
break;
|
||||
continue;
|
||||
case OPC_IsLegalToFold:
|
||||
assert(!NodeStack.size() == 1 && "No parent node");
|
||||
if (!IsLegalToFold(N, NodeStack[NodeStack.size()-2].getNode(),
|
||||
NodeToMatch))
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the code reached this point, then the match failed pop out to the next
|
||||
// match scope.
|
||||
if (MatchScopes.empty()) {
|
||||
CannotYetSelect(NodeToMatch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RecordedNodes.resize(MatchScopes.back().NumRecordedNodes);
|
||||
NodeStack.resize(MatchScopes.back().NodeStackSize);
|
||||
MatcherIndex = MatchScopes.back().FailIndex;
|
||||
MatchScopes.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* LLVM_CODEGEN_DAGISEL_HEADER_H */
|
||||
|
@ -76,11 +76,11 @@ class DwarfWriter : public ImmutablePass {
|
||||
|
||||
/// BeginFunction - Gather pre-function debug information. Assumes being
|
||||
/// emitted immediately after the function entry point.
|
||||
void BeginFunction(MachineFunction *MF);
|
||||
void BeginFunction(const MachineFunction *MF);
|
||||
|
||||
/// EndFunction - Gather and emit post-function debug information.
|
||||
///
|
||||
void EndFunction(MachineFunction *MF);
|
||||
void EndFunction(const MachineFunction *MF);
|
||||
|
||||
/// RecordSourceLine - Register a source line with debug info. Returns a
|
||||
/// unique label ID used to generate a label and provide correspondence to
|
||||
|
@ -1,37 +0,0 @@
|
||||
//===-- FileWriters.h - File Writers Creation Functions ---------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Functions to add the various file writer passes.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CODEGEN_FILEWRITERS_H
|
||||
#define LLVM_CODEGEN_FILEWRITERS_H
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class PassManagerBase;
|
||||
class ObjectCodeEmitter;
|
||||
class TargetMachine;
|
||||
class raw_ostream;
|
||||
class formatted_raw_ostream;
|
||||
class MachineFunctionPass;
|
||||
class MCAsmInfo;
|
||||
class MCCodeEmitter;
|
||||
|
||||
ObjectCodeEmitter *AddELFWriter(PassManagerBase &FPM, raw_ostream &O,
|
||||
TargetMachine &TM);
|
||||
MachineFunctionPass *createMachOWriter(formatted_raw_ostream &O,
|
||||
TargetMachine &TM,
|
||||
const MCAsmInfo *T,
|
||||
MCCodeEmitter *MCE);
|
||||
|
||||
} // end llvm namespace
|
||||
|
||||
#endif // LLVM_CODEGEN_FILEWRITERS_H
|
@ -146,7 +146,7 @@ class JITCodeEmitter : public MachineCodeEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
/// emitAlignment - Move the CurBufferPtr pointer up the the specified
|
||||
/// emitAlignment - Move the CurBufferPtr pointer up to the specified
|
||||
/// alignment (saturated to BufferEnd of course).
|
||||
void emitAlignment(unsigned Alignment) {
|
||||
if (Alignment == 0) Alignment = 1;
|
||||
|
@ -320,7 +320,7 @@ namespace llvm {
|
||||
/// advanceTo - Advance the specified iterator to point to the LiveRange
|
||||
/// containing the specified position, or end() if the position is past the
|
||||
/// end of the interval. If no LiveRange contains this position, but the
|
||||
/// position is in a hole, this method returns an iterator pointing the the
|
||||
/// position is in a hole, this method returns an iterator pointing to the
|
||||
/// LiveRange immediately after the hole.
|
||||
iterator advanceTo(iterator I, SlotIndex Pos) {
|
||||
if (Pos >= endIndex())
|
||||
|
@ -21,6 +21,9 @@ namespace llvm {
|
||||
|
||||
class BasicBlock;
|
||||
class MachineFunction;
|
||||
class MCContext;
|
||||
class MCSymbol;
|
||||
class StringRef;
|
||||
class raw_ostream;
|
||||
|
||||
template <>
|
||||
@ -338,7 +341,7 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
|
||||
bool isCond);
|
||||
|
||||
/// findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping
|
||||
/// any DEBUG_VALUE instructions. Return UnknownLoc if there is none.
|
||||
/// any DBG_VALUE instructions. Return UnknownLoc if there is none.
|
||||
DebugLoc findDebugLoc(MachineBasicBlock::iterator &MBBI);
|
||||
|
||||
// Debugging methods.
|
||||
@ -352,6 +355,10 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
|
||||
int getNumber() const { return Number; }
|
||||
void setNumber(int N) { Number = N; }
|
||||
|
||||
/// getSymbol - Return the MCSymbol for this basic block.
|
||||
///
|
||||
MCSymbol *getSymbol(MCContext &Ctx) const;
|
||||
|
||||
private: // Methods used to maintain doubly linked list of blocks...
|
||||
friend struct ilist_traits<MachineBasicBlock>;
|
||||
|
||||
|
@ -155,7 +155,7 @@ class MachineCodeEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
/// emitAlignment - Move the CurBufferPtr pointer up the the specified
|
||||
/// emitAlignment - Move the CurBufferPtr pointer up to the specified
|
||||
/// alignment (saturated to BufferEnd of course).
|
||||
void emitAlignment(unsigned Alignment) {
|
||||
if (Alignment == 0) Alignment = 1;
|
||||
|
@ -136,7 +136,7 @@ class MachineConstantPool {
|
||||
: TD(td), PoolAlignment(1) {}
|
||||
~MachineConstantPool();
|
||||
|
||||
/// getConstantPoolAlignment - Return the the alignment required by
|
||||
/// getConstantPoolAlignment - Return the alignment required by
|
||||
/// the whole constant pool, of which the first element must be aligned.
|
||||
unsigned getConstantPoolAlignment() const { return PoolAlignment; }
|
||||
|
||||
|
@ -276,6 +276,7 @@ class MachineFrameInfo {
|
||||
assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
|
||||
"Invalid Object Idx!");
|
||||
Objects[ObjectIdx+NumFixedObjects].Alignment = Align;
|
||||
MaxAlignment = std::max(MaxAlignment, Align);
|
||||
}
|
||||
|
||||
/// getObjectOffset - Return the assigned stack offset of the specified object
|
||||
@ -328,19 +329,6 @@ class MachineFrameInfo {
|
||||
///
|
||||
void setMaxAlignment(unsigned Align) { MaxAlignment = Align; }
|
||||
|
||||
/// calculateMaxStackAlignment() - If there is a local object which requires
|
||||
/// greater alignment than the current max alignment, adjust accordingly.
|
||||
void calculateMaxStackAlignment() {
|
||||
for (int i = getObjectIndexBegin(),
|
||||
e = getObjectIndexEnd(); i != e; ++i) {
|
||||
if (isDeadObjectIndex(i))
|
||||
continue;
|
||||
|
||||
unsigned Align = getObjectAlignment(i);
|
||||
MaxAlignment = std::max(MaxAlignment, Align);
|
||||
}
|
||||
}
|
||||
|
||||
/// hasCalls - Return true if the current function has no function calls.
|
||||
/// This is only valid during or after prolog/epilog code emission.
|
||||
///
|
||||
@ -402,6 +390,7 @@ class MachineFrameInfo {
|
||||
Objects.push_back(StackObject(Size, Alignment, 0, false, isSS));
|
||||
int Index = (int)Objects.size()-NumFixedObjects-1;
|
||||
assert(Index >= 0 && "Bad frame index!");
|
||||
MaxAlignment = std::max(MaxAlignment, Alignment);
|
||||
return Index;
|
||||
}
|
||||
|
||||
@ -412,6 +401,7 @@ class MachineFrameInfo {
|
||||
int CreateSpillStackObject(uint64_t Size, unsigned Alignment) {
|
||||
CreateStackObject(Size, Alignment, true);
|
||||
int Index = (int)Objects.size()-NumFixedObjects-1;
|
||||
MaxAlignment = std::max(MaxAlignment, Alignment);
|
||||
return Index;
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ class MachineRegisterInfo;
|
||||
class MachineFrameInfo;
|
||||
class MachineConstantPool;
|
||||
class MachineJumpTableInfo;
|
||||
class Pass;
|
||||
class TargetMachine;
|
||||
class TargetRegisterClass;
|
||||
|
||||
@ -112,6 +113,11 @@ class MachineFunction {
|
||||
// Tracks debug locations.
|
||||
DebugLocTracker DebugLocInfo;
|
||||
|
||||
/// FunctionNumber - This provides a unique ID for each function emitted in
|
||||
/// this translation unit.
|
||||
///
|
||||
unsigned FunctionNumber;
|
||||
|
||||
// The alignment of the function.
|
||||
unsigned Alignment;
|
||||
|
||||
@ -119,13 +125,17 @@ class MachineFunction {
|
||||
void operator=(const MachineFunction&); // intentionally unimplemented
|
||||
|
||||
public:
|
||||
MachineFunction(Function *Fn, const TargetMachine &TM);
|
||||
MachineFunction(Function *Fn, const TargetMachine &TM, unsigned FunctionNum);
|
||||
~MachineFunction();
|
||||
|
||||
/// getFunction - Return the LLVM function that this machine code represents
|
||||
///
|
||||
Function *getFunction() const { return Fn; }
|
||||
|
||||
/// getFunctionNumber - Return a unique ID for the current function.
|
||||
///
|
||||
unsigned getFunctionNumber() const { return FunctionNumber; }
|
||||
|
||||
/// getTarget - Return the target machine this machine code is compiled with
|
||||
///
|
||||
const TargetMachine &getTarget() const { return Target; }
|
||||
@ -143,11 +153,16 @@ class MachineFunction {
|
||||
const MachineFrameInfo *getFrameInfo() const { return FrameInfo; }
|
||||
|
||||
/// getJumpTableInfo - Return the jump table info object for the current
|
||||
/// function. This object contains information about jump tables for switch
|
||||
/// instructions in the current function.
|
||||
///
|
||||
MachineJumpTableInfo *getJumpTableInfo() { return JumpTableInfo; }
|
||||
/// function. This object contains information about jump tables in the
|
||||
/// current function. If the current function has no jump tables, this will
|
||||
/// return null.
|
||||
const MachineJumpTableInfo *getJumpTableInfo() const { return JumpTableInfo; }
|
||||
MachineJumpTableInfo *getJumpTableInfo() { return JumpTableInfo; }
|
||||
|
||||
/// getOrCreateJumpTableInfo - Get the JumpTableInfo for this function, if it
|
||||
/// does already exist, allocate one.
|
||||
MachineJumpTableInfo *getOrCreateJumpTableInfo(unsigned JTEntryKind);
|
||||
|
||||
|
||||
/// getConstantPool - Return the constant pool object for the current
|
||||
/// function.
|
||||
@ -163,6 +178,11 @@ class MachineFunction {
|
||||
///
|
||||
void setAlignment(unsigned A) { Alignment = A; }
|
||||
|
||||
/// EnsureAlignment - Make sure the function is at least 'A' bits aligned.
|
||||
void EnsureAlignment(unsigned A) {
|
||||
if (Alignment < A) Alignment = A;
|
||||
}
|
||||
|
||||
/// getInfo - Keep track of various per-function pieces of information for
|
||||
/// backends that would like to do so.
|
||||
///
|
||||
@ -310,7 +330,7 @@ class MachineFunction {
|
||||
bool NoImp = false);
|
||||
|
||||
/// CloneMachineInstr - Create a new MachineInstr which is a copy of the
|
||||
/// 'Orig' instruction, identical in all ways except the the instruction
|
||||
/// 'Orig' instruction, identical in all ways except the instruction
|
||||
/// has no parent, prev, or next.
|
||||
///
|
||||
/// See also TargetInstrInfo::duplicate() for target-specific fixes to cloned
|
||||
@ -362,6 +382,17 @@ class MachineFunction {
|
||||
extractStoreMemRefs(MachineInstr::mmo_iterator Begin,
|
||||
MachineInstr::mmo_iterator End);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Label Manipulation.
|
||||
//
|
||||
|
||||
/// getJTISymbol - Return the MCSymbol for the specified non-empty jump table.
|
||||
/// If isLinkerPrivate is specified, an 'l' label is returned, otherwise a
|
||||
/// normal 'L' label is returned.
|
||||
MCSymbol *getJTISymbol(unsigned JTI, MCContext &Ctx,
|
||||
bool isLinkerPrivate = false) const;
|
||||
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Debug location.
|
||||
//
|
||||
|
@ -28,7 +28,7 @@ struct MachineFunctionAnalysis : public FunctionPass {
|
||||
const TargetMachine &TM;
|
||||
CodeGenOpt::Level OptLevel;
|
||||
MachineFunction *MF;
|
||||
|
||||
unsigned NextFnNum;
|
||||
public:
|
||||
static char ID;
|
||||
explicit MachineFunctionAnalysis(const TargetMachine &tm,
|
||||
@ -39,6 +39,7 @@ struct MachineFunctionAnalysis : public FunctionPass {
|
||||
CodeGenOpt::Level getOptLevel() const { return OptLevel; }
|
||||
|
||||
private:
|
||||
virtual bool doInitialization(Module &) { NextFnNum = 1; return false; }
|
||||
virtual bool runOnFunction(Function &F);
|
||||
virtual void releaseMemory();
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
|
@ -19,9 +19,9 @@
|
||||
#include "llvm/ADT/ilist.h"
|
||||
#include "llvm/ADT/ilist_node.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/Target/TargetInstrDesc.h"
|
||||
#include "llvm/Target/TargetOpcodes.h"
|
||||
#include "llvm/Support/DebugLoc.h"
|
||||
#include <vector>
|
||||
|
||||
@ -41,6 +41,14 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
public:
|
||||
typedef MachineMemOperand **mmo_iterator;
|
||||
|
||||
/// Flags to specify different kinds of comments to output in
|
||||
/// assembly code. These flags carry semantic information not
|
||||
/// otherwise easily derivable from the IR text.
|
||||
///
|
||||
enum CommentFlag {
|
||||
ReloadReuse = 0x1
|
||||
};
|
||||
|
||||
private:
|
||||
const TargetInstrDesc *TID; // Instruction descriptor.
|
||||
unsigned short NumImplicitOps; // Number of implicit operands (which
|
||||
@ -121,14 +129,14 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
|
||||
/// getAsmPrinterFlag - Return whether an AsmPrinter flag is set.
|
||||
///
|
||||
bool getAsmPrinterFlag(AsmPrinter::CommentFlag Flag) const {
|
||||
bool getAsmPrinterFlag(CommentFlag Flag) const {
|
||||
return AsmPrinterFlags & Flag;
|
||||
}
|
||||
|
||||
/// setAsmPrinterFlag - Set a flag for the AsmPrinter.
|
||||
///
|
||||
void setAsmPrinterFlag(unsigned short Flag) {
|
||||
AsmPrinterFlags |= Flag;
|
||||
void setAsmPrinterFlag(CommentFlag Flag) {
|
||||
AsmPrinterFlags |= (unsigned short)Flag;
|
||||
}
|
||||
|
||||
/// getDebugLoc - Returns the debug location id of this MachineInstr.
|
||||
@ -193,12 +201,31 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
|
||||
/// isLabel - Returns true if the MachineInstr represents a label.
|
||||
///
|
||||
bool isLabel() const;
|
||||
|
||||
/// isDebugLabel - Returns true if the MachineInstr represents a debug label.
|
||||
///
|
||||
bool isDebugLabel() const;
|
||||
|
||||
bool isLabel() const {
|
||||
return getOpcode() == TargetOpcode::DBG_LABEL ||
|
||||
getOpcode() == TargetOpcode::EH_LABEL ||
|
||||
getOpcode() == TargetOpcode::GC_LABEL;
|
||||
}
|
||||
|
||||
bool isDebugLabel() const { return getOpcode() == TargetOpcode::DBG_LABEL; }
|
||||
bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; }
|
||||
bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; }
|
||||
bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; }
|
||||
|
||||
bool isPHI() const { return getOpcode() == TargetOpcode::PHI; }
|
||||
bool isKill() const { return getOpcode() == TargetOpcode::KILL; }
|
||||
bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; }
|
||||
bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; }
|
||||
bool isExtractSubreg() const {
|
||||
return getOpcode() == TargetOpcode::EXTRACT_SUBREG;
|
||||
}
|
||||
bool isInsertSubreg() const {
|
||||
return getOpcode() == TargetOpcode::INSERT_SUBREG;
|
||||
}
|
||||
bool isSubregToReg() const {
|
||||
return getOpcode() == TargetOpcode::SUBREG_TO_REG;
|
||||
}
|
||||
|
||||
/// readsRegister - Return true if the MachineInstr reads the specified
|
||||
/// register. If TargetRegisterInfo is passed, then it also checks if there
|
||||
/// is a read of a super-register.
|
||||
@ -320,7 +347,7 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
|
||||
/// isInvariantLoad - Return true if this instruction is loading from a
|
||||
/// location whose value is invariant across the function. For example,
|
||||
/// loading a value from the constant pool or from from the argument area of
|
||||
/// loading a value from the constant pool or from the argument area of
|
||||
/// a function if it does not change. This should only return true of *all*
|
||||
/// loads the instruction does are invariant (if it does multiple loads).
|
||||
bool isInvariantLoad(AliasAnalysis *AA) const;
|
||||
|
@ -32,6 +32,7 @@ namespace RegState {
|
||||
Dead = 0x10,
|
||||
Undef = 0x20,
|
||||
EarlyClobber = 0x40,
|
||||
Debug = 0x80,
|
||||
ImplicitDefine = Implicit | Define,
|
||||
ImplicitKill = Implicit | Kill
|
||||
};
|
||||
@ -62,7 +63,8 @@ class MachineInstrBuilder {
|
||||
flags & RegState::Dead,
|
||||
flags & RegState::Undef,
|
||||
flags & RegState::EarlyClobber,
|
||||
SubReg));
|
||||
SubReg,
|
||||
flags & RegState::Debug));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -40,13 +40,45 @@ struct MachineJumpTableEntry {
|
||||
};
|
||||
|
||||
class MachineJumpTableInfo {
|
||||
unsigned EntrySize;
|
||||
unsigned Alignment;
|
||||
public:
|
||||
/// JTEntryKind - This enum indicates how each entry of the jump table is
|
||||
/// represented and emitted.
|
||||
enum JTEntryKind {
|
||||
/// EK_BlockAddress - Each entry is a plain address of block, e.g.:
|
||||
/// .word LBB123
|
||||
EK_BlockAddress,
|
||||
|
||||
/// EK_GPRel32BlockAddress - Each entry is an address of block, encoded
|
||||
/// with a relocation as gp-relative, e.g.:
|
||||
/// .gprel32 LBB123
|
||||
EK_GPRel32BlockAddress,
|
||||
|
||||
/// EK_LabelDifference32 - Each entry is the address of the block minus
|
||||
/// the address of the jump table. This is used for PIC jump tables where
|
||||
/// gprel32 is not supported. e.g.:
|
||||
/// .word LBB123 - LJTI1_2
|
||||
/// If the .set directive is supported, this is emitted as:
|
||||
/// .set L4_5_set_123, LBB123 - LJTI1_2
|
||||
/// .word L4_5_set_123
|
||||
EK_LabelDifference32,
|
||||
|
||||
/// EK_Custom32 - Each entry is a 32-bit value that is custom lowered by the
|
||||
/// TargetLowering::LowerCustomJumpTableEntry hook.
|
||||
EK_Custom32
|
||||
};
|
||||
private:
|
||||
JTEntryKind EntryKind;
|
||||
std::vector<MachineJumpTableEntry> JumpTables;
|
||||
public:
|
||||
MachineJumpTableInfo(unsigned Size, unsigned Align)
|
||||
: EntrySize(Size), Alignment(Align) {}
|
||||
MachineJumpTableInfo(JTEntryKind Kind): EntryKind(Kind) {}
|
||||
|
||||
JTEntryKind getEntryKind() const { return EntryKind; }
|
||||
|
||||
/// getEntrySize - Return the size of each entry in the jump table.
|
||||
unsigned getEntrySize(const TargetData &TD) const;
|
||||
/// getEntryAlignment - Return the alignment of each entry in the jump table.
|
||||
unsigned getEntryAlignment(const TargetData &TD) const;
|
||||
|
||||
/// getJumpTableIndex - Create a new jump table or return an existing one.
|
||||
///
|
||||
unsigned getJumpTableIndex(const std::vector<MachineBasicBlock*> &DestBBs);
|
||||
@ -58,9 +90,9 @@ class MachineJumpTableInfo {
|
||||
const std::vector<MachineJumpTableEntry> &getJumpTables() const {
|
||||
return JumpTables;
|
||||
}
|
||||
|
||||
/// RemoveJumpTable - Mark the specific index as being dead. This will cause
|
||||
/// it to not be emitted.
|
||||
|
||||
/// RemoveJumpTable - Mark the specific index as being dead. This will
|
||||
/// prevent it from being emitted.
|
||||
void RemoveJumpTable(unsigned Idx) {
|
||||
JumpTables[Idx].MBBs.clear();
|
||||
}
|
||||
@ -74,13 +106,6 @@ class MachineJumpTableInfo {
|
||||
bool ReplaceMBBInJumpTable(unsigned Idx, MachineBasicBlock *Old,
|
||||
MachineBasicBlock *New);
|
||||
|
||||
/// getEntrySize - Returns the size of an individual field in a jump table.
|
||||
///
|
||||
unsigned getEntrySize() const { return EntrySize; }
|
||||
|
||||
/// getAlignment - returns the target's preferred alignment for jump tables
|
||||
unsigned getAlignment() const { return Alignment; }
|
||||
|
||||
/// print - Used by the MachineFunction printer to print information about
|
||||
/// jump tables. Implemented in MachineFunction.cpp
|
||||
///
|
||||
|
@ -46,7 +46,11 @@ class MachineMemOperand {
|
||||
/// The memory access writes data.
|
||||
MOStore = 2,
|
||||
/// The memory access is volatile.
|
||||
MOVolatile = 4
|
||||
MOVolatile = 4,
|
||||
/// The memory access is non-temporal.
|
||||
MONonTemporal = 8,
|
||||
// This is the number of bits we need to represent flags.
|
||||
MOMaxBits = 4
|
||||
};
|
||||
|
||||
/// MachineMemOperand - Construct an MachineMemOperand object with the
|
||||
@ -64,7 +68,7 @@ class MachineMemOperand {
|
||||
const Value *getValue() const { return V; }
|
||||
|
||||
/// getFlags - Return the raw flags of the source value, \see MemOperandFlags.
|
||||
unsigned int getFlags() const { return Flags & 7; }
|
||||
unsigned int getFlags() const { return Flags & ((1 << MOMaxBits) - 1); }
|
||||
|
||||
/// getOffset - For normal values, this is a byte offset added to the base
|
||||
/// address. For PseudoSourceValue::FPRel values, this is the FrameIndex
|
||||
@ -80,11 +84,12 @@ class MachineMemOperand {
|
||||
|
||||
/// getBaseAlignment - Return the minimum known alignment in bytes of the
|
||||
/// base address, without the offset.
|
||||
uint64_t getBaseAlignment() const { return (1u << (Flags >> 3)) >> 1; }
|
||||
uint64_t getBaseAlignment() const { return (1u << (Flags >> MOMaxBits)) >> 1; }
|
||||
|
||||
bool isLoad() const { return Flags & MOLoad; }
|
||||
bool isStore() const { return Flags & MOStore; }
|
||||
bool isVolatile() const { return Flags & MOVolatile; }
|
||||
bool isNonTemporal() const { return Flags & MONonTemporal; }
|
||||
|
||||
/// refineAlignment - Update this MachineMemOperand to reflect the alignment
|
||||
/// of MMO, if it has a greater alignment. This must only be used when the
|
||||
|
@ -50,6 +50,7 @@ namespace llvm {
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Forward declarations.
|
||||
class Constant;
|
||||
class MCSymbol;
|
||||
class MDNode;
|
||||
class GlobalVariable;
|
||||
class MachineBasicBlock;
|
||||
@ -66,6 +67,12 @@ class StructType;
|
||||
class MachineModuleInfoImpl {
|
||||
public:
|
||||
virtual ~MachineModuleInfoImpl();
|
||||
|
||||
typedef std::vector<std::pair<MCSymbol*, MCSymbol*> >
|
||||
SymbolListTy;
|
||||
protected:
|
||||
static SymbolListTy
|
||||
GetSortedStubs(const DenseMap<MCSymbol*, MCSymbol*> &Map);
|
||||
};
|
||||
|
||||
|
||||
@ -113,7 +120,14 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
// LandingPads - List of LandingPadInfo describing the landing pad information
|
||||
// in the current function.
|
||||
std::vector<LandingPadInfo> LandingPads;
|
||||
|
||||
|
||||
// Map of invoke call site index values to associated begin EH_LABEL for
|
||||
// the current function.
|
||||
DenseMap<unsigned, unsigned> CallSiteMap;
|
||||
|
||||
// The current call site index being processed, if any. 0 if none.
|
||||
unsigned CurCallSite;
|
||||
|
||||
// TypeInfos - List of C++ TypeInfo used in the current function.
|
||||
//
|
||||
std::vector<GlobalVariable *> TypeInfos;
|
||||
@ -157,10 +171,6 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
bool doInitialization();
|
||||
bool doFinalization();
|
||||
|
||||
/// BeginFunction - Begin gathering function meta information.
|
||||
///
|
||||
void BeginFunction(MachineFunction *) {}
|
||||
|
||||
/// EndFunction - Discard function meta information.
|
||||
///
|
||||
void EndFunction();
|
||||
@ -298,7 +308,26 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
const std::vector<LandingPadInfo> &getLandingPads() const {
|
||||
return LandingPads;
|
||||
}
|
||||
|
||||
|
||||
/// setCallSiteBeginLabel - Map the begin label for a call site
|
||||
void setCallSiteBeginLabel(unsigned BeginLabel, unsigned Site) {
|
||||
CallSiteMap[BeginLabel] = Site;
|
||||
}
|
||||
|
||||
/// getCallSiteBeginLabel - Get the call site number for a begin label
|
||||
unsigned getCallSiteBeginLabel(unsigned BeginLabel) {
|
||||
assert(CallSiteMap.count(BeginLabel) &&
|
||||
"Missing call site number for EH_LABEL!");
|
||||
return CallSiteMap[BeginLabel];
|
||||
}
|
||||
|
||||
/// setCurrentCallSite - Set the call site currently being processed.
|
||||
void setCurrentCallSite(unsigned Site) { CurCallSite = Site; }
|
||||
|
||||
/// getCurrentCallSite - Get the call site currently being processed, if any.
|
||||
/// return zero if none.
|
||||
unsigned getCurrentCallSite(void) { return CurCallSite; }
|
||||
|
||||
/// getTypeInfos - Return a reference to the C++ typeinfo for the current
|
||||
/// function.
|
||||
const std::vector<GlobalVariable *> &getTypeInfos() const {
|
||||
|
@ -19,46 +19,43 @@
|
||||
|
||||
namespace llvm {
|
||||
class MCSymbol;
|
||||
|
||||
|
||||
/// MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation
|
||||
/// for MachO targets.
|
||||
class MachineModuleInfoMachO : public MachineModuleInfoImpl {
|
||||
/// FnStubs - Darwin '$stub' stubs. The key is something like "Lfoo$stub",
|
||||
/// the value is something like "_foo".
|
||||
DenseMap<const MCSymbol*, const MCSymbol*> FnStubs;
|
||||
DenseMap<MCSymbol*, MCSymbol*> FnStubs;
|
||||
|
||||
/// GVStubs - Darwin '$non_lazy_ptr' stubs. The key is something like
|
||||
/// "Lfoo$non_lazy_ptr", the value is something like "_foo".
|
||||
DenseMap<const MCSymbol*, const MCSymbol*> GVStubs;
|
||||
DenseMap<MCSymbol*, MCSymbol*> GVStubs;
|
||||
|
||||
/// HiddenGVStubs - Darwin '$non_lazy_ptr' stubs. The key is something like
|
||||
/// "Lfoo$non_lazy_ptr", the value is something like "_foo". Unlike GVStubs
|
||||
/// these are for things with hidden visibility.
|
||||
DenseMap<const MCSymbol*, const MCSymbol*> HiddenGVStubs;
|
||||
DenseMap<MCSymbol*, MCSymbol*> HiddenGVStubs;
|
||||
|
||||
virtual void Anchor(); // Out of line virtual method.
|
||||
public:
|
||||
MachineModuleInfoMachO(const MachineModuleInfo &) {}
|
||||
|
||||
const MCSymbol *&getFnStubEntry(const MCSymbol *Sym) {
|
||||
MCSymbol *&getFnStubEntry(MCSymbol *Sym) {
|
||||
assert(Sym && "Key cannot be null");
|
||||
return FnStubs[Sym];
|
||||
}
|
||||
|
||||
const MCSymbol *&getGVStubEntry(const MCSymbol *Sym) {
|
||||
MCSymbol *&getGVStubEntry(MCSymbol *Sym) {
|
||||
assert(Sym && "Key cannot be null");
|
||||
return GVStubs[Sym];
|
||||
}
|
||||
|
||||
const MCSymbol *&getHiddenGVStubEntry(const MCSymbol *Sym) {
|
||||
MCSymbol *&getHiddenGVStubEntry(MCSymbol *Sym) {
|
||||
assert(Sym && "Key cannot be null");
|
||||
return HiddenGVStubs[Sym];
|
||||
}
|
||||
|
||||
|
||||
/// Accessor methods to return the set of stubs in sorted order.
|
||||
typedef std::vector<std::pair<const MCSymbol*, const MCSymbol*> >
|
||||
SymbolListTy;
|
||||
|
||||
SymbolListTy GetFnStubList() const {
|
||||
return GetSortedStubs(FnStubs);
|
||||
}
|
||||
@ -68,12 +65,31 @@ namespace llvm {
|
||||
SymbolListTy GetHiddenGVStubList() const {
|
||||
return GetSortedStubs(HiddenGVStubs);
|
||||
}
|
||||
|
||||
private:
|
||||
static SymbolListTy
|
||||
GetSortedStubs(const DenseMap<const MCSymbol*, const MCSymbol*> &Map);
|
||||
};
|
||||
|
||||
|
||||
/// MachineModuleInfoELF - This is a MachineModuleInfoImpl implementation
|
||||
/// for ELF targets.
|
||||
class MachineModuleInfoELF : public MachineModuleInfoImpl {
|
||||
/// GVStubs - These stubs are used to materialize global addresses in PIC
|
||||
/// mode.
|
||||
DenseMap<MCSymbol*, MCSymbol*> GVStubs;
|
||||
|
||||
virtual void Anchor(); // Out of line virtual method.
|
||||
public:
|
||||
MachineModuleInfoELF(const MachineModuleInfo &) {}
|
||||
|
||||
MCSymbol *&getGVStubEntry(MCSymbol *Sym) {
|
||||
assert(Sym && "Key cannot be null");
|
||||
return GVStubs[Sym];
|
||||
}
|
||||
|
||||
/// Accessor methods to return the set of stubs in sorted order.
|
||||
|
||||
SymbolListTy GetGVStubList() const {
|
||||
return GetSortedStubs(GVStubs);
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -87,6 +87,10 @@ class MachineOperand {
|
||||
/// model the GCC inline asm '&' constraint modifier.
|
||||
bool IsEarlyClobber : 1;
|
||||
|
||||
/// IsDebug - True if this MO_Register 'use' operand is in a debug pseudo,
|
||||
/// not a real instruction. Such uses should be ignored during codegen.
|
||||
bool IsDebug : 1;
|
||||
|
||||
/// ParentMI - This is the instruction that this operand is embedded into.
|
||||
/// This is valid for all operand types, when the operand is in an instr.
|
||||
MachineInstr *ParentMI;
|
||||
@ -214,6 +218,11 @@ class MachineOperand {
|
||||
return IsEarlyClobber;
|
||||
}
|
||||
|
||||
bool isDebug() const {
|
||||
assert(isReg() && "Wrong MachineOperand accessor");
|
||||
return IsDebug;
|
||||
}
|
||||
|
||||
/// getNextOperandForReg - Return the next MachineOperand in the function that
|
||||
/// uses or defines this register.
|
||||
MachineOperand *getNextOperandForReg() const {
|
||||
@ -236,11 +245,13 @@ class MachineOperand {
|
||||
|
||||
void setIsUse(bool Val = true) {
|
||||
assert(isReg() && "Wrong MachineOperand accessor");
|
||||
assert((Val || !isDebug()) && "Marking a debug operation as def");
|
||||
IsDef = !Val;
|
||||
}
|
||||
|
||||
void setIsDef(bool Val = true) {
|
||||
assert(isReg() && "Wrong MachineOperand accessor");
|
||||
assert((!Val || !isDebug()) && "Marking a debug operation as def");
|
||||
IsDef = Val;
|
||||
}
|
||||
|
||||
@ -251,6 +262,7 @@ class MachineOperand {
|
||||
|
||||
void setIsKill(bool Val = true) {
|
||||
assert(isReg() && !IsDef && "Wrong MachineOperand accessor");
|
||||
assert((!Val || !isDebug()) && "Marking a debug operation as kill");
|
||||
IsKill = Val;
|
||||
}
|
||||
|
||||
@ -366,7 +378,7 @@ class MachineOperand {
|
||||
/// the setReg method should be used.
|
||||
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
|
||||
bool isKill = false, bool isDead = false,
|
||||
bool isUndef = false);
|
||||
bool isUndef = false, bool isDebug = false);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Construction methods.
|
||||
@ -388,7 +400,8 @@ class MachineOperand {
|
||||
bool isKill = false, bool isDead = false,
|
||||
bool isUndef = false,
|
||||
bool isEarlyClobber = false,
|
||||
unsigned SubReg = 0) {
|
||||
unsigned SubReg = 0,
|
||||
bool isDebug = false) {
|
||||
MachineOperand Op(MachineOperand::MO_Register);
|
||||
Op.IsDef = isDef;
|
||||
Op.IsImp = isImp;
|
||||
@ -396,6 +409,7 @@ class MachineOperand {
|
||||
Op.IsDead = isDead;
|
||||
Op.IsUndef = isUndef;
|
||||
Op.IsEarlyClobber = isEarlyClobber;
|
||||
Op.IsDebug = isDebug;
|
||||
Op.Contents.Reg.RegNo = Reg;
|
||||
Op.Contents.Reg.Prev = 0;
|
||||
Op.Contents.Reg.Next = 0;
|
||||
|
@ -78,12 +78,12 @@ class MachineRegisterInfo {
|
||||
/// reg_begin/reg_end - Provide iteration support to walk over all definitions
|
||||
/// and uses of a register within the MachineFunction that corresponds to this
|
||||
/// MachineRegisterInfo object.
|
||||
template<bool Uses, bool Defs>
|
||||
template<bool Uses, bool Defs, bool SkipDebug>
|
||||
class defusechain_iterator;
|
||||
|
||||
/// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified
|
||||
/// register.
|
||||
typedef defusechain_iterator<true,true> reg_iterator;
|
||||
typedef defusechain_iterator<true,true,false> reg_iterator;
|
||||
reg_iterator reg_begin(unsigned RegNo) const {
|
||||
return reg_iterator(getRegUseDefListHead(RegNo));
|
||||
}
|
||||
@ -94,7 +94,7 @@ class MachineRegisterInfo {
|
||||
bool reg_empty(unsigned RegNo) const { return reg_begin(RegNo) == reg_end(); }
|
||||
|
||||
/// def_iterator/def_begin/def_end - Walk all defs of the specified register.
|
||||
typedef defusechain_iterator<false,true> def_iterator;
|
||||
typedef defusechain_iterator<false,true,false> def_iterator;
|
||||
def_iterator def_begin(unsigned RegNo) const {
|
||||
return def_iterator(getRegUseDefListHead(RegNo));
|
||||
}
|
||||
@ -105,7 +105,7 @@ class MachineRegisterInfo {
|
||||
bool def_empty(unsigned RegNo) const { return def_begin(RegNo) == def_end(); }
|
||||
|
||||
/// use_iterator/use_begin/use_end - Walk all uses of the specified register.
|
||||
typedef defusechain_iterator<true,false> use_iterator;
|
||||
typedef defusechain_iterator<true,false,false> use_iterator;
|
||||
use_iterator use_begin(unsigned RegNo) const {
|
||||
return use_iterator(getRegUseDefListHead(RegNo));
|
||||
}
|
||||
@ -115,7 +115,20 @@ class MachineRegisterInfo {
|
||||
/// register.
|
||||
bool use_empty(unsigned RegNo) const { return use_begin(RegNo) == use_end(); }
|
||||
|
||||
/// use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the
|
||||
/// specified register, skipping those marked as Debug.
|
||||
typedef defusechain_iterator<true,false,true> use_nodbg_iterator;
|
||||
use_nodbg_iterator use_nodbg_begin(unsigned RegNo) const {
|
||||
return use_nodbg_iterator(getRegUseDefListHead(RegNo));
|
||||
}
|
||||
static use_nodbg_iterator use_nodbg_end() { return use_nodbg_iterator(0); }
|
||||
|
||||
/// use_nodbg_empty - Return true if there are no non-Debug instructions
|
||||
/// using the specified register.
|
||||
bool use_nodbg_empty(unsigned RegNo) const {
|
||||
return use_nodbg_begin(RegNo) == use_nodbg_end();
|
||||
}
|
||||
|
||||
/// replaceRegWith - Replace all instances of FromReg with ToReg in the
|
||||
/// machine function. This is like llvm-level X->replaceAllUsesWith(Y),
|
||||
/// except that it also changes any definitions of the register as well.
|
||||
@ -258,8 +271,9 @@ class MachineRegisterInfo {
|
||||
/// operands in the function that use or define a specific register. If
|
||||
/// ReturnUses is true it returns uses of registers, if ReturnDefs is true it
|
||||
/// returns defs. If neither are true then you are silly and it always
|
||||
/// returns end().
|
||||
template<bool ReturnUses, bool ReturnDefs>
|
||||
/// returns end(). If SkipDebug is true it skips uses marked Debug
|
||||
/// when incrementing.
|
||||
template<bool ReturnUses, bool ReturnDefs, bool SkipDebug>
|
||||
class defusechain_iterator
|
||||
: public std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t> {
|
||||
MachineOperand *Op;
|
||||
@ -268,7 +282,8 @@ class MachineRegisterInfo {
|
||||
// we are interested in.
|
||||
if (op) {
|
||||
if ((!ReturnUses && op->isUse()) ||
|
||||
(!ReturnDefs && op->isDef()))
|
||||
(!ReturnDefs && op->isDef()) ||
|
||||
(SkipDebug && op->isDebug()))
|
||||
++*this;
|
||||
}
|
||||
}
|
||||
@ -299,7 +314,8 @@ class MachineRegisterInfo {
|
||||
|
||||
// If this is an operand we don't care about, skip it.
|
||||
while (Op && ((!ReturnUses && Op->isUse()) ||
|
||||
(!ReturnDefs && Op->isDef())))
|
||||
(!ReturnDefs && Op->isDef()) ||
|
||||
(SkipDebug && Op->isDebug())))
|
||||
Op = Op->getNextOperandForReg();
|
||||
|
||||
return *this;
|
||||
|
@ -138,14 +138,15 @@ class MachineRelocation {
|
||||
///
|
||||
static MachineRelocation getExtSym(uintptr_t offset, unsigned RelocationType,
|
||||
const char *ES, intptr_t cst = 0,
|
||||
bool GOTrelative = 0) {
|
||||
bool GOTrelative = 0,
|
||||
bool NeedStub = true) {
|
||||
assert((RelocationType & ~63) == 0 && "Relocation type too large!");
|
||||
MachineRelocation Result;
|
||||
Result.Offset = offset;
|
||||
Result.ConstantVal = cst;
|
||||
Result.TargetReloType = RelocationType;
|
||||
Result.AddrType = isExtSym;
|
||||
Result.MayNeedFarStub = true;
|
||||
Result.MayNeedFarStub = NeedStub;
|
||||
Result.GOTRelative = GOTrelative;
|
||||
Result.TargetResolve = false;
|
||||
Result.Target.ExtSym = ES;
|
||||
|
@ -81,7 +81,7 @@ class ObjectCodeEmitter : public MachineCodeEmitter {
|
||||
/// written to the data stream in big-endian format.
|
||||
void emitDWordBE(uint64_t W);
|
||||
|
||||
/// emitAlignment - Move the CurBufferPtr pointer up the the specified
|
||||
/// emitAlignment - Move the CurBufferPtr pointer up to the specified
|
||||
/// alignment (saturated to BufferEnd of course).
|
||||
void emitAlignment(unsigned Alignment = 0, uint8_t fill = 0);
|
||||
|
||||
|
@ -174,6 +174,10 @@ namespace llvm {
|
||||
/// optimization by increasing uses of extended values.
|
||||
FunctionPass *createOptimizeExtsPass();
|
||||
|
||||
/// createOptimizePHIsPass - This pass optimizes machine instruction PHIs
|
||||
/// to take advantage of opportunities created during DAG legalization.
|
||||
FunctionPass *createOptimizePHIsPass();
|
||||
|
||||
/// createStackSlotColoringPass - This pass performs stack slot coloring.
|
||||
FunctionPass *createStackSlotColoringPass(bool);
|
||||
|
||||
|
@ -581,18 +581,18 @@ class SelectionDAG {
|
||||
/// determined by their operands, and they produce a value AND a token chain.
|
||||
///
|
||||
SDValue getLoad(EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr,
|
||||
const Value *SV, int SVOffset, bool isVolatile=false,
|
||||
unsigned Alignment=0);
|
||||
const Value *SV, int SVOffset, bool isVolatile,
|
||||
bool isNonTemporal, unsigned Alignment);
|
||||
SDValue getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, EVT VT,
|
||||
SDValue Chain, SDValue Ptr, const Value *SV,
|
||||
int SVOffset, EVT MemVT, bool isVolatile=false,
|
||||
unsigned Alignment=0);
|
||||
SDValue Chain, SDValue Ptr, const Value *SV,
|
||||
int SVOffset, EVT MemVT, bool isVolatile,
|
||||
bool isNonTemporal, unsigned Alignment);
|
||||
SDValue getIndexedLoad(SDValue OrigLoad, DebugLoc dl, SDValue Base,
|
||||
SDValue Offset, ISD::MemIndexedMode AM);
|
||||
SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType,
|
||||
EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset,
|
||||
const Value *SV, int SVOffset, EVT MemVT,
|
||||
bool isVolatile=false, unsigned Alignment=0);
|
||||
bool isVolatile, bool isNonTemporal, unsigned Alignment);
|
||||
SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType,
|
||||
EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset,
|
||||
EVT MemVT, MachineMemOperand *MMO);
|
||||
@ -600,13 +600,14 @@ class SelectionDAG {
|
||||
/// getStore - Helper function to build ISD::STORE nodes.
|
||||
///
|
||||
SDValue getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
|
||||
const Value *SV, int SVOffset, bool isVolatile=false,
|
||||
unsigned Alignment=0);
|
||||
const Value *SV, int SVOffset, bool isVolatile,
|
||||
bool isNonTemporal, unsigned Alignment);
|
||||
SDValue getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
|
||||
MachineMemOperand *MMO);
|
||||
SDValue getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
|
||||
const Value *SV, int SVOffset, EVT TVT,
|
||||
bool isVolatile=false, unsigned Alignment=0);
|
||||
const Value *SV, int SVOffset, EVT TVT,
|
||||
bool isNonTemporal, bool isVolatile,
|
||||
unsigned Alignment);
|
||||
SDValue getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
|
||||
EVT TVT, MachineMemOperand *MMO);
|
||||
SDValue getIndexedStore(SDValue OrigStoe, DebugLoc dl, SDValue Base,
|
||||
@ -841,7 +842,7 @@ class SelectionDAG {
|
||||
}
|
||||
|
||||
/// AssignOrdering - Assign an order to the SDNode.
|
||||
void AssignOrdering(SDNode *SD, unsigned Order);
|
||||
void AssignOrdering(const SDNode *SD, unsigned Order);
|
||||
|
||||
/// GetOrdering - Get the order for the SDNode.
|
||||
unsigned GetOrdering(const SDNode *SD) const;
|
||||
|
@ -85,11 +85,13 @@ class SelectionDAGISel : public MachineFunctionPass {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// IsLegalAndProfitableToFold - Returns true if the specific operand node N of
|
||||
/// U can be folded during instruction selection that starts at Root and
|
||||
/// folding N is profitable.
|
||||
virtual
|
||||
bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U, SDNode *Root) const;
|
||||
/// IsProfitableToFold - Returns true if it's profitable to fold the specific
|
||||
/// operand node N of U during instruction selection that starts at Root.
|
||||
virtual bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const;
|
||||
|
||||
/// IsLegalToFold - Returns true if the specific operand node N of
|
||||
/// U can be folded during instruction selection that starts at Root.
|
||||
virtual bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const;
|
||||
|
||||
/// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer
|
||||
/// to use for this target when scheduling the DAG.
|
||||
@ -110,6 +112,25 @@ class SelectionDAGISel : public MachineFunctionPass {
|
||||
bool CheckOrMask(SDValue LHS, ConstantSDNode *RHS,
|
||||
int64_t DesiredMaskS) const;
|
||||
|
||||
|
||||
/// CheckPatternPredicate - This function is generated by tblgen in the
|
||||
/// target. It runs the specified pattern predicate and returns true if it
|
||||
/// succeeds or false if it fails. The number is a private implementation
|
||||
/// detail to the code tblgen produces.
|
||||
virtual bool CheckPatternPredicate(unsigned PredNo) const {
|
||||
assert(0 && "Tblgen should generate the implementation of this!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// CheckNodePredicate - This function is generated by tblgen in the
|
||||
/// target. It runs node predicate #PredNo and returns true if it succeeds or
|
||||
/// false if it fails. The number is a private implementation
|
||||
/// detail to the code tblgen produces.
|
||||
virtual bool CheckNodePredicate(SDNode *N, unsigned PredNo) const {
|
||||
assert(0 && "Tblgen should generate the implementation of this!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calls to these functions are generated by tblgen.
|
||||
SDNode *Select_INLINEASM(SDNode *N);
|
||||
SDNode *Select_UNDEF(SDNode *N);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user