This commit was manufactured by cvs2svn to create tag 'RELEASE_1'.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_1@9499 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
cvs2svn 2003-10-24 20:17:46 +00:00
parent e8a63eb78f
commit c5cf3309a2
48 changed files with 522 additions and 9952 deletions

View File

@ -1,37 +1,3 @@
NOTICE:
=======
All distributions of LLVM prior to the 1.0 Release will be licensed to you
under the LLVM pre-release license. The 1.0 Release will be announced on the
LLVM Announcements Mailing List.
After the 1.0 Release of LLVM, the LLVM code will be licensed to you under the
LLVM Release License (aka the Illinois Open Source License).
The main point is that you cannot re-distribute LLVM until the 1.0 Release.
==============================================================================
LLVM pre-release license
==============================================================================
This is a pre-release distribution of the LLVM software and is provided for
evaluation only. This version of the LLVM software or modifications thereof
should not be distributed to third parties for any purpose. Any third parties
interested in it can request a copy directly by sending e-mail to
llvmdev@cs.uiuc.edu. As this is an evaluation release, we would appreciate any
and all feedback, ideas, and reports of bugs that you encounter. You may
discuss development of LLVM on llvmdev@cs.uiuc.edu, and bugs can be submitted
through the LLVM Bug Tracker at http://llvm.cs.uiuc.edu/bugzilla/ . We thank
you for your interest in LLVM and look forward to any comments or feedback you
may have.
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
==============================================================================
LLVM Release License
==============================================================================

View File

@ -1,106 +1,129 @@
The LLVM Compiler Infrastructure
http://llvm.cs.uiuc.edu
Welcome to LLVM!
-----------------
This file is intended to do four things:
(1) help you get started using LLVM;
(2) tell you how to get questions about LLVM answered;
(3) tell you where to find documentation for different kinds of questions; and
(4) tell you about three LLVM-related mailing lists.
This file provides the location of all important LLVM documentation. In
particular, you should read the license information and the installation
directions before you begin using LLVM.
After that, there are several technical references that will help you use LLVM.
Consult them as necessary.
Getting Started with LLVM
-------------------------
Finally, you can find information on how to communicate with the LLVM
developers and LLVM community. This is of primary interest if you wish to
submit a bug, supply a patch, or just keep current with what's going on with
LLVM.
(1) For license information:
llvm/LICENSE.txt
Introductory Literature:
(2) Installing and compiling LLVM:
llvm/docs/GettingStarted.html
LLVM Home Page:
http://llvm.cs.uiuc.edu
(3) Learn about features and limitations of this release:
llvm/docs/ReleaseNotes.html
License Information:
llvm/LICENSE.txt
(4) Learn how to write a pass within the LLVM system:
llvm/docs/WritingAnLLVMPass.html
Release Notes:
llvm/docs/ReleaseNotes.html
(5) Learn how to start a new development project using LLVM, where your
new source code can live anywhere (outside or inside the LLVM tree),
while using LLVM header files and libraries:
llvm/docs/Projects.html
LLVM Design:
The LLVM Instruction Set and Compilation Strategy:
http://llvm.cs.uiuc.edu/pubs/2002-08-09-LLVMCompilationStrategy.html
Getting Help with LLVM
----------------------
(1) If you have questions or development problems not answered in the
documentation, send e-mail to llvmdev@cs.uiuc.edu. This mailing list is
monitored by all the people in the LLVM group at Illinois, and you should
expect prompt first responses.
(2) To report a bug, submit a bug report as described in the document:
http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html
(3) We now use Bugzilla to track bugs, so you can check the status of
previous bugs at:
http://llvm.cs.uiuc.edu/bugs/query.cgi
LLVM Documentation
------------------
All the documents mentioned below except the design overview tech report
are included as part of the LLVM release (in llvm/docs/*):
LLVM Design Overview:
LLVM : A Compilation Framework for Lifelong Program Analysis
and Transformation:
http://llvm.cs.uiuc.edu/pubs/2003-09-30-LifelongOptimizationTR.html
LLVM User Guides:
Download and Installation Instructions:
llvm/docs/GettingStarted.html
Download and Installation Instructions:
llvm/docs/GettingStarted.html
LLVM Command Guide:
llvm/docs/CommandGuide/CommandGuide.html
LLVM Command Guide:
llvm/docs/CommandGuide/index.html
LLVM Assembly Language:
llvm/docs/LangRef.html
LLVM Assembly Language:
llvm/docs/LangRef.html
LLVM Test Suite Guide:
llvm/docs/TestingGuide.html
LLVM Test Suite Guide:
llvm/docs/TestingGuide.html
LLVM Programming Documentation:
LLVM Programmers Manual:
llvm/docs/ProgrammersManual.html
LLVM Programmers Manual:
llvm/docs/ProgrammersManual.html
Writing an LLVM Pass:
llvm/docs/WritingAnLLVMPass.html
Writing an LLVM Pass:
llvm/docs/WritingAnLLVMPass.html
Alias Analysis in LLVM:
llvm/docs/AliasAnalysis.html
Alias Analysis in LLVM:
llvm/docs/AliasAnalysis.html
Command Line Library:
llvm/docs/CommandLine.html
Command Line Library:
llvm/docs/CommandLine.html
Coding Standards:
llvm/docs/CodingStandards.html
Coding Standards:
llvm/docs/CodingStandards.html
LLVM Community:
Other LLVM Resources:
Submitting a Bug:
http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html
Submitting a Bug:
http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html
Open Projects:
llvm/docs/OpenProjects.html
Open Projects:
llvm/docs/OpenProjects.html
Creating a new LLVM Project:
llvm/docs/Projects.html
Creating a new LLVM Project:
llvm/docs/Projects.html
Mailing Lists:
There are several mailing lists providing LLVM users with
information:
Mailing Lists
--------------
There are three mailing lists for providing LLVM users with information:
o LLVM Announcements List:
http://mail.cs.uiuc.edu/mailman/listinfo/llvm-announce
(1) LLVM Announcements List:
http://mail.cs.uiuc.edu/mailman/listinfo/llvm-announce
This is a low volume list that provides
important announcements regarding LLVM. It is
primarily intended to announce new releases,
major updates to the software, etc. This list
is highly recommended for anyone that uses LLVM.
This is a low volume list that provides important announcements regarding
LLVM. It is primarily intended to announce new releases, major updates to
the software, etc. This list is highly recommended for anyone that uses
LLVM.
(2) LLVM Developers List:
http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev
o LLVM Developers List:
http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev
This list is for people who want to be included in technical discussions
of LLVM. People post to this list when they have questions about writing
code for or using the LLVM tools. It is relatively low volume.
This list is for people who want to be included
in technical discussions of LLVM. People post
to this list when they have questions about
writing code for or using the LLVM tools. It
is low volume.
(3) LLVM Commits List
http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits
o LLVM Commits List
http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits
This list contains all commit messages that are
made when LLVM developers commit code changes
to the CVS archive. It is useful for those who
want to stay on the bleeding edge of LLVM
development.
This list is very high volume.
This list contains all commit messages that are made when LLVM developers
commit code changes to the CVS archive. It is useful for those who want to
stay on the bleeding edge of LLVM development. This list is very high
volume.

View File

@ -494,10 +494,12 @@ printed.
<!-- *********************************************************************** -->
<hr><font size="-1">
<hr>
<font size="-1">
<address><a href="mailto:sabre@nondot.org">Chris Lattner</a></address>
<a href="http://llvm.cs.uiuc.edu">The LLVM Compiler Infrastructure</a>
<br>
Last modified: $Date$
</font>
</body>
</html>

View File

@ -15,9 +15,12 @@
C/C++ front-end, based on GCC 3.4, from source.</p>
<p><b>NOTE:</b> This is currently a somewhat fragile, error-prone
process, and you should only try to do it if (A) you really, really,
really can't use the binaries we distribute, and (B) you are a wicked
good GCC hacker.</p>
process, and you should only try to do it if
<ul>
<li>(A) you really, really, really can't use the binaries we distribute
<li>(B) you need GCC to fix some of the header files on your system
<li>(C) you are an elite GCC hacker.</p>
</ul>
<p>We welcome patches to help make this process simpler.</p>
@ -105,6 +108,11 @@ good GCC hacker.</p>
<li>No inline assembly for position independent code. At the LLVM level,
everything is position independent.</li>
<li>We handle <tt>.init</tt> and <tt>.fini</tt> differently.</li>
<li>You may have to disable multilib support in your target. Using multilib
support causes the GCC compiler driver to add a lot of "<tt>-L</tt>"
options to the link line, which do not relate to LLVM and confuse
<tt>gccld</tt>. To disable multilibs, delete any
<tt>MULTILIB_OPTIONS</tt> lines from your target files.</li>
<li>Did we mention that we don't support inline assembly? You'll probably
have to add some fixinclude hacks to disable it in the system
headers.</li>
@ -149,6 +157,8 @@ following means:</p>
<hr><font size="-1">
<address><a href="mailto:gaeke -at- uiuc.edu">Brian Gaeke</a></address>
<a href="http://llvm.cs.uiuc.edu">The LLVM Compiler Infrastructure</a>
<br>
Last modified: $Date$
</font>

15
docs/ChrisNotes.txt Normal file
View File

@ -0,0 +1,15 @@
* Rewrite the llvm parser/lexer in http://www.antlr.org when time permits.
They actually do C++. Imagine that.
* Need a way to attach bytecode block info at various levels of asm code.
* Recognize and save comments in assembly and bytecode format
* Encode line number table in bytecode (like #line), optional table
* Encode negative relative offsets in the bytecode file
* Apparently bison has a %pure_parser option. Maybe useful for AsmParser
* Implement the following derived types:
* "packed format", like this: [4 x sbyte]: Packed SIMD datatype
* Bytecode reader should use extensions that may or may not be linked into the
application to read blocks. Thus an easy way to ignore symbol table info
would be to not link in that reader into the app.

View File

@ -831,6 +831,8 @@ something. :)
<hr>
<font size=-1>
<address><a href="mailto:sabre@nondot.org">Chris Lattner</a></address>
<a href="http://llvm.cs.uiuc.edu">The LLVM Compiler Infrastructure</a>
<br>
<!-- Created: Tue Jan 23 15:19:28 CST 2001 -->
<!-- hhmts start -->
Last modified: Sun Oct 12 22:12:43 CDT 2003

View File

@ -1530,6 +1530,8 @@ line options </b></font></td></tr></table><ul>
<hr>
<font size=-1>
<address><a href="mailto:sabre@nondot.org">Chris Lattner</a></address>
<a href="http://llvm.cs.uiuc.edu">The LLVM Compiler Infrastructure</a>
<br>
<!-- Created: Tue Jan 23 15:19:28 CST 2001 -->
<!-- hhmts start -->
Last modified: Fri Aug 1 16:30:11 CDT 2003

View File

@ -875,6 +875,8 @@ burg.llvm.lib analyze: ../../../include/llvm/Analysis/DSNode.h:7
<hr>
<address><a href="mailto:sabre@nondot.org">Chris Lattner</a></address>
<a href="http://llvm.cs.uiuc.edu">The LLVM Compiler Infrastructure</a>
<br>
<!-- Created: Wed Nov 6 19:57:57 CST 2002 -->
<!-- hhmts start -->
Last modified: Thu Nov 14 20:00:50 CST 2002

View File

@ -138,8 +138,25 @@ LLVM: Frequently Asked Questions
cases, this takes care of the problem. To do this, just type <tt>make
clean</tt> and then <tt>make</tt> in the directory that fails to build.
<p>
<dt><b>I've built LLVM and am testing it, but the tests freeze.</b>
<dd>
This is most likely occurring because you built a profile or release
(optimized) build of LLVM and have not specified the same information on
the <tt>gmake</tt> command line.
<p>
For example, if you built LLVM with the command:
<p>
<tt>gmake ENABLE_PROFILING=1</tt>
<p>
...then you must run the tests with the following commands:
<p>
<tt>cd llvm/test<br>gmake ENABLE_PROFILING=1</tt>
</dl>
<hr>
<a href="http://llvm.cs.uiuc.edu">The LLVM Compiler Infrastructure</a>
<br>
</body>
</html>

View File

@ -90,6 +90,11 @@
<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 Only:</b><br>
<tt>
cd cfrontend/sparc<br>
./fixheaders
</tt>
</ol>
<p>
@ -204,8 +209,7 @@
native code may not work on your platform.
<p>
The GCC front end is not very portable at the moment. If you want to get
it to work on another platform, you can always request
<a href="mailto:llvm-request@zion.cs.uiuc.edu">a copy of the source</a>
it to work on another platform, you can download a copy of the source
and try to compile it on your platform.
</p>
@ -377,7 +381,8 @@
<p>
Before configuring and compiling the LLVM suite, you need to extract the
LLVM GCC front end from the binary distribution. It is used for building the
LLVM GCC front end from the binary distribution. It is used for building
the
bytecode libraries later used by the GCC front end for linking programs, and
its location must be specified when the LLVM suite is configured.
</p>
@ -390,6 +395,29 @@
-</tt>
</ol>
If you are on a Sparc/Solaris machine, you will need to fix the header
files:
<p>
<tt>
cd cfrontend/sparc
<br>
./fixheaders
</tt>
<p>
The binary versions of the GCC front end may not suit all of your needs.
For example, the binary distribution may include an old version of a system
header file, not "fix" a header file that needs to be fixed for GCC, or it
may be linked with libraries not available on your system.
</p>
<p>
In cases like these, you may want to try
<a href="CFEBuildInstrs.html">building the GCC front end from source.</a>
This is not for the faint of heart, so be forewarned.
</p>
<!------------------------------------------------------------------------->
<h3><a name="config">Local LLVM Configuration</a></h3>
<!------------------------------------------------------------------------->
@ -1010,10 +1038,12 @@
If you have any questions or run into any snags (or you have any
additions...), please send an email to
<a href="mailto:sabre@nondot.org">Chris Lattner</a>.</p>
<a href="http://llvm.cs.uiuc.edu">The LLVM Compiler Infrastructure</a>
<br>
<!-- Created: Mon Jul 1 02:29:02 CDT 2002 -->
<!-- hhmts start -->
Last modified: Mon Aug 11 13:52:22 CDT 2003
<!-- hhmts end -->
<!-- Created: Mon Jul 1 02:29:02 CDT 2002 -->
<!-- hhmts start -->
Last modified: Mon Aug 11 13:52:22 CDT 2003
<!-- hhmts end -->
</body>
</html>

View File

@ -273,6 +273,8 @@ following:
<hr><font size-1>
<address><a href="mailto:sabre@nondot.org">Chris Lattner</a></address>
<a href="http://llvm.cs.uiuc.edu">The LLVM Compiler Infrastructure</a>
<br>
<!-- Created: Tue Aug 6 15:00:33 CDT 2002 -->
<!-- hhmts start -->
Last modified: Tue Oct 14 15:57:47 CDT 2003

View File

@ -1947,6 +1947,8 @@ arbitrarily complex and require memory allocation, for example.<p>
<hr>
<font size=-1>
<address><a href="mailto:sabre@nondot.org">Chris Lattner</a></address>
<a href="http://llvm.cs.uiuc.edu">The LLVM Compiler Infrastructure</a>
<br>
<!-- Created: Tue Jan 23 15:19:28 CST 2001 -->
<!-- hhmts start -->
Last modified: Tue Oct 21 10:43:36 CDT 2003

View File

@ -275,6 +275,8 @@ Ideas for profile guided transformations:<p>
<hr><font size-1>
<address><a href="mailto:sabre@nondot.org">Chris Lattner</a></address>
<a href="http://llvm.cs.uiuc.edu">The LLVM Compiler Infrastructure</a>
<br>
<!-- Created: Tue Aug 6 15:00:33 CDT 2002 -->
<!-- hhmts start -->
Last modified: Wed Oct 1 16:48:54 CDT 2003

View File

@ -1787,6 +1787,8 @@ pointer to the parent Function.
<hr><font size-1>
<address>By: <a href="mailto:dhurjati@cs.uiuc.edu">Dinakar Dhurjati</a> and
<a href="mailto:sabre@nondot.org">Chris Lattner</a></address>
<a href="http://llvm.cs.uiuc.edu">The LLVM Compiler Infrastructure</a>
<br>
<!-- Created: Tue Aug 6 15:00:33 CDT 2002 -->
<!-- hhmts start -->
Last modified: Sat Sep 20 09:25:11 CDT 2003

View File

@ -383,5 +383,8 @@
<hr>
Written by <a href="mailto:criswell@uiuc.edu">John Criswell</a>.
<br>
<a href="http://llvm.cs.uiuc.edu">The LLVM Compiler Infrastructure</a>
<br>
</body>
</html>

View File

@ -64,7 +64,10 @@ as well as a large suite of scalar and interprocedural optimizations.<p>
The default optimizer sequence used by the C/C++ front-ends is:<p>
<ol>
<li>CFG simplification (-simplifycfg)
<li>Interprocedural dead code elimination (-globaldce)
<li>Interprocedural constant propagation (-ipconstprop)
<li>Dead argument elimination (-deadargelim)
<li>Exception handling pruning (-prune-eh)
<li>Function inlining (-inline)
<li>Instruction combining (-instcombine)
@ -94,6 +97,7 @@ At link-time, the following optimizations are run:<p>
<ol>
<li>Global constant merging (-constmerge)
<li>[optional] Internalization [which marks most functions and global variables static] (-internalize)
<li>Interprocedural constant propagation (-ipconstprop)
<li>Interprocedural dead argument elimination (-deadargelim)
<li>Instruction combining (-instcombine)
<li>CFG simplification (-simplifycfg)
@ -103,7 +107,8 @@ At link-time, the following optimizations are run:<p>
At this time, LLVM is known to work properly with SPEC CPU 2000, the Olden
benchmarks, and the Ptrdist benchmarks among many other programs. Note however
that the Sparc and X86 backends do not currently support exception throwing or
long jumping. For these programs you must use the C backend.<p>
long jumping (including 253.perlbmk in SPEC). For these programs you must use
the C backend.<p>
<!-- *********************************************************************** -->
@ -358,6 +363,10 @@ problem probably cannot be fixed.<p>
<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.<p>
<li><a href="http://zion.cs.uiuc.edu/PR56">Zero arg vararg functions are not
supported</a>. This should not affect LLVM produced by the C or C++
frontends.<p>
<li>The code produces by the C back-end has only been tested with the Sun CC and
GCC compilers. It is possible that it will have to be adjusted to support other
C compilers.<p>

View File

@ -420,6 +420,8 @@
<hr><font size="-1">
<address>John T. Criswell</address>
<a href="http://llvm.cs.uiuc.edu">The LLVM Compiler Infrastructure</a>
<br>
Last modified: $Date$
</font>

View File

@ -1274,6 +1274,8 @@ href="#Pass"><tt>Pass</tt></a>, only the other way around.<p>
<hr><font size-1>
<address><a href="mailto:sabre@nondot.org">Chris Lattner</a></address>
<a href="http://llvm.cs.uiuc.edu">The LLVM Compiler Infrastructure</a>
<br>
<!-- Created: Tue Aug 6 15:00:33 CDT 2002 -->
<!-- hhmts start -->
Last modified: Tue Jul 22 15:52:30 CDT 2003

265
docs/index.html Normal file
View File

@ -0,0 +1,265 @@
<html>
<title>
The LLVM Compiler Infrastructure
</title>
<body>
<center>
<h1>
The LLVM Compiler Infrastructure
<br>
<a href="http://llvm.cs.uiuc.edu">http://llvm.cs.uiuc.edu</a>
</h1>
</center>
<hr>
<h2>
Welcome to LLVM!
</h2>
This file is intended to do four things:
<ol>
<li>
help you get started using LLVM;
</li>
<li>
tell you how to get questions about LLVM answered;
</li>
<li>
tell you where to find documentation for different kinds of questions; and
</li>
<li>
tell you about three LLVM-related mailing lists.
</li>
</ol>
<hr>
<h2>
Getting Started with LLVM
</h2>
<dl compact>
<dt>
For license information:
<dd>
<a href="../LICENSE.TXT">llvm/LICENSE.TXT</a>
<p>
<dt>
Installing and compiling LLVM:
<dd>
<a href="GettingStarted.html">llvm/docs/GettingStarted.html</a>
<p>
<dt>
Learn about features and limitations of this release:
<dd>
<a href="ReleaseNotes.html">llvm/docs/ReleaseNotes.html</a>
<p>
<dt>
Learn how to write a pass within the LLVM system:
<dd>
<a href="WritingAnLLVMPass.html">llvm/docs/WritingAnLLVMPass.html </a>
<p>
<dt>
Learn how to start a new development project using LLVM, where your
new source code can live anywhere (outside or inside the LLVM tree),
while using LLVM header files and libraries:
<dd>
<a href="Projects.html">llvm/docs/Projects.html</a>
</dl>
<hr>
<h2>
Getting Help with LLVM
</h2>
<ol>
<li>
If you have questions or development problems not answered in the
documentation, send e-mail to llvmdev@cs.uiuc.edu. This mailing list is
monitored by all the people in the LLVM group at Illinois, and you
should expect prompt first responses.
</li>
<li>
To report a bug, submit a bug report as described in the document:
<a href="http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html">
http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html</a>
</li>
<li>
We now use Bugzilla to track bugs, so you can check the status of
previous bugs at:
<a href="http://llvm.cs.uiuc.edu/bugs/query.cgi">
http://llvm.cs.uiuc.edu/bugs/query.cgi </a>
</li>
</ol>
<hr>
<h2>
LLVM Documentation
</h2>
All the documents mentioned below except the design overview tech report
are included as part of the LLVM release (in llvm/docs/*):
<h3>
LLVM Design Overview:
</h3>
<dl compact>
<dt>
LLVM : A Compilation Framework for Lifelong Program Analysis
and Transformation:
<dd>
<a href="http://llvm.cs.uiuc.edu/pubs/2003-09-30-LifelongOptimizationTR.html">
http://llvm.cs.uiuc.edu/pubs/2003-09-30-LifelongOptimizationTR.html </a>
</dl>
<h3>
LLVM User Guides:
</h3>
<dl compact>
<dt>
Download and Installation Instructions:
<dd>
<a href="GettingStarted.html"> llvm/docs/GettingStarted.html</a>
<p>
<dt>
LLVM Command Guide:
<dd>
<a href="CommandGuide/index.html">
llvm/docs/CommandGuide/index.html</a>
<p>
<dt>
LLVM Assembly Language:
<dd>
<a href="LangRef.html"> llvm/docs/LangRef.html</a>
<p>
<dt>
LLVM Test Suite Guide:
<dd>
<a href="TestingGuide.html"> llvm/docs/TestingGuide.html</a>
<p>
</dl>
<h3>
LLVM Programming Documentation:
</h3>
<dl compact>
<dt>
LLVM Programmers Manual:
<dd>
<a href="ProgrammersManual.html"> llvm/docs/ProgrammersManual.html</a>
<p>
<dt>
Writing an LLVM Pass:
<dd>
<a href="WritingAnLLVMPass.html"> llvm/docs/WritingAnLLVMPass.html</a>
<p>
<dt>
Alias Analysis in LLVM:
<dd>
<a href="AliasAnalysis.html"> llvm/docs/AliasAnalysis.html</a>
<p>
<dt>
Command Line Library:
<dd>
<a href="CommandLine.html"> llvm/docs/CommandLine.html</a>
<p>
<dt>
Coding Standards:
<dd>
<a href="CodingStandards.html"> llvm/docs/CodingStandards.html</a>
<p>
</dl>
<h3>
Other LLVM Resources:
</h3>
<dl compact>
<dt>
Submitting a Bug:
<dd>
<a href="http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html">
http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html</a>
<p>
<dt>
Open Projects:
<dd>
<a href="OpenProjects.html"> llvm/docs/OpenProjects.html</a>
<p>
<dt>
Creating a new LLVM Project:
<dd>
<a href="Projects.html"> llvm/docs/Projects.html</a>
<p>
</dl>
<hr>
<h2>
Mailing Lists
</h2>
There are three mailing lists for providing LLVM users with information:
<ol>
<li> LLVM Announcements List:<br>
<a href="http://mail.cs.uiuc.edu/mailman/listinfo/llvm-announce">
http://mail.cs.uiuc.edu/mailman/listinfo/llvm-announce</a>
<p>
This is a low volume list that provides important announcements regarding
LLVM. It is primarily intended to announce new releases, major updates to
the software, etc. This list is highly recommended for anyone that uses
LLVM.
</p>
<li> LLVM Developers List:<br>
<a href="http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev">
http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev</a>
<p>
This list is for people who want to be included in technical discussions
of LLVM. People post to this list when they have questions about writing
code for or using the LLVM tools. It is relatively low volume.
</p>
<li> LLVM Commits List<br>
<a href="http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits">
http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits</a>
<p>
This list contains all commit messages that are made when LLVM developers
commit code changes to the CVS archive. It is useful for those who want to
stay on the bleeding edge of LLVM development. This list is very high
volume.
</p>
</ol>
</body>
</html>

23
include/Config/strings.h Normal file
View File

@ -0,0 +1,23 @@
/*
* 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.
*
*===----------------------------------------------------------------------===//
*
* Description:
* This header file is the autoconf replacement for strings.h (if it lives
* on the system).
*/
#ifndef _CONFIG_STRINGS_H
#define _CONFIG_STRINGS_H
#include "Config/config.h"
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#endif

View File

@ -39,6 +39,10 @@ private:
///
void IncorporateType(const Type *Ty);
/// IncorporateSymbolTable - Include any named types.
///
void IncorporateSymbolTable(const SymbolTable &ST);
public:
/// run - This incorporates all types used by the specified module
bool run(Module &M);

View File

@ -1,240 +0,0 @@
/* Title: SparcRegClassInfo.h -*- C++ -*-
Author: Ruchira Sasanka
Date: Aug 20, 01
Purpose: Contains the description of integer register class of Sparc
*/
#ifndef SPARC_INT_REG_CLASS_H
#define SPARC_INT_REG_CLASS_H
#include "llvm/Target/RegInfo.h"
#include "llvm/CodeGen/IGNode.h"
//-----------------------------------------------------------------------------
// Integer Register Class
//-----------------------------------------------------------------------------
// Int register names in same order as enum in class SparcIntRegOrder
static string const IntRegNames[] =
{ "g1", "g2", "g3", "g4", "g5", "g6", "g7",
"o0", "o1", "o2", "o3", "o4", "o5", "o7",
"l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
"i0", "i1", "i2", "i3", "i4", "i5",
"g0", "i6", "i7", "o6" };
class SparcIntRegOrder{
public:
enum RegsInPrefOrder // colors possible for a LR (in preferred order)
{
// --- following colors are volatile across function calls
// %g0 can't be used for coloring - always 0
g1, g2, g3, g4, g5, g6, g7, //%g1-%g7
o0, o1, o2, o3, o4, o5, o7, // %o0-%o5,
// %o6 is sp,
// all %0's can get modified by a call
// --- following colors are NON-volatile across function calls
l0, l1, l2, l3, l4, l5, l6, l7, // %l0-%l7
i0, i1, i2, i3, i4, i5, // %i0-%i5: i's need not be preserved
// %i6 is the fp - so not allocated
// %i7 is the ret address - can be used if saved
// max # of colors reg coloring can allocate (NumOfAvailRegs)
// --- following colors are not available for allocation within this phase
// --- but can appear for pre-colored ranges
g0, i6, i7, o6
};
// max # of colors reg coloring can allocate
static unsigned int const NumOfAvailRegs = g0;
static unsigned int const StartOfNonVolatileRegs = l0;
static unsigned int const StartOfAllRegs = g1;
static unsigned int const NumOfAllRegs = o6 + 1;
static const string getRegName(const unsigned reg) {
assert( reg < NumOfAllRegs );
return IntRegNames[reg];
}
};
class SparcIntRegClass : public MachineRegClassInfo
{
public:
SparcIntRegClass(unsigned ID)
: MachineRegClassInfo(ID,
SparcIntRegOrder::NumOfAvailRegs,
SparcIntRegOrder::NumOfAllRegs)
{ }
void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const;
};
//-----------------------------------------------------------------------------
// Float Register Class
//-----------------------------------------------------------------------------
static string const FloatRegNames[] =
{
"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", "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
"f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47", "f48", "f49",
"f50", "f51", "f52", "f53", "f54", "f55", "f56", "f57", "f58", "f59",
"f60", "f61", "f62", "f63"
};
class SparcFloatRegOrder{
public:
enum RegsInPrefOrder {
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, f32, f33, f34, f35, f36, f37, f38, f39,
f40, f41, f42, f43, f44, f45, f46, f47, f48, f49,
f50, f51, f52, f53, f54, f55, f56, f57, f58, f59,
f60, f61, f62, f63
};
// there are 64 regs alltogether but only 32 regs can be allocated at
// a time.
static unsigned int const NumOfAvailRegs = 32;
static unsigned int const NumOfAllRegs = 64;
static unsigned int const StartOfNonVolatileRegs = f6;
static unsigned int const StartOfAllRegs = f0;
static const string getRegName(const unsigned reg) {
assert( reg < NumOfAllRegs );
return FloatRegNames[reg];
}
};
class SparcFloatRegClass : public MachineRegClassInfo
{
private:
int findFloatColor(const IGNode *const Node, unsigned Start,
unsigned End, bool IsColorUsedArr[] ) const;
public:
SparcFloatRegClass(unsigned ID)
: MachineRegClassInfo(ID,
SparcFloatRegOrder::NumOfAvailRegs,
SparcFloatRegOrder::NumOfAllRegs)
{ }
void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const;
};
//-----------------------------------------------------------------------------
// Int CC Register Class
// Only one integer cc register is available
//-----------------------------------------------------------------------------
class SparcIntCCRegClass : public MachineRegClassInfo
{
public:
SparcIntCCRegClass(unsigned ID)
: MachineRegClassInfo(ID,1, 1) { }
inline void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const {
Node->setColor(0); // only one int cc reg is available
}
};
//-----------------------------------------------------------------------------
// Float CC Register Class
// Only 4 Float CC registers are available
//-----------------------------------------------------------------------------
static string const FloatCCRegNames[] =
{
"fcc0", "fcc1", "fcc2", "fcc3"
};
class SparcFloatCCRegOrder{
public:
enum RegsInPrefOrder {
fcc0, fcc1, fcc2, fcc3
};
static const string getRegName(const unsigned reg) {
assert( reg < 4 );
return FloatCCRegNames[reg];
}
};
class SparcFloatCCRegClass : public MachineRegClassInfo
{
public:
SparcFloatCCRegClass(unsigned ID)
: MachineRegClassInfo(ID, 4, 4) { }
void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const {
int c;
for(c=0; c < 4 && IsColorUsedArr[c] ; ++c) ; // find color
assert( (c < 4) && "Can allocate only 4 float cc registers");
Node->setColor(c);
}
};
#endif

View File

@ -41,12 +41,22 @@ void FindUsedTypes::IncorporateType(const Type *Ty) {
IncorporateType(*I);
}
void FindUsedTypes::IncorporateSymbolTable(const SymbolTable &ST) {
SymbolTable::const_iterator TI = ST.find(Type::TypeTy);
if (TI == ST.end()) return; // No named types
for (SymbolTable::type_const_iterator I = TI->second.begin(),
E = TI->second.end(); I != E; ++I)
IncorporateType(cast<Type>(I->second));
}
// run - This incorporates all types used by the specified module
//
bool FindUsedTypes::run(Module &m) {
UsedTypes.clear(); // reset if run multiple times...
IncorporateSymbolTable(m.getSymbolTable());
// Loop over global variables, incorporating their types
for (Module::const_giterator I = m.gbegin(), E = m.gend(); I != E; ++I)
IncorporateType(I->getType());
@ -54,6 +64,7 @@ bool FindUsedTypes::run(Module &m) {
for (Module::iterator MI = m.begin(), ME = m.end(); MI != ME; ++MI) {
IncorporateType(MI->getType());
const Function &F = *MI;
IncorporateSymbolTable(F.getSymbolTable());
// Loop over all of the instructions in the function, adding their return
// type as well as the types of their operands.

File diff suppressed because it is too large Load Diff

View File

@ -1,332 +0,0 @@
//===-- InstrForest.cpp - Build instruction forest for inst selection -----===//
//
// 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.
//
//===----------------------------------------------------------------------===//
//
// The key goal is to group instructions into a single
// tree if one or more of them might be potentially combined into a single
// complex instruction in the target machine.
// Since this grouping is completely machine-independent, we do it as
// aggressive as possible to exploit any possible target instructions.
// In particular, we group two instructions O and I if:
// (1) Instruction O computes an operand used by instruction I,
// and (2) O and I are part of the same basic block,
// and (3) O has only a single use, viz., I.
//
//===----------------------------------------------------------------------===//
#include "llvm/Constant.h"
#include "llvm/Function.h"
#include "llvm/iTerminators.h"
#include "llvm/iMemory.h"
#include "llvm/Type.h"
#include "llvm/CodeGen/InstrForest.h"
#include "llvm/CodeGen/MachineCodeForInstruction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "Support/STLExtras.h"
#include "Config/alloca.h"
//------------------------------------------------------------------------
// class InstrTreeNode
//------------------------------------------------------------------------
void
InstrTreeNode::dump(int dumpChildren, int indent) const {
dumpNode(indent);
if (dumpChildren) {
if (LeftChild)
LeftChild->dump(dumpChildren, indent+1);
if (RightChild)
RightChild->dump(dumpChildren, indent+1);
}
}
InstructionNode::InstructionNode(Instruction* I)
: InstrTreeNode(NTInstructionNode, I), codeIsFoldedIntoParent(false)
{
opLabel = I->getOpcode();
// Distinguish special cases of some instructions such as Ret and Br
//
if (opLabel == Instruction::Ret && cast<ReturnInst>(I)->getReturnValue()) {
opLabel = RetValueOp; // ret(value) operation
}
else if (opLabel ==Instruction::Br && !cast<BranchInst>(I)->isUnconditional())
{
opLabel = BrCondOp; // br(cond) operation
} else if (opLabel >= Instruction::SetEQ && opLabel <= Instruction::SetGT) {
opLabel = SetCCOp; // common label for all SetCC ops
} else if (opLabel == Instruction::Alloca && I->getNumOperands() > 0) {
opLabel = AllocaN; // Alloca(ptr, N) operation
} else if (opLabel == Instruction::GetElementPtr &&
cast<GetElementPtrInst>(I)->hasIndices()) {
opLabel = opLabel + 100; // getElem with index vector
} else if (opLabel == Instruction::Xor &&
BinaryOperator::isNot(I)) {
opLabel = (I->getType() == Type::BoolTy)? NotOp // boolean Not operator
: BNotOp; // bitwise Not operator
} else if (opLabel == Instruction::And || opLabel == Instruction::Or ||
opLabel == Instruction::Xor) {
// Distinguish bitwise operators from logical operators!
if (I->getType() != Type::BoolTy)
opLabel = opLabel + 100; // bitwise operator
} else if (opLabel == Instruction::Cast) {
const Type *ITy = I->getType();
switch(ITy->getPrimitiveID())
{
case Type::BoolTyID: opLabel = ToBoolTy; break;
case Type::UByteTyID: opLabel = ToUByteTy; break;
case Type::SByteTyID: opLabel = ToSByteTy; break;
case Type::UShortTyID: opLabel = ToUShortTy; break;
case Type::ShortTyID: opLabel = ToShortTy; break;
case Type::UIntTyID: opLabel = ToUIntTy; break;
case Type::IntTyID: opLabel = ToIntTy; break;
case Type::ULongTyID: opLabel = ToULongTy; break;
case Type::LongTyID: opLabel = ToLongTy; break;
case Type::FloatTyID: opLabel = ToFloatTy; break;
case Type::DoubleTyID: opLabel = ToDoubleTy; break;
case Type::ArrayTyID: opLabel = ToArrayTy; break;
case Type::PointerTyID: opLabel = ToPointerTy; break;
default:
// Just use `Cast' opcode otherwise. It's probably ignored.
break;
}
}
}
void
InstructionNode::dumpNode(int indent) const {
for (int i=0; i < indent; i++)
std::cerr << " ";
std::cerr << getInstruction()->getOpcodeName()
<< " [label " << getOpLabel() << "]" << "\n";
}
void
VRegListNode::dumpNode(int indent) const {
for (int i=0; i < indent; i++)
std::cerr << " ";
std::cerr << "List" << "\n";
}
void
VRegNode::dumpNode(int indent) const {
for (int i=0; i < indent; i++)
std::cerr << " ";
std::cerr << "VReg " << getValue() << "\t(type "
<< (int) getValue()->getValueType() << ")" << "\n";
}
void
ConstantNode::dumpNode(int indent) const {
for (int i=0; i < indent; i++)
std::cerr << " ";
std::cerr << "Constant " << getValue() << "\t(type "
<< (int) getValue()->getValueType() << ")" << "\n";
}
void LabelNode::dumpNode(int indent) const {
for (int i=0; i < indent; i++)
std::cerr << " ";
std::cerr << "Label " << getValue() << "\n";
}
//------------------------------------------------------------------------
// class InstrForest
//
// A forest of instruction trees, usually for a single method.
//------------------------------------------------------------------------
InstrForest::InstrForest(Function *F) {
for (Function::iterator BB = F->begin(), FE = F->end(); BB != FE; ++BB) {
for(BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
buildTreeForInstruction(I);
}
}
InstrForest::~InstrForest() {
for_each(treeRoots.begin(), treeRoots.end(), deleter<InstructionNode>);
}
void InstrForest::dump() const {
for (const_root_iterator I = roots_begin(); I != roots_end(); ++I)
(*I)->dump(/*dumpChildren*/ 1, /*indent*/ 0);
}
inline void InstrForest::eraseRoot(InstructionNode* node) {
for (RootSet::reverse_iterator RI=treeRoots.rbegin(), RE=treeRoots.rend();
RI != RE; ++RI)
if (*RI == node)
treeRoots.erase(RI.base()-1);
}
inline void InstrForest::noteTreeNodeForInstr(Instruction *instr,
InstructionNode *treeNode) {
(*this)[instr] = treeNode;
treeRoots.push_back(treeNode); // mark node as root of a new tree
}
inline void InstrForest::setLeftChild(InstrTreeNode *parent,
InstrTreeNode *child) {
parent->LeftChild = child;
child->Parent = parent;
if (InstructionNode* instrNode = dyn_cast<InstructionNode>(child))
eraseRoot(instrNode); // no longer a tree root
}
inline void InstrForest::setRightChild(InstrTreeNode *parent,
InstrTreeNode *child) {
parent->RightChild = child;
child->Parent = parent;
if (InstructionNode* instrNode = dyn_cast<InstructionNode>(child))
eraseRoot(instrNode); // no longer a tree root
}
InstructionNode* InstrForest::buildTreeForInstruction(Instruction *instr) {
InstructionNode *treeNode = getTreeNodeForInstr(instr);
if (treeNode) {
// treeNode has already been constructed for this instruction
assert(treeNode->getInstruction() == instr);
return treeNode;
}
// Otherwise, create a new tree node for this instruction.
//
treeNode = new InstructionNode(instr);
noteTreeNodeForInstr(instr, treeNode);
if (instr->getOpcode() == Instruction::Call) {
// Operands of call instruction
return treeNode;
}
// If the instruction has more than 2 instruction operands,
// then we need to create artificial list nodes to hold them.
// (Note that we only count operands that get tree nodes, and not
// others such as branch labels for a branch or switch instruction.)
//
// To do this efficiently, we'll walk all operands, build treeNodes
// for all appropriate operands and save them in an array. We then
// insert children at the end, creating list nodes where needed.
// As a performance optimization, allocate a child array only
// if a fixed array is too small.
//
int numChildren = 0;
InstrTreeNode** childArray = new InstrTreeNode*[instr->getNumOperands()];
//
// Walk the operands of the instruction
//
for (Instruction::op_iterator O = instr->op_begin(); O!=instr->op_end(); ++O)
{
Value* operand = *O;
// Check if the operand is a data value, not an branch label, type,
// method or module. If the operand is an address type (i.e., label
// or method) that is used in an non-branching operation, e.g., `add'.
// that should be considered a data value.
// Check latter condition here just to simplify the next IF.
bool includeAddressOperand =
(isa<BasicBlock>(operand) || isa<Function>(operand))
&& !instr->isTerminator();
if (includeAddressOperand || isa<Instruction>(operand) ||
isa<Constant>(operand) || isa<Argument>(operand) ||
isa<GlobalVariable>(operand))
{
// This operand is a data value
// An instruction that computes the incoming value is added as a
// child of the current instruction if:
// the value has only a single use
// AND both instructions are in the same basic block.
// AND the current instruction is not a PHI (because the incoming
// value is conceptually in a predecessor block,
// even though it may be in the same static block)
//
// (Note that if the value has only a single use (viz., `instr'),
// the def of the value can be safely moved just before instr
// and therefore it is safe to combine these two instructions.)
//
// In all other cases, the virtual register holding the value
// is used directly, i.e., made a child of the instruction node.
//
InstrTreeNode* opTreeNode;
if (isa<Instruction>(operand) && operand->hasOneUse() &&
cast<Instruction>(operand)->getParent() == instr->getParent() &&
instr->getOpcode() != Instruction::PHI &&
instr->getOpcode() != Instruction::Call)
{
// Recursively create a treeNode for it.
opTreeNode = buildTreeForInstruction((Instruction*)operand);
} else if (Constant *CPV = dyn_cast<Constant>(operand)) {
// Create a leaf node for a constant
opTreeNode = new ConstantNode(CPV);
} else {
// Create a leaf node for the virtual register
opTreeNode = new VRegNode(operand);
}
childArray[numChildren++] = opTreeNode;
}
}
//--------------------------------------------------------------------
// Add any selected operands as children in the tree.
// Certain instructions can have more than 2 in some instances (viz.,
// a CALL or a memory access -- LOAD, STORE, and GetElemPtr -- to an
// array or struct). Make the operands of every such instruction into
// a right-leaning binary tree with the operand nodes at the leaves
// and VRegList nodes as internal nodes.
//--------------------------------------------------------------------
InstrTreeNode *parent = treeNode;
if (numChildren > 2) {
unsigned instrOpcode = treeNode->getInstruction()->getOpcode();
assert(instrOpcode == Instruction::PHI ||
instrOpcode == Instruction::Call ||
instrOpcode == Instruction::Load ||
instrOpcode == Instruction::Store ||
instrOpcode == Instruction::GetElementPtr);
}
// Insert the first child as a direct child
if (numChildren >= 1)
setLeftChild(parent, childArray[0]);
int n;
// Create a list node for children 2 .. N-1, if any
for (n = numChildren-1; n >= 2; n--) {
// We have more than two children
InstrTreeNode *listNode = new VRegListNode();
setRightChild(parent, listNode);
setLeftChild(listNode, childArray[numChildren - n]);
parent = listNode;
}
// Now insert the last remaining child (if any).
if (numChildren >= 2) {
assert(n == 1);
setRightChild(parent, childArray[numChildren - 1]);
}
delete [] childArray;
return treeNode;
}

View File

@ -1,385 +0,0 @@
//===- InstrSelection.cpp - Machine Independent Inst Selection Driver -----===//
//
// 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.
//
//===----------------------------------------------------------------------===//
//
// Machine-independent driver file for instruction selection. This file
// constructs a forest of BURG instruction trees and then uses the
// BURG-generated tree grammar (BURM) to find the optimal instruction sequences
// for a given machine.
//
//===----------------------------------------------------------------------===//
#include "llvm/Function.h"
#include "llvm/iPHINode.h"
#include "llvm/Pass.h"
#include "llvm/CodeGen/InstrForest.h"
#include "llvm/CodeGen/InstrSelection.h"
#include "llvm/CodeGen/InstrSelectionSupport.h"
#include "llvm/CodeGen/MachineCodeForInstruction.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegInfo.h"
#include "Support/CommandLine.h"
#include "Support/LeakDetector.h"
#include <vector>
std::vector<MachineInstr*>
FixConstantOperandsForInstr(Instruction* vmInstr, MachineInstr* minstr,
TargetMachine& target);
namespace {
//===--------------------------------------------------------------------===//
// SelectDebugLevel - Allow command line control over debugging.
//
enum SelectDebugLevel_t {
Select_NoDebugInfo,
Select_PrintMachineCode,
Select_DebugInstTrees,
Select_DebugBurgTrees,
};
// Enable Debug Options to be specified on the command line
cl::opt<SelectDebugLevel_t>
SelectDebugLevel("dselect", cl::Hidden,
cl::desc("enable instruction selection debug information"),
cl::values(
clEnumValN(Select_NoDebugInfo, "n", "disable debug output"),
clEnumValN(Select_PrintMachineCode, "y", "print generated machine code"),
clEnumValN(Select_DebugInstTrees, "i",
"print debugging info for instruction selection"),
clEnumValN(Select_DebugBurgTrees, "b", "print burg trees"),
0));
//===--------------------------------------------------------------------===//
// InstructionSelection Pass
//
// This is the actual pass object that drives the instruction selection
// process.
//
class InstructionSelection : public FunctionPass {
TargetMachine &Target;
void InsertCodeForPhis(Function &F);
void InsertPhiElimInstructions(BasicBlock *BB,
const std::vector<MachineInstr*>& CpVec);
void SelectInstructionsForTree(InstrTreeNode* treeRoot, int goalnt);
void PostprocessMachineCodeForTree(InstructionNode* instrNode,
int ruleForNode, short* nts);
public:
InstructionSelection(TargetMachine &T) : Target(T) {}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
}
bool runOnFunction(Function &F);
virtual const char *getPassName() const { return "Instruction Selection"; }
};
}
TmpInstruction::TmpInstruction(MachineCodeForInstruction& mcfi,
Value *s1, Value *s2, const std::string &name)
: Instruction(s1->getType(), Instruction::UserOp1, name)
{
mcfi.addTemp(this);
Operands.push_back(Use(s1, this)); // s1 must be non-null
if (s2)
Operands.push_back(Use(s2, this));
// TmpInstructions should not be garbage checked.
LeakDetector::removeGarbageObject(this);
}
// Constructor that requires the type of the temporary to be specified.
// Both S1 and S2 may be NULL.(
TmpInstruction::TmpInstruction(MachineCodeForInstruction& mcfi,
const Type *Ty, Value *s1, Value* s2,
const std::string &name)
: Instruction(Ty, Instruction::UserOp1, name)
{
mcfi.addTemp(this);
if (s1)
Operands.push_back(Use(s1, this));
if (s2)
Operands.push_back(Use(s2, this));
// TmpInstructions should not be garbage checked.
LeakDetector::removeGarbageObject(this);
}
bool InstructionSelection::runOnFunction(Function &F)
{
//
// Build the instruction trees to be given as inputs to BURG.
//
InstrForest instrForest(&F);
if (SelectDebugLevel >= Select_DebugInstTrees) {
std::cerr << "\n\n*** Input to instruction selection for function "
<< F.getName() << "\n\n" << F
<< "\n\n*** Instruction trees for function "
<< F.getName() << "\n\n";
instrForest.dump();
}
//
// Invoke BURG instruction selection for each tree
//
for (InstrForest::const_root_iterator RI = instrForest.roots_begin();
RI != instrForest.roots_end(); ++RI) {
InstructionNode* basicNode = *RI;
assert(basicNode->parent() == NULL && "A `root' node has a parent?");
// Invoke BURM to label each tree node with a state
burm_label(basicNode);
if (SelectDebugLevel >= Select_DebugBurgTrees) {
printcover(basicNode, 1, 0);
std::cerr << "\nCover cost == " << treecost(basicNode, 1, 0) <<"\n\n";
printMatches(basicNode);
}
// Then recursively walk the tree to select instructions
SelectInstructionsForTree(basicNode, /*goalnt*/1);
}
//
// Create the MachineBasicBlock records and add all of the MachineInstrs
// defined in the MachineCodeForInstruction objects to also live in the
// MachineBasicBlock objects.
//
MachineFunction &MF = MachineFunction::get(&F);
for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) {
MachineBasicBlock *MCBB = new MachineBasicBlock(BI);
MF.getBasicBlockList().push_back(MCBB);
for (BasicBlock::iterator II = BI->begin(); II != BI->end(); ++II) {
MachineCodeForInstruction &mvec = MachineCodeForInstruction::get(II);
MCBB->insert(MCBB->end(), mvec.begin(), mvec.end());
}
}
// Insert phi elimination code
InsertCodeForPhis(F);
if (SelectDebugLevel >= Select_PrintMachineCode) {
std::cerr << "\n*** Machine instructions after INSTRUCTION SELECTION\n";
MachineFunction::get(&F).dump();
}
return true;
}
//-------------------------------------------------------------------------
// This method inserts phi elimination code for all BBs in a method
//-------------------------------------------------------------------------
void
InstructionSelection::InsertCodeForPhis(Function &F) {
// for all basic blocks in function
//
MachineFunction &MF = MachineFunction::get(&F);
for (MachineFunction::iterator BB = MF.begin(); BB != MF.end(); ++BB) {
for (BasicBlock::const_iterator IIt = BB->getBasicBlock()->begin();
const PHINode *PN = dyn_cast<PHINode>(IIt); ++IIt) {
// FIXME: This is probably wrong...
Value *PhiCpRes = new PHINode(PN->getType(), "PhiCp:");
// The leak detector shouldn't track these nodes. They are not garbage,
// even though their parent field is never filled in.
//
LeakDetector::removeGarbageObject(PhiCpRes);
// for each incoming value of the phi, insert phi elimination
//
for (unsigned i = 0; i < PN->getNumIncomingValues(); ++i) {
// insert the copy instruction to the predecessor BB
std::vector<MachineInstr*> mvec, CpVec;
Target.getRegInfo().cpValue2Value(PN->getIncomingValue(i), PhiCpRes,
mvec);
for (std::vector<MachineInstr*>::iterator MI=mvec.begin();
MI != mvec.end(); ++MI) {
std::vector<MachineInstr*> CpVec2 =
FixConstantOperandsForInstr(const_cast<PHINode*>(PN), *MI, Target);
CpVec2.push_back(*MI);
CpVec.insert(CpVec.end(), CpVec2.begin(), CpVec2.end());
}
InsertPhiElimInstructions(PN->getIncomingBlock(i), CpVec);
}
std::vector<MachineInstr*> mvec;
Target.getRegInfo().cpValue2Value(PhiCpRes, const_cast<PHINode*>(PN),
mvec);
BB->insert(BB->begin(), mvec.begin(), mvec.end());
} // for each Phi Instr in BB
} // for all BBs in function
}
//-------------------------------------------------------------------------
// Thid method inserts a copy instruction to a predecessor BB as a result
// of phi elimination.
//-------------------------------------------------------------------------
void
InstructionSelection::InsertPhiElimInstructions(BasicBlock *BB,
const std::vector<MachineInstr*>& CpVec)
{
Instruction *TermInst = (Instruction*)BB->getTerminator();
MachineCodeForInstruction &MC4Term = MachineCodeForInstruction::get(TermInst);
MachineInstr *FirstMIOfTerm = MC4Term.front();
assert (FirstMIOfTerm && "No Machine Instrs for terminator");
MachineFunction &MF = MachineFunction::get(BB->getParent());
// FIXME: if PHI instructions existed in the machine code, this would be
// unnecessary.
MachineBasicBlock *MBB = 0;
for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
if (I->getBasicBlock() == BB) {
MBB = I;
break;
}
// find the position of first machine instruction generated by the
// terminator of this BB
MachineBasicBlock::iterator MCIt =
std::find(MBB->begin(), MBB->end(), FirstMIOfTerm);
assert(MCIt != MBB->end() && "Start inst of terminator not found");
// insert the copy instructions just before the first machine instruction
// generated for the terminator
MBB->insert(MCIt, CpVec.begin(), CpVec.end());
}
//---------------------------------------------------------------------------
// Function SelectInstructionsForTree
//
// Recursively walk the tree to select instructions.
// Do this top-down so that child instructions can exploit decisions
// made at the child instructions.
//
// E.g., if br(setle(reg,const)) decides the constant is 0 and uses
// a branch-on-integer-register instruction, then the setle node
// can use that information to avoid generating the SUBcc instruction.
//
// Note that this cannot be done bottom-up because setle must do this
// only if it is a child of the branch (otherwise, the result of setle
// may be used by multiple instructions).
//---------------------------------------------------------------------------
void
InstructionSelection::SelectInstructionsForTree(InstrTreeNode* treeRoot,
int goalnt)
{
// Get the rule that matches this node.
//
int ruleForNode = burm_rule(treeRoot->state, goalnt);
if (ruleForNode == 0) {
std::cerr << "Could not match instruction tree for instr selection\n";
abort();
}
// Get this rule's non-terminals and the corresponding child nodes (if any)
//
short *nts = burm_nts[ruleForNode];
// First, select instructions for the current node and rule.
// (If this is a list node, not an instruction, then skip this step).
// This function is specific to the target architecture.
//
if (treeRoot->opLabel != VRegListOp) {
std::vector<MachineInstr*> minstrVec;
InstructionNode* instrNode = (InstructionNode*)treeRoot;
assert(instrNode->getNodeType() == InstrTreeNode::NTInstructionNode);
GetInstructionsByRule(instrNode, ruleForNode, nts, Target, minstrVec);
MachineCodeForInstruction &mvec =
MachineCodeForInstruction::get(instrNode->getInstruction());
mvec.insert(mvec.end(), minstrVec.begin(), minstrVec.end());
}
// Then, recursively compile the child nodes, if any.
//
if (nts[0]) {
// i.e., there is at least one kid
InstrTreeNode* kids[2];
int currentRule = ruleForNode;
burm_kids(treeRoot, currentRule, kids);
// First skip over any chain rules so that we don't visit
// the current node again.
//
while (ThisIsAChainRule(currentRule)) {
currentRule = burm_rule(treeRoot->state, nts[0]);
nts = burm_nts[currentRule];
burm_kids(treeRoot, currentRule, kids);
}
// Now we have the first non-chain rule so we have found
// the actual child nodes. Recursively compile them.
//
for (unsigned i = 0; nts[i]; i++) {
assert(i < 2);
InstrTreeNode::InstrTreeNodeType nodeType = kids[i]->getNodeType();
if (nodeType == InstrTreeNode::NTVRegListNode ||
nodeType == InstrTreeNode::NTInstructionNode)
SelectInstructionsForTree(kids[i], nts[i]);
}
}
// Finally, do any post-processing on this node after its children
// have been translated
//
if (treeRoot->opLabel != VRegListOp)
PostprocessMachineCodeForTree((InstructionNode*)treeRoot, ruleForNode, nts);
}
//---------------------------------------------------------------------------
// Function PostprocessMachineCodeForTree
//
// Apply any final cleanups to machine code for the root of a subtree
// after selection for all its children has been completed.
//
void
InstructionSelection::PostprocessMachineCodeForTree(InstructionNode* instrNode,
int ruleForNode,
short* nts)
{
// Fix up any constant operands in the machine instructions to either
// use an immediate field or to load the constant into a register
// Walk backwards and use direct indexes to allow insertion before current
//
Instruction* vmInstr = instrNode->getInstruction();
MachineCodeForInstruction &mvec = MachineCodeForInstruction::get(vmInstr);
for (unsigned i = mvec.size(); i != 0; --i) {
std::vector<MachineInstr*> loadConstVec =
FixConstantOperandsForInstr(vmInstr, mvec[i-1], Target);
mvec.insert(mvec.begin()+i-1, loadConstVec.begin(), loadConstVec.end());
}
}
//===----------------------------------------------------------------------===//
// createInstructionSelectionPass - Public entrypoint for instruction selection
// and this file as a whole...
//
FunctionPass *createInstructionSelectionPass(TargetMachine &T) {
return new InstructionSelection(T);
}

View File

@ -1,259 +0,0 @@
//===-- InstrSelectionSupport.cpp -----------------------------------------===//
//
// 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 instruction selection code. See SparcInstrSelection.cpp
// for usage.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/InstrSelectionSupport.h"
#include "llvm/CodeGen/InstrSelection.h"
#include "llvm/CodeGen/MachineInstrAnnot.h"
#include "llvm/CodeGen/MachineCodeForInstruction.h"
#include "llvm/CodeGen/InstrForest.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Constants.h"
#include "llvm/BasicBlock.h"
#include "llvm/DerivedTypes.h"
#include "../../Target/Sparc/SparcInstrSelectionSupport.h" // FIXME!
// Generate code to load the constant into a TmpInstruction (virtual reg) and
// returns the virtual register.
//
static TmpInstruction*
InsertCodeToLoadConstant(Function *F,
Value* opValue,
Instruction* vmInstr,
std::vector<MachineInstr*>& loadConstVec,
TargetMachine& target)
{
// Create a tmp virtual register to hold the constant.
MachineCodeForInstruction &mcfi = MachineCodeForInstruction::get(vmInstr);
TmpInstruction* tmpReg = new TmpInstruction(mcfi, opValue);
target.getInstrInfo().CreateCodeToLoadConst(target, F, opValue, tmpReg,
loadConstVec, mcfi);
// Record the mapping from the tmp VM instruction to machine instruction.
// Do this for all machine instructions that were not mapped to any
// other temp values created by
// tmpReg->addMachineInstruction(loadConstVec.back());
return tmpReg;
}
MachineOperand::MachineOperandType
ChooseRegOrImmed(int64_t intValue,
bool isSigned,
MachineOpCode opCode,
const TargetMachine& target,
bool canUseImmed,
unsigned int& getMachineRegNum,
int64_t& getImmedValue)
{
MachineOperand::MachineOperandType opType=MachineOperand::MO_VirtualRegister;
getMachineRegNum = 0;
getImmedValue = 0;
if (canUseImmed &&
target.getInstrInfo().constantFitsInImmedField(opCode, intValue)) {
opType = isSigned? MachineOperand::MO_SignExtendedImmed
: MachineOperand::MO_UnextendedImmed;
getImmedValue = intValue;
} else if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0) {
opType = MachineOperand::MO_MachineRegister;
getMachineRegNum = target.getRegInfo().getZeroRegNum();
}
return opType;
}
MachineOperand::MachineOperandType
ChooseRegOrImmed(Value* val,
MachineOpCode opCode,
const TargetMachine& target,
bool canUseImmed,
unsigned int& getMachineRegNum,
int64_t& getImmedValue)
{
getMachineRegNum = 0;
getImmedValue = 0;
// To use reg or immed, constant needs to be integer, bool, or a NULL pointer
// TargetInstrInfo::ConvertConstantToIntType() does the right conversions:
bool isValidConstant;
uint64_t valueToUse =
target.getInstrInfo().ConvertConstantToIntType(target, val, val->getType(),
isValidConstant);
if (! isValidConstant)
return MachineOperand::MO_VirtualRegister;
// Now check if the constant value fits in the IMMED field.
//
return ChooseRegOrImmed((int64_t) valueToUse, val->getType()->isSigned(),
opCode, target, canUseImmed,
getMachineRegNum, getImmedValue);
}
//---------------------------------------------------------------------------
// Function: FixConstantOperandsForInstr
//
// Purpose:
// Special handling for constant operands of a machine instruction
// -- if the constant is 0, use the hardwired 0 register, if any;
// -- if the constant fits in the IMMEDIATE field, use that field;
// -- else create instructions to put the constant into a register, either
// directly or by loading explicitly from the constant pool.
//
// In the first 2 cases, the operand of `minstr' is modified in place.
// Returns a vector of machine instructions generated for operands that
// fall under case 3; these must be inserted before `minstr'.
//---------------------------------------------------------------------------
std::vector<MachineInstr*>
FixConstantOperandsForInstr(Instruction* vmInstr,
MachineInstr* minstr,
TargetMachine& target)
{
std::vector<MachineInstr*> MVec;
MachineOpCode opCode = minstr->getOpCode();
const TargetInstrInfo& instrInfo = target.getInstrInfo();
int resultPos = instrInfo.getResultPos(opCode);
int immedPos = instrInfo.getImmedConstantPos(opCode);
Function *F = vmInstr->getParent()->getParent();
for (unsigned op=0; op < minstr->getNumOperands(); op++)
{
const MachineOperand& mop = minstr->getOperand(op);
// Skip the result position, preallocated machine registers, or operands
// that cannot be constants (CC regs or PC-relative displacements)
if (resultPos == (int)op ||
mop.getType() == MachineOperand::MO_MachineRegister ||
mop.getType() == MachineOperand::MO_CCRegister ||
mop.getType() == MachineOperand::MO_PCRelativeDisp)
continue;
bool constantThatMustBeLoaded = false;
unsigned int machineRegNum = 0;
int64_t immedValue = 0;
Value* opValue = NULL;
MachineOperand::MachineOperandType opType =
MachineOperand::MO_VirtualRegister;
// Operand may be a virtual register or a compile-time constant
if (mop.getType() == MachineOperand::MO_VirtualRegister) {
assert(mop.getVRegValue() != NULL);
opValue = mop.getVRegValue();
if (Constant *opConst = dyn_cast<Constant>(opValue)) {
opType = ChooseRegOrImmed(opConst, opCode, target,
(immedPos == (int)op), machineRegNum,
immedValue);
if (opType == MachineOperand::MO_VirtualRegister)
constantThatMustBeLoaded = true;
}
} else {
assert(mop.isImmediate());
bool isSigned = mop.getType() == MachineOperand::MO_SignExtendedImmed;
// Bit-selection flags indicate an instruction that is extracting
// bits from its operand so ignore this even if it is a big constant.
if (mop.opHiBits32() || mop.opLoBits32() ||
mop.opHiBits64() || mop.opLoBits64())
continue;
opType = ChooseRegOrImmed(mop.getImmedValue(), isSigned,
opCode, target, (immedPos == (int)op),
machineRegNum, immedValue);
if (opType == MachineOperand::MO_SignExtendedImmed ||
opType == MachineOperand::MO_UnextendedImmed) {
// The optype is an immediate value
// This means we need to change the opcode, e.g. ADDr -> ADDi
unsigned newOpcode = convertOpcodeFromRegToImm(opCode);
minstr->setOpcode(newOpcode);
}
if (opType == mop.getType())
continue; // no change: this is the most common case
if (opType == MachineOperand::MO_VirtualRegister) {
constantThatMustBeLoaded = true;
opValue = isSigned
? (Value*)ConstantSInt::get(Type::LongTy, immedValue)
: (Value*)ConstantUInt::get(Type::ULongTy,(uint64_t)immedValue);
}
}
if (opType == MachineOperand::MO_MachineRegister)
minstr->SetMachineOperandReg(op, machineRegNum);
else if (opType == MachineOperand::MO_SignExtendedImmed ||
opType == MachineOperand::MO_UnextendedImmed) {
minstr->SetMachineOperandConst(op, opType, immedValue);
// The optype is or has become an immediate
// This means we need to change the opcode, e.g. ADDr -> ADDi
unsigned newOpcode = convertOpcodeFromRegToImm(opCode);
minstr->setOpcode(newOpcode);
} else if (constantThatMustBeLoaded ||
(opValue && isa<GlobalValue>(opValue)))
{ // opValue is a constant that must be explicitly loaded into a reg
assert(opValue);
TmpInstruction* tmpReg = InsertCodeToLoadConstant(F, opValue, vmInstr,
MVec, target);
minstr->SetMachineOperandVal(op, MachineOperand::MO_VirtualRegister,
tmpReg);
}
}
// Also, check for implicit operands used by the machine instruction
// (no need to check those defined since they cannot be constants).
// These include:
// -- arguments to a Call
// -- return value of a Return
// Any such operand that is a constant value needs to be fixed also.
// The current instructions with implicit refs (viz., Call and Return)
// have no immediate fields, so the constant always needs to be loaded
// into a register.
//
bool isCall = instrInfo.isCall(opCode);
unsigned lastCallArgNum = 0; // unused if not a call
CallArgsDescriptor* argDesc = NULL; // unused if not a call
if (isCall)
argDesc = CallArgsDescriptor::get(minstr);
for (unsigned i=0, N=minstr->getNumImplicitRefs(); i < N; ++i)
if (isa<Constant>(minstr->getImplicitRef(i)) ||
isa<GlobalValue>(minstr->getImplicitRef(i)))
{
Value* oldVal = minstr->getImplicitRef(i);
TmpInstruction* tmpReg =
InsertCodeToLoadConstant(F, oldVal, vmInstr, MVec, target);
minstr->setImplicitRef(i, tmpReg);
if (isCall) {
// find and replace the argument in the CallArgsDescriptor
unsigned i=lastCallArgNum;
while (argDesc->getArgInfo(i).getArgVal() != oldVal)
++i;
assert(i < argDesc->getNumArgs() &&
"Constant operands to a call *must* be in the arg list");
lastCallArgNum = i;
argDesc->getArgInfo(i).replaceArgVal(tmpReg);
}
}
return MVec;
}

View File

@ -1,15 +0,0 @@
##===- lib/CodeGen/InstrSelection/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 = ../../..
DIRS =
LIBRARYNAME = select
include $(LEVEL)/Makefile.common

View File

@ -1,58 +0,0 @@
//===-- IGNode.cpp --------------------------------------------------------===//
//
// 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 implements an Interference graph node for coloring-based register
// allocation.
//
//===----------------------------------------------------------------------===//
#include "IGNode.h"
#include <algorithm>
#include <iostream>
//-----------------------------------------------------------------------------
// Sets this IGNode on stack and reduce the degree of neighbors
//-----------------------------------------------------------------------------
void IGNode::pushOnStack() {
OnStack = true;
int neighs = AdjList.size();
if (neighs < 0) {
std::cerr << "\nAdj List size = " << neighs;
assert(0 && "Invalid adj list size");
}
for (int i=0; i < neighs; i++)
AdjList[i]->decCurDegree();
}
//-----------------------------------------------------------------------------
// Deletes an adjacency node. IGNodes are deleted when coalescing merges
// two IGNodes together.
//-----------------------------------------------------------------------------
void IGNode::delAdjIGNode(const IGNode *Node) {
std::vector<IGNode *>::iterator It=find(AdjList.begin(), AdjList.end(), Node);
assert(It != AdjList.end() && "The node must be there!");
AdjList.erase(It);
}
//-----------------------------------------------------------------------------
// Get the number of unique neighbors if these two nodes are merged
//-----------------------------------------------------------------------------
unsigned
IGNode::getCombinedDegree(const IGNode* otherNode) const {
std::vector<IGNode*> nbrs(AdjList);
nbrs.insert(nbrs.end(), otherNode->AdjList.begin(), otherNode->AdjList.end());
sort(nbrs.begin(), nbrs.end());
std::vector<IGNode*>::iterator new_end = unique(nbrs.begin(), nbrs.end());
return new_end - nbrs.begin();
}

View File

@ -1,118 +0,0 @@
//===-- IGNode.h - Represent a node in an interference graph ----*- 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 represents a node in an interference graph.
//
// For efficiency, the AdjList is updated only once - ie. we can add but not
// remove nodes from AdjList.
//
// The removal of nodes from IG is simulated by decrementing the CurDegree.
// If this node is put on stack (that is removed from IG), the CurDegree of all
// the neighbors are decremented and this node is marked OnStack. Hence
// the effective neighbors in the AdjList are the ones that do not have the
// OnStack flag set (therefore, they are in the IG).
//
// The methods that modify/use the CurDegree must be called only
// after all modifications to the IG are over (i.e., all neighbors are fixed).
//
// The vector representation is the most efficient one for adj list.
// Though nodes are removed when coalescing is done, we access it in sequence
// for far many times when coloring (colorNode()).
//
//===----------------------------------------------------------------------===//
#ifndef IGNODE_H
#define IGNODE_H
#include "LiveRange.h"
#include <vector>
class RegClass;
//----------------------------------------------------------------------------
// Class IGNode
//
// Represents a node in an interference graph.
//----------------------------------------------------------------------------
class IGNode {
const unsigned Index; // index within IGNodeList
bool OnStack; // this has been pushed on to stack for coloring
std::vector<IGNode *> AdjList;// adjacency list for this live range
int CurDegree;
//
// set by InterferenceGraph::setCurDegreeOfIGNodes() after calculating
// all adjacency lists.
// Decremented when a neighbor is pushed on to the stack.
// After that, never incremented/set again nor used.
LiveRange *const ParentLR;
public:
IGNode(LiveRange *LR, unsigned index) : Index(index), ParentLR(LR) {
OnStack = false;
CurDegree = -1;
ParentLR->setUserIGNode(this);
}
inline unsigned int getIndex() const { return Index; }
// adjLists must be updated only once. However, the CurDegree can be changed
//
inline void addAdjIGNode(IGNode *AdjNode) { AdjList.push_back(AdjNode); }
inline IGNode *getAdjIGNode(unsigned ind) const
{ assert ( ind < AdjList.size()); return AdjList[ind]; }
// delete a node in AdjList - node must be in the list
// should not be called often
//
void delAdjIGNode(const IGNode *Node);
inline unsigned getNumOfNeighbors() const { return AdjList.size(); }
// Get the number of unique neighbors if these two nodes are merged
unsigned getCombinedDegree(const IGNode* otherNode) const;
inline bool isOnStack() const { return OnStack; }
// remove form IG and pushes on to stack (reduce the degree of neighbors)
//
void pushOnStack();
// CurDegree is the effective number of neighbors when neighbors are
// pushed on to the stack during the coloring phase. Must be called
// after all modifications to the IG are over (i.e., all neighbors are
// fixed).
//
inline void setCurDegree() {
assert(CurDegree == -1);
CurDegree = AdjList.size();
}
inline int getCurDegree() const { return CurDegree; }
// called when a neigh is pushed on to stack
//
inline void decCurDegree() { assert(CurDegree > 0); --CurDegree; }
// The following methods call the methods in ParentLR
// They are added to this class for convenience
// If many of these are called within a single scope,
// consider calling the methods directly on LR
inline bool hasColor() const { return ParentLR->hasColor(); }
inline unsigned int getColor() const { return ParentLR->getColor(); }
inline void setColor(unsigned Col) { ParentLR->setColor(Col); }
inline LiveRange *getParentLR() const { return ParentLR; }
};
#endif

View File

@ -1,248 +0,0 @@
//===-- InterferenceGraph.cpp ---------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
//
// Interference graph for coloring-based register allocation for LLVM.
//
//===----------------------------------------------------------------------===//
#include "IGNode.h"
#include "InterferenceGraph.h"
#include "RegAllocCommon.h"
#include "Support/STLExtras.h"
#include <algorithm>
// for asserting this IG node is infact in the IGNodeList of this class
inline static void assertIGNode(const InterferenceGraph *IG,
const IGNode *Node) {
assert(IG->getIGNodeList()[Node->getIndex()] == Node);
}
//-----------------------------------------------------------------------------
// Constructor: Records the RegClass and initalizes IGNodeList.
// The matrix is NOT yet created by the constructor. Call createGraph()
// to create it after adding all IGNodes to the IGNodeList.
//-----------------------------------------------------------------------------
InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC) {
IG = NULL;
Size = 0;
if( DEBUG_RA >= RA_DEBUG_Interference)
std::cerr << "Interference graph created!\n";
}
//-----------------------------------------------------------------------------
// destructor. Deletes the bit matrix and all IGNodes
//-----------------------------------------------------------------------------
InterferenceGraph:: ~InterferenceGraph() {
// delete the matrix
for(unsigned int r=0; r < IGNodeList.size(); ++r)
delete[] IG[r];
delete[] IG;
// delete all IGNodes in the IGNodeList
for_each(IGNodeList.begin(), IGNodeList.end(), deleter<IGNode>);
}
//-----------------------------------------------------------------------------
// Creates (dynamically allocates) the bit matrix necessary to hold the
// interference graph.
//-----------------------------------------------------------------------------
void InterferenceGraph::createGraph()
{
Size = IGNodeList.size();
IG = new char*[Size];
for( unsigned int r=0; r < Size; ++r)
IG[r] = new char[Size];
// init IG matrix
for(unsigned int i=0; i < Size; i++)
for(unsigned int j=0; j < Size; j++)
IG[i][j] = 0;
}
//-----------------------------------------------------------------------------
// creates a new IGNode for the given live range and add to IG
//-----------------------------------------------------------------------------
void InterferenceGraph::addLRToIG(LiveRange *const LR)
{
IGNodeList.push_back(new IGNode(LR, IGNodeList.size()));
}
//-----------------------------------------------------------------------------
// set interference for two live ranges
// update both the matrix and AdjLists of nodes.
// If there is already an interference between LR1 and LR2, adj lists
// are not updated. LR1 and LR2 must be distinct since if not, it suggests
// that there is some wrong logic in some other method.
//-----------------------------------------------------------------------------
void InterferenceGraph::setInterference(const LiveRange *const LR1,
const LiveRange *const LR2 ) {
assert(LR1 != LR2);
IGNode *IGNode1 = LR1->getUserIGNode();
IGNode *IGNode2 = LR2->getUserIGNode();
assertIGNode(this, IGNode1);
assertIGNode(this, IGNode2);
unsigned row = IGNode1->getIndex();
unsigned col = IGNode2->getIndex();
char *val;
if( DEBUG_RA >= RA_DEBUG_Interference)
std::cerr << "setting intf for: [" << row << "][" << col << "]\n";
( row > col) ? val = &IG[row][col]: val = &IG[col][row];
if( ! (*val) ) { // if this interf is not previously set
*val = 1; // add edges between nodes
IGNode1->addAdjIGNode( IGNode2 );
IGNode2->addAdjIGNode( IGNode1 );
}
}
//----------------------------------------------------------------------------
// return whether two live ranges interfere
//----------------------------------------------------------------------------
unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
const LiveRange *const LR2) const {
assert(LR1 != LR2);
assertIGNode(this, LR1->getUserIGNode());
assertIGNode(this, LR2->getUserIGNode());
const unsigned int row = LR1->getUserIGNode()->getIndex();
const unsigned int col = LR2->getUserIGNode()->getIndex();
char ret;
if (row > col)
ret = IG[row][col];
else
ret = IG[col][row];
return ret;
}
//----------------------------------------------------------------------------
// Merge 2 IGNodes. The neighbors of the SrcNode will be added to the DestNode.
// Then the IGNode2L will be deleted. Necessary for coalescing.
// IMPORTANT: The live ranges are NOT merged by this method. Use
// LiveRangeInfo::unionAndUpdateLRs for that purpose.
//----------------------------------------------------------------------------
void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *LR1,
LiveRange *LR2) {
assert( LR1 != LR2); // cannot merge the same live range
IGNode *const DestNode = LR1->getUserIGNode();
IGNode *SrcNode = LR2->getUserIGNode();
assertIGNode(this, DestNode);
assertIGNode(this, SrcNode);
if( DEBUG_RA >= RA_DEBUG_Interference) {
std::cerr << "Merging LRs: \""; printSet(*LR1);
std::cerr << "\" and \""; printSet(*LR2);
std::cerr << "\"\n";
}
unsigned SrcDegree = SrcNode->getNumOfNeighbors();
const unsigned SrcInd = SrcNode->getIndex();
// for all neighs of SrcNode
for(unsigned i=0; i < SrcDegree; i++) {
IGNode *NeighNode = SrcNode->getAdjIGNode(i);
LiveRange *const LROfNeigh = NeighNode->getParentLR();
// delete edge between src and neigh - even neigh == dest
NeighNode->delAdjIGNode(SrcNode);
// set the matrix posn to 0 betn src and neigh - even neigh == dest
const unsigned NInd = NeighNode->getIndex();
( SrcInd > NInd) ? (IG[SrcInd][NInd]=0) : (IG[NInd][SrcInd]=0) ;
if( LR1 != LROfNeigh) { // if the neigh != dest
// add edge betwn Dest and Neigh - if there is no current edge
setInterference(LR1, LROfNeigh );
}
}
IGNodeList[ SrcInd ] = NULL;
// SrcNode is no longer necessary - LR2 must be deleted by the caller
delete( SrcNode );
}
//----------------------------------------------------------------------------
// must be called after modifications to the graph are over but before
// pushing IGNodes on to the stack for coloring.
//----------------------------------------------------------------------------
void InterferenceGraph::setCurDegreeOfIGNodes()
{
unsigned Size = IGNodeList.size();
for( unsigned i=0; i < Size; i++) {
IGNode *Node = IGNodeList[i];
if( Node )
Node->setCurDegree();
}
}
//--------------------- debugging (Printing) methods -----------------------
//----------------------------------------------------------------------------
// Print the IGnodes
//----------------------------------------------------------------------------
void InterferenceGraph::printIG() const {
for(unsigned i=0; i < Size; i++) {
const IGNode *const Node = IGNodeList[i];
if(Node) {
std::cerr << " [" << i << "] ";
for( unsigned int j=0; j < Size; j++)
if(IG[i][j])
std::cerr << "(" << i << "," << j << ") ";
std::cerr << "\n";
}
}
}
//----------------------------------------------------------------------------
// Print the IGnodes in the IGNode List
//----------------------------------------------------------------------------
void InterferenceGraph::printIGNodeList() const {
for(unsigned i=0; i < IGNodeList.size() ; ++i) {
const IGNode *const Node = IGNodeList[i];
if (Node) {
std::cerr << " [" << Node->getIndex() << "] ";
printSet(*Node->getParentLR());
//int Deg = Node->getCurDegree();
std::cerr << "\t <# of Neighs: " << Node->getNumOfNeighbors() << ">\n";
}
}
}

View File

@ -1,70 +0,0 @@
//===-- InterferenceGraph.h - Interference graph for register coloring -*- 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.
//
//===----------------------------------------------------------------------===//
/* Title: InterferenceGraph.h -*- C++ -*-
Author: Ruchira Sasanka
Date: July 20, 01
Purpose: Interference Graph used for register coloring.
Notes:
Adj Info is stored in the lower trangular matrix (i.e., row > col )
This class must be used in the following way:
* Construct class
* call addLRToIG as many times to add ALL LRs to this IG
* call createGraph to create the actual matrix
* Then setInterference, getInterference, mergeIGNodesOfLRs can be
called as desired to modify the graph.
* Once the modifications to the graph are over, call
setCurDegreeOfIGNodes() before pushing IGNodes on to stack for coloring.
*/
#ifndef INTERFERENCEGRAPH_H
#define INTERFERENCEGRAPH_H
#include <vector>
class LiveRange;
class RegClass;
class IGNode;
class InterferenceGraph {
char **IG; // a poiner to the interference graph
unsigned int Size; // size of a side of the IG
RegClass *const RegCl; // RegCl contains this IG
std::vector<IGNode *> IGNodeList; // a list of all IGNodes in a reg class
public:
// the matrix is not yet created by the constructor. Call createGraph()
// to create it after adding all IGNodes to the IGNodeList
InterferenceGraph(RegClass *RC);
~InterferenceGraph();
void createGraph();
void addLRToIG(LiveRange *LR);
void setInterference(const LiveRange *LR1,
const LiveRange *LR2);
unsigned getInterference(const LiveRange *LR1,
const LiveRange *LR2) const ;
void mergeIGNodesOfLRs(const LiveRange *LR1, LiveRange *LR2);
std::vector<IGNode *> &getIGNodeList() { return IGNodeList; }
const std::vector<IGNode *> &getIGNodeList() const { return IGNodeList; }
void setCurDegreeOfIGNodes();
void printIG() const;
void printIGNodeList() const;
};
#endif

View File

@ -1,180 +0,0 @@
//===-- LiveRange.h - Store info about a live range -------------*- 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.
//
//===----------------------------------------------------------------------===//
//
// Implements a live range using a ValueSet. A LiveRange is a simple set
// of Values.
//
// Since the Value pointed by a use is the same as of its def, it is sufficient
// to keep only defs in a LiveRange.
//
//===----------------------------------------------------------------------===//
#ifndef LIVERANGE_H
#define LIVERANGE_H
#include "llvm/Value.h"
#include "llvm/CodeGen/ValueSet.h"
class RegClass;
class IGNode;
class LiveRange : public ValueSet {
RegClass *MyRegClass; // register class (e.g., int, FP) for this LR
/// doesSpanAcrossCalls - Does this live range span across calls?
/// This information is used by graph coloring algo to avoid allocating
/// volatile colors to live ranges that span across calls (since they have to
/// be saved/restored)
///
bool doesSpanAcrossCalls;
IGNode *UserIGNode; // IGNode which uses this LR
int Color; // color assigned to this live range
bool mustSpill; // whether this LR must be spilt
/// mustSaveAcrossCalls - whether this LR must be saved accross calls
/// ***TODO REMOVE this
///
bool mustSaveAcrossCalls;
/// SuggestedColor - if this LR has a suggested color, can it be
/// really alloated? A suggested color cannot be allocated when the
/// suggested color is volatile and when there are call
/// interferences.
///
int SuggestedColor; // The suggested color for this LR
/// CanUseSuggestedCol - It is possible that a suggested color for
/// this live range is not available before graph coloring (e.g., it
/// can be allocated to another live range which interferes with
/// this)
///
bool CanUseSuggestedCol;
/// SpilledStackOffsetFromFP - If this LR is spilled, its stack
/// offset from *FP*. The spilled offsets must always be relative to
/// the FP.
///
int SpilledStackOffsetFromFP;
/// HasSpillOffset 0 Whether this live range has a spill offset
///
bool HasSpillOffset;
/// The spill cost of this live range. Calculated using loop depth of
/// each reference to each Value in the live range
///
unsigned SpillCost;
public:
LiveRange() {
Color = SuggestedColor = -1; // not yet colored
mustSpill = mustSaveAcrossCalls = false;
MyRegClass = 0;
UserIGNode = 0;
doesSpanAcrossCalls = false;
CanUseSuggestedCol = true;
HasSpillOffset = false;
SpillCost = 0;
}
void setRegClass(RegClass *RC) { MyRegClass = RC; }
RegClass *getRegClass() const { assert(MyRegClass); return MyRegClass; }
unsigned getRegClassID() const;
bool hasColor() const { return Color != -1; }
unsigned getColor() const { assert(Color != -1); return (unsigned)Color; }
void setColor(unsigned Col) { Color = (int)Col; }
inline void setCallInterference() {
doesSpanAcrossCalls = 1;
}
inline void clearCallInterference() {
doesSpanAcrossCalls = 0;
}
inline bool isCallInterference() const {
return doesSpanAcrossCalls == 1;
}
inline void markForSpill() { mustSpill = true; }
inline bool isMarkedForSpill() const { return mustSpill; }
inline void setSpillOffFromFP(int StackOffset) {
assert(mustSpill && "This LR is not spilled");
SpilledStackOffsetFromFP = StackOffset;
HasSpillOffset = true;
}
inline void modifySpillOffFromFP(int StackOffset) {
assert(mustSpill && "This LR is not spilled");
SpilledStackOffsetFromFP = StackOffset;
HasSpillOffset = true;
}
inline bool hasSpillOffset() const {
return HasSpillOffset;
}
inline int getSpillOffFromFP() const {
assert(HasSpillOffset && "This LR is not spilled");
return SpilledStackOffsetFromFP;
}
inline void markForSaveAcrossCalls() { mustSaveAcrossCalls = true; }
inline void setUserIGNode(IGNode *IGN) {
assert(!UserIGNode); UserIGNode = IGN;
}
// getUserIGNode - NULL if the user is not allocated
inline IGNode *getUserIGNode() const { return UserIGNode; }
inline const Type *getType() const {
return (*begin())->getType(); // set's don't have a front
}
inline void setSuggestedColor(int Col) {
if (SuggestedColor == -1)
SuggestedColor = Col;
}
inline unsigned getSuggestedColor() const {
assert(SuggestedColor != -1); // only a valid color is obtained
return (unsigned)SuggestedColor;
}
inline bool hasSuggestedColor() const {
return SuggestedColor != -1;
}
inline bool isSuggestedColorUsable() const {
assert(hasSuggestedColor() && "No suggested color");
return CanUseSuggestedCol;
}
inline void setSuggestedColorUsable(bool val) {
assert(hasSuggestedColor() && "No suggested color");
CanUseSuggestedCol = val;
}
inline void addSpillCost(unsigned cost) {
SpillCost += cost;
}
inline unsigned getSpillCost() const {
return SpillCost;
}
};
#endif

View File

@ -1,413 +0,0 @@
//===-- LiveRangeInfo.cpp -------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
//
// Live range construction for coloring-based register allocation for LLVM.
//
//===----------------------------------------------------------------------===//
#include "IGNode.h"
#include "LiveRangeInfo.h"
#include "RegAllocCommon.h"
#include "RegClass.h"
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetRegInfo.h"
#include "Support/SetOperations.h"
unsigned LiveRange::getRegClassID() const { return getRegClass()->getID(); }
LiveRangeInfo::LiveRangeInfo(const Function *F, const TargetMachine &tm,
std::vector<RegClass *> &RCL)
: Meth(F), TM(tm), RegClassList(RCL), MRI(tm.getRegInfo()) { }
LiveRangeInfo::~LiveRangeInfo() {
for (LiveRangeMapType::iterator MI = LiveRangeMap.begin();
MI != LiveRangeMap.end(); ++MI) {
if (MI->first && MI->second) {
LiveRange *LR = MI->second;
// we need to be careful in deleting LiveRanges in LiveRangeMap
// since two/more Values in the live range map can point to the same
// live range. We have to make the other entries NULL when we delete
// a live range.
for (LiveRange::iterator LI = LR->begin(); LI != LR->end(); ++LI)
LiveRangeMap[*LI] = 0;
delete LR;
}
}
}
//---------------------------------------------------------------------------
// union two live ranges into one. The 2nd LR is deleted. Used for coalescing.
// Note: the caller must make sure that L1 and L2 are distinct and both
// LRs don't have suggested colors
//---------------------------------------------------------------------------
void LiveRangeInfo::unionAndUpdateLRs(LiveRange *L1, LiveRange *L2) {
assert(L1 != L2 && (!L1->hasSuggestedColor() || !L2->hasSuggestedColor()));
assert(! (L1->hasColor() && L2->hasColor()) ||
L1->getColor() == L2->getColor());
set_union(*L1, *L2); // add elements of L2 to L1
for(ValueSet::iterator L2It = L2->begin(); L2It != L2->end(); ++L2It) {
//assert(( L1->getTypeID() == L2->getTypeID()) && "Merge:Different types");
L1->insert(*L2It); // add the var in L2 to L1
LiveRangeMap[*L2It] = L1; // now the elements in L2 should map
//to L1
}
// set call interference for L1 from L2
if (L2->isCallInterference())
L1->setCallInterference();
// add the spill costs
L1->addSpillCost(L2->getSpillCost());
// If L2 has a color, give L1 that color. Note that L1 may have had the same
// color or none, but would not have a different color as asserted above.
if (L2->hasColor())
L1->setColor(L2->getColor());
// Similarly, if LROfUse(L2) has a suggested color, the new range
// must have the same color.
if (L2->hasSuggestedColor())
L1->setSuggestedColor(L2->getSuggestedColor());
delete L2; // delete L2 as it is no longer needed
}
//---------------------------------------------------------------------------
// Method for creating a single live range for a definition.
// The definition must be represented by a virtual register (a Value).
// Note: this function does *not* check that no live range exists for def.
//---------------------------------------------------------------------------
LiveRange*
LiveRangeInfo::createNewLiveRange(const Value* Def, bool isCC /* = false*/)
{
LiveRange* DefRange = new LiveRange(); // Create a new live range,
DefRange->insert(Def); // add Def to it,
LiveRangeMap[Def] = DefRange; // and update the map.
// set the register class of the new live range
DefRange->setRegClass(RegClassList[MRI.getRegClassIDOfType(Def->getType(),
isCC)]);
if (DEBUG_RA >= RA_DEBUG_LiveRanges) {
std::cerr << " Creating a LR for def ";
if (isCC) std::cerr << " (CC Register!)";
std::cerr << " : " << RAV(Def) << "\n";
}
return DefRange;
}
LiveRange*
LiveRangeInfo::createOrAddToLiveRange(const Value* Def, bool isCC /* = false*/)
{
LiveRange *DefRange = LiveRangeMap[Def];
// check if the LR is already there (because of multiple defs)
if (!DefRange) {
DefRange = createNewLiveRange(Def, isCC);
} else { // live range already exists
DefRange->insert(Def); // add the operand to the range
LiveRangeMap[Def] = DefRange; // make operand point to merged set
if (DEBUG_RA >= RA_DEBUG_LiveRanges)
std::cerr << " Added to existing LR for def: " << RAV(Def) << "\n";
}
return DefRange;
}
//---------------------------------------------------------------------------
// Method for constructing all live ranges in a function. It creates live
// ranges for all values defined in the instruction stream. Also, it
// creates live ranges for all incoming arguments of the function.
//---------------------------------------------------------------------------
void LiveRangeInfo::constructLiveRanges() {
if (DEBUG_RA >= RA_DEBUG_LiveRanges)
std::cerr << "Constructing Live Ranges ...\n";
// first find the live ranges for all incoming args of the function since
// those LRs start from the start of the function
for (Function::const_aiterator AI = Meth->abegin(); AI != Meth->aend(); ++AI)
createNewLiveRange(AI, /*isCC*/ false);
// Now suggest hardware registers for these function args
MRI.suggestRegs4MethodArgs(Meth, *this);
// Now create LRs for machine instructions. A new LR will be created
// only for defs in the machine instr since, we assume that all Values are
// defined before they are used. However, there can be multiple defs for
// the same Value in machine instructions.
//
// Also, find CALL and RETURN instructions, which need extra work.
//
MachineFunction &MF = MachineFunction::get(Meth);
for (MachineFunction::iterator BBI = MF.begin(); BBI != MF.end(); ++BBI) {
MachineBasicBlock &MBB = *BBI;
// iterate over all the machine instructions in BB
for(MachineBasicBlock::iterator MInstIterator = MBB.begin();
MInstIterator != MBB.end(); ++MInstIterator) {
MachineInstr *MInst = *MInstIterator;
// If the machine instruction is a call/return instruction, add it to
// CallRetInstrList for processing its args, ret value, and ret addr.
//
if(TM.getInstrInfo().isReturn(MInst->getOpCode()) ||
TM.getInstrInfo().isCall(MInst->getOpCode()))
CallRetInstrList.push_back(MInst);
// iterate over explicit MI operands and create a new LR
// for each operand that is defined by the instruction
for (MachineInstr::val_op_iterator OpI = MInst->begin(),
OpE = MInst->end(); OpI != OpE; ++OpI)
if (OpI.isDefOnly() || OpI.isDefAndUse()) {
const Value *Def = *OpI;
bool isCC = (OpI.getMachineOperand().getType()
== MachineOperand::MO_CCRegister);
LiveRange* LR = createOrAddToLiveRange(Def, isCC);
// If the operand has a pre-assigned register,
// set it directly in the LiveRange
if (OpI.getMachineOperand().hasAllocatedReg()) {
unsigned getClassId;
LR->setColor(MRI.getClassRegNum(
OpI.getMachineOperand().getAllocatedRegNum(),
getClassId));
}
}
// iterate over implicit MI operands and create a new LR
// for each operand that is defined by the instruction
for (unsigned i = 0; i < MInst->getNumImplicitRefs(); ++i)
if (MInst->getImplicitOp(i).opIsDefOnly() ||
MInst->getImplicitOp(i).opIsDefAndUse()) {
const Value *Def = MInst->getImplicitRef(i);
LiveRange* LR = createOrAddToLiveRange(Def, /*isCC*/ false);
// If the implicit operand has a pre-assigned register,
// set it directly in the LiveRange
if (MInst->getImplicitOp(i).hasAllocatedReg()) {
unsigned getClassId;
LR->setColor(MRI.getClassRegNum(
MInst->getImplicitOp(i).getAllocatedRegNum(),
getClassId));
}
}
} // for all machine instructions in the BB
} // for all BBs in function
// Now we have to suggest clors for call and return arg live ranges.
// Also, if there are implicit defs (e.g., retun value of a call inst)
// they must be added to the live range list
//
suggestRegs4CallRets();
if( DEBUG_RA >= RA_DEBUG_LiveRanges)
std::cerr << "Initial Live Ranges constructed!\n";
}
//---------------------------------------------------------------------------
// If some live ranges must be colored with specific hardware registers
// (e.g., for outgoing call args), suggesting of colors for such live
// ranges is done using target specific function. Those functions are called
// from this function. The target specific methods must:
// 1) suggest colors for call and return args.
// 2) create new LRs for implicit defs in machine instructions
//---------------------------------------------------------------------------
void LiveRangeInfo::suggestRegs4CallRets() {
std::vector<MachineInstr*>::iterator It = CallRetInstrList.begin();
for( ; It != CallRetInstrList.end(); ++It) {
MachineInstr *MInst = *It;
MachineOpCode OpCode = MInst->getOpCode();
if ((TM.getInstrInfo()).isReturn(OpCode))
MRI.suggestReg4RetValue(MInst, *this);
else if ((TM.getInstrInfo()).isCall(OpCode))
MRI.suggestRegs4CallArgs(MInst, *this);
else
assert( 0 && "Non call/ret instr in CallRetInstrList" );
}
}
//--------------------------------------------------------------------------
// The following method coalesces live ranges when possible. This method
// must be called after the interference graph has been constructed.
/* Algorithm:
for each BB in function
for each machine instruction (inst)
for each definition (def) in inst
for each operand (op) of inst that is a use
if the def and op are of the same register type
if the def and op do not interfere //i.e., not simultaneously live
if (degree(LR of def) + degree(LR of op)) <= # avail regs
if both LRs do not have suggested colors
merge2IGNodes(def, op) // i.e., merge 2 LRs
*/
//---------------------------------------------------------------------------
// Checks if live range LR interferes with any node assigned or suggested to
// be assigned the specified color
//
inline bool InterferesWithColor(const LiveRange& LR, unsigned color) {
IGNode* lrNode = LR.getUserIGNode();
for (unsigned n=0, NN = lrNode->getNumOfNeighbors(); n < NN; n++) {
LiveRange *neighLR = lrNode->getAdjIGNode(n)->getParentLR();
if (neighLR->hasColor() && neighLR->getColor() == color)
return true;
if (neighLR->hasSuggestedColor() && neighLR->getSuggestedColor() == color)
return true;
}
return false;
}
// Cannot coalesce if any of the following is true:
// (1) Both LRs have suggested colors (should be "different suggested colors"?)
// (2) Both LR1 and LR2 have colors and the colors are different
// (but if the colors are the same, it is definitely safe to coalesce)
// (3) LR1 has color and LR2 interferes with any LR that has the same color
// (4) LR2 has color and LR1 interferes with any LR that has the same color
//
inline bool InterfsPreventCoalescing(const LiveRange& LROfDef,
const LiveRange& LROfUse) {
// (4) if they have different suggested colors, cannot coalesce
if (LROfDef.hasSuggestedColor() && LROfUse.hasSuggestedColor())
return true;
// if neither has a color, nothing more to do.
if (! LROfDef.hasColor() && ! LROfUse.hasColor())
return false;
// (2, 3) if L1 has color...
if (LROfDef.hasColor()) {
if (LROfUse.hasColor())
return (LROfUse.getColor() != LROfDef.getColor());
return InterferesWithColor(LROfUse, LROfDef.getColor());
}
// (4) else only LROfUse has a color: check if that could interfere
return InterferesWithColor(LROfDef, LROfUse.getColor());
}
void LiveRangeInfo::coalesceLRs()
{
if(DEBUG_RA >= RA_DEBUG_LiveRanges)
std::cerr << "\nCoalescing LRs ...\n";
MachineFunction &MF = MachineFunction::get(Meth);
for (MachineFunction::iterator BBI = MF.begin(); BBI != MF.end(); ++BBI) {
MachineBasicBlock &MBB = *BBI;
// iterate over all the machine instructions in BB
for(MachineBasicBlock::iterator MII = MBB.begin(); MII != MBB.end(); ++MII){
const MachineInstr *MI = *MII;
if( DEBUG_RA >= RA_DEBUG_LiveRanges) {
std::cerr << " *Iterating over machine instr ";
MI->dump();
std::cerr << "\n";
}
// iterate over MI operands to find defs
for(MachineInstr::const_val_op_iterator DefI = MI->begin(),
DefE = MI->end(); DefI != DefE; ++DefI) {
if (DefI.isDefOnly() || DefI.isDefAndUse()) { // this operand is modified
LiveRange *LROfDef = getLiveRangeForValue( *DefI );
RegClass *RCOfDef = LROfDef->getRegClass();
MachineInstr::const_val_op_iterator UseI = MI->begin(),
UseE = MI->end();
for( ; UseI != UseE; ++UseI) { // for all uses
LiveRange *LROfUse = getLiveRangeForValue( *UseI );
if (!LROfUse) { // if LR of use is not found
//don't warn about labels
if (!isa<BasicBlock>(*UseI) && DEBUG_RA >= RA_DEBUG_LiveRanges)
std::cerr << " !! Warning: No LR for use " << RAV(*UseI)<< "\n";
continue; // ignore and continue
}
if (LROfUse == LROfDef) // nothing to merge if they are same
continue;
if (MRI.getRegTypeForLR(LROfDef) ==
MRI.getRegTypeForLR(LROfUse)) {
// If the two RegTypes are the same
if (!RCOfDef->getInterference(LROfDef, LROfUse) ) {
unsigned CombinedDegree =
LROfDef->getUserIGNode()->getNumOfNeighbors() +
LROfUse->getUserIGNode()->getNumOfNeighbors();
if (CombinedDegree > RCOfDef->getNumOfAvailRegs()) {
// get more precise estimate of combined degree
CombinedDegree = LROfDef->getUserIGNode()->
getCombinedDegree(LROfUse->getUserIGNode());
}
if (CombinedDegree <= RCOfDef->getNumOfAvailRegs()) {
// if both LRs do not have different pre-assigned colors
// and both LRs do not have suggested colors
if (! InterfsPreventCoalescing(*LROfDef, *LROfUse)) {
RCOfDef->mergeIGNodesOfLRs(LROfDef, LROfUse);
unionAndUpdateLRs(LROfDef, LROfUse);
}
} // if combined degree is less than # of regs
} // if def and use do not interfere
}// if reg classes are the same
} // for all uses
} // if def
} // for all defs
} // for all machine instructions
} // for all BBs
if (DEBUG_RA >= RA_DEBUG_LiveRanges)
std::cerr << "\nCoalescing Done!\n";
}
/*--------------------------- Debug code for printing ---------------*/
void LiveRangeInfo::printLiveRanges() {
LiveRangeMapType::iterator HMI = LiveRangeMap.begin(); // hash map iterator
std::cerr << "\nPrinting Live Ranges from Hash Map:\n";
for( ; HMI != LiveRangeMap.end(); ++HMI) {
if (HMI->first && HMI->second) {
std::cerr << " Value* " << RAV(HMI->first) << "\t: ";
if (IGNode* igNode = HMI->second->getUserIGNode())
std::cerr << "LR# " << igNode->getIndex();
else
std::cerr << "LR# " << "<no-IGNode>";
std::cerr << "\t:Values = "; printSet(*HMI->second); std::cerr << "\n";
}
}
}

View File

@ -1,124 +0,0 @@
//===-- LiveRangeInfo.h - Track all LiveRanges for a Function ----*- 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 class LiveRangeInfo which constructs and keeps
// the LiveRangeMap which contains all the live ranges used in a method.
//
// Assumptions:
//
// All variables (llvm Values) are defined before they are used. However, a
// constant may not be defined in the machine instruction stream if it can be
// used as an immediate value within a machine instruction. However, register
// allocation does not have to worry about immediate constants since they
// do not require registers.
//
// Since an llvm Value has a list of uses associated, it is sufficient to
// record only the defs in a Live Range.
//
//===----------------------------------------------------------------------===//
#ifndef LIVERANGEINFO_H
#define LIVERANGEINFO_H
#include "llvm/CodeGen/ValueSet.h"
#include "Support/hash_map"
class LiveRange;
class MachineInstr;
class RegClass;
class TargetRegInfo;
class TargetMachine;
class Value;
class Function;
class Instruction;
typedef hash_map<const Value*, LiveRange*> LiveRangeMapType;
//----------------------------------------------------------------------------
// Class LiveRangeInfo
//
// Constructs and keeps the LiveRangeMap which contains all the live
// ranges used in a method. Also contain methods to coalesce live ranges.
//----------------------------------------------------------------------------
class LiveRangeInfo {
const Function *const Meth; // Func for which live range info is held
LiveRangeMapType LiveRangeMap; // A map from Value * to LiveRange * to
// record all live ranges in a method
// created by constructLiveRanges
const TargetMachine& TM; // target machine description
std::vector<RegClass *> & RegClassList;// vector containing register classess
const TargetRegInfo& MRI; // machine reg info
std::vector<MachineInstr*> CallRetInstrList; // a list of all call/ret instrs
//------------ Private methods (see LiveRangeInfo.cpp for description)-------
LiveRange* createNewLiveRange (const Value* Def,
bool isCC = false);
LiveRange* createOrAddToLiveRange (const Value* Def,
bool isCC = false);
void unionAndUpdateLRs (LiveRange *L1,
LiveRange *L2);
void addInterference (const Instruction *Inst,
const ValueSet *LVSet);
void suggestRegs4CallRets ();
const Function *getMethod () const { return Meth; }
public:
LiveRangeInfo(const Function *F,
const TargetMachine& tm,
std::vector<RegClass *> & RCList);
/// Destructor to destroy all LiveRanges in the LiveRange Map
///
~LiveRangeInfo();
// Main entry point for live range construction
//
void constructLiveRanges();
/// return the common live range map for this method
///
inline const LiveRangeMapType *getLiveRangeMap() const
{ return &LiveRangeMap; }
/// Method used to get the live range containing a Value.
/// This may return NULL if no live range exists for a Value (eg, some consts)
///
inline LiveRange *getLiveRangeForValue(const Value *Val) {
return LiveRangeMap[Val];
}
inline const LiveRange *getLiveRangeForValue(const Value *Val) const {
LiveRangeMapType::const_iterator I = LiveRangeMap.find(Val);
return I->second;
}
/// Method for coalescing live ranges. Called only after interference info
/// is calculated.
///
void coalesceLRs();
/// debugging method to print the live ranges
///
void printLiveRanges();
};
#endif

View File

@ -1,17 +0,0 @@
##===- lib/CodeGen/RegAlloc/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 = ../../..
DIRS =
LIBRARYNAME = regalloc
BUILD_ARCHIVE = 1
include $(LEVEL)/Makefile.common

File diff suppressed because it is too large Load Diff

View File

@ -1,177 +0,0 @@
//===-- PhyRegAlloc.h - Graph Coloring Register Allocator -------*- 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 is the main entry point for register allocation.
//
// Notes:
// * RegisterClasses: Each RegClass accepts a
// TargetRegClass which contains machine specific info about that register
// class. The code in the RegClass is machine independent and they use
// access functions in the TargetRegClass object passed into it to get
// machine specific info.
//
// * Machine dependent work: All parts of the register coloring algorithm
// except coloring of an individual node are machine independent.
//
//===----------------------------------------------------------------------===//
#ifndef PHYREGALLOC_H
#define PHYREGALLOC_H
#include "LiveRangeInfo.h"
#include "llvm/Pass.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegInfo.h"
#include <map>
class MachineFunction;
class FunctionLiveVarInfo;
class MachineInstr;
class LoopInfo;
class RegClass;
class Constant;
//----------------------------------------------------------------------------
// Class AddedInstrns:
// When register allocator inserts new instructions in to the existing
// instruction stream, it does NOT directly modify the instruction stream.
// Rather, it creates an object of AddedInstrns and stick it in the
// AddedInstrMap for an existing instruction. This class contains two vectors
// to store such instructions added before and after an existing instruction.
//----------------------------------------------------------------------------
struct AddedInstrns {
std::vector<MachineInstr*> InstrnsBefore;//Insts added BEFORE an existing inst
std::vector<MachineInstr*> InstrnsAfter; //Insts added AFTER an existing inst
inline void clear () { InstrnsBefore.clear (); InstrnsAfter.clear (); }
};
//----------------------------------------------------------------------------
// class PhyRegAlloc:
// Main class the register allocator. Call runOnFunction() to allocate
// registers for a Function.
//----------------------------------------------------------------------------
class PhyRegAlloc : public FunctionPass {
std::vector<RegClass *> RegClassList; // vector of register classes
const TargetMachine &TM; // target machine
const Function *Fn; // name of the function we work on
MachineFunction *MF; // descriptor for method's native code
FunctionLiveVarInfo *LVI; // LV information for this method
// (already computed for BBs)
LiveRangeInfo *LRI; // LR info (will be computed)
const TargetRegInfo &MRI; // Machine Register information
const unsigned NumOfRegClasses; // recorded here for efficiency
// Map to indicate whether operands of each MachineInstr have been
// updated according to their assigned colors. This is only used in
// assertion checking (debug builds).
std::map<const MachineInstr *, bool> OperandsColoredMap;
// AddedInstrMap - Used to store instrns added in this phase
std::map<const MachineInstr *, AddedInstrns> AddedInstrMap;
// ScratchRegsUsed - Contains scratch register uses for a particular MI.
typedef std::multimap<const MachineInstr*, int> ScratchRegsUsedTy;
ScratchRegsUsedTy ScratchRegsUsed;
AddedInstrns AddedInstrAtEntry; // to store instrns added at entry
const LoopInfo *LoopDepthCalc; // to calculate loop depths
std::map<const Function *, std::vector<Constant *> > FnAllocState;
PhyRegAlloc(const PhyRegAlloc&); // DO NOT IMPLEMENT
void operator=(const PhyRegAlloc&); // DO NOT IMPLEMENT
public:
inline PhyRegAlloc (const TargetMachine &TM_) :
TM (TM_), MRI (TM.getRegInfo ()),
NumOfRegClasses (MRI.getNumOfRegClasses ()) { }
virtual ~PhyRegAlloc() { }
/// runOnFunction - Main method called for allocating registers.
///
virtual bool runOnFunction (Function &F);
virtual bool doFinalization (Module &M);
virtual void getAnalysisUsage (AnalysisUsage &AU) const;
const char *getPassName () const {
return "Traditional graph-coloring reg. allocator";
}
inline const RegClass* getRegClassByID(unsigned id) const {
return RegClassList[id];
}
inline RegClass *getRegClassByID(unsigned id) { return RegClassList[id]; }
private:
void addInterference(const Value *Def, const ValueSet *LVSet,
bool isCallInst);
bool markAllocatedRegs(MachineInstr* MInst);
void addInterferencesForArgs();
void createIGNodeListsAndIGs();
void buildInterferenceGraphs();
void saveState();
void verifySavedState();
void setCallInterferences(const MachineInstr *MI,
const ValueSet *LVSetAft);
void move2DelayedInstr(const MachineInstr *OrigMI,
const MachineInstr *DelayedMI);
void markUnusableSugColors();
void allocateStackSpace4SpilledLRs();
void insertCode4SpilledLR(const LiveRange *LR,
MachineBasicBlock::iterator& MII,
MachineBasicBlock &MBB, unsigned OpNum);
/// Method for inserting caller saving code. The caller must save all the
/// volatile registers live across a call.
///
void insertCallerSavingCode(std::vector<MachineInstr*>& instrnsBefore,
std::vector<MachineInstr*>& instrnsAfter,
MachineInstr *CallMI,
const BasicBlock *BB);
void colorIncomingArgs();
void colorCallRetArgs();
void updateMachineCode();
void updateInstruction(MachineBasicBlock::iterator& MII,
MachineBasicBlock &MBB);
int getUsableUniRegAtMI(int RegType, const ValueSet *LVSetBef,
MachineInstr *MI,
std::vector<MachineInstr*>& MIBef,
std::vector<MachineInstr*>& MIAft);
/// Callback method used to find unused registers.
/// LVSetBef is the live variable set to search for an unused register.
/// If it is not specified, the LV set before the current MI is used.
/// This is sufficient as long as no new copy instructions are generated
/// to copy the free register to memory.
///
int getUnusedUniRegAtMI(RegClass *RC, int RegType,
const MachineInstr *MI,
const ValueSet *LVSetBef = 0);
void setRelRegsUsedByThisInst(RegClass *RC, int RegType,
const MachineInstr *MI);
int getUniRegNotUsedByThisInst(RegClass *RC, int RegType,
const MachineInstr *MI);
void addInterf4PseudoInstr(const MachineInstr *MI);
};
#endif

View File

@ -1,28 +0,0 @@
//===-- RegAllocCommon.h --------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
//
// Shared declarations for register allocation.
//
//===----------------------------------------------------------------------===//
#ifndef REGALLOCCOMMON_H
#define REGALLOCCOMMON_H
enum RegAllocDebugLevel_t {
RA_DEBUG_None = 0,
RA_DEBUG_Results = 1,
RA_DEBUG_Coloring = 2,
RA_DEBUG_Interference = 3,
RA_DEBUG_LiveRanges = 4,
RA_DEBUG_Verbose = 5
};
extern RegAllocDebugLevel_t DEBUG_RA;
#endif

View File

@ -1,248 +0,0 @@
//===-- RegClass.cpp -----------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
//
// class RegClass for coloring-based register allocation for LLVM.
//
//===----------------------------------------------------------------------===//
#include "IGNode.h"
#include "RegAllocCommon.h"
#include "RegClass.h"
#include "llvm/Target/TargetRegInfo.h"
//----------------------------------------------------------------------------
// This constructor inits IG. The actual matrix is created by a call to
// createInterferenceGraph() above.
//----------------------------------------------------------------------------
RegClass::RegClass(const Function *M,
const TargetRegInfo *_MRI_,
const TargetRegClassInfo *_MRC_)
: Meth(M), MRI(_MRI_), MRC(_MRC_),
RegClassID( _MRC_->getRegClassID() ),
IG(this), IGNodeStack() {
if (DEBUG_RA >= RA_DEBUG_Interference)
std::cerr << "Created Reg Class: " << RegClassID << "\n";
IsColorUsedArr.resize(MRC->getNumOfAllRegs());
}
//----------------------------------------------------------------------------
// Main entry point for coloring a register class.
//----------------------------------------------------------------------------
void RegClass::colorAllRegs()
{
if (DEBUG_RA >= RA_DEBUG_Coloring)
std::cerr << "Coloring IG of reg class " << RegClassID << " ...\n";
// pre-color IGNodes
pushAllIGNodes(); // push all IG Nodes
unsigned int StackSize = IGNodeStack.size();
IGNode *CurIGNode;
// for all LRs on stack
for (unsigned int IGN=0; IGN < StackSize; IGN++) {
CurIGNode = IGNodeStack.top(); // pop the IGNode on top of stack
IGNodeStack.pop();
colorIGNode (CurIGNode); // color it
}
}
//----------------------------------------------------------------------------
// The method for pushing all IGNodes on to the stack.
//----------------------------------------------------------------------------
void RegClass::pushAllIGNodes()
{
bool NeedMoreSpills;
IG.setCurDegreeOfIGNodes(); // calculate degree of IGNodes
// push non-constrained IGNodes
bool PushedAll = pushUnconstrainedIGNodes();
if (DEBUG_RA >= RA_DEBUG_Coloring) {
std::cerr << " Puhsed all-unconstrained IGNodes. ";
if( PushedAll ) std::cerr << " No constrained nodes left.";
std::cerr << "\n";
}
if (PushedAll) // if NO constrained nodes left
return;
// now, we have constrained nodes. So, push one of them (the one with min
// spill cost) and try to push the others as unConstrained nodes.
// Repeat this.
do {
//get node with min spill cost
IGNode *IGNodeSpill = getIGNodeWithMinSpillCost();
// push that node on to stack
IGNodeStack.push(IGNodeSpill);
// set its OnStack flag and decrement degree of neighs
IGNodeSpill->pushOnStack();
// now push NON-constrained ones, if any
NeedMoreSpills = !pushUnconstrainedIGNodes();
if (DEBUG_RA >= RA_DEBUG_Coloring)
std::cerr << "\nConstrained IG Node found !@!" << IGNodeSpill->getIndex();
} while(NeedMoreSpills); // repeat until we have pushed all
}
//--------------------------------------------------------------------------
// This method goes thru all IG nodes in the IGNodeList of an IG of a
// register class and push any unconstrained IG node left (that is not
// already pushed)
//--------------------------------------------------------------------------
bool RegClass::pushUnconstrainedIGNodes()
{
// # of LRs for this reg class
unsigned int IGNodeListSize = IG.getIGNodeList().size();
bool pushedall = true;
// a pass over IGNodeList
for (unsigned i =0; i < IGNodeListSize; i++) {
// get IGNode i from IGNodeList
IGNode *IGNode = IG.getIGNodeList()[i];
if (!IGNode ) // can be null due to merging
continue;
// if already pushed on stack, continue. This can happen since this
// method can be called repeatedly until all constrained nodes are
// pushed
if (IGNode->isOnStack() )
continue;
// if the degree of IGNode is lower
if ((unsigned) IGNode->getCurDegree() < MRC->getNumOfAvailRegs()) {
IGNodeStack.push( IGNode ); // push IGNode on to the stack
IGNode->pushOnStack(); // set OnStack and dec deg of neighs
if (DEBUG_RA >= RA_DEBUG_Coloring) {
std::cerr << " pushed un-constrained IGNode " << IGNode->getIndex()
<< " on to stack\n";
}
}
else pushedall = false; // we didn't push all live ranges
} // for
// returns true if we pushed all live ranges - else false
return pushedall;
}
//----------------------------------------------------------------------------
// Get the IGNode with the minimum spill cost
//----------------------------------------------------------------------------
IGNode * RegClass::getIGNodeWithMinSpillCost() {
unsigned int IGNodeListSize = IG.getIGNodeList().size();
double MinSpillCost = 0;
IGNode *MinCostIGNode = NULL;
bool isFirstNode = true;
// pass over IGNodeList to find the IGNode with minimum spill cost
// among all IGNodes that are not yet pushed on to the stack
for (unsigned int i =0; i < IGNodeListSize; i++) {
IGNode *IGNode = IG.getIGNodeList()[i];
if (!IGNode) // can be null due to merging
continue;
if (!IGNode->isOnStack()) {
double SpillCost = (double) IGNode->getParentLR()->getSpillCost() /
(double) (IGNode->getCurDegree() + 1);
if (isFirstNode) { // for the first IG node
MinSpillCost = SpillCost;
MinCostIGNode = IGNode;
isFirstNode = false;
} else if (MinSpillCost > SpillCost) {
MinSpillCost = SpillCost;
MinCostIGNode = IGNode;
}
}
}
assert (MinCostIGNode && "No IGNode to spill");
return MinCostIGNode;
}
//----------------------------------------------------------------------------
// Color the IGNode using the machine specific code.
//----------------------------------------------------------------------------
void RegClass::colorIGNode(IGNode *const Node) {
if (! Node->hasColor()) { // not colored as an arg etc.
// init all elements of to IsColorUsedAr false;
clearColorsUsed();
// initialize all colors used by neighbors of this node to true
LiveRange *LR = Node->getParentLR();
unsigned NumNeighbors = Node->getNumOfNeighbors();
for (unsigned n=0; n < NumNeighbors; n++) {
IGNode *NeighIGNode = Node->getAdjIGNode(n);
LiveRange *NeighLR = NeighIGNode->getParentLR();
// Don't use a color if it is in use by the neighbor,
// or is suggested for use by the neighbor,
// markColorsUsed() should be given the color and the reg type for
// LR, not for NeighLR, because it should mark registers used based on
// the type we are looking for, not on the regType for the neighbour.
if (NeighLR->hasColor())
this->markColorsUsed(NeighLR->getColor(),
MRI->getRegTypeForLR(NeighLR),
MRI->getRegTypeForLR(LR)); // use LR, not NeighLR
else if (NeighLR->hasSuggestedColor() &&
NeighLR->isSuggestedColorUsable())
this->markColorsUsed(NeighLR->getSuggestedColor(),
MRI->getRegTypeForLR(NeighLR),
MRI->getRegTypeForLR(LR)); // use LR, not NeighLR
}
// call the target specific code for coloring
//
MRC->colorIGNode(Node, IsColorUsedArr);
} else {
if (DEBUG_RA >= RA_DEBUG_Coloring) {
std::cerr << " Node " << Node->getIndex();
std::cerr << " already colored with color " << Node->getColor() << "\n";
}
}
if (!Node->hasColor() ) {
if (DEBUG_RA >= RA_DEBUG_Coloring) {
std::cerr << " Node " << Node->getIndex();
std::cerr << " - could not find a color (needs spilling)\n";
}
}
}
void RegClass::printIGNodeList() const {
std::cerr << "IG Nodes for Register Class " << RegClassID << ":" << "\n";
IG.printIGNodeList();
}
void RegClass::printIG() {
std::cerr << "IG for Register Class " << RegClassID << ":" << "\n";
IG.printIG();
}

View File

@ -1,142 +0,0 @@
//===-- RegClass.h - Machine Independent register coloring ------*- 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.
//
//===----------------------------------------------------------------------===//
/* Title: RegClass.h -*- C++ -*-
Author: Ruchira Sasanka
Date: Aug 20, 01
Purpose: Contains machine independent methods for register coloring.
*/
#ifndef REGCLASS_H
#define REGCLASS_H
#include "llvm/Target/TargetRegInfo.h"
#include "InterferenceGraph.h"
#include <stack>
class TargetRegClassInfo;
//-----------------------------------------------------------------------------
// Class RegClass
//
// Implements a machine independent register class.
//
// This is the class that contains all data structures and common algos
// for coloring a particular register class (e.g., int class, fp class).
// This class is hardware independent. This class accepts a hardware
// dependent description of machine registers (TargetRegInfo class) to
// get hardware specific info and to color an individual IG node.
//
// This class contains the InterferenceGraph (IG).
// Also it contains an IGNode stack that can be used for coloring.
// The class provides some easy access methods to the IG methods, since these
// methods are called thru a register class.
//
//-----------------------------------------------------------------------------
class RegClass {
const Function *const Meth; // Function we are working on
const TargetRegInfo *MRI; // Machine register information
const TargetRegClassInfo *const MRC; // Machine reg. class for this RegClass
const unsigned RegClassID; // my int ID
InterferenceGraph IG; // Interference graph - constructed by
// buildInterferenceGraph
std::stack<IGNode *> IGNodeStack; // the stack used for coloring
// IsColorUsedArr - An array used for coloring each node. This array must be
// of size MRC->getNumOfAllRegs(). Allocated once in the constructor for
// efficiency.
//
std::vector<bool> IsColorUsedArr;
//--------------------------- private methods ------------------------------
void pushAllIGNodes();
bool pushUnconstrainedIGNodes();
IGNode * getIGNodeWithMinSpillCost();
void colorIGNode(IGNode *const Node);
// This directly marks the colors used by a particular register number
// within the register class. External users should use the public
// versions of this function below.
inline void markColorUsed(unsigned classRegNum) {
assert(classRegNum < IsColorUsedArr.size() && "Invalid register used?");
IsColorUsedArr[classRegNum] = true;
}
inline bool isColorUsed(unsigned regNum) const {
assert(regNum < IsColorUsedArr.size() && "Invalid register used?");
return IsColorUsedArr[regNum];
}
public:
RegClass(const Function *M,
const TargetRegInfo *_MRI_,
const TargetRegClassInfo *_MRC_);
inline void createInterferenceGraph() { IG.createGraph(); }
inline InterferenceGraph &getIG() { return IG; }
inline const unsigned getID() const { return RegClassID; }
inline const TargetRegClassInfo* getTargetRegClass() const { return MRC; }
// main method called for coloring regs
//
void colorAllRegs();
inline unsigned getNumOfAvailRegs() const
{ return MRC->getNumOfAvailRegs(); }
// --- following methods are provided to access the IG contained within this
// ---- RegClass easilly.
inline void addLRToIG(LiveRange *const LR)
{ IG.addLRToIG(LR); }
inline void setInterference(const LiveRange *const LR1,
const LiveRange *const LR2)
{ IG.setInterference(LR1, LR2); }
inline unsigned getInterference(const LiveRange *const LR1,
const LiveRange *const LR2) const
{ return IG.getInterference(LR1, LR2); }
inline void mergeIGNodesOfLRs(const LiveRange *const LR1,
LiveRange *const LR2)
{ IG.mergeIGNodesOfLRs(LR1, LR2); }
inline void clearColorsUsed() {
IsColorUsedArr.clear();
IsColorUsedArr.resize(MRC->getNumOfAllRegs());
}
inline void markColorsUsed(unsigned ClassRegNum,
int UserRegType,
int RegTypeWanted) {
MRC->markColorsUsed(ClassRegNum, UserRegType, RegTypeWanted,IsColorUsedArr);
}
inline int getUnusedColor(int machineRegType) const {
return MRC->findUnusedColor(machineRegType, IsColorUsedArr);
}
void printIGNodeList() const;
void printIG();
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,600 +0,0 @@
//===-- FloatingPoint.cpp - Floating point Reg -> Stack converter ---------===//
//
// 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 defines the pass which converts floating point instructions from
// virtual registers into register stack instructions.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "fp"
#include "X86.h"
#include "X86InstrInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "Support/Debug.h"
#include "Support/Statistic.h"
#include <algorithm>
#include <iostream>
namespace {
Statistic<> NumFXCH("x86-codegen", "Number of fxch instructions inserted");
Statistic<> NumFP ("x86-codegen", "Number of floating point instructions");
struct FPS : public MachineFunctionPass {
virtual bool runOnMachineFunction(MachineFunction &MF);
virtual const char *getPassName() const { return "X86 FP Stackifier"; }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LiveVariables>();
MachineFunctionPass::getAnalysisUsage(AU);
}
private:
LiveVariables *LV; // Live variable info for current function...
MachineBasicBlock *MBB; // Current basic block
unsigned Stack[8]; // FP<n> Registers in each stack slot...
unsigned RegMap[8]; // Track which stack slot contains each register
unsigned StackTop; // The current top of the FP stack.
void dumpStack() const {
std::cerr << "Stack contents:";
for (unsigned i = 0; i != StackTop; ++i) {
std::cerr << " FP" << Stack[i];
assert(RegMap[Stack[i]] == i && "Stack[] doesn't match RegMap[]!");
}
std::cerr << "\n";
}
private:
// getSlot - Return the stack slot number a particular register number is
// in...
unsigned getSlot(unsigned RegNo) const {
assert(RegNo < 8 && "Regno out of range!");
return RegMap[RegNo];
}
// getStackEntry - Return the X86::FP<n> register in register ST(i)
unsigned getStackEntry(unsigned STi) const {
assert(STi < StackTop && "Access past stack top!");
return Stack[StackTop-1-STi];
}
// getSTReg - Return the X86::ST(i) register which contains the specified
// FP<RegNo> register
unsigned getSTReg(unsigned RegNo) const {
return StackTop - 1 - getSlot(RegNo) + X86::ST0;
}
// pushReg - Push the specifiex FP<n> register onto the stack
void pushReg(unsigned Reg) {
assert(Reg < 8 && "Register number out of range!");
assert(StackTop < 8 && "Stack overflow!");
Stack[StackTop] = Reg;
RegMap[Reg] = StackTop++;
}
bool isAtTop(unsigned RegNo) const { return getSlot(RegNo) == StackTop-1; }
void moveToTop(unsigned RegNo, MachineBasicBlock::iterator &I) {
if (!isAtTop(RegNo)) {
unsigned Slot = getSlot(RegNo);
unsigned STReg = getSTReg(RegNo);
unsigned RegOnTop = getStackEntry(0);
// Swap the slots the regs are in
std::swap(RegMap[RegNo], RegMap[RegOnTop]);
// Swap stack slot contents
assert(RegMap[RegOnTop] < StackTop);
std::swap(Stack[RegMap[RegOnTop]], Stack[StackTop-1]);
// Emit an fxch to update the runtime processors version of the state
MachineInstr *MI = BuildMI(X86::FXCH, 1).addReg(STReg);
I = 1+MBB->insert(I, MI);
NumFXCH++;
}
}
void duplicateToTop(unsigned RegNo, unsigned AsReg,
MachineBasicBlock::iterator &I) {
unsigned STReg = getSTReg(RegNo);
pushReg(AsReg); // New register on top of stack
MachineInstr *MI = BuildMI(X86::FLDrr, 1).addReg(STReg);
I = 1+MBB->insert(I, MI);
}
// popStackAfter - Pop the current value off of the top of the FP stack
// after the specified instruction.
void popStackAfter(MachineBasicBlock::iterator &I);
bool processBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB);
void handleZeroArgFP(MachineBasicBlock::iterator &I);
void handleOneArgFP(MachineBasicBlock::iterator &I);
void handleTwoArgFP(MachineBasicBlock::iterator &I);
void handleSpecialFP(MachineBasicBlock::iterator &I);
};
}
FunctionPass *createX86FloatingPointStackifierPass() { return new FPS(); }
/// runOnMachineFunction - Loop over all of the basic blocks, transforming FP
/// register references into FP stack references.
///
bool FPS::runOnMachineFunction(MachineFunction &MF) {
LV = &getAnalysis<LiveVariables>();
StackTop = 0;
bool Changed = false;
for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
Changed |= processBasicBlock(MF, *I);
return Changed;
}
/// processBasicBlock - Loop over all of the instructions in the basic block,
/// transforming FP instructions into their stack form.
///
bool FPS::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) {
const TargetInstrInfo &TII = MF.getTarget().getInstrInfo();
bool Changed = false;
MBB = &BB;
for (MachineBasicBlock::iterator I = BB.begin(); I != BB.end(); ++I) {
MachineInstr *MI = *I;
MachineInstr *PrevMI = I == BB.begin() ? 0 : *(I-1);
unsigned Flags = TII.get(MI->getOpcode()).TSFlags;
if ((Flags & X86II::FPTypeMask) == 0) continue; // Ignore non-fp insts!
++NumFP; // Keep track of # of pseudo instrs
DEBUG(std::cerr << "\nFPInst:\t";
MI->print(std::cerr, MF.getTarget()));
// Get dead variables list now because the MI pointer may be deleted as part
// of processing!
LiveVariables::killed_iterator IB = LV->dead_begin(MI);
LiveVariables::killed_iterator IE = LV->dead_end(MI);
DEBUG(const MRegisterInfo *MRI = MF.getTarget().getRegisterInfo();
LiveVariables::killed_iterator I = LV->killed_begin(MI);
LiveVariables::killed_iterator E = LV->killed_end(MI);
if (I != E) {
std::cerr << "Killed Operands:";
for (; I != E; ++I)
std::cerr << " %" << MRI->getName(I->second);
std::cerr << "\n";
});
switch (Flags & X86II::FPTypeMask) {
case X86II::ZeroArgFP: handleZeroArgFP(I); break;
case X86II::OneArgFP: handleOneArgFP(I); break;
case X86II::OneArgFPRW: // ST(0) = fsqrt(ST(0))
assert(0 && "FP instr type not handled yet!");
case X86II::TwoArgFP: handleTwoArgFP(I); break;
case X86II::SpecialFP: handleSpecialFP(I); break;
default: assert(0 && "Unknown FP Type!");
}
// Check to see if any of the values defined by this instruction are dead
// after definition. If so, pop them.
for (; IB != IE; ++IB) {
unsigned Reg = IB->second;
if (Reg >= X86::FP0 && Reg <= X86::FP6) {
DEBUG(std::cerr << "Register FP#" << Reg-X86::FP0 << " is dead!\n");
++I; // Insert fxch AFTER the instruction
moveToTop(Reg-X86::FP0, I); // Insert fxch if necessary
--I; // Move to fxch or old instruction
popStackAfter(I); // Pop the top of the stack, killing value
}
}
// Print out all of the instructions expanded to if -debug
DEBUG(if (*I == PrevMI) {
std::cerr<< "Just deleted pseudo instruction\n";
} else {
MachineBasicBlock::iterator Start = I;
// Rewind to first instruction newly inserted.
while (Start != BB.begin() && *(Start-1) != PrevMI) --Start;
std::cerr << "Inserted instructions:\n\t";
(*Start)->print(std::cerr, MF.getTarget());
while (++Start != I+1);
}
dumpStack();
);
Changed = true;
}
assert(StackTop == 0 && "Stack not empty at end of basic block?");
return Changed;
}
//===----------------------------------------------------------------------===//
// Efficient Lookup Table Support
//===----------------------------------------------------------------------===//
struct TableEntry {
unsigned from;
unsigned to;
bool operator<(const TableEntry &TE) const { return from < TE.from; }
bool operator<(unsigned V) const { return from < V; }
};
static bool TableIsSorted(const TableEntry *Table, unsigned NumEntries) {
for (unsigned i = 0; i != NumEntries-1; ++i)
if (!(Table[i] < Table[i+1])) return false;
return true;
}
static int Lookup(const TableEntry *Table, unsigned N, unsigned Opcode) {
const TableEntry *I = std::lower_bound(Table, Table+N, Opcode);
if (I != Table+N && I->from == Opcode)
return I->to;
return -1;
}
#define ARRAY_SIZE(TABLE) \
(sizeof(TABLE)/sizeof(TABLE[0]))
#ifdef NDEBUG
#define ASSERT_SORTED(TABLE)
#else
#define ASSERT_SORTED(TABLE) \
{ static bool TABLE##Checked = false; \
if (!TABLE##Checked) \
assert(TableIsSorted(TABLE, ARRAY_SIZE(TABLE)) && \
"All lookup tables must be sorted for efficient access!"); \
}
#endif
//===----------------------------------------------------------------------===//
// Helper Methods
//===----------------------------------------------------------------------===//
// PopTable - Sorted map of instructions to their popping version. The first
// element is an instruction, the second is the version which pops.
//
static const TableEntry PopTable[] = {
{ X86::FADDrST0 , X86::FADDPrST0 },
{ X86::FDIVRrST0, X86::FDIVRPrST0 },
{ X86::FDIVrST0 , X86::FDIVPrST0 },
{ X86::FISTr16 , X86::FISTPr16 },
{ X86::FISTr32 , X86::FISTPr32 },
{ X86::FMULrST0 , X86::FMULPrST0 },
{ X86::FSTr32 , X86::FSTPr32 },
{ X86::FSTr64 , X86::FSTPr64 },
{ X86::FSTrr , X86::FSTPrr },
{ X86::FSUBRrST0, X86::FSUBRPrST0 },
{ X86::FSUBrST0 , X86::FSUBPrST0 },
{ X86::FUCOMPr , X86::FUCOMPPr },
{ X86::FUCOMr , X86::FUCOMPr },
};
/// popStackAfter - Pop the current value off of the top of the FP stack after
/// the specified instruction. This attempts to be sneaky and combine the pop
/// into the instruction itself if possible. The iterator is left pointing to
/// the last instruction, be it a new pop instruction inserted, or the old
/// instruction if it was modified in place.
///
void FPS::popStackAfter(MachineBasicBlock::iterator &I) {
ASSERT_SORTED(PopTable);
assert(StackTop > 0 && "Cannot pop empty stack!");
RegMap[Stack[--StackTop]] = ~0; // Update state
// Check to see if there is a popping version of this instruction...
int Opcode = Lookup(PopTable, ARRAY_SIZE(PopTable), (*I)->getOpcode());
if (Opcode != -1) {
(*I)->setOpcode(Opcode);
if (Opcode == X86::FUCOMPPr)
(*I)->RemoveOperand(0);
} else { // Insert an explicit pop
MachineInstr *MI = BuildMI(X86::FSTPrr, 1).addReg(X86::ST0);
I = MBB->insert(I+1, MI);
}
}
static unsigned getFPReg(const MachineOperand &MO) {
assert(MO.isPhysicalRegister() && "Expected an FP register!");
unsigned Reg = MO.getReg();
assert(Reg >= X86::FP0 && Reg <= X86::FP6 && "Expected FP register!");
return Reg - X86::FP0;
}
//===----------------------------------------------------------------------===//
// Instruction transformation implementation
//===----------------------------------------------------------------------===//
/// handleZeroArgFP - ST(0) = fld0 ST(0) = flds <mem>
//
void FPS::handleZeroArgFP(MachineBasicBlock::iterator &I) {
MachineInstr *MI = *I;
unsigned DestReg = getFPReg(MI->getOperand(0));
MI->RemoveOperand(0); // Remove the explicit ST(0) operand
// Result gets pushed on the stack...
pushReg(DestReg);
}
/// handleOneArgFP - fst ST(0), <mem>
//
void FPS::handleOneArgFP(MachineBasicBlock::iterator &I) {
MachineInstr *MI = *I;
assert(MI->getNumOperands() == 5 && "Can only handle fst* instructions!");
unsigned Reg = getFPReg(MI->getOperand(4));
bool KillsSrc = false;
for (LiveVariables::killed_iterator KI = LV->killed_begin(MI),
E = LV->killed_end(MI); KI != E; ++KI)
KillsSrc |= KI->second == X86::FP0+Reg;
// FSTPr80 and FISTPr64 are strange because there are no non-popping versions.
// If we have one _and_ we don't want to pop the operand, duplicate the value
// on the stack instead of moving it. This ensure that popping the value is
// always ok.
//
if ((MI->getOpcode() == X86::FSTPr80 ||
MI->getOpcode() == X86::FISTPr64) && !KillsSrc) {
duplicateToTop(Reg, 7 /*temp register*/, I);
} else {
moveToTop(Reg, I); // Move to the top of the stack...
}
MI->RemoveOperand(4); // Remove explicit ST(0) operand
if (MI->getOpcode() == X86::FSTPr80 || MI->getOpcode() == X86::FISTPr64) {
assert(StackTop > 0 && "Stack empty??");
--StackTop;
} else if (KillsSrc) { // Last use of operand?
popStackAfter(I);
}
}
//===----------------------------------------------------------------------===//
// Define tables of various ways to map pseudo instructions
//
// ForwardST0Table - Map: A = B op C into: ST(0) = ST(0) op ST(i)
static const TableEntry ForwardST0Table[] = {
{ X86::FpADD, X86::FADDST0r },
{ X86::FpDIV, X86::FDIVST0r },
{ X86::FpMUL, X86::FMULST0r },
{ X86::FpSUB, X86::FSUBST0r },
{ X86::FpUCOM, X86::FUCOMr },
};
// ReverseST0Table - Map: A = B op C into: ST(0) = ST(i) op ST(0)
static const TableEntry ReverseST0Table[] = {
{ X86::FpADD, X86::FADDST0r }, // commutative
{ X86::FpDIV, X86::FDIVRST0r },
{ X86::FpMUL, X86::FMULST0r }, // commutative
{ X86::FpSUB, X86::FSUBRST0r },
{ X86::FpUCOM, ~0 },
};
// ForwardSTiTable - Map: A = B op C into: ST(i) = ST(0) op ST(i)
static const TableEntry ForwardSTiTable[] = {
{ X86::FpADD, X86::FADDrST0 }, // commutative
{ X86::FpDIV, X86::FDIVRrST0 },
{ X86::FpMUL, X86::FMULrST0 }, // commutative
{ X86::FpSUB, X86::FSUBRrST0 },
{ X86::FpUCOM, X86::FUCOMr },
};
// ReverseSTiTable - Map: A = B op C into: ST(i) = ST(i) op ST(0)
static const TableEntry ReverseSTiTable[] = {
{ X86::FpADD, X86::FADDrST0 },
{ X86::FpDIV, X86::FDIVrST0 },
{ X86::FpMUL, X86::FMULrST0 },
{ X86::FpSUB, X86::FSUBrST0 },
{ X86::FpUCOM, ~0 },
};
/// handleTwoArgFP - Handle instructions like FADD and friends which are virtual
/// instructions which need to be simplified and possibly transformed.
///
/// Result: ST(0) = fsub ST(0), ST(i)
/// ST(i) = fsub ST(0), ST(i)
/// ST(0) = fsubr ST(0), ST(i)
/// ST(i) = fsubr ST(0), ST(i)
///
/// In addition to three address instructions, this also handles the FpUCOM
/// instruction which only has two operands, but no destination. This
/// instruction is also annoying because there is no "reverse" form of it
/// available.
///
void FPS::handleTwoArgFP(MachineBasicBlock::iterator &I) {
ASSERT_SORTED(ForwardST0Table); ASSERT_SORTED(ReverseST0Table);
ASSERT_SORTED(ForwardSTiTable); ASSERT_SORTED(ReverseSTiTable);
MachineInstr *MI = *I;
unsigned NumOperands = MI->getNumOperands();
assert(NumOperands == 3 ||
(NumOperands == 2 && MI->getOpcode() == X86::FpUCOM) &&
"Illegal TwoArgFP instruction!");
unsigned Dest = getFPReg(MI->getOperand(0));
unsigned Op0 = getFPReg(MI->getOperand(NumOperands-2));
unsigned Op1 = getFPReg(MI->getOperand(NumOperands-1));
bool KillsOp0 = false, KillsOp1 = false;
for (LiveVariables::killed_iterator KI = LV->killed_begin(MI),
E = LV->killed_end(MI); KI != E; ++KI) {
KillsOp0 |= (KI->second == X86::FP0+Op0);
KillsOp1 |= (KI->second == X86::FP0+Op1);
}
// If this is an FpUCOM instruction, we must make sure the first operand is on
// the top of stack, the other one can be anywhere...
if (MI->getOpcode() == X86::FpUCOM)
moveToTop(Op0, I);
unsigned TOS = getStackEntry(0);
// One of our operands must be on the top of the stack. If neither is yet, we
// need to move one.
if (Op0 != TOS && Op1 != TOS) { // No operand at TOS?
// We can choose to move either operand to the top of the stack. If one of
// the operands is killed by this instruction, we want that one so that we
// can update right on top of the old version.
if (KillsOp0) {
moveToTop(Op0, I); // Move dead operand to TOS.
TOS = Op0;
} else if (KillsOp1) {
moveToTop(Op1, I);
TOS = Op1;
} else {
// All of the operands are live after this instruction executes, so we
// cannot update on top of any operand. Because of this, we must
// duplicate one of the stack elements to the top. It doesn't matter
// which one we pick.
//
duplicateToTop(Op0, Dest, I);
Op0 = TOS = Dest;
KillsOp0 = true;
}
} else if (!KillsOp0 && !KillsOp1 && MI->getOpcode() != X86::FpUCOM) {
// If we DO have one of our operands at the top of the stack, but we don't
// have a dead operand, we must duplicate one of the operands to a new slot
// on the stack.
duplicateToTop(Op0, Dest, I);
Op0 = TOS = Dest;
KillsOp0 = true;
}
// Now we know that one of our operands is on the top of the stack, and at
// least one of our operands is killed by this instruction.
assert((TOS == Op0 || TOS == Op1) &&
(KillsOp0 || KillsOp1 || MI->getOpcode() == X86::FpUCOM) &&
"Stack conditions not set up right!");
// We decide which form to use based on what is on the top of the stack, and
// which operand is killed by this instruction.
const TableEntry *InstTable;
bool isForward = TOS == Op0;
bool updateST0 = (TOS == Op0 && !KillsOp1) || (TOS == Op1 && !KillsOp0);
if (updateST0) {
if (isForward)
InstTable = ForwardST0Table;
else
InstTable = ReverseST0Table;
} else {
if (isForward)
InstTable = ForwardSTiTable;
else
InstTable = ReverseSTiTable;
}
int Opcode = Lookup(InstTable, ARRAY_SIZE(ForwardST0Table), MI->getOpcode());
assert(Opcode != -1 && "Unknown TwoArgFP pseudo instruction!");
// NotTOS - The register which is not on the top of stack...
unsigned NotTOS = (TOS == Op0) ? Op1 : Op0;
// Replace the old instruction with a new instruction
*I = BuildMI(Opcode, 1).addReg(getSTReg(NotTOS));
// If both operands are killed, pop one off of the stack in addition to
// overwriting the other one.
if (KillsOp0 && KillsOp1 && Op0 != Op1) {
assert(!updateST0 && "Should have updated other operand!");
popStackAfter(I); // Pop the top of stack
}
// Insert an explicit pop of the "updated" operand for FUCOM
if (MI->getOpcode() == X86::FpUCOM) {
if (KillsOp0 && !KillsOp1)
popStackAfter(I); // If we kill the first operand, pop it!
else if (KillsOp1 && Op0 != Op1) {
if (getStackEntry(0) == Op1) {
popStackAfter(I); // If it's right at the top of stack, just pop it
} else {
// Otherwise, move the top of stack into the dead slot, killing the
// operand without having to add in an explicit xchg then pop.
//
unsigned STReg = getSTReg(Op1);
unsigned OldSlot = getSlot(Op1);
unsigned TopReg = Stack[StackTop-1];
Stack[OldSlot] = TopReg;
RegMap[TopReg] = OldSlot;
RegMap[Op1] = ~0;
Stack[--StackTop] = ~0;
MachineInstr *MI = BuildMI(X86::FSTPrr, 1).addReg(STReg);
I = MBB->insert(I+1, MI);
}
}
}
// Update stack information so that we know the destination register is now on
// the stack.
if (MI->getOpcode() != X86::FpUCOM) {
unsigned UpdatedSlot = getSlot(updateST0 ? TOS : NotTOS);
assert(UpdatedSlot < StackTop && Dest < 7);
Stack[UpdatedSlot] = Dest;
RegMap[Dest] = UpdatedSlot;
}
delete MI; // Remove the old instruction
}
/// handleSpecialFP - Handle special instructions which behave unlike other
/// floating point instructions. This is primarily intended for use by pseudo
/// instructions.
///
void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) {
MachineInstr *MI = *I;
switch (MI->getOpcode()) {
default: assert(0 && "Unknown SpecialFP instruction!");
case X86::FpGETRESULT: // Appears immediately after a call returning FP type!
assert(StackTop == 0 && "Stack should be empty after a call!");
pushReg(getFPReg(MI->getOperand(0)));
break;
case X86::FpSETRESULT:
assert(StackTop == 1 && "Stack should have one element on it to return!");
--StackTop; // "Forget" we have something on the top of stack!
break;
case X86::FpMOV: {
unsigned SrcReg = getFPReg(MI->getOperand(1));
unsigned DestReg = getFPReg(MI->getOperand(0));
bool KillsSrc = false;
for (LiveVariables::killed_iterator KI = LV->killed_begin(MI),
E = LV->killed_end(MI); KI != E; ++KI)
KillsSrc |= KI->second == X86::FP0+SrcReg;
if (KillsSrc) {
// If the input operand is killed, we can just change the owner of the
// incoming stack slot into the result.
unsigned Slot = getSlot(SrcReg);
assert(Slot < 7 && DestReg < 7 && "FpMOV operands invalid!");
Stack[Slot] = DestReg;
RegMap[DestReg] = Slot;
} else {
// For FMOV we just duplicate the specified value to a new stack slot.
// This could be made better, but would require substantial changes.
duplicateToTop(SrcReg, DestReg, I);
}
break;
}
}
I = MBB->erase(I)-1; // Remove the pseudo instruction
}

View File

@ -1,124 +0,0 @@
//===-- InstSelectPattern.cpp - A pattern matching inst selector for X86 --===//
//
// 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 defines a pattern matching instruction selector for X86.
//
// FIXME: we could allocate one big array of unsigneds to use as the backing
// store for all of the nodes costs arrays.
//
//===----------------------------------------------------------------------===//
#include "X86.h"
#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/DerivedTypes.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "X86RegisterInfo.h"
// Include the generated instruction selector...
#include "X86GenInstrSelector.inc"
namespace {
struct ISel : public FunctionPass, SelectionDAGTargetBuilder {
TargetMachine &TM;
ISel(TargetMachine &tm) : TM(tm) {}
int VarArgsFrameIndex; // FrameIndex for start of varargs area
bool runOnFunction(Function &Fn) {
MachineFunction &MF = MachineFunction::construct(&Fn, TM);
SelectionDAG DAG(MF, TM, *this);
std::cerr << "\n\n\n=== "
<< DAG.getMachineFunction().getFunction()->getName() << "\n";
DAG.dump();
X86ISel(DAG).generateCode();
std::cerr << "\n\n\n";
return true;
}
public: // Implementation of the SelectionDAGTargetBuilder class...
/// expandArguments - Add nodes to the DAG to indicate how to load arguments
/// off of the X86 stack.
void expandArguments(SelectionDAG &SD);
void expandCall(SelectionDAG &SD, CallInst &CI);
};
}
void ISel::expandArguments(SelectionDAG &SD) {
// Add DAG nodes to load the arguments... On entry to a function on the X86,
// the stack frame looks like this:
//
// [ESP] -- return address
// [ESP + 4] -- first argument (leftmost lexically)
// [ESP + 8] -- second argument, if first argument is four bytes in size
// ...
//
MachineFunction &F = SD.getMachineFunction();
MachineFrameInfo *MFI = F.getFrameInfo();
const Function &Fn = *F.getFunction();
unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot
for (Function::const_aiterator I = Fn.abegin(), E = Fn.aend(); I != E; ++I) {
MVT::ValueType ObjectVT = SD.getValueType(I->getType());
unsigned ArgIncrement = 4;
unsigned ObjSize;
switch (ObjectVT) {
default: assert(0 && "Unhandled argument type!");
case MVT::i8: ObjSize = 1; break;
case MVT::i16: ObjSize = 2; break;
case MVT::i32: ObjSize = 4; break;
case MVT::i64: ObjSize = ArgIncrement = 8; break;
case MVT::f32: ObjSize = 4; break;
case MVT::f64: ObjSize = ArgIncrement = 8; break;
}
// Create the frame index object for this incoming parameter...
int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
// Create the SelectionDAG nodes corresponding to a load from this parameter
SelectionDAGNode *FIN = new SelectionDAGNode(ISD::FrameIndex, MVT::i32);
FIN->addValue(new ReducedValue_FrameIndex_i32(FI));
SelectionDAGNode *Arg
= new SelectionDAGNode(ISD::Load, ObjectVT, F.begin(), FIN);
// Add the SelectionDAGNodes to the SelectionDAG... note that there is no
// reason to add chain nodes here. We know that no loads ore stores will
// ever alias these loads, so we are free to perform the load at any time in
// the function
SD.addNode(FIN);
SD.addNodeForValue(Arg, I);
ArgOffset += ArgIncrement; // Move on to the next argument...
}
// If the function takes variable number of arguments, make a frame index for
// the start of the first vararg value... for expansion of llvm.va_start.
if (Fn.getFunctionType()->isVarArg())
VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset);
}
void ISel::expandCall(SelectionDAG &SD, CallInst &CI) {
assert(0 && "ISel::expandCall not implemented!");
}
/// createX86PatternInstructionSelector - This pass converts an LLVM function
/// into a machine code representation using pattern matching and a machine
/// description file.
///
FunctionPass *createX86PatternInstructionSelector(TargetMachine &TM) {
return new ISel(TM);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,133 +0,0 @@
//===-- PeepholeOptimizer.cpp - X86 Peephole Optimizer --------------------===//
//
// 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 peephole optimizer for the X86.
//
//===----------------------------------------------------------------------===//
#include "X86.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
namespace {
struct PH : public MachineFunctionPass {
virtual bool runOnMachineFunction(MachineFunction &MF);
bool PeepholeOptimize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &I);
virtual const char *getPassName() const { return "X86 Peephole Optimizer"; }
};
}
FunctionPass *createX86PeepholeOptimizerPass() { return new PH(); }
bool PH::runOnMachineFunction(MachineFunction &MF) {
bool Changed = false;
for (MachineFunction::iterator BI = MF.begin(), E = MF.end(); BI != E; ++BI)
for (MachineBasicBlock::iterator I = BI->begin(); I != BI->end(); )
if (PeepholeOptimize(*BI, I))
Changed = true;
else
++I;
return Changed;
}
bool PH::PeepholeOptimize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &I) {
MachineInstr *MI = *I;
MachineInstr *Next = (I+1 != MBB.end()) ? *(I+1) : 0;
unsigned Size = 0;
switch (MI->getOpcode()) {
case X86::MOVrr8:
case X86::MOVrr16:
case X86::MOVrr32: // Destroy X = X copies...
if (MI->getOperand(0).getReg() == MI->getOperand(1).getReg()) {
I = MBB.erase(I);
delete MI;
return true;
}
return false;
// A large number of X86 instructions have forms which take an 8-bit
// immediate despite the fact that the operands are 16 or 32 bits. Because
// this can save three bytes of code size (and icache space), we want to
// shrink them if possible.
case X86::ADDri16: case X86::ADDri32:
case X86::SUBri16: case X86::SUBri32:
case X86::IMULri16: case X86::IMULri32:
case X86::ANDri16: case X86::ANDri32:
case X86::ORri16: case X86::ORri32:
case X86::XORri16: case X86::XORri32:
assert(MI->getNumOperands() == 3 && "These should all have 3 operands!");
if (MI->getOperand(2).isImmediate()) {
int Val = MI->getOperand(2).getImmedValue();
// If the value is the same when signed extended from 8 bits...
if (Val == (signed int)(signed char)Val) {
unsigned Opcode;
switch (MI->getOpcode()) {
default: assert(0 && "Unknown opcode value!");
case X86::ADDri16: Opcode = X86::ADDri16b; break;
case X86::ADDri32: Opcode = X86::ADDri32b; break;
case X86::SUBri16: Opcode = X86::SUBri16b; break;
case X86::SUBri32: Opcode = X86::SUBri32b; break;
case X86::IMULri16: Opcode = X86::IMULri16b; break;
case X86::IMULri32: Opcode = X86::IMULri32b; break;
case X86::ANDri16: Opcode = X86::ANDri16b; break;
case X86::ANDri32: Opcode = X86::ANDri32b; break;
case X86::ORri16: Opcode = X86::ORri16b; break;
case X86::ORri32: Opcode = X86::ORri32b; break;
case X86::XORri16: Opcode = X86::XORri16b; break;
case X86::XORri32: Opcode = X86::XORri32b; break;
}
unsigned R0 = MI->getOperand(0).getReg();
unsigned R1 = MI->getOperand(1).getReg();
*I = BuildMI(Opcode, 2, R0).addReg(R1).addZImm((char)Val);
delete MI;
return true;
}
}
return false;
#if 0
case X86::MOVir32: Size++;
case X86::MOVir16: Size++;
case X86::MOVir8:
// FIXME: We can only do this transformation if we know that flags are not
// used here, because XOR clobbers the flags!
if (MI->getOperand(1).isImmediate()) { // avoid mov EAX, <value>
int Val = MI->getOperand(1).getImmedValue();
if (Val == 0) { // mov EAX, 0 -> xor EAX, EAX
static const unsigned Opcode[] ={X86::XORrr8,X86::XORrr16,X86::XORrr32};
unsigned Reg = MI->getOperand(0).getReg();
*I = BuildMI(Opcode[Size], 2, Reg).addReg(Reg).addReg(Reg);
delete MI;
return true;
} else if (Val == -1) { // mov EAX, -1 -> or EAX, -1
// TODO: 'or Reg, -1' has a smaller encoding than 'mov Reg, -1'
}
}
return false;
#endif
case X86::BSWAPr32: // Change bswap EAX, bswap EAX into nothing
if (Next->getOpcode() == X86::BSWAPr32 &&
MI->getOperand(0).getReg() == Next->getOperand(0).getReg()) {
I = MBB.erase(MBB.erase(I));
delete MI;
delete Next;
return true;
}
return false;
default:
return false;
}
}

View File

@ -1,4 +1,5 @@
; RUN: export PATH=/usr/bin:/bin/:${PATH}
; RUN: PATH=/usr/bin:/bin/:${PATH}
; RUN: export PATH
; RUN: bugpoint %s -dce -bugpoint-deletecalls -simplifycfg
%.LC0 = internal global [13 x sbyte] c"Hello World\0A\00"

View File

@ -1,12 +1,17 @@
LEVEL = ..
DIRS = Programs
include Makefile.tests
#
# Make QMTest the default for testing features and regressions
# Do this first to force QMTest to run first
#
all:: qmtest
#
# Include other test rules
#
include Makefile.tests
#
# New QMTest functionality:
# The test suite is being transitioned over to QMTest. Eventually, it