diff options
author | cvs2svn <nothing@nowhere.org> | 2003-10-24 20:17:46 +0000 |
---|---|---|
committer | cvs2svn <nothing@nowhere.org> | 2003-10-24 20:17:46 +0000 |
commit | c5cf3309a2126b626c10537eaee40d1d632f33c0 (patch) | |
tree | f9b6af80e159cec53f338ce1ebffdc9bf3c0fff8 | |
parent | e8a63eb78fc38853f951d77d171461e7ff651ad4 (diff) |
This commit was manufactured by cvs2svn to create tag 'RELEASE_1'.svn-tags/RELEASE_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_1@9499 91177308-0d34-0410-b5e6-96231b3b80d8
48 files changed, 522 insertions, 9952 deletions
diff --git a/LICENSE.TXT b/LICENSE.TXT index 91d27b507b..ec389f3176 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -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 ============================================================================== diff --git a/README.txt b/README.txt index 60fd024e62..af2973214d 100644 --- a/README.txt +++ b/README.txt @@ -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 +---------------------- -LLVM User Guides: +(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. - Download and Installation Instructions: - llvm/docs/GettingStarted.html +(2) To report a bug, submit a bug report as described in the document: + http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html - LLVM Command Guide: - llvm/docs/CommandGuide/CommandGuide.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 Assembly Language: - llvm/docs/LangRef.html - LLVM Test Suite Guide: - llvm/docs/TestingGuide.html +LLVM Documentation +------------------ -LLVM Programming 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 + + LLVM Command Guide: + llvm/docs/CommandGuide/index.html - LLVM Programmers Manual: - llvm/docs/ProgrammersManual.html + LLVM Assembly Language: + llvm/docs/LangRef.html - Writing an LLVM Pass: - llvm/docs/WritingAnLLVMPass.html + LLVM Test Suite Guide: + llvm/docs/TestingGuide.html + +LLVM Programming Documentation: - Alias Analysis in LLVM: - llvm/docs/AliasAnalysis.html + LLVM Programmers Manual: + llvm/docs/ProgrammersManual.html - Command Line Library: - llvm/docs/CommandLine.html + Writing an LLVM Pass: + llvm/docs/WritingAnLLVMPass.html - Coding Standards: - llvm/docs/CodingStandards.html + Alias Analysis in LLVM: + llvm/docs/AliasAnalysis.html -LLVM Community: + Command Line Library: + llvm/docs/CommandLine.html - Submitting a Bug: - http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html + Coding Standards: + llvm/docs/CodingStandards.html - Open Projects: - llvm/docs/OpenProjects.html +Other LLVM Resources: - Creating a new LLVM Project: - llvm/docs/Projects.html + Submitting a Bug: + http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html - Mailing Lists: - There are several mailing lists providing LLVM users with - information: + Open Projects: + llvm/docs/OpenProjects.html - o LLVM Announcements List: - http://mail.cs.uiuc.edu/mailman/listinfo/llvm-announce + Creating a new LLVM Project: + llvm/docs/Projects.html - 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. +Mailing Lists +-------------- +There are three mailing lists for providing LLVM users with information: +(1) LLVM Announcements List: + http://mail.cs.uiuc.edu/mailman/listinfo/llvm-announce - o LLVM Developers List: - http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev + 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 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. +(2) LLVM Developers List: + http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev - o LLVM Commits List - http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits + 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 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. +(3) LLVM Commits List + http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits - 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. diff --git a/docs/AliasAnalysis.html b/docs/AliasAnalysis.html index e4bebca8aa..921fabc5aa 100644 --- a/docs/AliasAnalysis.html +++ b/docs/AliasAnalysis.html @@ -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> diff --git a/docs/CFEBuildInstrs.html b/docs/CFEBuildInstrs.html index 080153fe8c..5e753ab992 100644 --- a/docs/CFEBuildInstrs.html +++ b/docs/CFEBuildInstrs.html @@ -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> diff --git a/docs/ChrisNotes.txt b/docs/ChrisNotes.txt new file mode 100644 index 0000000000..ef75ed919f --- /dev/null +++ b/docs/ChrisNotes.txt @@ -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. diff --git a/docs/CodingStandards.html b/docs/CodingStandards.html index d469d6315e..668f4ec626 100644 --- a/docs/CodingStandards.html +++ b/docs/CodingStandards.html @@ -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 diff --git a/docs/CommandLine.html b/docs/CommandLine.html index a418dcba45..390ca237e0 100644 --- a/docs/CommandLine.html +++ b/docs/CommandLine.html @@ -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 diff --git a/docs/DSGraphStatus.html b/docs/DSGraphStatus.html index 098ff65412..6b12cc35a0 100644 --- a/docs/DSGraphStatus.html +++ b/docs/DSGraphStatus.html @@ -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 diff --git a/docs/FAQ.html b/docs/FAQ.html index a76fea66f6..ba71573e8b 100644 --- a/docs/FAQ.html +++ b/docs/FAQ.html @@ -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> diff --git a/docs/GettingStarted.html b/docs/GettingStarted.html index 252d6dc056..10ef30478c 100644 --- a/docs/GettingStarted.html +++ b/docs/GettingStarted.html @@ -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> diff --git a/docs/HowToSubmitABug.html b/docs/HowToSubmitABug.html index 3afef5bf96..01a1a24275 100644 --- a/docs/HowToSubmitABug.html +++ b/docs/HowToSubmitABug.html @@ -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 diff --git a/docs/LangRef.html b/docs/LangRef.html index 56d5153a67..92cf8b2de3 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -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 diff --git a/docs/OpenProjects.html b/docs/OpenProjects.html index 5f648374d1..aefe9a71e6 100644 --- a/docs/OpenProjects.html +++ b/docs/OpenProjects.html @@ -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 diff --git a/docs/ProgrammersManual.html b/docs/ProgrammersManual.html index 0bde00e94a..58619e15f2 100644 --- a/docs/ProgrammersManual.html +++ b/docs/ProgrammersManual.html @@ -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 diff --git a/docs/Projects.html b/docs/Projects.html index 5de4b58670..b236ab8ac3 100644 --- a/docs/Projects.html +++ b/docs/Projects.html @@ -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> diff --git a/docs/ReleaseNotes.html b/docs/ReleaseNotes.html index c68cbf31b5..8c621c0455 100644 --- a/docs/ReleaseNotes.html +++ b/docs/ReleaseNotes.html @@ -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> diff --git a/docs/TestingGuide.html b/docs/TestingGuide.html index 71354e2957..107d75700c 100644 --- a/docs/TestingGuide.html +++ b/docs/TestingGuide.html @@ -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> diff --git a/docs/WritingAnLLVMPass.html b/docs/WritingAnLLVMPass.html index 0832a81644..a765f40135 100644 --- a/docs/WritingAnLLVMPass.html +++ b/docs/WritingAnLLVMPass.html @@ -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 diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000000..b2db1ba858 --- /dev/null +++ b/docs/index.html @@ -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> + diff --git a/include/Config/strings.h b/include/Config/strings.h new file mode 100644 index 0000000000..b279875f69 --- /dev/null +++ b/include/Config/strings.h @@ -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 diff --git a/include/llvm/Analysis/FindUsedTypes.h b/include/llvm/Analysis/FindUsedTypes.h index 7ce06046fa..50d659e2fa 100644 --- a/include/llvm/Analysis/FindUsedTypes.h +++ b/include/llvm/Analysis/FindUsedTypes.h @@ -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); diff --git a/include/llvm/CodeGen/SparcRegInfo.h b/include/llvm/CodeGen/SparcRegInfo.h deleted file mode 100644 index 2e52de7aa0..0000000000 --- a/include/llvm/CodeGen/SparcRegInfo.h +++ /dev/null @@ -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 diff --git a/lib/Analysis/IPA/FindUsedTypes.cpp b/lib/Analysis/IPA/FindUsedTypes.cpp index ad548d0f9a..91b599017e 100644 --- a/lib/Analysis/IPA/FindUsedTypes.cpp +++ b/lib/Analysis/IPA/FindUsedTypes.cpp @@ -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. diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp deleted file mode 100644 index b1f8793d64..0000000000 --- a/lib/Target/CBackend/CBackend.cpp +++ /dev/null @@ -1,1384 +0,0 @@ -//===-- Writer.cpp - Library for converting LLVM code to 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 library converts LLVM code to C code, compilable by GCC. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Assembly/CWriter.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/Instructions.h" -#include "llvm/Pass.h" -#include "llvm/SymbolTable.h" -#include "llvm/Intrinsics.h" -#include "llvm/Analysis/FindUsedTypes.h" -#include "llvm/Analysis/ConstantsScanner.h" -#include "llvm/Support/InstVisitor.h" -#include "llvm/Support/InstIterator.h" -#include "llvm/Support/CallSite.h" -#include "llvm/Support/Mangler.h" -#include "Support/StringExtras.h" -#include "Support/STLExtras.h" -#include "Config/config.h" -#include <algorithm> -#include <sstream> - -namespace { - class CWriter : public Pass, public InstVisitor<CWriter> { - std::ostream &Out; - Mangler *Mang; - const Module *TheModule; - std::map<const Type *, std::string> TypeNames; - std::set<const Value*> MangledGlobals; - bool needsMalloc, emittedInvoke; - - std::map<const ConstantFP *, unsigned> FPConstantMap; - public: - CWriter(std::ostream &o) : Out(o) {} - - void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequired<FindUsedTypes>(); - } - - virtual bool run(Module &M) { - // Initialize - TheModule = &M; - - // Ensure that all structure types have names... - bool Changed = nameAllUsedStructureTypes(M); - Mang = new Mangler(M); - - // Run... - printModule(&M); - - // Free memory... - delete Mang; - TypeNames.clear(); - MangledGlobals.clear(); - return false; - } - - std::ostream &printType(std::ostream &Out, const Type *Ty, - const std::string &VariableName = "", - bool IgnoreName = false, bool namedContext = true); - - void writeOperand(Value *Operand); - void writeOperandInternal(Value *Operand); - - private : - bool nameAllUsedStructureTypes(Module &M); - void printModule(Module *M); - void printFloatingPointConstants(Module &M); - void printSymbolTable(const SymbolTable &ST); - void printContainedStructs(const Type *Ty, std::set<const StructType *> &); - void printFunctionSignature(const Function *F, bool Prototype); - - void printFunction(Function *); - - void printConstant(Constant *CPV); - void printConstantArray(ConstantArray *CPA); - - // isInlinableInst - Attempt to inline instructions into their uses to build - // trees as much as possible. To do this, we have to consistently decide - // what is acceptable to inline, so that variable declarations don't get - // printed and an extra copy of the expr is not emitted. - // - static bool isInlinableInst(const Instruction &I) { - // Must be an expression, must be used exactly once. If it is dead, we - // emit it inline where it would go. - if (I.getType() == Type::VoidTy || !I.hasOneUse() || - isa<TerminatorInst>(I) || isa<CallInst>(I) || isa<PHINode>(I) || - isa<LoadInst>(I) || isa<VAArgInst>(I) || isa<VANextInst>(I)) - // Don't inline a load across a store or other bad things! - return false; - - // Only inline instruction it it's use is in the same BB as the inst. - return I.getParent() == cast<Instruction>(I.use_back())->getParent(); - } - - // isDirectAlloca - Define fixed sized allocas in the entry block as direct - // variables which are accessed with the & operator. This causes GCC to - // generate significantly better code than to emit alloca calls directly. - // - static const AllocaInst *isDirectAlloca(const Value *V) { - const AllocaInst *AI = dyn_cast<AllocaInst>(V); - if (!AI) return false; - if (AI->isArrayAllocation()) - return 0; // FIXME: we can also inline fixed size array allocas! - if (AI->getParent() != &AI->getParent()->getParent()->getEntryBlock()) - return 0; - return AI; - } - - // Instruction visitation functions - friend class InstVisitor<CWriter>; - - void visitReturnInst(ReturnInst &I); - void visitBranchInst(BranchInst &I); - void visitSwitchInst(SwitchInst &I); - void visitInvokeInst(InvokeInst &I); - void visitUnwindInst(UnwindInst &I); - - void visitPHINode(PHINode &I); - void visitBinaryOperator(Instruction &I); - - void visitCastInst (CastInst &I); - void visitCallInst (CallInst &I); - void visitCallSite (CallSite CS); - void visitShiftInst(ShiftInst &I) { visitBinaryOperator(I); } - - void visitMallocInst(MallocInst &I); - void visitAllocaInst(AllocaInst &I); - void visitFreeInst (FreeInst &I); - void visitLoadInst (LoadInst &I); - void visitStoreInst (StoreInst &I); - void visitGetElementPtrInst(GetElementPtrInst &I); - void visitVANextInst(VANextInst &I); - void visitVAArgInst (VAArgInst &I); - - void visitInstruction(Instruction &I) { - std::cerr << "C Writer does not know about " << I; - abort(); - } - - void outputLValue(Instruction *I) { - Out << " " << Mang->getValueName(I) << " = "; - } - void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock, - unsigned Indent); - void printIndexingExpression(Value *Ptr, User::op_iterator I, - User::op_iterator E); - }; -} - -// A pointer type should not use parens around *'s alone, e.g., (**) -inline bool ptrTypeNameNeedsParens(const std::string &NameSoFar) { - return NameSoFar.find_last_not_of('*') != std::string::npos; -} - -// Pass the Type* and the variable name and this prints out the variable -// declaration. -// -std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty, - const std::string &NameSoFar, - bool IgnoreName, bool namedContext) { - if (Ty->isPrimitiveType()) - switch (Ty->getPrimitiveID()) { - case Type::VoidTyID: return Out << "void " << NameSoFar; - case Type::BoolTyID: return Out << "bool " << NameSoFar; - case Type::UByteTyID: return Out << "unsigned char " << NameSoFar; - case Type::SByteTyID: return Out << "signed char " << NameSoFar; - case Type::UShortTyID: return Out << "unsigned short " << NameSoFar; - case Type::ShortTyID: return Out << "short " << NameSoFar; - case Type::UIntTyID: return Out << "unsigned " << NameSoFar; - case Type::IntTyID: return Out << "int " << NameSoFar; - case Type::ULongTyID: return Out << "unsigned long long " << NameSoFar; - case Type::LongTyID: return Out << "signed long long " << NameSoFar; - case Type::FloatTyID: return Out << "float " << NameSoFar; - case Type::DoubleTyID: return Out << "double " << NameSoFar; - default : - std::cerr << "Unknown primitive type: " << Ty << "\n"; - abort(); - } - - // Check to see if the type is named. - if (!IgnoreName || isa<OpaqueType>(Ty)) { - std::map<const Type *, std::string>::iterator I = TypeNames.find(Ty); - if (I != TypeNames.end()) return Out << I->second << " " << NameSoFar; - } - - switch (Ty->getPrimitiveID()) { - case Type::FunctionTyID: { - const FunctionType *MTy = cast<FunctionType>(Ty); - std::stringstream FunctionInnards; - FunctionInnards << " (" << NameSoFar << ") ("; - for (FunctionType::ParamTypes::const_iterator - I = MTy->getParamTypes().begin(), - E = MTy->getParamTypes().end(); I != E; ++I) { - if (I != MTy->getParamTypes().begin()) - FunctionInnards << ", "; - printType(FunctionInnards, *I, ""); - } - if (MTy->isVarArg()) { - if (!MTy->getParamTypes().empty()) - FunctionInnards << ", ..."; - } else if (MTy->getParamTypes().empty()) { - FunctionInnards << "void"; - } - FunctionInnards << ")"; - std::string tstr = FunctionInnards.str(); - printType(Out, MTy->getReturnType(), tstr); - return Out; - } - case Type::StructTyID: { - const StructType *STy = cast<StructType>(Ty); - Out << NameSoFar + " {\n"; - unsigned Idx = 0; - for (StructType::ElementTypes::const_iterator - I = STy->getElementTypes().begin(), - E = STy->getElementTypes().end(); I != E; ++I) { - Out << " "; - printType(Out, *I, "field" + utostr(Idx++)); - Out << ";\n"; - } - return Out << "}"; - } - - case Type::PointerTyID: { - const PointerType *PTy = cast<PointerType>(Ty); - std::string ptrName = "*" + NameSoFar; - - // Do not need parens around "* NameSoFar" if NameSoFar consists only - // of zero or more '*' chars *and* this is not an unnamed pointer type - // such as the result type in a cast statement. Otherwise, enclose in ( ). - if (ptrTypeNameNeedsParens(NameSoFar) || !namedContext || - PTy->getElementType()->getPrimitiveID() == Type::ArrayTyID) - ptrName = "(" + ptrName + ")"; // - - return printType(Out, PTy->getElementType(), ptrName); - } - - case Type::ArrayTyID: { - const ArrayType *ATy = cast<ArrayType>(Ty); - unsigned NumElements = ATy->getNumElements(); - return printType(Out, ATy->getElementType(), - NameSoFar + "[" + utostr(NumElements) + "]"); - } - - case Type::OpaqueTyID: { - static int Count = 0; - std::string TyName = "struct opaque_" + itostr(Count++); - assert(TypeNames.find(Ty) == TypeNames.end()); - TypeNames[Ty] = TyName; - return Out << TyName << " " << NameSoFar; - } - default: - assert(0 && "Unhandled case in getTypeProps!"); - abort(); - } - - return Out; -} - -void CWriter::printConstantArray(ConstantArray *CPA) { - - // As a special case, print the array as a string if it is an array of - // ubytes or an array of sbytes with positive values. - // - const Type *ETy = CPA->getType()->getElementType(); - bool isString = (ETy == Type::SByteTy || ETy == Type::UByteTy); - - // Make sure the last character is a null char, as automatically added by C - if (isString && (CPA->getNumOperands() == 0 || - !cast<Constant>(*(CPA->op_end()-1))->isNullValue())) - isString = false; - - if (isString) { - Out << "\""; - // Keep track of whether the last number was a hexadecimal escape - bool LastWasHex = false; - - // Do not include the last character, which we know is null - for (unsigned i = 0, e = CPA->getNumOperands()-1; i != e; ++i) { - unsigned char C = cast<ConstantInt>(CPA->getOperand(i))->getRawValue(); - - // Print it out literally if it is a printable character. The only thing - // to be careful about is when the last letter output was a hex escape - // code, in which case we have to be careful not to print out hex digits - // explicitly (the C compiler thinks it is a continuation of the previous - // character, sheesh...) - // - if (isprint(C) && (!LastWasHex || !isxdigit(C))) { - LastWasHex = false; - if (C == '"' || C == '\\') - Out << "\\" << C; - else - Out << C; - } else { - LastWasHex = false; - switch (C) { - case '\n': Out << "\\n"; break; - case '\t': Out << "\\t"; break; - case '\r': Out << "\\r"; break; - case '\v': Out << "\\v"; break; - case '\a': Out << "\\a"; break; - case '\"': Out << "\\\""; break; - case '\'': Out << "\\\'"; break; - default: - Out << "\\x"; - Out << (char)(( C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A')); - Out << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A')); - LastWasHex = true; - break; - } - } - } - Out << "\""; - } else { - Out << "{"; - if (CPA->getNumOperands()) { - Out << " "; - printConstant(cast<Constant>(CPA->getOperand(0))); - for (unsigned i = 1, e = CPA->getNumOperands(); i != e; ++i) { - Out << ", "; - printConstant(cast<Constant>(CPA->getOperand(i))); - } - } - Out << " }"; - } -} - -// isFPCSafeToPrint - Returns true if we may assume that CFP may be written out -// textually as a double (rather than as a reference to a stack-allocated -// variable). We decide this by converting CFP to a string and back into a -// double, and then checking whether the conversion results in a bit-equal -// double to the original value of CFP. This depends on us and the target C -// compiler agreeing on the conversion process (which is pretty likely since we -// only deal in IEEE FP). -// -static bool isFPCSafeToPrint(const ConstantFP *CFP) { -#if HAVE_PRINTF_A - char Buffer[100]; - sprintf(Buffer, "%a", CFP->getValue()); - - if (!strncmp(Buffer, "0x", 2) || - !strncmp(Buffer, "-0x", 3) || - !strncmp(Buffer, "+0x", 3)) - return atof(Buffer) == CFP->getValue(); - return false; -#else - std::string StrVal = ftostr(CFP->getValue()); - - while (StrVal[0] == ' ') - StrVal.erase(StrVal.begin()); - - // Check to make sure that the stringized number is not some string like "Inf" - // or NaN. Check that the string matches the "[-+]?[0-9]" regex. - if ((StrVal[0] >= '0' && StrVal[0] <= '9') || - ((StrVal[0] == '-' || StrVal[0] == '+') && - (StrVal[1] >= '0' && StrVal[1] <= '9'))) - // Reparse stringized version! - return atof(StrVal.c_str()) == CFP->getValue(); - return false; -#endif -} - -// printConstant - The LLVM Constant to C Constant converter. -void CWriter::printConstant(Constant *CPV) { - if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) { - switch (CE->getOpcode()) { - case Instruction::Cast: - Out << "(("; - printType(Out, CPV->getType()); - Out << ")"; - printConstant(CE->getOperand(0)); - Out << ")"; - return; - - case Instruction::GetElementPtr: - Out << "(&("; - printIndexingExpression(CE->getOperand(0), - CPV->op_begin()+1, CPV->op_end()); - Out << "))"; - return; - case Instruction::Add: - case Instruction::Sub: - case Instruction::Mul: - case Instruction::Div: - case Instruction::Rem: - case Instruction::SetEQ: - case Instruction::SetNE: - case Instruction::SetLT: - case Instruction::SetLE: - case Instruction::SetGT: - case Instruction::SetGE: - Out << "("; - printConstant(CE->getOperand(0)); - switch (CE->getOpcode()) { - case Instruction::Add: Out << " + "; break; - case Instruction::Sub: Out << " - "; break; - case Instruction::Mul: Out << " * "; break; - case Instruction::Div: Out << " / "; break; - case Instruction::Rem: Out << " % "; break; - case Instruction::SetEQ: Out << " == "; break; - case Instruction::SetNE: Out << " != "; break; - case Instruction::SetLT: Out << " < "; break; - case Instruction::SetLE: Out << " <= "; break; - case Instruction::SetGT: Out << " > "; break; - case Instruction::SetGE: Out << " >= "; break; - default: assert(0 && "Illegal opcode here!"); - } - printConstant(CE->getOperand(1)); - Out << ")"; - return; - - default: - std::cerr << "CWriter Error: Unhandled constant expression: " - << CE << "\n"; - abort(); - } - } - - switch (CPV->getType()->getPrimitiveID()) { - case Type::BoolTyID: - Out << (CPV == ConstantBool::False ? "0" : "1"); break; - case Type::SByteTyID: - case Type::ShortTyID: - Out << cast<ConstantSInt>(CPV)->getValue(); break; - case Type::IntTyID: - if ((int)cast<ConstantSInt>(CPV)->getValue() == (int)0x80000000) - Out << "((int)0x80000000)"; // Handle MININT specially to avoid warning - else - Out << cast<ConstantSInt>(CPV)->getValue(); - break; - - case Type::LongTyID: - Out << cast<ConstantSInt>(CPV)->getValue() << "ll"; break; - - case Type::UByteTyID: - case Type::UShortTyID: - Out << cast<ConstantUInt>(CPV)->getValue(); break; - case Type::UIntTyID: - Out << cast<ConstantUInt>(CPV)->getValue() << "u"; break; - case Type::ULongTyID: - Out << cast<ConstantUInt>(CPV)->getValue() << "ull"; break; - - case Type::FloatTyID: - case Type::DoubleTyID: { - ConstantFP *FPC = cast<ConstantFP>(CPV); - std::map<const ConstantFP*, unsigned>::iterator I = FPConstantMap.find(FPC); - if (I != FPConstantMap.end()) { - // Because of FP precision problems we must load from a stack allocated - // value that holds the value in hex. - Out << "(*(" << (FPC->getType() == Type::FloatTy ? "float" : "double") - << "*)&FPConstant" << I->second << ")"; - } else { -#if HAVE_PRINTF_A - // Print out the constant as a floating point number. - char Buffer[100]; - sprintf(Buffer, "%a", FPC->getValue()); - Out << Buffer << " /*" << FPC->getValue() << "*/ "; -#else - Out << ftostr(FPC->getValue()); -#endif - } - break; - } - - case Type::ArrayTyID: - printConstantArray(cast<ConstantArray>(CPV)); - break; - - case Type::StructTyID: { - Out << "{"; - if (CPV->getNumOperands()) { - Out << " "; - printConstant(cast<Constant>(CPV->getOperand(0))); - for (unsigned i = 1, e = CPV->getNumOperands(); i != e; ++i) { - Out << ", "; - printConstant(cast<Constant>(CPV->getOperand(i))); - } - } - Out << " }"; - break; - } - - case Type::PointerTyID: - if (isa<ConstantPointerNull>(CPV)) { - Out << "(("; - printType(Out, CPV->getType()); - Out << ")/*NULL*/0)"; - break; - } else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(CPV)) { - writeOperand(CPR->getValue()); - break; - } - // FALL THROUGH - default: - std::cerr << "Unknown constant type: " << CPV << "\n"; - abort(); - } -} - -void CWriter::writeOperandInternal(Value *Operand) { - if (Instruction *I = dyn_cast<Instruction>(Operand)) - if (isInlinableInst(*I) && !isDirectAlloca(I)) { - // Should we inline this instruction to build a tree? - Out << "("; - visit(*I); - Out << ")"; - return; - } - - if (Constant *CPV = dyn_cast<Constant>(Operand)) { - printConstant(CPV); - } else { - Out << Mang->getValueName(Operand); - } -} - -void CWriter::writeOperand(Value *Operand) { - if (isa<GlobalVariable>(Operand) || isDirectAlloca(Operand)) - Out << "(&"; // Global variables are references as their addresses by llvm - - writeOperandInternal(Operand); - - if (isa<GlobalVariable>(Operand) || isDirectAlloca(Operand)) - Out << ")"; -} - -// nameAllUsedStructureTypes - If there are structure types in the module that -// are used but do not have names assigned to them in the symbol table yet then -// we assign them names now. -// -bool CWriter::nameAllUsedStructureTypes(Module &M) { - // Get a set of types that are used by the program... - std::set<const Type *> UT = getAnalysis<FindUsedTypes>().getTypes(); - - // Loop over the module symbol table, removing types from UT that are already - // named. - // - SymbolTable &MST = M.getSymbolTable(); - if (MST.find(Type::TypeTy) != MST.end()) - for (SymbolTable::type_iterator I = MST.type_begin(Type::TypeTy), - E = MST.type_end(Type::TypeTy); I != E; ++I) - UT.erase(cast<Type>(I->second)); - - // UT now contains types that are not named. Loop over it, naming structure - // types. - // - bool Changed = false; - for (std::set<const Type *>::const_iterator I = UT.begin(), E = UT.end(); - I != E; ++I) - if (const StructType *ST = dyn_cast<StructType>(*I)) { - ((Value*)ST)->setName("unnamed", &MST); - Changed = true; - } - return Changed; -} - -// generateCompilerSpecificCode - This is where we add conditional compilation -// directives to cater to specific compilers as need be. -// -static void generateCompilerSpecificCode(std::ostream& Out) { - // Alloca is hard to get, and we don't want to include stdlib.h here... - Out << "/* get a declaration for alloca */\n" - << "#ifdef sun\n" - << "extern void *__builtin_alloca(unsigned long);\n" - << "#define alloca(x) __builtin_alloca(x)\n" - << "#else\n" - << "#ifndef __FreeBSD__\n" - << "#include <alloca.h>\n" - << "#endif\n" - << "#endif\n\n"; - - // We output GCC specific attributes to preserve 'linkonce'ness on globals. - // If we aren't being compiled with GCC, just drop these attributes. - Out << "#ifndef __GNUC__ /* Can only support \"linkonce\" vars with GCC */\n" - << "#define __attribute__(X)\n" - << "#endif\n"; -} - -void CWriter::printModule(Module *M) { - // Calculate which global values have names that will collide when we throw - // away type information. - { // Scope to delete the FoundNames set when we are done with it... - std::set<std::string> FoundNames; - for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) - if (I->hasName()) // If the global has a name... - if (FoundNames.count(I->getName())) // And the name is already used - MangledGlobals.insert(I); // Mangle the name - else - FoundNames.insert(I->getName()); // Otherwise, keep track of name - - for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) - if (I->hasName()) // If the global has a name... - if (FoundNames.count(I->getName())) // And the name is already used - MangledGlobals.insert(I); // Mangle the name - else - FoundNames.insert(I->getName()); // Otherwise, keep track of name - } - - // get declaration for alloca - Out << "/* Provide Declarations */\n"; - Out << "#include <stdarg.h>\n"; - Out << "#include <setjmp.h>\n"; - generateCompilerSpecificCode(Out); - - // Provide a definition for `bool' if not compiling with a C++ compiler. - Out << "\n" - << "#ifndef __cplusplus\ntypedef unsigned char bool;\n#endif\n" - - << "\n\n/* Support for floating point constants */\n" - << "typedef unsigned long long ConstantDoubleTy;\n" - << "typedef unsigned int ConstantFloatTy;\n" - - << "\n\n/* Support for the invoke instruction */\n" - << "extern struct __llvm_jmpbuf_list_t {\n" - << " jmp_buf buf; struct __llvm_jmpbuf_list_t *next;\n" - << "} *__llvm_jmpbuf_list;\n" - - << "\n\n/* Global Declarations */\n"; - - // First output all the declarations for the program, because C requires - // Functions & globals to be declared before they are used. - // - - // Loop over the symbol table, emitting all named constants... - printSymbolTable(M->getSymbolTable()); - - // Global variable declarations... - if (!M->gempty()) { - Out << "\n/* External Global Variable Declarations */\n"; - for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) { - if (I->hasExternalLinkage()) { - Out << "extern "; - printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); - Out << ";\n"; - } - } - } - - // Function declarations - if (!M->empty()) { - Out << "\n/* Function Declarations */\n"; - needsMalloc = true; - for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) { - // If the function is external and the name collides don't print it. - // Sometimes the bytecode likes to have multiple "declarations" for - // external functions - if ((I->hasInternalLinkage() || !MangledGlobals.count(I)) && - !I->getIntrinsicID()) { - printFunctionSignature(I, true); - Out << ";\n"; - } - } - } - - // Print Malloc prototype if needed - if (needsMalloc) { - Out << "\n/* Malloc to make sun happy */\n"; - Out << "extern void * malloc();\n\n"; - } - - // Output the global variable declarations - if (!M->gempty()) { - Out << "\n\n/* Global Variable Declarations */\n"; - for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) - if (!I->isExternal()) { - Out << "extern "; - printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); - - Out << ";\n"; - } - } - - // Output the global variable definitions and contents... - if (!M->gempty()) { - Out << "\n\n/* Global Variable Definitions and Initialization */\n"; - for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) - if (!I->isExternal()) { - if (I->hasInternalLinkage()) - Out << "static "; - printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); - if (I->hasLinkOnceLinkage()) - Out << " __attribute__((common))"; - else if (I->hasWeakLinkage()) - Out << " __attribute__((weak))"; - if (!I->getInitializer()->isNullValue()) { - Out << " = " ; - writeOperand(I->getInitializer()); - } - Out << ";\n"; - } - } - - // Output all floating point constants that cannot be printed accurately... - printFloatingPointConstants(*M); - - // Output all of the functions... - emittedInvoke = false; - if (!M->empty()) { - Out << "\n\n/* Function Bodies */\n"; - for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) - printFunction(I); - } - - // If the program included an invoke instruction, we need to output the - // support code for it here! - if (emittedInvoke) { - Out << "\n/* More support for the invoke instruction */\n" - << "struct __llvm_jmpbuf_list_t *__llvm_jmpbuf_list " - << "__attribute__((common)) = 0;\n"; - } - - // Done with global FP constants - FPConstantMap.clear(); -} - -/// Output all floating point constants that cannot be printed accurately... -void CWriter::printFloatingPointConstants(Module &M) { - union { - double D; - unsigned long long U; - } DBLUnion; - - union { - float F; - unsigned U; - } FLTUnion; - - // Scan the module for floating point constants. If any FP constant is used - // in the function, we want to redirect it here so that we do not depend on - // the precision of the printed form, unless the printed form preserves - // precision. - // - unsigned FPCounter = 0; - for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) - for (constant_iterator I = constant_begin(F), E = constant_end(F); - I != E; ++I) - if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I)) - if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe. - !FPConstantMap.count(FPC)) { - double Val = FPC->getValue(); - - FPConstantMap[FPC] = FPCounter; // Number the FP constants - - if (FPC->getType() == Type::DoubleTy) { - DBLUnion.D = Val; - Out << "const ConstantDoubleTy FPConstant" << FPCounter++ - << " = 0x" << std::hex << DBLUnion.U << std::dec - << "ULL; /* " << Val << " */\n"; - } else if (FPC->getType() == Type::FloatTy) { - FLTUnion.F = Val; - Out << "const ConstantFloatTy FPConstant" << FPCounter++ - << " = 0x" << std::hex << FLTUnion.U << std::dec - << "U; /* " << Val << " */\n"; - } else - assert(0 && "Unknown float type!"); - } - - Out << "\n"; - } - - -/// printSymbolTable - Run through symbol table looking for type names. If a -/// type name is found, emit it's declaration... -/// -void CWriter::printSymbolTable(const SymbolTable &ST) { - // If there are no type names, exit early. - if (ST.find(Type::TypeTy) == ST.end()) - return; - - // We are only interested in the type plane of the symbol table... - SymbolTable::type_const_iterator I = ST.type_begin(Type::TypeTy); - SymbolTable::type_const_iterator End = ST.type_end(Type::TypeTy); - - // Print out forward declarations for structure types before anything else! - Out << "/* Structure forward decls */\n"; - for (; I != End; ++I) - if (const Type *STy = dyn_cast<StructType>(I->second)) { - std::string Name = "struct l_" + Mangler::makeNameProper(I->first); - Out << Name << ";\n"; - TypeNames.insert(std::make_pair(STy, Name)); - } - - Out << "\n"; - - // Now we can print out typedefs... - Out << "/* Typedefs */\n"; - for (I = ST.type_begin(Type::TypeTy); I != End; ++I) { - const Type *Ty = cast<Type>(I->second); - std::string Name = "l_" + Mangler::makeNameProper(I->first); - Out << "typedef "; - printType(Out, Ty, Name); - Out << ";\n"; - } - - Out << "\n"; - - // Keep track of which structures have been printed so far... - std::set<const StructType *> StructPrinted; - - // Loop over all structures then push them into the stack so they are - // printed in the correct order. - // - Out << "/* Structure contents */\n"; - for (I = ST.type_begin(Type::TypeTy); I != End; ++I) - if (const StructType *STy = dyn_cast<StructType>(I->second)) - printContainedStructs(STy, StructPrinted); -} - -// Push the struct onto the stack and recursively push all structs -// this one depends on. -void CWriter::printContainedStructs(const Type *Ty, - std::set<const StructType*> &StructPrinted){ - if (const StructType *STy = dyn_cast<StructType>(Ty)) { - //Check to see if we have already printed this struct - if (StructPrinted.count(STy) == 0) { - // Print all contained types first... - for (StructType::ElementTypes::const_iterator - I = STy->getElementTypes().begin(), - E = STy->getElementTypes().end(); I != E; ++I) { - const Type *Ty1 = I->get(); - if (isa<StructType>(Ty1) || isa<ArrayType>(Ty1)) - printContainedStructs(*I, StructPrinted); - } - - //Print structure type out.. - StructPrinted.insert(STy); - std::string Name = TypeNames[STy]; - printType(Out, STy, Name, true); - Out << ";\n\n"; - } - - // If it is an array, check contained types and continue - } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)){ - const Type *Ty1 = ATy->getElementType(); - if (isa<StructType>(Ty1) || isa<ArrayType>(Ty1)) - printContainedStructs(Ty1, StructPrinted); - } -} - - -void CWriter::printFunctionSignature(const Function *F, bool Prototype) { - // If the program provides its own malloc prototype we don't need - // to include the general one. - if (Mang->getValueName(F) == "malloc") - needsMalloc = false; - - if (F->hasInternalLinkage()) Out << "static "; - if (F->hasLinkOnceLinkage()) Out << "inline "; - - // Loop over the arguments, printing them... - const FunctionType *FT = cast<FunctionType>(F->getFunctionType()); - - std::stringstream FunctionInnards; - - // Print out the name... - FunctionInnards << Mang->getValueName(F) << "("; - - if (!F->isExternal()) { - if (!F->aempty()) { - std::string ArgName; - if (F->abegin()->hasName() || !Prototype) - ArgName = Mang->getValueName(F->abegin()); - printType(FunctionInnards, F->afront().getType(), ArgName); - for (Function::const_aiterator I = ++F->abegin(), E = F->aend(); - I != E; ++I) { - FunctionInnards << ", "; - if (I->hasName() || !Prototype) - ArgName = Mang->getValueName(I); - else - ArgName = ""; - printType(FunctionInnards, I->getType(), ArgName); - } - } - } else { - // Loop over the arguments, printing them... - for (FunctionType::ParamTypes::const_iterator I = - FT->getParamTypes().begin(), - E = FT->getParamTypes().end(); I != E; ++I) { - if (I != FT->getParamTypes().begin()) FunctionInnards << ", "; - printType(FunctionInnards, *I); - } - } - - // Finish printing arguments... if this is a vararg function, print the ..., - // unless there are no known types, in which case, we just emit (). - // - if (FT->isVarArg() && !FT->getParamTypes().empty()) { - if (FT->getParamTypes().size()) FunctionInnards << ", "; - FunctionInnards << "..."; // Output varargs portion of signature! - } - FunctionInnards << ")"; - // Print out the return type and the entire signature for that matter - printType(Out, F->getReturnType(), FunctionInnards.str()); - - if (F->hasWeakLinkage()) Out << " __attribute((weak))"; -} - -void CWriter::printFunction(Function *F) { - if (F->isExternal()) return; - - printFunctionSignature(F, false); - Out << " {\n"; - - // print local variable information for the function - for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) - if (const AllocaInst *AI = isDirectAlloca(*I)) { - Out << " "; - printType(Out, AI->getAllocatedType(), Mang->getValueName(AI)); - Out << "; /* Address exposed local */\n"; - } else if ((*I)->getType() != Type::VoidTy && !isInlinableInst(**I)) { - Out << " "; - printType(Out, (*I)->getType(), Mang->getValueName(*I)); - Out << ";\n"; - - if (isa<PHINode>(*I)) { // Print out PHI node temporaries as well... - Out << " "; - printType(Out, (*I)->getType(), - Mang->getValueName(*I)+"__PHI_TEMPORARY"); - Out << ";\n"; - } - } - - Out << "\n"; - - // print the basic blocks - for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { - BasicBlock *Prev = BB->getPrev(); - - // Don't print the label for the basic block if there are no uses, or if the - // only terminator use is the predecessor basic block's terminator. We have - // to scan the use list because PHI nodes use basic blocks too but do not - // require a label to be generated. - // - bool NeedsLabel = false; - for (Value::use_iterator UI = BB->use_begin(), UE = BB->use_end(); - UI != UE; ++UI) - if (TerminatorInst *TI = dyn_cast<TerminatorInst>(*UI)) - if (TI != Prev->getTerminator() || - isa<SwitchInst>(Prev->getTerminator()) || - isa<InvokeInst>(Prev->getTerminator())) { - NeedsLabel = true; - break; - } - - if (NeedsLabel) Out << Mang->getValueName(BB) << ":\n"; - - // Output all of the instructions in the basic block... - for (BasicBlock::iterator II = BB->begin(), E = --BB->end(); II != E; ++II){ - if (!isInlinableInst(*II) && !isDirectAlloca(II)) { - if (II->getType() != Type::VoidTy) - outputLValue(II); - else - Out << " "; - visit(*II); - Out << ";\n"; - } - } - - // Don't emit prefix or suffix for the terminator... - visit(*BB->getTerminator()); - } - - Out << "}\n\n"; -} - -// Specific Instruction type classes... note that all of the casts are -// necessary because we use the instruction classes as opaque types... -// -void CWriter::visitReturnInst(ReturnInst &I) { - // Don't output a void return if this is the last basic block in the function - if (I.getNumOperands() == 0 && - &*--I.getParent()->getParent()->end() == I.getParent() && - !I.getParent()->size() == 1) { - return; - } - - Out << " return"; - if (I.getNumOperands()) { - Out << " "; - writeOperand(I.getOperand(0)); - } - Out << ";\n"; -} - -void CWriter::visitSwitchInst(SwitchInst &SI) { - Out << " switch ("; - writeOperand(SI.getOperand(0)); - Out << ") {\n default:\n"; - printBranchToBlock(SI.getParent(), SI.getDefaultDest(), 2); - Out << ";\n"; - for (unsigned i = 2, e = SI.getNumOperands(); i != e; i += 2) { - Out << " case "; - writeOperand(SI.getOperand(i)); - Out << ":\n"; - BasicBlock *Succ = cast<BasicBlock>(SI.getOperand(i+1)); - printBranchToBlock(SI.getParent(), Succ, 2); - if (Succ == SI.getParent()->getNext()) - Out << " break;\n"; - } - Out << " }\n"; -} - -void CWriter::visitInvokeInst(InvokeInst &II) { - Out << " {\n" - << " struct __llvm_jmpbuf_list_t Entry;\n" - << " Entry.next = __llvm_jmpbuf_list;\n" - << " if (setjmp(Entry.buf)) {\n" - << " __llvm_jmpbuf_list = Entry.next;\n"; - printBranchToBlock(II.getParent(), II.getExceptionalDest(), 4); - Out << " }\n" - << " __llvm_jmpbuf_list = &Entry;\n" - << " "; - - if (II.getType() != Type::VoidTy) outputLValue(&II); - visitCallSite(&II); - Out << ";\n" - << " __llvm_jmpbuf_list = Entry.next;\n" - << " }\n"; - printBranchToBlock(II.getParent(), II.getNormalDest(), 0); - emittedInvoke = true; -} - - -void CWriter::visitUnwindInst(UnwindInst &I) { - // The unwind instructions causes a control flow transfer out of the current - // function, unwinding the stack until a caller who used the invoke - // instruction is found. In this context, we code generated the invoke - // instruction to add an entry to the top of the jmpbuf_list. Thus, here we - // just have to longjmp to the specified handler. - Out << " if (__llvm_jmpbuf_list == 0) { /* unwind */\n" - << " extern write();\n" - << " ((void (*)(int, void*, unsigned))write)(2,\n" - << " \"throw found with no handler!\\n\", 31); abort();\n" - << " }\n" - << " longjmp(__llvm_jmpbuf_list->buf, 1);\n"; - emittedInvoke = true; -} - -static bool isGotoCodeNecessary(BasicBlock *From, BasicBlock *To) { - // If PHI nodes need copies, we need the copy code... - if (isa<PHINode>(To->front()) || - From->getNext() != To) // Not directly successor, need goto - return true; - - // Otherwise we don't need the code. - return false; -} - -void CWriter::printBranchToBlock(BasicBlock *CurBB, BasicBlock *Succ, - unsigned Indent) { - for (BasicBlock::iterator I = Succ->begin(); - PHINode *PN = dyn_cast<PHINode>(I); ++I) { - // now we have to do the printing - Out << std::string(Indent, ' '); - Out << " " << Mang->getValueName(I) << "__PHI_TEMPORARY = "; - writeOperand(PN->getIncomingValue(PN->getBasicBlockIndex(CurBB))); - Out << "; /* for PHI node */\n"; - } - - if (CurBB->getNext() != Succ || - isa<InvokeInst>(CurBB->getTerminator()) || - isa<SwitchInst>(CurBB->getTerminator())) { - Out << std::string(Indent, ' ') << " goto "; - writeOperand(Succ); - Out << ";\n"; - } -} - -// Branch instruction printing - Avoid printing out a branch to a basic block -// that immediately succeeds the current one. -// -void CWriter::visitBranchInst(BranchInst &I) { - if (I.isConditional()) { - if (isGotoCodeNecessary(I.getParent(), I.getSuccessor(0))) { - Out << " if ("; - writeOperand(I.getCondition()); - Out << ") {\n"; - - printBranchToBlock(I.getParent(), I.getSuccessor(0), 2); - - if (isGotoCodeNecessary(I.getParent(), I.getSuccessor(1))) { - Out << " } else {\n"; - printBranchToBlock(I.getParent(), I.getSuccessor(1), 2); - } - } else { - // First goto not necessary, assume second one is... - Out << " if (!"; - writeOperand(I.getCondition()); - Out << ") {\n"; - - printBranchToBlock(I.getParent(), I.getSuccessor(1), 2); - } - - Out << " }\n"; - } else { - printBranchToBlock(I.getParent(), I.getSuccessor(0), 0); - } - Out << "\n"; -} - -// PHI nodes get copied into temporary values at the end of predecessor basic -// blocks. We now need to copy these temporary values into the REAL value for -// the PHI. -void CWriter::visitPHINode(PHINode &I) { - writeOperand(&I); - Out << "__PHI_TEMPORARY"; -} - - -void CWriter::visitBinaryOperator(Instruction &I) { - // binary instructions, shift instructions, setCond instructions. - assert(!isa<PointerType>(I.getType())); - - // We must cast the results of binary operations which might be promoted. - bool needsCast = false; - if ((I.getType() == Type::UByteTy) || (I.getType() == Type::SByteTy) - || (I.getType() == Type::UShortTy) || (I.getType() == Type::ShortTy) - || (I.getType() == Type::FloatTy)) { - needsCast = true; - Out << "(("; - printType(Out, I.getType(), "", false, false); - Out << ")("; - } - - writeOperand(I.getOperand(0)); - - switch (I.getOpcode()) { - case Instruction::Add: Out << " + "; break; - case Instruction::Sub: Out << " - "; break; - case Instruction::Mul: Out << "*"; break; - case Instruction::Div: Out << "/"; break; - case Instruction::Rem: Out << "%"; break; - case Instruction::And: Out << " & "; break; - case Instruction::Or: Out << " | "; break; - case Instruction::Xor: Out << " ^ "; break; - case Instruction::SetEQ: Out << " == "; break; - case Instruction::SetNE: Out << " != "; break; - case Instruction::SetLE: Out << " <= "; break; - case Instruction::SetGE: Out << " >= "; break; - case Instruction::SetLT: Out << " < "; break; - case Instruction::SetGT: Out << " > "; break; - case Instruction::Shl : Out << " << "; break; - case Instruction::Shr : Out << " >> "; break; - default: std::cerr << "Invalid operator type!" << I; abort(); - } - - writeOperand(I.getOperand(1)); - - if (needsCast) { - Out << "))"; - } -} - -void CWriter::visitCastInst(CastInst &I) { - if (I.getType() == Type::BoolTy) { - Out << "("; - writeOperand(I.getOperand(0)); - Out << " != 0)"; - return; - } - Out << "("; - printType(Out, I.getType(), "", /*ignoreName*/false, /*namedContext*/false); - Out << ")"; - if (isa<PointerType>(I.getType())&&I.getOperand(0)->getType()->isIntegral() || - isa<PointerType>(I.getOperand(0)->getType())&&I.getType()->isIntegral()) { - // Avoid "cast to pointer from integer of different size" warnings - Out << "(long)"; - } - - writeOperand(I.getOperand(0)); -} - -void CWriter::visitCallInst(CallInst &I) { - // Handle intrinsic function calls first... - if (Function *F = I.getCalledFunction()) - if (LLVMIntrinsic::ID ID = (LLVMIntrinsic::ID)F->getIntrinsicID()) { - switch (ID) { - default: assert(0 && "Unknown LLVM intrinsic!"); - case LLVMIntrinsic::va_start: - Out << "0; "; - - Out << "va_start(*(va_list*)&" << Mang->getValueName(&I) << ", "; - // Output the last argument to the enclosing function... - if (I.getParent()->getParent()->aempty()) { - std::cerr << "The C backend does not currently support zero " - << "argument varargs functions, such as '" - << I.getParent()->getParent()->getName() << "'!\n"; - abort(); - } - writeOperand(&I.getParent()->getParent()->aback()); - Out << ")"; - return; - case LLVMIntrinsic::va_end: - Out << "va_end(*(va_list*)&"; - writeOperand(I.getOperand(1)); - Out << ")"; - return; - case LLVMIntrinsic::va_copy: - Out << "0;"; - Out << "va_copy(*(va_list*)&" << Mang->getValueName(&I) << ", "; - Out << "*(va_list*)&"; - writeOperand(I.getOperand(1)); - Out << ")"; - return; - case LLVMIntrinsic::setjmp: - case LLVMIntrinsic::sigsetjmp: - // This intrinsic should never exist in the program, but until we get - // setjmp/longjmp transformations going on, we should codegen it to - // something reasonable. This will allow code that never calls longjmp - // to work. - Out << "0"; - return; - case LLVMIntrinsic::longjmp: - case LLVMIntrinsic::siglongjmp: - // Longjmp is not implemented, and never will be. It would cause an - // exception throw. - Out << "abort()"; - return; - } - } - visitCallSite(&I); -} - -void CWriter::visitCallSite(CallSite CS) { - const PointerType *PTy = cast<PointerType>(CS.getCalledValue()->getType()); - const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); - const Type *RetTy = FTy->getReturnType(); - - writeOperand(CS.getCalledValue()); - Out << "("; - - if (CS.arg_begin() != CS.arg_end()) { - CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end(); - writeOperand(*AI); - - for (++AI; AI != AE; ++AI) { - Out << ", "; - writeOperand(*AI); - } - } - Out << ")"; -} - -void CWriter::visitMallocInst(MallocInst &I) { - Out << "("; - printType(Out, I.getType()); - Out << ")malloc(sizeof("; - printType(Out, I.getType()->getElementType()); - Out << ")"; - - if (I.isArrayAllocation()) { - Out << " * " ; - writeOperand(I.getOperand(0)); - } - Out << ")"; -} - -void CWriter::visitAllocaInst(AllocaInst &I) { - Out << "("; - printType(Out, I.getType()); - Out << ") alloca(sizeof("; - printType(Out, I.getType()->getElementType()); - Out << ")"; - if (I.isArrayAllocation()) { - Out << " * " ; - writeOperand(I.getOperand(0)); - } - Out << ")"; -} - -void CWriter::visitFreeInst(FreeInst &I) { - Out << "free((char*)"; - writeOperand(I.getOperand(0)); - Out << ")"; -} - -void CWriter::printIndexingExpression(Value *Ptr, User::op_iterator I, - User::op_iterator E) { - bool HasImplicitAddress = false; - // If accessing a global value with no indexing, avoid *(&GV) syndrome - if (GlobalValue *V = dyn_cast<GlobalValue>(Ptr)) { - HasImplicitAddress = true; - } else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Ptr)) { - HasImplicitAddress = true; - Ptr = CPR->getValue(); // Get to the global... - } else if (isDirectAlloca(Ptr)) { - HasImplicitAddress = true; - } - - if (I == E) { - if (!HasImplicitAddress) - Out << "*"; // Implicit zero first argument: '*x' is equivalent to 'x[0]' - - writeOperandInternal(Ptr); - return; - } - - const Constant *CI = dyn_cast<Constant>(I); - if (HasImplicitAddress && (!CI || !CI->isNullValue())) - Out << "(&"; - - writeOperandInternal(Ptr); - - if (HasImplicitAddress && (!CI || !CI->isNullValue())) { - Out << ")"; - HasImplicitAddress = false; // HIA is only true if we haven't addressed yet - } - - assert(!HasImplicitAddress || (CI && CI->isNullValue()) && - "Can only have implicit address with direct accessing"); - - if (HasImplicitAddress) { - ++I; - } else if (CI && CI->isNullValue() && I+1 != E) { - // Print out the -> operator if possible... - if ((*(I+1))->getType() == Type::UByteTy) { - Out << (HasImplicitAddress ? "." : "->"); - Out << "field" << cast<ConstantUInt>(*(I+1))->getValue(); - I += 2; - } - } - - for (; I != E; ++I) - if ((*I)->getType() == Type::LongTy) { - Out << "["; - writeOperand(*I); - Out << "]"; - } else { - Out << ".field" << cast<ConstantUInt>(*I)->getValue(); - } -} - -void CWriter::visitLoadInst(LoadInst &I) { - Out << "*"; - writeOperand(I.getOperand(0)); -} - -void CWriter::visitStoreInst(StoreInst &I) { - Out << "*"; - writeOperand(I.getPointerOperand()); - Out << " = "; - writeOperand(I.getOperand(0)); -} - -void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) { - Out << "&"; - printIndexingExpression(I.getPointerOperand(), I.idx_begin(), I.idx_end()); -} - -void CWriter::visitVANextInst(VANextInst &I) { - Out << Mang->getValueName(I.getOperand(0)); - Out << "; va_arg(*(va_list*)&" << Mang->getValueName(&I) << ", "; - printType(Out, I.getArgType(), "", /*ignoreName*/false, - /*namedContext*/false); - Out << ")"; -} - -void CWriter::visitVAArgInst(VAArgInst &I) { - Out << "0;\n"; - Out << "{ va_list Tmp; va_copy(Tmp, *(va_list*)&"; - writeOperand(I.getOperand(0)); - Out << ");\n " << Mang->getValueName(&I) << " = va_arg(Tmp, "; - printType(Out, I.getType(), "", /*ignoreName*/false, /*namedContext*/false); - Out << ");\n va_end(Tmp); }"; -} - - -//===----------------------------------------------------------------------===// -// External Interface declaration -//===----------------------------------------------------------------------===// - -Pass *createWriteToCPass(std::ostream &o) { return new CWriter(o); } diff --git a/lib/Target/SparcV9/InstrSelection/InstrForest.cpp b/lib/Target/SparcV9/InstrSelection/InstrForest.cpp deleted file mode 100644 index 5496502d5e..0000000000 --- a/lib/Target/SparcV9/InstrSelection/InstrForest.cpp +++ /dev/null @@ -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; -} diff --git a/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp b/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp deleted file mode 100644 index 0e3e2cdbf2..0000000000 --- a/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp +++ /dev/null @@ -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); -} diff --git a/lib/Target/SparcV9/InstrSelection/InstrSelectionSupport.cpp b/lib/Target/SparcV9/InstrSelection/InstrSelectionSupport.cpp deleted file mode 100644 index 93f7618641..0000000000 --- a/lib/Target/SparcV9/InstrSelection/InstrSelectionSupport.cpp +++ /dev/null @@ -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; -} diff --git a/lib/Target/SparcV9/InstrSelection/Makefile b/lib/Target/SparcV9/InstrSelection/Makefile deleted file mode 100644 index b1dd1afb25..0000000000 --- a/lib/Target/SparcV9/InstrSelection/Makefile +++ /dev/null @@ -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 diff --git a/lib/Target/SparcV9/RegAlloc/IGNode.cpp b/lib/Target/SparcV9/RegAlloc/IGNode.cpp deleted file mode 100644 index f883fb13c1..0000000000 --- a/lib/Target/SparcV9/RegAlloc/IGNode.cpp +++ /dev/null @@ -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(); -} diff --git a/lib/Target/SparcV9/RegAlloc/IGNode.h b/lib/Target/SparcV9/RegAlloc/IGNode.h deleted file mode 100644 index 82f07e0c7e..0000000000 --- a/lib/Target/SparcV9/RegAlloc/IGNode.h +++ /dev/null @@ -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 diff --git a/lib/Target/SparcV9/RegAlloc/InterferenceGraph.cpp b/lib/Target/SparcV9/RegAlloc/InterferenceGraph.cpp deleted file mode 100644 index 392a96c11c..0000000000 --- a/lib/Target/SparcV9/RegAlloc/InterferenceGraph.cpp +++ /dev/null @@ -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"; - } - } -} diff --git a/lib/Target/SparcV9/RegAlloc/InterferenceGraph.h b/lib/Target/SparcV9/RegAlloc/InterferenceGraph.h deleted file mode 100644 index 6b8cf3cd05..0000000000 --- a/lib/Target/SparcV9/RegAlloc/InterferenceGraph.h +++ /dev/null @@ -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 diff --git a/lib/Target/SparcV9/RegAlloc/LiveRange.h b/lib/Target/SparcV9/RegAlloc/LiveRange.h deleted file mode 100644 index aa409c63fb..0000000000 --- a/lib/Target/SparcV9/RegAlloc/LiveRange.h +++ /dev/null @@ -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 diff --git a/lib/Target/SparcV9/RegAlloc/LiveRangeInfo.cpp b/lib/Target/SparcV9/RegAlloc/LiveRangeInfo.cpp deleted file mode 100644 index b9fcda789f..0000000000 --- a/lib/Target/SparcV9/RegAlloc/LiveRangeInfo.cpp +++ /dev/null @@ -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"; - } - } -} diff --git a/lib/Target/SparcV9/RegAlloc/LiveRangeInfo.h b/lib/Target/SparcV9/RegAlloc/LiveRangeInfo.h deleted file mode 100644 index 5c5244bd62..0000000000 --- a/lib/Target/SparcV9/RegAlloc/LiveRangeInfo.h +++ /dev/null @@ -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 diff --git a/lib/Target/SparcV9/RegAlloc/Makefile b/lib/Target/SparcV9/RegAlloc/Makefile deleted file mode 100644 index 6c4f50b358..0000000000 --- a/lib/Target/SparcV9/RegAlloc/Makefile +++ /dev/null @@ -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 diff --git a/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp b/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp deleted file mode 100644 index c89e5aa0c4..0000000000 --- a/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp +++ /dev/null @@ -1,1380 +0,0 @@ -//===-- PhyRegAlloc.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. -// -//===----------------------------------------------------------------------===// -// -// Traditional graph-coloring global register allocator currently used -// by the SPARC back-end. -// -// NOTE: This register allocator has some special support -// for the Reoptimizer, such as not saving some registers on calls to -// the first-level instrumentation function. -// -// NOTE 2: This register allocator can save its state in a global -// variable in the module it's working on. This feature is not -// thread-safe; if you have doubts, leave it turned off. -// -//===----------------------------------------------------------------------===// - -#include "IGNode.h" -#include "PhyRegAlloc.h" -#include "RegAllocCommon.h" -#include "RegClass.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/iOther.h" -#include "llvm/Module.h" -#include "llvm/Type.h" -#include "llvm/Analysis/LoopInfo.h" -#include "llvm/CodeGen/FunctionLiveVarInfo.h" -#include "llvm/CodeGen/InstrSelection.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFunctionInfo.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineInstrAnnot.h" -#include "llvm/CodeGen/Passes.h" -#include "llvm/Support/InstIterator.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "Support/CommandLine.h" -#include "Support/SetOperations.h" -#include "Support/STLExtras.h" -#include <cmath> - -RegAllocDebugLevel_t DEBUG_RA; - -static cl::opt<RegAllocDebugLevel_t, true> -DRA_opt("dregalloc", cl::Hidden, cl::location(DEBUG_RA), - cl::desc("enable register allocation debugging information"), - cl::values( - clEnumValN(RA_DEBUG_None , "n", "disable debug output"), - clEnumValN(RA_DEBUG_Results, "y", "debug output for allocation results"), - clEnumValN(RA_DEBUG_Coloring, "c", "debug output for graph coloring step"), - clEnumValN(RA_DEBUG_Interference,"ig","debug output for interference graphs"), - clEnumValN(RA_DEBUG_LiveRanges , "lr","debug output for live ranges"), - clEnumValN(RA_DEBUG_Verbose, "v", "extra debug output"), - 0)); - -static cl::opt<bool> -SaveRegAllocState("save-ra-state", cl::Hidden, - cl::desc("write reg. allocator state into module")); - -FunctionPass *getRegisterAllocator(TargetMachine &T) { - return new PhyRegAlloc (T); -} - -void PhyRegAlloc::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired<LoopInfo> (); - AU.addRequired<FunctionLiveVarInfo> (); -} - - -/// Initialize interference graphs (one in each reg class) and IGNodeLists -/// (one in each IG). The actual nodes will be pushed later. -/// -void PhyRegAlloc::createIGNodeListsAndIGs() { - if (DEBUG_RA >= RA_DEBUG_LiveRanges) std::cerr << "Creating LR lists ...\n"; - - LiveRangeMapType::const_iterator HMI = LRI->getLiveRangeMap()->begin(); - LiveRangeMapType::const_iterator HMIEnd = LRI->getLiveRangeMap()->end(); - - for (; HMI != HMIEnd ; ++HMI ) { - if (HMI->first) { - LiveRange *L = HMI->second; // get the LiveRange - if (!L) { - if (DEBUG_RA) - std::cerr << "\n**** ?!?WARNING: NULL LIVE RANGE FOUND FOR: " - << RAV(HMI->first) << "****\n"; - continue; - } - - // if the Value * is not null, and LR is not yet written to the IGNodeList - if (!(L->getUserIGNode()) ) { - RegClass *const RC = // RegClass of first value in the LR - RegClassList[ L->getRegClassID() ]; - RC->addLRToIG(L); // add this LR to an IG - } - } - } - - // init RegClassList - for ( unsigned rc=0; rc < NumOfRegClasses ; rc++) - RegClassList[rc]->createInterferenceGraph(); - - if (DEBUG_RA >= RA_DEBUG_LiveRanges) std::cerr << "LRLists Created!\n"; -} - - -/// Add all interferences for a given instruction. Interference occurs only -/// if the LR of Def (Inst or Arg) is of the same reg class as that of live -/// var. The live var passed to this function is the LVset AFTER the -/// instruction. -/// -void PhyRegAlloc::addInterference(const Value *Def, const ValueSet *LVSet, - bool isCallInst) { - ValueSet::const_iterator LIt = LVSet->begin(); - - // get the live range of instruction - const LiveRange *const LROfDef = LRI->getLiveRangeForValue( Def ); - - IGNode *const IGNodeOfDef = LROfDef->getUserIGNode(); - assert( IGNodeOfDef ); - - RegClass *const RCOfDef = LROfDef->getRegClass(); - - // for each live var in live variable set - for ( ; LIt != LVSet->end(); ++LIt) { - - if (DEBUG_RA >= RA_DEBUG_Verbose) - std::cerr << "< Def=" << RAV(Def) << ", Lvar=" << RAV(*LIt) << "> "; - - // get the live range corresponding to live var - LiveRange *LROfVar = LRI->getLiveRangeForValue(*LIt); - - // LROfVar can be null if it is a const since a const - // doesn't have a dominating def - see Assumptions above - if (LROfVar) - if (LROfDef != LROfVar) // do not set interf for same LR - if (RCOfDef == LROfVar->getRegClass()) // 2 reg classes are the same - RCOfDef->setInterference( LROfDef, LROfVar); - } -} - - -/// For a call instruction, this method sets the CallInterference flag in -/// the LR of each variable live in the Live Variable Set live after the -/// call instruction (except the return value of the call instruction - since -/// the return value does not interfere with that call itself). -/// -void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst, - const ValueSet *LVSetAft) { - if (DEBUG_RA >= RA_DEBUG_Interference) - std::cerr << "\n For call inst: " << *MInst; - - // for each live var in live variable set after machine inst - for (ValueSet::const_iterator LIt = LVSetAft->begin(), LEnd = LVSetAft->end(); - LIt != LEnd; ++LIt) { - - // get the live range corresponding to live var - LiveRange *const LR = LRI->getLiveRangeForValue(*LIt ); - - // LR can be null if it is a const since a const - // doesn't have a dominating def - see Assumptions above - if (LR ) { - if (DEBUG_RA >= RA_DEBUG_Interference) { - std::cerr << "\n\tLR after Call: "; - printSet(*LR); - } - LR->setCallInterference(); - if (DEBUG_RA >= RA_DEBUG_Interference) { - std::cerr << "\n ++After adding call interference for LR: " ; - printSet(*LR); - } - } - - } - - // Now find the LR of the return value of the call - // We do this because, we look at the LV set *after* the instruction - // to determine, which LRs must be saved across calls. The return value - // of the call is live in this set - but it does not interfere with call - // (i.e., we can allocate a volatile register to the return value) - CallArgsDescriptor* argDesc = CallArgsDescriptor::get(MInst); - - if (const Value *RetVal = argDesc->getReturnValue()) { - LiveRange *RetValLR = LRI->getLiveRangeForValue( RetVal ); - assert( RetValLR && "No LR for RetValue of call"); - RetValLR->clearCallInterference(); - } - - // If the CALL is an indirect call, find the LR of the function pointer. - // That has a call interference because it conflicts with outgoing args. - if (const Value *AddrVal = argDesc->getIndirectFuncPtr()) { - LiveRange *AddrValLR = LRI->getLiveRangeForValue( AddrVal ); - assert( AddrValLR && "No LR for indirect addr val of call"); - AddrValLR->setCallInterference(); - } -} - - -/// Create interferences in the IG of each RegClass, and calculate the spill -/// cost of each Live Range (it is done in this method to save another pass -/// over the code). -/// -void PhyRegAlloc::buildInterferenceGraphs() { - if (DEBUG_RA >= RA_DEBUG_Interference) - std::cerr << "Creating interference graphs ...\n"; - - unsigned BBLoopDepthCost; - for (MachineFunction::iterator BBI = MF->begin(), BBE = MF->end(); - BBI != BBE; ++BBI) { - const MachineBasicBlock &MBB = *BBI; - const BasicBlock *BB = MBB.getBasicBlock(); - - // find the 10^(loop_depth) of this BB - BBLoopDepthCost = (unsigned)pow(10.0, LoopDepthCalc->getLoopDepth(BB)); - - // get the iterator for machine instructions - MachineBasicBlock::const_iterator MII = MBB.begin(); - - // iterate over all the machine instructions in BB - for ( ; MII != MBB.end(); ++MII) { - const MachineInstr *MInst = *MII; - - // get the LV set after the instruction - const ValueSet &LVSetAI = LVI->getLiveVarSetAfterMInst(MInst, BB); - bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode()); - - if (isCallInst) { - // set the isCallInterference flag of each live range which extends - // across this call instruction. This information is used by graph - // coloring algorithm to avoid allocating volatile colors to live ranges - // that span across calls (since they have to be saved/restored) - setCallInterferences(MInst, &LVSetAI); - } - - // iterate over all MI operands to find defs - for (MachineInstr::const_val_op_iterator OpI = MInst->begin(), - OpE = MInst->end(); OpI != OpE; ++OpI) { - if (OpI.isDefOnly() || OpI.isDefAndUse()) // create a new LR since def - addInterference(*OpI, &LVSetAI, isCallInst); - - // Calculate the spill cost of each live range - LiveRange *LR = LRI->getLiveRangeForValue(*OpI); - if (LR) LR->addSpillCost(BBLoopDepthCost); - } - - // Mark all operands of pseudo-instructions as interfering with one - // another. This must be done because pseudo-instructions may be - // expanded to multiple instructions by the assembler, so all the - // operands must get distinct registers. - if (TM.getInstrInfo().isPseudoInstr(MInst->getOpCode())) - addInterf4PseudoInstr(MInst); - - // Also add interference for any implicit definitions in a machine - // instr (currently, only calls have this). - unsigned NumOfImpRefs = MInst->getNumImplicitRefs(); - for (unsigned z=0; z < NumOfImpRefs; z++) - if (MInst->getImplicitOp(z).opIsDefOnly() || - MInst->getImplicitOp(z).opIsDefAndUse()) - addInterference( MInst->getImplicitRef(z), &LVSetAI, isCallInst ); - - } // for all machine instructions in BB - } // for all BBs in function - - // add interferences for function arguments. Since there are no explicit - // defs in the function for args, we have to add them manually - addInterferencesForArgs(); - - if (DEBUG_RA >= RA_DEBUG_Interference) - std::cerr << "Interference graphs calculated!\n"; -} - - -/// Mark all operands of the given MachineInstr as interfering with one -/// another. -/// -void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) { - bool setInterf = false; - - // iterate over MI operands to find defs - for (MachineInstr::const_val_op_iterator It1 = MInst->begin(), - ItE = MInst->end(); It1 != ItE; ++It1) { - const LiveRange *LROfOp1 = LRI->getLiveRangeForValue(*It1); - assert((LROfOp1 || !It1.isUseOnly())&&"No LR for Def in PSEUDO insruction"); - - MachineInstr::const_val_op_iterator It2 = It1; - for (++It2; It2 != ItE; ++It2) { - const LiveRange *LROfOp2 = LRI->getLiveRangeForValue(*It2); - - if (LROfOp2) { - RegClass *RCOfOp1 = LROfOp1->getRegClass(); - RegClass *RCOfOp2 = LROfOp2->getRegClass(); - - if (RCOfOp1 == RCOfOp2 ){ - RCOfOp1->setInterference( LROfOp1, LROfOp2 ); - setInterf = true; - } - } // if Op2 has a LR - } // for all other defs in machine instr - } // for all operands in an instruction - - if (!setInterf && MInst->getNumOperands() > 2) { - std::cerr << "\nInterf not set for any operand in pseudo instr:\n"; - std::cerr << *MInst; - assert(0 && "Interf not set for pseudo instr with > 2 operands" ); - } -} - - -/// Add interferences for incoming arguments to a function. -/// -void PhyRegAlloc::addInterferencesForArgs() { - // get the InSet of root BB - const ValueSet &InSet = LVI->getInSetOfBB(&Fn->front()); - - for (Function::const_aiterator AI = Fn->abegin(); AI != Fn->aend(); ++AI) { - // add interferences between args and LVars at start - addInterference(AI, &InSet, false); - - if (DEBUG_RA >= RA_DEBUG_Interference) - std::cerr << " - %% adding interference for argument " << RAV(AI) << "\n"; - } -} - - -/// The following are utility functions used solely by updateMachineCode and -/// the functions that it calls. They should probably be folded back into -/// updateMachineCode at some point. -/// - -// used by: updateMachineCode (1 time), PrependInstructions (1 time) -inline void InsertBefore(MachineInstr* newMI, MachineBasicBlock& MBB, - MachineBasicBlock::iterator& MII) { - MII = MBB.insert(MII, newMI); - ++MII; -} - -// used by: AppendInstructions (1 time) -inline void InsertAfter(MachineInstr* newMI, MachineBasicBlock& MBB, - MachineBasicBlock::iterator& MII) { - ++MII; // insert before the next instruction - MII = MBB.insert(MII, newMI); -} - -// used by: updateMachineCode (1 time) -inline void DeleteInstruction(MachineBasicBlock& MBB, - MachineBasicBlock::iterator& MII) { - MII = MBB.erase(MII); -} - -// used by: updateMachineCode (1 time) -inline void SubstituteInPlace(MachineInstr* newMI, MachineBasicBlock& MBB, - MachineBasicBlock::iterator MII) { - *MII = newMI; -} - -// used by: updateMachineCode (2 times) -inline void PrependInstructions(std::vector<MachineInstr *> &IBef, - MachineBasicBlock& MBB, - MachineBasicBlock::iterator& MII, - const std::string& msg) { - if (!IBef.empty()) { - MachineInstr* OrigMI = *MII; - std::vector<MachineInstr *>::iterator AdIt; - for (AdIt = IBef.begin(); AdIt != IBef.end() ; ++AdIt) { - if (DEBUG_RA) { - if (OrigMI) std::cerr << "For MInst:\n " << *OrigMI; - std::cerr << msg << "PREPENDed instr:\n " << **AdIt << "\n"; - } - InsertBefore(*AdIt, MBB, MII); - } - } -} - -// used by: updateMachineCode (1 time) -inline void AppendInstructions(std::vector<MachineInstr *> &IAft, - MachineBasicBlock& MBB, - MachineBasicBlock::iterator& MII, - const std::string& msg) { - if (!IAft.empty()) { - MachineInstr* OrigMI = *MII; - std::vector<MachineInstr *>::iterator AdIt; - for ( AdIt = IAft.begin(); AdIt != IAft.end() ; ++AdIt ) { - if (DEBUG_RA) { - if (OrigMI) std::cerr << "For MInst:\n " << *OrigMI; - std::cerr << msg << "APPENDed instr:\n " << **AdIt << "\n"; - } - InsertAfter(*AdIt, MBB, MII); - } - } -} - -/// Set the registers for operands in the given MachineInstr, if a register was -/// successfully allocated. Return true if any of its operands has been marked -/// for spill. -/// -bool PhyRegAlloc::markAllocatedRegs(MachineInstr* MInst) -{ - bool instrNeedsSpills = false; - - // First, set the registers for operands in the machine instruction - // if a register was successfully allocated. Do this first because we - // will need to know which registers are already used by this instr'n. - for (unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) { - MachineOperand& Op = MInst->getOperand(OpNum); - if (Op.getType() == MachineOperand::MO_VirtualRegister || - Op.getType() == MachineOperand::MO_CCRegister) { - const Value *const Val = Op.getVRegValue(); - if (const LiveRange* LR = LRI->getLiveRangeForValue(Val)) { - // Remember if any operand needs spilling - instrNeedsSpills |= LR->isMarkedForSpill(); - - // An operand may have a color whether or not it needs spilling - if (LR->hasColor()) - MInst->SetRegForOperand(OpNum, - MRI.getUnifiedRegNum(LR->getRegClassID(), - LR->getColor())); - } - } - } // for each operand - - return instrNeedsSpills; -} - -/// Mark allocated registers (using markAllocatedRegs()) on the instruction -/// that MII points to. Then, if it's a call instruction, insert caller-saving -/// code before and after it. Finally, insert spill code before and after it, -/// using insertCode4SpilledLR(). -/// -void PhyRegAlloc::updateInstruction(MachineBasicBlock::iterator& MII, - MachineBasicBlock &MBB) { - MachineInstr* MInst = *MII; - unsigned Opcode = MInst->getOpCode(); - - // Reset tmp stack positions so they can be reused for each machine instr. - MF->getInfo()->popAllTempValues(); - - // Mark the operands for which regs have been allocated. - bool instrNeedsSpills = markAllocatedRegs(*MII); - -#ifndef NDEBUG - // Mark that the operands have been updated. Later, - // setRelRegsUsedByThisInst() is called to find registers used by each - // MachineInst, and it should not be used for an instruction until - // this is done. This flag just serves as a sanity check. - OperandsColoredMap[MInst] = true; -#endif - - // Now insert caller-saving code before/after the call. - // Do this before inserting spill code since some registers must be - // used by save/restore and spill code should not use those registers. - if (TM.getInstrInfo().isCall(Opcode)) { - AddedInstrns &AI = AddedInstrMap[MInst]; - insertCallerSavingCode(AI.InstrnsBefore, AI.InstrnsAfter, MInst, - MBB.getBasicBlock()); - } - - // Now insert spill code for remaining operands not allocated to - // registers. This must be done even for call return instructions - // since those are not handled by the special code above. - if (instrNeedsSpills) - for (unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) { - MachineOperand& Op = MInst->getOperand(OpNum); - if (Op.getType() == MachineOperand::MO_VirtualRegister || - Op.getType() == MachineOperand::MO_CCRegister) { - const Value* Val = Op.getVRegValue(); - if (const LiveRange *LR = LRI->getLiveRangeForValue(Val)) - if (LR->isMarkedForSpill()) - insertCode4SpilledLR(LR, MII, MBB, OpNum); - } - } // for each operand -} - -/// Iterate over all the MachineBasicBlocks in the current function and set -/// the allocated registers for each instruction (using updateInstruction()), -/// after register allocation is complete. Then move code out of delay slots. -/// -void PhyRegAlloc::updateMachineCode() -{ - // Insert any instructions needed at method entry - MachineBasicBlock::iterator MII = MF->front().begin(); - PrependInstructions(AddedInstrAtEntry.InstrnsBefore, MF->front(), MII, - "At function entry: \n"); - assert(AddedInstrAtEntry.InstrnsAfter.empty() && - "InstrsAfter should be unnecessary since we are just inserting at " - "the function entry point here."); - - for (MachineFunction::iterator BBI = MF->begin(), BBE = MF->end(); - BBI != BBE; ++BBI) { - MachineBasicBlock &MBB = *BBI; - - // Iterate over all machine instructions in BB and mark operands with - // their assigned registers or insert spill code, as appropriate. - // Also, fix operands of call/return instructions. - for (MachineBasicBlock::iterator MII = MBB.begin(); MII != MBB.end(); ++MII) - if (! TM.getInstrInfo().isDummyPhiInstr((*MII)->getOpCode())) - updateInstruction(MII, MBB); - - // Now, move code out of delay slots of branches and returns if needed. - // (Also, move "after" code from calls to the last delay slot instruction.) - // Moving code out of delay slots is needed in 2 situations: - // (1) If this is a branch and it needs instructions inserted after it, - // move any existing instructions out of the delay slot so that the - // instructions can go into the delay slot. This only supports the - // case that #instrsAfter <= #delay slots. - // - // (2) If any instruction in the delay slot needs - // instructions inserted, move it out of the delay slot and before the - // branch because putting code before or after it would be VERY BAD! - // - // If the annul bit of the branch is set, neither of these is legal! - // If so, we need to handle spill differently but annulling is not yet used. - for (MachineBasicBlock::iterator MII = MBB.begin(); - MII != MBB.end(); ++MII) - if (unsigned delaySlots = - TM.getInstrInfo().getNumDelaySlots((*MII)->getOpCode())) { - MachineInstr *MInst = *MII, *DelaySlotMI = *(MII+1); - - // Check the 2 conditions above: - // (1) Does a branch need instructions added after it? - // (2) O/w does delay slot instr. need instrns before or after? - bool isBranch = (TM.getInstrInfo().isBranch(MInst->getOpCode()) || - TM.getInstrInfo().isReturn(MInst->getOpCode())); - bool cond1 = (isBranch && - AddedInstrMap.count(MInst) && - AddedInstrMap[MInst].InstrnsAfter.size() > 0); - bool cond2 = (AddedInstrMap.count(DelaySlotMI) && - (AddedInstrMap[DelaySlotMI].InstrnsBefore.size() > 0 || - AddedInstrMap[DelaySlotMI].InstrnsAfter.size() > 0)); - - if (cond1 || cond2) { - assert((MInst->getOpCodeFlags() & AnnulFlag) == 0 && - "FIXME: Moving an annulled delay slot instruction!"); - assert(delaySlots==1 && - "InsertBefore does not yet handle >1 delay slots!"); - InsertBefore(DelaySlotMI, MBB, MII); // MII pts back to branch - - // In case (1), delete it and don't replace with anything! - // Otherwise (i.e., case (2) only) replace it with a NOP. - if (cond1) { - DeleteInstruction(MBB, ++MII); // MII now points to next inst. - --MII; // reset MII for ++MII of loop - } - else - SubstituteInPlace(BuildMI(TM.getInstrInfo().getNOPOpCode(),1), - MBB, MII+1); // replace with NOP - - if (DEBUG_RA) { - std::cerr << "\nRegAlloc: Moved instr. with added code: " - << *DelaySlotMI - << " out of delay slots of instr: " << *MInst; - } - } - else - // For non-branch instr with delay slots (probably a call), move - // InstrAfter to the instr. in the last delay slot. - move2DelayedInstr(*MII, *(MII+delaySlots)); - } - - // Finally iterate over all instructions in BB and insert before/after - for (MachineBasicBlock::iterator MII=MBB.begin(); MII != MBB.end(); ++MII) { - MachineInstr *MInst = *MII; - - // do not process Phis - if (TM.getInstrInfo().isDummyPhiInstr(MInst->getOpCode())) - continue; - - // if there are any added instructions... - if (AddedInstrMap.count(MInst)) { - AddedInstrns &CallAI = AddedInstrMap[MInst]; - -#ifndef NDEBUG - bool isBranch = (TM.getInstrInfo().isBranch(MInst->getOpCode()) || - TM.getInstrInfo().isReturn(MInst->getOpCode())); - assert((!isBranch || - AddedInstrMap[MInst].InstrnsAfter.size() <= - TM.getInstrInfo().getNumDelaySlots(MInst->getOpCode())) && - "Cannot put more than #delaySlots instrns after " - "branch or return! Need to handle temps differently."); -#endif - -#ifndef NDEBUG - // Temporary sanity checking code to detect whether the same machine - // instruction is ever inserted twice before/after a call. - // I suspect this is happening but am not sure. --Vikram, 7/1/03. - std::set<const MachineInstr*> instrsSeen; - for (int i = 0, N = CallAI.InstrnsBefore.size(); i < N; ++i) { - assert(instrsSeen.count(CallAI.InstrnsBefore[i]) == 0 && - "Duplicate machine instruction in InstrnsBefore!"); - instrsSeen.insert(CallAI.InstrnsBefore[i]); - } - for (int i = 0, N = CallAI.InstrnsAfter.size(); i < N; ++i) { - assert(instrsSeen.count(CallAI.InstrnsAfter[i]) == 0 && - "Duplicate machine instruction in InstrnsBefore/After!"); - instrsSeen.insert(CallAI.InstrnsAfter[i]); - } -#endif - - // Now add the instructions before/after this MI. - // We do this here to ensure that spill for an instruction is inserted - // as close as possible to an instruction (see above insertCode4Spill) - if (! CallAI.InstrnsBefore.empty()) - PrependInstructions(CallAI.InstrnsBefore, MBB, MII,""); - - if (! CallAI.InstrnsAfter.empty()) - AppendInstructions(CallAI.InstrnsAfter, MBB, MII,""); - - } // if there are any added instructions - } // for each machine instruction - } -} - - -/// Insert spill code for AN operand whose LR was spilled. May be called -/// repeatedly for a single MachineInstr if it has many spilled operands. On -/// each call, it finds a register which is not live at that instruction and -/// also which is not used by other spilled operands of the same -/// instruction. Then it uses this register temporarily to accommodate the -/// spilled value. -/// -void PhyRegAlloc::insertCode4SpilledLR(const LiveRange *LR, - MachineBasicBlock::iterator& MII, - MachineBasicBlock &MBB, - const unsigned OpNum) { - MachineInstr *MInst = *MII; - const BasicBlock *BB = MBB.getBasicBlock(); - - assert((! TM.getInstrInfo().isCall(MInst->getOpCode()) || OpNum == 0) && - "Outgoing arg of a call must be handled elsewhere (func arg ok)"); - assert(! TM.getInstrInfo().isReturn(MInst->getOpCode()) && - "Return value of a ret must be handled elsewhere"); - - MachineOperand& Op = MInst->getOperand(OpNum); - bool isDef = Op.opIsDefOnly(); - bool isDefAndUse = Op.opIsDefAndUse(); - unsigned RegType = MRI.getRegTypeForLR(LR); - int SpillOff = LR->getSpillOffFromFP(); - RegClass *RC = LR->getRegClass(); - - // Get the live-variable set to find registers free before this instr. - const ValueSet &LVSetBef = LVI->getLiveVarSetBeforeMInst(MInst, BB); - -#ifndef NDEBUG - // If this instr. is in the delay slot of a branch or return, we need to - // include all live variables before that branch or return -- we don't want to - // trample those! Verify that the set is included in the LV set before MInst. - if (MII != MBB.begin()) { - MachineInstr *PredMI = *(MII-1); - if (unsigned DS = TM.getInstrInfo().getNumDelaySlots(PredMI->getOpCode())) - assert(set_difference(LVI->getLiveVarSetBeforeMInst(PredMI), LVSetBef) - .empty() && "Live-var set before branch should be included in " - "live-var set of each delay slot instruction!"); - } -#endif - - MF->getInfo()->pushTempValue(MRI.getSpilledRegSize(RegType)); - - std::vector<MachineInstr*> MIBef, MIAft; - std::vector<MachineInstr*> AdIMid; - - // Choose a register to hold the spilled value, if one was not preallocated. - // This may insert code before and after MInst to free up the value. If so, - // this code should be first/last in the spill sequence before/after MInst. - int TmpRegU=(LR->hasColor() - ? MRI.getUnifiedRegNum(LR->getRegClassID(),LR->getColor()) - : getUsableUniRegAtMI(RegType, &LVSetBef, MInst, MIBef,MIAft)); - - // Set the operand first so that it this register does not get used - // as a scratch register for later calls to getUsableUniRegAtMI below - MInst->SetRegForOperand(OpNum, TmpRegU); - - // get the added instructions for this instruction - AddedInstrns &AI = AddedInstrMap[MInst]; - - // We may need a scratch register to copy the spilled value to/from memory. - // This may itself have to insert code to free up a scratch register. - // Any such code should go before (after) the spill code for a load (store). - // The scratch reg is not marked as used because it is only used - // for the copy and not used across MInst. - int scratchRegType = -1; - int scratchReg = -1; - if (MRI.regTypeNeedsScratchReg(RegType, scratchRegType)) { - scratchReg = getUsableUniRegAtMI(scratchRegType, &LVSetBef, - MInst, MIBef, MIAft); - assert(scratchReg != MRI.getInvalidRegNum()); - } - - if (!isDef || isDefAndUse) { - // for a USE, we have to load the value of LR from stack to a TmpReg - // and use the TmpReg as one operand of instruction - - // actual loading instruction(s) - MRI.cpMem2RegMI(AdIMid, MRI.getFramePointer(), SpillOff, TmpRegU, - RegType, scratchReg); - - // the actual load should be after the instructions to free up TmpRegU - MIBef.insert(MIBef.end(), AdIMid.begin(), AdIMid.end()); - AdIMid.clear(); - } - - if (isDef || isDefAndUse) { // if this is a Def - // for a DEF, we have to store the value produced by this instruction - // on the stack position allocated for this LR - - // actual storing instruction(s) - MRI.cpReg2MemMI(AdIMid, TmpRegU, MRI.getFramePointer(), SpillOff, - RegType, scratchReg); - - MIAft.insert(MIAft.begin(), AdIMid.begin(), AdIMid.end()); - } // if !DEF - - // Finally, insert the entire spill code sequences before/after MInst - AI.InstrnsBefore.insert(AI.InstrnsBefore.end(), MIBef.begin(), MIBef.end()); - AI.InstrnsAfter.insert(AI.InstrnsAfter.begin(), MIAft.begin(), MIAft.end()); - - if (DEBUG_RA) { - std::cerr << "\nFor Inst:\n " << *MInst; - std::cerr << "SPILLED LR# " << LR->getUserIGNode()->getIndex(); - std::cerr << "; added Instructions:"; - for_each(MIBef.begin(), MIBef.end(), std::mem_fun(&MachineInstr::dump)); - for_each(MIAft.begin(), MIAft.end(), std::mem_fun(&MachineInstr::dump)); - } -} - - -/// Insert caller saving/restoring instructions before/after a call machine -/// instruction (before or after any other instructions that were inserted for -/// the call). -/// -void -PhyRegAlloc::insertCallerSavingCode(std::vector<MachineInstr*> &instrnsBefore, - std::vector<MachineInstr*> &instrnsAfter, - MachineInstr *CallMI, - const BasicBlock *BB) { - assert(TM.getInstrInfo().isCall(CallMI->getOpCode())); - - // hash set to record which registers were saved/restored - hash_set<unsigned> PushedRegSet; - - CallArgsDescriptor* argDesc = CallArgsDescriptor::get(CallMI); - - // if the call is to a instrumentation function, do not insert save and - // restore instructions the instrumentation function takes care of save - // restore for volatile regs. - // - // FIXME: this should be made general, not specific to the reoptimizer! - const Function *Callee = argDesc->getCallInst()->getCalledFunction(); - bool isLLVMFirstTrigger = Callee && Callee->getName() == "llvm_first_trigger"; - - // Now check if the call has a return value (using argDesc) and if so, - // find the LR of the TmpInstruction representing the return value register. - // (using the last or second-last *implicit operand* of the call MI). - // Insert it to to the PushedRegSet since we must not save that register - // and restore it after the call. - // We do this because, we look at the LV set *after* the instruction - // to determine, which LRs must be saved across calls. The return value - // of the call is live in this set - but we must not save/restore it. - if (const Value *origRetVal = argDesc->getReturnValue()) { - unsigned retValRefNum = (CallMI->getNumImplicitRefs() - - (argDesc->getIndirectFuncPtr()? 1 : 2)); - const TmpInstruction* tmpRetVal = - cast<TmpInstruction>(CallMI->getImplicitRef(retValRefNum)); - assert(tmpRetVal->getOperand(0) == origRetVal && - tmpRetVal->getType() == origRetVal->getType() && - "Wrong implicit ref?"); - LiveRange *RetValLR = LRI->getLiveRangeForValue(tmpRetVal); - assert(RetValLR && "No LR for RetValue of call"); - - if (! RetValLR->isMarkedForSpill()) - PushedRegSet.insert(MRI.getUnifiedRegNum(RetValLR->getRegClassID(), - RetValLR->getColor())); - } - - const ValueSet &LVSetAft = LVI->getLiveVarSetAfterMInst(CallMI, BB); - ValueSet::const_iterator LIt = LVSetAft.begin(); - - // for each live var in live variable set after machine inst - for( ; LIt != LVSetAft.end(); ++LIt) { - // get the live range corresponding to live var - LiveRange *const LR = LRI->getLiveRangeForValue(*LIt); - - // LR can be null if it is a const since a const - // doesn't have a dominating def - see Assumptions above - if (LR) { - if (! LR->isMarkedForSpill()) { - assert(LR->hasColor() && "LR is neither spilled nor colored?"); - unsigned RCID = LR->getRegClassID(); - unsigned Color = LR->getColor(); - - if (MRI.isRegVolatile(RCID, Color) ) { - // if this is a call to the first-level reoptimizer - // instrumentation entry point, and the register is not - // modified by call, don't save and restore it. - if (isLLVMFirstTrigger && !MRI.modifiedByCall(RCID, Color)) - continue; - - // if the value is in both LV sets (i.e., live before and after - // the call machine instruction) - unsigned Reg = MRI.getUnifiedRegNum(RCID, Color); - - // if we haven't already pushed this register... - if( PushedRegSet.find(Reg) == PushedRegSet.end() ) { - unsigned RegType = MRI.getRegTypeForLR(LR); - - // Now get two instructions - to push on stack and pop from stack - // and add them to InstrnsBefore and InstrnsAfter of the - // call instruction - int StackOff = - MF->getInfo()->pushTempValue(MRI.getSpilledRegSize(RegType)); - - //---- Insert code for pushing the reg on stack ---------- - - std::vector<MachineInstr*> AdIBef, AdIAft; - - // We may need a scratch register to copy the saved value - // to/from memory. This may itself have to insert code to - // free up a scratch register. Any such code should go before - // the save code. The scratch register, if any, is by default - // temporary and not "used" by the instruction unless the - // copy code itself decides to keep the value in the scratch reg. - int scratchRegType = -1; - int scratchReg = -1; - if (MRI.regTypeNeedsScratchReg(RegType, scratchRegType)) - { // Find a register not live in the LVSet before CallMI - const ValueSet &LVSetBef = - LVI->getLiveVarSetBeforeMInst(CallMI, BB); - scratchReg = getUsableUniRegAtMI(scratchRegType, &LVSetBef, - CallMI, AdIBef, AdIAft); - assert(scratchReg != MRI.getInvalidRegNum()); - } - - if (AdIBef.size() > 0) - instrnsBefore.insert(instrnsBefore.end(), - AdIBef.begin(), AdIBef.end()); - - MRI.cpReg2MemMI(instrnsBefore, Reg, MRI.getFramePointer(), - StackOff, RegType, scratchReg); - - if (AdIAft.size() > 0) - instrnsBefore.insert(instrnsBefore.end(), - AdIAft.begin(), AdIAft.end()); - - //---- Insert code for popping the reg from the stack ---------- - AdIBef.clear(); - AdIAft.clear(); - - // We may need a scratch register to copy the saved value - // from memory. This may itself have to insert code to - // free up a scratch register. Any such code should go - // after the save code. As above, scratch is not marked "used". - scratchRegType = -1; - scratchReg = -1; - if (MRI.regTypeNeedsScratchReg(RegType, scratchRegType)) - { // Find a register not live in the LVSet after CallMI - scratchReg = getUsableUniRegAtMI(scratchRegType, &LVSetAft, - CallMI, AdIBef, AdIAft); - assert(scratchReg != MRI.getInvalidRegNum()); - } - - if (AdIBef.size() > 0) - instrnsAfter.insert(instrnsAfter.end(), - AdIBef.begin(), AdIBef.end()); - - MRI.cpMem2RegMI(instrnsAfter, MRI.getFramePointer(), StackOff, - Reg, RegType, scratchReg); - - if (AdIAft.size() > 0) - instrnsAfter.insert(instrnsAfter.end(), - AdIAft.begin(), AdIAft.end()); - - PushedRegSet.insert(Reg); - - if(DEBUG_RA) { - std::cerr << "\nFor call inst:" << *CallMI; - std::cerr << " -inserted caller saving instrs: Before:\n\t "; - for_each(instrnsBefore.begin(), instrnsBefore.end(), - std::mem_fun(&MachineInstr::dump)); - std::cerr << " -and After:\n\t "; - for_each(instrnsAfter.begin(), instrnsAfter.end(), - std::mem_fun(&MachineInstr::dump)); - } - } // if not already pushed - } // if LR has a volatile color - } // if LR has color - } // if there is a LR for Var - } // for each value in the LV set after instruction -} - - -/// Returns the unified register number of a temporary register to be used -/// BEFORE MInst. If no register is available, it will pick one and modify -/// MIBef and MIAft to contain instructions used to free up this returned -/// register. -/// -int PhyRegAlloc::getUsableUniRegAtMI(const int RegType, - const ValueSet *LVSetBef, - MachineInstr *MInst, - std::vector<MachineInstr*>& MIBef, - std::vector<MachineInstr*>& MIAft) { - RegClass* RC = getRegClassByID(MRI.getRegClassIDOfRegType(RegType)); - - int RegU = getUnusedUniRegAtMI(RC, RegType, MInst, LVSetBef); - - if (RegU == -1) { - // we couldn't find an unused register. Generate code to free up a reg by - // saving it on stack and restoring after the instruction - - int TmpOff = MF->getInfo()->pushTempValue(MRI.getSpilledRegSize(RegType)); - - RegU = getUniRegNotUsedByThisInst(RC, RegType, MInst); - - // Check if we need a scratch register to copy this register to memory. - int scratchRegType = -1; - if (MRI.regTypeNeedsScratchReg(RegType, scratchRegType)) { - int scratchReg = getUsableUniRegAtMI(scratchRegType, LVSetBef, - MInst, MIBef, MIAft); - assert(scratchReg != MRI.getInvalidRegNum()); - - // We may as well hold the value in the scratch register instead - // of copying it to memory and back. But we have to mark the - // register as used by this instruction, so it does not get used - // as a scratch reg. by another operand or anyone else. - ScratchRegsUsed.insert(std::make_pair(MInst, scratchReg)); - MRI.cpReg2RegMI(MIBef, RegU, scratchReg, RegType); - MRI.cpReg2RegMI(MIAft, scratchReg, RegU, RegType); - } else { // the register can be copied directly to/from memory so do it. - MRI.cpReg2MemMI(MIBef, RegU, MRI.getFramePointer(), TmpOff, RegType); - MRI.cpMem2RegMI(MIAft, MRI.getFramePointer(), TmpOff, RegU, RegType); - } - } - - return RegU; -} - - -/// Returns the register-class register number of a new unused register that -/// can be used to accommodate a temporary value. May be called repeatedly -/// for a single MachineInstr. On each call, it finds a register which is not -/// live at that instruction and which is not used by any spilled operands of -/// that instruction. -/// -int PhyRegAlloc::getUnusedUniRegAtMI(RegClass *RC, const int RegType, - const MachineInstr *MInst, - const ValueSet* LVSetBef) { - RC->clearColorsUsed(); // Reset array - - if (LVSetBef == NULL) { - LVSetBef = &LVI->getLiveVarSetBeforeMInst(MInst); - assert(LVSetBef != NULL && "Unable to get live-var set before MInst?"); - } - - ValueSet::const_iterator LIt = LVSetBef->begin(); - - // for each live var in live variable set after machine inst - for ( ; LIt != LVSetBef->end(); ++LIt) { - // Get the live range corresponding to live var, and its RegClass - LiveRange *const LRofLV = LRI->getLiveRangeForValue(*LIt ); - - // LR can be null if it is a const since a const - // doesn't have a dominating def - see Assumptions above - if (LRofLV && LRofLV->getRegClass() == RC && LRofLV->hasColor()) - RC->markColorsUsed(LRofLV->getColor(), - MRI.getRegTypeForLR(LRofLV), RegType); - } - - // It is possible that one operand of this MInst was already spilled - // and it received some register temporarily. If that's the case, - // it is recorded in machine operand. We must skip such registers. - setRelRegsUsedByThisInst(RC, RegType, MInst); - - int unusedReg = RC->getUnusedColor(RegType); // find first unused color - if (unusedReg >= 0) - return MRI.getUnifiedRegNum(RC->getID(), unusedReg); - - return -1; -} - - -/// Return the unified register number of a register in class RC which is not -/// used by any operands of MInst. -/// -int PhyRegAlloc::getUniRegNotUsedByThisInst(RegClass *RC, - const int RegType, - const MachineInstr *MInst) { - RC->clearColorsUsed(); - - setRelRegsUsedByThisInst(RC, RegType, MInst); - - // find the first unused color - int unusedReg = RC->getUnusedColor(RegType); - assert(unusedReg >= 0 && - "FATAL: No free register could be found in reg class!!"); - - return MRI.getUnifiedRegNum(RC->getID(), unusedReg); -} - - -/// Modify the IsColorUsedArr of register class RC, by setting the bits -/// corresponding to register RegNo. This is a helper method of -/// setRelRegsUsedByThisInst(). -/// -static void markRegisterUsed(int RegNo, RegClass *RC, int RegType, - const TargetRegInfo &TRI) { - unsigned classId = 0; - int classRegNum = TRI.getClassRegNum(RegNo, classId); - if (RC->getID() == classId) - RC->markColorsUsed(classRegNum, RegType, RegType); -} - -void PhyRegAlloc::setRelRegsUsedByThisInst(RegClass *RC, int RegType, - const MachineInstr *MI) { - assert(OperandsColoredMap[MI] == true && - "Illegal to call setRelRegsUsedByThisInst() until colored operands " - "are marked for an instruction."); - - // Add the registers already marked as used by the instruction. Both - // explicit and implicit operands are set. - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) - if (MI->getOperand(i).hasAllocatedReg()) - markRegisterUsed(MI->getOperand(i).getAllocatedRegNum(), RC, RegType,MRI); - - for (unsigned i = 0, e = MI->getNumImplicitRefs(); i != e; ++i) - if (MI->getImplicitOp(i).hasAllocatedReg()) - markRegisterUsed(MI->getImplicitOp(i).getAllocatedRegNum(), RC, - RegType,MRI); - - // Add all of the scratch registers that are used to save values across the - // instruction (e.g., for saving state register values). - std::pair<ScratchRegsUsedTy::iterator, ScratchRegsUsedTy::iterator> - IR = ScratchRegsUsed.equal_range(MI); - for (ScratchRegsUsedTy::iterator I = IR.first; I != IR.second; ++I) - markRegisterUsed(I->second, RC, RegType, MRI); - - // If there are implicit references, mark their allocated regs as well - for (unsigned z=0; z < MI->getNumImplicitRefs(); z++) - if (const LiveRange* - LRofImpRef = LRI->getLiveRangeForValue(MI->getImplicitRef(z))) - if (LRofImpRef->hasColor()) - // this implicit reference is in a LR that received a color - RC->markColorsUsed(LRofImpRef->getColor(), - MRI.getRegTypeForLR(LRofImpRef), RegType); -} - - -/// If there are delay slots for an instruction, the instructions added after -/// it must really go after the delayed instruction(s). So, we Move the -/// InstrAfter of that instruction to the corresponding delayed instruction -/// using the following method. -/// -void PhyRegAlloc::move2DelayedInstr(const MachineInstr *OrigMI, - const MachineInstr *DelayedMI) -{ - // "added after" instructions of the original instr - std::vector<MachineInstr *> &OrigAft = AddedInstrMap[OrigMI].InstrnsAfter; - - if (DEBUG_RA && OrigAft.size() > 0) { - std::cerr << "\nRegAlloc: Moved InstrnsAfter for: " << *OrigMI; - std::cerr << " to last delay slot instrn: " << *DelayedMI; - } - - // "added after" instructions of the delayed instr - std::vector<MachineInstr *> &DelayedAft=AddedInstrMap[DelayedMI].InstrnsAfter; - - // go thru all the "added after instructions" of the original instruction - // and append them to the "added after instructions" of the delayed - // instructions - DelayedAft.insert(DelayedAft.end(), OrigAft.begin(), OrigAft.end()); - - // empty the "added after instructions" of the original instruction - OrigAft.clear(); -} - - -void PhyRegAlloc::colorIncomingArgs() -{ - MRI.colorMethodArgs(Fn, *LRI, AddedInstrAtEntry.InstrnsBefore, - AddedInstrAtEntry.InstrnsAfter); -} - - -/// Determine whether the suggested color of each live range is really usable, -/// and then call its setSuggestedColorUsable() method to record the answer. A -/// suggested color is NOT usable when the suggested color is volatile AND -/// when there are call interferences. -/// -void PhyRegAlloc::markUnusableSugColors() -{ - LiveRangeMapType::const_iterator HMI = (LRI->getLiveRangeMap())->begin(); - LiveRangeMapType::const_iterator HMIEnd = (LRI->getLiveRangeMap())->end(); - - for (; HMI != HMIEnd ; ++HMI ) { - if (HMI->first) { - LiveRange *L = HMI->second; // get the LiveRange - if (L && L->hasSuggestedColor ()) - L->setSuggestedColorUsable - (!(MRI.isRegVolatile (L->getRegClassID (), L->getSuggestedColor ()) - && L->isCallInterference ())); - } - } // for all LR's in hash map -} - - -/// For each live range that is spilled, allocates a new spill position on the -/// stack, and set the stack offsets of the live range that will be spilled to -/// that position. This must be called just after coloring the LRs. -/// -void PhyRegAlloc::allocateStackSpace4SpilledLRs() { - if (DEBUG_RA) std::cerr << "\nSetting LR stack offsets for spills...\n"; - - LiveRangeMapType::const_iterator HMI = LRI->getLiveRangeMap()->begin(); - LiveRangeMapType::const_iterator HMIEnd = LRI->getLiveRangeMap()->end(); - - for ( ; HMI != HMIEnd ; ++HMI) { - if (HMI->first && HMI->second) { - LiveRange *L = HMI->second; // get the LiveRange - if (L->isMarkedForSpill()) { // NOTE: allocating size of long Type ** - int stackOffset = MF->getInfo()->allocateSpilledValue(Type::LongTy); - L->setSpillOffFromFP(stackOffset); - if (DEBUG_RA) - std::cerr << " LR# " << L->getUserIGNode()->getIndex() - << ": stack-offset = " << stackOffset << "\n"; - } - } - } // for all LR's in hash map -} - - -namespace { - /// AllocInfo - Structure representing one instruction's - /// operand's-worth of register allocation state. We create tables - /// made out of these data structures to generate mapping information - /// for this register allocator. (FIXME: This might move to a header - /// file at some point.) - /// - struct AllocInfo { - unsigned Instruction; - unsigned Operand; - unsigned AllocState; - int Placement; - AllocInfo (unsigned Instruction_, unsigned Operand_, - unsigned AllocState_, int Placement_) : - Instruction (Instruction_), Operand (Operand_), - AllocState (AllocState_), Placement (Placement_) { } - /// getConstantType - Return a StructType representing an AllocInfo - /// object. - /// - static StructType *getConstantType () { - std::vector<const Type *> TV; - TV.push_back (Type::UIntTy); - TV.push_back (Type::UIntTy); - TV.push_back (Type::UIntTy); - TV.push_back (Type::IntTy); - return StructType::get (TV); - } - /// toConstant - Convert this AllocInfo into an LLVM Constant of type - /// getConstantType(), and return the Constant. - /// - Constant *toConstant () const { - StructType *ST = getConstantType (); - std::vector<Constant *> CV; - CV.push_back (ConstantUInt::get (Type::UIntTy, Instruction)); - CV.push_back (ConstantUInt::get (Type::UIntTy, Operand)); - CV.push_back (ConstantUInt::get (Type::UIntTy, AllocState)); - CV.push_back (ConstantSInt::get (Type::IntTy, Placement)); - return ConstantStruct::get (ST, CV); - } - }; -} - -/// Save the global register allocation decisions made by the register -/// allocator so that they can be accessed later (sort of like "poor man's -/// debug info"). -/// -void PhyRegAlloc::saveState () { - std::vector<Constant *> &state = FnAllocState[Fn]; - unsigned Insn = 0; - LiveRangeMapType::const_iterator HMIEnd = LRI->getLiveRangeMap ()->end (); - for (const_inst_iterator II=inst_begin (Fn), IE=inst_end (Fn); II != IE; ++II) - for (unsigned i = 0; i < (*II)->getNumOperands (); ++i) { - const Value *V = (*II)->getOperand (i); - // Don't worry about it unless it's something whose reg. we'll need. - if (!isa<Argument> (V) && !isa<Instruction> (V)) - continue; - LiveRangeMapType::const_iterator HMI = LRI->getLiveRangeMap ()->find (V); - static const unsigned NotAllocated = 0, Allocated = 1, Spilled = 2; - unsigned AllocState = NotAllocated; - int Placement = -1; - if ((HMI != HMIEnd) && HMI->second) { - LiveRange *L = HMI->second; - assert ((L->hasColor () || L->isMarkedForSpill ()) - && "Live range exists but not colored or spilled"); - if (L->hasColor()) { - AllocState = Allocated; - Placement = MRI.getUnifiedRegNum (L->getRegClassID (), - L->getColor ()); - } else if (L->isMarkedForSpill ()) { - AllocState = Spilled; - assert (L->hasSpillOffset () - && "Live range marked for spill but has no spill offset"); - Placement = L->getSpillOffFromFP (); - } - } - state.push_back (AllocInfo (Insn, i, AllocState, - Placement).toConstant ()); - } -} - -/// Check the saved state filled in by saveState(), and abort if it looks -/// wrong. Only used when debugging. -/// -void PhyRegAlloc::verifySavedState () { - /// not yet implemented -} - -bool PhyRegAlloc::doFinalization (Module &M) { - if (!SaveRegAllocState) - return false; // Nothing to do here, unless we're saving state. - - // Convert FnAllocState to a single Constant array and add it - // to the Module. - ArrayType *AT = ArrayType::get (AllocInfo::getConstantType (), 0); - std::vector<const Type *> TV; - TV.push_back (Type::UIntTy); - TV.push_back (AT); - PointerType *PT = PointerType::get (StructType::get (TV)); - - std::vector<Constant *> allstate; - for (Module::iterator I = M.begin (), E = M.end (); I != E; ++I) { - Function *F = I; - if (FnAllocState.find (F) == FnAllocState.end ()) { - allstate.push_back (ConstantPointerNull::get (PT)); - } else { - std::vector<Constant *> &state = FnAllocState[F]; - - // Convert state into an LLVM ConstantArray, and put it in a - // ConstantStruct (named S) along with its size. - unsigned Size = state.size (); - ArrayType *AT = ArrayType::get (AllocInfo::getConstantType (), Size); - std::vector<const Type *> TV; - TV.push_back (Type::UIntTy); - TV.push_back (AT); - StructType *ST = StructType::get (TV); - std::vector<Constant *> CV; - CV.push_back (ConstantUInt::get (Type::UIntTy, Size)); - CV.push_back (ConstantArray::get (AT, state)); - Constant *S = ConstantStruct::get (ST, CV); - - GlobalVariable *GV = - new GlobalVariable (ST, true, - GlobalValue::InternalLinkage, S, - F->getName () + ".regAllocState", &M); - - // Have: { uint, [Size x { uint, uint, uint, int }] } * - // Cast it to: { uint, [0 x { uint, uint, uint, int }] } * - Constant *CE = ConstantExpr::getCast (ConstantPointerRef::get (GV), PT); - allstate.push_back (CE); - } - } - - unsigned Size = allstate.size (); - // Final structure type is: - // { uint, [Size x { uint, [0 x { uint, uint, uint, int }] } *] } - std::vector<const Type *> TV2; - TV2.push_back (Type::UIntTy); - ArrayType *AT2 = ArrayType::get (PT, Size); - TV2.push_back (AT2); - StructType *ST2 = StructType::get (TV2); - std::vector<Constant *> CV2; - CV2.push_back (ConstantUInt::get (Type::UIntTy, Size)); - CV2.push_back (ConstantArray::get (AT2, allstate)); - new GlobalVariable (ST2, true, GlobalValue::InternalLinkage, - ConstantStruct::get (ST2, CV2), "_llvm_regAllocState", - &M); - return false; // No error. -} - - -/// Allocate registers for the machine code previously generated for F using -/// the graph-coloring algorithm. -/// -bool PhyRegAlloc::runOnFunction (Function &F) { - if (DEBUG_RA) - std::cerr << "\n********* Function "<< F.getName () << " ***********\n"; - - Fn = &F; - MF = &MachineFunction::get (Fn); - LVI = &getAnalysis<FunctionLiveVarInfo> (); - LRI = new LiveRangeInfo (Fn, TM, RegClassList); - LoopDepthCalc = &getAnalysis<LoopInfo> (); - - // Create each RegClass for the target machine and add it to the - // RegClassList. This must be done before calling constructLiveRanges(). - for (unsigned rc = 0; rc != NumOfRegClasses; ++rc) - RegClassList.push_back (new RegClass (Fn, &TM.getRegInfo (), - MRI.getMachineRegClass (rc))); - - LRI->constructLiveRanges(); // create LR info - if (DEBUG_RA >= RA_DEBUG_LiveRanges) - LRI->printLiveRanges(); - - createIGNodeListsAndIGs(); // create IGNode list and IGs - - buildInterferenceGraphs(); // build IGs in all reg classes - - if (DEBUG_RA >= RA_DEBUG_LiveRanges) { - // print all LRs in all reg classes - for ( unsigned rc=0; rc < NumOfRegClasses ; rc++) - RegClassList[rc]->printIGNodeList(); - - // print IGs in all register classes - for ( unsigned rc=0; rc < NumOfRegClasses ; rc++) - RegClassList[rc]->printIG(); - } - - LRI->coalesceLRs(); // coalesce all live ranges - - if (DEBUG_RA >= RA_DEBUG_LiveRanges) { - // print all LRs in all reg classes - for (unsigned rc=0; rc < NumOfRegClasses; rc++) - RegClassList[rc]->printIGNodeList(); - - // print IGs in all register classes - for (unsigned rc=0; rc < NumOfRegClasses; rc++) - RegClassList[rc]->printIG(); - } - - // mark un-usable suggested color before graph coloring algorithm. - // When this is done, the graph coloring algo will not reserve - // suggested color unnecessarily - they can be used by another LR - markUnusableSugColors(); - - // color all register classes using the graph coloring algo - for (unsigned rc=0; rc < NumOfRegClasses ; rc++) - RegClassList[rc]->colorAllRegs(); - - // After graph coloring, if some LRs did not receive a color (i.e, spilled) - // a position for such spilled LRs - allocateStackSpace4SpilledLRs(); - - // Reset the temp. area on the stack before use by the first instruction. - // This will also happen after updating each instruction. - MF->getInfo()->popAllTempValues(); - - // color incoming args - if the correct color was not received - // insert code to copy to the correct register - colorIncomingArgs(); - - // Save register allocation state for this function in a Constant. - if (SaveRegAllocState) - saveState(); - if (DEBUG_RA) { // Check our work. - verifySavedState (); - } - - // Now update the machine code with register names and add any additional - // code inserted by the register allocator to the instruction stream. - updateMachineCode(); - - if (DEBUG_RA) { - std::cerr << "\n**** Machine Code After Register Allocation:\n\n"; - MF->dump(); - } - - // Tear down temporary data structures - for (unsigned rc = 0; rc < NumOfRegClasses; ++rc) - delete RegClassList[rc]; - RegClassList.clear (); - AddedInstrMap.clear (); - OperandsColoredMap.clear (); - ScratchRegsUsed.clear (); - AddedInstrAtEntry.clear (); - delete LRI; - - if (DEBUG_RA) std::cerr << "\nRegister allocation complete!\n"; - return false; // Function was not modified -} diff --git a/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h b/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h deleted file mode 100644 index e93c51d124..0000000000 --- a/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h +++ /dev/null @@ -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 diff --git a/lib/Target/SparcV9/RegAlloc/RegAllocCommon.h b/lib/Target/SparcV9/RegAlloc/RegAllocCommon.h deleted file mode 100644 index 97d102a253..0000000000 --- a/lib/Target/SparcV9/RegAlloc/RegAllocCommon.h +++ /dev/null @@ -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 diff --git a/lib/Target/SparcV9/RegAlloc/RegClass.cpp b/lib/Target/SparcV9/RegAlloc/RegClass.cpp deleted file mode 100644 index 9c8603b82c..0000000000 --- a/lib/Target/SparcV9/RegAlloc/RegClass.cpp +++ /dev/null @@ -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(); -} - - diff --git a/lib/Target/SparcV9/RegAlloc/RegClass.h b/lib/Target/SparcV9/RegAlloc/RegClass.h deleted file mode 100644 index c861fbae21..0000000000 --- a/lib/Target/SparcV9/RegAlloc/RegClass.h +++ /dev/null @@ -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 diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp deleted file mode 100644 index c8072da052..0000000000 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ /dev/null @@ -1,1020 +0,0 @@ -//===-- X86/Printer.cpp - Convert X86 LLVM code to Intel assembly ---------===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains a printer that converts from our internal -// representation of machine-dependent LLVM code to Intel-format -// assembly language. This printer is the output mechanism used -// by `llc' and `lli -print-machineinstrs' on X86. -// -//===----------------------------------------------------------------------===// - -#include "X86.h" -#include "X86InstrInfo.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/Assembly/Writer.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Support/Mangler.h" -#include "Support/Statistic.h" -#include "Support/StringExtras.h" -#include "Support/CommandLine.h" - -namespace { - Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); - - // FIXME: This should be automatically picked up by autoconf from the C - // frontend - cl::opt<bool> EmitCygwin("enable-cygwin-compatible-output", cl::Hidden, - cl::desc("Emit X86 assembly code suitable for consumption by cygwin")); - - struct Printer : public MachineFunctionPass { - /// Output stream on which we're printing assembly code. - /// - std::ostream &O; - - /// Target machine description which we query for reg. names, data - /// layout, etc. - /// - TargetMachine &TM; - - /// Name-mangler for global names. - /// - Mangler *Mang; - - Printer(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) { } - - /// We name each basic block in a Function with a unique number, so - /// that we can consistently refer to them later. This is cleared - /// at the beginning of each call to runOnMachineFunction(). - /// - typedef std::map<const Value *, unsigned> ValueMapTy; - ValueMapTy NumberForBB; - - /// Cache of mangled name for current function. This is - /// recalculated at the beginning of each call to - /// runOnMachineFunction(). - /// - std::string CurrentFnName; - - virtual const char *getPassName() const { - return "X86 Assembly Printer"; - } - - void checkImplUses (const TargetInstrDescriptor &Desc); - void printMachineInstruction(const MachineInstr *MI); - void printOp(const MachineOperand &MO, - bool elideOffsetKeyword = false); - void printMemReference(const MachineInstr *MI, unsigned Op); - void printConstantPool(MachineConstantPool *MCP); - bool runOnMachineFunction(MachineFunction &F); - std::string ConstantExprToString(const ConstantExpr* CE); - std::string valToExprString(const Value* V); - bool doInitialization(Module &M); - bool doFinalization(Module &M); - void printConstantValueOnly(const Constant* CV); - void printSingleConstantValue(const Constant* CV); - }; -} // end of anonymous namespace - -/// createX86CodePrinterPass - Returns a pass that prints the X86 -/// assembly code for a MachineFunction to the given output stream, -/// using the given target machine description. This should work -/// regardless of whether the function is in SSA form. -/// -FunctionPass *createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){ - return new Printer(o, tm); -} - -/// valToExprString - Helper function for ConstantExprToString(). -/// Appends result to argument string S. -/// -std::string Printer::valToExprString(const Value* V) { - std::string S; - bool failed = false; - if (const Constant* CV = dyn_cast<Constant>(V)) { // symbolic or known - if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) - S += std::string(CB == ConstantBool::True ? "1" : "0"); - else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV)) - S += itostr(CI->getValue()); - else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV)) - S += utostr(CI->getValue()); - else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) - S += ftostr(CFP->getValue()); - else if (isa<ConstantPointerNull>(CV)) - S += "0"; - else if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(CV)) - S += valToExprString(CPR->getValue()); - else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) - S += ConstantExprToString(CE); - else - failed = true; - } else if (const GlobalValue* GV = dyn_cast<GlobalValue>(V)) { - S += Mang->getValueName(GV); - } - else - failed = true; - - if (failed) { - assert(0 && "Cannot convert value to string"); - S += "<illegal-value>"; - } - return S; -} - -/// ConstantExprToString - Convert a ConstantExpr to an asm expression -/// and return this as a string. -/// -std::string Printer::ConstantExprToString(const ConstantExpr* CE) { - const TargetData &TD = TM.getTargetData(); - switch(CE->getOpcode()) { - case Instruction::GetElementPtr: - { // generate a symbolic expression for the byte address - const Value* ptrVal = CE->getOperand(0); - std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end()); - if (unsigned Offset = TD.getIndexedOffset(ptrVal->getType(), idxVec)) - return "(" + valToExprString(ptrVal) + ") + " + utostr(Offset); - else - return valToExprString(ptrVal); - } - - case Instruction::Cast: - // Support only non-converting or widening casts for now, that is, - // ones that do not involve a change in value. This assertion is - // not a complete check. - { - Constant *Op = CE->getOperand(0); - const Type *OpTy = Op->getType(), *Ty = CE->getType(); - assert(((isa<PointerType>(OpTy) - && (Ty == Type::LongTy || Ty == Type::ULongTy)) - || (isa<PointerType>(Ty) - && (OpTy == Type::LongTy || OpTy == Type::ULongTy))) - || (((TD.getTypeSize(Ty) >= TD.getTypeSize(OpTy)) - && (OpTy->isLosslesslyConvertibleTo(Ty)))) - && "FIXME: Don't yet support this kind of constant cast expr"); - return "(" + valToExprString(Op) + ")"; - } - - case Instruction::Add: - return "(" + valToExprString(CE->getOperand(0)) + ") + (" - + valToExprString(CE->getOperand(1)) + ")"; - - default: - assert(0 && "Unsupported operator in ConstantExprToString()"); - return ""; - } -} - -/// printSingleConstantValue - Print a single constant value. -/// -void -Printer::printSingleConstantValue(const Constant* CV) -{ - assert(CV->getType() != Type::VoidTy && - CV->getType() != Type::TypeTy && - CV->getType() != Type::LabelTy && - "Unexpected type for Constant"); - - assert((!isa<ConstantArray>(CV) && ! isa<ConstantStruct>(CV)) - && "Aggregate types should be handled outside this function"); - - const Type *type = CV->getType(); - O << "\t"; - switch(type->getPrimitiveID()) - { - case Type::BoolTyID: case Type::UByteTyID: case Type::SByteTyID: - O << ".byte"; - break; - case Type::UShortTyID: case Type::ShortTyID: - O << ".word"; - break; - case Type::UIntTyID: case Type::IntTyID: case Type::PointerTyID: - O << ".long"; - break; - case Type::ULongTyID: case Type::LongTyID: - O << ".quad"; - break; - case Type::FloatTyID: - O << ".long"; - break; - case Type::DoubleTyID: - O << ".quad"; - break; - case Type::ArrayTyID: - if ((cast<ArrayType>(type)->getElementType() == Type::UByteTy) || - (cast<ArrayType>(type)->getElementType() == Type::SByteTy)) - O << ".string"; - else - assert (0 && "Can't handle printing this type of array"); - break; - default: - assert (0 && "Can't handle printing this type of thing"); - break; - } - O << "\t"; - - if (const ConstantExpr* CE = dyn_cast<ConstantExpr>(CV)) - { - // Constant expression built from operators, constants, and - // symbolic addrs - O << ConstantExprToString(CE) << "\n"; - } - else if (type->isPrimitiveType()) - { - if (type->isFloatingPoint()) { - // FP Constants are printed as integer constants to avoid losing - // precision... - double Val = cast<ConstantFP>(CV)->getValue(); - if (type == Type::FloatTy) { - float FVal = (float)Val; - char *ProxyPtr = (char*)&FVal; // Abide by C TBAA rules - O << *(unsigned int*)ProxyPtr; - } else if (type == Type::DoubleTy) { - char *ProxyPtr = (char*)&Val; // Abide by C TBAA rules - O << *(uint64_t*)ProxyPtr; - } else { - assert(0 && "Unknown floating point type!"); - } - - O << "\t# " << type->getDescription() << " value: " << Val << "\n"; - } else { - WriteAsOperand(O, CV, false, false) << "\n"; - } - } - else if (const ConstantPointerRef* CPR = dyn_cast<ConstantPointerRef>(CV)) - { - // This is a constant address for a global variable or method. - // Use the name of the variable or method as the address value. - O << Mang->getValueName(CPR->getValue()) << "\n"; - } - else if (isa<ConstantPointerNull>(CV)) - { - // Null pointer value - O << "0\n"; - } - else - { - assert(0 && "Unknown elementary type for constant"); - } -} - -/// isStringCompatible - Can we treat the specified array as a string? -/// Only if it is an array of ubytes or non-negative sbytes. -/// -static bool isStringCompatible(const ConstantArray *CVA) { - const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType(); - if (ETy == Type::UByteTy) return true; - if (ETy != Type::SByteTy) return false; - - for (unsigned i = 0; i < CVA->getNumOperands(); ++i) - if (cast<ConstantSInt>(CVA->getOperand(i))->getValue() < 0) - return false; - - return true; -} - -/// toOctal - Convert the low order bits of X into an octal digit. -/// -static inline char toOctal(int X) { - return (X&7)+'0'; -} - -/// getAsCString - Return the specified array as a C compatible -/// string, only if the predicate isStringCompatible is true. -/// -static std::string getAsCString(const ConstantArray *CVA) { - assert(isStringCompatible(CVA) && "Array is not string compatible!"); - - std::string Result; - const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType(); - Result = "\""; - for (unsigned i = 0; i < CVA->getNumOperands(); ++i) { - unsigned char C = cast<ConstantInt>(CVA->getOperand(i))->getRawValue(); - - if (C == '"') { - Result += "\\\""; - } else if (C == '\\') { - Result += "\\\\"; - } else if (isprint(C)) { - Result += C; - } else { - switch(C) { - case '\b': Result += "\\b"; break; - case '\f': Result += "\\f"; break; - case '\n': Result += "\\n"; break; - case '\r': Result += "\\r"; break; - case '\t': Result += "\\t"; break; - default: - Result += '\\'; - Result += toOctal(C >> 6); - Result += toOctal(C >> 3); - Result += toOctal(C >> 0); - break; - } - } - } - Result += "\""; - return Result; -} - -// Print a constant value or values (it may be an aggregate). -// Uses printSingleConstantValue() to print each individual value. -void Printer::printConstantValueOnly(const Constant *CV) { - const TargetData &TD = TM.getTargetData(); - - if (CV->isNullValue()) { - O << "\t.zero\t " << TD.getTypeSize(CV->getType()) << "\n"; - } else if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) { - if (isStringCompatible(CVA)) { - // print the string alone and return - O << "\t.ascii\t" << getAsCString(CVA) << "\n"; - } else { // Not a string. Print the values in successive locations - const std::vector<Use> &constValues = CVA->getValues(); - for (unsigned i=0; i < constValues.size(); i++) - printConstantValueOnly(cast<Constant>(constValues[i].get())); - } - } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) { - // Print the fields in successive locations. Pad to align if needed! - const StructLayout *cvsLayout = TD.getStructLayout(CVS->getType()); - const std::vector<Use>& constValues = CVS->getValues(); - unsigned sizeSoFar = 0; - for (unsigned i=0, N = constValues.size(); i < N; i++) { - const Constant* field = cast<Constant>(constValues[i].get()); - - // Check if padding is needed and insert one or more 0s. - unsigned fieldSize = TD.getTypeSize(field->getType()); - unsigned padSize = ((i == N-1? cvsLayout->StructSize - : cvsLayout->MemberOffsets[i+1]) - - cvsLayout->MemberOffsets[i]) - fieldSize; - sizeSoFar += fieldSize + padSize; - - // Now print the actual field value - printConstantValueOnly(field); - - // Insert the field padding unless it's zero bytes... - if (padSize) - O << "\t.zero\t " << padSize << "\n"; - } - assert(sizeSoFar == cvsLayout->StructSize && - "Layout of constant struct may be incorrect!"); - } else - printSingleConstantValue(CV); -} - -/// printConstantPool - Print to the current output stream assembly -/// representations of the constants in the constant pool MCP. This is -/// used to print out constants which have been "spilled to memory" by -/// the code generator. -/// -void Printer::printConstantPool(MachineConstantPool *MCP) { - const std::vector<Constant*> &CP = MCP->getConstants(); - const TargetData &TD = TM.getTargetData(); - - if (CP.empty()) return; - - for (unsigned i = 0, e = CP.size(); i != e; ++i) { - O << "\t.section .rodata\n"; - O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType()) - << "\n"; - O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t#" - << *CP[i] << "\n"; - printConstantValueOnly (CP[i]); - } -} - -/// runOnMachineFunction - This uses the printMachineInstruction() -/// method to print assembly for each instruction. -/// -bool Printer::runOnMachineFunction(MachineFunction &MF) { - // BBNumber is used here so that a given Printer will never give two - // BBs the same name. (If you have a better way, please let me know!) - static unsigned BBNumber = 0; - - O << "\n\n"; - // What's my mangled name? - CurrentFnName = Mang->getValueName(MF.getFunction()); - - // Print out constants referenced by the function - printConstantPool(MF.getConstantPool()); - - // Print out labels for the function. - O << "\t.text\n"; - O << "\t.align 16\n"; - O << "\t.globl\t" << CurrentFnName << "\n"; - if (!EmitCygwin) - O << "\t.type\t" << CurrentFnName << ", @function\n"; - O << CurrentFnName << ":\n"; - - // Number each basic block so that we can consistently refer to them - // in PC-relative references. - NumberForBB.clear(); - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - NumberForBB[I->getBasicBlock()] = BBNumber++; - } - - // Print out code for the function. - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - // Print a label for the basic block. - O << ".LBB" << NumberForBB[I->getBasicBlock()] << ":\t# " - << I->getBasicBlock()->getName() << "\n"; - for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); - II != E; ++II) { - // Print the assembly for the instruction. - O << "\t"; - printMachineInstruction(*II); - } - } - - // We didn't modify anything. - return false; -} - -static bool isScale(const MachineOperand &MO) { - return MO.isImmediate() && - (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 || - MO.getImmedValue() == 4 || MO.getImmedValue() == 8); -} - -static bool isMem(const MachineInstr *MI, unsigned Op) { - if (MI->getOperand(Op).isFrameIndex()) return true; - if (MI->getOperand(Op).isConstantPoolIndex()) return true; - return Op+4 <= MI->getNumOperands() && - MI->getOperand(Op ).isRegister() &&isScale(MI->getOperand(Op+1)) && - MI->getOperand(Op+2).isRegister() &&MI->getOperand(Op+3).isImmediate(); -} - - - -void Printer::printOp(const MachineOperand &MO, - bool elideOffsetKeyword /* = false */) { - const MRegisterInfo &RI = *TM.getRegisterInfo(); - switch (MO.getType()) { - case MachineOperand::MO_VirtualRegister: - if (Value *V = MO.getVRegValueOrNull()) { - O << "<" << V->getName() << ">"; - return; - } - // FALLTHROUGH - case MachineOperand::MO_MachineRegister: - if (MO.getReg() < MRegisterInfo::FirstVirtualRegister) - // Bug Workaround: See note in Printer::doInitialization about %. - O << "%" << RI.get(MO.getReg()).Name; - else - O << "%reg" << MO.getReg(); - return; - - case MachineOperand::MO_SignExtendedImmed: - case MachineOperand::MO_UnextendedImmed: - O << (int)MO.getImmedValue(); - return; - case MachineOperand::MO_PCRelativeDisp: { - ValueMapTy::const_iterator i = NumberForBB.find(MO.getVRegValue()); - assert (i != NumberForBB.end() - && "Could not find a BB in the NumberForBB map!"); - O << ".LBB" << i->second << " # PC rel: " << MO.getVRegValue()->getName(); - return; - } - case MachineOperand::MO_GlobalAddress: - if (!elideOffsetKeyword) - O << "OFFSET "; - O << Mang->getValueName(MO.getGlobal()); - return; - case MachineOperand::MO_ExternalSymbol: - O << MO.getSymbolName(); - return; - default: - O << "<unknown operand type>"; return; - } -} - -static const std::string sizePtr(const TargetInstrDescriptor &Desc) { - switch (Desc.TSFlags & X86II::ArgMask) { - default: assert(0 && "Unknown arg size!"); - case X86II::Arg8: return "BYTE PTR"; - case X86II::Arg16: return "WORD PTR"; - case X86II::Arg32: return "DWORD PTR"; - case X86II::Arg64: return "QWORD PTR"; - case X86II::ArgF32: return "DWORD PTR"; - case X86II::ArgF64: return "QWORD PTR"; - case X86II::ArgF80: return "XWORD PTR"; - } -} - -void Printer::printMemReference(const MachineInstr *MI, unsigned Op) { - assert(isMem(MI, Op) && "Invalid memory reference!"); - - if (MI->getOperand(Op).isFrameIndex()) { - O << "[frame slot #" << MI->getOperand(Op).getFrameIndex(); - if (MI->getOperand(Op+3).getImmedValue()) - O << " + " << MI->getOperand(Op+3).getImmedValue(); - O << "]"; - return; - } else if (MI->getOperand(Op).isConstantPoolIndex()) { - O << "[.CPI" << CurrentFnName << "_" - << MI->getOperand(Op).getConstantPoolIndex(); - if (MI->getOperand(Op+3).getImmedValue()) - O << " + " << MI->getOperand(Op+3).getImmedValue(); - O << "]"; - return; - } - - const MachineOperand &BaseReg = MI->getOperand(Op); - int ScaleVal = MI->getOperand(Op+1).getImmedValue(); - const MachineOperand &IndexReg = MI->getOperand(Op+2); - int DispVal = MI->getOperand(Op+3).getImmedValue(); - - O << "["; - bool NeedPlus = false; - if (BaseReg.getReg()) { - printOp(BaseReg); - NeedPlus = true; - } - - if (IndexReg.getReg()) { - if (NeedPlus) O << " + "; - if (ScaleVal != 1) - O << ScaleVal << "*"; - printOp(IndexReg); - NeedPlus = true; - } - - if (DispVal) { - if (NeedPlus) - if (DispVal > 0) - O << " + "; - else { - O << " - "; - DispVal = -DispVal; - } - O << DispVal; - } - O << "]"; -} - -/// checkImplUses - Emit the implicit-use registers for the -/// instruction described by DESC, if its PrintImplUses flag is set. -/// -void Printer::checkImplUses (const TargetInstrDescriptor &Desc) { - const MRegisterInfo &RI = *TM.getRegisterInfo(); - if (Desc.TSFlags & X86II::PrintImplUses) { - for (const unsigned *p = Desc.ImplicitUses; *p; ++p) { - // Bug Workaround: See note in Printer::doInitialization about %. - O << ", %" << RI.get(*p).Name; - } - } -} - -/// printMachineInstruction -- Print out a single X86 LLVM instruction -/// MI in Intel syntax to the current output stream. -/// -void Printer::printMachineInstruction(const MachineInstr *MI) { - unsigned Opcode = MI->getOpcode(); - const TargetInstrInfo &TII = TM.getInstrInfo(); - const TargetInstrDescriptor &Desc = TII.get(Opcode); - - ++EmittedInsts; - switch (Desc.TSFlags & X86II::FormMask) { - case X86II::Pseudo: - // Print pseudo-instructions as comments; either they should have been - // turned into real instructions by now, or they don't need to be - // seen by the assembler (e.g., IMPLICIT_USEs.) - O << "# "; - if (Opcode == X86::PHI) { - printOp(MI->getOperand(0)); - O << " = phi "; - for (unsigned i = 1, e = MI->getNumOperands(); i != e; i+=2) { - if (i != 1) O << ", "; - O << "["; - printOp(MI->getOperand(i)); - O << ", "; - printOp(MI->getOperand(i+1)); - O << "]"; - } - } else { - unsigned i = 0; - if (MI->getNumOperands() && (MI->getOperand(0).opIsDefOnly() || - MI->getOperand(0).opIsDefAndUse())) { - printOp(MI->getOperand(0)); - O << " = "; - ++i; - } - O << TII.getName(MI->getOpcode()); - - for (unsigned e = MI->getNumOperands(); i != e; ++i) { - O << " "; - if (MI->getOperand(i).opIsDefOnly() || - MI->getOperand(i).opIsDefAndUse()) O << "*"; - printOp(MI->getOperand(i)); - if (MI->getOperand(i).opIsDefOnly() || - MI->getOperand(i).opIsDefAndUse()) O << "*"; - } - } - O << "\n"; - return; - - case X86II::RawFrm: - // The accepted forms of Raw instructions are: - // 1. nop - No operand required - // 2. jmp foo - PC relative displacement operand - // 3. call bar - GlobalAddress Operand or External Symbol Operand - // - assert(MI->getNumOperands() == 0 || - (MI->getNumOperands() == 1 && - (MI->getOperand(0).isPCRelativeDisp() || - MI->getOperand(0).isGlobalAddress() || - MI->getOperand(0).isExternalSymbol())) && - "Illegal raw instruction!"); - O << TII.getName(MI->getOpcode()) << " "; - - if (MI->getNumOperands() == 1) { - printOp(MI->getOperand(0), true); // Don't print "OFFSET"... - } - O << "\n"; - return; - - case X86II::AddRegFrm: { - // There are currently two forms of acceptable AddRegFrm instructions. - // Either the instruction JUST takes a single register (like inc, dec, etc), - // or it takes a register and an immediate of the same size as the register - // (move immediate f.e.). Note that this immediate value might be stored as - // an LLVM value, to represent, for example, loading the address of a global - // into a register. The initial register might be duplicated if this is a - // M_2_ADDR_REG instruction - // - assert(MI->getOperand(0).isRegister() && - (MI->getNumOperands() == 1 || - (MI->getNumOperands() == 2 && - (MI->getOperand(1).getVRegValueOrNull() || - MI->getOperand(1).isImmediate() || - MI->getOperand(1).isRegister() || - MI->getOperand(1).isGlobalAddress() || - MI->getOperand(1).isExternalSymbol()))) && - "Illegal form for AddRegFrm instruction!"); - - unsigned Reg = MI->getOperand(0).getReg(); - - O << TII.getName(MI->getOpCode()) << " "; - printOp(MI->getOperand(0)); - if (MI->getNumOperands() == 2 && - (!MI->getOperand(1).isRegister() || - MI->getOperand(1).getVRegValueOrNull() || - MI->getOperand(1).isGlobalAddress() || - MI->getOperand(1).isExternalSymbol())) { - O << ", "; - printOp(MI->getOperand(1)); - } - checkImplUses(Desc); - O << "\n"; - return; - } - case X86II::MRMDestReg: { - // There are two acceptable forms of MRMDestReg instructions, those with 2, - // 3 and 4 operands: - // - // 2 Operands: this is for things like mov that do not read a second input - // - // 3 Operands: in this form, the first two registers (the destination, and - // the first operand) should be the same, post register allocation. The 3rd - // operand is an additional input. This should be for things like add - // instructions. - // - // 4 Operands: This form is for instructions which are 3 operands forms, but - // have a constant argument as well. - // - bool isTwoAddr = TII.isTwoAddrInstr(Opcode); - assert(MI->getOperand(0).isRegister() && - (MI->getNumOperands() == 2 || - (isTwoAddr && MI->getOperand(1).isRegister() && - MI->getOperand(0).getReg() == MI->getOperand(1).getReg() && - (MI->getNumOperands() == 3 || - (MI->getNumOperands() == 4 && MI->getOperand(3).isImmediate())))) - && "Bad format for MRMDestReg!"); - - O << TII.getName(MI->getOpCode()) << " "; - printOp(MI->getOperand(0)); - O << ", "; - printOp(MI->getOperand(1+isTwoAddr)); - if (MI->getNumOperands() == 4) { - O << ", "; - printOp(MI->getOperand(3)); - } - O << "\n"; - return; - } - - case X86II::MRMDestMem: { - // These instructions are the same as MRMDestReg, but instead of having a - // register reference for the mod/rm field, it's a memory reference. - // - assert(isMem(MI, 0) && MI->getNumOperands() == 4+1 && - MI->getOperand(4).isRegister() && "Bad format for MRMDestMem!"); - - O << TII.getName(MI->getOpCode()) << " " << sizePtr(Desc) << " "; - printMemReference(MI, 0); - O << ", "; - printOp(MI->getOperand(4)); - O << "\n"; - return; - } - - case X86II::MRMSrcReg: { - // There are three forms that are acceptable for MRMSrcReg instructions, - // those with 3 and 2 operands: - // - // 3 Operands: in this form, the last register (the second input) is the - // ModR/M input. The first two operands should be the same, post register - // allocation. This is for things like: add r32, r/m32 - // - // 3 Operands: in this form, we can have 'INST R, R, imm', which is used for - // instructions like the IMULri instructions. - // - // 2 Operands: this is for things like mov that do not read a second input - // - assert(MI->getOperand(0).isRegister() && - MI->getOperand(1).isRegister() && - (MI->getNumOperands() == 2 || - (MI->getNumOperands() == 3 && - (MI->getOperand(2).isRegister() || - MI->getOperand(2).isImmediate()))) - && "Bad format for MRMSrcReg!"); - if (MI->getNumOperands() == 3 && - MI->getOperand(0).getReg() != MI->getOperand(1).getReg()) - O << "**"; - - O << TII.getName(MI->getOpCode()) << " "; - printOp(MI->getOperand(0)); - - // If this is IMULri* instructions, print the non-two-address operand. - if (MI->getNumOperands() == 3 && MI->getOperand(2).isImmediate()) { - O << ", "; - printOp(MI->getOperand(1)); - } - - O << ", "; - printOp(MI->getOperand(MI->getNumOperands()-1)); - O << "\n"; - return; - } - - case X86II::MRMSrcMem: { - // These instructions are the same as MRMSrcReg, but instead of having a - // register reference for the mod/rm field, it's a memory reference. - // - assert(MI->getOperand(0).isRegister() && - (MI->getNumOperands() == 1+4 && isMem(MI, 1)) || - (MI->getNumOperands() == 2+4 && MI->getOperand(1).isRegister() && - isMem(MI, 2)) - && "Bad format for MRMDestReg!"); - if (MI->getNumOperands() == 2+4 && - MI->getOperand(0).getReg() != MI->getOperand(1).getReg()) - O << "**"; - - O << TII.getName(MI->getOpCode()) << " "; - printOp(MI->getOperand(0)); - O << ", " << sizePtr(Desc) << " "; - printMemReference(MI, MI->getNumOperands()-4); - O << "\n"; - return; - } - - case X86II::MRMS0r: case X86II::MRMS1r: - case X86II::MRMS2r: case X86II::MRMS3r: - case X86II::MRMS4r: case X86II::MRMS5r: - case X86II::MRMS6r: case X86II::MRMS7r: { - // In this form, the following are valid formats: - // 1. sete r - // 2. cmp reg, immediate - // 2. shl rdest, rinput <implicit CL or 1> - // 3. sbb rdest, rinput, immediate [rdest = rinput] - // - assert(MI->getNumOperands() > 0 && MI->getNumOperands() < 4 && - MI->getOperand(0).isRegister() && "Bad MRMSxR format!"); - assert((MI->getNumOperands() != 2 || - MI->getOperand(1).isRegister() || MI->getOperand(1).isImmediate())&& - "Bad MRMSxR format!"); - assert((MI->getNumOperands() < 3 || - (MI->getOperand(1).isRegister() && MI->getOperand(2).isImmediate())) && - "Bad MRMSxR format!"); - - if (MI->getNumOperands() > 1 && MI->getOperand(1).isRegister() && - MI->getOperand(0).getReg() != MI->getOperand(1).getReg()) - O << "**"; - - O << TII.getName(MI->getOpCode()) << " "; - printOp(MI->getOperand(0)); - if (MI->getOperand(MI->getNumOperands()-1).isImmediate()) { - O << ", "; - printOp(MI->getOperand(MI->getNumOperands()-1)); - } - checkImplUses(Desc); - O << "\n"; - - return; - } - - case X86II::MRMS0m: case X86II::MRMS1m: - case X86II::MRMS2m: case X86II::MRMS3m: - case X86II::MRMS4m: case X86II::MRMS5m: - case X86II::MRMS6m: case X86II::MRMS7m: { - // In this form, the following are valid formats: - // 1. sete [m] - // 2. cmp [m], immediate - // 2. shl [m], rinput <implicit CL or 1> - // 3. sbb [m], immediate - // - assert(MI->getNumOperands() >= 4 && MI->getNumOperands() <= 5 && - isMem(MI, 0) && "Bad MRMSxM format!"); - assert((MI->getNumOperands() != 5 || MI->getOperand(4).isImmediate()) && - "Bad MRMSxM format!"); - // Bug: The 80-bit FP store-pop instruction "fstp XWORD PTR [...]" - // is misassembled by gas in intel_syntax mode as its 32-bit - // equivalent "fstp DWORD PTR [...]". Workaround: Output the raw - // opcode bytes instead of the instruction. - if (MI->getOpCode() == X86::FSTPr80) { - if ((MI->getOperand(0).getReg() == X86::ESP) - && (MI->getOperand(1).getImmedValue() == 1)) { - int DispVal = MI->getOperand(3).getImmedValue(); - if ((DispVal < -128) || (DispVal > 127)) { // 4 byte disp. - unsigned int val = (unsigned int) DispVal; - O << ".byte 0xdb, 0xbc, 0x24\n\t"; - O << ".long 0x" << std::hex << (unsigned) val << std::dec << "\t# "; - } else { // 1 byte disp. - unsigned char val = (unsigned char) DispVal; - O << ".byte 0xdb, 0x7c, 0x24, 0x" << std::hex << (unsigned) val - << std::dec << "\t# "; - } - } - } - // Bug: The 80-bit FP load instruction "fld XWORD PTR [...]" is - // misassembled by gas in intel_syntax mode as its 32-bit - // equivalent "fld DWORD PTR [...]". Workaround: Output the raw - // opcode bytes instead of the instruction. - if (MI->getOpCode() == X86::FLDr80) { - if ((MI->getOperand(0).getReg() == X86::ESP) - && (MI->getOperand(1).getImmedValue() == 1)) { - int DispVal = MI->getOperand(3).getImmedValue(); - if ((DispVal < -128) || (DispVal > 127)) { // 4 byte disp. - unsigned int val = (unsigned int) DispVal; - O << ".byte 0xdb, 0xac, 0x24\n\t"; - O << ".long 0x" << std::hex << (unsigned) val << std::dec << "\t# "; - } else { // 1 byte disp. - unsigned char val = (unsigned char) DispVal; - O << ".byte 0xdb, 0x6c, 0x24, 0x" << std::hex << (unsigned) val - << std::dec << "\t# "; - } - } - } - // Bug: gas intel_syntax mode treats "fild QWORD PTR [...]" as an - // invalid opcode, saying "64 bit operations are only supported in - // 64 bit modes." libopcodes disassembles it as "fild DWORD PTR - // [...]", which is wrong. Workaround: Output the raw opcode bytes - // instead of the instruction. - if (MI->getOpCode() == X86::FILDr64) { - if ((MI->getOperand(0).getReg() == X86::ESP) - && (MI->getOperand(1).getImmedValue() == 1)) { - int DispVal = MI->getOperand(3).getImmedValue(); - if ((DispVal < -128) || (DispVal > 127)) { // 4 byte disp. - unsigned int val = (unsigned int) DispVal; - O << ".byte 0xdf, 0xac, 0x24\n\t"; - O << ".long 0x" << std::hex << (unsigned) val << std::dec << "\t# "; - } else { // 1 byte disp. - unsigned char val = (unsigned char) DispVal; - O << ".byte 0xdf, 0x6c, 0x24, 0x" << std::hex << (unsigned) val - << std::dec << "\t# "; - } - } - } - // Bug: gas intel_syntax mode treats "fistp QWORD PTR [...]" as - // an invalid opcode, saying "64 bit operations are only - // supported in 64 bit modes." libopcodes disassembles it as - // "fistpll DWORD PTR [...]", which is wrong. Workaround: Output - // "fistpll DWORD PTR " instead, which is what libopcodes is - // expecting to see. - if (MI->getOpCode() == X86::FISTPr64) { - O << "fistpll DWORD PTR "; - printMemReference(MI, 0); - if (MI->getNumOperands() == 5) { - O << ", "; - printOp(MI->getOperand(4)); - } - O << "\t# "; - } - - O << TII.getName(MI->getOpCode()) << " "; - O << sizePtr(Desc) << " "; - printMemReference(MI, 0); - if (MI->getNumOperands() == 5) { - O << ", "; - printOp(MI->getOperand(4)); - } - O << "\n"; - return; - } - - default: - O << "\tUNKNOWN FORM:\t\t-"; MI->print(O, TM); break; - } -} - -bool Printer::doInitialization(Module &M) { - // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly. - // - // Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an - // instruction as a reference to the register named sp, and if you try to - // reference a symbol `Sp' (e.g. `mov ECX, OFFSET Sp') then it gets lowercased - // before being looked up in the symbol table. This creates spurious - // `undefined symbol' errors when linking. Workaround: Do not use `noprefix' - // mode, and decorate all register names with percent signs. - O << "\t.intel_syntax\n"; - Mang = new Mangler(M, EmitCygwin); - return false; // success -} - -// SwitchSection - Switch to the specified section of the executable if we are -// not already in it! -// -static void SwitchSection(std::ostream &OS, std::string &CurSection, - const char *NewSection) { - if (CurSection != NewSection) { - CurSection = NewSection; - if (!CurSection.empty()) - OS << "\t" << NewSection << "\n"; - } -} - -bool Printer::doFinalization(Module &M) { - const TargetData &TD = TM.getTargetData(); - std::string CurSection; - - // Print out module-level global variables here. - for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) - if (I->hasInitializer()) { // External global require no code - O << "\n\n"; - std::string name = Mang->getValueName(I); - Constant *C = I->getInitializer(); - unsigned Size = TD.getTypeSize(C->getType()); - unsigned Align = TD.getTypeAlignment(C->getType()); - - if (C->isNullValue() && - (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || - I->hasWeakLinkage() /* FIXME: Verify correct */)) { - SwitchSection(O, CurSection, ".data"); - if (I->hasInternalLinkage()) - O << "\t.local " << name << "\n"; - - O << "\t.comm " << name << "," << TD.getTypeSize(C->getType()) - << "," << (unsigned)TD.getTypeAlignment(C->getType()); - O << "\t\t# "; - WriteAsOperand(O, I, true, true, &M); - O << "\n"; - } else { - switch (I->getLinkage()) { - case GlobalValue::LinkOnceLinkage: - case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. - // Nonnull linkonce -> weak - O << "\t.weak " << name << "\n"; - SwitchSection(O, CurSection, ""); - O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n"; - break; - - case GlobalValue::AppendingLinkage: - // FIXME: appending linkage variables should go into a section of - // their name or something. For now, just emit them as external. - case GlobalValue::ExternalLinkage: - // If external or appending, declare as a global symbol - O << "\t.globl " << name << "\n"; - // FALL THROUGH - case GlobalValue::InternalLinkage: - if (C->isNullValue()) - SwitchSection(O, CurSection, ".bss"); - else - SwitchSection(O, CurSection, ".data"); - break; - } - - O << "\t.align " << Align << "\n"; - O << "\t.type " << name << ",@object\n"; - O << "\t.size " << name << "," << Size << "\n"; - O << name << ":\t\t\t\t# "; - WriteAsOperand(O, I, true, true, &M); - O << " = "; - WriteAsOperand(O, C, false, false, &M); - O << "\n"; - printConstantValueOnly(C); - } - } - - delete Mang; - return false; // success -} diff --git a/lib/Target/X86/X86FloatingPoint.cpp b/lib/Target/X86/X86FloatingPoint.cpp deleted file mode 100644 index 07e58ba171..0000000000 --- a/lib/Target/X86/X86FloatingPoint.cpp +++ /dev/null @@ -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 -} diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp deleted file mode 100644 index 434ceee91c..0000000000 --- a/lib/Target/X86/X86ISelPattern.cpp +++ /dev/null @@ -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); -} diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp deleted file mode 100644 index 1242545d83..0000000000 --- a/lib/Target/X86/X86ISelSimple.cpp +++ /dev/null @@ -1,2137 +0,0 @@ -//===-- InstSelectSimple.cpp - A simple instruction 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 simple peephole instruction selector for the x86 target -// -//===----------------------------------------------------------------------===// - -#include "X86.h" -#include "X86InstrBuilder.h" -#include "X86InstrInfo.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Function.h" -#include "llvm/Instructions.h" -#include "llvm/Intrinsics.h" -#include "llvm/Pass.h" -#include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/SSARegMap.h" -#include "llvm/Target/MRegisterInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Support/InstVisitor.h" - -/// BMI - A special BuildMI variant that takes an iterator to insert the -/// instruction at as well as a basic block. This is the version for when you -/// have a destination register in mind. -inline static MachineInstrBuilder BMI(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &I, - int Opcode, unsigned NumOperands, - unsigned DestReg) { - assert(I >= MBB->begin() && I <= MBB->end() && "Bad iterator!"); - MachineInstr *MI = new MachineInstr(Opcode, NumOperands+1, true, true); - I = MBB->insert(I, MI)+1; - return MachineInstrBuilder(MI).addReg(DestReg, MOTy::Def); -} - -/// BMI - A special BuildMI variant that takes an iterator to insert the -/// instruction at as well as a basic block. -inline static MachineInstrBuilder BMI(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &I, - int Opcode, unsigned NumOperands) { - assert(I >= MBB->begin() && I <= MBB->end() && "Bad iterator!"); - MachineInstr *MI = new MachineInstr(Opcode, NumOperands, true, true); - I = MBB->insert(I, MI)+1; - return MachineInstrBuilder(MI); -} - - -namespace { - struct ISel : public FunctionPass, InstVisitor<ISel> { - TargetMachine &TM; - MachineFunction *F; // The function we are compiling into - MachineBasicBlock *BB; // The current MBB we are compiling - int VarArgsFrameIndex; // FrameIndex for start of varargs area - - std::map<Value*, unsigned> RegMap; // Mapping between Val's and SSA Regs - - // MBBMap - Mapping between LLVM BB -> Machine BB - std::map<const BasicBlock*, MachineBasicBlock*> MBBMap; - - ISel(TargetMachine &tm) : TM(tm), F(0), BB(0) {} - - /// runOnFunction - Top level implementation of instruction selection for - /// the entire function. - /// - bool runOnFunction(Function &Fn) { - F = &MachineFunction::construct(&Fn, TM); - - // Create all of the machine basic blocks for the function... - for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) - F->getBasicBlockList().push_back(MBBMap[I] = new MachineBasicBlock(I)); - - BB = &F->front(); - - // Copy incoming arguments off of the stack... - LoadArgumentsToVirtualRegs(Fn); - - // Instruction select everything except PHI nodes - visit(Fn); - - // Select the PHI nodes - SelectPHINodes(); - - RegMap.clear(); - MBBMap.clear(); - F = 0; - // We always build a machine code representation for the function - return true; - } - - virtual const char *getPassName() const { - return "X86 Simple Instruction Selection"; - } - - /// visitBasicBlock - This method is called when we are visiting a new basic - /// block. This simply creates a new MachineBasicBlock to emit code into - /// and adds it to the current MachineFunction. Subsequent visit* for - /// instructions will be invoked for all instructions in the basic block. - /// - void visitBasicBlock(BasicBlock &LLVM_BB) { - BB = MBBMap[&LLVM_BB]; - } - - /// LoadArgumentsToVirtualRegs - Load all of the arguments to this function - /// from the stack into virtual registers. - /// - void LoadArgumentsToVirtualRegs(Function &F); - - /// SelectPHINodes - Insert machine code to generate phis. This is tricky - /// because we have to generate our sources into the source basic blocks, - /// not the current one. - /// - void SelectPHINodes(); - - // Visitation methods for various instructions. These methods simply emit - // fixed X86 code for each instruction. - // - - // Control flow operators - void visitReturnInst(ReturnInst &RI); - void visitBranchInst(BranchInst &BI); - - struct ValueRecord { - Value *Val; - unsigned Reg; - const Type *Ty; - ValueRecord(unsigned R, const Type *T) : Val(0), Reg(R), Ty(T) {} - ValueRecord(Value *V) : Val(V), Reg(0), Ty(V->getType()) {} - }; - void doCall(const ValueRecord &Ret, MachineInstr *CallMI, - const std::vector<ValueRecord> &Args); - void visitCallInst(CallInst &I); - void visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &I); - - // Arithmetic operators - void visitSimpleBinary(BinaryOperator &B, unsigned OpcodeClass); - void visitAdd(BinaryOperator &B) { visitSimpleBinary(B, 0); } - void visitSub(BinaryOperator &B) { visitSimpleBinary(B, 1); } - void doMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator &MBBI, - unsigned DestReg, const Type *DestTy, - unsigned Op0Reg, unsigned Op1Reg); - void doMultiplyConst(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &MBBI, - unsigned DestReg, const Type *DestTy, - unsigned Op0Reg, unsigned Op1Val); - void visitMul(BinaryOperator &B); - - void visitDiv(BinaryOperator &B) { visitDivRem(B); } - void visitRem(BinaryOperator &B) { visitDivRem(B); } - void visitDivRem(BinaryOperator &B); - - // Bitwise operators - void visitAnd(BinaryOperator &B) { visitSimpleBinary(B, 2); } - void visitOr (BinaryOperator &B) { visitSimpleBinary(B, 3); } - void visitXor(BinaryOperator &B) { visitSimpleBinary(B, 4); } - - // Comparison operators... - void visitSetCondInst(SetCondInst &I); - unsigned EmitComparison(unsigned OpNum, Value *Op0, Value *Op1, - MachineBasicBlock *MBB, - MachineBasicBlock::iterator &MBBI); - - // Memory Instructions - void visitLoadInst(LoadInst &I); - void visitStoreInst(StoreInst &I); - void visitGetElementPtrInst(GetElementPtrInst &I); - void visitAllocaInst(AllocaInst &I); - void visitMallocInst(MallocInst &I); - void visitFreeInst(FreeInst &I); - - // Other operators - void visitShiftInst(ShiftInst &I); - void visitPHINode(PHINode &I) {} // PHI nodes handled by second pass - void visitCastInst(CastInst &I); - void visitVANextInst(VANextInst &I); - void visitVAArgInst(VAArgInst &I); - - void visitInstruction(Instruction &I) { - std::cerr << "Cannot instruction select: " << I; - abort(); - } - - /// promote32 - Make a value 32-bits wide, and put it somewhere. - /// - void promote32(unsigned targetReg, const ValueRecord &VR); - - /// emitGEPOperation - Common code shared between visitGetElementPtrInst and - /// constant expression GEP support. - /// - void emitGEPOperation(MachineBasicBlock *BB, MachineBasicBlock::iterator&IP, - Value *Src, User::op_iterator IdxBegin, - User::op_iterator IdxEnd, unsigned TargetReg); - - /// emitCastOperation - Common code shared between visitCastInst and - /// constant expression cast support. - void emitCastOperation(MachineBasicBlock *BB,MachineBasicBlock::iterator&IP, - Value *Src, const Type *DestTy, unsigned TargetReg); - - /// emitSimpleBinaryOperation - Common code shared between visitSimpleBinary - /// and constant expression support. - void emitSimpleBinaryOperation(MachineBasicBlock *BB, - MachineBasicBlock::iterator &IP, - Value *Op0, Value *Op1, - unsigned OperatorClass, unsigned TargetReg); - - void emitDivRemOperation(MachineBasicBlock *BB, - MachineBasicBlock::iterator &IP, - unsigned Op0Reg, unsigned Op1Reg, bool isDiv, - const Type *Ty, unsigned TargetReg); - - /// emitSetCCOperation - Common code shared between visitSetCondInst and - /// constant expression support. - void emitSetCCOperation(MachineBasicBlock *BB, - MachineBasicBlock::iterator &IP, - Value *Op0, Value *Op1, unsigned Opcode, - unsigned TargetReg); - - - /// copyConstantToRegister - Output the instructions required to put the - /// specified constant into the specified register. - /// - void copyConstantToRegister(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &MBBI, - Constant *C, unsigned Reg); - - /// makeAnotherReg - This method returns the next register number we haven't - /// yet used. - /// - /// Long values are handled somewhat specially. They are always allocated - /// as pairs of 32 bit integer values. The register number returned is the - /// lower 32 bits of the long value, and the regNum+1 is the upper 32 bits - /// of the long value. - /// - unsigned makeAnotherReg(const Type *Ty) { - assert(dynamic_cast<const X86RegisterInfo*>(TM.getRegisterInfo()) && - "Current target doesn't have X86 reg info??"); - const X86RegisterInfo *MRI = - static_cast<const X86RegisterInfo*>(TM.getRegisterInfo()); - if (Ty == Type::LongTy || Ty == Type::ULongTy) { - const TargetRegisterClass *RC = MRI->getRegClassForType(Type::IntTy); - // Create the lower part - F->getSSARegMap()->createVirtualRegister(RC); - // Create the upper part. - return F->getSSARegMap()->createVirtualRegister(RC)-1; - } - - // Add the mapping of regnumber => reg class to MachineFunction - const TargetRegisterClass *RC = MRI->getRegClassForType(Ty); - return F->getSSARegMap()->createVirtualRegister(RC); - } - - /// getReg - This method turns an LLVM value into a register number. This - /// is guaranteed to produce the same register number for a particular value - /// every time it is queried. - /// - unsigned getReg(Value &V) { return getReg(&V); } // Allow references - unsigned getReg(Value *V) { - // Just append to the end of the current bb. - MachineBasicBlock::iterator It = BB->end(); - return getReg(V, BB, It); - } - unsigned getReg(Value *V, MachineBasicBlock *MBB, - MachineBasicBlock::iterator &IPt) { - unsigned &Reg = RegMap[V]; - if (Reg == 0) { - Reg = makeAnotherReg(V->getType()); - RegMap[V] = Reg; - } - - // If this operand is a constant, emit the code to copy the constant into - // the register here... - // - if (Constant *C = dyn_cast<Constant>(V)) { - copyConstantToRegister(MBB, IPt, C, Reg); - RegMap.erase(V); // Assign a new name to this constant if ref'd again - } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) { - // Move the address of the global into the register - BMI(MBB, IPt, X86::MOVir32, 1, Reg).addGlobalAddress(GV); - RegMap.erase(V); // Assign a new name to this address if ref'd again - } - - return Reg; - } - }; -} - -/// TypeClass - Used by the X86 backend to group LLVM types by their basic X86 -/// Representation. -/// -enum TypeClass { - cByte, cShort, cInt, cFP, cLong -}; - -/// getClass - Turn a primitive type into a "class" number which is based on the -/// size of the type, and whether or not it is floating point. -/// -static inline TypeClass getClass(const Type *Ty) { - switch (Ty->getPrimitiveID()) { - case Type::SByteTyID: - case Type::UByteTyID: return cByte; // Byte operands are class #0 - case Type::ShortTyID: - case Type::UShortTyID: return cShort; // Short operands are class #1 - case Type::IntTyID: - case Type::UIntTyID: - case Type::PointerTyID: return cInt; // Int's and pointers are class #2 - - case Type::FloatTyID: - case Type::DoubleTyID: return cFP; // Floating Point is #3 - - case Type::LongTyID: - case Type::ULongTyID: return cLong; // Longs are class #4 - default: - assert(0 && "Invalid type to getClass!"); - return cByte; // not reached - } -} - -// getClassB - Just like getClass, but treat boolean values as bytes. -static inline TypeClass getClassB(const Type *Ty) { - if (Ty == Type::BoolTy) return cByte; - return getClass(Ty); -} - - -/// copyConstantToRegister - Output the instructions required to put the -/// specified constant into the specified register. -/// -void ISel::copyConstantToRegister(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &IP, - Constant *C, unsigned R) { - if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) { - unsigned Class = 0; - switch (CE->getOpcode()) { - case Instruction::GetElementPtr: - emitGEPOperation(MBB, IP, CE->getOperand(0), - CE->op_begin()+1, CE->op_end(), R); - return; - case Instruction::Cast: - emitCastOperation(MBB, IP, CE->getOperand(0), CE->getType(), R); - return; - - case Instruction::Xor: ++Class; // FALL THROUGH - case Instruction::Or: ++Class; // FALL THROUGH - case Instruction::And: ++Class; // FALL THROUGH - case Instruction::Sub: ++Class; // FALL THROUGH - case Instruction::Add: - emitSimpleBinaryOperation(MBB, IP, CE->getOperand(0), CE->getOperand(1), - Class, R); - return; - - case Instruction::Mul: { - unsigned Op0Reg = getReg(CE->getOperand(0), MBB, IP); - unsigned Op1Reg = getReg(CE->getOperand(1), MBB, IP); - doMultiply(MBB, IP, R, CE->getType(), Op0Reg, Op1Reg); - return; - } - case Instruction::Div: - case Instruction::Rem: { - unsigned Op0Reg = getReg(CE->getOperand(0), MBB, IP); - unsigned Op1Reg = getReg(CE->getOperand(1), MBB, IP); - emitDivRemOperation(MBB, IP, Op0Reg, Op1Reg, - CE->getOpcode() == Instruction::Div, - CE->getType(), R); - return; - } - - case Instruction::SetNE: - case Instruction::SetEQ: - case Instruction::SetLT: - case Instruction::SetGT: - case Instruction::SetLE: - case Instruction::SetGE: - emitSetCCOperation(MBB, IP, CE->getOperand(0), CE->getOperand(1), - CE->getOpcode(), R); - return; - - default: - std::cerr << "Offending expr: " << C << "\n"; - assert(0 && "Constant expression not yet handled!\n"); - } - } - - if (C->getType()->isIntegral()) { - unsigned Class = getClassB(C->getType()); - - if (Class == cLong) { - // Copy the value into the register pair. - uint64_t Val = cast<ConstantInt>(C)->getRawValue(); - BMI(MBB, IP, X86::MOVir32, 1, R).addZImm(Val & 0xFFFFFFFF); - BMI(MBB, IP, X86::MOVir32, 1, R+1).addZImm(Val >> 32); - return; - } - - assert(Class <= cInt && "Type not handled yet!"); - - static const unsigned IntegralOpcodeTab[] = { - X86::MOVir8, X86::MOVir16, X86::MOVir32 - }; - - if (C->getType() == Type::BoolTy) { - BMI(MBB, IP, X86::MOVir8, 1, R).addZImm(C == ConstantBool::True); - } else { - ConstantInt *CI = cast<ConstantInt>(C); - BMI(MBB, IP, IntegralOpcodeTab[Class], 1, R).addZImm(CI->getRawValue()); - } - } else if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) { - double Value = CFP->getValue(); - if (Value == +0.0) - BMI(MBB, IP, X86::FLD0, 0, R); - else if (Value == +1.0) - BMI(MBB, IP, X86::FLD1, 0, R); - else { - // Otherwise we need to spill the constant to memory... - MachineConstantPool *CP = F->getConstantPool(); - unsigned CPI = CP->getConstantPoolIndex(CFP); - const Type *Ty = CFP->getType(); - - assert(Ty == Type::FloatTy || Ty == Type::DoubleTy && "Unknown FP type!"); - unsigned LoadOpcode = Ty == Type::FloatTy ? X86::FLDr32 : X86::FLDr64; - addConstantPoolReference(BMI(MBB, IP, LoadOpcode, 4, R), CPI); - } - - } else if (isa<ConstantPointerNull>(C)) { - // Copy zero (null pointer) to the register. - BMI(MBB, IP, X86::MOVir32, 1, R).addZImm(0); - } else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(C)) { - unsigned SrcReg = getReg(CPR->getValue(), MBB, IP); - BMI(MBB, IP, X86::MOVrr32, 1, R).addReg(SrcReg); - } else { - std::cerr << "Offending constant: " << C << "\n"; - assert(0 && "Type not handled yet!"); - } -} - -/// LoadArgumentsToVirtualRegs - Load all of the arguments to this function from -/// the stack into virtual registers. -/// -void ISel::LoadArgumentsToVirtualRegs(Function &Fn) { - // Emit instructions 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 - // ... - // - unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot - MachineFrameInfo *MFI = F->getFrameInfo(); - - for (Function::aiterator I = Fn.abegin(), E = Fn.aend(); I != E; ++I) { - unsigned Reg = getReg(*I); - - int FI; // Frame object index - switch (getClassB(I->getType())) { - case cByte: - FI = MFI->CreateFixedObject(1, ArgOffset); - addFrameReference(BuildMI(BB, X86::MOVmr8, 4, Reg), FI); - break; - case cShort: - FI = MFI->CreateFixedObject(2, ArgOffset); - addFrameReference(BuildMI(BB, X86::MOVmr16, 4, Reg), FI); - break; - case cInt: - FI = MFI->CreateFixedObject(4, ArgOffset); - addFrameReference(BuildMI(BB, X86::MOVmr32, 4, Reg), FI); - break; - case cLong: - FI = MFI->CreateFixedObject(8, ArgOffset); - addFrameReference(BuildMI(BB, X86::MOVmr32, 4, Reg), FI); - addFrameReference(BuildMI(BB, X86::MOVmr32, 4, Reg+1), FI, 4); - ArgOffset += 4; // longs require 4 additional bytes - break; - case cFP: - unsigned Opcode; - if (I->getType() == Type::FloatTy) { - Opcode = X86::FLDr32; - FI = MFI->CreateFixedObject(4, ArgOffset); - } else { - Opcode = X86::FLDr64; - FI = MFI->CreateFixedObject(8, ArgOffset); - ArgOffset += 4; // doubles require 4 additional bytes - } - addFrameReference(BuildMI(BB, Opcode, 4, Reg), FI); - break; - default: - assert(0 && "Unhandled argument type!"); - } - ArgOffset += 4; // Each argument takes at least 4 bytes on the stack... - } - - // If the function takes variable number of arguments, add a frame offset for - // the start of the first vararg value... this is used to expand - // llvm.va_start. - if (Fn.getFunctionType()->isVarArg()) - VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset); -} - - -/// SelectPHINodes - Insert machine code to generate phis. This is tricky -/// because we have to generate our sources into the source basic blocks, not -/// the current one. -/// -void ISel::SelectPHINodes() { - const TargetInstrInfo &TII = TM.getInstrInfo(); - const Function &LF = *F->getFunction(); // The LLVM function... - for (Function::const_iterator I = LF.begin(), E = LF.end(); I != E; ++I) { - const BasicBlock *BB = I; - MachineBasicBlock *MBB = MBBMap[I]; - - // Loop over all of the PHI nodes in the LLVM basic block... - unsigned NumPHIs = 0; - for (BasicBlock::const_iterator I = BB->begin(); - PHINode *PN = const_cast<PHINode*>(dyn_cast<PHINode>(I)); ++I) { - - // Create a new machine instr PHI node, and insert it. - unsigned PHIReg = getReg(*PN); - MachineInstr *PhiMI = BuildMI(X86::PHI, PN->getNumOperands(), PHIReg); - MBB->insert(MBB->begin()+NumPHIs++, PhiMI); - - MachineInstr *LongPhiMI = 0; - if (PN->getType() == Type::LongTy || PN->getType() == Type::ULongTy) { - LongPhiMI = BuildMI(X86::PHI, PN->getNumOperands(), PHIReg+1); - MBB->insert(MBB->begin()+NumPHIs++, LongPhiMI); - } - - // PHIValues - Map of blocks to incoming virtual registers. We use this - // so that we only initialize one incoming value for a particular block, - // even if the block has multiple entries in the PHI node. - // - std::map<MachineBasicBlock*, unsigned> PHIValues; - - for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { - MachineBasicBlock *PredMBB = MBBMap[PN->getIncomingBlock(i)]; - unsigned ValReg; - std::map<MachineBasicBlock*, unsigned>::iterator EntryIt = - PHIValues.lower_bound(PredMBB); - - if (EntryIt != PHIValues.end() && EntryIt->first == PredMBB) { - // We already inserted an initialization of the register for this - // predecessor. Recycle it. - ValReg = EntryIt->second; - - } else { - // Get the incoming value into a virtual register. - // - Value *Val = PN->getIncomingValue(i); - - // If this is a constant or GlobalValue, we may have to insert code - // into the basic block to compute it into a virtual register. - if (isa<Constant>(Val) || isa<GlobalValue>(Val)) { - // Because we don't want to clobber any values which might be in - // physical registers with the computation of this constant (which - // might be arbitrarily complex if it is a constant expression), - // just insert the computation at the top of the basic block. - MachineBasicBlock::iterator PI = PredMBB->begin(); - - // Skip over any PHI nodes though! - while (PI != PredMBB->end() && (*PI)->getOpcode() == X86::PHI) - ++PI; - - ValReg = getReg(Val, PredMBB, PI); - } else { - ValReg = getReg(Val); - } - - // Remember that we inserted a value for this PHI for this predecessor - PHIValues.insert(EntryIt, std::make_pair(PredMBB, ValReg)); - } - - PhiMI->addRegOperand(ValReg); - PhiMI->addMachineBasicBlockOperand(PredMBB); - if (LongPhiMI) { - LongPhiMI->addRegOperand(ValReg+1); - LongPhiMI->addMachineBasicBlockOperand(PredMBB); - } - } - } - } -} - -// canFoldSetCCIntoBranch - Return the setcc instruction if we can fold it into -// the conditional branch instruction which is the only user of the cc -// instruction. This is the case if the conditional branch is the only user of -// the setcc, and if the setcc is in the same basic block as the conditional -// branch. We also don't handle long arguments below, so we reject them here as -// well. -// -static SetCondInst *canFoldSetCCIntoBranch(Value *V) { - if (SetCondInst *SCI = dyn_cast<SetCondInst>(V)) - if (SCI->hasOneUse() && isa<BranchInst>(SCI->use_back()) && - SCI->getParent() == cast<BranchInst>(SCI->use_back())->getParent()) { - const Type *Ty = SCI->getOperand(0)->getType(); - if (Ty != Type::LongTy && Ty != Type::ULongTy) - return SCI; - } - return 0; -} - -// Return a fixed numbering for setcc instructions which does not depend on the -// order of the opcodes. -// -static unsigned getSetCCNumber(unsigned Opcode) { - switch(Opcode) { - default: assert(0 && "Unknown setcc instruction!"); - case Instruction::SetEQ: return 0; - case Instruction::SetNE: return 1; - case Instruction::SetLT: return 2; - case Instruction::SetGE: return 3; - case Instruction::SetGT: return 4; - case Instruction::SetLE: return 5; - } -} - -// LLVM -> X86 signed X86 unsigned -// ----- ---------- ------------ -// seteq -> sete sete -// setne -> setne setne -// setlt -> setl setb -// setge -> setge setae -// setgt -> setg seta -// setle -> setle setbe -// ---- -// sets // Used by comparison with 0 optimization -// setns -static const unsigned SetCCOpcodeTab[2][8] = { - { X86::SETEr, X86::SETNEr, X86::SETBr, X86::SETAEr, X86::SETAr, X86::SETBEr, - 0, 0 }, - { X86::SETEr, X86::SETNEr, X86::SETLr, X86::SETGEr, X86::SETGr, X86::SETLEr, - X86::SETSr, X86::SETNSr }, -}; - -// EmitComparison - This function emits a comparison of the two operands, -// returning the extended setcc code to use. -unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1, - MachineBasicBlock *MBB, - MachineBasicBlock::iterator &IP) { - // The arguments are already supposed to be of the same type. - const Type *CompTy = Op0->getType(); - unsigned Class = getClassB(CompTy); - unsigned Op0r = getReg(Op0, MBB, IP); - - // Special case handling of: cmp R, i - if (Class == cByte || Class == cShort || Class == cInt) - if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) { - uint64_t Op1v = cast<ConstantInt>(CI)->getRawValue(); - - // Mask off any upper bits of the constant, if there are any... - Op1v &= (1ULL << (8 << Class)) - 1; - - // If this is a comparison against zero, emit more efficient code. We - // can't handle unsigned comparisons against zero unless they are == or - // !=. These should have been strength reduced already anyway. - if (Op1v == 0 && (CompTy->isSigned() || OpNum < 2)) { - static const unsigned TESTTab[] = { - X86::TESTrr8, X86::TESTrr16, X86::TESTrr32 - }; - BMI(MBB, IP, TESTTab[Class], 2).addReg(Op0r).addReg(Op0r); - - if (OpNum == 2) return 6; // Map jl -> js - if (OpNum == 3) return 7; // Map jg -> jns - return OpNum; - } - - static const unsigned CMPTab[] = { - X86::CMPri8, X86::CMPri16, X86::CMPri32 - }; - - BMI(MBB, IP, CMPTab[Class], 2).addReg(Op0r).addZImm(Op1v); - return OpNum; - } - - unsigned Op1r = getReg(Op1, MBB, IP); - switch (Class) { - default: assert(0 && "Unknown type class!"); - // Emit: cmp <var1>, <var2> (do the comparison). We can - // compare 8-bit with 8-bit, 16-bit with 16-bit, 32-bit with - // 32-bit. - case cByte: - BMI(MBB, IP, X86::CMPrr8, 2).addReg(Op0r).addReg(Op1r); - break; - case cShort: - BMI(MBB, IP, X86::CMPrr16, 2).addReg(Op0r).addReg(Op1r); - break; - case cInt: - BMI(MBB, IP, X86::CMPrr32, 2).addReg(Op0r).addReg(Op1r); - break; - case cFP: - BMI(MBB, IP, X86::FpUCOM, 2).addReg(Op0r).addReg(Op1r); - BMI(MBB, IP, X86::FNSTSWr8, 0); - BMI(MBB, IP, X86::SAHF, 1); - break; - - case cLong: - if (OpNum < 2) { // seteq, setne - unsigned LoTmp = makeAnotherReg(Type::IntTy); - unsigned HiTmp = makeAnotherReg(Type::IntTy); - unsigned FinalTmp = makeAnotherReg(Type::IntTy); - BMI(MBB, IP, X86::XORrr32, 2, LoTmp).addReg(Op0r).addReg(Op1r); - BMI(MBB, IP, X86::XORrr32, 2, HiTmp).addReg(Op0r+1).addReg(Op1r+1); - BMI(MBB, IP, X86::ORrr32, 2, FinalTmp).addReg(LoTmp).addReg(HiTmp); - break; // Allow the sete or setne to be generated from flags set by OR - } else { - // Emit a sequence of code which compares the high and low parts once - // each, then uses a conditional move to handle the overflow case. For - // example, a setlt for long would generate code like this: - // - // AL = lo(op1) < lo(op2) // Signedness depends on operands - // BL = hi(op1) < hi(op2) // Always unsigned comparison - // dest = hi(op1) == hi(op2) ? AL : BL; - // - - // FIXME: This would be much better if we had hierarchical register - // classes! Until then, hardcode registers so that we can deal with their - // aliases (because we don't have conditional byte moves). - // - BMI(MBB, IP, X86::CMPrr32, 2).addReg(Op0r).addReg(Op1r); - BMI(MBB, IP, SetCCOpcodeTab[0][OpNum], 0, X86::AL); - BMI(MBB, IP, X86::CMPrr32, 2).addReg(Op0r+1).addReg(Op1r+1); - BMI(MBB, IP, SetCCOpcodeTab[CompTy->isSigned()][OpNum], 0, X86::BL); - BMI(MBB, IP, X86::IMPLICIT_DEF, 0, X86::BH); - BMI(MBB, IP, X86::IMPLICIT_DEF, 0, X86::AH); - BMI(MBB, IP, X86::CMOVErr16, 2, X86::BX).addReg(X86::BX).addReg(X86::AX); - // NOTE: visitSetCondInst knows that the value is dumped into the BL - // register at this point for long values... - return OpNum; - } - } - return OpNum; -} - - -/// SetCC instructions - Here we just emit boilerplate code to set a byte-sized -/// register, then move it to wherever the result should be. -/// -void ISel::visitSetCondInst(SetCondInst &I) { - if (canFoldSetCCIntoBranch(&I)) return; // Fold this into a branch... - - unsigned DestReg = getReg(I); - MachineBasicBlock::iterator MII = BB->end(); - emitSetCCOperation(BB, MII, I.getOperand(0), I.getOperand(1), I.getOpcode(), - DestReg); -} - -/// emitSetCCOperation - Common code shared between visitSetCondInst and -/// constant expression support. -void ISel::emitSetCCOperation(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &IP, - Value *Op0, Value *Op1, unsigned Opcode, - unsigned TargetReg) { - unsigned OpNum = getSetCCNumber(Opcode); - OpNum = EmitComparison(OpNum, Op0, Op1, MBB, IP); - - const Type *CompTy = Op0->getType(); - unsigned CompClass = getClassB(CompTy); - bool isSigned = CompTy->isSigned() && CompClass != cFP; - - if (CompClass != cLong || OpNum < 2) { - // Handle normal comparisons with a setcc instruction... - BMI(MBB, IP, SetCCOpcodeTab[isSigned][OpNum], 0, TargetReg); - } else { - // Handle long comparisons by copying the value which is already in BL into - // the register we want... - BMI(MBB, IP, X86::MOVrr8, 1, TargetReg).addReg(X86::BL); - } -} - - - - -/// promote32 - Emit instructions to turn a narrow operand into a 32-bit-wide -/// operand, in the specified target register. -void ISel::promote32(unsigned targetReg, const ValueRecord &VR) { - bool isUnsigned = VR.Ty->isUnsigned(); - - // Make sure we have the register number for this value... - unsigned Reg = VR.Val ? getReg(VR.Val) : VR.Reg; - - switch (getClassB(VR.Ty)) { - case cByte: - // Extend value into target register (8->32) - if (isUnsigned) - BuildMI(BB, X86::MOVZXr32r8, 1, targetReg).addReg(Reg); - else - BuildMI(BB, X86::MOVSXr32r8, 1, targetReg).addReg(Reg); - break; - case cShort: - // Extend value into target register (16->32) - if (isUnsigned) - BuildMI(BB, X86::MOVZXr32r16, 1, targetReg).addReg(Reg); - else - BuildMI(BB, X86::MOVSXr32r16, 1, targetReg).addReg(Reg); - break; - case cInt: - // Move value into target register (32->32) - BuildMI(BB, X86::MOVrr32, 1, targetReg).addReg(Reg); - break; - default: - assert(0 && "Unpromotable operand class in promote32"); - } -} - -/// 'ret' instruction - Here we are interested in meeting the x86 ABI. As such, -/// we have the following possibilities: -/// -/// ret void: No return value, simply emit a 'ret' instruction -/// ret sbyte, ubyte : Extend value into EAX and return -/// ret short, ushort: Extend value into EAX and return -/// ret int, uint : Move value into EAX and return -/// ret pointer : Move value into EAX and return -/// ret long, ulong : Move value into EAX/EDX and return -/// ret float/double : Top of FP stack -/// -void ISel::visitReturnInst(ReturnInst &I) { - if (I.getNumOperands() == 0) { - BuildMI(BB, X86::RET, 0); // Just emit a 'ret' instruction - return; - } - - Value *RetVal = I.getOperand(0); - unsigned RetReg = getReg(RetVal); - switch (getClassB(RetVal->getType())) { - case cByte: // integral return values: extend or move into EAX and return - case cShort: - case cInt: - promote32(X86::EAX, ValueRecord(RetReg, RetVal->getType())); - // Declare that EAX is live on exit - BuildMI(BB, X86::IMPLICIT_USE, 2).addReg(X86::EAX).addReg(X86::ESP); - break; - case cFP: // Floats & Doubles: Return in ST(0) - BuildMI(BB, X86::FpSETRESULT, 1).addReg(RetReg); - // Declare that top-of-stack is live on exit - BuildMI(BB, X86::IMPLICIT_USE, 2).addReg(X86::ST0).addReg(X86::ESP); - break; - case cLong: - BuildMI(BB, X86::MOVrr32, 1, X86::EAX).addReg(RetReg); - BuildMI(BB, X86::MOVrr32, 1, X86::EDX).addReg(RetReg+1); - // Declare that EAX & EDX are live on exit - BuildMI(BB, X86::IMPLICIT_USE, 3).addReg(X86::EAX).addReg(X86::EDX) - .addReg(X86::ESP); - break; - default: - visitInstruction(I); - } - // Emit a 'ret' instruction - BuildMI(BB, X86::RET, 0); -} - -// getBlockAfter - Return the basic block which occurs lexically after the -// specified one. -static inline BasicBlock *getBlockAfter(BasicBlock *BB) { - Function::iterator I = BB; ++I; // Get iterator to next block - return I != BB->getParent()->end() ? &*I : 0; -} - -/// visitBranchInst - Handle conditional and unconditional branches here. Note -/// that since code layout is frozen at this point, that if we are trying to -/// jump to a block that is the immediate successor of the current block, we can -/// just make a fall-through (but we don't currently). -/// -void ISel::visitBranchInst(BranchInst &BI) { - BasicBlock *NextBB = getBlockAfter(BI.getParent()); // BB after current one - - if (!BI.isConditional()) { // Unconditional branch? - if (BI.getSuccessor(0) != NextBB) - BuildMI(BB, X86::JMP, 1).addPCDisp(BI.getSuccessor(0)); - return; - } - - // See if we can fold the setcc into the branch itself... - SetCondInst *SCI = canFoldSetCCIntoBranch(BI.getCondition()); - if (SCI == 0) { - // Nope, cannot fold setcc into this branch. Emit a branch on a condition - // computed some other way... - unsigned condReg = getReg(BI.getCondition()); - BuildMI(BB, X86::CMPri8, 2).addReg(condReg).addZImm(0); - if (BI.getSuccessor(1) == NextBB) { - if (BI.getSuccessor(0) != NextBB) - BuildMI(BB, X86::JNE, 1).addPCDisp(BI.getSuccessor(0)); - } else { - BuildMI(BB, X86::JE, 1).addPCDisp(BI.getSuccessor(1)); - - if (BI.getSuccessor(0) != NextBB) - BuildMI(BB, X86::JMP, 1).addPCDisp(BI.getSuccessor(0)); - } - return; - } - - unsigned OpNum = getSetCCNumber(SCI->getOpcode()); - MachineBasicBlock::iterator MII = BB->end(); - OpNum = EmitComparison(OpNum, SCI->getOperand(0), SCI->getOperand(1), BB,MII); - - const Type *CompTy = SCI->getOperand(0)->getType(); - bool isSigned = CompTy->isSigned() && getClassB(CompTy) != cFP; - - - // LLVM -> X86 signed X86 unsigned - // ----- ---------- ------------ - // seteq -> je je - // setne -> jne jne - // setlt -> jl jb - // setge -> jge jae - // setgt -> jg ja - // setle -> jle jbe - // ---- - // js // Used by comparison with 0 optimization - // jns - - static const unsigned OpcodeTab[2][8] = { - { X86::JE, X86::JNE, X86::JB, X86::JAE, X86::JA, X86::JBE, 0, 0 }, - { X86::JE, X86::JNE, X86::JL, X86::JGE, X86::JG, X86::JLE, - X86::JS, X86::JNS }, - }; - - if (BI.getSuccessor(0) != NextBB) { - BuildMI(BB, OpcodeTab[isSigned][OpNum], 1).addPCDisp(BI.getSuccessor(0)); - if (BI.getSuccessor(1) != NextBB) - BuildMI(BB, X86::JMP, 1).addPCDisp(BI.getSuccessor(1)); - } else { - // Change to the inverse condition... - if (BI.getSuccessor(1) != NextBB) { - OpNum ^= 1; - BuildMI(BB, OpcodeTab[isSigned][OpNum], 1).addPCDisp(BI.getSuccessor(1)); - } - } -} - - -/// doCall - This emits an abstract call instruction, setting up the arguments -/// and the return value as appropriate. For the actual function call itself, -/// it inserts the specified CallMI instruction into the stream. -/// -void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI, - const std::vector<ValueRecord> &Args) { - - // Count how many bytes are to be pushed on the stack... - unsigned NumBytes = 0; - - if (!Args.empty()) { - for (unsigned i = 0, e = Args.size(); i != e; ++i) - switch (getClassB(Args[i].Ty)) { - case cByte: case cShort: case cInt: - NumBytes += 4; break; - case cLong: - NumBytes += 8; break; - case cFP: - NumBytes += Args[i].Ty == Type::FloatTy ? 4 : 8; - break; - default: assert(0 && "Unknown class!"); - } - - // Adjust the stack pointer for the new arguments... - BuildMI(BB, X86::ADJCALLSTACKDOWN, 1).addZImm(NumBytes); - - // Arguments go on the stack in reverse order, as specified by the ABI. - unsigned ArgOffset = 0; - for (unsigned i = 0, e = Args.size(); i != e; ++i) { - unsigned ArgReg = Args[i].Val ? getReg(Args[i].Val) : Args[i].Reg; - switch (getClassB(Args[i].Ty)) { - case cByte: - case cShort: { - // Promote arg to 32 bits wide into a temporary register... - unsigned R = makeAnotherReg(Type::UIntTy); - promote32(R, Args[i]); - addRegOffset(BuildMI(BB, X86::MOVrm32, 5), - X86::ESP, ArgOffset).addReg(R); - break; - } - case cInt: - addRegOffset(BuildMI(BB, X86::MOVrm32, 5), - X86::ESP, ArgOffset).addReg(ArgReg); - break; - case cLong: - addRegOffset(BuildMI(BB, X86::MOVrm32, 5), - X86::ESP, ArgOffset).addReg(ArgReg); - addRegOffset(BuildMI(BB, X86::MOVrm32, 5), - X86::ESP, ArgOffset+4).addReg(ArgReg+1); - ArgOffset += 4; // 8 byte entry, not 4. - break; - - case cFP: - if (Args[i].Ty == Type::FloatTy) { - addRegOffset(BuildMI(BB, X86::FSTr32, 5), - X86::ESP, ArgOffset).addReg(ArgReg); - } else { - assert(Args[i].Ty == Type::DoubleTy && "Unknown FP type!"); - addRegOffset(BuildMI(BB, X86::FSTr64, 5), - X86::ESP, ArgOffset).addReg(ArgReg); - ArgOffset += 4; // 8 byte entry, not 4. - } - break; - - default: assert(0 && "Unknown class!"); - } - ArgOffset += 4; - } - } else { - BuildMI(BB, X86::ADJCALLSTACKDOWN, 1).addZImm(0); - } - - BB->push_back(CallMI); - - BuildMI(BB, X86::ADJCALLSTACKUP, 1).addZImm(NumBytes); - - // If there is a return value, scavenge the result from the location the call - // leaves it in... - // - if (Ret.Ty != Type::VoidTy) { - unsigned DestClass = getClassB(Ret.Ty); - switch (DestClass) { - case cByte: - case cShort: - case cInt: { - // Integral results are in %eax, or the appropriate portion - // thereof. - static const unsigned regRegMove[] = { - X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 - }; - static const unsigned AReg[] = { X86::AL, X86::AX, X86::EAX }; - BuildMI(BB, regRegMove[DestClass], 1, Ret.Reg).addReg(AReg[DestClass]); - break; - } - case cFP: // Floating-point return values live in %ST(0) - BuildMI(BB, X86::FpGETRESULT, 1, Ret.Reg); - break; - case cLong: // Long values are left in EDX:EAX - BuildMI(BB, X86::MOVrr32, 1, Ret.Reg).addReg(X86::EAX); - BuildMI(BB, X86::MOVrr32, 1, Ret.Reg+1).addReg(X86::EDX); - break; - default: assert(0 && "Unknown class!"); - } - } -} - - -/// visitCallInst - Push args on stack and do a procedure call instruction. -void ISel::visitCallInst(CallInst &CI) { - MachineInstr *TheCall; - if (Function *F = CI.getCalledFunction()) { - // Is it an intrinsic function call? - if (LLVMIntrinsic::ID ID = (LLVMIntrinsic::ID)F->getIntrinsicID()) { - visitIntrinsicCall(ID, CI); // Special intrinsics are not handled here - return; - } - - // Emit a CALL instruction with PC-relative displacement. - TheCall = BuildMI(X86::CALLpcrel32, 1).addGlobalAddress(F, true); - } else { // Emit an indirect call... - unsigned Reg = getReg(CI.getCalledValue()); - TheCall = BuildMI(X86::CALLr32, 1).addReg(Reg); - } - - std::vector<ValueRecord> Args; - for (unsigned i = 1, e = CI.getNumOperands(); i != e; ++i) - Args.push_back(ValueRecord(CI.getOperand(i))); - - unsigned DestReg = CI.getType() != Type::VoidTy ? getReg(CI) : 0; - doCall(ValueRecord(DestReg, CI.getType()), TheCall, Args); -} - - -void ISel::visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &CI) { - unsigned TmpReg1, TmpReg2; - switch (ID) { - case LLVMIntrinsic::va_start: - // Get the address of the first vararg value... - TmpReg1 = getReg(CI); - addFrameReference(BuildMI(BB, X86::LEAr32, 5, TmpReg1), VarArgsFrameIndex); - return; - - case LLVMIntrinsic::va_copy: - TmpReg1 = getReg(CI); - TmpReg2 = getReg(CI.getOperand(1)); - BuildMI(BB, X86::MOVrr32, 1, TmpReg1).addReg(TmpReg2); - return; - case LLVMIntrinsic::va_end: return; // Noop on X86 - - case LLVMIntrinsic::longjmp: - case LLVMIntrinsic::siglongjmp: - BuildMI(BB, X86::CALLpcrel32, 1).addExternalSymbol("abort", true); - return; - - case LLVMIntrinsic::setjmp: - case LLVMIntrinsic::sigsetjmp: - // Setjmp always returns zero... - BuildMI(BB, X86::MOVir32, 1, getReg(CI)).addZImm(0); - return; - default: assert(0 && "Unknown intrinsic for X86!"); - } -} - - -/// visitSimpleBinary - Implement simple binary operators for integral types... -/// OperatorClass is one of: 0 for Add, 1 for Sub, 2 for And, 3 for Or, 4 for -/// Xor. -void ISel::visitSimpleBinary(BinaryOperator &B, unsigned OperatorClass) { - unsigned DestReg = getReg(B); - MachineBasicBlock::iterator MI = BB->end(); - emitSimpleBinaryOperation(BB, MI, B.getOperand(0), B.getOperand(1), - OperatorClass, DestReg); -} - -/// emitSimpleBinaryOperation - Implement simple binary operators for integral -/// types... OperatorClass is one of: 0 for Add, 1 for Sub, 2 for And, 3 for -/// Or, 4 for Xor. -/// -/// emitSimpleBinaryOperation - Common code shared between visitSimpleBinary -/// and constant expression support. -/// -void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &IP, - Value *Op0, Value *Op1, - unsigned OperatorClass, unsigned DestReg) { - unsigned Class = getClassB(Op0->getType()); - - // sub 0, X -> neg X - if (OperatorClass == 1 && Class != cLong) - if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0)) - if (CI->isNullValue()) { - unsigned op1Reg = getReg(Op1, MBB, IP); - switch (Class) { - default: assert(0 && "Unknown class for this function!"); - case cByte: - BMI(MBB, IP, X86::NEGr8, 1, DestReg).addReg(op1Reg); - return; - case cShort: - BMI(MBB, IP, X86::NEGr16, 1, DestReg).addReg(op1Reg); - return; - case cInt: - BMI(MBB, IP, X86::NEGr32, 1, DestReg).addReg(op1Reg); - return; - } - } - - if (!isa<ConstantInt>(Op1) || Class == cLong) { - static const unsigned OpcodeTab[][4] = { - // Arithmetic operators - { X86::ADDrr8, X86::ADDrr16, X86::ADDrr32, X86::FpADD }, // ADD - { X86::SUBrr8, X86::SUBrr16, X86::SUBrr32, X86::FpSUB }, // SUB - - // Bitwise operators - { X86::ANDrr8, X86::ANDrr16, X86::ANDrr32, 0 }, // AND - { X86:: ORrr8, X86:: ORrr16, X86:: ORrr32, 0 }, // OR - { X86::XORrr8, X86::XORrr16, X86::XORrr32, 0 }, // XOR - }; - - bool isLong = false; - if (Class == cLong) { - isLong = true; - Class = cInt; // Bottom 32 bits are handled just like ints - } - - unsigned Opcode = OpcodeTab[OperatorClass][Class]; - assert(Opcode && "Floating point arguments to logical inst?"); - unsigned Op0r = getReg(Op0, MBB, IP); - unsigned Op1r = getReg(Op1, MBB, IP); - BMI(MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addReg(Op1r); - - if (isLong) { // Handle the upper 32 bits of long values... - static const unsigned TopTab[] = { - X86::ADCrr32, X86::SBBrr32, X86::ANDrr32, X86::ORrr32, X86::XORrr32 - }; - BMI(MBB, IP, TopTab[OperatorClass], 2, - DestReg+1).addReg(Op0r+1).addReg(Op1r+1); - } - return; - } - - // Special case: op Reg, <const> - ConstantInt *Op1C = cast<ConstantInt>(Op1); - unsigned Op0r = getReg(Op0, MBB, IP); - - // xor X, -1 -> not X - if (OperatorClass == 4 && Op1C->isAllOnesValue()) { - static unsigned const NOTTab[] = { X86::NOTr8, X86::NOTr16, X86::NOTr32 }; - BMI(MBB, IP, NOTTab[Class], 1, DestReg).addReg(Op0r); - return; - } - - // add X, -1 -> dec X - if (OperatorClass == 0 && Op1C->isAllOnesValue()) { - static unsigned const DECTab[] = { X86::DECr8, X86::DECr16, X86::DECr32 }; - BMI(MBB, IP, DECTab[Class], 1, DestReg).addReg(Op0r); - return; - } - - // add X, 1 -> inc X - if (OperatorClass == 0 && Op1C->equalsInt(1)) { - static unsigned const DECTab[] = { X86::INCr8, X86::INCr16, X86::INCr32 }; - BMI(MBB, IP, DECTab[Class], 1, DestReg).addReg(Op0r); - return; - } - - static const unsigned OpcodeTab[][3] = { - // Arithmetic operators - { X86::ADDri8, X86::ADDri16, X86::ADDri32 }, // ADD - { X86::SUBri8, X86::SUBri16, X86::SUBri32 }, // SUB - - // Bitwise operators - { X86::ANDri8, X86::ANDri16, X86::ANDri32 }, // AND - { X86:: ORri8, X86:: ORri16, X86:: ORri32 }, // OR - { X86::XORri8, X86::XORri16, X86::XORri32 }, // XOR - }; - - assert(Class < 3 && "General code handles 64-bit integer types!"); - unsigned Opcode = OpcodeTab[OperatorClass][Class]; - uint64_t Op1v = cast<ConstantInt>(Op1C)->getRawValue(); - - // Mask off any upper bits of the constant, if there are any... - Op1v &= (1ULL << (8 << Class)) - 1; - BMI(MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addZImm(Op1v); -} - -/// doMultiply - Emit appropriate instructions to multiply together the -/// registers op0Reg and op1Reg, and put the result in DestReg. The type of the -/// result should be given as DestTy. -/// -void ISel::doMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator &MBBI, - unsigned DestReg, const Type *DestTy, - unsigned op0Reg, unsigned op1Reg) { - unsigned Class = getClass(DestTy); - switch (Class) { - case cFP: // Floating point multiply - BMI(BB, MBBI, X86::FpMUL, 2, DestReg).addReg(op0Reg).addReg(op1Reg); - return; - case cInt: - case cShort: - BMI(BB, MBBI, Class == cInt ? X86::IMULrr32 : X86::IMULrr16, 2, DestReg) - .addReg(op0Reg).addReg(op1Reg); - return; - case cByte: - // Must use the MUL instruction, which forces use of AL... - BMI(MBB, MBBI, X86::MOVrr8, 1, X86::AL).addReg(op0Reg); - BMI(MBB, MBBI, X86::MULr8, 1).addReg(op1Reg); - BMI(MBB, MBBI, X86::MOVrr8, 1, DestReg).addReg(X86::AL); - return; - default: - case cLong: assert(0 && "doMultiply cannot operate on LONG values!"); - } -} - -// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N. It -// returns zero when the input is not exactly a power of two. -static unsigned ExactLog2(unsigned Val) { - if (Val == 0) return 0; - unsigned Count = 0; - while (Val != 1) { - if (Val & 1) return 0; - Val >>= 1; - ++Count; - } - return Count+1; -} - -void ISel::doMultiplyConst(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &IP, - unsigned DestReg, const Type *DestTy, - unsigned op0Reg, unsigned ConstRHS) { - unsigned Class = getClass(DestTy); - - // If the element size is exactly a power of 2, use a shift to get it. - if (unsigned Shift = ExactLog2(ConstRHS)) { - switch (Class) { - default: assert(0 && "Unknown class for this function!"); - case cByte: - BMI(MBB, IP, X86::SHLir32, 2, DestReg).addReg(op0Reg).addZImm(Shift-1); - return; - case cShort: - BMI(MBB, IP, X86::SHLir32, 2, DestReg).addReg(op0Reg).addZImm(Shift-1); - return; - case cInt: - BMI(MBB, IP, X86::SHLir32, 2, DestReg).addReg(op0Reg).addZImm(Shift-1); - return; - } - } - - if (Class == cShort) { - BMI(MBB, IP, X86::IMULri16, 2, DestReg).addReg(op0Reg).addZImm(ConstRHS); - return; - } else if (Class == cInt) { - BMI(MBB, IP, X86::IMULri32, 2, DestReg).addReg(op0Reg).addZImm(ConstRHS); - return; - } - - // Most general case, emit a normal multiply... - static const unsigned MOVirTab[] = { - X86::MOVir8, X86::MOVir16, X86::MOVir32 - }; - - unsigned TmpReg = makeAnotherReg(DestTy); - BMI(MBB, IP, MOVirTab[Class], 1, TmpReg).addZImm(ConstRHS); - - // Emit a MUL to multiply the register holding the index by - // elementSize, putting the result in OffsetReg. - doMultiply(MBB, IP, DestReg, DestTy, op0Reg, TmpReg); -} - -/// visitMul - Multiplies are not simple binary operators because they must deal -/// with the EAX register explicitly. -/// -void ISel::visitMul(BinaryOperator &I) { - unsigned Op0Reg = getReg(I.getOperand(0)); - unsigned DestReg = getReg(I); - - // Simple scalar multiply? - if (I.getType() != Type::LongTy && I.getType() != Type::ULongTy) { - if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1))) { - unsigned Val = (unsigned)CI->getRawValue(); // Cannot be 64-bit constant - MachineBasicBlock::iterator MBBI = BB->end(); - doMultiplyConst(BB, MBBI, DestReg, I.getType(), Op0Reg, Val); - } else { - unsigned Op1Reg = getReg(I.getOperand(1)); - MachineBasicBlock::iterator MBBI = BB->end(); - doMultiply(BB, MBBI, DestReg, I.getType(), Op0Reg, Op1Reg); - } - } else { - unsigned Op1Reg = getReg(I.getOperand(1)); - - // Long value. We have to do things the hard way... - // Multiply the two low parts... capturing carry into EDX - BuildMI(BB, X86::MOVrr32, 1, X86::EAX).addReg(Op0Reg); - BuildMI(BB, X86::MULr32, 1).addReg(Op1Reg); // AL*BL - - unsigned OverflowReg = makeAnotherReg(Type::UIntTy); - BuildMI(BB, X86::MOVrr32, 1, DestReg).addReg(X86::EAX); // AL*BL - BuildMI(BB, X86::MOVrr32, 1, OverflowReg).addReg(X86::EDX); // AL*BL >> 32 - - MachineBasicBlock::iterator MBBI = BB->end(); - unsigned AHBLReg = makeAnotherReg(Type::UIntTy); // AH*BL - BMI(BB, MBBI, X86::IMULrr32, 2, AHBLReg).addReg(Op0Reg+1).addReg(Op1Reg); - - unsigned AHBLplusOverflowReg = makeAnotherReg(Type::UIntTy); - BuildMI(BB, X86::ADDrr32, 2, // AH*BL+(AL*BL >> 32) - AHBLplusOverflowReg).addReg(AHBLReg).addReg(OverflowReg); - - MBBI = BB->end(); - unsigned ALBHReg = makeAnotherReg(Type::UIntTy); // AL*BH - BMI(BB, MBBI, X86::IMULrr32, 2, ALBHReg).addReg(Op0Reg).addReg(Op1Reg+1); - - BuildMI(BB, X86::ADDrr32, 2, // AL*BH + AH*BL + (AL*BL >> 32) - DestReg+1).addReg(AHBLplusOverflowReg).addReg(ALBHReg); - } -} - - -/// visitDivRem - Handle division and remainder instructions... these -/// instruction both require the same instructions to be generated, they just -/// select the result from a different register. Note that both of these -/// instructions work differently for signed and unsigned operands. -/// -void ISel::visitDivRem(BinaryOperator &I) { - unsigned Op0Reg = getReg(I.getOperand(0)); - unsigned Op1Reg = getReg(I.getOperand(1)); - unsigned ResultReg = getReg(I); - - MachineBasicBlock::iterator IP = BB->end(); - emitDivRemOperation(BB, IP, Op0Reg, Op1Reg, I.getOpcode() == Instruction::Div, - I.getType(), ResultReg); -} - -void ISel::emitDivRemOperation(MachineBasicBlock *BB, - MachineBasicBlock::iterator &IP, - unsigned Op0Reg, unsigned Op1Reg, bool isDiv, - const Type *Ty, unsigned ResultReg) { - unsigned Class = getClass(Ty); - switch (Class) { - case cFP: // Floating point divide - if (isDiv) { - BuildMI(BB, X86::FpDIV, 2, ResultReg).addReg(Op0Reg).addReg(Op1Reg); - } else { // Floating point remainder... - MachineInstr *TheCall = - BuildMI(X86::CALLpcrel32, 1).addExternalSymbol("fmod", true); - std::vector<ValueRecord> Args; - Args.push_back(ValueRecord(Op0Reg, Type::DoubleTy)); - Args.push_back(ValueRecord(Op1Reg, Type::DoubleTy)); - doCall(ValueRecord(ResultReg, Type::DoubleTy), TheCall, Args); - } - return; - case cLong: { - static const char *FnName[] = - { "__moddi3", "__divdi3", "__umoddi3", "__udivdi3" }; - - unsigned NameIdx = Ty->isUnsigned()*2 + isDiv; - MachineInstr *TheCall = - BuildMI(X86::CALLpcrel32, 1).addExternalSymbol(FnName[NameIdx], true); - - std::vector<ValueRecord> Args; - Args.push_back(ValueRecord(Op0Reg, Type::LongTy)); - Args.push_back(ValueRecord(Op1Reg, Type::LongTy)); - doCall(ValueRecord(ResultReg, Type::LongTy), TheCall, Args); - return; - } - case cByte: case cShort: case cInt: - break; // Small integrals, handled below... - default: assert(0 && "Unknown class!"); - } - - static const unsigned Regs[] ={ X86::AL , X86::AX , X86::EAX }; - static const unsigned MovOpcode[]={ X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 }; - static const unsigned SarOpcode[]={ X86::SARir8, X86::SARir16, X86::SARir32 }; - static const unsigned ClrOpcode[]={ X86::XORrr8, X86::XORrr16, X86::XORrr32 }; - static const unsigned ExtRegs[] ={ X86::AH , X86::DX , X86::EDX }; - - static const unsigned DivOpcode[][4] = { - { X86::DIVr8 , X86::DIVr16 , X86::DIVr32 , 0 }, // Unsigned division - { X86::IDIVr8, X86::IDIVr16, X86::IDIVr32, 0 }, // Signed division - }; - - bool isSigned = Ty->isSigned(); - unsigned Reg = Regs[Class]; - unsigned ExtReg = ExtRegs[Class]; - - // Put the first operand into one of the A registers... - BuildMI(BB, MovOpcode[Class], 1, Reg).addReg(Op0Reg); - - if (isSigned) { - // Emit a sign extension instruction... - unsigned ShiftResult = makeAnotherReg(Ty); - BuildMI(BB, SarOpcode[Class], 2, ShiftResult).addReg(Op0Reg).addZImm(31); - BuildMI(BB, MovOpcode[Class], 1, ExtReg).addReg(ShiftResult); - } else { - // If unsigned, emit a zeroing instruction... (reg = xor reg, reg) - BuildMI(BB, ClrOpcode[Class], 2, ExtReg).addReg(ExtReg).addReg(ExtReg); - } - - // Emit the appropriate divide or remainder instruction... - BuildMI(BB, DivOpcode[isSigned][Class], 1).addReg(Op1Reg); - - // Figure out which register we want to pick the result out of... - unsigned DestReg = isDiv ? Reg : ExtReg; - - // Put the result into the destination register... - BuildMI(BB, MovOpcode[Class], 1, ResultReg).addReg(DestReg); -} - - -/// Shift instructions: 'shl', 'sar', 'shr' - Some special cases here -/// for constant immediate shift values, and for constant immediate -/// shift values equal to 1. Even the general case is sort of special, -/// because the shift amount has to be in CL, not just any old register. -/// -void ISel::visitShiftInst(ShiftInst &I) { - unsigned SrcReg = getReg(I.getOperand(0)); - unsigned DestReg = getReg(I); - bool isLeftShift = I.getOpcode() == Instruction::Shl; - bool isSigned = I.getType()->isSigned(); - unsigned Class = getClass(I.getType()); - - static const unsigned ConstantOperand[][4] = { - { X86::SHRir8, X86::SHRir16, X86::SHRir32, X86::SHRDir32 }, // SHR - { X86::SARir8, X86::SARir16, X86::SARir32, X86::SHRDir32 }, // SAR - { X86::SHLir8, X86::SHLir16, X86::SHLir32, X86::SHLDir32 }, // SHL - { X86::SHLir8, X86::SHLir16, X86::SHLir32, X86::SHLDir32 }, // SAL = SHL - }; - - static const unsigned NonConstantOperand[][4] = { - { X86::SHRrr8, X86::SHRrr16, X86::SHRrr32 }, // SHR - { X86::SARrr8, X86::SARrr16, X86::SARrr32 }, // SAR - { X86::SHLrr8, X86::SHLrr16, X86::SHLrr32 }, // SHL - { X86::SHLrr8, X86::SHLrr16, X86::SHLrr32 }, // SAL = SHL - }; - - // Longs, as usual, are handled specially... - if (Class == cLong) { - // If we have a constant shift, we can generate much more efficient code - // than otherwise... - // - if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(I.getOperand(1))) { - unsigned Amount = CUI->getValue(); - if (Amount < 32) { - const unsigned *Opc = ConstantOperand[isLeftShift*2+isSigned]; - if (isLeftShift) { - BuildMI(BB, Opc[3], 3, - DestReg+1).addReg(SrcReg+1).addReg(SrcReg).addZImm(Amount); - BuildMI(BB, Opc[2], 2, DestReg).addReg(SrcReg).addZImm(Amount); - } else { - BuildMI(BB, Opc[3], 3, - DestReg).addReg(SrcReg ).addReg(SrcReg+1).addZImm(Amount); - BuildMI(BB, Opc[2], 2, DestReg+1).addReg(SrcReg+1).addZImm(Amount); - } - } else { // Shifting more than 32 bits - Amount -= 32; - if (isLeftShift) { - BuildMI(BB, X86::SHLir32, 2,DestReg+1).addReg(SrcReg).addZImm(Amount); - BuildMI(BB, X86::MOVir32, 1,DestReg ).addZImm(0); - } else { - unsigned Opcode = isSigned ? X86::SARir32 : X86::SHRir32; - BuildMI(BB, Opcode, 2, DestReg).addReg(SrcReg+1).addZImm(Amount); - BuildMI(BB, X86::MOVir32, 1, DestReg+1).addZImm(0); - } - } - } else { - unsigned TmpReg = makeAnotherReg(Type::IntTy); - - if (!isLeftShift && isSigned) { - // If this is a SHR of a Long, then we need to do funny sign extension - // stuff. TmpReg gets the value to use as the high-part if we are - // shifting more than 32 bits. - BuildMI(BB, X86::SARir32, 2, TmpReg).addReg(SrcReg).addZImm(31); - } else { - // Other shifts use a fixed zero value if the shift is more than 32 - // bits. - BuildMI(BB, X86::MOVir32, 1, TmpReg).addZImm(0); - } - - // Initialize CL with the shift amount... - unsigned ShiftAmount = getReg(I.getOperand(1)); - BuildMI(BB, X86::MOVrr8, 1, X86::CL).addReg(ShiftAmount); - - unsigned TmpReg2 = makeAnotherReg(Type::IntTy); - unsigned TmpReg3 = makeAnotherReg(Type::IntTy); - if (isLeftShift) { - // TmpReg2 = shld inHi, inLo - BuildMI(BB, X86::SHLDrr32, 2, TmpReg2).addReg(SrcReg+1).addReg(SrcReg); - // TmpReg3 = shl inLo, CL - BuildMI(BB, X86::SHLrr32, 1, TmpReg3).addReg(SrcReg); - - // Set the flags to indicate whether the shift was by more than 32 bits. - BuildMI(BB, X86::TESTri8, 2).addReg(X86::CL).addZImm(32); - - // DestHi = (>32) ? TmpReg3 : TmpReg2; - BuildMI(BB, X86::CMOVNErr32, 2, - DestReg+1).addReg(TmpReg2).addReg(TmpReg3); - // DestLo = (>32) ? TmpReg : TmpReg3; - BuildMI(BB, X86::CMOVNErr32, 2, DestReg).addReg(TmpReg3).addReg(TmpReg); - } else { - // TmpReg2 = shrd inLo, inHi - BuildMI(BB, X86::SHRDrr32, 2, TmpReg2).addReg(SrcReg).addReg(SrcReg+1); - // TmpReg3 = s[ah]r inHi, CL - BuildMI(BB, isSigned ? X86::SARrr32 : X86::SHRrr32, 1, TmpReg3) - .addReg(SrcReg+1); - - // Set the flags to indicate whether the shift was by more than 32 bits. - BuildMI(BB, X86::TESTri8, 2).addReg(X86::CL).addZImm(32); - - // DestLo = (>32) ? TmpReg3 : TmpReg2; - BuildMI(BB, X86::CMOVNErr32, 2, - DestReg).addReg(TmpReg2).addReg(TmpReg3); - - // DestHi = (>32) ? TmpReg : TmpReg3; - BuildMI(BB, X86::CMOVNErr32, 2, - DestReg+1).addReg(TmpReg3).addReg(TmpReg); - } - } - return; - } - - if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(I.getOperand(1))) { - // The shift amount is constant, guaranteed to be a ubyte. Get its value. - assert(CUI->getType() == Type::UByteTy && "Shift amount not a ubyte?"); - - const unsigned *Opc = ConstantOperand[isLeftShift*2+isSigned]; - BuildMI(BB, Opc[Class], 2, DestReg).addReg(SrcReg).addZImm(CUI->getValue()); - } else { // The shift amount is non-constant. - BuildMI(BB, X86::MOVrr8, 1, X86::CL).addReg(getReg(I.getOperand(1))); - - const unsigned *Opc = NonConstantOperand[isLeftShift*2+isSigned]; - BuildMI(BB, Opc[Class], 1, DestReg).addReg(SrcReg); - } -} - - -/// visitLoadInst - Implement LLVM load instructions in terms of the x86 'mov' -/// instruction. The load and store instructions are the only place where we -/// need to worry about the memory layout of the target machine. -/// -void ISel::visitLoadInst(LoadInst &I) { - unsigned SrcAddrReg = getReg(I.getOperand(0)); - unsigned DestReg = getReg(I); - - unsigned Class = getClassB(I.getType()); - - if (Class == cLong) { - addDirectMem(BuildMI(BB, X86::MOVmr32, 4, DestReg), SrcAddrReg); - addRegOffset(BuildMI(BB, X86::MOVmr32, 4, DestReg+1), SrcAddrReg, 4); - return; - } - - static const unsigned Opcodes[] = { - X86::MOVmr8, X86::MOVmr16, X86::MOVmr32, X86::FLDr32 - }; - unsigned Opcode = Opcodes[Class]; - if (I.getType() == Type::DoubleTy) Opcode = X86::FLDr64; - addDirectMem(BuildMI(BB, Opcode, 4, DestReg), SrcAddrReg); -} - -/// visitStoreInst - Implement LLVM store instructions in terms of the x86 'mov' -/// instruction. -/// -void ISel::visitStoreInst(StoreInst &I) { - unsigned ValReg = getReg(I.getOperand(0)); - unsigned AddressReg = getReg(I.getOperand(1)); - - const Type *ValTy = I.getOperand(0)->getType(); - unsigned Class = getClassB(ValTy); - - if (Class == cLong) { - addDirectMem(BuildMI(BB, X86::MOVrm32, 1+4), AddressReg).addReg(ValReg); - addRegOffset(BuildMI(BB, X86::MOVrm32, 1+4), AddressReg,4).addReg(ValReg+1); - return; - } - - static const unsigned Opcodes[] = { - X86::MOVrm8, X86::MOVrm16, X86::MOVrm32, X86::FSTr32 - }; - unsigned Opcode = Opcodes[Class]; - if (ValTy == Type::DoubleTy) Opcode = X86::FSTr64; - addDirectMem(BuildMI(BB, Opcode, 1+4), AddressReg).addReg(ValReg); -} - - -/// visitCastInst - Here we have various kinds of copying with or without -/// sign extension going on. -void ISel::visitCastInst(CastInst &CI) { - Value *Op = CI.getOperand(0); - // If this is a cast from a 32-bit integer to a Long type, and the only uses - // of the case are GEP instructions, then the cast does not need to be - // generated explicitly, it will be folded into the GEP. - if (CI.getType() == Type::LongTy && - (Op->getType() == Type::IntTy || Op->getType() == Type::UIntTy)) { - bool AllUsesAreGEPs = true; - for (Value::use_iterator I = CI.use_begin(), E = CI.use_end(); I != E; ++I) - if (!isa<GetElementPtrInst>(*I)) { - AllUsesAreGEPs = false; - break; - } - - // No need to codegen this cast if all users are getelementptr instrs... - if (AllUsesAreGEPs) return; - } - - unsigned DestReg = getReg(CI); - MachineBasicBlock::iterator MI = BB->end(); - emitCastOperation(BB, MI, Op, CI.getType(), DestReg); -} - -/// emitCastOperation - Common code shared between visitCastInst and -/// constant expression cast support. -void ISel::emitCastOperation(MachineBasicBlock *BB, - MachineBasicBlock::iterator &IP, - Value *Src, const Type *DestTy, - unsigned DestReg) { - unsigned SrcReg = getReg(Src, BB, IP); - const Type *SrcTy = Src->getType(); - unsigned SrcClass = getClassB(SrcTy); - unsigned DestClass = getClassB(DestTy); - - // Implement casts to bool by using compare on the operand followed by set if - // not zero on the result. - if (DestTy == Type::BoolTy) { - switch (SrcClass) { - case cByte: - BMI(BB, IP, X86::TESTrr8, 2).addReg(SrcReg).addReg(SrcReg); - break; - case cShort: - BMI(BB, IP, X86::TESTrr16, 2).addReg(SrcReg).addReg(SrcReg); - break; - case cInt: - BMI(BB, IP, X86::TESTrr32, 2).addReg(SrcReg).addReg(SrcReg); - break; - case cLong: { - unsigned TmpReg = makeAnotherReg(Type::IntTy); - BMI(BB, IP, X86::ORrr32, 2, TmpReg).addReg(SrcReg).addReg(SrcReg+1); - break; - } - case cFP: - assert(0 && "FIXME: implement cast FP to bool"); - abort(); - } - - // If the zero flag is not set, then the value is true, set the byte to - // true. - BMI(BB, IP, X86::SETNEr, 1, DestReg); - return; - } - - static const unsigned RegRegMove[] = { - X86::MOVrr8, X86::MOVrr16, X86::MOVrr32, X86::FpMOV, X86::MOVrr32 - }; - - // Implement casts between values of the same type class (as determined by - // getClass) by using a register-to-register move. - if (SrcClass == DestClass) { - if (SrcClass <= cInt || (SrcClass == cFP && SrcTy == DestTy)) { - BMI(BB, IP, RegRegMove[SrcClass], 1, DestReg).addReg(SrcReg); - } else if (SrcClass == cFP) { - if (SrcTy == Type::FloatTy) { // double -> float - assert(DestTy == Type::DoubleTy && "Unknown cFP member!"); - BMI(BB, IP, X86::FpMOV, 1, DestReg).addReg(SrcReg); - } else { // float -> double - assert(SrcTy == Type::DoubleTy && DestTy == Type::FloatTy && - "Unknown cFP member!"); - // Truncate from double to float by storing to memory as short, then - // reading it back. - unsigned FltAlign = TM.getTargetData().getFloatAlignment(); - int FrameIdx = F->getFrameInfo()->CreateStackObject(4, FltAlign); - addFrameReference(BMI(BB, IP, X86::FSTr32, 5), FrameIdx).addReg(SrcReg); - addFrameReference(BMI(BB, IP, X86::FLDr32, 5, DestReg), FrameIdx); - } - } else if (SrcClass == cLong) { - BMI(BB, IP, X86::MOVrr32, 1, DestReg).addReg(SrcReg); - BMI(BB, IP, X86::MOVrr32, 1, DestReg+1).addReg(SrcReg+1); - } else { - assert(0 && "Cannot handle this type of cast instruction!"); - abort(); - } - return; - } - - // Handle cast of SMALLER int to LARGER int using a move with sign extension - // or zero extension, depending on whether the source type was signed. - if (SrcClass <= cInt && (DestClass <= cInt || DestClass == cLong) && - SrcClass < DestClass) { - bool isLong = DestClass == cLong; - if (isLong) DestClass = cInt; - - static const unsigned Opc[][4] = { - { X86::MOVSXr16r8, X86::MOVSXr32r8, X86::MOVSXr32r16, X86::MOVrr32 }, // s - { X86::MOVZXr16r8, X86::MOVZXr32r8, X86::MOVZXr32r16, X86::MOVrr32 } // u - }; - - bool isUnsigned = SrcTy->isUnsigned(); - BMI(BB, IP, Opc[isUnsigned][SrcClass + DestClass - 1], 1, - DestReg).addReg(SrcReg); - - if (isLong) { // Handle upper 32 bits as appropriate... - if (isUnsigned) // Zero out top bits... - BMI(BB, IP, X86::MOVir32, 1, DestReg+1).addZImm(0); - else // Sign extend bottom half... - BMI(BB, IP, X86::SARir32, 2, DestReg+1).addReg(DestReg).addZImm(31); - } - return; - } - - // Special case long -> int ... - if (SrcClass == cLong && DestClass == cInt) { - BMI(BB, IP, X86::MOVrr32, 1, DestReg).addReg(SrcReg); - return; - } - - // Handle cast of LARGER int to SMALLER int using a move to EAX followed by a - // move out of AX or AL. - if ((SrcClass <= cInt || SrcClass == cLong) && DestClass <= cInt - && SrcClass > DestClass) { - static const unsigned AReg[] = { X86::AL, X86::AX, X86::EAX, 0, X86::EAX }; - BMI(BB, IP, RegRegMove[SrcClass], 1, AReg[SrcClass]).addReg(SrcReg); - BMI(BB, IP, RegRegMove[DestClass], 1, DestReg).addReg(AReg[DestClass]); - return; - } - - // Handle casts from integer to floating point now... - if (DestClass == cFP) { - // Promote the integer to a type supported by FLD. We do this because there - // are no unsigned FLD instructions, so we must promote an unsigned value to - // a larger signed value, then use FLD on the larger value. - // - const Type *PromoteType = 0; - unsigned PromoteOpcode; - switch (SrcTy->getPrimitiveID()) { - case Type::BoolTyID: - case Type::SByteTyID: - // We don't have the facilities for directly loading byte sized data from - // memory (even signed). Promote it to 16 bits. - PromoteType = Type::ShortTy; - PromoteOpcode = X86::MOVSXr16r8; - break; - case Type::UByteTyID: - PromoteType = Type::ShortTy; - PromoteOpcode = X86::MOVZXr16r8; - break; - case Type::UShortTyID: - PromoteType = Type::IntTy; - PromoteOpcode = X86::MOVZXr32r16; - break; - case Type::UIntTyID: { - // Make a 64 bit temporary... and zero out the top of it... - unsigned TmpReg = makeAnotherReg(Type::LongTy); - BMI(BB, IP, X86::MOVrr32, 1, TmpReg).addReg(SrcReg); - BMI(BB, IP, X86::MOVir32, 1, TmpReg+1).addZImm(0); - SrcTy = Type::LongTy; - SrcClass = cLong; - SrcReg = TmpReg; - break; - } - case Type::ULongTyID: - assert("FIXME: not implemented: cast ulong X to fp type!"); - default: // No promotion needed... - break; - } - - if (PromoteType) { - unsigned TmpReg = makeAnotherReg(PromoteType); - BMI(BB, IP, SrcTy->isSigned() ? X86::MOVSXr16r8 : X86::MOVZXr16r8, - 1, TmpReg).addReg(SrcReg); - SrcTy = PromoteType; - SrcClass = getClass(PromoteType); - SrcReg = TmpReg; - } - - // Spill the integer to memory and reload it from there... - int FrameIdx = - F->getFrameInfo()->CreateStackObject(SrcTy, TM.getTargetData()); - - if (SrcClass == cLong) { - addFrameReference(BMI(BB, IP, X86::MOVrm32, 5), FrameIdx).addReg(SrcReg); - addFrameReference(BMI(BB, IP, X86::MOVrm32, 5), - FrameIdx, 4).addReg(SrcReg+1); - } else { - static const unsigned Op1[] = { X86::MOVrm8, X86::MOVrm16, X86::MOVrm32 }; - addFrameReference(BMI(BB, IP, Op1[SrcClass], 5), FrameIdx).addReg(SrcReg); - } - - static const unsigned Op2[] = - { 0/*byte*/, X86::FILDr16, X86::FILDr32, 0/*FP*/, X86::FILDr64 }; - addFrameReference(BMI(BB, IP, Op2[SrcClass], 5, DestReg), FrameIdx); - return; - } - - // Handle casts from floating point to integer now... - if (SrcClass == cFP) { - // Change the floating point control register to use "round towards zero" - // mode when truncating to an integer value. - // - int CWFrameIdx = F->getFrameInfo()->CreateStackObject(2, 2); - addFrameReference(BMI(BB, IP, X86::FNSTCWm16, 4), CWFrameIdx); - - // Load the old value of the high byte of the control word... - unsigned HighPartOfCW = makeAnotherReg(Type::UByteTy); - addFrameReference(BMI(BB, IP, X86::MOVmr8, 4, HighPartOfCW), CWFrameIdx, 1); - - // Set the high part to be round to zero... - addFrameReference(BMI(BB, IP, X86::MOVim8, 5), CWFrameIdx, 1).addZImm(12); - - // Reload the modified control word now... - addFrameReference(BMI(BB, IP, X86::FLDCWm16, 4), CWFrameIdx); - - // Restore the memory image of control word to original value - addFrameReference(BMI(BB, IP, X86::MOVrm8, 5), - CWFrameIdx, 1).addReg(HighPartOfCW); - - // We don't have the facilities for directly storing byte sized data to - // memory. Promote it to 16 bits. We also must promote unsigned values to - // larger classes because we only have signed FP stores. - unsigned StoreClass = DestClass; - const Type *StoreTy = DestTy; - if (StoreClass == cByte || DestTy->isUnsigned()) - switch (StoreClass) { - case cByte: StoreTy = Type::ShortTy; StoreClass = cShort; break; - case cShort: StoreTy = Type::IntTy; StoreClass = cInt; break; - case cInt: StoreTy = Type::LongTy; StoreClass = cLong; break; - // The following treatment of cLong may not be perfectly right, - // but it survives chains of casts of the form - // double->ulong->double. - case cLong: StoreTy = Type::LongTy; StoreClass = cLong; break; - default: assert(0 && "Unknown store class!"); - } - - // Spill the integer to memory and reload it from there... - int FrameIdx = - F->getFrameInfo()->CreateStackObject(StoreTy, TM.getTargetData()); - - static const unsigned Op1[] = - { 0, X86::FISTr16, X86::FISTr32, 0, X86::FISTPr64 }; - addFrameReference(BMI(BB, IP, Op1[StoreClass], 5), FrameIdx).addReg(SrcReg); - - if (DestClass == cLong) { - addFrameReference(BMI(BB, IP, X86::MOVmr32, 4, DestReg), FrameIdx); - addFrameReference(BMI(BB, IP, X86::MOVmr32, 4, DestReg+1), FrameIdx, 4); - } else { - static const unsigned Op2[] = { X86::MOVmr8, X86::MOVmr16, X86::MOVmr32 }; - addFrameReference(BMI(BB, IP, Op2[DestClass], 4, DestReg), FrameIdx); - } - - // Reload the original control word now... - addFrameReference(BMI(BB, IP, X86::FLDCWm16, 4), CWFrameIdx); - return; - } - - // Anything we haven't handled already, we can't (yet) handle at all. - assert(0 && "Unhandled cast instruction!"); - abort(); -} - -/// visitVANextInst - Implement the va_next instruction... -/// -void ISel::visitVANextInst(VANextInst &I) { - unsigned VAList = getReg(I.getOperand(0)); - unsigned DestReg = getReg(I); - - unsigned Size; - switch (I.getArgType()->getPrimitiveID()) { - default: - std::cerr << I; - assert(0 && "Error: bad type for va_next instruction!"); - return; - case Type::PointerTyID: - case Type::UIntTyID: - case Type::IntTyID: - Size = 4; - break; - case Type::ULongTyID: - case Type::LongTyID: - case Type::DoubleTyID: - Size = 8; - break; - } - - // Increment the VAList pointer... - BuildMI(BB, X86::ADDri32, 2, DestReg).addReg(VAList).addZImm(Size); -} - -void ISel::visitVAArgInst(VAArgInst &I) { - unsigned VAList = getReg(I.getOperand(0)); - unsigned DestReg = getReg(I); - - switch (I.getType()->getPrimitiveID()) { - default: - std::cerr << I; - assert(0 && "Error: bad type for va_next instruction!"); - return; - case Type::PointerTyID: - case Type::UIntTyID: - case Type::IntTyID: - addDirectMem(BuildMI(BB, X86::MOVmr32, 4, DestReg), VAList); - break; - case Type::ULongTyID: - case Type::LongTyID: - addDirectMem(BuildMI(BB, X86::MOVmr32, 4, DestReg), VAList); - addRegOffset(BuildMI(BB, X86::MOVmr32, 4, DestReg+1), VAList, 4); - break; - case Type::DoubleTyID: - addDirectMem(BuildMI(BB, X86::FLDr64, 4, DestReg), VAList); - break; - } -} - - -void ISel::visitGetElementPtrInst(GetElementPtrInst &I) { - unsigned outputReg = getReg(I); - MachineBasicBlock::iterator MI = BB->end(); - emitGEPOperation(BB, MI, I.getOperand(0), - I.op_begin()+1, I.op_end(), outputReg); -} - -void ISel::emitGEPOperation(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &IP, - Value *Src, User::op_iterator IdxBegin, - User::op_iterator IdxEnd, unsigned TargetReg) { - const TargetData &TD = TM.getTargetData(); - const Type *Ty = Src->getType(); - unsigned BaseReg = getReg(Src, MBB, IP); - - // GEPs have zero or more indices; we must perform a struct access - // or array access for each one. - for (GetElementPtrInst::op_iterator oi = IdxBegin, - oe = IdxEnd; oi != oe; ++oi) { - Value *idx = *oi; - unsigned NextReg = BaseReg; - if (const StructType *StTy = dyn_cast<StructType>(Ty)) { - // It's a struct access. idx is the index into the structure, - // which names the field. This index must have ubyte type. - const ConstantUInt *CUI = cast<ConstantUInt>(idx); - assert(CUI->getType() == Type::UByteTy - && "Funny-looking structure index in GEP"); - // Use the TargetData structure to pick out what the layout of - // the structure is in memory. Since the structure index must - // be constant, we can get its value and use it to find the - // right byte offset from the StructLayout class's list of - // structure member offsets. - unsigned idxValue = CUI->getValue(); - unsigned FieldOff = TD.getStructLayout(StTy)->MemberOffsets[idxValue]; - if (FieldOff) { - NextReg = makeAnotherReg(Type::UIntTy); - // Emit an ADD to add FieldOff to the basePtr. - BMI(MBB, IP, X86::ADDri32, 2,NextReg).addReg(BaseReg).addZImm(FieldOff); - } - // The next type is the member of the structure selected by the - // index. - Ty = StTy->getElementTypes()[idxValue]; - } else if (const SequentialType *SqTy = cast<SequentialType>(Ty)) { - // It's an array or pointer access: [ArraySize x ElementType]. - - // idx is the index into the array. Unlike with structure - // indices, we may not know its actual value at code-generation - // time. - assert(idx->getType() == Type::LongTy && "Bad GEP array index!"); - - // Most GEP instructions use a [cast (int/uint) to LongTy] as their - // operand on X86. Handle this case directly now... - if (CastInst *CI = dyn_cast<CastInst>(idx)) - if (CI->getOperand(0)->getType() == Type::IntTy || - CI->getOperand(0)->getType() == Type::UIntTy) - idx = CI->getOperand(0); - - // We want to add BaseReg to(idxReg * sizeof ElementType). First, we - // must find the size of the pointed-to type (Not coincidentally, the next - // type is the type of the elements in the array). - Ty = SqTy->getElementType(); - unsigned elementSize = TD.getTypeSize(Ty); - - // If idxReg is a constant, we don't need to perform the multiply! - if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(idx)) { - if (!CSI->isNullValue()) { - unsigned Offset = elementSize*CSI->getValue(); - NextReg = makeAnotherReg(Type::UIntTy); - BMI(MBB, IP, X86::ADDri32, 2,NextReg).addReg(BaseReg).addZImm(Offset); - } - } else if (elementSize == 1) { - // If the element size is 1, we don't have to multiply, just add - unsigned idxReg = getReg(idx, MBB, IP); - NextReg = makeAnotherReg(Type::UIntTy); - BMI(MBB, IP, X86::ADDrr32, 2, NextReg).addReg(BaseReg).addReg(idxReg); - } else { - unsigned idxReg = getReg(idx, MBB, IP); - unsigned OffsetReg = makeAnotherReg(Type::UIntTy); - - doMultiplyConst(MBB, IP, OffsetReg, Type::IntTy, idxReg, elementSize); - - // Emit an ADD to add OffsetReg to the basePtr. - NextReg = makeAnotherReg(Type::UIntTy); - BMI(MBB, IP, X86::ADDrr32, 2,NextReg).addReg(BaseReg).addReg(OffsetReg); - } - } - // Now that we are here, further indices refer to subtypes of this - // one, so we don't need to worry about BaseReg itself, anymore. - BaseReg = NextReg; - } - // After we have processed all the indices, the result is left in - // BaseReg. Move it to the register where we were expected to - // put the answer. A 32-bit move should do it, because we are in - // ILP32 land. - BMI(MBB, IP, X86::MOVrr32, 1, TargetReg).addReg(BaseReg); -} - - -/// visitAllocaInst - If this is a fixed size alloca, allocate space from the -/// frame manager, otherwise do it the hard way. -/// -void ISel::visitAllocaInst(AllocaInst &I) { - // Find the data size of the alloca inst's getAllocatedType. - const Type *Ty = I.getAllocatedType(); - unsigned TySize = TM.getTargetData().getTypeSize(Ty); - - // If this is a fixed size alloca in the entry block for the function, - // statically stack allocate the space. - // - if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(I.getArraySize())) { - if (I.getParent() == I.getParent()->getParent()->begin()) { - TySize *= CUI->getValue(); // Get total allocated size... - unsigned Alignment = TM.getTargetData().getTypeAlignment(Ty); - - // Create a new stack object using the frame manager... - int FrameIdx = F->getFrameInfo()->CreateStackObject(TySize, Alignment); - addFrameReference(BuildMI(BB, X86::LEAr32, 5, getReg(I)), FrameIdx); - return; - } - } - - // Create a register to hold the temporary result of multiplying the type size - // constant by the variable amount. - unsigned TotalSizeReg = makeAnotherReg(Type::UIntTy); - unsigned SrcReg1 = getReg(I.getArraySize()); - - // TotalSizeReg = mul <numelements>, <TypeSize> - MachineBasicBlock::iterator MBBI = BB->end(); - doMultiplyConst(BB, MBBI, TotalSizeReg, Type::UIntTy, SrcReg1, TySize); - - // AddedSize = add <TotalSizeReg>, 15 - unsigned AddedSizeReg = makeAnotherReg(Type::UIntTy); - BuildMI(BB, X86::ADDri32, 2, AddedSizeReg).addReg(TotalSizeReg).addZImm(15); - - // AlignedSize = and <AddedSize>, ~15 - unsigned AlignedSize = makeAnotherReg(Type::UIntTy); - BuildMI(BB, X86::ANDri32, 2, AlignedSize).addReg(AddedSizeReg).addZImm(~15); - - // Subtract size from stack pointer, thereby allocating some space. - BuildMI(BB, X86::SUBrr32, 2, X86::ESP).addReg(X86::ESP).addReg(AlignedSize); - - // Put a pointer to the space into the result register, by copying - // the stack pointer. - BuildMI(BB, X86::MOVrr32, 1, getReg(I)).addReg(X86::ESP); - - // Inform the Frame Information that we have just allocated a variable-sized - // object. - F->getFrameInfo()->CreateVariableSizedObject(); -} - -/// visitMallocInst - Malloc instructions are code generated into direct calls -/// to the library malloc. -/// -void ISel::visitMallocInst(MallocInst &I) { - unsigned AllocSize = TM.getTargetData().getTypeSize(I.getAllocatedType()); - unsigned Arg; - - if (ConstantUInt *C = dyn_cast<ConstantUInt>(I.getOperand(0))) { - Arg = getReg(ConstantUInt::get(Type::UIntTy, C->getValue() * AllocSize)); - } else { - Arg = makeAnotherReg(Type::UIntTy); - unsigned Op0Reg = getReg(I.getOperand(0)); - MachineBasicBlock::iterator MBBI = BB->end(); - doMultiplyConst(BB, MBBI, Arg, Type::UIntTy, Op0Reg, AllocSize); - } - - std::vector<ValueRecord> Args; - Args.push_back(ValueRecord(Arg, Type::UIntTy)); - MachineInstr *TheCall = BuildMI(X86::CALLpcrel32, - 1).addExternalSymbol("malloc", true); - doCall(ValueRecord(getReg(I), I.getType()), TheCall, Args); -} - - -/// visitFreeInst - Free instructions are code gen'd to call the free libc -/// function. -/// -void ISel::visitFreeInst(FreeInst &I) { - std::vector<ValueRecord> Args; - Args.push_back(ValueRecord(I.getOperand(0))); - MachineInstr *TheCall = BuildMI(X86::CALLpcrel32, - 1).addExternalSymbol("free", true); - doCall(ValueRecord(0, Type::VoidTy), TheCall, Args); -} - - -/// createX86SimpleInstructionSelector - This pass converts an LLVM function -/// into a machine code representation is a very simple peep-hole fashion. The -/// generated code sucks but the implementation is nice and simple. -/// -FunctionPass *createX86SimpleInstructionSelector(TargetMachine &TM) { - return new ISel(TM); -} diff --git a/lib/Target/X86/X86PeepholeOpt.cpp b/lib/Target/X86/X86PeepholeOpt.cpp deleted file mode 100644 index fbc84f7e87..0000000000 --- a/lib/Target/X86/X86PeepholeOpt.cpp +++ /dev/null @@ -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; - } -} diff --git a/test/BugPoint/misopt-basictest.ll b/test/BugPoint/misopt-basictest.ll index 1ba9adb82b..76363dfb1f 100644 --- a/test/BugPoint/misopt-basictest.ll +++ b/test/BugPoint/misopt-basictest.ll @@ -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" diff --git a/test/Makefile b/test/Makefile index 29f823666a..3b98ef8b98 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,13 +1,18 @@ 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 # will use QMTest by default. |