Compare commits
21 Commits
llvmorg-4.
...
llvmorg-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c594b19468 | ||
|
|
2347d61b1a | ||
|
|
3aa5569e16 | ||
|
|
7727db668b | ||
|
|
16bef36da3 | ||
|
|
aa9e1128cf | ||
|
|
ab14717d86 | ||
|
|
033f96e969 | ||
|
|
a14df74021 | ||
|
|
11003970f3 | ||
|
|
034431a297 | ||
|
|
b0a4fa1e22 | ||
|
|
ca62d763b0 | ||
|
|
160bf47d68 | ||
|
|
b49aeb238e | ||
|
|
ee964cecce | ||
|
|
22c93692b4 | ||
|
|
85b9191ee4 | ||
|
|
eb6437a14f | ||
|
|
13e0bb8554 | ||
|
|
1c8ba66d60 |
@@ -41,7 +41,4 @@ dist-hook::
|
||||
$(TopDistDir)/include/llvm/Support/DataTypes.h \
|
||||
$(TopDistDir)/include/llvm/Support/ThreadSupport.h
|
||||
|
||||
check :
|
||||
$(MAKE) -C test check TESTSUITE=$(TESTSUITE)
|
||||
|
||||
tools-only: all
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
# Define the various target sets
|
||||
#--------------------------------------------------------------------
|
||||
RecursiveTargets := all clean clean-all install uninstall install-bytecode
|
||||
LocalTargets := all-local clean-local clean-all-local \
|
||||
LocalTargets := all-local clean-local clean-all-local check-local \
|
||||
install-local printvars uninstall-local \
|
||||
install-bytecode-local
|
||||
TopLevelTargets := dist dist-check dist-clean tags dist-gzip dist-bzip2 \
|
||||
TopLevelTargets := check dist dist-check dist-clean tags dist-gzip dist-bzip2 \
|
||||
dist-zip
|
||||
UserTargets := $(RecursiveTargets) $(LocalTargets) $(TopLevelTargets)
|
||||
InternalTargets := preconditions distdir dist-hook
|
||||
@@ -154,12 +154,13 @@ ifdef ENABLE_PROFILING
|
||||
else
|
||||
ifdef ENABLE_OPTIMIZED
|
||||
BuildMode := Release
|
||||
CXX.Flags := -O3 -DNDEBUG -finline-functions -felide-constructors -fomit-frame-pointer
|
||||
CXX.Flags := -O3 -DNDEBUG -finline-functions \
|
||||
-felide-constructors -fomit-frame-pointer
|
||||
C.Flags := -O3 -DNDEBUG -fomit-frame-pointer
|
||||
LD.Flags := -O3 -DNDEBUG
|
||||
else
|
||||
BuildMode := Debug
|
||||
CXX.Flags := -g -D_DEBUG
|
||||
CXX.Flags := -g -D_DEBUG
|
||||
C.Flags := -g -D_DEBUG
|
||||
LD.Flags := -g -D_DEBUG
|
||||
KEEP_SYMBOLS := 1
|
||||
@@ -214,10 +215,6 @@ ifndef LLVMGXX
|
||||
LLVMGXX := PATH=$(LLVMToolDir):$(PATH) $(LLVMGCCDIR)/bin/g++
|
||||
endif
|
||||
|
||||
# Need a better way to compute this.
|
||||
LLVMGCCLibDir := $(dir $(shell $(LLVMGCC) -print-file-name=libgcc.a))/
|
||||
LLVMGCCStdCXXLibDir := $(dir $(shell $(LLVMGCC) -print-file-name=libstdc++.a))/
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Adjust to user's request
|
||||
#--------------------------------------------------------------------
|
||||
@@ -1089,6 +1086,23 @@ endif
|
||||
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
# CHECK: Running the test suite
|
||||
###############################################################################
|
||||
|
||||
check::
|
||||
$(Verb) if test -d "$(BUILD_OBJ_ROOT)/test" ; then \
|
||||
if test -f "$(BUILD_OBJ_ROOT)/test/Makefile" ; then \
|
||||
$(EchoCmd) Running test suite ; \
|
||||
$(MAKE) -C $(BUILD_OBJ_ROOT)/test check-local \
|
||||
TESTSUITE=$(TESTSUITE) ; \
|
||||
else \
|
||||
$(EchoCmd) No Makefile in test directory ; \
|
||||
fi ; \
|
||||
else \
|
||||
$(EchoCmd) No test directory ; \
|
||||
fi
|
||||
|
||||
###############################################################################
|
||||
# DISTRIBUTION: Handle construction of a distribution tarball
|
||||
###############################################################################
|
||||
@@ -1212,7 +1226,7 @@ $(DistDir)/.makedistdir: $(DistSources)
|
||||
fi ; \
|
||||
$(EchoCmd) Removing old $(DistDir) ; \
|
||||
$(RM) -rf $(DistDir); \
|
||||
$(EchoCmd) Making 'all' to be sure. ; \
|
||||
$(EchoCmd) Making 'all' to verify build ; \
|
||||
$(MAKE) all ; \
|
||||
fi
|
||||
$(Echo) Building Distribution Directory $(DistDir)
|
||||
@@ -1296,7 +1310,7 @@ endif
|
||||
ifeq ($(LEVEL),.)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# Install support for project's include files:
|
||||
# Install support for the project's include files:
|
||||
#------------------------------------------------------------------------
|
||||
install-local::
|
||||
$(Echo) Installing include files
|
||||
|
||||
@@ -567,8 +567,6 @@ AC_CONFIG_MAKEFILE(lib/Makefile)
|
||||
AC_CONFIG_MAKEFILE(runtime/Makefile)
|
||||
AC_CONFIG_MAKEFILE(test/Makefile)
|
||||
AC_CONFIG_MAKEFILE(test/Makefile.tests)
|
||||
AC_CONFIG_MAKEFILE(test/QMTest/llvm.py)
|
||||
AC_CONFIG_MAKEFILE(test/QMTest/llvmdb.py)
|
||||
AC_CONFIG_MAKEFILE(tools/Makefile)
|
||||
AC_CONFIG_MAKEFILE(utils/Makefile)
|
||||
AC_CONFIG_MAKEFILE(projects/Makefile)
|
||||
|
||||
12
llvm/configure
vendored
12
llvm/configure
vendored
@@ -29575,12 +29575,6 @@ _ACEOF
|
||||
ac_config_commands="$ac_config_commands test/Makefile.tests"
|
||||
|
||||
|
||||
ac_config_commands="$ac_config_commands test/QMTest/llvm.py"
|
||||
|
||||
|
||||
ac_config_commands="$ac_config_commands test/QMTest/llvmdb.py"
|
||||
|
||||
|
||||
ac_config_commands="$ac_config_commands tools/Makefile"
|
||||
|
||||
|
||||
@@ -30139,8 +30133,6 @@ ${srcdir}/autoconf/mkinstalldirs `dirname lib/Makefile`
|
||||
${srcdir}/autoconf/mkinstalldirs `dirname runtime/Makefile`
|
||||
${srcdir}/autoconf/mkinstalldirs `dirname test/Makefile`
|
||||
${srcdir}/autoconf/mkinstalldirs `dirname test/Makefile.tests`
|
||||
${srcdir}/autoconf/mkinstalldirs `dirname test/QMTest/llvm.py`
|
||||
${srcdir}/autoconf/mkinstalldirs `dirname test/QMTest/llvmdb.py`
|
||||
${srcdir}/autoconf/mkinstalldirs `dirname tools/Makefile`
|
||||
${srcdir}/autoconf/mkinstalldirs `dirname utils/Makefile`
|
||||
${srcdir}/autoconf/mkinstalldirs `dirname projects/Makefile`
|
||||
@@ -30168,8 +30160,6 @@ do
|
||||
"runtime/Makefile" ) CONFIG_COMMANDS="$CONFIG_COMMANDS runtime/Makefile" ;;
|
||||
"test/Makefile" ) CONFIG_COMMANDS="$CONFIG_COMMANDS test/Makefile" ;;
|
||||
"test/Makefile.tests" ) CONFIG_COMMANDS="$CONFIG_COMMANDS test/Makefile.tests" ;;
|
||||
"test/QMTest/llvm.py" ) CONFIG_COMMANDS="$CONFIG_COMMANDS test/QMTest/llvm.py" ;;
|
||||
"test/QMTest/llvmdb.py" ) CONFIG_COMMANDS="$CONFIG_COMMANDS test/QMTest/llvmdb.py" ;;
|
||||
"tools/Makefile" ) CONFIG_COMMANDS="$CONFIG_COMMANDS tools/Makefile" ;;
|
||||
"utils/Makefile" ) CONFIG_COMMANDS="$CONFIG_COMMANDS utils/Makefile" ;;
|
||||
"projects/Makefile" ) CONFIG_COMMANDS="$CONFIG_COMMANDS projects/Makefile" ;;
|
||||
@@ -31087,8 +31077,6 @@ echo "$as_me: executing $ac_dest commands" >&6;}
|
||||
runtime/Makefile ) ${SHELL} ${srcdir}/autoconf/install-sh -c ${srcdir}/runtime/Makefile runtime/Makefile ;;
|
||||
test/Makefile ) ${SHELL} ${srcdir}/autoconf/install-sh -c ${srcdir}/test/Makefile test/Makefile ;;
|
||||
test/Makefile.tests ) ${SHELL} ${srcdir}/autoconf/install-sh -c ${srcdir}/test/Makefile.tests test/Makefile.tests ;;
|
||||
test/QMTest/llvm.py ) ${SHELL} ${srcdir}/autoconf/install-sh -c ${srcdir}/test/QMTest/llvm.py test/QMTest/llvm.py ;;
|
||||
test/QMTest/llvmdb.py ) ${SHELL} ${srcdir}/autoconf/install-sh -c ${srcdir}/test/QMTest/llvmdb.py test/QMTest/llvmdb.py ;;
|
||||
tools/Makefile ) ${SHELL} ${srcdir}/autoconf/install-sh -c ${srcdir}/tools/Makefile tools/Makefile ;;
|
||||
utils/Makefile ) ${SHELL} ${srcdir}/autoconf/install-sh -c ${srcdir}/utils/Makefile utils/Makefile ;;
|
||||
projects/Makefile ) ${SHELL} ${srcdir}/autoconf/install-sh -c ${srcdir}/projects/Makefile projects/Makefile ;;
|
||||
|
||||
2
llvm/docs/.cvsignore
Normal file
2
llvm/docs/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
doxygen.cfg
|
||||
|
||||
@@ -45,7 +45,6 @@ process, and you should <b>only</b> try to do it if:</p>
|
||||
|
||||
<ol>
|
||||
<li>you really, really, really can't use the binaries we distribute</li>
|
||||
<li>you need GCC to fix some of the header files on your system</li>
|
||||
<li>you are an elite GCC hacker.</li>
|
||||
</ol>
|
||||
|
||||
@@ -59,7 +58,7 @@ process, and you should <b>only</b> try to do it if:</p>
|
||||
<!--=========================================================================-->
|
||||
|
||||
<div class="doc_text">
|
||||
<p>If you are building LLVM and the C front-end under Cygwin, please note that
|
||||
<p>If you are building LLVM and the GCC front-end under Cygwin, please note that
|
||||
the LLVM and GCC makefiles do not correctly handle spaces in paths. To deal
|
||||
with this issue, make sure that your LLVM and GCC source and build trees are
|
||||
located in a top-level directory (like <tt>/cygdrive/c/llvm</tt> and
|
||||
@@ -76,7 +75,7 @@ and Settings" directory). We welcome patches to fix this issue.
|
||||
<!--=========================================================================-->
|
||||
|
||||
<div class="doc_text">
|
||||
<p>If you are building LLVM and the C front-end under AIX, do NOT use GNU
|
||||
<p>If you are building LLVM and the GCC front-end under AIX, do NOT use GNU
|
||||
Binutils. They are not stable under AIX and may produce incorrect and/or
|
||||
invalid code. Instead, use the system assembler and linker.
|
||||
</p>
|
||||
@@ -121,7 +120,7 @@ invalid code. Instead, use the system assembler and linker.
|
||||
</pre></li>
|
||||
|
||||
|
||||
<li><p>Configure, build, and install the C front-end:</p>
|
||||
<li><p>Configure, build, and install the GCC front-end:</p>
|
||||
|
||||
<p>
|
||||
<b>Linux/x86:</b><br>
|
||||
@@ -176,7 +175,7 @@ functions from C as referenced from C++, so we typically configure with
|
||||
<ul>
|
||||
<li><p><b>Fix 1:</b> If you have system header files that include
|
||||
inline assembly, you may have to modify them to remove the inline
|
||||
assembly, and install the modified versions in
|
||||
assembly and install the modified versions in
|
||||
<code>$CFEINSTALL/lib/gcc/<i>target-triplet</i>/3.4-llvm/include</code>.</li>
|
||||
|
||||
<li><b>Fix 2:</b> If you are building the C++ front-end on a CPU we
|
||||
@@ -186,10 +185,10 @@ functions from C as referenced from C++, so we typically configure with
|
||||
and apply a patch so that it does not use inline assembly.</li>
|
||||
</ul>
|
||||
|
||||
<p><b>Porting to a new architecture:</b> If you are porting the new front-end
|
||||
to a new architecture, or compiling in a different configuration that we have
|
||||
previously, there are probably several changes you will have to make to the GCC
|
||||
target to get it to work correctly. These include:<p>
|
||||
<p><b>Porting to a new architecture:</b> If you are porting the front-end
|
||||
to a new architecture or compiling in a configuration that we have
|
||||
not tried previously, there are probably several changes you will have to make
|
||||
to the GCC target to get it to work correctly. These include:<p>
|
||||
|
||||
<ul>
|
||||
<li>Often targets include special assembler or linker flags which
|
||||
@@ -216,7 +215,7 @@ functions from C as referenced from C++, so we typically configure with
|
||||
|
||||
<li><p>Go back into the LLVM source tree proper. Rerun configure, using
|
||||
the <code>--with-llvmgccdir=$CFEINSTALL</code> option to specify the path
|
||||
to the newly built C front-end.</p></li>
|
||||
to the newly built GCC front-end.</p></li>
|
||||
|
||||
<li><p>If you edited header files during the C/C++ front-end build as
|
||||
described in "Fix 1" above, you must now copy those header files from
|
||||
@@ -228,7 +227,7 @@ libgcc.a library, which you can find by running
|
||||
|
||||
<li><p>Rebuild your CVS tree. This shouldn't cause the whole thing to be
|
||||
rebuilt, but it should build the runtime libraries. After the tree is
|
||||
built, install the runtime libraries into your C front-end build tree.
|
||||
built, install the runtime libraries into your GCC front-end build tree.
|
||||
These are the commands you need.</p>
|
||||
<pre>
|
||||
% gmake
|
||||
@@ -255,8 +254,8 @@ the <tt>llvm-ranlib</tt> tool to do this, as follows:</p>
|
||||
following means:</p>
|
||||
<ul>
|
||||
<li> compiling and running a "hello, LLVM" program in C and C++.</li>
|
||||
<li> running the tests under <tt>test/Programs</tt> using <code>gmake -C
|
||||
test/Programs</code></li>
|
||||
<li> running the regression tests in <tt>llvm/test</tt>
|
||||
<li> running the tests found in the <tt>llvm-test</tt> CVS module</li>
|
||||
</ul></li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
@@ -7,6 +7,39 @@
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
ifdef BUILD_FOR_WEBSITE
|
||||
|
||||
# This special case is for keeping the CommandGuide on the LLVM web site
|
||||
# up to date automatically as the documents are checked in. It must build
|
||||
# the POD files to HTML only and keep them in the src directories. It must also
|
||||
# build in an unconfigured tree, hence the ifdef. To use this, run
|
||||
# make -s BUILD_FOR_WEBSITE=1 inside the cvs commit script.
|
||||
|
||||
POD := $(wildcard *.pod)
|
||||
HTML := $(patsubst %.pod, html/%.html, $(POD))
|
||||
MAN := $(patsubst %.pod, man/man1/%.1, $(POD))
|
||||
PS := $(patsubst %.pod, ps/%.ps, $(POD))
|
||||
|
||||
all: $(HTML) $(MAN) $(PS)
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .html .pod .1 .ps
|
||||
|
||||
html/%.html: %.pod
|
||||
pod2html --css=manpage.css --htmlroot=. \
|
||||
--podpath=. --noindex --infile=$< --outfile=$@ --title=$*
|
||||
|
||||
man/man1/%.1: %.pod
|
||||
pod2man --release=1.4 --center="LLVM Command Guide" $< $@
|
||||
|
||||
ps/%.ps: man/man1/%.1
|
||||
groff -Tps -man $< > $@
|
||||
|
||||
clean:
|
||||
rm -f pod2htm*.*~~ $(HTML) $(MAN) $(PS)
|
||||
|
||||
else
|
||||
|
||||
LEVEL := ../..
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
@@ -62,3 +95,5 @@ uninstall-local::
|
||||
printvars::
|
||||
$(Echo) "POD : " '$(POD)'
|
||||
$(Echo) "HTML : " '$(HTML)'
|
||||
|
||||
endif
|
||||
|
||||
@@ -14,34 +14,9 @@ The B<llc> command compiles LLVM bytecode into assembly language for a
|
||||
specified architecture. The assembly language output can then be passed through
|
||||
a native assembler and linker to generate native code.
|
||||
|
||||
The choice of architecture for the output assembly code is determined as
|
||||
follows, by attempting to satisfy each of the following rules in turn (first
|
||||
one wins):
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
If the user has specified an architecture with the -m option, use that
|
||||
architecture.
|
||||
|
||||
=item *
|
||||
|
||||
Examine the input LLVM bytecode file: if it is little endian and has a
|
||||
pointer size of 32 bits, select the Intel IA-32 architecture. If it is big
|
||||
endian and has a pointer size of 64 bits, select the SparcV9 architecture.
|
||||
|
||||
=item *
|
||||
|
||||
If B<llc> was compiled on an architecture for which it can generate code, select
|
||||
the architecture upon which B<llc> was compiled.
|
||||
|
||||
=item *
|
||||
|
||||
Exit with an error message telling the user to specify the output
|
||||
architecture explicitly.
|
||||
|
||||
=back
|
||||
The choice of architecture for the output assembly code is automatically
|
||||
determined from the input bytecode file, unless a B<-m> option is used to override
|
||||
the default.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
@@ -90,41 +65,31 @@ Emit C code, not assembly
|
||||
|
||||
=back
|
||||
|
||||
=item B<-enable-correct-eh-support>
|
||||
|
||||
Instruct the B<-lowerinvoke> pass to insert code for correct exception handling
|
||||
support. This is expensive and is by default omitted for efficiency.
|
||||
|
||||
=item B<-help>
|
||||
|
||||
Print a summary of command line options.
|
||||
|
||||
=item B<-stats>
|
||||
|
||||
Print statistics recorded by code-generation passes.
|
||||
|
||||
=item B<-time-passes>
|
||||
|
||||
Record the amount of time needed for each pass and print a report to standard
|
||||
error.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Intel IA-32-specific Options
|
||||
|
||||
=over
|
||||
|
||||
=item B<--disable-fp-elim>
|
||||
|
||||
Disable frame pointer elimination optimization.
|
||||
|
||||
=item B<--disable-pattern-isel>
|
||||
=item B<--enable-correct-eh-support>
|
||||
|
||||
Use the 'simple' X86 instruction selector (the default).
|
||||
Instruct the B<lowerinvoke> pass to insert code for correct exception handling
|
||||
support. This is expensive and is by default omitted for efficiency.
|
||||
|
||||
=item B<--help>
|
||||
|
||||
Print a summary of command line options.
|
||||
|
||||
=item B<--stats>
|
||||
|
||||
Print statistics recorded by code-generation passes.
|
||||
|
||||
=item B<--time-passes>
|
||||
|
||||
Record the amount of time needed for each pass and print a report to standard
|
||||
error.
|
||||
|
||||
=item B<--print-machineinstrs>
|
||||
|
||||
Print generated machine code.
|
||||
Print generated machine code between compilation phases (useful for debugging).
|
||||
|
||||
=item B<--regalloc>=I<allocator>
|
||||
|
||||
@@ -171,6 +136,17 @@ Local spiller
|
||||
|
||||
=back
|
||||
|
||||
=head2 Intel IA-32-specific Options
|
||||
|
||||
=over
|
||||
|
||||
=item B<--x86-asm-syntax=att|intel>
|
||||
|
||||
Specify whether to emit assembly code in AT&T syntax (the default) or intel
|
||||
syntax.
|
||||
|
||||
=back
|
||||
|
||||
=head2 SPARCV9-specific Options
|
||||
|
||||
=over
|
||||
@@ -183,15 +159,6 @@ Disable peephole optimization pass.
|
||||
|
||||
Disable local scheduling pass.
|
||||
|
||||
=item B<--disable-strip>
|
||||
|
||||
The Sparc backend embeds the LLVM bytecode into the assembly output. This
|
||||
option requests that symbol names be retained; by default, they are stripped out.
|
||||
|
||||
=item B<--enable-maps>
|
||||
|
||||
Emit LLVM-to-machine code mapping information into the assembly output.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXIT STATUS
|
||||
|
||||
@@ -23,7 +23,7 @@ The B<llvm-ar> command can be used to I<read> both SVR4 and BSD style archive
|
||||
files. However, it cannot be used to write them. While the B<llvm-ar> command
|
||||
produces files that are I<almost> identical to the format used by other C<ar>
|
||||
implementations, it has two significant departures in order to make the
|
||||
archive appropriate for LLVM. There are first departure is that B<llvm-ar> only
|
||||
archive appropriate for LLVM. The first departure is that B<llvm-ar> only
|
||||
uses BSD4.4 style long path names (stored immediately after the header) and
|
||||
never contains a string table for long names. The second departure is that the
|
||||
symbol table is formated for efficient construction of an in-memory data
|
||||
@@ -63,7 +63,7 @@ slash (/) character.
|
||||
B<llvm-ar> can compress the members of an archive to save space. The
|
||||
compression used depends on what's available on the platform and what choices
|
||||
the LLVM Compressor utility makes. It generally favors bzip2 but will select
|
||||
between "no compression", bzip2 or zlib depending on what makes sense for the
|
||||
between "no compression" or bzip2 depending on what makes sense for the
|
||||
file's content.
|
||||
|
||||
=item I<Directory Recursion>
|
||||
@@ -229,9 +229,9 @@ a time stamp than the time stamp of the member in the archive.
|
||||
=item [z]
|
||||
|
||||
When inserting or replacing any file in the archive, compress the file first.
|
||||
The compression will attempt to use the zlib compression algorithm. This
|
||||
This
|
||||
modifier is safe to use when (previously) compressed bytecode files are added to
|
||||
the archive; the compress bytecode files will not be doubly compressed.
|
||||
the archive; the compressed bytecode files will not be doubly compressed.
|
||||
|
||||
=back
|
||||
|
||||
@@ -342,9 +342,8 @@ This field provides the size of the file, in bytes, encoded as a decimal ASCII
|
||||
string. If the size field is negative (starts with a minus sign, 0x02D), then
|
||||
the archive member is stored in compressed form. The first byte of the archive
|
||||
member's data indicates the compression type used. A value of 0 (0x30) indicates
|
||||
that no compression was used. A value of 1 (0x31) indicates that zlib
|
||||
compression was used. A value of 2 (0x32) indicates that bzip2 compression was
|
||||
used.
|
||||
that no compression was used. A value of 2 (0x32) indicates that bzip2
|
||||
compression was used.
|
||||
|
||||
=item fmag - char[2]
|
||||
|
||||
|
||||
@@ -168,10 +168,6 @@ LLVM have been ported to a plethora of platforms.</p>
|
||||
<li>The GCC front end code is not as portable as the LLVM suite, so it may not
|
||||
compile as well on unsupported platforms.</li>
|
||||
|
||||
<li>The Python test classes are more UNIX-centric than they should be, so
|
||||
porting to non-UNIX like platforms (i.e. Windows, MacOS 9) will require some
|
||||
effort.</li>
|
||||
|
||||
<li>The LLVM build system relies heavily on UNIX shell tools, like the Bourne
|
||||
Shell and sed. Porting to systems without these tools (MacOS 9, Plan 9) will
|
||||
require more effort.</li>
|
||||
|
||||
@@ -38,13 +38,16 @@
|
||||
<li><a href="#layout">Program layout</a>
|
||||
<ol>
|
||||
<li><a href="#cvsdir"><tt>CVS</tt> directories</a>
|
||||
<li><a href="#examples"><tt>llvm/examples</tt></a>
|
||||
<li><a href="#include"><tt>llvm/include</tt></a>
|
||||
<li><a href="#lib"><tt>llvm/lib</tt></a>
|
||||
<li><a href="#projects"><tt>llvm/projects</tt></a>
|
||||
<li><a href="#runtime"><tt>llvm/runtime</tt></a>
|
||||
<li><a href="#test"><tt>llvm/test</tt></a>
|
||||
<li><a href="#llvmtest"><tt>llvm-test</tt></a>
|
||||
<li><a href="#tools"><tt>llvm/tools</tt></a>
|
||||
<li><a href="#utils"><tt>llvm/utils</tt></a>
|
||||
<li><a href="#win32"><tt>llvm/win32</tt></a>
|
||||
</ol></li>
|
||||
|
||||
<li><a href="#tutorial">An Example Using the LLVM Tool Chain</a>
|
||||
@@ -86,6 +89,12 @@ end is a modified version of GCC 3.4 (we track the GCC 3.4 development). Once
|
||||
compiled into LLVM bytecode, a program can be manipulated with the LLVM tools
|
||||
from the LLVM suite.</p>
|
||||
|
||||
<p>
|
||||
There is a third, optional piece called llvm-test. It is a suite of programs
|
||||
with a testing harness that can be used to further test LLVM's functionality
|
||||
and performance.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
@@ -106,8 +115,7 @@ from the LLVM suite.</p>
|
||||
<ol>
|
||||
<li><tt>cd <i>where-you-want-the-C-front-end-to-live</i></tt>
|
||||
<li><tt>gunzip --stdout cfrontend.<i>platform</i>.tar.gz | tar -xvf -</tt>
|
||||
<li><b>Sparc and MacOS X Only:</b><br>
|
||||
<tt>cd cfrontend/<i>platform</i><br>
|
||||
<li><tt>cd cfrontend/<i>platform</i><br>
|
||||
./fixheaders</tt>
|
||||
</ol></li>
|
||||
|
||||
@@ -117,7 +125,7 @@ from the LLVM suite.</p>
|
||||
<ol>
|
||||
<li><tt>cd <i>where-you-want-llvm-to-live</i></tt>
|
||||
<li><tt>gunzip --stdout llvm-<i>version</i>.tar.gz | tar -xvf -</tt>
|
||||
<li><tt>cd llvm</tt>
|
||||
<li><tt>cd llvm</tt></li>
|
||||
</ol></li>
|
||||
|
||||
<li>With anonymous CVS access (or use a <a href="#mirror">mirror</a>):
|
||||
@@ -133,6 +141,32 @@ from the LLVM suite.</p>
|
||||
</ol></li>
|
||||
</ul></li>
|
||||
|
||||
<li>Get the Test Suite Source Code (<em>optional</em>)
|
||||
<ul>
|
||||
<li>With the distributed files:
|
||||
<ol>
|
||||
<li><tt>cd <i>where-you-want-llvm-to-live</i></tt>
|
||||
<li><tt>cd llvm/projects</tt>
|
||||
<li><tt>gunzip --stdout llvm-test-<i>version</i>.tar.gz | tar -xvf -</tt>
|
||||
<li><tt>cd ..</tt></li>
|
||||
</ol></li>
|
||||
|
||||
<li>With anonymous CVS access (or use a <a href="#mirror">mirror</a>):
|
||||
<ol>
|
||||
<li><tt>cd <i>where-you-want-llvm-to-live</i></tt></li>
|
||||
<li><tt>cd llvm/projects</tt>
|
||||
<li><tt>cvs -d
|
||||
:pserver:anon@llvm-cvs.cs.uiuc.edu:/var/cvs/llvm login</tt></li>
|
||||
<li>Hit the return key when prompted for the password.
|
||||
<li><tt>cvs -z3 -d :pserver:anon@llvm-cvs.cs.uiuc.edu:/var/cvs/llvm
|
||||
co llvm-test</tt></li>
|
||||
<li><tt>cd llvm-test</tt></li>
|
||||
<li><tt>cvs up -P -d</tt></li>
|
||||
<li><tt>cd ..</tt></li>
|
||||
</ol></li>
|
||||
</ul></li>
|
||||
|
||||
|
||||
<li>Configure the LLVM Build Environment
|
||||
<ol>
|
||||
<li>Change directory to where you want to store the LLVM object
|
||||
@@ -295,7 +329,7 @@ href="CFEBuildInstrs.html">try to compile it</a> on your platform.</p>
|
||||
<tr>
|
||||
<td><a href="http://gcc.gnu.org">GCC</a></td>
|
||||
<td>3.4.2</td>
|
||||
<td>C/C++ compiler (<a href="#Note4">Note 4</a>)</td>
|
||||
<td>C/C++ compiler (<a href="#Note3">Note 3</a>)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -342,13 +376,13 @@ href="CFEBuildInstrs.html">try to compile it</a> on your platform.</p>
|
||||
|
||||
<tr>
|
||||
<td><a href="http://www.gnu.org/software/automake">GNU Automake</a></td>
|
||||
<td>2.59</td>
|
||||
<td>1.9.2</td>
|
||||
<td>aclocal macro generator (<a href="#Note1">Note 1</a>)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><a href="http://www.perl.com/download.csp">perl</a></td>
|
||||
<td>>5.6.0</td>
|
||||
<td>≥5.6.0</td>
|
||||
<td>Nightly tester, utilities</td>
|
||||
</tr>
|
||||
|
||||
@@ -358,24 +392,10 @@ href="CFEBuildInstrs.html">try to compile it</a> on your platform.</p>
|
||||
<td>Shared library manager (<a href="#Note1">Note 1</a>)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><a href="http://www.codesourcery.com/qmtest">QMTest</a></td>
|
||||
<td>2.0.3</td>
|
||||
<td>Automated test suite (<a href="#Note2">Note 2</a>,<a href="#Note3">
|
||||
Note 3</a>)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><a href="http://www.python.org">Python</a></td>
|
||||
<td>2.3</td>
|
||||
<td>Automated test suite (<a href="#Note2">Note 2</a>,<a href="#Note3">
|
||||
Note 3</a>)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><a href="https://www.cvshome.org/downloads.html">CVS</a></td>
|
||||
<td>>1.11</td>
|
||||
<td>CVS access to LLVM (<a href="#Note5">Note 5</a>)</td>
|
||||
<td>≥1.11</td>
|
||||
<td>CVS access to LLVM (<a href="#Note4">Note 4</a>)</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
@@ -384,25 +404,16 @@ href="CFEBuildInstrs.html">try to compile it</a> on your platform.</p>
|
||||
<ol>
|
||||
<li><a name="Note1">If you want to make changes to the configure scripts,
|
||||
you will need GNU autoconf (2.59), and consequently, GNU M4 (version 1.4
|
||||
or higher). You will also need automake. We only use aclocal from that
|
||||
package.</a></li>
|
||||
or higher). You will also need automake (1.9.2). We only use aclocal
|
||||
from that package.</a></li>
|
||||
<li><a name="Note2">Only needed if you want to run the automated test
|
||||
suite in the <tt>test</tt> directory.</a></li>
|
||||
<li><a name="Note3">These are needed to use the LLVM test suite.</a>
|
||||
Please note that newer versions of QMTest may not work with the LLVM
|
||||
test suite. QMTest 2.0.3 can be retrieved from the QMTest CVS
|
||||
repository using the following commands:
|
||||
<ul>
|
||||
<li><tt>cvs -d :pserver:anoncvs@cvs.codesourcery.com:/home/qm/Repository login</tt></li>
|
||||
<li>When prompted, use <tt>anoncvs</tt> as the password. </li>
|
||||
<li><tt>cvs -d :pserver:anoncvs@cvs.codesourcery.com:/home/qm/Repository co -r release-2-0-3 qm</tt></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a name="Note4">Only the C and C++ languages are needed so there's no
|
||||
<li><a name="Note3">Only the C and C++ languages are needed so there's no
|
||||
need to build the other languages for LLVM's purposes.</a> See
|
||||
<a href="#brokengcc">below</a> for specific version info.
|
||||
</li>
|
||||
<li><a name="Note5">You only need CVS if you intend to build from the
|
||||
<li><a name="Note4">You only need CVS if you intend to build from the
|
||||
latest LLVM sources. If you're working from a release distribution, you
|
||||
don't need CVS.</a></li>
|
||||
</ol>
|
||||
@@ -413,7 +424,7 @@ href="CFEBuildInstrs.html">try to compile it</a> on your platform.</p>
|
||||
<li><b>bzip2*</b> - bzip2 command for distribution generation</li>
|
||||
<li><b>bunzip2*</b> - bunzip2 command for distribution checking</li>
|
||||
<li><b>chmod</b> - change permissions on a file</li>
|
||||
<li><b>cat</b> - output concatentation utility</li>
|
||||
<li><b>cat</b> - output concatenation utility</li>
|
||||
<li><b>cp</b> - copy files</li>
|
||||
<li><b>date</b> - print the current date/time </li>
|
||||
<li><b>echo</b> - print to standard output</li>
|
||||
@@ -546,7 +557,7 @@ You can set these on the command line, or better yet, set them in your
|
||||
<dt>alias llvmgcc <i>LLVMGCCDIR</i><tt>/bin/gcc</tt>
|
||||
<dt>alias llvmg++ <i>LLVMGCCDIR</i><tt>/bin/g++</tt>
|
||||
<dd>
|
||||
This alias allows you to use the LLVM C and C++ front ends without putting
|
||||
These aliases allow you to use the LLVM C and C++ front ends without putting
|
||||
them in your <tt>PATH</tt> or typing in their complete pathnames.
|
||||
</dl>
|
||||
|
||||
@@ -562,34 +573,34 @@ You can set these on the command line, or better yet, set them in your
|
||||
<p>
|
||||
If you have the LLVM distribution, you will need to unpack it before you
|
||||
can begin to compile it. LLVM is distributed as a set of two files: the LLVM
|
||||
suite and the LLVM GCC front end compiled for your platform. Each
|
||||
file is a TAR archive that is compressed with the gzip program.
|
||||
suite and the LLVM GCC front end compiled for your platform. There is an
|
||||
additional test suite that is optional. Each file is a TAR archive that is
|
||||
compressed with the gzip program.
|
||||
</p>
|
||||
|
||||
<p> The files are as follows:
|
||||
<dl>
|
||||
<dt>llvm-1.3.tar.gz
|
||||
<dd>This is the source code to the LLVM suite.
|
||||
<p>
|
||||
<dt><tt>llvm-1.4.tar.gz</tt></dt>
|
||||
<dd>This is the source code for the LLVM libraries and tools.<br/></dd>
|
||||
|
||||
<dt>cfrontend-1.3.source.tar.gz
|
||||
<dd>This is the source release of the GCC front end.
|
||||
<p>
|
||||
<dt><tt>llvm-test-1.4.tar.gz</tt></dt>
|
||||
<dd>This is the source code for the LLVM test suite.</tt></dd>
|
||||
|
||||
<dt>cfrontend-1.3.sparc-sun-solaris2.8.tar.gz
|
||||
<dd>This is the binary release of the GCC front end for Solaris/Sparc.
|
||||
<p>
|
||||
<dt><tt>cfrontend-1.4.source.tar.gz</tt></dt>
|
||||
<dd>This is the source release of the GCC front end.<br/></dd>
|
||||
|
||||
<dt>cfrontend-1.3.i686-redhat-linux-gnu.tar.gz
|
||||
<dd>This is the binary release of the GCC front end for Linux/x86.
|
||||
<p>
|
||||
<dt><tt>cfrontend-1.4.sparc-sun-solaris2.8.tar.gz</tt></dt>
|
||||
<dd>This is the binary release of the GCC front end for Solaris/Sparc.
|
||||
<br/></dd>
|
||||
|
||||
<dt>cfrontend-1.3.i386-unknown-freebsd5.1.tar.gz
|
||||
<dd>This is the binary release of the GCC front end for FreeBSD/x86.
|
||||
<p>
|
||||
<dt><tt>cfrontend-1.4.i686-redhat-linux-gnu.tar.gz</tt></dt>
|
||||
<dd>This is the binary release of the GCC front end for Linux/x86.<br/></dd>
|
||||
|
||||
<dt>cfrontend-1.3.powerpc-apple-darwin7.0.0.tar.gz
|
||||
<dd>This is the binary release of the GCC front end for MacOS X/PPC.
|
||||
<dt><tt>cfrontend-1.4.i386-unknown-freebsd5.1.tar.gz</tt></dt>
|
||||
<dd>This is the binary release of the GCC front end for FreeBSD/x86.<br/></dd>
|
||||
|
||||
<dt><tt>cfrontend-1.4.powerpc-apple-darwin7.6.0.tar.gz</tt></dt>
|
||||
<dd>This is the binary release of the GCC front end for MacOS X/PPC.<br/></dd>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
@@ -622,12 +633,23 @@ revision), you can specify a label. The following releases have the following
|
||||
label:</p>
|
||||
|
||||
<ul>
|
||||
<li>Release 1.4: <b>RELEASE_14</b></li>
|
||||
<li>Release 1.3: <b>RELEASE_13</b></li>
|
||||
<li>Release 1.2: <b>RELEASE_12</b></li>
|
||||
<li>Release 1.1: <b>RELEASE_11</b></li>
|
||||
<li>Release 1.0: <b>RELEASE_1</b></li>
|
||||
</ul>
|
||||
|
||||
<p>If you would like to get the LLVM test suite (a separate package as of 1.4),
|
||||
you get it from the CVS repository:</p>
|
||||
<pre>
|
||||
cd llvm/projects
|
||||
cvs -z3 -d :pserver:anon@llvm-cvs.cs.uiuc.edu:/var/cvs/llvm co llvm-test
|
||||
</pre>
|
||||
<p>By placing it in the <tt>llvm/projects</tt>, it will be automatically
|
||||
configured by the LLVM configure script as well as automatically updated when
|
||||
you run <tt>cvs update</tt>.</p>
|
||||
|
||||
<p>If you would like to get the GCC front end source code, you can also get it
|
||||
from the CVS repository:</p>
|
||||
|
||||
@@ -636,7 +658,7 @@ from the CVS repository:</p>
|
||||
</pre>
|
||||
|
||||
<p>Please note that you must follow <a href="CFEBuildInstrs.html">these
|
||||
instructions</a> to successfully build the LLVM C front-end.</p>
|
||||
instructions</a> to successfully build the LLVM GCC front-end.</p>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -676,8 +698,7 @@ location must be specified when the LLVM suite is configured.</p>
|
||||
-</tt></li>
|
||||
</ol>
|
||||
|
||||
<p>If you are using Solaris/Sparc or MacOS X/PPC, you will need to fix the
|
||||
header files:</p>
|
||||
<p>Next, you will need to fix your system header files:</p>
|
||||
|
||||
<p><tt>cd cfrontend/<i>platform</i><br>
|
||||
./fixheaders</tt></p>
|
||||
@@ -701,10 +722,10 @@ not for the faint of heart, so be forewarned.</p>
|
||||
<div class="doc_text">
|
||||
|
||||
<p>Once checked out from the CVS repository, the LLVM suite source code must be
|
||||
configured via the <tt>configure</tt> script. This script sets variables in
|
||||
<tt>llvm/Makefile.config</tt> and <tt>llvm/include/Config/config.h</tt>. It
|
||||
also populates <i>OBJ_ROOT</i> with the Makefiles needed to begin building
|
||||
LLVM.</p>
|
||||
configured via the <tt>configure</tt> script. This script sets variables in the
|
||||
various <tt>*.in</tt> files, most notably <tt>llvm/Makefile.config</tt> and
|
||||
<tt>llvm/include/Config/config.h</tt>. It also populates <i>OBJ_ROOT</i> with
|
||||
the Makefiles needed to begin building LLVM.</p>
|
||||
|
||||
<p>The following environment variables are used by the <tt>configure</tt>
|
||||
script to configure the build system:</p>
|
||||
@@ -730,47 +751,41 @@ script to configure the build system:</p>
|
||||
<p>The following options can be used to set or enable LLVM specific options:</p>
|
||||
|
||||
<dl>
|
||||
<dt><i>--with-llvmgccdir=LLVMGCCDIR</i>
|
||||
<dt><i>--with-llvmgccdir=LLVMGCCDIR</i></dt>
|
||||
<dd>
|
||||
Path to the location where the LLVM GCC front end binaries and
|
||||
associated libraries were installed. This must be specified as an
|
||||
absolute pathname.
|
||||
<p>
|
||||
<dt><i>--enable-optimized</i>
|
||||
<p></p>
|
||||
</dd>
|
||||
<dt><i>--with-tclinclude</i></dt>
|
||||
<dd>Path to the tcl include directory under which the <tt>tclsh</tt> can be
|
||||
found. Use this if you have multiple tcl installations on your machine and you
|
||||
want to use a specific one (8.x) for LLVM. LLVM only uses tcl for running the
|
||||
dejagnu based test suite in <tt>llvm/test</tt>. If you don't specify this
|
||||
option, the LLVM configure script will search for tcl 8.4 and 8.3 releases.
|
||||
<p></p>
|
||||
</dd>
|
||||
<dt><i>--enable-optimized</i></dt>
|
||||
<dd>
|
||||
Enables optimized compilation by default (debugging symbols are removed
|
||||
and GCC optimization flags are enabled). The default is to use an
|
||||
unoptimized build (also known as a debug build).
|
||||
<p>
|
||||
<dt><i>--enable-jit</i>
|
||||
<p></p>
|
||||
</dd>
|
||||
<dt><i>--enable-jit</i></dt>
|
||||
<dd>
|
||||
Compile the Just In Time (JIT) compiler functionality. This is not
|
||||
available
|
||||
on all platforms. The default is dependent on platform, so it is best
|
||||
to explicitly enable it if you want it.
|
||||
<p>
|
||||
<dt><i>--enable-spec2000</i>
|
||||
<dt><i>--enable-spec2000=<<tt>directory</tt>></i>
|
||||
<dd>
|
||||
Enable the use of SPEC2000 when testing LLVM. This is disabled by default
|
||||
(unless <tt>configure</tt> finds SPEC2000 installed). By specifying
|
||||
<tt>directory</tt>, you can tell configure where to find the SPEC2000
|
||||
benchmarks. If <tt>directory</tt> is left unspecified, <tt>configure</tt>
|
||||
uses the default value
|
||||
<tt>/home/vadve/shared/benchmarks/speccpu2000/benchspec</tt>.
|
||||
<p>
|
||||
<dt><i>--enable-spec95</i>
|
||||
<dt><i>--enable-spec95=<<tt>directory</tt>></i>
|
||||
<dd>
|
||||
Enable the use of SPEC95 when testing LLVM. It is similar to the
|
||||
<i>--enable-spec2000</i> option.
|
||||
<p>
|
||||
<dt><i>--enable-povray</i>
|
||||
<dt><i>--enable-povray=<<tt>directory</tt>></i>
|
||||
<dd>
|
||||
Enable the use of Povray as an external test. Versions of Povray written
|
||||
in C should work. This option is similar to the <i>--enable-spec2000</i>
|
||||
option.
|
||||
<p></p>
|
||||
</dd>
|
||||
<dt><i>--enable-doxygen</i></dt>
|
||||
<dd>Look for the doxygen program and enable construction of doxygen based
|
||||
documentation from the source code. This is disabled by default because
|
||||
generating the documentation can take a long time and producess 100s of
|
||||
megabytes of output.</dd>
|
||||
</dl>
|
||||
|
||||
<p>To configure LLVM, follow these steps:</p>
|
||||
@@ -783,13 +798,13 @@ script to configure the build system:</p>
|
||||
|
||||
<li>Run the <tt>configure</tt> script located in the LLVM source tree:
|
||||
<br>
|
||||
<tt><i>SRC_ROOT</i>/configure</tt>
|
||||
<tt><i>SRC_ROOT</i>/configure --prefix=/install/path [other options]</tt>
|
||||
<p>
|
||||
</ol>
|
||||
|
||||
<p>In addition to running <tt>configure</tt>, you must set the
|
||||
<tt>LLVM_LIB_SEARCH_PATH</tt> environment variable in your startup scripts.
|
||||
This environment variable is used to locate "system" libraries like
|
||||
<tt>LLVM_LIB_SEARCH_PATH</tt> environment variable in your startup shell
|
||||
scripts. This environment variable is used to locate "system" libraries like
|
||||
"<tt>-lc</tt>" and "<tt>-lm</tt>" when linking. This variable should be set to
|
||||
the absolute path of the <tt>bytecode-libs</tt> subdirectory of the GCC front
|
||||
end, or <i>LLVMGCCDIR</i>/<tt>bytecode-libs</tt>. For example, one might set
|
||||
@@ -841,7 +856,7 @@ builds:</p>
|
||||
<p><tt>gmake</tt></p>
|
||||
|
||||
<p>If the build fails, please <a href="#brokengcc">check here</a> to see if you
|
||||
are using a known broken version of GCC to compile LLVM with.</p>
|
||||
are using a version of GCC that is known not to compile LLVM.</p>
|
||||
|
||||
<p>
|
||||
If you have multiple processors in your machine, you may wish to use some of
|
||||
@@ -860,7 +875,7 @@ source code:</p>
|
||||
generated C/C++ files, libraries, and executables.
|
||||
<p>
|
||||
|
||||
<dt><tt>gmake distclean</tt>
|
||||
<dt><tt>gmake dist-clean</tt>
|
||||
<dd>
|
||||
Removes everything that <tt>gmake clean</tt> does, but also removes files
|
||||
generated by <tt>configure</tt>. It attempts to return the source tree to the
|
||||
@@ -869,11 +884,13 @@ source code:</p>
|
||||
|
||||
<dt><tt>gmake install</tt>
|
||||
<dd>
|
||||
Installs LLVM libraries and tools in a heirarchy under $PREFIX, specified with
|
||||
<tt>./configure --prefix=[dir]</tt>, defaults to <tt>/usr/local</tt>.
|
||||
Installs LLVM header files, libraries, tools, and documentation in a
|
||||
hierarchy
|
||||
under $PREFIX, specified with <tt>./configure --prefix=[dir]</tt>, which
|
||||
defaults to <tt>/usr/local</tt>.
|
||||
<p>
|
||||
|
||||
<dt><tt>gmake -C runtime install</tt>
|
||||
<dt><tt>gmake -C runtime install-bytecode</tt>
|
||||
<dd>
|
||||
Assuming you built LLVM into $OBJDIR, when this command is run, it will
|
||||
install bytecode libraries into the GCC front end's bytecode library
|
||||
@@ -882,6 +899,10 @@ source code:</p>
|
||||
<p>
|
||||
</dl>
|
||||
|
||||
<p>Please see the <a href="MakefileGuide.html">Makefile Guide</a> for further
|
||||
details on these <tt>make</tt> targets and descriptions of other targets
|
||||
available.</p>
|
||||
|
||||
<p>It is also possible to override default values from <tt>configure</tt> by
|
||||
declaring variables on the command line. The following are some examples:</p>
|
||||
|
||||
@@ -900,6 +921,11 @@ declaring variables on the command line. The following are some examples:</p>
|
||||
<dd>
|
||||
Print what <tt>gmake</tt> is doing on standard output.
|
||||
<p>
|
||||
|
||||
<dt><tt>gmake TOOL_VERBOSE=1</tt></dt>
|
||||
<dd>Ask each tool invoked by the makefiles to print out what it is doing on
|
||||
the standard output. This also implies <tt>VERBOSE=1</tt>.
|
||||
<p></dd>
|
||||
</dl>
|
||||
|
||||
<p>Every directory in the LLVM object tree includes a <tt>Makefile</tt> to build
|
||||
@@ -941,9 +967,9 @@ named after the build type:</p>
|
||||
<dd>
|
||||
<dl>
|
||||
<dt>Tools
|
||||
<dd><tt><i>OBJ_ROOT</i>/tools/Debug</tt>
|
||||
<dd><tt><i>OBJ_ROOT</i>/Debug/bin</tt>
|
||||
<dt>Libraries
|
||||
<dd><tt><i>OBJ_ROOT</i>/lib/Debug</tt>
|
||||
<dd><tt><i>OBJ_ROOT</i>/Debug/lib</tt>
|
||||
</dl>
|
||||
<p>
|
||||
|
||||
@@ -951,9 +977,9 @@ named after the build type:</p>
|
||||
<dd>
|
||||
<dl>
|
||||
<dt>Tools
|
||||
<dd><tt><i>OBJ_ROOT</i>/tools/Release</tt>
|
||||
<dd><tt><i>OBJ_ROOT</i>/Release/bin</tt>
|
||||
<dt>Libraries
|
||||
<dd><tt><i>OBJ_ROOT</i>/lib/Release</tt>
|
||||
<dd><tt><i>OBJ_ROOT</i>/Release/lib</tt>
|
||||
</dl>
|
||||
<p>
|
||||
|
||||
@@ -961,9 +987,9 @@ named after the build type:</p>
|
||||
<dd>
|
||||
<dl>
|
||||
<dt>Tools
|
||||
<dd><tt><i>OBJ_ROOT</i>/tools/Profile</tt>
|
||||
<dd><tt><i>OBJ_ROOT</i>/Profile/bin</tt>
|
||||
<dt>Libraries
|
||||
<dd><tt><i>OBJ_ROOT</i>/lib/Profile</tt>
|
||||
<dd><tt><i>OBJ_ROOT</i>/Profile/lib</tt>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
@@ -978,7 +1004,8 @@ named after the build type:</p>
|
||||
|
||||
<p>
|
||||
If you're running on a linux system that supports the "<a
|
||||
href="http://www.tat.physik.uni-tuebingen.de/~rguenth/linux/binfmt_misc.html">binfmt_misc</a>"
|
||||
href="http://www.tat.physik.uni-tuebingen.de/~rguenth/linux/binfmt_misc.html">
|
||||
binfmt_misc</a>"
|
||||
module, and you have root access on the system, you can set your system up to
|
||||
execute LLVM bytecode files directly. To do this, use commands like this (the
|
||||
first command may not be required if you are already using the module):</p>
|
||||
@@ -1015,17 +1042,20 @@ The following is a brief introduction to code layout:</p>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="cvsdir"><tt>CVS</tt> directories</a></div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>Every directory checked out of CVS will contain a <tt>CVS</tt> directory; for
|
||||
the most part these can just be ignored.</p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="examples"><tt>llvm/examples</tt></a></div>
|
||||
<div class="doc_text">
|
||||
<p>This directory contains some simple examples of how to use the LLVM IR and
|
||||
JIT.</p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="include"><tt>llvm/include</tt></a></div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>This directory contains public header files exported from the LLVM
|
||||
@@ -1054,7 +1084,6 @@ library. The three main subdirectories of this directory are:</p>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="lib"><tt>llvm/lib</tt></a></div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>This directory contains most of the source files of the LLVM system. In LLVM,
|
||||
@@ -1114,6 +1143,16 @@ different <a href="#tools">tools</a>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="projects"><tt>llvm/projects</tt></a></div>
|
||||
<div class="doc_text">
|
||||
<p>This directory contains projects that are not strictly part of LLVM but are
|
||||
shipped with LLVM. This is also the directory where you should create your own
|
||||
LLVM-based projects. See <tt>llvm/projects/sample</tt> for an example of how
|
||||
to set up your own project. See <tt>llvm/projects/Stacker</tt> for a fully
|
||||
functional example of a compiler front end.</p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="runtime"><tt>llvm/runtime</tt></a></div>
|
||||
<div class="doc_text">
|
||||
@@ -1139,9 +1178,10 @@ end to compile.</p>
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="llvmtest"><tt>llvm-test</tt></a></div>
|
||||
<div class="doc_text">
|
||||
<p>This is not a directory in the normal llvm module, it is a separate CVS
|
||||
<p>This is not a directory in the normal llvm module; it is a separate CVS
|
||||
module that must be checked out (usually to <tt>projects/llvm-test</tt>). This
|
||||
module contains a comprehensive correctness, performance and benchmarking test
|
||||
module contains a comprehensive correctness, performance, and benchmarking
|
||||
test
|
||||
suite for LLVM. It is a separate CVS module because not every LLVM user is
|
||||
interested in downloading or building such a comprehensive test. For further
|
||||
details on this test suite, please see the
|
||||
@@ -1179,7 +1219,9 @@ information is in the <a href="CommandGuide/index.html">Command Guide</a>.</p>
|
||||
pre-processing, translation, optimization, assembly, and linking of programs
|
||||
all from one command line. <tt>llvmc</tt> also takes care of processing the
|
||||
dependent libraries found in bytecode. This reduces the need to get the
|
||||
traditional <tt>-l<name></tt> options right on the command line.</dd>
|
||||
traditional <tt>-l<name></tt> options right on the command line. Please
|
||||
note that this tool is new in 1.4 and considered experimental. It will be
|
||||
fully supported in 1.5.</dd>
|
||||
|
||||
<dt><tt><b>llvm-ar</b></tt></dt>
|
||||
<dd>The archiver produces an archive containing
|
||||
@@ -1194,6 +1236,14 @@ information is in the <a href="CommandGuide/index.html">Command Guide</a>.</p>
|
||||
<dd>The disassembler transforms the LLVM bytecode to human readable
|
||||
LLVM assembly.</dd>
|
||||
|
||||
<dt><tt><b>llvm-ld</b></tt></dt>
|
||||
<dd><tt>llvm-ld</tt> is very similar to gccld and provides a general purpose
|
||||
and extensible linker for LLVM. This is the linker invoked by <tt>llvmc</tt>.
|
||||
It allows optimization modules to be loaded so that language specific
|
||||
optimizations can be applied at link time. Please note that this tool is new
|
||||
in LLVM 1.4 and still considered experimental. It will be fully supported in
|
||||
LLVM 1.5.</dd>
|
||||
|
||||
<dt><tt><b>llvm-link</b></tt></dt>
|
||||
<dd><tt>llvm-link</tt>, not surprisingly, links multiple LLVM modules into
|
||||
a single program.</dd>
|
||||
@@ -1203,7 +1253,7 @@ information is in the <a href="CommandGuide/index.html">Command Guide</a>.</p>
|
||||
can directly execute LLVM bytecode (although very slowly...). In addition
|
||||
to a simple interpreter, <tt>lli</tt> also has a tracing mode (entered by
|
||||
specifying <tt>-trace</tt> on the command line). Finally, for
|
||||
architectures that support it (currently only x86 and Sparc), by default,
|
||||
architectures that support it (currently x86, Sparc, and PowerPC), by default,
|
||||
<tt>lli</tt> will function as a Just-In-Time compiler (if the
|
||||
functionality was compiled in), and will execute the code <i>much</i>
|
||||
faster than the interpreter.</dd>
|
||||
@@ -1331,6 +1381,15 @@ are code generators for parts of LLVM infrastructure.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="win32"><tt>llvm/win32</tt></a></div>
|
||||
<div class="doc_text">
|
||||
<p>This directory contains build scripts and project files for use with
|
||||
Visual C++. This allows developers on Windows to build LLVM without the need
|
||||
for Cygwin. The contents of this directory should be considered experimental
|
||||
at this time.
|
||||
</p>
|
||||
</div>
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section">
|
||||
<a name="tutorial">An Example Using the LLVM Tool Chain</a>
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
<title>LLVM vs. the World - Comparing Compilers to Compilers</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="doc_title">
|
||||
LLVM vs. the World - Comparing Compilers to Compilers
|
||||
</div>
|
||||
|
||||
<ol>
|
||||
<li><a href="#introduction">Introduction</a></li>
|
||||
<li><a href="#generalapplicability">General Applicability</a></li>
|
||||
<li><a href="#typesystem">Type System</a></li>
|
||||
<li><a href="#dataflowinformation">Control-flow and Data-flow Information</a></li>
|
||||
<li><a href="#registers">Registers</a></li>
|
||||
<li><a href="#programmerinterface">Programmer Interface</a></li>
|
||||
<li><a href="#codeemission">Machine Code Emission</a></li>
|
||||
</ol>
|
||||
|
||||
<div class="doc_author">
|
||||
<p>Written by Brian R. Gaeke</p>
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section">
|
||||
<a name="introduction">Introduction</a>
|
||||
</div>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_text">
|
||||
<p>Whether you are a stranger to LLVM or not, and whether you are considering
|
||||
using it for your projects or not, you may find it useful to understand how we
|
||||
compare ourselves to other well-known compilers. The following list of points
|
||||
should help you understand -- from our point of view -- some of the important
|
||||
ways in which we see LLVM as different from other selected compilers and
|
||||
code generation systems.</p>
|
||||
|
||||
<p>At the moment, we only compare ourselves below to <a
|
||||
href="http://gcc.gnu.org/">GCC</a> and <a
|
||||
href="http://www.gnu.org/software/lightning/">GNU lightning</a>, but we will try
|
||||
to revise and expand it as our knowledge and experience permit. Contributions are
|
||||
welcome.</p>
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section">
|
||||
<a name="generalapplicability">General Applicability</a>
|
||||
</div>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_text">
|
||||
<p>GNU lightning: Only currently usable for dynamic runtime emission of binary
|
||||
machine code to memory. Supports one backend at a time.</p>
|
||||
|
||||
<p>LLVM: Supports compilation of C and C++ (with more languages coming soon),
|
||||
strong SSA-based optimization at compile-time, link-time, run-time, and
|
||||
off-line, and multiple platform backends with Just-in-Time and ahead-of-time
|
||||
compilation frameworks. (See our document on <a
|
||||
href="http://llvm.cs.uiuc.edu/pubs/2004-01-30-CGO-LLVM.html">Lifelong
|
||||
Code Optimization</a> for more.)</p>
|
||||
|
||||
<p>GCC: Many relatively mature platform backends support assembly-language code
|
||||
generation from many source languages. No run-time compilation
|
||||
support.</p>
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section">
|
||||
<a name="typesystem">Type System</a>
|
||||
</div>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_text">
|
||||
<p>GNU lightning: C integer types and "void *" are supported. No type checking
|
||||
is performed. Explicit type casts are not typically necessary unless the
|
||||
underlying machine-specific types are distinct (e.g., sign- or zero-extension is
|
||||
apparently necessary, but casting "int" to "void *" would not be.)
|
||||
Floating-point support may not work on all platforms (it does not appear to be
|
||||
documented in the latest release).</p>
|
||||
|
||||
<p>LLVM: Compositional type system based on C types, supporting structures,
|
||||
opaque types, and C integer and floating point types. Explicit cast instructions
|
||||
are required to transform a value from one type to another.</p>
|
||||
|
||||
<p>GCC: Union of high-level types including those used in Pascal, C, C++, Ada,
|
||||
Java, and FORTRAN.</p>
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section">
|
||||
<a name="dataflowinformation">Control-flow and Data-flow Information</a>
|
||||
</div>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_text">
|
||||
<p>GNU lightning: No data-flow information encoded in the generated program. No
|
||||
support for calculating CFG or def-use chains over generated programs.</p>
|
||||
|
||||
<p>LLVM: Scalar values in Static Single-Assignment form; def-use chains and CFG
|
||||
always implicitly available and automatically kept up to date.</p>
|
||||
|
||||
<p>GCC: Trees and RTL do not directly encode data-flow info; but def-use chains
|
||||
and CFGs can be calculated on the side. They are not automatically kept up to
|
||||
date.</p>
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section">
|
||||
<a name="registers">Registers</a>
|
||||
</div>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_text">
|
||||
<p>GNU lightning: Very small fixed register set -- it takes the least common
|
||||
denominator of supported platforms; basically it inherits its tiny register set
|
||||
from IA-32, unnecessarily crippling targets like PowerPC with a large register
|
||||
set.</p>
|
||||
|
||||
<p>LLVM: An infinite register set, reduced to a particular platform's finite
|
||||
register set by register allocator.</p>
|
||||
|
||||
<p>GCC: Trees and RTL provide an arbitrarily large set of values. Reduced to a
|
||||
particular platform's finite register set by register allocator.</p>
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section">
|
||||
<a name="programmerinterface">Programmer Interface</a>
|
||||
</div>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_text">
|
||||
<p>GNU lightning: Library interface based on C preprocessor macros that emit
|
||||
binary code for a particular instruction to memory. No support for manipulating
|
||||
code before emission.</p>
|
||||
|
||||
<p>LLVM: Library interface based on classes representing platform-independent
|
||||
intermediate code (Instruction) and platform-dependent code (MachineInstr) which
|
||||
can be manipulated arbitrarily and then emitted to memory.</p>
|
||||
|
||||
<p>GCC: Internal header file interface (tree.h) to abstract syntax trees,
|
||||
representing roughly the union of all possible supported source-language
|
||||
constructs; also, an internal header file interface (rtl.h, rtl.def) to a
|
||||
low-level IR called RTL which represents roughly the union of all possible
|
||||
target machine instructions.</p>
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section">
|
||||
<a name="codeemission">Machine Code Emission</a>
|
||||
</div>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_text">
|
||||
<p>GNU lightning: Only supports binary machine code emission to memory.</p>
|
||||
|
||||
<p>LLVM: Supports writing out assembly language to a file, and binary machine
|
||||
code to memory, from the same back-end.</p>
|
||||
|
||||
<p>GCC: Supports writing out assembly language to a file. No support for
|
||||
emitting machine code to memory.</p>
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<hr>
|
||||
<div class="doc_footer">
|
||||
<address>Brian R. Gaeke</address>
|
||||
<a href="http://llvm.cs.uiuc.edu">The LLVM Compiler Infrastructure</a>
|
||||
<br>
|
||||
Last modified: $Date$
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -17,6 +17,14 @@
|
||||
<li><a href="#abstract">Abstract</a></li>
|
||||
<li><a href="#introduction">Introduction</a></li>
|
||||
<li><a href="#identifiers">Identifiers</a></li>
|
||||
<li><a href="#highlevel">High Level Structure</a>
|
||||
<ol>
|
||||
<li><a href="#modulestructure">Module Structure</a></li>
|
||||
<li><a href="#linkage">Linkage Types</a></li>
|
||||
<li><a href="#globalvars">Global Variables</a></li>
|
||||
<li><a href="#functionstructure">Function Structure</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="#typesystem">Type System</a>
|
||||
<ol>
|
||||
<li><a href="#t_primitive">Primitive Types</a>
|
||||
@@ -35,11 +43,13 @@
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="#highlevel">High Level Structure</a>
|
||||
<li><a href="#constants">Constants</a>
|
||||
<ol>
|
||||
<li><a href="#modulestructure">Module Structure</a></li>
|
||||
<li><a href="#globalvars">Global Variables</a></li>
|
||||
<li><a href="#functionstructure">Function Structure</a></li>
|
||||
<li><a href="#simpleconstants">Simple Constants</a>
|
||||
<li><a href="#aggregateconstants">Aggregate Constants</a>
|
||||
<li><a href="#globalconstants">Global Variable and Function Addresses</a>
|
||||
<li><a href="#undefvalues">Undefined Values</a>
|
||||
<li><a href="#constantexprs">Constant Expressions</a>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="#instref">Instruction Reference</a>
|
||||
@@ -218,71 +228,256 @@ the parser.</p>
|
||||
purposes:</p>
|
||||
|
||||
<ol>
|
||||
<li>Numeric constants are represented as you would expect: 12, -3
|
||||
123.421, etc. Floating point constants have an optional hexadecimal
|
||||
notation.</li>
|
||||
<li>Named values are represented as a string of characters with a '%'
|
||||
prefix. For example, %foo, %DivisionByZero,
|
||||
%a.really.long.identifier. The actual regular expression used is '<tt>%[a-zA-Z$._][a-zA-Z$._0-9]*</tt>'.
|
||||
Identifiers which require other characters in their names can be
|
||||
surrounded with quotes. In this way, anything except a <tt>"</tt>
|
||||
character can be used in a name.</li>
|
||||
<li>Unnamed values are represented as an unsigned numeric value with
|
||||
a '%' prefix. For example, %12, %2, %44.</li>
|
||||
<li>Named values are represented as a string of characters with a '%' prefix.
|
||||
For example, %foo, %DivisionByZero, %a.really.long.identifier. The actual
|
||||
regular expression used is '<tt>%[a-zA-Z$._][a-zA-Z$._0-9]*</tt>'.
|
||||
Identifiers which require other characters in their names can be surrounded
|
||||
with quotes. In this way, anything except a <tt>"</tt> character can be used
|
||||
in a name.</li>
|
||||
|
||||
<li>Unnamed values are represented as an unsigned numeric value with a '%'
|
||||
prefix. For example, %12, %2, %44.</li>
|
||||
|
||||
<li>Constants, which are described in a <a href="#constants">section about
|
||||
constants</a>, below.</li>
|
||||
</ol>
|
||||
<p>LLVM requires that values start with a '%' sign for two reasons:
|
||||
Compilers don't need to worry about name clashes with reserved words,
|
||||
and the set of reserved words may be expanded in the future without
|
||||
penalty. Additionally, unnamed identifiers allow a compiler to quickly
|
||||
come up with a temporary variable without having to avoid symbol table
|
||||
conflicts.</p>
|
||||
|
||||
<p>LLVM requires that values start with a '%' sign for two reasons: Compilers
|
||||
don't need to worry about name clashes with reserved words, and the set of
|
||||
reserved words may be expanded in the future without penalty. Additionally,
|
||||
unnamed identifiers allow a compiler to quickly come up with a temporary
|
||||
variable without having to avoid symbol table conflicts.</p>
|
||||
|
||||
<p>Reserved words in LLVM are very similar to reserved words in other
|
||||
languages. There are keywords for different opcodes ('<tt><a
|
||||
href="#i_add">add</a></tt>', '<tt><a href="#i_cast">cast</a></tt>', '<tt><a
|
||||
href="#i_ret">ret</a></tt>', etc...), for primitive type names ('<tt><a
|
||||
href="#t_void">void</a></tt>', '<tt><a href="#t_uint">uint</a></tt>',
|
||||
etc...), and others. These reserved words cannot conflict with
|
||||
variable names, because none of them start with a '%' character.</p>
|
||||
<p>Here is an example of LLVM code to multiply the integer variable '<tt>%X</tt>'
|
||||
by 8:</p>
|
||||
href="#i_add">add</a></tt>', '<tt><a href="#i_cast">cast</a></tt>', '<tt><a
|
||||
href="#i_ret">ret</a></tt>', etc...), for primitive type names ('<tt><a
|
||||
href="#t_void">void</a></tt>', '<tt><a href="#t_uint">uint</a></tt>', etc...),
|
||||
and others. These reserved words cannot conflict with variable names, because
|
||||
none of them start with a '%' character.</p>
|
||||
|
||||
<p>Here is an example of LLVM code to multiply the integer variable
|
||||
'<tt>%X</tt>' by 8:</p>
|
||||
|
||||
<p>The easy way:</p>
|
||||
<pre> %result = <a href="#i_mul">mul</a> uint %X, 8<br></pre>
|
||||
|
||||
<pre>
|
||||
%result = <a href="#i_mul">mul</a> uint %X, 8
|
||||
</pre>
|
||||
|
||||
<p>After strength reduction:</p>
|
||||
<pre> %result = <a href="#i_shl">shl</a> uint %X, ubyte 3<br></pre>
|
||||
|
||||
<pre>
|
||||
%result = <a href="#i_shl">shl</a> uint %X, ubyte 3
|
||||
</pre>
|
||||
|
||||
<p>And the hard way:</p>
|
||||
<pre> <a href="#i_add">add</a> uint %X, %X <i>; yields {uint}:%0</i>
|
||||
<a
|
||||
href="#i_add">add</a> uint %0, %0 <i>; yields {uint}:%1</i>
|
||||
%result = <a
|
||||
href="#i_add">add</a> uint %1, %1<br></pre>
|
||||
|
||||
<pre>
|
||||
<a href="#i_add">add</a> uint %X, %X <i>; yields {uint}:%0</i>
|
||||
<a href="#i_add">add</a> uint %0, %0 <i>; yields {uint}:%1</i>
|
||||
%result = <a href="#i_add">add</a> uint %1, %1
|
||||
</pre>
|
||||
|
||||
<p>This last way of multiplying <tt>%X</tt> by 8 illustrates several
|
||||
important lexical features of LLVM:</p>
|
||||
|
||||
<ol>
|
||||
<li>Comments are delimited with a '<tt>;</tt>' and go until the end
|
||||
of line.</li>
|
||||
<li>Unnamed temporaries are created when the result of a computation
|
||||
is not assigned to a named value.</li>
|
||||
|
||||
<li>Comments are delimited with a '<tt>;</tt>' and go until the end of
|
||||
line.</li>
|
||||
|
||||
<li>Unnamed temporaries are created when the result of a computation is not
|
||||
assigned to a named value.</li>
|
||||
|
||||
<li>Unnamed temporaries are numbered sequentially</li>
|
||||
|
||||
</ol>
|
||||
<p>...and it also show a convention that we follow in this document.
|
||||
When demonstrating instructions, we will follow an instruction with a
|
||||
comment that defines the type and name of value produced. Comments are
|
||||
shown in italic text.</p>
|
||||
<p>The one non-intuitive notation for constants is the optional
|
||||
hexidecimal form of floating point constants. For example, the form '<tt>double
|
||||
0x432ff973cafa8000</tt>' is equivalent to (but harder to read than) '<tt>double
|
||||
4.5e+15</tt>' which is also supported by the parser. The only time
|
||||
hexadecimal floating point constants are useful (and the only time that
|
||||
they are generated by the disassembler) is when an FP constant has to
|
||||
be emitted that is not representable as a decimal floating point number
|
||||
exactly. For example, NaN's, infinities, and other special cases are
|
||||
represented in their IEEE hexadecimal format so that assembly and
|
||||
disassembly do not cause any bits to change in the constants.</p>
|
||||
|
||||
<p>...and it also show a convention that we follow in this document. When
|
||||
demonstrating instructions, we will follow an instruction with a comment that
|
||||
defines the type and name of value produced. Comments are shown in italic
|
||||
text.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section"> <a name="highlevel">High Level Structure</a> </div>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"> <a name="modulestructure">Module Structure</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>LLVM programs are composed of "Module"s, each of which is a
|
||||
translation unit of the input programs. Each module consists of
|
||||
functions, global variables, and symbol table entries. Modules may be
|
||||
combined together with the LLVM linker, which merges function (and
|
||||
global variable) definitions, resolves forward declarations, and merges
|
||||
symbol table entries. Here is an example of the "hello world" module:</p>
|
||||
|
||||
<pre><i>; Declare the string constant as a global constant...</i>
|
||||
<a href="#identifiers">%.LC0</a> = <a href="#linkage_internal">internal</a> <a
|
||||
href="#globalvars">constant</a> <a href="#t_array">[13 x sbyte]</a> c"hello world\0A\00" <i>; [13 x sbyte]*</i>
|
||||
|
||||
<i>; External declaration of the puts function</i>
|
||||
<a href="#functionstructure">declare</a> int %puts(sbyte*) <i>; int(sbyte*)* </i>
|
||||
|
||||
<i>; Definition of main function</i>
|
||||
int %main() { <i>; int()* </i>
|
||||
<i>; Convert [13x sbyte]* to sbyte *...</i>
|
||||
%cast210 = <a
|
||||
href="#i_getelementptr">getelementptr</a> [13 x sbyte]* %.LC0, long 0, long 0 <i>; sbyte*</i>
|
||||
|
||||
<i>; Call puts function to write out the string to stdout...</i>
|
||||
<a
|
||||
href="#i_call">call</a> int %puts(sbyte* %cast210) <i>; int</i>
|
||||
<a
|
||||
href="#i_ret">ret</a> int 0<br>}<br></pre>
|
||||
|
||||
<p>This example is made up of a <a href="#globalvars">global variable</a>
|
||||
named "<tt>.LC0</tt>", an external declaration of the "<tt>puts</tt>"
|
||||
function, and a <a href="#functionstructure">function definition</a>
|
||||
for "<tt>main</tt>".</p>
|
||||
|
||||
<p>In general, a module is made up of a list of global values,
|
||||
where both functions and global variables are global values. Global values are
|
||||
represented by a pointer to a memory location (in this case, a pointer to an
|
||||
array of char, and a pointer to a function), and have one of the following <a
|
||||
href="#linkage">linkage types</a>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
<a name="linkage">Linkage Types</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>
|
||||
All Global Variables and Functions have one of the following types of linkage:
|
||||
</p>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><tt><b><a name="linkage_internal">internal</a></b></tt> </dt>
|
||||
|
||||
<dd>Global values with internal linkage are only directly accessible by
|
||||
objects in the current module. In particular, linking code into a module with
|
||||
an internal global value may cause the internal to be renamed as necessary to
|
||||
avoid collisions. Because the symbol is internal to the module, all
|
||||
references can be updated. This corresponds to the notion of the
|
||||
'<tt>static</tt>' keyword in C, or the idea of "anonymous namespaces" in C++.
|
||||
</dd>
|
||||
|
||||
<dt><tt><b><a name="linkage_linkonce">linkonce</a></b></tt>: </dt>
|
||||
|
||||
<dd>"<tt>linkonce</tt>" linkage is similar to <tt>internal</tt> linkage, with
|
||||
the twist that linking together two modules defining the same
|
||||
<tt>linkonce</tt> globals will cause one of the globals to be discarded. This
|
||||
is typically used to implement inline functions. Unreferenced
|
||||
<tt>linkonce</tt> globals are allowed to be discarded.
|
||||
</dd>
|
||||
|
||||
<dt><tt><b><a name="linkage_weak">weak</a></b></tt>: </dt>
|
||||
|
||||
<dd>"<tt>weak</tt>" linkage is exactly the same as <tt>linkonce</tt> linkage,
|
||||
except that unreferenced <tt>weak</tt> globals may not be discarded. This is
|
||||
used to implement constructs in C such as "<tt>int X;</tt>" at global scope.
|
||||
</dd>
|
||||
|
||||
<dt><tt><b><a name="linkage_appending">appending</a></b></tt>: </dt>
|
||||
|
||||
<dd>"<tt>appending</tt>" linkage may only be applied to global variables of
|
||||
pointer to array type. When two global variables with appending linkage are
|
||||
linked together, the two global arrays are appended together. This is the
|
||||
LLVM, typesafe, equivalent of having the system linker append together
|
||||
"sections" with identical names when .o files are linked.
|
||||
</dd>
|
||||
|
||||
<dt><tt><b><a name="linkage_external">externally visible</a></b></tt>:</dt>
|
||||
|
||||
<dd>If none of the above identifiers are used, the global is externally
|
||||
visible, meaning that it participates in linkage and can be used to resolve
|
||||
external symbol references.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<p><a name="linkage_external">For example, since the "<tt>.LC0</tt>"
|
||||
variable is defined to be internal, if another module defined a "<tt>.LC0</tt>"
|
||||
variable and was linked with this one, one of the two would be renamed,
|
||||
preventing a collision. Since "<tt>main</tt>" and "<tt>puts</tt>" are
|
||||
external (i.e., lacking any linkage declarations), they are accessible
|
||||
outside of the current module. It is illegal for a function <i>declaration</i>
|
||||
to have any linkage type other than "externally visible".</a></p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
<a name="globalvars">Global Variables</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>Global variables define regions of memory allocated at compilation
|
||||
time instead of run-time. Global variables may optionally be
|
||||
initialized. A variable may be defined as a global "constant", which
|
||||
indicates that the contents of the variable will never be modified
|
||||
(enabling better optimization, allowing the global data to be placed in the
|
||||
read-only section of an executable, etc).</p>
|
||||
|
||||
<p>As SSA values, global variables define pointer values that are in
|
||||
scope (i.e. they dominate) all basic blocks in the program. Global
|
||||
variables always define a pointer to their "content" type because they
|
||||
describe a region of memory, and all memory objects in LLVM are
|
||||
accessed through pointers.</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
<a name="functionstructure">Functions</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>LLVM function definitions are composed of a (possibly empty) argument list,
|
||||
an opening curly brace, a list of basic blocks, and a closing curly brace. LLVM
|
||||
function declarations are defined with the "<tt>declare</tt>" keyword, a
|
||||
function name, and a function signature.</p>
|
||||
|
||||
<p>A function definition contains a list of basic blocks, forming the CFG for
|
||||
the function. Each basic block may optionally start with a label (giving the
|
||||
basic block a symbol table entry), contains a list of instructions, and ends
|
||||
with a <a href="#terminators">terminator</a> instruction (such as a branch or
|
||||
function return).</p>
|
||||
|
||||
<p>The first basic block in program is special in two ways: it is immediately
|
||||
executed on entrance to the function, and it is not allowed to have predecessor
|
||||
basic blocks (i.e. there can not be any branches to the entry block of a
|
||||
function). Because the block can have no predecessors, it also cannot have any
|
||||
<a href="#i_phi">PHI nodes</a>.</p>
|
||||
|
||||
<p>LLVM functions are identified by their name and type signature. Hence, two
|
||||
functions with the same name but different parameter lists or return values are
|
||||
considered different functions, and LLVM will resolves references to each
|
||||
appropriately.</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section"> <a name="typesystem">Type System</a> </div>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The LLVM type system is one of the most important features of the
|
||||
intermediate representation. Being typed enables a number of
|
||||
optimizations to be performed on the IR directly, without having to do
|
||||
@@ -290,9 +485,9 @@ extra analyses on the side before the transformation. A strong type
|
||||
system makes it easier to read the generated code and enables novel
|
||||
analyses and transformations that are not feasible to perform on normal
|
||||
three address code representations.</p>
|
||||
<!-- The written form for the type system was heavily influenced by the
|
||||
syntactic problems with types in the C language<sup><a
|
||||
href="#rw_stroustrup">1</a></sup>.<p> --> </div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"> <a name="t_primitive">Primitive Types</a> </div>
|
||||
<div class="doc_text">
|
||||
@@ -378,25 +573,39 @@ produced by instructions, passed as arguments, or used as operands to
|
||||
instructions. This means that all structures and arrays must be
|
||||
manipulated either by pointer or by component.</p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"> <a name="t_derived">Derived Types</a> </div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The real power in LLVM comes from the derived types in the system.
|
||||
This is what allows a programmer to represent arrays, functions,
|
||||
pointers, and other useful types. Note that these derived types may be
|
||||
recursive: For example, it is possible to have a two dimensional array.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"> <a name="t_array">Array Type</a> </div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<h5>Overview:</h5>
|
||||
|
||||
<p>The array type is a very simple derived type that arranges elements
|
||||
sequentially in memory. The array type requires a size (number of
|
||||
elements) and an underlying data type.</p>
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<pre> [<# elements> x <elementtype>]<br></pre>
|
||||
|
||||
<pre>
|
||||
[<# elements> x <elementtype>]
|
||||
</pre>
|
||||
|
||||
<p>The number of elements is a constant integer value, elementtype may
|
||||
be any type with a size.</p>
|
||||
|
||||
<h5>Examples:</h5>
|
||||
<table class="layout">
|
||||
<tr class="layout">
|
||||
@@ -558,179 +767,212 @@ be any integral or floating point type.</p>
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section"> <a name="highlevel">High Level Structure</a> </div>
|
||||
<div class="doc_section"> <a name="constants">Constants</a> </div>
|
||||
<!-- *********************************************************************** -->
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"> <a name="modulestructure">Module Structure</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<p>LLVM programs are composed of "Module"s, each of which is a
|
||||
translation unit of the input programs. Each module consists of
|
||||
functions, global variables, and symbol table entries. Modules may be
|
||||
combined together with the LLVM linker, which merges function (and
|
||||
global variable) definitions, resolves forward declarations, and merges
|
||||
symbol table entries. Here is an example of the "hello world" module:</p>
|
||||
<pre><i>; Declare the string constant as a global constant...</i>
|
||||
<a href="#identifiers">%.LC0</a> = <a href="#linkage_internal">internal</a> <a
|
||||
href="#globalvars">constant</a> <a href="#t_array">[13 x sbyte]</a> c"hello world\0A\00" <i>; [13 x sbyte]*</i>
|
||||
|
||||
<i>; External declaration of the puts function</i>
|
||||
<a href="#functionstructure">declare</a> int %puts(sbyte*) <i>; int(sbyte*)* </i>
|
||||
<p>LLVM has several different basic types of constants. This section describes
|
||||
them all and their syntax.</p>
|
||||
|
||||
<i>; Definition of main function</i>
|
||||
int %main() { <i>; int()* </i>
|
||||
<i>; Convert [13x sbyte]* to sbyte *...</i>
|
||||
%cast210 = <a
|
||||
href="#i_getelementptr">getelementptr</a> [13 x sbyte]* %.LC0, long 0, long 0 <i>; sbyte*</i>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="simpleconstants">Simple Constants</a></div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<i>; Call puts function to write out the string to stdout...</i>
|
||||
<a
|
||||
href="#i_call">call</a> int %puts(sbyte* %cast210) <i>; int</i>
|
||||
<a
|
||||
href="#i_ret">ret</a> int 0<br>}<br></pre>
|
||||
<p>This example is made up of a <a href="#globalvars">global variable</a>
|
||||
named "<tt>.LC0</tt>", an external declaration of the "<tt>puts</tt>"
|
||||
function, and a <a href="#functionstructure">function definition</a>
|
||||
for "<tt>main</tt>".</p>
|
||||
<a name="linkage"> In general, a module is made up of a list of global
|
||||
values, where both functions and global variables are global values.
|
||||
Global values are represented by a pointer to a memory location (in
|
||||
this case, a pointer to an array of char, and a pointer to a function),
|
||||
and have one of the following linkage types:</a>
|
||||
<p> </p>
|
||||
<dl>
|
||||
<dt><tt><b><a name="linkage_internal">internal</a></b></tt> </dt>
|
||||
<dd>Global values with internal linkage are only directly accessible
|
||||
by objects in the current module. In particular, linking code into a
|
||||
module with an internal global value may cause the internal to be
|
||||
renamed as necessary to avoid collisions. Because the symbol is
|
||||
internal to the module, all references can be updated. This
|
||||
corresponds to the notion of the '<tt>static</tt>' keyword in C, or the
|
||||
idea of "anonymous namespaces" in C++.
|
||||
<p> </p>
|
||||
<dt><b>Boolean constants</b></dt>
|
||||
|
||||
<dd>The two strings '<tt>true</tt>' and '<tt>false</tt>' are both valid
|
||||
constants of the <tt><a href="#t_primitive">bool</a></tt> type.
|
||||
</dd>
|
||||
<dt><tt><b><a name="linkage_linkonce">linkonce</a></b></tt>: </dt>
|
||||
<dd>"<tt>linkonce</tt>" linkage is similar to <tt>internal</tt>
|
||||
linkage, with the twist that linking together two modules defining the
|
||||
same <tt>linkonce</tt> globals will cause one of the globals to be
|
||||
discarded. This is typically used to implement inline functions.
|
||||
Unreferenced <tt>linkonce</tt> globals are allowed to be discarded.
|
||||
<p> </p>
|
||||
|
||||
<dt><b>Integer constants</b></dt>
|
||||
|
||||
<dd>Standard integers (such as '4') are constants of the <a
|
||||
href="#t_integer">integer</a> type. Negative numbers may be used with signed
|
||||
integer types.
|
||||
</dd>
|
||||
<dt><tt><b><a name="linkage_weak">weak</a></b></tt>: </dt>
|
||||
<dd>"<tt>weak</tt>" linkage is exactly the same as <tt>linkonce</tt>
|
||||
linkage, except that unreferenced <tt>weak</tt> globals may not be
|
||||
discarded. This is used to implement constructs in C such as "<tt>int
|
||||
X;</tt>" at global scope.
|
||||
<p> </p>
|
||||
|
||||
<dt><b>Floating point constants</b></dt>
|
||||
|
||||
<dd>Floating point constants use standard decimal notation (e.g. 123.421),
|
||||
exponential notation (e.g. 1.23421e+2), or a more precise hexadecimal
|
||||
notation. Floating point constants have an optional hexadecimal
|
||||
notation (see below). Floating point constants must have a <a
|
||||
href="#t_floating">floating point</a> type. </dd>
|
||||
|
||||
<dt><b>Null pointer constants</b></dt>
|
||||
|
||||
<dd>The identifier '<tt>null</tt>' is recognized as a null pointer constant
|
||||
and must be of <a href="#t_pointer">pointer type</a>.</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<p>The one non-intuitive notation for constants is the optional hexadecimal form
|
||||
of floating point constants. For example, the form '<tt>double
|
||||
0x432ff973cafa8000</tt>' is equivalent to (but harder to read than) '<tt>double
|
||||
4.5e+15</tt>'. The only time hexadecimal floating point constants are required
|
||||
(and the only time that they are generated by the disassembler) is when a
|
||||
floating point constant must be emitted but it cannot be represented as a
|
||||
decimal floating point number. For example, NaN's, infinities, and other
|
||||
special values are represented in their IEEE hexadecimal format so that
|
||||
assembly and disassembly do not cause any bits to change in the constants.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="aggregateconstants">Aggregate Constants</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<dl>
|
||||
<dt><b>Structure constants</b></dt>
|
||||
|
||||
<dd>Structure constants are represented with notation similar to structure
|
||||
type definitions (a comma separated list of elements, surrounded by braces
|
||||
(<tt>{}</tt>)). For example: "<tt>{ int 4, float 17.0 }</tt>". Structure
|
||||
constants must have <a href="#t_struct">structure type</a>, and the number and
|
||||
types of elements must match those specified by the type.
|
||||
</dd>
|
||||
<dt><tt><b><a name="linkage_appending">appending</a></b></tt>: </dt>
|
||||
<dd>"<tt>appending</tt>" linkage may only be applied to global
|
||||
variables of pointer to array type. When two global variables with
|
||||
appending linkage are linked together, the two global arrays are
|
||||
appended together. This is the LLVM, typesafe, equivalent of having
|
||||
the system linker append together "sections" with identical names when
|
||||
.o files are linked.
|
||||
<p> </p>
|
||||
|
||||
<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 brackets
|
||||
(<tt>[]</tt>)). For example: "<tt>[ int 42, int 11, int 74 ]</tt>". Array
|
||||
constants must have <a href="#t_array">array type</a>, and the number and
|
||||
types of elements must match those specified by the type.
|
||||
</dd>
|
||||
<dt><tt><b><a name="linkage_external">externally visible</a></b></tt>:</dt>
|
||||
<dd>If none of the above identifiers are used, the global is
|
||||
externally visible, meaning that it participates in linkage and can be
|
||||
used to resolve external symbol references.
|
||||
<p> </p>
|
||||
|
||||
<dt><b>Packed constants</b></dt>
|
||||
|
||||
<dd>Packed constants are represented with notation similar to packed type
|
||||
definitions (a comma separated list of elements, surrounded by
|
||||
less-than/greater-than's (<tt><></tt>)). For example: "<tt>< int 42,
|
||||
int 11, int 74, int 100 ></tt>". Packed constants must have <a
|
||||
href="#t_packed">packed type</a>, and the number and types of elements must
|
||||
match those specified by the type.
|
||||
</dd>
|
||||
|
||||
<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.
|
||||
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>
|
||||
</dl>
|
||||
<p> </p>
|
||||
<p><a name="linkage_external">For example, since the "<tt>.LC0</tt>"
|
||||
variable is defined to be internal, if another module defined a "<tt>.LC0</tt>"
|
||||
variable and was linked with this one, one of the two would be renamed,
|
||||
preventing a collision. Since "<tt>main</tt>" and "<tt>puts</tt>" are
|
||||
external (i.e., lacking any linkage declarations), they are accessible
|
||||
outside of the current module. It is illegal for a function <i>declaration</i>
|
||||
to have any linkage type other than "externally visible".</a></p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
<a name="globalvars">Global Variables</a>
|
||||
<a name="globalconstants">Global Variable and Function Addresses</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>Global variables define regions of memory allocated at compilation
|
||||
time instead of run-time. Global variables may optionally be
|
||||
initialized. A variable may be defined as a global "constant", which
|
||||
indicates that the contents of the variable will never be modified
|
||||
(opening options for optimization).</p>
|
||||
<p>The addresses of <a href="#globalvars">global variables</a> and <a
|
||||
href="#functionstructure">functions</a> are always implicitly valid (link-time)
|
||||
constants. These constants are explicitly referenced when the <a
|
||||
href="#identifiers">identifier for the global</a> is used and always have <a
|
||||
href="#t_pointer">pointer</a> type. For example, the following is a legal LLVM
|
||||
file:</p>
|
||||
|
||||
<p>As SSA values, global variables define pointer values that are in
|
||||
scope (i.e. they dominate) for all basic blocks in the program. Global
|
||||
variables always define a pointer to their "content" type because they
|
||||
describe a region of memory, and all memory objects in LLVM are
|
||||
accessed through pointers.</p>
|
||||
<pre>
|
||||
%X = global int 17
|
||||
%Y = global int 42
|
||||
%Z = global [2 x int*] [ int* %X, int* %Y ]
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
<a name="functionstructure">Functions</a>
|
||||
<div class="doc_subsection"><a name="undefvalues">Undefined Values</a></div>
|
||||
<div class="doc_text">
|
||||
<p>The string '<tt>undef</tt>' is recognized as a type-less constant that has
|
||||
no specific value. Undefined values may be of any type, and be used anywhere
|
||||
a constant is permitted.</p>
|
||||
|
||||
<p>Undefined values indicate to the compiler that the program is well defined
|
||||
no matter what value is used, giving the compiler more freedom to optimize.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="constantexprs">Constant Expressions</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>LLVM function definitions are composed of a (possibly empty) argument list,
|
||||
an opening curly brace, a list of basic blocks, and a closing curly brace. LLVM
|
||||
function declarations are defined with the "<tt>declare</tt>" keyword, a
|
||||
function name, and a function signature.</p>
|
||||
<p>Constant expressions are used to allow expressions involving other constants
|
||||
to be used as constants. Constant expressions may be of any <a
|
||||
href="#t_firstclass">first class</a> type, and may involve any LLVM operation
|
||||
that does not have side effects (e.g. load and call are not supported). The
|
||||
following is the syntax for constant expressions:</p>
|
||||
|
||||
<p>A function definition contains a list of basic blocks, forming the CFG for
|
||||
the function. Each basic block may optionally start with a label (giving the
|
||||
basic block a symbol table entry), contains a list of instructions, and ends
|
||||
with a <a href="#terminators">terminator</a> instruction (such as a branch or
|
||||
function return).</p>
|
||||
<dl>
|
||||
<dt><b><tt>cast ( CST to TYPE )</tt></b></dt>
|
||||
|
||||
<p>The first basic block in program is special in two ways: it is immediately
|
||||
executed on entrance to the function, and it is not allowed to have predecessor
|
||||
basic blocks (i.e. there can not be any branches to the entry block of a
|
||||
function). Because the block can have no predecessors, it also cannot have any
|
||||
<a href="#i_phi">PHI nodes</a>.</p>
|
||||
<dd>Cast a constant to another type.</dd>
|
||||
|
||||
<p>LLVM functions are identified by their name and type signature. Hence, two
|
||||
functions with the same name but different parameter lists or return values are
|
||||
considered different functions, and LLVM will resolves references to each
|
||||
appropriately.</p>
|
||||
<dt><b><tt>getelementptr ( CSTPTR, IDX0, IDX1, ... )</tt></b></dt>
|
||||
|
||||
<dd>Perform the <a href="#i_getelementptr">getelementptr operation</a> on
|
||||
constants. As with the <a href="#i_getelementptr">getelementptr</a>
|
||||
instruction, the index list may have zero or more indexes, which are required
|
||||
to make sense for the type of "CSTPTR".</dd>
|
||||
|
||||
<dt><b><tt>OPCODE ( LHS, RHS )</tt></b></dt>
|
||||
|
||||
<dd>Perform the specified operation of the LHS and RHS constants. OPCODE may
|
||||
be any of the <a href="#binaryops">binary</a> or <a href="#bitwiseops">bitwise
|
||||
binary</a> operations. The constraints on operands are the same as those for
|
||||
the corresponding instruction (e.g. no bitwise operations on floating point
|
||||
are allowed).</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section"> <a name="instref">Instruction Reference</a> </div>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The LLVM instruction set consists of several different
|
||||
classifications of instructions: <a href="#terminators">terminator
|
||||
instructions</a>, <a href="#binaryops">binary instructions</a>, <a
|
||||
href="#memoryops">memory instructions</a>, and <a href="#otherops">other
|
||||
instructions</a>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"> <a name="terminators">Terminator
|
||||
Instructions</a> </div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>As mentioned <a href="#functionstructure">previously</a>, every
|
||||
basic block in a program ends with a "Terminator" instruction, which
|
||||
indicates which block should be executed after the current block is
|
||||
finished. These terminator instructions typically yield a '<tt>void</tt>'
|
||||
value: they produce control flow, not values (the one exception being
|
||||
the '<a href="#i_invoke"><tt>invoke</tt></a>' instruction).</p>
|
||||
<p>There are five different terminator instructions: the '<a
|
||||
<p>There are six different terminator instructions: the '<a
|
||||
href="#i_ret"><tt>ret</tt></a>' instruction, the '<a href="#i_br"><tt>br</tt></a>'
|
||||
instruction, the '<a href="#i_switch"><tt>switch</tt></a>' instruction,
|
||||
the '<a href="#i_invoke"><tt>invoke</tt></a>' instruction, the '<a
|
||||
href="#i_unwind"><tt>unwind</tt></a>' instruction, and the '<a
|
||||
href="#i_unreachable"><tt>unreachable</tt></a>' instruction.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"> <a name="i_ret">'<tt>ret</tt>'
|
||||
Instruction</a> </div>
|
||||
@@ -957,7 +1199,7 @@ no-return function cannot be reached, and other facts.</p>
|
||||
<div class="doc_text">
|
||||
<p>Binary operators are used to do most of the computation in a
|
||||
program. They require two operands, execute an operation on them, and
|
||||
produce a single value. Although, that single value might represent
|
||||
produce a single value. The operands might represent
|
||||
multiple data, as is the case with the <a href="#t_packed">packed</a> data type.
|
||||
The result value of a binary operator is not
|
||||
necessarily the same type as its operands.</p>
|
||||
@@ -1135,7 +1377,7 @@ Operations</a> </div>
|
||||
<div class="doc_text">
|
||||
<p>Bitwise binary operators are used to do various forms of
|
||||
bit-twiddling in a program. They are generally very efficient
|
||||
instructions, and can commonly be strength reduced from other
|
||||
instructions and can commonly be strength reduced from other
|
||||
instructions. They require two operands, execute an operation on them,
|
||||
and produce a single value. The resulting value of the bitwise binary
|
||||
operators is always the same type as its first operand.</p>
|
||||
@@ -1360,7 +1602,7 @@ Operations</a></div>
|
||||
<p>A key design point of an SSA-based representation is how it
|
||||
represents memory. In LLVM, no memory locations are in SSA form, which
|
||||
makes things very simple. This section describes how to read, write,
|
||||
allocate and free memory in LLVM.</p>
|
||||
allocate, and free memory in LLVM.</p>
|
||||
</div>
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"> <a name="i_malloc">'<tt>malloc</tt>'
|
||||
@@ -1408,7 +1650,7 @@ memory heap, to be reallocated in the future.</p>
|
||||
that was allocated with the '<tt><a href="#i_malloc">malloc</a></tt>'
|
||||
instruction.</p>
|
||||
<h5>Semantics:</h5>
|
||||
<p>Access to the memory pointed to by the pointer is not longer defined
|
||||
<p>Access to the memory pointed to by the pointer is no longer defined
|
||||
after this instruction executes.</p>
|
||||
<h5>Example:</h5>
|
||||
<pre> %array = <a href="#i_malloc">malloc</a> [4 x ubyte] <i>; yields {[4 x ubyte]*}:array</i>
|
||||
@@ -1428,7 +1670,7 @@ Instruction</a> </div>
|
||||
stack frame of the procedure that is live until the current function
|
||||
returns to its caller.</p>
|
||||
<h5>Arguments:</h5>
|
||||
<p>The the '<tt>alloca</tt>' instruction allocates <tt>sizeof(<type>)*NumElements</tt>
|
||||
<p>The '<tt>alloca</tt>' instruction allocates <tt>sizeof(<type>)*NumElements</tt>
|
||||
bytes of memory on the runtime stack, returning a pointer of the
|
||||
appropriate type to the program. The second form of the instruction is
|
||||
a shorter version of the first that defaults to allocating one element.</p>
|
||||
@@ -2061,7 +2303,7 @@ href="GarbageCollection.html">Accurate Garbage Collection with LLVM</a>.
|
||||
|
||||
<h5>Overview:</h5>
|
||||
|
||||
<p>The '<tt>llvm.gcroot</tt>' intrinsic declares the existance of a GC root to
|
||||
<p>The '<tt>llvm.gcroot</tt>' intrinsic declares the existence of a GC root to
|
||||
the code generator, and allows some metadata to be associated with it.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
@@ -2308,7 +2550,9 @@ unsigned 16 bit value, and the return value must be 8, 16, or 32 bits.
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<pre>
|
||||
call void (<integer type>, <integer type>)* %llvm.writeport (<integer type> <value>, <integer type> <address>)
|
||||
call void (<integer type>, <integer type>)*
|
||||
%llvm.writeport (<integer type> <value>,
|
||||
<integer type> <address>)
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
|
||||
@@ -28,7 +28,11 @@
|
||||
</li>
|
||||
<li><a href="#tutorial">Tutorial</a>
|
||||
<ol>
|
||||
<li><a href="#libraries">Libraries</a></li>
|
||||
<li><a href="#libraries">Libraries</a>
|
||||
<ol>
|
||||
<li><a href="#Modules">Bytecode Modules</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="#tools">Tools</a>
|
||||
<ol>
|
||||
<li><a href="#JIT">JIT Tools</a></li>
|
||||
@@ -41,6 +45,7 @@
|
||||
<li><a href="#all">all</a></li>
|
||||
<li><a href="#all-local">all-local</a></li>
|
||||
<li><a href="#check">check</a></li>
|
||||
<li><a href="#check-local">check-local</a></li>
|
||||
<li><a href="#clean">clean</a></li>
|
||||
<li><a href="#clean-local">clean-local</a></li>
|
||||
<li><a href="#dist">dist</a></li>
|
||||
@@ -195,7 +200,7 @@
|
||||
<div class="doc_subsection"><a name="Comments">Comments</a></div>
|
||||
<div class="doc_text">
|
||||
<p>User Makefiles need not have comments in them unless the construction is
|
||||
unusual or it doesn't strictly follow the rules and patterns of the LLVM
|
||||
unusual or it does not strictly follow the rules and patterns of the LLVM
|
||||
makefile system. Makefile comments are invoked with the pound (#) character.
|
||||
The # character and any text following it, to the end of the line, are ignored
|
||||
by <tt>make</tt>.</p>
|
||||
@@ -235,6 +240,27 @@
|
||||
directory.</p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsubsection"><a name="Modules">Bytecode Modules</a></div>
|
||||
<div class="doc_text">
|
||||
<p>In some situations, it is desireable to build a single bytecode module from
|
||||
a variety of sources, instead of an archive, shared library, or bytecode
|
||||
library. Bytecode modules can be specified in addition to any of the other
|
||||
types of libraries by defining the <a href="#MODULE_NAME">MODULE_NAME</a>
|
||||
variable. For example:</p>
|
||||
<pre><tt>
|
||||
LIBRARYNAME = mylib
|
||||
BYTECODE_LIBRARY = 1
|
||||
MODULE_NAME = mymod
|
||||
</tt></pre>
|
||||
<p>will build a module named <tt>mymod.bc</tt> from the sources in the
|
||||
directory. This module will be an aggregation of all the bytecode modules
|
||||
derived from the sources. The example will also build a bytecode archive
|
||||
containing a bytecode module for each compiled source file. The difference is
|
||||
subtle, but important depending on how the module or library is to be linked.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="tools">Tools</a></div>
|
||||
<div class="doc_text">
|
||||
@@ -312,11 +338,13 @@
|
||||
<div class="doc_text">
|
||||
<p>This section describes each of the targets that can be built using the LLVM
|
||||
Makefile system. Any target can be invoked from any directory but not all are
|
||||
applicable to a given directory (e.g. "check", "dist", and "install" will
|
||||
applicable to a given directory (e.g. "check", "dist" and "install" will
|
||||
always operate as if invoked from the top level directory).</p>
|
||||
|
||||
<table style="text-align:left">
|
||||
<tr><th>Target Name</th><th>Implied Targets</th><th>Target Description</th></tr>
|
||||
<tr>
|
||||
<th>Target Name</th><th>Implied Targets</th><th>Target Description</th>
|
||||
</tr>
|
||||
<tr><td><a href="#all"><tt>all</tt></a></td><td></td>
|
||||
<td>Compile the software recursively. Default target.
|
||||
</td></tr>
|
||||
@@ -324,7 +352,12 @@
|
||||
<td>Compile the software in the local directory only.
|
||||
</td></tr>
|
||||
<tr><td><a href="#check"><tt>check</tt></a></td><td></td>
|
||||
<td>Change to the llvm/test directory and run regression tests.
|
||||
<td>Change to the <tt>test</tt> directory in a project and run the
|
||||
test suite there.
|
||||
</td></tr>
|
||||
<tr><td><a href="#check-local"><tt>check-local</tt></a></td><td></td>
|
||||
<td>Run a local test suite. Generally this is only defined in the
|
||||
<tt>Makefile</tt> of the project's <tt>test</tt> directory.
|
||||
</td></tr>
|
||||
<tr><td><a href="#clean"><tt>clean</tt></a></td><td></td>
|
||||
<td>Remove built objects recursively.
|
||||
@@ -377,12 +410,41 @@
|
||||
the current directory instead of recursively.</p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="check">check</a></div>
|
||||
<div class="doc_text">
|
||||
<p>This target can be invoked from anywhere within a project's directories
|
||||
but always invokes the <a href="#check-local"><tt>check-local</tt></a> target
|
||||
in the project's <tt>test</tt> directory, if it exists and has a
|
||||
<tt>Makefile</tt>. A warning is produced otherwise. If
|
||||
<a href="#TESTSUITE"><tt>TESTSUITE</tt></a> is defined on the <tt>make</tt>
|
||||
command line, it will be passed down to the invocation of
|
||||
<tt>make check-local</tt> in the <tt>test</tt> directory. The intended usage
|
||||
for this is to assist in running specific suites of tests. If
|
||||
<tt>TESTSUITE</tt> is not set, the implementation of <tt>check-local</tt>
|
||||
should run all normal tests. It is up to the project to define what
|
||||
different values for <tt>TESTSUTE</tt> will do. See the
|
||||
<a href="TestingGuide.html">TestingGuide</a> for further details.</p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="check-local">check-local</a></div>
|
||||
<div class="doc_text">
|
||||
<p>This target should be implemented by the <tt>Makefile</tt> in the project's
|
||||
<tt>test</tt> directory. It is invoked by the <tt>check</tt> target elsewhere.
|
||||
Each project is free to define the actions of <tt>check-local</tt> as
|
||||
appropriate for that project. The LLVM project itself uses dejagnu to run a
|
||||
suite of feature and regresson tests. Other projects may choose to use
|
||||
dejagnu or any other testing mechanism.</p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="clean">clean</a></div>
|
||||
<div class="doc_text">
|
||||
<p>This target cleans the build directory, recursively removing all things
|
||||
that the Makefile builds. Despite once or twice attempting to remove /*, the
|
||||
cleaning rules have been made guarded so they shouldn't go awry.</p>
|
||||
that the Makefile builds. The cleaning rules have been made guarded so they
|
||||
shouldn't go awry (via <tt>rm -f $(UNSET_VARIABLE)/*</tt> which will attempt
|
||||
to erase the entire directory structure.</p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
@@ -453,8 +515,8 @@
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="printvars">printvars</a></div>
|
||||
<div class="doc_text">
|
||||
<p>This utility target just causes LLVM to print out some of its variables so
|
||||
that you can double check how things are set. </p>
|
||||
<p>This utility target just causes the LLVM makefiles to print out some of
|
||||
the makefile variables so that you can double check how things are set. </p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
@@ -544,6 +606,14 @@
|
||||
source files, all built sources, all Makefiles, and most documentation files
|
||||
will be automatically distributed. Use this variable to distribute any
|
||||
files that are not automatically distributed.</dd>
|
||||
<dt><a name="FAKE_SOURCES"><tt>FAKE_SOURCES</tt><small>(optional)</small>
|
||||
</a></dt>
|
||||
<dd>This variable is like <a href="#SOURCES"><tt>SOURCES</tt></a> except that
|
||||
the source files don't need to exist. The makefiles only use
|
||||
<tt>FAKE_SOURCES</tt> to create the names of derived objects that should be
|
||||
included in the directory's result. It is assumed that the project's
|
||||
<tt>Makefile</tt> will define how to build the derived objects
|
||||
necessary.</dd>
|
||||
<dt><a name="KEEP_SYMBOLS"><tt>KEEP_SYMBOLS</tt></a></dt>
|
||||
<dd>If set to any value, specifies that when linking executables the
|
||||
makefiles should retain debug symbols in the executable. Normally, symbols
|
||||
@@ -588,6 +658,8 @@
|
||||
<dd>Specifies the name of the LLVM code generation target that the
|
||||
current directory builds. Setting this variable enables additional rules to
|
||||
build <tt>.inc</tt> files from <tt>.td</tt> files. </dd>
|
||||
<dt><a name="TESTSUITE"><tt>TESTSUITE</tt></a></dt>
|
||||
<dd>Specifies the directory of tests to run in <tt>llvm/test</tt>.</dd>
|
||||
<dt><a name="TOOLNAME"><tt>TOOLNAME</tt></a></dt>
|
||||
<dd>Specifies the name of the tool that the current directory should
|
||||
build.</dd>
|
||||
@@ -619,7 +691,7 @@
|
||||
<li>In the Makefile (only <em>after</em> the inclusion of <a
|
||||
href="#Makefile.common"><tt>$(LEVEL)/Makefile.common</tt></a>).</li>
|
||||
</ul>
|
||||
<p>The overridable variables are given below:</p>
|
||||
<p>The override variables are given below:</p>
|
||||
<dl>
|
||||
<dt><a name="AR"><tt>AR</tt></a> <small>(defaulted)</small></dt>
|
||||
<dd>Specifies the path to the <tt>ar</tt> tool.</dd>
|
||||
@@ -772,7 +844,8 @@
|
||||
<dd>The configuration specific directory into which executables are placed
|
||||
before they are installed.</dd>
|
||||
<dt><a name="TopDistDir"><tt>TopDistDir</tt></a></dt>
|
||||
<dd>The top most directory into which the distribution files are copied.</dd>
|
||||
<dd>The top most directory into which the distribution files are copied.
|
||||
</dd>
|
||||
<dt><a name="Verb"><tt>Verb</tt></a></dt>
|
||||
<dd>Use this as the first thing on your build script lines to enable or
|
||||
disable verbose mode. It expands to either an @ (quiet mode) or nothing
|
||||
@@ -786,83 +859,88 @@
|
||||
<p>Variables listed below are used by the LLVM Makefile System
|
||||
and considered internal. You should not use these variables under any
|
||||
circumstances.</p>
|
||||
<dl>
|
||||
<dt><a name="Archive"><tt>Archive</tt></a></dt><dd></dd>
|
||||
<dt><a name="AR.Flags"><tt>AR.Flags</tt></a></dt><dd></dd>
|
||||
<dt><a name="BaseNameSources"><tt>BaseNameSources</tt></a></dt><dd></dd>
|
||||
<dt><a name="BCCompile.C"><tt>BCCompile.C</tt></a></dt><dd></dd>
|
||||
<dt><a name="BCCompile.CXX"><tt>BCCompile.CXX</tt></a></dt><dd></dd>
|
||||
<dt><a name="BCLinkLib"><tt>BCLinkLib</tt></a></dt><dd></dd>
|
||||
<dt><a name="Burg"><tt>Burg</tt></a></dt><dd></dd>
|
||||
<dt><a name="C.Flags"><tt>C.Flags</tt></a></dt><dd></dd>
|
||||
<dt><a name="Compile.C"><tt>Compile.C</tt></a></dt><dd></dd>
|
||||
<dt><a name="CompileCommonOpts"><tt>CompileCommonOpts</tt></a></dt><dd></dd>
|
||||
<dt><a name="Compile.CXX"><tt>Compile.CXX</tt></a></dt><dd></dd>
|
||||
<dt><a name="ConfigStatusScript"><tt>ConfigStatusScript</tt></a></dt><dd></dd>
|
||||
<dt><a name="ConfigureScript"><tt>ConfigureScript</tt></a></dt><dd></dd>
|
||||
<dt><a name="CPP.Flags"><tt>CPP.Flags</tt></a></dt><dd></dd>
|
||||
<dt><a name="CPP.Flags "><tt>CPP.Flags </tt></a></dt><dd></dd>
|
||||
<dt><a name="CXX.Flags"><tt>CXX.Flags</tt></a></dt><dd></dd>
|
||||
<dt><a name="DependFiles"><tt>DependFiles</tt></a></dt><dd></dd>
|
||||
<dt><a name="DestArchiveLib"><tt>DestArchiveLib</tt></a></dt><dd></dd>
|
||||
<dt><a name="DestBytecodeLib"><tt>DestBytecodeLib</tt></a></dt><dd></dd>
|
||||
<dt><a name="DestRelinkedLib"><tt>DestRelinkedLib</tt></a></dt><dd></dd>
|
||||
<dt><a name="DestSharedLib"><tt>DestSharedLib</tt></a></dt><dd></dd>
|
||||
<dt><a name="DestTool"><tt>DestTool</tt></a></dt><dd></dd>
|
||||
<dt><a name="DistAlways"><tt>DistAlways</tt></a></dt><dd></dd>
|
||||
<dt><a name="DistCheckDir"><tt>DistCheckDir</tt></a></dt><dd></dd>
|
||||
<dt><a name="DistCheckTop"><tt>DistCheckTop</tt></a></dt><dd></dd>
|
||||
<dt><a name="DistFiles"><tt>DistFiles</tt></a></dt><dd></dd>
|
||||
<dt><a name="DistName"><tt>DistName</tt></a></dt><dd></dd>
|
||||
<dt><a name="DistOther"><tt>DistOther</tt></a></dt><dd></dd>
|
||||
<dt><a name="DistSources"><tt>DistSources</tt></a></dt><dd></dd>
|
||||
<dt><a name="DistSubDirs"><tt>DistSubDirs</tt></a></dt><dd></dd>
|
||||
<dt><a name="DistTarBZ2"><tt>DistTarBZ2</tt></a></dt><dd></dd>
|
||||
<dt><a name="DistTarGZip"><tt>DistTarGZip</tt></a></dt><dd></dd>
|
||||
<dt><a name="DistZip"><tt>DistZip</tt></a></dt><dd></dd>
|
||||
<dt><a name="ExtraLibs"><tt>ExtraLibs</tt></a></dt><dd></dd>
|
||||
<dt><a name="INCFiles"><tt>INCFiles</tt></a></dt><dd></dd>
|
||||
<dt><a name="InternalTargets"><tt>InternalTargets</tt></a></dt><dd></dd>
|
||||
<dt><a name="LD.Flags"><tt>LD.Flags</tt></a></dt><dd></dd>
|
||||
<dt><a name="LexOutput"><tt>LexOutput</tt></a></dt><dd></dd>
|
||||
<dt><a name="LibName.A"><tt>LibName.A</tt></a></dt><dd></dd>
|
||||
<dt><a name="LibName.BC"><tt>LibName.BC</tt></a></dt><dd></dd>
|
||||
<dt><a name="LibName.LA"><tt>LibName.LA</tt></a></dt><dd></dd>
|
||||
<dt><a name="LibName.O"><tt>LibName.O</tt></a></dt><dd></dd>
|
||||
<dt><a name="LibTool.Flags"><tt>LibTool.Flags</tt></a></dt><dd></dd>
|
||||
<dt><a name="Link"><tt>Link</tt></a></dt><dd></dd>
|
||||
<dt><a name="LLVMGCCLibDir"><tt>LLVMGCCLibDir</tt></a></dt><dd></dd>
|
||||
<dt><a name="LLVMLibDir"><tt>LLVMLibDir</tt></a></dt><dd></dd>
|
||||
<dt><a name="LLVMLibsOptions"><tt>LLVMLibsOptions</tt></a></dt><dd></dd>
|
||||
<dt><a name="LLVMLibsPaths"><tt>LLVMLibsPaths</tt></a></dt><dd></dd>
|
||||
<dt><a name="LLVMToolDir"><tt>LLVMToolDir</tt></a></dt><dd></dd>
|
||||
<dt><a name="LLVMUsedLibs"><tt>LLVMUsedLibs</tt></a></dt><dd></dd>
|
||||
<dt><a name="LocalTargets"><tt>LocalTargets</tt></a></dt><dd></dd>
|
||||
<dt><a name="LTCompile.C"><tt>LTCompile.C</tt></a></dt><dd></dd>
|
||||
<dt><a name="LTCompile.CXX"><tt>LTCompile.CXX</tt></a></dt><dd></dd>
|
||||
<dt><a name="LTInstall"><tt>LTInstall</tt></a></dt><dd></dd>
|
||||
<dt><a name="ObjectsBC"><tt>ObjectsBC</tt></a></dt><dd></dd>
|
||||
<dt><a name="ObjectsLO"><tt>ObjectsLO</tt></a></dt><dd></dd>
|
||||
<dt><a name="ObjectsO"><tt>ObjectsO</tt></a></dt><dd></dd>
|
||||
<dt><a name="ObjMakefiles"><tt>ObjMakefiles</tt></a></dt><dd></dd>
|
||||
<dt><a name="Parallel_Targets"><tt>Parallel_Targets</tt></a></dt><dd></dd>
|
||||
<dt><a name="PreConditions"><tt>PreConditions</tt></a></dt><dd></dd>
|
||||
<dt><a name="ProjLibsOptions"><tt>ProjLibsOptions</tt></a></dt><dd></dd>
|
||||
<dt><a name="ProjLibsPaths"><tt>ProjLibsPaths</tt></a></dt><dd></dd>
|
||||
<dt><a name="ProjUsedLibs"><tt>ProjUsedLibs</tt></a></dt><dd></dd>
|
||||
<dt><a name="Ranlib"><tt>Ranlib</tt></a></dt><dd></dd>
|
||||
<dt><a name="RecursiveTargets"><tt>RecursiveTargets</tt></a></dt><dd></dd>
|
||||
<dt><a name="Relink"><tt>Relink</tt></a></dt><dd></dd>
|
||||
<dt><a name="SrcMakefiles"><tt>SrcMakefiles</tt></a></dt><dd></dd>
|
||||
<dt><a name="Strip"><tt>Strip</tt></a></dt><dd></dd>
|
||||
<dt><a name="StripWarnMsg"><tt>StripWarnMsg</tt></a></dt><dd></dd>
|
||||
<dt><a name="TableGen"><tt>TableGen</tt></a></dt><dd></dd>
|
||||
<dt><a name="TDFiles"><tt>TDFiles</tt></a></dt><dd></dd>
|
||||
<dt><a name="ToolBuildPath"><tt>ToolBuildPath</tt></a></dt><dd></dd>
|
||||
<dt><a name="TopLevelTargets"><tt>TopLevelTargets</tt></a></dt><dd></dd>
|
||||
<dt><a name="UserTargets"><tt>UserTargets</tt></a></dt><dd></dd>
|
||||
<dt><a name="YaccOutput"><tt>YaccOutput</tt></a></dt><dd></dd>
|
||||
</dl>
|
||||
<p><tt>
|
||||
Archive
|
||||
AR.Flags
|
||||
BaseNameSources
|
||||
BCCompile.C
|
||||
BCCompile.CXX
|
||||
BCLinkLib
|
||||
Burg
|
||||
C.Flags
|
||||
Compile.C
|
||||
CompileCommonOpts
|
||||
Compile.CXX
|
||||
ConfigStatusScript
|
||||
ConfigureScript
|
||||
CPP.Flags
|
||||
CPP.Flags
|
||||
CXX.Flags
|
||||
DependFiles
|
||||
DestArchiveLib
|
||||
DestBytecodeLib
|
||||
DestModule
|
||||
DestRelinkedLib
|
||||
DestSharedLib
|
||||
DestTool
|
||||
DistAlways
|
||||
DistCheckDir
|
||||
DistCheckTop
|
||||
DistFiles
|
||||
DistName
|
||||
DistOther
|
||||
DistSources
|
||||
DistSubDirs
|
||||
DistTarBZ2
|
||||
DistTarGZip
|
||||
DistZip
|
||||
ExtraLibs
|
||||
FakeSources
|
||||
INCFiles
|
||||
InternalTargets
|
||||
LD.Flags
|
||||
LexFiles
|
||||
LexOutput
|
||||
LibName.A
|
||||
LibName.BC
|
||||
LibName.LA
|
||||
LibName.O
|
||||
LibTool.Flags
|
||||
Link
|
||||
LinkModule
|
||||
LLVMLibDir
|
||||
LLVMLibsOptions
|
||||
LLVMLibsPaths
|
||||
LLVMToolDir
|
||||
LLVMUsedLibs
|
||||
LocalTargets
|
||||
LTCompile.C
|
||||
LTCompile.CXX
|
||||
LTInstall
|
||||
Module
|
||||
ObjectsBC
|
||||
ObjectsLO
|
||||
ObjectsO
|
||||
ObjMakefiles
|
||||
ParallelTargets
|
||||
PreConditions
|
||||
ProjLibsOptions
|
||||
ProjLibsPaths
|
||||
ProjUsedLibs
|
||||
Ranlib
|
||||
RecursiveTargets
|
||||
Relink
|
||||
SrcMakefiles
|
||||
Strip
|
||||
StripWarnMsg
|
||||
TableGen
|
||||
TDFiles
|
||||
ToolBuildPath
|
||||
TopLevelTargets
|
||||
UserTargets
|
||||
YaccFiles
|
||||
YaccOutput
|
||||
</tt></p>
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<li>The <tt>-time-passes</tt> option</li>
|
||||
<li>How to use the LLVM Makefile system</li>
|
||||
<li>How to write a regression test</li>
|
||||
|
||||
-->
|
||||
</ul>
|
||||
</li>
|
||||
@@ -212,7 +213,7 @@ STL</a>.</li>
|
||||
<li><a href="http://www.research.att.com/%7Ebs/C++.html">Bjarne Stroustrup's C++
|
||||
Page</a></li>
|
||||
|
||||
<li><a href="http://www.linux.com.cn/Bruce_Eckel/TICPPv2/Contents.htm">
|
||||
<li><a href="http://64.78.49.204/">
|
||||
Bruce Eckel's Thinking in C++, 2nd ed. Volume 2 Revision 4.0 (even better, get
|
||||
the book).</a></li>
|
||||
|
||||
|
||||
@@ -186,30 +186,29 @@ directories:</p>
|
||||
This subdirectory should contain tests that verify that your code
|
||||
works correctly. Automated tests are especially useful.
|
||||
<p>
|
||||
Currently, the LLVM build system provides little support for tests,
|
||||
although some exists. Expanded support for tests will hopefully
|
||||
occur in the future. In the meantime, the LLVM system does provide the
|
||||
following:
|
||||
Currently, the LLVM build system provides basic support for tests.
|
||||
The LLVM system provides the following:
|
||||
<ul>
|
||||
<li>
|
||||
LLVM provides several QMTest test classes that can be used to
|
||||
create tests. They can be found in
|
||||
<tt>llvm/test/QMTest/llvm.py</tt>. These test classes perform a
|
||||
variety of functions, including code optimization tests, assembly
|
||||
tests, and code analysis tests. The Makefile in
|
||||
<tt>llvm/test</tt> provides the QMTest context needed by LLVM test
|
||||
classes.
|
||||
LLVM provides a tcl procedure that is used by Dejagnu to run
|
||||
tests. It can be found in <tt>llvm/lib/llvm-dg.exp</tt>. This
|
||||
test procedure uses RUN lines in the actual test case to determine
|
||||
how to run the test. See the <a
|
||||
href="TestingGuide.html">TestingGuide</a> for more details. You
|
||||
can easily write Makefile support similar to the Makefiles in <tt>llvm/test</tt>
|
||||
to use Dejagnu to run your project's tests.</li>
|
||||
|
||||
<p>
|
||||
|
||||
<li>
|
||||
The LLVM source tree provides benchmarks and programs which are
|
||||
known to compile with the LLVM GCC front ends. You can use these
|
||||
LLVM contains an optional package called <tt>llvm-test</tt>
|
||||
which provides benchmarks and programs that are known to compile with the
|
||||
LLVM GCC front ends. You can use these
|
||||
programs to test your code, gather statistics information, and
|
||||
compare it to the current LLVM performance statistics. These
|
||||
programs are found in the <tt>llvm/test/Programs</tt> directory.
|
||||
compare it to the current LLVM performance statistics.
|
||||
<p>
|
||||
Currently, there is no way to hook your tests directly into the
|
||||
<tt>llvm/test/Programs</tt> testing harness. You will simply
|
||||
<tt>llvm/test</tt> testing harness. You will simply
|
||||
need to find a way to use the source provided within that directory
|
||||
on your own.
|
||||
</ul>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<ul>
|
||||
<li><a href="#experimental">Experimental features included in this
|
||||
release</a>
|
||||
<li><a href="#build">Known problems with the LLVM Build</a>
|
||||
<li><a href="#core">Known problems with the LLVM Core</a>
|
||||
<li><a href="#c-fe">Known problems with the C Front-end</a>
|
||||
<li><a href="#c++-fe">Known problems with the C++ Front-end</a>
|
||||
@@ -44,14 +45,14 @@
|
||||
|
||||
<p>This document contains the release notes for the LLVM compiler
|
||||
infrastructure, release 1.4. Here we describe the status of LLVM, including any
|
||||
known problems and bug fixes from the previous release. The most up-to-date
|
||||
known problems and improvements from the previous release. The most up-to-date
|
||||
version of this document can be found on the <a
|
||||
href="http://llvm.cs.uiuc.edu/releases/1.4/">LLVM 1.4 web site</a>. If you are
|
||||
not reading this on the LLVM web pages, you should probably go there because
|
||||
this document may be updated after the release.</p>
|
||||
|
||||
<p>For more information about LLVM, including information about potentially more
|
||||
current releases, please check out the <a href="http://llvm.cs.uiuc.edu">main
|
||||
<p>For more information about LLVM, including information about the latest
|
||||
release, please check out the <a href="http://llvm.cs.uiuc.edu">main LLVM
|
||||
web site</a>. If you have questions or comments, the <a
|
||||
href="http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVM developer's mailing
|
||||
list</a> is a good place to send them.</p>
|
||||
@@ -73,9 +74,18 @@ href="http://llvm.cs.uiuc.edu/releases/">releases page</a>.</p>
|
||||
|
||||
<p>This is the fifth public release of the LLVM compiler infrastructure.</p>
|
||||
|
||||
<p> At this time, LLVM is known to correctly compile and run all C & C++
|
||||
SPEC CPU95 & 2000 benchmarks, the Olden benchmarks, and the Ptrdist
|
||||
benchmarks, and <b>many</b> other C and C++ programs.</p>
|
||||
<p> At this time, LLVM is known to correctly compile on a broad range of
|
||||
C and C++ programs, including the SPEC CPU95 & 2000 suite. This release
|
||||
includes several major enhancements to the LLVM system, including a new
|
||||
PowerPC JIT, enhancements to the C/C++ front-end to provide source line number
|
||||
information in LLVM, a new <a href="CommandGuide/html/llvmc.html">compiler
|
||||
driver</a>, and several other enhancements listed below. It also includes
|
||||
bug fixes for those problems found since the 1.3 release.</p>
|
||||
|
||||
<p>Note that this release seperates the LLVM Program Testsuite out of the
|
||||
main LLVM distribution into a seperate CVS repository and tarball. This
|
||||
reduces the size of the main LLVM distribution. Also note that LLVM now
|
||||
builds tools into llvm/Debug/bin by default instead of llvm/tools/Debug.</p>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -86,71 +96,67 @@ benchmarks, and <b>many</b> other C and C++ programs.</p>
|
||||
|
||||
<div class="doc_text">
|
||||
<ol>
|
||||
<li>LLVM now includes a JIT for the PowerPC target.</li>
|
||||
<li>LLVM now optimizes global variables significantly more than it did
|
||||
before.
|
||||
<li>LLVM now includes a Just-In-Time compiler for the PowerPC target.</li>
|
||||
<li>llvmgcc and llvmg++ now emit source line number information when '-g' is
|
||||
passed in, making it possible to map from LLVM code back to source.
|
||||
This information is currently used by llvm-db and can be used with other
|
||||
tools and passes.</li>
|
||||
<li>The test/Programs hierarchy <a href="http://llvm.cs.uiuc.edu/PR257">has
|
||||
been moved out of the main LLVM tree</a> into a separate CVS repository and
|
||||
tarball. This shrinks the distribution size of LLVM itself significantly.
|
||||
</li>
|
||||
<li>LLVM now optimizes global variables more aggressively than it did
|
||||
before.</li>
|
||||
<li>LLVM now includes the new '<tt>undef</tt>' value and
|
||||
<a href="LangRef.html#i_unreachable"><tt>unreachable</tt></a> instruction,
|
||||
which give the optimizer more information about the behavior of the
|
||||
program.
|
||||
</li>
|
||||
<li>llvmgcc and llvmg++ now emit source line number information when '-g' is
|
||||
passed in. This information can be used with llvm-db or other tools and
|
||||
passes.
|
||||
</li>
|
||||
<li>The test/Programs hierarchy <a href="http://llvm.cs.uiuc.edu/PR257">has
|
||||
been moved out of the main LLVM tree</a> into a separate CVS repository and
|
||||
tarball. This shrinks the distribution size of LLVM itself significantly.
|
||||
</li>
|
||||
<li>Bytecode compression with bzip2 has been implemented. All bytecode files
|
||||
generated by LLVM will now be compressed by default. Compression can be
|
||||
disabled with the <tt>-disable-compression</tt> option to the tools that can
|
||||
generate bytecode files.
|
||||
</li>
|
||||
<li>A generic <a href="http://llvm.cs.uiuc.edu/PR353">compiler driver</a> and
|
||||
an associated <a href="CommandGuide/html/llvm-ld.html">generic linker</a> have
|
||||
been implemented. The compiler driver is generic because it can be configured
|
||||
<li>A generic <a href="CommandGuide/html/llvmc.html">compiler driver</a>
|
||||
(llvmc) and
|
||||
an associated <a href="CommandGuide/html/llvm-ld.html">generic linker</a>
|
||||
(llvm-ld) have been added. The compiler driver is generic because it can be
|
||||
configured
|
||||
to pre-process, translate, optimize, assemble, and link code from any source
|
||||
language. This aids compiler writers because all that is needed is a
|
||||
source-to-bytecode or source-to-assembly translator and a configuration file.
|
||||
The linker is generic because it allows dynamically loadable optimization
|
||||
modules to be executed for link-time optimization. Language specific
|
||||
link-time optimization modules can be created and executed automatically.
|
||||
language with an LLVM front-end. This makes it easier for compiler writers
|
||||
to hide the multiple steps required to compile a program (compiling,
|
||||
optimizing, linking runtime libraries, etc) in one simple command.
|
||||
</li>
|
||||
<li>The <a href="http://llvm.cs.uiuc.edu/PR263">dependent libraries</a>
|
||||
feature has been implemented. This allows front end compilers to indicate in
|
||||
the bytecode which libraries the bytecode needs to be linked with. Both the
|
||||
C/C++ front end and Stacker support generating the required libraries. The
|
||||
Linker now supports using this information to ensure required libaries are
|
||||
C/C++ and Stacker front ends support generating the required dependencies.
|
||||
The linker now supports using this information to ensure required libaries are
|
||||
linked into the module. This minimizes the need to use the <tt>-l</tt> option
|
||||
when using <a href="CommandGuide/html/llvmc.html"><tt>llvmc</tt></a>
|
||||
when using <a href="CommandGuide/html/llvmc.html"><tt>llvmc</tt></a>.
|
||||
</li>
|
||||
<li>The LLVM makefiles have been improved to build LLVM faster (2x) and
|
||||
includes new targets (like dist-check, uninstall). One important change is
|
||||
associated with <a href="http://llvm.cs.uiuc.edu/PR456">PR456</a>. The
|
||||
libraries and tools will now be built into <tt>$builddir/Debug/{bin,lib}</tt>
|
||||
instead of <tt>$builddir/tools/Debug</tt> and <tt>$builddir/lib/Debug</tt>.
|
||||
Similarly for <tt>Release</tt> and <tt>Profile</tt> builds.
|
||||
<li>The LLVM makefiles have been improved to build LLVM much faster and
|
||||
includes new targets (like dist-check, uninstall). One important user-visible
|
||||
change is that libraries and tools will now be built into
|
||||
<tt>$builddir/Debug/{bin,lib}</tt>
|
||||
instead of <tt>$builddir/tools/Debug</tt> and <tt>$builddir/lib/Debug</tt>
|
||||
(Similarly for <tt>Release</tt> and <tt>Profile</tt> builds).
|
||||
</li>
|
||||
<li>The LLVM source code is much more compatible with Microsoft Visual C++,
|
||||
including the JIT and runtime-code generation, though the entire system
|
||||
may not work with it.
|
||||
</li>
|
||||
<li>The target-to-JIT interfaces <a href="http://llvm.cs.uiuc.edu/PR283">are
|
||||
<li>The JIT-Target interfaces <a href="http://llvm.cs.uiuc.edu/PR283">are
|
||||
now much simpler</a> and more powerful.
|
||||
</li>
|
||||
<li>LLVM now provides llvm-ar and llvm-ranlib tools for working with archives
|
||||
of LLVM bytecode files.</li>
|
||||
<li>zlib and libpng are <a href="http://llvm.cs.uiuc.edu/PR417">no longer
|
||||
included in the main LLVM tarball</a>.</li>
|
||||
<li>The LLVM code generator now generates asm writers for the target from
|
||||
an abstract target description, instead of requiring them to be hand
|
||||
written.</li>
|
||||
<li>LLVM regression and feature tests can now be run with DejaGNU.</li>
|
||||
<li>llvmgcc and llvmg++ now emit source-level line number information, making
|
||||
it possible to map from LLVM code back to source. This is currently used
|
||||
by llvm-db.</li>
|
||||
<li>Floating point intensive programs on X86 systems run much faster
|
||||
with the LLC code generator and JIT than in 1.3.</li>
|
||||
<li>The LLVM code generator now automatically generates assembly code writers
|
||||
from an abstract target descriptions, eliminating the need to write
|
||||
assembly printers manually.</li>
|
||||
<li>LLVM regression and feature tests now use DejaGNU instead of QMTest.</li>
|
||||
</ol>
|
||||
|
||||
</div>
|
||||
@@ -187,11 +193,12 @@ issues were fixed:</a>
|
||||
<div class="doc_text">
|
||||
|
||||
<ol>
|
||||
<li><a href="http://llvm.cs.uiuc.edu/PR426">[llvmg++] Tons of warnings
|
||||
are spewed when linking to libstdc++</a>
|
||||
<li>The linker no longer <a href="http://llvm.cs.uiuc.edu/PR426">emits many
|
||||
useless warnings</a> when linking C++ programs.
|
||||
</li>
|
||||
<li><a href="http://llvm.cs.uiuc.edu/PR352">include/{Support,Config} ->
|
||||
include/llvm/{Support,Config}</a>
|
||||
<li>The LLVM <a href="http://llvm.cs.uiuc.edu/PR352">#include namespace</a>
|
||||
has been made consistent. Files in <tt>llvm/include/{Support,Config}</tt>
|
||||
are now located in <tt>llvm/include/llvm/{Support,Config}</tt>.
|
||||
</li>
|
||||
<li>The names of the libraries generated by compiling LLVM source have been
|
||||
changed to ensure they do not conflict with other packages upon installation.
|
||||
@@ -199,23 +206,13 @@ issues were fixed:</a>
|
||||
the library <tt>libasmparser.a</tt> in 1.3 has become
|
||||
<tt>libLLVMAsmParser.a</tt> in release 1.4.
|
||||
</li>
|
||||
<li><a href="http://llvm.cs.uiuc.edu/PR459">[llvmg++] C++ frontend is expanding
|
||||
lots of unused inline functions</a></li>
|
||||
</ol>
|
||||
<li>The C++ frontend no longer expands and emits <a
|
||||
href="http://llvm.cs.uiuc.edu/PR459">all inline functions, even if they
|
||||
are unused</a>. It now properly tracks which functions are needed and
|
||||
only compiles those.</li>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<div class="doc_subsubsection">
|
||||
In this release, the following build problems were fixed:
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<ol>
|
||||
<li><a href="http://llvm.cs.uiuc.edu/PR256">[autoconf] further standardizing
|
||||
autoconf usage</a>. Various improvements in the configure.ac script were
|
||||
made as well as the makefile system.
|
||||
</li>
|
||||
<li>Many improvements in the <a href="http://llvm.cs.uiuc.edu/PR256">autoconf
|
||||
and makefile systems</a> have been implemented.</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
@@ -227,9 +224,12 @@ improvements:</a>
|
||||
|
||||
<div class="doc_text">
|
||||
<ol>
|
||||
<li><a href="http://llvm.cs.uiuc.edu/PR362">Ugly code generated for
|
||||
std::min/std::max</a>
|
||||
</li>
|
||||
<li>The optimizer produces <a href="http://llvm.cs.uiuc.edu/PR362">more
|
||||
efficient code for std::min/std::max</a> and other similar functions.</li>
|
||||
<li>The X86 backend generates substantially faster code for floating point
|
||||
intensive programs.</li>
|
||||
<li>The PowerPC backend generates more efficient code in many common
|
||||
scenarios.</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
@@ -269,7 +269,7 @@ were fixed:</a>
|
||||
bitfield which does not increase struct size</a></li>
|
||||
<li><a href="http://llvm.cs.uiuc.edu/PR424">[llvmgcc] llvmgcc emits invalid
|
||||
constant exprs</a></li>
|
||||
<li><a href="http://llvm.cs.uiuc.edu/PR421">[llvmg++] Crash in initializing
|
||||
<li><a href="http://llvm.cs.uiuc.edu/PR421">[llvmg++] Crash initializing
|
||||
array with constructors in hard EH situations</a></li>
|
||||
<li><a href="http://llvm.cs.uiuc.edu/PR397">[llvm-gcc] Inline function
|
||||
redefinitions error due to 'asm' function rename</a></li>
|
||||
@@ -298,14 +298,15 @@ were fixed:</a>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>LLVM is known to work in the following platforms:</p>
|
||||
<p>LLVM is known to work on the following platforms:</p>
|
||||
|
||||
<ul>
|
||||
<li>Intel and AMD machines running Red Hat Linux and FreeBSD (and probably
|
||||
other unix-like systems).</li>
|
||||
<li>Sun UltraSPARC workstations running Solaris 8.</li>
|
||||
<li>Intel and AMD machines running on Win32 with the Cygwin libraries.</li>
|
||||
<li>PowerPC-based Mac OS X boxes, running 10.2 and above.</li>
|
||||
<li>Intel and AMD machines running on Win32 with the Cygwin libraries (limited
|
||||
support is available for native builds with Visual C++).</li>
|
||||
<li>PowerPC-based Mac OS X systems, running 10.2 and above.</li>
|
||||
</ul>
|
||||
|
||||
<p>The core LLVM infrastructure uses
|
||||
@@ -314,6 +315,7 @@ to the machine and operating system on which it is built. However, minor
|
||||
porting may be required to get LLVM to work on new platforms. We welcome your
|
||||
portability patches and reports of successful builds or error messages.</p>
|
||||
|
||||
<!--
|
||||
<p>Note that the LLVM build system does not currently support directories with
|
||||
spaces on them when running on Win32/cygwin. We strongly recommend running
|
||||
LLVM and the C frontend out of a top-level directory without spaces (e.g.,
|
||||
@@ -322,6 +324,7 @@ cygwin packages. By default, many important tools are not installed that
|
||||
are needed by the LLVM build process or test suite (e.g., /bin/time). Finally,
|
||||
please make sure that there are no directories with spaces in them in your
|
||||
PATH environment variable.</p>
|
||||
-->
|
||||
|
||||
</div>
|
||||
|
||||
@@ -355,17 +358,31 @@ useful to some people. In particular, if you would like to work on one of these
|
||||
components, please contact us on the llvmdev list.</p>
|
||||
|
||||
<ul>
|
||||
<li>The following passes are incomplete or buggy: <tt>-pgmdep, -memdep,
|
||||
-ipmodref, -cee, -branch-combine, -instloops, -paths</tt></li>
|
||||
<li>The <tt>-pre</tt> pass is incomplete (there are cases it doesn't handle that
|
||||
it should) and not thoroughly tested.</li>
|
||||
<li>The <tt>llvm-db</tt> tool is in a very early stage of development.</li>
|
||||
<li>The following passes are incomplete or buggy, and may be removed in future
|
||||
releases: <tt>-pgmdep, -memdep, -ipmodref, -cee, -branch-combine,
|
||||
-instloops, -paths, -pre</tt></li>
|
||||
<li>The <tt>llvm-db</tt> tool is in a very early stage of development, but can
|
||||
be used to step through programs and inspect the stack.</li>
|
||||
<li>The "iterative scan" register allocator (enabled with -regalloc=iterativescan)
|
||||
is not stable.</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
<a name="build">Known problems with the LLVM Build</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
On some platforms, flex and bison may generate warnings. Usually, these can
|
||||
be safely ignored.
|
||||
</li>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
<a name="core">Known problems with the LLVM Core</a>
|
||||
@@ -380,22 +397,10 @@ components, please contact us on the llvmdev list.</p>
|
||||
such, execution of a threaded program could cause these data structures to be
|
||||
corrupted.
|
||||
</li>
|
||||
<li>Linking in static archive files (.a files) is slow by default because
|
||||
there is no symbol table in the archive. To remedy this, run
|
||||
<a href="CommandGuide/html/llvm-ranlib.html"><tt>llvm-ranlib</tt></a> on the
|
||||
archive to add an LLVM symbol table.
|
||||
</li>
|
||||
<li>The gccld program <a href="http://llvm.cs.uiuc.edu/PR139">does not link
|
||||
objects/archives in the order specified on the command line.</a>
|
||||
</li>
|
||||
<li><a href="http://llvm.cs.uiuc.edu/PR240">The lower-invoke pass does not
|
||||
mark values live across a setjmp as volatile</a>. This missing feature
|
||||
only affects targets whose setjmp/longjmp libraries do not save and restore
|
||||
the entire register file.</li>
|
||||
<li><a href="http://llvm.cs.uiuc.edu/PR427">[bytecode] Assertion on V1
|
||||
Bytecode Files</a>. This bug won't be fixed because V1 bytecode had its own
|
||||
problems, no one is using V1 bytecode any more, and the fix is non-trivial.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -421,9 +426,6 @@ components, please contact us on the llvmdev list.</p>
|
||||
<li>Initialization of global union variables can only be done <a
|
||||
href="http://llvm.cs.uiuc.edu/PR162">with the largest union member</a>.</li>
|
||||
|
||||
<li><a href="http://llvm.cs.uiuc.edu/PR244">[llvm-gcc] Error when an implicitly
|
||||
external function is re-declared as static</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -464,7 +466,7 @@ work:
|
||||
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Explicit-Reg-Vars.html#Explicit%20Reg%20Vars">Explicit Reg Vars</a>: Defining variables residing in specified registers.</li>
|
||||
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html#Vector%20Extensions">Vector Extensions</a>: Using vector instructions through built-in functions.</li>
|
||||
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Target-Builtins.html#Target%20Builtins">Target Builtins</a>: Built-in functions specific to particular targets.</li>
|
||||
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Thread-Local.html#Thread-Local">Thread-Local</a>: Per-thread variables.</li>
|
||||
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Thread_002dLocal.html">Thread-Local</a>: Per-thread variables.</li>
|
||||
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Pragmas.html#Pragmas">Pragmas</a>: Pragmas accepted by GCC.</li>
|
||||
</ol>
|
||||
|
||||
@@ -485,10 +487,11 @@ work:
|
||||
return.<br>
|
||||
|
||||
<b>Supported:</b> <tt>format</tt>, <tt>format_arg</tt>, <tt>non_null</tt>,
|
||||
<tt>constructor</tt>, <tt>destructor</tt>, <tt>unused</tt>,
|
||||
<tt>noreturn</tt>, <tt>constructor</tt>, <tt>destructor</tt>,
|
||||
<tt>unused</tt>,
|
||||
<tt>deprecated</tt>, <tt>warn_unused_result</tt>, <tt>weak</tt><br>
|
||||
|
||||
<b>Ignored:</b> <tt>noreturn</tt>, <tt>noinline</tt>,
|
||||
<b>Ignored:</b> <tt>noinline</tt>,
|
||||
<tt>always_inline</tt>, <tt>pure</tt>, <tt>const</tt>, <tt>nothrow</tt>,
|
||||
<tt>malloc</tt>, <tt>no_instrument_function</tt>, <tt>cdecl</tt><br>
|
||||
|
||||
@@ -549,7 +552,7 @@ or arrays as values.</li>
|
||||
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html#Case%20Ranges">Case Ranges</a>: `case 1 ... 9' and such.</li>
|
||||
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Mixed-Declarations.html#Mixed%20Declarations">Mixed Declarations</a>: Mixing declarations and code.</li>
|
||||
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Function-Prototypes.html#Function%20Prototypes">Function Prototypes</a>: Prototype declarations and old-style definitions.</li>
|
||||
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/C---Comments.html#C++%20Comments">C++ Comments</a>: C++ comments are recognized.</li>
|
||||
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Comments.html#C_002b_002b-Comments">C++ Comments</a>: C++ comments are recognized.</li>
|
||||
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Dollar-Signs.html#Dollar%20Signs">Dollar Signs</a>: Dollar sign is allowed in identifiers.</li>
|
||||
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Character-Escapes.html#Character%20Escapes">Character Escapes</a>: <code>\e</code> stands for the character <ESC>.</li>
|
||||
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Alignment.html#Alignment">Alignment</a>: Inquiring about the alignment of a type or variable.</li>
|
||||
@@ -576,10 +579,9 @@ lists, please let us know (also including whether or not they work).</p>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>For this release, the C++ front-end is considered to be fully functional but
|
||||
has not been tested as thoroughly as the C front-end. It has been tested and
|
||||
works for a number of non-trivial programs, but there may be lurking bugs.
|
||||
Please report any bugs or problems.</p>
|
||||
<p>For this release, the C++ front-end is considered to be fully
|
||||
tested and works for a number of non-trivial programs, including LLVM
|
||||
itself.</p>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -691,10 +693,6 @@ Analysis rules. As such, special options may be necessary to compile the code
|
||||
(for example, GCC requires the <tt>-fno-strict-aliasing</tt> option). This
|
||||
problem probably cannot be fixed.</li>
|
||||
|
||||
<li><a href="http://llvm.cs.uiuc.edu/PR33">Initializers for global variables</a>
|
||||
cannot include special floating point numbers like Not-A-Number or
|
||||
Infinity.</li>
|
||||
|
||||
<li><a href="http://llvm.cs.uiuc.edu/PR56">Zero arg vararg functions are not
|
||||
supported</a>. This should not affect LLVM produced by the C or C++
|
||||
frontends.</li>
|
||||
|
||||
@@ -22,15 +22,15 @@
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#tree">LLVM Test Suite Tree</a></li>
|
||||
<li><a href="#qmstructure">QMTest Structure</a></li>
|
||||
<li><a href="#dgstructure">DejaGNU Structure</a></li>
|
||||
<li><a href="#progstructure"><tt>llvm-test</tt> Structure</a></li>
|
||||
<li><a href="#run">Running the LLVM Tests</a></li>
|
||||
<li><a href="#nightly">Running the nightly tester</a></li>
|
||||
</ol>
|
||||
|
||||
<div class="doc_author">
|
||||
<p>Written by John T. Criswell and <a
|
||||
href="http://llvm.x10sys.com/rspencer">Reid Spencer</a></p>
|
||||
<p>Written by John T. Criswell, <a
|
||||
href="http://llvm.x10sys.com/rspencer">Reid Spencer</a>, and Tanya Lattner</p>
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
@@ -55,15 +55,12 @@ and run tests.</p>
|
||||
required to build LLVM, plus the following:</p>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://www.qmtest.com">QMTest</a></dt>
|
||||
<dd>The LLVM test suite uses QMTest to organize and run tests. <b>Note:
|
||||
you will need <a href="http://llvm.cs.uiuc.edu/qm-2.0.3.tar.gz">QMTest
|
||||
2.0.3 (source tar.gz file)</a> to be successful. The tests do not run with
|
||||
any other version.</b></dd>
|
||||
|
||||
<dt><a href="http://www.python.org">Python</a></dt>
|
||||
<dd>You will need a Python interpreter that works with QMTest. Python will
|
||||
need zlib and SAX support enabled.</dd>
|
||||
<dt><a href="http://www.gnu.org/software/dejagnu/">DejaGNU</a></dt>
|
||||
<dd>The Feature and Regressions tests are organized and run by DejaGNU.</dd>
|
||||
<dt><a href="http://expect.nist.gov/">Expect</a></dt>
|
||||
<dd>Expect is required by DejaGNU.</dd>
|
||||
<dt><a href="http://www.tcl.tk/software/tcltk/">tcl</a></dt>
|
||||
<dd>Tcl is required by DejaGNU. </dd>
|
||||
|
||||
<dt><a href="http://www.netlib.org/f2c">F2C</a></dt>
|
||||
<dd>For now, LLVM does not have a Fortran front-end, but using F2C, we can run
|
||||
@@ -105,30 +102,21 @@ regression tests are in the main "llvm" module under the directory
|
||||
programs in C and C++ is in the <tt>llvm-test</tt> module. This module should
|
||||
be checked out to the <tt>llvm/projects</tt> directory. When you
|
||||
<tt>configure</tt> the <tt>llvm</tt> module, the <tt>llvm-test</tt> module
|
||||
will be automatically configured. Or you can do it manually.</p>
|
||||
<p>To run all of the simple tests in LLVM, use the master Makefile in the
|
||||
will be automatically configured. Alternatively, you can configure the <tt>llvm-test</tt> module manually.</p>
|
||||
<p>To run all of the simple tests in LLVM using DejaGNU, use the master Makefile in the
|
||||
<tt>llvm/test</tt> directory:</p>
|
||||
<pre>
|
||||
% gmake -C llvm/test
|
||||
</pre>
|
||||
|
||||
<p>To run only the code fragment tests (i.e. those that do basic testing of
|
||||
LLVM), run the tests organized by QMTest:</p>
|
||||
or<br>
|
||||
<pre>
|
||||
% gmake -C llvm/test qmtest
|
||||
% gmake check
|
||||
</pre>
|
||||
|
||||
<p>To run only the basic feature tests, QMTest supports the following
|
||||
target:</p>
|
||||
<p>To run only a subdirectory of tests in llvm/test using DejaGNU (ie. Regression/Transforms). Just substitute the path to the subdirectory:</p>
|
||||
<pre>
|
||||
% gmake -C llvm/test Feature.t
|
||||
</pre>
|
||||
|
||||
<p>To run only the regression tests, QMTest supports the following
|
||||
target:</p>
|
||||
<pre>
|
||||
% gmake -C llvm/test Regression.t
|
||||
% gmake -C llvm/test TESTSUITE=Regression/Transforms
|
||||
</pre>
|
||||
<dd><b>Note: If you are running the tests with <tt>objdir != subdir</tt> you must have run the complete testsuite before you can specify a subdirectory.</b></dd>
|
||||
|
||||
<p>To run the comprehensive test suite (tests that compile and execute whole
|
||||
programs), run the <tt>llvm-test</tt> tests:</p>
|
||||
@@ -152,7 +140,7 @@ programs), run the <tt>llvm-test</tt> tests:</p>
|
||||
<p>The LLVM test suite contains two major categories of tests: code
|
||||
fragments and whole programs. Code fragments are in the <tt>llvm</tt> module
|
||||
under the directory under the <tt>llvm/test</tt> directory. The whole programs
|
||||
test suite are n the <tt>llvm-test</tt> module under the main directory.</p>
|
||||
test suite are in the <tt>llvm-test</tt> module under the main directory.</p>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -169,7 +157,7 @@ language front end.</p>
|
||||
<p>Code fragments are not complete programs, and they are never executed to
|
||||
determine correct behavior.</p>
|
||||
|
||||
<p>Thes code fragment tests are located in the <tt>llvm/test/Features</tt> and
|
||||
<p>These code fragment tests are located in the <tt>llvm/test/Features</tt> and
|
||||
<tt>llvm/test/Regression</tt> directories.</p>
|
||||
|
||||
</div>
|
||||
@@ -253,87 +241,85 @@ directory are the SPEC 95 and SPEC 2000 benchmark suites. The presence and
|
||||
location of these external programs is configured by the llvm-test
|
||||
<tt>configure</tt> script.</p></li>
|
||||
|
||||
<li><tt>llvm/test/QMTest</tt>
|
||||
<p>This directory contains the QMTest information files. Inside this directory
|
||||
are QMTest administration files and the Python code that implements the LLVM
|
||||
test and database classes.</p></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<div class="doc_section"><a name="qmstructure">QMTest Structure</a></div>
|
||||
<div class="doc_section"><a name="dgstructure">DejaGNU Structure</a></div>
|
||||
<!--=========================================================================-->
|
||||
|
||||
<div class="doc_text">
|
||||
<p>The LLVM test suite is partially driven by DejaGNU and partially
|
||||
driven by GNU Make. Specifically, the Features and Regression tests
|
||||
are all driven by DejaGNU. The <tt>llvm-test</tt>
|
||||
module is currently driven by a set of Makefiles.</p>
|
||||
|
||||
<p>The LLVM test suite is partially driven by QMTest and partially driven by GNU
|
||||
Make. Specifically, the Features and Regression tests are all driven by QMTest.
|
||||
The <tt>llvm-test</tt> module is currently driven by a set of Makefiles.</p>
|
||||
<p>The DejaGNU structure is very simple, but does require some
|
||||
information to be set. This information is gathered via <tt>configure</tt> and
|
||||
is written to a file, <tt>site.exp</tt> in <tt>llvm/test</tt>. The
|
||||
<tt>llvm/test</tt>
|
||||
Makefile does this work for you.</p>
|
||||
|
||||
<p>The QMTest system needs to have several pieces of information available;
|
||||
these pieces of configuration information are known collectively as the
|
||||
"context" in QMTest parlance. Since the context for LLVM is relatively large,
|
||||
the master Makefile in llvm/test sets it for you.</p>
|
||||
|
||||
<p>The LLVM database class makes the subdirectories of llvm/test a QMTest test
|
||||
database. For each directory that contains tests driven by QMTest, it knows
|
||||
what type of test the source file is and how to run it.</p>
|
||||
|
||||
<p>Hence, the QMTest namespace is essentially what you see in the Feature and
|
||||
Regression directories, but there is some magic that the database class performs
|
||||
(as described below).</p>
|
||||
|
||||
<p>The QMTest namespace is currently composed of the following tests and test
|
||||
suites:</p>
|
||||
<p>In order for DejaGNU to work, each directory of tests must have a
|
||||
<tt>dg.exp</tt> file. This file is a program written in tcl that calls
|
||||
the <tt>llvm-runtests</tt> procedure on each test file. The
|
||||
llvm-runtests procedure is defined in
|
||||
<tt>llvm/test/lib/llvm-dg.exp</tt>. Any directory that contains only
|
||||
directories does not need the <tt>dg.exp</tt> file.</p>
|
||||
|
||||
<p>In order for a test to be run, it must contain information within
|
||||
the test file on how to run the test. These are called <tt>RUN</tt>
|
||||
lines. Run lines are specified in the comments of the test program
|
||||
using the keyword <tt>RUN</tt> followed by a colon, and lastly the
|
||||
commands to execute. These commands will be executed in a bash script,
|
||||
so any bash syntax is acceptable. You can specify as many RUN lines as
|
||||
necessary. Each RUN line translates to one line in the resulting bash
|
||||
script. Below is an example of legal RUN lines in a <tt>.ll</tt>
|
||||
file:</p>
|
||||
<pre>
|
||||
; RUN: llvm-as < %s | llvm-dis > %t1
|
||||
; RUN: llvm-dis < %s.bc-13 > %t2
|
||||
; RUN: diff %t1 %t2
|
||||
</pre>
|
||||
<p>There are a couple patterns within a <tt>RUN</tt> line that the
|
||||
llvm-runtest procedure looks for and replaces with the appropriate
|
||||
syntax:</p>
|
||||
<ul>
|
||||
<li>Feature
|
||||
<dt>%p</dt>
|
||||
<dd>The path to the source directory. This is for locating
|
||||
any supporting files that are not generated by the test, but used by
|
||||
the test.</dd>
|
||||
<dt>%s</dt>
|
||||
<dd>The test file.</dd>
|
||||
|
||||
<p>These are the feature tests found in the Feature directory.
|
||||
They are broken up into the following categories:</p>
|
||||
<dt>%t</dt>
|
||||
<dd>Temporary filename: testscript.test_filename.tmp, where
|
||||
test_filename is the name of the test file. All temporary files are
|
||||
placed in the Output directory within the directory the test is
|
||||
located.</dd>
|
||||
|
||||
<ul>
|
||||
<li>ad
|
||||
<p>Assembler/Disassembler tests. These tests verify that a piece of LLVM
|
||||
assembly language can be assembled into bytecode and then disassembled
|
||||
into the original assembly language code. It does this several times to
|
||||
ensure that assembled output can be disassembled and disassembler output
|
||||
can be assembled. It also verifies that the give assembly language file
|
||||
can be assembled correctly.</p></li>
|
||||
<dt>%prcontext</dt>
|
||||
<dd>Path to a script that performs grep -C. Use this since not all
|
||||
platforms support grep -C.</dd>
|
||||
|
||||
<li>opt
|
||||
<p>Optimizer tests. These tests verify that two of the optimizer passes
|
||||
completely optimize a program (i.e. after a single pass, they cannot
|
||||
optimize a program any further).</p></li>
|
||||
|
||||
<li>mc
|
||||
<p> Machine code tests. These tests verify that the LLVM assembly
|
||||
language file can be translated into native assembly code.</p></li>
|
||||
|
||||
<li>cc
|
||||
<p>C code tests. These tests verify that the specified LLVM assembly
|
||||
code can be converted into C source code using the C backend.</p></li>
|
||||
<dt>%llvmgcc</dt> <dd>Full path to the llvmgcc executable.</dd>
|
||||
<dt>%llvmgxx</dt> <dd>Full path to the llvmg++ executable.</dd>
|
||||
</ul>
|
||||
|
||||
<p>The LLVM database class looks at every file in the Feature directory and
|
||||
creates a fake test hierarchy containing
|
||||
<tt>Feature.<testtype>.<testname></tt>. So, if you add an LLVM
|
||||
assembly language file to the Feature directory, it actually creates 5 new
|
||||
tests: assembler/disassembler, assembler, optimizer, machine code, and C code.
|
||||
</p></li>
|
||||
<p>There are also several scripts in the llvm/test/Scripts directory
|
||||
that you might find useful when writing <tt>RUN</tt> lines.</p>
|
||||
|
||||
<li>Regression
|
||||
<p>These are the regression tests. There is one suite for each
|
||||
subdirectory of the Regression directory. If you add a new subdirectory
|
||||
there, you will need to modify, at least, the <tt>RegressionMap</tt>
|
||||
variable in <tt>QMTest/llvmdb.py</tt> so that QMTest knows how to run the
|
||||
tests in the new subdirectory.</p>
|
||||
</li>
|
||||
<p>Lastly, you can easily mark a test that is expected to fail on a
|
||||
specific platform by using the <tt>XFAIL</tt> keyword. Xfail lines are
|
||||
specified in the comments of the test program using <tt>XFAIL</tt>,
|
||||
followed by a colon, and one or more regular expressions (separated by
|
||||
a comma) that will match against the target triplet for the
|
||||
machine. You can use * to match all targets. Here is an example of an
|
||||
<tt>XFAIL</tt> line:</p>
|
||||
<pre>
|
||||
; XFAIL: darwin,sun
|
||||
</pre>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
@@ -364,7 +350,33 @@ designed for internal LLVM research and will not work outside of the LLVM
|
||||
research group. They may still be valuable, however, as a guide to writing your
|
||||
own TEST Makefile for any optimization or analysis passes that you develop with
|
||||
LLVM.</p>
|
||||
|
||||
|
||||
<p>Note, when configuring the <tt>llvm-test</tt> module, you might want to
|
||||
specify the following configuration options:</p>
|
||||
<dl>
|
||||
<dt><i>--enable-spec2000</i>
|
||||
<dt><i>--enable-spec2000=<<tt>directory</tt>></i>
|
||||
<dd>
|
||||
Enable the use of SPEC2000 when testing LLVM. This is disabled by default
|
||||
(unless <tt>configure</tt> finds SPEC2000 installed). By specifying
|
||||
<tt>directory</tt>, you can tell configure where to find the SPEC2000
|
||||
benchmarks. If <tt>directory</tt> is left unspecified, <tt>configure</tt>
|
||||
uses the default value
|
||||
<tt>/home/vadve/shared/benchmarks/speccpu2000/benchspec</tt>.
|
||||
<p>
|
||||
<dt><i>--enable-spec95</i>
|
||||
<dt><i>--enable-spec95=<<tt>directory</tt>></i>
|
||||
<dd>
|
||||
Enable the use of SPEC95 when testing LLVM. It is similar to the
|
||||
<i>--enable-spec2000</i> option.
|
||||
<p>
|
||||
<dt><i>--enable-povray</i>
|
||||
<dt><i>--enable-povray=<<tt>directory</tt>></i>
|
||||
<dd>
|
||||
Enable the use of Povray as an external test. Versions of Povray written
|
||||
in C should work. This option is similar to the <i>--enable-spec2000</i>
|
||||
option.
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
@@ -377,18 +389,19 @@ LLVM.</p>
|
||||
<i>are not</i> executed inside of the LLVM source tree. This is because the
|
||||
test suite creates temporary files during execution.</p>
|
||||
|
||||
<p>The master Makefile in llvm/test is capable of running only the QMTest driven
|
||||
<p>The master Makefile in llvm/test is capable of running only the DejaGNU driven
|
||||
tests. By default, it will run all of these tests.</p>
|
||||
|
||||
<p>To run only the QMTest driven tests, run <tt>gmake qmtest</tt> at the
|
||||
command line in llvm/tests. To run a specific qmtest, suffix the test name with
|
||||
".t" when running gmake.</p>
|
||||
<p>To run only the DejaGNU driven tests, run <tt>gmake</tt> at the
|
||||
command line in llvm/tests. To run a specific directory of tests, use the
|
||||
TESTSUITE variable.
|
||||
</p>
|
||||
|
||||
<p>For example, to run the Regression.LLC tests, type
|
||||
<tt>gmake Regression.LLC.t</tt> in <tt>llvm/tests</tt>.</p>
|
||||
<p>For example, to run the Regression tests, type
|
||||
<tt>gmake TESTSUITE=Regression</tt> in <tt>llvm/tests</tt>.</p>
|
||||
|
||||
<p>Note that there are no Makefiles in <tt>llvm/test/Features</tt> and
|
||||
<tt>llvm/test/Regression</tt>. You must use QMTest from the <tt>llvm/test</tt>
|
||||
<tt>llvm/test/Regression</tt>. You must use DejaGNU from the <tt>llvm/test</tt>
|
||||
directory to run them.</p>
|
||||
|
||||
<p>To run the <tt>llvm-test</tt> suite, you need to use the following steps:
|
||||
@@ -430,7 +443,7 @@ output and standard error. You can redirect these results to a file if you
|
||||
choose.</p>
|
||||
|
||||
<p>Some tests are known to fail. Some are bugs that we have not fixed yet;
|
||||
others are features that we haven't added yet (or may never add). In QMTest,
|
||||
others are features that we haven't added yet (or may never add). In DejaGNU,
|
||||
the result for such tests will be XFAIL (eXpected FAILure). In this way, you
|
||||
can tell the difference between an expected and unexpected failure.</p>
|
||||
|
||||
|
||||
@@ -1212,7 +1212,7 @@ pass is the default implementation for the interface.</p>
|
||||
|
||||
<div class="doc_text">
|
||||
<p>The <a
|
||||
href="http:://llvm.cs.uiuc.edu/doxygen/Statistic_8h-source.html"><tt>Statistic</tt></a>
|
||||
href="http://llvm.cs.uiuc.edu/doxygen/Statistic_8h-source.html"><tt>Statistic</tt></a>
|
||||
class, is designed to be an easy way to expose various success
|
||||
metrics from passes. These statistics are printed at the end of a
|
||||
run, when the -stats command line option is enabled on the command
|
||||
|
||||
@@ -55,6 +55,7 @@ some tools.</li>
|
||||
manual for the LLVM command line utilities ("man" pages for LLVM tools).<br/>
|
||||
Current tools:
|
||||
<a href="CommandGuide/html/llvm-ar.html">llvm-ar</a>,
|
||||
<a href="CommandGuide/html/llvm-ranlib.html">llvm-ranlib</a>,
|
||||
<a href="CommandGuide/html/llvm-as.html">llvm-as</a>,
|
||||
<a href="CommandGuide/html/llvm-dis.html">llvm-dis</a>,
|
||||
<a href="CommandGuide/html/opt.html">opt</a>,
|
||||
|
||||
159
llvm/lib/Linker/LinkItems.cpp
Normal file
159
llvm/lib/Linker/LinkItems.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
//===- lib/Linker/LinkItems.cpp - Link LLVM objects and libraries ---------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by Reid Spencer and is distributed under the
|
||||
// University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains routines to handle linking together LLVM bytecode files,
|
||||
// and to handle annoying things like static libraries.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Linker.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/ModuleProvider.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/ADT/SetOperations.h"
|
||||
#include "llvm/Bytecode/Reader.h"
|
||||
#include "llvm/Bytecode/Archive.h"
|
||||
#include "llvm/Bytecode/WriteBytecodePass.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Transforms/IPO.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Config/config.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/FileUtilities.h"
|
||||
#include "llvm/Support/Timer.h"
|
||||
#include "llvm/System/Signals.h"
|
||||
#include "llvm/Support/SystemUtils.h"
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
using namespace llvm;
|
||||
|
||||
static bool
|
||||
LinkOneLibrary(const char*progname, Module* HeadModule,
|
||||
const std::string& Lib,
|
||||
const std::vector<std::string>& LibPaths,
|
||||
bool Verbose, bool Native) {
|
||||
|
||||
// String in which to receive error messages.
|
||||
std::string ErrorMessage;
|
||||
|
||||
// Determine where this library lives.
|
||||
std::string Pathname = FindLib(Lib, LibPaths);
|
||||
if (Pathname.empty()) {
|
||||
// If the pathname does not exist, then simply return if we're doing a
|
||||
// native link and give a warning if we're doing a bytecode link.
|
||||
if (!Native) {
|
||||
std::cerr << progname << ": warning: Cannot find library '"
|
||||
<< Lib << "'\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// A user may specify an ar archive without -l, perhaps because it
|
||||
// is not installed as a library. Detect that and link the library.
|
||||
if (IsArchive(Pathname)) {
|
||||
if (Verbose)
|
||||
std::cerr << "Trying to link archive '" << Pathname << "' (-l"
|
||||
<< Lib << ")\n";
|
||||
|
||||
if (LinkInArchive(HeadModule, Pathname, &ErrorMessage, Verbose)) {
|
||||
std::cerr << progname << ": " << ErrorMessage
|
||||
<< ": Error linking in archive '" << Pathname << "' (-l"
|
||||
<< Lib << ")\n";
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
std::cerr << progname << ": WARNING: Supposed library -l"
|
||||
<< Lib << " isn't a library.\n";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// LinkItems - preserve link order for an arbitrary set of linkage items.
|
||||
Module*
|
||||
llvm::LinkItems(const char *progname, const LinkItemList& Items,
|
||||
const std::vector<std::string>& LibPaths,
|
||||
bool Verbose, bool Native) {
|
||||
|
||||
// Construct the HeadModule to contain the result of the linkage
|
||||
std::auto_ptr<Module> HeadModule(new Module(progname));
|
||||
|
||||
// Construct a mutable path list we can add paths to. This list will always
|
||||
// have LLVM_LIB_SEARCH_PATH at the end so we place it there now.
|
||||
std::vector<std::string> MyLibPaths(LibPaths);
|
||||
MyLibPaths.insert(MyLibPaths.begin(),".");
|
||||
char* SearchPath = getenv("LLVM_LIB_SEARCH_PATH");
|
||||
if (SearchPath)
|
||||
MyLibPaths.push_back(SearchPath);
|
||||
|
||||
// For each linkage item ...
|
||||
for (LinkItemList::const_iterator I = Items.begin(), E = Items.end();
|
||||
I != E; ++I) {
|
||||
if (I->second) {
|
||||
// Link in the library suggested.
|
||||
if (LinkOneLibrary(progname,HeadModule.get(),I->first,MyLibPaths,
|
||||
Verbose,Native))
|
||||
return 0;
|
||||
} else {
|
||||
std::vector<std::string> Files;
|
||||
Files.push_back(I->first);
|
||||
if (LinkFiles(progname,HeadModule.get(),Files,Verbose))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// At this point we have processed all the link items provided to us. Since
|
||||
// we have an aggregated module at this point, the dependent libraries in
|
||||
// that module should also be aggregated with duplicates eliminated. This is
|
||||
// now the time to process the dependent libraries to resolve any remaining
|
||||
// symbols.
|
||||
const Module::LibraryListType& DepLibs = HeadModule->getLibraries();
|
||||
for (Module::LibraryListType::const_iterator I = DepLibs.begin(),
|
||||
E = DepLibs.end(); I != E; ++I) {
|
||||
if(LinkOneLibrary(progname,HeadModule.get(),*I,MyLibPaths,Verbose,Native))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return HeadModule.release();
|
||||
}
|
||||
|
||||
// BuildLinkItems -- This function
|
||||
void llvm::BuildLinkItems(
|
||||
LinkItemList& Items,
|
||||
const cl::list<std::string>& Files,
|
||||
const cl::list<std::string>& Libraries) {
|
||||
|
||||
// Build the list of linkage items for LinkItems.
|
||||
|
||||
cl::list<std::string>::const_iterator fileIt = Files.begin();
|
||||
cl::list<std::string>::const_iterator libIt = Libraries.begin();
|
||||
|
||||
int libPos = -1, filePos = -1;
|
||||
while ( 1 ) {
|
||||
if (libIt != Libraries.end())
|
||||
libPos = Libraries.getPosition(libIt - Libraries.begin());
|
||||
else
|
||||
libPos = -1;
|
||||
if (fileIt != Files.end())
|
||||
filePos = Files.getPosition(fileIt - Files.begin());
|
||||
else
|
||||
filePos = -1;
|
||||
|
||||
if (filePos != -1 && (libPos == -1 || filePos < libPos)) {
|
||||
// Add a source file
|
||||
Items.push_back(std::make_pair(*fileIt++, false));
|
||||
} else if (libPos != -1 && (filePos == -1 || libPos < filePos)) {
|
||||
// Add a library
|
||||
Items.push_back(std::make_pair(*libIt++, true));
|
||||
} else {
|
||||
break; // we're done with the list
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
//===-- DelaySlotFiller.cpp - SparcV8 delay slot filler -------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This is a simple local pass that fills delay slots with NOPs.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SparcV8.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
Statistic<> FilledSlots ("delayslotfiller", "Num. of delay slots filled");
|
||||
|
||||
struct Filler : public MachineFunctionPass {
|
||||
/// Target machine description which we query for reg. names, data
|
||||
/// layout, etc.
|
||||
///
|
||||
TargetMachine &TM;
|
||||
const TargetInstrInfo *TII;
|
||||
|
||||
Filler (TargetMachine &tm) : TM (tm), TII (tm.getInstrInfo ()) { }
|
||||
|
||||
virtual const char *getPassName () const {
|
||||
return "SparcV8 Delay Slot Filler";
|
||||
}
|
||||
|
||||
bool runOnMachineBasicBlock (MachineBasicBlock &MBB);
|
||||
bool runOnMachineFunction (MachineFunction &F) {
|
||||
bool Changed = false;
|
||||
for (MachineFunction::iterator FI = F.begin (), FE = F.end ();
|
||||
FI != FE; ++FI)
|
||||
Changed |= runOnMachineBasicBlock (*FI);
|
||||
return Changed;
|
||||
}
|
||||
|
||||
};
|
||||
} // end of anonymous namespace
|
||||
|
||||
/// createSparcV8DelaySlotFillerPass - Returns a pass that fills in delay
|
||||
/// slots in SparcV8 MachineFunctions
|
||||
///
|
||||
FunctionPass *llvm::createSparcV8DelaySlotFillerPass (TargetMachine &tm) {
|
||||
return new Filler (tm);
|
||||
}
|
||||
|
||||
/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
|
||||
/// Currently, we fill delay slots with NOPs. We assume there is only one
|
||||
/// delay slot per delayed instruction.
|
||||
///
|
||||
bool Filler::runOnMachineBasicBlock (MachineBasicBlock &MBB) {
|
||||
bool Changed = false;
|
||||
for (MachineBasicBlock::iterator I = MBB.begin (); I != MBB.end (); ++I)
|
||||
if (TII->hasDelaySlot (I->getOpcode ())) {
|
||||
MachineBasicBlock::iterator J = I;
|
||||
++J;
|
||||
BuildMI (MBB, J, V8::NOP, 0);
|
||||
++FilledSlots;
|
||||
Changed = true;
|
||||
}
|
||||
return Changed;
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
//===-- FPMover.cpp - SparcV8 double-precision floating point move fixer --===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Turns FpMOVD instructions into FMOVS pairs after regalloc.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SparcV8.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
Statistic<> NumFpMOVDs ("fpmover", "# FpMOVD instructions translated");
|
||||
Statistic<> SkippedFpMOVDs ("fpmover", "# FpMOVD instructions skipped");
|
||||
|
||||
struct FPMover : public MachineFunctionPass {
|
||||
/// Target machine description which we query for reg. names, data
|
||||
/// layout, etc.
|
||||
///
|
||||
TargetMachine &TM;
|
||||
|
||||
FPMover (TargetMachine &tm) : TM (tm) { }
|
||||
|
||||
virtual const char *getPassName () const {
|
||||
return "SparcV8 Double-FP Move Fixer";
|
||||
}
|
||||
|
||||
bool runOnMachineBasicBlock (MachineBasicBlock &MBB);
|
||||
bool runOnMachineFunction (MachineFunction &F) {
|
||||
bool Changed = false;
|
||||
for (MachineFunction::iterator FI = F.begin (), FE = F.end ();
|
||||
FI != FE; ++FI)
|
||||
Changed |= runOnMachineBasicBlock (*FI);
|
||||
return Changed;
|
||||
}
|
||||
|
||||
};
|
||||
} // end of anonymous namespace
|
||||
|
||||
/// createSparcV8FPMoverPass - Returns a pass that turns FpMOVD
|
||||
/// instructions into FMOVS instructions
|
||||
///
|
||||
FunctionPass *llvm::createSparcV8FPMoverPass (TargetMachine &tm) {
|
||||
return new FPMover (tm);
|
||||
}
|
||||
|
||||
static void doubleToSingleRegPair(unsigned doubleReg, unsigned &singleReg1, unsigned &singleReg2) {
|
||||
const unsigned EvenHalvesOfPairs[] = { V8::F0, V8::F2, V8::F4, V8::F6, V8::F8, V8::F10, V8::F12, V8::F14, V8::F16, V8::F18, V8::F20, V8::F22, V8::F24, V8::F26, V8::F28, V8::F30 };
|
||||
const unsigned OddHalvesOfPairs[] = { V8::F1, V8::F3, V8::F5, V8::F7, V8::F9, V8::F11, V8::F13, V8::F15, V8::F17, V8::F19, V8::F21, V8::F23, V8::F25, V8::F27, V8::F29, V8::F31 };
|
||||
const unsigned DoubleRegsInOrder[] = { V8::D0, V8::D1, V8::D2, V8::D3, V8::D4, V8::D5, V8::D6, V8::D7, V8::D8, V8::D9, V8::D10, V8::D11, V8::D12, V8::D13, V8::D14, V8::D15 };
|
||||
for (unsigned i = 0; i < sizeof(DoubleRegsInOrder)/sizeof(unsigned); ++i)
|
||||
if (DoubleRegsInOrder[i] == doubleReg) {
|
||||
singleReg1 = EvenHalvesOfPairs[i];
|
||||
singleReg2 = OddHalvesOfPairs[i];
|
||||
return;
|
||||
}
|
||||
assert (0 && "Can't find reg");
|
||||
}
|
||||
|
||||
/// runOnMachineBasicBlock - Fixup FpMOVD instructions in this MBB.
|
||||
///
|
||||
bool FPMover::runOnMachineBasicBlock (MachineBasicBlock &MBB) {
|
||||
bool Changed = false;
|
||||
for (MachineBasicBlock::iterator I = MBB.begin (); I != MBB.end (); ++I)
|
||||
if (V8::FpMOVD == I->getOpcode ()) {
|
||||
unsigned NewSrcReg0, NewSrcReg1, NewDestReg0, NewDestReg1;
|
||||
doubleToSingleRegPair (I->getOperand (0).getReg (), NewDestReg0,
|
||||
NewDestReg1);
|
||||
doubleToSingleRegPair (I->getOperand (1).getReg (), NewSrcReg0,
|
||||
NewSrcReg1);
|
||||
MachineBasicBlock::iterator J = I;
|
||||
++J;
|
||||
if (!(NewDestReg0 == NewSrcReg0 && NewDestReg1 == NewSrcReg1)) {
|
||||
I->setOpcode (V8::FMOVS);
|
||||
I->SetMachineOperandReg (0, NewDestReg0);
|
||||
I->SetMachineOperandReg (1, NewSrcReg0);
|
||||
DEBUG (std::cerr << "FPMover: new dest reg. is: " << NewDestReg0
|
||||
<< "; modified instr is: " << *I);
|
||||
// Insert copy for the other half of the double:
|
||||
MachineInstr *MI2 =
|
||||
BuildMI (MBB, J, V8::FMOVS, 1, NewDestReg1).addReg (NewSrcReg1);
|
||||
DEBUG (std::cerr << "FPMover: new dest reg. is " << NewDestReg1
|
||||
<< "; inserted instr is: " << *MI2);
|
||||
++NumFpMOVDs;
|
||||
} else {
|
||||
MBB.erase (I);
|
||||
++SkippedFpMOVDs;
|
||||
}
|
||||
I = J;
|
||||
Changed = true;
|
||||
}
|
||||
return Changed;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
##===- lib/Target/Sparc/V8/Makefile ------------------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file was developed by the LLVM research group and is distributed under
|
||||
# the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
LEVEL = ../../../..
|
||||
LIBRARYNAME = LLVMSparcV8
|
||||
TARGET = SparcV8
|
||||
|
||||
# Make sure that tblgen is run, first thing.
|
||||
BUILT_SOURCES = SparcV8GenRegisterInfo.h.inc SparcV8GenRegisterNames.inc \
|
||||
SparcV8GenRegisterInfo.inc SparcV8GenInstrNames.inc \
|
||||
SparcV8GenInstrInfo.inc SparcV8GenCodeEmitter.inc
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
|
||||
SparcV8 backend skeleton
|
||||
------------------------
|
||||
|
||||
This directory houses a 32-bit SPARC V8 backend employing an expander-based
|
||||
instruction selector. It is not yet functionally complete. Watch
|
||||
this space for more news coming soon!
|
||||
|
||||
Current expected test failures
|
||||
------------------------------
|
||||
|
||||
The SparcV8 backend works on many simple C++ SingleSource codes. Here
|
||||
are the known SingleSource failures:
|
||||
|
||||
UnitTests/SetjmpLongjmp/C++/SimpleC++Test
|
||||
Regression/C++/EH/exception_spec_test
|
||||
Regression/C++/EH/throw_rethrow_test
|
||||
Benchmarks/Shootout-C++/moments
|
||||
Benchmarks/Shootout-C++/random
|
||||
|
||||
Here are some known MultiSource test failures - this is probably not a
|
||||
complete list right now.
|
||||
|
||||
burg siod lambda make_dparser hbd treecc hexxagon fhourstones
|
||||
bisect testtrie eks imp power anagram bc distray
|
||||
|
||||
To-do
|
||||
-----
|
||||
|
||||
* support shifts on longs
|
||||
* support casting 64-bit integers to FP types
|
||||
* support FP rem
|
||||
|
||||
$Date$
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
//===-- SparcV8.h - Top-level interface for SparcV8 representation -*- C++ -*-//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the entry points for global functions defined in the LLVM
|
||||
// SparcV8 back-end.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef TARGET_SPARCV8_H
|
||||
#define TARGET_SPARCV8_H
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class FunctionPass;
|
||||
class TargetMachine;
|
||||
|
||||
FunctionPass *createSparcV8SimpleInstructionSelector(TargetMachine &TM);
|
||||
FunctionPass *createSparcV8CodePrinterPass(std::ostream &OS,
|
||||
TargetMachine &TM);
|
||||
FunctionPass *createSparcV8DelaySlotFillerPass(TargetMachine &TM);
|
||||
FunctionPass *createSparcV8FPMoverPass(TargetMachine &TM);
|
||||
|
||||
} // end namespace llvm;
|
||||
|
||||
// Defines symbolic names for SparcV8 registers. This defines a mapping from
|
||||
// register name to register number.
|
||||
//
|
||||
#include "SparcV8GenRegisterNames.inc"
|
||||
|
||||
// Defines symbolic names for the SparcV8 instructions.
|
||||
//
|
||||
#include "SparcV8GenInstrNames.inc"
|
||||
|
||||
#endif
|
||||
@@ -1,52 +0,0 @@
|
||||
//===- SparcV8.td - Describe the SparcV8 Target Machine ---------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Target-independent interfaces which we are implementing
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "../../Target.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Register File Description
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "SparcV8RegisterInfo.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction Descriptions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "SparcV8InstrInfo.td"
|
||||
|
||||
def SparcV8InstrInfo : InstrInfo {
|
||||
let PHIInst = PHI;
|
||||
|
||||
// Define how we want to layout our target-specific information field.
|
||||
let TSFlagsFields = [];
|
||||
let TSFlagsShifts = [];
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Declare the target which we are implementing
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def SparcV8 : Target {
|
||||
// Pointers are 32-bits in size.
|
||||
let PointerType = i32;
|
||||
|
||||
// FIXME: Specify callee-saved registers
|
||||
let CalleeSavedRegisters = [];
|
||||
|
||||
// Pull in Instruction Info:
|
||||
let InstructionSet = SparcV8InstrInfo;
|
||||
}
|
||||
@@ -1,645 +0,0 @@
|
||||
//===-- SparcV8AsmPrinter.cpp - SparcV8 LLVM assembly writer --------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains a printer that converts from our internal representation
|
||||
// of machine-dependent LLVM code to GAS-format Sparc V8 assembly language.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SparcV8.h"
|
||||
#include "SparcV8InstrInfo.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Assembly/Writer.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Support/Mangler.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include <cctype>
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
|
||||
|
||||
struct V8Printer : public MachineFunctionPass {
|
||||
/// Output stream on which we're printing assembly code.
|
||||
///
|
||||
std::ostream &O;
|
||||
|
||||
/// Target machine description which we query for reg. names, data
|
||||
/// layout, etc.
|
||||
///
|
||||
TargetMachine &TM;
|
||||
|
||||
/// Name-mangler for global names.
|
||||
///
|
||||
Mangler *Mang;
|
||||
|
||||
V8Printer(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) { }
|
||||
|
||||
/// We name each basic block in a Function with a unique number, so
|
||||
/// that we can consistently refer to them later. This is cleared
|
||||
/// at the beginning of each call to runOnMachineFunction().
|
||||
///
|
||||
typedef std::map<const Value *, unsigned> ValueMapTy;
|
||||
ValueMapTy NumberForBB;
|
||||
|
||||
/// Cache of mangled name for current function. This is
|
||||
/// recalculated at the beginning of each call to
|
||||
/// runOnMachineFunction().
|
||||
///
|
||||
std::string CurrentFnName;
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "SparcV8 Assembly Printer";
|
||||
}
|
||||
|
||||
void emitConstantValueOnly(const Constant *CV);
|
||||
void emitGlobalConstant(const Constant *CV);
|
||||
void printConstantPool(MachineConstantPool *MCP);
|
||||
void printOperand(const MachineInstr *MI, int opNum);
|
||||
void printBaseOffsetPair (const MachineInstr *MI, int i, bool brackets=true);
|
||||
void printMachineInstruction(const MachineInstr *MI);
|
||||
bool runOnMachineFunction(MachineFunction &F);
|
||||
bool doInitialization(Module &M);
|
||||
bool doFinalization(Module &M);
|
||||
};
|
||||
} // end of anonymous namespace
|
||||
|
||||
/// createSparcV8CodePrinterPass - Returns a pass that prints the SparcV8
|
||||
/// assembly code for a MachineFunction to the given output stream,
|
||||
/// using the given target machine description. This should work
|
||||
/// regardless of whether the function is in SSA form.
|
||||
///
|
||||
FunctionPass *llvm::createSparcV8CodePrinterPass (std::ostream &o,
|
||||
TargetMachine &tm) {
|
||||
return new V8Printer(o, tm);
|
||||
}
|
||||
|
||||
/// toOctal - Convert the low order bits of X into an octal digit.
|
||||
///
|
||||
static inline char toOctal(int X) {
|
||||
return (X&7)+'0';
|
||||
}
|
||||
|
||||
/// getAsCString - Return the specified array as a C compatible
|
||||
/// string, only if the predicate isStringCompatible is true.
|
||||
///
|
||||
static void printAsCString(std::ostream &O, const ConstantArray *CVA) {
|
||||
assert(CVA->isString() && "Array is not string compatible!");
|
||||
|
||||
O << "\"";
|
||||
for (unsigned i = 0; i != CVA->getNumOperands(); ++i) {
|
||||
unsigned char C = cast<ConstantInt>(CVA->getOperand(i))->getRawValue();
|
||||
|
||||
if (C == '"') {
|
||||
O << "\\\"";
|
||||
} else if (C == '\\') {
|
||||
O << "\\\\";
|
||||
} else if (isprint(C)) {
|
||||
O << C;
|
||||
} else {
|
||||
switch(C) {
|
||||
case '\b': O << "\\b"; break;
|
||||
case '\f': O << "\\f"; break;
|
||||
case '\n': O << "\\n"; break;
|
||||
case '\r': O << "\\r"; break;
|
||||
case '\t': O << "\\t"; break;
|
||||
default:
|
||||
O << '\\';
|
||||
O << toOctal(C >> 6);
|
||||
O << toOctal(C >> 3);
|
||||
O << toOctal(C >> 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
O << "\"";
|
||||
}
|
||||
|
||||
// Print out the specified constant, without a storage class. Only the
|
||||
// constants valid in constant expressions can occur here.
|
||||
void V8Printer::emitConstantValueOnly(const Constant *CV) {
|
||||
if (CV->isNullValue() || isa<UndefValue> (CV))
|
||||
O << "0";
|
||||
else if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) {
|
||||
assert(CB == ConstantBool::True);
|
||||
O << "1";
|
||||
} else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV))
|
||||
if (((CI->getValue() << 32) >> 32) == CI->getValue())
|
||||
O << CI->getValue();
|
||||
else
|
||||
O << (unsigned long long)CI->getValue();
|
||||
else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV))
|
||||
O << CI->getValue();
|
||||
else if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
|
||||
// This is a constant address for a global variable or function. Use the
|
||||
// name of the variable or function as the address value.
|
||||
O << Mang->getValueName(GV);
|
||||
else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
|
||||
const TargetData &TD = TM.getTargetData();
|
||||
switch(CE->getOpcode()) {
|
||||
case Instruction::GetElementPtr: {
|
||||
// generate a symbolic expression for the byte address
|
||||
const Constant *ptrVal = CE->getOperand(0);
|
||||
std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end());
|
||||
if (unsigned Offset = TD.getIndexedOffset(ptrVal->getType(), idxVec)) {
|
||||
O << "(";
|
||||
emitConstantValueOnly(ptrVal);
|
||||
O << ") + " << Offset;
|
||||
} else {
|
||||
emitConstantValueOnly(ptrVal);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Instruction::Cast: {
|
||||
// Support only non-converting or widening casts for now, that is, ones
|
||||
// that do not involve a change in value. This assertion is really gross,
|
||||
// and may not even be a complete check.
|
||||
Constant *Op = CE->getOperand(0);
|
||||
const Type *OpTy = Op->getType(), *Ty = CE->getType();
|
||||
|
||||
// Pointers on ILP32 machines can be losslessly converted back and
|
||||
// forth into 32-bit or wider integers, regardless of signedness.
|
||||
assert(((isa<PointerType>(OpTy)
|
||||
&& (Ty == Type::LongTy || Ty == Type::ULongTy
|
||||
|| Ty == Type::IntTy || Ty == Type::UIntTy))
|
||||
|| (isa<PointerType>(Ty)
|
||||
&& (OpTy == Type::LongTy || OpTy == Type::ULongTy
|
||||
|| OpTy == Type::IntTy || OpTy == Type::UIntTy))
|
||||
|| (((TD.getTypeSize(Ty) >= TD.getTypeSize(OpTy))
|
||||
&& OpTy->isLosslesslyConvertibleTo(Ty))))
|
||||
&& "FIXME: Don't yet support this kind of constant cast expr");
|
||||
O << "(";
|
||||
emitConstantValueOnly(Op);
|
||||
O << ")";
|
||||
break;
|
||||
}
|
||||
case Instruction::Add:
|
||||
O << "(";
|
||||
emitConstantValueOnly(CE->getOperand(0));
|
||||
O << ") + (";
|
||||
emitConstantValueOnly(CE->getOperand(1));
|
||||
O << ")";
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Unsupported operator!");
|
||||
}
|
||||
} else {
|
||||
assert(0 && "Unknown constant value!");
|
||||
}
|
||||
}
|
||||
|
||||
// Print a constant value or values, with the appropriate storage class as a
|
||||
// prefix.
|
||||
void V8Printer::emitGlobalConstant(const Constant *CV) {
|
||||
const TargetData &TD = TM.getTargetData();
|
||||
|
||||
if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
|
||||
if (CVA->isString()) {
|
||||
O << "\t.ascii\t";
|
||||
printAsCString(O, CVA);
|
||||
O << "\n";
|
||||
} else { // Not a string. Print the values in successive locations
|
||||
for (unsigned i = 0, e = CVA->getNumOperands(); i != e; i++)
|
||||
emitGlobalConstant(CVA->getOperand(i));
|
||||
}
|
||||
return;
|
||||
} else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) {
|
||||
// Print the fields in successive locations. Pad to align if needed!
|
||||
const StructLayout *cvsLayout = TD.getStructLayout(CVS->getType());
|
||||
unsigned sizeSoFar = 0;
|
||||
for (unsigned i = 0, e = CVS->getNumOperands(); i != e; i++) {
|
||||
const Constant* field = CVS->getOperand(i);
|
||||
|
||||
// Check if padding is needed and insert one or more 0s.
|
||||
unsigned fieldSize = TD.getTypeSize(field->getType());
|
||||
unsigned padSize = ((i == e-1? cvsLayout->StructSize
|
||||
: cvsLayout->MemberOffsets[i+1])
|
||||
- cvsLayout->MemberOffsets[i]) - fieldSize;
|
||||
sizeSoFar += fieldSize + padSize;
|
||||
|
||||
// Now print the actual field value
|
||||
emitGlobalConstant(field);
|
||||
|
||||
// Insert the field padding unless it's zero bytes...
|
||||
if (padSize)
|
||||
O << "\t.skip\t " << padSize << "\n";
|
||||
}
|
||||
assert(sizeSoFar == cvsLayout->StructSize &&
|
||||
"Layout of constant struct may be incorrect!");
|
||||
return;
|
||||
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
|
||||
// FP Constants are printed as integer constants to avoid losing
|
||||
// precision...
|
||||
double Val = CFP->getValue();
|
||||
switch (CFP->getType()->getTypeID()) {
|
||||
default: assert(0 && "Unknown floating point type!");
|
||||
case Type::FloatTyID: {
|
||||
union FU { // Abide by C TBAA rules
|
||||
float FVal;
|
||||
unsigned UVal;
|
||||
} U;
|
||||
U.FVal = Val;
|
||||
O << ".long\t" << U.UVal << "\t! float " << Val << "\n";
|
||||
return;
|
||||
}
|
||||
case Type::DoubleTyID: {
|
||||
union DU { // Abide by C TBAA rules
|
||||
double FVal;
|
||||
uint64_t UVal;
|
||||
} U;
|
||||
U.FVal = Val;
|
||||
O << ".word\t0x" << std::hex << (U.UVal >> 32) << std::dec << "\t! double " << Val << "\n";
|
||||
O << ".word\t0x" << std::hex << (U.UVal & 0xffffffffUL) << std::dec << "\t! double " << Val << "\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (isa<UndefValue> (CV)) {
|
||||
unsigned size = TD.getTypeSize (CV->getType ());
|
||||
O << "\t.skip\t " << size << "\n";
|
||||
return;
|
||||
} else if (isa<ConstantAggregateZero> (CV)) {
|
||||
unsigned size = TD.getTypeSize (CV->getType ());
|
||||
for (unsigned i = 0; i < size; ++i)
|
||||
O << "\t.byte 0\n";
|
||||
return;
|
||||
}
|
||||
|
||||
const Type *type = CV->getType();
|
||||
O << "\t";
|
||||
switch (type->getTypeID()) {
|
||||
case Type::BoolTyID: case Type::UByteTyID: case Type::SByteTyID:
|
||||
O << ".byte";
|
||||
break;
|
||||
case Type::UShortTyID: case Type::ShortTyID:
|
||||
O << ".word";
|
||||
break;
|
||||
case Type::FloatTyID: case Type::PointerTyID:
|
||||
case Type::UIntTyID: case Type::IntTyID:
|
||||
O << ".long";
|
||||
break;
|
||||
case Type::DoubleTyID:
|
||||
case Type::ULongTyID: case Type::LongTyID:
|
||||
O << ".quad";
|
||||
break;
|
||||
default:
|
||||
assert (0 && "Can't handle printing this type of thing");
|
||||
break;
|
||||
}
|
||||
O << "\t";
|
||||
emitConstantValueOnly(CV);
|
||||
O << "\n";
|
||||
}
|
||||
|
||||
/// printConstantPool - 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 V8Printer::printConstantPool(MachineConstantPool *MCP) {
|
||||
const std::vector<Constant*> &CP = MCP->getConstants();
|
||||
const TargetData &TD = TM.getTargetData();
|
||||
|
||||
if (CP.empty()) return;
|
||||
|
||||
for (unsigned i = 0, e = CP.size(); i != e; ++i) {
|
||||
O << "\t.section \".rodata\"\n";
|
||||
O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType())
|
||||
<< "\n";
|
||||
O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t!"
|
||||
<< *CP[i] << "\n";
|
||||
emitGlobalConstant(CP[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// runOnMachineFunction - This uses the printMachineInstruction()
|
||||
/// method to print assembly for each instruction.
|
||||
///
|
||||
bool V8Printer::runOnMachineFunction(MachineFunction &MF) {
|
||||
// BBNumber is used here so that a given Printer will never give two
|
||||
// BBs the same name. (If you have a better way, please let me know!)
|
||||
static unsigned BBNumber = 0;
|
||||
|
||||
O << "\n\n";
|
||||
// What's my mangled name?
|
||||
CurrentFnName = Mang->getValueName(MF.getFunction());
|
||||
|
||||
// Print out constants referenced by the function
|
||||
printConstantPool(MF.getConstantPool());
|
||||
|
||||
// Print out labels for the function.
|
||||
O << "\t.text\n";
|
||||
O << "\t.align 16\n";
|
||||
O << "\t.globl\t" << CurrentFnName << "\n";
|
||||
O << "\t.type\t" << CurrentFnName << ", #function\n";
|
||||
O << CurrentFnName << ":\n";
|
||||
|
||||
// Number each basic block so that we can consistently refer to them
|
||||
// in PC-relative references.
|
||||
NumberForBB.clear();
|
||||
for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
|
||||
I != E; ++I) {
|
||||
NumberForBB[I->getBasicBlock()] = BBNumber++;
|
||||
}
|
||||
|
||||
// Print out code for the function.
|
||||
for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
|
||||
I != E; ++I) {
|
||||
// Print a label for the basic block.
|
||||
O << ".LBB" << Mang->getValueName(MF.getFunction ())
|
||||
<< "_" << I->getNumber () << ":\t! "
|
||||
<< I->getBasicBlock ()->getName () << "\n";
|
||||
for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
|
||||
II != E; ++II) {
|
||||
// Print the assembly for the instruction.
|
||||
O << "\t";
|
||||
printMachineInstruction(II);
|
||||
}
|
||||
}
|
||||
|
||||
// We didn't modify anything.
|
||||
return false;
|
||||
}
|
||||
|
||||
void V8Printer::printOperand(const MachineInstr *MI, int opNum) {
|
||||
const MachineOperand &MO = MI->getOperand (opNum);
|
||||
const MRegisterInfo &RI = *TM.getRegisterInfo();
|
||||
bool CloseParen = false;
|
||||
if (MI->getOpcode() == V8::SETHIi && !MO.isRegister() && !MO.isImmediate()) {
|
||||
O << "%hi(";
|
||||
CloseParen = true;
|
||||
} else if (MI->getOpcode() ==V8::ORri &&!MO.isRegister() &&!MO.isImmediate())
|
||||
{
|
||||
O << "%lo(";
|
||||
CloseParen = true;
|
||||
}
|
||||
switch (MO.getType()) {
|
||||
case MachineOperand::MO_VirtualRegister:
|
||||
if (Value *V = MO.getVRegValueOrNull()) {
|
||||
O << "<" << V->getName() << ">";
|
||||
break;
|
||||
}
|
||||
// FALLTHROUGH
|
||||
case MachineOperand::MO_MachineRegister:
|
||||
if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
|
||||
O << "%" << LowercaseString (RI.get(MO.getReg()).Name);
|
||||
else
|
||||
O << "%reg" << MO.getReg();
|
||||
break;
|
||||
|
||||
case MachineOperand::MO_SignExtendedImmed:
|
||||
case MachineOperand::MO_UnextendedImmed:
|
||||
O << (int)MO.getImmedValue();
|
||||
break;
|
||||
case MachineOperand::MO_MachineBasicBlock: {
|
||||
MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
|
||||
O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
|
||||
<< "_" << MBBOp->getNumber () << "\t! "
|
||||
<< MBBOp->getBasicBlock ()->getName ();
|
||||
return;
|
||||
}
|
||||
case MachineOperand::MO_PCRelativeDisp:
|
||||
std::cerr << "Shouldn't use addPCDisp() when building SparcV8 MachineInstrs";
|
||||
abort ();
|
||||
return;
|
||||
case MachineOperand::MO_GlobalAddress:
|
||||
O << Mang->getValueName(MO.getGlobal());
|
||||
break;
|
||||
case MachineOperand::MO_ExternalSymbol:
|
||||
O << MO.getSymbolName();
|
||||
break;
|
||||
case MachineOperand::MO_ConstantPoolIndex:
|
||||
O << ".CPI" << CurrentFnName << "_" << MO.getConstantPoolIndex();
|
||||
break;
|
||||
default:
|
||||
O << "<unknown operand type>"; abort (); break;
|
||||
}
|
||||
if (CloseParen) O << ")";
|
||||
}
|
||||
|
||||
static bool isLoadInstruction (const MachineInstr *MI) {
|
||||
switch (MI->getOpcode ()) {
|
||||
case V8::LDSB:
|
||||
case V8::LDSH:
|
||||
case V8::LDUB:
|
||||
case V8::LDUH:
|
||||
case V8::LD:
|
||||
case V8::LDD:
|
||||
case V8::LDFrr:
|
||||
case V8::LDFri:
|
||||
case V8::LDDFrr:
|
||||
case V8::LDDFri:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool isStoreInstruction (const MachineInstr *MI) {
|
||||
switch (MI->getOpcode ()) {
|
||||
case V8::STB:
|
||||
case V8::STH:
|
||||
case V8::ST:
|
||||
case V8::STD:
|
||||
case V8::STFrr:
|
||||
case V8::STFri:
|
||||
case V8::STDFrr:
|
||||
case V8::STDFri:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool isPseudoInstruction (const MachineInstr *MI) {
|
||||
switch (MI->getOpcode ()) {
|
||||
case V8::PHI:
|
||||
case V8::ADJCALLSTACKUP:
|
||||
case V8::ADJCALLSTACKDOWN:
|
||||
case V8::IMPLICIT_USE:
|
||||
case V8::IMPLICIT_DEF:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// printBaseOffsetPair - Print two consecutive operands of MI, starting at #i,
|
||||
/// which form a base + offset pair (which may have brackets around it, if
|
||||
/// brackets is true, or may be in the form base - constant, if offset is a
|
||||
/// negative constant).
|
||||
///
|
||||
void V8Printer::printBaseOffsetPair (const MachineInstr *MI, int i,
|
||||
bool brackets) {
|
||||
if (brackets) O << "[";
|
||||
printOperand (MI, i);
|
||||
if (MI->getOperand (i + 1).isImmediate()) {
|
||||
int Val = (int) MI->getOperand (i + 1).getImmedValue ();
|
||||
if (Val != 0) {
|
||||
O << ((Val >= 0) ? " + " : " - ");
|
||||
O << ((Val >= 0) ? Val : -Val);
|
||||
}
|
||||
} else {
|
||||
O << " + ";
|
||||
printOperand (MI, i + 1);
|
||||
}
|
||||
if (brackets) O << "]";
|
||||
}
|
||||
|
||||
/// printMachineInstruction -- Print out a single SparcV8 LLVM instruction
|
||||
/// MI in GAS syntax to the current output stream.
|
||||
///
|
||||
void V8Printer::printMachineInstruction(const MachineInstr *MI) {
|
||||
unsigned Opcode = MI->getOpcode();
|
||||
const TargetInstrInfo &TII = *TM.getInstrInfo();
|
||||
const TargetInstrDescriptor &Desc = TII.get(Opcode);
|
||||
|
||||
// If it's a pseudo-instruction, comment it out.
|
||||
if (isPseudoInstruction (MI))
|
||||
O << "! ";
|
||||
|
||||
O << Desc.Name << " ";
|
||||
|
||||
// Printing memory instructions is a special case.
|
||||
// for loads: %dest = op %base, offset --> op [%base + offset], %dest
|
||||
// for stores: op %base, offset, %src --> op %src, [%base + offset]
|
||||
if (isLoadInstruction (MI)) {
|
||||
printBaseOffsetPair (MI, 1);
|
||||
O << ", ";
|
||||
printOperand (MI, 0);
|
||||
O << "\n";
|
||||
return;
|
||||
} else if (isStoreInstruction (MI)) {
|
||||
printOperand (MI, 2);
|
||||
O << ", ";
|
||||
printBaseOffsetPair (MI, 0);
|
||||
O << "\n";
|
||||
return;
|
||||
} else if (Opcode == V8::JMPLrr) {
|
||||
printBaseOffsetPair (MI, 1, false);
|
||||
O << ", ";
|
||||
printOperand (MI, 0);
|
||||
O << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// print non-immediate, non-register-def operands
|
||||
// then print immediate operands
|
||||
// then print register-def operands.
|
||||
std::vector<int> print_order;
|
||||
for (unsigned i = 0; i < MI->getNumOperands (); ++i)
|
||||
if (!(MI->getOperand (i).isImmediate ()
|
||||
|| (MI->getOperand (i).isRegister ()
|
||||
&& MI->getOperand (i).isDef ())))
|
||||
print_order.push_back (i);
|
||||
for (unsigned i = 0; i < MI->getNumOperands (); ++i)
|
||||
if (MI->getOperand (i).isImmediate ())
|
||||
print_order.push_back (i);
|
||||
for (unsigned i = 0; i < MI->getNumOperands (); ++i)
|
||||
if (MI->getOperand (i).isRegister () && MI->getOperand (i).isDef ())
|
||||
print_order.push_back (i);
|
||||
for (unsigned i = 0, e = print_order.size (); i != e; ++i) {
|
||||
printOperand (MI, print_order[i]);
|
||||
if (i != (print_order.size () - 1))
|
||||
O << ", ";
|
||||
}
|
||||
O << "\n";
|
||||
}
|
||||
|
||||
bool V8Printer::doInitialization(Module &M) {
|
||||
Mang = new Mangler(M);
|
||||
return false; // success
|
||||
}
|
||||
|
||||
// SwitchSection - Switch to the specified section of the executable if we are
|
||||
// not already in it!
|
||||
//
|
||||
static void SwitchSection(std::ostream &OS, std::string &CurSection,
|
||||
const char *NewSection) {
|
||||
if (CurSection != NewSection) {
|
||||
CurSection = NewSection;
|
||||
if (!CurSection.empty())
|
||||
OS << "\t.section \"" << NewSection << "\"\n";
|
||||
}
|
||||
}
|
||||
|
||||
bool V8Printer::doFinalization(Module &M) {
|
||||
const TargetData &TD = TM.getTargetData();
|
||||
std::string CurSection;
|
||||
|
||||
// Print out module-level global variables here.
|
||||
for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
|
||||
if (I->hasInitializer()) { // External global require no code
|
||||
O << "\n\n";
|
||||
std::string name = Mang->getValueName(I);
|
||||
Constant *C = I->getInitializer();
|
||||
unsigned Size = TD.getTypeSize(C->getType());
|
||||
unsigned Align = TD.getTypeAlignment(C->getType());
|
||||
|
||||
if (C->isNullValue() &&
|
||||
(I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
|
||||
I->hasWeakLinkage() /* FIXME: Verify correct */)) {
|
||||
SwitchSection(O, CurSection, ".data");
|
||||
if (I->hasInternalLinkage())
|
||||
O << "\t.local " << name << "\n";
|
||||
|
||||
O << "\t.comm " << name << "," << TD.getTypeSize(C->getType())
|
||||
<< "," << (unsigned)TD.getTypeAlignment(C->getType());
|
||||
O << "\t\t! ";
|
||||
WriteAsOperand(O, I, true, true, &M);
|
||||
O << "\n";
|
||||
} else {
|
||||
switch (I->getLinkage()) {
|
||||
case GlobalValue::LinkOnceLinkage:
|
||||
case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak.
|
||||
// Nonnull linkonce -> weak
|
||||
O << "\t.weak " << name << "\n";
|
||||
SwitchSection(O, CurSection, "");
|
||||
O << "\t.section\t\".llvm.linkonce.d." << name << "\",\"aw\",@progbits\n";
|
||||
break;
|
||||
|
||||
case GlobalValue::AppendingLinkage:
|
||||
// FIXME: appending linkage variables should go into a section of
|
||||
// their name or something. For now, just emit them as external.
|
||||
case GlobalValue::ExternalLinkage:
|
||||
// If external or appending, declare as a global symbol
|
||||
O << "\t.globl " << name << "\n";
|
||||
// FALL THROUGH
|
||||
case GlobalValue::InternalLinkage:
|
||||
if (C->isNullValue())
|
||||
SwitchSection(O, CurSection, ".bss");
|
||||
else
|
||||
SwitchSection(O, CurSection, ".data");
|
||||
break;
|
||||
case GlobalValue::GhostLinkage:
|
||||
std::cerr << "Should not have any unmaterialized functions!\n";
|
||||
abort();
|
||||
}
|
||||
|
||||
O << "\t.align " << Align << "\n";
|
||||
O << "\t.type " << name << ",#object\n";
|
||||
O << "\t.size " << name << "," << Size << "\n";
|
||||
O << name << ":\t\t\t\t! ";
|
||||
WriteAsOperand(O, I, true, true, &M);
|
||||
O << " = ";
|
||||
WriteAsOperand(O, C, false, false, &M);
|
||||
O << "\n";
|
||||
emitGlobalConstant(C);
|
||||
}
|
||||
}
|
||||
|
||||
delete Mang;
|
||||
return false; // success
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
//===-- SparcV8CodeEmitter.cpp - JIT Code Emitter for SparcV8 -----*- C++ -*-=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SparcV8.h"
|
||||
#include "SparcV8TargetMachine.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/CodeGen/MachineCodeEmitter.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include <cstdlib>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
namespace {
|
||||
class SparcV8CodeEmitter : public MachineFunctionPass {
|
||||
TargetMachine &TM;
|
||||
MachineCodeEmitter &MCE;
|
||||
|
||||
/// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
|
||||
///
|
||||
int64_t getMachineOpValue(MachineInstr &MI, MachineOperand &MO);
|
||||
|
||||
// Tracks which instruction references which BasicBlock
|
||||
std::vector<std::pair<const BasicBlock*,
|
||||
std::pair<unsigned*,MachineInstr*> > > BBRefs;
|
||||
// Tracks where each BasicBlock starts
|
||||
std::map<const BasicBlock*, long> BBLocations;
|
||||
|
||||
public:
|
||||
SparcV8CodeEmitter(TargetMachine &T, MachineCodeEmitter &M)
|
||||
: TM(T), MCE(M) {}
|
||||
|
||||
const char *getPassName() const { return "SparcV8 Machine Code Emitter"; }
|
||||
|
||||
/// runOnMachineFunction - emits the given MachineFunction to memory
|
||||
///
|
||||
bool runOnMachineFunction(MachineFunction &MF);
|
||||
|
||||
/// emitBasicBlock - emits the given MachineBasicBlock to memory
|
||||
///
|
||||
void emitBasicBlock(MachineBasicBlock &MBB);
|
||||
|
||||
/// emitWord - write a 32-bit word to memory at the current PC
|
||||
///
|
||||
void emitWord(unsigned w) { MCE.emitWord(w); }
|
||||
|
||||
/// getValueBit - return the particular bit of Val
|
||||
///
|
||||
unsigned getValueBit(int64_t Val, unsigned bit) { return (Val >> bit) & 1; }
|
||||
|
||||
/// getBinaryCodeForInstr - This function, generated by the
|
||||
/// CodeEmitterGenerator using TableGen, produces the binary encoding for
|
||||
/// machine instructions.
|
||||
///
|
||||
unsigned getBinaryCodeForInstr(MachineInstr &MI);
|
||||
};
|
||||
}
|
||||
|
||||
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to get
|
||||
/// machine code emitted. This uses a MachineCodeEmitter object to handle
|
||||
/// actually outputting the machine code and resolving things like the address
|
||||
/// of functions. This method should returns true if machine code emission is
|
||||
/// not supported.
|
||||
///
|
||||
bool SparcV8TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
|
||||
MachineCodeEmitter &MCE) {
|
||||
// Keep as `true' until this is a functional JIT to allow llvm-gcc to build
|
||||
return true;
|
||||
|
||||
// Machine code emitter pass for SparcV8
|
||||
PM.add(new SparcV8CodeEmitter(*this, MCE));
|
||||
// Delete machine code for this function after emitting it
|
||||
PM.add(createMachineCodeDeleter());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SparcV8CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
|
||||
MCE.startFunction(MF);
|
||||
MCE.emitConstantPool(MF.getConstantPool());
|
||||
for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
|
||||
emitBasicBlock(*I);
|
||||
MCE.finishFunction(MF);
|
||||
|
||||
// Resolve branches to BasicBlocks for the entire function
|
||||
for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) {
|
||||
long Location = BBLocations[BBRefs[i].first];
|
||||
unsigned *Ref = BBRefs[i].second.first;
|
||||
MachineInstr *MI = BBRefs[i].second.second;
|
||||
DEBUG(std::cerr << "Fixup @ " << std::hex << Ref << " to 0x" << Location
|
||||
<< " in instr: " << std::dec << *MI);
|
||||
for (unsigned ii = 0, ee = MI->getNumOperands(); ii != ee; ++ii) {
|
||||
MachineOperand &op = MI->getOperand(ii);
|
||||
if (op.isPCRelativeDisp()) {
|
||||
// the instruction's branch target is made such that it branches to
|
||||
// PC + (branchTarget * 4), so undo that arithmetic here:
|
||||
// Location is the target of the branch
|
||||
// Ref is the location of the instruction, and hence the PC
|
||||
int64_t branchTarget = (Location - (long)Ref) >> 2;
|
||||
MI->SetMachineOperandConst(ii, MachineOperand::MO_SignExtendedImmed,
|
||||
branchTarget);
|
||||
unsigned fixedInstr = SparcV8CodeEmitter::getBinaryCodeForInstr(*MI);
|
||||
MCE.emitWordAt(fixedInstr, Ref);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
BBRefs.clear();
|
||||
BBLocations.clear();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SparcV8CodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
|
||||
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I)
|
||||
emitWord(getBinaryCodeForInstr(*I));
|
||||
}
|
||||
|
||||
int64_t SparcV8CodeEmitter::getMachineOpValue(MachineInstr &MI,
|
||||
MachineOperand &MO) {
|
||||
int64_t rv = 0; // Return value; defaults to 0 for unhandled cases
|
||||
// or things that get fixed up later by the JIT.
|
||||
if (MO.isPCRelativeDisp()) {
|
||||
std::cerr << "SparcV8CodeEmitter: PC-relative disp unhandled\n";
|
||||
abort();
|
||||
} else if (MO.isRegister()) {
|
||||
rv = MO.getReg();
|
||||
} else if (MO.isImmediate()) {
|
||||
rv = MO.getImmedValue();
|
||||
} else if (MO.isGlobalAddress()) {
|
||||
GlobalValue *GV = MO.getGlobal();
|
||||
std::cerr << "Unhandled global value: " << GV << "\n";
|
||||
abort();
|
||||
} else if (MO.isMachineBasicBlock()) {
|
||||
const BasicBlock *BB = MO.getMachineBasicBlock()->getBasicBlock();
|
||||
unsigned* CurrPC = (unsigned*)(intptr_t)MCE.getCurrentPCValue();
|
||||
BBRefs.push_back(std::make_pair(BB, std::make_pair(CurrPC, &MI)));
|
||||
} else if (MO.isExternalSymbol()) {
|
||||
} else if (MO.isConstantPoolIndex()) {
|
||||
unsigned index = MO.getConstantPoolIndex();
|
||||
rv = MCE.getConstantPoolEntryAddress(index);
|
||||
} else if (MO.isFrameIndex()) {
|
||||
std::cerr << "SparcV8CodeEmitter: error: Frame index unhandled!\n";
|
||||
abort();
|
||||
} else {
|
||||
std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
|
||||
abort();
|
||||
}
|
||||
|
||||
// Adjust for special meaning of operands in some instructions
|
||||
unsigned Opcode = MI.getOpcode();
|
||||
if (Opcode == V8::SETHIi && !MO.isRegister() && !MO.isImmediate()) {
|
||||
rv &= 0x03ff;
|
||||
} else if (Opcode == V8::ORri &&!MO.isRegister() &&!MO.isImmediate()) {
|
||||
rv = (rv >> 10) & 0x03fffff;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void *SparcV8JITInfo::getJITStubForFunction(Function *F,
|
||||
MachineCodeEmitter &MCE) {
|
||||
std::cerr << "SparcV8JITInfo::getJITStubForFunction not implemented!\n";
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SparcV8JITInfo::replaceMachineCodeForFunction(void *Old, void *New) {
|
||||
std::cerr << "SparcV8JITInfo::replaceMachineCodeForFunction not implemented!";
|
||||
abort();
|
||||
}
|
||||
|
||||
#include "SparcV8GenCodeEmitter.inc"
|
||||
|
||||
} // end llvm namespace
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,95 +0,0 @@
|
||||
//===- SparcV8InstrFormats.td - SparcV8 Instr Formats ------*- tablegen -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Format #2 instruction classes in the SparcV8
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class F2 : InstV8 { // Format 2 instructions
|
||||
bits<3> op2;
|
||||
bits<22> imm22;
|
||||
let op = 0; // op = 0
|
||||
let Inst{24-22} = op2;
|
||||
let Inst{21-0} = imm22;
|
||||
}
|
||||
|
||||
// Specific F2 classes: SparcV8 manual, page 44
|
||||
//
|
||||
class F2_1<bits<3> op2Val, string name> : F2 {
|
||||
bits<5> rd;
|
||||
|
||||
let op2 = op2Val;
|
||||
let Name = name;
|
||||
|
||||
let Inst{29-25} = rd;
|
||||
}
|
||||
|
||||
class F2_2<bits<4> condVal, bits<3> op2Val, string name> : F2 {
|
||||
bits<4> cond;
|
||||
bit annul = 0; // currently unused
|
||||
|
||||
let cond = condVal;
|
||||
let op2 = op2Val;
|
||||
let Name = name;
|
||||
|
||||
let Inst{29} = annul;
|
||||
let Inst{28-25} = cond;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Format #3 instruction classes in the SparcV8
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class F3 : InstV8 {
|
||||
bits<5> rd;
|
||||
bits<6> op3;
|
||||
bits<5> rs1;
|
||||
let op{1} = 1; // Op = 2 or 3
|
||||
let Inst{29-25} = rd;
|
||||
let Inst{24-19} = op3;
|
||||
let Inst{18-14} = rs1;
|
||||
}
|
||||
|
||||
// Specific F3 classes: SparcV8 manual, page 44
|
||||
//
|
||||
class F3_1<bits<2> opVal, bits<6> op3val, string name> : F3 {
|
||||
bits<8> asi = 0; // asi not currently used in SparcV8
|
||||
bits<5> rs2;
|
||||
|
||||
let op = opVal;
|
||||
let op3 = op3val;
|
||||
let Name = name;
|
||||
|
||||
let Inst{13} = 0; // i field = 0
|
||||
let Inst{12-5} = asi; // address space identifier
|
||||
let Inst{4-0} = rs2;
|
||||
}
|
||||
|
||||
class F3_2<bits<2> opVal, bits<6> op3val, string name> : F3 {
|
||||
bits<13> simm13;
|
||||
|
||||
let op = opVal;
|
||||
let op3 = op3val;
|
||||
let Name = name;
|
||||
|
||||
let Inst{13} = 1; // i field = 1
|
||||
let Inst{12-0} = simm13;
|
||||
}
|
||||
|
||||
// floating-point
|
||||
class F3_3<bits<2> opVal, bits<6> op3val, bits<9> opfval, string name> : F3 {
|
||||
bits<5> rs2;
|
||||
|
||||
let op = opVal;
|
||||
let op3 = op3val;
|
||||
let Name = name;
|
||||
|
||||
let Inst{13-5} = opfval; // fp opcode
|
||||
let Inst{4-0} = rs2;
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
//===- SparcV8InstrInfo.cpp - SparcV8 Instruction Information ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the SparcV8 implementation of the TargetInstrInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SparcV8InstrInfo.h"
|
||||
#include "SparcV8.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "SparcV8GenInstrInfo.inc"
|
||||
using namespace llvm;
|
||||
|
||||
SparcV8InstrInfo::SparcV8InstrInfo()
|
||||
: TargetInstrInfo(SparcV8Insts, sizeof(SparcV8Insts)/sizeof(SparcV8Insts[0])){
|
||||
}
|
||||
|
||||
/// Return true if the instruction is a register to register move and
|
||||
/// leave the source and dest operands in the passed parameters.
|
||||
///
|
||||
bool SparcV8InstrInfo::isMoveInstr(const MachineInstr &MI,
|
||||
unsigned &SrcReg, unsigned &DstReg) const {
|
||||
if (MI.getOpcode() == V8::ORrr) {
|
||||
if (MI.getOperand(1).getReg() == V8::G0) { // X = or G0, Y -> X = Y
|
||||
DstReg = MI.getOperand(0).getReg();
|
||||
SrcReg = MI.getOperand(2).getReg();
|
||||
return true;
|
||||
}
|
||||
} else if (MI.getOpcode() == V8::FMOVS || MI.getOpcode() == V8::FpMOVD) {
|
||||
SrcReg = MI.getOperand(1).getReg();
|
||||
DstReg = MI.getOperand(0).getReg();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
//===- SparcV8InstrInfo.h - SparcV8 Instruction Information -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the SparcV8 implementation of the TargetInstrInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SPARCV8INSTRUCTIONINFO_H
|
||||
#define SPARCV8INSTRUCTIONINFO_H
|
||||
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "SparcV8RegisterInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// V8II - This namespace holds all of the target specific flags that
|
||||
/// instruction info tracks.
|
||||
///
|
||||
namespace V8II {
|
||||
enum {
|
||||
Pseudo = (1<<0),
|
||||
Load = (1<<1),
|
||||
Store = (1<<2),
|
||||
DelaySlot = (1<<3)
|
||||
};
|
||||
};
|
||||
|
||||
class SparcV8InstrInfo : public TargetInstrInfo {
|
||||
const SparcV8RegisterInfo RI;
|
||||
public:
|
||||
SparcV8InstrInfo();
|
||||
|
||||
/// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
|
||||
/// such, whenever a client has an instance of instruction info, it should
|
||||
/// always be able to get register info as well (through this method).
|
||||
///
|
||||
virtual const MRegisterInfo &getRegisterInfo() const { return RI; }
|
||||
|
||||
/// Return true if the instruction is a register to register move and
|
||||
/// leave the source and dest operands in the passed parameters.
|
||||
///
|
||||
virtual bool isMoveInstr(const MachineInstr &MI,
|
||||
unsigned &SrcReg, unsigned &DstReg) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,292 +0,0 @@
|
||||
//===- SparcV8Instrs.td - Target Description for SparcV8 Target -----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file describes the SparcV8 instructions in TableGen format.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction format superclass
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class InstV8 : Instruction { // SparcV8 instruction baseline
|
||||
field bits<32> Inst;
|
||||
|
||||
let Namespace = "V8";
|
||||
|
||||
bits<2> op;
|
||||
let Inst{31-30} = op; // Top two bits are the 'op' field
|
||||
|
||||
// Bit attributes specific to SparcV8 instructions
|
||||
bit isPasi = 0; // Does this instruction affect an alternate addr space?
|
||||
bit isPrivileged = 0; // Is this a privileged instruction?
|
||||
}
|
||||
|
||||
include "SparcV8InstrFormats.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Pseudo instructions.
|
||||
class PseudoInstV8<string nm> : InstV8 {
|
||||
let Name = nm;
|
||||
}
|
||||
def PHI : PseudoInstV8<"PHI">;
|
||||
def ADJCALLSTACKDOWN : PseudoInstV8<"ADJCALLSTACKDOWN">;
|
||||
def ADJCALLSTACKUP : PseudoInstV8<"ADJCALLSTACKUP">;
|
||||
def IMPLICIT_USE : PseudoInstV8<"IMPLICIT_USE">;
|
||||
def IMPLICIT_DEF : PseudoInstV8<"IMPLICIT_DEF">;
|
||||
def FpMOVD : PseudoInstV8<"FpMOVD">; // pseudo 64-bit double move
|
||||
|
||||
// Section A.3 - Synthetic Instructions, p. 85
|
||||
// special cases of JMPL:
|
||||
let isReturn = 1, isTerminator = 1, hasDelaySlot = 1 in {
|
||||
let rd = I7.Num, rs1 = G0.Num, simm13 = 8 in
|
||||
def RET : F3_2<2, 0b111000, "ret">;
|
||||
let rd = O7.Num, rs1 = G0.Num, simm13 = 8 in
|
||||
def RETL: F3_2<2, 0b111000, "retl">;
|
||||
}
|
||||
// CMP is a special case of SUBCC where destination is ignored, by setting it to
|
||||
// %g0 (hardwired zero).
|
||||
// FIXME: should keep track of the fact that it defs the integer condition codes
|
||||
let rd = 0 in
|
||||
def CMPri: F3_2<2, 0b010100, "cmp">;
|
||||
|
||||
// Section B.1 - Load Integer Instructions, p. 90
|
||||
def LDSB: F3_2<3, 0b001001, "ldsb">;
|
||||
def LDSH: F3_2<3, 0b001010, "ldsh">;
|
||||
def LDUB: F3_2<3, 0b000001, "ldub">;
|
||||
def LDUH: F3_2<3, 0b000010, "lduh">;
|
||||
def LD : F3_2<3, 0b000000, "ld">;
|
||||
def LDD : F3_2<3, 0b000011, "ldd">;
|
||||
|
||||
// Section B.2 - Load Floating-point Instructions, p. 92
|
||||
def LDFrr : F3_1<3, 0b100000, "ld">;
|
||||
def LDFri : F3_2<3, 0b100000, "ld">;
|
||||
def LDDFrr : F3_1<3, 0b100011, "ldd">;
|
||||
def LDDFri : F3_2<3, 0b100011, "ldd">;
|
||||
def LDFSRrr: F3_1<3, 0b100001, "ld">;
|
||||
def LDFSRri: F3_2<3, 0b100001, "ld">;
|
||||
|
||||
// Section B.4 - Store Integer Instructions, p. 95
|
||||
def STB : F3_2<3, 0b000101, "stb">;
|
||||
def STH : F3_2<3, 0b000110, "sth">;
|
||||
def ST : F3_2<3, 0b000100, "st">;
|
||||
def STD : F3_2<3, 0b000111, "std">;
|
||||
|
||||
// Section B.5 - Store Floating-point Instructions, p. 97
|
||||
def STFrr : F3_1<3, 0b100100, "st">;
|
||||
def STFri : F3_2<3, 0b100100, "st">;
|
||||
def STDFrr : F3_1<3, 0b100111, "std">;
|
||||
def STDFri : F3_2<3, 0b100111, "std">;
|
||||
def STFSRrr : F3_1<3, 0b100101, "st">;
|
||||
def STFSRri : F3_2<3, 0b100101, "st">;
|
||||
def STDFQrr : F3_1<3, 0b100110, "std">;
|
||||
def STDFQri : F3_2<3, 0b100110, "std">;
|
||||
|
||||
// Section B.9 - SETHI Instruction, p. 104
|
||||
def SETHIi: F2_1<0b100, "sethi">;
|
||||
|
||||
// Section B.10 - NOP Instruction, p. 105
|
||||
// (It's a special case of SETHI)
|
||||
let rd = 0, imm22 = 0 in
|
||||
def NOP : F2_1<0b100, "nop">;
|
||||
|
||||
// Section B.11 - Logical Instructions, p. 106
|
||||
def ANDrr : F3_1<2, 0b000001, "and">;
|
||||
def ANDri : F3_2<2, 0b000001, "and">;
|
||||
def ANDCCrr : F3_1<2, 0b010001, "andcc">;
|
||||
def ANDCCri : F3_2<2, 0b010001, "andcc">;
|
||||
def ANDNrr : F3_1<2, 0b000101, "andn">;
|
||||
def ANDNri : F3_2<2, 0b000101, "andn">;
|
||||
def ANDNCCrr: F3_1<2, 0b010101, "andncc">;
|
||||
def ANDNCCri: F3_2<2, 0b010101, "andncc">;
|
||||
def ORrr : F3_1<2, 0b000010, "or">;
|
||||
def ORri : F3_2<2, 0b000010, "or">;
|
||||
def ORCCrr : F3_1<2, 0b010010, "orcc">;
|
||||
def ORCCri : F3_2<2, 0b010010, "orcc">;
|
||||
def ORNrr : F3_1<2, 0b000110, "orn">;
|
||||
def ORNri : F3_2<2, 0b000110, "orn">;
|
||||
def ORNCCrr : F3_1<2, 0b010110, "orncc">;
|
||||
def ORNCCri : F3_2<2, 0b010110, "orncc">;
|
||||
def XORrr : F3_1<2, 0b000011, "xor">;
|
||||
def XORri : F3_2<2, 0b000011, "xor">;
|
||||
def XORCCrr : F3_1<2, 0b010011, "xorcc">;
|
||||
def XORCCri : F3_2<2, 0b010011, "xorcc">;
|
||||
def XNORrr : F3_1<2, 0b000111, "xnor">;
|
||||
def XNORri : F3_2<2, 0b000111, "xnor">;
|
||||
def XNORCCrr: F3_1<2, 0b010111, "xnorcc">;
|
||||
def XNORCCri: F3_2<2, 0b010111, "xnorcc">;
|
||||
|
||||
// Section B.12 - Shift Instructions, p. 107
|
||||
def SLLrr : F3_1<2, 0b100101, "sll">;
|
||||
def SLLri : F3_2<2, 0b100101, "sll">;
|
||||
def SRLrr : F3_1<2, 0b100110, "srl">;
|
||||
def SRLri : F3_2<2, 0b100110, "srl">;
|
||||
def SRArr : F3_1<2, 0b100111, "sra">;
|
||||
def SRAri : F3_2<2, 0b100111, "sra">;
|
||||
|
||||
// Section B.13 - Add Instructions, p. 108
|
||||
def ADDrr : F3_1<2, 0b000000, "add">;
|
||||
def ADDri : F3_2<2, 0b000000, "add">;
|
||||
def ADDCCrr : F3_1<2, 0b010000, "addcc">;
|
||||
def ADDCCri : F3_2<2, 0b010000, "addcc">;
|
||||
def ADDXrr : F3_1<2, 0b001000, "addx">;
|
||||
def ADDXri : F3_2<2, 0b001000, "addx">;
|
||||
def ADDXCCrr: F3_1<2, 0b011000, "addxcc">;
|
||||
def ADDXCCri: F3_2<2, 0b011000, "addxcc">;
|
||||
|
||||
// Section B.15 - Subtract Instructions, p. 110
|
||||
def SUBrr : F3_1<2, 0b000100, "sub">;
|
||||
def SUBri : F3_2<2, 0b000100, "sub">;
|
||||
def SUBCCrr : F3_1<2, 0b010100, "subcc">;
|
||||
def SUBCCri : F3_2<2, 0b010100, "subcc">;
|
||||
def SUBXrr : F3_1<2, 0b001100, "subx">;
|
||||
def SUBXri : F3_2<2, 0b001100, "subx">;
|
||||
def SUBXCCrr: F3_1<2, 0b011100, "subxcc">;
|
||||
def SUBXCCri: F3_2<2, 0b011100, "subxcc">;
|
||||
|
||||
// Section B.18 - Multiply Instructions, p. 113
|
||||
def UMULrr : F3_1<2, 0b001010, "umul">;
|
||||
def SMULrr : F3_1<2, 0b001011, "smul">;
|
||||
|
||||
// Section B.19 - Divide Instructions, p. 115
|
||||
def UDIVrr : F3_1<2, 0b001110, "udiv">;
|
||||
def UDIVri : F3_2<2, 0b001110, "udiv">;
|
||||
def SDIVrr : F3_1<2, 0b001111, "sdiv">;
|
||||
def SDIVri : F3_2<2, 0b001111, "sdiv">;
|
||||
def UDIVCCrr : F3_1<2, 0b011110, "udivcc">;
|
||||
def UDIVCCri : F3_2<2, 0b011110, "udivcc">;
|
||||
def SDIVCCrr : F3_1<2, 0b011111, "sdivcc">;
|
||||
def SDIVCCri : F3_2<2, 0b011111, "sdivcc">;
|
||||
|
||||
// Section B.20 - SAVE and RESTORE, p. 117
|
||||
def SAVErr : F3_1<2, 0b111100, "save">; // save r, r, r
|
||||
def SAVEri : F3_2<2, 0b111100, "save">; // save r, i, r
|
||||
def RESTORErr : F3_1<2, 0b111101, "restore">; // restore r, r, r
|
||||
def RESTOREri : F3_2<2, 0b111101, "restore">; // restore r, i, r
|
||||
|
||||
// Section B.21 - Branch on Integer Condition Codes Instructions, p. 119
|
||||
|
||||
// conditional branch class:
|
||||
class BranchV8<bits<4> cc, string nm> : F2_2<cc, 0b010, nm> {
|
||||
let isBranch = 1;
|
||||
let isTerminator = 1;
|
||||
let hasDelaySlot = 1;
|
||||
}
|
||||
|
||||
let isBarrier = 1 in
|
||||
def BA : BranchV8<0b1000, "ba">;
|
||||
def BN : BranchV8<0b0000, "bn">;
|
||||
def BNE : BranchV8<0b1001, "bne">;
|
||||
def BE : BranchV8<0b0001, "be">;
|
||||
def BG : BranchV8<0b1010, "bg">;
|
||||
def BLE : BranchV8<0b0010, "ble">;
|
||||
def BGE : BranchV8<0b1011, "bge">;
|
||||
def BL : BranchV8<0b0011, "bl">;
|
||||
def BGU : BranchV8<0b1100, "bgu">;
|
||||
def BLEU : BranchV8<0b0100, "bleu">;
|
||||
def BCC : BranchV8<0b1101, "bcc">;
|
||||
def BCS : BranchV8<0b0101, "bcs">;
|
||||
|
||||
// Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121
|
||||
|
||||
// floating-point conditional branch class:
|
||||
class FPBranchV8<bits<4> cc, string nm> : F2_2<cc, 0b110, nm> {
|
||||
let isBranch = 1;
|
||||
let isTerminator = 1;
|
||||
let hasDelaySlot = 1;
|
||||
}
|
||||
|
||||
def FBA : FPBranchV8<0b1000, "fba">;
|
||||
def FBN : FPBranchV8<0b0000, "fbn">;
|
||||
def FBU : FPBranchV8<0b0111, "fbu">;
|
||||
def FBG : FPBranchV8<0b0110, "fbg">;
|
||||
def FBUG : FPBranchV8<0b0101, "fbug">;
|
||||
def FBL : FPBranchV8<0b0100, "fbl">;
|
||||
def FBUL : FPBranchV8<0b0011, "fbul">;
|
||||
def FBLG : FPBranchV8<0b0010, "fblg">;
|
||||
def FBNE : FPBranchV8<0b0001, "fbne">;
|
||||
def FBE : FPBranchV8<0b1001, "fbe">;
|
||||
def FBUE : FPBranchV8<0b1010, "fbue">;
|
||||
def FBGE : FPBranchV8<0b1011, "fbge">;
|
||||
def FBUGE: FPBranchV8<0b1100, "fbuge">;
|
||||
def FBLE : FPBranchV8<0b1101, "fble">;
|
||||
def FBULE: FPBranchV8<0b1110, "fbule">;
|
||||
def FBO : FPBranchV8<0b1111, "fbo">;
|
||||
|
||||
|
||||
|
||||
// Section B.24 - Call and Link Instruction, p. 125
|
||||
// This is the only Format 1 instruction
|
||||
let Uses = [O0, O1, O2, O3, O4, O5], hasDelaySlot = 1, isCall = 1 in {
|
||||
// pc-relative call:
|
||||
let Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7,
|
||||
D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in
|
||||
def CALL : InstV8 {
|
||||
bits<30> disp;
|
||||
let op = 1;
|
||||
let Inst{29-0} = disp;
|
||||
let Name = "call";
|
||||
}
|
||||
|
||||
// indirect call (O7 is an EXPLICIT def in indirect calls, so it cannot also
|
||||
// be an implicit def):
|
||||
let Defs = [O0, O1, O2, O3, O4, O5, G1, G2, G3, G4, G5, G6, G7,
|
||||
D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in
|
||||
def JMPLrr : F3_1<2, 0b111000, "jmpl">; // jmpl [rs1+rs2], rd
|
||||
}
|
||||
|
||||
// Section B.29 - Write State Register Instructions
|
||||
def WRrr : F3_1<2, 0b110000, "wr">; // wr rs1, rs2, rd
|
||||
def WRri : F3_2<2, 0b110000, "wr">; // wr rs1, imm, rd
|
||||
|
||||
// Convert Integer to Floating-point Instructions, p. 141
|
||||
def FITOS : F3_3<2, 0b110100, 0b011000100, "fitos">;
|
||||
def FITOD : F3_3<2, 0b110100, 0b011001000, "fitod">;
|
||||
|
||||
// Convert Floating-point to Integer Instructions, p. 142
|
||||
def FSTOI : F3_3<2, 0b110100, 0b011010001, "fstoi">;
|
||||
def FDTOI : F3_3<2, 0b110100, 0b011010010, "fdtoi">;
|
||||
|
||||
// Convert between Floating-point Formats Instructions, p. 143
|
||||
def FSTOD : F3_3<2, 0b110100, 0b011001001, "fstod">;
|
||||
def FDTOS : F3_3<2, 0b110100, 0b011000110, "fdtos">;
|
||||
|
||||
// Floating-point Move Instructions, p. 144
|
||||
def FMOVS : F3_3<2, 0b110100, 0b000000001, "fmovs">;
|
||||
def FNEGS : F3_3<2, 0b110100, 0b000000101, "fnegs">;
|
||||
def FABSS : F3_3<2, 0b110100, 0b000001001, "fabss">;
|
||||
|
||||
// Floating-point Add and Subtract Instructions, p. 146
|
||||
def FADDS : F3_3<2, 0b110100, 0b001000001, "fadds">;
|
||||
def FADDD : F3_3<2, 0b110100, 0b001000010, "faddd">;
|
||||
def FSUBS : F3_3<2, 0b110100, 0b001000101, "fsubs">;
|
||||
def FSUBD : F3_3<2, 0b110100, 0b001000110, "fsubd">;
|
||||
|
||||
// Floating-point Multiply and Divide Instructions, p. 147
|
||||
def FMULS : F3_3<2, 0b110100, 0b001001001, "fmuls">;
|
||||
def FMULD : F3_3<2, 0b110100, 0b001001010, "fmuld">;
|
||||
def FSMULD : F3_3<2, 0b110100, 0b001101001, "fsmuld">;
|
||||
def FDIVS : F3_3<2, 0b110100, 0b001001101, "fdivs">;
|
||||
def FDIVD : F3_3<2, 0b110100, 0b001001110, "fdivd">;
|
||||
|
||||
// Floating-point Compare Instructions, p. 148
|
||||
// Note: the 2nd template arg is different for these guys.
|
||||
// Note 2: the result of a FCMP is not available until the 2nd cycle
|
||||
// after the instr is retired, but there is no interlock. This behavior
|
||||
// is modelled as a delay slot.
|
||||
let hasDelaySlot = 1 in {
|
||||
def FCMPS : F3_3<2, 0b110101, 0b001010001, "fcmps">;
|
||||
def FCMPD : F3_3<2, 0b110101, 0b001010010, "fcmpd">;
|
||||
def FCMPES : F3_3<2, 0b110101, 0b001010101, "fcmpes">;
|
||||
def FCMPED : F3_3<2, 0b110101, 0b001010110, "fcmped">;
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
//===- SparcV8JITInfo.h - SparcV8 impl. of the JIT interface ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the SparcV8 implementation of the TargetJITInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SPARCV8JITINFO_H
|
||||
#define SPARCV8JITINFO_H
|
||||
|
||||
#include "llvm/Target/TargetJITInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
class TargetMachine;
|
||||
class IntrinsicLowering;
|
||||
|
||||
class SparcV8JITInfo : public TargetJITInfo {
|
||||
TargetMachine &TM;
|
||||
public:
|
||||
SparcV8JITInfo(TargetMachine &tm) : TM(tm) {}
|
||||
|
||||
/// addPassesToJITCompile - Add passes to the specified pass manager to
|
||||
/// implement a fast dynamic compiler for this target. Return true if this
|
||||
/// is not supported for this target.
|
||||
///
|
||||
virtual void addPassesToJITCompile(FunctionPassManager &PM);
|
||||
|
||||
/// replaceMachineCodeForFunction - Make it so that calling the function
|
||||
/// whose machine code is at OLD turns into a call to NEW, perhaps by
|
||||
/// overwriting OLD with a branch to NEW. This is used for self-modifying
|
||||
/// code.
|
||||
///
|
||||
virtual void replaceMachineCodeForFunction(void *Old, void *New);
|
||||
|
||||
/// getJITStubForFunction - Create or return a stub for the specified
|
||||
/// function. This stub acts just like the specified function, except that
|
||||
/// it allows the "address" of the function to be taken without having to
|
||||
/// generate code for it.
|
||||
virtual void *getJITStubForFunction(Function *F, MachineCodeEmitter &MCE);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,176 +0,0 @@
|
||||
//===- SparcV8RegisterInfo.cpp - SparcV8 Register Information ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the SparcV8 implementation of the MRegisterInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SparcV8.h"
|
||||
#include "SparcV8RegisterInfo.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include <iostream>
|
||||
using namespace llvm;
|
||||
|
||||
SparcV8RegisterInfo::SparcV8RegisterInfo()
|
||||
: SparcV8GenRegisterInfo(V8::ADJCALLSTACKDOWN,
|
||||
V8::ADJCALLSTACKUP) {}
|
||||
|
||||
static const TargetRegisterClass *getClass(unsigned SrcReg) {
|
||||
if (SparcV8::IntRegsRegisterClass->contains(SrcReg))
|
||||
return SparcV8::IntRegsRegisterClass;
|
||||
else if (SparcV8::FPRegsRegisterClass->contains(SrcReg))
|
||||
return SparcV8::FPRegsRegisterClass;
|
||||
else if (SparcV8::DFPRegsRegisterClass->contains(SrcReg))
|
||||
return SparcV8::DFPRegsRegisterClass;
|
||||
else {
|
||||
std::cerr << "Error: register of unknown class found: " << SrcReg << "\n";
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
void SparcV8RegisterInfo::
|
||||
storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
||||
unsigned SrcReg, int FrameIdx) const {
|
||||
const TargetRegisterClass *RC = getClass(SrcReg);
|
||||
|
||||
// On the order of operands here: think "[FrameIdx + 0] = SrcReg".
|
||||
if (RC == SparcV8::IntRegsRegisterClass)
|
||||
BuildMI (MBB, I, V8::ST, 3).addFrameIndex (FrameIdx).addSImm (0)
|
||||
.addReg (SrcReg);
|
||||
else if (RC == SparcV8::FPRegsRegisterClass)
|
||||
BuildMI (MBB, I, V8::STFri, 3).addFrameIndex (FrameIdx).addSImm (0)
|
||||
.addReg (SrcReg);
|
||||
else if (RC == SparcV8::DFPRegsRegisterClass)
|
||||
BuildMI (MBB, I, V8::STDFri, 3).addFrameIndex (FrameIdx).addSImm (0)
|
||||
.addReg (SrcReg);
|
||||
else
|
||||
assert (0 && "Can't store this register to stack slot");
|
||||
}
|
||||
|
||||
void SparcV8RegisterInfo::
|
||||
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
||||
unsigned DestReg, int FrameIdx) const {
|
||||
const TargetRegisterClass *RC = getClass(DestReg);
|
||||
if (RC == SparcV8::IntRegsRegisterClass)
|
||||
BuildMI (MBB, I, V8::LD, 2, DestReg).addFrameIndex (FrameIdx).addSImm (0);
|
||||
else if (RC == SparcV8::FPRegsRegisterClass)
|
||||
BuildMI (MBB, I, V8::LDFri, 2, DestReg).addFrameIndex (FrameIdx)
|
||||
.addSImm (0);
|
||||
else if (RC == SparcV8::DFPRegsRegisterClass)
|
||||
BuildMI (MBB, I, V8::LDDFri, 2, DestReg).addFrameIndex (FrameIdx)
|
||||
.addSImm (0);
|
||||
else
|
||||
assert(0 && "Can't load this register from stack slot");
|
||||
}
|
||||
|
||||
void SparcV8RegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
unsigned DestReg, unsigned SrcReg,
|
||||
const TargetRegisterClass *RC) const {
|
||||
if (RC == SparcV8::IntRegsRegisterClass)
|
||||
BuildMI (MBB, I, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg);
|
||||
else if (RC == SparcV8::FPRegsRegisterClass)
|
||||
BuildMI (MBB, I, V8::FMOVS, 1, DestReg).addReg (SrcReg);
|
||||
else if (RC == SparcV8::DFPRegsRegisterClass)
|
||||
BuildMI (MBB, I, V8::FpMOVD, 1, DestReg).addReg (SrcReg);
|
||||
else
|
||||
assert (0 && "Can't copy this register");
|
||||
}
|
||||
|
||||
void SparcV8RegisterInfo::
|
||||
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I) const {
|
||||
MachineInstr &MI = *I;
|
||||
int size = MI.getOperand (0).getImmedValue ();
|
||||
if (MI.getOpcode () == V8::ADJCALLSTACKDOWN)
|
||||
size = -size;
|
||||
BuildMI (MBB, I, V8::ADDri, 2, V8::SP).addReg (V8::SP).addSImm (size);
|
||||
MBB.erase (I);
|
||||
}
|
||||
|
||||
void
|
||||
SparcV8RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
|
||||
unsigned i = 0;
|
||||
MachineInstr &MI = *II;
|
||||
while (!MI.getOperand(i).isFrameIndex()) {
|
||||
++i;
|
||||
assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
|
||||
}
|
||||
|
||||
int FrameIndex = MI.getOperand(i).getFrameIndex();
|
||||
|
||||
// Replace frame index with a frame pointer reference
|
||||
MI.SetMachineOperandReg (i, V8::FP);
|
||||
|
||||
// Addressable stack objects are accessed using neg. offsets from %fp
|
||||
MachineFunction &MF = *MI.getParent()->getParent();
|
||||
int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
|
||||
MI.getOperand(i+1).getImmedValue();
|
||||
// note: Offset < 0
|
||||
MI.SetMachineOperandConst (i+1, MachineOperand::MO_SignExtendedImmed, Offset);
|
||||
}
|
||||
|
||||
void SparcV8RegisterInfo::
|
||||
processFunctionBeforeFrameFinalized(MachineFunction &MF) const {}
|
||||
|
||||
void SparcV8RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||
MachineBasicBlock &MBB = MF.front();
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
|
||||
// Get the number of bytes to allocate from the FrameInfo
|
||||
int NumBytes = (int) MFI->getStackSize();
|
||||
|
||||
// Emit the correct save instruction based on the number of bytes in
|
||||
// the frame. Minimum stack frame size according to V8 ABI is:
|
||||
// 16 words for register window spill
|
||||
// 1 word for address of returned aggregate-value
|
||||
// + 6 words for passing parameters on the stack
|
||||
// ----------
|
||||
// 23 words * 4 bytes per word = 92 bytes
|
||||
NumBytes += 92;
|
||||
// Round up to next doubleword boundary -- a double-word boundary
|
||||
// is required by the ABI.
|
||||
NumBytes = (NumBytes + 7) & ~7;
|
||||
BuildMI(MBB, MBB.begin(), V8::SAVEri, 2,
|
||||
V8::SP).addImm(-NumBytes).addReg(V8::SP);
|
||||
}
|
||||
|
||||
void SparcV8RegisterInfo::emitEpilogue(MachineFunction &MF,
|
||||
MachineBasicBlock &MBB) const {
|
||||
MachineBasicBlock::iterator MBBI = prior(MBB.end());
|
||||
assert(MBBI->getOpcode() == V8::RETL &&
|
||||
"Can only put epilog before 'retl' instruction!");
|
||||
BuildMI(MBB, MBBI, V8::RESTORErr, 2, V8::G0).addReg(V8::G0).addReg(V8::G0);
|
||||
}
|
||||
|
||||
#include "SparcV8GenRegisterInfo.inc"
|
||||
|
||||
const TargetRegisterClass*
|
||||
SparcV8RegisterInfo::getRegClassForType(const Type* Ty) const {
|
||||
switch (Ty->getTypeID()) {
|
||||
case Type::FloatTyID: return &FPRegsInstance;
|
||||
case Type::DoubleTyID: return &DFPRegsInstance;
|
||||
case Type::LongTyID:
|
||||
case Type::ULongTyID: assert(0 && "Long values do not fit in registers!");
|
||||
default: assert(0 && "Invalid type to getClass!");
|
||||
case Type::BoolTyID:
|
||||
case Type::SByteTyID:
|
||||
case Type::UByteTyID:
|
||||
case Type::ShortTyID:
|
||||
case Type::UShortTyID:
|
||||
case Type::IntTyID:
|
||||
case Type::UIntTyID:
|
||||
case Type::PointerTyID: return &IntRegsInstance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
//===- SparcV8RegisterInfo.h - SparcV8 Register Information Impl -*- C++ -*-==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the SparcV8 implementation of the MRegisterInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SPARCV8REGISTERINFO_H
|
||||
#define SPARCV8REGISTERINFO_H
|
||||
|
||||
#include "llvm/Target/MRegisterInfo.h"
|
||||
#include "SparcV8GenRegisterInfo.h.inc"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Type;
|
||||
|
||||
struct SparcV8RegisterInfo : public SparcV8GenRegisterInfo {
|
||||
SparcV8RegisterInfo();
|
||||
const TargetRegisterClass* getRegClassForType(const Type* Ty) const;
|
||||
|
||||
/// Code Generation virtual methods...
|
||||
void storeRegToStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MBBI,
|
||||
unsigned SrcReg, int FrameIndex) const;
|
||||
|
||||
void loadRegFromStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MBBI,
|
||||
unsigned DestReg, int FrameIndex) const;
|
||||
|
||||
void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
|
||||
unsigned DestReg, unsigned SrcReg,
|
||||
const TargetRegisterClass *RC) const;
|
||||
|
||||
void eliminateCallFramePseudoInstr(MachineFunction &MF,
|
||||
MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I) const;
|
||||
|
||||
void eliminateFrameIndex(MachineBasicBlock::iterator II) const;
|
||||
|
||||
void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
|
||||
|
||||
void emitPrologue(MachineFunction &MF) const;
|
||||
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
@@ -1,51 +0,0 @@
|
||||
//===- SparcV8RegisterInfo.td - SparcV8 Register defs ------*- tablegen -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Declarations that describe the SparcV8 register file
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class SparcReg<string n> : Register<n> {
|
||||
field bits<5> Num;
|
||||
let Namespace = "V8";
|
||||
}
|
||||
|
||||
include "../SparcRegisterInfo.td"
|
||||
|
||||
// Register classes.
|
||||
//
|
||||
// FIXME: the register order should be defined in terms of the preferred
|
||||
// allocation order...
|
||||
//
|
||||
def IntRegs : RegisterClass<i32, 32, [L0, L1, L2, L3, L4, L5, L6, L7,
|
||||
I0, I1, I2, I3, I4, I5,
|
||||
G1,
|
||||
O0, O1, O2, O3, O4, O5, O7,
|
||||
// Non-allocatable regs:
|
||||
G2, G3, G4, // FIXME: OK for use only in
|
||||
// applications, not libraries.
|
||||
O6, // stack ptr
|
||||
I6, // frame ptr
|
||||
I7, // return address
|
||||
G0, // constant zero
|
||||
G5, G6, G7 // reserved for kernel
|
||||
]> {
|
||||
let Methods = [{
|
||||
iterator allocation_order_end(MachineFunction &MF) const {
|
||||
return end()-10; // Don't allocate special registers
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
def FPRegs : RegisterClass<f32, 32, [F0, F1, F2, F3, F4, F5, F6, F7, F8,
|
||||
F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22,
|
||||
F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
||||
|
||||
def DFPRegs : RegisterClass<f64, 64, [D0, D1, D2, D3, D4, D5, D6, D7,
|
||||
D8, D9, D10, D11, D12, D13, D14, D15]>;
|
||||
@@ -1,155 +0,0 @@
|
||||
//===-- SparcV8TargetMachine.cpp - Define TargetMachine for SparcV8 -------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SparcV8TargetMachine.h"
|
||||
#include "SparcV8.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/Target/TargetMachineRegistry.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include <iostream>
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
// Register the target.
|
||||
RegisterTarget<SparcV8TargetMachine> X("sparcv8"," SPARC V8 (experimental)");
|
||||
}
|
||||
|
||||
/// SparcV8TargetMachine ctor - Create an ILP32 architecture model
|
||||
///
|
||||
SparcV8TargetMachine::SparcV8TargetMachine(const Module &M,
|
||||
IntrinsicLowering *IL)
|
||||
: TargetMachine("SparcV8", IL, false, 4, 4, 8, 4, 8, 4, 4, 4, 4),
|
||||
FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0), JITInfo(*this) {
|
||||
}
|
||||
|
||||
unsigned SparcV8TargetMachine::getJITMatchQuality() {
|
||||
return 0; // No JIT yet.
|
||||
}
|
||||
|
||||
unsigned SparcV8TargetMachine::getModuleMatchQuality(const Module &M) {
|
||||
if (M.getEndianness() == Module::BigEndian &&
|
||||
M.getPointerSize() == Module::Pointer32)
|
||||
#ifdef __sparc__
|
||||
return 20; // BE/32 ==> Prefer sparcv8 on sparc
|
||||
#else
|
||||
return 5; // BE/32 ==> Prefer ppc elsewhere
|
||||
#endif
|
||||
else if (M.getEndianness() != Module::AnyEndianness ||
|
||||
M.getPointerSize() != Module::AnyPointerSize)
|
||||
return 0; // Match for some other target
|
||||
|
||||
return getJITMatchQuality()/2;
|
||||
}
|
||||
|
||||
/// addPassesToEmitAssembly - Add passes to the specified pass manager
|
||||
/// to implement a static compiler for this target.
|
||||
///
|
||||
bool SparcV8TargetMachine::addPassesToEmitAssembly(PassManager &PM,
|
||||
std::ostream &Out) {
|
||||
// FIXME: Implement efficient support for garbage collection intrinsics.
|
||||
PM.add(createLowerGCPass());
|
||||
|
||||
// Replace malloc and free instructions with library calls.
|
||||
PM.add(createLowerAllocationsPass());
|
||||
|
||||
// FIXME: implement the select instruction in the instruction selector.
|
||||
PM.add(createLowerSelectPass());
|
||||
|
||||
// FIXME: implement the switch instruction in the instruction selector.
|
||||
PM.add(createLowerSwitchPass());
|
||||
|
||||
// FIXME: implement the invoke/unwind instructions!
|
||||
PM.add(createLowerInvokePass());
|
||||
|
||||
PM.add(createLowerConstantExpressionsPass());
|
||||
|
||||
// Make sure that no unreachable blocks are instruction selected.
|
||||
PM.add(createUnreachableBlockEliminationPass());
|
||||
|
||||
PM.add(createSparcV8SimpleInstructionSelector(*this));
|
||||
|
||||
// Print machine instructions as they were initially generated.
|
||||
if (PrintMachineCode)
|
||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
||||
|
||||
PM.add(createRegisterAllocator());
|
||||
PM.add(createPrologEpilogCodeInserter());
|
||||
|
||||
// Print machine instructions after register allocation and prolog/epilog
|
||||
// insertion.
|
||||
if (PrintMachineCode)
|
||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
||||
|
||||
PM.add(createSparcV8FPMoverPass(*this));
|
||||
PM.add(createSparcV8DelaySlotFillerPass(*this));
|
||||
|
||||
// Print machine instructions after filling delay slots.
|
||||
if (PrintMachineCode)
|
||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
||||
|
||||
// Output assembly language.
|
||||
PM.add(createSparcV8CodePrinterPass(Out, *this));
|
||||
|
||||
// Delete the MachineInstrs we generated, since they're no longer needed.
|
||||
PM.add(createMachineCodeDeleter());
|
||||
return false;
|
||||
}
|
||||
|
||||
/// addPassesToJITCompile - Add passes to the specified pass manager to
|
||||
/// implement a fast dynamic compiler for this target.
|
||||
///
|
||||
void SparcV8JITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
|
||||
// FIXME: Implement efficient support for garbage collection intrinsics.
|
||||
PM.add(createLowerGCPass());
|
||||
|
||||
// Replace malloc and free instructions with library calls.
|
||||
PM.add(createLowerAllocationsPass());
|
||||
|
||||
// FIXME: implement the select instruction in the instruction selector.
|
||||
PM.add(createLowerSelectPass());
|
||||
|
||||
// FIXME: implement the switch instruction in the instruction selector.
|
||||
PM.add(createLowerSwitchPass());
|
||||
|
||||
// FIXME: implement the invoke/unwind instructions!
|
||||
PM.add(createLowerInvokePass());
|
||||
|
||||
PM.add(createLowerConstantExpressionsPass());
|
||||
|
||||
// Make sure that no unreachable blocks are instruction selected.
|
||||
PM.add(createUnreachableBlockEliminationPass());
|
||||
|
||||
PM.add(createSparcV8SimpleInstructionSelector(TM));
|
||||
|
||||
// Print machine instructions as they were initially generated.
|
||||
if (PrintMachineCode)
|
||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
||||
|
||||
PM.add(createRegisterAllocator());
|
||||
PM.add(createPrologEpilogCodeInserter());
|
||||
|
||||
// Print machine instructions after register allocation and prolog/epilog
|
||||
// insertion.
|
||||
if (PrintMachineCode)
|
||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
||||
|
||||
PM.add(createSparcV8FPMoverPass(TM));
|
||||
PM.add(createSparcV8DelaySlotFillerPass(TM));
|
||||
|
||||
// Print machine instructions after filling delay slots.
|
||||
if (PrintMachineCode)
|
||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
//===-- SparcV8TargetMachine.h - Define TargetMachine for SparcV8 -*- C++ -*-=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the SparcV8 specific subclass of TargetMachine.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SPARCV8TARGETMACHINE_H
|
||||
#define SPARCV8TARGETMACHINE_H
|
||||
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetFrameInfo.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "SparcV8InstrInfo.h"
|
||||
#include "SparcV8JITInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class IntrinsicLowering;
|
||||
class Module;
|
||||
|
||||
class SparcV8TargetMachine : public TargetMachine {
|
||||
SparcV8InstrInfo InstrInfo;
|
||||
TargetFrameInfo FrameInfo;
|
||||
SparcV8JITInfo JITInfo;
|
||||
public:
|
||||
SparcV8TargetMachine(const Module &M, IntrinsicLowering *IL);
|
||||
|
||||
virtual const SparcV8InstrInfo *getInstrInfo() const { return &InstrInfo; }
|
||||
virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; }
|
||||
virtual const MRegisterInfo *getRegisterInfo() const {
|
||||
return &InstrInfo.getRegisterInfo();
|
||||
}
|
||||
virtual TargetJITInfo *getJITInfo() {
|
||||
return &JITInfo;
|
||||
}
|
||||
|
||||
static unsigned getModuleMatchQuality(const Module &M);
|
||||
static unsigned getJITMatchQuality();
|
||||
|
||||
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
|
||||
/// get machine code emitted. This uses a MachineCodeEmitter object to handle
|
||||
/// actually outputting the machine code and resolving things like the address
|
||||
/// of functions. This method should returns true if machine code emission is
|
||||
/// not supported.
|
||||
///
|
||||
virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
|
||||
MachineCodeEmitter &MCE);
|
||||
|
||||
virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
@@ -47,14 +47,14 @@ $(ObjDir)/comp_main.bc: $(MainObj)
|
||||
$(Echo) Linking $(notdir $@) component...
|
||||
$(Verb) $(GCCLD) -link-as-library \
|
||||
-internalize-public-api-file=$(BUILD_SRC_DIR)/comp_main.lst \
|
||||
$(MainObj) -o $@ \
|
||||
$(MainObj) -o $@
|
||||
|
||||
# Generic exception handling support runtime.
|
||||
$(ObjDir)/comp_genericeh.bc: $(GenericEHObj)
|
||||
$(Echo) Linking $(notdir $@) component...
|
||||
$(Verb) $(GCCLD) -link-as-library \
|
||||
-internalize-public-api-file=$(BUILD_SRC_DIR)/comp_genericeh.lst \
|
||||
$(GenericEHObj) -o $@
|
||||
$(GenericEHObj) -o $@
|
||||
|
||||
# setjmp/longjmp exception handling support runtime.
|
||||
$(ObjDir)/comp_sjljeh.bc: $(SJLJEHObj)
|
||||
|
||||
@@ -13,105 +13,11 @@ DIRS =
|
||||
#
|
||||
# Make Dejagnu the default for testing
|
||||
#
|
||||
all:: check
|
||||
all:: check-local
|
||||
|
||||
# Include other test rules
|
||||
include Makefile.tests
|
||||
|
||||
# New QMTest functionality:
|
||||
# The test suite is being transitioned over to QMTest. Eventually, it
|
||||
# will use QMTest by default.
|
||||
|
||||
# QMTest option specifying the location of the QMTest database.
|
||||
QMDB= -D $(LLVM_SRC_ROOT)/test
|
||||
QMCLASSES=$(LLVM_OBJ_ROOT)/test/QMTest
|
||||
|
||||
#
|
||||
# Determine which expectations file we will use
|
||||
#
|
||||
QMEXPECT:=$(LLVM_SRC_ROOT)/test/QMTest/expectations.unknown.qmr
|
||||
ifeq ($(OS),Linux)
|
||||
QMEXPECT:=$(LLVM_SRC_ROOT)/test/QMTest/expectations.linux.qmr
|
||||
endif
|
||||
|
||||
ifeq ($(OS),SunOS)
|
||||
QMEXPECT:=$(LLVM_SRC_ROOT)/test/QMTest/expectations.sunos.qmr
|
||||
endif
|
||||
|
||||
ifeq ($(OS),Darwin)
|
||||
QMEXPECT:=$(LLVM_SRC_ROOT)/test/QMTest/expectations.darwin.qmr
|
||||
endif
|
||||
|
||||
#
|
||||
# This is configuration information used by the test suite. In QM Test, it's
|
||||
# called a 'context.'
|
||||
#
|
||||
CONTEXT= -c "srcroot=$(LLVM_SRC_ROOT)" \
|
||||
-c "buildroot=$(LLVM_OBJ_ROOT)" \
|
||||
-c "buildtype=$(BuildMode)" \
|
||||
-c "tmpdir=$(LLVM_OBJ_ROOT)/test/tmp" \
|
||||
-c "coresize=0" \
|
||||
-c "cc=$(CC)" \
|
||||
-c "cxx=$(CXX)" \
|
||||
-c "llvmgcc=$(LLVMGCC)" \
|
||||
-c "llvmgxx=$(LLVMGXX)" \
|
||||
-c "make=$(MAKE)" \
|
||||
-c "python=$(PYTHON)"
|
||||
|
||||
#
|
||||
# Location of the QMTest program.
|
||||
#
|
||||
QMTEST= QMTEST_CLASS_PATH=$(QMCLASSES) qmtest $(QMDB)
|
||||
|
||||
|
||||
#
|
||||
# Execute the tests
|
||||
#
|
||||
qmtest:: $(LLVM_OBJ_ROOT)/test/tmp register
|
||||
-$(QMTEST) run -O $(QMEXPECT) $(CONTEXT)
|
||||
|
||||
%.t:: $(LLVM_OBJ_ROOT)/test/tmp register
|
||||
-$(QMTEST) run -O $(QMEXPECT) $(CONTEXT) $*
|
||||
|
||||
#
|
||||
# Create the temporary directory used by the test suite.
|
||||
#
|
||||
$(LLVM_OBJ_ROOT)/test/tmp::
|
||||
${MKDIR} $(LLVM_OBJ_ROOT)/test/tmp
|
||||
|
||||
#
|
||||
# Right now, QMTest compiles the python test classes and put them into the
|
||||
# source tree. Since Python bytecode is *not* cross-platform compatible (I
|
||||
# think), we'll regenerate every time.
|
||||
#
|
||||
# Simultaneous builds won't work, but shared source trees will.
|
||||
#
|
||||
register:
|
||||
$(QMTEST) register test llvm.TestAsmDisasm
|
||||
$(QMTEST) register test llvm.AssembleTest
|
||||
$(QMTEST) register test llvm.ConvertToCTest
|
||||
$(QMTEST) register test llvm.LLToCTest
|
||||
$(QMTEST) register test llvm.MachineCodeTest
|
||||
$(QMTEST) register test llvm.TestOptimizer
|
||||
$(QMTEST) register test llvm.LLITest
|
||||
$(QMTEST) register test llvm.TestRunner
|
||||
$(QMTEST) register test llvm.VerifierTest
|
||||
$(QMTEST) register test llvm.CTest
|
||||
$(QMTEST) register test llvm.CXXTest
|
||||
$(QMTEST) register database llvmdb.llvmdb
|
||||
|
||||
# Start up the QMTest GUI
|
||||
gui::
|
||||
$(QMTEST) gui --no-browser --daemon
|
||||
|
||||
# Also get rid of qmtest garbage when we 'make clean' in this directory.
|
||||
qmtest-clean:
|
||||
$(RM) -rf $(LLVM_OBJ_ROOT)/test/tmp
|
||||
$(RM) -f $(LLVM_SRC_ROOT)/test/QMTest/*.pyo \
|
||||
$(LLVM_OBJ_ROOT)/test/QMTest/*.pyo
|
||||
$(RM) -f $(LLVM_SRC_ROOT)/test/results.qmr \
|
||||
$(LLVM_OBJ_ROOT)/test/results.qmr
|
||||
|
||||
#===------------------------------------------------------------------------===#
|
||||
# DejaGNU testing support
|
||||
#===------------------------------------------------------------------------===#
|
||||
@@ -120,7 +26,7 @@ ifdef TESTSUITE
|
||||
RUNTESTFLAGS := --tool $(TESTSUITE)
|
||||
endif
|
||||
|
||||
check:: site.exp
|
||||
check-local:: site.exp
|
||||
PATH=$(LLVMToolDir):$(LLVM_SRC_ROOT)/test/Scripts:$(PATH) \
|
||||
$(RUNTEST) $(RUNTESTFLAGS)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
* This regression test ensures that the C front end can compile initializers
|
||||
* even when it cannot determine the size (as below).
|
||||
* XFAIL: linux,darwin
|
||||
* XFAIL: *
|
||||
*/
|
||||
struct one
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// RUN: llvmgcc -xc -std=c99 %s -c -o - | llvm-dis | grep -v llvm.isunordered | not grep call
|
||||
// RUN: %llvmgcc -xc -std=c99 %s -c -o - | llvm-dis | grep -v llvm.isunordered | not grep call
|
||||
// XFAIL: sparcv9
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
;; XFAIL: darwin,sun
|
||||
;; RUN: echo create > %t.commands
|
||||
;; RUN: echo s >> %t.commands
|
||||
;; RUN: echo s >> %t.commands
|
||||
|
||||
@@ -168,31 +168,37 @@ int main(int argc, char **argv, char **envp) {
|
||||
int exitCode = 0;
|
||||
|
||||
try {
|
||||
std::string ModuleID("gccld-output");
|
||||
std::auto_ptr<Module> Composite(new Module(ModuleID));
|
||||
|
||||
// We always look first in the current directory when searching for
|
||||
// libraries.
|
||||
LibPaths.insert(LibPaths.begin(), ".");
|
||||
|
||||
// If the user specified an extra search path in their environment, respect
|
||||
// it.
|
||||
if (char *SearchPath = getenv("LLVM_LIB_SEARCH_PATH"))
|
||||
LibPaths.push_back(SearchPath);
|
||||
|
||||
// Remove any consecutive duplicates of the same library...
|
||||
Libraries.erase(std::unique(Libraries.begin(), Libraries.end()),
|
||||
Libraries.end());
|
||||
|
||||
// Link in all of the files
|
||||
if (LinkFiles(argv[0], Composite.get(), InputFilenames, Verbose))
|
||||
return 1; // Error already printed
|
||||
// Set up the Composite module.
|
||||
std::auto_ptr<Module> Composite(0);
|
||||
|
||||
if (!LinkAsLibrary)
|
||||
LinkLibraries(argv[0], Composite.get(), Libraries, LibPaths,
|
||||
Verbose, Native);
|
||||
if (LinkAsLibrary) {
|
||||
// Link in only the files.
|
||||
Composite.reset( new Module(argv[0]) );
|
||||
if (LinkFiles(argv[0], Composite.get(), InputFilenames, Verbose))
|
||||
return 1; // Error already printed
|
||||
// The libraries aren't linked in but are noted as "dependent" in the
|
||||
// module.
|
||||
for (cl::list<std::string>::const_iterator I = Libraries.begin(),
|
||||
E = Libraries.end(); I != E ; ++I) {
|
||||
Composite.get()->addLibrary(*I);
|
||||
}
|
||||
|
||||
// Link in all of the libraries next...
|
||||
} else {
|
||||
// Build a list of the items from our command line
|
||||
LinkItemList Items;
|
||||
BuildLinkItems(Items, InputFilenames, Libraries);
|
||||
|
||||
// Link all the items together
|
||||
Composite.reset( LinkItems(argv[0], Items, LibPaths, Verbose, Native) );
|
||||
|
||||
// Check for an error during linker
|
||||
if (!Composite.get())
|
||||
return 1; // Error already printed
|
||||
}
|
||||
|
||||
// Create the output file.
|
||||
std::string RealBytecodeOutput = OutputFilename;
|
||||
|
||||
@@ -389,29 +389,37 @@ int main(int argc, char **argv, char **envp) {
|
||||
cl::ParseCommandLineOptions(argc, argv, " llvm linker for GCC\n");
|
||||
sys::PrintStackTraceOnErrorSignal();
|
||||
|
||||
std::string ModuleID("llvm-ld-output");
|
||||
std::auto_ptr<Module> Composite(new Module(ModuleID));
|
||||
|
||||
// We always look first in the current directory when searching for libraries.
|
||||
LibPaths.insert(LibPaths.begin(), ".");
|
||||
|
||||
// If the user specified an extra search path in their environment, respect
|
||||
// it.
|
||||
if (char *SearchPath = getenv("LLVM_LIB_SEARCH_PATH"))
|
||||
LibPaths.push_back(SearchPath);
|
||||
|
||||
// Remove any consecutive duplicates of the same library...
|
||||
Libraries.erase(std::unique(Libraries.begin(), Libraries.end()),
|
||||
Libraries.end());
|
||||
|
||||
// Link in all of the files
|
||||
if (LinkFiles(argv[0], Composite.get(), InputFilenames, Verbose))
|
||||
return 1; // Error already printed
|
||||
// Set up the Composite module.
|
||||
std::auto_ptr<Module> Composite(0);
|
||||
|
||||
// Link in all of the libraries next...
|
||||
if (!LinkAsLibrary)
|
||||
LinkLibraries(argv[0], Composite.get(), Libraries, LibPaths,
|
||||
Verbose, Native);
|
||||
if (LinkAsLibrary) {
|
||||
// Link in only the files.
|
||||
Composite.reset( new Module(argv[0]) );
|
||||
if (LinkFiles(argv[0], Composite.get(), InputFilenames, Verbose))
|
||||
return 1; // Error already printed
|
||||
|
||||
// The libraries aren't linked in but are noted as "dependent" in the
|
||||
// module.
|
||||
for (cl::list<std::string>::const_iterator I = Libraries.begin(),
|
||||
E = Libraries.end(); I != E ; ++I) {
|
||||
Composite.get()->addLibrary(*I);
|
||||
}
|
||||
} else {
|
||||
// Build a list of the items from our command line
|
||||
LinkItemList Items;
|
||||
BuildLinkItems(Items, InputFilenames, Libraries);
|
||||
|
||||
// Link all the items together
|
||||
Composite.reset( LinkItems(argv[0], Items, LibPaths, Verbose, Native) );
|
||||
|
||||
// Check for an error during linker
|
||||
if (!Composite.get())
|
||||
return 1; // Error already printed
|
||||
}
|
||||
|
||||
// Optimize the module
|
||||
Optimize(Composite.get());
|
||||
|
||||
Reference in New Issue
Block a user