From sabre at nondot.org Mon Oct 26 00:01:09 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 00:01:09 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2009-03-ACMSE-Superpage.html 2009-03-ACMSE-Superpage.pdf pubs.js Message-ID: <200910260501.n9Q5197x003334@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2009-03-ACMSE-Superpage.html added (r1.1) 2009-03-ACMSE-Superpage.pdf added (r1.1) pubs.js updated: 1.51 -> 1.52 --- Log message: add another paper --- Diffs of the changes: (+56 -0) 2009-03-ACMSE-Superpage.html | 49 +++++++++++++++++++++++++++++++++++++++++++ 2009-03-ACMSE-Superpage.pdf | 0 pubs.js | 7 ++++++ 3 files changed, 56 insertions(+) Index: llvm-www/pubs/2009-03-ACMSE-Superpage.html diff -c /dev/null llvm-www/pubs/2009-03-ACMSE-Superpage.html:1.1 *** /dev/null Mon Oct 26 00:01:04 2009 --- llvm-www/pubs/2009-03-ACMSE-Superpage.html Mon Oct 26 00:00:54 2009 *************** *** 0 **** --- 1,49 ---- + + + + + + A Case for Compiler-driven Superpage Allocation + + + +
+ A Case for Compiler-driven Superpage Allocation +
+
+ Joshua Magee and Apan Qasem +
+ +

Abstract:

+
+ Most modern microprocessor-based systems provide support for superpages both at the hardware and software level. Judicious use of superpages can significantly cut down the number of TLB misses and improve overall system performance. However, indiscriminate superpage allocation results in page fragmentation and increased application footprint, which often outweigh the benefits of reduced TLB misses. Previous research has explored policies for smart allocation of superpages from an operating systems perspective. This paper presents a compiler-based strategy for automatic and profitable memory allocation via superpages. A significant advantage of a compiler-based approach is the availability of data-reuse information within an application. Our strategy employs data-locality analysis to estimate the TLB demands of a program and uses this metric to determine if the program will benefit from superpage allocation. Apart from its obvious utility in improving TLB performance, this ! strategy can be used to improve the effectiveness of certain data-layout transformations and can be a useful tool in benchmarking and empirical tuning. We demonstrate the effectiveness of this strategy with experiments on an Intel Core 2 Duo with a two-level TLB. +
+ +

Published:

+
+ "A Case for Compiler-driven Superpage Allocation" +
+ Joshua Magee and Apan Qasem. +
+ + Proceedings of the 47th ACM Southeast Regional Conference (ACMSE09) + , Mar 2009. +
+

Download:

+

Paper:

+ + + + +
+ Valid CSS! + Valid HTML 4.01! + + + Index: llvm-www/pubs/2009-03-ACMSE-Superpage.pdf Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.51 llvm-www/pubs/pubs.js:1.52 --- llvm-www/pubs/pubs.js:1.51 Sun Oct 25 23:51:40 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 00:00:54 2009 @@ -110,6 +110,13 @@ month: 3, year: 2009}, + {url: '2009-03-ACMSE-Superpage.html', + title: 'A Case for Compiler-driven Superpage Allocation', + author: 'Joshua Magee and Apan Qasem', + published: "Proc. of the 47th ACM Southeast Regional Conference (ACMSE09)", + month: 3, + year: 2009}, + {url: '2009-02-PPoPP-MappingParallelism.html', title: 'Mapping parallelism to multi-cores: a machine learning based approach', author: "Zheng Wang and Michael F.P. O'Boyle", From sabre at nondot.org Mon Oct 26 00:18:55 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 00:18:55 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2009-07-ISSTA-BegBunch.html 2009-07-ISSTA-BegBunch.pdf pubs.js Message-ID: <200910260518.n9Q5It9k004044@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2009-07-ISSTA-BegBunch.html added (r1.1) 2009-07-ISSTA-BegBunch.pdf added (r1.1) pubs.js updated: 1.52 -> 1.53 --- Log message: add BegBunch: benchmarking for C bug detection tools --- Diffs of the changes: (+76 -0) 2009-07-ISSTA-BegBunch.html | 68 ++++++++++++++++++++++++++++++++++++++++++++ 2009-07-ISSTA-BegBunch.pdf | 0 pubs.js | 8 +++++ 3 files changed, 76 insertions(+) Index: llvm-www/pubs/2009-07-ISSTA-BegBunch.html diff -c /dev/null llvm-www/pubs/2009-07-ISSTA-BegBunch.html:1.1 *** /dev/null Mon Oct 26 00:18:49 2009 --- llvm-www/pubs/2009-07-ISSTA-BegBunch.html Mon Oct 26 00:18:39 2009 *************** *** 0 **** --- 1,68 ---- + + + + + + BegBunch: benchmarking for C bug detection tools + + + +
+ BegBunch: benchmarking for C bug detection tools +
+
+ Cristina Cifuentes, Christian Hoermann, Nathan Keynes, Lian Li, Simon Long, Erica Mealy, Michael Mounteney, Bernhard Scholz +
+ +

Abstract:

+
+ Benchmarks for bug detection tools are still in their infancy. Though in recent years various tools and techniques were introduced, little effort has been spent on creating a benchmark suite and a harness for a consistent quantitative and qualitative performance measurement. For assessing the performance of a bug detection tool and determining which tool is better than another for the type of code to be looked at, the following questions arise: 1) how many bugs are correctly found, 2) what is the tool's average false positive rate, 3) how many bugs are missed by the tool altogether, and 4) does the tool scale.

+ + In this paper we present our contribution to the C bug detection community: two benchmark suites that allow developers and users to evaluate accuracy and scalability of a given tool. The two suites contain buggy, mature open source code; bugs are representative of "real world" bugs. A harness accompanies each benchmark suite to compute automatically qualitative and quantitative performance of a bug detection tool.

+ + BegBunch has been tested to run on the Solaris, Mac OS X and Linux operating systems. We show the generality of the harness by evaluating it with our own Parfait and three publicly available bug detection tools developed by others.

+

+ +

Published:

+
+ "BegBunch: benchmarking for C bug detection tools" +
+ Cristina Cifuentes, Christian Hoermann, Nathan Keynes, Lian Li, Simon Long, Erica Mealy, Michael Mounteney, Bernhard Scholz. +
+ + Proceedings of the 2nd International Workshop on Defects in Large Software Systems: Held in conjunction with the ACM SIGSOFT International Symposium on Software Testing and Analysis (ISSTA 2009) + , Chicago, Illinois, July 2009. +
+

Download:

+

Paper:

+ + +

BibTeX Entry:

+
+ @inproceedings{1555866,
+  author = {Cifuentes, Cristina and Hoermann, Christian and Keynes, Nathan and Li, Lian and Long, Simon and Mealy, Erica and Mounteney, Michael and Scholz, Bernhard},
+  title = {BegBunch: benchmarking for C bug detection tools},
+  booktitle = {DEFECTS '09: Proceedings of the 2nd International Workshop on Defects in Large Software Systems},
+  year = {2009},
+  isbn = {978-1-60558-654-0},
+  pages = {16--20},
+  location = {Chicago, Illinois},
+  doi = {http://doi.acm.org/10.1145/1555860.1555866},
+  publisher = {ACM},
+  address = {New York, NY, USA},
+  }
+ 
+ + +
+ Valid CSS! + Valid HTML 4.01! + + + Index: llvm-www/pubs/2009-07-ISSTA-BegBunch.pdf Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.52 llvm-www/pubs/pubs.js:1.53 --- llvm-www/pubs/pubs.js:1.52 Mon Oct 26 00:00:54 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 00:18:39 2009 @@ -9,6 +9,14 @@ month: 8, year: 2009}, + {url: '2009-07-ISSTA-BegBunch.html', + title: 'BegBunch: benchmarking for C bug detection tools', + author: 'Cristina Cifuentes, Christian Hoermann, Nathan Keynes, Lian Li, Simon Long, Erica Mealy, Michael Mounteney, and Bernhard Scholz', + published: 'Proc. of the 2nd International Workshop on Defects in Large Software Systems: Held in conjunction with the ACM SIGSOFT International Symposium on Software Testing and Analysis (ISSTA 2009)', + location: 'Chicago, Illinois', + month: 7, + year: 2009}, + {url: '2009-06-PLDI-LibraryBindings.html', title: 'Automatic generation of library bindings using static analysis', author: 'Tristan Ravitch, Steve Jackson, Eric Aderhold, and Ben Liblit', From sabre at nondot.org Mon Oct 26 00:45:31 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 00:45:31 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2009-08-SAS-IPSSA.html 2009-08-SAS-IPSSA.pdf pubs.js Message-ID: <200910260545.n9Q5jVQ3005012@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2009-08-SAS-IPSSA.html added (r1.1) 2009-08-SAS-IPSSA.pdf added (r1.1) pubs.js updated: 1.53 -> 1.54 --- Log message: add another paper and add a bunch that I can't find pdf's for. --- Diffs of the changes: (+90 -0) 2009-08-SAS-IPSSA.html | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 2009-08-SAS-IPSSA.pdf | 0 pubs.js | 40 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) Index: llvm-www/pubs/2009-08-SAS-IPSSA.html diff -c /dev/null llvm-www/pubs/2009-08-SAS-IPSSA.html:1.1 *** /dev/null Mon Oct 26 00:44:51 2009 --- llvm-www/pubs/2009-08-SAS-IPSSA.html Mon Oct 26 00:44:40 2009 *************** *** 0 **** --- 1,50 ---- + + + + + + Increasing the scope and resolution of Interprocedural Static Single Assignment + + + +
+ Increasing the scope and resolution of Interprocedural Static Single Assignment +
+
+ Silvian Calman and Jianwen Zhu +
+ +

Abstract:

+
+ While intraprocedural Static Single Assignment (SSA) is ubiquitous in modern compilers, the use of interprocedural SSA, although seemingly a natural extension, is limited. We find that part of the impediment is due to the narrow scope of variables handled by previously reported approaches, leading to limited benefits in optimization.

+ + In this study, we increase the scope of Interprocedural SSA (ISSA) to record elements and singleton heap variables. We show that ISSA scales reasonably well (to all MediaBench and most of the SPEC2K), while resolving on average 1.72 times more loads to their definition. We propose and evaluate an interprocedural copy propagation and an interprocedural liveness analysis and demonstrate their effectiveness on reducing input and output instructions by 44.5% and 23.3%, respectively. ISSA is then leveraged for constant propagation and dead code removal, where 11.8% additional expressions are folded. +

+ +

Published:

+
+ "Increasing the scope and resolution of Interprocedural Static Single Assignment" +
+ Silvian Calman and Jianwen Zhu. +
+ + Proceeding of the 16th International Static Analysis Symposium (SAS 2009) + , Los Angeles, CA, August, 2009. +
+

Download:

+

Paper:

+ + + +
+ Valid CSS! + Valid HTML 4.01! + + + Index: llvm-www/pubs/2009-08-SAS-IPSSA.pdf Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.53 llvm-www/pubs/pubs.js:1.54 --- llvm-www/pubs/pubs.js:1.53 Mon Oct 26 00:18:39 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 00:44:41 2009 @@ -1,6 +1,26 @@ // The array should be sorted reverse-chronologically, and will be displayed on // the page in the order listed. var PUBS = [ + {title: 'AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware', + published: "28th International Conference, SAFECOMP 2009", + location: "Hamburg, Germany", + month: 9, + year: 2009}, + + {title: 'Automatic Generation of Cycle-Approximate TLMs with Timed RTOS Model Support', + published: "Analysis, Architectures and Modelling of Embedded Systems 2009 (IESS 2009)", + location: "Langenargen, Germany", + month: 9, + year: 2009}, + + {url: '2009-08-SAS-IPSSA.html', + title: "Increasing the scope and resolution of Interprocedural Static Single Assignment", + author: "Silvian Calman and Jianwen Zhu", + published: "Proc. of the 16th International Static Analysis Symposium (SAS 2009)", + location: "Los Angeles, CA", + month: 8, + year: 2009}, + {url: '2009-08-12-UsenixSecurity-SafeSVAOS.html', title: 'Memory Safety for Low-Level Software/Hardware Interactions', author: 'John Criswell, Nicolas Geoffray, and Vikram Adve', @@ -17,6 +37,20 @@ month: 7, year: 2009}, + {title: 'Verifying the Implementation of an Operating System Scheduler', + author: 'Moritz Kleine, Bj??rn Bartels, Thomas G??thel, and Sabine Glesner', + published: 'IEEE International Symposium on Theoretical Aspects of Software Engineering', + location: 'Tianjin, China', + month: 7, + year: 2009}, + + {title: 'Programmable and Scalable Architecture for Graphics Processing Units', + author: "Carlos S. Lama, Pekka J????skel??inen, Jarmo Takala", + published "Proc. of the 9th International Workshop on Embedded Computer Systems: Architectures, Modeling, and Simulation", + location: "Samos, Greece", + month: 7, + year: 2009}, + {url: '2009-06-PLDI-LibraryBindings.html', title: 'Automatic generation of library bindings using static analysis', author: 'Tristan Ravitch, Steve Jackson, Eric Aderhold, and Ben Liblit', @@ -97,6 +131,12 @@ month: 4, year: 2009}, + {title: 'Scheduling Techniques for Multi-Core Architectures', + author: 'Akira Hatanaka and Nader Bagherzadeh', + published: "2009 Sixth International Conference on Information Technology: New Generations", + month: 4, + year: 2009}, + {url: '2009-03-CGO-ESoftCheck.html', title: 'ESoftCheck: Removal of Non-vital Checks for Fault Tolerance', author: 'Jing Yu, Maria Jesus Garzaran, Marc Snir', From sabre at nondot.org Mon Oct 26 00:49:51 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 00:49:51 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/pubs.js Message-ID: <200910260549.n9Q5npVu005200@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: pubs.js updated: 1.54 -> 1.55 --- Log message: try to get this working again --- Diffs of the changes: (+13 -8) pubs.js | 21 +++++++++++++-------- 1 files changed, 13 insertions(+), 8 deletions(-) Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.54 llvm-www/pubs/pubs.js:1.55 --- llvm-www/pubs/pubs.js:1.54 Mon Oct 26 00:44:41 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 00:49:35 2009 @@ -1,13 +1,15 @@ // The array should be sorted reverse-chronologically, and will be displayed on // the page in the order listed. var PUBS = [ - {title: 'AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware', + {url: "", + title: "AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware", published: "28th International Conference, SAFECOMP 2009", location: "Hamburg, Germany", month: 9, year: 2009}, - {title: 'Automatic Generation of Cycle-Approximate TLMs with Timed RTOS Model Support', + {url: "", + title: "Automatic Generation of Cycle-Approximate TLMs with Timed RTOS Model Support", published: "Analysis, Architectures and Modelling of Embedded Systems 2009 (IESS 2009)", location: "Langenargen, Germany", month: 9, @@ -37,14 +39,16 @@ month: 7, year: 2009}, - {title: 'Verifying the Implementation of an Operating System Scheduler', - author: 'Moritz Kleine, Bj??rn Bartels, Thomas G??thel, and Sabine Glesner', - published: 'IEEE International Symposium on Theoretical Aspects of Software Engineering', + {url: "", + title: "Verifying the Implementation of an Operating System Scheduler", + author: "Moritz Kleine, Bj??rn Bartels, Thomas G??thel, and Sabine Glesner", + published: "IEEE International Symposium on Theoretical Aspects of Software Engineering", location: 'Tianjin, China', month: 7, year: 2009}, - {title: 'Programmable and Scalable Architecture for Graphics Processing Units', + {url: "", + title: "Programmable and Scalable Architecture for Graphics Processing Units", author: "Carlos S. Lama, Pekka J????skel??inen, Jarmo Takala", published "Proc. of the 9th International Workshop on Embedded Computer Systems: Architectures, Modeling, and Simulation", location: "Samos, Greece", @@ -131,8 +135,9 @@ month: 4, year: 2009}, - {title: 'Scheduling Techniques for Multi-Core Architectures', - author: 'Akira Hatanaka and Nader Bagherzadeh', + {url: "", + title: "Scheduling Techniques for Multi-Core Architectures", + author: "Akira Hatanaka and Nader Bagherzadeh", published: "2009 Sixth International Conference on Information Technology: New Generations", month: 4, year: 2009}, From sabre at nondot.org Mon Oct 26 00:52:07 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 00:52:07 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/pubs.js Message-ID: <200910260552.n9Q5q70K005302@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: pubs.js updated: 1.55 -> 1.56 --- Log message: temporarily disable some. --- Diffs of the changes: (+34 -34) pubs.js | 68 ++++++++++++++++++++++++++++++++-------------------------------- 1 files changed, 34 insertions(+), 34 deletions(-) Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.55 llvm-www/pubs/pubs.js:1.56 --- llvm-www/pubs/pubs.js:1.55 Mon Oct 26 00:49:35 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 00:51:51 2009 @@ -1,19 +1,19 @@ // The array should be sorted reverse-chronologically, and will be displayed on // the page in the order listed. var PUBS = [ - {url: "", - title: "AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware", - published: "28th International Conference, SAFECOMP 2009", - location: "Hamburg, Germany", - month: 9, - year: 2009}, - - {url: "", - title: "Automatic Generation of Cycle-Approximate TLMs with Timed RTOS Model Support", - published: "Analysis, Architectures and Modelling of Embedded Systems 2009 (IESS 2009)", - location: "Langenargen, Germany", - month: 9, - year: 2009}, +// {url: "", +// title: "AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware", +// published: "28th International Conference, SAFECOMP 2009", +// location: "Hamburg, Germany", +// month: 9, +// year: 2009}, + +// {url: "", +// title: "Automatic Generation of Cycle-Approximate TLMs with Timed RTOS Model Support", +// published: "Analysis, Architectures and Modelling of Embedded Systems 2009 (IESS 2009)", +// location: "Langenargen, Germany", +// month: 9, +// year: 2009}, {url: '2009-08-SAS-IPSSA.html', title: "Increasing the scope and resolution of Interprocedural Static Single Assignment", @@ -39,21 +39,21 @@ month: 7, year: 2009}, - {url: "", - title: "Verifying the Implementation of an Operating System Scheduler", - author: "Moritz Kleine, Bj??rn Bartels, Thomas G??thel, and Sabine Glesner", - published: "IEEE International Symposium on Theoretical Aspects of Software Engineering", - location: 'Tianjin, China', - month: 7, - year: 2009}, - - {url: "", - title: "Programmable and Scalable Architecture for Graphics Processing Units", - author: "Carlos S. Lama, Pekka J????skel??inen, Jarmo Takala", - published "Proc. of the 9th International Workshop on Embedded Computer Systems: Architectures, Modeling, and Simulation", - location: "Samos, Greece", - month: 7, - year: 2009}, +// {url: "", +// title: "Verifying the Implementation of an Operating System Scheduler", +// author: "Moritz Kleine, Bj??rn Bartels, Thomas G??thel, and Sabine Glesner", +// published: "IEEE International Symposium on Theoretical Aspects of Software Engineering", +// location: 'Tianjin, China', +// month: 7, +// year: 2009}, + +// {url: "", +// title: "Programmable and Scalable Architecture for Graphics Processing Units", +// author: "Carlos S. Lama, Pekka J????skel??inen, Jarmo Takala", +// published "Proc. of the 9th International Workshop on Embedded Computer Systems: Architectures, Modeling, and Simulation", +// location: "Samos, Greece", +// month: 7, +// year: 2009}, {url: '2009-06-PLDI-LibraryBindings.html', title: 'Automatic generation of library bindings using static analysis', @@ -135,12 +135,12 @@ month: 4, year: 2009}, - {url: "", - title: "Scheduling Techniques for Multi-Core Architectures", - author: "Akira Hatanaka and Nader Bagherzadeh", - published: "2009 Sixth International Conference on Information Technology: New Generations", - month: 4, - year: 2009}, +// {url: "", +// title: "Scheduling Techniques for Multi-Core Architectures", +// author: "Akira Hatanaka and Nader Bagherzadeh", +// published: "2009 Sixth International Conference on Information Technology: New Generations", +// month: 4, +// year: 2009}, {url: '2009-03-CGO-ESoftCheck.html', title: 'ESoftCheck: Removal of Non-vital Checks for Fault Tolerance', From sabre at nondot.org Mon Oct 26 00:52:29 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 00:52:29 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/pubs.js Message-ID: <200910260552.n9Q5qTcY005340@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: pubs.js updated: 1.56 -> 1.57 --- Log message: add one back --- Diffs of the changes: (+6 -6) pubs.js | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.56 llvm-www/pubs/pubs.js:1.57 --- llvm-www/pubs/pubs.js:1.56 Mon Oct 26 00:51:51 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 00:52:13 2009 @@ -135,12 +135,12 @@ month: 4, year: 2009}, -// {url: "", -// title: "Scheduling Techniques for Multi-Core Architectures", -// author: "Akira Hatanaka and Nader Bagherzadeh", -// published: "2009 Sixth International Conference on Information Technology: New Generations", -// month: 4, -// year: 2009}, + {url: "", + title: "Scheduling Techniques for Multi-Core Architectures", + author: "Akira Hatanaka and Nader Bagherzadeh", + published: "2009 Sixth International Conference on Information Technology: New Generations", + month: 4, + year: 2009}, {url: '2009-03-CGO-ESoftCheck.html', title: 'ESoftCheck: Removal of Non-vital Checks for Fault Tolerance', From sabre at nondot.org Mon Oct 26 00:53:41 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 00:53:41 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/pubs.js Message-ID: <200910260553.n9Q5rfdV005414@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: pubs.js updated: 1.57 -> 1.58 --- Log message: add some more --- Diffs of the changes: (+13 -13) pubs.js | 26 +++++++++++++------------- 1 files changed, 13 insertions(+), 13 deletions(-) Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.57 llvm-www/pubs/pubs.js:1.58 --- llvm-www/pubs/pubs.js:1.57 Mon Oct 26 00:52:13 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 00:53:25 2009 @@ -1,19 +1,19 @@ // The array should be sorted reverse-chronologically, and will be displayed on // the page in the order listed. var PUBS = [ -// {url: "", -// title: "AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware", -// published: "28th International Conference, SAFECOMP 2009", -// location: "Hamburg, Germany", -// month: 9, -// year: 2009}, + {url: "", + title: "AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware", + published: "28th International Conference, SAFECOMP 2009", + location: "Hamburg, Germany", + month: 9, + year: 2009}, -// {url: "", -// title: "Automatic Generation of Cycle-Approximate TLMs with Timed RTOS Model Support", -// published: "Analysis, Architectures and Modelling of Embedded Systems 2009 (IESS 2009)", -// location: "Langenargen, Germany", -// month: 9, -// year: 2009}, + {url: "", + title: "Automatic Generation of Cycle-Approximate TLMs with Timed RTOS Model Support", + published: "Analysis, Architectures and Modelling of Embedded Systems 2009 (IESS 2009)", + location: "Langenargen, Germany", + month: 9, + year: 2009}, {url: '2009-08-SAS-IPSSA.html', title: "Increasing the scope and resolution of Interprocedural Static Single Assignment", @@ -135,7 +135,7 @@ month: 4, year: 2009}, - {url: "", + {//url: "", title: "Scheduling Techniques for Multi-Core Architectures", author: "Akira Hatanaka and Nader Bagherzadeh", published: "2009 Sixth International Conference on Information Technology: New Generations", From sabre at nondot.org Mon Oct 26 00:54:07 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 00:54:07 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/pubs.js Message-ID: <200910260554.n9Q5s7jC005452@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: pubs.js updated: 1.58 -> 1.59 --- Log message: add a URL --- Diffs of the changes: (+1 -1) pubs.js | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.58 llvm-www/pubs/pubs.js:1.59 --- llvm-www/pubs/pubs.js:1.58 Mon Oct 26 00:53:25 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 00:53:51 2009 @@ -135,7 +135,7 @@ month: 4, year: 2009}, - {//url: "", + {url: "", title: "Scheduling Techniques for Multi-Core Architectures", author: "Akira Hatanaka and Nader Bagherzadeh", published: "2009 Sixth International Conference on Information Technology: New Generations", From sabre at nondot.org Mon Oct 26 00:55:45 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 00:55:45 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/pubs.js Message-ID: <200910260555.n9Q5tj6n005544@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: pubs.js updated: 1.59 -> 1.60 --- Log message: remove again. :( --- Diffs of the changes: (+6 -6) pubs.js | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.59 llvm-www/pubs/pubs.js:1.60 --- llvm-www/pubs/pubs.js:1.59 Mon Oct 26 00:53:51 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 00:55:30 2009 @@ -1,12 +1,12 @@ // The array should be sorted reverse-chronologically, and will be displayed on // the page in the order listed. var PUBS = [ - {url: "", - title: "AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware", - published: "28th International Conference, SAFECOMP 2009", - location: "Hamburg, Germany", - month: 9, - year: 2009}, +// {url: "", +// title: "AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware", +// published: "28th International Conference, SAFECOMP 2009", +// location: "Hamburg, Germany", +// month: 9, +// year: 2009}, {url: "", title: "Automatic Generation of Cycle-Approximate TLMs with Timed RTOS Model Support", From sabre at nondot.org Mon Oct 26 00:56:17 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 00:56:17 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/pubs.js Message-ID: <200910260556.n9Q5uHHQ005592@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: pubs.js updated: 1.60 -> 1.61 --- Log message: next one --- Diffs of the changes: (+11 -11) pubs.js | 22 +++++++++++----------- 1 files changed, 11 insertions(+), 11 deletions(-) Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.60 llvm-www/pubs/pubs.js:1.61 --- llvm-www/pubs/pubs.js:1.60 Mon Oct 26 00:55:30 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 00:56:00 2009 @@ -1,19 +1,19 @@ // The array should be sorted reverse-chronologically, and will be displayed on // the page in the order listed. var PUBS = [ -// {url: "", -// title: "AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware", -// published: "28th International Conference, SAFECOMP 2009", -// location: "Hamburg, Germany", -// month: 9, -// year: 2009}, - {url: "", - title: "Automatic Generation of Cycle-Approximate TLMs with Timed RTOS Model Support", - published: "Analysis, Architectures and Modelling of Embedded Systems 2009 (IESS 2009)", - location: "Langenargen, Germany", + title: "AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware", + published: "28th International Conference, SAFECOMP 2009", + location: "Hamburg, Germany", month: 9, - year: 2009}, + year: 2009}, + +// {url: "", +// title: "Automatic Generation of Cycle-Approximate TLMs with Timed RTOS Model Support", +// published: "Analysis, Architectures and Modelling of Embedded Systems 2009 (IESS 2009)", +// location: "Langenargen, Germany", +// month: 9, +// year: 2009}, {url: '2009-08-SAS-IPSSA.html', title: "Increasing the scope and resolution of Interprocedural Static Single Assignment", From sabre at nondot.org Mon Oct 26 00:56:43 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 00:56:43 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/pubs.js Message-ID: <200910260556.n9Q5uhmt005636@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: pubs.js updated: 1.61 -> 1.62 --- Log message: neither of these work? --- Diffs of the changes: (+6 -6) pubs.js | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.61 llvm-www/pubs/pubs.js:1.62 --- llvm-www/pubs/pubs.js:1.61 Mon Oct 26 00:56:00 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 00:56:28 2009 @@ -1,12 +1,12 @@ // The array should be sorted reverse-chronologically, and will be displayed on // the page in the order listed. var PUBS = [ - {url: "", - title: "AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware", - published: "28th International Conference, SAFECOMP 2009", - location: "Hamburg, Germany", - month: 9, - year: 2009}, +// {url: "", +// title: "AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware", +// published: "28th International Conference, SAFECOMP 2009", +// location: "Hamburg, Germany", +// month: 9, +// year: 2009}, // {url: "", // title: "Automatic Generation of Cycle-Approximate TLMs with Timed RTOS Model Support", From sabre at nondot.org Mon Oct 26 00:57:29 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 00:57:29 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/pubs.js Message-ID: <200910260557.n9Q5vTgj005690@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: pubs.js updated: 1.62 -> 1.63 --- Log message: theory: we *must* have an author field. --- Diffs of the changes: (+14 -12) pubs.js | 26 ++++++++++++++------------ 1 files changed, 14 insertions(+), 12 deletions(-) Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.62 llvm-www/pubs/pubs.js:1.63 --- llvm-www/pubs/pubs.js:1.62 Mon Oct 26 00:56:28 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 00:57:14 2009 @@ -1,19 +1,21 @@ // The array should be sorted reverse-chronologically, and will be displayed on // the page in the order listed. var PUBS = [ -// {url: "", -// title: "AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware", -// published: "28th International Conference, SAFECOMP 2009", -// location: "Hamburg, Germany", -// month: 9, -// year: 2009}, + {url: "", + title: "AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware", + published: "28th International Conference, SAFECOMP 2009", + author: "", + location: "Hamburg, Germany", + month: 9, + year: 2009}, -// {url: "", -// title: "Automatic Generation of Cycle-Approximate TLMs with Timed RTOS Model Support", -// published: "Analysis, Architectures and Modelling of Embedded Systems 2009 (IESS 2009)", -// location: "Langenargen, Germany", -// month: 9, -// year: 2009}, + {url: "", + title: "Automatic Generation of Cycle-Approximate TLMs with Timed RTOS Model Support", + published: "Analysis, Architectures and Modelling of Embedded Systems 2009 (IESS 2009)", + author: "", + location: "Langenargen, Germany", + month: 9, + year: 2009}, {url: '2009-08-SAS-IPSSA.html', title: "Increasing the scope and resolution of Interprocedural Static Single Assignment", From sabre at nondot.org Mon Oct 26 00:58:59 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 00:58:59 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/pubs.js Message-ID: <200910260558.n9Q5wxIu005776@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: pubs.js updated: 1.63 -> 1.64 --- Log message: that was it, add the rest back, sorry for the thrashing. --- Diffs of the changes: (+17 -17) pubs.js | 34 +++++++++++++++++----------------- 1 files changed, 17 insertions(+), 17 deletions(-) Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.63 llvm-www/pubs/pubs.js:1.64 --- llvm-www/pubs/pubs.js:1.63 Mon Oct 26 00:57:14 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 00:58:43 2009 @@ -4,7 +4,7 @@ {url: "", title: "AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware", published: "28th International Conference, SAFECOMP 2009", - author: "", + author: "Christof Fetzer, Ute Schiffel, and Martin S????kraut", location: "Hamburg, Germany", month: 9, year: 2009}, @@ -12,7 +12,7 @@ {url: "", title: "Automatic Generation of Cycle-Approximate TLMs with Timed RTOS Model Support", published: "Analysis, Architectures and Modelling of Embedded Systems 2009 (IESS 2009)", - author: "", + author: "Yonghyun Hwang, Gunar Schirner, and Samar Abdi", location: "Langenargen, Germany", month: 9, year: 2009}, @@ -41,21 +41,21 @@ month: 7, year: 2009}, -// {url: "", -// title: "Verifying the Implementation of an Operating System Scheduler", -// author: "Moritz Kleine, Bj??rn Bartels, Thomas G??thel, and Sabine Glesner", -// published: "IEEE International Symposium on Theoretical Aspects of Software Engineering", -// location: 'Tianjin, China', -// month: 7, -// year: 2009}, - -// {url: "", -// title: "Programmable and Scalable Architecture for Graphics Processing Units", -// author: "Carlos S. Lama, Pekka J????skel??inen, Jarmo Takala", -// published "Proc. of the 9th International Workshop on Embedded Computer Systems: Architectures, Modeling, and Simulation", -// location: "Samos, Greece", -// month: 7, -// year: 2009}, + {url: "", + title: "Verifying the Implementation of an Operating System Scheduler", + author: "Moritz Kleine, Bj??rn Bartels, Thomas G??thel, and Sabine Glesner", + published: "IEEE International Symposium on Theoretical Aspects of Software Engineering", + location: 'Tianjin, China', + month: 7, + year: 2009}, + + {url: "", + title: "Programmable and Scalable Architecture for Graphics Processing Units", + author: "Carlos S. Lama, Pekka J????skel??inen, Jarmo Takala", + published "Proc. of the 9th International Workshop on Embedded Computer Systems: Architectures, Modeling, and Simulation", + location: "Samos, Greece", + month: 7, + year: 2009}, {url: '2009-06-PLDI-LibraryBindings.html', title: 'Automatic generation of library bindings using static analysis', From sabre at nondot.org Mon Oct 26 01:01:35 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 01:01:35 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/pubs.js Message-ID: <200910260601.n9Q61Z9I005894@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: pubs.js updated: 1.64 -> 1.65 --- Log message: kill funny characters? --- Diffs of the changes: (+3 -3) pubs.js | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.64 llvm-www/pubs/pubs.js:1.65 --- llvm-www/pubs/pubs.js:1.64 Mon Oct 26 00:58:43 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 01:01:18 2009 @@ -4,7 +4,7 @@ {url: "", title: "AN-Encoding Compiler: Building Safety-Critical Systems with Commodity Hardware", published: "28th International Conference, SAFECOMP 2009", - author: "Christof Fetzer, Ute Schiffel, and Martin S????kraut", + author: "Christof Fetzer, Ute Schiffel, and Martin SuBkraut", location: "Hamburg, Germany", month: 9, year: 2009}, @@ -43,7 +43,7 @@ {url: "", title: "Verifying the Implementation of an Operating System Scheduler", - author: "Moritz Kleine, Bj??rn Bartels, Thomas G??thel, and Sabine Glesner", + author: "Moritz Kleine, Bjorn Bartels, Thomas Gothel, and Sabine Glesner", published: "IEEE International Symposium on Theoretical Aspects of Software Engineering", location: 'Tianjin, China', month: 7, @@ -51,7 +51,7 @@ {url: "", title: "Programmable and Scalable Architecture for Graphics Processing Units", - author: "Carlos S. Lama, Pekka J????skel??inen, Jarmo Takala", + author: "Carlos S. Lama, Pekka Jaaskelainen, Jarmo Takala", published "Proc. of the 9th International Workshop on Embedded Computer Systems: Architectures, Modeling, and Simulation", location: "Samos, Greece", month: 7, From sabre at nondot.org Mon Oct 26 01:02:57 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 01:02:57 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/pubs.js Message-ID: <200910260602.n9Q62vJD005959@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: pubs.js updated: 1.65 -> 1.66 --- Log message: I hate the internet --- Diffs of the changes: (+7 -7) pubs.js | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.65 llvm-www/pubs/pubs.js:1.66 --- llvm-www/pubs/pubs.js:1.65 Mon Oct 26 01:01:18 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 01:02:41 2009 @@ -41,13 +41,13 @@ month: 7, year: 2009}, - {url: "", - title: "Verifying the Implementation of an Operating System Scheduler", - author: "Moritz Kleine, Bjorn Bartels, Thomas Gothel, and Sabine Glesner", - published: "IEEE International Symposium on Theoretical Aspects of Software Engineering", - location: 'Tianjin, China', - month: 7, - year: 2009}, + // {url: "", + // title: "Verifying the Implementation of an Operating System Scheduler", + // author: "Moritz Kleine, Bjorn Bartels, Thomas Gothel, and Sabine Glesner", + // published: "IEEE International Symposium on Theoretical Aspects of Software Engineering", + // location: 'Tianjin, China', + // month: 7, + // year: 2009}, {url: "", title: "Programmable and Scalable Architecture for Graphics Processing Units", From sabre at nondot.org Mon Oct 26 01:03:33 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 01:03:33 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/pubs.js Message-ID: <200910260603.n9Q63Xkj006002@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: pubs.js updated: 1.66 -> 1.67 --- Log message: missing colon. --- Diffs of the changes: (+8 -8) pubs.js | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-) Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.66 llvm-www/pubs/pubs.js:1.67 --- llvm-www/pubs/pubs.js:1.66 Mon Oct 26 01:02:41 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 01:03:17 2009 @@ -41,18 +41,18 @@ month: 7, year: 2009}, - // {url: "", - // title: "Verifying the Implementation of an Operating System Scheduler", - // author: "Moritz Kleine, Bjorn Bartels, Thomas Gothel, and Sabine Glesner", - // published: "IEEE International Symposium on Theoretical Aspects of Software Engineering", - // location: 'Tianjin, China', - // month: 7, - // year: 2009}, + {url: "", + title: "Verifying the Implementation of an Operating System Scheduler", + author: "Moritz Kleine, Bjorn Bartels, Thomas Gothel, and Sabine Glesner", + published: "IEEE International Symposium on Theoretical Aspects of Software Engineering", + location: 'Tianjin, China', + month: 7, + year: 2009}, {url: "", title: "Programmable and Scalable Architecture for Graphics Processing Units", author: "Carlos S. Lama, Pekka Jaaskelainen, Jarmo Takala", - published "Proc. of the 9th International Workshop on Embedded Computer Systems: Architectures, Modeling, and Simulation", + published: "Proc. of the 9th International Workshop on Embedded Computer Systems: Architectures, Modeling, and Simulation", location: "Samos, Greece", month: 7, year: 2009}, From daniel at zuster.org Mon Oct 26 01:08:10 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Sun, 25 Oct 2009 23:08:10 -0700 Subject: [llvm-commits] [llvm] r83353 - in /llvm/trunk: lib/ExecutionEngine/JIT/JITEmitter.cpp unittests/ExecutionEngine/JIT/JITTest.cpp In-Reply-To: <200910060035.n960Zuca025893@zion.cs.uiuc.edu> References: <200910060035.n960Zuca025893@zion.cs.uiuc.edu> Message-ID: <6a8523d60910252308p3db171bh75a1ce1d6669726b@mail.gmail.com> On Mon, Oct 5, 2009 at 5:35 PM, Jeffrey Yasskin wrote: > Author: jyasskin > Date: Mon Oct ?5 19:35:55 2009 > New Revision: 83353 > > URL: http://llvm.org/viewvc/llvm-project?rev=83353&view=rev > Log: > Fix http://llvm.org/PR5116 by rolling back r60822. ?This passes `make unittests > check-lit` on both x86-64 Linux and x86-32 Darwin. Note that the unittests are automatically run as part of 'make check-lit'. - Daniel > > Modified: > ? ?llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp > ? ?llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp > > Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=83353&r1=83352&r2=83353&view=diff > > ============================================================================== > --- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original) > +++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Mon Oct ?5 19:35:55 2009 > @@ -644,7 +644,7 @@ > ? // If we have already compiled the function, return a pointer to its body. > ? Function *F = cast(V); > ? void *ResultPtr; > - ?if (!DoesntNeedStub && !TheJIT->isLazyCompilationDisabled()) { > + ?if (!DoesntNeedStub) { > ? ? // Return the function stub if it's already created. > ? ? ResultPtr = Resolver.getFunctionStubIfAvailable(F); > ? ? if (ResultPtr) > > Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=83353&r1=83352&r2=83353&view=diff > > ============================================================================== > --- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original) > +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Mon Oct ?5 19:35:55 2009 > @@ -22,6 +22,7 @@ > ?#include "llvm/Module.h" > ?#include "llvm/ModuleProvider.h" > ?#include "llvm/Support/IRBuilder.h" > +#include "llvm/Support/TypeBuilder.h" > ?#include "llvm/Target/TargetSelect.h" > ?#include "llvm/Type.h" > > @@ -44,6 +45,21 @@ > ? return F; > ?} > > +class JITTest : public testing::Test { > + protected: > + ?virtual void SetUp() { > + ? ?M = new Module("
", Context); > + ? ?std::string Error; > + ? ?TheJIT.reset(EngineBuilder(M).setEngineKind(EngineKind::JIT) > + ? ? ? ? ? ? ? ? .setErrorStr(&Error).create()); > + ? ?ASSERT_TRUE(TheJIT.get() != NULL) << Error; > + ?} > + > + ?LLVMContext Context; > + ?Module *M; ?// Owned by ExecutionEngine. > + ?OwningPtr TheJIT; > +}; > + > ?// Regression test for a bug. ?The JIT used to allocate globals inside the same > ?// memory block used for the function, and when the function code was freed, > ?// the global was left in the same place. ?This test allocates a function > @@ -115,6 +131,43 @@ > ? EXPECT_EQ(3, *GPtr); > ?} > > +int PlusOne(int arg) { > + ?return arg + 1; > +} > + > +TEST_F(JITTest, FarCallToKnownFunction) { > + ?// x86-64 can only make direct calls to functions within 32 bits of > + ?// the current PC. ?To call anything farther away, we have to load > + ?// the address into a register and call through the register. ?The > + ?// current JIT does this by allocating a stub for any far call. > + ?// There was a bug in which the JIT tried to emit a direct call when > + ?// the target was already in the JIT's global mappings and lazy > + ?// compilation was disabled. > + > + ?Function *KnownFunction = Function::Create( > + ? ? ?TypeBuilder::get(Context), > + ? ? ?GlobalValue::ExternalLinkage, "known", M); > + ?TheJIT->addGlobalMapping(KnownFunction, (void*)(intptr_t)PlusOne); > + > + ?// int test() { return known(7); } > + ?Function *TestFunction = Function::Create( > + ? ? ?TypeBuilder::get(Context), > + ? ? ?GlobalValue::ExternalLinkage, "test", M); > + ?BasicBlock *Entry = BasicBlock::Create(Context, "entry", TestFunction); > + ?IRBuilder<> Builder(Entry); > + ?Value *result = Builder.CreateCall( > + ? ? ?KnownFunction, > + ? ? ?ConstantInt::get(TypeBuilder::get(Context), 7)); > + ?Builder.CreateRet(result); > + > + ?TheJIT->EnableDlsymStubs(false); > + ?TheJIT->DisableLazyCompilation(); > + ?int (*TestFunctionPtr)() = reinterpret_cast( > + ? ? ?(intptr_t)TheJIT->getPointerToFunction(TestFunction)); > + ?// This used to crash in trying to call PlusOne(). > + ?EXPECT_EQ(8, TestFunctionPtr()); > +} > + > ?// This code is copied from JITEventListenerTest, but it only runs once for all > ?// the tests in this directory. ?Everything seems fine, but that's strange > ?// behavior. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From sabre at nondot.org Mon Oct 26 01:20:24 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 01:20:24 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2009-08-Zoltar.html 2009-08-Zoltar.pdf pubs.js Message-ID: <200910260620.n9Q6KOWW006712@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2009-08-Zoltar.html added (r1.1) 2009-08-Zoltar.pdf added (r1.1) pubs.js updated: 1.67 -> 1.68 --- Log message: add Zoltar: a spectrum-based fault localization tool and another one without a pdf. --- Diffs of the changes: (+79 -0) 2009-08-Zoltar.html | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2009-08-Zoltar.pdf | 0 pubs.js | 15 ++++++++++++ 3 files changed, 79 insertions(+) Index: llvm-www/pubs/2009-08-Zoltar.html diff -c /dev/null llvm-www/pubs/2009-08-Zoltar.html:1.1 *** /dev/null Mon Oct 26 01:19:55 2009 --- llvm-www/pubs/2009-08-Zoltar.html Mon Oct 26 01:19:45 2009 *************** *** 0 **** --- 1,64 ---- + + + + + + Zoltar: a spectrum-based fault localization tool + + + +
+ Zoltar: a spectrum-based fault localization tool +
+
+ Tom Janssen, Rui Abreu, and Arjan J.C. van Gemund +
+ +

Abstract:

+
+ Locating software components which are responsible for observed failures is the most expensive, error-prone phase in the software development life cycle. Automated diagnosis of software faults can improve the efficiency of the debugging process, and is therefore an important process for the development of dependable software. In this paper we present a toolset for automatic fault localization, dubbed Zoltar, which adopts a spectrum-based fault localization technique. The toolset provides the infrastructure to automatically instrument the source code of software programs to produce runtime data, which is subsequently analyzed to return a ranked list of likely faulty locations. Aimed at total automation (e.g., for runtime fault diagnosis), Zoltar has the capability of instrumenting the program under analysis with fault screeners, for automatic error detection. Using a small thread-based example program as well as a large realistic program, we show the applicability of the pr! oposed toolset. +
+ +

Published:

+
+ "Zoltar: a spectrum-based fault localization tool" +
+ Tom Janssen, Rui Abreu, and Arjan J.C. van Gemund. +
+ + Proceedings of the 2009 ESEC/FSE workshop on Software integration and evolution @ runtime + , Amsterdam, The Netherlands, August 2009. +
+

Download:

+

Paper:

+ + +

BibTeX Entry:

+
+ @inproceedings{1596502,
+  author = {Janssen, Tom and Abreu, Rui and van Gemund, Arjan J.C.},
+  title = {Zoltar: a spectrum-based fault localization tool},
+  booktitle = {SINTER '09: Proceedings of the 2009 ESEC/FSE workshop on Software integration and evolution @ runtime},
+  year = {2009},
+  isbn = {978-1-60558-681-6},
+  pages = {23--30},
+  location = {Amsterdam, The Netherlands},
+  doi = {http://doi.acm.org/10.1145/1596495.1596502},
+  publisher = {ACM},
+  address = {New York, NY, USA},
+  }
+ 
+ + +
+ Valid CSS! + Valid HTML 4.01! + + + Index: llvm-www/pubs/2009-08-Zoltar.pdf Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.67 llvm-www/pubs/pubs.js:1.68 --- llvm-www/pubs/pubs.js:1.67 Mon Oct 26 01:03:17 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 01:19:45 2009 @@ -33,6 +33,14 @@ month: 8, year: 2009}, + {url: '2009-08-Zoltar.html', + title: "Zoltar: a spectrum-based fault localization tool", + author: "Tom Janssen, Rui Abreu, and Arjan J.C. van Gemund", + published: "Proc. of the 2009 ESEC/FSE workshop on Software integration and evolution @ runtime", + location: "Amsterdam, The Netherlands", + month: 8, + year: 2009}, + {url: '2009-07-ISSTA-BegBunch.html', title: 'BegBunch: benchmarking for C bug detection tools', author: 'Cristina Cifuentes, Christian Hoermann, Nathan Keynes, Lian Li, Simon Long, Erica Mealy, Michael Mounteney, and Bernhard Scholz', @@ -172,6 +180,13 @@ month: 3, year: 2009}, + {url: "", + title: "SORU: A Reconfigurable Vector Unit for Adaptable Embedded Systems", + author: "Jos?? M. Moya, Javier Rodr??guez, et al", + published: "Proc. of the 5th International Workshop on Reconfigurable Computing: Architectures, Tools and Applications", + month: 3, + year: 2009}, + {url: '2009-02-PPoPP-MappingParallelism.html', title: 'Mapping parallelism to multi-cores: a machine learning based approach', author: "Zheng Wang and Michael F.P. O'Boyle", From sabre at nondot.org Mon Oct 26 01:29:41 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 01:29:41 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2009-08-FSE-Altair.html 2009-08-FSE-Altair.pdf pubs.js Message-ID: <200910260629.n9Q6Tf4P007045@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2009-08-FSE-Altair.html added (r1.1) 2009-08-FSE-Altair.pdf added (r1.1) pubs.js updated: 1.68 -> 1.69 --- Log message: add a couple more. --- Diffs of the changes: (+70 -0) 2009-08-FSE-Altair.html | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 2009-08-FSE-Altair.pdf | 0 pubs.js | 15 +++++++++++++ 3 files changed, 70 insertions(+) Index: llvm-www/pubs/2009-08-FSE-Altair.html diff -c /dev/null llvm-www/pubs/2009-08-FSE-Altair.html:1.1 *** /dev/null Mon Oct 26 01:29:34 2009 --- llvm-www/pubs/2009-08-FSE-Altair.html Mon Oct 26 01:29:24 2009 *************** *** 0 **** --- 1,55 ---- + + + + + + API hyperlinking via structural overlap + + + +
+ API hyperlinking via structural overlap +
+
+ Fan Long, Xi Wang, and Yang Cai +
+ +

Abstract:

+
+ This paper presents a tool Altair that automatically generates API function cross-references, which emphasizes reliable structural measures and does not depend on specific client code. Altair ranks related API functions for a given query according to pair-wise overlap, i.e., how they share state, and clusters tightly related ones into meaningful modules.

+ + Experiments against several popular C software packages show that Altair recommends related API functions for a given query with remarkably more precise and complete results than previous tools, that it can extract modules from moderate-sized software (e.g., Apache with 1000+ functions) at high precision and recall rates (e.g., both exceeding 70% for two modules in Apache), and that the computation can finish within a few seconds. +

+ +

Published:

+
+ "API hyperlinking via structural overlap" +
+ Fan Long, Xi Wang, and Yang Cai. +
+ + Proceedings of the 7th joint meeting of the European software engineering conference and the ACM SIGSOFT symposium on The foundations of software engineering on European software engineering conference and foundations of software engineering symposium (FSE'09) + , Amsterdam, The Netherlands, August 2009. +
+

Download:

+

Paper:

+ + +

BibTeX Entry:

+
+ BIBTEX
+ 
+ + +
+ Valid CSS! + Valid HTML 4.01! + + + Index: llvm-www/pubs/2009-08-FSE-Altair.pdf Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.68 llvm-www/pubs/pubs.js:1.69 --- llvm-www/pubs/pubs.js:1.68 Mon Oct 26 01:19:45 2009 +++ llvm-www/pubs/pubs.js Mon Oct 26 01:29:24 2009 @@ -17,6 +17,14 @@ month: 9, year: 2009}, + {url: "2009-08-FSE-Altair.html", + title: "API hyperlinking via structural overlap", + published: "Proc. of the ACM symposium on The foundations of software engineering symposium (FSE'09)", + author: "Fan Long, Xi Wang, and Yang Cai", + location: "Amsterdam, The Netherlands", + month: 8, + year: 2009}, + {url: '2009-08-SAS-IPSSA.html', title: "Increasing the scope and resolution of Interprocedural Static Single Assignment", author: "Silvian Calman and Jianwen Zhu", @@ -187,6 +195,13 @@ month: 3, year: 2009}, + {url: "", + title: "Compiling Techniques for Coarse Grained Runtime Reconfigurable Architecture", + author: "Mythri Alle, Keshavan Varadarajan, Alexander Fell, S. K. Nandy and Ranjani Narayan", + published: "Proc. of the 5th International Workshop on Reconfigurable Computing: Architectures, Tools and Applications", + month: 3, + year: 2009}, + {url: '2009-02-PPoPP-MappingParallelism.html', title: 'Mapping parallelism to multi-cores: a machine learning based approach', author: "Zheng Wang and Michael F.P. O'Boyle", From jyasskin at google.com Mon Oct 26 02:19:16 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Mon, 26 Oct 2009 00:19:16 -0700 Subject: [llvm-commits] [llvm] r83353 - in /llvm/trunk: lib/ExecutionEngine/JIT/JITEmitter.cpp unittests/ExecutionEngine/JIT/JITTest.cpp In-Reply-To: <6a8523d60910252308p3db171bh75a1ce1d6669726b@mail.gmail.com> References: <200910060035.n960Zuca025893@zion.cs.uiuc.edu> <6a8523d60910252308p3db171bh75a1ce1d6669726b@mail.gmail.com> Message-ID: On Sun, Oct 25, 2009 at 11:08 PM, Daniel Dunbar wrote: > On Mon, Oct 5, 2009 at 5:35 PM, Jeffrey Yasskin wrote: >> Author: jyasskin >> Date: Mon Oct ?5 19:35:55 2009 >> New Revision: 83353 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=83353&view=rev >> Log: >> Fix http://llvm.org/PR5116 by rolling back r60822. ?This passes `make unittests >> check-lit` on both x86-64 Linux and x86-32 Darwin. > > Note that the unittests are automatically run as part of 'make check-lit'. Thanks :) From gohman at apple.com Mon Oct 26 10:32:57 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 26 Oct 2009 15:32:57 -0000 Subject: [llvm-commits] [llvm] r85118 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/negative-stride-fptosi-user.ll Message-ID: <200910261532.n9QFWvqE018728@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 26 10:32:57 2009 New Revision: 85118 URL: http://llvm.org/viewvc/llvm-project?rev=85118&view=rev Log: Make LSR's OptimizeShadowIV ignore induction variables with negative strides for now, because it doesn't handle them correctly. This fixes a miscompile of SingleSource/Benchmarks/Misc-C++/ray. This problem was usually hidden because indvars transforms such induction variables into negations of canonical induction variables. Added: llvm/trunk/test/CodeGen/X86/negative-stride-fptosi-user.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=85118&r1=85117&r2=85118&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Oct 26 10:32:57 2009 @@ -2262,6 +2262,10 @@ if (!C) continue; + // Ignore negative constants, as the code below doesn't handle them + // correctly. TODO: Remove this restriction. + if (!C->getValue().isStrictlyPositive()) continue; + /* Add new PHINode. */ PHINode *NewPH = PHINode::Create(DestTy, "IV.S.", PH); Added: llvm/trunk/test/CodeGen/X86/negative-stride-fptosi-user.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/negative-stride-fptosi-user.ll?rev=85118&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/negative-stride-fptosi-user.ll (added) +++ llvm/trunk/test/CodeGen/X86/negative-stride-fptosi-user.ll Mon Oct 26 10:32:57 2009 @@ -0,0 +1,25 @@ +; RUN: llc < %s -march=x86-64 | grep cvtsi2sd + +; LSR previously eliminated the sitofp by introducing an induction +; variable which stepped by a bogus ((double)UINT32_C(-1)). It's theoretically +; possible to eliminate the sitofp using a proper -1.0 step though; this +; test should be changed if that is done. + +define void @foo(i32 %N) nounwind { +entry: + %0 = icmp slt i32 %N, 0 ; [#uses=1] + br i1 %0, label %bb, label %return + +bb: ; preds = %bb, %entry + %i.03 = phi i32 [ 0, %entry ], [ %2, %bb ] ; [#uses=2] + %1 = sitofp i32 %i.03 to double ; [#uses=1] + tail call void @bar(double %1) nounwind + %2 = add nsw i32 %i.03, -1 ; [#uses=2] + %exitcond = icmp eq i32 %2, %N ; [#uses=1] + br i1 %exitcond, label %return, label %bb + +return: ; preds = %bb, %entry + ret void +} + +declare void @bar(double) From sabre at nondot.org Mon Oct 26 10:40:08 2009 From: sabre at nondot.org (Chris Lattner) Date: Mon, 26 Oct 2009 15:40:08 -0000 Subject: [llvm-commits] [llvm] r85119 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/or.ll Message-ID: <200910261540.n9QFe8qO019069@zion.cs.uiuc.edu> Author: lattner Date: Mon Oct 26 10:40:07 2009 New Revision: 85119 URL: http://llvm.org/viewvc/llvm-project?rev=85119&view=rev Log: reapply r85085 with a bugfix to avoid infinite looping. All of the 'demorgan' related xforms need to use dyn_castNotVal, not m_Not. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/test/Transforms/InstCombine/or.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=85119&r1=85118&r2=85119&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Oct 26 10:40:07 2009 @@ -631,9 +631,32 @@ return 0; } -static inline Value *dyn_castNotVal(Value *V) { +/// isFreeToInvert - Return true if the specified value is free to invert (apply +/// ~ to). This happens in cases where the ~ can be eliminated. +static inline bool isFreeToInvert(Value *V) { + // ~(~(X)) -> X. if (BinaryOperator::isNot(V)) - return BinaryOperator::getNotArgument(V); + return true; + + // Constants can be considered to be not'ed values. + if (isa(V)) + return true; + + // Compares can be inverted if they have a single use. + if (CmpInst *CI = dyn_cast(V)) + return CI->hasOneUse(); + + return false; +} + +static inline Value *dyn_castNotVal(Value *V) { + // If this is not(not(x)) don't return that this is a not: we want the two + // not's to be folded first. + if (BinaryOperator::isNot(V)) { + Value *Operand = BinaryOperator::getNotArgument(V); + if (!isFreeToInvert(Operand)) + return Operand; + } // Constants can be considered to be not'ed values... if (ConstantInt *C = dyn_cast(V)) @@ -641,6 +664,8 @@ return 0; } + + // dyn_castFoldableMul - If this value is a multiply that can be folded into // other computations (because it has a constant operand), return the // non-constant operand of the multiply, and set CST to point to the multiplier. @@ -4166,7 +4191,7 @@ if (Instruction *CastOp = dyn_cast(CI->getOperand(0))) { if ((isa(CI) || isa(CI)) && CastOp->getNumOperands() == 2) - if (ConstantInt *AndCI = dyn_cast(CastOp->getOperand(1))) { + if (ConstantInt *AndCI =dyn_cast(CastOp->getOperand(1))){ if (CastOp->getOpcode() == Instruction::And) { // Change: and (cast (and X, C1) to T), C2 // into : and (cast X to T), trunc_or_bitcast(C1)&C2 @@ -4960,14 +4985,14 @@ if (Ret) return Ret; } - if (match(Op0, m_Not(m_Value(A)))) { // ~A | Op1 + if ((A = dyn_castNotVal(Op0))) { // ~A | Op1 if (A == Op1) // ~A | A == -1 return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); } else { A = 0; } // Note, A is still live here! - if (match(Op1, m_Not(m_Value(B)))) { // Op0 | ~B + if ((B = dyn_castNotVal(Op1))) { // Op0 | ~B if (Op0 == B) return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); @@ -5064,12 +5089,13 @@ // Is this a ~ operation? if (Value *NotOp = dyn_castNotVal(&I)) { - // ~(~X & Y) --> (X | ~Y) - De Morgan's Law - // ~(~X | Y) === (X & ~Y) - De Morgan's Law if (BinaryOperator *Op0I = dyn_cast(NotOp)) { if (Op0I->getOpcode() == Instruction::And || Op0I->getOpcode() == Instruction::Or) { - if (dyn_castNotVal(Op0I->getOperand(1))) Op0I->swapOperands(); + // ~(~X & Y) --> (X | ~Y) - De Morgan's Law + // ~(~X | Y) === (X & ~Y) - De Morgan's Law + if (dyn_castNotVal(Op0I->getOperand(1))) + Op0I->swapOperands(); if (Value *Op0NotVal = dyn_castNotVal(Op0I->getOperand(0))) { Value *NotY = Builder->CreateNot(Op0I->getOperand(1), @@ -5078,6 +5104,19 @@ return BinaryOperator::CreateOr(Op0NotVal, NotY); return BinaryOperator::CreateAnd(Op0NotVal, NotY); } + + // ~(X & Y) --> (~X | ~Y) - De Morgan's Law + // ~(X | Y) === (~X & ~Y) - De Morgan's Law + if (isFreeToInvert(Op0I->getOperand(0)) && + isFreeToInvert(Op0I->getOperand(1))) { + Value *NotX = + Builder->CreateNot(Op0I->getOperand(0), "notlhs"); + Value *NotY = + Builder->CreateNot(Op0I->getOperand(1), "notrhs"); + if (Op0I->getOpcode() == Instruction::And) + return BinaryOperator::CreateOr(NotX, NotY); + return BinaryOperator::CreateAnd(NotX, NotY); + } } } } Modified: llvm/trunk/test/Transforms/InstCombine/or.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/or.ll?rev=85119&r1=85118&r2=85119&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/or.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/or.ll Mon Oct 26 10:40:07 2009 @@ -1,7 +1,6 @@ ; This test makes sure that these instructions are properly eliminated. ; ; RUN: opt < %s -instcombine -S | FileCheck %s -; XFAIL: * define i32 @test1(i32 %A) { %B = or i32 %A, 0 From gohman at apple.com Mon Oct 26 10:51:41 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 26 Oct 2009 08:51:41 -0700 Subject: [llvm-commits] [llvm] r85017 - in /llvm/trunk/test/Transforms: Inline/callgraph-update.ll JumpThreading/no-irreducible-loops.ll LICM/Preserve-LCSSA.ll LoopRotate/2009-01-25-SingleEntryPhi.ll LoopRotate/LRCrash-1.ll LoopRotate/LRCrash-2.ll LoopRotate/LRCrash-3.ll LoopRotate/LRCrash-4.ll LoopRotate/LRCrash-5.ll LoopRotate/PhiRename-1.ll LoopRotate/PhiSelfRefernce-1.ll LoopRotate/pr2639.ll LoopRotate/preserve-scev.ll LoopSimplify/merge-exits.ll In-Reply-To: <4AE41298.4050102@free.fr> References: <200910242323.n9ONN5fF025552@zion.cs.uiuc.edu> <4AE41298.4050102@free.fr> Message-ID: On Oct 25, 2009, at 1:55 AM, Duncan Sands wrote: > Hi Dan, > >> Make these tests more interesting by using >> -verify-dom-info and -verify-loop-info, which enable additional >> (expensive) consistency checks. > > maybe also these checks can be turned on automatically after loop > passes if LLVM is built with expensive checking turned on. Trying > to bootstrap gcc with an expensive checks build can be informative :) These options are already enabled by default in expensive checks builds. Thanks, Dan From gohman at apple.com Mon Oct 26 10:55:25 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 26 Oct 2009 15:55:25 -0000 Subject: [llvm-commits] [llvm] r85120 - /llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Message-ID: <200910261555.n9QFtPCs020088@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 26 10:55:24 2009 New Revision: 85120 URL: http://llvm.org/viewvc/llvm-project?rev=85120&view=rev Log: Fix a typo in a comment. Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=85120&r1=85119&r2=85120&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Mon Oct 26 10:55:24 2009 @@ -211,7 +211,7 @@ for (I = OrigHeader->begin(); PHINode *PN = dyn_cast(I); ++I) PN->removeIncomingValue(PN->getBasicBlockIndex(OrigPreHeader)); - // Now fix up users of the instructions in OrigHeader, insertting PHI nodes + // Now fix up users of the instructions in OrigHeader, inserting PHI nodes // as necessary. SSAUpdater SSA; for (I = OrigHeader->begin(); I != E; ++I) { From gohman at apple.com Mon Oct 26 10:58:33 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 26 Oct 2009 08:58:33 -0700 Subject: [llvm-commits] [llvm] r85016 - /llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp In-Reply-To: <6FE2703A-1167-451D-B151-E84B042B2378@apple.com> References: <200910242319.n9ONJrei025407@zion.cs.uiuc.edu> <6FE2703A-1167-451D-B151-E84B042B2378@apple.com> Message-ID: <7064681D-2A98-432F-A88E-53E851C2FFF4@apple.com> On Oct 24, 2009, at 6:20 PM, Chris Lattner wrote: > > On Oct 24, 2009, at 4:19 PM, Dan Gohman wrote: > >> Author: djg >> Date: Sat Oct 24 18:19:52 2009 >> New Revision: 85016 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=85016&view=rev >> Log: >> Rewrite LoopRotation's SSA updating code using SSAUpdater. > > Awesome, I didn't remember loop rotate had its own ssa update code. > > If, in your travels, you run into any cases where SSAUpdate is a > significant compile time issue, please give me a testcase. I have > many less-than-crazy ideas for speeding it up. One problem I'm seeing is redundant PHIs. Sphereflake for example now gets code like this: %p.013.i = phi %struct.node_t* [ %p.0.be.i, %bb5.backedge.i ], [ %78, %bb9.i ] ; <%struct.node_t*> [#uses=1] %p.012.i = phi %struct.node_t* [ %p.0.be.i, %bb5.backedge.i ], [ %78, %bb9.i ] ; <%struct.node_t*> [#uses=1] %p.011.i = phi %struct.node_t* [ %p.0.be.i, %bb5.backedge.i ], [ %78, %bb9.i ] ; <%struct.node_t*> [#uses=1] %p.010.i = phi %struct.node_t* [ %p.0.be.i, %bb5.backedge.i ], [ %78, %bb9.i ] ; <%struct.node_t*> [#uses=1] %p.09.i = phi %struct.node_t* [ %p.0.be.i, %bb5.backedge.i ], [ %78, %bb9.i ] ; <%struct.node_t*> [#uses=7] Indvars can't eliminate these because they aren't a function of the canonical induction variable. These PHIs stick around and end up being allocated registers, which is suboptimal. > >> + >> + // Now fix up users of the instructions in OrigHeader, >> insertting PHI nodes > > typo insertting. Fixed. > >> + // as necessary. >> + SSAUpdater SSA; >> + for (I = OrigHeader->begin(); I != E; ++I) { >> + Value *OrigHeaderVal = I; > > Most instructions only have uses within their block and these don't > need to be rewritten. It would improve efficiency to do something > like this if it is safe: > if (I->hasOneUse() && I->use_back()->getParent() == I && > !isa(I->use_back())) > continue; The code already avoids calling RewriteUse in these cases. Are you concerned about the SSAUpdater::Initialize and AddAvailableValue calls? Dan From daniel at zuster.org Mon Oct 26 11:02:25 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 26 Oct 2009 09:02:25 -0700 Subject: [llvm-commits] [llvm] r83424 - /llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp In-Reply-To: <200910062226.n96MQgaB016790@zion.cs.uiuc.edu> References: <200910062226.n96MQgaB016790@zion.cs.uiuc.edu> Message-ID: <6a8523d60910260902i74d4d85dje53cb78d6f7fa5b@mail.gmail.com> Hi Kevin, A few comments inline: On Tue, Oct 6, 2009 at 3:26 PM, Kevin Enderby wrote: > Author: enderby > Date: Tue Oct ?6 17:26:42 2009 > New Revision: 83424 > > URL: http://llvm.org/viewvc/llvm-project?rev=83424&view=rev > Log: > Added bits of the ARM target assembler to llvm-mc to parse some load instruction > operands. ?Some parsing of arm memory operands for preindexing and postindexing > forms including with register controled shifts. ?This is a work in progress. > > Modified: > ? ?llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp > > Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=83424&r1=83423&r2=83424&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original) > +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Tue Oct ?6 17:26:42 2009 > @@ -23,6 +23,15 @@ > ?namespace { > ?struct ARMOperand; > > +// The shift types for register controlled shifts in arm memory addressing > +enum ShiftType { > + ?Lsl, > + ?Lsr, > + ?Asr, > + ?Ror, > + ?Rrx > +}; > + > ?class ARMAsmParser : public TargetAsmParser { > ? MCAsmParser &Parser; > > @@ -35,8 +44,31 @@ > > ? bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } > > + ?bool ParseRegister(ARMOperand &Op); > + > + ?bool ParseMemory(ARMOperand &Op); > + > + ?bool ParseShift(enum ShiftType *St, const MCExpr *ShiftAmount); > + > + ?bool ParseOperand(ARMOperand &Op); > + > ? bool ParseDirectiveWord(unsigned Size, SMLoc L); > > + ?// TODO - For now hacked versions of the next two are in here in this file to > + ?// allow some parser testing until the table gen versions are implemented. > + > + ?/// @name Auto-generated Match Functions > + ?/// { > + ?bool MatchInstruction(SmallVectorImpl &Operands, > + ? ? ? ? ? ? ? ? ? ? ? ?MCInst &Inst); > + > + ?/// MatchRegisterName - Match the given string to a register name, or 0 if > + ?/// there is no match. > + ?unsigned MatchRegisterName(const StringRef &Name); > + > + ?/// } > + > + > ?public: > ? ARMAsmParser(const Target &T, MCAsmParser &_Parser) > ? ? : TargetAsmParser(T), Parser(_Parser) {} > @@ -48,9 +80,380 @@ > > ?} // end anonymous namespace > > +namespace { > + > +/// ARMOperand - Instances of this class represent a parsed ARM machine > +/// instruction. > +struct ARMOperand { > + ?enum { > + ? ?Token, > + ? ?Register, > + ? ?Memory > + ?} Kind; > + > + > + ?union { > + ? ?struct { > + ? ? ?const char *Data; > + ? ? ?unsigned Length; > + ? ?} Tok; > + > + ? ?struct { > + ? ? ?unsigned RegNum; > + ? ?} Reg; > + > + ? ?// This is for all forms of ARM address expressions > + ? ?struct { > + ? ? ?unsigned BaseRegNum; > + ? ? ?bool OffsetIsReg; > + ? ? ?const MCExpr *Offset; // used when OffsetIsReg is false > + ? ? ?unsigned OffsetRegNum; // used when OffsetIsReg is true > + ? ? ?bool OffsetRegShifted; // only used when OffsetIsReg is true > + ? ? ?enum ShiftType ShiftType; ?// used when OffsetRegShifted is true > + ? ? ?const MCExpr *ShiftAmount; // used when OffsetRegShifted is true > + ? ? ?bool Preindexed; > + ? ? ?bool Postindexed; > + ? ? ?bool Negative; // only used when OffsetIsReg is true > + ? ? ?bool Writeback; > + ? ?} Mem; It probably makes sense to reorder these fields to make the struct smaller (bool -> 'unsigned foo : 1', and make MCExpr* fields adjacent). > +// Try to parse a register name. ?The token must be an Identifier when called, > +// and if it is a register name a Reg operand is created, the token is eaten > +// and false is returned. ?Else true is returned and no token is eaten. > +// TODO this is likely to change to allow different register types and or to > +// parse for a specific register type. Please use '///' instead of '//' so the comment gets picked up by doxygen. This applies in a number of places in this file. > +bool ARMAsmParser::ParseRegister(ARMOperand &Op) { > + ?const AsmToken &Tok = getLexer().getTok(); > + ?assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); > + > + ?// FIXME: Validate register for the current architecture; we have to do > + ?// validation later, so maybe there is no need for this here. > + ?unsigned RegNum; > + > + ?RegNum = MatchRegisterName(Tok.getString()); > + ?if (RegNum == 0) > + ? ?return true; > + > + ?Op = ARMOperand::CreateReg(RegNum); > + ?getLexer().Lex(); // Eat identifier token. > + > + ?return false; > +} Since this is a "try parse" routine, and doesn't emit errors or consume tokens on failure, it should be called MaybeParseRegister. > + > +// Try to parse an arm memory expression. ?It must start with a '[' token. > +// TODO Only preindexing and postindexing addressing are started, unindexed > +// with option, etc are still to do. > +bool ARMAsmParser::ParseMemory(ARMOperand &Op) { > + ?const AsmToken &LBracTok = getLexer().getTok(); > + ?assert(LBracTok.is(AsmToken::LBrac) && "Token is not an Left Bracket"); > + ?getLexer().Lex(); // Eat left bracket token. > + > + ?const AsmToken &BaseRegTok = getLexer().getTok(); > + ?if (BaseRegTok.isNot(AsmToken::Identifier)) > + ? ?return Error(BaseRegTok.getLoc(), "register expected"); > + ?unsigned BaseRegNum = MatchRegisterName(BaseRegTok.getString()); > + ?if (BaseRegNum == 0) > + ? ?return Error(BaseRegTok.getLoc(), "register expected"); Shouldn't this just call ParseRegister? > + ?getLexer().Lex(); // Eat identifier token. > + > + ?bool Preindexed = false; > + ?bool Postindexed = false; > + ?bool OffsetIsReg = false; > + ?bool Negative = false; > + ?bool Writeback = false; > + > + ?// First look for preindexed address forms: > + ?// ?[Rn, +/-Rm] > + ?// ?[Rn, #offset] > + ?// ?[Rn, +/-Rm, shift] > + ?// that is after the "[Rn" we now have see if the next token is a comma. > + ?const AsmToken &Tok = getLexer().getTok(); > + ?if (Tok.is(AsmToken::Comma)) { > + ? ?Preindexed = true; > + ? ?getLexer().Lex(); // Eat comma token. > + > + ? ?const AsmToken &NextTok = getLexer().getTok(); > + ? ?if (NextTok.is(AsmToken::Plus)) > + ? ? ?getLexer().Lex(); // Eat plus token. > + ? ?else if (NextTok.is(AsmToken::Minus)) { > + ? ? ?Negative = true; > + ? ? ?getLexer().Lex(); // Eat minus token > + ? ?} > + > + ? ?// See if there is a register following the "[Rn," we have so far. > + ? ?const AsmToken &OffsetRegTok = getLexer().getTok(); > + ? ?unsigned OffsetRegNum = MatchRegisterName(OffsetRegTok.getString()); Again, I think this should just call ParseRegister. Is a plus/minus not required here? This code will accept [Rn, Rm], is that intended? If so the comment above listing the forms should be updated. > + ? ?bool OffsetRegShifted = false; > + ? ?enum ShiftType ShiftType; > + ? ?const MCExpr *ShiftAmount; > + ? ?const MCExpr *Offset; > + ? ?if (OffsetRegNum != 0) { > + ? ? ?OffsetIsReg = true; > + ? ? ?getLexer().Lex(); // Eat identifier token for the offset register. > + ? ? ?// Look for a comma then a shift > + ? ? ?const AsmToken &Tok = getLexer().getTok(); > + ? ? ?if (Tok.is(AsmToken::Comma)) { > + ? ? ? ?getLexer().Lex(); // Eat comma token. > + > + ? ? ? ?const AsmToken &Tok = getLexer().getTok(); > + ? ? ? ?if (ParseShift(&ShiftType, ShiftAmount)) > + ? ? ? ? ?return Error(Tok.getLoc(), "shift expected"); > + ? ? ? ?OffsetRegShifted = true; > + ? ? ?} > + ? ?} > + ? ?else { // "[Rn," we have so far was not followed by "Rm" > + ? ? ?// Look for #offset following the "[Rn," > + ? ? ?const AsmToken &HashTok = getLexer().getTok(); > + ? ? ?if (HashTok.isNot(AsmToken::Hash)) > + ? ? ? ?return Error(HashTok.getLoc(), "'#' expected"); > + ? ? ?getLexer().Lex(); // Eat hash token. > + > + ? ? ?if (getParser().ParseExpression(Offset)) > + ? ? ? return true; > + ? ?} > + ? ?const AsmToken &RBracTok = getLexer().getTok(); > + ? ?if (RBracTok.isNot(AsmToken::RBrac)) > + ? ? ?return Error(RBracTok.getLoc(), "']' expected"); > + ? ?getLexer().Lex(); // Eat right bracket token. > + > + ? ?const AsmToken &ExclaimTok = getLexer().getTok(); > + ? ?if (ExclaimTok.is(AsmToken::Exclaim)) { > + ? ? ?Writeback = true; > + ? ? ?getLexer().Lex(); // Eat exclaim token > + ? ?} Can you please include an example of this form in the list of forms this routine is parsing? > + ? ?Op = ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OffsetRegShifted, ShiftType, ShiftAmount, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Preindexed, Postindexed, Negative, Writeback); > + ? ?return false; > + ?} > + ?// The "[Rn" we have so far was not followed by a comma. > + ?else if (Tok.is(AsmToken::RBrac)) { > + ? ?// This is a post indexing addressing forms: > + ? ?// ?[Rn], #offset > + ? ?// ?[Rn], +/-Rm > + ? ?// ?[Rn], +/-Rm, shift > + ? ?// that is a ']' follows after the "[Rn". > + ? ?Postindexed = true; > + ? ?Writeback = true; > + ? ?getLexer().Lex(); // Eat right bracket token. > + > + ? ?const AsmToken &CommaTok = getLexer().getTok(); > + ? ?if (CommaTok.isNot(AsmToken::Comma)) > + ? ? ?return Error(CommaTok.getLoc(), "',' expected"); > + ? ?getLexer().Lex(); // Eat comma token. > + > + ? ?const AsmToken &NextTok = getLexer().getTok(); > + ? ?if (NextTok.is(AsmToken::Plus)) > + ? ? ?getLexer().Lex(); // Eat plus token. > + ? ?else if (NextTok.is(AsmToken::Minus)) { > + ? ? ?Negative = true; > + ? ? ?getLexer().Lex(); // Eat minus token > + ? ?} > + > + ? ?// See if there is a register following the "[Rn]," we have so far. > + ? ?const AsmToken &OffsetRegTok = getLexer().getTok(); > + ? ?unsigned OffsetRegNum = MatchRegisterName(OffsetRegTok.getString()); > + ? ?bool OffsetRegShifted = false; > + ? ?enum ShiftType ShiftType; > + ? ?const MCExpr *ShiftAmount; > + ? ?const MCExpr *Offset; > + ? ?if (OffsetRegNum != 0) { > + ? ? ?OffsetIsReg = true; > + ? ? ?getLexer().Lex(); // Eat identifier token for the offset register. > + ? ? ?// Look for a comma then a shift > + ? ? ?const AsmToken &Tok = getLexer().getTok(); > + ? ? ?if (Tok.is(AsmToken::Comma)) { > + ? ? ? ?getLexer().Lex(); // Eat comma token. > + > + ? ? ? ?const AsmToken &Tok = getLexer().getTok(); > + ? ? ? ?if (ParseShift(&ShiftType, ShiftAmount)) > + ? ? ? ? ?return Error(Tok.getLoc(), "shift expected"); > + ? ? ? ?OffsetRegShifted = true; > + ? ? ?} > + ? ?} > + ? ?else { // "[Rn]," we have so far was not followed by "Rm" > + ? ? ?// Look for #offset following the "[Rn]," > + ? ? ?const AsmToken &HashTok = getLexer().getTok(); > + ? ? ?if (HashTok.isNot(AsmToken::Hash)) > + ? ? ? ?return Error(HashTok.getLoc(), "'#' expected"); > + ? ? ?getLexer().Lex(); // Eat hash token. > + > + ? ? ?if (getParser().ParseExpression(Offset)) > + ? ? ? return true; > + ? ?} > + ? ?Op = ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OffsetRegShifted, ShiftType, ShiftAmount, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Preindexed, Postindexed, Negative, Writeback); > + ? ?return false; > + ?} > + > + ?return true; > +} I think it might be cleaner to factor this routine into a part that parses: ',' #offset ',' +/-Rm ',' +/-Rm, shift and then reuse that for both the pre and post indexed forms. > +/// ParseShift as one of these two: > +/// ? ( lsl | lsr | asr | ror ) , # shift_amount > +/// ? rrx > +/// and returns true if it parses a shift otherwise it returns false. > +bool ARMAsmParser::ParseShift(ShiftType *St, const MCExpr *ShiftAmount) { This should take a reference to ShiftType instead of taking a pointer to it (convention). > + ?const AsmToken &Tok = getLexer().getTok(); > + ?if (Tok.isNot(AsmToken::Identifier)) > + ? ?return true; > + ?const StringRef &ShiftName = Tok.getString(); > + ?if (ShiftName == "lsl" || ShiftName == "LSL") > + ? ?*St = Lsl; > + ?else if (ShiftName == "lsr" || ShiftName == "LSR") > + ? ?*St = Lsr; > + ?else if (ShiftName == "asr" || ShiftName == "ASR") > + ? ?*St = Asr; > + ?else if (ShiftName == "ror" || ShiftName == "ROR") > + ? ?*St = Ror; > + ?else if (ShiftName == "rrx" || ShiftName == "RRX") > + ? ?*St = Rrx; > + ?else > + ? ?return true; > + ?getLexer().Lex(); // Eat shift type token. > + > + ?// For all but a Rotate right there must be a '#' and a shift amount > + ?if (*St != Rrx) { Chris will be happier if you write this as: -- // Rrx stands alone. if (*St == Rrx) return false; // Otherwise, there must be a '#' and a shift amount. ... -- to reduce the nesting. :) > + ? ?// Look for # following the shift type > + ? ?const AsmToken &HashTok = getLexer().getTok(); > + ? ?if (HashTok.isNot(AsmToken::Hash)) > + ? ? ?return Error(HashTok.getLoc(), "'#' expected"); > + ? ?getLexer().Lex(); // Eat hash token. > + > + ? ?if (getParser().ParseExpression(ShiftAmount)) > + ? ? ?return true; > + ?} > + > + ?return false; > +} > + > +// A hack to allow some testing > +unsigned ARMAsmParser::MatchRegisterName(const StringRef &Name) { > + ?if (Name == "r1") > + ? ?return 1; > + ?else if (Name == "r2") > + ? ?return 2; > + ?else if (Name == "r3") > + ? ?return 3; > + ?return 0; > +} > + > +// A hack to allow some testing > +bool ARMAsmParser::MatchInstruction(SmallVectorImpl &Operands, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?MCInst &Inst) { > + ?struct ARMOperand Op0 = Operands[0]; > + ?assert(Op0.Kind == ARMOperand::Token && "First operand not a Token"); > + ?const StringRef &Mnemonic = Op0.getToken(); > + ?if (Mnemonic == "add" || > + ? ? ?Mnemonic == "ldr") > + ? ?return false; > + > + ?return true; > +} > + > +// TODO - this is a work in progress > +bool ARMAsmParser::ParseOperand(ARMOperand &Op) { > + ?switch (getLexer().getKind()) { > + ?case AsmToken::Identifier: > + ? ?if (!ParseRegister(Op)) > + ? ? ?return false; > + ? ?// TODO parse other operands that start with an identifier > + ? ?return true; > + ?case AsmToken::LBrac: > + ? ?if (!ParseMemory(Op)) > + ? ? ?return false; > + ?default: > + ? ?return true; > + ?} > +} > + > ?bool ARMAsmParser::ParseInstruction(const StringRef &Name, MCInst &Inst) { > + ?SmallVector Operands; > + > + ?Operands.push_back(ARMOperand::CreateToken(Name)); > + > ? SMLoc Loc = getLexer().getTok().getLoc(); > - ?Error(Loc, "ARMAsmParser::ParseInstruction currently unimplemented"); > + ?if (getLexer().isNot(AsmToken::EndOfStatement)) { > + > + ? ?// Read the first operand. > + ? ?Operands.push_back(ARMOperand()); > + ? ?if (ParseOperand(Operands.back())) > + ? ? ?return true; > + > + ? ?while (getLexer().is(AsmToken::Comma)) { > + ? ? ?getLexer().Lex(); ?// Eat the comma. > + > + ? ? ?// Parse and remember the operand. > + ? ? ?Operands.push_back(ARMOperand()); > + ? ? ?if (ParseOperand(Operands.back())) > + ? ? ? ?return true; > + ? ?} > + ?} > + ?if (!MatchInstruction(Operands, Inst)) > + ? ?return false; > + > + ?Error(Loc, "ARMAsmParser::ParseInstruction only partly implemented"); > ? return true; > ?} Thanks! - Daniel From dpatel at apple.com Mon Oct 26 11:54:36 2009 From: dpatel at apple.com (Devang Patel) Date: Mon, 26 Oct 2009 16:54:36 -0000 Subject: [llvm-commits] [llvm] r85126 - in /llvm/trunk: include/llvm/Analysis/DebugInfo.h lib/Analysis/DebugInfo.cpp Message-ID: <200910261654.n9QGsapO023661@zion.cs.uiuc.edu> Author: dpatel Date: Mon Oct 26 11:54:35 2009 New Revision: 85126 URL: http://llvm.org/viewvc/llvm-project?rev=85126&view=rev Log: Add support to encode type info using llvm::Constant. Patch by Talin! Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h llvm/trunk/lib/Analysis/DebugInfo.cpp Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=85126&r1=85125&r2=85126&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Mon Oct 26 11:54:35 2009 @@ -514,6 +514,13 @@ uint64_t OffsetInBits, unsigned Flags, unsigned Encoding); + /// CreateBasicType - Create a basic type like int, float, etc. + DIBasicType CreateBasicTypeEx(DIDescriptor Context, StringRef Name, + DICompileUnit CompileUnit, unsigned LineNumber, + Constant *SizeInBits, Constant *AlignInBits, + Constant *OffsetInBits, unsigned Flags, + unsigned Encoding); + /// CreateDerivedType - Create a derived type like const qualified type, /// pointer, typedef, etc. DIDerivedType CreateDerivedType(unsigned Tag, DIDescriptor Context, @@ -524,6 +531,16 @@ uint64_t OffsetInBits, unsigned Flags, DIType DerivedFrom); + /// CreateDerivedType - Create a derived type like const qualified type, + /// pointer, typedef, etc. + DIDerivedType CreateDerivedTypeEx(unsigned Tag, DIDescriptor Context, + StringRef Name, + DICompileUnit CompileUnit, + unsigned LineNumber, + Constant *SizeInBits, Constant *AlignInBits, + Constant *OffsetInBits, unsigned Flags, + DIType DerivedFrom); + /// CreateCompositeType - Create a composite type like array, struct, etc. DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context, StringRef Name, @@ -536,6 +553,18 @@ DIArray Elements, unsigned RunTimeLang = 0); + /// CreateCompositeType - Create a composite type like array, struct, etc. + DICompositeType CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context, + StringRef Name, + DICompileUnit CompileUnit, + unsigned LineNumber, + Constant *SizeInBits, + Constant *AlignInBits, + Constant *OffsetInBits, unsigned Flags, + DIType DerivedFrom, + DIArray Elements, + unsigned RunTimeLang = 0); + /// CreateSubprogram - Create a new descriptor for the specified subprogram. /// See comments in DISubprogram for descriptions of these fields. DISubprogram CreateSubprogram(DIDescriptor Context, StringRef Name, Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=85126&r1=85125&r2=85126&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Mon Oct 26 11:54:35 2009 @@ -695,6 +695,32 @@ return DIBasicType(MDNode::get(VMContext, &Elts[0], 10)); } + +/// CreateBasicType - Create a basic type like int, float, etc. +DIBasicType DIFactory::CreateBasicTypeEx(DIDescriptor Context, + StringRef Name, + DICompileUnit CompileUnit, + unsigned LineNumber, + Constant *SizeInBits, + Constant *AlignInBits, + Constant *OffsetInBits, unsigned Flags, + unsigned Encoding) { + Value *Elts[] = { + GetTagConstant(dwarf::DW_TAG_base_type), + Context.getNode(), + MDString::get(VMContext, Name), + CompileUnit.getNode(), + ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), + SizeInBits, + AlignInBits, + OffsetInBits, + ConstantInt::get(Type::getInt32Ty(VMContext), Flags), + ConstantInt::get(Type::getInt32Ty(VMContext), Encoding) + }; + return DIBasicType(MDNode::get(VMContext, &Elts[0], 10)); +} + + /// CreateDerivedType - Create a derived type like const qualified type, /// pointer, typedef, etc. DIDerivedType DIFactory::CreateDerivedType(unsigned Tag, @@ -722,6 +748,35 @@ return DIDerivedType(MDNode::get(VMContext, &Elts[0], 10)); } + +/// CreateDerivedType - Create a derived type like const qualified type, +/// pointer, typedef, etc. +DIDerivedType DIFactory::CreateDerivedTypeEx(unsigned Tag, + DIDescriptor Context, + StringRef Name, + DICompileUnit CompileUnit, + unsigned LineNumber, + Constant *SizeInBits, + Constant *AlignInBits, + Constant *OffsetInBits, + unsigned Flags, + DIType DerivedFrom) { + Value *Elts[] = { + GetTagConstant(Tag), + Context.getNode(), + MDString::get(VMContext, Name), + CompileUnit.getNode(), + ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), + SizeInBits, + AlignInBits, + OffsetInBits, + ConstantInt::get(Type::getInt32Ty(VMContext), Flags), + DerivedFrom.getNode(), + }; + return DIDerivedType(MDNode::get(VMContext, &Elts[0], 10)); +} + + /// CreateCompositeType - Create a composite type like array, struct, etc. DICompositeType DIFactory::CreateCompositeType(unsigned Tag, DIDescriptor Context, @@ -754,6 +809,38 @@ } +/// CreateCompositeType - Create a composite type like array, struct, etc. +DICompositeType DIFactory::CreateCompositeTypeEx(unsigned Tag, + DIDescriptor Context, + StringRef Name, + DICompileUnit CompileUnit, + unsigned LineNumber, + Constant *SizeInBits, + Constant *AlignInBits, + Constant *OffsetInBits, + unsigned Flags, + DIType DerivedFrom, + DIArray Elements, + unsigned RuntimeLang) { + + Value *Elts[] = { + GetTagConstant(Tag), + Context.getNode(), + MDString::get(VMContext, Name), + CompileUnit.getNode(), + ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), + SizeInBits, + AlignInBits, + OffsetInBits, + ConstantInt::get(Type::getInt32Ty(VMContext), Flags), + DerivedFrom.getNode(), + Elements.getNode(), + ConstantInt::get(Type::getInt32Ty(VMContext), RuntimeLang) + }; + return DICompositeType(MDNode::get(VMContext, &Elts[0], 12)); +} + + /// CreateSubprogram - Create a new descriptor for the specified subprogram. /// See comments in DISubprogram for descriptions of these fields. This /// method does not unique the generated descriptors. From david_goodwin at apple.com Mon Oct 26 11:59:04 2009 From: david_goodwin at apple.com (David Goodwin) Date: Mon, 26 Oct 2009 16:59:04 -0000 Subject: [llvm-commits] [llvm] r85127 - in /llvm/trunk: include/llvm/CodeGen/AntiDepBreaker.h lib/CodeGen/CMakeLists.txt lib/CodeGen/CriticalAntiDepBreaker.cpp lib/CodeGen/CriticalAntiDepBreaker.h lib/CodeGen/PostRASchedulerList.cpp lib/Target/ARM/ARMSubtarget.h test/CodeGen/X86/break-anti-dependencies.ll Message-ID: <200910261659.n9QGx4Yj023936@zion.cs.uiuc.edu> Author: david_goodwin Date: Mon Oct 26 11:59:04 2009 New Revision: 85127 URL: http://llvm.org/viewvc/llvm-project?rev=85127&view=rev Log: Break anti-dependence breaking out into its own class. Added: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp llvm/trunk/lib/Target/ARM/ARMSubtarget.h llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll Added: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h?rev=85127&view=auto ============================================================================== --- llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h (added) +++ llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Mon Oct 26 11:59:04 2009 @@ -0,0 +1,56 @@ +//=- llvm/CodeGen/AntiDepBreaker.h - Anti-Dependence Breaking -*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the AntiDepBreaker class, which implements +// anti-dependence breaking heuristics for post-register-allocation scheduling. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_ANTIDEPBREAKER_H +#define LLVM_CODEGEN_ANTIDEPBREAKER_H + +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/Target/TargetRegisterInfo.h" + +namespace llvm { + +/// AntiDepBreaker - This class works into conjunction with the +/// post-RA scheduler to rename registers to break register +/// anti-dependencies. +class AntiDepBreaker { +public: + /// Start - Initialize anti-dep breaking for a new basic block. + virtual void StartBlock(MachineBasicBlock *BB) =0; + + /// BreakAntiDependencies - Identifiy anti-dependencies within a + /// basic-block region and break them by renaming registers. Return + /// the number of anti-dependencies broken. + /// + virtual unsigned BreakAntiDependencies(std::vector& SUnits, + MachineBasicBlock::iterator& Begin, + MachineBasicBlock::iterator& End, + unsigned InsertPosIndex) =0; + + /// Observe - Update liveness information to account for the current + /// instruction, which will not be scheduled. + /// + virtual void Observe(MachineInstr *MI, unsigned Count, + unsigned InsertPosIndex) =0; + + /// Finish - Finish anti-dep breaking for a basic block. + virtual void FinishBlock() =0; +}; + +} + +#endif Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=85127&r1=85126&r2=85127&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CMakeLists.txt (original) +++ llvm/trunk/lib/CodeGen/CMakeLists.txt Mon Oct 26 11:59:04 2009 @@ -1,6 +1,7 @@ add_llvm_library(LLVMCodeGen BranchFolding.cpp CodePlacementOpt.cpp + CriticalAntiDepBreaker.cpp DeadMachineInstructionElim.cpp DwarfEHPrepare.cpp ELFCodeEmitter.cpp Added: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp?rev=85127&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp (added) +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp Mon Oct 26 11:59:04 2009 @@ -0,0 +1,539 @@ +//===----- CriticalAntiDepBreaker.cpp - Anti-dep breaker -------- ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the CriticalAntiDepBreaker class, which +// implements register anti-dependence breaking along a blocks +// critical path during post-RA scheduler. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "critical-antidep" +#include "CriticalAntiDepBreaker.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +CriticalAntiDepBreaker:: +CriticalAntiDepBreaker(MachineFunction& MFi) : + AntiDepBreaker(), MF(MFi), + MRI(MF.getRegInfo()), + TRI(MF.getTarget().getRegisterInfo()), + AllocatableSet(TRI->getAllocatableSet(MF)) +{ +} + +CriticalAntiDepBreaker::~CriticalAntiDepBreaker() { +} + +void CriticalAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { + // Clear out the register class data. + std::fill(Classes, array_endof(Classes), + static_cast(0)); + + // Initialize the indices to indicate that no registers are live. + std::fill(KillIndices, array_endof(KillIndices), ~0u); + std::fill(DefIndices, array_endof(DefIndices), BB->size()); + + // Clear "do not change" set. + KeepRegs.clear(); + + bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn()); + + // Determine the live-out physregs for this block. + if (IsReturnBlock) { + // In a return block, examine the function live-out regs. + for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), + E = MRI.liveout_end(); I != E; ++I) { + unsigned Reg = *I; + Classes[Reg] = reinterpret_cast(-1); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = ~0u; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + Classes[AliasReg] = reinterpret_cast(-1); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = ~0u; + } + } + } else { + // In a non-return block, examine the live-in regs of all successors. + for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), + SE = BB->succ_end(); SI != SE; ++SI) + for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), + E = (*SI)->livein_end(); I != E; ++I) { + unsigned Reg = *I; + Classes[Reg] = reinterpret_cast(-1); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = ~0u; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + Classes[AliasReg] = reinterpret_cast(-1); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = ~0u; + } + } + } + + // Mark live-out callee-saved registers. In a return block this is + // all callee-saved registers. In non-return this is any + // callee-saved register that is not saved in the prolog. + const MachineFrameInfo *MFI = MF.getFrameInfo(); + BitVector Pristine = MFI->getPristineRegs(BB); + for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { + unsigned Reg = *I; + if (!IsReturnBlock && !Pristine.test(Reg)) continue; + Classes[Reg] = reinterpret_cast(-1); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = ~0u; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + Classes[AliasReg] = reinterpret_cast(-1); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = ~0u; + } + } +} + +void CriticalAntiDepBreaker::FinishBlock() { + RegRefs.clear(); + KeepRegs.clear(); +} + +void CriticalAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count, + unsigned InsertPosIndex) { + assert(Count < InsertPosIndex && "Instruction index out of expected range!"); + + // Any register which was defined within the previous scheduling region + // may have been rescheduled and its lifetime may overlap with registers + // in ways not reflected in our current liveness state. For each such + // register, adjust the liveness state to be conservatively correct. + for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) + if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) { + assert(KillIndices[Reg] == ~0u && "Clobbered register is live!"); + // Mark this register to be non-renamable. + Classes[Reg] = reinterpret_cast(-1); + // Move the def index to the end of the previous region, to reflect + // that the def could theoretically have been scheduled at the end. + DefIndices[Reg] = InsertPosIndex; + } + + PrescanInstruction(MI); + ScanInstruction(MI, Count); +} + +/// CriticalPathStep - Return the next SUnit after SU on the bottom-up +/// critical path. +static SDep *CriticalPathStep(SUnit *SU) { + SDep *Next = 0; + unsigned NextDepth = 0; + // Find the predecessor edge with the greatest depth. + for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end(); + P != PE; ++P) { + SUnit *PredSU = P->getSUnit(); + unsigned PredLatency = P->getLatency(); + unsigned PredTotalLatency = PredSU->getDepth() + PredLatency; + // In the case of a latency tie, prefer an anti-dependency edge over + // other types of edges. + if (NextDepth < PredTotalLatency || + (NextDepth == PredTotalLatency && P->getKind() == SDep::Anti)) { + NextDepth = PredTotalLatency; + Next = &*P; + } + } + return Next; +} + +void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr *MI) { + // Scan the register operands for this instruction and update + // Classes and RegRefs. + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + const TargetRegisterClass *NewRC = 0; + + if (i < MI->getDesc().getNumOperands()) + NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); + + // For now, only allow the register to be changed if its register + // class is consistent across all uses. + if (!Classes[Reg] && NewRC) + Classes[Reg] = NewRC; + else if (!NewRC || Classes[Reg] != NewRC) + Classes[Reg] = reinterpret_cast(-1); + + // Now check for aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + // If an alias of the reg is used during the live range, give up. + // Note that this allows us to skip checking if AntiDepReg + // overlaps with any of the aliases, among other things. + unsigned AliasReg = *Alias; + if (Classes[AliasReg]) { + Classes[AliasReg] = reinterpret_cast(-1); + Classes[Reg] = reinterpret_cast(-1); + } + } + + // If we're still willing to consider this register, note the reference. + if (Classes[Reg] != reinterpret_cast(-1)) + RegRefs.insert(std::make_pair(Reg, &MO)); + + // It's not safe to change register allocation for source operands of + // that have special allocation requirements. + if (MO.isUse() && MI->getDesc().hasExtraSrcRegAllocReq()) { + if (KeepRegs.insert(Reg)) { + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); + *Subreg; ++Subreg) + KeepRegs.insert(*Subreg); + } + } + } +} + +void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI, + unsigned Count) { + // Update liveness. + // Proceding upwards, registers that are defed but not used in this + // instruction are now dead. + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + if (!MO.isDef()) continue; + // Ignore two-addr defs. + if (MI->isRegTiedToUseOperand(i)) continue; + + DefIndices[Reg] = Count; + KillIndices[Reg] = ~0u; + assert(((KillIndices[Reg] == ~0u) != + (DefIndices[Reg] == ~0u)) && + "Kill and Def maps aren't consistent for Reg!"); + KeepRegs.erase(Reg); + Classes[Reg] = 0; + RegRefs.erase(Reg); + // Repeat, for all subregs. + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); + *Subreg; ++Subreg) { + unsigned SubregReg = *Subreg; + DefIndices[SubregReg] = Count; + KillIndices[SubregReg] = ~0u; + KeepRegs.erase(SubregReg); + Classes[SubregReg] = 0; + RegRefs.erase(SubregReg); + } + // Conservatively mark super-registers as unusable. + for (const unsigned *Super = TRI->getSuperRegisters(Reg); + *Super; ++Super) { + unsigned SuperReg = *Super; + Classes[SuperReg] = reinterpret_cast(-1); + } + } + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + if (!MO.isUse()) continue; + + const TargetRegisterClass *NewRC = 0; + if (i < MI->getDesc().getNumOperands()) + NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); + + // For now, only allow the register to be changed if its register + // class is consistent across all uses. + if (!Classes[Reg] && NewRC) + Classes[Reg] = NewRC; + else if (!NewRC || Classes[Reg] != NewRC) + Classes[Reg] = reinterpret_cast(-1); + + RegRefs.insert(std::make_pair(Reg, &MO)); + + // It wasn't previously live but now it is, this is a kill. + if (KillIndices[Reg] == ~0u) { + KillIndices[Reg] = Count; + DefIndices[Reg] = ~0u; + assert(((KillIndices[Reg] == ~0u) != + (DefIndices[Reg] == ~0u)) && + "Kill and Def maps aren't consistent for Reg!"); + } + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + if (KillIndices[AliasReg] == ~0u) { + KillIndices[AliasReg] = Count; + DefIndices[AliasReg] = ~0u; + } + } + } +} + +unsigned +CriticalAntiDepBreaker::findSuitableFreeRegister(unsigned AntiDepReg, + unsigned LastNewReg, + const TargetRegisterClass *RC) { + for (TargetRegisterClass::iterator R = RC->allocation_order_begin(MF), + RE = RC->allocation_order_end(MF); R != RE; ++R) { + unsigned NewReg = *R; + // Don't replace a register with itself. + if (NewReg == AntiDepReg) continue; + // Don't replace a register with one that was recently used to repair + // an anti-dependence with this AntiDepReg, because that would + // re-introduce that anti-dependence. + if (NewReg == LastNewReg) continue; + // If NewReg is dead and NewReg's most recent def is not before + // AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg. + assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u)) && + "Kill and Def maps aren't consistent for AntiDepReg!"); + assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u)) && + "Kill and Def maps aren't consistent for NewReg!"); + if (KillIndices[NewReg] != ~0u || + Classes[NewReg] == reinterpret_cast(-1) || + KillIndices[AntiDepReg] > DefIndices[NewReg]) + continue; + return NewReg; + } + + // No registers are free and available! + return 0; +} + +unsigned CriticalAntiDepBreaker:: +BreakAntiDependencies(std::vector& SUnits, + MachineBasicBlock::iterator& Begin, + MachineBasicBlock::iterator& End, + unsigned InsertPosIndex) { + // The code below assumes that there is at least one instruction, + // so just duck out immediately if the block is empty. + if (SUnits.empty()) return 0; + + // Find the node at the bottom of the critical path. + SUnit *Max = 0; + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { + SUnit *SU = &SUnits[i]; + if (!Max || SU->getDepth() + SU->Latency > Max->getDepth() + Max->Latency) + Max = SU; + } + +#ifndef NDEBUG + { + DEBUG(errs() << "Critical path has total latency " + << (Max->getDepth() + Max->Latency) << "\n"); + DEBUG(errs() << "Available regs:"); + for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { + if (KillIndices[Reg] == ~0u) + DEBUG(errs() << " " << TRI->getName(Reg)); + } + DEBUG(errs() << '\n'); + } +#endif + + // Track progress along the critical path through the SUnit graph as we walk + // the instructions. + SUnit *CriticalPathSU = Max; + MachineInstr *CriticalPathMI = CriticalPathSU->getInstr(); + + // Consider this pattern: + // A = ... + // ... = A + // A = ... + // ... = A + // A = ... + // ... = A + // A = ... + // ... = A + // There are three anti-dependencies here, and without special care, + // we'd break all of them using the same register: + // A = ... + // ... = A + // B = ... + // ... = B + // B = ... + // ... = B + // B = ... + // ... = B + // because at each anti-dependence, B is the first register that + // isn't A which is free. This re-introduces anti-dependencies + // at all but one of the original anti-dependencies that we were + // trying to break. To avoid this, keep track of the most recent + // register that each register was replaced with, avoid + // using it to repair an anti-dependence on the same register. + // This lets us produce this: + // A = ... + // ... = A + // B = ... + // ... = B + // C = ... + // ... = C + // B = ... + // ... = B + // This still has an anti-dependence on B, but at least it isn't on the + // original critical path. + // + // TODO: If we tracked more than one register here, we could potentially + // fix that remaining critical edge too. This is a little more involved, + // because unlike the most recent register, less recent registers should + // still be considered, though only if no other registers are available. + unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = {}; + + // Attempt to break anti-dependence edges on the critical path. Walk the + // instructions from the bottom up, tracking information about liveness + // as we go to help determine which registers are available. + unsigned Broken = 0; + unsigned Count = InsertPosIndex - 1; + for (MachineBasicBlock::iterator I = End, E = Begin; + I != E; --Count) { + MachineInstr *MI = --I; + + // Check if this instruction has a dependence on the critical path that + // is an anti-dependence that we may be able to break. If it is, set + // AntiDepReg to the non-zero register associated with the anti-dependence. + // + // We limit our attention to the critical path as a heuristic to avoid + // breaking anti-dependence edges that aren't going to significantly + // impact the overall schedule. There are a limited number of registers + // and we want to save them for the important edges. + // + // TODO: Instructions with multiple defs could have multiple + // anti-dependencies. The current code here only knows how to break one + // edge per instruction. Note that we'd have to be able to break all of + // the anti-dependencies in an instruction in order to be effective. + unsigned AntiDepReg = 0; + if (MI == CriticalPathMI) { + if (SDep *Edge = CriticalPathStep(CriticalPathSU)) { + SUnit *NextSU = Edge->getSUnit(); + + // Only consider anti-dependence edges. + if (Edge->getKind() == SDep::Anti) { + AntiDepReg = Edge->getReg(); + assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); + if (!AllocatableSet.test(AntiDepReg)) + // Don't break anti-dependencies on non-allocatable registers. + AntiDepReg = 0; + else if (KeepRegs.count(AntiDepReg)) + // Don't break anti-dependencies if an use down below requires + // this exact register. + AntiDepReg = 0; + else { + // If the SUnit has other dependencies on the SUnit that it + // anti-depends on, don't bother breaking the anti-dependency + // since those edges would prevent such units from being + // scheduled past each other regardless. + // + // Also, if there are dependencies on other SUnits with the + // same register as the anti-dependency, don't attempt to + // break it. + for (SUnit::pred_iterator P = CriticalPathSU->Preds.begin(), + PE = CriticalPathSU->Preds.end(); P != PE; ++P) + if (P->getSUnit() == NextSU ? + (P->getKind() != SDep::Anti || P->getReg() != AntiDepReg) : + (P->getKind() == SDep::Data && P->getReg() == AntiDepReg)) { + AntiDepReg = 0; + break; + } + } + } + CriticalPathSU = NextSU; + CriticalPathMI = CriticalPathSU->getInstr(); + } else { + // We've reached the end of the critical path. + CriticalPathSU = 0; + CriticalPathMI = 0; + } + } + + PrescanInstruction(MI); + + if (MI->getDesc().hasExtraDefRegAllocReq()) + // If this instruction's defs have special allocation requirement, don't + // break this anti-dependency. + AntiDepReg = 0; + else if (AntiDepReg) { + // If this instruction has a use of AntiDepReg, breaking it + // is invalid. + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + if (MO.isUse() && AntiDepReg == Reg) { + AntiDepReg = 0; + break; + } + } + } + + // Determine AntiDepReg's register class, if it is live and is + // consistently used within a single class. + const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes[AntiDepReg] : 0; + assert((AntiDepReg == 0 || RC != NULL) && + "Register should be live if it's causing an anti-dependence!"); + if (RC == reinterpret_cast(-1)) + AntiDepReg = 0; + + // Look for a suitable register to use to break the anti-depenence. + // + // TODO: Instead of picking the first free register, consider which might + // be the best. + if (AntiDepReg != 0) { + if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg, + LastNewReg[AntiDepReg], + RC)) { + DEBUG(errs() << "Breaking anti-dependence edge on " + << TRI->getName(AntiDepReg) + << " with " << RegRefs.count(AntiDepReg) << " references" + << " using " << TRI->getName(NewReg) << "!\n"); + + // Update the references to the old register to refer to the new + // register. + std::pair::iterator, + std::multimap::iterator> + Range = RegRefs.equal_range(AntiDepReg); + for (std::multimap::iterator + Q = Range.first, QE = Range.second; Q != QE; ++Q) + Q->second->setReg(NewReg); + + // We just went back in time and modified history; the + // liveness information for the anti-depenence reg is now + // inconsistent. Set the state as if it were dead. + Classes[NewReg] = Classes[AntiDepReg]; + DefIndices[NewReg] = DefIndices[AntiDepReg]; + KillIndices[NewReg] = KillIndices[AntiDepReg]; + assert(((KillIndices[NewReg] == ~0u) != + (DefIndices[NewReg] == ~0u)) && + "Kill and Def maps aren't consistent for NewReg!"); + + Classes[AntiDepReg] = 0; + DefIndices[AntiDepReg] = KillIndices[AntiDepReg]; + KillIndices[AntiDepReg] = ~0u; + assert(((KillIndices[AntiDepReg] == ~0u) != + (DefIndices[AntiDepReg] == ~0u)) && + "Kill and Def maps aren't consistent for AntiDepReg!"); + + RegRefs.erase(AntiDepReg); + LastNewReg[AntiDepReg] = NewReg; + ++Broken; + } + } + + ScanInstruction(MI, Count); + } + + return Broken; +} Added: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h?rev=85127&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h (added) +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h Mon Oct 26 11:59:04 2009 @@ -0,0 +1,95 @@ +//=- llvm/CodeGen/CriticalAntiDepBreaker.h - Anti-Dep Support -*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the CriticalAntiDepBreaker class, which +// implements register anti-dependence breaking along a blocks +// critical path during post-RA scheduler. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H +#define LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H + +#include "llvm/CodeGen/AntiDepBreaker.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/SmallSet.h" + +namespace llvm { + class CriticalAntiDepBreaker : public AntiDepBreaker { + MachineFunction& MF; + MachineRegisterInfo &MRI; + const TargetRegisterInfo *TRI; + + /// AllocatableSet - The set of allocatable registers. + /// We'll be ignoring anti-dependencies on non-allocatable registers, + /// because they may not be safe to break. + const BitVector AllocatableSet; + + /// Classes - For live regs that are only used in one register class in a + /// live range, the register class. If the register is not live, the + /// corresponding value is null. If the register is live but used in + /// multiple register classes, the corresponding value is -1 casted to a + /// pointer. + const TargetRegisterClass * + Classes[TargetRegisterInfo::FirstVirtualRegister]; + + /// RegRegs - Map registers to all their references within a live range. + std::multimap RegRefs; + + /// KillIndices - The index of the most recent kill (proceding bottom-up), + /// or ~0u if the register is not live. + unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; + + /// DefIndices - The index of the most recent complete def (proceding bottom + /// up), or ~0u if the register is live. + unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; + + /// KeepRegs - A set of registers which are live and cannot be changed to + /// break anti-dependencies. + SmallSet KeepRegs; + + public: + CriticalAntiDepBreaker(MachineFunction& MFi); + ~CriticalAntiDepBreaker(); + + /// Start - Initialize anti-dep breaking for a new basic block. + void StartBlock(MachineBasicBlock *BB); + + /// BreakAntiDependencies - Identifiy anti-dependencies along the critical path + /// of the ScheduleDAG and break them by renaming registers. + /// + unsigned BreakAntiDependencies(std::vector& SUnits, + MachineBasicBlock::iterator& Begin, + MachineBasicBlock::iterator& End, + unsigned InsertPosIndex); + + /// Observe - Update liveness information to account for the current + /// instruction, which will not be scheduled. + /// + void Observe(MachineInstr *MI, unsigned Count, unsigned InsertPosIndex); + + /// Finish - Finish anti-dep breaking for a basic block. + void FinishBlock(); + + private: + void PrescanInstruction(MachineInstr *MI); + void ScanInstruction(MachineInstr *MI, unsigned Count); + unsigned findSuitableFreeRegister(unsigned AntiDepReg, + unsigned LastNewReg, + const TargetRegisterClass *); + }; +} + +#endif Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=85127&r1=85126&r2=85127&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Mon Oct 26 11:59:04 2009 @@ -19,6 +19,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "post-RA-sched" +#include "CriticalAntiDepBreaker.h" #include "ExactHazardRecognizer.h" #include "SimpleHazardRecognizer.h" #include "ScheduleDAGInstrs.h" @@ -40,6 +41,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/Statistic.h" #include #include @@ -47,6 +49,7 @@ STATISTIC(NumNoops, "Number of noops inserted"); STATISTIC(NumStalls, "Number of pipeline stalls"); +STATISTIC(NumFixedAnti, "Number of fixed anti-dependencies"); // Post-RA scheduling is enabled with // TargetSubtarget.enablePostRAScheduler(). This flag can be used to @@ -55,10 +58,11 @@ EnablePostRAScheduler("post-RA-scheduler", cl::desc("Enable scheduling after register allocation"), cl::init(false), cl::Hidden); -static cl::opt +static cl::opt EnableAntiDepBreaking("break-anti-dependencies", - cl::desc("Break post-RA scheduling anti-dependencies"), - cl::init(true), cl::Hidden); + cl::desc("Break post-RA scheduling anti-dependencies: " + "\"critical\", \"all\", or \"none\""), + cl::init("none"), cl::Hidden); static cl::opt EnablePostRAHazardAvoidance("avoid-hazards", cl::desc("Enable exact hazard avoidance"), @@ -116,56 +120,30 @@ /// Topo - A topological ordering for SUnits. ScheduleDAGTopologicalSort Topo; - /// AllocatableSet - The set of allocatable registers. - /// We'll be ignoring anti-dependencies on non-allocatable registers, - /// because they may not be safe to break. - const BitVector AllocatableSet; - /// HazardRec - The hazard recognizer to use. ScheduleHazardRecognizer *HazardRec; + /// AntiDepBreak - Anti-dependence breaking object, or NULL if none + AntiDepBreaker *AntiDepBreak; + /// AA - AliasAnalysis for making memory reference queries. AliasAnalysis *AA; - /// AntiDepMode - Anti-dependence breaking mode - TargetSubtarget::AntiDepBreakMode AntiDepMode; - - /// Classes - For live regs that are only used in one register class in a - /// live range, the register class. If the register is not live, the - /// corresponding value is null. If the register is live but used in - /// multiple register classes, the corresponding value is -1 casted to a - /// pointer. - const TargetRegisterClass * - Classes[TargetRegisterInfo::FirstVirtualRegister]; - - /// RegRegs - Map registers to all their references within a live range. - std::multimap RegRefs; - /// KillIndices - The index of the most recent kill (proceding bottom-up), /// or ~0u if the register is not live. unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; - /// DefIndices - The index of the most recent complete def (proceding bottom - /// up), or ~0u if the register is live. - unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; - - /// KeepRegs - A set of registers which are live and cannot be changed to - /// break anti-dependencies. - SmallSet KeepRegs; - public: SchedulePostRATDList(MachineFunction &MF, const MachineLoopInfo &MLI, const MachineDominatorTree &MDT, ScheduleHazardRecognizer *HR, - AliasAnalysis *aa, - TargetSubtarget::AntiDepBreakMode adm) + AntiDepBreaker *ADB, + AliasAnalysis *aa) : ScheduleDAGInstrs(MF, MLI, MDT), Topo(SUnits), - AllocatableSet(TRI->getAllocatableSet(MF)), - HazardRec(HR), AA(aa), AntiDepMode(adm) {} + HazardRec(HR), AntiDepBreak(ADB), AA(aa) {} ~SchedulePostRATDList() { - delete HazardRec; } /// StartBlock - Initialize register live-range state for scheduling in @@ -177,11 +155,6 @@ /// void Schedule(); - /// FixupKills - Fix register kill flags that have been made - /// invalid due to scheduling - /// - void FixupKills(MachineBasicBlock *MBB); - /// Observe - Update liveness information to account for the current /// instruction, which will not be scheduled. /// @@ -191,17 +164,16 @@ /// void FinishBlock(); + /// FixupKills - Fix register kill flags that have been made + /// invalid due to scheduling + /// + void FixupKills(MachineBasicBlock *MBB); + private: - void PrescanInstruction(MachineInstr *MI); - void ScanInstruction(MachineInstr *MI, unsigned Count); void ReleaseSucc(SUnit *SU, SDep *SuccEdge); void ReleaseSuccessors(SUnit *SU); void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); void ListScheduleTopDown(); - bool BreakAntiDependencies(); - unsigned findSuitableFreeRegister(unsigned AntiDepReg, - unsigned LastNewReg, - const TargetRegisterClass *); void StartBlockForKills(MachineBasicBlock *BB); // ToggleKillFlag - Toggle a register operand kill flag. Other @@ -250,8 +222,9 @@ // Check for antidep breaking override... if (EnableAntiDepBreaking.getPosition() > 0) { - AntiDepMode = (EnableAntiDepBreaking) ? - TargetSubtarget::ANTIDEP_CRITICAL : TargetSubtarget::ANTIDEP_NONE; + AntiDepMode = (EnableAntiDepBreaking == "all") ? TargetSubtarget::ANTIDEP_ALL : + (EnableAntiDepBreaking == "critical") ? TargetSubtarget::ANTIDEP_CRITICAL : + TargetSubtarget::ANTIDEP_NONE; } DEBUG(errs() << "PostRAScheduler\n"); @@ -262,8 +235,12 @@ ScheduleHazardRecognizer *HR = EnablePostRAHazardAvoidance ? (ScheduleHazardRecognizer *)new ExactHazardRecognizer(InstrItins) : (ScheduleHazardRecognizer *)new SimpleHazardRecognizer(); + AntiDepBreaker *ADB = + (AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? NULL /* FIXME */ : + (AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? + new CriticalAntiDepBreaker(Fn) : NULL; - SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, AA, AntiDepMode); + SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, ADB, AA); // Loop over all of the basic blocks for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); @@ -311,6 +288,9 @@ Scheduler.FixupKills(MBB); } + delete HR; + delete ADB; + return true; } @@ -321,78 +301,10 @@ // Call the superclass. ScheduleDAGInstrs::StartBlock(BB); - // Reset the hazard recognizer. + // Reset the hazard recognizer and anti-dep breaker. HazardRec->Reset(); - - // Clear out the register class data. - std::fill(Classes, array_endof(Classes), - static_cast(0)); - - // Initialize the indices to indicate that no registers are live. - std::fill(KillIndices, array_endof(KillIndices), ~0u); - std::fill(DefIndices, array_endof(DefIndices), BB->size()); - - // Clear "do not change" set. - KeepRegs.clear(); - - bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn()); - - // Determine the live-out physregs for this block. - if (IsReturnBlock) { - // In a return block, examine the function live-out regs. - for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), - E = MRI.liveout_end(); I != E; ++I) { - unsigned Reg = *I; - Classes[Reg] = reinterpret_cast(-1); - KillIndices[Reg] = BB->size(); - DefIndices[Reg] = ~0u; - // Repeat, for all aliases. - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - unsigned AliasReg = *Alias; - Classes[AliasReg] = reinterpret_cast(-1); - KillIndices[AliasReg] = BB->size(); - DefIndices[AliasReg] = ~0u; - } - } - } else { - // In a non-return block, examine the live-in regs of all successors. - for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), - SE = BB->succ_end(); SI != SE; ++SI) - for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), - E = (*SI)->livein_end(); I != E; ++I) { - unsigned Reg = *I; - Classes[Reg] = reinterpret_cast(-1); - KillIndices[Reg] = BB->size(); - DefIndices[Reg] = ~0u; - // Repeat, for all aliases. - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - unsigned AliasReg = *Alias; - Classes[AliasReg] = reinterpret_cast(-1); - KillIndices[AliasReg] = BB->size(); - DefIndices[AliasReg] = ~0u; - } - } - } - - // Mark live-out callee-saved registers. In a return block this is - // all callee-saved registers. In non-return this is any - // callee-saved register that is not saved in the prolog. - const MachineFrameInfo *MFI = MF.getFrameInfo(); - BitVector Pristine = MFI->getPristineRegs(BB); - for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { - unsigned Reg = *I; - if (!IsReturnBlock && !Pristine.test(Reg)) continue; - Classes[Reg] = reinterpret_cast(-1); - KillIndices[Reg] = BB->size(); - DefIndices[Reg] = ~0u; - // Repeat, for all aliases. - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - unsigned AliasReg = *Alias; - Classes[AliasReg] = reinterpret_cast(-1); - KillIndices[AliasReg] = BB->size(); - DefIndices[AliasReg] = ~0u; - } - } + if (AntiDepBreak != NULL) + AntiDepBreak->StartBlock(BB); } /// Schedule - Schedule the instruction range using list scheduling. @@ -403,8 +315,11 @@ // Build the scheduling graph. BuildSchedGraph(AA); - if (AntiDepMode != TargetSubtarget::ANTIDEP_NONE) { - if (BreakAntiDependencies()) { + if (AntiDepBreak != NULL) { + unsigned Broken = + AntiDepBreak->BreakAntiDependencies(SUnits, Begin, InsertPos, + InsertPosIndex); + if (Broken > 0) { // We made changes. Update the dependency graph. // Theoretically we could update the graph in place: // When a live range is changed to use a different register, remove @@ -415,6 +330,8 @@ EntrySU = SUnit(); ExitSU = SUnit(); BuildSchedGraph(AA); + + NumFixedAnti += Broken; } } @@ -432,436 +349,20 @@ /// instruction, which will not be scheduled. /// void SchedulePostRATDList::Observe(MachineInstr *MI, unsigned Count) { - assert(Count < InsertPosIndex && "Instruction index out of expected range!"); - - // Any register which was defined within the previous scheduling region - // may have been rescheduled and its lifetime may overlap with registers - // in ways not reflected in our current liveness state. For each such - // register, adjust the liveness state to be conservatively correct. - for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) - if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) { - assert(KillIndices[Reg] == ~0u && "Clobbered register is live!"); - // Mark this register to be non-renamable. - Classes[Reg] = reinterpret_cast(-1); - // Move the def index to the end of the previous region, to reflect - // that the def could theoretically have been scheduled at the end. - DefIndices[Reg] = InsertPosIndex; - } - - PrescanInstruction(MI); - ScanInstruction(MI, Count); + if (AntiDepBreak != NULL) + AntiDepBreak->Observe(MI, Count, InsertPosIndex); } /// FinishBlock - Clean up register live-range state. /// void SchedulePostRATDList::FinishBlock() { - RegRefs.clear(); + if (AntiDepBreak != NULL) + AntiDepBreak->FinishBlock(); // Call the superclass. ScheduleDAGInstrs::FinishBlock(); } -/// CriticalPathStep - Return the next SUnit after SU on the bottom-up -/// critical path. -static SDep *CriticalPathStep(SUnit *SU) { - SDep *Next = 0; - unsigned NextDepth = 0; - // Find the predecessor edge with the greatest depth. - for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end(); - P != PE; ++P) { - SUnit *PredSU = P->getSUnit(); - unsigned PredLatency = P->getLatency(); - unsigned PredTotalLatency = PredSU->getDepth() + PredLatency; - // In the case of a latency tie, prefer an anti-dependency edge over - // other types of edges. - if (NextDepth < PredTotalLatency || - (NextDepth == PredTotalLatency && P->getKind() == SDep::Anti)) { - NextDepth = PredTotalLatency; - Next = &*P; - } - } - return Next; -} - -void SchedulePostRATDList::PrescanInstruction(MachineInstr *MI) { - // Scan the register operands for this instruction and update - // Classes and RegRefs. - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg()) continue; - unsigned Reg = MO.getReg(); - if (Reg == 0) continue; - const TargetRegisterClass *NewRC = 0; - - if (i < MI->getDesc().getNumOperands()) - NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); - - // For now, only allow the register to be changed if its register - // class is consistent across all uses. - if (!Classes[Reg] && NewRC) - Classes[Reg] = NewRC; - else if (!NewRC || Classes[Reg] != NewRC) - Classes[Reg] = reinterpret_cast(-1); - - // Now check for aliases. - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - // If an alias of the reg is used during the live range, give up. - // Note that this allows us to skip checking if AntiDepReg - // overlaps with any of the aliases, among other things. - unsigned AliasReg = *Alias; - if (Classes[AliasReg]) { - Classes[AliasReg] = reinterpret_cast(-1); - Classes[Reg] = reinterpret_cast(-1); - } - } - - // If we're still willing to consider this register, note the reference. - if (Classes[Reg] != reinterpret_cast(-1)) - RegRefs.insert(std::make_pair(Reg, &MO)); - - // It's not safe to change register allocation for source operands of - // that have special allocation requirements. - if (MO.isUse() && MI->getDesc().hasExtraSrcRegAllocReq()) { - if (KeepRegs.insert(Reg)) { - for (const unsigned *Subreg = TRI->getSubRegisters(Reg); - *Subreg; ++Subreg) - KeepRegs.insert(*Subreg); - } - } - } -} - -void SchedulePostRATDList::ScanInstruction(MachineInstr *MI, - unsigned Count) { - // Update liveness. - // Proceding upwards, registers that are defed but not used in this - // instruction are now dead. - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg()) continue; - unsigned Reg = MO.getReg(); - if (Reg == 0) continue; - if (!MO.isDef()) continue; - // Ignore two-addr defs. - if (MI->isRegTiedToUseOperand(i)) continue; - - DefIndices[Reg] = Count; - KillIndices[Reg] = ~0u; - assert(((KillIndices[Reg] == ~0u) != - (DefIndices[Reg] == ~0u)) && - "Kill and Def maps aren't consistent for Reg!"); - KeepRegs.erase(Reg); - Classes[Reg] = 0; - RegRefs.erase(Reg); - // Repeat, for all subregs. - for (const unsigned *Subreg = TRI->getSubRegisters(Reg); - *Subreg; ++Subreg) { - unsigned SubregReg = *Subreg; - DefIndices[SubregReg] = Count; - KillIndices[SubregReg] = ~0u; - KeepRegs.erase(SubregReg); - Classes[SubregReg] = 0; - RegRefs.erase(SubregReg); - } - // Conservatively mark super-registers as unusable. - for (const unsigned *Super = TRI->getSuperRegisters(Reg); - *Super; ++Super) { - unsigned SuperReg = *Super; - Classes[SuperReg] = reinterpret_cast(-1); - } - } - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg()) continue; - unsigned Reg = MO.getReg(); - if (Reg == 0) continue; - if (!MO.isUse()) continue; - - const TargetRegisterClass *NewRC = 0; - if (i < MI->getDesc().getNumOperands()) - NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); - - // For now, only allow the register to be changed if its register - // class is consistent across all uses. - if (!Classes[Reg] && NewRC) - Classes[Reg] = NewRC; - else if (!NewRC || Classes[Reg] != NewRC) - Classes[Reg] = reinterpret_cast(-1); - - RegRefs.insert(std::make_pair(Reg, &MO)); - - // It wasn't previously live but now it is, this is a kill. - if (KillIndices[Reg] == ~0u) { - KillIndices[Reg] = Count; - DefIndices[Reg] = ~0u; - assert(((KillIndices[Reg] == ~0u) != - (DefIndices[Reg] == ~0u)) && - "Kill and Def maps aren't consistent for Reg!"); - } - // Repeat, for all aliases. - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - unsigned AliasReg = *Alias; - if (KillIndices[AliasReg] == ~0u) { - KillIndices[AliasReg] = Count; - DefIndices[AliasReg] = ~0u; - } - } - } -} - -unsigned -SchedulePostRATDList::findSuitableFreeRegister(unsigned AntiDepReg, - unsigned LastNewReg, - const TargetRegisterClass *RC) { - for (TargetRegisterClass::iterator R = RC->allocation_order_begin(MF), - RE = RC->allocation_order_end(MF); R != RE; ++R) { - unsigned NewReg = *R; - // Don't replace a register with itself. - if (NewReg == AntiDepReg) continue; - // Don't replace a register with one that was recently used to repair - // an anti-dependence with this AntiDepReg, because that would - // re-introduce that anti-dependence. - if (NewReg == LastNewReg) continue; - // If NewReg is dead and NewReg's most recent def is not before - // AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg. - assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u)) && - "Kill and Def maps aren't consistent for AntiDepReg!"); - assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u)) && - "Kill and Def maps aren't consistent for NewReg!"); - if (KillIndices[NewReg] != ~0u || - Classes[NewReg] == reinterpret_cast(-1) || - KillIndices[AntiDepReg] > DefIndices[NewReg]) - continue; - return NewReg; - } - - // No registers are free and available! - return 0; -} - -/// BreakAntiDependencies - Identifiy anti-dependencies along the critical path -/// of the ScheduleDAG and break them by renaming registers. -/// -bool SchedulePostRATDList::BreakAntiDependencies() { - // The code below assumes that there is at least one instruction, - // so just duck out immediately if the block is empty. - if (SUnits.empty()) return false; - - // Find the node at the bottom of the critical path. - SUnit *Max = 0; - for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { - SUnit *SU = &SUnits[i]; - if (!Max || SU->getDepth() + SU->Latency > Max->getDepth() + Max->Latency) - Max = SU; - } - -#ifndef NDEBUG - { - DEBUG(errs() << "Critical path has total latency " - << (Max->getDepth() + Max->Latency) << "\n"); - DEBUG(errs() << "Available regs:"); - for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { - if (KillIndices[Reg] == ~0u) - DEBUG(errs() << " " << TRI->getName(Reg)); - } - DEBUG(errs() << '\n'); - } -#endif - - // Track progress along the critical path through the SUnit graph as we walk - // the instructions. - SUnit *CriticalPathSU = Max; - MachineInstr *CriticalPathMI = CriticalPathSU->getInstr(); - - // Consider this pattern: - // A = ... - // ... = A - // A = ... - // ... = A - // A = ... - // ... = A - // A = ... - // ... = A - // There are three anti-dependencies here, and without special care, - // we'd break all of them using the same register: - // A = ... - // ... = A - // B = ... - // ... = B - // B = ... - // ... = B - // B = ... - // ... = B - // because at each anti-dependence, B is the first register that - // isn't A which is free. This re-introduces anti-dependencies - // at all but one of the original anti-dependencies that we were - // trying to break. To avoid this, keep track of the most recent - // register that each register was replaced with, avoid - // using it to repair an anti-dependence on the same register. - // This lets us produce this: - // A = ... - // ... = A - // B = ... - // ... = B - // C = ... - // ... = C - // B = ... - // ... = B - // This still has an anti-dependence on B, but at least it isn't on the - // original critical path. - // - // TODO: If we tracked more than one register here, we could potentially - // fix that remaining critical edge too. This is a little more involved, - // because unlike the most recent register, less recent registers should - // still be considered, though only if no other registers are available. - unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = {}; - - // Attempt to break anti-dependence edges on the critical path. Walk the - // instructions from the bottom up, tracking information about liveness - // as we go to help determine which registers are available. - bool Changed = false; - unsigned Count = InsertPosIndex - 1; - for (MachineBasicBlock::iterator I = InsertPos, E = Begin; - I != E; --Count) { - MachineInstr *MI = --I; - - // Check if this instruction has a dependence on the critical path that - // is an anti-dependence that we may be able to break. If it is, set - // AntiDepReg to the non-zero register associated with the anti-dependence. - // - // We limit our attention to the critical path as a heuristic to avoid - // breaking anti-dependence edges that aren't going to significantly - // impact the overall schedule. There are a limited number of registers - // and we want to save them for the important edges. - // - // TODO: Instructions with multiple defs could have multiple - // anti-dependencies. The current code here only knows how to break one - // edge per instruction. Note that we'd have to be able to break all of - // the anti-dependencies in an instruction in order to be effective. - unsigned AntiDepReg = 0; - if (MI == CriticalPathMI) { - if (SDep *Edge = CriticalPathStep(CriticalPathSU)) { - SUnit *NextSU = Edge->getSUnit(); - - // Only consider anti-dependence edges. - if (Edge->getKind() == SDep::Anti) { - AntiDepReg = Edge->getReg(); - assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); - if (!AllocatableSet.test(AntiDepReg)) - // Don't break anti-dependencies on non-allocatable registers. - AntiDepReg = 0; - else if (KeepRegs.count(AntiDepReg)) - // Don't break anti-dependencies if an use down below requires - // this exact register. - AntiDepReg = 0; - else { - // If the SUnit has other dependencies on the SUnit that it - // anti-depends on, don't bother breaking the anti-dependency - // since those edges would prevent such units from being - // scheduled past each other regardless. - // - // Also, if there are dependencies on other SUnits with the - // same register as the anti-dependency, don't attempt to - // break it. - for (SUnit::pred_iterator P = CriticalPathSU->Preds.begin(), - PE = CriticalPathSU->Preds.end(); P != PE; ++P) - if (P->getSUnit() == NextSU ? - (P->getKind() != SDep::Anti || P->getReg() != AntiDepReg) : - (P->getKind() == SDep::Data && P->getReg() == AntiDepReg)) { - AntiDepReg = 0; - break; - } - } - } - CriticalPathSU = NextSU; - CriticalPathMI = CriticalPathSU->getInstr(); - } else { - // We've reached the end of the critical path. - CriticalPathSU = 0; - CriticalPathMI = 0; - } - } - - PrescanInstruction(MI); - - if (MI->getDesc().hasExtraDefRegAllocReq()) - // If this instruction's defs have special allocation requirement, don't - // break this anti-dependency. - AntiDepReg = 0; - else if (AntiDepReg) { - // If this instruction has a use of AntiDepReg, breaking it - // is invalid. - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg()) continue; - unsigned Reg = MO.getReg(); - if (Reg == 0) continue; - if (MO.isUse() && AntiDepReg == Reg) { - AntiDepReg = 0; - break; - } - } - } - - // Determine AntiDepReg's register class, if it is live and is - // consistently used within a single class. - const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes[AntiDepReg] : 0; - assert((AntiDepReg == 0 || RC != NULL) && - "Register should be live if it's causing an anti-dependence!"); - if (RC == reinterpret_cast(-1)) - AntiDepReg = 0; - - // Look for a suitable register to use to break the anti-depenence. - // - // TODO: Instead of picking the first free register, consider which might - // be the best. - if (AntiDepReg != 0) { - if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg, - LastNewReg[AntiDepReg], - RC)) { - DEBUG(errs() << "Breaking anti-dependence edge on " - << TRI->getName(AntiDepReg) - << " with " << RegRefs.count(AntiDepReg) << " references" - << " using " << TRI->getName(NewReg) << "!\n"); - - // Update the references to the old register to refer to the new - // register. - std::pair::iterator, - std::multimap::iterator> - Range = RegRefs.equal_range(AntiDepReg); - for (std::multimap::iterator - Q = Range.first, QE = Range.second; Q != QE; ++Q) - Q->second->setReg(NewReg); - - // We just went back in time and modified history; the - // liveness information for the anti-depenence reg is now - // inconsistent. Set the state as if it were dead. - Classes[NewReg] = Classes[AntiDepReg]; - DefIndices[NewReg] = DefIndices[AntiDepReg]; - KillIndices[NewReg] = KillIndices[AntiDepReg]; - assert(((KillIndices[NewReg] == ~0u) != - (DefIndices[NewReg] == ~0u)) && - "Kill and Def maps aren't consistent for NewReg!"); - - Classes[AntiDepReg] = 0; - DefIndices[AntiDepReg] = KillIndices[AntiDepReg]; - KillIndices[AntiDepReg] = ~0u; - assert(((KillIndices[AntiDepReg] == ~0u) != - (DefIndices[AntiDepReg] == ~0u)) && - "Kill and Def maps aren't consistent for AntiDepReg!"); - - RegRefs.erase(AntiDepReg); - Changed = true; - LastNewReg[AntiDepReg] = NewReg; - } - } - - ScanInstruction(MI, Count); - } - - return Changed; -} - /// StartBlockForKills - Initialize register live-range state for updating kills /// void SchedulePostRATDList::StartBlockForKills(MachineBasicBlock *BB) { Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=85127&r1=85126&r2=85127&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original) +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Mon Oct 26 11:59:04 2009 @@ -130,7 +130,7 @@ /// for Thumb1. bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, TargetSubtarget::AntiDepBreakMode& mode) const { - mode = TargetSubtarget::ANTIDEP_NONE; + mode = TargetSubtarget::ANTIDEP_CRITICAL; return PostRAScheduler && OptLevel >= CodeGenOpt::Default; } Modified: llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll?rev=85127&r1=85126&r2=85127&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll (original) +++ llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll Mon Oct 26 11:59:04 2009 @@ -1,7 +1,7 @@ -; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies=false > %t +; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies=none > %t ; RUN: grep {%xmm0} %t | count 14 ; RUN: not grep {%xmm1} %t -; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies > %t +; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies=critical > %t ; RUN: grep {%xmm0} %t | count 7 ; RUN: grep {%xmm1} %t | count 7 From benny.kra at googlemail.com Mon Oct 26 12:01:22 2009 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Mon, 26 Oct 2009 17:01:22 -0000 Subject: [llvm-commits] [llvm] r85128 - in /llvm/trunk: include/llvm/Support/ include/llvm/System/ lib/Target/Blackfin/ lib/Target/PIC16/PIC16Passes/ utils/count/ utils/not/ utils/unittest/UnitTestMain/ Message-ID: <200910261701.n9QH1Mhu024053@zion.cs.uiuc.edu> Author: d0k Date: Mon Oct 26 12:01:20 2009 New Revision: 85128 URL: http://llvm.org/viewvc/llvm-project?rev=85128&view=rev Log: Some svn:ignore tweaks. Modified: llvm/trunk/include/llvm/Support/ (props changed) llvm/trunk/include/llvm/System/ (props changed) llvm/trunk/lib/Target/Blackfin/ (props changed) llvm/trunk/lib/Target/PIC16/PIC16Passes/ (props changed) llvm/trunk/utils/count/ (props changed) llvm/trunk/utils/not/ (props changed) llvm/trunk/utils/unittest/UnitTestMain/ (props changed) Propchange: llvm/trunk/include/llvm/Support/ ------------------------------------------------------------------------------ --- svn:ignore (original) +++ svn:ignore (removed) @@ -1,2 +0,0 @@ -.cvsignore -DataTypes.h Propchange: llvm/trunk/include/llvm/System/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Mon Oct 26 12:01:20 2009 @@ -0,0 +1 @@ +DataTypes.h Propchange: llvm/trunk/lib/Target/Blackfin/ ------------------------------------------------------------------------------ --- svn:ignore (original) +++ svn:ignore Mon Oct 26 12:01:20 2009 @@ -6,6 +6,7 @@ BlackfinGenDAGISel.inc BlackfinGenInstrInfo.inc BlackfinGenInstrNames.inc +BlackfinGenIntrinsics.inc BlackfinGenRegisterInfo.h.inc BlackfinGenRegisterInfo.inc BlackfinGenRegisterNames.inc Propchange: llvm/trunk/lib/Target/PIC16/PIC16Passes/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Mon Oct 26 12:01:20 2009 @@ -0,0 +1,4 @@ +Debug +Release-Asserts +Release +Debug+Checks Propchange: llvm/trunk/utils/count/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Mon Oct 26 12:01:20 2009 @@ -0,0 +1,4 @@ +Debug +Release-Asserts +Release +Debug+Checks Propchange: llvm/trunk/utils/not/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Mon Oct 26 12:01:20 2009 @@ -0,0 +1,4 @@ +Debug +Release-Asserts +Release +Debug+Checks Propchange: llvm/trunk/utils/unittest/UnitTestMain/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Mon Oct 26 12:01:20 2009 @@ -0,0 +1,4 @@ +Debug +Release-Asserts +Release +Debug+Checks From dpatel at apple.com Mon Oct 26 12:09:13 2009 From: dpatel at apple.com (Devang Patel) Date: Mon, 26 Oct 2009 17:09:13 -0000 Subject: [llvm-commits] [llvm] r85130 - /llvm/trunk/lib/VMCore/Metadata.cpp Message-ID: <200910261709.n9QH9IIq024599@zion.cs.uiuc.edu> Author: dpatel Date: Mon Oct 26 12:09:00 2009 New Revision: 85130 URL: http://llvm.org/viewvc/llvm-project?rev=85130&view=rev Log: Do not use expensive sort(). Modified: llvm/trunk/lib/VMCore/Metadata.cpp Modified: llvm/trunk/lib/VMCore/Metadata.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Metadata.cpp?rev=85130&r1=85129&r2=85130&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Metadata.cpp (original) +++ llvm/trunk/lib/VMCore/Metadata.cpp Mon Oct 26 12:09:00 2009 @@ -344,20 +344,22 @@ MDStoreTy::iterator I = MetadataStore.find(Inst); if (I == MetadataStore.end()) return; + MDs.resize(I->second.size()); for (MDMapTy::iterator MI = I->second.begin(), ME = I->second.end(); MI != ME; ++MI) - MDs.push_back(std::make_pair(MI->first, MI->second)); - std::sort(MDs.begin(), MDs.end()); + // MD kinds are numbered from 1. + MDs[MI->first - 1] = std::make_pair(MI->first, MI->second); } /// getHandlerNames - Populate client supplied smallvector using custome /// metadata name and ID. void MetadataContextImpl:: getHandlerNames(SmallVectorImpl >&Names) const { + Names.resize(MDHandlerNames.size()); for (StringMap::const_iterator I = MDHandlerNames.begin(), E = MDHandlerNames.end(); I != E; ++I) - Names.push_back(std::make_pair(I->second, I->first())); - std::sort(Names.begin(), Names.end()); + // MD Handlers are numbered from 1. + Names[I->second - 1] = std::make_pair(I->second, I->first()); } /// ValueIsCloned - This handler is used to update metadata store From sanjiv.gupta at microchip.com Mon Oct 26 13:23:00 2009 From: sanjiv.gupta at microchip.com (Sanjiv Gupta) Date: Mon, 26 Oct 2009 18:23:00 -0000 Subject: [llvm-commits] [llvm] r85134 - in /llvm/trunk/lib/Target/PIC16/PIC16Passes: Makefile PIC16Overlay.cpp Message-ID: <200910261823.n9QIN0hc027720@zion.cs.uiuc.edu> Author: sgupta Date: Mon Oct 26 13:22:59 2009 New Revision: 85134 URL: http://llvm.org/viewvc/llvm-project?rev=85134&view=rev Log: Make PIC16 overlay a loadable pass. Modified: llvm/trunk/lib/Target/PIC16/PIC16Passes/Makefile llvm/trunk/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp Modified: llvm/trunk/lib/Target/PIC16/PIC16Passes/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16Passes/Makefile?rev=85134&r1=85133&r2=85134&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16Passes/Makefile (original) +++ llvm/trunk/lib/Target/PIC16/PIC16Passes/Makefile Mon Oct 26 13:22:59 2009 @@ -8,9 +8,8 @@ ##===----------------------------------------------------------------------===## LEVEL = ../../../.. TARGET = PIC16 -LIBRARYNAME = LLVMpic16passes -BUILD_ARCHIVE = 1 - +LIBRARYNAME = PIC16Passes +LOADABLE_MODULE = 1 include $(LEVEL)/Makefile.common Modified: llvm/trunk/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp?rev=85134&r1=85133&r2=85134&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp Mon Oct 26 13:22:59 2009 @@ -25,7 +25,8 @@ namespace llvm { char PIC16FrameOverlay::ID = 0; - ModulePass *createPIC16OverlayPass() { return new PIC16FrameOverlay(); } + static RegisterPass + X("pic16overlay", "PIC16 Frame Overlay Analysis"); } void PIC16FrameOverlay::getAnalysisUsage(AnalysisUsage &AU) const { From gohman at apple.com Mon Oct 26 13:26:19 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 26 Oct 2009 18:26:19 -0000 Subject: [llvm-commits] [llvm] r85135 - /llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Message-ID: <200910261826.n9QIQJae027819@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 26 13:26:18 2009 New Revision: 85135 URL: http://llvm.org/viewvc/llvm-project?rev=85135&view=rev Log: When checking whether a def of an aliased register is dead, ask the machineinstr whether the aliased register is dead, rather than the original register is dead. This allows it to get the correct answer when examining an instruction like this: CALLpcrel32 , %AL, %EAX where EAX is dead but a subregister of it is still live. This fixes PR5294. Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=85135&r1=85134&r2=85135&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Mon Oct 26 13:26:18 2009 @@ -208,7 +208,7 @@ SUnit *DefSU = DefList[i]; if (DefSU != SU && (Kind != SDep::Output || !MO.isDead() || - !DefSU->getInstr()->registerDefIsDead(Reg))) + !DefSU->getInstr()->registerDefIsDead(*Alias))) DefSU->addPred(SDep(SU, Kind, AOLatency, /*Reg=*/ *Alias)); } } From anton at korobeynikov.info Mon Oct 26 13:33:00 2009 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Mon, 26 Oct 2009 21:33:00 +0300 Subject: [llvm-commits] [llvm] r85134 - in /llvm/trunk/lib/Target/PIC16/PIC16Passes: Makefile PIC16Overlay.cpp In-Reply-To: <200910261823.n9QIN0hc027720@zion.cs.uiuc.edu> References: <200910261823.n9QIN0hc027720@zion.cs.uiuc.edu> Message-ID: Hello, Sanjiv > URL: http://llvm.org/viewvc/llvm-project?rev=85134&view=rev > Log: > Make PIC16 overlay a loadable pass. This commit was reverted previously because it breaks mingw build. It will be reverted again. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From gohman at apple.com Mon Oct 26 13:36:40 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 26 Oct 2009 18:36:40 -0000 Subject: [llvm-commits] [llvm] r85137 - /llvm/trunk/include/llvm/Support/TargetFolder.h Message-ID: <200910261836.n9QIae0n028340@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 26 13:36:40 2009 New Revision: 85137 URL: http://llvm.org/viewvc/llvm-project?rev=85137&view=rev Log: Add CreateZExtOrBitCast and CreateSExtOrBitCast to TargetFolder for consistency with ConstantFolder. Modified: llvm/trunk/include/llvm/Support/TargetFolder.h Modified: llvm/trunk/include/llvm/Support/TargetFolder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/TargetFolder.h?rev=85137&r1=85136&r2=85137&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/TargetFolder.h (original) +++ llvm/trunk/include/llvm/Support/TargetFolder.h Mon Oct 26 13:36:40 2009 @@ -179,6 +179,16 @@ Constant *CreatePtrToInt(Constant *C, const Type *DestTy) const { return CreateCast(Instruction::PtrToInt, C, DestTy); } + Constant *CreateZExtOrBitCast(Constant *C, const Type *DestTy) const { + if (C->getType() == DestTy) + return C; // avoid calling Fold + return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy)); + } + Constant *CreateSExtOrBitCast(Constant *C, const Type *DestTy) const { + if (C->getType() == DestTy) + return C; // avoid calling Fold + return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy)); + } Constant *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const { if (C->getType() == DestTy) return C; // avoid calling Fold From asl at math.spbu.ru Mon Oct 26 13:40:24 2009 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Mon, 26 Oct 2009 18:40:24 -0000 Subject: [llvm-commits] [llvm] r85138 - in /llvm/trunk/lib/Target/PIC16/PIC16Passes: Makefile PIC16Overlay.cpp Message-ID: <200910261840.n9QIeOew028514@zion.cs.uiuc.edu> Author: asl Date: Mon Oct 26 13:40:24 2009 New Revision: 85138 URL: http://llvm.org/viewvc/llvm-project?rev=85138&view=rev Log: Revert r85134, it breaks mingw build Modified: llvm/trunk/lib/Target/PIC16/PIC16Passes/Makefile llvm/trunk/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp Modified: llvm/trunk/lib/Target/PIC16/PIC16Passes/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16Passes/Makefile?rev=85138&r1=85137&r2=85138&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16Passes/Makefile (original) +++ llvm/trunk/lib/Target/PIC16/PIC16Passes/Makefile Mon Oct 26 13:40:24 2009 @@ -8,9 +8,8 @@ ##===----------------------------------------------------------------------===## LEVEL = ../../../.. TARGET = PIC16 -LIBRARYNAME = PIC16Passes -LOADABLE_MODULE = 1 - +LIBRARYNAME = LLVMpic16passes +BUILD_ARCHIVE = 1 include $(LEVEL)/Makefile.common Modified: llvm/trunk/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp?rev=85138&r1=85137&r2=85138&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp Mon Oct 26 13:40:24 2009 @@ -25,8 +25,7 @@ namespace llvm { char PIC16FrameOverlay::ID = 0; - static RegisterPass - X("pic16overlay", "PIC16 Frame Overlay Analysis"); + ModulePass *createPIC16OverlayPass() { return new PIC16FrameOverlay(); } } void PIC16FrameOverlay::getAnalysisUsage(AnalysisUsage &AU) const { From johnny.chen at apple.com Mon Oct 26 13:48:28 2009 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 26 Oct 2009 11:48:28 -0700 Subject: [llvm-commits] Added more 's' bit set encoding and "rs" register encoding bits Message-ID: <31E018AE-6E13-4514-AF87-D875A8A09C9B@apple.com> Hi, For multiclass AI1_adde_sube_irs definition, I also added: let Inst{31-28} = 0b1110; for the Sri, Srr, and Srs variants. From the AsmString field of the respective record definitions (take SBCSrs, for example): string AsmString = "sbcs $dst, $a, $b"; it looks like this is the right thing to do. Please remove the three "set condition code to ALways" lines from the submitted patch if this is not correct. Thanks. -------------- next part -------------- A non-text attachment was scrubbed... Name: ARMInstrInfo.td.patch Type: application/octet-stream Size: 2981 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091026/d73aadb7/attachment.obj From david_goodwin at apple.com Mon Oct 26 14:00:47 2009 From: david_goodwin at apple.com (David Goodwin) Date: Mon, 26 Oct 2009 19:00:47 -0000 Subject: [llvm-commits] [llvm] r85141 - /llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Message-ID: <200910261900.n9QJ0lP6029737@zion.cs.uiuc.edu> Author: david_goodwin Date: Mon Oct 26 14:00:47 2009 New Revision: 85141 URL: http://llvm.org/viewvc/llvm-project?rev=85141&view=rev Log: Add virtual destructor. Modified: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Modified: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h?rev=85141&r1=85140&r2=85141&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h (original) +++ llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Mon Oct 26 14:00:47 2009 @@ -29,6 +29,8 @@ /// anti-dependencies. class AntiDepBreaker { public: + virtual ~AntiDepBreaker() { }; + /// Start - Initialize anti-dep breaking for a new basic block. virtual void StartBlock(MachineBasicBlock *BB) =0; From david_goodwin at apple.com Mon Oct 26 14:02:10 2009 From: david_goodwin at apple.com (David Goodwin) Date: Mon, 26 Oct 2009 12:02:10 -0700 Subject: [llvm-commits] [llvm] r85127 - in /llvm/trunk: include/llvm/CodeGen/AntiDepBreaker.h lib/CodeGen/CMakeLists.txt lib/CodeGen/CriticalAntiDepBreaker.cpp lib/CodeGen/CriticalAntiDepBreaker.h lib/CodeGen/PostRASchedulerList.cpp lib/Target/ARM/ARMSubt In-Reply-To: <74c447500910261138m3326f8a7t859d0bc8eac504e9@mail.gmail.com> References: <74c447500910261138m3326f8a7t859d0bc8eac504e9@mail.gmail.com> Message-ID: Thanks, added virtual destructor.... Author: david_goodwin Date: Mon Oct 26 14:00:47 2009 New Revision: 85141 URL: http://llvm.org/viewvc/llvm-project?rev=85141&view=rev Log: Add virtual destructor. Modified: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h On Oct 26, 2009, at 11:38 AM, Chandler Carruth wrote: > FYI, this change causes both llvm::AntiDepBreaker and > llvm::CriticalAntiDepBreaker to have virtual functions and an > accessible non-virtual destructor. > > On Mon, Oct 26, 2009 at 9:59 AM, David Goodwin > wrote: >> Author: david_goodwin >> Date: Mon Oct 26 11:59:04 2009 >> New Revision: 85127 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=85127&view=rev >> Log: >> Break anti-dependence breaking out into its own class. >> >> Added: >> llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h >> llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp >> llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h >> Modified: >> llvm/trunk/lib/CodeGen/CMakeLists.txt >> llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp >> llvm/trunk/lib/Target/ARM/ARMSubtarget.h >> llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll >> >> Added: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h?rev=85127&view=auto >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h (added) >> +++ llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Mon Oct 26 >> 11:59:04 2009 >> @@ -0,0 +1,56 @@ >> +//=- llvm/CodeGen/AntiDepBreaker.h - Anti-Dependence Breaking -*- C >> ++ -*-=// >> +// >> +// The LLVM Compiler Infrastructure >> +// >> +// This file is distributed under the University of Illinois Open >> Source >> +// License. See LICENSE.TXT for details. >> +// >> +// >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> +// >> +// This file implements the AntiDepBreaker class, which implements >> +// anti-dependence breaking heuristics for post-register- >> allocation scheduling. >> +// >> +// >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> + >> +#ifndef LLVM_CODEGEN_ANTIDEPBREAKER_H >> +#define LLVM_CODEGEN_ANTIDEPBREAKER_H >> + >> +#include "llvm/CodeGen/MachineBasicBlock.h" >> +#include "llvm/CodeGen/MachineFrameInfo.h" >> +#include "llvm/CodeGen/MachineFunction.h" >> +#include "llvm/CodeGen/MachineRegisterInfo.h" >> +#include "llvm/CodeGen/ScheduleDAG.h" >> +#include "llvm/Target/TargetRegisterInfo.h" >> + >> +namespace llvm { >> + >> +/// AntiDepBreaker - This class works into conjunction with the >> +/// post-RA scheduler to rename registers to break register >> +/// anti-dependencies. >> +class AntiDepBreaker { >> +public: >> + /// Start - Initialize anti-dep breaking for a new basic block. >> + virtual void StartBlock(MachineBasicBlock *BB) =0; >> + >> + /// BreakAntiDependencies - Identifiy anti-dependencies within a >> + /// basic-block region and break them by renaming registers. >> Return >> + /// the number of anti-dependencies broken. >> + /// >> + virtual unsigned BreakAntiDependencies(std::vector& SUnits, >> + >> MachineBasicBlock::iterator& Begin, >> + >> MachineBasicBlock::iterator& End, >> + unsigned InsertPosIndex) >> =0; >> + >> + /// Observe - Update liveness information to account for the >> current >> + /// instruction, which will not be scheduled. >> + /// >> + virtual void Observe(MachineInstr *MI, unsigned Count, >> + unsigned InsertPosIndex) =0; >> + >> + /// Finish - Finish anti-dep breaking for a basic block. >> + virtual void FinishBlock() =0; >> +}; >> + >> +} >> + >> +#endif >> >> Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=85127&r1=85126&r2=85127&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/CodeGen/CMakeLists.txt (original) >> +++ llvm/trunk/lib/CodeGen/CMakeLists.txt Mon Oct 26 11:59:04 2009 >> @@ -1,6 +1,7 @@ >> add_llvm_library(LLVMCodeGen >> BranchFolding.cpp >> CodePlacementOpt.cpp >> + CriticalAntiDepBreaker.cpp >> DeadMachineInstructionElim.cpp >> DwarfEHPrepare.cpp >> ELFCodeEmitter.cpp >> >> Added: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp?rev=85127&view=auto >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp (added) >> +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp Mon Oct 26 >> 11:59:04 2009 >> @@ -0,0 +1,539 @@ >> +//===----- CriticalAntiDepBreaker.cpp - Anti-dep breaker -------- >> ---------===// >> +// >> +// The LLVM Compiler Infrastructure >> +// >> +// This file is distributed under the University of Illinois Open >> Source >> +// License. See LICENSE.TXT for details. >> +// >> +// >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> +// >> +// This file implements the CriticalAntiDepBreaker class, which >> +// implements register anti-dependence breaking along a blocks >> +// critical path during post-RA scheduler. >> +// >> +// >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> + >> +#define DEBUG_TYPE "critical-antidep" >> +#include "CriticalAntiDepBreaker.h" >> +#include "llvm/CodeGen/MachineBasicBlock.h" >> +#include "llvm/CodeGen/MachineFrameInfo.h" >> +#include "llvm/Target/TargetMachine.h" >> +#include "llvm/Target/TargetRegisterInfo.h" >> +#include "llvm/Support/Debug.h" >> +#include "llvm/Support/ErrorHandling.h" >> +#include "llvm/Support/raw_ostream.h" >> + >> +using namespace llvm; >> + >> +CriticalAntiDepBreaker:: >> +CriticalAntiDepBreaker(MachineFunction& MFi) : >> + AntiDepBreaker(), MF(MFi), >> + MRI(MF.getRegInfo()), >> + TRI(MF.getTarget().getRegisterInfo()), >> + AllocatableSet(TRI->getAllocatableSet(MF)) >> +{ >> +} >> + >> +CriticalAntiDepBreaker::~CriticalAntiDepBreaker() { >> +} >> + >> +void CriticalAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { >> + // Clear out the register class data. >> + std::fill(Classes, array_endof(Classes), >> + static_cast(0)); >> + >> + // Initialize the indices to indicate that no registers are live. >> + std::fill(KillIndices, array_endof(KillIndices), ~0u); >> + std::fill(DefIndices, array_endof(DefIndices), BB->size()); >> + >> + // Clear "do not change" set. >> + KeepRegs.clear(); >> + >> + bool IsReturnBlock = (!BB->empty() && BB->back().getDesc >> ().isReturn()); >> + >> + // Determine the live-out physregs for this block. >> + if (IsReturnBlock) { >> + // In a return block, examine the function live-out regs. >> + for (MachineRegisterInfo::liveout_iterator I = >> MRI.liveout_begin(), >> + E = MRI.liveout_end(); I != E; ++I) { >> + unsigned Reg = *I; >> + Classes[Reg] = reinterpret_cast(-1); >> + KillIndices[Reg] = BB->size(); >> + DefIndices[Reg] = ~0u; >> + // Repeat, for all aliases. >> + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; + >> +Alias) { >> + unsigned AliasReg = *Alias; >> + Classes[AliasReg] = reinterpret_cast >> (-1); >> + KillIndices[AliasReg] = BB->size(); >> + DefIndices[AliasReg] = ~0u; >> + } >> + } >> + } else { >> + // In a non-return block, examine the live-in regs of all >> successors. >> + for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), >> + SE = BB->succ_end(); SI != SE; ++SI) >> + for (MachineBasicBlock::livein_iterator I = (*SI)- >> >livein_begin(), >> + E = (*SI)->livein_end(); I != E; ++I) { >> + unsigned Reg = *I; >> + Classes[Reg] = reinterpret_cast(-1); >> + KillIndices[Reg] = BB->size(); >> + DefIndices[Reg] = ~0u; >> + // Repeat, for all aliases. >> + for (const unsigned *Alias = TRI->getAliasSet(Reg); >> *Alias; ++Alias) { >> + unsigned AliasReg = *Alias; >> + Classes[AliasReg] = reinterpret_cast> *>(-1); >> + KillIndices[AliasReg] = BB->size(); >> + DefIndices[AliasReg] = ~0u; >> + } >> + } >> + } >> + >> + // Mark live-out callee-saved registers. In a return block this is >> + // all callee-saved registers. In non-return this is any >> + // callee-saved register that is not saved in the prolog. >> + const MachineFrameInfo *MFI = MF.getFrameInfo(); >> + BitVector Pristine = MFI->getPristineRegs(BB); >> + for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { >> + unsigned Reg = *I; >> + if (!IsReturnBlock && !Pristine.test(Reg)) continue; >> + Classes[Reg] = reinterpret_cast(-1); >> + KillIndices[Reg] = BB->size(); >> + DefIndices[Reg] = ~0u; >> + // Repeat, for all aliases. >> + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; + >> +Alias) { >> + unsigned AliasReg = *Alias; >> + Classes[AliasReg] = reinterpret_cast >> (-1); >> + KillIndices[AliasReg] = BB->size(); >> + DefIndices[AliasReg] = ~0u; >> + } >> + } >> +} >> + >> +void CriticalAntiDepBreaker::FinishBlock() { >> + RegRefs.clear(); >> + KeepRegs.clear(); >> +} >> + >> +void CriticalAntiDepBreaker::Observe(MachineInstr *MI, unsigned >> Count, >> + unsigned InsertPosIndex) { >> + assert(Count < InsertPosIndex && "Instruction index out of >> expected range!"); >> + >> + // Any register which was defined within the previous scheduling >> region >> + // may have been rescheduled and its lifetime may overlap with >> registers >> + // in ways not reflected in our current liveness state. For each >> such >> + // register, adjust the liveness state to be conservatively >> correct. >> + for (unsigned Reg = 0; Reg != >> TargetRegisterInfo::FirstVirtualRegister; ++Reg) >> + if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= >> Count) { >> + assert(KillIndices[Reg] == ~0u && "Clobbered register is >> live!"); >> + // Mark this register to be non-renamable. >> + Classes[Reg] = reinterpret_cast(-1); >> + // Move the def index to the end of the previous region, to >> reflect >> + // that the def could theoretically have been scheduled at >> the end. >> + DefIndices[Reg] = InsertPosIndex; >> + } >> + >> + PrescanInstruction(MI); >> + ScanInstruction(MI, Count); >> +} >> + >> +/// CriticalPathStep - Return the next SUnit after SU on the >> bottom-up >> +/// critical path. >> +static SDep *CriticalPathStep(SUnit *SU) { >> + SDep *Next = 0; >> + unsigned NextDepth = 0; >> + // Find the predecessor edge with the greatest depth. >> + for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU- >> >Preds.end(); >> + P != PE; ++P) { >> + SUnit *PredSU = P->getSUnit(); >> + unsigned PredLatency = P->getLatency(); >> + unsigned PredTotalLatency = PredSU->getDepth() + PredLatency; >> + // In the case of a latency tie, prefer an anti-dependency >> edge over >> + // other types of edges. >> + if (NextDepth < PredTotalLatency || >> + (NextDepth == PredTotalLatency && P->getKind() == >> SDep::Anti)) { >> + NextDepth = PredTotalLatency; >> + Next = &*P; >> + } >> + } >> + return Next; >> +} >> + >> +void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr *MI) { >> + // Scan the register operands for this instruction and update >> + // Classes and RegRefs. >> + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >> + MachineOperand &MO = MI->getOperand(i); >> + if (!MO.isReg()) continue; >> + unsigned Reg = MO.getReg(); >> + if (Reg == 0) continue; >> + const TargetRegisterClass *NewRC = 0; >> + >> + if (i < MI->getDesc().getNumOperands()) >> + NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); >> + >> + // For now, only allow the register to be changed if its >> register >> + // class is consistent across all uses. >> + if (!Classes[Reg] && NewRC) >> + Classes[Reg] = NewRC; >> + else if (!NewRC || Classes[Reg] != NewRC) >> + Classes[Reg] = reinterpret_cast(-1); >> + >> + // Now check for aliases. >> + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; + >> +Alias) { >> + // If an alias of the reg is used during the live range, >> give up. >> + // Note that this allows us to skip checking if AntiDepReg >> + // overlaps with any of the aliases, among other things. >> + unsigned AliasReg = *Alias; >> + if (Classes[AliasReg]) { >> + Classes[AliasReg] = reinterpret_cast >> (-1); >> + Classes[Reg] = reinterpret_cast(-1); >> + } >> + } >> + >> + // If we're still willing to consider this register, note the >> reference. >> + if (Classes[Reg] != reinterpret_cast(-1)) >> + RegRefs.insert(std::make_pair(Reg, &MO)); >> + >> + // It's not safe to change register allocation for source >> operands of >> + // that have special allocation requirements. >> + if (MO.isUse() && MI->getDesc().hasExtraSrcRegAllocReq()) { >> + if (KeepRegs.insert(Reg)) { >> + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); >> + *Subreg; ++Subreg) >> + KeepRegs.insert(*Subreg); >> + } >> + } >> + } >> +} >> + >> +void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI, >> + unsigned Count) { >> + // Update liveness. >> + // Proceding upwards, registers that are defed but not used in >> this >> + // instruction are now dead. >> + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >> + MachineOperand &MO = MI->getOperand(i); >> + if (!MO.isReg()) continue; >> + unsigned Reg = MO.getReg(); >> + if (Reg == 0) continue; >> + if (!MO.isDef()) continue; >> + // Ignore two-addr defs. >> + if (MI->isRegTiedToUseOperand(i)) continue; >> + >> + DefIndices[Reg] = Count; >> + KillIndices[Reg] = ~0u; >> + assert(((KillIndices[Reg] == ~0u) != >> + (DefIndices[Reg] == ~0u)) && >> + "Kill and Def maps aren't consistent for Reg!"); >> + KeepRegs.erase(Reg); >> + Classes[Reg] = 0; >> + RegRefs.erase(Reg); >> + // Repeat, for all subregs. >> + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); >> + *Subreg; ++Subreg) { >> + unsigned SubregReg = *Subreg; >> + DefIndices[SubregReg] = Count; >> + KillIndices[SubregReg] = ~0u; >> + KeepRegs.erase(SubregReg); >> + Classes[SubregReg] = 0; >> + RegRefs.erase(SubregReg); >> + } >> + // Conservatively mark super-registers as unusable. >> + for (const unsigned *Super = TRI->getSuperRegisters(Reg); >> + *Super; ++Super) { >> + unsigned SuperReg = *Super; >> + Classes[SuperReg] = reinterpret_cast >> (-1); >> + } >> + } >> + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >> + MachineOperand &MO = MI->getOperand(i); >> + if (!MO.isReg()) continue; >> + unsigned Reg = MO.getReg(); >> + if (Reg == 0) continue; >> + if (!MO.isUse()) continue; >> + >> + const TargetRegisterClass *NewRC = 0; >> + if (i < MI->getDesc().getNumOperands()) >> + NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); >> + >> + // For now, only allow the register to be changed if its >> register >> + // class is consistent across all uses. >> + if (!Classes[Reg] && NewRC) >> + Classes[Reg] = NewRC; >> + else if (!NewRC || Classes[Reg] != NewRC) >> + Classes[Reg] = reinterpret_cast(-1); >> + >> + RegRefs.insert(std::make_pair(Reg, &MO)); >> + >> + // It wasn't previously live but now it is, this is a kill. >> + if (KillIndices[Reg] == ~0u) { >> + KillIndices[Reg] = Count; >> + DefIndices[Reg] = ~0u; >> + assert(((KillIndices[Reg] == ~0u) != >> + (DefIndices[Reg] == ~0u)) && >> + "Kill and Def maps aren't consistent for Reg!"); >> + } >> + // Repeat, for all aliases. >> + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; + >> +Alias) { >> + unsigned AliasReg = *Alias; >> + if (KillIndices[AliasReg] == ~0u) { >> + KillIndices[AliasReg] = Count; >> + DefIndices[AliasReg] = ~0u; >> + } >> + } >> + } >> +} >> + >> +unsigned >> +CriticalAntiDepBreaker::findSuitableFreeRegister(unsigned >> AntiDepReg, >> + unsigned >> LastNewReg, >> + const >> TargetRegisterClass *RC) { >> + for (TargetRegisterClass::iterator R = RC->allocation_order_begin >> (MF), >> + RE = RC->allocation_order_end(MF); R != RE; ++R) { >> + unsigned NewReg = *R; >> + // Don't replace a register with itself. >> + if (NewReg == AntiDepReg) continue; >> + // Don't replace a register with one that was recently used to >> repair >> + // an anti-dependence with this AntiDepReg, because that would >> + // re-introduce that anti-dependence. >> + if (NewReg == LastNewReg) continue; >> + // If NewReg is dead and NewReg's most recent def is not before >> + // AntiDepReg's kill, it's safe to replace AntiDepReg with >> NewReg. >> + assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices >> [AntiDepReg] == ~0u)) && >> + "Kill and Def maps aren't consistent for AntiDepReg!"); >> + assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == >> ~0u)) && >> + "Kill and Def maps aren't consistent for NewReg!"); >> + if (KillIndices[NewReg] != ~0u || >> + Classes[NewReg] == reinterpret_cast >> (-1) || >> + KillIndices[AntiDepReg] > DefIndices[NewReg]) >> + continue; >> + return NewReg; >> + } >> + >> + // No registers are free and available! >> + return 0; >> +} >> + >> +unsigned CriticalAntiDepBreaker:: >> +BreakAntiDependencies(std::vector& SUnits, >> + MachineBasicBlock::iterator& Begin, >> + MachineBasicBlock::iterator& End, >> + unsigned InsertPosIndex) { >> + // The code below assumes that there is at least one instruction, >> + // so just duck out immediately if the block is empty. >> + if (SUnits.empty()) return 0; >> + >> + // Find the node at the bottom of the critical path. >> + SUnit *Max = 0; >> + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { >> + SUnit *SU = &SUnits[i]; >> + if (!Max || SU->getDepth() + SU->Latency > Max->getDepth() + >> Max->Latency) >> + Max = SU; >> + } >> + >> +#ifndef NDEBUG >> + { >> + DEBUG(errs() << "Critical path has total latency " >> + << (Max->getDepth() + Max->Latency) << "\n"); >> + DEBUG(errs() << "Available regs:"); >> + for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { >> + if (KillIndices[Reg] == ~0u) >> + DEBUG(errs() << " " << TRI->getName(Reg)); >> + } >> + DEBUG(errs() << '\n'); >> + } >> +#endif >> + >> + // Track progress along the critical path through the SUnit >> graph as we walk >> + // the instructions. >> + SUnit *CriticalPathSU = Max; >> + MachineInstr *CriticalPathMI = CriticalPathSU->getInstr(); >> + >> + // Consider this pattern: >> + // A = ... >> + // ... = A >> + // A = ... >> + // ... = A >> + // A = ... >> + // ... = A >> + // A = ... >> + // ... = A >> + // There are three anti-dependencies here, and without special >> care, >> + // we'd break all of them using the same register: >> + // A = ... >> + // ... = A >> + // B = ... >> + // ... = B >> + // B = ... >> + // ... = B >> + // B = ... >> + // ... = B >> + // because at each anti-dependence, B is the first register that >> + // isn't A which is free. This re-introduces anti-dependencies >> + // at all but one of the original anti-dependencies that we were >> + // trying to break. To avoid this, keep track of the most recent >> + // register that each register was replaced with, avoid >> + // using it to repair an anti-dependence on the same register. >> + // This lets us produce this: >> + // A = ... >> + // ... = A >> + // B = ... >> + // ... = B >> + // C = ... >> + // ... = C >> + // B = ... >> + // ... = B >> + // This still has an anti-dependence on B, but at least it isn't >> on the >> + // original critical path. >> + // >> + // TODO: If we tracked more than one register here, we could >> potentially >> + // fix that remaining critical edge too. This is a little more >> involved, >> + // because unlike the most recent register, less recent >> registers should >> + // still be considered, though only if no other registers are >> available. >> + unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = >> {}; >> + >> + // Attempt to break anti-dependence edges on the critical path. >> Walk the >> + // instructions from the bottom up, tracking information about >> liveness >> + // as we go to help determine which registers are available. >> + unsigned Broken = 0; >> + unsigned Count = InsertPosIndex - 1; >> + for (MachineBasicBlock::iterator I = End, E = Begin; >> + I != E; --Count) { >> + MachineInstr *MI = --I; >> + >> + // Check if this instruction has a dependence on the critical >> path that >> + // is an anti-dependence that we may be able to break. If it >> is, set >> + // AntiDepReg to the non-zero register associated with the >> anti-dependence. >> + // >> + // We limit our attention to the critical path as a heuristic >> to avoid >> + // breaking anti-dependence edges that aren't going to >> significantly >> + // impact the overall schedule. There are a limited number of >> registers >> + // and we want to save them for the important edges. >> + // >> + // TODO: Instructions with multiple defs could have multiple >> + // anti-dependencies. The current code here only knows how to >> break one >> + // edge per instruction. Note that we'd have to be able to >> break all of >> + // the anti-dependencies in an instruction in order to be >> effective. >> + unsigned AntiDepReg = 0; >> + if (MI == CriticalPathMI) { >> + if (SDep *Edge = CriticalPathStep(CriticalPathSU)) { >> + SUnit *NextSU = Edge->getSUnit(); >> + >> + // Only consider anti-dependence edges. >> + if (Edge->getKind() == SDep::Anti) { >> + AntiDepReg = Edge->getReg(); >> + assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); >> + if (!AllocatableSet.test(AntiDepReg)) >> + // Don't break anti-dependencies on non-allocatable >> registers. >> + AntiDepReg = 0; >> + else if (KeepRegs.count(AntiDepReg)) >> + // Don't break anti-dependencies if an use down below >> requires >> + // this exact register. >> + AntiDepReg = 0; >> + else { >> + // If the SUnit has other dependencies on the SUnit >> that it >> + // anti-depends on, don't bother breaking the anti- >> dependency >> + // since those edges would prevent such units from being >> + // scheduled past each other regardless. >> + // >> + // Also, if there are dependencies on other SUnits >> with the >> + // same register as the anti-dependency, don't attempt >> to >> + // break it. >> + for (SUnit::pred_iterator P = CriticalPathSU- >> >Preds.begin(), >> + PE = CriticalPathSU->Preds.end(); P != PE; ++P) >> + if (P->getSUnit() == NextSU ? >> + (P->getKind() != SDep::Anti || P->getReg() != >> AntiDepReg) : >> + (P->getKind() == SDep::Data && P->getReg() == >> AntiDepReg)) { >> + AntiDepReg = 0; >> + break; >> + } >> + } >> + } >> + CriticalPathSU = NextSU; >> + CriticalPathMI = CriticalPathSU->getInstr(); >> + } else { >> + // We've reached the end of the critical path. >> + CriticalPathSU = 0; >> + CriticalPathMI = 0; >> + } >> + } >> + >> + PrescanInstruction(MI); >> + >> + if (MI->getDesc().hasExtraDefRegAllocReq()) >> + // If this instruction's defs have special allocation >> requirement, don't >> + // break this anti-dependency. >> + AntiDepReg = 0; >> + else if (AntiDepReg) { >> + // If this instruction has a use of AntiDepReg, breaking it >> + // is invalid. >> + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >> + MachineOperand &MO = MI->getOperand(i); >> + if (!MO.isReg()) continue; >> + unsigned Reg = MO.getReg(); >> + if (Reg == 0) continue; >> + if (MO.isUse() && AntiDepReg == Reg) { >> + AntiDepReg = 0; >> + break; >> + } >> + } >> + } >> + >> + // Determine AntiDepReg's register class, if it is live and is >> + // consistently used within a single class. >> + const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes >> [AntiDepReg] : 0; >> + assert((AntiDepReg == 0 || RC != NULL) && >> + "Register should be live if it's causing an anti- >> dependence!"); >> + if (RC == reinterpret_cast(-1)) >> + AntiDepReg = 0; >> + >> + // Look for a suitable register to use to break the anti- >> depenence. >> + // >> + // TODO: Instead of picking the first free register, consider >> which might >> + // be the best. >> + if (AntiDepReg != 0) { >> + if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg, >> + LastNewReg >> [AntiDepReg], >> + RC)) { >> + DEBUG(errs() << "Breaking anti-dependence edge on " >> + << TRI->getName(AntiDepReg) >> + << " with " << RegRefs.count(AntiDepReg) << " >> references" >> + << " using " << TRI->getName(NewReg) << "!\n"); >> + >> + // Update the references to the old register to refer to >> the new >> + // register. >> + std::pair> *>::iterator, >> + std::multimap> *>::iterator> >> + Range = RegRefs.equal_range(AntiDepReg); >> + for (std::multimap::iterator >> + Q = Range.first, QE = Range.second; Q != QE; ++Q) >> + Q->second->setReg(NewReg); >> + >> + // We just went back in time and modified history; the >> + // liveness information for the anti-depenence reg is now >> + // inconsistent. Set the state as if it were dead. >> + Classes[NewReg] = Classes[AntiDepReg]; >> + DefIndices[NewReg] = DefIndices[AntiDepReg]; >> + KillIndices[NewReg] = KillIndices[AntiDepReg]; >> + assert(((KillIndices[NewReg] == ~0u) != >> + (DefIndices[NewReg] == ~0u)) && >> + "Kill and Def maps aren't consistent for NewReg!"); >> + >> + Classes[AntiDepReg] = 0; >> + DefIndices[AntiDepReg] = KillIndices[AntiDepReg]; >> + KillIndices[AntiDepReg] = ~0u; >> + assert(((KillIndices[AntiDepReg] == ~0u) != >> + (DefIndices[AntiDepReg] == ~0u)) && >> + "Kill and Def maps aren't consistent for AntiDepReg!"); >> + >> + RegRefs.erase(AntiDepReg); >> + LastNewReg[AntiDepReg] = NewReg; >> + ++Broken; >> + } >> + } >> + >> + ScanInstruction(MI, Count); >> + } >> + >> + return Broken; >> +} >> >> Added: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h?rev=85127&view=auto >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h (added) >> +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h Mon Oct 26 >> 11:59:04 2009 >> @@ -0,0 +1,95 @@ >> +//=- llvm/CodeGen/CriticalAntiDepBreaker.h - Anti-Dep Support -*- C >> ++ -*-=// >> +// >> +// The LLVM Compiler Infrastructure >> +// >> +// This file is distributed under the University of Illinois Open >> Source >> +// License. See LICENSE.TXT for details. >> +// >> +// >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> +// >> +// This file implements the CriticalAntiDepBreaker class, which >> +// implements register anti-dependence breaking along a blocks >> +// critical path during post-RA scheduler. >> +// >> +// >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> + >> +#ifndef LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H >> +#define LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H >> + >> +#include "llvm/CodeGen/AntiDepBreaker.h" >> +#include "llvm/CodeGen/MachineBasicBlock.h" >> +#include "llvm/CodeGen/MachineFrameInfo.h" >> +#include "llvm/CodeGen/MachineFunction.h" >> +#include "llvm/CodeGen/MachineRegisterInfo.h" >> +#include "llvm/CodeGen/ScheduleDAG.h" >> +#include "llvm/Target/TargetRegisterInfo.h" >> +#include "llvm/ADT/BitVector.h" >> +#include "llvm/ADT/SmallSet.h" >> + >> +namespace llvm { >> + class CriticalAntiDepBreaker : public AntiDepBreaker { >> + MachineFunction& MF; >> + MachineRegisterInfo &MRI; >> + const TargetRegisterInfo *TRI; >> + >> + /// AllocatableSet - The set of allocatable registers. >> + /// We'll be ignoring anti-dependencies on non-allocatable >> registers, >> + /// because they may not be safe to break. >> + const BitVector AllocatableSet; >> + >> + /// Classes - For live regs that are only used in one register >> class in a >> + /// live range, the register class. If the register is not >> live, the >> + /// corresponding value is null. If the register is live but >> used in >> + /// multiple register classes, the corresponding value is -1 >> casted to a >> + /// pointer. >> + const TargetRegisterClass * >> + Classes[TargetRegisterInfo::FirstVirtualRegister]; >> + >> + /// RegRegs - Map registers to all their references within a >> live range. >> + std::multimap RegRefs; >> + >> + /// KillIndices - The index of the most recent kill (proceding >> bottom-up), >> + /// or ~0u if the register is not live. >> + unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; >> + >> + /// DefIndices - The index of the most recent complete def >> (proceding bottom >> + /// up), or ~0u if the register is live. >> + unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; >> + >> + /// KeepRegs - A set of registers which are live and cannot be >> changed to >> + /// break anti-dependencies. >> + SmallSet KeepRegs; >> + >> + public: >> + CriticalAntiDepBreaker(MachineFunction& MFi); >> + ~CriticalAntiDepBreaker(); >> + >> + /// Start - Initialize anti-dep breaking for a new basic block. >> + void StartBlock(MachineBasicBlock *BB); >> + >> + /// BreakAntiDependencies - Identifiy anti-dependencies along >> the critical path >> + /// of the ScheduleDAG and break them by renaming registers. >> + /// >> + unsigned BreakAntiDependencies(std::vector& SUnits, >> + MachineBasicBlock::iterator& >> Begin, >> + MachineBasicBlock::iterator& End, >> + unsigned InsertPosIndex); >> + >> + /// Observe - Update liveness information to account for the >> current >> + /// instruction, which will not be scheduled. >> + /// >> + void Observe(MachineInstr *MI, unsigned Count, unsigned >> InsertPosIndex); >> + >> + /// Finish - Finish anti-dep breaking for a basic block. >> + void FinishBlock(); >> + >> + private: >> + void PrescanInstruction(MachineInstr *MI); >> + void ScanInstruction(MachineInstr *MI, unsigned Count); >> + unsigned findSuitableFreeRegister(unsigned AntiDepReg, >> + unsigned LastNewReg, >> + const TargetRegisterClass *); >> + }; >> +} >> + >> +#endif >> >> Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=85127&r1=85126&r2=85127&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) >> +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Mon Oct 26 >> 11:59:04 2009 >> @@ -19,6 +19,7 @@ >> // >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> >> #define DEBUG_TYPE "post-RA-sched" >> +#include "CriticalAntiDepBreaker.h" >> #include "ExactHazardRecognizer.h" >> #include "SimpleHazardRecognizer.h" >> #include "ScheduleDAGInstrs.h" >> @@ -40,6 +41,7 @@ >> #include "llvm/Support/Debug.h" >> #include "llvm/Support/ErrorHandling.h" >> #include "llvm/Support/raw_ostream.h" >> +#include "llvm/ADT/BitVector.h" >> #include "llvm/ADT/Statistic.h" >> #include >> #include >> @@ -47,6 +49,7 @@ >> >> STATISTIC(NumNoops, "Number of noops inserted"); >> STATISTIC(NumStalls, "Number of pipeline stalls"); >> +STATISTIC(NumFixedAnti, "Number of fixed anti-dependencies"); >> >> // Post-RA scheduling is enabled with >> // TargetSubtarget.enablePostRAScheduler(). This flag can be used to >> @@ -55,10 +58,11 @@ >> EnablePostRAScheduler("post-RA-scheduler", >> cl::desc("Enable scheduling after register >> allocation"), >> cl::init(false), cl::Hidden); >> -static cl::opt >> +static cl::opt >> EnableAntiDepBreaking("break-anti-dependencies", >> - cl::desc("Break post-RA scheduling anti- >> dependencies"), >> - cl::init(true), cl::Hidden); >> + cl::desc("Break post-RA scheduling anti- >> dependencies: " >> + "\"critical\", \"all\", or \"none >> \""), >> + cl::init("none"), cl::Hidden); >> static cl::opt >> EnablePostRAHazardAvoidance("avoid-hazards", >> cl::desc("Enable exact hazard avoidance"), >> @@ -116,56 +120,30 @@ >> /// Topo - A topological ordering for SUnits. >> ScheduleDAGTopologicalSort Topo; >> >> - /// AllocatableSet - The set of allocatable registers. >> - /// We'll be ignoring anti-dependencies on non-allocatable >> registers, >> - /// because they may not be safe to break. >> - const BitVector AllocatableSet; >> - >> /// HazardRec - The hazard recognizer to use. >> ScheduleHazardRecognizer *HazardRec; >> >> + /// AntiDepBreak - Anti-dependence breaking object, or NULL if >> none >> + AntiDepBreaker *AntiDepBreak; >> + >> /// AA - AliasAnalysis for making memory reference queries. >> AliasAnalysis *AA; >> >> - /// AntiDepMode - Anti-dependence breaking mode >> - TargetSubtarget::AntiDepBreakMode AntiDepMode; >> - >> - /// Classes - For live regs that are only used in one register >> class in a >> - /// live range, the register class. If the register is not >> live, the >> - /// corresponding value is null. If the register is live but >> used in >> - /// multiple register classes, the corresponding value is -1 >> casted to a >> - /// pointer. >> - const TargetRegisterClass * >> - Classes[TargetRegisterInfo::FirstVirtualRegister]; >> - >> - /// RegRegs - Map registers to all their references within a >> live range. >> - std::multimap RegRefs; >> - >> /// KillIndices - The index of the most recent kill (proceding >> bottom-up), >> /// or ~0u if the register is not live. >> unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; >> >> - /// DefIndices - The index of the most recent complete def >> (proceding bottom >> - /// up), or ~0u if the register is live. >> - unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; >> - >> - /// KeepRegs - A set of registers which are live and cannot be >> changed to >> - /// break anti-dependencies. >> - SmallSet KeepRegs; >> - >> public: >> SchedulePostRATDList(MachineFunction &MF, >> const MachineLoopInfo &MLI, >> const MachineDominatorTree &MDT, >> ScheduleHazardRecognizer *HR, >> - AliasAnalysis *aa, >> - TargetSubtarget::AntiDepBreakMode adm) >> + AntiDepBreaker *ADB, >> + AliasAnalysis *aa) >> : ScheduleDAGInstrs(MF, MLI, MDT), Topo(SUnits), >> - AllocatableSet(TRI->getAllocatableSet(MF)), >> - HazardRec(HR), AA(aa), AntiDepMode(adm) {} >> + HazardRec(HR), AntiDepBreak(ADB), AA(aa) {} >> >> ~SchedulePostRATDList() { >> - delete HazardRec; >> } >> >> /// StartBlock - Initialize register live-range state for >> scheduling in >> @@ -177,11 +155,6 @@ >> /// >> void Schedule(); >> >> - /// FixupKills - Fix register kill flags that have been made >> - /// invalid due to scheduling >> - /// >> - void FixupKills(MachineBasicBlock *MBB); >> - >> /// Observe - Update liveness information to account for the >> current >> /// instruction, which will not be scheduled. >> /// >> @@ -191,17 +164,16 @@ >> /// >> void FinishBlock(); >> >> + /// FixupKills - Fix register kill flags that have been made >> + /// invalid due to scheduling >> + /// >> + void FixupKills(MachineBasicBlock *MBB); >> + >> private: >> - void PrescanInstruction(MachineInstr *MI); >> - void ScanInstruction(MachineInstr *MI, unsigned Count); >> void ReleaseSucc(SUnit *SU, SDep *SuccEdge); >> void ReleaseSuccessors(SUnit *SU); >> void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); >> void ListScheduleTopDown(); >> - bool BreakAntiDependencies(); >> - unsigned findSuitableFreeRegister(unsigned AntiDepReg, >> - unsigned LastNewReg, >> - const TargetRegisterClass *); >> void StartBlockForKills(MachineBasicBlock *BB); >> >> // ToggleKillFlag - Toggle a register operand kill flag. Other >> @@ -250,8 +222,9 @@ >> >> // Check for antidep breaking override... >> if (EnableAntiDepBreaking.getPosition() > 0) { >> - AntiDepMode = (EnableAntiDepBreaking) ? >> - TargetSubtarget::ANTIDEP_CRITICAL : >> TargetSubtarget::ANTIDEP_NONE; >> + AntiDepMode = (EnableAntiDepBreaking == "all") ? >> TargetSubtarget::ANTIDEP_ALL : >> + (EnableAntiDepBreaking == "critical") ? >> TargetSubtarget::ANTIDEP_CRITICAL : >> + TargetSubtarget::ANTIDEP_NONE; >> } >> >> DEBUG(errs() << "PostRAScheduler\n"); >> @@ -262,8 +235,12 @@ >> ScheduleHazardRecognizer *HR = EnablePostRAHazardAvoidance ? >> (ScheduleHazardRecognizer *)new ExactHazardRecognizer >> (InstrItins) : >> (ScheduleHazardRecognizer *)new SimpleHazardRecognizer(); >> + AntiDepBreaker *ADB = >> + (AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? NULL /* FIXME >> */ : >> + (AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? >> + new CriticalAntiDepBreaker(Fn) : NULL; >> >> - SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, AA, AntiDepMode); >> + SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, ADB, AA); >> >> // Loop over all of the basic blocks >> for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); >> @@ -311,6 +288,9 @@ >> Scheduler.FixupKills(MBB); >> } >> >> + delete HR; >> + delete ADB; >> + >> return true; >> } >> >> @@ -321,78 +301,10 @@ >> // Call the superclass. >> ScheduleDAGInstrs::StartBlock(BB); >> >> - // Reset the hazard recognizer. >> + // Reset the hazard recognizer and anti-dep breaker. >> HazardRec->Reset(); >> - >> - // Clear out the register class data. >> - std::fill(Classes, array_endof(Classes), >> - static_cast(0)); >> - >> - // Initialize the indices to indicate that no registers are live. >> - std::fill(KillIndices, array_endof(KillIndices), ~0u); >> - std::fill(DefIndices, array_endof(DefIndices), BB->size()); >> - >> - // Clear "do not change" set. >> - KeepRegs.clear(); >> - >> - bool IsReturnBlock = (!BB->empty() && BB->back().getDesc >> ().isReturn()); >> - >> - // Determine the live-out physregs for this block. >> - if (IsReturnBlock) { >> - // In a return block, examine the function live-out regs. >> - for (MachineRegisterInfo::liveout_iterator I = >> MRI.liveout_begin(), >> - E = MRI.liveout_end(); I != E; ++I) { >> - unsigned Reg = *I; >> - Classes[Reg] = reinterpret_cast(-1); >> - KillIndices[Reg] = BB->size(); >> - DefIndices[Reg] = ~0u; >> - // Repeat, for all aliases. >> - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; + >> +Alias) { >> - unsigned AliasReg = *Alias; >> - Classes[AliasReg] = reinterpret_cast >> (-1); >> - KillIndices[AliasReg] = BB->size(); >> - DefIndices[AliasReg] = ~0u; >> - } >> - } >> - } else { >> - // In a non-return block, examine the live-in regs of all >> successors. >> - for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), >> - SE = BB->succ_end(); SI != SE; ++SI) >> - for (MachineBasicBlock::livein_iterator I = (*SI)- >> >livein_begin(), >> - E = (*SI)->livein_end(); I != E; ++I) { >> - unsigned Reg = *I; >> - Classes[Reg] = reinterpret_cast(-1); >> - KillIndices[Reg] = BB->size(); >> - DefIndices[Reg] = ~0u; >> - // Repeat, for all aliases. >> - for (const unsigned *Alias = TRI->getAliasSet(Reg); >> *Alias; ++Alias) { >> - unsigned AliasReg = *Alias; >> - Classes[AliasReg] = reinterpret_cast> *>(-1); >> - KillIndices[AliasReg] = BB->size(); >> - DefIndices[AliasReg] = ~0u; >> - } >> - } >> - } >> - >> - // Mark live-out callee-saved registers. In a return block this is >> - // all callee-saved registers. In non-return this is any >> - // callee-saved register that is not saved in the prolog. >> - const MachineFrameInfo *MFI = MF.getFrameInfo(); >> - BitVector Pristine = MFI->getPristineRegs(BB); >> - for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { >> - unsigned Reg = *I; >> - if (!IsReturnBlock && !Pristine.test(Reg)) continue; >> - Classes[Reg] = reinterpret_cast(-1); >> - KillIndices[Reg] = BB->size(); >> - DefIndices[Reg] = ~0u; >> - // Repeat, for all aliases. >> - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; + >> +Alias) { >> - unsigned AliasReg = *Alias; >> - Classes[AliasReg] = reinterpret_cast >> (-1); >> - KillIndices[AliasReg] = BB->size(); >> - DefIndices[AliasReg] = ~0u; >> - } >> - } >> + if (AntiDepBreak != NULL) >> + AntiDepBreak->StartBlock(BB); >> } >> >> /// Schedule - Schedule the instruction range using list scheduling. >> @@ -403,8 +315,11 @@ >> // Build the scheduling graph. >> BuildSchedGraph(AA); >> >> - if (AntiDepMode != TargetSubtarget::ANTIDEP_NONE) { >> - if (BreakAntiDependencies()) { >> + if (AntiDepBreak != NULL) { >> + unsigned Broken = >> + AntiDepBreak->BreakAntiDependencies(SUnits, Begin, InsertPos, >> + InsertPosIndex); >> + if (Broken > 0) { >> // We made changes. Update the dependency graph. >> // Theoretically we could update the graph in place: >> // When a live range is changed to use a different register, >> remove >> @@ -415,6 +330,8 @@ >> EntrySU = SUnit(); >> ExitSU = SUnit(); >> BuildSchedGraph(AA); >> + >> + NumFixedAnti += Broken; >> } >> } >> >> @@ -432,436 +349,20 @@ >> /// instruction, which will not be scheduled. >> /// >> void SchedulePostRATDList::Observe(MachineInstr *MI, unsigned >> Count) { >> - assert(Count < InsertPosIndex && "Instruction index out of >> expected range!"); >> - >> - // Any register which was defined within the previous scheduling >> region >> - // may have been rescheduled and its lifetime may overlap with >> registers >> - // in ways not reflected in our current liveness state. For each >> such >> - // register, adjust the liveness state to be conservatively >> correct. >> - for (unsigned Reg = 0; Reg != >> TargetRegisterInfo::FirstVirtualRegister; ++Reg) >> - if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= >> Count) { >> - assert(KillIndices[Reg] == ~0u && "Clobbered register is >> live!"); >> - // Mark this register to be non-renamable. >> - Classes[Reg] = reinterpret_cast(-1); >> - // Move the def index to the end of the previous region, to >> reflect >> - // that the def could theoretically have been scheduled at >> the end. >> - DefIndices[Reg] = InsertPosIndex; >> - } >> - >> - PrescanInstruction(MI); >> - ScanInstruction(MI, Count); >> + if (AntiDepBreak != NULL) >> + AntiDepBreak->Observe(MI, Count, InsertPosIndex); >> } >> >> /// FinishBlock - Clean up register live-range state. >> /// >> void SchedulePostRATDList::FinishBlock() { >> - RegRefs.clear(); >> + if (AntiDepBreak != NULL) >> + AntiDepBreak->FinishBlock(); >> >> // Call the superclass. >> ScheduleDAGInstrs::FinishBlock(); >> } >> >> -/// CriticalPathStep - Return the next SUnit after SU on the >> bottom-up >> -/// critical path. >> -static SDep *CriticalPathStep(SUnit *SU) { >> - SDep *Next = 0; >> - unsigned NextDepth = 0; >> - // Find the predecessor edge with the greatest depth. >> - for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU- >> >Preds.end(); >> - P != PE; ++P) { >> - SUnit *PredSU = P->getSUnit(); >> - unsigned PredLatency = P->getLatency(); >> - unsigned PredTotalLatency = PredSU->getDepth() + PredLatency; >> - // In the case of a latency tie, prefer an anti-dependency >> edge over >> - // other types of edges. >> - if (NextDepth < PredTotalLatency || >> - (NextDepth == PredTotalLatency && P->getKind() == >> SDep::Anti)) { >> - NextDepth = PredTotalLatency; >> - Next = &*P; >> - } >> - } >> - return Next; >> -} >> - >> -void SchedulePostRATDList::PrescanInstruction(MachineInstr *MI) { >> - // Scan the register operands for this instruction and update >> - // Classes and RegRefs. >> - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >> - MachineOperand &MO = MI->getOperand(i); >> - if (!MO.isReg()) continue; >> - unsigned Reg = MO.getReg(); >> - if (Reg == 0) continue; >> - const TargetRegisterClass *NewRC = 0; >> - >> - if (i < MI->getDesc().getNumOperands()) >> - NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); >> - >> - // For now, only allow the register to be changed if its >> register >> - // class is consistent across all uses. >> - if (!Classes[Reg] && NewRC) >> - Classes[Reg] = NewRC; >> - else if (!NewRC || Classes[Reg] != NewRC) >> - Classes[Reg] = reinterpret_cast(-1); >> - >> - // Now check for aliases. >> - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; + >> +Alias) { >> - // If an alias of the reg is used during the live range, >> give up. >> - // Note that this allows us to skip checking if AntiDepReg >> - // overlaps with any of the aliases, among other things. >> - unsigned AliasReg = *Alias; >> - if (Classes[AliasReg]) { >> - Classes[AliasReg] = reinterpret_cast >> (-1); >> - Classes[Reg] = reinterpret_cast(-1); >> - } >> - } >> - >> - // If we're still willing to consider this register, note the >> reference. >> - if (Classes[Reg] != reinterpret_cast(-1)) >> - RegRefs.insert(std::make_pair(Reg, &MO)); >> - >> - // It's not safe to change register allocation for source >> operands of >> - // that have special allocation requirements. >> - if (MO.isUse() && MI->getDesc().hasExtraSrcRegAllocReq()) { >> - if (KeepRegs.insert(Reg)) { >> - for (const unsigned *Subreg = TRI->getSubRegisters(Reg); >> - *Subreg; ++Subreg) >> - KeepRegs.insert(*Subreg); >> - } >> - } >> - } >> -} >> - >> -void SchedulePostRATDList::ScanInstruction(MachineInstr *MI, >> - unsigned Count) { >> - // Update liveness. >> - // Proceding upwards, registers that are defed but not used in >> this >> - // instruction are now dead. >> - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >> - MachineOperand &MO = MI->getOperand(i); >> - if (!MO.isReg()) continue; >> - unsigned Reg = MO.getReg(); >> - if (Reg == 0) continue; >> - if (!MO.isDef()) continue; >> - // Ignore two-addr defs. >> - if (MI->isRegTiedToUseOperand(i)) continue; >> - >> - DefIndices[Reg] = Count; >> - KillIndices[Reg] = ~0u; >> - assert(((KillIndices[Reg] == ~0u) != >> - (DefIndices[Reg] == ~0u)) && >> - "Kill and Def maps aren't consistent for Reg!"); >> - KeepRegs.erase(Reg); >> - Classes[Reg] = 0; >> - RegRefs.erase(Reg); >> - // Repeat, for all subregs. >> - for (const unsigned *Subreg = TRI->getSubRegisters(Reg); >> - *Subreg; ++Subreg) { >> - unsigned SubregReg = *Subreg; >> - DefIndices[SubregReg] = Count; >> - KillIndices[SubregReg] = ~0u; >> - KeepRegs.erase(SubregReg); >> - Classes[SubregReg] = 0; >> - RegRefs.erase(SubregReg); >> - } >> - // Conservatively mark super-registers as unusable. >> - for (const unsigned *Super = TRI->getSuperRegisters(Reg); >> - *Super; ++Super) { >> - unsigned SuperReg = *Super; >> - Classes[SuperReg] = reinterpret_cast >> (-1); >> - } >> - } >> - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >> - MachineOperand &MO = MI->getOperand(i); >> - if (!MO.isReg()) continue; >> - unsigned Reg = MO.getReg(); >> - if (Reg == 0) continue; >> - if (!MO.isUse()) continue; >> - >> - const TargetRegisterClass *NewRC = 0; >> - if (i < MI->getDesc().getNumOperands()) >> - NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); >> - >> - // For now, only allow the register to be changed if its >> register >> - // class is consistent across all uses. >> - if (!Classes[Reg] && NewRC) >> - Classes[Reg] = NewRC; >> - else if (!NewRC || Classes[Reg] != NewRC) >> - Classes[Reg] = reinterpret_cast(-1); >> - >> - RegRefs.insert(std::make_pair(Reg, &MO)); >> - >> - // It wasn't previously live but now it is, this is a kill. >> - if (KillIndices[Reg] == ~0u) { >> - KillIndices[Reg] = Count; >> - DefIndices[Reg] = ~0u; >> - assert(((KillIndices[Reg] == ~0u) != >> - (DefIndices[Reg] == ~0u)) && >> - "Kill and Def maps aren't consistent for Reg!"); >> - } >> - // Repeat, for all aliases. >> - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; + >> +Alias) { >> - unsigned AliasReg = *Alias; >> - if (KillIndices[AliasReg] == ~0u) { >> - KillIndices[AliasReg] = Count; >> - DefIndices[AliasReg] = ~0u; >> - } >> - } >> - } >> -} >> - >> -unsigned >> -SchedulePostRATDList::findSuitableFreeRegister(unsigned AntiDepReg, >> - unsigned LastNewReg, >> - const >> TargetRegisterClass *RC) { >> - for (TargetRegisterClass::iterator R = RC->allocation_order_begin >> (MF), >> - RE = RC->allocation_order_end(MF); R != RE; ++R) { >> - unsigned NewReg = *R; >> - // Don't replace a register with itself. >> - if (NewReg == AntiDepReg) continue; >> - // Don't replace a register with one that was recently used to >> repair >> - // an anti-dependence with this AntiDepReg, because that would >> - // re-introduce that anti-dependence. >> - if (NewReg == LastNewReg) continue; >> - // If NewReg is dead and NewReg's most recent def is not before >> - // AntiDepReg's kill, it's safe to replace AntiDepReg with >> NewReg. >> - assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices >> [AntiDepReg] == ~0u)) && >> - "Kill and Def maps aren't consistent for AntiDepReg!"); >> - assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == >> ~0u)) && >> - "Kill and Def maps aren't consistent for NewReg!"); >> - if (KillIndices[NewReg] != ~0u || >> - Classes[NewReg] == reinterpret_cast >> (-1) || >> - KillIndices[AntiDepReg] > DefIndices[NewReg]) >> - continue; >> - return NewReg; >> - } >> - >> - // No registers are free and available! >> - return 0; >> -} >> - >> -/// BreakAntiDependencies - Identifiy anti-dependencies along the >> critical path >> -/// of the ScheduleDAG and break them by renaming registers. >> -/// >> -bool SchedulePostRATDList::BreakAntiDependencies() { >> - // The code below assumes that there is at least one instruction, >> - // so just duck out immediately if the block is empty. >> - if (SUnits.empty()) return false; >> - >> - // Find the node at the bottom of the critical path. >> - SUnit *Max = 0; >> - for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { >> - SUnit *SU = &SUnits[i]; >> - if (!Max || SU->getDepth() + SU->Latency > Max->getDepth() + >> Max->Latency) >> - Max = SU; >> - } >> - >> -#ifndef NDEBUG >> - { >> - DEBUG(errs() << "Critical path has total latency " >> - << (Max->getDepth() + Max->Latency) << "\n"); >> - DEBUG(errs() << "Available regs:"); >> - for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { >> - if (KillIndices[Reg] == ~0u) >> - DEBUG(errs() << " " << TRI->getName(Reg)); >> - } >> - DEBUG(errs() << '\n'); >> - } >> -#endif >> - >> - // Track progress along the critical path through the SUnit >> graph as we walk >> - // the instructions. >> - SUnit *CriticalPathSU = Max; >> - MachineInstr *CriticalPathMI = CriticalPathSU->getInstr(); >> - >> - // Consider this pattern: >> - // A = ... >> - // ... = A >> - // A = ... >> - // ... = A >> - // A = ... >> - // ... = A >> - // A = ... >> - // ... = A >> - // There are three anti-dependencies here, and without special >> care, >> - // we'd break all of them using the same register: >> - // A = ... >> - // ... = A >> - // B = ... >> - // ... = B >> - // B = ... >> - // ... = B >> - // B = ... >> - // ... = B >> - // because at each anti-dependence, B is the first register that >> - // isn't A which is free. This re-introduces anti-dependencies >> - // at all but one of the original anti-dependencies that we were >> - // trying to break. To avoid this, keep track of the most recent >> - // register that each register was replaced with, avoid >> - // using it to repair an anti-dependence on the same register. >> - // This lets us produce this: >> - // A = ... >> - // ... = A >> - // B = ... >> - // ... = B >> - // C = ... >> - // ... = C >> - // B = ... >> - // ... = B >> - // This still has an anti-dependence on B, but at least it isn't >> on the >> - // original critical path. >> - // >> - // TODO: If we tracked more than one register here, we could >> potentially >> - // fix that remaining critical edge too. This is a little more >> involved, >> - // because unlike the most recent register, less recent >> registers should >> - // still be considered, though only if no other registers are >> available. >> - unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = >> {}; >> - >> - // Attempt to break anti-dependence edges on the critical path. >> Walk the >> - // instructions from the bottom up, tracking information about >> liveness >> - // as we go to help determine which registers are available. >> - bool Changed = false; >> - unsigned Count = InsertPosIndex - 1; >> - for (MachineBasicBlock::iterator I = InsertPos, E = Begin; >> - I != E; --Count) { >> - MachineInstr *MI = --I; >> - >> - // Check if this instruction has a dependence on the critical >> path that >> - // is an anti-dependence that we may be able to break. If it >> is, set >> - // AntiDepReg to the non-zero register associated with the >> anti-dependence. >> - // >> - // We limit our attention to the critical path as a heuristic >> to avoid >> - // breaking anti-dependence edges that aren't going to >> significantly >> - // impact the overall schedule. There are a limited number of >> registers >> - // and we want to save them for the important edges. >> - // >> - // TODO: Instructions with multiple defs could have multiple >> - // anti-dependencies. The current code here only knows how to >> break one >> - // edge per instruction. Note that we'd have to be able to >> break all of >> - // the anti-dependencies in an instruction in order to be >> effective. >> - unsigned AntiDepReg = 0; >> - if (MI == CriticalPathMI) { >> - if (SDep *Edge = CriticalPathStep(CriticalPathSU)) { >> - SUnit *NextSU = Edge->getSUnit(); >> - >> - // Only consider anti-dependence edges. >> - if (Edge->getKind() == SDep::Anti) { >> - AntiDepReg = Edge->getReg(); >> - assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); >> - if (!AllocatableSet.test(AntiDepReg)) >> - // Don't break anti-dependencies on non-allocatable >> registers. >> - AntiDepReg = 0; >> - else if (KeepRegs.count(AntiDepReg)) >> - // Don't break anti-dependencies if an use down below >> requires >> - // this exact register. >> - AntiDepReg = 0; >> - else { >> - // If the SUnit has other dependencies on the SUnit >> that it >> - // anti-depends on, don't bother breaking the anti- >> dependency >> - // since those edges would prevent such units from being >> - // scheduled past each other regardless. >> - // >> - // Also, if there are dependencies on other SUnits >> with the >> - // same register as the anti-dependency, don't attempt >> to >> - // break it. >> - for (SUnit::pred_iterator P = CriticalPathSU- >> >Preds.begin(), >> - PE = CriticalPathSU->Preds.end(); P != PE; ++P) >> - if (P->getSUnit() == NextSU ? >> - (P->getKind() != SDep::Anti || P->getReg() != >> AntiDepReg) : >> - (P->getKind() == SDep::Data && P->getReg() == >> AntiDepReg)) { >> - AntiDepReg = 0; >> - break; >> - } >> - } >> - } >> - CriticalPathSU = NextSU; >> - CriticalPathMI = CriticalPathSU->getInstr(); >> - } else { >> - // We've reached the end of the critical path. >> - CriticalPathSU = 0; >> - CriticalPathMI = 0; >> - } >> - } >> - >> - PrescanInstruction(MI); >> - >> - if (MI->getDesc().hasExtraDefRegAllocReq()) >> - // If this instruction's defs have special allocation >> requirement, don't >> - // break this anti-dependency. >> - AntiDepReg = 0; >> - else if (AntiDepReg) { >> - // If this instruction has a use of AntiDepReg, breaking it >> - // is invalid. >> - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >> - MachineOperand &MO = MI->getOperand(i); >> - if (!MO.isReg()) continue; >> - unsigned Reg = MO.getReg(); >> - if (Reg == 0) continue; >> - if (MO.isUse() && AntiDepReg == Reg) { >> - AntiDepReg = 0; >> - break; >> - } >> - } >> - } >> - >> - // Determine AntiDepReg's register class, if it is live and is >> - // consistently used within a single class. >> - const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes >> [AntiDepReg] : 0; >> - assert((AntiDepReg == 0 || RC != NULL) && >> - "Register should be live if it's causing an anti- >> dependence!"); >> - if (RC == reinterpret_cast(-1)) >> - AntiDepReg = 0; >> - >> - // Look for a suitable register to use to break the anti- >> depenence. >> - // >> - // TODO: Instead of picking the first free register, consider >> which might >> - // be the best. >> - if (AntiDepReg != 0) { >> - if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg, >> - LastNewReg >> [AntiDepReg], >> - RC)) { >> - DEBUG(errs() << "Breaking anti-dependence edge on " >> - << TRI->getName(AntiDepReg) >> - << " with " << RegRefs.count(AntiDepReg) << " >> references" >> - << " using " << TRI->getName(NewReg) << "!\n"); >> - >> - // Update the references to the old register to refer to >> the new >> - // register. >> - std::pair> *>::iterator, >> - std::multimap> *>::iterator> >> - Range = RegRefs.equal_range(AntiDepReg); >> - for (std::multimap::iterator >> - Q = Range.first, QE = Range.second; Q != QE; ++Q) >> - Q->second->setReg(NewReg); >> - >> - // We just went back in time and modified history; the >> - // liveness information for the anti-depenence reg is now >> - // inconsistent. Set the state as if it were dead. >> - Classes[NewReg] = Classes[AntiDepReg]; >> - DefIndices[NewReg] = DefIndices[AntiDepReg]; >> - KillIndices[NewReg] = KillIndices[AntiDepReg]; >> - assert(((KillIndices[NewReg] == ~0u) != >> - (DefIndices[NewReg] == ~0u)) && >> - "Kill and Def maps aren't consistent for NewReg!"); >> - >> - Classes[AntiDepReg] = 0; >> - DefIndices[AntiDepReg] = KillIndices[AntiDepReg]; >> - KillIndices[AntiDepReg] = ~0u; >> - assert(((KillIndices[AntiDepReg] == ~0u) != >> - (DefIndices[AntiDepReg] == ~0u)) && >> - "Kill and Def maps aren't consistent for AntiDepReg!"); >> - >> - RegRefs.erase(AntiDepReg); >> - Changed = true; >> - LastNewReg[AntiDepReg] = NewReg; >> - } >> - } >> - >> - ScanInstruction(MI, Count); >> - } >> - >> - return Changed; >> -} >> - >> /// StartBlockForKills - Initialize register live-range state for >> updating kills >> /// >> void SchedulePostRATDList::StartBlockForKills(MachineBasicBlock >> *BB) { >> >> Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=85127&r1=85126&r2=85127&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original) >> +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Mon Oct 26 11:59:04 2009 >> @@ -130,7 +130,7 @@ >> /// for Thumb1. >> bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, >> TargetSubtarget::AntiDepBreakMode& >> mode) const { >> - mode = TargetSubtarget::ANTIDEP_NONE; >> + mode = TargetSubtarget::ANTIDEP_CRITICAL; >> return PostRAScheduler && OptLevel >= CodeGenOpt::Default; >> } >> >> >> Modified: llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll?rev=85127&r1=85126&r2=85127&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll (original) >> +++ llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll Mon Oct >> 26 11:59:04 2009 >> @@ -1,7 +1,7 @@ >> -; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti- >> dependencies=false > %t >> +; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti- >> dependencies=none > %t >> ; RUN: grep {%xmm0} %t | count 14 >> ; RUN: not grep {%xmm1} %t >> -; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti- >> dependencies > %t >> +; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti- >> dependencies=critical > %t >> ; RUN: grep {%xmm0} %t | count 7 >> ; RUN: grep {%xmm1} %t | count 7 >> >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091026/7eecfdc4/attachment.html From wendling at apple.com Mon Oct 26 14:07:00 2009 From: wendling at apple.com (Bill Wendling) Date: Mon, 26 Oct 2009 12:07:00 -0700 Subject: [llvm-commits] [llvm] r85141 - /llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h In-Reply-To: <200910261900.n9QJ0lP6029737@zion.cs.uiuc.edu> References: <200910261900.n9QJ0lP6029737@zion.cs.uiuc.edu> Message-ID: On Oct 26, 2009, at 12:00 PM, David Goodwin wrote: > Author: david_goodwin > Date: Mon Oct 26 14:00:47 2009 > New Revision: 85141 > > URL: http://llvm.org/viewvc/llvm-project?rev=85141&view=rev > Log: > Add virtual destructor. > > Modified: > llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h > > Modified: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h?rev=85141&r1=85140&r2=85141&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h (original) > +++ llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Mon Oct 26 > 14:00:47 2009 > @@ -29,6 +29,8 @@ > /// anti-dependencies. > class AntiDepBreaker { > public: > + virtual ~AntiDepBreaker() { }; > + It's good to have the definition of a virtual destructor in the .cpp file. It "anchors" the vtable. -bw From gohman at apple.com Mon Oct 26 14:12:14 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 26 Oct 2009 19:12:14 -0000 Subject: [llvm-commits] [llvm] r85144 - in /llvm/trunk: include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/GEPSplitter.cpp Message-ID: <200910261912.n9QJCE4a030428@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 26 14:12:14 2009 New Revision: 85144 URL: http://llvm.org/viewvc/llvm-project?rev=85144&view=rev Log: Check in the experimental GEP splitter pass. This pass splits complex GEPs (more than one non-zero index) into simple GEPs (at most one non-zero index). In some simple experiments using this it's not uncommon to see 3% overall code size wins, because it exposes redundancies that can be eliminated, however it's tricky to use because instcombine aggressively undoes the work that this pass does. Added: llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp Modified: llvm/trunk/include/llvm/LinkAllPasses.h llvm/trunk/include/llvm/Transforms/Scalar.h Modified: llvm/trunk/include/llvm/LinkAllPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=85144&r1=85143&r2=85144&view=diff ============================================================================== --- llvm/trunk/include/llvm/LinkAllPasses.h (original) +++ llvm/trunk/include/llvm/LinkAllPasses.h Mon Oct 26 14:12:14 2009 @@ -141,6 +141,7 @@ (void) llvm::createPartialInliningPass(); (void) llvm::createSSIPass(); (void) llvm::createSSIEverythingPass(); + (void) llvm::createGEPSplitterPass(); (void)new llvm::IntervalPartition(); (void)new llvm::FindUsedTypes(); Modified: llvm/trunk/include/llvm/Transforms/Scalar.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=85144&r1=85143&r2=85144&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Scalar.h (original) +++ llvm/trunk/include/llvm/Transforms/Scalar.h Mon Oct 26 14:12:14 2009 @@ -341,6 +341,12 @@ // FunctionPass *createSSIEverythingPass(); +//===----------------------------------------------------------------------===// +// +// GEPSplitter - Split complex GEPs into simple ones +// +FunctionPass *createGEPSplitterPass(); + } // End llvm namespace #endif Added: llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp?rev=85144&view=auto ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp (added) +++ llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp Mon Oct 26 14:12:14 2009 @@ -0,0 +1,81 @@ +//===- GEPSplitter.cpp - Split complex GEPs into simple ones --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This function breaks GEPs with more than 2 non-zero operands into smaller +// GEPs each with no more than 2 non-zero operands. This exposes redundancy +// between GEPs with common initial operand sequences. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "split-geps" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Constants.h" +#include "llvm/Function.h" +#include "llvm/Instructions.h" +#include "llvm/Pass.h" +using namespace llvm; + +namespace { + class GEPSplitter : public FunctionPass { + virtual bool runOnFunction(Function &F); + virtual void getAnalysisUsage(AnalysisUsage &AU) const; + public: + static char ID; // Pass identification, replacement for typeid + explicit GEPSplitter() : FunctionPass(&ID) {} + }; +} + +char GEPSplitter::ID = 0; +static RegisterPass X("split-geps", + "split complex GEPs into simple GEPs"); + +FunctionPass *llvm::createGEPSplitterPass() { + return new GEPSplitter(); +} + +bool GEPSplitter::runOnFunction(Function &F) { + bool Changed = false; + + // Visit each GEP instruction. + for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) + for (BasicBlock::iterator II = I->begin(), IE = I->end(); II != IE; ) + if (GetElementPtrInst *GEP = dyn_cast(II++)) { + unsigned NumOps = GEP->getNumOperands(); + // Ignore GEPs which are already simple. + if (NumOps <= 2) + continue; + bool FirstIndexIsZero = isa(GEP->getOperand(1)) && + cast(GEP->getOperand(1))->isZero(); + if (NumOps == 3 && FirstIndexIsZero) + continue; + // The first index is special and gets expanded with a 2-operand GEP + // (unless it's zero, in which case we can skip this). + Value *NewGEP = FirstIndexIsZero ? + GEP->getOperand(0) : + GetElementPtrInst::Create(GEP->getOperand(0), GEP->getOperand(1), + "tmp", GEP); + // All remaining indices get expanded with a 3-operand GEP with zero + // as the second operand. + Value *Idxs[2]; + Idxs[0] = ConstantInt::get(Type::getInt64Ty(F.getContext()), 0); + for (unsigned i = 2; i != NumOps; ++i) { + Idxs[1] = GEP->getOperand(i); + NewGEP = GetElementPtrInst::Create(NewGEP, Idxs, Idxs+2, "tmp", GEP); + } + GEP->replaceAllUsesWith(NewGEP); + GEP->eraseFromParent(); + Changed = true; + } + + return Changed; +} + +void GEPSplitter::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); +} From jlerouge at apple.com Mon Oct 26 14:30:12 2009 From: jlerouge at apple.com (Julien Lerouge) Date: Mon, 26 Oct 2009 12:30:12 -0700 Subject: [llvm-commits] [llvm] r81719 - in /llvm/trunk: unittests/Makefile unittests/TestMain.cpp utils/unittest/Makefile utils/unittest/UnitTestMain/ utils/unittest/UnitTestMain/Makefile utils/unittest/UnitTestMain/TestMain.cpp In-Reply-To: <20090930215928.GA15682@pom.apple.com> References: <200909132131.n8DLVLIl028742@zion.cs.uiuc.edu> <20090918161136.GB59666@pom.apple.com> <5DDA39F1-474A-4D6D-A039-5B36C6597C5D@apple.com> <20090930215928.GA15682@pom.apple.com> Message-ID: <20091026193011.GA75617@pom.apple.com> On Wed, Sep 30, 2009 at 02:59:29PM -0700, Julien Lerouge wrote: > On Sun, Sep 27, 2009 at 02:20:39PM -0700, Chris Lattner wrote: > > On Sep 18, 2009, at 9:11 AM, Julien Lerouge wrote: > >>> +++ llvm/trunk/utils/unittest/UnitTestMain/Makefile Sun Sep 13 16:31:21 > >>> 2009 > >>> @@ -16,9 +16,4 @@ > >>> CPP.Flags += -I$(LLVM_SRC_ROOT)/utils/unittest/googletest/include > >>> CPP.Flags += -Wno-variadic-macros > >>> > >> > >> -Wno-variadic-macros is not supported with older GCC, can we re-use the > >> logic in googletest/Makefile ? patch attached. > > > > This patch seems reasonable to me, though an autoconf check for those flags > > would be even better (make builds go faster). > > > > This patch adds an autoconf check and removes another flag that was used > in unittests/Makefile.unittest. I have kept the orignal names (NO_xxx). > Should fix the build with older GCC. > > Thanks, > Julien Is it ok to commit this thing ? It's blocking the build of LLVM on MingW with gcc < 4 http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20090928/088200.html Thanks, Julien -- Julien Lerouge PGP Key Id: 0xB1964A62 PGP Fingerprint: 392D 4BAD DB8B CE7F 4E5F FA3C 62DB 4AA7 B196 4A62 PGP Public Key from: keyserver.pgp.com From david_goodwin at apple.com Mon Oct 26 14:32:57 2009 From: david_goodwin at apple.com (David Goodwin) Date: Mon, 26 Oct 2009 19:32:57 -0000 Subject: [llvm-commits] [llvm] r85145 - in /llvm/trunk/lib/CodeGen: AggressiveAntiDepBreaker.cpp AggressiveAntiDepBreaker.h CMakeLists.txt PostRASchedulerList.cpp Message-ID: <200910261933.n9QJX15N031496@zion.cs.uiuc.edu> Author: david_goodwin Date: Mon Oct 26 14:32:42 2009 New Revision: 85145 URL: http://llvm.org/viewvc/llvm-project?rev=85145&view=rev Log: Add aggressive anti-dependence breaker. Currently it is not the default for any target. Enable with -break-anti-dependencies=all. Added: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Added: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp?rev=85145&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp (added) +++ llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp Mon Oct 26 14:32:42 2009 @@ -0,0 +1,687 @@ +//===----- AggressiveAntiDepBreaker.cpp - Anti-dep breaker -------- ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the AggressiveAntiDepBreaker class, which +// implements register anti-dependence breaking during post-RA +// scheduling. It attempts to break all anti-dependencies within a +// block. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "aggressive-antidep" +#include "AggressiveAntiDepBreaker.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +AggressiveAntiDepBreaker:: +AggressiveAntiDepBreaker(MachineFunction& MFi) : + AntiDepBreaker(), MF(MFi), + MRI(MF.getRegInfo()), + TRI(MF.getTarget().getRegisterInfo()), + AllocatableSet(TRI->getAllocatableSet(MF)), + GroupNodes(TargetRegisterInfo::FirstVirtualRegister, 0) +{ +} + +AggressiveAntiDepBreaker::~AggressiveAntiDepBreaker() { +} + +void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { + // Initialize all registers to be in their own group. Initially we + // assign the register to the same-indexed GroupNode. + for (unsigned i = 0; i < TargetRegisterInfo::FirstVirtualRegister; ++i) + GroupNodeIndices[i] = i; + + // Initialize the indices to indicate that no registers are live. + std::fill(KillIndices, array_endof(KillIndices), ~0u); + std::fill(DefIndices, array_endof(DefIndices), BB->size()); + + bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn()); + + // Determine the live-out physregs for this block. + if (IsReturnBlock) { + // In a return block, examine the function live-out regs. + for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), + E = MRI.liveout_end(); I != E; ++I) { + unsigned Reg = *I; + UnionGroups(Reg, 0); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = ~0u; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + UnionGroups(AliasReg, 0); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = ~0u; + } + } + } else { + // In a non-return block, examine the live-in regs of all successors. + for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), + SE = BB->succ_end(); SI != SE; ++SI) + for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), + E = (*SI)->livein_end(); I != E; ++I) { + unsigned Reg = *I; + UnionGroups(Reg, 0); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = ~0u; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + UnionGroups(AliasReg, 0); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = ~0u; + } + } + } + + // Mark live-out callee-saved registers. In a return block this is + // all callee-saved registers. In non-return this is any + // callee-saved register that is not saved in the prolog. + const MachineFrameInfo *MFI = MF.getFrameInfo(); + BitVector Pristine = MFI->getPristineRegs(BB); + for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { + unsigned Reg = *I; + if (!IsReturnBlock && !Pristine.test(Reg)) continue; + UnionGroups(Reg, 0); + KillIndices[Reg] = BB->size(); + DefIndices[Reg] = ~0u; + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + UnionGroups(AliasReg, 0); + KillIndices[AliasReg] = BB->size(); + DefIndices[AliasReg] = ~0u; + } + } +} + +void AggressiveAntiDepBreaker::FinishBlock() { + RegRefs.clear(); +} + +void AggressiveAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count, + unsigned InsertPosIndex) { + assert(Count < InsertPosIndex && "Instruction index out of expected range!"); + + DEBUG(errs() << "Observe: "); + DEBUG(MI->dump()); + + for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) { + // If Reg is current live, then mark that it can't be renamed as + // we don't know the extent of its live-range anymore (now that it + // has been scheduled). If it is not live but was defined in the + // previous schedule region, then set its def index to the most + // conservative location (i.e. the beginning of the previous + // schedule region). + if (IsLive(Reg)) { + DEBUG(if (GetGroup(Reg) != 0) + errs() << " " << TRI->getName(Reg) << "=g" << + GetGroup(Reg) << "->g0(region live-out)"); + UnionGroups(Reg, 0); + } else if ((DefIndices[Reg] < InsertPosIndex) && (DefIndices[Reg] >= Count)) { + DefIndices[Reg] = Count; + } + } + + std::set PassthruRegs; + GetPassthruRegs(MI, PassthruRegs); + PrescanInstruction(MI, Count, PassthruRegs); + ScanInstruction(MI, Count); +} + +unsigned AggressiveAntiDepBreaker::GetGroup(unsigned Reg) +{ + unsigned Node = GroupNodeIndices[Reg]; + while (GroupNodes[Node] != Node) + Node = GroupNodes[Node]; + + return Node; +} + +void AggressiveAntiDepBreaker::GetGroupRegs(unsigned Group, std::vector &Regs) +{ + for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) { + if (GetGroup(Reg) == Group) + Regs.push_back(Reg); + } +} + +unsigned AggressiveAntiDepBreaker::UnionGroups(unsigned Reg1, unsigned Reg2) +{ + assert(GroupNodes[0] == 0 && "GroupNode 0 not parent!"); + assert(GroupNodeIndices[0] == 0 && "Reg 0 not in Group 0!"); + + // find group for each register + unsigned Group1 = GetGroup(Reg1); + unsigned Group2 = GetGroup(Reg2); + + // if either group is 0, then that must become the parent + unsigned Parent = (Group1 == 0) ? Group1 : Group2; + unsigned Other = (Parent == Group1) ? Group2 : Group1; + GroupNodes.at(Other) = Parent; + return Parent; +} + +unsigned AggressiveAntiDepBreaker::LeaveGroup(unsigned Reg) +{ + // Create a new GroupNode for Reg. Reg's existing GroupNode must + // stay as is because there could be other GroupNodes referring to + // it. + unsigned idx = GroupNodes.size(); + GroupNodes.push_back(idx); + GroupNodeIndices[Reg] = idx; + return idx; +} + +bool AggressiveAntiDepBreaker::IsLive(unsigned Reg) +{ + // KillIndex must be defined and DefIndex not defined for a register + // to be live. + return((KillIndices[Reg] != ~0u) && (DefIndices[Reg] == ~0u)); +} + +bool AggressiveAntiDepBreaker::IsImplicitDefUse(MachineInstr *MI, + MachineOperand& MO) +{ + if (!MO.isReg() || !MO.isImplicit()) + return false; + + unsigned Reg = MO.getReg(); + if (Reg == 0) + return false; + + MachineOperand *Op = NULL; + if (MO.isDef()) + Op = MI->findRegisterUseOperand(Reg, true); + else + Op = MI->findRegisterDefOperand(Reg); + + return((Op != NULL) && Op->isImplicit()); +} + +void AggressiveAntiDepBreaker::GetPassthruRegs(MachineInstr *MI, + std::set& PassthruRegs) { + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) continue; + if ((MO.isDef() && MI->isRegTiedToUseOperand(i)) || + IsImplicitDefUse(MI, MO)) { + const unsigned Reg = MO.getReg(); + PassthruRegs.insert(Reg); + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); + *Subreg; ++Subreg) { + PassthruRegs.insert(*Subreg); + } + } + } +} + +/// AntiDepPathStep - Return SUnit that SU has an anti-dependence on. +static void AntiDepPathStep(SUnit *SU, std::vector& Edges) { + SmallSet Dups; + for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end(); + P != PE; ++P) { + if (P->getKind() == SDep::Anti) { + unsigned Reg = P->getReg(); + if (Dups.count(Reg) == 0) { + Edges.push_back(&*P); + Dups.insert(Reg); + } + } + } +} + +void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Count, + std::set& PassthruRegs) { + // Scan the register defs for this instruction and update + // live-ranges, groups and RegRefs. + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isDef()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + // Ignore passthru registers for liveness... + if (PassthruRegs.count(Reg) != 0) continue; + + // Update Def for Reg and subregs. + DefIndices[Reg] = Count; + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); + *Subreg; ++Subreg) { + unsigned SubregReg = *Subreg; + DefIndices[SubregReg] = Count; + } + } + + DEBUG(errs() << "\tDef Groups:"); + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isDef()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + + DEBUG(errs() << " " << TRI->getName(Reg) << "=g" << GetGroup(Reg)); + + // If MI's defs have special allocation requirement, don't allow + // any def registers to be changed. Also assume all registers + // defined in a call must not be changed (ABI). + if (MI->getDesc().isCall() || MI->getDesc().hasExtraDefRegAllocReq()) { + DEBUG(if (GetGroup(Reg) != 0) errs() << "->g0(alloc-req)"); + UnionGroups(Reg, 0); + } + + // Any aliased that are live at this point are completely or + // partially defined here, so group those subregisters with Reg. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + if (IsLive(AliasReg)) { + UnionGroups(Reg, AliasReg); + DEBUG(errs() << "->g" << GetGroup(Reg) << "(via " << + TRI->getName(AliasReg) << ")"); + } + } + + // Note register reference... + const TargetRegisterClass *RC = NULL; + if (i < MI->getDesc().getNumOperands()) + RC = MI->getDesc().OpInfo[i].getRegClass(TRI); + RegisterReference RR = { &MO, RC }; + RegRefs.insert(std::make_pair(Reg, RR)); + } + + DEBUG(errs() << '\n'); +} + +void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI, + unsigned Count) { + DEBUG(errs() << "\tUse Groups:"); + + // Scan the register uses for this instruction and update + // live-ranges, groups and RegRefs. + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isUse()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + + DEBUG(errs() << " " << TRI->getName(Reg) << "=g" << GetGroup(Reg)); + + // It wasn't previously live but now it is, this is a kill. Forget + // the previous live-range information and start a new live-range + // for the register. + if (!IsLive(Reg)) { + KillIndices[Reg] = Count; + DefIndices[Reg] = ~0u; + RegRefs.erase(Reg); + LeaveGroup(Reg); + DEBUG(errs() << "->g" << GetGroup(Reg) << "(last-use)"); + } + // Repeat, for subregisters. + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); + *Subreg; ++Subreg) { + unsigned SubregReg = *Subreg; + if (!IsLive(SubregReg)) { + KillIndices[SubregReg] = Count; + DefIndices[SubregReg] = ~0u; + RegRefs.erase(SubregReg); + LeaveGroup(SubregReg); + DEBUG(errs() << " " << TRI->getName(SubregReg) << "->g" << + GetGroup(SubregReg) << "(last-use)"); + } + } + + // If MI's uses have special allocation requirement, don't allow + // any use registers to be changed. Also assume all registers + // used in a call must not be changed (ABI). + if (MI->getDesc().isCall() || MI->getDesc().hasExtraSrcRegAllocReq()) { + DEBUG(if (GetGroup(Reg) != 0) errs() << "->g0(alloc-req)"); + UnionGroups(Reg, 0); + } + + // Note register reference... + const TargetRegisterClass *RC = NULL; + if (i < MI->getDesc().getNumOperands()) + RC = MI->getDesc().OpInfo[i].getRegClass(TRI); + RegisterReference RR = { &MO, RC }; + RegRefs.insert(std::make_pair(Reg, RR)); + } + + DEBUG(errs() << '\n'); + + // Form a group of all defs and uses of a KILL instruction to ensure + // that all registers are renamed as a group. + if (MI->getOpcode() == TargetInstrInfo::KILL) { + DEBUG(errs() << "\tKill Group:"); + + unsigned FirstReg = 0; + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + + if (FirstReg != 0) { + DEBUG(errs() << "=" << TRI->getName(Reg)); + UnionGroups(FirstReg, Reg); + } else { + DEBUG(errs() << " " << TRI->getName(Reg)); + FirstReg = Reg; + } + } + + DEBUG(errs() << "->g" << GetGroup(FirstReg) << '\n'); + } +} + +BitVector AggressiveAntiDepBreaker::GetRenameRegisters(unsigned Reg) { + BitVector BV(TRI->getNumRegs(), false); + bool first = true; + + // Check all references that need rewriting for Reg. For each, use + // the corresponding register class to narrow the set of registers + // that are appropriate for renaming. + std::pair::iterator, + std::multimap::iterator> + Range = RegRefs.equal_range(Reg); + for (std::multimap::iterator + Q = Range.first, QE = Range.second; Q != QE; ++Q) { + const TargetRegisterClass *RC = Q->second.RC; + if (RC == NULL) continue; + + BitVector RCBV = TRI->getAllocatableSet(MF, RC); + if (first) { + BV |= RCBV; + first = false; + } else { + BV &= RCBV; + } + + DEBUG(errs() << " " << RC->getName()); + } + + return BV; +} + +bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters( + unsigned AntiDepGroupIndex, + std::map &RenameMap) { + // Collect all registers in the same group as AntiDepReg. These all + // need to be renamed together if we are to break the + // anti-dependence. + std::vector Regs; + GetGroupRegs(AntiDepGroupIndex, Regs); + assert(Regs.size() > 0 && "Empty register group!"); + if (Regs.size() == 0) + return false; + + // Find the "superest" register in the group. At the same time, + // collect the BitVector of registers that can be used to rename + // each register. + DEBUG(errs() << "\tRename Candidates for Group g" << AntiDepGroupIndex << ":\n"); + std::map RenameRegisterMap; + unsigned SuperReg = 0; + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + unsigned Reg = Regs[i]; + if ((SuperReg == 0) || TRI->isSuperRegister(SuperReg, Reg)) + SuperReg = Reg; + + // If Reg has any references, then collect possible rename regs + if (RegRefs.count(Reg) > 0) { + DEBUG(errs() << "\t\t" << TRI->getName(Reg) << ":"); + + BitVector BV = GetRenameRegisters(Reg); + RenameRegisterMap.insert(std::pair(Reg, BV)); + + DEBUG(errs() << " ::"); + DEBUG(for (int r = BV.find_first(); r != -1; r = BV.find_next(r)) + errs() << " " << TRI->getName(r)); + DEBUG(errs() << "\n"); + } + } + + // All group registers should be a subreg of SuperReg. + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + unsigned Reg = Regs[i]; + if (Reg == SuperReg) continue; + bool IsSub = TRI->isSubRegister(SuperReg, Reg); + assert(IsSub && "Expecting group subregister"); + if (!IsSub) + return false; + } + + // FIXME: for now just handle single register in group case... + if (Regs.size() > 1) + return false; + + // Check each possible rename register for SuperReg. If that register + // is available, and the corresponding registers are available for + // the other group subregisters, then we can use those registers to + // rename. + DEBUG(errs() << "\tFind Register:"); + BitVector SuperBV = RenameRegisterMap[SuperReg]; + for (int r = SuperBV.find_first(); r != -1; r = SuperBV.find_next(r)) { + const unsigned Reg = (unsigned)r; + // Don't replace a register with itself. + if (Reg == SuperReg) continue; + + DEBUG(errs() << " " << TRI->getName(Reg)); + + // If Reg is dead and Reg's most recent def is not before + // SuperRegs's kill, it's safe to replace SuperReg with + // Reg. We must also check all subregisters of Reg. + if (IsLive(Reg) || (KillIndices[SuperReg] > DefIndices[Reg])) { + DEBUG(errs() << "(live)"); + continue; + } else { + bool found = false; + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); + *Subreg; ++Subreg) { + unsigned SubregReg = *Subreg; + if (IsLive(SubregReg) || (KillIndices[SuperReg] > DefIndices[SubregReg])) { + DEBUG(errs() << "(subreg " << TRI->getName(SubregReg) << " live)"); + found = true; + break; + } + } + if (found) + continue; + } + + if (Reg != 0) { + DEBUG(errs() << '\n'); + RenameMap.insert(std::pair(SuperReg, Reg)); + return true; + } + } + + DEBUG(errs() << '\n'); + + // No registers are free and available! + return false; +} + +/// BreakAntiDependencies - Identifiy anti-dependencies within the +/// ScheduleDAG and break them by renaming registers. +/// +unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(std::vector& SUnits, + MachineBasicBlock::iterator& Begin, + MachineBasicBlock::iterator& End, + unsigned InsertPosIndex) { + // The code below assumes that there is at least one instruction, + // so just duck out immediately if the block is empty. + if (SUnits.empty()) return false; + + // ...need a map from MI to SUnit. + std::map MISUnitMap; + + DEBUG(errs() << "Breaking all anti-dependencies\n"); + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { + SUnit *SU = &SUnits[i]; + MISUnitMap.insert(std::pair(SU->getInstr(), SU)); + } + +#ifndef NDEBUG + { + DEBUG(errs() << "Available regs:"); + for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { + if (!IsLive(Reg)) + DEBUG(errs() << " " << TRI->getName(Reg)); + } + DEBUG(errs() << '\n'); + } +#endif + + // Attempt to break anti-dependence edges. Walk the instructions + // from the bottom up, tracking information about liveness as we go + // to help determine which registers are available. + unsigned Broken = 0; + unsigned Count = InsertPosIndex - 1; + for (MachineBasicBlock::iterator I = End, E = Begin; + I != E; --Count) { + MachineInstr *MI = --I; + + DEBUG(errs() << "Anti: "); + DEBUG(MI->dump()); + + std::set PassthruRegs; + GetPassthruRegs(MI, PassthruRegs); + + // Process the defs in MI... + PrescanInstruction(MI, Count, PassthruRegs); + + std::vector Edges; + SUnit *PathSU = MISUnitMap[MI]; + if (PathSU) + AntiDepPathStep(PathSU, Edges); + + // Ignore KILL instructions (they form a group in ScanInstruction + // but don't cause any anti-dependence breaking themselves) + if (MI->getOpcode() != TargetInstrInfo::KILL) { + // Attempt to break each anti-dependency... + for (unsigned i = 0, e = Edges.size(); i != e; ++i) { + SDep *Edge = Edges[i]; + SUnit *NextSU = Edge->getSUnit(); + + if (Edge->getKind() != SDep::Anti) continue; + + unsigned AntiDepReg = Edge->getReg(); + DEBUG(errs() << "\tAntidep reg: " << TRI->getName(AntiDepReg)); + assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); + + if (!AllocatableSet.test(AntiDepReg)) { + // Don't break anti-dependencies on non-allocatable registers. + DEBUG(errs() << " (non-allocatable)\n"); + continue; + } else if (PassthruRegs.count(AntiDepReg) != 0) { + // If the anti-dep register liveness "passes-thru", then + // don't try to change it. It will be changed along with + // the use if required to break an earlier antidep. + DEBUG(errs() << " (passthru)\n"); + continue; + } else { + // No anti-dep breaking for implicit deps + MachineOperand *AntiDepOp = MI->findRegisterDefOperand(AntiDepReg); + assert(AntiDepOp != NULL && "Can't find index for defined register operand"); + if ((AntiDepOp == NULL) || AntiDepOp->isImplicit()) { + DEBUG(errs() << " (implicit)\n"); + continue; + } + + // If the SUnit has other dependencies on the SUnit that + // it anti-depends on, don't bother breaking the + // anti-dependency since those edges would prevent such + // units from being scheduled past each other + // regardless. + for (SUnit::pred_iterator P = PathSU->Preds.begin(), + PE = PathSU->Preds.end(); P != PE; ++P) { + if ((P->getSUnit() == NextSU) && (P->getKind() != SDep::Anti)) { + DEBUG(errs() << " (real dependency)\n"); + AntiDepReg = 0; + break; + } + } + + if (AntiDepReg == 0) continue; + } + + assert(AntiDepReg != 0); + if (AntiDepReg == 0) continue; + + // Determine AntiDepReg's register group. + const unsigned GroupIndex = GetGroup(AntiDepReg); + if (GroupIndex == 0) { + DEBUG(errs() << " (zero group)\n"); + continue; + } + + DEBUG(errs() << '\n'); + + // Look for a suitable register to use to break the anti-dependence. + std::map RenameMap; + if (FindSuitableFreeRegisters(GroupIndex, RenameMap)) { + DEBUG(errs() << "\tBreaking anti-dependence edge on " + << TRI->getName(AntiDepReg) << ":"); + + // Handle each group register... + for (std::map::iterator + S = RenameMap.begin(), E = RenameMap.end(); S != E; ++S) { + unsigned CurrReg = S->first; + unsigned NewReg = S->second; + + DEBUG(errs() << " " << TRI->getName(CurrReg) << "->" << + TRI->getName(NewReg) << "(" << + RegRefs.count(CurrReg) << " refs)"); + + // Update the references to the old register CurrReg to + // refer to the new register NewReg. + std::pair::iterator, + std::multimap::iterator> + Range = RegRefs.equal_range(CurrReg); + for (std::multimap::iterator + Q = Range.first, QE = Range.second; Q != QE; ++Q) { + Q->second.Operand->setReg(NewReg); + } + + // We just went back in time and modified history; the + // liveness information for CurrReg is now inconsistent. Set + // the state as if it were dead. + UnionGroups(NewReg, 0); + RegRefs.erase(NewReg); + DefIndices[NewReg] = DefIndices[CurrReg]; + KillIndices[NewReg] = KillIndices[CurrReg]; + + UnionGroups(CurrReg, 0); + RegRefs.erase(CurrReg); + DefIndices[CurrReg] = KillIndices[CurrReg]; + KillIndices[CurrReg] = ~0u; + assert(((KillIndices[CurrReg] == ~0u) != + (DefIndices[CurrReg] == ~0u)) && + "Kill and Def maps aren't consistent for AntiDepReg!"); + } + + ++Broken; + DEBUG(errs() << '\n'); + } + } + } + + ScanInstruction(MI, Count); + } + + return Broken; +} Added: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h?rev=85145&view=auto ============================================================================== --- llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h (added) +++ llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h Mon Oct 26 14:32:42 2009 @@ -0,0 +1,136 @@ +//=- llvm/CodeGen/AggressiveAntiDepBreaker.h - Anti-Dep Support -*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the AggressiveAntiDepBreaker class, which +// implements register anti-dependence breaking during post-RA +// scheduling. It attempts to break all anti-dependencies within a +// block. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H +#define LLVM_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H + +#include "llvm/CodeGen/AntiDepBreaker.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/SmallSet.h" + +namespace llvm { + class AggressiveAntiDepBreaker : public AntiDepBreaker { + MachineFunction& MF; + MachineRegisterInfo &MRI; + const TargetRegisterInfo *TRI; + + /// RegisterReference - Information about a register reference + /// within a liverange + typedef struct { + /// Operand - The registers operand + MachineOperand *Operand; + /// RC - The register class + const TargetRegisterClass *RC; + } RegisterReference; + + /// AllocatableSet - The set of allocatable registers. + /// We'll be ignoring anti-dependencies on non-allocatable registers, + /// because they may not be safe to break. + const BitVector AllocatableSet; + + /// GroupNodes - Implements a disjoint-union data structure to + /// form register groups. A node is represented by an index into + /// the vector. A node can "point to" itself to indicate that it + /// is the parent of a group, or point to another node to indicate + /// that it is a member of the same group as that node. + std::vector GroupNodes; + + /// GroupNodeIndices - For each register, the index of the GroupNode + /// currently representing the group that the register belongs to. + /// Register 0 is always represented by the 0 group, a group + /// composed of registers that are not eligible for anti-aliasing. + unsigned GroupNodeIndices[TargetRegisterInfo::FirstVirtualRegister]; + + /// RegRegs - Map registers to all their references within a live range. + std::multimap RegRefs; + + /// KillIndices - The index of the most recent kill (proceding bottom-up), + /// or ~0u if the register is not live. + unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; + + /// DefIndices - The index of the most recent complete def (proceding bottom + /// up), or ~0u if the register is live. + unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; + + public: + AggressiveAntiDepBreaker(MachineFunction& MFi); + ~AggressiveAntiDepBreaker(); + + /// Start - Initialize anti-dep breaking for a new basic block. + void StartBlock(MachineBasicBlock *BB); + + /// BreakAntiDependencies - Identifiy anti-dependencies along the critical path + /// of the ScheduleDAG and break them by renaming registers. + /// + unsigned BreakAntiDependencies(std::vector& SUnits, + MachineBasicBlock::iterator& Begin, + MachineBasicBlock::iterator& End, + unsigned InsertPosIndex); + + /// Observe - Update liveness information to account for the current + /// instruction, which will not be scheduled. + /// + void Observe(MachineInstr *MI, unsigned Count, unsigned InsertPosIndex); + + /// Finish - Finish anti-dep breaking for a basic block. + void FinishBlock(); + + private: + // GetGroup - Get the group for a register. The returned value is + // the index of the GroupNode representing the group. + unsigned GetGroup(unsigned Reg); + + // GetGroupRegs - Return a vector of the registers belonging to a + // group. + void GetGroupRegs(unsigned Group, std::vector &Regs); + + // UnionGroups - Union Reg1's and Reg2's groups to form a new + // group. Return the index of the GroupNode representing the + // group. + unsigned UnionGroups(unsigned Reg1, unsigned Reg2); + + // LeaveGroup - Remove a register from its current group and place + // it alone in its own group. Return the index of the GroupNode + // representing the registers new group. + unsigned LeaveGroup(unsigned Reg); + + /// IsLive - Return true if Reg is live + bool IsLive(unsigned Reg); + + /// IsImplicitDefUse - Return true if MO represents a register + /// that is both implicitly used and defined in MI + bool IsImplicitDefUse(MachineInstr *MI, MachineOperand& MO); + + /// GetPassthruRegs - If MI implicitly def/uses a register, then + /// return that register and all subregisters. + void GetPassthruRegs(MachineInstr *MI, std::set& PassthruRegs); + + void PrescanInstruction(MachineInstr *MI, unsigned Count, + std::set& PassthruRegs); + void ScanInstruction(MachineInstr *MI, unsigned Count); + BitVector GetRenameRegisters(unsigned Reg); + bool FindSuitableFreeRegisters(unsigned AntiDepGroupIndex, + std::map &RenameMap); + }; +} + +#endif Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=85145&r1=85144&r2=85145&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CMakeLists.txt (original) +++ llvm/trunk/lib/CodeGen/CMakeLists.txt Mon Oct 26 14:32:42 2009 @@ -1,4 +1,5 @@ add_llvm_library(LLVMCodeGen + AggressiveAntiDepBreaker.cpp BranchFolding.cpp CodePlacementOpt.cpp CriticalAntiDepBreaker.cpp Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=85145&r1=85144&r2=85145&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Mon Oct 26 14:32:42 2009 @@ -19,6 +19,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "post-RA-sched" +#include "AggressiveAntiDepBreaker.h" #include "CriticalAntiDepBreaker.h" #include "ExactHazardRecognizer.h" #include "SimpleHazardRecognizer.h" @@ -236,9 +237,10 @@ (ScheduleHazardRecognizer *)new ExactHazardRecognizer(InstrItins) : (ScheduleHazardRecognizer *)new SimpleHazardRecognizer(); AntiDepBreaker *ADB = - (AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? NULL /* FIXME */ : - (AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? - new CriticalAntiDepBreaker(Fn) : NULL; + ((AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? + (AntiDepBreaker *)new AggressiveAntiDepBreaker(Fn) : + ((AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? + (AntiDepBreaker *)new CriticalAntiDepBreaker(Fn) : NULL)); SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, ADB, AA); From anton at korobeynikov.info Mon Oct 26 14:39:40 2009 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Mon, 26 Oct 2009 22:39:40 +0300 Subject: [llvm-commits] [llvm] r81719 - in /llvm/trunk: unittests/Makefile unittests/TestMain.cpp utils/unittest/Makefile utils/unittest/UnitTestMain/ utils/unittest/UnitTestMain/Makefile utils/unittest/UnitTestMain/TestMain.cpp In-Reply-To: <20091026193011.GA75617@pom.apple.com> References: <200909132131.n8DLVLIl028742@zion.cs.uiuc.edu> <20090918161136.GB59666@pom.apple.com> <5DDA39F1-474A-4D6D-A039-5B36C6597C5D@apple.com> <20090930215928.GA15682@pom.apple.com> <20091026193011.GA75617@pom.apple.com> Message-ID: Hello, Julien > Is it ok to commit this thing ? It's blocking the build of LLVM on MingW > with gcc < 4 > > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20090928/088200.html Looks ok to me, please commit -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From david_goodwin at apple.com Mon Oct 26 14:41:01 2009 From: david_goodwin at apple.com (David Goodwin) Date: Mon, 26 Oct 2009 19:41:01 -0000 Subject: [llvm-commits] [llvm] r85146 - in /llvm/trunk: include/llvm/CodeGen/AntiDepBreaker.h lib/CodeGen/PostRASchedulerList.cpp Message-ID: <200910261941.n9QJf1r5031824@zion.cs.uiuc.edu> Author: david_goodwin Date: Mon Oct 26 14:41:00 2009 New Revision: 85146 URL: http://llvm.org/viewvc/llvm-project?rev=85146&view=rev Log: Define virtual destructor in *.cpp file. Modified: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Modified: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h?rev=85146&r1=85145&r2=85146&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h (original) +++ llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Mon Oct 26 14:41:00 2009 @@ -29,7 +29,7 @@ /// anti-dependencies. class AntiDepBreaker { public: - virtual ~AntiDepBreaker() { }; + virtual ~AntiDepBreaker(); /// Start - Initialize anti-dep breaking for a new basic block. virtual void StartBlock(MachineBasicBlock *BB) =0; Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=85146&r1=85145&r2=85146&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Mon Oct 26 14:41:00 2009 @@ -24,6 +24,7 @@ #include "ExactHazardRecognizer.h" #include "SimpleHazardRecognizer.h" #include "ScheduleDAGInstrs.h" +#include "llvm/CodeGen/AntiDepBreaker.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/LatencyPriorityQueue.h" #include "llvm/CodeGen/SchedulerRegistry.h" @@ -79,6 +80,8 @@ cl::desc("Debug control MBBs that are scheduled"), cl::init(0), cl::Hidden); +AntiDepBreaker::~AntiDepBreaker() { } + namespace { class PostRAScheduler : public MachineFunctionPass { AliasAnalysis *AA; From david_goodwin at apple.com Mon Oct 26 14:41:38 2009 From: david_goodwin at apple.com (David Goodwin) Date: Mon, 26 Oct 2009 12:41:38 -0700 Subject: [llvm-commits] [llvm] r85141 - /llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h In-Reply-To: References: <200910261900.n9QJ0lP6029737@zion.cs.uiuc.edu> Message-ID: Sending include/llvm/CodeGen/AntiDepBreaker.h Sending lib/CodeGen/PostRASchedulerList.cpp Transmitting file data .. Committed revision 85146. On Oct 26, 2009, at 12:07 PM, Bill Wendling wrote: > On Oct 26, 2009, at 12:00 PM, David Goodwin wrote: > >> Author: david_goodwin >> Date: Mon Oct 26 14:00:47 2009 >> New Revision: 85141 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=85141&view=rev >> Log: >> Add virtual destructor. >> >> Modified: >> llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h >> >> Modified: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h?rev=85141&r1=85140&r2=85141&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h (original) >> +++ llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Mon Oct 26 >> 14:00:47 2009 >> @@ -29,6 +29,8 @@ >> /// anti-dependencies. >> class AntiDepBreaker { >> public: >> + virtual ~AntiDepBreaker() { }; >> + > > It's good to have the definition of a virtual destructor in the .cpp > file. It "anchors" the vtable. > > -bw > From jlerouge at apple.com Mon Oct 26 14:58:45 2009 From: jlerouge at apple.com (Julien Lerouge) Date: Mon, 26 Oct 2009 19:58:45 -0000 Subject: [llvm-commits] [llvm] r85147 - in /llvm/trunk: Makefile.config.in autoconf/configure.ac autoconf/m4/cxx_flag_check.m4 Message-ID: <200910261958.n9QJwjjp000406@zion.cs.uiuc.edu> Author: jlerouge Date: Mon Oct 26 14:58:44 2009 New Revision: 85147 URL: http://llvm.org/viewvc/llvm-project?rev=85147&view=rev Log: Add an autoconf test to check for optional compiler flags like -Wno-missing-field-initializers or -Wno-variadic-macros. Added: llvm/trunk/autoconf/m4/cxx_flag_check.m4 Modified: llvm/trunk/Makefile.config.in llvm/trunk/autoconf/configure.ac Modified: llvm/trunk/Makefile.config.in URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile.config.in?rev=85147&r1=85146&r2=85147&view=diff ============================================================================== --- llvm/trunk/Makefile.config.in (original) +++ llvm/trunk/Makefile.config.in Mon Oct 26 14:58:44 2009 @@ -320,3 +320,9 @@ # support (via the -load option). ENABLE_LLVMC_DYNAMIC_PLUGINS = 1 #@ENABLE_LLVMC_DYNAMIC_PLUGINS@ + +# Optional flags supported by the compiler +# -Wno-missing-field-initializers +NO_MISSING_FIELD_INITIALIZERS = @NO_MISSING_FIELD_INITIALIZERS@ +# -Wno-variadic-macros +NO_VARIADIC_MACROS = @NO_VARIADIC_MACROS@ Modified: llvm/trunk/autoconf/configure.ac URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/autoconf/configure.ac?rev=85147&r1=85146&r2=85147&view=diff ============================================================================== --- llvm/trunk/autoconf/configure.ac (original) +++ llvm/trunk/autoconf/configure.ac Mon Oct 26 14:58:44 2009 @@ -943,6 +943,12 @@ dnl Tool compatibility is okay if we make it here. AC_MSG_RESULT([ok]) +dnl Check optional compiler flags. +AC_MSG_CHECKING([optional compiler flags]) +CXX_FLAG_CHECK(NO_VARIADIC_MACROS, [-Wno-variadic-macros]) +CXX_FLAG_CHECK(NO_MISSING_FIELD_INITIALIZERS, [-Wno-missing-field-initializers]) +AC_MSG_RESULT([$NO_VARIADIC_MACROS $NO_MISSING_FIELD_INITIALIZERS]) + dnl===-----------------------------------------------------------------------=== dnl=== dnl=== SECTION 5: Check for libraries Added: llvm/trunk/autoconf/m4/cxx_flag_check.m4 URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/autoconf/m4/cxx_flag_check.m4?rev=85147&view=auto ============================================================================== --- llvm/trunk/autoconf/m4/cxx_flag_check.m4 (added) +++ llvm/trunk/autoconf/m4/cxx_flag_check.m4 Mon Oct 26 14:58:44 2009 @@ -0,0 +1,2 @@ +AC_DEFUN([CXX_FLAG_CHECK], + [AC_SUBST($1, `$CXX $2 -fsyntax-only -xc /dev/null 2>/dev/null && echo $2`)]) From jlerouge at apple.com Mon Oct 26 15:00:35 2009 From: jlerouge at apple.com (Julien Lerouge) Date: Mon, 26 Oct 2009 20:00:35 -0000 Subject: [llvm-commits] [llvm] r85148 - /llvm/trunk/configure Message-ID: <200910262000.n9QK0aDq000551@zion.cs.uiuc.edu> Author: jlerouge Date: Mon Oct 26 15:00:35 2009 New Revision: 85148 URL: http://llvm.org/viewvc/llvm-project?rev=85148&view=rev Log: Regenerate. Modified: llvm/trunk/configure Modified: llvm/trunk/configure URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/configure?rev=85148&r1=85147&r2=85148&view=diff ============================================================================== --- llvm/trunk/configure (original) +++ llvm/trunk/configure Mon Oct 26 15:00:35 2009 @@ -913,6 +913,8 @@ LLVMGXXCOMMAND LLVMGCC LLVMGXX +NO_VARIADIC_MACROS +NO_MISSING_FIELD_INITIALIZERS USE_UDIS86 USE_OPROFILE HAVE_PTHREAD @@ -11008,7 +11010,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext + echo '#line 13157 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -14870,11 +14872,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14873: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14875: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14877: \$? = $ac_status" >&5 + echo "$as_me:14879: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -15138,11 +15140,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15141: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15143: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:15145: \$? = $ac_status" >&5 + echo "$as_me:15147: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -15242,11 +15244,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15245: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15247: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:15249: \$? = $ac_status" >&5 + echo "$as_me:15251: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -17694,7 +17696,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:20167: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:20169: \$? = $ac_status" >&5 + echo "$as_me:20171: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -20266,11 +20268,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:20269: $lt_compile\"" >&5) + (eval echo "\"\$as_me:20271: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:20273: \$? = $ac_status" >&5 + echo "$as_me:20275: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -21836,11 +21838,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:21839: $lt_compile\"" >&5) + (eval echo "\"\$as_me:21841: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:21843: \$? = $ac_status" >&5 + echo "$as_me:21845: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -21940,11 +21942,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:21943: $lt_compile\"" >&5) + (eval echo "\"\$as_me:21945: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:21947: \$? = $ac_status" >&5 + echo "$as_me:21949: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -24175,11 +24177,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:24178: $lt_compile\"" >&5) + (eval echo "\"\$as_me:24180: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:24182: \$? = $ac_status" >&5 + echo "$as_me:24184: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -24443,11 +24445,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:24446: $lt_compile\"" >&5) + (eval echo "\"\$as_me:24448: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:24450: \$? = $ac_status" >&5 + echo "$as_me:24452: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -24547,11 +24549,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:24550: $lt_compile\"" >&5) + (eval echo "\"\$as_me:24552: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:24554: \$? = $ac_status" >&5 + echo "$as_me:24556: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -27459,6 +27461,15 @@ { echo "$as_me:$LINENO: result: ok" >&5 echo "${ECHO_T}ok" >&6; } +{ echo "$as_me:$LINENO: checking optional compiler flags" >&5 +echo $ECHO_N "checking optional compiler flags... $ECHO_C" >&6; } +NO_VARIADIC_MACROS=`$CXX -Wno-variadic-macros -fsyntax-only -xc /dev/null 2>/dev/null && echo -Wno-variadic-macros` + +NO_MISSING_FIELD_INITIALIZERS=`$CXX -Wno-missing-field-initializers -fsyntax-only -xc /dev/null 2>/dev/null && echo -Wno-missing-field-initializers` + +{ echo "$as_me:$LINENO: result: $NO_VARIADIC_MACROS $NO_MISSING_FIELD_INITIALIZERS" >&5 +echo "${ECHO_T}$NO_VARIADIC_MACROS $NO_MISSING_FIELD_INITIALIZERS" >&6; } + { echo "$as_me:$LINENO: checking for sin in -lm" >&5 @@ -36167,6 +36178,8 @@ LLVMGXXCOMMAND!$LLVMGXXCOMMAND$ac_delim LLVMGCC!$LLVMGCC$ac_delim LLVMGXX!$LLVMGXX$ac_delim +NO_VARIADIC_MACROS!$NO_VARIADIC_MACROS$ac_delim +NO_MISSING_FIELD_INITIALIZERS!$NO_MISSING_FIELD_INITIALIZERS$ac_delim USE_UDIS86!$USE_UDIS86$ac_delim USE_OPROFILE!$USE_OPROFILE$ac_delim HAVE_PTHREAD!$HAVE_PTHREAD$ac_delim @@ -36201,7 +36214,7 @@ LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 92; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 94; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 From resistor at me.com Mon Oct 26 14:58:09 2009 From: resistor at me.com (Owen Anderson) Date: Mon, 26 Oct 2009 12:58:09 -0700 Subject: [llvm-commits] [llvm] r85144 - in /llvm/trunk: include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/GEPSplitter.cpp In-Reply-To: <200910261912.n9QJCE4a030428@zion.cs.uiuc.edu> References: <200910261912.n9QJCE4a030428@zion.cs.uiuc.edu> Message-ID: <83489F21-6E25-42FB-B136-84DDBE36BF0E@me.com> On Oct 26, 2009, at 12:12 PM, Dan Gohman wrote: > Author: djg > Date: Mon Oct 26 14:12:14 2009 > New Revision: 85144 > > URL: http://llvm.org/viewvc/llvm-project?rev=85144&view=rev > Log: > Check in the experimental GEP splitter pass. This pass splits complex > GEPs (more than one non-zero index) into simple GEPs (at most one > non-zero index). In some simple experiments using this it's not > uncommon to see 3% overall code size wins, because it exposes > redundancies that can be eliminated, however it's tricky to use > because instcombine aggressively undoes the work that this pass does. > How about running it right before GVN, and letting a later instcombine pass clean it up? --Owen > Added: > llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp > Modified: > llvm/trunk/include/llvm/LinkAllPasses.h > llvm/trunk/include/llvm/Transforms/Scalar.h > > Modified: llvm/trunk/include/llvm/LinkAllPasses.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=85144&r1=85143&r2=85144&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/LinkAllPasses.h (original) > +++ llvm/trunk/include/llvm/LinkAllPasses.h Mon Oct 26 14:12:14 2009 > @@ -141,6 +141,7 @@ > (void) llvm::createPartialInliningPass(); > (void) llvm::createSSIPass(); > (void) llvm::createSSIEverythingPass(); > + (void) llvm::createGEPSplitterPass(); > > (void)new llvm::IntervalPartition(); > (void)new llvm::FindUsedTypes(); > > Modified: llvm/trunk/include/llvm/Transforms/Scalar.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=85144&r1=85143&r2=85144&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/Transforms/Scalar.h (original) > +++ llvm/trunk/include/llvm/Transforms/Scalar.h Mon Oct 26 14:12:14 > 2009 > @@ -341,6 +341,12 @@ > // > FunctionPass *createSSIEverythingPass(); > > +// > = > = > = > ----------------------------------------------------------------------= > ==// > +// > +// GEPSplitter - Split complex GEPs into simple ones > +// > +FunctionPass *createGEPSplitterPass(); > + > } // End llvm namespace > > #endif > > Added: llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp?rev=85144&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp (added) > +++ llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp Mon Oct 26 > 14:12:14 2009 > @@ -0,0 +1,81 @@ > +//===- GEPSplitter.cpp - Split complex GEPs into simple ones > --------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open > Source > +// License. See LICENSE.TXT for details. > +// > +// > = > = > = > ----------------------------------------------------------------------= > ==// > +// > +// This function breaks GEPs with more than 2 non-zero operands > into smaller > +// GEPs each with no more than 2 non-zero operands. This exposes > redundancy > +// between GEPs with common initial operand sequences. > +// > +// > = > = > = > ----------------------------------------------------------------------= > ==// > + > +#define DEBUG_TYPE "split-geps" > +#include "llvm/Transforms/Scalar.h" > +#include "llvm/Constants.h" > +#include "llvm/Function.h" > +#include "llvm/Instructions.h" > +#include "llvm/Pass.h" > +using namespace llvm; > + > +namespace { > + class GEPSplitter : public FunctionPass { > + virtual bool runOnFunction(Function &F); > + virtual void getAnalysisUsage(AnalysisUsage &AU) const; > + public: > + static char ID; // Pass identification, replacement for typeid > + explicit GEPSplitter() : FunctionPass(&ID) {} > + }; > +} > + > +char GEPSplitter::ID = 0; > +static RegisterPass X("split-geps", > + "split complex GEPs into simple > GEPs"); > + > +FunctionPass *llvm::createGEPSplitterPass() { > + return new GEPSplitter(); > +} > + > +bool GEPSplitter::runOnFunction(Function &F) { > + bool Changed = false; > + > + // Visit each GEP instruction. > + for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) > + for (BasicBlock::iterator II = I->begin(), IE = I->end(); II != > IE; ) > + if (GetElementPtrInst *GEP = dyn_cast(II+ > +)) { > + unsigned NumOps = GEP->getNumOperands(); > + // Ignore GEPs which are already simple. > + if (NumOps <= 2) > + continue; > + bool FirstIndexIsZero = isa(GEP->getOperand > (1)) && > + cast(GEP->getOperand > (1))->isZero(); > + if (NumOps == 3 && FirstIndexIsZero) > + continue; > + // The first index is special and gets expanded with a 2- > operand GEP > + // (unless it's zero, in which case we can skip this). > + Value *NewGEP = FirstIndexIsZero ? > + GEP->getOperand(0) : > + GetElementPtrInst::Create(GEP->getOperand(0), GEP- > >getOperand(1), > + "tmp", GEP); > + // All remaining indices get expanded with a 3-operand GEP > with zero > + // as the second operand. > + Value *Idxs[2]; > + Idxs[0] = ConstantInt::get(Type::getInt64Ty(F.getContext > ()), 0); > + for (unsigned i = 2; i != NumOps; ++i) { > + Idxs[1] = GEP->getOperand(i); > + NewGEP = GetElementPtrInst::Create(NewGEP, Idxs, Idxs+2, > "tmp", GEP); > + } > + GEP->replaceAllUsesWith(NewGEP); > + GEP->eraseFromParent(); > + Changed = true; > + } > + > + return Changed; > +} > + > +void GEPSplitter::getAnalysisUsage(AnalysisUsage &AU) const { > + AU.setPreservesCFG(); > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From jlerouge at apple.com Mon Oct 26 15:01:35 2009 From: jlerouge at apple.com (Julien Lerouge) Date: Mon, 26 Oct 2009 20:01:35 -0000 Subject: [llvm-commits] [llvm] r85149 - in /llvm/trunk: unittests/Makefile.unittest utils/unittest/UnitTestMain/Makefile utils/unittest/googletest/Makefile Message-ID: <200910262001.n9QK1ajv000600@zion.cs.uiuc.edu> Author: jlerouge Date: Mon Oct 26 15:01:35 2009 New Revision: 85149 URL: http://llvm.org/viewvc/llvm-project?rev=85149&view=rev Log: Remove / use flags that are now set in the Makefile.config. Modified: llvm/trunk/unittests/Makefile.unittest llvm/trunk/utils/unittest/UnitTestMain/Makefile llvm/trunk/utils/unittest/googletest/Makefile Modified: llvm/trunk/unittests/Makefile.unittest URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Makefile.unittest?rev=85149&r1=85148&r2=85149&view=diff ============================================================================== --- llvm/trunk/unittests/Makefile.unittest (original) +++ llvm/trunk/unittests/Makefile.unittest Mon Oct 26 15:01:35 2009 @@ -19,7 +19,7 @@ LLVMUnitTestExe = $(BuildMode)/$(TESTNAME)Tests$(EXEEXT) CPP.Flags += -I$(LLVM_SRC_ROOT)/utils/unittest/googletest/include/ -CPP.Flags += -Wno-variadic-macros +CPP.Flags += $(NO_VARIADIC_MACROS) TESTLIBS = -lGoogleTest -lUnitTestMain $(LLVMUnitTestExe): $(ObjectsO) $(ProjLibsPaths) $(LLVMLibsPaths) Modified: llvm/trunk/utils/unittest/UnitTestMain/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/UnitTestMain/Makefile?rev=85149&r1=85148&r2=85149&view=diff ============================================================================== --- llvm/trunk/utils/unittest/UnitTestMain/Makefile (original) +++ llvm/trunk/utils/unittest/UnitTestMain/Makefile Mon Oct 26 15:01:35 2009 @@ -10,8 +10,6 @@ LEVEL = ../../.. include $(LEVEL)/Makefile.config -NO_MISSING_FIELD_INITIALIZERS := $(shell $(CXX) -Wno-missing-field-initializers -fsyntax-only -xc /dev/null 2>/dev/null && echo -Wno-missing-field-initializers) -NO_VARIADIC_MACROS := $(shell $(CXX) -Wno-variadic-macros -fsyntax-only -xc /dev/null 2>/dev/null && echo -Wno-variadic-macros) LIBRARYNAME = UnitTestMain BUILD_ARCHIVE = 1 Modified: llvm/trunk/utils/unittest/googletest/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/unittest/googletest/Makefile?rev=85149&r1=85148&r2=85149&view=diff ============================================================================== --- llvm/trunk/utils/unittest/googletest/Makefile (original) +++ llvm/trunk/utils/unittest/googletest/Makefile Mon Oct 26 15:01:35 2009 @@ -10,8 +10,6 @@ LEVEL := ../../.. include $(LEVEL)/Makefile.config -NO_MISSING_FIELD_INITIALIZERS := $(shell $(CXX) -Wno-missing-field-initializers -fsyntax-only -xc /dev/null 2>/dev/null && echo -Wno-missing-field-initializers) -NO_VARIADIC_MACROS := $(shell $(CXX) -Wno-variadic-macros -fsyntax-only -xc /dev/null 2>/dev/null && echo -Wno-variadic-macros) LIBRARYNAME = GoogleTest BUILD_ARCHIVE = 1 From gohman at apple.com Mon Oct 26 15:34:45 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 26 Oct 2009 13:34:45 -0700 Subject: [llvm-commits] [llvm] r85144 - in /llvm/trunk: include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/GEPSplitter.cpp In-Reply-To: <83489F21-6E25-42FB-B136-84DDBE36BF0E@me.com> References: <200910261912.n9QJCE4a030428@zion.cs.uiuc.edu> <83489F21-6E25-42FB-B136-84DDBE36BF0E@me.com> Message-ID: <9C3EC32B-AE0D-462E-A6FD-2307ED306406@apple.com> On Oct 26, 2009, at 12:58 PM, Owen Anderson wrote: > > On Oct 26, 2009, at 12:12 PM, Dan Gohman wrote: > >> Author: djg >> Date: Mon Oct 26 14:12:14 2009 >> New Revision: 85144 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=85144&view=rev >> Log: >> Check in the experimental GEP splitter pass. This pass splits complex >> GEPs (more than one non-zero index) into simple GEPs (at most one >> non-zero index). In some simple experiments using this it's not >> uncommon to see 3% overall code size wins, because it exposes >> redundancies that can be eliminated, however it's tricky to use >> because instcombine aggressively undoes the work that this pass does. >> > > > How about running it right before GVN, and letting a later instcombine > pass clean it up? Instcombine currently merges GEPs even when they have multiple uses, so it defeats even this. And it's not entirely unjustified: BasicAA understands standalone complex GEPs better than chains of simple GEPs. Dan From wendling at apple.com Mon Oct 26 15:37:33 2009 From: wendling at apple.com (Bill Wendling) Date: Mon, 26 Oct 2009 13:37:33 -0700 Subject: [llvm-commits] [llvm] r85141 - /llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h In-Reply-To: References: <200910261900.n9QJ0lP6029737@zion.cs.uiuc.edu> Message-ID: <9E8C82EF-C4C2-46BF-9F55-DE25AB0D6B84@apple.com> Thanks! :-) -bw On Oct 26, 2009, at 12:41 PM, David Goodwin wrote: > Sending include/llvm/CodeGen/AntiDepBreaker.h > Sending lib/CodeGen/PostRASchedulerList.cpp > Transmitting file data .. > Committed revision 85146. > > On Oct 26, 2009, at 12:07 PM, Bill Wendling wrote: > >> On Oct 26, 2009, at 12:00 PM, David Goodwin wrote: >> >>> Author: david_goodwin >>> Date: Mon Oct 26 14:00:47 2009 >>> New Revision: 85141 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=85141&view=rev >>> Log: >>> Add virtual destructor. >>> >>> Modified: >>> llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h >>> >>> Modified: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h?rev=85141&r1=85140&r2=85141&view=diff >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h (original) >>> +++ llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Mon Oct 26 >>> 14:00:47 2009 >>> @@ -29,6 +29,8 @@ >>> /// anti-dependencies. >>> class AntiDepBreaker { >>> public: >>> + virtual ~AntiDepBreaker() { }; >>> + >> >> It's good to have the definition of a virtual destructor in >> the .cpp file. It "anchors" the vtable. >> >> -bw >> > From evan.cheng at apple.com Mon Oct 26 16:23:32 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 26 Oct 2009 14:23:32 -0700 Subject: [llvm-commits] [llvm] r85127 - in /llvm/trunk: include/llvm/CodeGen/AntiDepBreaker.h lib/CodeGen/CMakeLists.txt lib/CodeGen/CriticalAntiDepBreaker.cpp lib/CodeGen/CriticalAntiDepBreaker.h lib/CodeGen/PostRASchedulerList.cpp lib/Target/ARM/ARMSubtarget.h test/CodeGen/X86/break-anti-dependencies.ll In-Reply-To: <200910261659.n9QGx4Yj023936@zion.cs.uiuc.edu> References: <200910261659.n9QGx4Yj023936@zion.cs.uiuc.edu> Message-ID: It seems to be AntiDepBreaker.h should be inside lib/CodeGen. Is there a reason to expose it? Evan On Oct 26, 2009, at 9:59 AM, David Goodwin wrote: > Author: david_goodwin > Date: Mon Oct 26 11:59:04 2009 > New Revision: 85127 > > URL: http://llvm.org/viewvc/llvm-project?rev=85127&view=rev > Log: > Break anti-dependence breaking out into its own class. > > Added: > llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h > llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp > llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h > Modified: > llvm/trunk/lib/CodeGen/CMakeLists.txt > llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp > llvm/trunk/lib/Target/ARM/ARMSubtarget.h > llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll > > Added: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h?rev=85127&view=auto > > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h (added) > +++ llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Mon Oct 26 11:59:04 2009 > @@ -0,0 +1,56 @@ > +//=- llvm/CodeGen/AntiDepBreaker.h - Anti-Dependence Breaking -*- C++ -*-=// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > +// > +// This file implements the AntiDepBreaker class, which implements > +// anti-dependence breaking heuristics for post-register-allocation scheduling. > +// > +//===----------------------------------------------------------------------===// > + > +#ifndef LLVM_CODEGEN_ANTIDEPBREAKER_H > +#define LLVM_CODEGEN_ANTIDEPBREAKER_H > + > +#include "llvm/CodeGen/MachineBasicBlock.h" > +#include "llvm/CodeGen/MachineFrameInfo.h" > +#include "llvm/CodeGen/MachineFunction.h" > +#include "llvm/CodeGen/MachineRegisterInfo.h" > +#include "llvm/CodeGen/ScheduleDAG.h" > +#include "llvm/Target/TargetRegisterInfo.h" > + > +namespace llvm { > + > +/// AntiDepBreaker - This class works into conjunction with the > +/// post-RA scheduler to rename registers to break register > +/// anti-dependencies. > +class AntiDepBreaker { > +public: > + /// Start - Initialize anti-dep breaking for a new basic block. > + virtual void StartBlock(MachineBasicBlock *BB) =0; > + > + /// BreakAntiDependencies - Identifiy anti-dependencies within a > + /// basic-block region and break them by renaming registers. Return > + /// the number of anti-dependencies broken. > + /// > + virtual unsigned BreakAntiDependencies(std::vector& SUnits, > + MachineBasicBlock::iterator& Begin, > + MachineBasicBlock::iterator& End, > + unsigned InsertPosIndex) =0; > + > + /// Observe - Update liveness information to account for the current > + /// instruction, which will not be scheduled. > + /// > + virtual void Observe(MachineInstr *MI, unsigned Count, > + unsigned InsertPosIndex) =0; > + > + /// Finish - Finish anti-dep breaking for a basic block. > + virtual void FinishBlock() =0; > +}; > + > +} > + > +#endif > > Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=85127&r1=85126&r2=85127&view=diff > > ============================================================================== > --- llvm/trunk/lib/CodeGen/CMakeLists.txt (original) > +++ llvm/trunk/lib/CodeGen/CMakeLists.txt Mon Oct 26 11:59:04 2009 > @@ -1,6 +1,7 @@ > add_llvm_library(LLVMCodeGen > BranchFolding.cpp > CodePlacementOpt.cpp > + CriticalAntiDepBreaker.cpp > DeadMachineInstructionElim.cpp > DwarfEHPrepare.cpp > ELFCodeEmitter.cpp > > Added: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp?rev=85127&view=auto > > ============================================================================== > --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp (added) > +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp Mon Oct 26 11:59:04 2009 > @@ -0,0 +1,539 @@ > +//===----- CriticalAntiDepBreaker.cpp - Anti-dep breaker -------- ---------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > +// > +// This file implements the CriticalAntiDepBreaker class, which > +// implements register anti-dependence breaking along a blocks > +// critical path during post-RA scheduler. > +// > +//===----------------------------------------------------------------------===// > + > +#define DEBUG_TYPE "critical-antidep" > +#include "CriticalAntiDepBreaker.h" > +#include "llvm/CodeGen/MachineBasicBlock.h" > +#include "llvm/CodeGen/MachineFrameInfo.h" > +#include "llvm/Target/TargetMachine.h" > +#include "llvm/Target/TargetRegisterInfo.h" > +#include "llvm/Support/Debug.h" > +#include "llvm/Support/ErrorHandling.h" > +#include "llvm/Support/raw_ostream.h" > + > +using namespace llvm; > + > +CriticalAntiDepBreaker:: > +CriticalAntiDepBreaker(MachineFunction& MFi) : > + AntiDepBreaker(), MF(MFi), > + MRI(MF.getRegInfo()), > + TRI(MF.getTarget().getRegisterInfo()), > + AllocatableSet(TRI->getAllocatableSet(MF)) > +{ > +} > + > +CriticalAntiDepBreaker::~CriticalAntiDepBreaker() { > +} > + > +void CriticalAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { > + // Clear out the register class data. > + std::fill(Classes, array_endof(Classes), > + static_cast(0)); > + > + // Initialize the indices to indicate that no registers are live. > + std::fill(KillIndices, array_endof(KillIndices), ~0u); > + std::fill(DefIndices, array_endof(DefIndices), BB->size()); > + > + // Clear "do not change" set. > + KeepRegs.clear(); > + > + bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn()); > + > + // Determine the live-out physregs for this block. > + if (IsReturnBlock) { > + // In a return block, examine the function live-out regs. > + for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), > + E = MRI.liveout_end(); I != E; ++I) { > + unsigned Reg = *I; > + Classes[Reg] = reinterpret_cast(-1); > + KillIndices[Reg] = BB->size(); > + DefIndices[Reg] = ~0u; > + // Repeat, for all aliases. > + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > + unsigned AliasReg = *Alias; > + Classes[AliasReg] = reinterpret_cast(-1); > + KillIndices[AliasReg] = BB->size(); > + DefIndices[AliasReg] = ~0u; > + } > + } > + } else { > + // In a non-return block, examine the live-in regs of all successors. > + for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), > + SE = BB->succ_end(); SI != SE; ++SI) > + for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), > + E = (*SI)->livein_end(); I != E; ++I) { > + unsigned Reg = *I; > + Classes[Reg] = reinterpret_cast(-1); > + KillIndices[Reg] = BB->size(); > + DefIndices[Reg] = ~0u; > + // Repeat, for all aliases. > + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > + unsigned AliasReg = *Alias; > + Classes[AliasReg] = reinterpret_cast(-1); > + KillIndices[AliasReg] = BB->size(); > + DefIndices[AliasReg] = ~0u; > + } > + } > + } > + > + // Mark live-out callee-saved registers. In a return block this is > + // all callee-saved registers. In non-return this is any > + // callee-saved register that is not saved in the prolog. > + const MachineFrameInfo *MFI = MF.getFrameInfo(); > + BitVector Pristine = MFI->getPristineRegs(BB); > + for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { > + unsigned Reg = *I; > + if (!IsReturnBlock && !Pristine.test(Reg)) continue; > + Classes[Reg] = reinterpret_cast(-1); > + KillIndices[Reg] = BB->size(); > + DefIndices[Reg] = ~0u; > + // Repeat, for all aliases. > + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > + unsigned AliasReg = *Alias; > + Classes[AliasReg] = reinterpret_cast(-1); > + KillIndices[AliasReg] = BB->size(); > + DefIndices[AliasReg] = ~0u; > + } > + } > +} > + > +void CriticalAntiDepBreaker::FinishBlock() { > + RegRefs.clear(); > + KeepRegs.clear(); > +} > + > +void CriticalAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count, > + unsigned InsertPosIndex) { > + assert(Count < InsertPosIndex && "Instruction index out of expected range!"); > + > + // Any register which was defined within the previous scheduling region > + // may have been rescheduled and its lifetime may overlap with registers > + // in ways not reflected in our current liveness state. For each such > + // register, adjust the liveness state to be conservatively correct. > + for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) > + if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) { > + assert(KillIndices[Reg] == ~0u && "Clobbered register is live!"); > + // Mark this register to be non-renamable. > + Classes[Reg] = reinterpret_cast(-1); > + // Move the def index to the end of the previous region, to reflect > + // that the def could theoretically have been scheduled at the end. > + DefIndices[Reg] = InsertPosIndex; > + } > + > + PrescanInstruction(MI); > + ScanInstruction(MI, Count); > +} > + > +/// CriticalPathStep - Return the next SUnit after SU on the bottom-up > +/// critical path. > +static SDep *CriticalPathStep(SUnit *SU) { > + SDep *Next = 0; > + unsigned NextDepth = 0; > + // Find the predecessor edge with the greatest depth. > + for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end(); > + P != PE; ++P) { > + SUnit *PredSU = P->getSUnit(); > + unsigned PredLatency = P->getLatency(); > + unsigned PredTotalLatency = PredSU->getDepth() + PredLatency; > + // In the case of a latency tie, prefer an anti-dependency edge over > + // other types of edges. > + if (NextDepth < PredTotalLatency || > + (NextDepth == PredTotalLatency && P->getKind() == SDep::Anti)) { > + NextDepth = PredTotalLatency; > + Next = &*P; > + } > + } > + return Next; > +} > + > +void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr *MI) { > + // Scan the register operands for this instruction and update > + // Classes and RegRefs. > + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > + MachineOperand &MO = MI->getOperand(i); > + if (!MO.isReg()) continue; > + unsigned Reg = MO.getReg(); > + if (Reg == 0) continue; > + const TargetRegisterClass *NewRC = 0; > + > + if (i < MI->getDesc().getNumOperands()) > + NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); > + > + // For now, only allow the register to be changed if its register > + // class is consistent across all uses. > + if (!Classes[Reg] && NewRC) > + Classes[Reg] = NewRC; > + else if (!NewRC || Classes[Reg] != NewRC) > + Classes[Reg] = reinterpret_cast(-1); > + > + // Now check for aliases. > + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > + // If an alias of the reg is used during the live range, give up. > + // Note that this allows us to skip checking if AntiDepReg > + // overlaps with any of the aliases, among other things. > + unsigned AliasReg = *Alias; > + if (Classes[AliasReg]) { > + Classes[AliasReg] = reinterpret_cast(-1); > + Classes[Reg] = reinterpret_cast(-1); > + } > + } > + > + // If we're still willing to consider this register, note the reference. > + if (Classes[Reg] != reinterpret_cast(-1)) > + RegRefs.insert(std::make_pair(Reg, &MO)); > + > + // It's not safe to change register allocation for source operands of > + // that have special allocation requirements. > + if (MO.isUse() && MI->getDesc().hasExtraSrcRegAllocReq()) { > + if (KeepRegs.insert(Reg)) { > + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); > + *Subreg; ++Subreg) > + KeepRegs.insert(*Subreg); > + } > + } > + } > +} > + > +void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI, > + unsigned Count) { > + // Update liveness. > + // Proceding upwards, registers that are defed but not used in this > + // instruction are now dead. > + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > + MachineOperand &MO = MI->getOperand(i); > + if (!MO.isReg()) continue; > + unsigned Reg = MO.getReg(); > + if (Reg == 0) continue; > + if (!MO.isDef()) continue; > + // Ignore two-addr defs. > + if (MI->isRegTiedToUseOperand(i)) continue; > + > + DefIndices[Reg] = Count; > + KillIndices[Reg] = ~0u; > + assert(((KillIndices[Reg] == ~0u) != > + (DefIndices[Reg] == ~0u)) && > + "Kill and Def maps aren't consistent for Reg!"); > + KeepRegs.erase(Reg); > + Classes[Reg] = 0; > + RegRefs.erase(Reg); > + // Repeat, for all subregs. > + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); > + *Subreg; ++Subreg) { > + unsigned SubregReg = *Subreg; > + DefIndices[SubregReg] = Count; > + KillIndices[SubregReg] = ~0u; > + KeepRegs.erase(SubregReg); > + Classes[SubregReg] = 0; > + RegRefs.erase(SubregReg); > + } > + // Conservatively mark super-registers as unusable. > + for (const unsigned *Super = TRI->getSuperRegisters(Reg); > + *Super; ++Super) { > + unsigned SuperReg = *Super; > + Classes[SuperReg] = reinterpret_cast(-1); > + } > + } > + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > + MachineOperand &MO = MI->getOperand(i); > + if (!MO.isReg()) continue; > + unsigned Reg = MO.getReg(); > + if (Reg == 0) continue; > + if (!MO.isUse()) continue; > + > + const TargetRegisterClass *NewRC = 0; > + if (i < MI->getDesc().getNumOperands()) > + NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); > + > + // For now, only allow the register to be changed if its register > + // class is consistent across all uses. > + if (!Classes[Reg] && NewRC) > + Classes[Reg] = NewRC; > + else if (!NewRC || Classes[Reg] != NewRC) > + Classes[Reg] = reinterpret_cast(-1); > + > + RegRefs.insert(std::make_pair(Reg, &MO)); > + > + // It wasn't previously live but now it is, this is a kill. > + if (KillIndices[Reg] == ~0u) { > + KillIndices[Reg] = Count; > + DefIndices[Reg] = ~0u; > + assert(((KillIndices[Reg] == ~0u) != > + (DefIndices[Reg] == ~0u)) && > + "Kill and Def maps aren't consistent for Reg!"); > + } > + // Repeat, for all aliases. > + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > + unsigned AliasReg = *Alias; > + if (KillIndices[AliasReg] == ~0u) { > + KillIndices[AliasReg] = Count; > + DefIndices[AliasReg] = ~0u; > + } > + } > + } > +} > + > +unsigned > +CriticalAntiDepBreaker::findSuitableFreeRegister(unsigned AntiDepReg, > + unsigned LastNewReg, > + const TargetRegisterClass *RC) { > + for (TargetRegisterClass::iterator R = RC->allocation_order_begin(MF), > + RE = RC->allocation_order_end(MF); R != RE; ++R) { > + unsigned NewReg = *R; > + // Don't replace a register with itself. > + if (NewReg == AntiDepReg) continue; > + // Don't replace a register with one that was recently used to repair > + // an anti-dependence with this AntiDepReg, because that would > + // re-introduce that anti-dependence. > + if (NewReg == LastNewReg) continue; > + // If NewReg is dead and NewReg's most recent def is not before > + // AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg. > + assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u)) && > + "Kill and Def maps aren't consistent for AntiDepReg!"); > + assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u)) && > + "Kill and Def maps aren't consistent for NewReg!"); > + if (KillIndices[NewReg] != ~0u || > + Classes[NewReg] == reinterpret_cast(-1) || > + KillIndices[AntiDepReg] > DefIndices[NewReg]) > + continue; > + return NewReg; > + } > + > + // No registers are free and available! > + return 0; > +} > + > +unsigned CriticalAntiDepBreaker:: > +BreakAntiDependencies(std::vector& SUnits, > + MachineBasicBlock::iterator& Begin, > + MachineBasicBlock::iterator& End, > + unsigned InsertPosIndex) { > + // The code below assumes that there is at least one instruction, > + // so just duck out immediately if the block is empty. > + if (SUnits.empty()) return 0; > + > + // Find the node at the bottom of the critical path. > + SUnit *Max = 0; > + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { > + SUnit *SU = &SUnits[i]; > + if (!Max || SU->getDepth() + SU->Latency > Max->getDepth() + Max->Latency) > + Max = SU; > + } > + > +#ifndef NDEBUG > + { > + DEBUG(errs() << "Critical path has total latency " > + << (Max->getDepth() + Max->Latency) << "\n"); > + DEBUG(errs() << "Available regs:"); > + for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { > + if (KillIndices[Reg] == ~0u) > + DEBUG(errs() << " " << TRI->getName(Reg)); > + } > + DEBUG(errs() << '\n'); > + } > +#endif > + > + // Track progress along the critical path through the SUnit graph as we walk > + // the instructions. > + SUnit *CriticalPathSU = Max; > + MachineInstr *CriticalPathMI = CriticalPathSU->getInstr(); > + > + // Consider this pattern: > + // A = ... > + // ... = A > + // A = ... > + // ... = A > + // A = ... > + // ... = A > + // A = ... > + // ... = A > + // There are three anti-dependencies here, and without special care, > + // we'd break all of them using the same register: > + // A = ... > + // ... = A > + // B = ... > + // ... = B > + // B = ... > + // ... = B > + // B = ... > + // ... = B > + // because at each anti-dependence, B is the first register that > + // isn't A which is free. This re-introduces anti-dependencies > + // at all but one of the original anti-dependencies that we were > + // trying to break. To avoid this, keep track of the most recent > + // register that each register was replaced with, avoid > + // using it to repair an anti-dependence on the same register. > + // This lets us produce this: > + // A = ... > + // ... = A > + // B = ... > + // ... = B > + // C = ... > + // ... = C > + // B = ... > + // ... = B > + // This still has an anti-dependence on B, but at least it isn't on the > + // original critical path. > + // > + // TODO: If we tracked more than one register here, we could potentially > + // fix that remaining critical edge too. This is a little more involved, > + // because unlike the most recent register, less recent registers should > + // still be considered, though only if no other registers are available. > + unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = {}; > + > + // Attempt to break anti-dependence edges on the critical path. Walk the > + // instructions from the bottom up, tracking information about liveness > + // as we go to help determine which registers are available. > + unsigned Broken = 0; > + unsigned Count = InsertPosIndex - 1; > + for (MachineBasicBlock::iterator I = End, E = Begin; > + I != E; --Count) { > + MachineInstr *MI = --I; > + > + // Check if this instruction has a dependence on the critical path that > + // is an anti-dependence that we may be able to break. If it is, set > + // AntiDepReg to the non-zero register associated with the anti-dependence. > + // > + // We limit our attention to the critical path as a heuristic to avoid > + // breaking anti-dependence edges that aren't going to significantly > + // impact the overall schedule. There are a limited number of registers > + // and we want to save them for the important edges. > + // > + // TODO: Instructions with multiple defs could have multiple > + // anti-dependencies. The current code here only knows how to break one > + // edge per instruction. Note that we'd have to be able to break all of > + // the anti-dependencies in an instruction in order to be effective. > + unsigned AntiDepReg = 0; > + if (MI == CriticalPathMI) { > + if (SDep *Edge = CriticalPathStep(CriticalPathSU)) { > + SUnit *NextSU = Edge->getSUnit(); > + > + // Only consider anti-dependence edges. > + if (Edge->getKind() == SDep::Anti) { > + AntiDepReg = Edge->getReg(); > + assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); > + if (!AllocatableSet.test(AntiDepReg)) > + // Don't break anti-dependencies on non-allocatable registers. > + AntiDepReg = 0; > + else if (KeepRegs.count(AntiDepReg)) > + // Don't break anti-dependencies if an use down below requires > + // this exact register. > + AntiDepReg = 0; > + else { > + // If the SUnit has other dependencies on the SUnit that it > + // anti-depends on, don't bother breaking the anti-dependency > + // since those edges would prevent such units from being > + // scheduled past each other regardless. > + // > + // Also, if there are dependencies on other SUnits with the > + // same register as the anti-dependency, don't attempt to > + // break it. > + for (SUnit::pred_iterator P = CriticalPathSU->Preds.begin(), > + PE = CriticalPathSU->Preds.end(); P != PE; ++P) > + if (P->getSUnit() == NextSU ? > + (P->getKind() != SDep::Anti || P->getReg() != AntiDepReg) : > + (P->getKind() == SDep::Data && P->getReg() == AntiDepReg)) { > + AntiDepReg = 0; > + break; > + } > + } > + } > + CriticalPathSU = NextSU; > + CriticalPathMI = CriticalPathSU->getInstr(); > + } else { > + // We've reached the end of the critical path. > + CriticalPathSU = 0; > + CriticalPathMI = 0; > + } > + } > + > + PrescanInstruction(MI); > + > + if (MI->getDesc().hasExtraDefRegAllocReq()) > + // If this instruction's defs have special allocation requirement, don't > + // break this anti-dependency. > + AntiDepReg = 0; > + else if (AntiDepReg) { > + // If this instruction has a use of AntiDepReg, breaking it > + // is invalid. > + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > + MachineOperand &MO = MI->getOperand(i); > + if (!MO.isReg()) continue; > + unsigned Reg = MO.getReg(); > + if (Reg == 0) continue; > + if (MO.isUse() && AntiDepReg == Reg) { > + AntiDepReg = 0; > + break; > + } > + } > + } > + > + // Determine AntiDepReg's register class, if it is live and is > + // consistently used within a single class. > + const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes[AntiDepReg] : 0; > + assert((AntiDepReg == 0 || RC != NULL) && > + "Register should be live if it's causing an anti-dependence!"); > + if (RC == reinterpret_cast(-1)) > + AntiDepReg = 0; > + > + // Look for a suitable register to use to break the anti-depenence. > + // > + // TODO: Instead of picking the first free register, consider which might > + // be the best. > + if (AntiDepReg != 0) { > + if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg, > + LastNewReg[AntiDepReg], > + RC)) { > + DEBUG(errs() << "Breaking anti-dependence edge on " > + << TRI->getName(AntiDepReg) > + << " with " << RegRefs.count(AntiDepReg) << " references" > + << " using " << TRI->getName(NewReg) << "!\n"); > + > + // Update the references to the old register to refer to the new > + // register. > + std::pair::iterator, > + std::multimap::iterator> > + Range = RegRefs.equal_range(AntiDepReg); > + for (std::multimap::iterator > + Q = Range.first, QE = Range.second; Q != QE; ++Q) > + Q->second->setReg(NewReg); > + > + // We just went back in time and modified history; the > + // liveness information for the anti-depenence reg is now > + // inconsistent. Set the state as if it were dead. > + Classes[NewReg] = Classes[AntiDepReg]; > + DefIndices[NewReg] = DefIndices[AntiDepReg]; > + KillIndices[NewReg] = KillIndices[AntiDepReg]; > + assert(((KillIndices[NewReg] == ~0u) != > + (DefIndices[NewReg] == ~0u)) && > + "Kill and Def maps aren't consistent for NewReg!"); > + > + Classes[AntiDepReg] = 0; > + DefIndices[AntiDepReg] = KillIndices[AntiDepReg]; > + KillIndices[AntiDepReg] = ~0u; > + assert(((KillIndices[AntiDepReg] == ~0u) != > + (DefIndices[AntiDepReg] == ~0u)) && > + "Kill and Def maps aren't consistent for AntiDepReg!"); > + > + RegRefs.erase(AntiDepReg); > + LastNewReg[AntiDepReg] = NewReg; > + ++Broken; > + } > + } > + > + ScanInstruction(MI, Count); > + } > + > + return Broken; > +} > > Added: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h?rev=85127&view=auto > > ============================================================================== > --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h (added) > +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h Mon Oct 26 11:59:04 2009 > @@ -0,0 +1,95 @@ > +//=- llvm/CodeGen/CriticalAntiDepBreaker.h - Anti-Dep Support -*- C++ -*-=// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > +// > +// This file implements the CriticalAntiDepBreaker class, which > +// implements register anti-dependence breaking along a blocks > +// critical path during post-RA scheduler. > +// > +//===----------------------------------------------------------------------===// > + > +#ifndef LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H > +#define LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H > + > +#include "llvm/CodeGen/AntiDepBreaker.h" > +#include "llvm/CodeGen/MachineBasicBlock.h" > +#include "llvm/CodeGen/MachineFrameInfo.h" > +#include "llvm/CodeGen/MachineFunction.h" > +#include "llvm/CodeGen/MachineRegisterInfo.h" > +#include "llvm/CodeGen/ScheduleDAG.h" > +#include "llvm/Target/TargetRegisterInfo.h" > +#include "llvm/ADT/BitVector.h" > +#include "llvm/ADT/SmallSet.h" > + > +namespace llvm { > + class CriticalAntiDepBreaker : public AntiDepBreaker { > + MachineFunction& MF; > + MachineRegisterInfo &MRI; > + const TargetRegisterInfo *TRI; > + > + /// AllocatableSet - The set of allocatable registers. > + /// We'll be ignoring anti-dependencies on non-allocatable registers, > + /// because they may not be safe to break. > + const BitVector AllocatableSet; > + > + /// Classes - For live regs that are only used in one register class in a > + /// live range, the register class. If the register is not live, the > + /// corresponding value is null. If the register is live but used in > + /// multiple register classes, the corresponding value is -1 casted to a > + /// pointer. > + const TargetRegisterClass * > + Classes[TargetRegisterInfo::FirstVirtualRegister]; > + > + /// RegRegs - Map registers to all their references within a live range. > + std::multimap RegRefs; > + > + /// KillIndices - The index of the most recent kill (proceding bottom-up), > + /// or ~0u if the register is not live. > + unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; > + > + /// DefIndices - The index of the most recent complete def (proceding bottom > + /// up), or ~0u if the register is live. > + unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; > + > + /// KeepRegs - A set of registers which are live and cannot be changed to > + /// break anti-dependencies. > + SmallSet KeepRegs; > + > + public: > + CriticalAntiDepBreaker(MachineFunction& MFi); > + ~CriticalAntiDepBreaker(); > + > + /// Start - Initialize anti-dep breaking for a new basic block. > + void StartBlock(MachineBasicBlock *BB); > + > + /// BreakAntiDependencies - Identifiy anti-dependencies along the critical path > + /// of the ScheduleDAG and break them by renaming registers. > + /// > + unsigned BreakAntiDependencies(std::vector& SUnits, > + MachineBasicBlock::iterator& Begin, > + MachineBasicBlock::iterator& End, > + unsigned InsertPosIndex); > + > + /// Observe - Update liveness information to account for the current > + /// instruction, which will not be scheduled. > + /// > + void Observe(MachineInstr *MI, unsigned Count, unsigned InsertPosIndex); > + > + /// Finish - Finish anti-dep breaking for a basic block. > + void FinishBlock(); > + > + private: > + void PrescanInstruction(MachineInstr *MI); > + void ScanInstruction(MachineInstr *MI, unsigned Count); > + unsigned findSuitableFreeRegister(unsigned AntiDepReg, > + unsigned LastNewReg, > + const TargetRegisterClass *); > + }; > +} > + > +#endif > > Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=85127&r1=85126&r2=85127&view=diff > > ============================================================================== > --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) > +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Mon Oct 26 11:59:04 2009 > @@ -19,6 +19,7 @@ > //===----------------------------------------------------------------------===// > > #define DEBUG_TYPE "post-RA-sched" > +#include "CriticalAntiDepBreaker.h" > #include "ExactHazardRecognizer.h" > #include "SimpleHazardRecognizer.h" > #include "ScheduleDAGInstrs.h" > @@ -40,6 +41,7 @@ > #include "llvm/Support/Debug.h" > #include "llvm/Support/ErrorHandling.h" > #include "llvm/Support/raw_ostream.h" > +#include "llvm/ADT/BitVector.h" > #include "llvm/ADT/Statistic.h" > #include > #include > @@ -47,6 +49,7 @@ > > STATISTIC(NumNoops, "Number of noops inserted"); > STATISTIC(NumStalls, "Number of pipeline stalls"); > +STATISTIC(NumFixedAnti, "Number of fixed anti-dependencies"); > > // Post-RA scheduling is enabled with > // TargetSubtarget.enablePostRAScheduler(). This flag can be used to > @@ -55,10 +58,11 @@ > EnablePostRAScheduler("post-RA-scheduler", > cl::desc("Enable scheduling after register allocation"), > cl::init(false), cl::Hidden); > -static cl::opt > +static cl::opt > EnableAntiDepBreaking("break-anti-dependencies", > - cl::desc("Break post-RA scheduling anti-dependencies"), > - cl::init(true), cl::Hidden); > + cl::desc("Break post-RA scheduling anti-dependencies: " > + "\"critical\", \"all\", or \"none\""), > + cl::init("none"), cl::Hidden); > static cl::opt > EnablePostRAHazardAvoidance("avoid-hazards", > cl::desc("Enable exact hazard avoidance"), > @@ -116,56 +120,30 @@ > /// Topo - A topological ordering for SUnits. > ScheduleDAGTopologicalSort Topo; > > - /// AllocatableSet - The set of allocatable registers. > - /// We'll be ignoring anti-dependencies on non-allocatable registers, > - /// because they may not be safe to break. > - const BitVector AllocatableSet; > - > /// HazardRec - The hazard recognizer to use. > ScheduleHazardRecognizer *HazardRec; > > + /// AntiDepBreak - Anti-dependence breaking object, or NULL if none > + AntiDepBreaker *AntiDepBreak; > + > /// AA - AliasAnalysis for making memory reference queries. > AliasAnalysis *AA; > > - /// AntiDepMode - Anti-dependence breaking mode > - TargetSubtarget::AntiDepBreakMode AntiDepMode; > - > - /// Classes - For live regs that are only used in one register class in a > - /// live range, the register class. If the register is not live, the > - /// corresponding value is null. If the register is live but used in > - /// multiple register classes, the corresponding value is -1 casted to a > - /// pointer. > - const TargetRegisterClass * > - Classes[TargetRegisterInfo::FirstVirtualRegister]; > - > - /// RegRegs - Map registers to all their references within a live range. > - std::multimap RegRefs; > - > /// KillIndices - The index of the most recent kill (proceding bottom-up), > /// or ~0u if the register is not live. > unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; > > - /// DefIndices - The index of the most recent complete def (proceding bottom > - /// up), or ~0u if the register is live. > - unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; > - > - /// KeepRegs - A set of registers which are live and cannot be changed to > - /// break anti-dependencies. > - SmallSet KeepRegs; > - > public: > SchedulePostRATDList(MachineFunction &MF, > const MachineLoopInfo &MLI, > const MachineDominatorTree &MDT, > ScheduleHazardRecognizer *HR, > - AliasAnalysis *aa, > - TargetSubtarget::AntiDepBreakMode adm) > + AntiDepBreaker *ADB, > + AliasAnalysis *aa) > : ScheduleDAGInstrs(MF, MLI, MDT), Topo(SUnits), > - AllocatableSet(TRI->getAllocatableSet(MF)), > - HazardRec(HR), AA(aa), AntiDepMode(adm) {} > + HazardRec(HR), AntiDepBreak(ADB), AA(aa) {} > > ~SchedulePostRATDList() { > - delete HazardRec; > } > > /// StartBlock - Initialize register live-range state for scheduling in > @@ -177,11 +155,6 @@ > /// > void Schedule(); > > - /// FixupKills - Fix register kill flags that have been made > - /// invalid due to scheduling > - /// > - void FixupKills(MachineBasicBlock *MBB); > - > /// Observe - Update liveness information to account for the current > /// instruction, which will not be scheduled. > /// > @@ -191,17 +164,16 @@ > /// > void FinishBlock(); > > + /// FixupKills - Fix register kill flags that have been made > + /// invalid due to scheduling > + /// > + void FixupKills(MachineBasicBlock *MBB); > + > private: > - void PrescanInstruction(MachineInstr *MI); > - void ScanInstruction(MachineInstr *MI, unsigned Count); > void ReleaseSucc(SUnit *SU, SDep *SuccEdge); > void ReleaseSuccessors(SUnit *SU); > void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); > void ListScheduleTopDown(); > - bool BreakAntiDependencies(); > - unsigned findSuitableFreeRegister(unsigned AntiDepReg, > - unsigned LastNewReg, > - const TargetRegisterClass *); > void StartBlockForKills(MachineBasicBlock *BB); > > // ToggleKillFlag - Toggle a register operand kill flag. Other > @@ -250,8 +222,9 @@ > > // Check for antidep breaking override... > if (EnableAntiDepBreaking.getPosition() > 0) { > - AntiDepMode = (EnableAntiDepBreaking) ? > - TargetSubtarget::ANTIDEP_CRITICAL : TargetSubtarget::ANTIDEP_NONE; > + AntiDepMode = (EnableAntiDepBreaking == "all") ? TargetSubtarget::ANTIDEP_ALL : > + (EnableAntiDepBreaking == "critical") ? TargetSubtarget::ANTIDEP_CRITICAL : > + TargetSubtarget::ANTIDEP_NONE; > } > > DEBUG(errs() << "PostRAScheduler\n"); > @@ -262,8 +235,12 @@ > ScheduleHazardRecognizer *HR = EnablePostRAHazardAvoidance ? > (ScheduleHazardRecognizer *)new ExactHazardRecognizer(InstrItins) : > (ScheduleHazardRecognizer *)new SimpleHazardRecognizer(); > + AntiDepBreaker *ADB = > + (AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? NULL /* FIXME */ : > + (AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? > + new CriticalAntiDepBreaker(Fn) : NULL; > > - SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, AA, AntiDepMode); > + SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, ADB, AA); > > // Loop over all of the basic blocks > for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); > @@ -311,6 +288,9 @@ > Scheduler.FixupKills(MBB); > } > > + delete HR; > + delete ADB; > + > return true; > } > > @@ -321,78 +301,10 @@ > // Call the superclass. > ScheduleDAGInstrs::StartBlock(BB); > > - // Reset the hazard recognizer. > + // Reset the hazard recognizer and anti-dep breaker. > HazardRec->Reset(); > - > - // Clear out the register class data. > - std::fill(Classes, array_endof(Classes), > - static_cast(0)); > - > - // Initialize the indices to indicate that no registers are live. > - std::fill(KillIndices, array_endof(KillIndices), ~0u); > - std::fill(DefIndices, array_endof(DefIndices), BB->size()); > - > - // Clear "do not change" set. > - KeepRegs.clear(); > - > - bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn()); > - > - // Determine the live-out physregs for this block. > - if (IsReturnBlock) { > - // In a return block, examine the function live-out regs. > - for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), > - E = MRI.liveout_end(); I != E; ++I) { > - unsigned Reg = *I; > - Classes[Reg] = reinterpret_cast(-1); > - KillIndices[Reg] = BB->size(); > - DefIndices[Reg] = ~0u; > - // Repeat, for all aliases. > - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > - unsigned AliasReg = *Alias; > - Classes[AliasReg] = reinterpret_cast(-1); > - KillIndices[AliasReg] = BB->size(); > - DefIndices[AliasReg] = ~0u; > - } > - } > - } else { > - // In a non-return block, examine the live-in regs of all successors. > - for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), > - SE = BB->succ_end(); SI != SE; ++SI) > - for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), > - E = (*SI)->livein_end(); I != E; ++I) { > - unsigned Reg = *I; > - Classes[Reg] = reinterpret_cast(-1); > - KillIndices[Reg] = BB->size(); > - DefIndices[Reg] = ~0u; > - // Repeat, for all aliases. > - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > - unsigned AliasReg = *Alias; > - Classes[AliasReg] = reinterpret_cast(-1); > - KillIndices[AliasReg] = BB->size(); > - DefIndices[AliasReg] = ~0u; > - } > - } > - } > - > - // Mark live-out callee-saved registers. In a return block this is > - // all callee-saved registers. In non-return this is any > - // callee-saved register that is not saved in the prolog. > - const MachineFrameInfo *MFI = MF.getFrameInfo(); > - BitVector Pristine = MFI->getPristineRegs(BB); > - for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { > - unsigned Reg = *I; > - if (!IsReturnBlock && !Pristine.test(Reg)) continue; > - Classes[Reg] = reinterpret_cast(-1); > - KillIndices[Reg] = BB->size(); > - DefIndices[Reg] = ~0u; > - // Repeat, for all aliases. > - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > - unsigned AliasReg = *Alias; > - Classes[AliasReg] = reinterpret_cast(-1); > - KillIndices[AliasReg] = BB->size(); > - DefIndices[AliasReg] = ~0u; > - } > - } > + if (AntiDepBreak != NULL) > + AntiDepBreak->StartBlock(BB); > } > > /// Schedule - Schedule the instruction range using list scheduling. > @@ -403,8 +315,11 @@ > // Build the scheduling graph. > BuildSchedGraph(AA); > > - if (AntiDepMode != TargetSubtarget::ANTIDEP_NONE) { > - if (BreakAntiDependencies()) { > + if (AntiDepBreak != NULL) { > + unsigned Broken = > + AntiDepBreak->BreakAntiDependencies(SUnits, Begin, InsertPos, > + InsertPosIndex); > + if (Broken > 0) { > // We made changes. Update the dependency graph. > // Theoretically we could update the graph in place: > // When a live range is changed to use a different register, remove > @@ -415,6 +330,8 @@ > EntrySU = SUnit(); > ExitSU = SUnit(); > BuildSchedGraph(AA); > + > + NumFixedAnti += Broken; > } > } > > @@ -432,436 +349,20 @@ > /// instruction, which will not be scheduled. > /// > void SchedulePostRATDList::Observe(MachineInstr *MI, unsigned Count) { > - assert(Count < InsertPosIndex && "Instruction index out of expected range!"); > - > - // Any register which was defined within the previous scheduling region > - // may have been rescheduled and its lifetime may overlap with registers > - // in ways not reflected in our current liveness state. For each such > - // register, adjust the liveness state to be conservatively correct. > - for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) > - if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) { > - assert(KillIndices[Reg] == ~0u && "Clobbered register is live!"); > - // Mark this register to be non-renamable. > - Classes[Reg] = reinterpret_cast(-1); > - // Move the def index to the end of the previous region, to reflect > - // that the def could theoretically have been scheduled at the end. > - DefIndices[Reg] = InsertPosIndex; > - } > - > - PrescanInstruction(MI); > - ScanInstruction(MI, Count); > + if (AntiDepBreak != NULL) > + AntiDepBreak->Observe(MI, Count, InsertPosIndex); > } > > /// FinishBlock - Clean up register live-range state. > /// > void SchedulePostRATDList::FinishBlock() { > - RegRefs.clear(); > + if (AntiDepBreak != NULL) > + AntiDepBreak->FinishBlock(); > > // Call the superclass. > ScheduleDAGInstrs::FinishBlock(); > } > > -/// CriticalPathStep - Return the next SUnit after SU on the bottom-up > -/// critical path. > -static SDep *CriticalPathStep(SUnit *SU) { > - SDep *Next = 0; > - unsigned NextDepth = 0; > - // Find the predecessor edge with the greatest depth. > - for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end(); > - P != PE; ++P) { > - SUnit *PredSU = P->getSUnit(); > - unsigned PredLatency = P->getLatency(); > - unsigned PredTotalLatency = PredSU->getDepth() + PredLatency; > - // In the case of a latency tie, prefer an anti-dependency edge over > - // other types of edges. > - if (NextDepth < PredTotalLatency || > - (NextDepth == PredTotalLatency && P->getKind() == SDep::Anti)) { > - NextDepth = PredTotalLatency; > - Next = &*P; > - } > - } > - return Next; > -} > - > -void SchedulePostRATDList::PrescanInstruction(MachineInstr *MI) { > - // Scan the register operands for this instruction and update > - // Classes and RegRefs. > - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > - MachineOperand &MO = MI->getOperand(i); > - if (!MO.isReg()) continue; > - unsigned Reg = MO.getReg(); > - if (Reg == 0) continue; > - const TargetRegisterClass *NewRC = 0; > - > - if (i < MI->getDesc().getNumOperands()) > - NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); > - > - // For now, only allow the register to be changed if its register > - // class is consistent across all uses. > - if (!Classes[Reg] && NewRC) > - Classes[Reg] = NewRC; > - else if (!NewRC || Classes[Reg] != NewRC) > - Classes[Reg] = reinterpret_cast(-1); > - > - // Now check for aliases. > - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > - // If an alias of the reg is used during the live range, give up. > - // Note that this allows us to skip checking if AntiDepReg > - // overlaps with any of the aliases, among other things. > - unsigned AliasReg = *Alias; > - if (Classes[AliasReg]) { > - Classes[AliasReg] = reinterpret_cast(-1); > - Classes[Reg] = reinterpret_cast(-1); > - } > - } > - > - // If we're still willing to consider this register, note the reference. > - if (Classes[Reg] != reinterpret_cast(-1)) > - RegRefs.insert(std::make_pair(Reg, &MO)); > - > - // It's not safe to change register allocation for source operands of > - // that have special allocation requirements. > - if (MO.isUse() && MI->getDesc().hasExtraSrcRegAllocReq()) { > - if (KeepRegs.insert(Reg)) { > - for (const unsigned *Subreg = TRI->getSubRegisters(Reg); > - *Subreg; ++Subreg) > - KeepRegs.insert(*Subreg); > - } > - } > - } > -} > - > -void SchedulePostRATDList::ScanInstruction(MachineInstr *MI, > - unsigned Count) { > - // Update liveness. > - // Proceding upwards, registers that are defed but not used in this > - // instruction are now dead. > - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > - MachineOperand &MO = MI->getOperand(i); > - if (!MO.isReg()) continue; > - unsigned Reg = MO.getReg(); > - if (Reg == 0) continue; > - if (!MO.isDef()) continue; > - // Ignore two-addr defs. > - if (MI->isRegTiedToUseOperand(i)) continue; > - > - DefIndices[Reg] = Count; > - KillIndices[Reg] = ~0u; > - assert(((KillIndices[Reg] == ~0u) != > - (DefIndices[Reg] == ~0u)) && > - "Kill and Def maps aren't consistent for Reg!"); > - KeepRegs.erase(Reg); > - Classes[Reg] = 0; > - RegRefs.erase(Reg); > - // Repeat, for all subregs. > - for (const unsigned *Subreg = TRI->getSubRegisters(Reg); > - *Subreg; ++Subreg) { > - unsigned SubregReg = *Subreg; > - DefIndices[SubregReg] = Count; > - KillIndices[SubregReg] = ~0u; > - KeepRegs.erase(SubregReg); > - Classes[SubregReg] = 0; > - RegRefs.erase(SubregReg); > - } > - // Conservatively mark super-registers as unusable. > - for (const unsigned *Super = TRI->getSuperRegisters(Reg); > - *Super; ++Super) { > - unsigned SuperReg = *Super; > - Classes[SuperReg] = reinterpret_cast(-1); > - } > - } > - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > - MachineOperand &MO = MI->getOperand(i); > - if (!MO.isReg()) continue; > - unsigned Reg = MO.getReg(); > - if (Reg == 0) continue; > - if (!MO.isUse()) continue; > - > - const TargetRegisterClass *NewRC = 0; > - if (i < MI->getDesc().getNumOperands()) > - NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); > - > - // For now, only allow the register to be changed if its register > - // class is consistent across all uses. > - if (!Classes[Reg] && NewRC) > - Classes[Reg] = NewRC; > - else if (!NewRC || Classes[Reg] != NewRC) > - Classes[Reg] = reinterpret_cast(-1); > - > - RegRefs.insert(std::make_pair(Reg, &MO)); > - > - // It wasn't previously live but now it is, this is a kill. > - if (KillIndices[Reg] == ~0u) { > - KillIndices[Reg] = Count; > - DefIndices[Reg] = ~0u; > - assert(((KillIndices[Reg] == ~0u) != > - (DefIndices[Reg] == ~0u)) && > - "Kill and Def maps aren't consistent for Reg!"); > - } > - // Repeat, for all aliases. > - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > - unsigned AliasReg = *Alias; > - if (KillIndices[AliasReg] == ~0u) { > - KillIndices[AliasReg] = Count; > - DefIndices[AliasReg] = ~0u; > - } > - } > - } > -} > - > -unsigned > -SchedulePostRATDList::findSuitableFreeRegister(unsigned AntiDepReg, > - unsigned LastNewReg, > - const TargetRegisterClass *RC) { > - for (TargetRegisterClass::iterator R = RC->allocation_order_begin(MF), > - RE = RC->allocation_order_end(MF); R != RE; ++R) { > - unsigned NewReg = *R; > - // Don't replace a register with itself. > - if (NewReg == AntiDepReg) continue; > - // Don't replace a register with one that was recently used to repair > - // an anti-dependence with this AntiDepReg, because that would > - // re-introduce that anti-dependence. > - if (NewReg == LastNewReg) continue; > - // If NewReg is dead and NewReg's most recent def is not before > - // AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg. > - assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u)) && > - "Kill and Def maps aren't consistent for AntiDepReg!"); > - assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u)) && > - "Kill and Def maps aren't consistent for NewReg!"); > - if (KillIndices[NewReg] != ~0u || > - Classes[NewReg] == reinterpret_cast(-1) || > - KillIndices[AntiDepReg] > DefIndices[NewReg]) > - continue; > - return NewReg; > - } > - > - // No registers are free and available! > - return 0; > -} > - > -/// BreakAntiDependencies - Identifiy anti-dependencies along the critical path > -/// of the ScheduleDAG and break them by renaming registers. > -/// > -bool SchedulePostRATDList::BreakAntiDependencies() { > - // The code below assumes that there is at least one instruction, > - // so just duck out immediately if the block is empty. > - if (SUnits.empty()) return false; > - > - // Find the node at the bottom of the critical path. > - SUnit *Max = 0; > - for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { > - SUnit *SU = &SUnits[i]; > - if (!Max || SU->getDepth() + SU->Latency > Max->getDepth() + Max->Latency) > - Max = SU; > - } > - > -#ifndef NDEBUG > - { > - DEBUG(errs() << "Critical path has total latency " > - << (Max->getDepth() + Max->Latency) << "\n"); > - DEBUG(errs() << "Available regs:"); > - for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { > - if (KillIndices[Reg] == ~0u) > - DEBUG(errs() << " " << TRI->getName(Reg)); > - } > - DEBUG(errs() << '\n'); > - } > -#endif > - > - // Track progress along the critical path through the SUnit graph as we walk > - // the instructions. > - SUnit *CriticalPathSU = Max; > - MachineInstr *CriticalPathMI = CriticalPathSU->getInstr(); > - > - // Consider this pattern: > - // A = ... > - // ... = A > - // A = ... > - // ... = A > - // A = ... > - // ... = A > - // A = ... > - // ... = A > - // There are three anti-dependencies here, and without special care, > - // we'd break all of them using the same register: > - // A = ... > - // ... = A > - // B = ... > - // ... = B > - // B = ... > - // ... = B > - // B = ... > - // ... = B > - // because at each anti-dependence, B is the first register that > - // isn't A which is free. This re-introduces anti-dependencies > - // at all but one of the original anti-dependencies that we were > - // trying to break. To avoid this, keep track of the most recent > - // register that each register was replaced with, avoid > - // using it to repair an anti-dependence on the same register. > - // This lets us produce this: > - // A = ... > - // ... = A > - // B = ... > - // ... = B > - // C = ... > - // ... = C > - // B = ... > - // ... = B > - // This still has an anti-dependence on B, but at least it isn't on the > - // original critical path. > - // > - // TODO: If we tracked more than one register here, we could potentially > - // fix that remaining critical edge too. This is a little more involved, > - // because unlike the most recent register, less recent registers should > - // still be considered, though only if no other registers are available. > - unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = {}; > - > - // Attempt to break anti-dependence edges on the critical path. Walk the > - // instructions from the bottom up, tracking information about liveness > - // as we go to help determine which registers are available. > - bool Changed = false; > - unsigned Count = InsertPosIndex - 1; > - for (MachineBasicBlock::iterator I = InsertPos, E = Begin; > - I != E; --Count) { > - MachineInstr *MI = --I; > - > - // Check if this instruction has a dependence on the critical path that > - // is an anti-dependence that we may be able to break. If it is, set > - // AntiDepReg to the non-zero register associated with the anti-dependence. > - // > - // We limit our attention to the critical path as a heuristic to avoid > - // breaking anti-dependence edges that aren't going to significantly > - // impact the overall schedule. There are a limited number of registers > - // and we want to save them for the important edges. > - // > - // TODO: Instructions with multiple defs could have multiple > - // anti-dependencies. The current code here only knows how to break one > - // edge per instruction. Note that we'd have to be able to break all of > - // the anti-dependencies in an instruction in order to be effective. > - unsigned AntiDepReg = 0; > - if (MI == CriticalPathMI) { > - if (SDep *Edge = CriticalPathStep(CriticalPathSU)) { > - SUnit *NextSU = Edge->getSUnit(); > - > - // Only consider anti-dependence edges. > - if (Edge->getKind() == SDep::Anti) { > - AntiDepReg = Edge->getReg(); > - assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); > - if (!AllocatableSet.test(AntiDepReg)) > - // Don't break anti-dependencies on non-allocatable registers. > - AntiDepReg = 0; > - else if (KeepRegs.count(AntiDepReg)) > - // Don't break anti-dependencies if an use down below requires > - // this exact register. > - AntiDepReg = 0; > - else { > - // If the SUnit has other dependencies on the SUnit that it > - // anti-depends on, don't bother breaking the anti-dependency > - // since those edges would prevent such units from being > - // scheduled past each other regardless. > - // > - // Also, if there are dependencies on other SUnits with the > - // same register as the anti-dependency, don't attempt to > - // break it. > - for (SUnit::pred_iterator P = CriticalPathSU->Preds.begin(), > - PE = CriticalPathSU->Preds.end(); P != PE; ++P) > - if (P->getSUnit() == NextSU ? > - (P->getKind() != SDep::Anti || P->getReg() != AntiDepReg) : > - (P->getKind() == SDep::Data && P->getReg() == AntiDepReg)) { > - AntiDepReg = 0; > - break; > - } > - } > - } > - CriticalPathSU = NextSU; > - CriticalPathMI = CriticalPathSU->getInstr(); > - } else { > - // We've reached the end of the critical path. > - CriticalPathSU = 0; > - CriticalPathMI = 0; > - } > - } > - > - PrescanInstruction(MI); > - > - if (MI->getDesc().hasExtraDefRegAllocReq()) > - // If this instruction's defs have special allocation requirement, don't > - // break this anti-dependency. > - AntiDepReg = 0; > - else if (AntiDepReg) { > - // If this instruction has a use of AntiDepReg, breaking it > - // is invalid. > - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > - MachineOperand &MO = MI->getOperand(i); > - if (!MO.isReg()) continue; > - unsigned Reg = MO.getReg(); > - if (Reg == 0) continue; > - if (MO.isUse() && AntiDepReg == Reg) { > - AntiDepReg = 0; > - break; > - } > - } > - } > - > - // Determine AntiDepReg's register class, if it is live and is > - // consistently used within a single class. > - const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes[AntiDepReg] : 0; > - assert((AntiDepReg == 0 || RC != NULL) && > - "Register should be live if it's causing an anti-dependence!"); > - if (RC == reinterpret_cast(-1)) > - AntiDepReg = 0; > - > - // Look for a suitable register to use to break the anti-depenence. > - // > - // TODO: Instead of picking the first free register, consider which might > - // be the best. > - if (AntiDepReg != 0) { > - if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg, > - LastNewReg[AntiDepReg], > - RC)) { > - DEBUG(errs() << "Breaking anti-dependence edge on " > - << TRI->getName(AntiDepReg) > - << " with " << RegRefs.count(AntiDepReg) << " references" > - << " using " << TRI->getName(NewReg) << "!\n"); > - > - // Update the references to the old register to refer to the new > - // register. > - std::pair::iterator, > - std::multimap::iterator> > - Range = RegRefs.equal_range(AntiDepReg); > - for (std::multimap::iterator > - Q = Range.first, QE = Range.second; Q != QE; ++Q) > - Q->second->setReg(NewReg); > - > - // We just went back in time and modified history; the > - // liveness information for the anti-depenence reg is now > - // inconsistent. Set the state as if it were dead. > - Classes[NewReg] = Classes[AntiDepReg]; > - DefIndices[NewReg] = DefIndices[AntiDepReg]; > - KillIndices[NewReg] = KillIndices[AntiDepReg]; > - assert(((KillIndices[NewReg] == ~0u) != > - (DefIndices[NewReg] == ~0u)) && > - "Kill and Def maps aren't consistent for NewReg!"); > - > - Classes[AntiDepReg] = 0; > - DefIndices[AntiDepReg] = KillIndices[AntiDepReg]; > - KillIndices[AntiDepReg] = ~0u; > - assert(((KillIndices[AntiDepReg] == ~0u) != > - (DefIndices[AntiDepReg] == ~0u)) && > - "Kill and Def maps aren't consistent for AntiDepReg!"); > - > - RegRefs.erase(AntiDepReg); > - Changed = true; > - LastNewReg[AntiDepReg] = NewReg; > - } > - } > - > - ScanInstruction(MI, Count); > - } > - > - return Changed; > -} > - > /// StartBlockForKills - Initialize register live-range state for updating kills > /// > void SchedulePostRATDList::StartBlockForKills(MachineBasicBlock *BB) { > > Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=85127&r1=85126&r2=85127&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Mon Oct 26 11:59:04 2009 > @@ -130,7 +130,7 @@ > /// for Thumb1. > bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, > TargetSubtarget::AntiDepBreakMode& mode) const { > - mode = TargetSubtarget::ANTIDEP_NONE; > + mode = TargetSubtarget::ANTIDEP_CRITICAL; > return PostRAScheduler && OptLevel >= CodeGenOpt::Default; > } > > > Modified: llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll?rev=85127&r1=85126&r2=85127&view=diff > > ============================================================================== > --- llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll (original) > +++ llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll Mon Oct 26 11:59:04 2009 > @@ -1,7 +1,7 @@ > -; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies=false > %t > +; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies=none > %t > ; RUN: grep {%xmm0} %t | count 14 > ; RUN: not grep {%xmm1} %t > -; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies > %t > +; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies=critical > %t > ; RUN: grep {%xmm0} %t | count 7 > ; RUN: grep {%xmm1} %t | count 7 > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From clattner at apple.com Mon Oct 26 16:26:16 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 26 Oct 2009 14:26:16 -0700 Subject: [llvm-commits] [llvm] r85147 - in /llvm/trunk: Makefile.config.in autoconf/configure.ac autoconf/m4/cxx_flag_check.m4 In-Reply-To: <200910261958.n9QJwjjp000406@zion.cs.uiuc.edu> References: <200910261958.n9QJwjjp000406@zion.cs.uiuc.edu> Message-ID: <5E72AE8E-1A5B-4A67-A916-CE8ABEC0D83E@apple.com> On Oct 26, 2009, at 12:58 PM, Julien Lerouge wrote: > Author: jlerouge > Date: Mon Oct 26 14:58:44 2009 > New Revision: 85147 > > URL: http://llvm.org/viewvc/llvm-project?rev=85147&view=rev > Log: > Add an autoconf test to check for optional compiler flags like > -Wno-missing-field-initializers or -Wno-variadic-macros. Nice, thanks Julien! -Chris > > Added: > llvm/trunk/autoconf/m4/cxx_flag_check.m4 > Modified: > llvm/trunk/Makefile.config.in > llvm/trunk/autoconf/configure.ac > > Modified: llvm/trunk/Makefile.config.in > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile.config.in?rev=85147&r1=85146&r2=85147&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/Makefile.config.in (original) > +++ llvm/trunk/Makefile.config.in Mon Oct 26 14:58:44 2009 > @@ -320,3 +320,9 @@ > # support (via the -load option). > ENABLE_LLVMC_DYNAMIC_PLUGINS = 1 > #@ENABLE_LLVMC_DYNAMIC_PLUGINS@ > + > +# Optional flags supported by the compiler > +# -Wno-missing-field-initializers > +NO_MISSING_FIELD_INITIALIZERS = @NO_MISSING_FIELD_INITIALIZERS@ > +# -Wno-variadic-macros > +NO_VARIADIC_MACROS = @NO_VARIADIC_MACROS@ > > Modified: llvm/trunk/autoconf/configure.ac > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/autoconf/configure.ac?rev=85147&r1=85146&r2=85147&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/autoconf/configure.ac (original) > +++ llvm/trunk/autoconf/configure.ac Mon Oct 26 14:58:44 2009 > @@ -943,6 +943,12 @@ > dnl Tool compatibility is okay if we make it here. > AC_MSG_RESULT([ok]) > > +dnl Check optional compiler flags. > +AC_MSG_CHECKING([optional compiler flags]) > +CXX_FLAG_CHECK(NO_VARIADIC_MACROS, [-Wno-variadic-macros]) > +CXX_FLAG_CHECK(NO_MISSING_FIELD_INITIALIZERS, [-Wno-missing-field- > initializers]) > +AC_MSG_RESULT([$NO_VARIADIC_MACROS $NO_MISSING_FIELD_INITIALIZERS]) > + > dnl > = > = > = > -----------------------------------------------------------------------= > == > dnl=== > dnl=== SECTION 5: Check for libraries > > Added: llvm/trunk/autoconf/m4/cxx_flag_check.m4 > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/autoconf/m4/cxx_flag_check.m4?rev=85147&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/autoconf/m4/cxx_flag_check.m4 (added) > +++ llvm/trunk/autoconf/m4/cxx_flag_check.m4 Mon Oct 26 14:58:44 2009 > @@ -0,0 +1,2 @@ > +AC_DEFUN([CXX_FLAG_CHECK], > + [AC_SUBST($1, `$CXX $2 -fsyntax-only -xc /dev/null 2>/dev/null && > echo $2`)]) > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From david_goodwin at apple.com Mon Oct 26 16:27:07 2009 From: david_goodwin at apple.com (David Goodwin) Date: Mon, 26 Oct 2009 14:27:07 -0700 Subject: [llvm-commits] [llvm] r85127 - in /llvm/trunk: include/llvm/CodeGen/AntiDepBreaker.h lib/CodeGen/CMakeLists.txt lib/CodeGen/CriticalAntiDepBreaker.cpp lib/CodeGen/CriticalAntiDepBreaker.h lib/CodeGen/PostRASchedulerList.cpp lib/Target/ARM/ARMSubtarget.h test/CodeGen/X86/break-anti-dependencies.ll In-Reply-To: References: <200910261659.n9QGx4Yj023936@zion.cs.uiuc.edu> Message-ID: <35E02EF7-4CBB-4607-BC71-849E46D366D2@apple.com> I was just following the style of ScheduleHazardRecognizer, as it has the same "visibility" as AntiDepBreaker. But I can move it if that would be better... David On Oct 26, 2009, at 2:23 PM, Evan Cheng wrote: > It seems to be AntiDepBreaker.h should be inside lib/CodeGen. Is > there a reason to expose it? > > Evan > > On Oct 26, 2009, at 9:59 AM, David Goodwin wrote: > >> Author: david_goodwin >> Date: Mon Oct 26 11:59:04 2009 >> New Revision: 85127 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=85127&view=rev >> Log: >> Break anti-dependence breaking out into its own class. >> >> Added: >> llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h >> llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp >> llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h >> Modified: >> llvm/trunk/lib/CodeGen/CMakeLists.txt >> llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp >> llvm/trunk/lib/Target/ARM/ARMSubtarget.h >> llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll >> >> Added: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h?rev=85127&view=auto >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h (added) >> +++ llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Mon Oct 26 >> 11:59:04 2009 >> @@ -0,0 +1,56 @@ >> +//=- llvm/CodeGen/AntiDepBreaker.h - Anti-Dependence Breaking -*- C >> ++ -*-=// >> +// >> +// The LLVM Compiler Infrastructure >> +// >> +// This file is distributed under the University of Illinois Open >> Source >> +// License. See LICENSE.TXT for details. >> +// >> +// >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> +// >> +// This file implements the AntiDepBreaker class, which implements >> +// anti-dependence breaking heuristics for post-register- >> allocation scheduling. >> +// >> +// >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> + >> +#ifndef LLVM_CODEGEN_ANTIDEPBREAKER_H >> +#define LLVM_CODEGEN_ANTIDEPBREAKER_H >> + >> +#include "llvm/CodeGen/MachineBasicBlock.h" >> +#include "llvm/CodeGen/MachineFrameInfo.h" >> +#include "llvm/CodeGen/MachineFunction.h" >> +#include "llvm/CodeGen/MachineRegisterInfo.h" >> +#include "llvm/CodeGen/ScheduleDAG.h" >> +#include "llvm/Target/TargetRegisterInfo.h" >> + >> +namespace llvm { >> + >> +/// AntiDepBreaker - This class works into conjunction with the >> +/// post-RA scheduler to rename registers to break register >> +/// anti-dependencies. >> +class AntiDepBreaker { >> +public: >> + /// Start - Initialize anti-dep breaking for a new basic block. >> + virtual void StartBlock(MachineBasicBlock *BB) =0; >> + >> + /// BreakAntiDependencies - Identifiy anti-dependencies within a >> + /// basic-block region and break them by renaming registers. >> Return >> + /// the number of anti-dependencies broken. >> + /// >> + virtual unsigned BreakAntiDependencies(std::vector& SUnits, >> + >> MachineBasicBlock::iterator& Begin, >> + >> MachineBasicBlock::iterator& End, >> + unsigned InsertPosIndex) >> =0; >> + >> + /// Observe - Update liveness information to account for the >> current >> + /// instruction, which will not be scheduled. >> + /// >> + virtual void Observe(MachineInstr *MI, unsigned Count, >> + unsigned InsertPosIndex) =0; >> + >> + /// Finish - Finish anti-dep breaking for a basic block. >> + virtual void FinishBlock() =0; >> +}; >> + >> +} >> + >> +#endif >> >> Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=85127&r1=85126&r2=85127&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/CodeGen/CMakeLists.txt (original) >> +++ llvm/trunk/lib/CodeGen/CMakeLists.txt Mon Oct 26 11:59:04 2009 >> @@ -1,6 +1,7 @@ >> add_llvm_library(LLVMCodeGen >> BranchFolding.cpp >> CodePlacementOpt.cpp >> + CriticalAntiDepBreaker.cpp >> DeadMachineInstructionElim.cpp >> DwarfEHPrepare.cpp >> ELFCodeEmitter.cpp >> >> Added: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp?rev=85127&view=auto >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp (added) >> +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp Mon Oct 26 >> 11:59:04 2009 >> @@ -0,0 +1,539 @@ >> +//===----- CriticalAntiDepBreaker.cpp - Anti-dep breaker -------- >> ---------===// >> +// >> +// The LLVM Compiler Infrastructure >> +// >> +// This file is distributed under the University of Illinois Open >> Source >> +// License. See LICENSE.TXT for details. >> +// >> +// >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> +// >> +// This file implements the CriticalAntiDepBreaker class, which >> +// implements register anti-dependence breaking along a blocks >> +// critical path during post-RA scheduler. >> +// >> +// >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> + >> +#define DEBUG_TYPE "critical-antidep" >> +#include "CriticalAntiDepBreaker.h" >> +#include "llvm/CodeGen/MachineBasicBlock.h" >> +#include "llvm/CodeGen/MachineFrameInfo.h" >> +#include "llvm/Target/TargetMachine.h" >> +#include "llvm/Target/TargetRegisterInfo.h" >> +#include "llvm/Support/Debug.h" >> +#include "llvm/Support/ErrorHandling.h" >> +#include "llvm/Support/raw_ostream.h" >> + >> +using namespace llvm; >> + >> +CriticalAntiDepBreaker:: >> +CriticalAntiDepBreaker(MachineFunction& MFi) : >> + AntiDepBreaker(), MF(MFi), >> + MRI(MF.getRegInfo()), >> + TRI(MF.getTarget().getRegisterInfo()), >> + AllocatableSet(TRI->getAllocatableSet(MF)) >> +{ >> +} >> + >> +CriticalAntiDepBreaker::~CriticalAntiDepBreaker() { >> +} >> + >> +void CriticalAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { >> + // Clear out the register class data. >> + std::fill(Classes, array_endof(Classes), >> + static_cast(0)); >> + >> + // Initialize the indices to indicate that no registers are live. >> + std::fill(KillIndices, array_endof(KillIndices), ~0u); >> + std::fill(DefIndices, array_endof(DefIndices), BB->size()); >> + >> + // Clear "do not change" set. >> + KeepRegs.clear(); >> + >> + bool IsReturnBlock = (!BB->empty() && BB->back().getDesc >> ().isReturn()); >> + >> + // Determine the live-out physregs for this block. >> + if (IsReturnBlock) { >> + // In a return block, examine the function live-out regs. >> + for (MachineRegisterInfo::liveout_iterator I = >> MRI.liveout_begin(), >> + E = MRI.liveout_end(); I != E; ++I) { >> + unsigned Reg = *I; >> + Classes[Reg] = reinterpret_cast(-1); >> + KillIndices[Reg] = BB->size(); >> + DefIndices[Reg] = ~0u; >> + // Repeat, for all aliases. >> + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; + >> +Alias) { >> + unsigned AliasReg = *Alias; >> + Classes[AliasReg] = reinterpret_cast >> (-1); >> + KillIndices[AliasReg] = BB->size(); >> + DefIndices[AliasReg] = ~0u; >> + } >> + } >> + } else { >> + // In a non-return block, examine the live-in regs of all >> successors. >> + for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), >> + SE = BB->succ_end(); SI != SE; ++SI) >> + for (MachineBasicBlock::livein_iterator I = (*SI)- >> >livein_begin(), >> + E = (*SI)->livein_end(); I != E; ++I) { >> + unsigned Reg = *I; >> + Classes[Reg] = reinterpret_cast(-1); >> + KillIndices[Reg] = BB->size(); >> + DefIndices[Reg] = ~0u; >> + // Repeat, for all aliases. >> + for (const unsigned *Alias = TRI->getAliasSet(Reg); >> *Alias; ++Alias) { >> + unsigned AliasReg = *Alias; >> + Classes[AliasReg] = reinterpret_cast> *>(-1); >> + KillIndices[AliasReg] = BB->size(); >> + DefIndices[AliasReg] = ~0u; >> + } >> + } >> + } >> + >> + // Mark live-out callee-saved registers. In a return block this is >> + // all callee-saved registers. In non-return this is any >> + // callee-saved register that is not saved in the prolog. >> + const MachineFrameInfo *MFI = MF.getFrameInfo(); >> + BitVector Pristine = MFI->getPristineRegs(BB); >> + for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { >> + unsigned Reg = *I; >> + if (!IsReturnBlock && !Pristine.test(Reg)) continue; >> + Classes[Reg] = reinterpret_cast(-1); >> + KillIndices[Reg] = BB->size(); >> + DefIndices[Reg] = ~0u; >> + // Repeat, for all aliases. >> + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; + >> +Alias) { >> + unsigned AliasReg = *Alias; >> + Classes[AliasReg] = reinterpret_cast >> (-1); >> + KillIndices[AliasReg] = BB->size(); >> + DefIndices[AliasReg] = ~0u; >> + } >> + } >> +} >> + >> +void CriticalAntiDepBreaker::FinishBlock() { >> + RegRefs.clear(); >> + KeepRegs.clear(); >> +} >> + >> +void CriticalAntiDepBreaker::Observe(MachineInstr *MI, unsigned >> Count, >> + unsigned InsertPosIndex) { >> + assert(Count < InsertPosIndex && "Instruction index out of >> expected range!"); >> + >> + // Any register which was defined within the previous scheduling >> region >> + // may have been rescheduled and its lifetime may overlap with >> registers >> + // in ways not reflected in our current liveness state. For each >> such >> + // register, adjust the liveness state to be conservatively >> correct. >> + for (unsigned Reg = 0; Reg != >> TargetRegisterInfo::FirstVirtualRegister; ++Reg) >> + if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= >> Count) { >> + assert(KillIndices[Reg] == ~0u && "Clobbered register is >> live!"); >> + // Mark this register to be non-renamable. >> + Classes[Reg] = reinterpret_cast(-1); >> + // Move the def index to the end of the previous region, to >> reflect >> + // that the def could theoretically have been scheduled at >> the end. >> + DefIndices[Reg] = InsertPosIndex; >> + } >> + >> + PrescanInstruction(MI); >> + ScanInstruction(MI, Count); >> +} >> + >> +/// CriticalPathStep - Return the next SUnit after SU on the >> bottom-up >> +/// critical path. >> +static SDep *CriticalPathStep(SUnit *SU) { >> + SDep *Next = 0; >> + unsigned NextDepth = 0; >> + // Find the predecessor edge with the greatest depth. >> + for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU- >> >Preds.end(); >> + P != PE; ++P) { >> + SUnit *PredSU = P->getSUnit(); >> + unsigned PredLatency = P->getLatency(); >> + unsigned PredTotalLatency = PredSU->getDepth() + PredLatency; >> + // In the case of a latency tie, prefer an anti-dependency >> edge over >> + // other types of edges. >> + if (NextDepth < PredTotalLatency || >> + (NextDepth == PredTotalLatency && P->getKind() == >> SDep::Anti)) { >> + NextDepth = PredTotalLatency; >> + Next = &*P; >> + } >> + } >> + return Next; >> +} >> + >> +void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr *MI) { >> + // Scan the register operands for this instruction and update >> + // Classes and RegRefs. >> + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >> + MachineOperand &MO = MI->getOperand(i); >> + if (!MO.isReg()) continue; >> + unsigned Reg = MO.getReg(); >> + if (Reg == 0) continue; >> + const TargetRegisterClass *NewRC = 0; >> + >> + if (i < MI->getDesc().getNumOperands()) >> + NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); >> + >> + // For now, only allow the register to be changed if its >> register >> + // class is consistent across all uses. >> + if (!Classes[Reg] && NewRC) >> + Classes[Reg] = NewRC; >> + else if (!NewRC || Classes[Reg] != NewRC) >> + Classes[Reg] = reinterpret_cast(-1); >> + >> + // Now check for aliases. >> + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; + >> +Alias) { >> + // If an alias of the reg is used during the live range, >> give up. >> + // Note that this allows us to skip checking if AntiDepReg >> + // overlaps with any of the aliases, among other things. >> + unsigned AliasReg = *Alias; >> + if (Classes[AliasReg]) { >> + Classes[AliasReg] = reinterpret_cast >> (-1); >> + Classes[Reg] = reinterpret_cast(-1); >> + } >> + } >> + >> + // If we're still willing to consider this register, note the >> reference. >> + if (Classes[Reg] != reinterpret_cast(-1)) >> + RegRefs.insert(std::make_pair(Reg, &MO)); >> + >> + // It's not safe to change register allocation for source >> operands of >> + // that have special allocation requirements. >> + if (MO.isUse() && MI->getDesc().hasExtraSrcRegAllocReq()) { >> + if (KeepRegs.insert(Reg)) { >> + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); >> + *Subreg; ++Subreg) >> + KeepRegs.insert(*Subreg); >> + } >> + } >> + } >> +} >> + >> +void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI, >> + unsigned Count) { >> + // Update liveness. >> + // Proceding upwards, registers that are defed but not used in >> this >> + // instruction are now dead. >> + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >> + MachineOperand &MO = MI->getOperand(i); >> + if (!MO.isReg()) continue; >> + unsigned Reg = MO.getReg(); >> + if (Reg == 0) continue; >> + if (!MO.isDef()) continue; >> + // Ignore two-addr defs. >> + if (MI->isRegTiedToUseOperand(i)) continue; >> + >> + DefIndices[Reg] = Count; >> + KillIndices[Reg] = ~0u; >> + assert(((KillIndices[Reg] == ~0u) != >> + (DefIndices[Reg] == ~0u)) && >> + "Kill and Def maps aren't consistent for Reg!"); >> + KeepRegs.erase(Reg); >> + Classes[Reg] = 0; >> + RegRefs.erase(Reg); >> + // Repeat, for all subregs. >> + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); >> + *Subreg; ++Subreg) { >> + unsigned SubregReg = *Subreg; >> + DefIndices[SubregReg] = Count; >> + KillIndices[SubregReg] = ~0u; >> + KeepRegs.erase(SubregReg); >> + Classes[SubregReg] = 0; >> + RegRefs.erase(SubregReg); >> + } >> + // Conservatively mark super-registers as unusable. >> + for (const unsigned *Super = TRI->getSuperRegisters(Reg); >> + *Super; ++Super) { >> + unsigned SuperReg = *Super; >> + Classes[SuperReg] = reinterpret_cast >> (-1); >> + } >> + } >> + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >> + MachineOperand &MO = MI->getOperand(i); >> + if (!MO.isReg()) continue; >> + unsigned Reg = MO.getReg(); >> + if (Reg == 0) continue; >> + if (!MO.isUse()) continue; >> + >> + const TargetRegisterClass *NewRC = 0; >> + if (i < MI->getDesc().getNumOperands()) >> + NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); >> + >> + // For now, only allow the register to be changed if its >> register >> + // class is consistent across all uses. >> + if (!Classes[Reg] && NewRC) >> + Classes[Reg] = NewRC; >> + else if (!NewRC || Classes[Reg] != NewRC) >> + Classes[Reg] = reinterpret_cast(-1); >> + >> + RegRefs.insert(std::make_pair(Reg, &MO)); >> + >> + // It wasn't previously live but now it is, this is a kill. >> + if (KillIndices[Reg] == ~0u) { >> + KillIndices[Reg] = Count; >> + DefIndices[Reg] = ~0u; >> + assert(((KillIndices[Reg] == ~0u) != >> + (DefIndices[Reg] == ~0u)) && >> + "Kill and Def maps aren't consistent for Reg!"); >> + } >> + // Repeat, for all aliases. >> + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; + >> +Alias) { >> + unsigned AliasReg = *Alias; >> + if (KillIndices[AliasReg] == ~0u) { >> + KillIndices[AliasReg] = Count; >> + DefIndices[AliasReg] = ~0u; >> + } >> + } >> + } >> +} >> + >> +unsigned >> +CriticalAntiDepBreaker::findSuitableFreeRegister(unsigned >> AntiDepReg, >> + unsigned >> LastNewReg, >> + const >> TargetRegisterClass *RC) { >> + for (TargetRegisterClass::iterator R = RC->allocation_order_begin >> (MF), >> + RE = RC->allocation_order_end(MF); R != RE; ++R) { >> + unsigned NewReg = *R; >> + // Don't replace a register with itself. >> + if (NewReg == AntiDepReg) continue; >> + // Don't replace a register with one that was recently used to >> repair >> + // an anti-dependence with this AntiDepReg, because that would >> + // re-introduce that anti-dependence. >> + if (NewReg == LastNewReg) continue; >> + // If NewReg is dead and NewReg's most recent def is not before >> + // AntiDepReg's kill, it's safe to replace AntiDepReg with >> NewReg. >> + assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices >> [AntiDepReg] == ~0u)) && >> + "Kill and Def maps aren't consistent for AntiDepReg!"); >> + assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == >> ~0u)) && >> + "Kill and Def maps aren't consistent for NewReg!"); >> + if (KillIndices[NewReg] != ~0u || >> + Classes[NewReg] == reinterpret_cast >> (-1) || >> + KillIndices[AntiDepReg] > DefIndices[NewReg]) >> + continue; >> + return NewReg; >> + } >> + >> + // No registers are free and available! >> + return 0; >> +} >> + >> +unsigned CriticalAntiDepBreaker:: >> +BreakAntiDependencies(std::vector& SUnits, >> + MachineBasicBlock::iterator& Begin, >> + MachineBasicBlock::iterator& End, >> + unsigned InsertPosIndex) { >> + // The code below assumes that there is at least one instruction, >> + // so just duck out immediately if the block is empty. >> + if (SUnits.empty()) return 0; >> + >> + // Find the node at the bottom of the critical path. >> + SUnit *Max = 0; >> + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { >> + SUnit *SU = &SUnits[i]; >> + if (!Max || SU->getDepth() + SU->Latency > Max->getDepth() + >> Max->Latency) >> + Max = SU; >> + } >> + >> +#ifndef NDEBUG >> + { >> + DEBUG(errs() << "Critical path has total latency " >> + << (Max->getDepth() + Max->Latency) << "\n"); >> + DEBUG(errs() << "Available regs:"); >> + for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { >> + if (KillIndices[Reg] == ~0u) >> + DEBUG(errs() << " " << TRI->getName(Reg)); >> + } >> + DEBUG(errs() << '\n'); >> + } >> +#endif >> + >> + // Track progress along the critical path through the SUnit >> graph as we walk >> + // the instructions. >> + SUnit *CriticalPathSU = Max; >> + MachineInstr *CriticalPathMI = CriticalPathSU->getInstr(); >> + >> + // Consider this pattern: >> + // A = ... >> + // ... = A >> + // A = ... >> + // ... = A >> + // A = ... >> + // ... = A >> + // A = ... >> + // ... = A >> + // There are three anti-dependencies here, and without special >> care, >> + // we'd break all of them using the same register: >> + // A = ... >> + // ... = A >> + // B = ... >> + // ... = B >> + // B = ... >> + // ... = B >> + // B = ... >> + // ... = B >> + // because at each anti-dependence, B is the first register that >> + // isn't A which is free. This re-introduces anti-dependencies >> + // at all but one of the original anti-dependencies that we were >> + // trying to break. To avoid this, keep track of the most recent >> + // register that each register was replaced with, avoid >> + // using it to repair an anti-dependence on the same register. >> + // This lets us produce this: >> + // A = ... >> + // ... = A >> + // B = ... >> + // ... = B >> + // C = ... >> + // ... = C >> + // B = ... >> + // ... = B >> + // This still has an anti-dependence on B, but at least it isn't >> on the >> + // original critical path. >> + // >> + // TODO: If we tracked more than one register here, we could >> potentially >> + // fix that remaining critical edge too. This is a little more >> involved, >> + // because unlike the most recent register, less recent >> registers should >> + // still be considered, though only if no other registers are >> available. >> + unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = >> {}; >> + >> + // Attempt to break anti-dependence edges on the critical path. >> Walk the >> + // instructions from the bottom up, tracking information about >> liveness >> + // as we go to help determine which registers are available. >> + unsigned Broken = 0; >> + unsigned Count = InsertPosIndex - 1; >> + for (MachineBasicBlock::iterator I = End, E = Begin; >> + I != E; --Count) { >> + MachineInstr *MI = --I; >> + >> + // Check if this instruction has a dependence on the critical >> path that >> + // is an anti-dependence that we may be able to break. If it >> is, set >> + // AntiDepReg to the non-zero register associated with the >> anti-dependence. >> + // >> + // We limit our attention to the critical path as a heuristic >> to avoid >> + // breaking anti-dependence edges that aren't going to >> significantly >> + // impact the overall schedule. There are a limited number of >> registers >> + // and we want to save them for the important edges. >> + // >> + // TODO: Instructions with multiple defs could have multiple >> + // anti-dependencies. The current code here only knows how to >> break one >> + // edge per instruction. Note that we'd have to be able to >> break all of >> + // the anti-dependencies in an instruction in order to be >> effective. >> + unsigned AntiDepReg = 0; >> + if (MI == CriticalPathMI) { >> + if (SDep *Edge = CriticalPathStep(CriticalPathSU)) { >> + SUnit *NextSU = Edge->getSUnit(); >> + >> + // Only consider anti-dependence edges. >> + if (Edge->getKind() == SDep::Anti) { >> + AntiDepReg = Edge->getReg(); >> + assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); >> + if (!AllocatableSet.test(AntiDepReg)) >> + // Don't break anti-dependencies on non-allocatable >> registers. >> + AntiDepReg = 0; >> + else if (KeepRegs.count(AntiDepReg)) >> + // Don't break anti-dependencies if an use down below >> requires >> + // this exact register. >> + AntiDepReg = 0; >> + else { >> + // If the SUnit has other dependencies on the SUnit >> that it >> + // anti-depends on, don't bother breaking the anti- >> dependency >> + // since those edges would prevent such units from being >> + // scheduled past each other regardless. >> + // >> + // Also, if there are dependencies on other SUnits >> with the >> + // same register as the anti-dependency, don't attempt >> to >> + // break it. >> + for (SUnit::pred_iterator P = CriticalPathSU- >> >Preds.begin(), >> + PE = CriticalPathSU->Preds.end(); P != PE; ++P) >> + if (P->getSUnit() == NextSU ? >> + (P->getKind() != SDep::Anti || P->getReg() != >> AntiDepReg) : >> + (P->getKind() == SDep::Data && P->getReg() == >> AntiDepReg)) { >> + AntiDepReg = 0; >> + break; >> + } >> + } >> + } >> + CriticalPathSU = NextSU; >> + CriticalPathMI = CriticalPathSU->getInstr(); >> + } else { >> + // We've reached the end of the critical path. >> + CriticalPathSU = 0; >> + CriticalPathMI = 0; >> + } >> + } >> + >> + PrescanInstruction(MI); >> + >> + if (MI->getDesc().hasExtraDefRegAllocReq()) >> + // If this instruction's defs have special allocation >> requirement, don't >> + // break this anti-dependency. >> + AntiDepReg = 0; >> + else if (AntiDepReg) { >> + // If this instruction has a use of AntiDepReg, breaking it >> + // is invalid. >> + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >> + MachineOperand &MO = MI->getOperand(i); >> + if (!MO.isReg()) continue; >> + unsigned Reg = MO.getReg(); >> + if (Reg == 0) continue; >> + if (MO.isUse() && AntiDepReg == Reg) { >> + AntiDepReg = 0; >> + break; >> + } >> + } >> + } >> + >> + // Determine AntiDepReg's register class, if it is live and is >> + // consistently used within a single class. >> + const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes >> [AntiDepReg] : 0; >> + assert((AntiDepReg == 0 || RC != NULL) && >> + "Register should be live if it's causing an anti- >> dependence!"); >> + if (RC == reinterpret_cast(-1)) >> + AntiDepReg = 0; >> + >> + // Look for a suitable register to use to break the anti- >> depenence. >> + // >> + // TODO: Instead of picking the first free register, consider >> which might >> + // be the best. >> + if (AntiDepReg != 0) { >> + if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg, >> + LastNewReg >> [AntiDepReg], >> + RC)) { >> + DEBUG(errs() << "Breaking anti-dependence edge on " >> + << TRI->getName(AntiDepReg) >> + << " with " << RegRefs.count(AntiDepReg) << " >> references" >> + << " using " << TRI->getName(NewReg) << "!\n"); >> + >> + // Update the references to the old register to refer to >> the new >> + // register. >> + std::pair> *>::iterator, >> + std::multimap> *>::iterator> >> + Range = RegRefs.equal_range(AntiDepReg); >> + for (std::multimap::iterator >> + Q = Range.first, QE = Range.second; Q != QE; ++Q) >> + Q->second->setReg(NewReg); >> + >> + // We just went back in time and modified history; the >> + // liveness information for the anti-depenence reg is now >> + // inconsistent. Set the state as if it were dead. >> + Classes[NewReg] = Classes[AntiDepReg]; >> + DefIndices[NewReg] = DefIndices[AntiDepReg]; >> + KillIndices[NewReg] = KillIndices[AntiDepReg]; >> + assert(((KillIndices[NewReg] == ~0u) != >> + (DefIndices[NewReg] == ~0u)) && >> + "Kill and Def maps aren't consistent for NewReg!"); >> + >> + Classes[AntiDepReg] = 0; >> + DefIndices[AntiDepReg] = KillIndices[AntiDepReg]; >> + KillIndices[AntiDepReg] = ~0u; >> + assert(((KillIndices[AntiDepReg] == ~0u) != >> + (DefIndices[AntiDepReg] == ~0u)) && >> + "Kill and Def maps aren't consistent for AntiDepReg!"); >> + >> + RegRefs.erase(AntiDepReg); >> + LastNewReg[AntiDepReg] = NewReg; >> + ++Broken; >> + } >> + } >> + >> + ScanInstruction(MI, Count); >> + } >> + >> + return Broken; >> +} >> >> Added: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h?rev=85127&view=auto >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h (added) >> +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h Mon Oct 26 >> 11:59:04 2009 >> @@ -0,0 +1,95 @@ >> +//=- llvm/CodeGen/CriticalAntiDepBreaker.h - Anti-Dep Support -*- C >> ++ -*-=// >> +// >> +// The LLVM Compiler Infrastructure >> +// >> +// This file is distributed under the University of Illinois Open >> Source >> +// License. See LICENSE.TXT for details. >> +// >> +// >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> +// >> +// This file implements the CriticalAntiDepBreaker class, which >> +// implements register anti-dependence breaking along a blocks >> +// critical path during post-RA scheduler. >> +// >> +// >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> + >> +#ifndef LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H >> +#define LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H >> + >> +#include "llvm/CodeGen/AntiDepBreaker.h" >> +#include "llvm/CodeGen/MachineBasicBlock.h" >> +#include "llvm/CodeGen/MachineFrameInfo.h" >> +#include "llvm/CodeGen/MachineFunction.h" >> +#include "llvm/CodeGen/MachineRegisterInfo.h" >> +#include "llvm/CodeGen/ScheduleDAG.h" >> +#include "llvm/Target/TargetRegisterInfo.h" >> +#include "llvm/ADT/BitVector.h" >> +#include "llvm/ADT/SmallSet.h" >> + >> +namespace llvm { >> + class CriticalAntiDepBreaker : public AntiDepBreaker { >> + MachineFunction& MF; >> + MachineRegisterInfo &MRI; >> + const TargetRegisterInfo *TRI; >> + >> + /// AllocatableSet - The set of allocatable registers. >> + /// We'll be ignoring anti-dependencies on non-allocatable >> registers, >> + /// because they may not be safe to break. >> + const BitVector AllocatableSet; >> + >> + /// Classes - For live regs that are only used in one register >> class in a >> + /// live range, the register class. If the register is not >> live, the >> + /// corresponding value is null. If the register is live but >> used in >> + /// multiple register classes, the corresponding value is -1 >> casted to a >> + /// pointer. >> + const TargetRegisterClass * >> + Classes[TargetRegisterInfo::FirstVirtualRegister]; >> + >> + /// RegRegs - Map registers to all their references within a >> live range. >> + std::multimap RegRefs; >> + >> + /// KillIndices - The index of the most recent kill (proceding >> bottom-up), >> + /// or ~0u if the register is not live. >> + unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; >> + >> + /// DefIndices - The index of the most recent complete def >> (proceding bottom >> + /// up), or ~0u if the register is live. >> + unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; >> + >> + /// KeepRegs - A set of registers which are live and cannot be >> changed to >> + /// break anti-dependencies. >> + SmallSet KeepRegs; >> + >> + public: >> + CriticalAntiDepBreaker(MachineFunction& MFi); >> + ~CriticalAntiDepBreaker(); >> + >> + /// Start - Initialize anti-dep breaking for a new basic block. >> + void StartBlock(MachineBasicBlock *BB); >> + >> + /// BreakAntiDependencies - Identifiy anti-dependencies along >> the critical path >> + /// of the ScheduleDAG and break them by renaming registers. >> + /// >> + unsigned BreakAntiDependencies(std::vector& SUnits, >> + MachineBasicBlock::iterator& >> Begin, >> + MachineBasicBlock::iterator& End, >> + unsigned InsertPosIndex); >> + >> + /// Observe - Update liveness information to account for the >> current >> + /// instruction, which will not be scheduled. >> + /// >> + void Observe(MachineInstr *MI, unsigned Count, unsigned >> InsertPosIndex); >> + >> + /// Finish - Finish anti-dep breaking for a basic block. >> + void FinishBlock(); >> + >> + private: >> + void PrescanInstruction(MachineInstr *MI); >> + void ScanInstruction(MachineInstr *MI, unsigned Count); >> + unsigned findSuitableFreeRegister(unsigned AntiDepReg, >> + unsigned LastNewReg, >> + const TargetRegisterClass *); >> + }; >> +} >> + >> +#endif >> >> Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=85127&r1=85126&r2=85127&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) >> +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Mon Oct 26 >> 11:59:04 2009 >> @@ -19,6 +19,7 @@ >> // >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> >> #define DEBUG_TYPE "post-RA-sched" >> +#include "CriticalAntiDepBreaker.h" >> #include "ExactHazardRecognizer.h" >> #include "SimpleHazardRecognizer.h" >> #include "ScheduleDAGInstrs.h" >> @@ -40,6 +41,7 @@ >> #include "llvm/Support/Debug.h" >> #include "llvm/Support/ErrorHandling.h" >> #include "llvm/Support/raw_ostream.h" >> +#include "llvm/ADT/BitVector.h" >> #include "llvm/ADT/Statistic.h" >> #include >> #include >> @@ -47,6 +49,7 @@ >> >> STATISTIC(NumNoops, "Number of noops inserted"); >> STATISTIC(NumStalls, "Number of pipeline stalls"); >> +STATISTIC(NumFixedAnti, "Number of fixed anti-dependencies"); >> >> // Post-RA scheduling is enabled with >> // TargetSubtarget.enablePostRAScheduler(). This flag can be used to >> @@ -55,10 +58,11 @@ >> EnablePostRAScheduler("post-RA-scheduler", >> cl::desc("Enable scheduling after register >> allocation"), >> cl::init(false), cl::Hidden); >> -static cl::opt >> +static cl::opt >> EnableAntiDepBreaking("break-anti-dependencies", >> - cl::desc("Break post-RA scheduling anti- >> dependencies"), >> - cl::init(true), cl::Hidden); >> + cl::desc("Break post-RA scheduling anti- >> dependencies: " >> + "\"critical\", \"all\", or \"none >> \""), >> + cl::init("none"), cl::Hidden); >> static cl::opt >> EnablePostRAHazardAvoidance("avoid-hazards", >> cl::desc("Enable exact hazard avoidance"), >> @@ -116,56 +120,30 @@ >> /// Topo - A topological ordering for SUnits. >> ScheduleDAGTopologicalSort Topo; >> >> - /// AllocatableSet - The set of allocatable registers. >> - /// We'll be ignoring anti-dependencies on non-allocatable >> registers, >> - /// because they may not be safe to break. >> - const BitVector AllocatableSet; >> - >> /// HazardRec - The hazard recognizer to use. >> ScheduleHazardRecognizer *HazardRec; >> >> + /// AntiDepBreak - Anti-dependence breaking object, or NULL if >> none >> + AntiDepBreaker *AntiDepBreak; >> + >> /// AA - AliasAnalysis for making memory reference queries. >> AliasAnalysis *AA; >> >> - /// AntiDepMode - Anti-dependence breaking mode >> - TargetSubtarget::AntiDepBreakMode AntiDepMode; >> - >> - /// Classes - For live regs that are only used in one register >> class in a >> - /// live range, the register class. If the register is not >> live, the >> - /// corresponding value is null. If the register is live but >> used in >> - /// multiple register classes, the corresponding value is -1 >> casted to a >> - /// pointer. >> - const TargetRegisterClass * >> - Classes[TargetRegisterInfo::FirstVirtualRegister]; >> - >> - /// RegRegs - Map registers to all their references within a >> live range. >> - std::multimap RegRefs; >> - >> /// KillIndices - The index of the most recent kill (proceding >> bottom-up), >> /// or ~0u if the register is not live. >> unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; >> >> - /// DefIndices - The index of the most recent complete def >> (proceding bottom >> - /// up), or ~0u if the register is live. >> - unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; >> - >> - /// KeepRegs - A set of registers which are live and cannot be >> changed to >> - /// break anti-dependencies. >> - SmallSet KeepRegs; >> - >> public: >> SchedulePostRATDList(MachineFunction &MF, >> const MachineLoopInfo &MLI, >> const MachineDominatorTree &MDT, >> ScheduleHazardRecognizer *HR, >> - AliasAnalysis *aa, >> - TargetSubtarget::AntiDepBreakMode adm) >> + AntiDepBreaker *ADB, >> + AliasAnalysis *aa) >> : ScheduleDAGInstrs(MF, MLI, MDT), Topo(SUnits), >> - AllocatableSet(TRI->getAllocatableSet(MF)), >> - HazardRec(HR), AA(aa), AntiDepMode(adm) {} >> + HazardRec(HR), AntiDepBreak(ADB), AA(aa) {} >> >> ~SchedulePostRATDList() { >> - delete HazardRec; >> } >> >> /// StartBlock - Initialize register live-range state for >> scheduling in >> @@ -177,11 +155,6 @@ >> /// >> void Schedule(); >> >> - /// FixupKills - Fix register kill flags that have been made >> - /// invalid due to scheduling >> - /// >> - void FixupKills(MachineBasicBlock *MBB); >> - >> /// Observe - Update liveness information to account for the >> current >> /// instruction, which will not be scheduled. >> /// >> @@ -191,17 +164,16 @@ >> /// >> void FinishBlock(); >> >> + /// FixupKills - Fix register kill flags that have been made >> + /// invalid due to scheduling >> + /// >> + void FixupKills(MachineBasicBlock *MBB); >> + >> private: >> - void PrescanInstruction(MachineInstr *MI); >> - void ScanInstruction(MachineInstr *MI, unsigned Count); >> void ReleaseSucc(SUnit *SU, SDep *SuccEdge); >> void ReleaseSuccessors(SUnit *SU); >> void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); >> void ListScheduleTopDown(); >> - bool BreakAntiDependencies(); >> - unsigned findSuitableFreeRegister(unsigned AntiDepReg, >> - unsigned LastNewReg, >> - const TargetRegisterClass *); >> void StartBlockForKills(MachineBasicBlock *BB); >> >> // ToggleKillFlag - Toggle a register operand kill flag. Other >> @@ -250,8 +222,9 @@ >> >> // Check for antidep breaking override... >> if (EnableAntiDepBreaking.getPosition() > 0) { >> - AntiDepMode = (EnableAntiDepBreaking) ? >> - TargetSubtarget::ANTIDEP_CRITICAL : >> TargetSubtarget::ANTIDEP_NONE; >> + AntiDepMode = (EnableAntiDepBreaking == "all") ? >> TargetSubtarget::ANTIDEP_ALL : >> + (EnableAntiDepBreaking == "critical") ? >> TargetSubtarget::ANTIDEP_CRITICAL : >> + TargetSubtarget::ANTIDEP_NONE; >> } >> >> DEBUG(errs() << "PostRAScheduler\n"); >> @@ -262,8 +235,12 @@ >> ScheduleHazardRecognizer *HR = EnablePostRAHazardAvoidance ? >> (ScheduleHazardRecognizer *)new ExactHazardRecognizer >> (InstrItins) : >> (ScheduleHazardRecognizer *)new SimpleHazardRecognizer(); >> + AntiDepBreaker *ADB = >> + (AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? NULL /* FIXME >> */ : >> + (AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? >> + new CriticalAntiDepBreaker(Fn) : NULL; >> >> - SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, AA, AntiDepMode); >> + SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, ADB, AA); >> >> // Loop over all of the basic blocks >> for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); >> @@ -311,6 +288,9 @@ >> Scheduler.FixupKills(MBB); >> } >> >> + delete HR; >> + delete ADB; >> + >> return true; >> } >> >> @@ -321,78 +301,10 @@ >> // Call the superclass. >> ScheduleDAGInstrs::StartBlock(BB); >> >> - // Reset the hazard recognizer. >> + // Reset the hazard recognizer and anti-dep breaker. >> HazardRec->Reset(); >> - >> - // Clear out the register class data. >> - std::fill(Classes, array_endof(Classes), >> - static_cast(0)); >> - >> - // Initialize the indices to indicate that no registers are live. >> - std::fill(KillIndices, array_endof(KillIndices), ~0u); >> - std::fill(DefIndices, array_endof(DefIndices), BB->size()); >> - >> - // Clear "do not change" set. >> - KeepRegs.clear(); >> - >> - bool IsReturnBlock = (!BB->empty() && BB->back().getDesc >> ().isReturn()); >> - >> - // Determine the live-out physregs for this block. >> - if (IsReturnBlock) { >> - // In a return block, examine the function live-out regs. >> - for (MachineRegisterInfo::liveout_iterator I = >> MRI.liveout_begin(), >> - E = MRI.liveout_end(); I != E; ++I) { >> - unsigned Reg = *I; >> - Classes[Reg] = reinterpret_cast(-1); >> - KillIndices[Reg] = BB->size(); >> - DefIndices[Reg] = ~0u; >> - // Repeat, for all aliases. >> - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; + >> +Alias) { >> - unsigned AliasReg = *Alias; >> - Classes[AliasReg] = reinterpret_cast >> (-1); >> - KillIndices[AliasReg] = BB->size(); >> - DefIndices[AliasReg] = ~0u; >> - } >> - } >> - } else { >> - // In a non-return block, examine the live-in regs of all >> successors. >> - for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), >> - SE = BB->succ_end(); SI != SE; ++SI) >> - for (MachineBasicBlock::livein_iterator I = (*SI)- >> >livein_begin(), >> - E = (*SI)->livein_end(); I != E; ++I) { >> - unsigned Reg = *I; >> - Classes[Reg] = reinterpret_cast(-1); >> - KillIndices[Reg] = BB->size(); >> - DefIndices[Reg] = ~0u; >> - // Repeat, for all aliases. >> - for (const unsigned *Alias = TRI->getAliasSet(Reg); >> *Alias; ++Alias) { >> - unsigned AliasReg = *Alias; >> - Classes[AliasReg] = reinterpret_cast> *>(-1); >> - KillIndices[AliasReg] = BB->size(); >> - DefIndices[AliasReg] = ~0u; >> - } >> - } >> - } >> - >> - // Mark live-out callee-saved registers. In a return block this is >> - // all callee-saved registers. In non-return this is any >> - // callee-saved register that is not saved in the prolog. >> - const MachineFrameInfo *MFI = MF.getFrameInfo(); >> - BitVector Pristine = MFI->getPristineRegs(BB); >> - for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { >> - unsigned Reg = *I; >> - if (!IsReturnBlock && !Pristine.test(Reg)) continue; >> - Classes[Reg] = reinterpret_cast(-1); >> - KillIndices[Reg] = BB->size(); >> - DefIndices[Reg] = ~0u; >> - // Repeat, for all aliases. >> - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; + >> +Alias) { >> - unsigned AliasReg = *Alias; >> - Classes[AliasReg] = reinterpret_cast >> (-1); >> - KillIndices[AliasReg] = BB->size(); >> - DefIndices[AliasReg] = ~0u; >> - } >> - } >> + if (AntiDepBreak != NULL) >> + AntiDepBreak->StartBlock(BB); >> } >> >> /// Schedule - Schedule the instruction range using list scheduling. >> @@ -403,8 +315,11 @@ >> // Build the scheduling graph. >> BuildSchedGraph(AA); >> >> - if (AntiDepMode != TargetSubtarget::ANTIDEP_NONE) { >> - if (BreakAntiDependencies()) { >> + if (AntiDepBreak != NULL) { >> + unsigned Broken = >> + AntiDepBreak->BreakAntiDependencies(SUnits, Begin, InsertPos, >> + InsertPosIndex); >> + if (Broken > 0) { >> // We made changes. Update the dependency graph. >> // Theoretically we could update the graph in place: >> // When a live range is changed to use a different register, >> remove >> @@ -415,6 +330,8 @@ >> EntrySU = SUnit(); >> ExitSU = SUnit(); >> BuildSchedGraph(AA); >> + >> + NumFixedAnti += Broken; >> } >> } >> >> @@ -432,436 +349,20 @@ >> /// instruction, which will not be scheduled. >> /// >> void SchedulePostRATDList::Observe(MachineInstr *MI, unsigned >> Count) { >> - assert(Count < InsertPosIndex && "Instruction index out of >> expected range!"); >> - >> - // Any register which was defined within the previous scheduling >> region >> - // may have been rescheduled and its lifetime may overlap with >> registers >> - // in ways not reflected in our current liveness state. For each >> such >> - // register, adjust the liveness state to be conservatively >> correct. >> - for (unsigned Reg = 0; Reg != >> TargetRegisterInfo::FirstVirtualRegister; ++Reg) >> - if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= >> Count) { >> - assert(KillIndices[Reg] == ~0u && "Clobbered register is >> live!"); >> - // Mark this register to be non-renamable. >> - Classes[Reg] = reinterpret_cast(-1); >> - // Move the def index to the end of the previous region, to >> reflect >> - // that the def could theoretically have been scheduled at >> the end. >> - DefIndices[Reg] = InsertPosIndex; >> - } >> - >> - PrescanInstruction(MI); >> - ScanInstruction(MI, Count); >> + if (AntiDepBreak != NULL) >> + AntiDepBreak->Observe(MI, Count, InsertPosIndex); >> } >> >> /// FinishBlock - Clean up register live-range state. >> /// >> void SchedulePostRATDList::FinishBlock() { >> - RegRefs.clear(); >> + if (AntiDepBreak != NULL) >> + AntiDepBreak->FinishBlock(); >> >> // Call the superclass. >> ScheduleDAGInstrs::FinishBlock(); >> } >> >> -/// CriticalPathStep - Return the next SUnit after SU on the >> bottom-up >> -/// critical path. >> -static SDep *CriticalPathStep(SUnit *SU) { >> - SDep *Next = 0; >> - unsigned NextDepth = 0; >> - // Find the predecessor edge with the greatest depth. >> - for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU- >> >Preds.end(); >> - P != PE; ++P) { >> - SUnit *PredSU = P->getSUnit(); >> - unsigned PredLatency = P->getLatency(); >> - unsigned PredTotalLatency = PredSU->getDepth() + PredLatency; >> - // In the case of a latency tie, prefer an anti-dependency >> edge over >> - // other types of edges. >> - if (NextDepth < PredTotalLatency || >> - (NextDepth == PredTotalLatency && P->getKind() == >> SDep::Anti)) { >> - NextDepth = PredTotalLatency; >> - Next = &*P; >> - } >> - } >> - return Next; >> -} >> - >> -void SchedulePostRATDList::PrescanInstruction(MachineInstr *MI) { >> - // Scan the register operands for this instruction and update >> - // Classes and RegRefs. >> - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >> - MachineOperand &MO = MI->getOperand(i); >> - if (!MO.isReg()) continue; >> - unsigned Reg = MO.getReg(); >> - if (Reg == 0) continue; >> - const TargetRegisterClass *NewRC = 0; >> - >> - if (i < MI->getDesc().getNumOperands()) >> - NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); >> - >> - // For now, only allow the register to be changed if its >> register >> - // class is consistent across all uses. >> - if (!Classes[Reg] && NewRC) >> - Classes[Reg] = NewRC; >> - else if (!NewRC || Classes[Reg] != NewRC) >> - Classes[Reg] = reinterpret_cast(-1); >> - >> - // Now check for aliases. >> - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; + >> +Alias) { >> - // If an alias of the reg is used during the live range, >> give up. >> - // Note that this allows us to skip checking if AntiDepReg >> - // overlaps with any of the aliases, among other things. >> - unsigned AliasReg = *Alias; >> - if (Classes[AliasReg]) { >> - Classes[AliasReg] = reinterpret_cast >> (-1); >> - Classes[Reg] = reinterpret_cast(-1); >> - } >> - } >> - >> - // If we're still willing to consider this register, note the >> reference. >> - if (Classes[Reg] != reinterpret_cast(-1)) >> - RegRefs.insert(std::make_pair(Reg, &MO)); >> - >> - // It's not safe to change register allocation for source >> operands of >> - // that have special allocation requirements. >> - if (MO.isUse() && MI->getDesc().hasExtraSrcRegAllocReq()) { >> - if (KeepRegs.insert(Reg)) { >> - for (const unsigned *Subreg = TRI->getSubRegisters(Reg); >> - *Subreg; ++Subreg) >> - KeepRegs.insert(*Subreg); >> - } >> - } >> - } >> -} >> - >> -void SchedulePostRATDList::ScanInstruction(MachineInstr *MI, >> - unsigned Count) { >> - // Update liveness. >> - // Proceding upwards, registers that are defed but not used in >> this >> - // instruction are now dead. >> - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >> - MachineOperand &MO = MI->getOperand(i); >> - if (!MO.isReg()) continue; >> - unsigned Reg = MO.getReg(); >> - if (Reg == 0) continue; >> - if (!MO.isDef()) continue; >> - // Ignore two-addr defs. >> - if (MI->isRegTiedToUseOperand(i)) continue; >> - >> - DefIndices[Reg] = Count; >> - KillIndices[Reg] = ~0u; >> - assert(((KillIndices[Reg] == ~0u) != >> - (DefIndices[Reg] == ~0u)) && >> - "Kill and Def maps aren't consistent for Reg!"); >> - KeepRegs.erase(Reg); >> - Classes[Reg] = 0; >> - RegRefs.erase(Reg); >> - // Repeat, for all subregs. >> - for (const unsigned *Subreg = TRI->getSubRegisters(Reg); >> - *Subreg; ++Subreg) { >> - unsigned SubregReg = *Subreg; >> - DefIndices[SubregReg] = Count; >> - KillIndices[SubregReg] = ~0u; >> - KeepRegs.erase(SubregReg); >> - Classes[SubregReg] = 0; >> - RegRefs.erase(SubregReg); >> - } >> - // Conservatively mark super-registers as unusable. >> - for (const unsigned *Super = TRI->getSuperRegisters(Reg); >> - *Super; ++Super) { >> - unsigned SuperReg = *Super; >> - Classes[SuperReg] = reinterpret_cast >> (-1); >> - } >> - } >> - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >> - MachineOperand &MO = MI->getOperand(i); >> - if (!MO.isReg()) continue; >> - unsigned Reg = MO.getReg(); >> - if (Reg == 0) continue; >> - if (!MO.isUse()) continue; >> - >> - const TargetRegisterClass *NewRC = 0; >> - if (i < MI->getDesc().getNumOperands()) >> - NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); >> - >> - // For now, only allow the register to be changed if its >> register >> - // class is consistent across all uses. >> - if (!Classes[Reg] && NewRC) >> - Classes[Reg] = NewRC; >> - else if (!NewRC || Classes[Reg] != NewRC) >> - Classes[Reg] = reinterpret_cast(-1); >> - >> - RegRefs.insert(std::make_pair(Reg, &MO)); >> - >> - // It wasn't previously live but now it is, this is a kill. >> - if (KillIndices[Reg] == ~0u) { >> - KillIndices[Reg] = Count; >> - DefIndices[Reg] = ~0u; >> - assert(((KillIndices[Reg] == ~0u) != >> - (DefIndices[Reg] == ~0u)) && >> - "Kill and Def maps aren't consistent for Reg!"); >> - } >> - // Repeat, for all aliases. >> - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; + >> +Alias) { >> - unsigned AliasReg = *Alias; >> - if (KillIndices[AliasReg] == ~0u) { >> - KillIndices[AliasReg] = Count; >> - DefIndices[AliasReg] = ~0u; >> - } >> - } >> - } >> -} >> - >> -unsigned >> -SchedulePostRATDList::findSuitableFreeRegister(unsigned AntiDepReg, >> - unsigned LastNewReg, >> - const >> TargetRegisterClass *RC) { >> - for (TargetRegisterClass::iterator R = RC->allocation_order_begin >> (MF), >> - RE = RC->allocation_order_end(MF); R != RE; ++R) { >> - unsigned NewReg = *R; >> - // Don't replace a register with itself. >> - if (NewReg == AntiDepReg) continue; >> - // Don't replace a register with one that was recently used to >> repair >> - // an anti-dependence with this AntiDepReg, because that would >> - // re-introduce that anti-dependence. >> - if (NewReg == LastNewReg) continue; >> - // If NewReg is dead and NewReg's most recent def is not before >> - // AntiDepReg's kill, it's safe to replace AntiDepReg with >> NewReg. >> - assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices >> [AntiDepReg] == ~0u)) && >> - "Kill and Def maps aren't consistent for AntiDepReg!"); >> - assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == >> ~0u)) && >> - "Kill and Def maps aren't consistent for NewReg!"); >> - if (KillIndices[NewReg] != ~0u || >> - Classes[NewReg] == reinterpret_cast >> (-1) || >> - KillIndices[AntiDepReg] > DefIndices[NewReg]) >> - continue; >> - return NewReg; >> - } >> - >> - // No registers are free and available! >> - return 0; >> -} >> - >> -/// BreakAntiDependencies - Identifiy anti-dependencies along the >> critical path >> -/// of the ScheduleDAG and break them by renaming registers. >> -/// >> -bool SchedulePostRATDList::BreakAntiDependencies() { >> - // The code below assumes that there is at least one instruction, >> - // so just duck out immediately if the block is empty. >> - if (SUnits.empty()) return false; >> - >> - // Find the node at the bottom of the critical path. >> - SUnit *Max = 0; >> - for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { >> - SUnit *SU = &SUnits[i]; >> - if (!Max || SU->getDepth() + SU->Latency > Max->getDepth() + >> Max->Latency) >> - Max = SU; >> - } >> - >> -#ifndef NDEBUG >> - { >> - DEBUG(errs() << "Critical path has total latency " >> - << (Max->getDepth() + Max->Latency) << "\n"); >> - DEBUG(errs() << "Available regs:"); >> - for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { >> - if (KillIndices[Reg] == ~0u) >> - DEBUG(errs() << " " << TRI->getName(Reg)); >> - } >> - DEBUG(errs() << '\n'); >> - } >> -#endif >> - >> - // Track progress along the critical path through the SUnit >> graph as we walk >> - // the instructions. >> - SUnit *CriticalPathSU = Max; >> - MachineInstr *CriticalPathMI = CriticalPathSU->getInstr(); >> - >> - // Consider this pattern: >> - // A = ... >> - // ... = A >> - // A = ... >> - // ... = A >> - // A = ... >> - // ... = A >> - // A = ... >> - // ... = A >> - // There are three anti-dependencies here, and without special >> care, >> - // we'd break all of them using the same register: >> - // A = ... >> - // ... = A >> - // B = ... >> - // ... = B >> - // B = ... >> - // ... = B >> - // B = ... >> - // ... = B >> - // because at each anti-dependence, B is the first register that >> - // isn't A which is free. This re-introduces anti-dependencies >> - // at all but one of the original anti-dependencies that we were >> - // trying to break. To avoid this, keep track of the most recent >> - // register that each register was replaced with, avoid >> - // using it to repair an anti-dependence on the same register. >> - // This lets us produce this: >> - // A = ... >> - // ... = A >> - // B = ... >> - // ... = B >> - // C = ... >> - // ... = C >> - // B = ... >> - // ... = B >> - // This still has an anti-dependence on B, but at least it isn't >> on the >> - // original critical path. >> - // >> - // TODO: If we tracked more than one register here, we could >> potentially >> - // fix that remaining critical edge too. This is a little more >> involved, >> - // because unlike the most recent register, less recent >> registers should >> - // still be considered, though only if no other registers are >> available. >> - unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = >> {}; >> - >> - // Attempt to break anti-dependence edges on the critical path. >> Walk the >> - // instructions from the bottom up, tracking information about >> liveness >> - // as we go to help determine which registers are available. >> - bool Changed = false; >> - unsigned Count = InsertPosIndex - 1; >> - for (MachineBasicBlock::iterator I = InsertPos, E = Begin; >> - I != E; --Count) { >> - MachineInstr *MI = --I; >> - >> - // Check if this instruction has a dependence on the critical >> path that >> - // is an anti-dependence that we may be able to break. If it >> is, set >> - // AntiDepReg to the non-zero register associated with the >> anti-dependence. >> - // >> - // We limit our attention to the critical path as a heuristic >> to avoid >> - // breaking anti-dependence edges that aren't going to >> significantly >> - // impact the overall schedule. There are a limited number of >> registers >> - // and we want to save them for the important edges. >> - // >> - // TODO: Instructions with multiple defs could have multiple >> - // anti-dependencies. The current code here only knows how to >> break one >> - // edge per instruction. Note that we'd have to be able to >> break all of >> - // the anti-dependencies in an instruction in order to be >> effective. >> - unsigned AntiDepReg = 0; >> - if (MI == CriticalPathMI) { >> - if (SDep *Edge = CriticalPathStep(CriticalPathSU)) { >> - SUnit *NextSU = Edge->getSUnit(); >> - >> - // Only consider anti-dependence edges. >> - if (Edge->getKind() == SDep::Anti) { >> - AntiDepReg = Edge->getReg(); >> - assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); >> - if (!AllocatableSet.test(AntiDepReg)) >> - // Don't break anti-dependencies on non-allocatable >> registers. >> - AntiDepReg = 0; >> - else if (KeepRegs.count(AntiDepReg)) >> - // Don't break anti-dependencies if an use down below >> requires >> - // this exact register. >> - AntiDepReg = 0; >> - else { >> - // If the SUnit has other dependencies on the SUnit >> that it >> - // anti-depends on, don't bother breaking the anti- >> dependency >> - // since those edges would prevent such units from being >> - // scheduled past each other regardless. >> - // >> - // Also, if there are dependencies on other SUnits >> with the >> - // same register as the anti-dependency, don't attempt >> to >> - // break it. >> - for (SUnit::pred_iterator P = CriticalPathSU- >> >Preds.begin(), >> - PE = CriticalPathSU->Preds.end(); P != PE; ++P) >> - if (P->getSUnit() == NextSU ? >> - (P->getKind() != SDep::Anti || P->getReg() != >> AntiDepReg) : >> - (P->getKind() == SDep::Data && P->getReg() == >> AntiDepReg)) { >> - AntiDepReg = 0; >> - break; >> - } >> - } >> - } >> - CriticalPathSU = NextSU; >> - CriticalPathMI = CriticalPathSU->getInstr(); >> - } else { >> - // We've reached the end of the critical path. >> - CriticalPathSU = 0; >> - CriticalPathMI = 0; >> - } >> - } >> - >> - PrescanInstruction(MI); >> - >> - if (MI->getDesc().hasExtraDefRegAllocReq()) >> - // If this instruction's defs have special allocation >> requirement, don't >> - // break this anti-dependency. >> - AntiDepReg = 0; >> - else if (AntiDepReg) { >> - // If this instruction has a use of AntiDepReg, breaking it >> - // is invalid. >> - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >> - MachineOperand &MO = MI->getOperand(i); >> - if (!MO.isReg()) continue; >> - unsigned Reg = MO.getReg(); >> - if (Reg == 0) continue; >> - if (MO.isUse() && AntiDepReg == Reg) { >> - AntiDepReg = 0; >> - break; >> - } >> - } >> - } >> - >> - // Determine AntiDepReg's register class, if it is live and is >> - // consistently used within a single class. >> - const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes >> [AntiDepReg] : 0; >> - assert((AntiDepReg == 0 || RC != NULL) && >> - "Register should be live if it's causing an anti- >> dependence!"); >> - if (RC == reinterpret_cast(-1)) >> - AntiDepReg = 0; >> - >> - // Look for a suitable register to use to break the anti- >> depenence. >> - // >> - // TODO: Instead of picking the first free register, consider >> which might >> - // be the best. >> - if (AntiDepReg != 0) { >> - if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg, >> - LastNewReg >> [AntiDepReg], >> - RC)) { >> - DEBUG(errs() << "Breaking anti-dependence edge on " >> - << TRI->getName(AntiDepReg) >> - << " with " << RegRefs.count(AntiDepReg) << " >> references" >> - << " using " << TRI->getName(NewReg) << "!\n"); >> - >> - // Update the references to the old register to refer to >> the new >> - // register. >> - std::pair> *>::iterator, >> - std::multimap> *>::iterator> >> - Range = RegRefs.equal_range(AntiDepReg); >> - for (std::multimap::iterator >> - Q = Range.first, QE = Range.second; Q != QE; ++Q) >> - Q->second->setReg(NewReg); >> - >> - // We just went back in time and modified history; the >> - // liveness information for the anti-depenence reg is now >> - // inconsistent. Set the state as if it were dead. >> - Classes[NewReg] = Classes[AntiDepReg]; >> - DefIndices[NewReg] = DefIndices[AntiDepReg]; >> - KillIndices[NewReg] = KillIndices[AntiDepReg]; >> - assert(((KillIndices[NewReg] == ~0u) != >> - (DefIndices[NewReg] == ~0u)) && >> - "Kill and Def maps aren't consistent for NewReg!"); >> - >> - Classes[AntiDepReg] = 0; >> - DefIndices[AntiDepReg] = KillIndices[AntiDepReg]; >> - KillIndices[AntiDepReg] = ~0u; >> - assert(((KillIndices[AntiDepReg] == ~0u) != >> - (DefIndices[AntiDepReg] == ~0u)) && >> - "Kill and Def maps aren't consistent for AntiDepReg!"); >> - >> - RegRefs.erase(AntiDepReg); >> - Changed = true; >> - LastNewReg[AntiDepReg] = NewReg; >> - } >> - } >> - >> - ScanInstruction(MI, Count); >> - } >> - >> - return Changed; >> -} >> - >> /// StartBlockForKills - Initialize register live-range state for >> updating kills >> /// >> void SchedulePostRATDList::StartBlockForKills(MachineBasicBlock >> *BB) { >> >> Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=85127&r1=85126&r2=85127&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original) >> +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Mon Oct 26 11:59:04 2009 >> @@ -130,7 +130,7 @@ >> /// for Thumb1. >> bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, >> TargetSubtarget::AntiDepBreakMode& >> mode) const { >> - mode = TargetSubtarget::ANTIDEP_NONE; >> + mode = TargetSubtarget::ANTIDEP_CRITICAL; >> return PostRAScheduler && OptLevel >= CodeGenOpt::Default; >> } >> >> >> Modified: llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll?rev=85127&r1=85126&r2=85127&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll (original) >> +++ llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll Mon Oct >> 26 11:59:04 2009 >> @@ -1,7 +1,7 @@ >> -; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti- >> dependencies=false > %t >> +; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti- >> dependencies=none > %t >> ; RUN: grep {%xmm0} %t | count 14 >> ; RUN: not grep {%xmm1} %t >> -; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti- >> dependencies > %t >> +; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti- >> dependencies=critical > %t >> ; RUN: grep {%xmm0} %t | count 7 >> ; RUN: grep {%xmm1} %t | count 7 >> >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From evan.cheng at apple.com Mon Oct 26 16:29:25 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 26 Oct 2009 14:29:25 -0700 Subject: [llvm-commits] [llvm] r85127 - in /llvm/trunk: include/llvm/CodeGen/AntiDepBreaker.h lib/CodeGen/CMakeLists.txt lib/CodeGen/CriticalAntiDepBreaker.cpp lib/CodeGen/CriticalAntiDepBreaker.h lib/CodeGen/PostRASchedulerList.cpp lib/Target/ARM/ARMSubtarget.h test/CodeGen/X86/break-anti-dependencies.ll In-Reply-To: <35E02EF7-4CBB-4607-BC71-849E46D366D2@apple.com> References: <200910261659.n9QGx4Yj023936@zion.cs.uiuc.edu> <35E02EF7-4CBB-4607-BC71-849E46D366D2@apple.com> Message-ID: <62D81C23-FB80-4694-B347-5A7F94998189@apple.com> Targets must provide their own variants of the ScheduleHazardRecognizer. That's why it's exposed. Unless you feel there are reasons for targets to override the default AntiDepBreaker, it should be moved to lib/CodeGen. Thanks, Evan On Oct 26, 2009, at 2:27 PM, David Goodwin wrote: > I was just following the style of ScheduleHazardRecognizer, as it has the same "visibility" as AntiDepBreaker. But I can move it if that would be better... > > David > > On Oct 26, 2009, at 2:23 PM, Evan Cheng wrote: > >> It seems to be AntiDepBreaker.h should be inside lib/CodeGen. Is there a reason to expose it? >> >> Evan >> >> On Oct 26, 2009, at 9:59 AM, David Goodwin wrote: >> >>> Author: david_goodwin >>> Date: Mon Oct 26 11:59:04 2009 >>> New Revision: 85127 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=85127&view=rev >>> Log: >>> Break anti-dependence breaking out into its own class. >>> >>> Added: >>> llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h >>> llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp >>> llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h >>> Modified: >>> llvm/trunk/lib/CodeGen/CMakeLists.txt >>> llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp >>> llvm/trunk/lib/Target/ARM/ARMSubtarget.h >>> llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll >>> >>> Added: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h?rev=85127&view=auto >>> >>> ============================================================================== >>> --- llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h (added) >>> +++ llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Mon Oct 26 11:59:04 2009 >>> @@ -0,0 +1,56 @@ >>> +//=- llvm/CodeGen/AntiDepBreaker.h - Anti-Dependence Breaking -*- C++ -*-=// >>> +// >>> +// The LLVM Compiler Infrastructure >>> +// >>> +// This file is distributed under the University of Illinois Open Source >>> +// License. See LICENSE.TXT for details. >>> +// >>> +//===----------------------------------------------------------------------===// >>> +// >>> +// This file implements the AntiDepBreaker class, which implements >>> +// anti-dependence breaking heuristics for post-register-allocation scheduling. >>> +// >>> +//===----------------------------------------------------------------------===// >>> + >>> +#ifndef LLVM_CODEGEN_ANTIDEPBREAKER_H >>> +#define LLVM_CODEGEN_ANTIDEPBREAKER_H >>> + >>> +#include "llvm/CodeGen/MachineBasicBlock.h" >>> +#include "llvm/CodeGen/MachineFrameInfo.h" >>> +#include "llvm/CodeGen/MachineFunction.h" >>> +#include "llvm/CodeGen/MachineRegisterInfo.h" >>> +#include "llvm/CodeGen/ScheduleDAG.h" >>> +#include "llvm/Target/TargetRegisterInfo.h" >>> + >>> +namespace llvm { >>> + >>> +/// AntiDepBreaker - This class works into conjunction with the >>> +/// post-RA scheduler to rename registers to break register >>> +/// anti-dependencies. >>> +class AntiDepBreaker { >>> +public: >>> + /// Start - Initialize anti-dep breaking for a new basic block. >>> + virtual void StartBlock(MachineBasicBlock *BB) =0; >>> + >>> + /// BreakAntiDependencies - Identifiy anti-dependencies within a >>> + /// basic-block region and break them by renaming registers. Return >>> + /// the number of anti-dependencies broken. >>> + /// >>> + virtual unsigned BreakAntiDependencies(std::vector& SUnits, >>> + MachineBasicBlock::iterator& Begin, >>> + MachineBasicBlock::iterator& End, >>> + unsigned InsertPosIndex) =0; >>> + >>> + /// Observe - Update liveness information to account for the current >>> + /// instruction, which will not be scheduled. >>> + /// >>> + virtual void Observe(MachineInstr *MI, unsigned Count, >>> + unsigned InsertPosIndex) =0; >>> + >>> + /// Finish - Finish anti-dep breaking for a basic block. >>> + virtual void FinishBlock() =0; >>> +}; >>> + >>> +} >>> + >>> +#endif >>> >>> Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=85127&r1=85126&r2=85127&view=diff >>> >>> ============================================================================== >>> --- llvm/trunk/lib/CodeGen/CMakeLists.txt (original) >>> +++ llvm/trunk/lib/CodeGen/CMakeLists.txt Mon Oct 26 11:59:04 2009 >>> @@ -1,6 +1,7 @@ >>> add_llvm_library(LLVMCodeGen >>> BranchFolding.cpp >>> CodePlacementOpt.cpp >>> + CriticalAntiDepBreaker.cpp >>> DeadMachineInstructionElim.cpp >>> DwarfEHPrepare.cpp >>> ELFCodeEmitter.cpp >>> >>> Added: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp?rev=85127&view=auto >>> >>> ============================================================================== >>> --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp (added) >>> +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp Mon Oct 26 11:59:04 2009 >>> @@ -0,0 +1,539 @@ >>> +//===----- CriticalAntiDepBreaker.cpp - Anti-dep breaker -------- ---------===// >>> +// >>> +// The LLVM Compiler Infrastructure >>> +// >>> +// This file is distributed under the University of Illinois Open Source >>> +// License. See LICENSE.TXT for details. >>> +// >>> +//===----------------------------------------------------------------------===// >>> +// >>> +// This file implements the CriticalAntiDepBreaker class, which >>> +// implements register anti-dependence breaking along a blocks >>> +// critical path during post-RA scheduler. >>> +// >>> +//===----------------------------------------------------------------------===// >>> + >>> +#define DEBUG_TYPE "critical-antidep" >>> +#include "CriticalAntiDepBreaker.h" >>> +#include "llvm/CodeGen/MachineBasicBlock.h" >>> +#include "llvm/CodeGen/MachineFrameInfo.h" >>> +#include "llvm/Target/TargetMachine.h" >>> +#include "llvm/Target/TargetRegisterInfo.h" >>> +#include "llvm/Support/Debug.h" >>> +#include "llvm/Support/ErrorHandling.h" >>> +#include "llvm/Support/raw_ostream.h" >>> + >>> +using namespace llvm; >>> + >>> +CriticalAntiDepBreaker:: >>> +CriticalAntiDepBreaker(MachineFunction& MFi) : >>> + AntiDepBreaker(), MF(MFi), >>> + MRI(MF.getRegInfo()), >>> + TRI(MF.getTarget().getRegisterInfo()), >>> + AllocatableSet(TRI->getAllocatableSet(MF)) >>> +{ >>> +} >>> + >>> +CriticalAntiDepBreaker::~CriticalAntiDepBreaker() { >>> +} >>> + >>> +void CriticalAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { >>> + // Clear out the register class data. >>> + std::fill(Classes, array_endof(Classes), >>> + static_cast(0)); >>> + >>> + // Initialize the indices to indicate that no registers are live. >>> + std::fill(KillIndices, array_endof(KillIndices), ~0u); >>> + std::fill(DefIndices, array_endof(DefIndices), BB->size()); >>> + >>> + // Clear "do not change" set. >>> + KeepRegs.clear(); >>> + >>> + bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn()); >>> + >>> + // Determine the live-out physregs for this block. >>> + if (IsReturnBlock) { >>> + // In a return block, examine the function live-out regs. >>> + for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), >>> + E = MRI.liveout_end(); I != E; ++I) { >>> + unsigned Reg = *I; >>> + Classes[Reg] = reinterpret_cast(-1); >>> + KillIndices[Reg] = BB->size(); >>> + DefIndices[Reg] = ~0u; >>> + // Repeat, for all aliases. >>> + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { >>> + unsigned AliasReg = *Alias; >>> + Classes[AliasReg] = reinterpret_cast(-1); >>> + KillIndices[AliasReg] = BB->size(); >>> + DefIndices[AliasReg] = ~0u; >>> + } >>> + } >>> + } else { >>> + // In a non-return block, examine the live-in regs of all successors. >>> + for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), >>> + SE = BB->succ_end(); SI != SE; ++SI) >>> + for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), >>> + E = (*SI)->livein_end(); I != E; ++I) { >>> + unsigned Reg = *I; >>> + Classes[Reg] = reinterpret_cast(-1); >>> + KillIndices[Reg] = BB->size(); >>> + DefIndices[Reg] = ~0u; >>> + // Repeat, for all aliases. >>> + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { >>> + unsigned AliasReg = *Alias; >>> + Classes[AliasReg] = reinterpret_cast(-1); >>> + KillIndices[AliasReg] = BB->size(); >>> + DefIndices[AliasReg] = ~0u; >>> + } >>> + } >>> + } >>> + >>> + // Mark live-out callee-saved registers. In a return block this is >>> + // all callee-saved registers. In non-return this is any >>> + // callee-saved register that is not saved in the prolog. >>> + const MachineFrameInfo *MFI = MF.getFrameInfo(); >>> + BitVector Pristine = MFI->getPristineRegs(BB); >>> + for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { >>> + unsigned Reg = *I; >>> + if (!IsReturnBlock && !Pristine.test(Reg)) continue; >>> + Classes[Reg] = reinterpret_cast(-1); >>> + KillIndices[Reg] = BB->size(); >>> + DefIndices[Reg] = ~0u; >>> + // Repeat, for all aliases. >>> + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { >>> + unsigned AliasReg = *Alias; >>> + Classes[AliasReg] = reinterpret_cast(-1); >>> + KillIndices[AliasReg] = BB->size(); >>> + DefIndices[AliasReg] = ~0u; >>> + } >>> + } >>> +} >>> + >>> +void CriticalAntiDepBreaker::FinishBlock() { >>> + RegRefs.clear(); >>> + KeepRegs.clear(); >>> +} >>> + >>> +void CriticalAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count, >>> + unsigned InsertPosIndex) { >>> + assert(Count < InsertPosIndex && "Instruction index out of expected range!"); >>> + >>> + // Any register which was defined within the previous scheduling region >>> + // may have been rescheduled and its lifetime may overlap with registers >>> + // in ways not reflected in our current liveness state. For each such >>> + // register, adjust the liveness state to be conservatively correct. >>> + for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) >>> + if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) { >>> + assert(KillIndices[Reg] == ~0u && "Clobbered register is live!"); >>> + // Mark this register to be non-renamable. >>> + Classes[Reg] = reinterpret_cast(-1); >>> + // Move the def index to the end of the previous region, to reflect >>> + // that the def could theoretically have been scheduled at the end. >>> + DefIndices[Reg] = InsertPosIndex; >>> + } >>> + >>> + PrescanInstruction(MI); >>> + ScanInstruction(MI, Count); >>> +} >>> + >>> +/// CriticalPathStep - Return the next SUnit after SU on the bottom-up >>> +/// critical path. >>> +static SDep *CriticalPathStep(SUnit *SU) { >>> + SDep *Next = 0; >>> + unsigned NextDepth = 0; >>> + // Find the predecessor edge with the greatest depth. >>> + for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end(); >>> + P != PE; ++P) { >>> + SUnit *PredSU = P->getSUnit(); >>> + unsigned PredLatency = P->getLatency(); >>> + unsigned PredTotalLatency = PredSU->getDepth() + PredLatency; >>> + // In the case of a latency tie, prefer an anti-dependency edge over >>> + // other types of edges. >>> + if (NextDepth < PredTotalLatency || >>> + (NextDepth == PredTotalLatency && P->getKind() == SDep::Anti)) { >>> + NextDepth = PredTotalLatency; >>> + Next = &*P; >>> + } >>> + } >>> + return Next; >>> +} >>> + >>> +void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr *MI) { >>> + // Scan the register operands for this instruction and update >>> + // Classes and RegRefs. >>> + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >>> + MachineOperand &MO = MI->getOperand(i); >>> + if (!MO.isReg()) continue; >>> + unsigned Reg = MO.getReg(); >>> + if (Reg == 0) continue; >>> + const TargetRegisterClass *NewRC = 0; >>> + >>> + if (i < MI->getDesc().getNumOperands()) >>> + NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); >>> + >>> + // For now, only allow the register to be changed if its register >>> + // class is consistent across all uses. >>> + if (!Classes[Reg] && NewRC) >>> + Classes[Reg] = NewRC; >>> + else if (!NewRC || Classes[Reg] != NewRC) >>> + Classes[Reg] = reinterpret_cast(-1); >>> + >>> + // Now check for aliases. >>> + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { >>> + // If an alias of the reg is used during the live range, give up. >>> + // Note that this allows us to skip checking if AntiDepReg >>> + // overlaps with any of the aliases, among other things. >>> + unsigned AliasReg = *Alias; >>> + if (Classes[AliasReg]) { >>> + Classes[AliasReg] = reinterpret_cast(-1); >>> + Classes[Reg] = reinterpret_cast(-1); >>> + } >>> + } >>> + >>> + // If we're still willing to consider this register, note the reference. >>> + if (Classes[Reg] != reinterpret_cast(-1)) >>> + RegRefs.insert(std::make_pair(Reg, &MO)); >>> + >>> + // It's not safe to change register allocation for source operands of >>> + // that have special allocation requirements. >>> + if (MO.isUse() && MI->getDesc().hasExtraSrcRegAllocReq()) { >>> + if (KeepRegs.insert(Reg)) { >>> + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); >>> + *Subreg; ++Subreg) >>> + KeepRegs.insert(*Subreg); >>> + } >>> + } >>> + } >>> +} >>> + >>> +void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI, >>> + unsigned Count) { >>> + // Update liveness. >>> + // Proceding upwards, registers that are defed but not used in this >>> + // instruction are now dead. >>> + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >>> + MachineOperand &MO = MI->getOperand(i); >>> + if (!MO.isReg()) continue; >>> + unsigned Reg = MO.getReg(); >>> + if (Reg == 0) continue; >>> + if (!MO.isDef()) continue; >>> + // Ignore two-addr defs. >>> + if (MI->isRegTiedToUseOperand(i)) continue; >>> + >>> + DefIndices[Reg] = Count; >>> + KillIndices[Reg] = ~0u; >>> + assert(((KillIndices[Reg] == ~0u) != >>> + (DefIndices[Reg] == ~0u)) && >>> + "Kill and Def maps aren't consistent for Reg!"); >>> + KeepRegs.erase(Reg); >>> + Classes[Reg] = 0; >>> + RegRefs.erase(Reg); >>> + // Repeat, for all subregs. >>> + for (const unsigned *Subreg = TRI->getSubRegisters(Reg); >>> + *Subreg; ++Subreg) { >>> + unsigned SubregReg = *Subreg; >>> + DefIndices[SubregReg] = Count; >>> + KillIndices[SubregReg] = ~0u; >>> + KeepRegs.erase(SubregReg); >>> + Classes[SubregReg] = 0; >>> + RegRefs.erase(SubregReg); >>> + } >>> + // Conservatively mark super-registers as unusable. >>> + for (const unsigned *Super = TRI->getSuperRegisters(Reg); >>> + *Super; ++Super) { >>> + unsigned SuperReg = *Super; >>> + Classes[SuperReg] = reinterpret_cast(-1); >>> + } >>> + } >>> + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >>> + MachineOperand &MO = MI->getOperand(i); >>> + if (!MO.isReg()) continue; >>> + unsigned Reg = MO.getReg(); >>> + if (Reg == 0) continue; >>> + if (!MO.isUse()) continue; >>> + >>> + const TargetRegisterClass *NewRC = 0; >>> + if (i < MI->getDesc().getNumOperands()) >>> + NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); >>> + >>> + // For now, only allow the register to be changed if its register >>> + // class is consistent across all uses. >>> + if (!Classes[Reg] && NewRC) >>> + Classes[Reg] = NewRC; >>> + else if (!NewRC || Classes[Reg] != NewRC) >>> + Classes[Reg] = reinterpret_cast(-1); >>> + >>> + RegRefs.insert(std::make_pair(Reg, &MO)); >>> + >>> + // It wasn't previously live but now it is, this is a kill. >>> + if (KillIndices[Reg] == ~0u) { >>> + KillIndices[Reg] = Count; >>> + DefIndices[Reg] = ~0u; >>> + assert(((KillIndices[Reg] == ~0u) != >>> + (DefIndices[Reg] == ~0u)) && >>> + "Kill and Def maps aren't consistent for Reg!"); >>> + } >>> + // Repeat, for all aliases. >>> + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { >>> + unsigned AliasReg = *Alias; >>> + if (KillIndices[AliasReg] == ~0u) { >>> + KillIndices[AliasReg] = Count; >>> + DefIndices[AliasReg] = ~0u; >>> + } >>> + } >>> + } >>> +} >>> + >>> +unsigned >>> +CriticalAntiDepBreaker::findSuitableFreeRegister(unsigned AntiDepReg, >>> + unsigned LastNewReg, >>> + const TargetRegisterClass *RC) { >>> + for (TargetRegisterClass::iterator R = RC->allocation_order_begin(MF), >>> + RE = RC->allocation_order_end(MF); R != RE; ++R) { >>> + unsigned NewReg = *R; >>> + // Don't replace a register with itself. >>> + if (NewReg == AntiDepReg) continue; >>> + // Don't replace a register with one that was recently used to repair >>> + // an anti-dependence with this AntiDepReg, because that would >>> + // re-introduce that anti-dependence. >>> + if (NewReg == LastNewReg) continue; >>> + // If NewReg is dead and NewReg's most recent def is not before >>> + // AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg. >>> + assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u)) && >>> + "Kill and Def maps aren't consistent for AntiDepReg!"); >>> + assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u)) && >>> + "Kill and Def maps aren't consistent for NewReg!"); >>> + if (KillIndices[NewReg] != ~0u || >>> + Classes[NewReg] == reinterpret_cast(-1) || >>> + KillIndices[AntiDepReg] > DefIndices[NewReg]) >>> + continue; >>> + return NewReg; >>> + } >>> + >>> + // No registers are free and available! >>> + return 0; >>> +} >>> + >>> +unsigned CriticalAntiDepBreaker:: >>> +BreakAntiDependencies(std::vector& SUnits, >>> + MachineBasicBlock::iterator& Begin, >>> + MachineBasicBlock::iterator& End, >>> + unsigned InsertPosIndex) { >>> + // The code below assumes that there is at least one instruction, >>> + // so just duck out immediately if the block is empty. >>> + if (SUnits.empty()) return 0; >>> + >>> + // Find the node at the bottom of the critical path. >>> + SUnit *Max = 0; >>> + for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { >>> + SUnit *SU = &SUnits[i]; >>> + if (!Max || SU->getDepth() + SU->Latency > Max->getDepth() + Max->Latency) >>> + Max = SU; >>> + } >>> + >>> +#ifndef NDEBUG >>> + { >>> + DEBUG(errs() << "Critical path has total latency " >>> + << (Max->getDepth() + Max->Latency) << "\n"); >>> + DEBUG(errs() << "Available regs:"); >>> + for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { >>> + if (KillIndices[Reg] == ~0u) >>> + DEBUG(errs() << " " << TRI->getName(Reg)); >>> + } >>> + DEBUG(errs() << '\n'); >>> + } >>> +#endif >>> + >>> + // Track progress along the critical path through the SUnit graph as we walk >>> + // the instructions. >>> + SUnit *CriticalPathSU = Max; >>> + MachineInstr *CriticalPathMI = CriticalPathSU->getInstr(); >>> + >>> + // Consider this pattern: >>> + // A = ... >>> + // ... = A >>> + // A = ... >>> + // ... = A >>> + // A = ... >>> + // ... = A >>> + // A = ... >>> + // ... = A >>> + // There are three anti-dependencies here, and without special care, >>> + // we'd break all of them using the same register: >>> + // A = ... >>> + // ... = A >>> + // B = ... >>> + // ... = B >>> + // B = ... >>> + // ... = B >>> + // B = ... >>> + // ... = B >>> + // because at each anti-dependence, B is the first register that >>> + // isn't A which is free. This re-introduces anti-dependencies >>> + // at all but one of the original anti-dependencies that we were >>> + // trying to break. To avoid this, keep track of the most recent >>> + // register that each register was replaced with, avoid >>> + // using it to repair an anti-dependence on the same register. >>> + // This lets us produce this: >>> + // A = ... >>> + // ... = A >>> + // B = ... >>> + // ... = B >>> + // C = ... >>> + // ... = C >>> + // B = ... >>> + // ... = B >>> + // This still has an anti-dependence on B, but at least it isn't on the >>> + // original critical path. >>> + // >>> + // TODO: If we tracked more than one register here, we could potentially >>> + // fix that remaining critical edge too. This is a little more involved, >>> + // because unlike the most recent register, less recent registers should >>> + // still be considered, though only if no other registers are available. >>> + unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = {}; >>> + >>> + // Attempt to break anti-dependence edges on the critical path. Walk the >>> + // instructions from the bottom up, tracking information about liveness >>> + // as we go to help determine which registers are available. >>> + unsigned Broken = 0; >>> + unsigned Count = InsertPosIndex - 1; >>> + for (MachineBasicBlock::iterator I = End, E = Begin; >>> + I != E; --Count) { >>> + MachineInstr *MI = --I; >>> + >>> + // Check if this instruction has a dependence on the critical path that >>> + // is an anti-dependence that we may be able to break. If it is, set >>> + // AntiDepReg to the non-zero register associated with the anti-dependence. >>> + // >>> + // We limit our attention to the critical path as a heuristic to avoid >>> + // breaking anti-dependence edges that aren't going to significantly >>> + // impact the overall schedule. There are a limited number of registers >>> + // and we want to save them for the important edges. >>> + // >>> + // TODO: Instructions with multiple defs could have multiple >>> + // anti-dependencies. The current code here only knows how to break one >>> + // edge per instruction. Note that we'd have to be able to break all of >>> + // the anti-dependencies in an instruction in order to be effective. >>> + unsigned AntiDepReg = 0; >>> + if (MI == CriticalPathMI) { >>> + if (SDep *Edge = CriticalPathStep(CriticalPathSU)) { >>> + SUnit *NextSU = Edge->getSUnit(); >>> + >>> + // Only consider anti-dependence edges. >>> + if (Edge->getKind() == SDep::Anti) { >>> + AntiDepReg = Edge->getReg(); >>> + assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); >>> + if (!AllocatableSet.test(AntiDepReg)) >>> + // Don't break anti-dependencies on non-allocatable registers. >>> + AntiDepReg = 0; >>> + else if (KeepRegs.count(AntiDepReg)) >>> + // Don't break anti-dependencies if an use down below requires >>> + // this exact register. >>> + AntiDepReg = 0; >>> + else { >>> + // If the SUnit has other dependencies on the SUnit that it >>> + // anti-depends on, don't bother breaking the anti-dependency >>> + // since those edges would prevent such units from being >>> + // scheduled past each other regardless. >>> + // >>> + // Also, if there are dependencies on other SUnits with the >>> + // same register as the anti-dependency, don't attempt to >>> + // break it. >>> + for (SUnit::pred_iterator P = CriticalPathSU->Preds.begin(), >>> + PE = CriticalPathSU->Preds.end(); P != PE; ++P) >>> + if (P->getSUnit() == NextSU ? >>> + (P->getKind() != SDep::Anti || P->getReg() != AntiDepReg) : >>> + (P->getKind() == SDep::Data && P->getReg() == AntiDepReg)) { >>> + AntiDepReg = 0; >>> + break; >>> + } >>> + } >>> + } >>> + CriticalPathSU = NextSU; >>> + CriticalPathMI = CriticalPathSU->getInstr(); >>> + } else { >>> + // We've reached the end of the critical path. >>> + CriticalPathSU = 0; >>> + CriticalPathMI = 0; >>> + } >>> + } >>> + >>> + PrescanInstruction(MI); >>> + >>> + if (MI->getDesc().hasExtraDefRegAllocReq()) >>> + // If this instruction's defs have special allocation requirement, don't >>> + // break this anti-dependency. >>> + AntiDepReg = 0; >>> + else if (AntiDepReg) { >>> + // If this instruction has a use of AntiDepReg, breaking it >>> + // is invalid. >>> + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >>> + MachineOperand &MO = MI->getOperand(i); >>> + if (!MO.isReg()) continue; >>> + unsigned Reg = MO.getReg(); >>> + if (Reg == 0) continue; >>> + if (MO.isUse() && AntiDepReg == Reg) { >>> + AntiDepReg = 0; >>> + break; >>> + } >>> + } >>> + } >>> + >>> + // Determine AntiDepReg's register class, if it is live and is >>> + // consistently used within a single class. >>> + const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes[AntiDepReg] : 0; >>> + assert((AntiDepReg == 0 || RC != NULL) && >>> + "Register should be live if it's causing an anti-dependence!"); >>> + if (RC == reinterpret_cast(-1)) >>> + AntiDepReg = 0; >>> + >>> + // Look for a suitable register to use to break the anti-depenence. >>> + // >>> + // TODO: Instead of picking the first free register, consider which might >>> + // be the best. >>> + if (AntiDepReg != 0) { >>> + if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg, >>> + LastNewReg[AntiDepReg], >>> + RC)) { >>> + DEBUG(errs() << "Breaking anti-dependence edge on " >>> + << TRI->getName(AntiDepReg) >>> + << " with " << RegRefs.count(AntiDepReg) << " references" >>> + << " using " << TRI->getName(NewReg) << "!\n"); >>> + >>> + // Update the references to the old register to refer to the new >>> + // register. >>> + std::pair::iterator, >>> + std::multimap::iterator> >>> + Range = RegRefs.equal_range(AntiDepReg); >>> + for (std::multimap::iterator >>> + Q = Range.first, QE = Range.second; Q != QE; ++Q) >>> + Q->second->setReg(NewReg); >>> + >>> + // We just went back in time and modified history; the >>> + // liveness information for the anti-depenence reg is now >>> + // inconsistent. Set the state as if it were dead. >>> + Classes[NewReg] = Classes[AntiDepReg]; >>> + DefIndices[NewReg] = DefIndices[AntiDepReg]; >>> + KillIndices[NewReg] = KillIndices[AntiDepReg]; >>> + assert(((KillIndices[NewReg] == ~0u) != >>> + (DefIndices[NewReg] == ~0u)) && >>> + "Kill and Def maps aren't consistent for NewReg!"); >>> + >>> + Classes[AntiDepReg] = 0; >>> + DefIndices[AntiDepReg] = KillIndices[AntiDepReg]; >>> + KillIndices[AntiDepReg] = ~0u; >>> + assert(((KillIndices[AntiDepReg] == ~0u) != >>> + (DefIndices[AntiDepReg] == ~0u)) && >>> + "Kill and Def maps aren't consistent for AntiDepReg!"); >>> + >>> + RegRefs.erase(AntiDepReg); >>> + LastNewReg[AntiDepReg] = NewReg; >>> + ++Broken; >>> + } >>> + } >>> + >>> + ScanInstruction(MI, Count); >>> + } >>> + >>> + return Broken; >>> +} >>> >>> Added: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h?rev=85127&view=auto >>> >>> ============================================================================== >>> --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h (added) >>> +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h Mon Oct 26 11:59:04 2009 >>> @@ -0,0 +1,95 @@ >>> +//=- llvm/CodeGen/CriticalAntiDepBreaker.h - Anti-Dep Support -*- C++ -*-=// >>> +// >>> +// The LLVM Compiler Infrastructure >>> +// >>> +// This file is distributed under the University of Illinois Open Source >>> +// License. See LICENSE.TXT for details. >>> +// >>> +//===----------------------------------------------------------------------===// >>> +// >>> +// This file implements the CriticalAntiDepBreaker class, which >>> +// implements register anti-dependence breaking along a blocks >>> +// critical path during post-RA scheduler. >>> +// >>> +//===----------------------------------------------------------------------===// >>> + >>> +#ifndef LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H >>> +#define LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H >>> + >>> +#include "llvm/CodeGen/AntiDepBreaker.h" >>> +#include "llvm/CodeGen/MachineBasicBlock.h" >>> +#include "llvm/CodeGen/MachineFrameInfo.h" >>> +#include "llvm/CodeGen/MachineFunction.h" >>> +#include "llvm/CodeGen/MachineRegisterInfo.h" >>> +#include "llvm/CodeGen/ScheduleDAG.h" >>> +#include "llvm/Target/TargetRegisterInfo.h" >>> +#include "llvm/ADT/BitVector.h" >>> +#include "llvm/ADT/SmallSet.h" >>> + >>> +namespace llvm { >>> + class CriticalAntiDepBreaker : public AntiDepBreaker { >>> + MachineFunction& MF; >>> + MachineRegisterInfo &MRI; >>> + const TargetRegisterInfo *TRI; >>> + >>> + /// AllocatableSet - The set of allocatable registers. >>> + /// We'll be ignoring anti-dependencies on non-allocatable registers, >>> + /// because they may not be safe to break. >>> + const BitVector AllocatableSet; >>> + >>> + /// Classes - For live regs that are only used in one register class in a >>> + /// live range, the register class. If the register is not live, the >>> + /// corresponding value is null. If the register is live but used in >>> + /// multiple register classes, the corresponding value is -1 casted to a >>> + /// pointer. >>> + const TargetRegisterClass * >>> + Classes[TargetRegisterInfo::FirstVirtualRegister]; >>> + >>> + /// RegRegs - Map registers to all their references within a live range. >>> + std::multimap RegRefs; >>> + >>> + /// KillIndices - The index of the most recent kill (proceding bottom-up), >>> + /// or ~0u if the register is not live. >>> + unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; >>> + >>> + /// DefIndices - The index of the most recent complete def (proceding bottom >>> + /// up), or ~0u if the register is live. >>> + unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; >>> + >>> + /// KeepRegs - A set of registers which are live and cannot be changed to >>> + /// break anti-dependencies. >>> + SmallSet KeepRegs; >>> + >>> + public: >>> + CriticalAntiDepBreaker(MachineFunction& MFi); >>> + ~CriticalAntiDepBreaker(); >>> + >>> + /// Start - Initialize anti-dep breaking for a new basic block. >>> + void StartBlock(MachineBasicBlock *BB); >>> + >>> + /// BreakAntiDependencies - Identifiy anti-dependencies along the critical path >>> + /// of the ScheduleDAG and break them by renaming registers. >>> + /// >>> + unsigned BreakAntiDependencies(std::vector& SUnits, >>> + MachineBasicBlock::iterator& Begin, >>> + MachineBasicBlock::iterator& End, >>> + unsigned InsertPosIndex); >>> + >>> + /// Observe - Update liveness information to account for the current >>> + /// instruction, which will not be scheduled. >>> + /// >>> + void Observe(MachineInstr *MI, unsigned Count, unsigned InsertPosIndex); >>> + >>> + /// Finish - Finish anti-dep breaking for a basic block. >>> + void FinishBlock(); >>> + >>> + private: >>> + void PrescanInstruction(MachineInstr *MI); >>> + void ScanInstruction(MachineInstr *MI, unsigned Count); >>> + unsigned findSuitableFreeRegister(unsigned AntiDepReg, >>> + unsigned LastNewReg, >>> + const TargetRegisterClass *); >>> + }; >>> +} >>> + >>> +#endif >>> >>> Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=85127&r1=85126&r2=85127&view=diff >>> >>> ============================================================================== >>> --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) >>> +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Mon Oct 26 11:59:04 2009 >>> @@ -19,6 +19,7 @@ >>> //===----------------------------------------------------------------------===// >>> >>> #define DEBUG_TYPE "post-RA-sched" >>> +#include "CriticalAntiDepBreaker.h" >>> #include "ExactHazardRecognizer.h" >>> #include "SimpleHazardRecognizer.h" >>> #include "ScheduleDAGInstrs.h" >>> @@ -40,6 +41,7 @@ >>> #include "llvm/Support/Debug.h" >>> #include "llvm/Support/ErrorHandling.h" >>> #include "llvm/Support/raw_ostream.h" >>> +#include "llvm/ADT/BitVector.h" >>> #include "llvm/ADT/Statistic.h" >>> #include >>> #include >>> @@ -47,6 +49,7 @@ >>> >>> STATISTIC(NumNoops, "Number of noops inserted"); >>> STATISTIC(NumStalls, "Number of pipeline stalls"); >>> +STATISTIC(NumFixedAnti, "Number of fixed anti-dependencies"); >>> >>> // Post-RA scheduling is enabled with >>> // TargetSubtarget.enablePostRAScheduler(). This flag can be used to >>> @@ -55,10 +58,11 @@ >>> EnablePostRAScheduler("post-RA-scheduler", >>> cl::desc("Enable scheduling after register allocation"), >>> cl::init(false), cl::Hidden); >>> -static cl::opt >>> +static cl::opt >>> EnableAntiDepBreaking("break-anti-dependencies", >>> - cl::desc("Break post-RA scheduling anti-dependencies"), >>> - cl::init(true), cl::Hidden); >>> + cl::desc("Break post-RA scheduling anti-dependencies: " >>> + "\"critical\", \"all\", or \"none\""), >>> + cl::init("none"), cl::Hidden); >>> static cl::opt >>> EnablePostRAHazardAvoidance("avoid-hazards", >>> cl::desc("Enable exact hazard avoidance"), >>> @@ -116,56 +120,30 @@ >>> /// Topo - A topological ordering for SUnits. >>> ScheduleDAGTopologicalSort Topo; >>> >>> - /// AllocatableSet - The set of allocatable registers. >>> - /// We'll be ignoring anti-dependencies on non-allocatable registers, >>> - /// because they may not be safe to break. >>> - const BitVector AllocatableSet; >>> - >>> /// HazardRec - The hazard recognizer to use. >>> ScheduleHazardRecognizer *HazardRec; >>> >>> + /// AntiDepBreak - Anti-dependence breaking object, or NULL if none >>> + AntiDepBreaker *AntiDepBreak; >>> + >>> /// AA - AliasAnalysis for making memory reference queries. >>> AliasAnalysis *AA; >>> >>> - /// AntiDepMode - Anti-dependence breaking mode >>> - TargetSubtarget::AntiDepBreakMode AntiDepMode; >>> - >>> - /// Classes - For live regs that are only used in one register class in a >>> - /// live range, the register class. If the register is not live, the >>> - /// corresponding value is null. If the register is live but used in >>> - /// multiple register classes, the corresponding value is -1 casted to a >>> - /// pointer. >>> - const TargetRegisterClass * >>> - Classes[TargetRegisterInfo::FirstVirtualRegister]; >>> - >>> - /// RegRegs - Map registers to all their references within a live range. >>> - std::multimap RegRefs; >>> - >>> /// KillIndices - The index of the most recent kill (proceding bottom-up), >>> /// or ~0u if the register is not live. >>> unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; >>> >>> - /// DefIndices - The index of the most recent complete def (proceding bottom >>> - /// up), or ~0u if the register is live. >>> - unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; >>> - >>> - /// KeepRegs - A set of registers which are live and cannot be changed to >>> - /// break anti-dependencies. >>> - SmallSet KeepRegs; >>> - >>> public: >>> SchedulePostRATDList(MachineFunction &MF, >>> const MachineLoopInfo &MLI, >>> const MachineDominatorTree &MDT, >>> ScheduleHazardRecognizer *HR, >>> - AliasAnalysis *aa, >>> - TargetSubtarget::AntiDepBreakMode adm) >>> + AntiDepBreaker *ADB, >>> + AliasAnalysis *aa) >>> : ScheduleDAGInstrs(MF, MLI, MDT), Topo(SUnits), >>> - AllocatableSet(TRI->getAllocatableSet(MF)), >>> - HazardRec(HR), AA(aa), AntiDepMode(adm) {} >>> + HazardRec(HR), AntiDepBreak(ADB), AA(aa) {} >>> >>> ~SchedulePostRATDList() { >>> - delete HazardRec; >>> } >>> >>> /// StartBlock - Initialize register live-range state for scheduling in >>> @@ -177,11 +155,6 @@ >>> /// >>> void Schedule(); >>> >>> - /// FixupKills - Fix register kill flags that have been made >>> - /// invalid due to scheduling >>> - /// >>> - void FixupKills(MachineBasicBlock *MBB); >>> - >>> /// Observe - Update liveness information to account for the current >>> /// instruction, which will not be scheduled. >>> /// >>> @@ -191,17 +164,16 @@ >>> /// >>> void FinishBlock(); >>> >>> + /// FixupKills - Fix register kill flags that have been made >>> + /// invalid due to scheduling >>> + /// >>> + void FixupKills(MachineBasicBlock *MBB); >>> + >>> private: >>> - void PrescanInstruction(MachineInstr *MI); >>> - void ScanInstruction(MachineInstr *MI, unsigned Count); >>> void ReleaseSucc(SUnit *SU, SDep *SuccEdge); >>> void ReleaseSuccessors(SUnit *SU); >>> void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); >>> void ListScheduleTopDown(); >>> - bool BreakAntiDependencies(); >>> - unsigned findSuitableFreeRegister(unsigned AntiDepReg, >>> - unsigned LastNewReg, >>> - const TargetRegisterClass *); >>> void StartBlockForKills(MachineBasicBlock *BB); >>> >>> // ToggleKillFlag - Toggle a register operand kill flag. Other >>> @@ -250,8 +222,9 @@ >>> >>> // Check for antidep breaking override... >>> if (EnableAntiDepBreaking.getPosition() > 0) { >>> - AntiDepMode = (EnableAntiDepBreaking) ? >>> - TargetSubtarget::ANTIDEP_CRITICAL : TargetSubtarget::ANTIDEP_NONE; >>> + AntiDepMode = (EnableAntiDepBreaking == "all") ? TargetSubtarget::ANTIDEP_ALL : >>> + (EnableAntiDepBreaking == "critical") ? TargetSubtarget::ANTIDEP_CRITICAL : >>> + TargetSubtarget::ANTIDEP_NONE; >>> } >>> >>> DEBUG(errs() << "PostRAScheduler\n"); >>> @@ -262,8 +235,12 @@ >>> ScheduleHazardRecognizer *HR = EnablePostRAHazardAvoidance ? >>> (ScheduleHazardRecognizer *)new ExactHazardRecognizer(InstrItins) : >>> (ScheduleHazardRecognizer *)new SimpleHazardRecognizer(); >>> + AntiDepBreaker *ADB = >>> + (AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? NULL /* FIXME */ : >>> + (AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? >>> + new CriticalAntiDepBreaker(Fn) : NULL; >>> >>> - SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, AA, AntiDepMode); >>> + SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, ADB, AA); >>> >>> // Loop over all of the basic blocks >>> for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); >>> @@ -311,6 +288,9 @@ >>> Scheduler.FixupKills(MBB); >>> } >>> >>> + delete HR; >>> + delete ADB; >>> + >>> return true; >>> } >>> >>> @@ -321,78 +301,10 @@ >>> // Call the superclass. >>> ScheduleDAGInstrs::StartBlock(BB); >>> >>> - // Reset the hazard recognizer. >>> + // Reset the hazard recognizer and anti-dep breaker. >>> HazardRec->Reset(); >>> - >>> - // Clear out the register class data. >>> - std::fill(Classes, array_endof(Classes), >>> - static_cast(0)); >>> - >>> - // Initialize the indices to indicate that no registers are live. >>> - std::fill(KillIndices, array_endof(KillIndices), ~0u); >>> - std::fill(DefIndices, array_endof(DefIndices), BB->size()); >>> - >>> - // Clear "do not change" set. >>> - KeepRegs.clear(); >>> - >>> - bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn()); >>> - >>> - // Determine the live-out physregs for this block. >>> - if (IsReturnBlock) { >>> - // In a return block, examine the function live-out regs. >>> - for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), >>> - E = MRI.liveout_end(); I != E; ++I) { >>> - unsigned Reg = *I; >>> - Classes[Reg] = reinterpret_cast(-1); >>> - KillIndices[Reg] = BB->size(); >>> - DefIndices[Reg] = ~0u; >>> - // Repeat, for all aliases. >>> - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { >>> - unsigned AliasReg = *Alias; >>> - Classes[AliasReg] = reinterpret_cast(-1); >>> - KillIndices[AliasReg] = BB->size(); >>> - DefIndices[AliasReg] = ~0u; >>> - } >>> - } >>> - } else { >>> - // In a non-return block, examine the live-in regs of all successors. >>> - for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), >>> - SE = BB->succ_end(); SI != SE; ++SI) >>> - for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), >>> - E = (*SI)->livein_end(); I != E; ++I) { >>> - unsigned Reg = *I; >>> - Classes[Reg] = reinterpret_cast(-1); >>> - KillIndices[Reg] = BB->size(); >>> - DefIndices[Reg] = ~0u; >>> - // Repeat, for all aliases. >>> - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { >>> - unsigned AliasReg = *Alias; >>> - Classes[AliasReg] = reinterpret_cast(-1); >>> - KillIndices[AliasReg] = BB->size(); >>> - DefIndices[AliasReg] = ~0u; >>> - } >>> - } >>> - } >>> - >>> - // Mark live-out callee-saved registers. In a return block this is >>> - // all callee-saved registers. In non-return this is any >>> - // callee-saved register that is not saved in the prolog. >>> - const MachineFrameInfo *MFI = MF.getFrameInfo(); >>> - BitVector Pristine = MFI->getPristineRegs(BB); >>> - for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { >>> - unsigned Reg = *I; >>> - if (!IsReturnBlock && !Pristine.test(Reg)) continue; >>> - Classes[Reg] = reinterpret_cast(-1); >>> - KillIndices[Reg] = BB->size(); >>> - DefIndices[Reg] = ~0u; >>> - // Repeat, for all aliases. >>> - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { >>> - unsigned AliasReg = *Alias; >>> - Classes[AliasReg] = reinterpret_cast(-1); >>> - KillIndices[AliasReg] = BB->size(); >>> - DefIndices[AliasReg] = ~0u; >>> - } >>> - } >>> + if (AntiDepBreak != NULL) >>> + AntiDepBreak->StartBlock(BB); >>> } >>> >>> /// Schedule - Schedule the instruction range using list scheduling. >>> @@ -403,8 +315,11 @@ >>> // Build the scheduling graph. >>> BuildSchedGraph(AA); >>> >>> - if (AntiDepMode != TargetSubtarget::ANTIDEP_NONE) { >>> - if (BreakAntiDependencies()) { >>> + if (AntiDepBreak != NULL) { >>> + unsigned Broken = >>> + AntiDepBreak->BreakAntiDependencies(SUnits, Begin, InsertPos, >>> + InsertPosIndex); >>> + if (Broken > 0) { >>> // We made changes. Update the dependency graph. >>> // Theoretically we could update the graph in place: >>> // When a live range is changed to use a different register, remove >>> @@ -415,6 +330,8 @@ >>> EntrySU = SUnit(); >>> ExitSU = SUnit(); >>> BuildSchedGraph(AA); >>> + >>> + NumFixedAnti += Broken; >>> } >>> } >>> >>> @@ -432,436 +349,20 @@ >>> /// instruction, which will not be scheduled. >>> /// >>> void SchedulePostRATDList::Observe(MachineInstr *MI, unsigned Count) { >>> - assert(Count < InsertPosIndex && "Instruction index out of expected range!"); >>> - >>> - // Any register which was defined within the previous scheduling region >>> - // may have been rescheduled and its lifetime may overlap with registers >>> - // in ways not reflected in our current liveness state. For each such >>> - // register, adjust the liveness state to be conservatively correct. >>> - for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) >>> - if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) { >>> - assert(KillIndices[Reg] == ~0u && "Clobbered register is live!"); >>> - // Mark this register to be non-renamable. >>> - Classes[Reg] = reinterpret_cast(-1); >>> - // Move the def index to the end of the previous region, to reflect >>> - // that the def could theoretically have been scheduled at the end. >>> - DefIndices[Reg] = InsertPosIndex; >>> - } >>> - >>> - PrescanInstruction(MI); >>> - ScanInstruction(MI, Count); >>> + if (AntiDepBreak != NULL) >>> + AntiDepBreak->Observe(MI, Count, InsertPosIndex); >>> } >>> >>> /// FinishBlock - Clean up register live-range state. >>> /// >>> void SchedulePostRATDList::FinishBlock() { >>> - RegRefs.clear(); >>> + if (AntiDepBreak != NULL) >>> + AntiDepBreak->FinishBlock(); >>> >>> // Call the superclass. >>> ScheduleDAGInstrs::FinishBlock(); >>> } >>> >>> -/// CriticalPathStep - Return the next SUnit after SU on the bottom-up >>> -/// critical path. >>> -static SDep *CriticalPathStep(SUnit *SU) { >>> - SDep *Next = 0; >>> - unsigned NextDepth = 0; >>> - // Find the predecessor edge with the greatest depth. >>> - for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end(); >>> - P != PE; ++P) { >>> - SUnit *PredSU = P->getSUnit(); >>> - unsigned PredLatency = P->getLatency(); >>> - unsigned PredTotalLatency = PredSU->getDepth() + PredLatency; >>> - // In the case of a latency tie, prefer an anti-dependency edge over >>> - // other types of edges. >>> - if (NextDepth < PredTotalLatency || >>> - (NextDepth == PredTotalLatency && P->getKind() == SDep::Anti)) { >>> - NextDepth = PredTotalLatency; >>> - Next = &*P; >>> - } >>> - } >>> - return Next; >>> -} >>> - >>> -void SchedulePostRATDList::PrescanInstruction(MachineInstr *MI) { >>> - // Scan the register operands for this instruction and update >>> - // Classes and RegRefs. >>> - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >>> - MachineOperand &MO = MI->getOperand(i); >>> - if (!MO.isReg()) continue; >>> - unsigned Reg = MO.getReg(); >>> - if (Reg == 0) continue; >>> - const TargetRegisterClass *NewRC = 0; >>> - >>> - if (i < MI->getDesc().getNumOperands()) >>> - NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); >>> - >>> - // For now, only allow the register to be changed if its register >>> - // class is consistent across all uses. >>> - if (!Classes[Reg] && NewRC) >>> - Classes[Reg] = NewRC; >>> - else if (!NewRC || Classes[Reg] != NewRC) >>> - Classes[Reg] = reinterpret_cast(-1); >>> - >>> - // Now check for aliases. >>> - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { >>> - // If an alias of the reg is used during the live range, give up. >>> - // Note that this allows us to skip checking if AntiDepReg >>> - // overlaps with any of the aliases, among other things. >>> - unsigned AliasReg = *Alias; >>> - if (Classes[AliasReg]) { >>> - Classes[AliasReg] = reinterpret_cast(-1); >>> - Classes[Reg] = reinterpret_cast(-1); >>> - } >>> - } >>> - >>> - // If we're still willing to consider this register, note the reference. >>> - if (Classes[Reg] != reinterpret_cast(-1)) >>> - RegRefs.insert(std::make_pair(Reg, &MO)); >>> - >>> - // It's not safe to change register allocation for source operands of >>> - // that have special allocation requirements. >>> - if (MO.isUse() && MI->getDesc().hasExtraSrcRegAllocReq()) { >>> - if (KeepRegs.insert(Reg)) { >>> - for (const unsigned *Subreg = TRI->getSubRegisters(Reg); >>> - *Subreg; ++Subreg) >>> - KeepRegs.insert(*Subreg); >>> - } >>> - } >>> - } >>> -} >>> - >>> -void SchedulePostRATDList::ScanInstruction(MachineInstr *MI, >>> - unsigned Count) { >>> - // Update liveness. >>> - // Proceding upwards, registers that are defed but not used in this >>> - // instruction are now dead. >>> - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >>> - MachineOperand &MO = MI->getOperand(i); >>> - if (!MO.isReg()) continue; >>> - unsigned Reg = MO.getReg(); >>> - if (Reg == 0) continue; >>> - if (!MO.isDef()) continue; >>> - // Ignore two-addr defs. >>> - if (MI->isRegTiedToUseOperand(i)) continue; >>> - >>> - DefIndices[Reg] = Count; >>> - KillIndices[Reg] = ~0u; >>> - assert(((KillIndices[Reg] == ~0u) != >>> - (DefIndices[Reg] == ~0u)) && >>> - "Kill and Def maps aren't consistent for Reg!"); >>> - KeepRegs.erase(Reg); >>> - Classes[Reg] = 0; >>> - RegRefs.erase(Reg); >>> - // Repeat, for all subregs. >>> - for (const unsigned *Subreg = TRI->getSubRegisters(Reg); >>> - *Subreg; ++Subreg) { >>> - unsigned SubregReg = *Subreg; >>> - DefIndices[SubregReg] = Count; >>> - KillIndices[SubregReg] = ~0u; >>> - KeepRegs.erase(SubregReg); >>> - Classes[SubregReg] = 0; >>> - RegRefs.erase(SubregReg); >>> - } >>> - // Conservatively mark super-registers as unusable. >>> - for (const unsigned *Super = TRI->getSuperRegisters(Reg); >>> - *Super; ++Super) { >>> - unsigned SuperReg = *Super; >>> - Classes[SuperReg] = reinterpret_cast(-1); >>> - } >>> - } >>> - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >>> - MachineOperand &MO = MI->getOperand(i); >>> - if (!MO.isReg()) continue; >>> - unsigned Reg = MO.getReg(); >>> - if (Reg == 0) continue; >>> - if (!MO.isUse()) continue; >>> - >>> - const TargetRegisterClass *NewRC = 0; >>> - if (i < MI->getDesc().getNumOperands()) >>> - NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); >>> - >>> - // For now, only allow the register to be changed if its register >>> - // class is consistent across all uses. >>> - if (!Classes[Reg] && NewRC) >>> - Classes[Reg] = NewRC; >>> - else if (!NewRC || Classes[Reg] != NewRC) >>> - Classes[Reg] = reinterpret_cast(-1); >>> - >>> - RegRefs.insert(std::make_pair(Reg, &MO)); >>> - >>> - // It wasn't previously live but now it is, this is a kill. >>> - if (KillIndices[Reg] == ~0u) { >>> - KillIndices[Reg] = Count; >>> - DefIndices[Reg] = ~0u; >>> - assert(((KillIndices[Reg] == ~0u) != >>> - (DefIndices[Reg] == ~0u)) && >>> - "Kill and Def maps aren't consistent for Reg!"); >>> - } >>> - // Repeat, for all aliases. >>> - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { >>> - unsigned AliasReg = *Alias; >>> - if (KillIndices[AliasReg] == ~0u) { >>> - KillIndices[AliasReg] = Count; >>> - DefIndices[AliasReg] = ~0u; >>> - } >>> - } >>> - } >>> -} >>> - >>> -unsigned >>> -SchedulePostRATDList::findSuitableFreeRegister(unsigned AntiDepReg, >>> - unsigned LastNewReg, >>> - const TargetRegisterClass *RC) { >>> - for (TargetRegisterClass::iterator R = RC->allocation_order_begin(MF), >>> - RE = RC->allocation_order_end(MF); R != RE; ++R) { >>> - unsigned NewReg = *R; >>> - // Don't replace a register with itself. >>> - if (NewReg == AntiDepReg) continue; >>> - // Don't replace a register with one that was recently used to repair >>> - // an anti-dependence with this AntiDepReg, because that would >>> - // re-introduce that anti-dependence. >>> - if (NewReg == LastNewReg) continue; >>> - // If NewReg is dead and NewReg's most recent def is not before >>> - // AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg. >>> - assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u)) && >>> - "Kill and Def maps aren't consistent for AntiDepReg!"); >>> - assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u)) && >>> - "Kill and Def maps aren't consistent for NewReg!"); >>> - if (KillIndices[NewReg] != ~0u || >>> - Classes[NewReg] == reinterpret_cast(-1) || >>> - KillIndices[AntiDepReg] > DefIndices[NewReg]) >>> - continue; >>> - return NewReg; >>> - } >>> - >>> - // No registers are free and available! >>> - return 0; >>> -} >>> - >>> -/// BreakAntiDependencies - Identifiy anti-dependencies along the critical path >>> -/// of the ScheduleDAG and break them by renaming registers. >>> -/// >>> -bool SchedulePostRATDList::BreakAntiDependencies() { >>> - // The code below assumes that there is at least one instruction, >>> - // so just duck out immediately if the block is empty. >>> - if (SUnits.empty()) return false; >>> - >>> - // Find the node at the bottom of the critical path. >>> - SUnit *Max = 0; >>> - for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { >>> - SUnit *SU = &SUnits[i]; >>> - if (!Max || SU->getDepth() + SU->Latency > Max->getDepth() + Max->Latency) >>> - Max = SU; >>> - } >>> - >>> -#ifndef NDEBUG >>> - { >>> - DEBUG(errs() << "Critical path has total latency " >>> - << (Max->getDepth() + Max->Latency) << "\n"); >>> - DEBUG(errs() << "Available regs:"); >>> - for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { >>> - if (KillIndices[Reg] == ~0u) >>> - DEBUG(errs() << " " << TRI->getName(Reg)); >>> - } >>> - DEBUG(errs() << '\n'); >>> - } >>> -#endif >>> - >>> - // Track progress along the critical path through the SUnit graph as we walk >>> - // the instructions. >>> - SUnit *CriticalPathSU = Max; >>> - MachineInstr *CriticalPathMI = CriticalPathSU->getInstr(); >>> - >>> - // Consider this pattern: >>> - // A = ... >>> - // ... = A >>> - // A = ... >>> - // ... = A >>> - // A = ... >>> - // ... = A >>> - // A = ... >>> - // ... = A >>> - // There are three anti-dependencies here, and without special care, >>> - // we'd break all of them using the same register: >>> - // A = ... >>> - // ... = A >>> - // B = ... >>> - // ... = B >>> - // B = ... >>> - // ... = B >>> - // B = ... >>> - // ... = B >>> - // because at each anti-dependence, B is the first register that >>> - // isn't A which is free. This re-introduces anti-dependencies >>> - // at all but one of the original anti-dependencies that we were >>> - // trying to break. To avoid this, keep track of the most recent >>> - // register that each register was replaced with, avoid >>> - // using it to repair an anti-dependence on the same register. >>> - // This lets us produce this: >>> - // A = ... >>> - // ... = A >>> - // B = ... >>> - // ... = B >>> - // C = ... >>> - // ... = C >>> - // B = ... >>> - // ... = B >>> - // This still has an anti-dependence on B, but at least it isn't on the >>> - // original critical path. >>> - // >>> - // TODO: If we tracked more than one register here, we could potentially >>> - // fix that remaining critical edge too. This is a little more involved, >>> - // because unlike the most recent register, less recent registers should >>> - // still be considered, though only if no other registers are available. >>> - unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = {}; >>> - >>> - // Attempt to break anti-dependence edges on the critical path. Walk the >>> - // instructions from the bottom up, tracking information about liveness >>> - // as we go to help determine which registers are available. >>> - bool Changed = false; >>> - unsigned Count = InsertPosIndex - 1; >>> - for (MachineBasicBlock::iterator I = InsertPos, E = Begin; >>> - I != E; --Count) { >>> - MachineInstr *MI = --I; >>> - >>> - // Check if this instruction has a dependence on the critical path that >>> - // is an anti-dependence that we may be able to break. If it is, set >>> - // AntiDepReg to the non-zero register associated with the anti-dependence. >>> - // >>> - // We limit our attention to the critical path as a heuristic to avoid >>> - // breaking anti-dependence edges that aren't going to significantly >>> - // impact the overall schedule. There are a limited number of registers >>> - // and we want to save them for the important edges. >>> - // >>> - // TODO: Instructions with multiple defs could have multiple >>> - // anti-dependencies. The current code here only knows how to break one >>> - // edge per instruction. Note that we'd have to be able to break all of >>> - // the anti-dependencies in an instruction in order to be effective. >>> - unsigned AntiDepReg = 0; >>> - if (MI == CriticalPathMI) { >>> - if (SDep *Edge = CriticalPathStep(CriticalPathSU)) { >>> - SUnit *NextSU = Edge->getSUnit(); >>> - >>> - // Only consider anti-dependence edges. >>> - if (Edge->getKind() == SDep::Anti) { >>> - AntiDepReg = Edge->getReg(); >>> - assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); >>> - if (!AllocatableSet.test(AntiDepReg)) >>> - // Don't break anti-dependencies on non-allocatable registers. >>> - AntiDepReg = 0; >>> - else if (KeepRegs.count(AntiDepReg)) >>> - // Don't break anti-dependencies if an use down below requires >>> - // this exact register. >>> - AntiDepReg = 0; >>> - else { >>> - // If the SUnit has other dependencies on the SUnit that it >>> - // anti-depends on, don't bother breaking the anti-dependency >>> - // since those edges would prevent such units from being >>> - // scheduled past each other regardless. >>> - // >>> - // Also, if there are dependencies on other SUnits with the >>> - // same register as the anti-dependency, don't attempt to >>> - // break it. >>> - for (SUnit::pred_iterator P = CriticalPathSU->Preds.begin(), >>> - PE = CriticalPathSU->Preds.end(); P != PE; ++P) >>> - if (P->getSUnit() == NextSU ? >>> - (P->getKind() != SDep::Anti || P->getReg() != AntiDepReg) : >>> - (P->getKind() == SDep::Data && P->getReg() == AntiDepReg)) { >>> - AntiDepReg = 0; >>> - break; >>> - } >>> - } >>> - } >>> - CriticalPathSU = NextSU; >>> - CriticalPathMI = CriticalPathSU->getInstr(); >>> - } else { >>> - // We've reached the end of the critical path. >>> - CriticalPathSU = 0; >>> - CriticalPathMI = 0; >>> - } >>> - } >>> - >>> - PrescanInstruction(MI); >>> - >>> - if (MI->getDesc().hasExtraDefRegAllocReq()) >>> - // If this instruction's defs have special allocation requirement, don't >>> - // break this anti-dependency. >>> - AntiDepReg = 0; >>> - else if (AntiDepReg) { >>> - // If this instruction has a use of AntiDepReg, breaking it >>> - // is invalid. >>> - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { >>> - MachineOperand &MO = MI->getOperand(i); >>> - if (!MO.isReg()) continue; >>> - unsigned Reg = MO.getReg(); >>> - if (Reg == 0) continue; >>> - if (MO.isUse() && AntiDepReg == Reg) { >>> - AntiDepReg = 0; >>> - break; >>> - } >>> - } >>> - } >>> - >>> - // Determine AntiDepReg's register class, if it is live and is >>> - // consistently used within a single class. >>> - const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes[AntiDepReg] : 0; >>> - assert((AntiDepReg == 0 || RC != NULL) && >>> - "Register should be live if it's causing an anti-dependence!"); >>> - if (RC == reinterpret_cast(-1)) >>> - AntiDepReg = 0; >>> - >>> - // Look for a suitable register to use to break the anti-depenence. >>> - // >>> - // TODO: Instead of picking the first free register, consider which might >>> - // be the best. >>> - if (AntiDepReg != 0) { >>> - if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg, >>> - LastNewReg[AntiDepReg], >>> - RC)) { >>> - DEBUG(errs() << "Breaking anti-dependence edge on " >>> - << TRI->getName(AntiDepReg) >>> - << " with " << RegRefs.count(AntiDepReg) << " references" >>> - << " using " << TRI->getName(NewReg) << "!\n"); >>> - >>> - // Update the references to the old register to refer to the new >>> - // register. >>> - std::pair::iterator, >>> - std::multimap::iterator> >>> - Range = RegRefs.equal_range(AntiDepReg); >>> - for (std::multimap::iterator >>> - Q = Range.first, QE = Range.second; Q != QE; ++Q) >>> - Q->second->setReg(NewReg); >>> - >>> - // We just went back in time and modified history; the >>> - // liveness information for the anti-depenence reg is now >>> - // inconsistent. Set the state as if it were dead. >>> - Classes[NewReg] = Classes[AntiDepReg]; >>> - DefIndices[NewReg] = DefIndices[AntiDepReg]; >>> - KillIndices[NewReg] = KillIndices[AntiDepReg]; >>> - assert(((KillIndices[NewReg] == ~0u) != >>> - (DefIndices[NewReg] == ~0u)) && >>> - "Kill and Def maps aren't consistent for NewReg!"); >>> - >>> - Classes[AntiDepReg] = 0; >>> - DefIndices[AntiDepReg] = KillIndices[AntiDepReg]; >>> - KillIndices[AntiDepReg] = ~0u; >>> - assert(((KillIndices[AntiDepReg] == ~0u) != >>> - (DefIndices[AntiDepReg] == ~0u)) && >>> - "Kill and Def maps aren't consistent for AntiDepReg!"); >>> - >>> - RegRefs.erase(AntiDepReg); >>> - Changed = true; >>> - LastNewReg[AntiDepReg] = NewReg; >>> - } >>> - } >>> - >>> - ScanInstruction(MI, Count); >>> - } >>> - >>> - return Changed; >>> -} >>> - >>> /// StartBlockForKills - Initialize register live-range state for updating kills >>> /// >>> void SchedulePostRATDList::StartBlockForKills(MachineBasicBlock *BB) { >>> >>> Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=85127&r1=85126&r2=85127&view=diff >>> >>> ============================================================================== >>> --- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original) >>> +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Mon Oct 26 11:59:04 2009 >>> @@ -130,7 +130,7 @@ >>> /// for Thumb1. >>> bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, >>> TargetSubtarget::AntiDepBreakMode& mode) const { >>> - mode = TargetSubtarget::ANTIDEP_NONE; >>> + mode = TargetSubtarget::ANTIDEP_CRITICAL; >>> return PostRAScheduler && OptLevel >= CodeGenOpt::Default; >>> } >>> >>> >>> Modified: llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll?rev=85127&r1=85126&r2=85127&view=diff >>> >>> ============================================================================== >>> --- llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll (original) >>> +++ llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll Mon Oct 26 11:59:04 2009 >>> @@ -1,7 +1,7 @@ >>> -; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies=false > %t >>> +; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies=none > %t >>> ; RUN: grep {%xmm0} %t | count 14 >>> ; RUN: not grep {%xmm1} %t >>> -; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies > %t >>> +; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies=critical > %t >>> ; RUN: grep {%xmm0} %t | count 7 >>> ; RUN: grep {%xmm1} %t | count 7 >>> >>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > From johnny.chen at apple.com Mon Oct 26 16:39:13 2009 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 26 Oct 2009 14:39:13 -0700 Subject: [llvm-commits] Typo in ARMInstrFormats.td for ASuIn? Message-ID: <5E360501-8B49-454C-A0CC-0EE2FE75BB82@apple.com> Hi, Opcod3 is not passed to ASuI parent class. -------------- next part -------------- A non-text attachment was scrubbed... Name: ARMInstrFormats.td.patch Type: application/octet-stream Size: 784 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091026/4a66c9b8/attachment.obj From gohman at apple.com Mon Oct 26 16:55:44 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 26 Oct 2009 21:55:44 -0000 Subject: [llvm-commits] [llvm] r85158 - in /llvm/trunk: lib/Analysis/BasicAliasAnalysis.cpp test/Analysis/BasicAA/phi-and-select.ll Message-ID: <200910262155.n9QLtiAA006376@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 26 16:55:43 2009 New Revision: 85158 URL: http://llvm.org/viewvc/llvm-project?rev=85158&view=rev Log: Teach BasicAA how to analyze Select instructions, and make it more aggressive on PHI instructions. Added: llvm/trunk/test/Analysis/BasicAA/phi-and-select.ll Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=85158&r1=85157&r2=85158&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Mon Oct 26 16:55:43 2009 @@ -217,7 +217,7 @@ private: // VisitedPHIs - Track PHI nodes visited by a aliasCheck() call. - SmallPtrSet VisitedPHIs; + SmallPtrSet VisitedPHIs; // aliasGEP - Provide a bunch of ad-hoc rules to disambiguate a GEP instruction // against another. @@ -229,6 +229,10 @@ AliasResult aliasPHI(const PHINode *PN, unsigned PNSize, const Value *V2, unsigned V2Size); + /// aliasSelect - Disambiguate a Select instruction against another value. + AliasResult aliasSelect(const SelectInst *SI, unsigned SISize, + const Value *V2, unsigned V2Size); + AliasResult aliasCheck(const Value *V1, unsigned V1Size, const Value *V2, unsigned V2Size); @@ -519,6 +523,41 @@ return MayAlias; } +// aliasSelect - Provide a bunch of ad-hoc rules to disambiguate a Select instruction +// against another. +AliasAnalysis::AliasResult +BasicAliasAnalysis::aliasSelect(const SelectInst *SI, unsigned SISize, + const Value *V2, unsigned V2Size) { + // If the values are Selects with the same condition, we can do a more precise + // check: just check for aliases between the values on corresponding arms. + if (const SelectInst *SI2 = dyn_cast(V2)) + if (SI->getCondition() == SI2->getCondition()) { + AliasResult Alias = + aliasCheck(SI->getTrueValue(), SISize, + SI2->getTrueValue(), V2Size); + if (Alias == MayAlias) + return MayAlias; + AliasResult ThisAlias = + aliasCheck(SI->getFalseValue(), SISize, + SI2->getFalseValue(), V2Size); + if (ThisAlias != Alias) + return MayAlias; + return Alias; + } + + // If both arms of the Select node NoAlias or MustAlias V2, then returns + // NoAlias / MustAlias. Otherwise, returns MayAlias. + AliasResult Alias = + aliasCheck(SI->getTrueValue(), SISize, V2, V2Size); + if (Alias == MayAlias) + return MayAlias; + AliasResult ThisAlias = + aliasCheck(SI->getFalseValue(), SISize, V2, V2Size); + if (ThisAlias != Alias) + return MayAlias; + return Alias; +} + // aliasPHI - Provide a bunch of ad-hoc rules to disambiguate a PHI instruction // against another. AliasAnalysis::AliasResult @@ -528,6 +567,28 @@ if (!VisitedPHIs.insert(PN)) return MayAlias; + // If the values are PHIs in the same block, we can do a more precise + // as well as efficient check: just check for aliases between the values + // on corresponding edges. + if (const PHINode *PN2 = dyn_cast(V2)) + if (PN2->getParent() == PN->getParent()) { + AliasResult Alias = + aliasCheck(PN->getIncomingValue(0), PNSize, + PN2->getIncomingValueForBlock(PN->getIncomingBlock(0)), + V2Size); + if (Alias == MayAlias) + return MayAlias; + for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i) { + AliasResult ThisAlias = + aliasCheck(PN->getIncomingValue(i), PNSize, + PN2->getIncomingValueForBlock(PN->getIncomingBlock(i)), + V2Size); + if (ThisAlias != Alias) + return MayAlias; + } + return Alias; + } + SmallPtrSet UniqueSrc; SmallVector V1Srcs; for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { @@ -542,7 +603,7 @@ V1Srcs.push_back(PV1); } - AliasResult Alias = aliasCheck(V1Srcs[0], PNSize, V2, V2Size); + AliasResult Alias = aliasCheck(V2, V2Size, V1Srcs[0], PNSize); // Early exit if the check of the first PHI source against V2 is MayAlias. // Other results are not possible. if (Alias == MayAlias) @@ -552,6 +613,12 @@ // NoAlias / MustAlias. Otherwise, returns MayAlias. for (unsigned i = 1, e = V1Srcs.size(); i != e; ++i) { Value *V = V1Srcs[i]; + + // If V2 is a PHI, the recursive case will have been caught in the + // above aliasCheck call, so these subsequent calls to aliasCheck + // don't need to assume that V2 is being visited recursively. + VisitedPHIs.erase(V2); + AliasResult ThisAlias = aliasCheck(V2, V2Size, V, PNSize); if (ThisAlias != Alias || ThisAlias == MayAlias) return MayAlias; @@ -628,6 +695,13 @@ if (const PHINode *PN = dyn_cast(V1)) return aliasPHI(PN, V1Size, V2, V2Size); + if (isa(V2) && !isa(V1)) { + std::swap(V1, V2); + std::swap(V1Size, V2Size); + } + if (const SelectInst *S1 = dyn_cast(V1)) + return aliasSelect(S1, V1Size, V2, V2Size); + return MayAlias; } Added: llvm/trunk/test/Analysis/BasicAA/phi-and-select.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/phi-and-select.ll?rev=85158&view=auto ============================================================================== --- llvm/trunk/test/Analysis/BasicAA/phi-and-select.ll (added) +++ llvm/trunk/test/Analysis/BasicAA/phi-and-select.ll Mon Oct 26 16:55:43 2009 @@ -0,0 +1,73 @@ +; RUN: opt < %s -aa-eval -print-all-alias-modref-info -disable-output \ +; RUN: |& grep {NoAlias: double\\* \[%\]a, double\\* \[%\]b\$} | count 4 + +; BasicAA should detect NoAliases in PHIs and Selects. + +; Two PHIs in the same block. +define void @foo(i1 %m, double* noalias %x, double* noalias %y) { +entry: + br i1 %m, label %true, label %false + +true: + br label %exit + +false: + br label %exit + +exit: + %a = phi double* [ %x, %true ], [ %y, %false ] + %b = phi double* [ %x, %false ], [ %y, %true ] + volatile store double 0.0, double* %a + volatile store double 1.0, double* %b + ret void +} + +; Two selects with the same condition. +define void @bar(i1 %m, double* noalias %x, double* noalias %y) { +entry: + %a = select i1 %m, double* %x, double* %y + %b = select i1 %m, double* %y, double* %x + volatile store double 0.000000e+00, double* %a + volatile store double 1.000000e+00, double* %b + ret void +} + +; Two PHIs with disjoint sets of inputs. +define void @qux(i1 %m, double* noalias %x, double* noalias %y, + i1 %n, double* noalias %v, double* noalias %w) { +entry: + br i1 %m, label %true, label %false + +true: + br label %exit + +false: + br label %exit + +exit: + %a = phi double* [ %x, %true ], [ %y, %false ] + br i1 %n, label %ntrue, label %nfalse + +ntrue: + br label %nexit + +nfalse: + br label %nexit + +nexit: + %b = phi double* [ %v, %ntrue ], [ %w, %nfalse ] + volatile store double 0.0, double* %a + volatile store double 1.0, double* %b + ret void +} + +; Two selects with disjoint sets of arms. +define void @fin(i1 %m, double* noalias %x, double* noalias %y, + i1 %n, double* noalias %v, double* noalias %w) { +entry: + %a = select i1 %m, double* %x, double* %y + %b = select i1 %n, double* %v, double* %w + volatile store double 0.000000e+00, double* %a + volatile store double 1.000000e+00, double* %b + ret void +} From kremenek at apple.com Mon Oct 26 17:06:01 2009 From: kremenek at apple.com (Ted Kremenek) Date: Mon, 26 Oct 2009 22:06:01 -0000 Subject: [llvm-commits] [llvm] r85161 - in /llvm/trunk/lib: Target/MSP430/AsmPrinter/CMakeLists.txt Transforms/Scalar/CMakeLists.txt Message-ID: <200910262206.n9QM61eR006887@zion.cs.uiuc.edu> Author: kremenek Date: Mon Oct 26 17:06:01 2009 New Revision: 85161 URL: http://llvm.org/viewvc/llvm-project?rev=85161&view=rev Log: Update CMake files. Modified: llvm/trunk/lib/Target/MSP430/AsmPrinter/CMakeLists.txt llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt Modified: llvm/trunk/lib/Target/MSP430/AsmPrinter/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/AsmPrinter/CMakeLists.txt?rev=85161&r1=85160&r2=85161&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/AsmPrinter/CMakeLists.txt (original) +++ llvm/trunk/lib/Target/MSP430/AsmPrinter/CMakeLists.txt Mon Oct 26 17:06:01 2009 @@ -1,8 +1,8 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. ) add_llvm_library(LLVMMSP430AsmPrinter - MSP430InstPrinter.cpp MSP430AsmPrinter.cpp + MSP430InstPrinter.cpp MSP430MCInstLower.cpp ) add_dependencies(LLVMMSP430AsmPrinter MSP430CodeGenTable_gen) Modified: llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt?rev=85161&r1=85160&r2=85161&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt (original) +++ llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt Mon Oct 26 17:06:01 2009 @@ -7,6 +7,7 @@ ConstantProp.cpp DCE.cpp DeadStoreElimination.cpp + GEPSplitter.cpp GVN.cpp IndVarSimplify.cpp InstructionCombining.cpp From gohman at apple.com Mon Oct 26 17:14:23 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 26 Oct 2009 22:14:23 -0000 Subject: [llvm-commits] [llvm] r85164 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/add-shrink.ll test/Transforms/InstCombine/add-sitofp.ll Message-ID: <200910262214.n9QMENxO007270@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 26 17:14:22 2009 New Revision: 85164 URL: http://llvm.org/viewvc/llvm-project?rev=85164&view=rev Log: Code that checks WillNotOverflowSignedAdd before creating an Add can safely use the NSW bit on the Add. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/test/Transforms/InstCombine/add-shrink.ll llvm/trunk/test/Transforms/InstCombine/add-sitofp.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=85164&r1=85163&r2=85164&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Oct 26 17:14:22 2009 @@ -2420,8 +2420,8 @@ ConstantExpr::getSExt(CI, I.getType()) == RHSC && WillNotOverflowSignedAdd(LHSConv->getOperand(0), CI)) { // Insert the new, smaller add. - Value *NewAdd = Builder->CreateAdd(LHSConv->getOperand(0), - CI, "addconv"); + Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0), + CI, "addconv"); return new SExtInst(NewAdd, I.getType()); } } @@ -2436,8 +2436,8 @@ WillNotOverflowSignedAdd(LHSConv->getOperand(0), RHSConv->getOperand(0))) { // Insert the new integer add. - Value *NewAdd = Builder->CreateAdd(LHSConv->getOperand(0), - RHSConv->getOperand(0), "addconv"); + Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0), + RHSConv->getOperand(0), "addconv"); return new SExtInst(NewAdd, I.getType()); } } @@ -2493,8 +2493,8 @@ ConstantExpr::getSIToFP(CI, I.getType()) == CFP && WillNotOverflowSignedAdd(LHSConv->getOperand(0), CI)) { // Insert the new integer add. - Value *NewAdd = Builder->CreateAdd(LHSConv->getOperand(0), - CI, "addconv"); + Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0), + CI, "addconv"); return new SIToFPInst(NewAdd, I.getType()); } } @@ -2509,8 +2509,8 @@ WillNotOverflowSignedAdd(LHSConv->getOperand(0), RHSConv->getOperand(0))) { // Insert the new integer add. - Value *NewAdd = Builder->CreateAdd(LHSConv->getOperand(0), - RHSConv->getOperand(0), "addconv"); + Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0), + RHSConv->getOperand(0), "addconv"); return new SIToFPInst(NewAdd, I.getType()); } } Modified: llvm/trunk/test/Transforms/InstCombine/add-shrink.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/add-shrink.ll?rev=85164&r1=85163&r2=85164&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/add-shrink.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/add-shrink.ll Mon Oct 26 17:14:22 2009 @@ -1,4 +1,4 @@ -; RUN: opt < %s -instcombine -S | grep {add i32} +; RUN: opt < %s -instcombine -S | grep {add nsw i32} ; RUN: opt < %s -instcombine -S | grep sext | count 1 ; Should only have one sext and the add should be i32 instead of i64. Modified: llvm/trunk/test/Transforms/InstCombine/add-sitofp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/add-sitofp.ll?rev=85164&r1=85163&r2=85164&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/add-sitofp.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/add-sitofp.ll Mon Oct 26 17:14:22 2009 @@ -1,4 +1,4 @@ -; RUN: opt < %s -instcombine -S | grep {add i32} +; RUN: opt < %s -instcombine -S | grep {add nsw i32} define double @x(i32 %a, i32 %b) nounwind { %m = lshr i32 %a, 24 From gohman at apple.com Mon Oct 26 17:18:58 2009 From: gohman at apple.com (Dan Gohman) Date: Mon, 26 Oct 2009 22:18:58 -0000 Subject: [llvm-commits] [llvm] r85165 - /llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp Message-ID: <200910262218.n9QMIxVo007520@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 26 17:18:58 2009 New Revision: 85165 URL: http://llvm.org/viewvc/llvm-project?rev=85165&view=rev Log: Simplify this code. LoopDeletion doesn't need to explicit check that the loop exiting block dominates the latch block; if ScalarEvolution can prove that the trip-count is finite, that's sufficient. Modified: llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp?rev=85165&r1=85164&r2=85165&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp Mon Oct 26 17:18:58 2009 @@ -33,8 +33,6 @@ // Possibly eliminate loop L if it is dead. bool runOnLoop(Loop* L, LPPassManager& LPM); - bool SingleDominatingExit(Loop* L, - SmallVector& exitingBlocks); bool IsLoopDead(Loop* L, SmallVector& exitingBlocks, SmallVector& exitBlocks, bool &Changed, BasicBlock *Preheader); @@ -63,25 +61,6 @@ return new LoopDeletion(); } -/// SingleDominatingExit - Checks that there is only a single blocks that -/// branches out of the loop, and that it also g the latch block. Loops -/// with multiple or non-latch-dominating exiting blocks could be dead, but we'd -/// have to do more extensive analysis to make sure, for instance, that the -/// control flow logic involved was or could be made loop-invariant. -bool LoopDeletion::SingleDominatingExit(Loop* L, - SmallVector& exitingBlocks) { - - if (exitingBlocks.size() != 1) - return false; - - BasicBlock* latch = L->getLoopLatch(); - if (!latch) - return false; - - DominatorTree& DT = getAnalysis(); - return DT.dominates(exitingBlocks[0], latch); -} - /// IsLoopDead - Determined if a loop is dead. This assumes that we've already /// checked for unique exit and exiting blocks, and that the code is in LCSSA /// form. @@ -154,9 +133,8 @@ if (exitBlocks.size() != 1) return false; - // Loops with multiple exits or exits that don't dominate the latch - // are too complicated to handle correctly. - if (!SingleDominatingExit(L, exitingBlocks)) + // Loops with multiple exits are too complicated to handle correctly. + if (exitingBlocks.size() != 1) return false; // Finally, we have to check that the loop really is dead. From david_goodwin at apple.com Mon Oct 26 17:31:19 2009 From: david_goodwin at apple.com (David Goodwin) Date: Mon, 26 Oct 2009 22:31:19 -0000 Subject: [llvm-commits] [llvm] r85166 - in /llvm/trunk: include/llvm/CodeGen/AntiDepBreaker.h lib/CodeGen/AggressiveAntiDepBreaker.cpp lib/CodeGen/AggressiveAntiDepBreaker.h lib/CodeGen/CriticalAntiDepBreaker.h lib/CodeGen/PostRASchedulerList.cpp Message-ID: <200910262231.n9QMVJwG008113@zion.cs.uiuc.edu> Author: david_goodwin Date: Mon Oct 26 17:31:16 2009 New Revision: 85166 URL: http://llvm.org/viewvc/llvm-project?rev=85166&view=rev Log: Allow the aggressive anti-dep breaker to process the same region multiple times. This is necessary because new anti-dependencies are exposed when "current" ones are broken. Modified: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Modified: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h?rev=85166&r1=85165&r2=85166&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h (original) +++ llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Mon Oct 26 17:31:16 2009 @@ -31,6 +31,10 @@ public: virtual ~AntiDepBreaker(); + /// GetMaxTrials - Return the maximum number of anti-dependence + /// breaking attempts that will be made for a block. + virtual unsigned GetMaxTrials() =0; + /// Start - Initialize anti-dep breaking for a new basic block. virtual void StartBlock(MachineBasicBlock *BB) =0; Modified: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp?rev=85166&r1=85165&r2=85166&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp (original) +++ llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.cpp Mon Oct 26 17:31:16 2009 @@ -22,36 +22,109 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" - using namespace llvm; +static cl::opt +AntiDepTrials("agg-antidep-trials", + cl::desc("Maximum number of anti-dependency breaking passes"), + cl::init(2), cl::Hidden); + +AggressiveAntiDepState::AggressiveAntiDepState(MachineBasicBlock *BB) : + GroupNodes(TargetRegisterInfo::FirstVirtualRegister, 0) { + // Initialize all registers to be in their own group. Initially we + // assign the register to the same-indexed GroupNode. + for (unsigned i = 0; i < TargetRegisterInfo::FirstVirtualRegister; ++i) + GroupNodeIndices[i] = i; + + // Initialize the indices to indicate that no registers are live. + std::fill(KillIndices, array_endof(KillIndices), ~0u); + std::fill(DefIndices, array_endof(DefIndices), BB->size()); +} + +unsigned AggressiveAntiDepState::GetGroup(unsigned Reg) +{ + unsigned Node = GroupNodeIndices[Reg]; + while (GroupNodes[Node] != Node) + Node = GroupNodes[Node]; + + return Node; +} + +void AggressiveAntiDepState::GetGroupRegs(unsigned Group, std::vector &Regs) +{ + for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) { + if (GetGroup(Reg) == Group) + Regs.push_back(Reg); + } +} + +unsigned AggressiveAntiDepState::UnionGroups(unsigned Reg1, unsigned Reg2) +{ + assert(GroupNodes[0] == 0 && "GroupNode 0 not parent!"); + assert(GroupNodeIndices[0] == 0 && "Reg 0 not in Group 0!"); + + // find group for each register + unsigned Group1 = GetGroup(Reg1); + unsigned Group2 = GetGroup(Reg2); + + // if either group is 0, then that must become the parent + unsigned Parent = (Group1 == 0) ? Group1 : Group2; + unsigned Other = (Parent == Group1) ? Group2 : Group1; + GroupNodes.at(Other) = Parent; + return Parent; +} + +unsigned AggressiveAntiDepState::LeaveGroup(unsigned Reg) +{ + // Create a new GroupNode for Reg. Reg's existing GroupNode must + // stay as is because there could be other GroupNodes referring to + // it. + unsigned idx = GroupNodes.size(); + GroupNodes.push_back(idx); + GroupNodeIndices[Reg] = idx; + return idx; +} + +bool AggressiveAntiDepState::IsLive(unsigned Reg) +{ + // KillIndex must be defined and DefIndex not defined for a register + // to be live. + return((KillIndices[Reg] != ~0u) && (DefIndices[Reg] == ~0u)); +} + + + AggressiveAntiDepBreaker:: AggressiveAntiDepBreaker(MachineFunction& MFi) : AntiDepBreaker(), MF(MFi), MRI(MF.getRegInfo()), TRI(MF.getTarget().getRegisterInfo()), AllocatableSet(TRI->getAllocatableSet(MF)), - GroupNodes(TargetRegisterInfo::FirstVirtualRegister, 0) -{ + State(NULL), SavedState(NULL) { } AggressiveAntiDepBreaker::~AggressiveAntiDepBreaker() { + delete State; + delete SavedState; } -void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { - // Initialize all registers to be in their own group. Initially we - // assign the register to the same-indexed GroupNode. - for (unsigned i = 0; i < TargetRegisterInfo::FirstVirtualRegister; ++i) - GroupNodeIndices[i] = i; +unsigned AggressiveAntiDepBreaker::GetMaxTrials() { + if (AntiDepTrials <= 0) + return 1; + return AntiDepTrials; +} - // Initialize the indices to indicate that no registers are live. - std::fill(KillIndices, array_endof(KillIndices), ~0u); - std::fill(DefIndices, array_endof(DefIndices), BB->size()); +void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { + assert(State == NULL); + State = new AggressiveAntiDepState(BB); bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn()); + unsigned *KillIndices = State->GetKillIndices(); + unsigned *DefIndices = State->GetDefIndices(); // Determine the live-out physregs for this block. if (IsReturnBlock) { @@ -59,13 +132,13 @@ for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), E = MRI.liveout_end(); I != E; ++I) { unsigned Reg = *I; - UnionGroups(Reg, 0); + State->UnionGroups(Reg, 0); KillIndices[Reg] = BB->size(); DefIndices[Reg] = ~0u; // Repeat, for all aliases. for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { unsigned AliasReg = *Alias; - UnionGroups(AliasReg, 0); + State->UnionGroups(AliasReg, 0); KillIndices[AliasReg] = BB->size(); DefIndices[AliasReg] = ~0u; } @@ -77,13 +150,13 @@ for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), E = (*SI)->livein_end(); I != E; ++I) { unsigned Reg = *I; - UnionGroups(Reg, 0); + State->UnionGroups(Reg, 0); KillIndices[Reg] = BB->size(); DefIndices[Reg] = ~0u; // Repeat, for all aliases. for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { unsigned AliasReg = *Alias; - UnionGroups(AliasReg, 0); + State->UnionGroups(AliasReg, 0); KillIndices[AliasReg] = BB->size(); DefIndices[AliasReg] = ~0u; } @@ -98,13 +171,13 @@ for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { unsigned Reg = *I; if (!IsReturnBlock && !Pristine.test(Reg)) continue; - UnionGroups(Reg, 0); + State->UnionGroups(Reg, 0); KillIndices[Reg] = BB->size(); DefIndices[Reg] = ~0u; // Repeat, for all aliases. for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { unsigned AliasReg = *Alias; - UnionGroups(AliasReg, 0); + State->UnionGroups(AliasReg, 0); KillIndices[AliasReg] = BB->size(); DefIndices[AliasReg] = ~0u; } @@ -112,7 +185,10 @@ } void AggressiveAntiDepBreaker::FinishBlock() { - RegRefs.clear(); + delete State; + State = NULL; + delete SavedState; + SavedState = NULL; } void AggressiveAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count, @@ -122,6 +198,7 @@ DEBUG(errs() << "Observe: "); DEBUG(MI->dump()); + unsigned *DefIndices = State->GetDefIndices(); for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) { // If Reg is current live, then mark that it can't be renamed as // we don't know the extent of its live-range anymore (now that it @@ -129,11 +206,11 @@ // previous schedule region, then set its def index to the most // conservative location (i.e. the beginning of the previous // schedule region). - if (IsLive(Reg)) { - DEBUG(if (GetGroup(Reg) != 0) + if (State->IsLive(Reg)) { + DEBUG(if (State->GetGroup(Reg) != 0) errs() << " " << TRI->getName(Reg) << "=g" << - GetGroup(Reg) << "->g0(region live-out)"); - UnionGroups(Reg, 0); + State->GetGroup(Reg) << "->g0(region live-out)"); + State->UnionGroups(Reg, 0); } else if ((DefIndices[Reg] < InsertPosIndex) && (DefIndices[Reg] >= Count)) { DefIndices[Reg] = Count; } @@ -143,57 +220,10 @@ GetPassthruRegs(MI, PassthruRegs); PrescanInstruction(MI, Count, PassthruRegs); ScanInstruction(MI, Count); -} - -unsigned AggressiveAntiDepBreaker::GetGroup(unsigned Reg) -{ - unsigned Node = GroupNodeIndices[Reg]; - while (GroupNodes[Node] != Node) - Node = GroupNodes[Node]; - return Node; -} - -void AggressiveAntiDepBreaker::GetGroupRegs(unsigned Group, std::vector &Regs) -{ - for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) { - if (GetGroup(Reg) == Group) - Regs.push_back(Reg); - } -} - -unsigned AggressiveAntiDepBreaker::UnionGroups(unsigned Reg1, unsigned Reg2) -{ - assert(GroupNodes[0] == 0 && "GroupNode 0 not parent!"); - assert(GroupNodeIndices[0] == 0 && "Reg 0 not in Group 0!"); - - // find group for each register - unsigned Group1 = GetGroup(Reg1); - unsigned Group2 = GetGroup(Reg2); - - // if either group is 0, then that must become the parent - unsigned Parent = (Group1 == 0) ? Group1 : Group2; - unsigned Other = (Parent == Group1) ? Group2 : Group1; - GroupNodes.at(Other) = Parent; - return Parent; -} - -unsigned AggressiveAntiDepBreaker::LeaveGroup(unsigned Reg) -{ - // Create a new GroupNode for Reg. Reg's existing GroupNode must - // stay as is because there could be other GroupNodes referring to - // it. - unsigned idx = GroupNodes.size(); - GroupNodes.push_back(idx); - GroupNodeIndices[Reg] = idx; - return idx; -} - -bool AggressiveAntiDepBreaker::IsLive(unsigned Reg) -{ - // KillIndex must be defined and DefIndex not defined for a register - // to be live. - return((KillIndices[Reg] != ~0u) && (DefIndices[Reg] == ~0u)); + // We're starting a new schedule region so forget any saved state. + delete SavedState; + SavedState = NULL; } bool AggressiveAntiDepBreaker::IsImplicitDefUse(MachineInstr *MI, @@ -249,6 +279,10 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Count, std::set& PassthruRegs) { + unsigned *DefIndices = State->GetDefIndices(); + std::multimap& + RegRefs = State->GetRegRefs(); + // Scan the register defs for this instruction and update // live-ranges, groups and RegRefs. for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { @@ -275,23 +309,23 @@ unsigned Reg = MO.getReg(); if (Reg == 0) continue; - DEBUG(errs() << " " << TRI->getName(Reg) << "=g" << GetGroup(Reg)); + DEBUG(errs() << " " << TRI->getName(Reg) << "=g" << State->GetGroup(Reg)); // If MI's defs have special allocation requirement, don't allow // any def registers to be changed. Also assume all registers // defined in a call must not be changed (ABI). if (MI->getDesc().isCall() || MI->getDesc().hasExtraDefRegAllocReq()) { - DEBUG(if (GetGroup(Reg) != 0) errs() << "->g0(alloc-req)"); - UnionGroups(Reg, 0); + DEBUG(if (State->GetGroup(Reg) != 0) errs() << "->g0(alloc-req)"); + State->UnionGroups(Reg, 0); } // Any aliased that are live at this point are completely or // partially defined here, so group those subregisters with Reg. for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { unsigned AliasReg = *Alias; - if (IsLive(AliasReg)) { - UnionGroups(Reg, AliasReg); - DEBUG(errs() << "->g" << GetGroup(Reg) << "(via " << + if (State->IsLive(AliasReg)) { + State->UnionGroups(Reg, AliasReg); + DEBUG(errs() << "->g" << State->GetGroup(Reg) << "(via " << TRI->getName(AliasReg) << ")"); } } @@ -300,7 +334,7 @@ const TargetRegisterClass *RC = NULL; if (i < MI->getDesc().getNumOperands()) RC = MI->getDesc().OpInfo[i].getRegClass(TRI); - RegisterReference RR = { &MO, RC }; + AggressiveAntiDepState::RegisterReference RR = { &MO, RC }; RegRefs.insert(std::make_pair(Reg, RR)); } @@ -310,6 +344,10 @@ void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI, unsigned Count) { DEBUG(errs() << "\tUse Groups:"); + unsigned *KillIndices = State->GetKillIndices(); + unsigned *DefIndices = State->GetDefIndices(); + std::multimap& + RegRefs = State->GetRegRefs(); // Scan the register uses for this instruction and update // live-ranges, groups and RegRefs. @@ -319,29 +357,30 @@ unsigned Reg = MO.getReg(); if (Reg == 0) continue; - DEBUG(errs() << " " << TRI->getName(Reg) << "=g" << GetGroup(Reg)); + DEBUG(errs() << " " << TRI->getName(Reg) << "=g" << + State->GetGroup(Reg)); // It wasn't previously live but now it is, this is a kill. Forget // the previous live-range information and start a new live-range // for the register. - if (!IsLive(Reg)) { + if (!State->IsLive(Reg)) { KillIndices[Reg] = Count; DefIndices[Reg] = ~0u; RegRefs.erase(Reg); - LeaveGroup(Reg); - DEBUG(errs() << "->g" << GetGroup(Reg) << "(last-use)"); + State->LeaveGroup(Reg); + DEBUG(errs() << "->g" << State->GetGroup(Reg) << "(last-use)"); } // Repeat, for subregisters. for (const unsigned *Subreg = TRI->getSubRegisters(Reg); *Subreg; ++Subreg) { unsigned SubregReg = *Subreg; - if (!IsLive(SubregReg)) { + if (!State->IsLive(SubregReg)) { KillIndices[SubregReg] = Count; DefIndices[SubregReg] = ~0u; RegRefs.erase(SubregReg); - LeaveGroup(SubregReg); + State->LeaveGroup(SubregReg); DEBUG(errs() << " " << TRI->getName(SubregReg) << "->g" << - GetGroup(SubregReg) << "(last-use)"); + State->GetGroup(SubregReg) << "(last-use)"); } } @@ -349,15 +388,15 @@ // any use registers to be changed. Also assume all registers // used in a call must not be changed (ABI). if (MI->getDesc().isCall() || MI->getDesc().hasExtraSrcRegAllocReq()) { - DEBUG(if (GetGroup(Reg) != 0) errs() << "->g0(alloc-req)"); - UnionGroups(Reg, 0); + DEBUG(if (State->GetGroup(Reg) != 0) errs() << "->g0(alloc-req)"); + State->UnionGroups(Reg, 0); } // Note register reference... const TargetRegisterClass *RC = NULL; if (i < MI->getDesc().getNumOperands()) RC = MI->getDesc().OpInfo[i].getRegClass(TRI); - RegisterReference RR = { &MO, RC }; + AggressiveAntiDepState::RegisterReference RR = { &MO, RC }; RegRefs.insert(std::make_pair(Reg, RR)); } @@ -377,14 +416,14 @@ if (FirstReg != 0) { DEBUG(errs() << "=" << TRI->getName(Reg)); - UnionGroups(FirstReg, Reg); + State->UnionGroups(FirstReg, Reg); } else { DEBUG(errs() << " " << TRI->getName(Reg)); FirstReg = Reg; } } - DEBUG(errs() << "->g" << GetGroup(FirstReg) << '\n'); + DEBUG(errs() << "->g" << State->GetGroup(FirstReg) << '\n'); } } @@ -395,10 +434,12 @@ // Check all references that need rewriting for Reg. For each, use // the corresponding register class to narrow the set of registers // that are appropriate for renaming. - std::pair::iterator, - std::multimap::iterator> - Range = RegRefs.equal_range(Reg); - for (std::multimap::iterator + std::pair::iterator, + std::multimap::iterator> + Range = State->GetRegRefs().equal_range(Reg); + for (std::multimap::iterator Q = Range.first, QE = Range.second; Q != QE; ++Q) { const TargetRegisterClass *RC = Q->second.RC; if (RC == NULL) continue; @@ -420,11 +461,16 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters( unsigned AntiDepGroupIndex, std::map &RenameMap) { + unsigned *KillIndices = State->GetKillIndices(); + unsigned *DefIndices = State->GetDefIndices(); + std::multimap& + RegRefs = State->GetRegRefs(); + // Collect all registers in the same group as AntiDepReg. These all // need to be renamed together if we are to break the // anti-dependence. std::vector Regs; - GetGroupRegs(AntiDepGroupIndex, Regs); + State->GetGroupRegs(AntiDepGroupIndex, Regs); assert(Regs.size() > 0 && "Empty register group!"); if (Regs.size() == 0) return false; @@ -484,7 +530,7 @@ // If Reg is dead and Reg's most recent def is not before // SuperRegs's kill, it's safe to replace SuperReg with // Reg. We must also check all subregisters of Reg. - if (IsLive(Reg) || (KillIndices[SuperReg] > DefIndices[Reg])) { + if (State->IsLive(Reg) || (KillIndices[SuperReg] > DefIndices[Reg])) { DEBUG(errs() << "(live)"); continue; } else { @@ -492,7 +538,7 @@ for (const unsigned *Subreg = TRI->getSubRegisters(Reg); *Subreg; ++Subreg) { unsigned SubregReg = *Subreg; - if (IsLive(SubregReg) || (KillIndices[SuperReg] > DefIndices[SubregReg])) { + if (State->IsLive(SubregReg) || (KillIndices[SuperReg] > DefIndices[SubregReg])) { DEBUG(errs() << "(subreg " << TRI->getName(SubregReg) << " live)"); found = true; break; @@ -518,13 +564,29 @@ /// BreakAntiDependencies - Identifiy anti-dependencies within the /// ScheduleDAG and break them by renaming registers. /// -unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(std::vector& SUnits, - MachineBasicBlock::iterator& Begin, - MachineBasicBlock::iterator& End, - unsigned InsertPosIndex) { +unsigned AggressiveAntiDepBreaker::BreakAntiDependencies( + std::vector& SUnits, + MachineBasicBlock::iterator& Begin, + MachineBasicBlock::iterator& End, + unsigned InsertPosIndex) { + unsigned *KillIndices = State->GetKillIndices(); + unsigned *DefIndices = State->GetDefIndices(); + std::multimap& + RegRefs = State->GetRegRefs(); + // The code below assumes that there is at least one instruction, // so just duck out immediately if the block is empty. if (SUnits.empty()) return false; + + // Manage saved state to enable multiple passes... + if (AntiDepTrials > 1) { + if (SavedState == NULL) { + SavedState = new AggressiveAntiDepState(*State); + } else { + delete State; + State = new AggressiveAntiDepState(*SavedState); + } + } // ...need a map from MI to SUnit. std::map MISUnitMap; @@ -539,7 +601,7 @@ { DEBUG(errs() << "Available regs:"); for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { - if (!IsLive(Reg)) + if (!State->IsLive(Reg)) DEBUG(errs() << " " << TRI->getName(Reg)); } DEBUG(errs() << '\n'); @@ -623,7 +685,7 @@ if (AntiDepReg == 0) continue; // Determine AntiDepReg's register group. - const unsigned GroupIndex = GetGroup(AntiDepReg); + const unsigned GroupIndex = State->GetGroup(AntiDepReg); if (GroupIndex == 0) { DEBUG(errs() << " (zero group)\n"); continue; @@ -649,10 +711,12 @@ // Update the references to the old register CurrReg to // refer to the new register NewReg. - std::pair::iterator, - std::multimap::iterator> + std::pair::iterator, + std::multimap::iterator> Range = RegRefs.equal_range(CurrReg); - for (std::multimap::iterator + for (std::multimap::iterator Q = Range.first, QE = Range.second; Q != QE; ++Q) { Q->second.Operand->setReg(NewReg); } @@ -660,12 +724,12 @@ // We just went back in time and modified history; the // liveness information for CurrReg is now inconsistent. Set // the state as if it were dead. - UnionGroups(NewReg, 0); + State->UnionGroups(NewReg, 0); RegRefs.erase(NewReg); DefIndices[NewReg] = DefIndices[CurrReg]; KillIndices[NewReg] = KillIndices[CurrReg]; - UnionGroups(CurrReg, 0); + State->UnionGroups(CurrReg, 0); RegRefs.erase(CurrReg); DefIndices[CurrReg] = KillIndices[CurrReg]; KillIndices[CurrReg] = ~0u; Modified: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h?rev=85166&r1=85165&r2=85166&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h (original) +++ llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h Mon Oct 26 17:31:16 2009 @@ -28,11 +28,12 @@ #include "llvm/ADT/SmallSet.h" namespace llvm { - class AggressiveAntiDepBreaker : public AntiDepBreaker { - MachineFunction& MF; - MachineRegisterInfo &MRI; - const TargetRegisterInfo *TRI; - + /// Class AggressiveAntiDepState + /// Contains all the state necessary for anti-dep breaking. We place + /// into a separate class so be can conveniently save/restore it to + /// enable multi-pass anti-dep breaking. + class AggressiveAntiDepState { + public: /// RegisterReference - Information about a register reference /// within a liverange typedef struct { @@ -42,59 +43,43 @@ const TargetRegisterClass *RC; } RegisterReference; - /// AllocatableSet - The set of allocatable registers. - /// We'll be ignoring anti-dependencies on non-allocatable registers, - /// because they may not be safe to break. - const BitVector AllocatableSet; - + private: /// GroupNodes - Implements a disjoint-union data structure to /// form register groups. A node is represented by an index into /// the vector. A node can "point to" itself to indicate that it /// is the parent of a group, or point to another node to indicate /// that it is a member of the same group as that node. std::vector GroupNodes; - + /// GroupNodeIndices - For each register, the index of the GroupNode /// currently representing the group that the register belongs to. /// Register 0 is always represented by the 0 group, a group /// composed of registers that are not eligible for anti-aliasing. unsigned GroupNodeIndices[TargetRegisterInfo::FirstVirtualRegister]; - - /// RegRegs - Map registers to all their references within a live range. + + /// RegRefs - Map registers to all their references within a live range. std::multimap RegRefs; - + /// KillIndices - The index of the most recent kill (proceding bottom-up), /// or ~0u if the register is not live. unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; - + /// DefIndices - The index of the most recent complete def (proceding bottom /// up), or ~0u if the register is live. unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; public: - AggressiveAntiDepBreaker(MachineFunction& MFi); - ~AggressiveAntiDepBreaker(); + AggressiveAntiDepState(MachineBasicBlock *BB); - /// Start - Initialize anti-dep breaking for a new basic block. - void StartBlock(MachineBasicBlock *BB); - - /// BreakAntiDependencies - Identifiy anti-dependencies along the critical path - /// of the ScheduleDAG and break them by renaming registers. - /// - unsigned BreakAntiDependencies(std::vector& SUnits, - MachineBasicBlock::iterator& Begin, - MachineBasicBlock::iterator& End, - unsigned InsertPosIndex); + /// GetKillIndices - Return the kill indices. + unsigned *GetKillIndices() { return KillIndices; } - /// Observe - Update liveness information to account for the current - /// instruction, which will not be scheduled. - /// - void Observe(MachineInstr *MI, unsigned Count, unsigned InsertPosIndex); + /// GetDefIndices - Return the define indices. + unsigned *GetDefIndices() { return DefIndices; } - /// Finish - Finish anti-dep breaking for a basic block. - void FinishBlock(); + /// GetRegRefs - Return the RegRefs map. + std::multimap& GetRegRefs() { return RegRefs; } - private: // GetGroup - Get the group for a register. The returned value is // the index of the GroupNode representing the group. unsigned GetGroup(unsigned Reg); @@ -115,7 +100,57 @@ /// IsLive - Return true if Reg is live bool IsLive(unsigned Reg); + }; + + + /// Class AggressiveAntiDepBreaker + class AggressiveAntiDepBreaker : public AntiDepBreaker { + MachineFunction& MF; + MachineRegisterInfo &MRI; + const TargetRegisterInfo *TRI; + + /// AllocatableSet - The set of allocatable registers. + /// We'll be ignoring anti-dependencies on non-allocatable registers, + /// because they may not be safe to break. + const BitVector AllocatableSet; + + /// State - The state used to identify and rename anti-dependence + /// registers. + AggressiveAntiDepState *State; + + /// SavedState - The state for the start of an anti-dep + /// region. Used to restore the state at the beginning of each + /// pass + AggressiveAntiDepState *SavedState; + + public: + AggressiveAntiDepBreaker(MachineFunction& MFi); + ~AggressiveAntiDepBreaker(); + /// GetMaxTrials - As anti-dependencies are broken, additional + /// dependencies may be exposed, so multiple passes are required. + unsigned GetMaxTrials(); + + /// Start - Initialize anti-dep breaking for a new basic block. + void StartBlock(MachineBasicBlock *BB); + + /// BreakAntiDependencies - Identifiy anti-dependencies along the critical path + /// of the ScheduleDAG and break them by renaming registers. + /// + unsigned BreakAntiDependencies(std::vector& SUnits, + MachineBasicBlock::iterator& Begin, + MachineBasicBlock::iterator& End, + unsigned InsertPosIndex); + + /// Observe - Update liveness information to account for the current + /// instruction, which will not be scheduled. + /// + void Observe(MachineInstr *MI, unsigned Count, unsigned InsertPosIndex); + + /// Finish - Finish anti-dep breaking for a basic block. + void FinishBlock(); + + private: /// IsImplicitDefUse - Return true if MO represents a register /// that is both implicitly used and defined in MI bool IsImplicitDefUse(MachineInstr *MI, MachineOperand& MO); Modified: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h?rev=85166&r1=85165&r2=85166&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h (original) +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h Mon Oct 26 17:31:16 2009 @@ -64,6 +64,10 @@ CriticalAntiDepBreaker(MachineFunction& MFi); ~CriticalAntiDepBreaker(); + /// GetMaxTrials - Critical path anti-dependence breaking requires + /// only a single pass + unsigned GetMaxTrials() { return 1; } + /// Start - Initialize anti-dep breaking for a new basic block. void StartBlock(MachineBasicBlock *BB); Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=85166&r1=85165&r2=85166&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Mon Oct 26 17:31:16 2009 @@ -40,6 +40,7 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetSubtarget.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -315,16 +316,20 @@ /// Schedule - Schedule the instruction range using list scheduling. /// void SchedulePostRATDList::Schedule() { - DEBUG(errs() << "********** List Scheduling **********\n"); - // Build the scheduling graph. BuildSchedGraph(AA); if (AntiDepBreak != NULL) { - unsigned Broken = - AntiDepBreak->BreakAntiDependencies(SUnits, Begin, InsertPos, - InsertPosIndex); - if (Broken > 0) { + for (unsigned i = 0, Trials = AntiDepBreak->GetMaxTrials(); + i < Trials; ++i) { + DEBUG(errs() << "********** Break Anti-Deps, Trial " << + i << " **********\n"); + unsigned Broken = + AntiDepBreak->BreakAntiDependencies(SUnits, Begin, InsertPos, + InsertPosIndex); + if (Broken == 0) + break; + // We made changes. Update the dependency graph. // Theoretically we could update the graph in place: // When a live range is changed to use a different register, remove @@ -340,6 +345,8 @@ } } + DEBUG(errs() << "********** List Scheduling **********\n"); + DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) SUnits[su].dumpAll(this)); From bob.wilson at apple.com Mon Oct 26 17:34:44 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 26 Oct 2009 22:34:44 -0000 Subject: [llvm-commits] [llvm] r85167 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Message-ID: <200910262234.n9QMYjSu008411@zion.cs.uiuc.edu> Author: bwilson Date: Mon Oct 26 17:34:44 2009 New Revision: 85167 URL: http://llvm.org/viewvc/llvm-project?rev=85167&view=rev Log: Add more ARM instruction encodings for 's' bit set and "rs" register encoding bits. Patch by Johnny Chen. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=85167&r1=85166&r2=85167&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Mon Oct 26 17:34:44 2009 @@ -398,6 +398,7 @@ def ri : AI1 { + let Inst{20} = 1; let Inst{25} = 1; } def rr : AI1 { let isCommutable = Commutable; let Inst{4} = 0; + let Inst{20} = 1; let Inst{25} = 0; } def rs : AI1 { let Inst{4} = 1; let Inst{7} = 0; + let Inst{20} = 1; let Inst{25} = 0; } } @@ -512,6 +515,7 @@ [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>, Requires<[IsARM, CarryDefIsUsed]> { let Defs = [CPSR]; + let Inst{20} = 1; let Inst{25} = 1; } def Srr : AXI1 { let Defs = [CPSR]; let Inst{4} = 0; + let Inst{20} = 1; let Inst{25} = 0; } def Srs : AXI1; + [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> { + let Inst{4} = 1; + let Inst{7} = 0; + let Inst{25} = 0; +} // RSB with 's' bit set. let Defs = [CPSR] in { def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iALUi, "rsb", "s $dst, $a, $b", [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> { + let Inst{20} = 1; let Inst{25} = 1; } def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iALUsr, "rsb", "s $dst, $a, $b", - [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]>; + [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> { + let Inst{4} = 1; + let Inst{7} = 0; + let Inst{20} = 1; + let Inst{25} = 0; +} } let Uses = [CPSR] in { From bob.wilson at apple.com Mon Oct 26 17:34:22 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 26 Oct 2009 15:34:22 -0700 Subject: [llvm-commits] Added more 's' bit set encoding and "rs" register encoding bits In-Reply-To: <31E018AE-6E13-4514-AF87-D875A8A09C9B@apple.com> References: <31E018AE-6E13-4514-AF87-D875A8A09C9B@apple.com> Message-ID: <7FF0BB59-BFFE-41EC-B784-4A20CCBCD46F@apple.com> As far as I can tell, the lack of predication for ADC/SBC is a temporary limitation in llvm. Evan, can you confirm? I've applied the rest of the patch for now, without the change to force the condition fields. That should be done as a separate patch anyway, since it is unrelated to this change. On Oct 26, 2009, at 11:48 AM, Johnny Chen wrote: > Hi, > > For multiclass AI1_adde_sube_irs definition, I also added: > > let Inst{31-28} = 0b1110; > > for the Sri, Srr, and Srs variants. From the AsmString field of the > respective record definitions > (take SBCSrs, for example): > > string AsmString = "sbcs $dst, $a, $b"; > > it looks like this is the right thing to do. Please remove the > three "set condition code to ALways" > lines from the submitted patch if this is not correct. > > Thanks. > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From bob.wilson at apple.com Mon Oct 26 17:42:13 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 26 Oct 2009 22:42:13 -0000 Subject: [llvm-commits] [llvm] r85169 - /llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Message-ID: <200910262242.n9QMgDgT008840@zion.cs.uiuc.edu> Author: bwilson Date: Mon Oct 26 17:42:13 2009 New Revision: 85169 URL: http://llvm.org/viewvc/llvm-project?rev=85169&view=rev Log: Fix ARM encoding typo: Opcod3 is not passed to ASuI parent class. Patch by Johnny Chen. Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=85169&r1=85168&r2=85169&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Mon Oct 26 17:42:13 2009 @@ -1125,8 +1125,8 @@ // Single precision unary, if no NEON // Same as ASuI except not available if NEON is enabled class ASuIn opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops, - InstrItinClass itin, string opc, string asm, list pattern> - : ASuI { + InstrItinClass itin, string opc, string asm, list pattern> + : ASuI { list Predicates = [HasVFP2,DontUseNEONForFP]; } From bob.wilson at apple.com Mon Oct 26 17:39:42 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 26 Oct 2009 15:39:42 -0700 Subject: [llvm-commits] Typo in ARMInstrFormats.td for ASuIn? In-Reply-To: <5E360501-8B49-454C-A0CC-0EE2FE75BB82@apple.com> References: <5E360501-8B49-454C-A0CC-0EE2FE75BB82@apple.com> Message-ID: <50747BC5-41FD-409F-8A49-9561AB959419@apple.com> Applied. Thanks. On Oct 26, 2009, at 2:39 PM, Johnny Chen wrote: > Hi, > > Opcod3 is not passed to ASuI parent class. > > < > ARMInstrFormats.td.patch > >_______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From eocallaghan at auroraux.org Mon Oct 26 17:52:04 2009 From: eocallaghan at auroraux.org (Edward O'Callaghan) Date: Mon, 26 Oct 2009 22:52:04 -0000 Subject: [llvm-commits] [llvm] r85171 - in /llvm/trunk/test/Transforms: ConstProp/float-to-ptr-cast.ll InstCombine/preserve-sminmax.ll LICM/2008-07-22-LoadGlobalConstant.ll Message-ID: <200910262252.n9QMq4Zq009440@zion.cs.uiuc.edu> Author: evocallaghan Date: Mon Oct 26 17:52:03 2009 New Revision: 85171 URL: http://llvm.org/viewvc/llvm-project?rev=85171&view=rev Log: Convert a few tests to FileCheck for PR5307. Modified: llvm/trunk/test/Transforms/ConstProp/float-to-ptr-cast.ll llvm/trunk/test/Transforms/InstCombine/preserve-sminmax.ll llvm/trunk/test/Transforms/LICM/2008-07-22-LoadGlobalConstant.ll Modified: llvm/trunk/test/Transforms/ConstProp/float-to-ptr-cast.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ConstProp/float-to-ptr-cast.ll?rev=85171&r1=85170&r2=85171&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ConstProp/float-to-ptr-cast.ll (original) +++ llvm/trunk/test/Transforms/ConstProp/float-to-ptr-cast.ll Mon Oct 26 17:52:03 2009 @@ -1,12 +1,15 @@ -; RUN: opt < %s -constprop -S | \ -; RUN: grep -F {ret i32* null} | count 2 +; RUN: opt < %s -constprop -S | FileCheck %s define i32* @test1() { %X = inttoptr i64 0 to i32* ; [#uses=1] ret i32* %X } +; CHECK: ret i32* null + define i32* @test2() { ret i32* null } +; CHECK: ret i32* null + Modified: llvm/trunk/test/Transforms/InstCombine/preserve-sminmax.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/preserve-sminmax.ll?rev=85171&r1=85170&r2=85171&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/preserve-sminmax.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/preserve-sminmax.ll Mon Oct 26 17:52:03 2009 @@ -1,4 +1,4 @@ -; RUN: opt < %s -instcombine -S | grep { i32 \[%\]sd, \[\[:alnum:\]\]* \\?1\\>} | count 4 +; RUN: opt < %s -instcombine -S | FileCheck %s ; Instcombine normally would fold the sdiv into the comparison, ; making "icmp slt i32 %h, 2", but in this case the sdiv has @@ -13,6 +13,11 @@ ret i32 %r } +; CHECK: %sd = sdiv i32 %h, 2 +; CHECK: %t = icmp slt i32 %sd, 1 +; CHECK: %r = select i1 %t, i32 %sd, i32 1 +; CHECK: ret i32 %r + define i32 @bar(i32 %h) { %sd = sdiv i32 %h, 2 %t = icmp sgt i32 %sd, 1 @@ -20,3 +25,8 @@ ret i32 %r } +; CHECK: %sd = sdiv i32 %h, 2 +; CHECK: %t = icmp sgt i32 %sd, 1 +; CHECK: %r = select i1 %t, i32 %sd, i32 1 +; CHECK: ret i32 %r + Modified: llvm/trunk/test/Transforms/LICM/2008-07-22-LoadGlobalConstant.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/2008-07-22-LoadGlobalConstant.ll?rev=85171&r1=85170&r2=85171&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LICM/2008-07-22-LoadGlobalConstant.ll (original) +++ llvm/trunk/test/Transforms/LICM/2008-07-22-LoadGlobalConstant.ll Mon Oct 26 17:52:03 2009 @@ -1,15 +1,23 @@ -; RUN: opt < %s -licm -enable-licm-constant-variables -S | grep -A 1 entry | grep load.*@a +; RUN: opt < %s -licm -enable-licm-constant-variables -S | FileCheck %s + @a = external constant float* define void @test(i32 %count) { entry: br label %forcond +; CHECK: %tmp3 = load float** @a +; CHECK: br label %forcond + forcond: %i.0 = phi i32 [ 0, %entry ], [ %inc, %forbody ] %cmp = icmp ult i32 %i.0, %count br i1 %cmp, label %forbody, label %afterfor +; CHECK: %i.0 = phi i32 [ 0, %entry ], [ %inc, %forbody ] +; CHECK: %cmp = icmp ult i32 %i.0, %count +; CHECK: br i1 %cmp, label %forbody, label %afterfor + forbody: %tmp3 = load float** @a %arrayidx = getelementptr float* %tmp3, i32 %i.0 @@ -18,6 +26,14 @@ %inc = add i32 %i.0, 1 br label %forcond +; CHECK: %arrayidx = getelementptr float* %tmp3, i32 %i.0 +; CHECK: %tmp7 = uitofp i32 %i.0 to float +; CHECK: store float %tmp7, float* %arrayidx +; CHECK: %inc = add i32 %i.0, 1 +; CHECK: br label %forcond + afterfor: ret void } + +; CHECK: ret void From bob.wilson at apple.com Mon Oct 26 17:59:12 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 26 Oct 2009 22:59:12 -0000 Subject: [llvm-commits] [llvm] r85173 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Message-ID: <200910262259.n9QMxCmT009821@zion.cs.uiuc.edu> Author: bwilson Date: Mon Oct 26 17:59:12 2009 New Revision: 85173 URL: http://llvm.org/viewvc/llvm-project?rev=85173&view=rev Log: Try to get ahead of Johnny Chen and pro-actively add some more ARM encoding bits. Johnny, please review -- I do not have a good track record of getting these right. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=85173&r1=85172&r2=85173&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Mon Oct 26 17:59:12 2009 @@ -1092,6 +1092,7 @@ def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iALUi, "rsb", " $dst, $a, $b", [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> { + let Inst{20} = 0; let Inst{25} = 1; } @@ -1100,6 +1101,7 @@ [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> { let Inst{4} = 1; let Inst{7} = 0; + let Inst{20} = 0; let Inst{25} = 0; } @@ -1126,12 +1128,18 @@ DPFrm, IIC_iALUi, "rsc", " $dst, $a, $b", [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>, Requires<[IsARM, CarryDefIsUnused]> { + let Inst{20} = 0; let Inst{25} = 1; } def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iALUsr, "rsc", " $dst, $a, $b", [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>, - Requires<[IsARM, CarryDefIsUnused]>; + Requires<[IsARM, CarryDefIsUnused]> { + let Inst{4} = 1; + let Inst{7} = 0; + let Inst{20} = 0; + let Inst{25} = 0; +} } // FIXME: Allow these to be predicated. @@ -1140,12 +1148,18 @@ DPFrm, IIC_iALUi, "rscs $dst, $a, $b", [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>, Requires<[IsARM, CarryDefIsUnused]> { + let Inst{20} = 1; let Inst{25} = 1; } def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iALUsr, "rscs $dst, $a, $b", [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>, - Requires<[IsARM, CarryDefIsUnused]>; + Requires<[IsARM, CarryDefIsUnused]> { + let Inst{4} = 1; + let Inst{7} = 0; + let Inst{20} = 1; + let Inst{25} = 0; +} } // (sub X, imm) gets canonicalized to (add X, -imm). Match this form. From resistor at mac.com Mon Oct 26 18:13:57 2009 From: resistor at mac.com (Owen Anderson) Date: Mon, 26 Oct 2009 16:13:57 -0700 Subject: [llvm-commits] [llvm] r85144 - in /llvm/trunk: include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/GEPSplitter.cpp In-Reply-To: <9C3EC32B-AE0D-462E-A6FD-2307ED306406@apple.com> References: <200910261912.n9QJCE4a030428@zion.cs.uiuc.edu> <83489F21-6E25-42FB-B136-84DDBE36BF0E@me.com> <9C3EC32B-AE0D-462E-A6FD-2307ED306406@apple.com> Message-ID: <75753053-06D5-4807-BB11-94A18420CBC7@mac.com> On Oct 26, 2009, at 1:34 PM, Dan Gohman wrote: > > On Oct 26, 2009, at 12:58 PM, Owen Anderson wrote: > >> >> On Oct 26, 2009, at 12:12 PM, Dan Gohman wrote: >>> URL: http://llvm.org/viewvc/llvm-project?rev=85144&view=rev >>> Log: >>> Check in the experimental GEP splitter pass. This pass splits >>> complex >>> GEPs (more than one non-zero index) into simple GEPs (at most one >>> non-zero index). In some simple experiments using this it's not >>> uncommon to see 3% overall code size wins, because it exposes >>> redundancies that can be eliminated, however it's tricky to use >>> because instcombine aggressively undoes the work that this pass >>> does. >>> >> >> >> How about running it right before GVN, and letting a later >> instcombine >> pass clean it up? > > Instcombine currently merges GEPs even when they have multiple uses, > so > it defeats even this. And it's not entirely unjustified: BasicAA > understands standalone complex GEPs better than chains of > simple GEPs. That seems bad. Shouldn't it check at all of the users are themselves GEPs before folding? --Owen From evan.cheng at apple.com Mon Oct 26 18:27:15 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 26 Oct 2009 16:27:15 -0700 Subject: [llvm-commits] Added more 's' bit set encoding and "rs" register encoding bits In-Reply-To: <7FF0BB59-BFFE-41EC-B784-4A20CCBCD46F@apple.com> References: <31E018AE-6E13-4514-AF87-D875A8A09C9B@apple.com> <7FF0BB59-BFFE-41EC-B784-4A20CCBCD46F@apple.com> Message-ID: <104BA0C7-6E97-4EAE-AE82-03029C92E5E8@apple.com> On Oct 26, 2009, at 3:34 PM, Bob Wilson wrote: > As far as I can tell, the lack of predication for ADC/SBC is a > temporary limitation in llvm. Evan, can you confirm? Right. > > I've applied the rest of the patch for now, without the change to > force the condition fields. That should be done as a separate patch > anyway, since it is unrelated to this change. Are you guys making sure the ARM JIT is still working correctly after these series of encoding changes? Evan > > On Oct 26, 2009, at 11:48 AM, Johnny Chen wrote: > >> Hi, >> >> For multiclass AI1_adde_sube_irs definition, I also added: >> >> let Inst{31-28} = 0b1110; >> >> for the Sri, Srr, and Srs variants. From the AsmString field of the >> respective record definitions >> (take SBCSrs, for example): >> >> string AsmString = "sbcs $dst, $a, $b"; >> >> it looks like this is the right thing to do. Please remove the >> three "set condition code to ALways" >> lines from the submitted patch if this is not correct. >> >> Thanks. >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From bob.wilson at apple.com Mon Oct 26 18:32:07 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 26 Oct 2009 16:32:07 -0700 Subject: [llvm-commits] Added more 's' bit set encoding and "rs" register encoding bits In-Reply-To: <104BA0C7-6E97-4EAE-AE82-03029C92E5E8@apple.com> References: <31E018AE-6E13-4514-AF87-D875A8A09C9B@apple.com> <7FF0BB59-BFFE-41EC-B784-4A20CCBCD46F@apple.com> <104BA0C7-6E97-4EAE-AE82-03029C92E5E8@apple.com> Message-ID: <1B6B4FC9-817F-48CD-925D-869CC3125F76@apple.com> On Oct 26, 2009, at 4:27 PM, Evan Cheng wrote: > > Are you guys making sure the ARM JIT is still working correctly > after these series of encoding changes? Not necessarily. I'll try to test that soon. From deeppatel1987 at gmail.com Mon Oct 26 18:37:14 2009 From: deeppatel1987 at gmail.com (Sandeep Patel) Date: Mon, 26 Oct 2009 23:37:14 +0000 Subject: [llvm-commits] [PATCH] ARM AAPCS-VFP hard float homogeneous struct returns Message-ID: <305d6f60910261637t3fcc907fsaf47a4dbb968241a@mail.gmail.com> The attached patch to llvm-gcc-4.2 fixes incorrect returns of homogeneous structures. Instead of using a shadow parameter they are now register allocated. deep -------------- next part -------------- A non-text attachment was scrubbed... Name: deep-gcc-homogeneous-returns.diff Type: application/octet-stream Size: 15808 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091026/36602ac1/attachment.obj From vhernandez at apple.com Mon Oct 26 18:43:49 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Mon, 26 Oct 2009 23:43:49 -0000 Subject: [llvm-commits] [llvm] r85176 - in /llvm/trunk: examples/BrainF/ include/llvm-c/ include/llvm/ include/llvm/Analysis/ include/llvm/Support/ include/llvm/Transforms/ lib/Analysis/ lib/Analysis/IPA/ lib/AsmParser/ lib/Bitcode/Writer/ lib/CodeGen/SelectionDAG/ lib/ExecutionEngine/Interpreter/ lib/Target/CBackend/ lib/Target/CppBackend/ lib/Target/MSIL/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ Message-ID: <200910262343.n9QNhpYj012068@zion.cs.uiuc.edu> Author: hernande Date: Mon Oct 26 18:43:48 2009 New Revision: 85176 URL: http://llvm.org/viewvc/llvm-project?rev=85176&view=rev Log: Remove FreeInst. Remove LowerAllocations pass. Update some more passes to treate free calls just like they were treating FreeInst. Removed: llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp Modified: llvm/trunk/examples/BrainF/BrainF.cpp llvm/trunk/include/llvm-c/Core.h llvm/trunk/include/llvm/Analysis/AliasSetTracker.h llvm/trunk/include/llvm/Analysis/MallocHelper.h llvm/trunk/include/llvm/InstrTypes.h llvm/trunk/include/llvm/Instruction.def llvm/trunk/include/llvm/Instructions.h llvm/trunk/include/llvm/LinkAllPasses.h llvm/trunk/include/llvm/Support/IRBuilder.h llvm/trunk/include/llvm/Support/InstVisitor.h llvm/trunk/include/llvm/Transforms/Scalar.h llvm/trunk/lib/Analysis/AliasSetTracker.cpp llvm/trunk/lib/Analysis/CaptureTracking.cpp llvm/trunk/lib/Analysis/IPA/Andersens.cpp llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp llvm/trunk/lib/Analysis/InlineCost.cpp llvm/trunk/lib/Analysis/InstCount.cpp llvm/trunk/lib/Analysis/MallocHelper.cpp llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/AsmParser/LLLexer.cpp llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h llvm/trunk/lib/Target/CBackend/CBackend.cpp llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp llvm/trunk/lib/Target/MSIL/MSILWriter.cpp llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/lib/Transforms/Scalar/SCCP.cpp llvm/trunk/lib/Transforms/Utils/CMakeLists.txt llvm/trunk/lib/Transforms/Utils/Local.cpp llvm/trunk/lib/Transforms/Utils/LowerInvoke.cpp llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp llvm/trunk/lib/Transforms/Utils/Mem2Reg.cpp llvm/trunk/lib/VMCore/Core.cpp llvm/trunk/lib/VMCore/Instruction.cpp llvm/trunk/lib/VMCore/Instructions.cpp Modified: llvm/trunk/examples/BrainF/BrainF.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/BrainF/BrainF.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/examples/BrainF/BrainF.cpp (original) +++ llvm/trunk/examples/BrainF/BrainF.cpp Mon Oct 26 18:43:48 2009 @@ -117,8 +117,8 @@ //brainf.end: endbb = BasicBlock::Create(C, label, brainf_func); - //free i8 *%arr - new FreeInst(ptr_arr, endbb); + //call free(i8 *%arr) + endbb->getInstList().push_back(CallInst::CreateFree(ptr_arr, endbb)); //ret void ReturnInst::Create(C, endbb); Modified: llvm/trunk/include/llvm-c/Core.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/include/llvm-c/Core.h (original) +++ llvm/trunk/include/llvm-c/Core.h Mon Oct 26 18:43:48 2009 @@ -470,7 +470,6 @@ macro(UIToFPInst) \ macro(ZExtInst) \ macro(ExtractValueInst) \ - macro(FreeInst) \ macro(LoadInst) \ macro(VAArgInst) Modified: llvm/trunk/include/llvm/Analysis/AliasSetTracker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AliasSetTracker.h?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/AliasSetTracker.h (original) +++ llvm/trunk/include/llvm/Analysis/AliasSetTracker.h Mon Oct 26 18:43:48 2009 @@ -29,7 +29,6 @@ class AliasAnalysis; class LoadInst; class StoreInst; -class FreeInst; class VAArgInst; class AliasSetTracker; class AliasSet; @@ -298,7 +297,6 @@ bool add(Value *Ptr, unsigned Size); // Add a location bool add(LoadInst *LI); bool add(StoreInst *SI); - bool add(FreeInst *FI); bool add(VAArgInst *VAAI); bool add(CallSite CS); // Call/Invoke instructions bool add(CallInst *CI) { return add(CallSite(CI)); } @@ -313,7 +311,6 @@ bool remove(Value *Ptr, unsigned Size); // Remove a location bool remove(LoadInst *LI); bool remove(StoreInst *SI); - bool remove(FreeInst *FI); bool remove(VAArgInst *VAAI); bool remove(CallSite CS); bool remove(CallInst *CI) { return remove(CallSite(CI)); } Modified: llvm/trunk/include/llvm/Analysis/MallocHelper.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MallocHelper.h?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MallocHelper.h (original) +++ llvm/trunk/include/llvm/Analysis/MallocHelper.h Mon Oct 26 18:43:48 2009 @@ -1,4 +1,4 @@ -//===- llvm/Analysis/MallocHelper.h ---- Identify malloc calls --*- C++ -*-===// +//===- llvm/Analysis/MallocFreeHelper.h - Identify malloc/free --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -8,7 +8,8 @@ //===----------------------------------------------------------------------===// // // This family of functions identifies calls to malloc, bitcasts of malloc -// calls, and the types and array sizes associated with them. +// calls, and the types and array sizes associated with them. It also +// identifies calls to the free builtin. // //===----------------------------------------------------------------------===// Modified: llvm/trunk/include/llvm/InstrTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InstrTypes.h?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/include/llvm/InstrTypes.h (original) +++ llvm/trunk/include/llvm/InstrTypes.h Mon Oct 26 18:43:48 2009 @@ -117,7 +117,6 @@ static inline bool classof(const UnaryInstruction *) { return true; } static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Alloca || - I->getOpcode() == Instruction::Free || I->getOpcode() == Instruction::Load || I->getOpcode() == Instruction::VAArg || I->getOpcode() == Instruction::ExtractValue || Modified: llvm/trunk/include/llvm/Instruction.def URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instruction.def?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instruction.def (original) +++ llvm/trunk/include/llvm/Instruction.def Mon Oct 26 18:43:48 2009 @@ -128,48 +128,47 @@ // Memory operators... FIRST_MEMORY_INST(25) -HANDLE_MEMORY_INST(25, Free , FreeInst ) // Heap management instructions -HANDLE_MEMORY_INST(26, Alloca, AllocaInst) // Stack management -HANDLE_MEMORY_INST(27, Load , LoadInst ) // Memory manipulation instrs -HANDLE_MEMORY_INST(28, Store , StoreInst ) -HANDLE_MEMORY_INST(29, GetElementPtr, GetElementPtrInst) - LAST_MEMORY_INST(29) +HANDLE_MEMORY_INST(25, Alloca, AllocaInst) // Stack management +HANDLE_MEMORY_INST(26, Load , LoadInst ) // Memory manipulation instrs +HANDLE_MEMORY_INST(27, Store , StoreInst ) +HANDLE_MEMORY_INST(28, GetElementPtr, GetElementPtrInst) + LAST_MEMORY_INST(28) // Cast operators ... // NOTE: The order matters here because CastInst::isEliminableCastPair // NOTE: (see Instructions.cpp) encodes a table based on this ordering. - FIRST_CAST_INST(30) -HANDLE_CAST_INST(30, Trunc , TruncInst ) // Truncate integers -HANDLE_CAST_INST(31, ZExt , ZExtInst ) // Zero extend integers -HANDLE_CAST_INST(32, SExt , SExtInst ) // Sign extend integers -HANDLE_CAST_INST(33, FPToUI , FPToUIInst ) // floating point -> UInt -HANDLE_CAST_INST(34, FPToSI , FPToSIInst ) // floating point -> SInt -HANDLE_CAST_INST(35, UIToFP , UIToFPInst ) // UInt -> floating point -HANDLE_CAST_INST(36, SIToFP , SIToFPInst ) // SInt -> floating point -HANDLE_CAST_INST(37, FPTrunc , FPTruncInst ) // Truncate floating point -HANDLE_CAST_INST(38, FPExt , FPExtInst ) // Extend floating point -HANDLE_CAST_INST(39, PtrToInt, PtrToIntInst) // Pointer -> Integer -HANDLE_CAST_INST(40, IntToPtr, IntToPtrInst) // Integer -> Pointer -HANDLE_CAST_INST(41, BitCast , BitCastInst ) // Type cast - LAST_CAST_INST(41) + FIRST_CAST_INST(29) +HANDLE_CAST_INST(29, Trunc , TruncInst ) // Truncate integers +HANDLE_CAST_INST(30, ZExt , ZExtInst ) // Zero extend integers +HANDLE_CAST_INST(31, SExt , SExtInst ) // Sign extend integers +HANDLE_CAST_INST(32, FPToUI , FPToUIInst ) // floating point -> UInt +HANDLE_CAST_INST(33, FPToSI , FPToSIInst ) // floating point -> SInt +HANDLE_CAST_INST(34, UIToFP , UIToFPInst ) // UInt -> floating point +HANDLE_CAST_INST(35, SIToFP , SIToFPInst ) // SInt -> floating point +HANDLE_CAST_INST(36, FPTrunc , FPTruncInst ) // Truncate floating point +HANDLE_CAST_INST(37, FPExt , FPExtInst ) // Extend floating point +HANDLE_CAST_INST(38, PtrToInt, PtrToIntInst) // Pointer -> Integer +HANDLE_CAST_INST(39, IntToPtr, IntToPtrInst) // Integer -> Pointer +HANDLE_CAST_INST(40, BitCast , BitCastInst ) // Type cast + LAST_CAST_INST(40) // Other operators... - FIRST_OTHER_INST(42) -HANDLE_OTHER_INST(42, ICmp , ICmpInst ) // Integer comparison instruction -HANDLE_OTHER_INST(43, FCmp , FCmpInst ) // Floating point comparison instr. -HANDLE_OTHER_INST(44, PHI , PHINode ) // PHI node instruction -HANDLE_OTHER_INST(45, Call , CallInst ) // Call a function -HANDLE_OTHER_INST(46, Select , SelectInst ) // select instruction -HANDLE_OTHER_INST(47, UserOp1, Instruction) // May be used internally in a pass -HANDLE_OTHER_INST(48, UserOp2, Instruction) // Internal to passes only -HANDLE_OTHER_INST(49, VAArg , VAArgInst ) // vaarg instruction -HANDLE_OTHER_INST(50, ExtractElement, ExtractElementInst)// extract from vector -HANDLE_OTHER_INST(51, InsertElement, InsertElementInst) // insert into vector -HANDLE_OTHER_INST(52, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. -HANDLE_OTHER_INST(53, ExtractValue, ExtractValueInst)// extract from aggregate -HANDLE_OTHER_INST(54, InsertValue, InsertValueInst) // insert into aggregate + FIRST_OTHER_INST(41) +HANDLE_OTHER_INST(41, ICmp , ICmpInst ) // Integer comparison instruction +HANDLE_OTHER_INST(42, FCmp , FCmpInst ) // Floating point comparison instr. +HANDLE_OTHER_INST(43, PHI , PHINode ) // PHI node instruction +HANDLE_OTHER_INST(44, Call , CallInst ) // Call a function +HANDLE_OTHER_INST(45, Select , SelectInst ) // select instruction +HANDLE_OTHER_INST(46, UserOp1, Instruction) // May be used internally in a pass +HANDLE_OTHER_INST(47, UserOp2, Instruction) // Internal to passes only +HANDLE_OTHER_INST(48, VAArg , VAArgInst ) // vaarg instruction +HANDLE_OTHER_INST(49, ExtractElement, ExtractElementInst)// extract from vector +HANDLE_OTHER_INST(50, InsertElement, InsertElementInst) // insert into vector +HANDLE_OTHER_INST(51, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. +HANDLE_OTHER_INST(52, ExtractValue, ExtractValueInst)// extract from aggregate +HANDLE_OTHER_INST(53, InsertValue, InsertValueInst) // insert into aggregate - LAST_OTHER_INST(54) + LAST_OTHER_INST(53) #undef FIRST_TERM_INST #undef HANDLE_TERM_INST Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Mon Oct 26 18:43:48 2009 @@ -104,35 +104,6 @@ //===----------------------------------------------------------------------===// -// FreeInst Class -//===----------------------------------------------------------------------===// - -/// FreeInst - an instruction to deallocate memory -/// -class FreeInst : public UnaryInstruction { - void AssertOK(); -public: - explicit FreeInst(Value *Ptr, Instruction *InsertBefore = 0); - FreeInst(Value *Ptr, BasicBlock *InsertAfter); - - virtual FreeInst *clone() const; - - // Accessor methods for consistency with other memory operations - Value *getPointerOperand() { return getOperand(0); } - const Value *getPointerOperand() const { return getOperand(0); } - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const FreeInst *) { return true; } - static inline bool classof(const Instruction *I) { - return (I->getOpcode() == Instruction::Free); - } - static inline bool classof(const Value *V) { - return isa(V) && classof(cast(V)); - } -}; - - -//===----------------------------------------------------------------------===// // LoadInst Class //===----------------------------------------------------------------------===// Modified: llvm/trunk/include/llvm/LinkAllPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/include/llvm/LinkAllPasses.h (original) +++ llvm/trunk/include/llvm/LinkAllPasses.h Mon Oct 26 18:43:48 2009 @@ -91,7 +91,6 @@ (void) llvm::createLoopUnswitchPass(); (void) llvm::createLoopRotatePass(); (void) llvm::createLoopIndexSplitPass(); - (void) llvm::createLowerAllocationsPass(); (void) llvm::createLowerInvokePass(); (void) llvm::createLowerSetJmpPass(); (void) llvm::createLowerSwitchPass(); Modified: llvm/trunk/include/llvm/Support/IRBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/IRBuilder.h?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/IRBuilder.h (original) +++ llvm/trunk/include/llvm/Support/IRBuilder.h Mon Oct 26 18:43:48 2009 @@ -433,9 +433,6 @@ const Twine &Name = "") { return Insert(new AllocaInst(Ty, ArraySize), Name); } - FreeInst *CreateFree(Value *Ptr) { - return Insert(new FreeInst(Ptr)); - } // Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of // converting the string to 'bool' for the isVolatile parameter. LoadInst *CreateLoad(Value *Ptr, const char *Name) { Modified: llvm/trunk/include/llvm/Support/InstVisitor.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/InstVisitor.h?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/InstVisitor.h (original) +++ llvm/trunk/include/llvm/Support/InstVisitor.h Mon Oct 26 18:43:48 2009 @@ -166,7 +166,6 @@ RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);} RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);} RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(Instruction); } - RetTy visitFreeInst(FreeInst &I) { DELEGATE(Instruction); } RetTy visitLoadInst(LoadInst &I) { DELEGATE(Instruction); } RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction); } RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction); } Modified: llvm/trunk/include/llvm/Transforms/Scalar.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Scalar.h (original) +++ llvm/trunk/include/llvm/Transforms/Scalar.h Mon Oct 26 18:43:48 2009 @@ -225,15 +225,6 @@ //===----------------------------------------------------------------------===// // -// LowerAllocations - Turn free instructions into @free calls. -// -// AU.addRequiredID(LowerAllocationsID); -// -Pass *createLowerAllocationsPass(); -extern const PassInfo *const LowerAllocationsID; - -//===----------------------------------------------------------------------===// -// // TailCallElimination - This pass eliminates call instructions to the current // function which occur immediately before return instructions. // Modified: llvm/trunk/lib/Analysis/AliasSetTracker.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasSetTracker.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/AliasSetTracker.cpp (original) +++ llvm/trunk/lib/Analysis/AliasSetTracker.cpp Mon Oct 26 18:43:48 2009 @@ -13,6 +13,7 @@ #include "llvm/Analysis/AliasSetTracker.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/MallocHelper.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" #include "llvm/Pass.h" @@ -296,12 +297,6 @@ return NewPtr; } -bool AliasSetTracker::add(FreeInst *FI) { - bool NewPtr; - addPointer(FI->getOperand(0), ~0, AliasSet::Mods, NewPtr); - return NewPtr; -} - bool AliasSetTracker::add(VAArgInst *VAAI) { bool NewPtr; addPointer(VAAI->getOperand(0), ~0, AliasSet::ModRef, NewPtr); @@ -310,6 +305,13 @@ bool AliasSetTracker::add(CallSite CS) { + Instruction* Inst = CS.getInstruction(); + if (isFreeCall(Inst)) { + bool NewPtr; + addPointer(Inst->getOperand(1), ~0, AliasSet::Mods, NewPtr); + return NewPtr; + } + if (isa(CS.getInstruction())) return true; // Ignore DbgInfo Intrinsics. if (AA.doesNotAccessMemory(CS)) @@ -337,8 +339,6 @@ return add(CI); else if (InvokeInst *II = dyn_cast(I)) return add(II); - else if (FreeInst *FI = dyn_cast(I)) - return add(FI); else if (VAArgInst *VAAI = dyn_cast(I)) return add(VAAI); return true; @@ -427,13 +427,6 @@ return true; } -bool AliasSetTracker::remove(FreeInst *FI) { - AliasSet *AS = findAliasSetForPointer(FI->getOperand(0), ~0); - if (!AS) return false; - remove(*AS); - return true; -} - bool AliasSetTracker::remove(VAArgInst *VAAI) { AliasSet *AS = findAliasSetForPointer(VAAI->getOperand(0), ~0); if (!AS) return false; @@ -442,6 +435,14 @@ } bool AliasSetTracker::remove(CallSite CS) { + Instruction* Inst = CS.getInstruction(); + if (isFreeCall(Inst)) { + AliasSet *AS = findAliasSetForPointer(Inst->getOperand(1), ~0); + if (!AS) return false; + remove(*AS); + return true; + } + if (AA.doesNotAccessMemory(CS)) return false; // doesn't alias anything @@ -459,8 +460,6 @@ return remove(SI); else if (CallInst *CI = dyn_cast(I)) return remove(CI); - else if (FreeInst *FI = dyn_cast(I)) - return remove(FI); else if (VAArgInst *VAAI = dyn_cast(I)) return remove(VAAI); return true; Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CaptureTracking.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/CaptureTracking.cpp (original) +++ llvm/trunk/lib/Analysis/CaptureTracking.cpp Mon Oct 26 18:43:48 2009 @@ -17,6 +17,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/CaptureTracking.h" +#include "llvm/Analysis/MallocHelper.h" #include "llvm/Instructions.h" #include "llvm/Value.h" #include "llvm/ADT/SmallSet.h" @@ -48,6 +49,9 @@ switch (I->getOpcode()) { case Instruction::Call: + if (isFreeCall(I)) + // Freeing a pointer does not cause it to be captured. + break; case Instruction::Invoke: { CallSite CS = CallSite::get(I); // Not captured if the callee is readonly, doesn't return a copy through @@ -73,9 +77,6 @@ // captured. break; } - case Instruction::Free: - // Freeing a pointer does not cause it to be captured. - break; case Instruction::Load: // Loading from a pointer does not cause it to be captured. break; Modified: llvm/trunk/lib/Analysis/IPA/Andersens.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/Andersens.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/IPA/Andersens.cpp (original) +++ llvm/trunk/lib/Analysis/IPA/Andersens.cpp Mon Oct 26 18:43:48 2009 @@ -1016,7 +1016,7 @@ } } else if (GetElementPtrInst *GEP = dyn_cast(*UI)) { if (AnalyzeUsesOfFunction(GEP)) return true; - } else if (isa(*UI) || isFreeCall(*UI)) { + } else if (isFreeCall(*UI)) { return false; } else if (CallInst *CI = dyn_cast(*UI)) { // Make sure that this is just the function being called, not that it is @@ -1156,7 +1156,6 @@ case Instruction::Switch: case Instruction::Unwind: case Instruction::Unreachable: - case Instruction::Free: case Instruction::ICmp: case Instruction::FCmp: return; Modified: llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp (original) +++ llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp Mon Oct 26 18:43:48 2009 @@ -238,7 +238,7 @@ } else if (BitCastInst *BCI = dyn_cast(*UI)) { if (AnalyzeUsesOfPointer(BCI, Readers, Writers, OkayStoreDest)) return true; - } else if (isa(*UI) || isFreeCall(*UI)) { + } else if (isFreeCall(*UI)) { Writers.push_back(cast(*UI)->getParent()->getParent()); } else if (CallInst *CI = dyn_cast(*UI)) { // Make sure that this is just the function being called, not that it is @@ -437,7 +437,7 @@ if (cast(*II).isVolatile()) // Treat volatile stores as reading memory somewhere. FunctionEffect |= Ref; - } else if (isMalloc(&cast(*II)) || isa(*II) || + } else if (isMalloc(&cast(*II)) || isFreeCall(&cast(*II))) { FunctionEffect |= ModRef; } Modified: llvm/trunk/lib/Analysis/InlineCost.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InlineCost.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InlineCost.cpp (original) +++ llvm/trunk/lib/Analysis/InlineCost.cpp Mon Oct 26 18:43:48 2009 @@ -130,10 +130,6 @@ NumInsts += InlineConstants::CallPenalty; } - // These, too, are calls. - if (isa(II)) - NumInsts += InlineConstants::CallPenalty; - if (const AllocaInst *AI = dyn_cast(II)) { if (!AI->isStaticAlloca()) this->usesDynamicAlloca = true; Modified: llvm/trunk/lib/Analysis/InstCount.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstCount.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstCount.cpp (original) +++ llvm/trunk/lib/Analysis/InstCount.cpp Mon Oct 26 18:43:48 2009 @@ -74,11 +74,11 @@ bool InstCount::runOnFunction(Function &F) { unsigned StartMemInsts = NumGetElementPtrInst + NumLoadInst + NumStoreInst + NumCallInst + - NumInvokeInst + NumAllocaInst + NumFreeInst; + NumInvokeInst + NumAllocaInst; visit(F); unsigned EndMemInsts = NumGetElementPtrInst + NumLoadInst + NumStoreInst + NumCallInst + - NumInvokeInst + NumAllocaInst + NumFreeInst; + NumInvokeInst + NumAllocaInst; TotalMemInst += EndMemInsts-StartMemInsts; return false; } Modified: llvm/trunk/lib/Analysis/MallocHelper.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MallocHelper.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MallocHelper.cpp (original) +++ llvm/trunk/lib/Analysis/MallocHelper.cpp Mon Oct 26 18:43:48 2009 @@ -1,4 +1,4 @@ -//===-- MallocHelper.cpp - Functions to identify malloc calls -------------===// +//===-- MallocFreeHelper.cpp - Identify calls to malloc and free builtins -===// // // The LLVM Compiler Infrastructure // @@ -8,7 +8,8 @@ //===----------------------------------------------------------------------===// // // This family of functions identifies calls to malloc, bitcasts of malloc -// calls, and the types and array sizes associated with them. +// calls, and the types and array sizes associated with them. It also +// identifies calls to the free builtin. // //===----------------------------------------------------------------------===// @@ -264,6 +265,10 @@ return BO->getOperand(0); } +//===----------------------------------------------------------------------===// +// free Call Utility Functions. +// + /// isFreeCall - Returns true if the the value is a call to the builtin free() bool llvm::isFreeCall(const Value* I) { const CallInst *CI = dyn_cast(I); Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Mon Oct 26 18:43:48 2009 @@ -113,10 +113,9 @@ } else if (VAArgInst *V = dyn_cast(Inst)) { Pointer = V->getOperand(0); PointerSize = AA->getTypeStoreSize(V->getType()); - } else if (FreeInst *F = dyn_cast(Inst)) { - Pointer = F->getPointerOperand(); - - // FreeInsts erase the entire structure + } else if (isFreeCall(Inst)) { + Pointer = Inst->getOperand(1); + // calls to free() erase the entire structure PointerSize = ~0ULL; } else if (isFreeCall(Inst)) { Pointer = Inst->getOperand(0); @@ -319,7 +318,7 @@ MemSize = AA->getTypeStoreSize(LI->getType()); } } else if (isFreeCall(QueryInst)) { - MemPtr = QueryInst->getOperand(0); + MemPtr = QueryInst->getOperand(1); // calls to free() erase the entire structure, not just a field. MemSize = ~0UL; } else if (isa(QueryInst) || isa(QueryInst)) { @@ -327,10 +326,6 @@ bool isReadOnly = AA->onlyReadsMemory(QueryCS); LocalCache = getCallSiteDependencyFrom(QueryCS, isReadOnly, ScanPos, QueryParent); - } else if (FreeInst *FI = dyn_cast(QueryInst)) { - MemPtr = FI->getPointerOperand(); - // FreeInsts erase the entire structure, not just a field. - MemSize = ~0UL; } else { // Non-memory instruction. LocalCache = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos)); Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLLexer.cpp (original) +++ llvm/trunk/lib/AsmParser/LLLexer.cpp Mon Oct 26 18:43:48 2009 @@ -606,6 +606,10 @@ // FIXME: Remove in LLVM 3.0. // Autoupgrade malloc instruction. return lltok::kw_malloc; + } else if (Len == 4 && !memcmp(StartChar, "free", 4)) { + // FIXME: Remove in LLVM 3.0. + // Autoupgrade malloc instruction. + return lltok::kw_free; } // Keywords for instructions. @@ -646,7 +650,6 @@ INSTKEYWORD(unreachable, Unreachable); INSTKEYWORD(alloca, Alloca); - INSTKEYWORD(free, Free); INSTKEYWORD(load, Load); INSTKEYWORD(store, Store); INSTKEYWORD(getelementptr, GetElementPtr); Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon Oct 26 18:43:48 2009 @@ -1054,11 +1054,6 @@ Vals.push_back(VE.getValueID(I.getOperand(i))); break; - case Instruction::Free: - Code = bitc::FUNC_CODE_INST_FREE; - PushValueAndType(I.getOperand(0), InstID, Vals, VE); - break; - case Instruction::Alloca: Code = bitc::FUNC_CODE_INST_ALLOCA; Vals.push_back(VE.getTypeID(I.getType())); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Mon Oct 26 18:43:48 2009 @@ -5486,26 +5486,6 @@ DAG.setRoot(Chain); } -void SelectionDAGLowering::visitFree(FreeInst &I) { - TargetLowering::ArgListTy Args; - TargetLowering::ArgListEntry Entry; - Entry.Node = getValue(I.getOperand(0)); - Entry.Ty = TLI.getTargetData()->getIntPtrType(*DAG.getContext()); - Args.push_back(Entry); - EVT IntPtr = TLI.getPointerTy(); - bool isTailCall = PerformTailCallOpt && - isInTailCallPosition(&I, Attribute::None, TLI); - std::pair Result = - TLI.LowerCallTo(getRoot(), Type::getVoidTy(*DAG.getContext()), - false, false, false, false, - 0, CallingConv::C, isTailCall, - /*isReturnValueUsed=*/true, - DAG.getExternalSymbol("free", IntPtr), Args, DAG, - getCurDebugLoc()); - if (Result.second.getNode()) - DAG.setRoot(Result.second); -} - void SelectionDAGLowering::visitVAStart(CallInst &I) { DAG.setRoot(DAG.getNode(ISD::VASTART, getCurDebugLoc(), MVT::Other, getRoot(), Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h Mon Oct 26 18:43:48 2009 @@ -44,7 +44,6 @@ class FPToSIInst; class FPToUIInst; class FPTruncInst; -class FreeInst; class Function; class GetElementPtrInst; class GCFunctionInfo; @@ -528,7 +527,6 @@ void visitGetElementPtr(User &I); void visitSelect(User &I); - void visitFree(FreeInst &I); void visitAlloca(AllocaInst &I); void visitLoad(LoadInst &I); void visitStore(StoreInst &I); Modified: llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp Mon Oct 26 18:43:48 2009 @@ -749,14 +749,6 @@ ECStack.back().Allocas.add(Memory); } -void Interpreter::visitFreeInst(FreeInst &I) { - ExecutionContext &SF = ECStack.back(); - assert(isa(I.getOperand(0)->getType()) && "Freeing nonptr?"); - GenericValue Value = getOperandValue(I.getOperand(0), SF); - // TODO: Check to make sure memory is allocated - free(GVTOP(Value)); // Free memory -} - // getElementOffset - The workhorse for getelementptr. // GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I, Modified: llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h (original) +++ llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h Mon Oct 26 18:43:48 2009 @@ -140,7 +140,6 @@ void visitICmpInst(ICmpInst &I); void visitFCmpInst(FCmpInst &I); void visitAllocaInst(AllocaInst &I); - void visitFreeInst(FreeInst &I); void visitLoadInst(LoadInst &I); void visitStoreInst(StoreInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Mon Oct 26 18:43:48 2009 @@ -303,7 +303,6 @@ bool visitBuiltinCall(CallInst &I, Intrinsic::ID ID, bool &WroteCallee); void visitAllocaInst(AllocaInst &I); - void visitFreeInst (FreeInst &I); void visitLoadInst (LoadInst &I); void visitStoreInst (StoreInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); @@ -3417,10 +3416,6 @@ Out << ')'; } -void CWriter::visitFreeInst(FreeInst &I) { - llvm_unreachable("lowerallocations pass didn't work!"); -} - void CWriter::printGEPExpression(Value *Ptr, gep_type_iterator I, gep_type_iterator E, bool Static) { @@ -3685,7 +3680,6 @@ if (FileType != TargetMachine::AssemblyFile) return true; PM.add(createGCLoweringPass()); - PM.add(createLowerAllocationsPass()); PM.add(createLowerInvokePass()); PM.add(createCFGSimplificationPass()); // clean up after lower invoke. PM.add(new CBackendNameAllUsedStructsAndMergeFunctions()); Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original) +++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Mon Oct 26 18:43:48 2009 @@ -1258,11 +1258,6 @@ Out << "\");"; break; } - case Instruction::Free: { - Out << "FreeInst* " << iName << " = new FreeInst(" - << getCppName(I->getOperand(0)) << ", " << bbname << ");"; - break; - } case Instruction::Alloca: { const AllocaInst* allocaI = cast(I); Out << "AllocaInst* " << iName << " = new AllocaInst(" Modified: llvm/trunk/lib/Target/MSIL/MSILWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSIL/MSILWriter.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSIL/MSILWriter.cpp (original) +++ llvm/trunk/lib/Target/MSIL/MSILWriter.cpp Mon Oct 26 18:43:48 2009 @@ -1191,9 +1191,6 @@ case Instruction::Alloca: printAllocaInstruction(cast(Inst)); break; - case Instruction::Free: - llvm_unreachable("LowerAllocationsPass used"); - break; case Instruction::Unreachable: printSimpleInstruction("ldstr", "\"Unreachable instruction\""); printSimpleInstruction("newobj", @@ -1699,7 +1696,6 @@ if (FileType != TargetMachine::AssemblyFile) return true; MSILWriter* Writer = new MSILWriter(o); PM.add(createGCLoweringPass()); - PM.add(createLowerAllocationsPass()); // FIXME: Handle switch trougth native IL instruction "switch" PM.add(createLowerSwitchPass()); PM.add(createCFGSimplificationPass()); Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Mon Oct 26 18:43:48 2009 @@ -89,7 +89,7 @@ Instruction *Inst = BBI++; // If we find a store or a free, get its memory dependence. - if (!isa(Inst) && !isa(Inst) && !isFreeCall(Inst)) + if (!isa(Inst) && !isFreeCall(Inst)) continue; // Don't molest volatile stores or do queries that will return "clobber". @@ -104,7 +104,7 @@ if (InstDep.isNonLocal()) continue; // Handle frees whose dependencies are non-trivial. - if (isa(Inst) || isFreeCall(Inst)) { + if (isFreeCall(Inst)) { MadeChange |= handleFreeWithNonTrivialDependency(Inst, InstDep); continue; } @@ -176,8 +176,7 @@ Value *DepPointer = Dependency->getPointerOperand()->getUnderlyingObject(); // Check for aliasing. - Value* FreeVal = isa(F) ? F->getOperand(0) : F->getOperand(1); - if (AA.alias(FreeVal, 1, DepPointer, 1) != + if (AA.alias(F->getOperand(1), 1, DepPointer, 1) != AliasAnalysis::MustAlias) return false; Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Oct 26 18:43:48 2009 @@ -285,7 +285,6 @@ Instruction *visitPHINode(PHINode &PN); Instruction *visitGetElementPtrInst(GetElementPtrInst &GEP); Instruction *visitAllocaInst(AllocaInst &AI); - Instruction *visitFreeInst(FreeInst &FI); Instruction *visitFree(Instruction &FI); Instruction *visitLoadInst(LoadInst &LI); Instruction *visitStoreInst(StoreInst &SI); @@ -11328,56 +11327,6 @@ return 0; } -Instruction *InstCombiner::visitFreeInst(FreeInst &FI) { - Value *Op = FI.getOperand(0); - - // free undef -> unreachable. - if (isa(Op)) { - // Insert a new store to null because we cannot modify the CFG here. - new StoreInst(ConstantInt::getTrue(*Context), - UndefValue::get(Type::getInt1PtrTy(*Context)), &FI); - return EraseInstFromFunction(FI); - } - - // If we have 'free null' delete the instruction. This can happen in stl code - // when lots of inlining happens. - if (isa(Op)) - return EraseInstFromFunction(FI); - - // Change free * (cast * X to *) into free * X - if (BitCastInst *CI = dyn_cast(Op)) { - FI.setOperand(0, CI->getOperand(0)); - return &FI; - } - - // Change free (gep X, 0,0,0,0) into free(X) - if (GetElementPtrInst *GEPI = dyn_cast(Op)) { - if (GEPI->hasAllZeroIndices()) { - Worklist.Add(GEPI); - FI.setOperand(0, GEPI->getOperand(0)); - return &FI; - } - } - - if (isMalloc(Op)) { - if (CallInst* CI = extractMallocCallFromBitCast(Op)) { - if (Op->hasOneUse() && CI->hasOneUse()) { - EraseInstFromFunction(FI); - EraseInstFromFunction(*CI); - return EraseInstFromFunction(*cast(Op)); - } - } else { - // Op is a call to malloc - if (Op->hasOneUse()) { - EraseInstFromFunction(FI); - return EraseInstFromFunction(*cast(Op)); - } - } - } - - return 0; -} - Instruction *InstCombiner::visitFree(Instruction &FI) { Value *Op = FI.getOperand(1); @@ -11394,9 +11343,8 @@ if (isa(Op)) return EraseInstFromFunction(FI); - // FIXME: Bring back free (gep X, 0,0,0,0) into free(X) transform - - if (isMalloc(Op)) { + // If we have a malloc call whose only use is a free call, delete both. + if (isMalloc(Op)) if (CallInst* CI = extractMallocCallFromBitCast(Op)) { if (Op->hasOneUse() && CI->hasOneUse()) { EraseInstFromFunction(FI); @@ -11410,7 +11358,6 @@ return EraseInstFromFunction(*cast(Op)); } } - } return 0; } Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Mon Oct 26 18:43:48 2009 @@ -416,7 +416,6 @@ void visitAllocaInst (Instruction &I) { markOverdefined(&I); } void visitVANextInst (Instruction &I) { markOverdefined(&I); } void visitVAArgInst (Instruction &I) { markOverdefined(&I); } - void visitFreeInst (Instruction &I) { /*returns void*/ } void visitInstruction(Instruction &I) { // If a new instruction is added to LLVM that we don't handle... Modified: llvm/trunk/lib/Transforms/Utils/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CMakeLists.txt?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CMakeLists.txt (original) +++ llvm/trunk/lib/Transforms/Utils/CMakeLists.txt Mon Oct 26 18:43:48 2009 @@ -13,7 +13,6 @@ LCSSA.cpp Local.cpp LoopSimplify.cpp - LowerAllocations.cpp LowerInvoke.cpp LowerSwitch.cpp Mem2Reg.cpp Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Mon Oct 26 18:43:48 2009 @@ -60,9 +60,8 @@ // If we see a free or a call which may write to memory (i.e. which might do // a free) the pointer could be marked invalid. - if (isa(BBI) || isFreeCall(BBI) || - (isa(BBI) && BBI->mayWriteToMemory() && - !isa(BBI))) + if (isFreeCall(BBI) || (isa(BBI) && BBI->mayWriteToMemory() && + !isa(BBI))) return false; if (LoadInst *LI = dyn_cast(BBI)) { Removed: llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp?rev=85175&view=auto ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LowerAllocations.cpp (removed) @@ -1,116 +0,0 @@ -//===- LowerAllocations.cpp - Reduce free insts to calls ------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// The LowerAllocations transformation is a target-dependent tranformation -// because it depends on the size of data types and alignment constraints. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "lowerallocs" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" -#include "llvm/Module.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Instructions.h" -#include "llvm/Constants.h" -#include "llvm/LLVMContext.h" -#include "llvm/Pass.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/Target/TargetData.h" -using namespace llvm; - -STATISTIC(NumLowered, "Number of allocations lowered"); - -namespace { - /// LowerAllocations - Turn free instructions into @free calls. - /// - class LowerAllocations : public BasicBlockPass { - Constant *FreeFunc; // Functions in the module we are processing - // Initialized by doInitialization - public: - static char ID; // Pass ID, replacement for typeid - explicit LowerAllocations() - : BasicBlockPass(&ID), FreeFunc(0) {} - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); - AU.setPreservesCFG(); - - // This is a cluster of orthogonal Transforms: - AU.addPreserved(); - AU.addPreservedID(PromoteMemoryToRegisterID); - AU.addPreservedID(LowerSwitchID); - AU.addPreservedID(LowerInvokePassID); - } - - /// doPassInitialization - For the lower allocations pass, this ensures that - /// a module contains a declaration for a free function. - /// - bool doInitialization(Module &M); - - virtual bool doInitialization(Function &F) { - return doInitialization(*F.getParent()); - } - - /// runOnBasicBlock - This method does the actual work of converting - /// instructions over, assuming that the pass has already been initialized. - /// - bool runOnBasicBlock(BasicBlock &BB); - }; -} - -char LowerAllocations::ID = 0; -static RegisterPass -X("lowerallocs", "Lower allocations from instructions to calls"); - -// Publically exposed interface to pass... -const PassInfo *const llvm::LowerAllocationsID = &X; -// createLowerAllocationsPass - Interface to this file... -Pass *llvm::createLowerAllocationsPass() { - return new LowerAllocations(); -} - - -// doInitialization - For the lower allocations pass, this ensures that a -// module contains a declaration for a free function. -// -// This function is always successful. -// -bool LowerAllocations::doInitialization(Module &M) { - const Type *BPTy = Type::getInt8PtrTy(M.getContext()); - FreeFunc = M.getOrInsertFunction("free" , Type::getVoidTy(M.getContext()), - BPTy, (Type *)0); - return true; -} - -// runOnBasicBlock - This method does the actual work of converting -// instructions over, assuming that the pass has already been initialized. -// -bool LowerAllocations::runOnBasicBlock(BasicBlock &BB) { - bool Changed = false; - assert(FreeFunc && "Pass not initialized!"); - - BasicBlock::InstListType &BBIL = BB.getInstList(); - - // Loop over all of the instructions, looking for free instructions - for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) { - if (FreeInst *FI = dyn_cast(I)) { - // Insert a call to the free function... - CallInst::CreateFree(FI->getOperand(0), I); - - // Delete the old free instruction - I = --BBIL.erase(I); - Changed = true; - ++NumLowered; - } - } - - return Changed; -} - Modified: llvm/trunk/lib/Transforms/Utils/LowerInvoke.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LowerInvoke.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LowerInvoke.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LowerInvoke.cpp Mon Oct 26 18:43:48 2009 @@ -86,7 +86,6 @@ // This is a cluster of orthogonal Transforms AU.addPreservedID(PromoteMemoryToRegisterID); AU.addPreservedID(LowerSwitchID); - AU.addPreservedID(LowerAllocationsID); } private: Modified: llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp Mon Oct 26 18:43:48 2009 @@ -43,7 +43,6 @@ AU.addPreserved(); AU.addPreservedID(PromoteMemoryToRegisterID); AU.addPreservedID(LowerInvokePassID); - AU.addPreservedID(LowerAllocationsID); } struct CaseRange { Modified: llvm/trunk/lib/Transforms/Utils/Mem2Reg.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Mem2Reg.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Mem2Reg.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Mem2Reg.cpp Mon Oct 26 18:43:48 2009 @@ -44,7 +44,6 @@ AU.addPreserved(); AU.addPreservedID(LowerSwitchID); AU.addPreservedID(LowerInvokePassID); - AU.addPreservedID(LowerAllocationsID); } }; } // end of anonymous namespace Modified: llvm/trunk/lib/VMCore/Core.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Core.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Core.cpp (original) +++ llvm/trunk/lib/VMCore/Core.cpp Mon Oct 26 18:43:48 2009 @@ -1724,7 +1724,8 @@ } LLVMValueRef LLVMBuildFree(LLVMBuilderRef B, LLVMValueRef PointerVal) { - return wrap(unwrap(B)->CreateFree(unwrap(PointerVal))); + return wrap(unwrap(B)->Insert( + CallInst::CreateFree(unwrap(PointerVal), unwrap(B)->GetInsertBlock()))); } Modified: llvm/trunk/lib/VMCore/Instruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instruction.cpp (original) +++ llvm/trunk/lib/VMCore/Instruction.cpp Mon Oct 26 18:43:48 2009 @@ -127,7 +127,6 @@ case Xor: return "xor"; // Memory instructions... - case Free: return "free"; case Alloca: return "alloca"; case Load: return "load"; case Store: return "store"; @@ -303,16 +302,43 @@ return false; } +// Code here matches isFreeCall from MallocHelper, which is not in VMCore. +static bool isFreeCall(const Value* I) { + const CallInst *CI = dyn_cast(I); + if (!CI) + return false; + + const Module* M = CI->getParent()->getParent()->getParent(); + Function *FreeFunc = M->getFunction("free"); + + if (CI->getOperand(0) != FreeFunc) + return false; + + // Check free prototype. + // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin + // attribute will exist. + const FunctionType *FTy = FreeFunc->getFunctionType(); + if (FTy->getReturnType() != Type::getVoidTy(M->getContext())) + return false; + if (FTy->getNumParams() != 1) + return false; + if (FTy->param_begin()->get() != Type::getInt8PtrTy(M->getContext())) + return false; + + return true; +} + /// mayReadFromMemory - Return true if this instruction may read memory. /// bool Instruction::mayReadFromMemory() const { switch (getOpcode()) { default: return false; - case Instruction::Free: case Instruction::VAArg: case Instruction::Load: return true; case Instruction::Call: + if (isFreeCall(this)) + return true; return !cast(this)->doesNotAccessMemory(); case Instruction::Invoke: return !cast(this)->doesNotAccessMemory(); @@ -326,11 +352,12 @@ bool Instruction::mayWriteToMemory() const { switch (getOpcode()) { default: return false; - case Instruction::Free: case Instruction::Store: case Instruction::VAArg: return true; case Instruction::Call: + if (isFreeCall(this)) + return true; return !cast(this)->onlyReadsMemory(); case Instruction::Invoke: return !cast(this)->onlyReadsMemory(); @@ -398,7 +425,19 @@ if (CI->getOperand(0) != MallocFunc) return false; - return true; + // Check malloc prototype. + // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin + // attribute will exist. + const FunctionType *FTy = cast(MallocFunc)->getFunctionType(); + if (FTy->getNumParams() != 1) + return false; + if (IntegerType *ITy = dyn_cast(FTy->param_begin()->get())) { + if (ITy->getBitWidth() != 32 && ITy->getBitWidth() != 64) + return false; + return true; + } + + return false; } bool Instruction::isSafeToSpeculativelyExecute() const { @@ -444,7 +483,6 @@ case Invoke: case PHI: case Store: - case Free: case Ret: case Br: case Switch: Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=85176&r1=85175&r2=85176&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Mon Oct 26 18:43:48 2009 @@ -985,28 +985,6 @@ } //===----------------------------------------------------------------------===// -// FreeInst Implementation -//===----------------------------------------------------------------------===// - -void FreeInst::AssertOK() { - assert(isa(getOperand(0)->getType()) && - "Can not free something of nonpointer type!"); -} - -FreeInst::FreeInst(Value *Ptr, Instruction *InsertBefore) - : UnaryInstruction(Type::getVoidTy(Ptr->getContext()), - Free, Ptr, InsertBefore) { - AssertOK(); -} - -FreeInst::FreeInst(Value *Ptr, BasicBlock *InsertAtEnd) - : UnaryInstruction(Type::getVoidTy(Ptr->getContext()), - Free, Ptr, InsertAtEnd) { - AssertOK(); -} - - -//===----------------------------------------------------------------------===// // LoadInst Implementation //===----------------------------------------------------------------------===// @@ -3181,16 +3159,6 @@ return New; } -FreeInst *FreeInst::clone() const { - FreeInst *New = new FreeInst(getOperand(0)); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - LoadInst *LoadInst::clone() const { LoadInst *New = new LoadInst(getOperand(0), Twine(), isVolatile(), From vhernandez at apple.com Mon Oct 26 18:44:29 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Mon, 26 Oct 2009 23:44:29 -0000 Subject: [llvm-commits] [llvm] r85177 - /llvm/trunk/docs/LangRef.html Message-ID: <200910262344.n9QNiTro012098@zion.cs.uiuc.edu> Author: hernande Date: Mon Oct 26 18:44:29 2009 New Revision: 85177 URL: http://llvm.org/viewvc/llvm-project?rev=85177&view=rev Log: Remove all references to MallocInst and FreeInst Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=85177&r1=85176&r2=85177&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Mon Oct 26 18:44:29 2009 @@ -156,8 +156,6 @@
  • Memory Access and Addressing Operations
      -
    1. 'malloc' Instruction
    2. -
    3. 'free' Instruction
    4. 'alloca' Instruction
    5. 'load' Instruction
    6. 'store' Instruction
    7. @@ -3833,95 +3831,13 @@

      A key design point of an SSA-based representation is how it represents memory. In LLVM, no memory locations are in SSA form, which makes things - very simple. This section describes how to read, write, allocate, and free + very simple. This section describes how to read, write, and allocate memory in LLVM.

      - -
      - -
      Syntax:
      -
      -  <result> = malloc <type>[, i32 <NumElements>][, align <alignment>]     ; yields {type*}:result
      -
      - -
      Overview:
      -

      The 'malloc' instruction allocates memory from the system heap and - returns a pointer to it. The object is always allocated in the generic - address space (address space zero).

      - -
      Arguments:
      -

      The 'malloc' instruction allocates - sizeof(<type>)*NumElements bytes of memory from the operating - system and returns a pointer of the appropriate type to the program. If - "NumElements" is specified, it is the number of elements allocated, otherwise - "NumElements" is defaulted to be one. If a constant alignment is specified, - the value result of the allocation is guaranteed to be aligned to at least - that boundary. If not specified, or if zero, the target can choose to align - the allocation on any convenient boundary compatible with the type.

      - -

      'type' must be a sized type.

      - -
      Semantics:
      -

      Memory is allocated using the system "malloc" function, and a - pointer is returned. The result of a zero byte allocation is undefined. The - result is null if there is insufficient memory available.

      - -
      Example:
      -
      -  %array  = malloc [4 x i8]                     ; yields {[%4 x i8]*}:array
      -
      -  %size   = add i32 2, 2                        ; yields {i32}:size = i32 4
      -  %array1 = malloc i8, i32 4                    ; yields {i8*}:array1
      -  %array2 = malloc [12 x i8], i32 %size         ; yields {[12 x i8]*}:array2
      -  %array3 = malloc i32, i32 4, align 1024       ; yields {i32*}:array3
      -  %array4 = malloc i32, align 1024              ; yields {i32*}:array4
      -
      - -

      Note that the code generator does not yet respect the alignment value.

      - -
      - - - - -
      - -
      Syntax:
      -
      -  free <type> <value>                           ; yields {void}
      -
      - -
      Overview:
      -

      The 'free' instruction returns memory back to the unused memory heap - to be reallocated in the future.

      - -
      Arguments:
      -

      'value' shall be a pointer value that points to a value that was - allocated with the 'malloc' instruction.

      - -
      Semantics:
      -

      Access to the memory pointed to by the pointer is no longer defined after - this instruction executes. If the pointer is null, the operation is a - noop.

      - -
      Example:
      -
      -  %array  = malloc [4 x i8]                     ; yields {[4 x i8]*}:array
      -            free   [4 x i8]* %array
      -
      - -
      - - - @@ -6624,7 +6540,8 @@
      Example:
      -%ptr      = malloc i32
      +%mallocP  = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
      +%ptr      = bitcast i8* %mallocP to i32*
                   store i32 4, %ptr
       
       %result1  = load i32* %ptr      ; yields {i32}:result1 = 4
      @@ -6675,7 +6592,8 @@
       
       
      Examples:
      -%ptr      = malloc i32
      +%mallocP  = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
      +%ptr      = bitcast i8* %mallocP to i32*
                   store i32 4, %ptr
       
       %val1     = add i32 4, 4
      @@ -6730,7 +6648,8 @@
       
       
      Examples:
      -%ptr      = malloc i32
      +%mallocP  = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
      +%ptr      = bitcast i8* %mallocP to i32*
                   store i32 4, %ptr
       
       %val1     = add i32 4, 4
      @@ -6785,8 +6704,9 @@
       
       
      Examples:
      -%ptr      = malloc i32
      -        store i32 4, %ptr
      +%mallocP  = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
      +%ptr      = bitcast i8* %mallocP to i32*
      +            store i32 4, %ptr
       %result1  = call i32 @llvm.atomic.load.add.i32.p0i32( i32* %ptr, i32 4 )
                                       ; yields {i32}:result1 = 4
       %result2  = call i32 @llvm.atomic.load.add.i32.p0i32( i32* %ptr, i32 2 )
      @@ -6836,8 +6756,9 @@
       
       
      Examples:
      -%ptr      = malloc i32
      -        store i32 8, %ptr
      +%mallocP  = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
      +%ptr      = bitcast i8* %mallocP to i32*
      +            store i32 8, %ptr
       %result1  = call i32 @llvm.atomic.load.sub.i32.p0i32( i32* %ptr, i32 4 )
                                       ; yields {i32}:result1 = 8
       %result2  = call i32 @llvm.atomic.load.sub.i32.p0i32( i32* %ptr, i32 2 )
      @@ -6913,8 +6834,9 @@
       
       
      Examples:
      -%ptr      = malloc i32
      -        store i32 0x0F0F, %ptr
      +%mallocP  = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
      +%ptr      = bitcast i8* %mallocP to i32*
      +            store i32 0x0F0F, %ptr
       %result0  = call i32 @llvm.atomic.load.nand.i32.p0i32( i32* %ptr, i32 0xFF )
                                       ; yields {i32}:result0 = 0x0F0F
       %result1  = call i32 @llvm.atomic.load.and.i32.p0i32( i32* %ptr, i32 0xFF )
      @@ -6991,8 +6913,9 @@
       
       
      Examples:
      -%ptr      = malloc i32
      -        store i32 7, %ptr
      +%mallocP  = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
      +%ptr      = bitcast i8* %mallocP to i32*
      +            store i32 7, %ptr
       %result0  = call i32 @llvm.atomic.load.min.i32.p0i32( i32* %ptr, i32 -2 )
                                       ; yields {i32}:result0 = 7
       %result1  = call i32 @llvm.atomic.load.max.i32.p0i32( i32* %ptr, i32 8 )
      
      
      
      
      From evan.cheng at apple.com  Mon Oct 26 18:45:59 2009
      From: evan.cheng at apple.com (Evan Cheng)
      Date: Mon, 26 Oct 2009 23:45:59 -0000
      Subject: [llvm-commits] [llvm] r85178 - in /llvm/trunk/lib/Target/ARM:
       ARMInstrInfo.td AsmPrinter/ARMAsmPrinter.cpp
      Message-ID: <200910262345.n9QNjxRn012162@zion.cs.uiuc.edu>
      
      Author: evancheng
      Date: Mon Oct 26 18:45:59 2009
      New Revision: 85178
      
      URL: http://llvm.org/viewvc/llvm-project?rev=85178&view=rev
      Log:
      Change ARM asm strings to separate opcode from operands with a tab instead of a space.
      
      Modified:
          llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
          llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
      
      Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=85178&r1=85177&r2=85178&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
      +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Mon Oct 26 18:45:59 2009
      @@ -370,19 +370,19 @@
       multiclass AsI1_bin_irs opcod, string opc, PatFrag opnode,
                               bit Commutable = 0> {
         def ri : AsI1 {
           let Inst{25} = 1;
         }
         def rr : AsI1 {
           let Inst{4} = 0;
           let Inst{25} = 0;
           let isCommutable = Commutable;
         }
         def rs : AsI1 {
           let Inst{4} = 1;
           let Inst{7} = 0;
      @@ -396,13 +396,13 @@
       multiclass AI1_bin_s_irs opcod, string opc, PatFrag opnode,
                                bit Commutable = 0> {
         def ri : AI1 {
           let Inst{20} = 1;
           let Inst{25} = 1;
         }
         def rr : AI1 {
           let isCommutable = Commutable;
           let Inst{4} = 0;
      @@ -410,7 +410,7 @@
           let Inst{25} = 0;
         }
         def rs : AI1 {
           let Inst{4} = 1;
           let Inst{7} = 0;
      @@ -427,13 +427,13 @@
       multiclass AI1_cmp_irs opcod, string opc, PatFrag opnode,
                              bit Commutable = 0> {
         def ri : AI1 {
           let Inst{20} = 1;
           let Inst{25} = 1;
         }
         def rr : AI1 {
           let Inst{4} = 0;
           let Inst{20} = 1;
      @@ -441,7 +441,7 @@
           let isCommutable = Commutable;
         }
         def rs : AI1 {
           let Inst{4} = 1;
           let Inst{7} = 0;
      @@ -456,13 +456,13 @@
       /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
       multiclass AI_unary_rrot opcod, string opc, PatFrag opnode> {
         def r     : AExtI,
                     Requires<[IsARM, HasV6]> {
                       let Inst{19-16} = 0b1111;
                     }
         def r_rot : AExtI,
                     Requires<[IsARM, HasV6]> {
                       let Inst{19-16} = 0b1111;
      @@ -473,11 +473,11 @@
       /// register and one whose operand is a register rotated by 8/16/24.
       multiclass AI_bin_rrot opcod, string opc, PatFrag opnode> {
         def rr     : AExtI,
                         Requires<[IsARM, HasV6]>;
         def rr_rot : AExtI,
                         Requires<[IsARM, HasV6]>;
      @@ -488,13 +488,13 @@
       multiclass AI1_adde_sube_irs opcod, string opc, PatFrag opnode,
                                    bit Commutable = 0> {
         def ri : AsI1,
                      Requires<[IsARM, CarryDefIsUnused]> {
           let Inst{25} = 1;
         }
         def rr : AsI1,
                      Requires<[IsARM, CarryDefIsUnused]> {
           let isCommutable = Commutable;
      @@ -502,7 +502,7 @@
           let Inst{25} = 0;
         }
         def rs : AsI1,
                      Requires<[IsARM, CarryDefIsUnused]> {
           let Inst{4} = 1;
      @@ -511,7 +511,7 @@
         }
         // Carry setting variants
         def Sri : AXI1,
                      Requires<[IsARM, CarryDefIsUsed]> {
           let Defs = [CPSR];
      @@ -519,7 +519,7 @@
           let Inst{25} = 1;
         }
         def Srr : AXI1,
                      Requires<[IsARM, CarryDefIsUsed]> {
           let Defs = [CPSR];
      @@ -528,7 +528,7 @@
           let Inst{25} = 0;
         }
         def Srs : AXI1,
                      Requires<[IsARM, CarryDefIsUsed]> {
           let Defs = [CPSR];
      @@ -579,42 +579,42 @@
       // Address computation and loads and stores in PIC mode.
       let isNotDuplicable = 1 in {
       def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
      -                  Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p $dst, pc, $a",
      +                  Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a",
                          [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
       
       let AddedComplexity = 10 in {
       let canFoldAsLoad = 1 in
       def PICLDR  : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
      -                  Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p $dst, $addr",
      +                  Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr",
                         [(set GPR:$dst, (load addrmodepc:$addr))]>;
       
       def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
      -                 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr${p}h $dst, $addr",
      +                Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr${p}h\t$dst, $addr",
                         [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
       
       def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
      -                 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr${p}b $dst, $addr",
      +                Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr${p}b\t$dst, $addr",
                         [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
       
       def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
      -                Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr${p}sh $dst, $addr",
      +               Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr${p}sh\t$dst, $addr",
                         [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
       
       def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
      -                Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr${p}sb $dst, $addr",
      +               Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr${p}sb\t$dst, $addr",
                         [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
       }
       let AddedComplexity = 10 in {
       def PICSTR  : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
      -               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p $src, $addr",
      +               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr",
                      [(store GPR:$src, addrmodepc:$addr)]>;
       
       def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
      -               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr${p}h $src, $addr",
      +               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr${p}h\t$src, $addr",
                      [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
       
       def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
      -               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr${p}b $src, $addr",
      +               Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr${p}b\t$src, $addr",
                      [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
       }
       } // isNotDuplicable = 1
      @@ -624,10 +624,10 @@
       // assembler.
       def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
                           Pseudo, IIC_iALUi,
      -            !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
      -                                  "${:private}PCRELL${:uid}+8))\n"),
      -                       !strconcat("${:private}PCRELL${:uid}:\n\t",
      -                                  "add$p $dst, pc, #${:private}PCRELV${:uid}")),
      +           !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
      +                                 "${:private}PCRELL${:uid}+8))\n"),
      +                      !strconcat("${:private}PCRELL${:uid}:\n\t",
      +                                 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
                          []>;
       
       def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
      @@ -637,7 +637,7 @@
                                "(${label}_${id}-(",
                                         "${:private}PCRELL${:uid}+8))\n"),
                              !strconcat("${:private}PCRELL${:uid}:\n\t",
      -                                  "add$p $dst, pc, #${:private}PCRELV${:uid}")),
      +                                  "add$p\t$dst, pc, #${:private}PCRELV${:uid}")),
                          []> {
           let Inst{25} = 1;
       }
      @@ -648,7 +648,7 @@
       
       let isReturn = 1, isTerminator = 1, isBarrier = 1 in
         def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br, 
      -                  "bx", " lr", [(ARMretflag)]> {
      +                  "bx", "\tlr", [(ARMretflag)]> {
         let Inst{7-4}   = 0b0001;
         let Inst{19-8}  = 0b111111111111;
         let Inst{27-20} = 0b00010010;
      @@ -660,7 +660,7 @@
           hasExtraDefRegAllocReq = 1 in
         def LDM_RET : AXI4ld<(outs),
                           (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
      -                    LdStMulFrm, IIC_Br, "ldm${p}${addr:submode} $addr, $wb",
      +                    LdStMulFrm, IIC_Br, "ldm${p}${addr:submode}\t$addr, $wb",
                           []>;
       
       // On non-Darwin platforms R9 is callee-saved.
      @@ -670,18 +670,18 @@
                 D16, D17, D18, D19, D20, D21, D22, D23,
                 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
         def BL  : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
      -                IIC_Br, "bl ${func:call}",
      +                IIC_Br, "bl\t${func:call}",
                       [(ARMcall tglobaladdr:$func)]>,
                   Requires<[IsARM, IsNotDarwin]>;
       
         def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
      -                   IIC_Br, "bl", " ${func:call}",
      +                   IIC_Br, "bl", "\t${func:call}",
                          [(ARMcall_pred tglobaladdr:$func)]>,
                       Requires<[IsARM, IsNotDarwin]>;
       
         // ARMv5T and above
         def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
      -                IIC_Br, "blx $func",
      +                IIC_Br, "blx\t$func",
                       [(ARMcall GPR:$func)]>,
                   Requires<[IsARM, HasV5T, IsNotDarwin]> {
           let Inst{7-4}   = 0b0011;
      @@ -691,7 +691,7 @@
       
         // ARMv4T
         def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
      -                  IIC_Br, "mov lr, pc\n\tbx $func",
      +                  IIC_Br, "mov\tlr, pc\n\tbx\t$func",
                         [(ARMcall_nolink GPR:$func)]>,
                  Requires<[IsARM, IsNotDarwin]> {
           let Inst{7-4}   = 0b0001;
      @@ -707,17 +707,17 @@
                 D16, D17, D18, D19, D20, D21, D22, D23,
                 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
         def BLr9  : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
      -                IIC_Br, "bl ${func:call}",
      +                IIC_Br, "bl\t${func:call}",
                       [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]>;
       
         def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
      -                   IIC_Br, "bl", " ${func:call}",
      +                   IIC_Br, "bl", "\t${func:call}",
                          [(ARMcall_pred tglobaladdr:$func)]>,
                         Requires<[IsARM, IsDarwin]>;
       
         // ARMv5T and above
         def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
      -                IIC_Br, "blx $func",
      +                IIC_Br, "blx\t$func",
                       [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
           let Inst{7-4}   = 0b0011;
           let Inst{19-8}  = 0b111111111111;
      @@ -726,7 +726,7 @@
       
         // ARMv4T
         def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
      -                  IIC_Br, "mov lr, pc\n\tbx $func",
      +                  IIC_Br, "mov\tlr, pc\n\tbx\t$func",
                         [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> {
           let Inst{7-4}   = 0b0001;
           let Inst{19-8}  = 0b111111111111;
      @@ -739,11 +739,11 @@
         let isBarrier = 1 in {
           let isPredicable = 1 in
           def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
      -                "b $target", [(br bb:$target)]>;
      +                "b\t$target", [(br bb:$target)]>;
       
         let isNotDuplicable = 1, isIndirectBranch = 1 in {
         def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
      -                    IIC_Br, "mov pc, $target \n$jt",
      +                    IIC_Br, "mov\tpc, $target \n$jt",
                           [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
           let Inst{20}    = 0; // S Bit
           let Inst{24-21} = 0b1101;
      @@ -751,7 +751,7 @@
         }
         def BR_JTm : JTI<(outs),
                          (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
      -                   IIC_Br, "ldr pc, $target \n$jt",
      +                   IIC_Br, "ldr\tpc, $target \n$jt",
                          [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
                            imm:$id)]> {
           let Inst{20}    = 1; // L bit
      @@ -762,7 +762,7 @@
         }
         def BR_JTadd : JTI<(outs),
                          (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
      -                    IIC_Br, "add pc, $target, $idx \n$jt",
      +                    IIC_Br, "add\tpc, $target, $idx \n$jt",
                           [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
                             imm:$id)]> {
           let Inst{20}    = 0; // S bit
      @@ -775,7 +775,7 @@
         // FIXME: should be able to write a pattern for ARMBrcond, but can't use
         // a two-value operand where a dag node expects two operands. :( 
         def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
      -               IIC_Br, "b", " $target",
      +               IIC_Br, "b", "\t$target",
                      [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
       }
       
      @@ -786,140 +786,140 @@
       // Load
       let canFoldAsLoad = 1, isReMaterializable = 1 in 
       def LDR  : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
      -               "ldr", " $dst, $addr",
      +               "ldr", "\t$dst, $addr",
                      [(set GPR:$dst, (load addrmode2:$addr))]>;
       
       // Special LDR for loads from non-pc-relative constpools.
       let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
       def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
      -                 "ldr", " $dst, $addr", []>;
      +                 "ldr", "\t$dst, $addr", []>;
       
       // Loads with zero extension
       def LDRH  : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
      -                  IIC_iLoadr, "ldr", "h $dst, $addr",
      +                  IIC_iLoadr, "ldr", "h\t$dst, $addr",
                         [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
       
       def LDRB  : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, 
      -                  IIC_iLoadr, "ldr", "b $dst, $addr",
      +                  IIC_iLoadr, "ldr", "b\t$dst, $addr",
                         [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
       
       // Loads with sign extension
       def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
      -                   IIC_iLoadr, "ldr", "sh $dst, $addr",
      +                   IIC_iLoadr, "ldr", "sh\t$dst, $addr",
                          [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
       
       def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
      -                   IIC_iLoadr, "ldr", "sb $dst, $addr",
      +                   IIC_iLoadr, "ldr", "sb\t$dst, $addr",
                          [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
       
       let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
       // Load doubleword
       def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
      -                 IIC_iLoadr, "ldr", "d $dst1, $addr",
      +                 IIC_iLoadr, "ldr", "d\t$dst1, $addr",
                        []>, Requires<[IsARM, HasV5TE]>;
       
       // Indexed loads
       def LDR_PRE  : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
                            (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
      -                     "ldr", " $dst, $addr!", "$addr.base = $base_wb", []>;
      +                     "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
       
       def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
                            (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
      -                     "ldr", " $dst, [$base], $offset", "$base = $base_wb", []>;
      +                     "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
       
       def LDRH_PRE  : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
                            (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
      -                     "ldr", "h $dst, $addr!", "$addr.base = $base_wb", []>;
      +                     "ldr", "h\t$dst, $addr!", "$addr.base = $base_wb", []>;
       
       def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
                            (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
      -                     "ldr", "h $dst, [$base], $offset", "$base = $base_wb", []>;
      +                     "ldr", "h\t$dst, [$base], $offset", "$base = $base_wb", []>;
       
       def LDRB_PRE  : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
                            (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
      -                     "ldr", "b $dst, $addr!", "$addr.base = $base_wb", []>;
      +                     "ldr", "b\t$dst, $addr!", "$addr.base = $base_wb", []>;
       
       def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
                            (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
      -                     "ldr", "b $dst, [$base], $offset", "$base = $base_wb", []>;
      +                     "ldr", "b\t$dst, [$base], $offset", "$base = $base_wb", []>;
       
       def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
                             (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
      -                      "ldr", "sh $dst, $addr!", "$addr.base = $base_wb", []>;
      +                      "ldr", "sh\t$dst, $addr!", "$addr.base = $base_wb", []>;
       
       def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
                             (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
      -                    "ldr", "sh $dst, [$base], $offset", "$base = $base_wb", []>;
      +                    "ldr", "sh\t$dst, [$base], $offset", "$base = $base_wb", []>;
       
       def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
                             (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
      -                      "ldr", "sb $dst, $addr!", "$addr.base = $base_wb", []>;
      +                      "ldr", "sb\t$dst, $addr!", "$addr.base = $base_wb", []>;
       
       def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
                             (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
      -                    "ldr", "sb $dst, [$base], $offset", "$base = $base_wb", []>;
      +                    "ldr", "sb\t$dst, [$base], $offset", "$base = $base_wb", []>;
       }
       
       // Store
       def STR  : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
      -               "str", " $src, $addr",
      +               "str", "\t$src, $addr",
                      [(store GPR:$src, addrmode2:$addr)]>;
       
       // Stores with truncate
       def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, IIC_iStorer,
      -               "str", "h $src, $addr",
      +               "str", "h\t$src, $addr",
                      [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
       
       def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
      -               "str", "b $src, $addr",
      +               "str", "b\t$src, $addr",
                      [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
       
       // Store doubleword
       let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
       def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
                      StMiscFrm, IIC_iStorer,
      -               "str", "d $src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
      +               "str", "d\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
       
       // Indexed stores
       def STR_PRE  : AI2stwpr<(outs GPR:$base_wb),
                            (ins GPR:$src, GPR:$base, am2offset:$offset), 
                            StFrm, IIC_iStoreru,
      -                    "str", " $src, [$base, $offset]!", "$base = $base_wb",
      +                    "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
                           [(set GPR:$base_wb,
                             (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
       
       def STR_POST : AI2stwpo<(outs GPR:$base_wb),
                            (ins GPR:$src, GPR:$base,am2offset:$offset), 
                            StFrm, IIC_iStoreru,
      -                    "str", " $src, [$base], $offset", "$base = $base_wb",
      +                    "str", "\t$src, [$base], $offset", "$base = $base_wb",
                           [(set GPR:$base_wb,
                             (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
       
       def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
                            (ins GPR:$src, GPR:$base,am3offset:$offset), 
                            StMiscFrm, IIC_iStoreru,
      -                     "str", "h $src, [$base, $offset]!", "$base = $base_wb",
      +                     "str", "h\t$src, [$base, $offset]!", "$base = $base_wb",
                           [(set GPR:$base_wb,
                             (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
       
       def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
                            (ins GPR:$src, GPR:$base,am3offset:$offset), 
                            StMiscFrm, IIC_iStoreru,
      -                     "str", "h $src, [$base], $offset", "$base = $base_wb",
      +                     "str", "h\t$src, [$base], $offset", "$base = $base_wb",
                           [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
                                                GPR:$base, am3offset:$offset))]>;
       
       def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
                            (ins GPR:$src, GPR:$base,am2offset:$offset), 
                            StFrm, IIC_iStoreru,
      -                     "str", "b $src, [$base, $offset]!", "$base = $base_wb",
      +                     "str", "b\t$src, [$base, $offset]!", "$base = $base_wb",
                           [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
                                                GPR:$base, am2offset:$offset))]>;
       
       def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
                            (ins GPR:$src, GPR:$base,am2offset:$offset), 
                            StFrm, IIC_iStoreru,
      -                     "str", "b $src, [$base], $offset", "$base = $base_wb",
      +                     "str", "b\t$src, [$base], $offset", "$base = $base_wb",
                           [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
                                                GPR:$base, am2offset:$offset))]>;
       
      @@ -930,13 +930,13 @@
       let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
       def LDM : AXI4ld<(outs),
                      (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
      -               LdStMulFrm, IIC_iLoadm, "ldm${p}${addr:submode} $addr, $wb",
      +               LdStMulFrm, IIC_iLoadm, "ldm${p}${addr:submode}\t$addr, $wb",
                      []>;
       
       let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
       def STM : AXI4st<(outs),
                      (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
      -               LdStMulFrm, IIC_iStorem, "stm${p}${addr:submode} $addr, $wb",
      +               LdStMulFrm, IIC_iStorem, "stm${p}${addr:submode}\t$addr, $wb",
                      []>;
       
       //===----------------------------------------------------------------------===//
      @@ -945,14 +945,14 @@
       
       let neverHasSideEffects = 1 in
       def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
      -                "mov", " $dst, $src", []>, UnaryDP {
      +                "mov", "\t$dst, $src", []>, UnaryDP {
         let Inst{4} = 0;
         let Inst{25} = 0;
       }
       
       def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), 
                       DPSoRegFrm, IIC_iMOVsr,
      -                "mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
      +                "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
         let Inst{4} = 1;
         let Inst{7} = 0;
         let Inst{25} = 0;
      @@ -960,14 +960,14 @@
       
       let isReMaterializable = 1, isAsCheapAsAMove = 1 in
       def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
      -                "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
      +                "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
         let Inst{25} = 1;
       }
       
       let isReMaterializable = 1, isAsCheapAsAMove = 1 in
       def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src), 
                        DPFrm, IIC_iMOVi,
      -                 "movw", " $dst, $src",
      +                 "movw", "\t$dst, $src",
                        [(set GPR:$dst, imm0_65535:$src)]>,
                        Requires<[IsARM, HasV6T2]> {
         let Inst{20} = 0;
      @@ -977,7 +977,7 @@
       let Constraints = "$src = $dst" in
       def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
                         DPFrm, IIC_iMOVi,
      -                  "movt", " $dst, $imm", 
      +                  "movt", "\t$dst, $imm", 
                         [(set GPR:$dst,
                               (or (and GPR:$src, 0xffff), 
                                   lo16AllZero:$imm))]>, UnaryDP,
      @@ -991,7 +991,7 @@
       
       let Uses = [CPSR] in
       def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
      -                 "mov", " $dst, $src, rrx",
      +                 "mov", "\t$dst, $src, rrx",
                        [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
       
       // These aren't really mov instructions, but we have to define them this way
      @@ -999,10 +999,10 @@
       
       let Defs = [CPSR] in {
       def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, 
      -                      IIC_iMOVsi, "mov", "s $dst, $src, lsr #1",
      +                      IIC_iMOVsi, "mov", "s\t$dst, $src, lsr #1",
                             [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
       def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
      -                      IIC_iMOVsi, "mov", "s $dst, $src, asr #1",
      +                      IIC_iMOVsi, "mov", "s\t$dst, $src, asr #1",
                             [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
       }
       
      @@ -1053,7 +1053,7 @@
       def SBFX  : I<(outs GPR:$dst),
                     (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
                      AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
      -               "sbfx", " $dst, $src, $lsb, $width", "", []>,
      +               "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
                      Requires<[IsARM, HasV6T2]> {
         let Inst{27-21} = 0b0111101;
         let Inst{6-4}   = 0b101;
      @@ -1062,7 +1062,7 @@
       def UBFX  : I<(outs GPR:$dst),
                     (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
                      AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
      -               "ubfx", " $dst, $src, $lsb, $width", "", []>,
      +               "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
                      Requires<[IsARM, HasV6T2]> {
         let Inst{27-21} = 0b0111111;
         let Inst{6-4}   = 0b101;
      @@ -1090,14 +1090,14 @@
       
       // These don't define reg/reg forms, because they are handled above.
       def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
      -                  IIC_iALUi, "rsb", " $dst, $a, $b",
      +                  IIC_iALUi, "rsb", "\t$dst, $a, $b",
                         [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
           let Inst{20} = 0;
           let Inst{25} = 1;
       }
       
       def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
      -                  IIC_iALUsr, "rsb", " $dst, $a, $b",
      +                  IIC_iALUsr, "rsb", "\t$dst, $a, $b",
                         [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
           let Inst{4} = 1;
           let Inst{7} = 0;
      @@ -1108,13 +1108,13 @@
       // RSB with 's' bit set.
       let Defs = [CPSR] in {
       def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
      -                 IIC_iALUi, "rsb", "s $dst, $a, $b",
      +                 IIC_iALUi, "rsb", "s\t$dst, $a, $b",
                        [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
           let Inst{20} = 1;
           let Inst{25} = 1;
       }
       def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
      -                 IIC_iALUsr, "rsb", "s $dst, $a, $b",
      +                 IIC_iALUsr, "rsb", "s\t$dst, $a, $b",
                        [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
           let Inst{4} = 1;
           let Inst{7} = 0;
      @@ -1125,14 +1125,14 @@
       
       let Uses = [CPSR] in {
       def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
      -                 DPFrm, IIC_iALUi, "rsc", " $dst, $a, $b",
      +                 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
                        [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
                        Requires<[IsARM, CarryDefIsUnused]> {
           let Inst{20} = 0;
           let Inst{25} = 1;
       }
       def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
      -                 DPSoRegFrm, IIC_iALUsr, "rsc", " $dst, $a, $b",
      +                 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
                        [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
                        Requires<[IsARM, CarryDefIsUnused]> {
           let Inst{4} = 1;
      @@ -1145,14 +1145,14 @@
       // FIXME: Allow these to be predicated.
       let Defs = [CPSR], Uses = [CPSR] in {
       def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
      -                  DPFrm, IIC_iALUi, "rscs $dst, $a, $b",
      +                  DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
                         [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
                         Requires<[IsARM, CarryDefIsUnused]> {
           let Inst{20} = 1;
           let Inst{25} = 1;
       }
       def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
      -                  DPSoRegFrm, IIC_iALUsr, "rscs $dst, $a, $b",
      +                  DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
                         [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
                         Requires<[IsARM, CarryDefIsUnused]> {
           let Inst{4} = 1;
      @@ -1193,7 +1193,7 @@
       
       def BFC    : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
                      AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
      -               "bfc", " $dst, $imm", "$src = $dst",
      +               "bfc", "\t$dst, $imm", "$src = $dst",
                      [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
                      Requires<[IsARM, HasV6T2]> {
         let Inst{27-21} = 0b0111110;
      @@ -1201,19 +1201,19 @@
       }
       
       def  MVNr  : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
      -                  "mvn", " $dst, $src",
      +                  "mvn", "\t$dst, $src",
                         [(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
         let Inst{4} = 0;
       }
       def  MVNs  : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
      -                  IIC_iMOVsr, "mvn", " $dst, $src",
      +                  IIC_iMOVsr, "mvn", "\t$dst, $src",
                         [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
         let Inst{4} = 1;
         let Inst{7} = 0;
       }
       let isReMaterializable = 1, isAsCheapAsAMove = 1 in
       def  MVNi  : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm, 
      -                  IIC_iMOVi, "mvn", " $dst, $imm",
      +                  IIC_iMOVi, "mvn", "\t$dst, $imm",
                         [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
           let Inst{25} = 1;
       }
      @@ -1227,15 +1227,15 @@
       
       let isCommutable = 1 in
       def MUL   : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
      -                   IIC_iMUL32, "mul", " $dst, $a, $b",
      +                   IIC_iMUL32, "mul", "\t$dst, $a, $b",
                          [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
       
       def MLA   : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
      -                    IIC_iMAC32, "mla", " $dst, $a, $b, $c",
      +                    IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
                          [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
       
       def MLS   : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
      -                   IIC_iMAC32, "mls", " $dst, $a, $b, $c",
      +                   IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
                          [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
                          Requires<[IsARM, HasV6T2]>;
       
      @@ -1244,31 +1244,31 @@
       let isCommutable = 1 in {
       def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
                                      (ins GPR:$a, GPR:$b), IIC_iMUL64,
      -                    "smull", " $ldst, $hdst, $a, $b", []>;
      +                    "smull", "\t$ldst, $hdst, $a, $b", []>;
       
       def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
                                      (ins GPR:$a, GPR:$b), IIC_iMUL64,
      -                    "umull", " $ldst, $hdst, $a, $b", []>;
      +                    "umull", "\t$ldst, $hdst, $a, $b", []>;
       }
       
       // Multiply + accumulate
       def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
                                      (ins GPR:$a, GPR:$b), IIC_iMAC64,
      -                    "smlal", " $ldst, $hdst, $a, $b", []>;
      +                    "smlal", "\t$ldst, $hdst, $a, $b", []>;
       
       def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
                                      (ins GPR:$a, GPR:$b), IIC_iMAC64,
      -                    "umlal", " $ldst, $hdst, $a, $b", []>;
      +                    "umlal", "\t$ldst, $hdst, $a, $b", []>;
       
       def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
                                      (ins GPR:$a, GPR:$b), IIC_iMAC64,
      -                    "umaal", " $ldst, $hdst, $a, $b", []>,
      +                    "umaal", "\t$ldst, $hdst, $a, $b", []>,
                           Requires<[IsARM, HasV6]>;
       } // neverHasSideEffects
       
       // Most significant word multiply
       def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
      -               IIC_iMUL32, "smmul", " $dst, $a, $b",
      +               IIC_iMUL32, "smmul", "\t$dst, $a, $b",
                      [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
                   Requires<[IsARM, HasV6]> {
         let Inst{7-4}   = 0b0001;
      @@ -1276,7 +1276,7 @@
       }
       
       def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
      -               IIC_iMAC32, "smmla", " $dst, $a, $b, $c",
      +               IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
                      [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
                   Requires<[IsARM, HasV6]> {
         let Inst{7-4}   = 0b0001;
      @@ -1284,7 +1284,7 @@
       
       
       def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
      -               IIC_iMAC32, "smmls", " $dst, $a, $b, $c",
      +               IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
                      [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
                   Requires<[IsARM, HasV6]> {
         let Inst{7-4}   = 0b1101;
      @@ -1292,7 +1292,7 @@
       
       multiclass AI_smul {
         def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
      -              IIC_iMUL32, !strconcat(opc, "bb"), " $dst, $a, $b",
      +              IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
                     [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
                                             (sext_inreg GPR:$b, i16)))]>,
                  Requires<[IsARM, HasV5TE]> {
      @@ -1301,7 +1301,7 @@
                  }
       
         def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
      -              IIC_iMUL32, !strconcat(opc, "bt"), " $dst, $a, $b",
      +              IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b",
                     [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
                                             (sra GPR:$b, (i32 16))))]>,
                  Requires<[IsARM, HasV5TE]> {
      @@ -1310,7 +1310,7 @@
                  }
       
         def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
      -              IIC_iMUL32, !strconcat(opc, "tb"), " $dst, $a, $b",
      +              IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
                     [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
                                             (sext_inreg GPR:$b, i16)))]>,
                  Requires<[IsARM, HasV5TE]> {
      @@ -1319,7 +1319,7 @@
                  }
       
         def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
      -              IIC_iMUL32, !strconcat(opc, "tt"), " $dst, $a, $b",
      +              IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
                     [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
                                             (sra GPR:$b, (i32 16))))]>,
                   Requires<[IsARM, HasV5TE]> {
      @@ -1328,7 +1328,7 @@
                  }
       
         def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
      -              IIC_iMUL16, !strconcat(opc, "wb"), " $dst, $a, $b",
      +              IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
                     [(set GPR:$dst, (sra (opnode GPR:$a,
                                           (sext_inreg GPR:$b, i16)), (i32 16)))]>,
                  Requires<[IsARM, HasV5TE]> {
      @@ -1337,7 +1337,7 @@
                  }
       
         def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
      -              IIC_iMUL16, !strconcat(opc, "wt"), " $dst, $a, $b",
      +              IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
                     [(set GPR:$dst, (sra (opnode GPR:$a,
                                           (sra GPR:$b, (i32 16))), (i32 16)))]>,
                   Requires<[IsARM, HasV5TE]> {
      @@ -1349,7 +1349,7 @@
       
       multiclass AI_smla {
         def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
      -              IIC_iMAC16, !strconcat(opc, "bb"), " $dst, $a, $b, $acc",
      +              IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
                     [(set GPR:$dst, (add GPR:$acc,
                                      (opnode (sext_inreg GPR:$a, i16),
                                              (sext_inreg GPR:$b, i16))))]>,
      @@ -1359,7 +1359,7 @@
                  }
       
         def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
      -              IIC_iMAC16, !strconcat(opc, "bt"), " $dst, $a, $b, $acc",
      +              IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
                     [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
                                                            (sra GPR:$b, (i32 16)))))]>,
                  Requires<[IsARM, HasV5TE]> {
      @@ -1368,7 +1368,7 @@
                  }
       
         def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
      -              IIC_iMAC16, !strconcat(opc, "tb"), " $dst, $a, $b, $acc",
      +              IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
                     [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
                                                        (sext_inreg GPR:$b, i16))))]>,
                  Requires<[IsARM, HasV5TE]> {
      @@ -1377,16 +1377,16 @@
                  }
       
         def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
      -              IIC_iMAC16, !strconcat(opc, "tt"), " $dst, $a, $b, $acc",
      -              [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
      -                                                     (sra GPR:$b, (i32 16)))))]>,
      +              IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
      +             [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
      +                                                    (sra GPR:$b, (i32 16)))))]>,
                   Requires<[IsARM, HasV5TE]> {
                    let Inst{5} = 1;
                    let Inst{6} = 1;
                  }
       
         def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
      -              IIC_iMAC16, !strconcat(opc, "wb"), " $dst, $a, $b, $acc",
      +              IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
                     [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
                                              (sext_inreg GPR:$b, i16)), (i32 16))))]>,
                  Requires<[IsARM, HasV5TE]> {
      @@ -1395,7 +1395,7 @@
                  }
       
         def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
      -              IIC_iMAC16, !strconcat(opc, "wt"), " $dst, $a, $b, $acc",
      +              IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
                     [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
                                                (sra GPR:$b, (i32 16))), (i32 16))))]>,
                   Requires<[IsARM, HasV5TE]> {
      @@ -1415,7 +1415,7 @@
       //
       
       def CLZ  : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
      -              "clz", " $dst, $src",
      +              "clz", "\t$dst, $src",
                     [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
         let Inst{7-4}   = 0b0001;
         let Inst{11-8}  = 0b1111;
      @@ -1423,7 +1423,7 @@
       }
       
       def REV  : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
      -              "rev", " $dst, $src",
      +              "rev", "\t$dst, $src",
                     [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
         let Inst{7-4}   = 0b0011;
         let Inst{11-8}  = 0b1111;
      @@ -1431,7 +1431,7 @@
       }
       
       def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
      -               "rev16", " $dst, $src",
      +               "rev16", "\t$dst, $src",
                      [(set GPR:$dst,
                          (or (and (srl GPR:$src, (i32 8)), 0xFF),
                              (or (and (shl GPR:$src, (i32 8)), 0xFF00),
      @@ -1444,7 +1444,7 @@
       }
       
       def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
      -               "revsh", " $dst, $src",
      +               "revsh", "\t$dst, $src",
                      [(set GPR:$dst,
                         (sext_inreg
                           (or (srl (and GPR:$src, 0xFF00), (i32 8)),
      @@ -1457,7 +1457,7 @@
       
       def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
                                        (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
      -               IIC_iALUsi, "pkhbt", " $dst, $src1, $src2, LSL $shamt",
      +               IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt",
                      [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
                                          (and (shl GPR:$src2, (i32 imm:$shamt)),
                                               0xFFFF0000)))]>,
      @@ -1474,7 +1474,7 @@
       
       def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
                                        (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
      -               IIC_iALUsi, "pkhtb", " $dst, $src1, $src2, ASR $shamt",
      +               IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt",
                      [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
                                          (and (sra GPR:$src2, imm16_31:$shamt),
                                               0xFFFF)))]>, Requires<[IsARM, HasV6]> {
      @@ -1520,7 +1520,7 @@
       // FIXME: should be able to write a pattern for ARMcmov, but can't use
       // a two-value operand where a dag node expects two operands. :( 
       def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
      -                IIC_iCMOVr, "mov", " $dst, $true",
      +                IIC_iCMOVr, "mov", "\t$dst, $true",
             [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
                       RegConstraint<"$false = $dst">, UnaryDP {
         let Inst{4} = 0;
      @@ -1529,7 +1529,7 @@
       
       def MOVCCs : AI1<0b1101, (outs GPR:$dst),
                               (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
      -                "mov", " $dst, $true",
      +                "mov", "\t$dst, $true",
          [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
                       RegConstraint<"$false = $dst">, UnaryDP {
         let Inst{4} = 1;
      @@ -1539,7 +1539,7 @@
       
       def MOVCCi : AI1<0b1101, (outs GPR:$dst),
                               (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
      -                "mov", " $dst, $true",
      +                "mov", "\t$dst, $true",
          [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
                       RegConstraint<"$false = $dst">, UnaryDP {
         let Inst{25} = 1;
      @@ -1554,7 +1554,7 @@
       let isCall = 1,
         Defs = [R0, R12, LR, CPSR] in {
         def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
      -               "bl __aeabi_read_tp",
      +               "bl\t__aeabi_read_tp",
                      [(set R0, ARMthread_pointer)]>;
       }
       
      @@ -1578,12 +1578,12 @@
         def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src),
                                      AddrModeNone, SizeSpecial, IndexModeNone,
                                      Pseudo, NoItinerary,
      -                               "str sp, [$src, #+8] @ eh_setjmp begin\n\t"
      -                               "add r12, pc, #8\n\t"
      -                               "str r12, [$src, #+4]\n\t"
      -                               "mov r0, #0\n\t"
      -                               "add pc, pc, #0\n\t"
      -                               "mov r0, #1 @ eh_setjmp end", "",
      +                               "str\tsp, [$src, #+8] @ eh_setjmp begin\n\t"
      +                               "add\tr12, pc, #8\n\t"
      +                               "str\tr12, [$src, #+4]\n\t"
      +                               "mov\tr0, #0\n\t"
      +                               "add\tpc, pc, #0\n\t"
      +                               "mov\tr0, #1 @ eh_setjmp end", "",
                                      [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
       }
       
      @@ -1603,7 +1603,7 @@
       let isReMaterializable = 1 in
       def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), 
                                Pseudo, IIC_iMOVi,
      -                         "mov", " $dst, $src",
      +                         "mov", "\t$dst, $src",
                                [(set GPR:$dst, so_imm2part:$src)]>,
                         Requires<[IsARM, NoV6T2]>;
       
      @@ -1626,7 +1626,7 @@
       // FIXME: Remove this when we can do generalized remat.
       let isReMaterializable = 1 in
       def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi,
      -                     "movw", " $dst, ${src:lo16}\n\tmovt${p} $dst, ${src:hi16}",
      +                    "movw", "\t$dst, ${src:lo16}\n\tmovt${p} $dst, ${src:hi16}",
                            [(set GPR:$dst, (i32 imm:$src))]>,
                      Requires<[IsARM, HasV6T2]>;
       
      
      Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=85178&r1=85177&r2=85178&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original)
      +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Mon Oct 26 18:45:59 2009
      @@ -419,7 +419,7 @@
         printSOImm(O, V1, VerboseAsm, MAI);
         O << "\n\torr";
         printPredicateOperand(MI, 2);
      -  O << " ";
      +  O << "\t";
         printOperand(MI, 0);
         O << ", ";
         printOperand(MI, 0);
      
      
      
      
      From resistor at mac.com  Mon Oct 26 18:55:48 2009
      From: resistor at mac.com (Owen Anderson)
      Date: Mon, 26 Oct 2009 23:55:48 -0000
      Subject: [llvm-commits] [llvm] r85179 -
      	/llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp
      Message-ID: <200910262355.n9QNtm5o012581@zion.cs.uiuc.edu>
      
      Author: resistor
      Date: Mon Oct 26 18:55:47 2009
      New Revision: 85179
      
      URL: http://llvm.org/viewvc/llvm-project?rev=85179&view=rev
      Log:
      Add a straight-forward implementation of SCCVN for aggressively eliminating scalar redundancies.
      
      Added:
          llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp
      
      Added: llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp?rev=85179&view=auto
      
      ==============================================================================
      --- llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp (added)
      +++ llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp Mon Oct 26 18:55:47 2009
      @@ -0,0 +1,721 @@
      +//===- SCCVN.cpp - Eliminate redundant values -----------------------------===//
      +//
      +//                     The LLVM Compiler Infrastructure
      +//
      +// This file is distributed under the University of Illinois Open Source
      +// License. See LICENSE.TXT for details.
      +//
      +//===----------------------------------------------------------------------===//
      +//
      +// This pass performs global value numbering to eliminate fully redundant
      +// instructions.  This is based on the paper "SCC-based Value Numbering"
      +// by Cooper, et al.
      +//
      +//===----------------------------------------------------------------------===//
      +
      +#define DEBUG_TYPE "sccvn"
      +#include "llvm/Transforms/Scalar.h"
      +#include "llvm/BasicBlock.h"
      +#include "llvm/Constants.h"
      +#include "llvm/DerivedTypes.h"
      +#include "llvm/Function.h"
      +#include "llvm/LLVMContext.h"
      +#include "llvm/Operator.h"
      +#include "llvm/Value.h"
      +#include "llvm/ADT/DenseMap.h"
      +#include "llvm/ADT/DepthFirstIterator.h"
      +#include "llvm/ADT/PostOrderIterator.h"
      +#include "llvm/ADT/SmallPtrSet.h"
      +#include "llvm/ADT/SmallVector.h"
      +#include "llvm/ADT/SparseBitVector.h"
      +#include "llvm/ADT/Statistic.h"
      +#include "llvm/Analysis/Dominators.h"
      +#include "llvm/Support/CFG.h"
      +#include "llvm/Support/CommandLine.h"
      +#include "llvm/Support/Debug.h"
      +#include "llvm/Support/ErrorHandling.h"
      +#include "llvm/Transforms/Utils/SSAUpdater.h"
      +#include 
      +using namespace llvm;
      +
      +STATISTIC(NumSCCVNInstr,  "Number of instructions deleted by SCCVN");
      +STATISTIC(NumSCCVNPhi,  "Number of phis deleted by SCCVN");
      +
      +//===----------------------------------------------------------------------===//
      +//                         ValueTable Class
      +//===----------------------------------------------------------------------===//
      +
      +/// This class holds the mapping between values and value numbers.  It is used
      +/// as an efficient mechanism to determine the expression-wise equivalence of
      +/// two values.
      +namespace {
      +  struct Expression {
      +    enum ExpressionOpcode { ADD, FADD, SUB, FSUB, MUL, FMUL,
      +                            UDIV, SDIV, FDIV, UREM, SREM,
      +                            FREM, SHL, LSHR, ASHR, AND, OR, XOR, ICMPEQ,
      +                            ICMPNE, ICMPUGT, ICMPUGE, ICMPULT, ICMPULE,
      +                            ICMPSGT, ICMPSGE, ICMPSLT, ICMPSLE, FCMPOEQ,
      +                            FCMPOGT, FCMPOGE, FCMPOLT, FCMPOLE, FCMPONE,
      +                            FCMPORD, FCMPUNO, FCMPUEQ, FCMPUGT, FCMPUGE,
      +                            FCMPULT, FCMPULE, FCMPUNE, EXTRACT, INSERT,
      +                            SHUFFLE, SELECT, TRUNC, ZEXT, SEXT, FPTOUI,
      +                            FPTOSI, UITOFP, SITOFP, FPTRUNC, FPEXT,
      +                            PTRTOINT, INTTOPTR, BITCAST, GEP, CALL, CONSTANT,
      +                            INSERTVALUE, EXTRACTVALUE, EMPTY, TOMBSTONE };
      +
      +    ExpressionOpcode opcode;
      +    const Type* type;
      +    SmallVector varargs;
      +
      +    Expression() { }
      +    Expression(ExpressionOpcode o) : opcode(o) { }
      +
      +    bool operator==(const Expression &other) const {
      +      if (opcode != other.opcode)
      +        return false;
      +      else if (opcode == EMPTY || opcode == TOMBSTONE)
      +        return true;
      +      else if (type != other.type)
      +        return false;
      +      else {
      +        if (varargs.size() != other.varargs.size())
      +          return false;
      +
      +        for (size_t i = 0; i < varargs.size(); ++i)
      +          if (varargs[i] != other.varargs[i])
      +            return false;
      +
      +        return true;
      +      }
      +    }
      +
      +    bool operator!=(const Expression &other) const {
      +      return !(*this == other);
      +    }
      +  };
      +
      +  class ValueTable {
      +    private:
      +      DenseMap valueNumbering;
      +      DenseMap expressionNumbering;
      +      DenseMap constantsNumbering;
      +
      +      uint32_t nextValueNumber;
      +
      +      Expression::ExpressionOpcode getOpcode(BinaryOperator* BO);
      +      Expression::ExpressionOpcode getOpcode(CmpInst* C);
      +      Expression::ExpressionOpcode getOpcode(CastInst* C);
      +      Expression create_expression(BinaryOperator* BO);
      +      Expression create_expression(CmpInst* C);
      +      Expression create_expression(ShuffleVectorInst* V);
      +      Expression create_expression(ExtractElementInst* C);
      +      Expression create_expression(InsertElementInst* V);
      +      Expression create_expression(SelectInst* V);
      +      Expression create_expression(CastInst* C);
      +      Expression create_expression(GetElementPtrInst* G);
      +      Expression create_expression(CallInst* C);
      +      Expression create_expression(Constant* C);
      +      Expression create_expression(ExtractValueInst* C);
      +      Expression create_expression(InsertValueInst* C);
      +    public:
      +      ValueTable() : nextValueNumber(1) { }
      +      uint32_t computeNumber(Value *V);
      +      uint32_t lookup(Value *V);
      +      void add(Value *V, uint32_t num);
      +      void clear();
      +      void clearExpressions();
      +      void erase(Value *v);
      +      unsigned size();
      +      void verifyRemoved(const Value *) const;
      +  };
      +}
      +
      +namespace llvm {
      +template <> struct DenseMapInfo {
      +  static inline Expression getEmptyKey() {
      +    return Expression(Expression::EMPTY);
      +  }
      +
      +  static inline Expression getTombstoneKey() {
      +    return Expression(Expression::TOMBSTONE);
      +  }
      +
      +  static unsigned getHashValue(const Expression e) {
      +    unsigned hash = e.opcode;
      +
      +    hash = ((unsigned)((uintptr_t)e.type >> 4) ^
      +            (unsigned)((uintptr_t)e.type >> 9));
      +
      +    for (SmallVector::const_iterator I = e.varargs.begin(),
      +         E = e.varargs.end(); I != E; ++I)
      +      hash = *I + hash * 37;
      +
      +    return hash;
      +  }
      +  static bool isEqual(const Expression &LHS, const Expression &RHS) {
      +    return LHS == RHS;
      +  }
      +  static bool isPod() { return true; }
      +};
      +}
      +
      +//===----------------------------------------------------------------------===//
      +//                     ValueTable Internal Functions
      +//===----------------------------------------------------------------------===//
      +Expression::ExpressionOpcode ValueTable::getOpcode(BinaryOperator* BO) {
      +  switch(BO->getOpcode()) {
      +  default: // THIS SHOULD NEVER HAPPEN
      +    llvm_unreachable("Binary operator with unknown opcode?");
      +  case Instruction::Add:  return Expression::ADD;
      +  case Instruction::FAdd: return Expression::FADD;
      +  case Instruction::Sub:  return Expression::SUB;
      +  case Instruction::FSub: return Expression::FSUB;
      +  case Instruction::Mul:  return Expression::MUL;
      +  case Instruction::FMul: return Expression::FMUL;
      +  case Instruction::UDiv: return Expression::UDIV;
      +  case Instruction::SDiv: return Expression::SDIV;
      +  case Instruction::FDiv: return Expression::FDIV;
      +  case Instruction::URem: return Expression::UREM;
      +  case Instruction::SRem: return Expression::SREM;
      +  case Instruction::FRem: return Expression::FREM;
      +  case Instruction::Shl:  return Expression::SHL;
      +  case Instruction::LShr: return Expression::LSHR;
      +  case Instruction::AShr: return Expression::ASHR;
      +  case Instruction::And:  return Expression::AND;
      +  case Instruction::Or:   return Expression::OR;
      +  case Instruction::Xor:  return Expression::XOR;
      +  }
      +}
      +
      +Expression::ExpressionOpcode ValueTable::getOpcode(CmpInst* C) {
      +  if (isa(C)) {
      +    switch (C->getPredicate()) {
      +    default:  // THIS SHOULD NEVER HAPPEN
      +      llvm_unreachable("Comparison with unknown predicate?");
      +    case ICmpInst::ICMP_EQ:  return Expression::ICMPEQ;
      +    case ICmpInst::ICMP_NE:  return Expression::ICMPNE;
      +    case ICmpInst::ICMP_UGT: return Expression::ICMPUGT;
      +    case ICmpInst::ICMP_UGE: return Expression::ICMPUGE;
      +    case ICmpInst::ICMP_ULT: return Expression::ICMPULT;
      +    case ICmpInst::ICMP_ULE: return Expression::ICMPULE;
      +    case ICmpInst::ICMP_SGT: return Expression::ICMPSGT;
      +    case ICmpInst::ICMP_SGE: return Expression::ICMPSGE;
      +    case ICmpInst::ICMP_SLT: return Expression::ICMPSLT;
      +    case ICmpInst::ICMP_SLE: return Expression::ICMPSLE;
      +    }
      +  } else {
      +    switch (C->getPredicate()) {
      +    default: // THIS SHOULD NEVER HAPPEN
      +      llvm_unreachable("Comparison with unknown predicate?");
      +    case FCmpInst::FCMP_OEQ: return Expression::FCMPOEQ;
      +    case FCmpInst::FCMP_OGT: return Expression::FCMPOGT;
      +    case FCmpInst::FCMP_OGE: return Expression::FCMPOGE;
      +    case FCmpInst::FCMP_OLT: return Expression::FCMPOLT;
      +    case FCmpInst::FCMP_OLE: return Expression::FCMPOLE;
      +    case FCmpInst::FCMP_ONE: return Expression::FCMPONE;
      +    case FCmpInst::FCMP_ORD: return Expression::FCMPORD;
      +    case FCmpInst::FCMP_UNO: return Expression::FCMPUNO;
      +    case FCmpInst::FCMP_UEQ: return Expression::FCMPUEQ;
      +    case FCmpInst::FCMP_UGT: return Expression::FCMPUGT;
      +    case FCmpInst::FCMP_UGE: return Expression::FCMPUGE;
      +    case FCmpInst::FCMP_ULT: return Expression::FCMPULT;
      +    case FCmpInst::FCMP_ULE: return Expression::FCMPULE;
      +    case FCmpInst::FCMP_UNE: return Expression::FCMPUNE;
      +    }
      +  }
      +}
      +
      +Expression::ExpressionOpcode ValueTable::getOpcode(CastInst* C) {
      +  switch(C->getOpcode()) {
      +  default: // THIS SHOULD NEVER HAPPEN
      +    llvm_unreachable("Cast operator with unknown opcode?");
      +  case Instruction::Trunc:    return Expression::TRUNC;
      +  case Instruction::ZExt:     return Expression::ZEXT;
      +  case Instruction::SExt:     return Expression::SEXT;
      +  case Instruction::FPToUI:   return Expression::FPTOUI;
      +  case Instruction::FPToSI:   return Expression::FPTOSI;
      +  case Instruction::UIToFP:   return Expression::UITOFP;
      +  case Instruction::SIToFP:   return Expression::SITOFP;
      +  case Instruction::FPTrunc:  return Expression::FPTRUNC;
      +  case Instruction::FPExt:    return Expression::FPEXT;
      +  case Instruction::PtrToInt: return Expression::PTRTOINT;
      +  case Instruction::IntToPtr: return Expression::INTTOPTR;
      +  case Instruction::BitCast:  return Expression::BITCAST;
      +  }
      +}
      +
      +Expression ValueTable::create_expression(CallInst* C) {
      +  Expression e;
      +
      +  e.type = C->getType();
      +  e.opcode = Expression::CALL;
      +
      +  e.varargs.push_back(lookup(C->getCalledFunction()));
      +  for (CallInst::op_iterator I = C->op_begin()+1, E = C->op_end();
      +       I != E; ++I)
      +    e.varargs.push_back(lookup(*I));
      +
      +  return e;
      +}
      +
      +Expression ValueTable::create_expression(BinaryOperator* BO) {
      +  Expression e;
      +  e.varargs.push_back(lookup(BO->getOperand(0)));
      +  e.varargs.push_back(lookup(BO->getOperand(1)));
      +  e.type = BO->getType();
      +  e.opcode = getOpcode(BO);
      +
      +  return e;
      +}
      +
      +Expression ValueTable::create_expression(CmpInst* C) {
      +  Expression e;
      +
      +  e.varargs.push_back(lookup(C->getOperand(0)));
      +  e.varargs.push_back(lookup(C->getOperand(1)));
      +  e.type = C->getType();
      +  e.opcode = getOpcode(C);
      +
      +  return e;
      +}
      +
      +Expression ValueTable::create_expression(CastInst* C) {
      +  Expression e;
      +
      +  e.varargs.push_back(lookup(C->getOperand(0)));
      +  e.type = C->getType();
      +  e.opcode = getOpcode(C);
      +
      +  return e;
      +}
      +
      +Expression ValueTable::create_expression(ShuffleVectorInst* S) {
      +  Expression e;
      +
      +  e.varargs.push_back(lookup(S->getOperand(0)));
      +  e.varargs.push_back(lookup(S->getOperand(1)));
      +  e.varargs.push_back(lookup(S->getOperand(2)));
      +  e.type = S->getType();
      +  e.opcode = Expression::SHUFFLE;
      +
      +  return e;
      +}
      +
      +Expression ValueTable::create_expression(ExtractElementInst* E) {
      +  Expression e;
      +
      +  e.varargs.push_back(lookup(E->getOperand(0)));
      +  e.varargs.push_back(lookup(E->getOperand(1)));
      +  e.type = E->getType();
      +  e.opcode = Expression::EXTRACT;
      +
      +  return e;
      +}
      +
      +Expression ValueTable::create_expression(InsertElementInst* I) {
      +  Expression e;
      +
      +  e.varargs.push_back(lookup(I->getOperand(0)));
      +  e.varargs.push_back(lookup(I->getOperand(1)));
      +  e.varargs.push_back(lookup(I->getOperand(2)));
      +  e.type = I->getType();
      +  e.opcode = Expression::INSERT;
      +
      +  return e;
      +}
      +
      +Expression ValueTable::create_expression(SelectInst* I) {
      +  Expression e;
      +
      +  e.varargs.push_back(lookup(I->getCondition()));
      +  e.varargs.push_back(lookup(I->getTrueValue()));
      +  e.varargs.push_back(lookup(I->getFalseValue()));
      +  e.type = I->getType();
      +  e.opcode = Expression::SELECT;
      +
      +  return e;
      +}
      +
      +Expression ValueTable::create_expression(GetElementPtrInst* G) {
      +  Expression e;
      +
      +  e.varargs.push_back(lookup(G->getPointerOperand()));
      +  e.type = G->getType();
      +  e.opcode = Expression::GEP;
      +
      +  for (GetElementPtrInst::op_iterator I = G->idx_begin(), E = G->idx_end();
      +       I != E; ++I)
      +    e.varargs.push_back(lookup(*I));
      +
      +  return e;
      +}
      +
      +Expression ValueTable::create_expression(ExtractValueInst* E) {
      +  Expression e;
      +
      +  e.varargs.push_back(lookup(E->getAggregateOperand()));
      +  for (ExtractValueInst::idx_iterator II = E->idx_begin(), IE = E->idx_end();
      +       II != IE; ++II)
      +    e.varargs.push_back(*II);
      +  e.type = E->getType();
      +  e.opcode = Expression::EXTRACTVALUE;
      +
      +  return e;
      +}
      +
      +Expression ValueTable::create_expression(InsertValueInst* E) {
      +  Expression e;
      +
      +  e.varargs.push_back(lookup(E->getAggregateOperand()));
      +  e.varargs.push_back(lookup(E->getInsertedValueOperand()));
      +  for (InsertValueInst::idx_iterator II = E->idx_begin(), IE = E->idx_end();
      +       II != IE; ++II)
      +    e.varargs.push_back(*II);
      +  e.type = E->getType();
      +  e.opcode = Expression::INSERTVALUE;
      +
      +  return e;
      +}
      +
      +//===----------------------------------------------------------------------===//
      +//                     ValueTable External Functions
      +//===----------------------------------------------------------------------===//
      +
      +/// add - Insert a value into the table with a specified value number.
      +void ValueTable::add(Value *V, uint32_t num) {
      +  valueNumbering[V] = num;
      +}
      +
      +/// computeNumber - Returns the value number for the specified value, assigning
      +/// it a new number if it did not have one before.
      +uint32_t ValueTable::computeNumber(Value *V) {
      +  if (uint32_t v = valueNumbering[V])
      +    return v;
      +  else if (uint32_t v= constantsNumbering[V])
      +    return v;
      +
      +  if (!isa(V)) {
      +    constantsNumbering[V] = nextValueNumber;
      +    return nextValueNumber++;
      +  }
      +  
      +  Instruction* I = cast(V);
      +  Expression exp;
      +  switch (I->getOpcode()) {
      +    case Instruction::Add:
      +    case Instruction::FAdd:
      +    case Instruction::Sub:
      +    case Instruction::FSub:
      +    case Instruction::Mul:
      +    case Instruction::FMul:
      +    case Instruction::UDiv:
      +    case Instruction::SDiv:
      +    case Instruction::FDiv:
      +    case Instruction::URem:
      +    case Instruction::SRem:
      +    case Instruction::FRem:
      +    case Instruction::Shl:
      +    case Instruction::LShr:
      +    case Instruction::AShr:
      +    case Instruction::And:
      +    case Instruction::Or :
      +    case Instruction::Xor:
      +      exp = create_expression(cast(I));
      +      break;
      +    case Instruction::ICmp:
      +    case Instruction::FCmp:
      +      exp = create_expression(cast(I));
      +      break;
      +    case Instruction::Trunc:
      +    case Instruction::ZExt:
      +    case Instruction::SExt:
      +    case Instruction::FPToUI:
      +    case Instruction::FPToSI:
      +    case Instruction::UIToFP:
      +    case Instruction::SIToFP:
      +    case Instruction::FPTrunc:
      +    case Instruction::FPExt:
      +    case Instruction::PtrToInt:
      +    case Instruction::IntToPtr:
      +    case Instruction::BitCast:
      +      exp = create_expression(cast(I));
      +      break;
      +    case Instruction::Select:
      +      exp = create_expression(cast(I));
      +      break;
      +    case Instruction::ExtractElement:
      +      exp = create_expression(cast(I));
      +      break;
      +    case Instruction::InsertElement:
      +      exp = create_expression(cast(I));
      +      break;
      +    case Instruction::ShuffleVector:
      +      exp = create_expression(cast(I));
      +      break;
      +    case Instruction::ExtractValue:
      +      exp = create_expression(cast(I));
      +      break;
      +    case Instruction::InsertValue:
      +      exp = create_expression(cast(I));
      +      break;      
      +    case Instruction::GetElementPtr:
      +      exp = create_expression(cast(I));
      +      break;
      +    default:
      +      valueNumbering[V] = nextValueNumber;
      +      return nextValueNumber++;
      +  }
      +
      +  uint32_t& e = expressionNumbering[exp];
      +  if (!e) e = nextValueNumber++;
      +  valueNumbering[V] = e;
      +  
      +  return e;
      +}
      +
      +/// lookup - Returns the value number of the specified value. Returns 0 if
      +/// the value has not yet been numbered.
      +uint32_t ValueTable::lookup(Value *V) {
      +  if (!isa(V)) {
      +    if (!constantsNumbering.count(V))
      +      constantsNumbering[V] = nextValueNumber++;
      +    return constantsNumbering[V];
      +  }
      +  
      +  return valueNumbering[V];
      +}
      +
      +/// clear - Remove all entries from the ValueTable
      +void ValueTable::clear() {
      +  valueNumbering.clear();
      +  expressionNumbering.clear();
      +  constantsNumbering.clear();
      +  nextValueNumber = 1;
      +}
      +
      +void ValueTable::clearExpressions() {
      +  expressionNumbering.clear();
      +  constantsNumbering.clear();
      +  nextValueNumber = 1;
      +}
      +
      +/// erase - Remove a value from the value numbering
      +void ValueTable::erase(Value *V) {
      +  valueNumbering.erase(V);
      +}
      +
      +/// verifyRemoved - Verify that the value is removed from all internal data
      +/// structures.
      +void ValueTable::verifyRemoved(const Value *V) const {
      +  for (DenseMap::iterator
      +         I = valueNumbering.begin(), E = valueNumbering.end(); I != E; ++I) {
      +    assert(I->first != V && "Inst still occurs in value numbering map!");
      +  }
      +}
      +
      +//===----------------------------------------------------------------------===//
      +//                              SCCVN Pass
      +//===----------------------------------------------------------------------===//
      +
      +namespace {
      +
      +  struct ValueNumberScope {
      +    ValueNumberScope* parent;
      +    DenseMap table;
      +    SparseBitVector<128> availIn;
      +    SparseBitVector<128> availOut;
      +    
      +    ValueNumberScope(ValueNumberScope* p) : parent(p) { }
      +  };
      +
      +  class SCCVN : public FunctionPass {
      +    bool runOnFunction(Function &F);
      +  public:
      +    static char ID; // Pass identification, replacement for typeid
      +    SCCVN() : FunctionPass(&ID) { }
      +
      +  private:
      +    ValueTable VT;
      +    DenseMap BBMap;
      +    
      +    // This transformation requires dominator postdominator info
      +    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      +      AU.addRequired();
      +
      +      AU.addPreserved();
      +      AU.setPreservesCFG();
      +    }
      +  };
      +
      +  char SCCVN::ID = 0;
      +}
      +
      +// createSCCVNPass - The public interface to this file...
      +FunctionPass *llvm::createSCCVNPass() { return new SCCVN(); }
      +
      +static RegisterPass X("sccvn",
      +                              "SCC Value Numbering");
      +
      +static Value *lookupNumber(ValueNumberScope *Locals, uint32_t num) {
      +  while (Locals) {
      +    DenseMap::iterator I = Locals->table.find(num);
      +    if (I != Locals->table.end())
      +      return I->second;
      +    Locals = Locals->parent;
      +  }
      +
      +  return 0;
      +}
      +
      +bool SCCVN::runOnFunction(Function& F) {
      +  // Implement the RPO version of the SCCVN algorithm.  Conceptually, 
      +  // we optimisitically assume that all instructions with the same opcode have
      +  // the same VN.  Then we deepen our comparison by one level, to all 
      +  // instructions whose operands have the same opcodes get the same VN.  We
      +  // iterate this process until the partitioning stops changing, at which
      +  // point we have computed a full numbering.
      +  ReversePostOrderTraversal RPOT(&F);
      +  bool done = false;
      +  while (!done) {
      +    done = true;
      +    VT.clearExpressions();
      +    for (ReversePostOrderTraversal::rpo_iterator I = RPOT.begin(),
      +         E = RPOT.end(); I != E; ++I) {
      +      BasicBlock* BB = *I;
      +      for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();
      +           BI != BE; ++BI) {
      +         uint32_t origVN = VT.lookup(BI);
      +         uint32_t newVN = VT.computeNumber(BI);
      +         if (origVN != newVN)
      +           done = false;
      +      }
      +    }
      +  }
      +  
      +  // Now, do a dominator walk, eliminating simple, dominated redundancies as we
      +  // go.  Also, build the ValueNumberScope structure that will be used for
      +  // computing full availability.
      +  DominatorTree& DT = getAnalysis();
      +  bool changed = false;
      +  for (df_iterator DI = df_begin(DT.getRootNode()),
      +       DE = df_end(DT.getRootNode()); DI != DE; ++DI) {
      +    BasicBlock* BB = DI->getBlock();
      +    if (DI->getIDom())
      +      BBMap[BB] = new ValueNumberScope(BBMap[DI->getIDom()->getBlock()]);
      +    else
      +      BBMap[BB] = new ValueNumberScope(0);
      +    
      +    for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
      +      uint32_t num = VT.lookup(I);
      +      Value* repl = lookupNumber(BBMap[BB], num);
      +      
      +      if (repl) {
      +        if (isa(I))
      +          ++NumSCCVNPhi;
      +        else
      +          ++NumSCCVNInstr;
      +        I->replaceAllUsesWith(repl);
      +        Instruction* OldInst = I;
      +        ++I;
      +        BBMap[BB]->table[num] = repl;
      +        OldInst->eraseFromParent();
      +        changed = true;
      +      } else {
      +        BBMap[BB]->table[num] = I;
      +        BBMap[BB]->availOut.set(num);
      +  
      +        ++I;
      +      }
      +    }
      +  }
      +
      +  // FIXME: This code is commented out for now, because it can lead to the
      +  // insertion of a lot of redundant PHIs being inserted by SSAUpdater.
      +#if 0
      +  // Perform a forward data-flow to compute availability at all points on
      +  // the CFG.
      +  do {
      +    changed = false;
      +    for (ReversePostOrderTraversal::rpo_iterator I = RPOT.begin(),
      +         E = RPOT.end(); I != E; ++I) {
      +      BasicBlock* BB = *I;
      +      ValueNumberScope *VNS = BBMap[BB];
      +      
      +      SparseBitVector<128> preds;
      +      bool first = true;
      +      for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
      +           PI != PE; ++PI) {
      +        if (first) {
      +          preds = BBMap[*PI]->availOut;
      +          first = false;
      +        } else {
      +          preds &= BBMap[*PI]->availOut;
      +        }
      +      }
      +      
      +      changed |= (VNS->availIn |= preds);
      +      changed |= (VNS->availOut |= preds);
      +    }
      +  } while (changed);
      +  
      +  // Use full availability information to perform non-dominated replacements.
      +  SSAUpdater SSU; 
      +  for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) {
      +    if (!BBMap.count(FI)) continue;
      +    for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
      +         BI != BE; ) {
      +      uint32_t num = VT.lookup(BI);
      +      if (!BBMap[FI]->availIn.test(num)) {
      +        ++BI;
      +        continue;
      +      }
      +      
      +      SSU.Initialize(BI);
      +      
      +      SmallPtrSet visited;
      +      SmallVector stack;
      +      visited.insert(FI);
      +      for (pred_iterator PI = pred_begin(FI), PE = pred_end(FI);
      +           PI != PE; ++PI)
      +        if (!visited.count(*PI))
      +          stack.push_back(*PI);
      +      
      +      while (!stack.empty()) {
      +        BasicBlock* CurrBB = stack.back();
      +        stack.pop_back();
      +        visited.insert(CurrBB);
      +        
      +        ValueNumberScope* S = BBMap[CurrBB];
      +        if (S->table.count(num)) {
      +          SSU.AddAvailableValue(CurrBB, S->table[num]);
      +        } else {
      +          for (pred_iterator PI = pred_begin(CurrBB), PE = pred_end(CurrBB);
      +               PI != PE; ++PI)
      +            if (!visited.count(*PI))
      +              stack.push_back(*PI);
      +        }
      +      }
      +      
      +      Value* repl = SSU.GetValueInMiddleOfBlock(FI);
      +      BI->replaceAllUsesWith(repl);
      +      Instruction* CurInst = BI;
      +      ++BI;
      +      BBMap[FI]->table[num] = repl;
      +      if (isa(CurInst))
      +        ++NumSCCVNPhi;
      +      else
      +        ++NumSCCVNInstr;
      +        
      +      CurInst->eraseFromParent();
      +    }
      +  }
      +#endif
      +
      +  VT.clear();
      +  for (DenseMap::iterator
      +       I = BBMap.begin(), E = BBMap.end(); I != E; ++I)
      +    delete I->second;
      +  BBMap.clear();
      +  
      +  return changed;
      +}
      \ No newline at end of file
      
      
      
      
      From resistor at mac.com  Mon Oct 26 18:56:52 2009
      From: resistor at mac.com (Owen Anderson)
      Date: Mon, 26 Oct 2009 23:56:52 -0000
      Subject: [llvm-commits] [llvm] r85180 - in /llvm/trunk/include/llvm:
       LinkAllPasses.h Transforms/Scalar.h
      Message-ID: <200910262356.n9QNuqst012692@zion.cs.uiuc.edu>
      
      Author: resistor
      Date: Mon Oct 26 18:56:52 2009
      New Revision: 85180
      
      URL: http://llvm.org/viewvc/llvm-project?rev=85180&view=rev
      Log:
      Forgot to commit these.
      
      Modified:
          llvm/trunk/include/llvm/LinkAllPasses.h
          llvm/trunk/include/llvm/Transforms/Scalar.h
      
      Modified: llvm/trunk/include/llvm/LinkAllPasses.h
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=85180&r1=85179&r2=85180&view=diff
      
      ==============================================================================
      --- llvm/trunk/include/llvm/LinkAllPasses.h (original)
      +++ llvm/trunk/include/llvm/LinkAllPasses.h Mon Oct 26 18:56:52 2009
      @@ -141,6 +141,7 @@
             (void) llvm::createSSIPass();
             (void) llvm::createSSIEverythingPass();
             (void) llvm::createGEPSplitterPass();
      +      (void) llvm::createSCCVNPass();
       
             (void)new llvm::IntervalPartition();
             (void)new llvm::FindUsedTypes();
      
      Modified: llvm/trunk/include/llvm/Transforms/Scalar.h
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=85180&r1=85179&r2=85180&view=diff
      
      ==============================================================================
      --- llvm/trunk/include/llvm/Transforms/Scalar.h (original)
      +++ llvm/trunk/include/llvm/Transforms/Scalar.h Mon Oct 26 18:56:52 2009
      @@ -338,6 +338,12 @@
       //
       FunctionPass *createGEPSplitterPass();
       
      +//===----------------------------------------------------------------------===//
      +//
      +// SCCVN - Aggressively eliminate redundant scalar values
      +//
      +FunctionPass *createSCCVNPass();
      +
       } // End llvm namespace
       
       #endif
      
      
      
      
      From vhernandez at apple.com  Mon Oct 26 18:58:57 2009
      From: vhernandez at apple.com (Victor Hernandez)
      Date: Mon, 26 Oct 2009 23:58:57 -0000
      Subject: [llvm-commits] [llvm] r85181 - in /llvm/trunk:
       include/llvm/Analysis/ lib/Analysis/ lib/Analysis/IPA/ lib/Transforms/IPO/
       lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/
      Message-ID: <200910262358.n9QNwwUP012836@zion.cs.uiuc.edu>
      
      Author: hernande
      Date: Mon Oct 26 18:58:56 2009
      New Revision: 85181
      
      URL: http://llvm.org/viewvc/llvm-project?rev=85181&view=rev
      Log:
      Rename MallocHelper as MallocFreeHelper, since it now also identifies calls to free()
      
      Added:
          llvm/trunk/include/llvm/Analysis/MallocFreeHelper.h
            - copied unchanged from r85176, llvm/trunk/include/llvm/Analysis/MallocHelper.h
          llvm/trunk/lib/Analysis/MallocFreeHelper.cpp
            - copied, changed from r85176, llvm/trunk/lib/Analysis/MallocHelper.cpp
      Removed:
          llvm/trunk/include/llvm/Analysis/MallocHelper.h
          llvm/trunk/lib/Analysis/MallocHelper.cpp
      Modified:
          llvm/trunk/lib/Analysis/AliasSetTracker.cpp
          llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp
          llvm/trunk/lib/Analysis/CMakeLists.txt
          llvm/trunk/lib/Analysis/CaptureTracking.cpp
          llvm/trunk/lib/Analysis/IPA/Andersens.cpp
          llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp
          llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp
          llvm/trunk/lib/Analysis/PointerTracking.cpp
          llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp
          llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
          llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp
          llvm/trunk/lib/Transforms/Scalar/GVN.cpp
          llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
          llvm/trunk/lib/Transforms/Scalar/SCCP.cpp
          llvm/trunk/lib/Transforms/Utils/Local.cpp
          llvm/trunk/lib/VMCore/Instruction.cpp
      
      Removed: llvm/trunk/include/llvm/Analysis/MallocHelper.h
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MallocHelper.h?rev=85180&view=auto
      
      ==============================================================================
      --- llvm/trunk/include/llvm/Analysis/MallocHelper.h (original)
      +++ llvm/trunk/include/llvm/Analysis/MallocHelper.h (removed)
      @@ -1,93 +0,0 @@
      -//===- llvm/Analysis/MallocFreeHelper.h - Identify malloc/free --*- C++ -*-===//
      -//
      -//                     The LLVM Compiler Infrastructure
      -//
      -// This file is distributed under the University of Illinois Open Source
      -// License. See LICENSE.TXT for details.
      -//
      -//===----------------------------------------------------------------------===//
      -//
      -// This family of functions identifies calls to malloc, bitcasts of malloc
      -// calls, and the types and array sizes associated with them.  It also
      -// identifies calls to the free builtin.
      -//
      -//===----------------------------------------------------------------------===//
      -
      -#ifndef LLVM_ANALYSIS_MALLOCHELPER_H
      -#define LLVM_ANALYSIS_MALLOCHELPER_H
      -
      -namespace llvm {
      -class CallInst;
      -class LLVMContext;
      -class PointerType;
      -class TargetData;
      -class Type;
      -class Value;
      -
      -//===----------------------------------------------------------------------===//
      -//  malloc Call Utility Functions.
      -//
      -
      -/// isMalloc - Returns true if the value is either a malloc call or a bitcast of 
      -/// the result of a malloc call
      -bool isMalloc(const Value* I);
      -
      -/// extractMallocCall - Returns the corresponding CallInst if the instruction
      -/// is a malloc call.  Since CallInst::CreateMalloc() only creates calls, we
      -/// ignore InvokeInst here.
      -const CallInst* extractMallocCall(const Value* I);
      -CallInst* extractMallocCall(Value* I);
      -
      -/// extractMallocCallFromBitCast - Returns the corresponding CallInst if the
      -/// instruction is a bitcast of the result of a malloc call.
      -const CallInst* extractMallocCallFromBitCast(const Value* I);
      -CallInst* extractMallocCallFromBitCast(Value* I);
      -
      -/// isArrayMalloc - Returns the corresponding CallInst if the instruction 
      -/// matches the malloc call IR generated by CallInst::CreateMalloc().  This 
      -/// means that it is a malloc call with one bitcast use AND the malloc call's 
      -/// size argument is:
      -///  1. a constant not equal to the size of the malloced type
      -/// or
      -///  2. the result of a multiplication by the size of the malloced type
      -/// Otherwise it returns NULL.
      -/// The unique bitcast is needed to determine the type/size of the array
      -/// allocation.
      -CallInst* isArrayMalloc(Value* I, LLVMContext &Context, const TargetData* TD);
      -const CallInst* isArrayMalloc(const Value* I, LLVMContext &Context,
      -                              const TargetData* TD);
      -
      -/// getMallocType - Returns the PointerType resulting from the malloc call.
      -/// This PointerType is the result type of the call's only bitcast use.
      -/// If there is no unique bitcast use, then return NULL.
      -const PointerType* getMallocType(const CallInst* CI);
      -
      -/// getMallocAllocatedType - Returns the Type allocated by malloc call. This
      -/// Type is the result type of the call's only bitcast use. If there is no
      -/// unique bitcast use, then return NULL.
      -const Type* getMallocAllocatedType(const CallInst* CI);
      -
      -/// getMallocArraySize - Returns the array size of a malloc call.  For array
      -/// mallocs, the size is computated in 1 of 3 ways:
      -///  1. If the element type is of size 1, then array size is the argument to 
      -///     malloc.
      -///  2. Else if the malloc's argument is a constant, the array size is that
      -///     argument divided by the element type's size.
      -///  3. Else the malloc argument must be a multiplication and the array size is
      -///     the first operand of the multiplication.
      -/// For non-array mallocs, the computed size is constant 1. 
      -/// This function returns NULL for all mallocs whose array size cannot be
      -/// determined.
      -Value* getMallocArraySize(CallInst* CI, LLVMContext &Context,
      -                          const TargetData* TD);
      -                          
      -//===----------------------------------------------------------------------===//
      -//  free Call Utility Functions.
      -//
      -
      -/// isFreeCall - Returns true if the the value is a call to the builtin free()
      -bool isFreeCall(const Value* I);
      -
      -} // End llvm namespace
      -
      -#endif
      
      Modified: llvm/trunk/lib/Analysis/AliasSetTracker.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasSetTracker.cpp?rev=85181&r1=85180&r2=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Analysis/AliasSetTracker.cpp (original)
      +++ llvm/trunk/lib/Analysis/AliasSetTracker.cpp Mon Oct 26 18:58:56 2009
      @@ -13,7 +13,7 @@
       
       #include "llvm/Analysis/AliasSetTracker.h"
       #include "llvm/Analysis/AliasAnalysis.h"
      -#include "llvm/Analysis/MallocHelper.h"
      +#include "llvm/Analysis/MallocFreeHelper.h"
       #include "llvm/Instructions.h"
       #include "llvm/IntrinsicInst.h"
       #include "llvm/Pass.h"
      
      Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=85181&r1=85180&r2=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original)
      +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Mon Oct 26 18:58:56 2009
      @@ -15,7 +15,7 @@
       
       #include "llvm/Analysis/AliasAnalysis.h"
       #include "llvm/Analysis/CaptureTracking.h"
      -#include "llvm/Analysis/MallocHelper.h"
      +#include "llvm/Analysis/MallocFreeHelper.h"
       #include "llvm/Analysis/Passes.h"
       #include "llvm/Constants.h"
       #include "llvm/DerivedTypes.h"
      
      Modified: llvm/trunk/lib/Analysis/CMakeLists.txt
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=85181&r1=85180&r2=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Analysis/CMakeLists.txt (original)
      +++ llvm/trunk/lib/Analysis/CMakeLists.txt Mon Oct 26 18:58:56 2009
      @@ -23,7 +23,7 @@
         LoopDependenceAnalysis.cpp
         LoopInfo.cpp
         LoopPass.cpp
      -  MallocHelper.cpp
      +  MallocFreeHelper.cpp
         MemoryDependenceAnalysis.cpp
         PointerTracking.cpp
         PostDominators.cpp
      
      Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CaptureTracking.cpp?rev=85181&r1=85180&r2=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Analysis/CaptureTracking.cpp (original)
      +++ llvm/trunk/lib/Analysis/CaptureTracking.cpp Mon Oct 26 18:58:56 2009
      @@ -17,7 +17,7 @@
       //===----------------------------------------------------------------------===//
       
       #include "llvm/Analysis/CaptureTracking.h"
      -#include "llvm/Analysis/MallocHelper.h"
      +#include "llvm/Analysis/MallocFreeHelper.h"
       #include "llvm/Instructions.h"
       #include "llvm/Value.h"
       #include "llvm/ADT/SmallSet.h"
      
      Modified: llvm/trunk/lib/Analysis/IPA/Andersens.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/Andersens.cpp?rev=85181&r1=85180&r2=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Analysis/IPA/Andersens.cpp (original)
      +++ llvm/trunk/lib/Analysis/IPA/Andersens.cpp Mon Oct 26 18:58:56 2009
      @@ -63,7 +63,7 @@
       #include "llvm/Support/InstIterator.h"
       #include "llvm/Support/InstVisitor.h"
       #include "llvm/Analysis/AliasAnalysis.h"
      -#include "llvm/Analysis/MallocHelper.h"
      +#include "llvm/Analysis/MallocFreeHelper.h"
       #include "llvm/Analysis/Passes.h"
       #include "llvm/Support/Debug.h"
       #include "llvm/System/Atomic.h"
      
      Modified: llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp?rev=85181&r1=85180&r2=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp (original)
      +++ llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp Mon Oct 26 18:58:56 2009
      @@ -23,7 +23,7 @@
       #include "llvm/DerivedTypes.h"
       #include "llvm/Analysis/AliasAnalysis.h"
       #include "llvm/Analysis/CallGraph.h"
      -#include "llvm/Analysis/MallocHelper.h"
      +#include "llvm/Analysis/MallocFreeHelper.h"
       #include "llvm/Support/CommandLine.h"
       #include "llvm/Support/InstIterator.h"
       #include "llvm/ADT/Statistic.h"
      
      Copied: llvm/trunk/lib/Analysis/MallocFreeHelper.cpp (from r85176, llvm/trunk/lib/Analysis/MallocHelper.cpp)
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MallocFreeHelper.cpp?p2=llvm/trunk/lib/Analysis/MallocFreeHelper.cpp&p1=llvm/trunk/lib/Analysis/MallocHelper.cpp&r1=85176&r2=85181&rev=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Analysis/MallocHelper.cpp (original)
      +++ llvm/trunk/lib/Analysis/MallocFreeHelper.cpp Mon Oct 26 18:58:56 2009
      @@ -13,7 +13,7 @@
       //
       //===----------------------------------------------------------------------===//
       
      -#include "llvm/Analysis/MallocHelper.h"
      +#include "llvm/Analysis/MallocFreeHelper.h"
       #include "llvm/Constants.h"
       #include "llvm/Instructions.h"
       #include "llvm/Module.h"
      
      Removed: llvm/trunk/lib/Analysis/MallocHelper.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MallocHelper.cpp?rev=85180&view=auto
      
      ==============================================================================
      --- llvm/trunk/lib/Analysis/MallocHelper.cpp (original)
      +++ llvm/trunk/lib/Analysis/MallocHelper.cpp (removed)
      @@ -1,296 +0,0 @@
      -//===-- MallocFreeHelper.cpp - Identify calls to malloc and free builtins -===//
      -//
      -//                     The LLVM Compiler Infrastructure
      -//
      -// This file is distributed under the University of Illinois Open Source
      -// License. See LICENSE.TXT for details.
      -//
      -//===----------------------------------------------------------------------===//
      -//
      -// This family of functions identifies calls to malloc, bitcasts of malloc
      -// calls, and the types and array sizes associated with them.  It also
      -// identifies calls to the free builtin.
      -//
      -//===----------------------------------------------------------------------===//
      -
      -#include "llvm/Analysis/MallocHelper.h"
      -#include "llvm/Constants.h"
      -#include "llvm/Instructions.h"
      -#include "llvm/Module.h"
      -#include "llvm/Analysis/ConstantFolding.h"
      -using namespace llvm;
      -
      -//===----------------------------------------------------------------------===//
      -//  malloc Call Utility Functions.
      -//
      -
      -/// isMalloc - Returns true if the the value is either a malloc call or a
      -/// bitcast of the result of a malloc call.
      -bool llvm::isMalloc(const Value* I) {
      -  return extractMallocCall(I) || extractMallocCallFromBitCast(I);
      -}
      -
      -static bool isMallocCall(const CallInst *CI) {
      -  if (!CI)
      -    return false;
      -
      -  const Module* M = CI->getParent()->getParent()->getParent();
      -  Function *MallocFunc = M->getFunction("malloc");
      -
      -  if (CI->getOperand(0) != MallocFunc)
      -    return false;
      -
      -  // Check malloc prototype.
      -  // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin 
      -  // attribute will exist.
      -  const FunctionType *FTy = MallocFunc->getFunctionType();
      -  if (FTy->getNumParams() != 1)
      -    return false;
      -  if (IntegerType *ITy = dyn_cast(FTy->param_begin()->get())) {
      -    if (ITy->getBitWidth() != 32 && ITy->getBitWidth() != 64)
      -      return false;
      -    return true;
      -  }
      -
      -  return false;
      -}
      -
      -/// extractMallocCall - Returns the corresponding CallInst if the instruction
      -/// is a malloc call.  Since CallInst::CreateMalloc() only creates calls, we
      -/// ignore InvokeInst here.
      -const CallInst* llvm::extractMallocCall(const Value* I) {
      -  const CallInst *CI = dyn_cast(I);
      -  return (isMallocCall(CI)) ? CI : NULL;
      -}
      -
      -CallInst* llvm::extractMallocCall(Value* I) {
      -  CallInst *CI = dyn_cast(I);
      -  return (isMallocCall(CI)) ? CI : NULL;
      -}
      -
      -static bool isBitCastOfMallocCall(const BitCastInst* BCI) {
      -  if (!BCI)
      -    return false;
      -    
      -  return isMallocCall(dyn_cast(BCI->getOperand(0)));
      -}
      -
      -/// extractMallocCallFromBitCast - Returns the corresponding CallInst if the
      -/// instruction is a bitcast of the result of a malloc call.
      -CallInst* llvm::extractMallocCallFromBitCast(Value* I) {
      -  BitCastInst *BCI = dyn_cast(I);
      -  return (isBitCastOfMallocCall(BCI)) ? cast(BCI->getOperand(0))
      -                                      : NULL;
      -}
      -
      -const CallInst* llvm::extractMallocCallFromBitCast(const Value* I) {
      -  const BitCastInst *BCI = dyn_cast(I);
      -  return (isBitCastOfMallocCall(BCI)) ? cast(BCI->getOperand(0))
      -                                      : NULL;
      -}
      -
      -static bool isArrayMallocHelper(const CallInst *CI, LLVMContext &Context,
      -                                const TargetData* TD) {
      -  if (!CI)
      -    return false;
      -
      -  const Type* T = getMallocAllocatedType(CI);
      -
      -  // We can only indentify an array malloc if we know the type of the malloc 
      -  // call.
      -  if (!T) return false;
      -
      -  Value* MallocArg = CI->getOperand(1);
      -  Constant *ElementSize = ConstantExpr::getSizeOf(T);
      -  ElementSize = ConstantExpr::getTruncOrBitCast(ElementSize, 
      -                                                MallocArg->getType());
      -  Constant *FoldedElementSize = ConstantFoldConstantExpression(
      -                                       cast(ElementSize), 
      -                                       Context, TD);
      -
      -
      -  if (isa(MallocArg))
      -    return (MallocArg != ElementSize);
      -
      -  BinaryOperator *BI = dyn_cast(MallocArg);
      -  if (!BI)
      -    return false;
      -
      -  if (BI->getOpcode() == Instruction::Mul)
      -    // ArraySize * ElementSize
      -    if (BI->getOperand(1) == ElementSize ||
      -        (FoldedElementSize && BI->getOperand(1) == FoldedElementSize))
      -      return true;
      -
      -  // TODO: Detect case where MallocArg mul has been transformed to shl.
      -
      -  return false;
      -}
      -
      -/// isArrayMalloc - Returns the corresponding CallInst if the instruction 
      -/// matches the malloc call IR generated by CallInst::CreateMalloc().  This 
      -/// means that it is a malloc call with one bitcast use AND the malloc call's 
      -/// size argument is:
      -///  1. a constant not equal to the size of the malloced type
      -/// or
      -///  2. the result of a multiplication by the size of the malloced type
      -/// Otherwise it returns NULL.
      -/// The unique bitcast is needed to determine the type/size of the array
      -/// allocation.
      -CallInst* llvm::isArrayMalloc(Value* I, LLVMContext &Context,
      -                              const TargetData* TD) {
      -  CallInst *CI = extractMallocCall(I);
      -  return (isArrayMallocHelper(CI, Context, TD)) ? CI : NULL;
      -}
      -
      -const CallInst* llvm::isArrayMalloc(const Value* I, LLVMContext &Context,
      -                                    const TargetData* TD) {
      -  const CallInst *CI = extractMallocCall(I);
      -  return (isArrayMallocHelper(CI, Context, TD)) ? CI : NULL;
      -}
      -
      -/// getMallocType - Returns the PointerType resulting from the malloc call.
      -/// This PointerType is the result type of the call's only bitcast use.
      -/// If there is no unique bitcast use, then return NULL.
      -const PointerType* llvm::getMallocType(const CallInst* CI) {
      -  assert(isMalloc(CI) && "GetMallocType and not malloc call");
      -  
      -  const BitCastInst* BCI = NULL;
      -  
      -  // Determine if CallInst has a bitcast use.
      -  for (Value::use_const_iterator UI = CI->use_begin(), E = CI->use_end();
      -       UI != E; )
      -    if ((BCI = dyn_cast(cast(*UI++))))
      -      break;
      -
      -  // Malloc call has 1 bitcast use and no other uses, so type is the bitcast's
      -  // destination type.
      -  if (BCI && CI->hasOneUse())
      -    return cast(BCI->getDestTy());
      -
      -  // Malloc call was not bitcast, so type is the malloc function's return type.
      -  if (!BCI)
      -    return cast(CI->getType());
      -
      -  // Type could not be determined.
      -  return NULL;
      -}
      -
      -/// getMallocAllocatedType - Returns the Type allocated by malloc call. This
      -/// Type is the result type of the call's only bitcast use. If there is no
      -/// unique bitcast use, then return NULL.
      -const Type* llvm::getMallocAllocatedType(const CallInst* CI) {
      -  const PointerType* PT = getMallocType(CI);
      -  return PT ? PT->getElementType() : NULL;
      -}
      -
      -/// isSafeToGetMallocArraySize - Returns true if the array size of a malloc can
      -/// be determined.  It can be determined in these 3 cases of malloc codegen:
      -/// 1. non-array malloc: The malloc's size argument is a constant and equals the ///    size of the type being malloced.
      -/// 2. array malloc: This is a malloc call with one bitcast use AND the malloc
      -///    call's size argument is a constant multiple of the size of the malloced
      -///    type.
      -/// 3. array malloc: This is a malloc call with one bitcast use AND the malloc
      -///    call's size argument is the result of a multiplication by the size of the
      -///    malloced type.
      -/// Otherwise returns false.
      -static bool isSafeToGetMallocArraySize(const CallInst *CI,
      -                                       LLVMContext &Context,
      -                                       const TargetData* TD) {
      -  if (!CI)
      -    return false;
      -
      -  // Type must be known to determine array size.
      -  const Type* T = getMallocAllocatedType(CI);
      -  if (!T) return false;
      -
      -  Value* MallocArg = CI->getOperand(1);
      -  Constant *ElementSize = ConstantExpr::getSizeOf(T);
      -  ElementSize = ConstantExpr::getTruncOrBitCast(ElementSize, 
      -                                                MallocArg->getType());
      -
      -  // First, check if it is a non-array malloc.
      -  if (isa(MallocArg) && (MallocArg == ElementSize))
      -    return true;
      -
      -  // Second, check if it can be determined that this is an array malloc.
      -  return isArrayMallocHelper(CI, Context, TD);
      -}
      -
      -/// isConstantOne - Return true only if val is constant int 1.
      -static bool isConstantOne(Value *val) {
      -  return isa(val) && cast(val)->isOne();
      -}
      -
      -/// getMallocArraySize - Returns the array size of a malloc call.  For array
      -/// mallocs, the size is computated in 1 of 3 ways:
      -///  1. If the element type is of size 1, then array size is the argument to 
      -///     malloc.
      -///  2. Else if the malloc's argument is a constant, the array size is that
      -///     argument divided by the element type's size.
      -///  3. Else the malloc argument must be a multiplication and the array size is
      -///     the first operand of the multiplication.
      -/// For non-array mallocs, the computed size is constant 1. 
      -/// This function returns NULL for all mallocs whose array size cannot be
      -/// determined.
      -Value* llvm::getMallocArraySize(CallInst* CI, LLVMContext &Context,
      -                                const TargetData* TD) {
      -  if (!isSafeToGetMallocArraySize(CI, Context, TD))
      -    return NULL;
      -
      -  // Match CreateMalloc's use of constant 1 array-size for non-array mallocs.
      -  if (!isArrayMalloc(CI, Context, TD))
      -    return ConstantInt::get(CI->getOperand(1)->getType(), 1);
      -
      -  Value* MallocArg = CI->getOperand(1);
      -  assert(getMallocAllocatedType(CI) && "getMallocArraySize and no type");
      -  Constant *ElementSize = ConstantExpr::getSizeOf(getMallocAllocatedType(CI));
      -  ElementSize = ConstantExpr::getTruncOrBitCast(ElementSize, 
      -                                                MallocArg->getType());
      -
      -  Constant* CO = dyn_cast(MallocArg);
      -  BinaryOperator* BO = dyn_cast(MallocArg);
      -  assert((isConstantOne(ElementSize) || CO || BO) &&
      -         "getMallocArraySize and malformed malloc IR");
      -      
      -  if (isConstantOne(ElementSize))
      -    return MallocArg;
      -    
      -  if (CO)
      -    return CO->getOperand(0);
      -    
      -  // TODO: Detect case where MallocArg mul has been transformed to shl.
      -
      -  assert(BO && "getMallocArraySize not constant but not multiplication either");
      -  return BO->getOperand(0);
      -}
      -
      -//===----------------------------------------------------------------------===//
      -//  free Call Utility Functions.
      -//
      -
      -/// isFreeCall - Returns true if the the value is a call to the builtin free()
      -bool llvm::isFreeCall(const Value* I) {
      -  const CallInst *CI = dyn_cast(I);
      -  if (!CI)
      -    return false;
      -
      -  const Module* M = CI->getParent()->getParent()->getParent();
      -  Function *FreeFunc = M->getFunction("free");
      -
      -  if (CI->getOperand(0) != FreeFunc)
      -    return false;
      -
      -  // Check free prototype.
      -  // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin 
      -  // attribute will exist.
      -  const FunctionType *FTy = FreeFunc->getFunctionType();
      -  if (FTy->getReturnType() != Type::getVoidTy(M->getContext()))
      -    return false;
      -  if (FTy->getNumParams() != 1)
      -    return false;
      -  if (FTy->param_begin()->get() != Type::getInt8PtrTy(M->getContext()))
      -    return false;
      -
      -  return true;
      -}
      
      Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=85181&r1=85180&r2=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original)
      +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Mon Oct 26 18:58:56 2009
      @@ -20,7 +20,7 @@
       #include "llvm/IntrinsicInst.h"
       #include "llvm/Function.h"
       #include "llvm/Analysis/AliasAnalysis.h"
      -#include "llvm/Analysis/MallocHelper.h"
      +#include "llvm/Analysis/MallocFreeHelper.h"
       #include "llvm/ADT/Statistic.h"
       #include "llvm/ADT/STLExtras.h"
       #include "llvm/Support/PredIteratorCache.h"
      
      Modified: llvm/trunk/lib/Analysis/PointerTracking.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PointerTracking.cpp?rev=85181&r1=85180&r2=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Analysis/PointerTracking.cpp (original)
      +++ llvm/trunk/lib/Analysis/PointerTracking.cpp Mon Oct 26 18:58:56 2009
      @@ -13,7 +13,7 @@
       #include "llvm/Analysis/ConstantFolding.h"
       #include "llvm/Analysis/Dominators.h"
       #include "llvm/Analysis/LoopInfo.h"
      -#include "llvm/Analysis/MallocHelper.h"
      +#include "llvm/Analysis/MallocFreeHelper.h"
       #include "llvm/Analysis/PointerTracking.h"
       #include "llvm/Analysis/ScalarEvolution.h"
       #include "llvm/Analysis/ScalarEvolutionExpressions.h"
      
      Modified: llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp?rev=85181&r1=85180&r2=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp (original)
      +++ llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp Mon Oct 26 18:58:56 2009
      @@ -26,7 +26,7 @@
       #include "llvm/Analysis/AliasAnalysis.h"
       #include "llvm/Analysis/CallGraph.h"
       #include "llvm/Analysis/CaptureTracking.h"
      -#include "llvm/Analysis/MallocHelper.h"
      +#include "llvm/Analysis/MallocFreeHelper.h"
       #include "llvm/ADT/SmallSet.h"
       #include "llvm/ADT/Statistic.h"
       #include "llvm/ADT/UniqueVector.h"
      
      Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=85181&r1=85180&r2=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
      +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Mon Oct 26 18:58:56 2009
      @@ -24,7 +24,7 @@
       #include "llvm/Module.h"
       #include "llvm/Pass.h"
       #include "llvm/Analysis/ConstantFolding.h"
      -#include "llvm/Analysis/MallocHelper.h"
      +#include "llvm/Analysis/MallocFreeHelper.h"
       #include "llvm/Target/TargetData.h"
       #include "llvm/Support/CallSite.h"
       #include "llvm/Support/Debug.h"
      
      Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=85181&r1=85180&r2=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original)
      +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Mon Oct 26 18:58:56 2009
      @@ -26,7 +26,7 @@
       #include "llvm/ADT/Statistic.h"
       #include "llvm/Analysis/AliasAnalysis.h"
       #include "llvm/Analysis/Dominators.h"
      -#include "llvm/Analysis/MallocHelper.h"
      +#include "llvm/Analysis/MallocFreeHelper.h"
       #include "llvm/Analysis/MemoryDependenceAnalysis.h"
       #include "llvm/Target/TargetData.h"
       #include "llvm/Transforms/Utils/Local.h"
      
      Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=85181&r1=85180&r2=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original)
      +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Mon Oct 26 18:58:56 2009
      @@ -33,7 +33,7 @@
       #include "llvm/ADT/Statistic.h"
       #include "llvm/Analysis/Dominators.h"
       #include "llvm/Analysis/AliasAnalysis.h"
      -#include "llvm/Analysis/MallocHelper.h"
      +#include "llvm/Analysis/MallocFreeHelper.h"
       #include "llvm/Analysis/MemoryDependenceAnalysis.h"
       #include "llvm/Support/CFG.h"
       #include "llvm/Support/CommandLine.h"
      
      Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=85181&r1=85180&r2=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
      +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Oct 26 18:58:56 2009
      @@ -42,7 +42,7 @@
       #include "llvm/GlobalVariable.h"
       #include "llvm/Operator.h"
       #include "llvm/Analysis/ConstantFolding.h"
      -#include "llvm/Analysis/MallocHelper.h"
      +#include "llvm/Analysis/MallocFreeHelper.h"
       #include "llvm/Analysis/ValueTracking.h"
       #include "llvm/Target/TargetData.h"
       #include "llvm/Transforms/Utils/BasicBlockUtils.h"
      
      Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85181&r1=85180&r2=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original)
      +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Mon Oct 26 18:58:56 2009
      @@ -30,7 +30,7 @@
       #include "llvm/LLVMContext.h"
       #include "llvm/Pass.h"
       #include "llvm/Analysis/ConstantFolding.h"
      -#include "llvm/Analysis/MallocHelper.h"
      +#include "llvm/Analysis/MallocFreeHelper.h"
       #include "llvm/Analysis/ValueTracking.h"
       #include "llvm/Transforms/Utils/Local.h"
       #include "llvm/Support/CallSite.h"
      
      Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=85181&r1=85180&r2=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original)
      +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Mon Oct 26 18:58:56 2009
      @@ -24,7 +24,7 @@
       #include "llvm/ADT/SmallPtrSet.h"
       #include "llvm/Analysis/ConstantFolding.h"
       #include "llvm/Analysis/DebugInfo.h"
      -#include "llvm/Analysis/MallocHelper.h"
      +#include "llvm/Analysis/MallocFreeHelper.h"
       #include "llvm/Analysis/ProfileInfo.h"
       #include "llvm/Target/TargetData.h"
       #include "llvm/Support/GetElementPtrTypeIterator.h"
      
      Modified: llvm/trunk/lib/VMCore/Instruction.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=85181&r1=85180&r2=85181&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/VMCore/Instruction.cpp (original)
      +++ llvm/trunk/lib/VMCore/Instruction.cpp Mon Oct 26 18:58:56 2009
      @@ -302,7 +302,7 @@
         return false;
       }
       
      -// Code here matches isFreeCall from MallocHelper, which is not in VMCore.
      +// Code here matches isFreeCall from MallocFreeHelper, which is not in VMCore.
       static bool isFreeCall(const Value* I) {
         const CallInst *CI = dyn_cast(I);
         if (!CI)
      @@ -407,7 +407,7 @@
         }
       }
       
      -// Code here matches isMalloc from MallocHelper, which is not in VMCore.
      +// Code here matches isMalloc from MallocFreeHelper, which is not in VMCore.
       static bool isMalloc(const Value* I) {
         const CallInst *CI = dyn_cast(I);
         if (!CI) {
      
      
      
      
      From jyasskin at google.com  Mon Oct 26 19:03:05 2009
      From: jyasskin at google.com (Jeffrey Yasskin)
      Date: Tue, 27 Oct 2009 00:03:05 -0000
      Subject: [llvm-commits] [llvm] r85182 - in /llvm/trunk:
       include/llvm/ExecutionEngine/ExecutionEngine.h
       include/llvm/ExecutionEngine/JITEventListener.h
       lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngine/JIT/JIT.h
       lib/ExecutionEngine/JIT/JITEmitter.cpp
       lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp
       unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
       unittests/ExecutionEngine/JIT/JITTest.cpp
      Message-ID: <200910270003.n9R036DH013027@zion.cs.uiuc.edu>
      
      Author: jyasskin
      Date: Mon Oct 26 19:03:05 2009
      New Revision: 85182
      
      URL: http://llvm.org/viewvc/llvm-project?rev=85182&view=rev
      Log:
      Automatically do the equivalent of freeMachineCodeForFunction(F) when F is
      being destroyed. This allows users to run global optimizations like globaldce
      even after some functions have been jitted.
      
      This patch also removes the Function* parameter to
      JITEventListener::NotifyFreeingMachineCode() since it can cause that to be
      called when the Function is partially destroyed. This change will be even more
      helpful later when I think we'll want to allow machine code to actually outlive
      its Function.
      
      Modified:
          llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h
          llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h
          llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp
          llvm/trunk/lib/ExecutionEngine/JIT/JIT.h
          llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp
          llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp
          llvm/trunk/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
          llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp
      
      Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h?rev=85182&r1=85181&r2=85182&view=diff
      
      ==============================================================================
      --- llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h (original)
      +++ llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h Mon Oct 26 19:03:05 2009
      @@ -263,9 +263,8 @@
         /// getPointerToFunction - The different EE's represent function bodies in
         /// different ways.  They should each implement this to say what a function
         /// pointer should look like.  When F is destroyed, the ExecutionEngine will
      -  /// remove its global mapping but will not yet free its machine code.  Call
      -  /// freeMachineCodeForFunction(F) explicitly to do that.  Note that global
      -  /// optimizations can destroy Functions without notifying the ExecutionEngine.
      +  /// remove its global mapping and free any machine code.  Be sure no threads
      +  /// are running inside F when that happens.
         ///
         virtual void *getPointerToFunction(Function *F) = 0;
       
      
      Modified: llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h?rev=85182&r1=85181&r2=85182&view=diff
      
      ==============================================================================
      --- llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h (original)
      +++ llvm/trunk/include/llvm/ExecutionEngine/JITEventListener.h Mon Oct 26 19:03:05 2009
      @@ -63,8 +63,11 @@
         /// NotifyFreeingMachineCode - This is called inside of
         /// freeMachineCodeForFunction(), after the global mapping is removed, but
         /// before the machine code is returned to the allocator.  OldPtr is the
      -  /// address of the machine code.
      -  virtual void NotifyFreeingMachineCode(const Function &F, void *OldPtr) {}
      +  /// address of the machine code and will be the same as the Code parameter to
      +  /// a previous NotifyFunctionEmitted call.  The Function passed to
      +  /// NotifyFunctionEmitted may have been destroyed by the time of the matching
      +  /// NotifyFreeingMachineCode call.
      +  virtual void NotifyFreeingMachineCode(void *OldPtr) {}
       };
       
       // This returns NULL if support isn't available.
      
      Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=85182&r1=85181&r2=85182&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original)
      +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Mon Oct 26 19:03:05 2009
      @@ -556,10 +556,10 @@
         }
       }
       
      -void JIT::NotifyFreeingMachineCode(const Function &F, void *OldPtr) {
      +void JIT::NotifyFreeingMachineCode(void *OldPtr) {
         MutexGuard locked(lock);
         for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) {
      -    EventListeners[I]->NotifyFreeingMachineCode(F, OldPtr);
      +    EventListeners[I]->NotifyFreeingMachineCode(OldPtr);
         }
       }
       
      
      Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.h
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.h?rev=85182&r1=85181&r2=85182&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.h (original)
      +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.h Mon Oct 26 19:03:05 2009
      @@ -183,7 +183,7 @@
         void NotifyFunctionEmitted(
             const Function &F, void *Code, size_t Size,
             const JITEvent_EmittedFunctionDetails &Details);
      -  void NotifyFreeingMachineCode(const Function &F, void *OldPtr);
      +  void NotifyFreeingMachineCode(void *OldPtr);
       
       private:
         static JITCodeEmitter *createEmitter(JIT &J, JITMemoryManager *JMM,
      
      Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=85182&r1=85181&r2=85182&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original)
      +++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Mon Oct 26 19:03:05 2009
      @@ -582,17 +582,24 @@
           JITEvent_EmittedFunctionDetails EmissionDetails;
       
           struct EmittedCode {
      -      void *FunctionBody;
      +      void *FunctionBody;  // Beginning of the function's allocation.
      +      void *Code;  // The address the function's code actually starts at.
             void *ExceptionTable;
      -      EmittedCode() : FunctionBody(0), ExceptionTable(0) {}
      +      EmittedCode() : FunctionBody(0), Code(0), ExceptionTable(0) {}
           };
      -    DenseMap EmittedFunctions;
      +    struct EmittedFunctionConfig : public ValueMapConfig {
      +      typedef JITEmitter *ExtraData;
      +      static void onDelete(JITEmitter *, const Function*);
      +      static void onRAUW(JITEmitter *, const Function*, const Function*);
      +    };
      +    ValueMap EmittedFunctions;
       
           // CurFnStubUses - For a given Function, a vector of stubs that it
           // references.  This facilitates the JIT detecting that a stub is no
           // longer used, so that it may be deallocated.
      -    DenseMap > CurFnStubUses;
      -    
      +    DenseMap, SmallVector > CurFnStubUses;
      +
           // StubFnRefs - For a given pointer to a stub, a set of Functions which
           // reference the stub.  When the count of a stub's references drops to zero,
           // the stub is unused.
      @@ -606,7 +613,8 @@
       
         public:
           JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM)
      -        : SizeEstimate(0), Resolver(jit), MMI(0), CurFn(0) {
      +        : SizeEstimate(0), Resolver(jit), MMI(0), CurFn(0),
      +          EmittedFunctions(this) {
             MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager();
             if (jit.getJITInfo().needsGOT()) {
               MemMgr->AllocateGOT();
      @@ -1062,6 +1070,7 @@
         // About to start emitting the machine code for the function.
         emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
         TheJIT->updateGlobalMapping(F.getFunction(), CurBufferPtr);
      +  EmittedFunctions[F.getFunction()].Code = CurBufferPtr;
       
         MBBLocations.clear();
       
      @@ -1285,12 +1294,15 @@
       
       /// deallocateMemForFunction - Deallocate all memory for the specified
       /// function body.  Also drop any references the function has to stubs.
      +/// May be called while the Function is being destroyed inside ~Value().
       void JITEmitter::deallocateMemForFunction(const Function *F) {
      -  DenseMap::iterator Emitted =
      -    EmittedFunctions.find(F);
      +  ValueMap::iterator
      +    Emitted = EmittedFunctions.find(F);
         if (Emitted != EmittedFunctions.end()) {
           MemMgr->deallocateFunctionBody(Emitted->second.FunctionBody);
           MemMgr->deallocateExceptionTable(Emitted->second.ExceptionTable);
      +    TheJIT->NotifyFreeingMachineCode(Emitted->second.Code);
      +
           EmittedFunctions.erase(Emitted);
         }
       
      @@ -1519,6 +1531,17 @@
         return (uintptr_t)((char *)JumpTableBase + Offset);
       }
       
      +void JITEmitter::EmittedFunctionConfig::onDelete(
      +  JITEmitter *Emitter, const Function *F) {
      +  Emitter->deallocateMemForFunction(F);
      +}
      +void JITEmitter::EmittedFunctionConfig::onRAUW(
      +  JITEmitter *, const Function*, const Function*) {
      +  llvm_unreachable("The JIT doesn't know how to handle a"
      +                   " RAUW on a value it has emitted.");
      +}
      +
      +
       //===----------------------------------------------------------------------===//
       //  Public interface to this file
       //===----------------------------------------------------------------------===//
      @@ -1657,13 +1680,9 @@
       /// freeMachineCodeForFunction - release machine code memory for given Function.
       ///
       void JIT::freeMachineCodeForFunction(Function *F) {
      -
         // Delete translation for this from the ExecutionEngine, so it will get
         // retranslated next time it is used.
      -  void *OldPtr = updateGlobalMapping(F, 0);
      -
      -  if (OldPtr)
      -    TheJIT->NotifyFreeingMachineCode(*F, OldPtr);
      +  updateGlobalMapping(F, 0);
       
         // Free the actual memory for the function body and related stuff.
         assert(isa(JCE) && "Unexpected MCE?");
      
      Modified: llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp?rev=85182&r1=85181&r2=85182&view=diff
      
      ==============================================================================
      --- llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp (original)
      +++ llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp Mon Oct 26 19:03:05 2009
      @@ -147,13 +147,13 @@
         }
       }
       
      -// Removes the to-be-deleted function from the symbol table.
      -void OProfileJITEventListener::NotifyFreeingMachineCode(
      -    const Function &F, void *FnStart) {
      +// Removes the being-deleted function from the symbol table.
      +void OProfileJITEventListener::NotifyFreeingMachineCode(void *FnStart) {
         assert(FnStart && "Invalid function pointer");
         if (op_unload_native_code(Agent, reinterpret_cast(FnStart)) == -1) {
      -    DEBUG(errs() << "Failed to tell OProfile about unload of native function "
      -                 << F.getName() << " at " << FnStart << "\n");
      +    DEBUG(errs()
      +          << "Failed to tell OProfile about unload of native function at "
      +          << FnStart << "\n");
         }
       }
       
      
      Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp?rev=85182&r1=85181&r2=85182&view=diff
      
      ==============================================================================
      --- llvm/trunk/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp (original)
      +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp Mon Oct 26 19:03:05 2009
      @@ -37,7 +37,6 @@
       };
       struct FunctionFreedEvent {
         unsigned Index;
      -  const Function *F;
         void *Code;
       };
       
      @@ -56,8 +55,8 @@
           EmittedEvents.push_back(Event);
         }
       
      -  virtual void NotifyFreeingMachineCode(const Function &F, void *OldPtr) {
      -    FunctionFreedEvent Event = {NextIndex++, &F, OldPtr};
      +  virtual void NotifyFreeingMachineCode(void *OldPtr) {
      +    FunctionFreedEvent Event = {NextIndex++, OldPtr};
           FreedEvents.push_back(Event);
         }
       };
      @@ -116,11 +115,9 @@
             << " contain some bytes.";
       
         EXPECT_EQ(2U, Listener.FreedEvents[0].Index);
      -  EXPECT_EQ(F1, Listener.FreedEvents[0].F);
         EXPECT_EQ(F1_addr, Listener.FreedEvents[0].Code);
       
         EXPECT_EQ(3U, Listener.FreedEvents[1].Index);
      -  EXPECT_EQ(F2, Listener.FreedEvents[1].F);
         EXPECT_EQ(F2_addr, Listener.FreedEvents[1].Code);
       
         F1->eraseFromParent();
      @@ -164,7 +161,6 @@
             << " contain some bytes.";
       
         EXPECT_EQ(1U, Listener1.FreedEvents[0].Index);
      -  EXPECT_EQ(F2, Listener1.FreedEvents[0].F);
         EXPECT_EQ(F2_addr, Listener1.FreedEvents[0].Code);
       
         // Listener 2.
      @@ -186,7 +182,6 @@
             << " contain some bytes.";
       
         EXPECT_EQ(2U, Listener2.FreedEvents[0].Index);
      -  EXPECT_EQ(F2, Listener2.FreedEvents[0].F);
         EXPECT_EQ(F2_addr, Listener2.FreedEvents[0].Code);
       
         // Listener 3.
      @@ -201,7 +196,6 @@
             << " contain some bytes.";
       
         EXPECT_EQ(1U, Listener3.FreedEvents[0].Index);
      -  EXPECT_EQ(F2, Listener3.FreedEvents[0].F);
         EXPECT_EQ(F2_addr, Listener3.FreedEvents[0].Code);
       
         F1->eraseFromParent();
      @@ -228,7 +222,6 @@
         EXPECT_EQ(MCI.size(), Listener.EmittedEvents[0].Size);
       
         EXPECT_EQ(1U, Listener.FreedEvents[0].Index);
      -  EXPECT_EQ(F, Listener.FreedEvents[0].F);
         EXPECT_EQ(F_addr, Listener.FreedEvents[0].Code);
       }
       
      
      Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp
      URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=85182&r1=85181&r2=85182&view=diff
      
      ==============================================================================
      --- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original)
      +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Mon Oct 26 19:03:05 2009
      @@ -9,6 +9,7 @@
       
       #include "gtest/gtest.h"
       #include "llvm/ADT/OwningPtr.h"
      +#include "llvm/ADT/SmallPtrSet.h"
       #include "llvm/Assembly/Parser.h"
       #include "llvm/BasicBlock.h"
       #include "llvm/Constant.h"
      @@ -28,6 +29,8 @@
       #include "llvm/Target/TargetSelect.h"
       #include "llvm/Type.h"
       
      +#include 
      +
       using namespace llvm;
       
       namespace {
      @@ -47,13 +50,141 @@
         return F;
       }
       
      +std::string DumpFunction(const Function *F) {
      +  std::string Result;
      +  raw_string_ostream(Result) << "" << *F;
      +  return Result;
      +}
      +
      +class RecordingJITMemoryManager : public JITMemoryManager {
      +  const OwningPtr Base;
      +public:
      +  RecordingJITMemoryManager()
      +    : Base(JITMemoryManager::CreateDefaultMemManager()) {
      +  }
      +
      +  virtual void setMemoryWritable() { Base->setMemoryWritable(); }
      +  virtual void setMemoryExecutable() { Base->setMemoryExecutable(); }
      +  virtual void setPoisonMemory(bool poison) { Base->setPoisonMemory(poison); }
      +  virtual void AllocateGOT() { Base->AllocateGOT(); }
      +  virtual uint8_t *getGOTBase() const { return Base->getGOTBase(); }
      +  virtual void SetDlsymTable(void *ptr) { Base->SetDlsymTable(ptr); }
      +  virtual void *getDlsymTable() const { return Base->getDlsymTable(); }
      +  struct StartFunctionBodyCall {
      +    StartFunctionBodyCall(uint8_t *Result, const Function *F,
      +                          uintptr_t ActualSize, uintptr_t ActualSizeResult)
      +      : Result(Result), F(F), F_dump(DumpFunction(F)),
      +        ActualSize(ActualSize), ActualSizeResult(ActualSizeResult) {}
      +    uint8_t *Result;
      +    const Function *F;
      +    std::string F_dump;
      +    uintptr_t ActualSize;
      +    uintptr_t ActualSizeResult;
      +  };
      +  std::vector startFunctionBodyCalls;
      +  virtual uint8_t *startFunctionBody(const Function *F,
      +                                     uintptr_t &ActualSize) {
      +    uintptr_t InitialActualSize = ActualSize;
      +    uint8_t *Result = Base->startFunctionBody(F, ActualSize);
      +    startFunctionBodyCalls.push_back(
      +      StartFunctionBodyCall(Result, F, InitialActualSize, ActualSize));
      +    return Result;
      +  }
      +  virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
      +                                unsigned Alignment) {
      +    return Base->allocateStub(F, StubSize, Alignment);
      +  }
      +  struct EndFunctionBodyCall {
      +    EndFunctionBodyCall(const Function *F, uint8_t *FunctionStart,
      +                        uint8_t *FunctionEnd)
      +      : F(F), F_dump(DumpFunction(F)),
      +        FunctionStart(FunctionStart), FunctionEnd(FunctionEnd) {}
      +    const Function *F;
      +    std::string F_dump;
      +    uint8_t *FunctionStart;
      +    uint8_t *FunctionEnd;
      +  };
      +  std::vector endFunctionBodyCalls;
      +  virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
      +                               uint8_t *FunctionEnd) {
      +    endFunctionBodyCalls.push_back(
      +      EndFunctionBodyCall(F, FunctionStart, FunctionEnd));
      +    Base->endFunctionBody(F, FunctionStart, FunctionEnd);
      +  }
      +  virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
      +    return Base->allocateSpace(Size, Alignment);
      +  }
      +  virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
      +    return Base->allocateGlobal(Size, Alignment);
      +  }
      +  struct DeallocateFunctionBodyCall {
      +    DeallocateFunctionBodyCall(const void *Body) : Body(Body) {}
      +    const void *Body;
      +  };
      +  std::vector deallocateFunctionBodyCalls;
      +  virtual void deallocateFunctionBody(void *Body) {
      +    deallocateFunctionBodyCalls.push_back(DeallocateFunctionBodyCall(Body));
      +    Base->deallocateFunctionBody(Body);
      +  }
      +  struct DeallocateExceptionTableCall {
      +    DeallocateExceptionTableCall(const void *ET) : ET(ET) {}
      +    const void *ET;
      +  };
      +  std::vector deallocateExceptionTableCalls;
      +  virtual void deallocateExceptionTable(void *ET) {
      +    deallocateExceptionTableCalls.push_back(DeallocateExceptionTableCall(ET));
      +    Base->deallocateExceptionTable(ET);
      +  }
      +  struct StartExceptionTableCall {
      +    StartExceptionTableCall(uint8_t *Result, const Function *F,
      +                            uintptr_t ActualSize, uintptr_t ActualSizeResult)
      +      : Result(Result), F(F), F_dump(DumpFunction(F)),
      +        ActualSize(ActualSize), ActualSizeResult(ActualSizeResult) {}
      +    uint8_t *Result;
      +    const Function *F;
      +    std::string F_dump;
      +    uintptr_t ActualSize;
      +    uintptr_t ActualSizeResult;
      +  };
      +  std::vector startExceptionTableCalls;
      +  virtual uint8_t* startExceptionTable(const Function* F,
      +                                       uintptr_t &ActualSize) {
      +    uintptr_t InitialActualSize = ActualSize;
      +    uint8_t *Result = Base->startExceptionTable(F, ActualSize);
      +    startExceptionTableCalls.push_back(
      +      StartExceptionTableCall(Result, F, InitialActualSize, ActualSize));
      +    return Result;
      +  }
      +  struct EndExceptionTableCall {
      +    EndExceptionTableCall(const Function *F, uint8_t *TableStart,
      +                          uint8_t *TableEnd, uint8_t* FrameRegister)
      +      : F(F), F_dump(DumpFunction(F)),
      +        TableStart(TableStart), TableEnd(TableEnd),
      +        FrameRegister(FrameRegister) {}
      +    const Function *F;
      +    std::string F_dump;
      +    uint8_t *TableStart;
      +    uint8_t *TableEnd;
      +    uint8_t *FrameRegister;
      +  };
      +  std::vector endExceptionTableCalls;
      +  virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
      +                                 uint8_t *TableEnd, uint8_t* FrameRegister) {
      +      endExceptionTableCalls.push_back(
      +          EndExceptionTableCall(F, TableStart, TableEnd, FrameRegister));
      +    return Base->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
      +  }
      +};
      +
       class JITTest : public testing::Test {
        protected:
         virtual void SetUp() {
           M = new Module("
      ", Context); MP = new ExistingModuleProvider(M); + RJMM = new RecordingJITMemoryManager; std::string Error; TheJIT.reset(EngineBuilder(MP).setEngineKind(EngineKind::JIT) + .setJITMemoryManager(RJMM) .setErrorStr(&Error).create()); ASSERT_TRUE(TheJIT.get() != NULL) << Error; } @@ -70,6 +201,7 @@ LLVMContext Context; Module *M; // Owned by MP. ModuleProvider *MP; // Owned by ExecutionEngine. + RecordingJITMemoryManager *RJMM; OwningPtr TheJIT; }; @@ -289,6 +421,34 @@ Function *func = M->getFunction("main"); TheJIT->getPointerToFunction(func); TheJIT->deleteModuleProvider(MP); + + SmallPtrSet FunctionsDeallocated; + for (unsigned i = 0, e = RJMM->deallocateFunctionBodyCalls.size(); + i != e; ++i) { + FunctionsDeallocated.insert(RJMM->deallocateFunctionBodyCalls[i].Body); + } + for (unsigned i = 0, e = RJMM->startFunctionBodyCalls.size(); i != e; ++i) { + EXPECT_TRUE(FunctionsDeallocated.count( + RJMM->startFunctionBodyCalls[i].Result)) + << "Function leaked: \n" << RJMM->startFunctionBodyCalls[i].F_dump; + } + EXPECT_EQ(RJMM->startFunctionBodyCalls.size(), + RJMM->deallocateFunctionBodyCalls.size()); + + SmallPtrSet ExceptionTablesDeallocated; + for (unsigned i = 0, e = RJMM->deallocateExceptionTableCalls.size(); + i != e; ++i) { + ExceptionTablesDeallocated.insert( + RJMM->deallocateExceptionTableCalls[i].ET); + } + for (unsigned i = 0, e = RJMM->startExceptionTableCalls.size(); i != e; ++i) { + EXPECT_TRUE(ExceptionTablesDeallocated.count( + RJMM->startExceptionTableCalls[i].Result)) + << "Function's exception table leaked: \n" + << RJMM->startExceptionTableCalls[i].F_dump; + } + EXPECT_EQ(RJMM->startExceptionTableCalls.size(), + RJMM->deallocateExceptionTableCalls.size()); } // This code is copied from JITEventListenerTest, but it only runs once for all From evan.cheng at apple.com Mon Oct 26 19:08:59 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 27 Oct 2009 00:08:59 -0000 Subject: [llvm-commits] [llvm] r85184 - in /llvm/trunk/lib/Target/ARM: ARMInstrThumb.td ARMInstrThumb2.td Message-ID: <200910270008.n9R08xTj013255@zion.cs.uiuc.edu> Author: evancheng Date: Mon Oct 26 19:08:59 2009 New Revision: 85184 URL: http://llvm.org/viewvc/llvm-project?rev=85184&view=rev Log: Change Thumb1 and Thumb2 instructions to separate opcode from operands with a tab instead of a space. Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=85184&r1=85183&r2=85184&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Mon Oct 26 19:08:59 2009 @@ -130,44 +130,44 @@ // For both thumb1 and thumb2. let isNotDuplicable = 1 in def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALUr, - "\n$cp:\n\tadd $dst, pc", + "\n$cp:\n\tadd\t$dst, pc", [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>; // PC relative add. def tADDrPCi : T1I<(outs tGPR:$dst), (ins i32imm:$rhs), IIC_iALUi, - "add $dst, pc, $rhs * 4", []>; + "add\t$dst, pc, $rhs * 4", []>; // ADD rd, sp, #imm8 def tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, i32imm:$rhs), IIC_iALUi, - "add $dst, $sp, $rhs * 4", []>; + "add\t$dst, $sp, $rhs * 4", []>; // ADD sp, sp, #imm7 def tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALUi, - "add $dst, $rhs * 4", []>; + "add\t$dst, $rhs * 4", []>; // SUB sp, sp, #imm7 def tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALUi, - "sub $dst, $rhs * 4", []>; + "sub\t$dst, $rhs * 4", []>; // ADD rm, sp def tADDrSP : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, - "add $dst, $rhs", []>; + "add\t$dst, $rhs", []>; // ADD sp, rm def tADDspr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, - "add $dst, $rhs", []>; + "add\t$dst, $rhs", []>; // Pseudo instruction that will expand into a tSUBspi + a copy. let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. def tSUBspi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), - NoItinerary, "@ sub $dst, $rhs * 4", []>; + NoItinerary, "@ sub\t$dst, $rhs * 4", []>; def tADDspr_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), - NoItinerary, "@ add $dst, $rhs", []>; + NoItinerary, "@ add\t$dst, $rhs", []>; let Defs = [CPSR] in def tANDsp : PseudoInst<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), - NoItinerary, "@ and $dst, $rhs", []>; + NoItinerary, "@ and\t$dst, $rhs", []>; } // usesCustomDAGSchedInserter //===----------------------------------------------------------------------===// @@ -175,16 +175,16 @@ // let isReturn = 1, isTerminator = 1, isBarrier = 1 in { - def tBX_RET : TI<(outs), (ins), IIC_Br, "bx lr", [(ARMretflag)]>; + def tBX_RET : TI<(outs), (ins), IIC_Br, "bx\tlr", [(ARMretflag)]>; // Alternative return instruction used by vararg functions. - def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx $target", []>; + def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t$target", []>; } // FIXME: remove when we have a way to marking a MI with these properties. let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, hasExtraDefRegAllocReq = 1 in def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, - "pop${p} $wb", []>; + "pop${p}\t$wb", []>; let isCall = 1, Defs = [R0, R1, R2, R3, R12, LR, @@ -193,25 +193,25 @@ D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { // Also used for Thumb2 def tBL : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, - "bl ${func:call}", + "bl\t${func:call}", [(ARMtcall tglobaladdr:$func)]>, Requires<[IsThumb, IsNotDarwin]>; // ARMv5T and above, also used for Thumb2 def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, - "blx ${func:call}", + "blx\t${func:call}", [(ARMcall tglobaladdr:$func)]>, Requires<[IsThumb, HasV5T, IsNotDarwin]>; // Also used for Thumb2 def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, - "blx $func", + "blx\t$func", [(ARMtcall GPR:$func)]>, Requires<[IsThumb, HasV5T, IsNotDarwin]>; // ARMv4T def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, - "mov lr, pc\n\tbx $func", + "mov\tlr, pc\n\tbx\t$func", [(ARMcall_nolink tGPR:$func)]>, Requires<[IsThumb1Only, IsNotDarwin]>; } @@ -224,25 +224,25 @@ D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { // Also used for Thumb2 def tBLr9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, - "bl ${func:call}", + "bl\t${func:call}", [(ARMtcall tglobaladdr:$func)]>, Requires<[IsThumb, IsDarwin]>; // ARMv5T and above, also used for Thumb2 def tBLXi_r9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, - "blx ${func:call}", + "blx\t${func:call}", [(ARMcall tglobaladdr:$func)]>, Requires<[IsThumb, HasV5T, IsDarwin]>; // Also used for Thumb2 def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, - "blx $func", + "blx\t$func", [(ARMtcall GPR:$func)]>, Requires<[IsThumb, HasV5T, IsDarwin]>; // ARMv4T def tBXr9 : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, - "mov lr, pc\n\tbx $func", + "mov\tlr, pc\n\tbx\t$func", [(ARMcall_nolink tGPR:$func)]>, Requires<[IsThumb1Only, IsDarwin]>; } @@ -251,16 +251,16 @@ let isBarrier = 1 in { let isPredicable = 1 in def tB : T1I<(outs), (ins brtarget:$target), IIC_Br, - "b $target", [(br bb:$target)]>; + "b\t$target", [(br bb:$target)]>; // Far jump let Defs = [LR] in def tBfar : TIx2<(outs), (ins brtarget:$target), IIC_Br, - "bl $target\t@ far jump",[]>; + "bl\t$target\t@ far jump",[]>; def tBR_JTr : T1JTI<(outs), (ins tGPR:$target, jtblock_operand:$jt, i32imm:$id), - IIC_Br, "mov pc, $target\n\t.align\t2\n$jt", + IIC_Br, "mov\tpc, $target\n\t.align\t2\n$jt", [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>; } } @@ -269,7 +269,7 @@ // a two-value operand where a dag node expects two operands. :( let isBranch = 1, isTerminator = 1 in def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), IIC_Br, - "b$cc $target", + "b$cc\t$target", [/*(ARMbrcond bb:$target, imm:$cc)*/]>; //===----------------------------------------------------------------------===// @@ -278,70 +278,70 @@ let canFoldAsLoad = 1 in def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, - "ldr", " $dst, $addr", + "ldr", "\t$dst, $addr", [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>; def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr, - "ldrb", " $dst, $addr", + "ldrb", "\t$dst, $addr", [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr, - "ldrh", " $dst, $addr", + "ldrh", "\t$dst, $addr", [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>; let AddedComplexity = 10 in def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr, - "ldrsb", " $dst, $addr", + "ldrsb", "\t$dst, $addr", [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>; let AddedComplexity = 10 in def tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr, - "ldrsh", " $dst, $addr", + "ldrsh", "\t$dst, $addr", [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>; let canFoldAsLoad = 1 in def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi, - "ldr", " $dst, $addr", + "ldr", "\t$dst, $addr", [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>; // Special instruction for restore. It cannot clobber condition register // when it's expanded by eliminateCallFramePseudoInstr(). let canFoldAsLoad = 1, mayLoad = 1 in def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi, - "ldr", " $dst, $addr", []>; + "ldr", "\t$dst, $addr", []>; // Load tconstpool let canFoldAsLoad = 1 in def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, - "ldr", " $dst, $addr", + "ldr", "\t$dst, $addr", [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; // Special LDR for loads from non-pc-relative constpools. let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, - "ldr", " $dst, $addr", []>; + "ldr", "\t$dst, $addr", []>; def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer, - "str", " $src, $addr", + "str", "\t$src, $addr", [(store tGPR:$src, t_addrmode_s4:$addr)]>; def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer, - "strb", " $src, $addr", + "strb", "\t$src, $addr", [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>; def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer, - "strh", " $src, $addr", + "strh", "\t$src, $addr", [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>; def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei, - "str", " $src, $addr", + "str", "\t$src, $addr", [(store tGPR:$src, t_addrmode_sp:$addr)]>; let mayStore = 1 in { // Special instruction for spill. It cannot clobber condition register // when it's expanded by eliminateCallFramePseudoInstr(). def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei, - "str", " $src, $addr", []>; + "str", "\t$src, $addr", []>; } //===----------------------------------------------------------------------===// @@ -353,21 +353,21 @@ def tLDM : T1I<(outs), (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), IIC_iLoadm, - "ldm${addr:submode}${p} $addr, $wb", []>; + "ldm${addr:submode}${p}\t$addr, $wb", []>; let mayStore = 1, hasExtraSrcRegAllocReq = 1 in def tSTM : T1I<(outs), (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), IIC_iStorem, - "stm${addr:submode}${p} $addr, $wb", []>; + "stm${addr:submode}${p}\t$addr, $wb", []>; let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in def tPOP : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, - "pop${p} $wb", []>; + "pop${p}\t$wb", []>; let mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in def tPUSH : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, - "push${p} $wb", []>; + "push${p}\t$wb", []>; //===----------------------------------------------------------------------===// // Arithmetic Instructions. @@ -376,66 +376,66 @@ // Add with carry register let isCommutable = 1, Uses = [CPSR] in def tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, - "adc", " $dst, $rhs", + "adc", "\t$dst, $rhs", [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>; // Add immediate def tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, - "add", " $dst, $lhs, $rhs", + "add", "\t$dst, $lhs, $rhs", [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>; def tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, - "add", " $dst, $rhs", + "add", "\t$dst, $rhs", [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>; // Add register let isCommutable = 1 in def tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, - "add", " $dst, $lhs, $rhs", + "add", "\t$dst, $lhs, $rhs", [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>; let neverHasSideEffects = 1 in def tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, - "add", " $dst, $rhs", []>; + "add", "\t$dst, $rhs", []>; // And register let isCommutable = 1 in def tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, - "and", " $dst, $rhs", + "and", "\t$dst, $rhs", [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>; // ASR immediate def tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, - "asr", " $dst, $lhs, $rhs", + "asr", "\t$dst, $lhs, $rhs", [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>; // ASR register def tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, - "asr", " $dst, $rhs", + "asr", "\t$dst, $rhs", [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>; // BIC register def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, - "bic", " $dst, $rhs", + "bic", "\t$dst, $rhs", [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>; // CMN register let Defs = [CPSR] in { def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, - "cmn", " $lhs, $rhs", + "cmn", "\t$lhs, $rhs", [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>; def tCMNZ : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, - "cmn", " $lhs, $rhs", + "cmn", "\t$lhs, $rhs", [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>; } // CMP immediate let Defs = [CPSR] in { def tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, - "cmp", " $lhs, $rhs", + "cmp", "\t$lhs, $rhs", [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>; def tCMPzi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, - "cmp", " $lhs, $rhs", + "cmp", "\t$lhs, $rhs", [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>; } @@ -443,48 +443,48 @@ // CMP register let Defs = [CPSR] in { def tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, - "cmp", " $lhs, $rhs", + "cmp", "\t$lhs, $rhs", [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>; def tCMPzr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, - "cmp", " $lhs, $rhs", + "cmp", "\t$lhs, $rhs", [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>; def tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, - "cmp", " $lhs, $rhs", []>; + "cmp", "\t$lhs, $rhs", []>; def tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, - "cmp", " $lhs, $rhs", []>; + "cmp", "\t$lhs, $rhs", []>; } // XOR register let isCommutable = 1 in def tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, - "eor", " $dst, $rhs", + "eor", "\t$dst, $rhs", [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>; // LSL immediate def tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, - "lsl", " $dst, $lhs, $rhs", + "lsl", "\t$dst, $lhs, $rhs", [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>; // LSL register def tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, - "lsl", " $dst, $rhs", + "lsl", "\t$dst, $rhs", [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>; // LSR immediate def tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, - "lsr", " $dst, $lhs, $rhs", + "lsr", "\t$dst, $lhs, $rhs", [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>; // LSR register def tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, - "lsr", " $dst, $rhs", + "lsr", "\t$dst, $rhs", [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>; // move register def tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src), IIC_iMOVi, - "mov", " $dst, $src", + "mov", "\t$dst, $src", [(set tGPR:$dst, imm0_255:$src)]>; // TODO: A7-73: MOV(2) - mov setting flag. @@ -493,45 +493,45 @@ let neverHasSideEffects = 1 in { // FIXME: Make this predicable. def tMOVr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, - "mov $dst, $src", []>; + "mov\t$dst, $src", []>; let Defs = [CPSR] in def tMOVSr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, - "movs $dst, $src", []>; + "movs\t$dst, $src", []>; // FIXME: Make these predicable. def tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iMOVr, - "mov $dst, $src", []>; + "mov\t$dst, $src", []>; def tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iMOVr, - "mov $dst, $src", []>; + "mov\t$dst, $src", []>; def tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, - "mov $dst, $src", []>; + "mov\t$dst, $src", []>; } // neverHasSideEffects // multiply register let isCommutable = 1 in def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMUL32, - "mul", " $dst, $rhs", + "mul", "\t$dst, $rhs", [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>; // move inverse register def tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, - "mvn", " $dst, $src", + "mvn", "\t$dst, $src", [(set tGPR:$dst, (not tGPR:$src))]>; // bitwise or register let isCommutable = 1 in def tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, - "orr", " $dst, $rhs", + "orr", "\t$dst, $rhs", [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>; // swaps def tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, - "rev", " $dst, $src", + "rev", "\t$dst, $src", [(set tGPR:$dst, (bswap tGPR:$src))]>, Requires<[IsThumb1Only, HasV6]>; def tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, - "rev16", " $dst, $src", + "rev16", "\t$dst, $src", [(set tGPR:$dst, (or (and (srl tGPR:$src, (i32 8)), 0xFF), (or (and (shl tGPR:$src, (i32 8)), 0xFF00), @@ -540,7 +540,7 @@ Requires<[IsThumb1Only, HasV6]>; def tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, - "revsh", " $dst, $src", + "revsh", "\t$dst, $src", [(set tGPR:$dst, (sext_inreg (or (srl (and tGPR:$src, 0xFF00), (i32 8)), @@ -549,63 +549,63 @@ // rotate right register def tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, - "ror", " $dst, $rhs", + "ror", "\t$dst, $rhs", [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>; // negate register def tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALUi, - "rsb", " $dst, $src, #0", + "rsb", "\t$dst, $src, #0", [(set tGPR:$dst, (ineg tGPR:$src))]>; // Subtract with carry register let Uses = [CPSR] in def tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, - "sbc", " $dst, $rhs", + "sbc", "\t$dst, $rhs", [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>; // Subtract immediate def tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, - "sub", " $dst, $lhs, $rhs", + "sub", "\t$dst, $lhs, $rhs", [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>; def tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, - "sub", " $dst, $rhs", + "sub", "\t$dst, $rhs", [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>; // subtract register def tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, - "sub", " $dst, $lhs, $rhs", + "sub", "\t$dst, $lhs, $rhs", [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>; // TODO: A7-96: STMIA - store multiple. // sign-extend byte def tSXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, - "sxtb", " $dst, $src", + "sxtb", "\t$dst, $src", [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>, Requires<[IsThumb1Only, HasV6]>; // sign-extend short def tSXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, - "sxth", " $dst, $src", + "sxth", "\t$dst, $src", [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>, Requires<[IsThumb1Only, HasV6]>; // test let isCommutable = 1, Defs = [CPSR] in def tTST : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, - "tst", " $lhs, $rhs", + "tst", "\t$lhs, $rhs", [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>; // zero-extend byte def tUXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, - "uxtb", " $dst, $src", + "uxtb", "\t$dst, $src", [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>, Requires<[IsThumb1Only, HasV6]>; // zero-extend short def tUXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, - "uxth", " $dst, $src", + "uxth", "\t$dst, $src", [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>, Requires<[IsThumb1Only, HasV6]>; @@ -621,19 +621,19 @@ // 16-bit movcc in IT blocks for Thumb2. def tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iCMOVr, - "mov", " $dst, $rhs", []>; + "mov", "\t$dst, $rhs", []>; def tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iCMOVi, - "mov", " $dst, $rhs", []>; + "mov", "\t$dst, $rhs", []>; // tLEApcrel - Load a pc-relative address into a register without offending the // assembler. def tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi, - "adr$p $dst, #$label", []>; + "adr$p\t$dst, #$label", []>; def tLEApcrelJT : T1I<(outs tGPR:$dst), (ins i32imm:$label, nohash_imm:$id, pred:$p), - IIC_iALUi, "adr$p $dst, #${label}_${id}", []>; + IIC_iALUi, "adr$p\t$dst, #${label}_${id}", []>; //===----------------------------------------------------------------------===// // TLS Instructions @@ -643,7 +643,7 @@ let isCall = 1, Defs = [R0, LR] in { def tTPsoft : TIx2<(outs), (ins), IIC_Br, - "bl __aeabi_read_tp", + "bl\t__aeabi_read_tp", [(set R0, ARMthread_pointer)]>; } Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=85184&r1=85183&r2=85184&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon Oct 26 19:08:59 2009 @@ -153,18 +153,18 @@ multiclass T2I_un_irs{ // shifted imm def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi, - opc, " $dst, $src", + opc, "\t$dst, $src", [(set GPR:$dst, (opnode t2_so_imm:$src))]> { let isAsCheapAsAMove = Cheap; let isReMaterializable = ReMat; } // register def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, - opc, ".w $dst, $src", + opc, ".w\t$dst, $src", [(set GPR:$dst, (opnode GPR:$src))]>; // shifted register def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), IIC_iMOVsi, - opc, ".w $dst, $src", + opc, ".w\t$dst, $src", [(set GPR:$dst, (opnode t2_so_reg:$src))]>; } @@ -175,17 +175,17 @@ bit Commutable = 0, string wide =""> { // shifted imm def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi, - opc, " $dst, $lhs, $rhs", + opc, "\t$dst, $lhs, $rhs", [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; // register def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, - opc, !strconcat(wide, " $dst, $lhs, $rhs"), + opc, !strconcat(wide, "\t$dst, $lhs, $rhs"), [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { let isCommutable = Commutable; } // shifted register def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi, - opc, !strconcat(wide, " $dst, $lhs, $rhs"), + opc, !strconcat(wide, "\t$dst, $lhs, $rhs"), [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; } @@ -200,11 +200,11 @@ multiclass T2I_rbin_is { // shifted imm def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), IIC_iALUi, - opc, ".w $dst, $rhs, $lhs", + opc, ".w\t$dst, $rhs, $lhs", [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; // shifted register def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), IIC_iALUsi, - opc, " $dst, $rhs, $lhs", + opc, "\t$dst, $rhs, $lhs", [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>; } @@ -214,17 +214,17 @@ multiclass T2I_bin_s_irs { // shifted imm def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi, - !strconcat(opc, "s"), ".w $dst, $lhs, $rhs", + !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs", [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; // register def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, - !strconcat(opc, "s"), ".w $dst, $lhs, $rhs", + !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs", [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { let isCommutable = Commutable; } // shifted register def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi, - !strconcat(opc, "s"), ".w $dst, $lhs, $rhs", + !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs", [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; } } @@ -234,21 +234,21 @@ multiclass T2I_bin_ii12rs { // shifted imm def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi, - opc, ".w $dst, $lhs, $rhs", + opc, ".w\t$dst, $lhs, $rhs", [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; // 12-bit imm def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), IIC_iALUi, - !strconcat(opc, "w"), " $dst, $lhs, $rhs", + !strconcat(opc, "w"), "\t$dst, $lhs, $rhs", [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]>; // register def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, - opc, ".w $dst, $lhs, $rhs", + opc, ".w\t$dst, $lhs, $rhs", [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { let isCommutable = Commutable; } // shifted register def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi, - opc, ".w $dst, $lhs, $rhs", + opc, ".w\t$dst, $lhs, $rhs", [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; } @@ -259,32 +259,32 @@ multiclass T2I_adde_sube_irs { // shifted imm def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi, - opc, " $dst, $lhs, $rhs", + opc, "\t$dst, $lhs, $rhs", [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>, Requires<[IsThumb2, CarryDefIsUnused]>; // register def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, - opc, ".w $dst, $lhs, $rhs", + opc, ".w\t$dst, $lhs, $rhs", [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>, Requires<[IsThumb2, CarryDefIsUnused]> { let isCommutable = Commutable; } // shifted register def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi, - opc, ".w $dst, $lhs, $rhs", + opc, ".w\t$dst, $lhs, $rhs", [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>, Requires<[IsThumb2, CarryDefIsUnused]>; // Carry setting variants // shifted imm def Sri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi, - !strconcat(opc, "s $dst, $lhs, $rhs"), + !strconcat(opc, "s\t$dst, $lhs, $rhs"), [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>, Requires<[IsThumb2, CarryDefIsUsed]> { let Defs = [CPSR]; } // register def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, - !strconcat(opc, "s.w $dst, $lhs, $rhs"), + !strconcat(opc, "s.w\t$dst, $lhs, $rhs"), [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>, Requires<[IsThumb2, CarryDefIsUsed]> { let Defs = [CPSR]; @@ -292,7 +292,7 @@ } // shifted register def Srs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi, - !strconcat(opc, "s.w $dst, $lhs, $rhs"), + !strconcat(opc, "s.w\t$dst, $lhs, $rhs"), [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>, Requires<[IsThumb2, CarryDefIsUsed]> { let Defs = [CPSR]; @@ -306,12 +306,12 @@ // shifted imm def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s), IIC_iALUi, - !strconcat(opc, "${s}.w $dst, $rhs, $lhs"), + !strconcat(opc, "${s}.w\t$dst, $rhs, $lhs"), [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; // shifted register def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s), IIC_iALUsi, - !strconcat(opc, "${s} $dst, $rhs, $lhs"), + !strconcat(opc, "${s}\t$dst, $rhs, $lhs"), [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>; } } @@ -321,11 +321,11 @@ multiclass T2I_sh_ir { // 5-bit imm def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iMOVsi, - opc, ".w $dst, $lhs, $rhs", + opc, ".w\t$dst, $lhs, $rhs", [(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]>; // register def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iMOVsr, - opc, ".w $dst, $lhs, $rhs", + opc, ".w\t$dst, $lhs, $rhs", [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>; } @@ -336,15 +336,15 @@ multiclass T2I_cmp_is { // shifted imm def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iCMPi, - opc, ".w $lhs, $rhs", + opc, ".w\t$lhs, $rhs", [(opnode GPR:$lhs, t2_so_imm:$rhs)]>; // register def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, - opc, ".w $lhs, $rhs", + opc, ".w\t$lhs, $rhs", [(opnode GPR:$lhs, GPR:$rhs)]>; // shifted register def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iCMPsi, - opc, ".w $lhs, $rhs", + opc, ".w\t$lhs, $rhs", [(opnode GPR:$lhs, t2_so_reg:$rhs)]>; } } @@ -352,42 +352,42 @@ /// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns. multiclass T2I_ld { def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), IIC_iLoadi, - opc, ".w $dst, $addr", + opc, ".w\t$dst, $addr", [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]>; def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), IIC_iLoadi, - opc, " $dst, $addr", + opc, "\t$dst, $addr", [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]>; def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), IIC_iLoadr, - opc, ".w $dst, $addr", + opc, ".w\t$dst, $addr", [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]>; def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoadi, - opc, ".w $dst, $addr", + opc, ".w\t$dst, $addr", [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]>; } /// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns. multiclass T2I_st { def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), IIC_iStorei, - opc, ".w $src, $addr", + opc, ".w\t$src, $addr", [(opnode GPR:$src, t2addrmode_imm12:$addr)]>; def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), IIC_iStorei, - opc, " $src, $addr", + opc, "\t$src, $addr", [(opnode GPR:$src, t2addrmode_imm8:$addr)]>; def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), IIC_iStorer, - opc, ".w $src, $addr", + opc, ".w\t$src, $addr", [(opnode GPR:$src, t2addrmode_so_reg:$addr)]>; } /// T2I_picld - Defines the PIC load pattern. class T2I_picld : T2I<(outs GPR:$dst), (ins addrmodepc:$addr), IIC_iLoadi, - !strconcat("\n${addr:label}:\n\t", opc), " $dst, $addr", + !strconcat("\n${addr:label}:\n\t", opc), "\t$dst, $addr", [(set GPR:$dst, (opnode addrmodepc:$addr))]>; /// T2I_picst - Defines the PIC store pattern. class T2I_picst : T2I<(outs), (ins GPR:$src, addrmodepc:$addr), IIC_iStorer, - !strconcat("\n${addr:label}:\n\t", opc), " $src, $addr", + !strconcat("\n${addr:label}:\n\t", opc), "\t$src, $addr", [(opnode GPR:$src, addrmodepc:$addr)]>; @@ -395,10 +395,10 @@ /// register and one whose operand is a register rotated by 8/16/24. multiclass T2I_unary_rrot { def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, - opc, ".w $dst, $src", + opc, ".w\t$dst, $src", [(set GPR:$dst, (opnode GPR:$src))]>; def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi, - opc, ".w $dst, $src, ror $rot", + opc, ".w\t$dst, $src, ror $rot", [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>; } @@ -406,10 +406,10 @@ /// register and one whose operand is a register rotated by 8/16/24. multiclass T2I_bin_rrot { def rr : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), IIC_iALUr, - opc, " $dst, $LHS, $RHS", + opc, "\t$dst, $LHS, $RHS", [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>; def rr_rot : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot), - IIC_iALUsr, opc, " $dst, $LHS, $RHS, ror $rot", + IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot", [(set GPR:$dst, (opnode GPR:$LHS, (rotr GPR:$RHS, rot_imm:$rot)))]>; } @@ -425,42 +425,42 @@ // LEApcrel - Load a pc-relative address into a register without offending the // assembler. def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi, - "adr$p.w $dst, #$label", []>; + "adr$p.w\t$dst, #$label", []>; def t2LEApcrelJT : T2XI<(outs GPR:$dst), (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi, - "adr$p.w $dst, #${label}_${id}", []>; + "adr$p.w\t$dst, #${label}_${id}", []>; // ADD r, sp, {so_imm|i12} def t2ADDrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm), - IIC_iALUi, "add", ".w $dst, $sp, $imm", []>; + IIC_iALUi, "add", ".w\t$dst, $sp, $imm", []>; def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm), - IIC_iALUi, "addw", " $dst, $sp, $imm", []>; + IIC_iALUi, "addw", "\t$dst, $sp, $imm", []>; // ADD r, sp, so_reg def t2ADDrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs), - IIC_iALUsi, "add", ".w $dst, $sp, $rhs", []>; + IIC_iALUsi, "add", ".w\t$dst, $sp, $rhs", []>; // SUB r, sp, {so_imm|i12} def t2SUBrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm), - IIC_iALUi, "sub", ".w $dst, $sp, $imm", []>; + IIC_iALUi, "sub", ".w\t$dst, $sp, $imm", []>; def t2SUBrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm), - IIC_iALUi, "subw", " $dst, $sp, $imm", []>; + IIC_iALUi, "subw", "\t$dst, $sp, $imm", []>; // SUB r, sp, so_reg def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs), IIC_iALUsi, - "sub", " $dst, $sp, $rhs", []>; + "sub", "\t$dst, $sp, $rhs", []>; // Pseudo instruction that will expand into a t2SUBrSPi + a copy. let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. def t2SUBrSPi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm), - NoItinerary, "@ sub.w $dst, $sp, $imm", []>; + NoItinerary, "@ sub.w\t$dst, $sp, $imm", []>; def t2SUBrSPi12_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm), - NoItinerary, "@ subw $dst, $sp, $imm", []>; + NoItinerary, "@ subw\t$dst, $sp, $imm", []>; def t2SUBrSPs_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs), - NoItinerary, "@ sub $dst, $sp, $rhs", []>; + NoItinerary, "@ sub\t$dst, $sp, $rhs", []>; } // usesCustomDAGSchedInserter @@ -484,10 +484,10 @@ // Load doubleword def t2LDRDi8 : T2Ii8s4<(outs GPR:$dst1, GPR:$dst2), (ins t2addrmode_imm8s4:$addr), - IIC_iLoadi, "ldrd", " $dst1, $addr", []>; + IIC_iLoadi, "ldrd", "\t$dst1, $addr", []>; def t2LDRDpci : T2Ii8s4<(outs GPR:$dst1, GPR:$dst2), (ins i32imm:$addr), IIC_iLoadi, - "ldrd", " $dst1, $addr", []>; + "ldrd", "\t$dst1, $addr", []>; } // zextload i1 -> zextload i8 @@ -535,57 +535,57 @@ def t2LDR_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), (ins t2addrmode_imm8:$addr), AddrModeT2_i8, IndexModePre, IIC_iLoadiu, - "ldr", " $dst, $addr!", "$addr.base = $base_wb", + "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>; def t2LDR_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), (ins GPR:$base, t2am_imm8_offset:$offset), AddrModeT2_i8, IndexModePost, IIC_iLoadiu, - "ldr", " $dst, [$base], $offset", "$base = $base_wb", + "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>; def t2LDRB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), (ins t2addrmode_imm8:$addr), AddrModeT2_i8, IndexModePre, IIC_iLoadiu, - "ldrb", " $dst, $addr!", "$addr.base = $base_wb", + "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>; def t2LDRB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), (ins GPR:$base, t2am_imm8_offset:$offset), AddrModeT2_i8, IndexModePost, IIC_iLoadiu, - "ldrb", " $dst, [$base], $offset", "$base = $base_wb", + "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>; def t2LDRH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), (ins t2addrmode_imm8:$addr), AddrModeT2_i8, IndexModePre, IIC_iLoadiu, - "ldrh", " $dst, $addr!", "$addr.base = $base_wb", + "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>; def t2LDRH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), (ins GPR:$base, t2am_imm8_offset:$offset), AddrModeT2_i8, IndexModePost, IIC_iLoadiu, - "ldrh", " $dst, [$base], $offset", "$base = $base_wb", + "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>; def t2LDRSB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), (ins t2addrmode_imm8:$addr), AddrModeT2_i8, IndexModePre, IIC_iLoadiu, - "ldrsb", " $dst, $addr!", "$addr.base = $base_wb", + "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>; def t2LDRSB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), (ins GPR:$base, t2am_imm8_offset:$offset), AddrModeT2_i8, IndexModePost, IIC_iLoadiu, - "ldrsb", " $dst, [$base], $offset", "$base = $base_wb", + "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>; def t2LDRSH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), (ins t2addrmode_imm8:$addr), AddrModeT2_i8, IndexModePre, IIC_iLoadiu, - "ldrsh", " $dst, $addr!", "$addr.base = $base_wb", + "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>; def t2LDRSH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), (ins GPR:$base, t2am_imm8_offset:$offset), AddrModeT2_i8, IndexModePost, IIC_iLoadiu, - "ldrsh", " $dst, [$base], $offset", "$base = $base_wb", + "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>; } @@ -598,48 +598,48 @@ let mayLoad = 1, hasExtraSrcRegAllocReq = 1 in def t2STRDi8 : T2Ii8s4<(outs), (ins GPR:$src1, GPR:$src2, t2addrmode_imm8s4:$addr), - IIC_iStorer, "strd", " $src1, $addr", []>; + IIC_iStorer, "strd", "\t$src1, $addr", []>; // Indexed stores def t2STR_PRE : T2Iidxldst<(outs GPR:$base_wb), (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), AddrModeT2_i8, IndexModePre, IIC_iStoreiu, - "str", " $src, [$base, $offset]!", "$base = $base_wb", + "str", "\t$src, [$base, $offset]!", "$base = $base_wb", [(set GPR:$base_wb, (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; def t2STR_POST : T2Iidxldst<(outs GPR:$base_wb), (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), AddrModeT2_i8, IndexModePost, IIC_iStoreiu, - "str", " $src, [$base], $offset", "$base = $base_wb", + "str", "\t$src, [$base], $offset", "$base = $base_wb", [(set GPR:$base_wb, (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; def t2STRH_PRE : T2Iidxldst<(outs GPR:$base_wb), (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), AddrModeT2_i8, IndexModePre, IIC_iStoreiu, - "strh", " $src, [$base, $offset]!", "$base = $base_wb", + "strh", "\t$src, [$base, $offset]!", "$base = $base_wb", [(set GPR:$base_wb, (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; def t2STRH_POST : T2Iidxldst<(outs GPR:$base_wb), (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), AddrModeT2_i8, IndexModePost, IIC_iStoreiu, - "strh", " $src, [$base], $offset", "$base = $base_wb", + "strh", "\t$src, [$base], $offset", "$base = $base_wb", [(set GPR:$base_wb, (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; def t2STRB_PRE : T2Iidxldst<(outs GPR:$base_wb), (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), AddrModeT2_i8, IndexModePre, IIC_iStoreiu, - "strb", " $src, [$base, $offset]!", "$base = $base_wb", + "strb", "\t$src, [$base, $offset]!", "$base = $base_wb", [(set GPR:$base_wb, (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; def t2STRB_POST : T2Iidxldst<(outs GPR:$base_wb), (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), AddrModeT2_i8, IndexModePost, IIC_iStoreiu, - "strb", " $src, [$base], $offset", "$base = $base_wb", + "strb", "\t$src, [$base], $offset", "$base = $base_wb", [(set GPR:$base_wb, (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; @@ -653,12 +653,12 @@ let mayLoad = 1, hasExtraDefRegAllocReq = 1 in def t2LDM : T2XI<(outs), (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), - IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide} $addr, $wb", []>; + IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb", []>; let mayStore = 1, hasExtraSrcRegAllocReq = 1 in def t2STM : T2XI<(outs), (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), - IIC_iStorem, "stm${addr:submode}${p}${addr:wide} $addr, $wb", []>; + IIC_iStorem, "stm${addr:submode}${p}${addr:wide}\t$addr, $wb", []>; //===----------------------------------------------------------------------===// // Move Instructions. @@ -666,22 +666,22 @@ let neverHasSideEffects = 1 in def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, - "mov", ".w $dst, $src", []>; + "mov", ".w\t$dst, $src", []>; // AddedComplexity to ensure isel tries t2MOVi before t2MOVi16. let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = 1 in def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi, - "mov", ".w $dst, $src", + "mov", ".w\t$dst, $src", [(set GPR:$dst, t2_so_imm:$src)]>; let isReMaterializable = 1, isAsCheapAsAMove = 1 in def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi, - "movw", " $dst, $src", + "movw", "\t$dst, $src", [(set GPR:$dst, imm0_65535:$src)]>; let Constraints = "$src = $dst" in def t2MOVTi16 : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), IIC_iMOVi, - "movt", " $dst, $imm", + "movt", "\t$dst, $imm", [(set GPR:$dst, (or (and GPR:$src, 0xffff), lo16AllZero:$imm))]>; @@ -760,16 +760,16 @@ let Uses = [CPSR] in { def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, - "rrx", " $dst, $src", + "rrx", "\t$dst, $src", [(set GPR:$dst, (ARMrrx GPR:$src))]>; } let Defs = [CPSR] in { def t2MOVsrl_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, - "lsrs.w $dst, $src, #1", + "lsrs.w\t$dst, $src, #1", [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>; def t2MOVsra_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, - "asrs.w $dst, $src, #1", + "asrs.w\t$dst, $src, #1", [(set GPR:$dst, (ARMsra_flag GPR:$src))]>; } @@ -785,14 +785,14 @@ let Constraints = "$src = $dst" in def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm), - IIC_iALUi, "bfc", " $dst, $imm", + IIC_iALUi, "bfc", "\t$dst, $imm", [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>; def t2SBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width), - IIC_iALUi, "sbfx", " $dst, $src, $lsb, $width", []>; + IIC_iALUi, "sbfx", "\t$dst, $src, $lsb, $width", []>; def t2UBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width), - IIC_iALUi, "ubfx", " $dst, $src, $lsb, $width", []>; + IIC_iALUi, "ubfx", "\t$dst, $src, $lsb, $width", []>; // FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1) @@ -819,80 +819,80 @@ // let isCommutable = 1 in def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, - "mul", " $dst, $a, $b", + "mul", "\t$dst, $a, $b", [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>; def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32, - "mla", " $dst, $a, $b, $c", + "mla", "\t$dst, $a, $b, $c", [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>; def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32, - "mls", " $dst, $a, $b, $c", + "mls", "\t$dst, $a, $b, $c", [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>; // Extra precision multiplies with low / high results let neverHasSideEffects = 1 in { let isCommutable = 1 in { def t2SMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMUL64, - "smull", " $ldst, $hdst, $a, $b", []>; + "smull", "\t$ldst, $hdst, $a, $b", []>; def t2UMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMUL64, - "umull", " $ldst, $hdst, $a, $b", []>; + "umull", "\t$ldst, $hdst, $a, $b", []>; } // Multiply + accumulate def t2SMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64, - "smlal", " $ldst, $hdst, $a, $b", []>; + "smlal", "\t$ldst, $hdst, $a, $b", []>; def t2UMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64, - "umlal", " $ldst, $hdst, $a, $b", []>; + "umlal", "\t$ldst, $hdst, $a, $b", []>; def t2UMAAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64, - "umaal", " $ldst, $hdst, $a, $b", []>; + "umaal", "\t$ldst, $hdst, $a, $b", []>; } // neverHasSideEffects // Most significant word multiply def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, - "smmul", " $dst, $a, $b", + "smmul", "\t$dst, $a, $b", [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>; def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32, - "smmla", " $dst, $a, $b, $c", + "smmla", "\t$dst, $a, $b, $c", [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>; def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32, - "smmls", " $dst, $a, $b, $c", + "smmls", "\t$dst, $a, $b, $c", [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>; multiclass T2I_smul { def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, - !strconcat(opc, "bb"), " $dst, $a, $b", + !strconcat(opc, "bb"), "\t$dst, $a, $b", [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16), (sext_inreg GPR:$b, i16)))]>; def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, - !strconcat(opc, "bt"), " $dst, $a, $b", + !strconcat(opc, "bt"), "\t$dst, $a, $b", [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16), (sra GPR:$b, (i32 16))))]>; def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, - !strconcat(opc, "tb"), " $dst, $a, $b", + !strconcat(opc, "tb"), "\t$dst, $a, $b", [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)), (sext_inreg GPR:$b, i16)))]>; def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, - !strconcat(opc, "tt"), " $dst, $a, $b", + !strconcat(opc, "tt"), "\t$dst, $a, $b", [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)), (sra GPR:$b, (i32 16))))]>; def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16, - !strconcat(opc, "wb"), " $dst, $a, $b", + !strconcat(opc, "wb"), "\t$dst, $a, $b", [(set GPR:$dst, (sra (opnode GPR:$a, (sext_inreg GPR:$b, i16)), (i32 16)))]>; def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16, - !strconcat(opc, "wt"), " $dst, $a, $b", + !strconcat(opc, "wt"), "\t$dst, $a, $b", [(set GPR:$dst, (sra (opnode GPR:$a, (sra GPR:$b, (i32 16))), (i32 16)))]>; } @@ -900,33 +900,33 @@ multiclass T2I_smla { def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16, - !strconcat(opc, "bb"), " $dst, $a, $b, $acc", + !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc", [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16), (sext_inreg GPR:$b, i16))))]>; def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16, - !strconcat(opc, "bt"), " $dst, $a, $b, $acc", + !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc", [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16), (sra GPR:$b, (i32 16)))))]>; def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16, - !strconcat(opc, "tb"), " $dst, $a, $b, $acc", + !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc", [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)), (sext_inreg GPR:$b, i16))))]>; def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16, - !strconcat(opc, "tt"), " $dst, $a, $b, $acc", + !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc", [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)), (sra GPR:$b, (i32 16)))))]>; def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16, - !strconcat(opc, "wb"), " $dst, $a, $b, $acc", + !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc", [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a, (sext_inreg GPR:$b, i16)), (i32 16))))]>; def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16, - !strconcat(opc, "wt"), " $dst, $a, $b, $acc", + !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc", [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a, (sra GPR:$b, (i32 16))), (i32 16))))]>; } @@ -943,15 +943,15 @@ // def t2CLZ : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, - "clz", " $dst, $src", + "clz", "\t$dst, $src", [(set GPR:$dst, (ctlz GPR:$src))]>; def t2REV : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, - "rev", ".w $dst, $src", + "rev", ".w\t$dst, $src", [(set GPR:$dst, (bswap GPR:$src))]>; def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, - "rev16", ".w $dst, $src", + "rev16", ".w\t$dst, $src", [(set GPR:$dst, (or (and (srl GPR:$src, (i32 8)), 0xFF), (or (and (shl GPR:$src, (i32 8)), 0xFF00), @@ -959,14 +959,14 @@ (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>; def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, - "revsh", ".w $dst, $src", + "revsh", ".w\t$dst, $src", [(set GPR:$dst, (sext_inreg (or (srl (and GPR:$src, 0xFF00), (i32 8)), (shl GPR:$src, (i32 8))), i16))]>; def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt), - IIC_iALUsi, "pkhbt", " $dst, $src1, $src2, LSL $shamt", + IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt", [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF), (and (shl GPR:$src2, (i32 imm:$shamt)), 0xFFFF0000)))]>; @@ -978,7 +978,7 @@ (t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>; def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt), - IIC_iALUsi, "pkhtb", " $dst, $src1, $src2, ASR $shamt", + IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt", [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000), (and (sra GPR:$src2, imm16_31:$shamt), 0xFFFF)))]>; @@ -1025,26 +1025,26 @@ // FIXME: should be able to write a pattern for ARMcmov, but can't use // a two-value operand where a dag node expects two operands. :( def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true), IIC_iCMOVr, - "mov", ".w $dst, $true", + "mov", ".w\t$dst, $true", [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>, RegConstraint<"$false = $dst">; def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm:$true), - IIC_iCMOVi, "mov", ".w $dst, $true", + IIC_iCMOVi, "mov", ".w\t$dst, $true", [/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>, RegConstraint<"$false = $dst">; def t2MOVCClsl : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs), - IIC_iCMOVsi, "lsl", ".w $dst, $true, $rhs", []>, + IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", []>, RegConstraint<"$false = $dst">; def t2MOVCClsr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs), - IIC_iCMOVsi, "lsr", ".w $dst, $true, $rhs", []>, + IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", []>, RegConstraint<"$false = $dst">; def t2MOVCCasr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs), - IIC_iCMOVsi, "asr", ".w $dst, $true, $rhs", []>, + IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", []>, RegConstraint<"$false = $dst">; def t2MOVCCror : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs), - IIC_iCMOVsi, "ror", ".w $dst, $true, $rhs", []>, + IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", []>, RegConstraint<"$false = $dst">; //===----------------------------------------------------------------------===// @@ -1055,7 +1055,7 @@ let isCall = 1, Defs = [R0, R12, LR, CPSR] in { def t2TPsoft : T2XI<(outs), (ins), IIC_Br, - "bl __aeabi_read_tp", + "bl\t__aeabi_read_tp", [(set R0, ARMthread_pointer)]>; } @@ -1078,13 +1078,13 @@ D31 ] in { def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src), AddrModeNone, SizeSpecial, NoItinerary, - "str.w sp, [$src, #+8] @ eh_setjmp begin\n" - "\tadr r12, 0f\n" - "\torr r12, #1\n" - "\tstr.w r12, [$src, #+4]\n" - "\tmovs r0, #0\n" - "\tb 1f\n" - "0:\tmovs r0, #1 @ eh_setjmp end\n" + "str.w\tsp, [$src, #+8] @ eh_setjmp begin\n" + "\tadr\tr12, 0f\n" + "\torr\tr12, #1\n" + "\tstr.w\tr12, [$src, #+4]\n" + "\tmovs\tr0, #0\n" + "\tb\t1f\n" + "0:\tmovs\tr0, #1 @ eh_setjmp end\n" "1:", "", [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>; } @@ -1103,32 +1103,32 @@ hasExtraDefRegAllocReq = 1 in def t2LDM_RET : T2XI<(outs), (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), - IIC_Br, "ldm${addr:submode}${p}${addr:wide} $addr, $wb", + IIC_Br, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb", []>; let isBranch = 1, isTerminator = 1, isBarrier = 1 in { let isPredicable = 1 in def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br, - "b.w $target", + "b.w\t$target", [(br bb:$target)]>; let isNotDuplicable = 1, isIndirectBranch = 1 in { def t2BR_JT : T2JTI<(outs), (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id), - IIC_Br, "mov pc, $target\n$jt", + IIC_Br, "mov\tpc, $target\n$jt", [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>; // FIXME: Add a non-pc based case that can be predicated. def t2TBB : T2JTI<(outs), (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id), - IIC_Br, "tbb $index\n$jt", []>; + IIC_Br, "tbb\t$index\n$jt", []>; def t2TBH : T2JTI<(outs), (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id), - IIC_Br, "tbh $index\n$jt", []>; + IIC_Br, "tbh\t$index\n$jt", []>; } // isNotDuplicable, isIndirectBranch } // isBranch, isTerminator, isBarrier @@ -1137,14 +1137,14 @@ // a two-value operand where a dag node expects two operands. :( let isBranch = 1, isTerminator = 1 in def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br, - "b", ".w $target", + "b", ".w\t$target", [/*(ARMbrcond bb:$target, imm:$cc)*/]>; // IT block def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask), AddrModeNone, Size2Bytes, IIC_iALUx, - "it$mask $cc", "", []>; + "it$mask\t$cc", "", []>; //===----------------------------------------------------------------------===// // Non-Instruction Patterns @@ -1175,5 +1175,5 @@ // when we can do generalized remat. let isReMaterializable = 1 in def t2MOVi32imm : T2Ix2<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi, - "movw", " $dst, ${src:lo16}\n\tmovt${p} $dst, ${src:hi16}", + "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}", [(set GPR:$dst, (i32 imm:$src))]>; From gohman at apple.com Mon Oct 26 19:11:02 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 27 Oct 2009 00:11:02 -0000 Subject: [llvm-commits] [llvm] r85185 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200910270011.n9R0B3H4013387@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 26 19:11:02 2009 New Revision: 85185 URL: http://llvm.org/viewvc/llvm-project?rev=85185&view=rev Log: Add braces to avoid ambiguous else. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=85185&r1=85184&r2=85185&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Oct 26 19:11:02 2009 @@ -11344,7 +11344,7 @@ return EraseInstFromFunction(FI); // If we have a malloc call whose only use is a free call, delete both. - if (isMalloc(Op)) + if (isMalloc(Op)) { if (CallInst* CI = extractMallocCallFromBitCast(Op)) { if (Op->hasOneUse() && CI->hasOneUse()) { EraseInstFromFunction(FI); @@ -11358,6 +11358,7 @@ return EraseInstFromFunction(*cast(Op)); } } + } return 0; } From evan.cheng at apple.com Mon Oct 26 19:20:49 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 27 Oct 2009 00:20:49 -0000 Subject: [llvm-commits] [llvm] r85186 - /llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Message-ID: <200910270020.n9R0Knw6013971@zion.cs.uiuc.edu> Author: evancheng Date: Mon Oct 26 19:20:49 2009 New Revision: 85186 URL: http://llvm.org/viewvc/llvm-project?rev=85186&view=rev Log: Now VFP instructions. Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=85186&r1=85185&r2=85186&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Mon Oct 26 19:20:49 2009 @@ -36,20 +36,20 @@ let canFoldAsLoad = 1 in { def FLDD : ADI5<0b1101, 0b01, (outs DPR:$dst), (ins addrmode5:$addr), - IIC_fpLoad64, "fldd", " $dst, $addr", + IIC_fpLoad64, "fldd", "\t$dst, $addr", [(set DPR:$dst, (load addrmode5:$addr))]>; def FLDS : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr), - IIC_fpLoad32, "flds", " $dst, $addr", + IIC_fpLoad32, "flds", "\t$dst, $addr", [(set SPR:$dst, (load addrmode5:$addr))]>; } // canFoldAsLoad def FSTD : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr), - IIC_fpStore64, "fstd", " $src, $addr", + IIC_fpStore64, "fstd", "\t$src, $addr", [(store DPR:$src, addrmode5:$addr)]>; def FSTS : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr), - IIC_fpStore32, "fsts", " $src, $addr", + IIC_fpStore32, "fsts", "\t$src, $addr", [(store SPR:$src, addrmode5:$addr)]>; //===----------------------------------------------------------------------===// @@ -59,14 +59,14 @@ let mayLoad = 1, hasExtraDefRegAllocReq = 1 in { def FLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb, variable_ops), IIC_fpLoadm, - "fldm${addr:submode}d${p} ${addr:base}, $wb", + "fldm${addr:submode}d${p}\t${addr:base}, $wb", []> { let Inst{20} = 1; } def FLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb, variable_ops), IIC_fpLoadm, - "fldm${addr:submode}s${p} ${addr:base}, $wb", + "fldm${addr:submode}s${p}\t${addr:base}, $wb", []> { let Inst{20} = 1; } @@ -75,14 +75,14 @@ let mayStore = 1, hasExtraSrcRegAllocReq = 1 in { def FSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb, variable_ops), IIC_fpStorem, - "fstm${addr:submode}d${p} ${addr:base}, $wb", + "fstm${addr:submode}d${p}\t${addr:base}, $wb", []> { let Inst{20} = 0; } def FSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb, variable_ops), IIC_fpStorem, - "fstm${addr:submode}s${p} ${addr:base}, $wb", + "fstm${addr:submode}s${p}\t${addr:base}, $wb", []> { let Inst{20} = 0; } @@ -95,48 +95,48 @@ // def FADDD : ADbI<0b11100011, (outs DPR:$dst), (ins DPR:$a, DPR:$b), - IIC_fpALU64, "faddd", " $dst, $a, $b", + IIC_fpALU64, "faddd", "\t$dst, $a, $b", [(set DPR:$dst, (fadd DPR:$a, DPR:$b))]>; def FADDS : ASbIn<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b), - IIC_fpALU32, "fadds", " $dst, $a, $b", + IIC_fpALU32, "fadds", "\t$dst, $a, $b", [(set SPR:$dst, (fadd SPR:$a, SPR:$b))]>; // These are encoded as unary instructions. let Defs = [FPSCR] in { def FCMPED : ADuI<0b11101011, 0b0100, 0b1100, (outs), (ins DPR:$a, DPR:$b), - IIC_fpCMP64, "fcmped", " $a, $b", + IIC_fpCMP64, "fcmped", "\t$a, $b", [(arm_cmpfp DPR:$a, DPR:$b)]>; def FCMPES : ASuI<0b11101011, 0b0100, 0b1100, (outs), (ins SPR:$a, SPR:$b), - IIC_fpCMP32, "fcmpes", " $a, $b", + IIC_fpCMP32, "fcmpes", "\t$a, $b", [(arm_cmpfp SPR:$a, SPR:$b)]>; } def FDIVD : ADbI<0b11101000, (outs DPR:$dst), (ins DPR:$a, DPR:$b), - IIC_fpDIV64, "fdivd", " $dst, $a, $b", + IIC_fpDIV64, "fdivd", "\t$dst, $a, $b", [(set DPR:$dst, (fdiv DPR:$a, DPR:$b))]>; def FDIVS : ASbI<0b11101000, (outs SPR:$dst), (ins SPR:$a, SPR:$b), - IIC_fpDIV32, "fdivs", " $dst, $a, $b", + IIC_fpDIV32, "fdivs", "\t$dst, $a, $b", [(set SPR:$dst, (fdiv SPR:$a, SPR:$b))]>; def FMULD : ADbI<0b11100010, (outs DPR:$dst), (ins DPR:$a, DPR:$b), - IIC_fpMUL64, "fmuld", " $dst, $a, $b", + IIC_fpMUL64, "fmuld", "\t$dst, $a, $b", [(set DPR:$dst, (fmul DPR:$a, DPR:$b))]>; def FMULS : ASbIn<0b11100010, (outs SPR:$dst), (ins SPR:$a, SPR:$b), - IIC_fpMUL32, "fmuls", " $dst, $a, $b", + IIC_fpMUL32, "fmuls", "\t$dst, $a, $b", [(set SPR:$dst, (fmul SPR:$a, SPR:$b))]>; def FNMULD : ADbI<0b11100010, (outs DPR:$dst), (ins DPR:$a, DPR:$b), - IIC_fpMUL64, "fnmuld", " $dst, $a, $b", + IIC_fpMUL64, "fnmuld", "\t$dst, $a, $b", [(set DPR:$dst, (fneg (fmul DPR:$a, DPR:$b)))]> { let Inst{6} = 1; } def FNMULS : ASbI<0b11100010, (outs SPR:$dst), (ins SPR:$a, SPR:$b), - IIC_fpMUL32, "fnmuls", " $dst, $a, $b", + IIC_fpMUL32, "fnmuls", "\t$dst, $a, $b", [(set SPR:$dst, (fneg (fmul SPR:$a, SPR:$b)))]> { let Inst{6} = 1; } @@ -149,13 +149,13 @@ def FSUBD : ADbI<0b11100011, (outs DPR:$dst), (ins DPR:$a, DPR:$b), - IIC_fpALU64, "fsubd", " $dst, $a, $b", + IIC_fpALU64, "fsubd", "\t$dst, $a, $b", [(set DPR:$dst, (fsub DPR:$a, DPR:$b))]> { let Inst{6} = 1; } def FSUBS : ASbIn<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b), - IIC_fpALU32, "fsubs", " $dst, $a, $b", + IIC_fpALU32, "fsubs", "\t$dst, $a, $b", [(set SPR:$dst, (fsub SPR:$a, SPR:$b))]> { let Inst{6} = 1; } @@ -165,30 +165,30 @@ // def FABSD : ADuI<0b11101011, 0b0000, 0b1100, (outs DPR:$dst), (ins DPR:$a), - IIC_fpUNA64, "fabsd", " $dst, $a", + IIC_fpUNA64, "fabsd", "\t$dst, $a", [(set DPR:$dst, (fabs DPR:$a))]>; def FABSS : ASuIn<0b11101011, 0b0000, 0b1100, (outs SPR:$dst), (ins SPR:$a), - IIC_fpUNA32, "fabss", " $dst, $a", + IIC_fpUNA32, "fabss", "\t$dst, $a", [(set SPR:$dst, (fabs SPR:$a))]>; let Defs = [FPSCR] in { def FCMPEZD : ADuI<0b11101011, 0b0101, 0b1100, (outs), (ins DPR:$a), - IIC_fpCMP64, "fcmpezd", " $a", + IIC_fpCMP64, "fcmpezd", "\t$a", [(arm_cmpfp0 DPR:$a)]>; def FCMPEZS : ASuI<0b11101011, 0b0101, 0b1100, (outs), (ins SPR:$a), - IIC_fpCMP32, "fcmpezs", " $a", + IIC_fpCMP32, "fcmpezs", "\t$a", [(arm_cmpfp0 SPR:$a)]>; } def FCVTDS : ASuI<0b11101011, 0b0111, 0b1100, (outs DPR:$dst), (ins SPR:$a), - IIC_fpCVTDS, "fcvtds", " $dst, $a", + IIC_fpCVTDS, "fcvtds", "\t$dst, $a", [(set DPR:$dst, (fextend SPR:$a))]>; // Special case encoding: bits 11-8 is 0b1011. def FCVTSD : VFPAI<(outs SPR:$dst), (ins DPR:$a), VFPUnaryFrm, - IIC_fpCVTSD, "fcvtsd", " $dst, $a", + IIC_fpCVTSD, "fcvtsd", "\t$dst, $a", [(set SPR:$dst, (fround DPR:$a))]> { let Inst{27-23} = 0b11101; let Inst{21-16} = 0b110111; @@ -198,26 +198,26 @@ let neverHasSideEffects = 1 in { def FCPYD : ADuI<0b11101011, 0b0000, 0b0100, (outs DPR:$dst), (ins DPR:$a), - IIC_fpUNA64, "fcpyd", " $dst, $a", []>; + IIC_fpUNA64, "fcpyd", "\t$dst, $a", []>; def FCPYS : ASuI<0b11101011, 0b0000, 0b0100, (outs SPR:$dst), (ins SPR:$a), - IIC_fpUNA32, "fcpys", " $dst, $a", []>; + IIC_fpUNA32, "fcpys", "\t$dst, $a", []>; } // neverHasSideEffects def FNEGD : ADuI<0b11101011, 0b0001, 0b0100, (outs DPR:$dst), (ins DPR:$a), - IIC_fpUNA64, "fnegd", " $dst, $a", + IIC_fpUNA64, "fnegd", "\t$dst, $a", [(set DPR:$dst, (fneg DPR:$a))]>; def FNEGS : ASuIn<0b11101011, 0b0001, 0b0100, (outs SPR:$dst), (ins SPR:$a), - IIC_fpUNA32, "fnegs", " $dst, $a", + IIC_fpUNA32, "fnegs", "\t$dst, $a", [(set SPR:$dst, (fneg SPR:$a))]>; def FSQRTD : ADuI<0b11101011, 0b0001, 0b1100, (outs DPR:$dst), (ins DPR:$a), - IIC_fpSQRT64, "fsqrtd", " $dst, $a", + IIC_fpSQRT64, "fsqrtd", "\t$dst, $a", [(set DPR:$dst, (fsqrt DPR:$a))]>; def FSQRTS : ASuI<0b11101011, 0b0001, 0b1100, (outs SPR:$dst), (ins SPR:$a), - IIC_fpSQRT32, "fsqrts", " $dst, $a", + IIC_fpSQRT32, "fsqrts", "\t$dst, $a", [(set SPR:$dst, (fsqrt SPR:$a))]>; //===----------------------------------------------------------------------===// @@ -225,16 +225,16 @@ // def FMRS : AVConv2I<0b11100001, 0b1010, (outs GPR:$dst), (ins SPR:$src), - IIC_VMOVSI, "fmrs", " $dst, $src", + IIC_VMOVSI, "fmrs", "\t$dst, $src", [(set GPR:$dst, (bitconvert SPR:$src))]>; def FMSR : AVConv4I<0b11100000, 0b1010, (outs SPR:$dst), (ins GPR:$src), - IIC_VMOVIS, "fmsr", " $dst, $src", + IIC_VMOVIS, "fmsr", "\t$dst, $src", [(set SPR:$dst, (bitconvert GPR:$src))]>; def FMRRD : AVConv3I<0b11000101, 0b1011, (outs GPR:$wb, GPR:$dst2), (ins DPR:$src), - IIC_VMOVDI, "fmrrd", " $wb, $dst2, $src", + IIC_VMOVDI, "fmrrd", "\t$wb, $dst2, $src", [/* FIXME: Can't write pattern for multiple result instr*/]>; // FMDHR: GPR -> SPR @@ -242,7 +242,7 @@ def FMDRR : AVConv5I<0b11000100, 0b1011, (outs DPR:$dst), (ins GPR:$src1, GPR:$src2), - IIC_VMOVID, "fmdrr", " $dst, $src1, $src2", + IIC_VMOVID, "fmdrr", "\t$dst, $src1, $src2", [(set DPR:$dst, (arm_fmdrr GPR:$src1, GPR:$src2))]>; // FMRDH: SPR -> GPR @@ -258,23 +258,23 @@ // Int to FP: def FSITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a), - IIC_fpCVTID, "fsitod", " $dst, $a", + IIC_fpCVTID, "fsitod", "\t$dst, $a", [(set DPR:$dst, (arm_sitof SPR:$a))]> { let Inst{7} = 1; } def FSITOS : AVConv1In<0b11101011, 0b1000, 0b1010, (outs SPR:$dst),(ins SPR:$a), - IIC_fpCVTIS, "fsitos", " $dst, $a", + IIC_fpCVTIS, "fsitos", "\t$dst, $a", [(set SPR:$dst, (arm_sitof SPR:$a))]> { let Inst{7} = 1; } def FUITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a), - IIC_fpCVTID, "fuitod", " $dst, $a", + IIC_fpCVTID, "fuitod", "\t$dst, $a", [(set DPR:$dst, (arm_uitof SPR:$a))]>; def FUITOS : AVConv1In<0b11101011, 0b1000, 0b1010, (outs SPR:$dst),(ins SPR:$a), - IIC_fpCVTIS, "fuitos", " $dst, $a", + IIC_fpCVTIS, "fuitos", "\t$dst, $a", [(set SPR:$dst, (arm_uitof SPR:$a))]>; // FP to Int: @@ -282,28 +282,28 @@ def FTOSIZD : AVConv1I<0b11101011, 0b1101, 0b1011, (outs SPR:$dst), (ins DPR:$a), - IIC_fpCVTDI, "ftosizd", " $dst, $a", + IIC_fpCVTDI, "ftosizd", "\t$dst, $a", [(set SPR:$dst, (arm_ftosi DPR:$a))]> { let Inst{7} = 1; // Z bit } def FTOSIZS : AVConv1In<0b11101011, 0b1101, 0b1010, (outs SPR:$dst), (ins SPR:$a), - IIC_fpCVTSI, "ftosizs", " $dst, $a", + IIC_fpCVTSI, "ftosizs", "\t$dst, $a", [(set SPR:$dst, (arm_ftosi SPR:$a))]> { let Inst{7} = 1; // Z bit } def FTOUIZD : AVConv1I<0b11101011, 0b1100, 0b1011, (outs SPR:$dst), (ins DPR:$a), - IIC_fpCVTDI, "ftouizd", " $dst, $a", + IIC_fpCVTDI, "ftouizd", "\t$dst, $a", [(set SPR:$dst, (arm_ftoui DPR:$a))]> { let Inst{7} = 1; // Z bit } def FTOUIZS : AVConv1In<0b11101011, 0b1100, 0b1010, (outs SPR:$dst), (ins SPR:$a), - IIC_fpCVTSI, "ftouizs", " $dst, $a", + IIC_fpCVTSI, "ftouizs", "\t$dst, $a", [(set SPR:$dst, (arm_ftoui SPR:$a))]> { let Inst{7} = 1; // Z bit } @@ -313,34 +313,34 @@ // def FMACD : ADbI<0b11100000, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b), - IIC_fpMAC64, "fmacd", " $dst, $a, $b", + IIC_fpMAC64, "fmacd", "\t$dst, $a, $b", [(set DPR:$dst, (fadd (fmul DPR:$a, DPR:$b), DPR:$dstin))]>, RegConstraint<"$dstin = $dst">; def FMACS : ASbIn<0b11100000, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b), - IIC_fpMAC32, "fmacs", " $dst, $a, $b", + IIC_fpMAC32, "fmacs", "\t$dst, $a, $b", [(set SPR:$dst, (fadd (fmul SPR:$a, SPR:$b), SPR:$dstin))]>, RegConstraint<"$dstin = $dst">; def FMSCD : ADbI<0b11100001, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b), - IIC_fpMAC64, "fmscd", " $dst, $a, $b", + IIC_fpMAC64, "fmscd", "\t$dst, $a, $b", [(set DPR:$dst, (fsub (fmul DPR:$a, DPR:$b), DPR:$dstin))]>, RegConstraint<"$dstin = $dst">; def FMSCS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b), - IIC_fpMAC32, "fmscs", " $dst, $a, $b", + IIC_fpMAC32, "fmscs", "\t$dst, $a, $b", [(set SPR:$dst, (fsub (fmul SPR:$a, SPR:$b), SPR:$dstin))]>, RegConstraint<"$dstin = $dst">; def FNMACD : ADbI<0b11100000, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b), - IIC_fpMAC64, "fnmacd", " $dst, $a, $b", + IIC_fpMAC64, "fnmacd", "\t$dst, $a, $b", [(set DPR:$dst, (fadd (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>, RegConstraint<"$dstin = $dst"> { let Inst{6} = 1; } def FNMACS : ASbIn<0b11100000, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b), - IIC_fpMAC32, "fnmacs", " $dst, $a, $b", + IIC_fpMAC32, "fnmacs", "\t$dst, $a, $b", [(set SPR:$dst, (fadd (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin))]>, RegConstraint<"$dstin = $dst"> { let Inst{6} = 1; @@ -352,14 +352,14 @@ (FNMACS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[DontUseNEONForFP]>; def FNMSCD : ADbI<0b11100001, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b), - IIC_fpMAC64, "fnmscd", " $dst, $a, $b", + IIC_fpMAC64, "fnmscd", "\t$dst, $a, $b", [(set DPR:$dst, (fsub (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>, RegConstraint<"$dstin = $dst"> { let Inst{6} = 1; } def FNMSCS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b), - IIC_fpMAC32, "fnmscs", " $dst, $a, $b", + IIC_fpMAC32, "fnmscs", "\t$dst, $a, $b", [(set SPR:$dst, (fsub (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin))]>, RegConstraint<"$dstin = $dst"> { let Inst{6} = 1; @@ -371,25 +371,25 @@ def FCPYDcc : ADuI<0b11101011, 0b0000, 0b0100, (outs DPR:$dst), (ins DPR:$false, DPR:$true), - IIC_fpUNA64, "fcpyd", " $dst, $true", + IIC_fpUNA64, "fcpyd", "\t$dst, $true", [/*(set DPR:$dst, (ARMcmov DPR:$false, DPR:$true, imm:$cc))*/]>, RegConstraint<"$false = $dst">; def FCPYScc : ASuI<0b11101011, 0b0000, 0b0100, (outs SPR:$dst), (ins SPR:$false, SPR:$true), - IIC_fpUNA32, "fcpys", " $dst, $true", + IIC_fpUNA32, "fcpys", "\t$dst, $true", [/*(set SPR:$dst, (ARMcmov SPR:$false, SPR:$true, imm:$cc))*/]>, RegConstraint<"$false = $dst">; def FNEGDcc : ADuI<0b11101011, 0b0001, 0b0100, (outs DPR:$dst), (ins DPR:$false, DPR:$true), - IIC_fpUNA64, "fnegd", " $dst, $true", + IIC_fpUNA64, "fnegd", "\t$dst, $true", [/*(set DPR:$dst, (ARMcneg DPR:$false, DPR:$true, imm:$cc))*/]>, RegConstraint<"$false = $dst">; def FNEGScc : ASuI<0b11101011, 0b0001, 0b0100, (outs SPR:$dst), (ins SPR:$false, SPR:$true), - IIC_fpUNA32, "fnegs", " $dst, $true", + IIC_fpUNA32, "fnegs", "\t$dst, $true", [/*(set SPR:$dst, (ARMcneg SPR:$false, SPR:$true, imm:$cc))*/]>, RegConstraint<"$false = $dst">; @@ -399,7 +399,8 @@ // let Defs = [CPSR], Uses = [FPSCR] in -def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT, "fmstat", "", [(arm_fmstat)]> { +def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT, "fmstat", "", + [(arm_fmstat)]> { let Inst{27-20} = 0b11101111; let Inst{19-16} = 0b0001; let Inst{15-12} = 0b1111; From johnny.chen at apple.com Mon Oct 26 19:17:39 2009 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 26 Oct 2009 17:17:39 -0700 Subject: [llvm-commits] r/rr vs. r/rr_rot distinction (lib/Target/ARM/ARMInstrInfo.td) Message-ID: <6ACC8681-7455-4542-88FB-073447D81739@apple.com> Hi, Adding "let Inst{11-10} = 0b00;" for the non-_rot definitions makes it much easier to decode/distinguish between the two instructions. -------------- next part -------------- A non-text attachment was scrubbed... Name: ARMInstrInfo.td.patch2 Type: application/octet-stream Size: 1119 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091026/842e393f/attachment.obj From vkutuzov at accesssoftek.com Mon Oct 26 19:23:20 2009 From: vkutuzov at accesssoftek.com (Viktor Kutuzov) Date: Mon, 26 Oct 2009 17:23:20 -0700 Subject: [llvm-commits] FW: [PATCH] Fix to pass options from Gold plugin to LTO codegen References: <3FE2DECEF38F9247AE7C8BC1FD2B015F0817022C@ALLISON>, <6AE1604EE3EC5F4296C096518C6B77EEF11643FF@mail.accesssoftek.com> <6AE1604EE3EC5F4296C096518C6B77EEF1163385@mail.accesssoftek.com> <4AE250D1.4090403@mxc.ca> Message-ID: Hello Nick, Thanks for the review. Please find the updated patch attached. I didn't remove the lto_codegen_debug_options yet, just marked it as deprecated. It is actually used in Ada, in files bindings/ada/llvm/llvm_linktimeoptimizer_wrap.cxx bindings/ada/llvm/llvm_link_time_optimizer-binding.ads Edward, is this fine to use lto_codegen_set_options there instead? > And that would be even better if it took an argc+argv pair Gold plug-in gets all arguments from gold one by one. It is not a big dial to construct argc+argv pair there and pass it down to the LTO, but LTO internally keeps a vector of char*, so, argc+argv doesn't make much sense unless we want to replace that vector with argc+argv pair as well and to change setCodeGenOptions behavior to set options instead of add them. If this is fine with everyone, I can prepare this patch, but would prefer to make it separately from this one since it would change the API and will break a backward compatibility. What do you think? Thanks, Viktor ----- Original Message ----- From: "Nick Lewycky" To: "Viktor Kutuzov" Cc: "Commit Messages and Patches for LLVM" Sent: Friday, October 23, 2009 5:56 PM Subject: Re: [llvm-commits] FW: [PATCH] Fix to pass options from Gold plugin to LTO codegen Viktor Kutuzov wrote: > Hello everyone, > > Please find the patch attached. > This should fix the issue when gold plugin doesn't pass the -plugin-opt options down to the LTO codegen. > See the thread "[LLVMdev] getting gold plugin to work?" for more details. > > This is the second try. > It looks like the first one was bounced, not sure why. > Sorry if anyone will get it twise. Hi Viktor, this looks like the same patch I already reviewed here: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20091019/089467.html To reiterate: "What's the difference between setCodeGenDebugOptions and setCodeGenOption? It looks like they should be merged into one then exposed by lto_codegen_set_option. And that would be even better if it took an argc+argv pair, even if that's a little harder to construct from the gold plugin, many option parsing packages work by removing the options they recognize from argc+argv and leaving the rest in place." Nick -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-gold-plugin-process_command_line.diff Type: application/octet-stream Size: 6622 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091026/d4af8bdc/attachment.obj From clattner at apple.com Mon Oct 26 19:42:14 2009 From: clattner at apple.com (Chris Lattner) Date: Mon, 26 Oct 2009 17:42:14 -0700 Subject: [llvm-commits] [llvm] r85186 - /llvm/trunk/lib/Target/ARM/ARMInstrVFP.td In-Reply-To: <200910270020.n9R0Knw6013971@zion.cs.uiuc.edu> References: <200910270020.n9R0Knw6013971@zion.cs.uiuc.edu> Message-ID: On Oct 26, 2009, at 5:20 PM, Evan Cheng wrote: > Author: evancheng > Date: Mon Oct 26 19:20:49 2009 > New Revision: 85186 > > URL: http://llvm.org/viewvc/llvm-project?rev=85186&view=rev > Log: > Now VFP instructions. Should the separator go in the ADI5 or higher level instcombine classes? -Chris > > Modified: > llvm/trunk/lib/Target/ARM/ARMInstrVFP.td > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=85186&r1=85185&r2=85186&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Mon Oct 26 19:20:49 2009 > @@ -36,20 +36,20 @@ > > let canFoldAsLoad = 1 in { > def FLDD : ADI5<0b1101, 0b01, (outs DPR:$dst), (ins addrmode5:$addr), > - IIC_fpLoad64, "fldd", " $dst, $addr", > + IIC_fpLoad64, "fldd", "\t$dst, $addr", > [(set DPR:$dst, (load addrmode5:$addr))]>; > > def FLDS : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr), > - IIC_fpLoad32, "flds", " $dst, $addr", > + IIC_fpLoad32, "flds", "\t$dst, $addr", > [(set SPR:$dst, (load addrmode5:$addr))]>; > } // canFoldAsLoad > > def FSTD : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, > addrmode5:$addr), > - IIC_fpStore64, "fstd", " $src, $addr", > + IIC_fpStore64, "fstd", "\t$src, $addr", > [(store DPR:$src, addrmode5:$addr)]>; > > def FSTS : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, > addrmode5:$addr), > - IIC_fpStore32, "fsts", " $src, $addr", > + IIC_fpStore32, "fsts", "\t$src, $addr", > [(store SPR:$src, addrmode5:$addr)]>; > > // > = > = > = > ----------------------------------------------------------------------= > ==// > @@ -59,14 +59,14 @@ > let mayLoad = 1, hasExtraDefRegAllocReq = 1 in { > def FLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb, > variable_ops), IIC_fpLoadm, > - "fldm${addr:submode}d${p} ${addr:base}, $wb", > + "fldm${addr:submode}d${p}\t${addr:base}, $wb", > []> { > let Inst{20} = 1; > } > > def FLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb, > variable_ops), IIC_fpLoadm, > - "fldm${addr:submode}s${p} ${addr:base}, $wb", > + "fldm${addr:submode}s${p}\t${addr:base}, $wb", > []> { > let Inst{20} = 1; > } > @@ -75,14 +75,14 @@ > let mayStore = 1, hasExtraSrcRegAllocReq = 1 in { > def FSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb, > variable_ops), IIC_fpStorem, > - "fstm${addr:submode}d${p} ${addr:base}, $wb", > + "fstm${addr:submode}d${p}\t${addr:base}, $wb", > []> { > let Inst{20} = 0; > } > > def FSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb, > variable_ops), IIC_fpStorem, > - "fstm${addr:submode}s${p} ${addr:base}, $wb", > + "fstm${addr:submode}s${p}\t${addr:base}, $wb", > []> { > let Inst{20} = 0; > } > @@ -95,48 +95,48 @@ > // > > def FADDD : ADbI<0b11100011, (outs DPR:$dst), (ins DPR:$a, DPR:$b), > - IIC_fpALU64, "faddd", " $dst, $a, $b", > + IIC_fpALU64, "faddd", "\t$dst, $a, $b", > [(set DPR:$dst, (fadd DPR:$a, DPR:$b))]>; > > def FADDS : ASbIn<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b), > - IIC_fpALU32, "fadds", " $dst, $a, $b", > + IIC_fpALU32, "fadds", "\t$dst, $a, $b", > [(set SPR:$dst, (fadd SPR:$a, SPR:$b))]>; > > // These are encoded as unary instructions. > let Defs = [FPSCR] in { > def FCMPED : ADuI<0b11101011, 0b0100, 0b1100, (outs), (ins DPR:$a, > DPR:$b), > - IIC_fpCMP64, "fcmped", " $a, $b", > + IIC_fpCMP64, "fcmped", "\t$a, $b", > [(arm_cmpfp DPR:$a, DPR:$b)]>; > > def FCMPES : ASuI<0b11101011, 0b0100, 0b1100, (outs), (ins SPR:$a, > SPR:$b), > - IIC_fpCMP32, "fcmpes", " $a, $b", > + IIC_fpCMP32, "fcmpes", "\t$a, $b", > [(arm_cmpfp SPR:$a, SPR:$b)]>; > } > > def FDIVD : ADbI<0b11101000, (outs DPR:$dst), (ins DPR:$a, DPR:$b), > - IIC_fpDIV64, "fdivd", " $dst, $a, $b", > + IIC_fpDIV64, "fdivd", "\t$dst, $a, $b", > [(set DPR:$dst, (fdiv DPR:$a, DPR:$b))]>; > > def FDIVS : ASbI<0b11101000, (outs SPR:$dst), (ins SPR:$a, SPR:$b), > - IIC_fpDIV32, "fdivs", " $dst, $a, $b", > + IIC_fpDIV32, "fdivs", "\t$dst, $a, $b", > [(set SPR:$dst, (fdiv SPR:$a, SPR:$b))]>; > > def FMULD : ADbI<0b11100010, (outs DPR:$dst), (ins DPR:$a, DPR:$b), > - IIC_fpMUL64, "fmuld", " $dst, $a, $b", > + IIC_fpMUL64, "fmuld", "\t$dst, $a, $b", > [(set DPR:$dst, (fmul DPR:$a, DPR:$b))]>; > > def FMULS : ASbIn<0b11100010, (outs SPR:$dst), (ins SPR:$a, SPR:$b), > - IIC_fpMUL32, "fmuls", " $dst, $a, $b", > + IIC_fpMUL32, "fmuls", "\t$dst, $a, $b", > [(set SPR:$dst, (fmul SPR:$a, SPR:$b))]>; > > def FNMULD : ADbI<0b11100010, (outs DPR:$dst), (ins DPR:$a, DPR:$b), > - IIC_fpMUL64, "fnmuld", " $dst, $a, $b", > + IIC_fpMUL64, "fnmuld", "\t$dst, $a, $b", > [(set DPR:$dst, (fneg (fmul DPR:$a, DPR:$b)))]> { > let Inst{6} = 1; > } > > def FNMULS : ASbI<0b11100010, (outs SPR:$dst), (ins SPR:$a, SPR:$b), > - IIC_fpMUL32, "fnmuls", " $dst, $a, $b", > + IIC_fpMUL32, "fnmuls", "\t$dst, $a, $b", > [(set SPR:$dst, (fneg (fmul SPR:$a, SPR:$b)))]> { > let Inst{6} = 1; > } > @@ -149,13 +149,13 @@ > > > def FSUBD : ADbI<0b11100011, (outs DPR:$dst), (ins DPR:$a, DPR:$b), > - IIC_fpALU64, "fsubd", " $dst, $a, $b", > + IIC_fpALU64, "fsubd", "\t$dst, $a, $b", > [(set DPR:$dst, (fsub DPR:$a, DPR:$b))]> { > let Inst{6} = 1; > } > > def FSUBS : ASbIn<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b), > - IIC_fpALU32, "fsubs", " $dst, $a, $b", > + IIC_fpALU32, "fsubs", "\t$dst, $a, $b", > [(set SPR:$dst, (fsub SPR:$a, SPR:$b))]> { > let Inst{6} = 1; > } > @@ -165,30 +165,30 @@ > // > > def FABSD : ADuI<0b11101011, 0b0000, 0b1100, (outs DPR:$dst), (ins > DPR:$a), > - IIC_fpUNA64, "fabsd", " $dst, $a", > + IIC_fpUNA64, "fabsd", "\t$dst, $a", > [(set DPR:$dst, (fabs DPR:$a))]>; > > def FABSS : ASuIn<0b11101011, 0b0000, 0b1100, (outs SPR:$dst), (ins > SPR:$a), > - IIC_fpUNA32, "fabss", " $dst, $a", > + IIC_fpUNA32, "fabss", "\t$dst, $a", > [(set SPR:$dst, (fabs SPR:$a))]>; > > let Defs = [FPSCR] in { > def FCMPEZD : ADuI<0b11101011, 0b0101, 0b1100, (outs), (ins DPR:$a), > - IIC_fpCMP64, "fcmpezd", " $a", > + IIC_fpCMP64, "fcmpezd", "\t$a", > [(arm_cmpfp0 DPR:$a)]>; > > def FCMPEZS : ASuI<0b11101011, 0b0101, 0b1100, (outs), (ins SPR:$a), > - IIC_fpCMP32, "fcmpezs", " $a", > + IIC_fpCMP32, "fcmpezs", "\t$a", > [(arm_cmpfp0 SPR:$a)]>; > } > > def FCVTDS : ASuI<0b11101011, 0b0111, 0b1100, (outs DPR:$dst), (ins > SPR:$a), > - IIC_fpCVTDS, "fcvtds", " $dst, $a", > + IIC_fpCVTDS, "fcvtds", "\t$dst, $a", > [(set DPR:$dst, (fextend SPR:$a))]>; > > // Special case encoding: bits 11-8 is 0b1011. > def FCVTSD : VFPAI<(outs SPR:$dst), (ins DPR:$a), VFPUnaryFrm, > - IIC_fpCVTSD, "fcvtsd", " $dst, $a", > + IIC_fpCVTSD, "fcvtsd", "\t$dst, $a", > [(set SPR:$dst, (fround DPR:$a))]> { > let Inst{27-23} = 0b11101; > let Inst{21-16} = 0b110111; > @@ -198,26 +198,26 @@ > > let neverHasSideEffects = 1 in { > def FCPYD : ADuI<0b11101011, 0b0000, 0b0100, (outs DPR:$dst), (ins > DPR:$a), > - IIC_fpUNA64, "fcpyd", " $dst, $a", []>; > + IIC_fpUNA64, "fcpyd", "\t$dst, $a", []>; > > def FCPYS : ASuI<0b11101011, 0b0000, 0b0100, (outs SPR:$dst), (ins > SPR:$a), > - IIC_fpUNA32, "fcpys", " $dst, $a", []>; > + IIC_fpUNA32, "fcpys", "\t$dst, $a", []>; > } // neverHasSideEffects > > def FNEGD : ADuI<0b11101011, 0b0001, 0b0100, (outs DPR:$dst), (ins > DPR:$a), > - IIC_fpUNA64, "fnegd", " $dst, $a", > + IIC_fpUNA64, "fnegd", "\t$dst, $a", > [(set DPR:$dst, (fneg DPR:$a))]>; > > def FNEGS : ASuIn<0b11101011, 0b0001, 0b0100, (outs SPR:$dst), (ins > SPR:$a), > - IIC_fpUNA32, "fnegs", " $dst, $a", > + IIC_fpUNA32, "fnegs", "\t$dst, $a", > [(set SPR:$dst, (fneg SPR:$a))]>; > > def FSQRTD : ADuI<0b11101011, 0b0001, 0b1100, (outs DPR:$dst), (ins > DPR:$a), > - IIC_fpSQRT64, "fsqrtd", " $dst, $a", > + IIC_fpSQRT64, "fsqrtd", "\t$dst, $a", > [(set DPR:$dst, (fsqrt DPR:$a))]>; > > def FSQRTS : ASuI<0b11101011, 0b0001, 0b1100, (outs SPR:$dst), (ins > SPR:$a), > - IIC_fpSQRT32, "fsqrts", " $dst, $a", > + IIC_fpSQRT32, "fsqrts", "\t$dst, $a", > [(set SPR:$dst, (fsqrt SPR:$a))]>; > > // > = > = > = > ----------------------------------------------------------------------= > ==// > @@ -225,16 +225,16 @@ > // > > def FMRS : AVConv2I<0b11100001, 0b1010, (outs GPR:$dst), (ins SPR: > $src), > - IIC_VMOVSI, "fmrs", " $dst, $src", > + IIC_VMOVSI, "fmrs", "\t$dst, $src", > [(set GPR:$dst, (bitconvert SPR:$src))]>; > > def FMSR : AVConv4I<0b11100000, 0b1010, (outs SPR:$dst), (ins GPR: > $src), > - IIC_VMOVIS, "fmsr", " $dst, $src", > + IIC_VMOVIS, "fmsr", "\t$dst, $src", > [(set SPR:$dst, (bitconvert GPR:$src))]>; > > def FMRRD : AVConv3I<0b11000101, 0b1011, > (outs GPR:$wb, GPR:$dst2), (ins DPR:$src), > - IIC_VMOVDI, "fmrrd", " $wb, $dst2, $src", > + IIC_VMOVDI, "fmrrd", "\t$wb, $dst2, $src", > [/* FIXME: Can't write pattern for multiple result > instr*/]>; > > // FMDHR: GPR -> SPR > @@ -242,7 +242,7 @@ > > def FMDRR : AVConv5I<0b11000100, 0b1011, > (outs DPR:$dst), (ins GPR:$src1, GPR:$src2), > - IIC_VMOVID, "fmdrr", " $dst, $src1, $src2", > + IIC_VMOVID, "fmdrr", "\t$dst, $src1, $src2", > [(set DPR:$dst, (arm_fmdrr GPR:$src1, GPR:$src2))]>; > > // FMRDH: SPR -> GPR > @@ -258,23 +258,23 @@ > // Int to FP: > > def FSITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), > (ins SPR:$a), > - IIC_fpCVTID, "fsitod", " $dst, $a", > + IIC_fpCVTID, "fsitod", "\t$dst, $a", > [(set DPR:$dst, (arm_sitof SPR:$a))]> { > let Inst{7} = 1; > } > > def FSITOS : AVConv1In<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), > (ins SPR:$a), > - IIC_fpCVTIS, "fsitos", " $dst, $a", > + IIC_fpCVTIS, "fsitos", "\t$dst, $a", > [(set SPR:$dst, (arm_sitof SPR:$a))]> { > let Inst{7} = 1; > } > > def FUITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), > (ins SPR:$a), > - IIC_fpCVTID, "fuitod", " $dst, $a", > + IIC_fpCVTID, "fuitod", "\t$dst, $a", > [(set DPR:$dst, (arm_uitof SPR:$a))]>; > > def FUITOS : AVConv1In<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), > (ins SPR:$a), > - IIC_fpCVTIS, "fuitos", " $dst, $a", > + IIC_fpCVTIS, "fuitos", "\t$dst, $a", > [(set SPR:$dst, (arm_uitof SPR:$a))]>; > > // FP to Int: > @@ -282,28 +282,28 @@ > > def FTOSIZD : AVConv1I<0b11101011, 0b1101, 0b1011, > (outs SPR:$dst), (ins DPR:$a), > - IIC_fpCVTDI, "ftosizd", " $dst, $a", > + IIC_fpCVTDI, "ftosizd", "\t$dst, $a", > [(set SPR:$dst, (arm_ftosi DPR:$a))]> { > let Inst{7} = 1; // Z bit > } > > def FTOSIZS : AVConv1In<0b11101011, 0b1101, 0b1010, > (outs SPR:$dst), (ins SPR:$a), > - IIC_fpCVTSI, "ftosizs", " $dst, $a", > + IIC_fpCVTSI, "ftosizs", "\t$dst, $a", > [(set SPR:$dst, (arm_ftosi SPR:$a))]> { > let Inst{7} = 1; // Z bit > } > > def FTOUIZD : AVConv1I<0b11101011, 0b1100, 0b1011, > (outs SPR:$dst), (ins DPR:$a), > - IIC_fpCVTDI, "ftouizd", " $dst, $a", > + IIC_fpCVTDI, "ftouizd", "\t$dst, $a", > [(set SPR:$dst, (arm_ftoui DPR:$a))]> { > let Inst{7} = 1; // Z bit > } > > def FTOUIZS : AVConv1In<0b11101011, 0b1100, 0b1010, > (outs SPR:$dst), (ins SPR:$a), > - IIC_fpCVTSI, "ftouizs", " $dst, $a", > + IIC_fpCVTSI, "ftouizs", "\t$dst, $a", > [(set SPR:$dst, (arm_ftoui SPR:$a))]> { > let Inst{7} = 1; // Z bit > } > @@ -313,34 +313,34 @@ > // > > def FMACD : ADbI<0b11100000, (outs DPR:$dst), (ins DPR:$dstin, DPR: > $a, DPR:$b), > - IIC_fpMAC64, "fmacd", " $dst, $a, $b", > + IIC_fpMAC64, "fmacd", "\t$dst, $a, $b", > [(set DPR:$dst, (fadd (fmul DPR:$a, DPR:$b), DPR: > $dstin))]>, > RegConstraint<"$dstin = $dst">; > > def FMACS : ASbIn<0b11100000, (outs SPR:$dst), (ins SPR:$dstin, SPR: > $a, SPR:$b), > - IIC_fpMAC32, "fmacs", " $dst, $a, $b", > + IIC_fpMAC32, "fmacs", "\t$dst, $a, $b", > [(set SPR:$dst, (fadd (fmul SPR:$a, SPR:$b), SPR: > $dstin))]>, > RegConstraint<"$dstin = $dst">; > > def FMSCD : ADbI<0b11100001, (outs DPR:$dst), (ins DPR:$dstin, DPR: > $a, DPR:$b), > - IIC_fpMAC64, "fmscd", " $dst, $a, $b", > + IIC_fpMAC64, "fmscd", "\t$dst, $a, $b", > [(set DPR:$dst, (fsub (fmul DPR:$a, DPR:$b), DPR: > $dstin))]>, > RegConstraint<"$dstin = $dst">; > > def FMSCS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR: > $a, SPR:$b), > - IIC_fpMAC32, "fmscs", " $dst, $a, $b", > + IIC_fpMAC32, "fmscs", "\t$dst, $a, $b", > [(set SPR:$dst, (fsub (fmul SPR:$a, SPR:$b), SPR: > $dstin))]>, > RegConstraint<"$dstin = $dst">; > > def FNMACD : ADbI<0b11100000, (outs DPR:$dst), (ins DPR:$dstin, DPR: > $a, DPR:$b), > - IIC_fpMAC64, "fnmacd", " $dst, $a, $b", > + IIC_fpMAC64, "fnmacd", "\t$dst, $a, $b", > [(set DPR:$dst, (fadd (fneg (fmul DPR:$a, DPR:$b)), DPR: > $dstin))]>, > RegConstraint<"$dstin = $dst"> { > let Inst{6} = 1; > } > > def FNMACS : ASbIn<0b11100000, (outs SPR:$dst), (ins SPR:$dstin, SPR: > $a, SPR:$b), > - IIC_fpMAC32, "fnmacs", " $dst, $a, $b", > + IIC_fpMAC32, "fnmacs", "\t$dst, $a, $b", > [(set SPR:$dst, (fadd (fneg (fmul SPR:$a, SPR:$b)), SPR: > $dstin))]>, > RegConstraint<"$dstin = $dst"> { > let Inst{6} = 1; > @@ -352,14 +352,14 @@ > (FNMACS SPR:$dstin, SPR:$a, SPR:$b)>, > Requires<[DontUseNEONForFP]>; > > def FNMSCD : ADbI<0b11100001, (outs DPR:$dst), (ins DPR:$dstin, DPR: > $a, DPR:$b), > - IIC_fpMAC64, "fnmscd", " $dst, $a, $b", > + IIC_fpMAC64, "fnmscd", "\t$dst, $a, $b", > [(set DPR:$dst, (fsub (fneg (fmul DPR:$a, DPR:$b)), DPR: > $dstin))]>, > RegConstraint<"$dstin = $dst"> { > let Inst{6} = 1; > } > > def FNMSCS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR: > $a, SPR:$b), > - IIC_fpMAC32, "fnmscs", " $dst, $a, $b", > + IIC_fpMAC32, "fnmscs", "\t$dst, $a, $b", > [(set SPR:$dst, (fsub (fneg (fmul SPR:$a, SPR:$b)), SPR: > $dstin))]>, > RegConstraint<"$dstin = $dst"> { > let Inst{6} = 1; > @@ -371,25 +371,25 @@ > > def FCPYDcc : ADuI<0b11101011, 0b0000, 0b0100, > (outs DPR:$dst), (ins DPR:$false, DPR:$true), > - IIC_fpUNA64, "fcpyd", " $dst, $true", > + IIC_fpUNA64, "fcpyd", "\t$dst, $true", > [/*(set DPR:$dst, (ARMcmov DPR:$false, DPR:$true, > imm:$cc))*/]>, > RegConstraint<"$false = $dst">; > > def FCPYScc : ASuI<0b11101011, 0b0000, 0b0100, > (outs SPR:$dst), (ins SPR:$false, SPR:$true), > - IIC_fpUNA32, "fcpys", " $dst, $true", > + IIC_fpUNA32, "fcpys", "\t$dst, $true", > [/*(set SPR:$dst, (ARMcmov SPR:$false, SPR:$true, > imm:$cc))*/]>, > RegConstraint<"$false = $dst">; > > def FNEGDcc : ADuI<0b11101011, 0b0001, 0b0100, > (outs DPR:$dst), (ins DPR:$false, DPR:$true), > - IIC_fpUNA64, "fnegd", " $dst, $true", > + IIC_fpUNA64, "fnegd", "\t$dst, $true", > [/*(set DPR:$dst, (ARMcneg DPR:$false, DPR:$true, > imm:$cc))*/]>, > RegConstraint<"$false = $dst">; > > def FNEGScc : ASuI<0b11101011, 0b0001, 0b0100, > (outs SPR:$dst), (ins SPR:$false, SPR:$true), > - IIC_fpUNA32, "fnegs", " $dst, $true", > + IIC_fpUNA32, "fnegs", "\t$dst, $true", > [/*(set SPR:$dst, (ARMcneg SPR:$false, SPR:$true, > imm:$cc))*/]>, > RegConstraint<"$false = $dst">; > > @@ -399,7 +399,8 @@ > // > > let Defs = [CPSR], Uses = [FPSCR] in > -def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT, "fmstat", > "", [(arm_fmstat)]> { > +def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT, "fmstat", > "", > + [(arm_fmstat)]> { > let Inst{27-20} = 0b11101111; > let Inst{19-16} = 0b0001; > let Inst{15-12} = 0b1111; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From echristo at apple.com Mon Oct 26 19:52:25 2009 From: echristo at apple.com (Eric Christopher) Date: Tue, 27 Oct 2009 00:52:25 -0000 Subject: [llvm-commits] [llvm] r85189 - in /llvm/trunk: include/llvm/Intrinsics.td lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp lib/Transforms/Scalar/SimplifyLibCalls.cpp Message-ID: <200910270052.n9R0qPfC015484@zion.cs.uiuc.edu> Author: echristo Date: Mon Oct 26 19:52:25 2009 New Revision: 85189 URL: http://llvm.org/viewvc/llvm-project?rev=85189&view=rev Log: Add objectsize intrinsic and hook it up through codegen. Doesn't do anything than return "I don't know" at the moment. Modified: llvm/trunk/include/llvm/Intrinsics.td llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Modified: llvm/trunk/include/llvm/Intrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=85189&r1=85188&r2=85189&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.td (original) +++ llvm/trunk/include/llvm/Intrinsics.td Mon Oct 26 19:52:25 2009 @@ -259,6 +259,11 @@ def int_sigsetjmp : Intrinsic<[llvm_i32_ty] , [llvm_ptr_ty, llvm_i32_ty]>; def int_siglongjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_i32_ty]>; +// Internal interface for object size checking +def int_objectsize : Intrinsic<[llvm_anyint_ty], [llvm_ptr_ty, llvm_i32_ty], + [IntrReadArgMem]>, + GCCBuiltin<"__builtin_object_size">; + //===-------------------- Bit Manipulation Intrinsics ---------------------===// // Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=85189&r1=85188&r2=85189&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Mon Oct 26 19:52:25 2009 @@ -4204,6 +4204,18 @@ DAG.setRoot(Result); return 0; } + case Intrinsic::objectsize: { + // If we don't know by now, we're never going to know. + ConstantInt *CI = dyn_cast(I.getOperand(2)); + + assert(CI && "Non-constant type in __builtin_object_size?"); + + if (CI->getZExtValue() < 2) + setValue(&I, DAG.getConstant(-1, MVT::i32)); + else + setValue(&I, DAG.getConstant(0, MVT::i32)); + return 0; + } case Intrinsic::var_annotation: // Discard annotate attributes return 0; Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp?rev=85189&r1=85188&r2=85189&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Mon Oct 26 19:52:25 2009 @@ -509,6 +509,27 @@ } //===----------------------------------------------------------------------===// +// Miscellaneous LibCall/Intrinsic Optimizations +//===----------------------------------------------------------------------===// + +namespace { +struct SizeOpt : public LibCallOptimization { + virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { + // TODO: We can do more with this, but delaying to here should be no change + // in behavior. + ConstantInt *Const = dyn_cast(CI->getOperand(2)); + + if (!Const) return 0; + + if (Const->getZExtValue() < 2) + return Constant::getAllOnesValue(Const->getType()); + else + return ConstantInt::get(Const->getType(), 0); + } +}; +} + +//===----------------------------------------------------------------------===// // String and Memory LibCall Optimizations //===----------------------------------------------------------------------===// @@ -1548,6 +1569,7 @@ // Formatting and IO Optimizations SPrintFOpt SPrintF; PrintFOpt PrintF; FWriteOpt FWrite; FPutsOpt FPuts; FPrintFOpt FPrintF; + SizeOpt ObjectSize; bool Modified; // This is only used by doInitialization. public: @@ -1653,6 +1675,9 @@ Optimizations["fwrite"] = &FWrite; Optimizations["fputs"] = &FPuts; Optimizations["fprintf"] = &FPrintF; + + // Miscellaneous + Optimizations["llvm.objectsize"] = &ObjectSize; } From echristo at apple.com Mon Oct 26 19:53:46 2009 From: echristo at apple.com (Eric Christopher) Date: Tue, 27 Oct 2009 00:53:46 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r85190 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200910270053.n9R0rkqP015550@zion.cs.uiuc.edu> Author: echristo Date: Mon Oct 26 19:53:46 2009 New Revision: 85190 URL: http://llvm.org/viewvc/llvm-project?rev=85190&view=rev Log: Use new objectsize intrinsic for object size checking instead of folding to "don't know" immediately. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=85190&r1=85189&r2=85190&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Oct 26 19:53:46 2009 @@ -4976,12 +4976,12 @@ return EmitBuiltinUnwindInit(exp, Result); case BUILT_IN_OBJECT_SIZE: { - tree ArgList = TREE_OPERAND (exp, 1); - if (!validate_arglist(ArgList, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) { + tree arglist = TREE_OPERAND (exp, 1); + if (!validate_arglist(arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) { error("Invalid builtin_object_size argument types"); return false; } - tree ObjSizeTree = TREE_VALUE (TREE_CHAIN (ArgList)); + tree ObjSizeTree = TREE_VALUE (TREE_CHAIN (arglist)); STRIP_NOPS (ObjSizeTree); if (TREE_CODE (ObjSizeTree) != INTEGER_CST || tree_int_cst_sgn (ObjSizeTree) < 0 @@ -4990,12 +4990,24 @@ return false; } - // This treats everything as unknown, and is minimally defensible as - // correct, although completely useless. - if (tree_low_cst (ObjSizeTree, 0) < 2) - Result = Constant::getAllOnesValue(TD.getIntPtrType(Context)); - else - Result = ConstantInt::get(TD.getIntPtrType(Context), 0); + tree Object = TREE_VALUE(arglist); + tree ObjTy = TREE_VALUE(TREE_CHAIN(arglist)); + + Value* Args[] = { + Emit(Object, 0), + Emit(ObjTy, 0) + }; + + const Type* Ty[3]; + Ty[0] = ConvertType(TREE_TYPE(exp)); + Ty[1] = Type::getInt8PtrTy(Context); + Ty[2] = Type::getInt32Ty(Context); + + Result = Builder.CreateCall(Intrinsic::getDeclaration(TheModule, + Intrinsic::objectsize, + Ty, + 1), + Args, Args + 2); return true; } // Unary bit counting intrinsics. From jyasskin at google.com Mon Oct 26 20:06:51 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Tue, 27 Oct 2009 01:06:51 -0000 Subject: [llvm-commits] [llvm] r85192 - /llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp Message-ID: <200910270106.n9R16qwq016238@zion.cs.uiuc.edu> Author: jyasskin Date: Mon Oct 26 20:06:51 2009 New Revision: 85192 URL: http://llvm.org/viewvc/llvm-project?rev=85192&view=rev Log: Fix OProfileJITEventListener after r85182. Modified: llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp Modified: llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp?rev=85192&r1=85191&r2=85192&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp Mon Oct 26 20:06:51 2009 @@ -43,7 +43,7 @@ virtual void NotifyFunctionEmitted(const Function &F, void *FnStart, size_t FnSize, const EmittedFunctionDetails &Details); - virtual void NotifyFreeingMachineCode(const Function &F, void *OldPtr); + virtual void NotifyFreeingMachineCode(void *OldPtr); }; OProfileJITEventListener::OProfileJITEventListener() From mrs at apple.com Mon Oct 26 21:14:14 2009 From: mrs at apple.com (Mike Stump) Date: Tue, 27 Oct 2009 02:14:14 -0000 Subject: [llvm-commits] [llvm] r85197 - /llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt Message-ID: <200910270214.n9R2EEo0019088@zion.cs.uiuc.edu> Author: mrs Date: Mon Oct 26 21:14:13 2009 New Revision: 85197 URL: http://llvm.org/viewvc/llvm-project?rev=85197&view=rev Log: VS build fix, patch by Marius Wachtler. Modified: llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt Modified: llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt?rev=85197&r1=85196&r2=85197&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt (original) +++ llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt Mon Oct 26 21:14:13 2009 @@ -23,6 +23,7 @@ Reassociate.cpp Reg2Mem.cpp SCCP.cpp + SCCVN.cpp Scalar.cpp ScalarReplAggregates.cpp SimplifyCFGPass.cpp From mrs at apple.com Mon Oct 26 21:17:51 2009 From: mrs at apple.com (Mike Stump) Date: Tue, 27 Oct 2009 02:17:51 -0000 Subject: [llvm-commits] [llvm] r85198 - /llvm/trunk/include/llvm/ADT/ValueMap.h Message-ID: <200910270217.n9R2HpV5019230@zion.cs.uiuc.edu> Author: mrs Date: Mon Oct 26 21:17:51 2009 New Revision: 85198 URL: http://llvm.org/viewvc/llvm-project?rev=85198&view=rev Log: Fix VS build, patch by Marius Wachtler. Modified: llvm/trunk/include/llvm/ADT/ValueMap.h Modified: llvm/trunk/include/llvm/ADT/ValueMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ValueMap.h?rev=85198&r1=85197&r2=85198&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/ValueMap.h (original) +++ llvm/trunk/include/llvm/ADT/ValueMap.h Mon Oct 26 21:17:51 2009 @@ -199,7 +199,7 @@ template class ValueMapCallbackVH : public CallbackVH { friend class ValueMap; - friend class DenseMapInfo; + friend struct DenseMapInfo; typedef ValueMap ValueMapT; typedef typename llvm::remove_pointer::type KeySansPointerT; From chandlerc at google.com Mon Oct 26 13:38:10 2009 From: chandlerc at google.com (Chandler Carruth) Date: Mon, 26 Oct 2009 11:38:10 -0700 Subject: [llvm-commits] [llvm] r85127 - in /llvm/trunk: include/llvm/CodeGen/AntiDepBreaker.h lib/CodeGen/CMakeLists.txt lib/CodeGen/CriticalAntiDepBreaker.cpp lib/CodeGen/CriticalAntiDepBreaker.h lib/CodeGen/PostRASchedulerList.cpp lib/Target/ARM/ARMSubt Message-ID: <74c447500910261138m3326f8a7t859d0bc8eac504e9@mail.gmail.com> FYI, this change causes both llvm::AntiDepBreaker and llvm::CriticalAntiDepBreaker to have virtual functions and an accessible non-virtual destructor. On Mon, Oct 26, 2009 at 9:59 AM, David Goodwin wrote: > Author: david_goodwin > Date: Mon Oct 26 11:59:04 2009 > New Revision: 85127 > > URL: http://llvm.org/viewvc/llvm-project?rev=85127&view=rev > Log: > Break anti-dependence breaking out into its own class. > > Added: > ? ?llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h > ? ?llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp > ? ?llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h > Modified: > ? ?llvm/trunk/lib/CodeGen/CMakeLists.txt > ? ?llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp > ? ?llvm/trunk/lib/Target/ARM/ARMSubtarget.h > ? ?llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll > > Added: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h?rev=85127&view=auto > > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h (added) > +++ llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Mon Oct 26 11:59:04 2009 > @@ -0,0 +1,56 @@ > +//=- llvm/CodeGen/AntiDepBreaker.h - Anti-Dependence Breaking -*- C++ -*-=// > +// > +// ? ? ? ? ? ? ? ? ? ? The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > +// > +// This file implements the AntiDepBreaker class, which implements > +// anti-dependence breaking heuristics for post-register-allocation scheduling. > +// > +//===----------------------------------------------------------------------===// > + > +#ifndef LLVM_CODEGEN_ANTIDEPBREAKER_H > +#define LLVM_CODEGEN_ANTIDEPBREAKER_H > + > +#include "llvm/CodeGen/MachineBasicBlock.h" > +#include "llvm/CodeGen/MachineFrameInfo.h" > +#include "llvm/CodeGen/MachineFunction.h" > +#include "llvm/CodeGen/MachineRegisterInfo.h" > +#include "llvm/CodeGen/ScheduleDAG.h" > +#include "llvm/Target/TargetRegisterInfo.h" > + > +namespace llvm { > + > +/// AntiDepBreaker - This class works into conjunction with the > +/// post-RA scheduler to rename registers to break register > +/// anti-dependencies. > +class AntiDepBreaker { > +public: > + ?/// Start - Initialize anti-dep breaking for a new basic block. > + ?virtual void StartBlock(MachineBasicBlock *BB) =0; > + > + ?/// BreakAntiDependencies - Identifiy anti-dependencies within a > + ?/// basic-block region and break them by renaming registers. Return > + ?/// the number of anti-dependencies broken. > + ?/// > + ?virtual unsigned BreakAntiDependencies(std::vector& SUnits, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MachineBasicBlock::iterator& Begin, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MachineBasicBlock::iterator& End, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned InsertPosIndex) =0; > + > + ?/// Observe - Update liveness information to account for the current > + ?/// instruction, which will not be scheduled. > + ?/// > + ?virtual void Observe(MachineInstr *MI, unsigned Count, > + ? ? ? ? ? ? ? ? ? ? ? unsigned InsertPosIndex) =0; > + > + ?/// Finish - Finish anti-dep breaking for a basic block. > + ?virtual void FinishBlock() =0; > +}; > + > +} > + > +#endif > > Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=85127&r1=85126&r2=85127&view=diff > > ============================================================================== > --- llvm/trunk/lib/CodeGen/CMakeLists.txt (original) > +++ llvm/trunk/lib/CodeGen/CMakeLists.txt Mon Oct 26 11:59:04 2009 > @@ -1,6 +1,7 @@ > ?add_llvm_library(LLVMCodeGen > ? BranchFolding.cpp > ? CodePlacementOpt.cpp > + ?CriticalAntiDepBreaker.cpp > ? DeadMachineInstructionElim.cpp > ? DwarfEHPrepare.cpp > ? ELFCodeEmitter.cpp > > Added: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp?rev=85127&view=auto > > ============================================================================== > --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp (added) > +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp Mon Oct 26 11:59:04 2009 > @@ -0,0 +1,539 @@ > +//===----- CriticalAntiDepBreaker.cpp - Anti-dep breaker -------- ---------===// > +// > +// ? ? ? ? ? ? ? ? ? ? The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > +// > +// This file implements the CriticalAntiDepBreaker class, which > +// implements register anti-dependence breaking along a blocks > +// critical path during post-RA scheduler. > +// > +//===----------------------------------------------------------------------===// > + > +#define DEBUG_TYPE "critical-antidep" > +#include "CriticalAntiDepBreaker.h" > +#include "llvm/CodeGen/MachineBasicBlock.h" > +#include "llvm/CodeGen/MachineFrameInfo.h" > +#include "llvm/Target/TargetMachine.h" > +#include "llvm/Target/TargetRegisterInfo.h" > +#include "llvm/Support/Debug.h" > +#include "llvm/Support/ErrorHandling.h" > +#include "llvm/Support/raw_ostream.h" > + > +using namespace llvm; > + > +CriticalAntiDepBreaker:: > +CriticalAntiDepBreaker(MachineFunction& MFi) : > + ?AntiDepBreaker(), MF(MFi), > + ?MRI(MF.getRegInfo()), > + ?TRI(MF.getTarget().getRegisterInfo()), > + ?AllocatableSet(TRI->getAllocatableSet(MF)) > +{ > +} > + > +CriticalAntiDepBreaker::~CriticalAntiDepBreaker() { > +} > + > +void CriticalAntiDepBreaker::StartBlock(MachineBasicBlock *BB) { > + ?// Clear out the register class data. > + ?std::fill(Classes, array_endof(Classes), > + ? ? ? ? ? ?static_cast(0)); > + > + ?// Initialize the indices to indicate that no registers are live. > + ?std::fill(KillIndices, array_endof(KillIndices), ~0u); > + ?std::fill(DefIndices, array_endof(DefIndices), BB->size()); > + > + ?// Clear "do not change" set. > + ?KeepRegs.clear(); > + > + ?bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn()); > + > + ?// Determine the live-out physregs for this block. > + ?if (IsReturnBlock) { > + ? ?// In a return block, examine the function live-out regs. > + ? ?for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), > + ? ? ? ? E = MRI.liveout_end(); I != E; ++I) { > + ? ? ?unsigned Reg = *I; > + ? ? ?Classes[Reg] = reinterpret_cast(-1); > + ? ? ?KillIndices[Reg] = BB->size(); > + ? ? ?DefIndices[Reg] = ~0u; > + ? ? ?// Repeat, for all aliases. > + ? ? ?for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > + ? ? ? ?unsigned AliasReg = *Alias; > + ? ? ? ?Classes[AliasReg] = reinterpret_cast(-1); > + ? ? ? ?KillIndices[AliasReg] = BB->size(); > + ? ? ? ?DefIndices[AliasReg] = ~0u; > + ? ? ?} > + ? ?} > + ?} else { > + ? ?// In a non-return block, examine the live-in regs of all successors. > + ? ?for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), > + ? ? ? ? SE = BB->succ_end(); SI != SE; ++SI) > + ? ? ?for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), > + ? ? ? ? ? E = (*SI)->livein_end(); I != E; ++I) { > + ? ? ? ?unsigned Reg = *I; > + ? ? ? ?Classes[Reg] = reinterpret_cast(-1); > + ? ? ? ?KillIndices[Reg] = BB->size(); > + ? ? ? ?DefIndices[Reg] = ~0u; > + ? ? ? ?// Repeat, for all aliases. > + ? ? ? ?for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > + ? ? ? ? ?unsigned AliasReg = *Alias; > + ? ? ? ? ?Classes[AliasReg] = reinterpret_cast(-1); > + ? ? ? ? ?KillIndices[AliasReg] = BB->size(); > + ? ? ? ? ?DefIndices[AliasReg] = ~0u; > + ? ? ? ?} > + ? ? ?} > + ?} > + > + ?// Mark live-out callee-saved registers. In a return block this is > + ?// all callee-saved registers. In non-return this is any > + ?// callee-saved register that is not saved in the prolog. > + ?const MachineFrameInfo *MFI = MF.getFrameInfo(); > + ?BitVector Pristine = MFI->getPristineRegs(BB); > + ?for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { > + ? ?unsigned Reg = *I; > + ? ?if (!IsReturnBlock && !Pristine.test(Reg)) continue; > + ? ?Classes[Reg] = reinterpret_cast(-1); > + ? ?KillIndices[Reg] = BB->size(); > + ? ?DefIndices[Reg] = ~0u; > + ? ?// Repeat, for all aliases. > + ? ?for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > + ? ? ?unsigned AliasReg = *Alias; > + ? ? ?Classes[AliasReg] = reinterpret_cast(-1); > + ? ? ?KillIndices[AliasReg] = BB->size(); > + ? ? ?DefIndices[AliasReg] = ~0u; > + ? ?} > + ?} > +} > + > +void CriticalAntiDepBreaker::FinishBlock() { > + ?RegRefs.clear(); > + ?KeepRegs.clear(); > +} > + > +void CriticalAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned InsertPosIndex) { > + ?assert(Count < InsertPosIndex && "Instruction index out of expected range!"); > + > + ?// Any register which was defined within the previous scheduling region > + ?// may have been rescheduled and its lifetime may overlap with registers > + ?// in ways not reflected in our current liveness state. For each such > + ?// register, adjust the liveness state to be conservatively correct. > + ?for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) > + ? ?if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) { > + ? ? ?assert(KillIndices[Reg] == ~0u && "Clobbered register is live!"); > + ? ? ?// Mark this register to be non-renamable. > + ? ? ?Classes[Reg] = reinterpret_cast(-1); > + ? ? ?// Move the def index to the end of the previous region, to reflect > + ? ? ?// that the def could theoretically have been scheduled at the end. > + ? ? ?DefIndices[Reg] = InsertPosIndex; > + ? ?} > + > + ?PrescanInstruction(MI); > + ?ScanInstruction(MI, Count); > +} > + > +/// CriticalPathStep - Return the next SUnit after SU on the bottom-up > +/// critical path. > +static SDep *CriticalPathStep(SUnit *SU) { > + ?SDep *Next = 0; > + ?unsigned NextDepth = 0; > + ?// Find the predecessor edge with the greatest depth. > + ?for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end(); > + ? ? ? P != PE; ++P) { > + ? ?SUnit *PredSU = P->getSUnit(); > + ? ?unsigned PredLatency = P->getLatency(); > + ? ?unsigned PredTotalLatency = PredSU->getDepth() + PredLatency; > + ? ?// In the case of a latency tie, prefer an anti-dependency edge over > + ? ?// other types of edges. > + ? ?if (NextDepth < PredTotalLatency || > + ? ? ? ?(NextDepth == PredTotalLatency && P->getKind() == SDep::Anti)) { > + ? ? ?NextDepth = PredTotalLatency; > + ? ? ?Next = &*P; > + ? ?} > + ?} > + ?return Next; > +} > + > +void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr *MI) { > + ?// Scan the register operands for this instruction and update > + ?// Classes and RegRefs. > + ?for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > + ? ?MachineOperand &MO = MI->getOperand(i); > + ? ?if (!MO.isReg()) continue; > + ? ?unsigned Reg = MO.getReg(); > + ? ?if (Reg == 0) continue; > + ? ?const TargetRegisterClass *NewRC = 0; > + > + ? ?if (i < MI->getDesc().getNumOperands()) > + ? ? ?NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); > + > + ? ?// For now, only allow the register to be changed if its register > + ? ?// class is consistent across all uses. > + ? ?if (!Classes[Reg] && NewRC) > + ? ? ?Classes[Reg] = NewRC; > + ? ?else if (!NewRC || Classes[Reg] != NewRC) > + ? ? ?Classes[Reg] = reinterpret_cast(-1); > + > + ? ?// Now check for aliases. > + ? ?for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > + ? ? ?// If an alias of the reg is used during the live range, give up. > + ? ? ?// Note that this allows us to skip checking if AntiDepReg > + ? ? ?// overlaps with any of the aliases, among other things. > + ? ? ?unsigned AliasReg = *Alias; > + ? ? ?if (Classes[AliasReg]) { > + ? ? ? ?Classes[AliasReg] = reinterpret_cast(-1); > + ? ? ? ?Classes[Reg] = reinterpret_cast(-1); > + ? ? ?} > + ? ?} > + > + ? ?// If we're still willing to consider this register, note the reference. > + ? ?if (Classes[Reg] != reinterpret_cast(-1)) > + ? ? ?RegRefs.insert(std::make_pair(Reg, &MO)); > + > + ? ?// It's not safe to change register allocation for source operands of > + ? ?// that have special allocation requirements. > + ? ?if (MO.isUse() && MI->getDesc().hasExtraSrcRegAllocReq()) { > + ? ? ?if (KeepRegs.insert(Reg)) { > + ? ? ? ?for (const unsigned *Subreg = TRI->getSubRegisters(Reg); > + ? ? ? ? ? ? *Subreg; ++Subreg) > + ? ? ? ? ?KeepRegs.insert(*Subreg); > + ? ? ?} > + ? ?} > + ?} > +} > + > +void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned Count) { > + ?// Update liveness. > + ?// Proceding upwards, registers that are defed but not used in this > + ?// instruction are now dead. > + ?for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > + ? ?MachineOperand &MO = MI->getOperand(i); > + ? ?if (!MO.isReg()) continue; > + ? ?unsigned Reg = MO.getReg(); > + ? ?if (Reg == 0) continue; > + ? ?if (!MO.isDef()) continue; > + ? ?// Ignore two-addr defs. > + ? ?if (MI->isRegTiedToUseOperand(i)) continue; > + > + ? ?DefIndices[Reg] = Count; > + ? ?KillIndices[Reg] = ~0u; > + ? ?assert(((KillIndices[Reg] == ~0u) != > + ? ? ? ? ? ?(DefIndices[Reg] == ~0u)) && > + ? ? ? ? ? "Kill and Def maps aren't consistent for Reg!"); > + ? ?KeepRegs.erase(Reg); > + ? ?Classes[Reg] = 0; > + ? ?RegRefs.erase(Reg); > + ? ?// Repeat, for all subregs. > + ? ?for (const unsigned *Subreg = TRI->getSubRegisters(Reg); > + ? ? ? ? *Subreg; ++Subreg) { > + ? ? ?unsigned SubregReg = *Subreg; > + ? ? ?DefIndices[SubregReg] = Count; > + ? ? ?KillIndices[SubregReg] = ~0u; > + ? ? ?KeepRegs.erase(SubregReg); > + ? ? ?Classes[SubregReg] = 0; > + ? ? ?RegRefs.erase(SubregReg); > + ? ?} > + ? ?// Conservatively mark super-registers as unusable. > + ? ?for (const unsigned *Super = TRI->getSuperRegisters(Reg); > + ? ? ? ? *Super; ++Super) { > + ? ? ?unsigned SuperReg = *Super; > + ? ? ?Classes[SuperReg] = reinterpret_cast(-1); > + ? ?} > + ?} > + ?for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > + ? ?MachineOperand &MO = MI->getOperand(i); > + ? ?if (!MO.isReg()) continue; > + ? ?unsigned Reg = MO.getReg(); > + ? ?if (Reg == 0) continue; > + ? ?if (!MO.isUse()) continue; > + > + ? ?const TargetRegisterClass *NewRC = 0; > + ? ?if (i < MI->getDesc().getNumOperands()) > + ? ? ?NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); > + > + ? ?// For now, only allow the register to be changed if its register > + ? ?// class is consistent across all uses. > + ? ?if (!Classes[Reg] && NewRC) > + ? ? ?Classes[Reg] = NewRC; > + ? ?else if (!NewRC || Classes[Reg] != NewRC) > + ? ? ?Classes[Reg] = reinterpret_cast(-1); > + > + ? ?RegRefs.insert(std::make_pair(Reg, &MO)); > + > + ? ?// It wasn't previously live but now it is, this is a kill. > + ? ?if (KillIndices[Reg] == ~0u) { > + ? ? ?KillIndices[Reg] = Count; > + ? ? ?DefIndices[Reg] = ~0u; > + ? ? ? ? ?assert(((KillIndices[Reg] == ~0u) != > + ? ? ? ? ? ? ? ? ?(DefIndices[Reg] == ~0u)) && > + ? ? ? ? ? ? ? "Kill and Def maps aren't consistent for Reg!"); > + ? ?} > + ? ?// Repeat, for all aliases. > + ? ?for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > + ? ? ?unsigned AliasReg = *Alias; > + ? ? ?if (KillIndices[AliasReg] == ~0u) { > + ? ? ? ?KillIndices[AliasReg] = Count; > + ? ? ? ?DefIndices[AliasReg] = ~0u; > + ? ? ?} > + ? ?} > + ?} > +} > + > +unsigned > +CriticalAntiDepBreaker::findSuitableFreeRegister(unsigned AntiDepReg, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned LastNewReg, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const TargetRegisterClass *RC) { > + ?for (TargetRegisterClass::iterator R = RC->allocation_order_begin(MF), > + ? ? ? RE = RC->allocation_order_end(MF); R != RE; ++R) { > + ? ?unsigned NewReg = *R; > + ? ?// Don't replace a register with itself. > + ? ?if (NewReg == AntiDepReg) continue; > + ? ?// Don't replace a register with one that was recently used to repair > + ? ?// an anti-dependence with this AntiDepReg, because that would > + ? ?// re-introduce that anti-dependence. > + ? ?if (NewReg == LastNewReg) continue; > + ? ?// If NewReg is dead and NewReg's most recent def is not before > + ? ?// AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg. > + ? ?assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u)) && > + ? ? ? ? ? "Kill and Def maps aren't consistent for AntiDepReg!"); > + ? ?assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u)) && > + ? ? ? ? ? "Kill and Def maps aren't consistent for NewReg!"); > + ? ?if (KillIndices[NewReg] != ~0u || > + ? ? ? ?Classes[NewReg] == reinterpret_cast(-1) || > + ? ? ? ?KillIndices[AntiDepReg] > DefIndices[NewReg]) > + ? ? ?continue; > + ? ?return NewReg; > + ?} > + > + ?// No registers are free and available! > + ?return 0; > +} > + > +unsigned CriticalAntiDepBreaker:: > +BreakAntiDependencies(std::vector& SUnits, > + ? ? ? ? ? ? ? ? ? ? ?MachineBasicBlock::iterator& Begin, > + ? ? ? ? ? ? ? ? ? ? ?MachineBasicBlock::iterator& End, > + ? ? ? ? ? ? ? ? ? ? ?unsigned InsertPosIndex) { > + ?// The code below assumes that there is at least one instruction, > + ?// so just duck out immediately if the block is empty. > + ?if (SUnits.empty()) return 0; > + > + ?// Find the node at the bottom of the critical path. > + ?SUnit *Max = 0; > + ?for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { > + ? ?SUnit *SU = &SUnits[i]; > + ? ?if (!Max || SU->getDepth() + SU->Latency > Max->getDepth() + Max->Latency) > + ? ? ?Max = SU; > + ?} > + > +#ifndef NDEBUG > + ?{ > + ? ?DEBUG(errs() << "Critical path has total latency " > + ? ? ? ? ?<< (Max->getDepth() + Max->Latency) << "\n"); > + ? ?DEBUG(errs() << "Available regs:"); > + ? ?for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { > + ? ? ?if (KillIndices[Reg] == ~0u) > + ? ? ? ?DEBUG(errs() << " " << TRI->getName(Reg)); > + ? ?} > + ? ?DEBUG(errs() << '\n'); > + ?} > +#endif > + > + ?// Track progress along the critical path through the SUnit graph as we walk > + ?// the instructions. > + ?SUnit *CriticalPathSU = Max; > + ?MachineInstr *CriticalPathMI = CriticalPathSU->getInstr(); > + > + ?// Consider this pattern: > + ?// ? A = ... > + ?// ? ... = A > + ?// ? A = ... > + ?// ? ... = A > + ?// ? A = ... > + ?// ? ... = A > + ?// ? A = ... > + ?// ? ... = A > + ?// There are three anti-dependencies here, and without special care, > + ?// we'd break all of them using the same register: > + ?// ? A = ... > + ?// ? ... = A > + ?// ? B = ... > + ?// ? ... = B > + ?// ? B = ... > + ?// ? ... = B > + ?// ? B = ... > + ?// ? ... = B > + ?// because at each anti-dependence, B is the first register that > + ?// isn't A which is free. ?This re-introduces anti-dependencies > + ?// at all but one of the original anti-dependencies that we were > + ?// trying to break. ?To avoid this, keep track of the most recent > + ?// register that each register was replaced with, avoid > + ?// using it to repair an anti-dependence on the same register. > + ?// This lets us produce this: > + ?// ? A = ... > + ?// ? ... = A > + ?// ? B = ... > + ?// ? ... = B > + ?// ? C = ... > + ?// ? ... = C > + ?// ? B = ... > + ?// ? ... = B > + ?// This still has an anti-dependence on B, but at least it isn't on the > + ?// original critical path. > + ?// > + ?// TODO: If we tracked more than one register here, we could potentially > + ?// fix that remaining critical edge too. This is a little more involved, > + ?// because unlike the most recent register, less recent registers should > + ?// still be considered, though only if no other registers are available. > + ?unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = {}; > + > + ?// Attempt to break anti-dependence edges on the critical path. Walk the > + ?// instructions from the bottom up, tracking information about liveness > + ?// as we go to help determine which registers are available. > + ?unsigned Broken = 0; > + ?unsigned Count = InsertPosIndex - 1; > + ?for (MachineBasicBlock::iterator I = End, E = Begin; > + ? ? ? I != E; --Count) { > + ? ?MachineInstr *MI = --I; > + > + ? ?// Check if this instruction has a dependence on the critical path that > + ? ?// is an anti-dependence that we may be able to break. If it is, set > + ? ?// AntiDepReg to the non-zero register associated with the anti-dependence. > + ? ?// > + ? ?// We limit our attention to the critical path as a heuristic to avoid > + ? ?// breaking anti-dependence edges that aren't going to significantly > + ? ?// impact the overall schedule. There are a limited number of registers > + ? ?// and we want to save them for the important edges. > + ? ?// > + ? ?// TODO: Instructions with multiple defs could have multiple > + ? ?// anti-dependencies. The current code here only knows how to break one > + ? ?// edge per instruction. Note that we'd have to be able to break all of > + ? ?// the anti-dependencies in an instruction in order to be effective. > + ? ?unsigned AntiDepReg = 0; > + ? ?if (MI == CriticalPathMI) { > + ? ? ?if (SDep *Edge = CriticalPathStep(CriticalPathSU)) { > + ? ? ? ?SUnit *NextSU = Edge->getSUnit(); > + > + ? ? ? ?// Only consider anti-dependence edges. > + ? ? ? ?if (Edge->getKind() == SDep::Anti) { > + ? ? ? ? ?AntiDepReg = Edge->getReg(); > + ? ? ? ? ?assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); > + ? ? ? ? ?if (!AllocatableSet.test(AntiDepReg)) > + ? ? ? ? ? ?// Don't break anti-dependencies on non-allocatable registers. > + ? ? ? ? ? ?AntiDepReg = 0; > + ? ? ? ? ?else if (KeepRegs.count(AntiDepReg)) > + ? ? ? ? ? ?// Don't break anti-dependencies if an use down below requires > + ? ? ? ? ? ?// this exact register. > + ? ? ? ? ? ?AntiDepReg = 0; > + ? ? ? ? ?else { > + ? ? ? ? ? ?// If the SUnit has other dependencies on the SUnit that it > + ? ? ? ? ? ?// anti-depends on, don't bother breaking the anti-dependency > + ? ? ? ? ? ?// since those edges would prevent such units from being > + ? ? ? ? ? ?// scheduled past each other regardless. > + ? ? ? ? ? ?// > + ? ? ? ? ? ?// Also, if there are dependencies on other SUnits with the > + ? ? ? ? ? ?// same register as the anti-dependency, don't attempt to > + ? ? ? ? ? ?// break it. > + ? ? ? ? ? ?for (SUnit::pred_iterator P = CriticalPathSU->Preds.begin(), > + ? ? ? ? ? ? ? ? PE = CriticalPathSU->Preds.end(); P != PE; ++P) > + ? ? ? ? ? ? ?if (P->getSUnit() == NextSU ? > + ? ? ? ? ? ? ? ? ? ?(P->getKind() != SDep::Anti || P->getReg() != AntiDepReg) : > + ? ? ? ? ? ? ? ? ? ?(P->getKind() == SDep::Data && P->getReg() == AntiDepReg)) { > + ? ? ? ? ? ? ? ?AntiDepReg = 0; > + ? ? ? ? ? ? ? ?break; > + ? ? ? ? ? ? ?} > + ? ? ? ? ?} > + ? ? ? ?} > + ? ? ? ?CriticalPathSU = NextSU; > + ? ? ? ?CriticalPathMI = CriticalPathSU->getInstr(); > + ? ? ?} else { > + ? ? ? ?// We've reached the end of the critical path. > + ? ? ? ?CriticalPathSU = 0; > + ? ? ? ?CriticalPathMI = 0; > + ? ? ?} > + ? ?} > + > + ? ?PrescanInstruction(MI); > + > + ? ?if (MI->getDesc().hasExtraDefRegAllocReq()) > + ? ? ?// If this instruction's defs have special allocation requirement, don't > + ? ? ?// break this anti-dependency. > + ? ? ?AntiDepReg = 0; > + ? ?else if (AntiDepReg) { > + ? ? ?// If this instruction has a use of AntiDepReg, breaking it > + ? ? ?// is invalid. > + ? ? ?for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > + ? ? ? ?MachineOperand &MO = MI->getOperand(i); > + ? ? ? ?if (!MO.isReg()) continue; > + ? ? ? ?unsigned Reg = MO.getReg(); > + ? ? ? ?if (Reg == 0) continue; > + ? ? ? ?if (MO.isUse() && AntiDepReg == Reg) { > + ? ? ? ? ?AntiDepReg = 0; > + ? ? ? ? ?break; > + ? ? ? ?} > + ? ? ?} > + ? ?} > + > + ? ?// Determine AntiDepReg's register class, if it is live and is > + ? ?// consistently used within a single class. > + ? ?const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes[AntiDepReg] : 0; > + ? ?assert((AntiDepReg == 0 || RC != NULL) && > + ? ? ? ? ? "Register should be live if it's causing an anti-dependence!"); > + ? ?if (RC == reinterpret_cast(-1)) > + ? ? ?AntiDepReg = 0; > + > + ? ?// Look for a suitable register to use to break the anti-depenence. > + ? ?// > + ? ?// TODO: Instead of picking the first free register, consider which might > + ? ?// be the best. > + ? ?if (AntiDepReg != 0) { > + ? ? ?if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LastNewReg[AntiDepReg], > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? RC)) { > + ? ? ? ?DEBUG(errs() << "Breaking anti-dependence edge on " > + ? ? ? ? ? ? ?<< TRI->getName(AntiDepReg) > + ? ? ? ? ? ? ?<< " with " << RegRefs.count(AntiDepReg) << " references" > + ? ? ? ? ? ? ?<< " using " << TRI->getName(NewReg) << "!\n"); > + > + ? ? ? ?// Update the references to the old register to refer to the new > + ? ? ? ?// register. > + ? ? ? ?std::pair::iterator, > + ? ? ? ? ? ? ? ? ?std::multimap::iterator> > + ? ? ? ? ? Range = RegRefs.equal_range(AntiDepReg); > + ? ? ? ?for (std::multimap::iterator > + ? ? ? ? ? ? Q = Range.first, QE = Range.second; Q != QE; ++Q) > + ? ? ? ? ?Q->second->setReg(NewReg); > + > + ? ? ? ?// We just went back in time and modified history; the > + ? ? ? ?// liveness information for the anti-depenence reg is now > + ? ? ? ?// inconsistent. Set the state as if it were dead. > + ? ? ? ?Classes[NewReg] = Classes[AntiDepReg]; > + ? ? ? ?DefIndices[NewReg] = DefIndices[AntiDepReg]; > + ? ? ? ?KillIndices[NewReg] = KillIndices[AntiDepReg]; > + ? ? ? ?assert(((KillIndices[NewReg] == ~0u) != > + ? ? ? ? ? ? ? ?(DefIndices[NewReg] == ~0u)) && > + ? ? ? ? ? ? "Kill and Def maps aren't consistent for NewReg!"); > + > + ? ? ? ?Classes[AntiDepReg] = 0; > + ? ? ? ?DefIndices[AntiDepReg] = KillIndices[AntiDepReg]; > + ? ? ? ?KillIndices[AntiDepReg] = ~0u; > + ? ? ? ?assert(((KillIndices[AntiDepReg] == ~0u) != > + ? ? ? ? ? ? ? ?(DefIndices[AntiDepReg] == ~0u)) && > + ? ? ? ? ? ? "Kill and Def maps aren't consistent for AntiDepReg!"); > + > + ? ? ? ?RegRefs.erase(AntiDepReg); > + ? ? ? ?LastNewReg[AntiDepReg] = NewReg; > + ? ? ? ?++Broken; > + ? ? ?} > + ? ?} > + > + ? ?ScanInstruction(MI, Count); > + ?} > + > + ?return Broken; > +} > > Added: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h?rev=85127&view=auto > > ============================================================================== > --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h (added) > +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h Mon Oct 26 11:59:04 2009 > @@ -0,0 +1,95 @@ > +//=- llvm/CodeGen/CriticalAntiDepBreaker.h - Anti-Dep Support -*- C++ -*-=// > +// > +// ? ? ? ? ? ? ? ? ? ? The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > +// > +// This file implements the CriticalAntiDepBreaker class, which > +// implements register anti-dependence breaking along a blocks > +// critical path during post-RA scheduler. > +// > +//===----------------------------------------------------------------------===// > + > +#ifndef LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H > +#define LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H > + > +#include "llvm/CodeGen/AntiDepBreaker.h" > +#include "llvm/CodeGen/MachineBasicBlock.h" > +#include "llvm/CodeGen/MachineFrameInfo.h" > +#include "llvm/CodeGen/MachineFunction.h" > +#include "llvm/CodeGen/MachineRegisterInfo.h" > +#include "llvm/CodeGen/ScheduleDAG.h" > +#include "llvm/Target/TargetRegisterInfo.h" > +#include "llvm/ADT/BitVector.h" > +#include "llvm/ADT/SmallSet.h" > + > +namespace llvm { > + ?class CriticalAntiDepBreaker : public AntiDepBreaker { > + ? ?MachineFunction& MF; > + ? ?MachineRegisterInfo &MRI; > + ? ?const TargetRegisterInfo *TRI; > + > + ? ?/// AllocatableSet - The set of allocatable registers. > + ? ?/// We'll be ignoring anti-dependencies on non-allocatable registers, > + ? ?/// because they may not be safe to break. > + ? ?const BitVector AllocatableSet; > + > + ? ?/// Classes - For live regs that are only used in one register class in a > + ? ?/// live range, the register class. If the register is not live, the > + ? ?/// corresponding value is null. If the register is live but used in > + ? ?/// multiple register classes, the corresponding value is -1 casted to a > + ? ?/// pointer. > + ? ?const TargetRegisterClass * > + ? ? ?Classes[TargetRegisterInfo::FirstVirtualRegister]; > + > + ? ?/// RegRegs - Map registers to all their references within a live range. > + ? ?std::multimap RegRefs; > + > + ? ?/// KillIndices - The index of the most recent kill (proceding bottom-up), > + ? ?/// or ~0u if the register is not live. > + ? ?unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; > + > + ? ?/// DefIndices - The index of the most recent complete def (proceding bottom > + ? ?/// up), or ~0u if the register is live. > + ? ?unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; > + > + ? ?/// KeepRegs - A set of registers which are live and cannot be changed to > + ? ?/// break anti-dependencies. > + ? ?SmallSet KeepRegs; > + > + ?public: > + ? ?CriticalAntiDepBreaker(MachineFunction& MFi); > + ? ?~CriticalAntiDepBreaker(); > + > + ? ?/// Start - Initialize anti-dep breaking for a new basic block. > + ? ?void StartBlock(MachineBasicBlock *BB); > + > + ? ?/// BreakAntiDependencies - Identifiy anti-dependencies along the critical path > + ? ?/// of the ScheduleDAG and break them by renaming registers. > + ? ?/// > + ? ?unsigned BreakAntiDependencies(std::vector& SUnits, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MachineBasicBlock::iterator& Begin, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MachineBasicBlock::iterator& End, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned InsertPosIndex); > + > + ? ?/// Observe - Update liveness information to account for the current > + ? ?/// instruction, which will not be scheduled. > + ? ?/// > + ? ?void Observe(MachineInstr *MI, unsigned Count, unsigned InsertPosIndex); > + > + ? ?/// Finish - Finish anti-dep breaking for a basic block. > + ? ?void FinishBlock(); > + > + ?private: > + ? ?void PrescanInstruction(MachineInstr *MI); > + ? ?void ScanInstruction(MachineInstr *MI, unsigned Count); > + ? ?unsigned findSuitableFreeRegister(unsigned AntiDepReg, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned LastNewReg, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const TargetRegisterClass *); > + ?}; > +} > + > +#endif > > Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=85127&r1=85126&r2=85127&view=diff > > ============================================================================== > --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) > +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Mon Oct 26 11:59:04 2009 > @@ -19,6 +19,7 @@ > ?//===----------------------------------------------------------------------===// > > ?#define DEBUG_TYPE "post-RA-sched" > +#include "CriticalAntiDepBreaker.h" > ?#include "ExactHazardRecognizer.h" > ?#include "SimpleHazardRecognizer.h" > ?#include "ScheduleDAGInstrs.h" > @@ -40,6 +41,7 @@ > ?#include "llvm/Support/Debug.h" > ?#include "llvm/Support/ErrorHandling.h" > ?#include "llvm/Support/raw_ostream.h" > +#include "llvm/ADT/BitVector.h" > ?#include "llvm/ADT/Statistic.h" > ?#include > ?#include > @@ -47,6 +49,7 @@ > > ?STATISTIC(NumNoops, "Number of noops inserted"); > ?STATISTIC(NumStalls, "Number of pipeline stalls"); > +STATISTIC(NumFixedAnti, "Number of fixed anti-dependencies"); > > ?// Post-RA scheduling is enabled with > ?// TargetSubtarget.enablePostRAScheduler(). This flag can be used to > @@ -55,10 +58,11 @@ > ?EnablePostRAScheduler("post-RA-scheduler", > ? ? ? ? ? ? ? ? ? ? ? ?cl::desc("Enable scheduling after register allocation"), > ? ? ? ? ? ? ? ? ? ? ? ?cl::init(false), cl::Hidden); > -static cl::opt > +static cl::opt > ?EnableAntiDepBreaking("break-anti-dependencies", > - ? ? ? ? ? ? ? ? ? ? ?cl::desc("Break post-RA scheduling anti-dependencies"), > - ? ? ? ? ? ? ? ? ? ? ?cl::init(true), cl::Hidden); > + ? ? ? ? ? ? ? ? ? ? ?cl::desc("Break post-RA scheduling anti-dependencies: " > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "\"critical\", \"all\", or \"none\""), > + ? ? ? ? ? ? ? ? ? ? ?cl::init("none"), cl::Hidden); > ?static cl::opt > ?EnablePostRAHazardAvoidance("avoid-hazards", > ? ? ? ? ? ? ? ? ? ? ? cl::desc("Enable exact hazard avoidance"), > @@ -116,56 +120,30 @@ > ? ? /// Topo - A topological ordering for SUnits. > ? ? ScheduleDAGTopologicalSort Topo; > > - ? ?/// AllocatableSet - The set of allocatable registers. > - ? ?/// We'll be ignoring anti-dependencies on non-allocatable registers, > - ? ?/// because they may not be safe to break. > - ? ?const BitVector AllocatableSet; > - > ? ? /// HazardRec - The hazard recognizer to use. > ? ? ScheduleHazardRecognizer *HazardRec; > > + ? ?/// AntiDepBreak - Anti-dependence breaking object, or NULL if none > + ? ?AntiDepBreaker *AntiDepBreak; > + > ? ? /// AA - AliasAnalysis for making memory reference queries. > ? ? AliasAnalysis *AA; > > - ? ?/// AntiDepMode - Anti-dependence breaking mode > - ? ?TargetSubtarget::AntiDepBreakMode AntiDepMode; > - > - ? ?/// Classes - For live regs that are only used in one register class in a > - ? ?/// live range, the register class. If the register is not live, the > - ? ?/// corresponding value is null. If the register is live but used in > - ? ?/// multiple register classes, the corresponding value is -1 casted to a > - ? ?/// pointer. > - ? ?const TargetRegisterClass * > - ? ? ?Classes[TargetRegisterInfo::FirstVirtualRegister]; > - > - ? ?/// RegRegs - Map registers to all their references within a live range. > - ? ?std::multimap RegRefs; > - > ? ? /// KillIndices - The index of the most recent kill (proceding bottom-up), > ? ? /// or ~0u if the register is not live. > ? ? unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister]; > > - ? ?/// DefIndices - The index of the most recent complete def (proceding bottom > - ? ?/// up), or ~0u if the register is live. > - ? ?unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister]; > - > - ? ?/// KeepRegs - A set of registers which are live and cannot be changed to > - ? ?/// break anti-dependencies. > - ? ?SmallSet KeepRegs; > - > ? public: > ? ? SchedulePostRATDList(MachineFunction &MF, > ? ? ? ? ? ? ? ? ? ? ? ? ?const MachineLoopInfo &MLI, > ? ? ? ? ? ? ? ? ? ? ? ? ?const MachineDominatorTree &MDT, > ? ? ? ? ? ? ? ? ? ? ? ? ?ScheduleHazardRecognizer *HR, > - ? ? ? ? ? ? ? ? ? ? ? ? AliasAnalysis *aa, > - ? ? ? ? ? ? ? ? ? ? ? ? TargetSubtarget::AntiDepBreakMode adm) > + ? ? ? ? ? ? ? ? ? ? ? ? AntiDepBreaker *ADB, > + ? ? ? ? ? ? ? ? ? ? ? ? AliasAnalysis *aa) > ? ? ? : ScheduleDAGInstrs(MF, MLI, MDT), Topo(SUnits), > - ? ? ? ?AllocatableSet(TRI->getAllocatableSet(MF)), > - ? ? ?HazardRec(HR), AA(aa), AntiDepMode(adm) {} > + ? ? ?HazardRec(HR), AntiDepBreak(ADB), AA(aa) {} > > ? ? ~SchedulePostRATDList() { > - ? ? ?delete HazardRec; > ? ? } > > ? ? /// StartBlock - Initialize register live-range state for scheduling in > @@ -177,11 +155,6 @@ > ? ? /// > ? ? void Schedule(); > > - ? ?/// FixupKills - Fix register kill flags that have been made > - ? ?/// invalid due to scheduling > - ? ?/// > - ? ?void FixupKills(MachineBasicBlock *MBB); > - > ? ? /// Observe - Update liveness information to account for the current > ? ? /// instruction, which will not be scheduled. > ? ? /// > @@ -191,17 +164,16 @@ > ? ? /// > ? ? void FinishBlock(); > > + ? ?/// FixupKills - Fix register kill flags that have been made > + ? ?/// invalid due to scheduling > + ? ?/// > + ? ?void FixupKills(MachineBasicBlock *MBB); > + > ? private: > - ? ?void PrescanInstruction(MachineInstr *MI); > - ? ?void ScanInstruction(MachineInstr *MI, unsigned Count); > ? ? void ReleaseSucc(SUnit *SU, SDep *SuccEdge); > ? ? void ReleaseSuccessors(SUnit *SU); > ? ? void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); > ? ? void ListScheduleTopDown(); > - ? ?bool BreakAntiDependencies(); > - ? ?unsigned findSuitableFreeRegister(unsigned AntiDepReg, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned LastNewReg, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const TargetRegisterClass *); > ? ? void StartBlockForKills(MachineBasicBlock *BB); > > ? ? // ToggleKillFlag - Toggle a register operand kill flag. Other > @@ -250,8 +222,9 @@ > > ? // Check for antidep breaking override... > ? if (EnableAntiDepBreaking.getPosition() > 0) { > - ? ?AntiDepMode = (EnableAntiDepBreaking) ? > - ? ? ?TargetSubtarget::ANTIDEP_CRITICAL : TargetSubtarget::ANTIDEP_NONE; > + ? ?AntiDepMode = (EnableAntiDepBreaking == "all") ? TargetSubtarget::ANTIDEP_ALL : > + ? ? ?(EnableAntiDepBreaking == "critical") ? TargetSubtarget::ANTIDEP_CRITICAL : > + ? ? ?TargetSubtarget::ANTIDEP_NONE; > ? } > > ? DEBUG(errs() << "PostRAScheduler\n"); > @@ -262,8 +235,12 @@ > ? ScheduleHazardRecognizer *HR = EnablePostRAHazardAvoidance ? > ? ? (ScheduleHazardRecognizer *)new ExactHazardRecognizer(InstrItins) : > ? ? (ScheduleHazardRecognizer *)new SimpleHazardRecognizer(); > + ?AntiDepBreaker *ADB = > + ? ?(AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? NULL /* FIXME */ : > + ? ?(AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ? > + ? ?new CriticalAntiDepBreaker(Fn) : NULL; > > - ?SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, AA, AntiDepMode); > + ?SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, ADB, AA); > > ? // Loop over all of the basic blocks > ? for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); > @@ -311,6 +288,9 @@ > ? ? Scheduler.FixupKills(MBB); > ? } > > + ?delete HR; > + ?delete ADB; > + > ? return true; > ?} > > @@ -321,78 +301,10 @@ > ? // Call the superclass. > ? ScheduleDAGInstrs::StartBlock(BB); > > - ?// Reset the hazard recognizer. > + ?// Reset the hazard recognizer and anti-dep breaker. > ? HazardRec->Reset(); > - > - ?// Clear out the register class data. > - ?std::fill(Classes, array_endof(Classes), > - ? ? ? ? ? ?static_cast(0)); > - > - ?// Initialize the indices to indicate that no registers are live. > - ?std::fill(KillIndices, array_endof(KillIndices), ~0u); > - ?std::fill(DefIndices, array_endof(DefIndices), BB->size()); > - > - ?// Clear "do not change" set. > - ?KeepRegs.clear(); > - > - ?bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn()); > - > - ?// Determine the live-out physregs for this block. > - ?if (IsReturnBlock) { > - ? ?// In a return block, examine the function live-out regs. > - ? ?for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(), > - ? ? ? ? E = MRI.liveout_end(); I != E; ++I) { > - ? ? ?unsigned Reg = *I; > - ? ? ?Classes[Reg] = reinterpret_cast(-1); > - ? ? ?KillIndices[Reg] = BB->size(); > - ? ? ?DefIndices[Reg] = ~0u; > - ? ? ?// Repeat, for all aliases. > - ? ? ?for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > - ? ? ? ?unsigned AliasReg = *Alias; > - ? ? ? ?Classes[AliasReg] = reinterpret_cast(-1); > - ? ? ? ?KillIndices[AliasReg] = BB->size(); > - ? ? ? ?DefIndices[AliasReg] = ~0u; > - ? ? ?} > - ? ?} > - ?} else { > - ? ?// In a non-return block, examine the live-in regs of all successors. > - ? ?for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), > - ? ? ? ? SE = BB->succ_end(); SI != SE; ++SI) > - ? ? ?for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(), > - ? ? ? ? ? E = (*SI)->livein_end(); I != E; ++I) { > - ? ? ? ?unsigned Reg = *I; > - ? ? ? ?Classes[Reg] = reinterpret_cast(-1); > - ? ? ? ?KillIndices[Reg] = BB->size(); > - ? ? ? ?DefIndices[Reg] = ~0u; > - ? ? ? ?// Repeat, for all aliases. > - ? ? ? ?for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > - ? ? ? ? ?unsigned AliasReg = *Alias; > - ? ? ? ? ?Classes[AliasReg] = reinterpret_cast(-1); > - ? ? ? ? ?KillIndices[AliasReg] = BB->size(); > - ? ? ? ? ?DefIndices[AliasReg] = ~0u; > - ? ? ? ?} > - ? ? ?} > - ?} > - > - ?// Mark live-out callee-saved registers. In a return block this is > - ?// all callee-saved registers. In non-return this is any > - ?// callee-saved register that is not saved in the prolog. > - ?const MachineFrameInfo *MFI = MF.getFrameInfo(); > - ?BitVector Pristine = MFI->getPristineRegs(BB); > - ?for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { > - ? ?unsigned Reg = *I; > - ? ?if (!IsReturnBlock && !Pristine.test(Reg)) continue; > - ? ?Classes[Reg] = reinterpret_cast(-1); > - ? ?KillIndices[Reg] = BB->size(); > - ? ?DefIndices[Reg] = ~0u; > - ? ?// Repeat, for all aliases. > - ? ?for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > - ? ? ?unsigned AliasReg = *Alias; > - ? ? ?Classes[AliasReg] = reinterpret_cast(-1); > - ? ? ?KillIndices[AliasReg] = BB->size(); > - ? ? ?DefIndices[AliasReg] = ~0u; > - ? ?} > - ?} > + ?if (AntiDepBreak != NULL) > + ? ?AntiDepBreak->StartBlock(BB); > ?} > > ?/// Schedule - Schedule the instruction range using list scheduling. > @@ -403,8 +315,11 @@ > ? // Build the scheduling graph. > ? BuildSchedGraph(AA); > > - ?if (AntiDepMode != TargetSubtarget::ANTIDEP_NONE) { > - ? ?if (BreakAntiDependencies()) { > + ?if (AntiDepBreak != NULL) { > + ? ?unsigned Broken = > + ? ? ?AntiDepBreak->BreakAntiDependencies(SUnits, Begin, InsertPos, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?InsertPosIndex); > + ? ?if (Broken > 0) { > ? ? ? // We made changes. Update the dependency graph. > ? ? ? // Theoretically we could update the graph in place: > ? ? ? // When a live range is changed to use a different register, remove > @@ -415,6 +330,8 @@ > ? ? ? EntrySU = SUnit(); > ? ? ? ExitSU = SUnit(); > ? ? ? BuildSchedGraph(AA); > + > + ? ? ?NumFixedAnti += Broken; > ? ? } > ? } > > @@ -432,436 +349,20 @@ > ?/// instruction, which will not be scheduled. > ?/// > ?void SchedulePostRATDList::Observe(MachineInstr *MI, unsigned Count) { > - ?assert(Count < InsertPosIndex && "Instruction index out of expected range!"); > - > - ?// Any register which was defined within the previous scheduling region > - ?// may have been rescheduled and its lifetime may overlap with registers > - ?// in ways not reflected in our current liveness state. For each such > - ?// register, adjust the liveness state to be conservatively correct. > - ?for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg) > - ? ?if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) { > - ? ? ?assert(KillIndices[Reg] == ~0u && "Clobbered register is live!"); > - ? ? ?// Mark this register to be non-renamable. > - ? ? ?Classes[Reg] = reinterpret_cast(-1); > - ? ? ?// Move the def index to the end of the previous region, to reflect > - ? ? ?// that the def could theoretically have been scheduled at the end. > - ? ? ?DefIndices[Reg] = InsertPosIndex; > - ? ?} > - > - ?PrescanInstruction(MI); > - ?ScanInstruction(MI, Count); > + ?if (AntiDepBreak != NULL) > + ? ?AntiDepBreak->Observe(MI, Count, InsertPosIndex); > ?} > > ?/// FinishBlock - Clean up register live-range state. > ?/// > ?void SchedulePostRATDList::FinishBlock() { > - ?RegRefs.clear(); > + ?if (AntiDepBreak != NULL) > + ? ?AntiDepBreak->FinishBlock(); > > ? // Call the superclass. > ? ScheduleDAGInstrs::FinishBlock(); > ?} > > -/// CriticalPathStep - Return the next SUnit after SU on the bottom-up > -/// critical path. > -static SDep *CriticalPathStep(SUnit *SU) { > - ?SDep *Next = 0; > - ?unsigned NextDepth = 0; > - ?// Find the predecessor edge with the greatest depth. > - ?for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end(); > - ? ? ? P != PE; ++P) { > - ? ?SUnit *PredSU = P->getSUnit(); > - ? ?unsigned PredLatency = P->getLatency(); > - ? ?unsigned PredTotalLatency = PredSU->getDepth() + PredLatency; > - ? ?// In the case of a latency tie, prefer an anti-dependency edge over > - ? ?// other types of edges. > - ? ?if (NextDepth < PredTotalLatency || > - ? ? ? ?(NextDepth == PredTotalLatency && P->getKind() == SDep::Anti)) { > - ? ? ?NextDepth = PredTotalLatency; > - ? ? ?Next = &*P; > - ? ?} > - ?} > - ?return Next; > -} > - > -void SchedulePostRATDList::PrescanInstruction(MachineInstr *MI) { > - ?// Scan the register operands for this instruction and update > - ?// Classes and RegRefs. > - ?for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > - ? ?MachineOperand &MO = MI->getOperand(i); > - ? ?if (!MO.isReg()) continue; > - ? ?unsigned Reg = MO.getReg(); > - ? ?if (Reg == 0) continue; > - ? ?const TargetRegisterClass *NewRC = 0; > - > - ? ?if (i < MI->getDesc().getNumOperands()) > - ? ? ?NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); > - > - ? ?// For now, only allow the register to be changed if its register > - ? ?// class is consistent across all uses. > - ? ?if (!Classes[Reg] && NewRC) > - ? ? ?Classes[Reg] = NewRC; > - ? ?else if (!NewRC || Classes[Reg] != NewRC) > - ? ? ?Classes[Reg] = reinterpret_cast(-1); > - > - ? ?// Now check for aliases. > - ? ?for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > - ? ? ?// If an alias of the reg is used during the live range, give up. > - ? ? ?// Note that this allows us to skip checking if AntiDepReg > - ? ? ?// overlaps with any of the aliases, among other things. > - ? ? ?unsigned AliasReg = *Alias; > - ? ? ?if (Classes[AliasReg]) { > - ? ? ? ?Classes[AliasReg] = reinterpret_cast(-1); > - ? ? ? ?Classes[Reg] = reinterpret_cast(-1); > - ? ? ?} > - ? ?} > - > - ? ?// If we're still willing to consider this register, note the reference. > - ? ?if (Classes[Reg] != reinterpret_cast(-1)) > - ? ? ?RegRefs.insert(std::make_pair(Reg, &MO)); > - > - ? ?// It's not safe to change register allocation for source operands of > - ? ?// that have special allocation requirements. > - ? ?if (MO.isUse() && MI->getDesc().hasExtraSrcRegAllocReq()) { > - ? ? ?if (KeepRegs.insert(Reg)) { > - ? ? ? ?for (const unsigned *Subreg = TRI->getSubRegisters(Reg); > - ? ? ? ? ? ? *Subreg; ++Subreg) > - ? ? ? ? ?KeepRegs.insert(*Subreg); > - ? ? ?} > - ? ?} > - ?} > -} > - > -void SchedulePostRATDList::ScanInstruction(MachineInstr *MI, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned Count) { > - ?// Update liveness. > - ?// Proceding upwards, registers that are defed but not used in this > - ?// instruction are now dead. > - ?for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > - ? ?MachineOperand &MO = MI->getOperand(i); > - ? ?if (!MO.isReg()) continue; > - ? ?unsigned Reg = MO.getReg(); > - ? ?if (Reg == 0) continue; > - ? ?if (!MO.isDef()) continue; > - ? ?// Ignore two-addr defs. > - ? ?if (MI->isRegTiedToUseOperand(i)) continue; > - > - ? ?DefIndices[Reg] = Count; > - ? ?KillIndices[Reg] = ~0u; > - ? ?assert(((KillIndices[Reg] == ~0u) != > - ? ? ? ? ? ?(DefIndices[Reg] == ~0u)) && > - ? ? ? ? ? "Kill and Def maps aren't consistent for Reg!"); > - ? ?KeepRegs.erase(Reg); > - ? ?Classes[Reg] = 0; > - ? ?RegRefs.erase(Reg); > - ? ?// Repeat, for all subregs. > - ? ?for (const unsigned *Subreg = TRI->getSubRegisters(Reg); > - ? ? ? ? *Subreg; ++Subreg) { > - ? ? ?unsigned SubregReg = *Subreg; > - ? ? ?DefIndices[SubregReg] = Count; > - ? ? ?KillIndices[SubregReg] = ~0u; > - ? ? ?KeepRegs.erase(SubregReg); > - ? ? ?Classes[SubregReg] = 0; > - ? ? ?RegRefs.erase(SubregReg); > - ? ?} > - ? ?// Conservatively mark super-registers as unusable. > - ? ?for (const unsigned *Super = TRI->getSuperRegisters(Reg); > - ? ? ? ? *Super; ++Super) { > - ? ? ?unsigned SuperReg = *Super; > - ? ? ?Classes[SuperReg] = reinterpret_cast(-1); > - ? ?} > - ?} > - ?for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > - ? ?MachineOperand &MO = MI->getOperand(i); > - ? ?if (!MO.isReg()) continue; > - ? ?unsigned Reg = MO.getReg(); > - ? ?if (Reg == 0) continue; > - ? ?if (!MO.isUse()) continue; > - > - ? ?const TargetRegisterClass *NewRC = 0; > - ? ?if (i < MI->getDesc().getNumOperands()) > - ? ? ?NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI); > - > - ? ?// For now, only allow the register to be changed if its register > - ? ?// class is consistent across all uses. > - ? ?if (!Classes[Reg] && NewRC) > - ? ? ?Classes[Reg] = NewRC; > - ? ?else if (!NewRC || Classes[Reg] != NewRC) > - ? ? ?Classes[Reg] = reinterpret_cast(-1); > - > - ? ?RegRefs.insert(std::make_pair(Reg, &MO)); > - > - ? ?// It wasn't previously live but now it is, this is a kill. > - ? ?if (KillIndices[Reg] == ~0u) { > - ? ? ?KillIndices[Reg] = Count; > - ? ? ?DefIndices[Reg] = ~0u; > - ? ? ? ? ?assert(((KillIndices[Reg] == ~0u) != > - ? ? ? ? ? ? ? ? ?(DefIndices[Reg] == ~0u)) && > - ? ? ? ? ? ? ? "Kill and Def maps aren't consistent for Reg!"); > - ? ?} > - ? ?// Repeat, for all aliases. > - ? ?for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { > - ? ? ?unsigned AliasReg = *Alias; > - ? ? ?if (KillIndices[AliasReg] == ~0u) { > - ? ? ? ?KillIndices[AliasReg] = Count; > - ? ? ? ?DefIndices[AliasReg] = ~0u; > - ? ? ?} > - ? ?} > - ?} > -} > - > -unsigned > -SchedulePostRATDList::findSuitableFreeRegister(unsigned AntiDepReg, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned LastNewReg, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const TargetRegisterClass *RC) { > - ?for (TargetRegisterClass::iterator R = RC->allocation_order_begin(MF), > - ? ? ? RE = RC->allocation_order_end(MF); R != RE; ++R) { > - ? ?unsigned NewReg = *R; > - ? ?// Don't replace a register with itself. > - ? ?if (NewReg == AntiDepReg) continue; > - ? ?// Don't replace a register with one that was recently used to repair > - ? ?// an anti-dependence with this AntiDepReg, because that would > - ? ?// re-introduce that anti-dependence. > - ? ?if (NewReg == LastNewReg) continue; > - ? ?// If NewReg is dead and NewReg's most recent def is not before > - ? ?// AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg. > - ? ?assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u)) && > - ? ? ? ? ? "Kill and Def maps aren't consistent for AntiDepReg!"); > - ? ?assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u)) && > - ? ? ? ? ? "Kill and Def maps aren't consistent for NewReg!"); > - ? ?if (KillIndices[NewReg] != ~0u || > - ? ? ? ?Classes[NewReg] == reinterpret_cast(-1) || > - ? ? ? ?KillIndices[AntiDepReg] > DefIndices[NewReg]) > - ? ? ?continue; > - ? ?return NewReg; > - ?} > - > - ?// No registers are free and available! > - ?return 0; > -} > - > -/// BreakAntiDependencies - Identifiy anti-dependencies along the critical path > -/// of the ScheduleDAG and break them by renaming registers. > -/// > -bool SchedulePostRATDList::BreakAntiDependencies() { > - ?// The code below assumes that there is at least one instruction, > - ?// so just duck out immediately if the block is empty. > - ?if (SUnits.empty()) return false; > - > - ?// Find the node at the bottom of the critical path. > - ?SUnit *Max = 0; > - ?for (unsigned i = 0, e = SUnits.size(); i != e; ++i) { > - ? ?SUnit *SU = &SUnits[i]; > - ? ?if (!Max || SU->getDepth() + SU->Latency > Max->getDepth() + Max->Latency) > - ? ? ?Max = SU; > - ?} > - > -#ifndef NDEBUG > - ?{ > - ? ?DEBUG(errs() << "Critical path has total latency " > - ? ? ? ? ?<< (Max->getDepth() + Max->Latency) << "\n"); > - ? ?DEBUG(errs() << "Available regs:"); > - ? ?for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) { > - ? ? ?if (KillIndices[Reg] == ~0u) > - ? ? ? ?DEBUG(errs() << " " << TRI->getName(Reg)); > - ? ?} > - ? ?DEBUG(errs() << '\n'); > - ?} > -#endif > - > - ?// Track progress along the critical path through the SUnit graph as we walk > - ?// the instructions. > - ?SUnit *CriticalPathSU = Max; > - ?MachineInstr *CriticalPathMI = CriticalPathSU->getInstr(); > - > - ?// Consider this pattern: > - ?// ? A = ... > - ?// ? ... = A > - ?// ? A = ... > - ?// ? ... = A > - ?// ? A = ... > - ?// ? ... = A > - ?// ? A = ... > - ?// ? ... = A > - ?// There are three anti-dependencies here, and without special care, > - ?// we'd break all of them using the same register: > - ?// ? A = ... > - ?// ? ... = A > - ?// ? B = ... > - ?// ? ... = B > - ?// ? B = ... > - ?// ? ... = B > - ?// ? B = ... > - ?// ? ... = B > - ?// because at each anti-dependence, B is the first register that > - ?// isn't A which is free. ?This re-introduces anti-dependencies > - ?// at all but one of the original anti-dependencies that we were > - ?// trying to break. ?To avoid this, keep track of the most recent > - ?// register that each register was replaced with, avoid > - ?// using it to repair an anti-dependence on the same register. > - ?// This lets us produce this: > - ?// ? A = ... > - ?// ? ... = A > - ?// ? B = ... > - ?// ? ... = B > - ?// ? C = ... > - ?// ? ... = C > - ?// ? B = ... > - ?// ? ... = B > - ?// This still has an anti-dependence on B, but at least it isn't on the > - ?// original critical path. > - ?// > - ?// TODO: If we tracked more than one register here, we could potentially > - ?// fix that remaining critical edge too. This is a little more involved, > - ?// because unlike the most recent register, less recent registers should > - ?// still be considered, though only if no other registers are available. > - ?unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = {}; > - > - ?// Attempt to break anti-dependence edges on the critical path. Walk the > - ?// instructions from the bottom up, tracking information about liveness > - ?// as we go to help determine which registers are available. > - ?bool Changed = false; > - ?unsigned Count = InsertPosIndex - 1; > - ?for (MachineBasicBlock::iterator I = InsertPos, E = Begin; > - ? ? ? I != E; --Count) { > - ? ?MachineInstr *MI = --I; > - > - ? ?// Check if this instruction has a dependence on the critical path that > - ? ?// is an anti-dependence that we may be able to break. If it is, set > - ? ?// AntiDepReg to the non-zero register associated with the anti-dependence. > - ? ?// > - ? ?// We limit our attention to the critical path as a heuristic to avoid > - ? ?// breaking anti-dependence edges that aren't going to significantly > - ? ?// impact the overall schedule. There are a limited number of registers > - ? ?// and we want to save them for the important edges. > - ? ?// > - ? ?// TODO: Instructions with multiple defs could have multiple > - ? ?// anti-dependencies. The current code here only knows how to break one > - ? ?// edge per instruction. Note that we'd have to be able to break all of > - ? ?// the anti-dependencies in an instruction in order to be effective. > - ? ?unsigned AntiDepReg = 0; > - ? ?if (MI == CriticalPathMI) { > - ? ? ?if (SDep *Edge = CriticalPathStep(CriticalPathSU)) { > - ? ? ? ?SUnit *NextSU = Edge->getSUnit(); > - > - ? ? ? ?// Only consider anti-dependence edges. > - ? ? ? ?if (Edge->getKind() == SDep::Anti) { > - ? ? ? ? ?AntiDepReg = Edge->getReg(); > - ? ? ? ? ?assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); > - ? ? ? ? ?if (!AllocatableSet.test(AntiDepReg)) > - ? ? ? ? ? ?// Don't break anti-dependencies on non-allocatable registers. > - ? ? ? ? ? ?AntiDepReg = 0; > - ? ? ? ? ?else if (KeepRegs.count(AntiDepReg)) > - ? ? ? ? ? ?// Don't break anti-dependencies if an use down below requires > - ? ? ? ? ? ?// this exact register. > - ? ? ? ? ? ?AntiDepReg = 0; > - ? ? ? ? ?else { > - ? ? ? ? ? ?// If the SUnit has other dependencies on the SUnit that it > - ? ? ? ? ? ?// anti-depends on, don't bother breaking the anti-dependency > - ? ? ? ? ? ?// since those edges would prevent such units from being > - ? ? ? ? ? ?// scheduled past each other regardless. > - ? ? ? ? ? ?// > - ? ? ? ? ? ?// Also, if there are dependencies on other SUnits with the > - ? ? ? ? ? ?// same register as the anti-dependency, don't attempt to > - ? ? ? ? ? ?// break it. > - ? ? ? ? ? ?for (SUnit::pred_iterator P = CriticalPathSU->Preds.begin(), > - ? ? ? ? ? ? ? ? PE = CriticalPathSU->Preds.end(); P != PE; ++P) > - ? ? ? ? ? ? ?if (P->getSUnit() == NextSU ? > - ? ? ? ? ? ? ? ? ? ?(P->getKind() != SDep::Anti || P->getReg() != AntiDepReg) : > - ? ? ? ? ? ? ? ? ? ?(P->getKind() == SDep::Data && P->getReg() == AntiDepReg)) { > - ? ? ? ? ? ? ? ?AntiDepReg = 0; > - ? ? ? ? ? ? ? ?break; > - ? ? ? ? ? ? ?} > - ? ? ? ? ?} > - ? ? ? ?} > - ? ? ? ?CriticalPathSU = NextSU; > - ? ? ? ?CriticalPathMI = CriticalPathSU->getInstr(); > - ? ? ?} else { > - ? ? ? ?// We've reached the end of the critical path. > - ? ? ? ?CriticalPathSU = 0; > - ? ? ? ?CriticalPathMI = 0; > - ? ? ?} > - ? ?} > - > - ? ?PrescanInstruction(MI); > - > - ? ?if (MI->getDesc().hasExtraDefRegAllocReq()) > - ? ? ?// If this instruction's defs have special allocation requirement, don't > - ? ? ?// break this anti-dependency. > - ? ? ?AntiDepReg = 0; > - ? ?else if (AntiDepReg) { > - ? ? ?// If this instruction has a use of AntiDepReg, breaking it > - ? ? ?// is invalid. > - ? ? ?for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { > - ? ? ? ?MachineOperand &MO = MI->getOperand(i); > - ? ? ? ?if (!MO.isReg()) continue; > - ? ? ? ?unsigned Reg = MO.getReg(); > - ? ? ? ?if (Reg == 0) continue; > - ? ? ? ?if (MO.isUse() && AntiDepReg == Reg) { > - ? ? ? ? ?AntiDepReg = 0; > - ? ? ? ? ?break; > - ? ? ? ?} > - ? ? ?} > - ? ?} > - > - ? ?// Determine AntiDepReg's register class, if it is live and is > - ? ?// consistently used within a single class. > - ? ?const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes[AntiDepReg] : 0; > - ? ?assert((AntiDepReg == 0 || RC != NULL) && > - ? ? ? ? ? "Register should be live if it's causing an anti-dependence!"); > - ? ?if (RC == reinterpret_cast(-1)) > - ? ? ?AntiDepReg = 0; > - > - ? ?// Look for a suitable register to use to break the anti-depenence. > - ? ?// > - ? ?// TODO: Instead of picking the first free register, consider which might > - ? ?// be the best. > - ? ?if (AntiDepReg != 0) { > - ? ? ?if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LastNewReg[AntiDepReg], > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? RC)) { > - ? ? ? ?DEBUG(errs() << "Breaking anti-dependence edge on " > - ? ? ? ? ? ? ?<< TRI->getName(AntiDepReg) > - ? ? ? ? ? ? ?<< " with " << RegRefs.count(AntiDepReg) << " references" > - ? ? ? ? ? ? ?<< " using " << TRI->getName(NewReg) << "!\n"); > - > - ? ? ? ?// Update the references to the old register to refer to the new > - ? ? ? ?// register. > - ? ? ? ?std::pair::iterator, > - ? ? ? ? ? ? ? ? ?std::multimap::iterator> > - ? ? ? ? ? Range = RegRefs.equal_range(AntiDepReg); > - ? ? ? ?for (std::multimap::iterator > - ? ? ? ? ? ? Q = Range.first, QE = Range.second; Q != QE; ++Q) > - ? ? ? ? ?Q->second->setReg(NewReg); > - > - ? ? ? ?// We just went back in time and modified history; the > - ? ? ? ?// liveness information for the anti-depenence reg is now > - ? ? ? ?// inconsistent. Set the state as if it were dead. > - ? ? ? ?Classes[NewReg] = Classes[AntiDepReg]; > - ? ? ? ?DefIndices[NewReg] = DefIndices[AntiDepReg]; > - ? ? ? ?KillIndices[NewReg] = KillIndices[AntiDepReg]; > - ? ? ? ?assert(((KillIndices[NewReg] == ~0u) != > - ? ? ? ? ? ? ? ?(DefIndices[NewReg] == ~0u)) && > - ? ? ? ? ? ? "Kill and Def maps aren't consistent for NewReg!"); > - > - ? ? ? ?Classes[AntiDepReg] = 0; > - ? ? ? ?DefIndices[AntiDepReg] = KillIndices[AntiDepReg]; > - ? ? ? ?KillIndices[AntiDepReg] = ~0u; > - ? ? ? ?assert(((KillIndices[AntiDepReg] == ~0u) != > - ? ? ? ? ? ? ? ?(DefIndices[AntiDepReg] == ~0u)) && > - ? ? ? ? ? ? "Kill and Def maps aren't consistent for AntiDepReg!"); > - > - ? ? ? ?RegRefs.erase(AntiDepReg); > - ? ? ? ?Changed = true; > - ? ? ? ?LastNewReg[AntiDepReg] = NewReg; > - ? ? ?} > - ? ?} > - > - ? ?ScanInstruction(MI, Count); > - ?} > - > - ?return Changed; > -} > - > ?/// StartBlockForKills - Initialize register live-range state for updating kills > ?/// > ?void SchedulePostRATDList::StartBlockForKills(MachineBasicBlock *BB) { > > Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=85127&r1=85126&r2=85127&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Mon Oct 26 11:59:04 2009 > @@ -130,7 +130,7 @@ > ? /// for Thumb1. > ? bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?TargetSubtarget::AntiDepBreakMode& mode) const { > - ? ?mode = TargetSubtarget::ANTIDEP_NONE; > + ? ?mode = TargetSubtarget::ANTIDEP_CRITICAL; > ? ? return PostRAScheduler && OptLevel >= CodeGenOpt::Default; > ? } > > > Modified: llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll?rev=85127&r1=85126&r2=85127&view=diff > > ============================================================================== > --- llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll (original) > +++ llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll Mon Oct 26 11:59:04 2009 > @@ -1,7 +1,7 @@ > -; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies=false > %t > +; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies=none > %t > ?; RUN: ? grep {%xmm0} %t | count 14 > ?; RUN: ? not grep {%xmm1} %t > -; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies > %t > +; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies=critical > %t > ?; RUN: ? grep {%xmm0} %t | count 7 > ?; RUN: ? grep {%xmm1} %t | count 7 > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From resistor at me.com Mon Oct 26 14:58:09 2009 From: resistor at me.com (Owen Anderson) Date: Mon, 26 Oct 2009 12:58:09 -0700 Subject: [llvm-commits] [llvm] r85144 - in /llvm/trunk: include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/GEPSplitter.cpp In-Reply-To: <200910261912.n9QJCE4a030428@zion.cs.uiuc.edu> References: <200910261912.n9QJCE4a030428@zion.cs.uiuc.edu> Message-ID: <83489F21-6E25-42FB-B136-84DDBE36BF0E@me.com> On Oct 26, 2009, at 12:12 PM, Dan Gohman wrote: > Author: djg > Date: Mon Oct 26 14:12:14 2009 > New Revision: 85144 > > URL: http://llvm.org/viewvc/llvm-project?rev=85144&view=rev > Log: > Check in the experimental GEP splitter pass. This pass splits complex > GEPs (more than one non-zero index) into simple GEPs (at most one > non-zero index). In some simple experiments using this it's not > uncommon to see 3% overall code size wins, because it exposes > redundancies that can be eliminated, however it's tricky to use > because instcombine aggressively undoes the work that this pass does. > How about running it right before GVN, and letting a later instcombine pass clean it up? --Owen > Added: > llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp > Modified: > llvm/trunk/include/llvm/LinkAllPasses.h > llvm/trunk/include/llvm/Transforms/Scalar.h > > Modified: llvm/trunk/include/llvm/LinkAllPasses.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=85144&r1=85143&r2=85144&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/LinkAllPasses.h (original) > +++ llvm/trunk/include/llvm/LinkAllPasses.h Mon Oct 26 14:12:14 2009 > @@ -141,6 +141,7 @@ > (void) llvm::createPartialInliningPass(); > (void) llvm::createSSIPass(); > (void) llvm::createSSIEverythingPass(); > + (void) llvm::createGEPSplitterPass(); > > (void)new llvm::IntervalPartition(); > (void)new llvm::FindUsedTypes(); > > Modified: llvm/trunk/include/llvm/Transforms/Scalar.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=85144&r1=85143&r2=85144&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/Transforms/Scalar.h (original) > +++ llvm/trunk/include/llvm/Transforms/Scalar.h Mon Oct 26 14:12:14 > 2009 > @@ -341,6 +341,12 @@ > // > FunctionPass *createSSIEverythingPass(); > > +// > = > = > = > ----------------------------------------------------------------------= > ==// > +// > +// GEPSplitter - Split complex GEPs into simple ones > +// > +FunctionPass *createGEPSplitterPass(); > + > } // End llvm namespace > > #endif > > Added: llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp?rev=85144&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp (added) > +++ llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp Mon Oct 26 > 14:12:14 2009 > @@ -0,0 +1,81 @@ > +//===- GEPSplitter.cpp - Split complex GEPs into simple ones > --------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open > Source > +// License. See LICENSE.TXT for details. > +// > +// > = > = > = > ----------------------------------------------------------------------= > ==// > +// > +// This function breaks GEPs with more than 2 non-zero operands > into smaller > +// GEPs each with no more than 2 non-zero operands. This exposes > redundancy > +// between GEPs with common initial operand sequences. > +// > +// > = > = > = > ----------------------------------------------------------------------= > ==// > + > +#define DEBUG_TYPE "split-geps" > +#include "llvm/Transforms/Scalar.h" > +#include "llvm/Constants.h" > +#include "llvm/Function.h" > +#include "llvm/Instructions.h" > +#include "llvm/Pass.h" > +using namespace llvm; > + > +namespace { > + class GEPSplitter : public FunctionPass { > + virtual bool runOnFunction(Function &F); > + virtual void getAnalysisUsage(AnalysisUsage &AU) const; > + public: > + static char ID; // Pass identification, replacement for typeid > + explicit GEPSplitter() : FunctionPass(&ID) {} > + }; > +} > + > +char GEPSplitter::ID = 0; > +static RegisterPass X("split-geps", > + "split complex GEPs into simple > GEPs"); > + > +FunctionPass *llvm::createGEPSplitterPass() { > + return new GEPSplitter(); > +} > + > +bool GEPSplitter::runOnFunction(Function &F) { > + bool Changed = false; > + > + // Visit each GEP instruction. > + for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) > + for (BasicBlock::iterator II = I->begin(), IE = I->end(); II != > IE; ) > + if (GetElementPtrInst *GEP = dyn_cast(II+ > +)) { > + unsigned NumOps = GEP->getNumOperands(); > + // Ignore GEPs which are already simple. > + if (NumOps <= 2) > + continue; > + bool FirstIndexIsZero = isa(GEP->getOperand > (1)) && > + cast(GEP->getOperand > (1))->isZero(); > + if (NumOps == 3 && FirstIndexIsZero) > + continue; > + // The first index is special and gets expanded with a 2- > operand GEP > + // (unless it's zero, in which case we can skip this). > + Value *NewGEP = FirstIndexIsZero ? > + GEP->getOperand(0) : > + GetElementPtrInst::Create(GEP->getOperand(0), GEP- > >getOperand(1), > + "tmp", GEP); > + // All remaining indices get expanded with a 3-operand GEP > with zero > + // as the second operand. > + Value *Idxs[2]; > + Idxs[0] = ConstantInt::get(Type::getInt64Ty(F.getContext > ()), 0); > + for (unsigned i = 2; i != NumOps; ++i) { > + Idxs[1] = GEP->getOperand(i); > + NewGEP = GetElementPtrInst::Create(NewGEP, Idxs, Idxs+2, > "tmp", GEP); > + } > + GEP->replaceAllUsesWith(NewGEP); > + GEP->eraseFromParent(); > + Changed = true; > + } > + > + return Changed; > +} > + > +void GEPSplitter::getAnalysisUsage(AnalysisUsage &AU) const { > + AU.setPreservesCFG(); > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From resistor at me.com Mon Oct 26 14:58:09 2009 From: resistor at me.com (Owen Anderson) Date: Mon, 26 Oct 2009 12:58:09 -0700 Subject: [llvm-commits] [llvm] r85144 - in /llvm/trunk: include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/GEPSplitter.cpp In-Reply-To: <200910261912.n9QJCE4a030428@zion.cs.uiuc.edu> References: <200910261912.n9QJCE4a030428@zion.cs.uiuc.edu> Message-ID: <83489F21-6E25-42FB-B136-84DDBE36BF0E@me.com> On Oct 26, 2009, at 12:12 PM, Dan Gohman wrote: > Author: djg > Date: Mon Oct 26 14:12:14 2009 > New Revision: 85144 > > URL: http://llvm.org/viewvc/llvm-project?rev=85144&view=rev > Log: > Check in the experimental GEP splitter pass. This pass splits complex > GEPs (more than one non-zero index) into simple GEPs (at most one > non-zero index). In some simple experiments using this it's not > uncommon to see 3% overall code size wins, because it exposes > redundancies that can be eliminated, however it's tricky to use > because instcombine aggressively undoes the work that this pass does. > How about running it right before GVN, and letting a later instcombine pass clean it up? --Owen > Added: > llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp > Modified: > llvm/trunk/include/llvm/LinkAllPasses.h > llvm/trunk/include/llvm/Transforms/Scalar.h > > Modified: llvm/trunk/include/llvm/LinkAllPasses.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=85144&r1=85143&r2=85144&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/LinkAllPasses.h (original) > +++ llvm/trunk/include/llvm/LinkAllPasses.h Mon Oct 26 14:12:14 2009 > @@ -141,6 +141,7 @@ > (void) llvm::createPartialInliningPass(); > (void) llvm::createSSIPass(); > (void) llvm::createSSIEverythingPass(); > + (void) llvm::createGEPSplitterPass(); > > (void)new llvm::IntervalPartition(); > (void)new llvm::FindUsedTypes(); > > Modified: llvm/trunk/include/llvm/Transforms/Scalar.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=85144&r1=85143&r2=85144&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/Transforms/Scalar.h (original) > +++ llvm/trunk/include/llvm/Transforms/Scalar.h Mon Oct 26 14:12:14 > 2009 > @@ -341,6 +341,12 @@ > // > FunctionPass *createSSIEverythingPass(); > > +// > = > = > = > ----------------------------------------------------------------------= > ==// > +// > +// GEPSplitter - Split complex GEPs into simple ones > +// > +FunctionPass *createGEPSplitterPass(); > + > } // End llvm namespace > > #endif > > Added: llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp?rev=85144&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp (added) > +++ llvm/trunk/lib/Transforms/Scalar/GEPSplitter.cpp Mon Oct 26 > 14:12:14 2009 > @@ -0,0 +1,81 @@ > +//===- GEPSplitter.cpp - Split complex GEPs into simple ones > --------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open > Source > +// License. See LICENSE.TXT for details. > +// > +// > = > = > = > ----------------------------------------------------------------------= > ==// > +// > +// This function breaks GEPs with more than 2 non-zero operands > into smaller > +// GEPs each with no more than 2 non-zero operands. This exposes > redundancy > +// between GEPs with common initial operand sequences. > +// > +// > = > = > = > ----------------------------------------------------------------------= > ==// > + > +#define DEBUG_TYPE "split-geps" > +#include "llvm/Transforms/Scalar.h" > +#include "llvm/Constants.h" > +#include "llvm/Function.h" > +#include "llvm/Instructions.h" > +#include "llvm/Pass.h" > +using namespace llvm; > + > +namespace { > + class GEPSplitter : public FunctionPass { > + virtual bool runOnFunction(Function &F); > + virtual void getAnalysisUsage(AnalysisUsage &AU) const; > + public: > + static char ID; // Pass identification, replacement for typeid > + explicit GEPSplitter() : FunctionPass(&ID) {} > + }; > +} > + > +char GEPSplitter::ID = 0; > +static RegisterPass X("split-geps", > + "split complex GEPs into simple > GEPs"); > + > +FunctionPass *llvm::createGEPSplitterPass() { > + return new GEPSplitter(); > +} > + > +bool GEPSplitter::runOnFunction(Function &F) { > + bool Changed = false; > + > + // Visit each GEP instruction. > + for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) > + for (BasicBlock::iterator II = I->begin(), IE = I->end(); II != > IE; ) > + if (GetElementPtrInst *GEP = dyn_cast(II+ > +)) { > + unsigned NumOps = GEP->getNumOperands(); > + // Ignore GEPs which are already simple. > + if (NumOps <= 2) > + continue; > + bool FirstIndexIsZero = isa(GEP->getOperand > (1)) && > + cast(GEP->getOperand > (1))->isZero(); > + if (NumOps == 3 && FirstIndexIsZero) > + continue; > + // The first index is special and gets expanded with a 2- > operand GEP > + // (unless it's zero, in which case we can skip this). > + Value *NewGEP = FirstIndexIsZero ? > + GEP->getOperand(0) : > + GetElementPtrInst::Create(GEP->getOperand(0), GEP- > >getOperand(1), > + "tmp", GEP); > + // All remaining indices get expanded with a 3-operand GEP > with zero > + // as the second operand. > + Value *Idxs[2]; > + Idxs[0] = ConstantInt::get(Type::getInt64Ty(F.getContext > ()), 0); > + for (unsigned i = 2; i != NumOps; ++i) { > + Idxs[1] = GEP->getOperand(i); > + NewGEP = GetElementPtrInst::Create(NewGEP, Idxs, Idxs+2, > "tmp", GEP); > + } > + GEP->replaceAllUsesWith(NewGEP); > + GEP->eraseFromParent(); > + Changed = true; > + } > + > + return Changed; > +} > + > +void GEPSplitter::getAnalysisUsage(AnalysisUsage &AU) const { > + AU.setPreservesCFG(); > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From nicholas at mxc.ca Mon Oct 26 23:43:56 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 26 Oct 2009 21:43:56 -0700 Subject: [llvm-commits] [llvm] r85189 - in /llvm/trunk: include/llvm/Intrinsics.td lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp lib/Transforms/Scalar/SimplifyLibCalls.cpp In-Reply-To: <200910270052.n9R0qPfC015484@zion.cs.uiuc.edu> References: <200910270052.n9R0qPfC015484@zion.cs.uiuc.edu> Message-ID: <4AE67A8C.6070403@mxc.ca> Eric Christopher wrote: > Author: echristo > Date: Mon Oct 26 19:52:25 2009 > New Revision: 85189 > > URL: http://llvm.org/viewvc/llvm-project?rev=85189&view=rev > Log: > Add objectsize intrinsic and hook it up through codegen. Doesn't > do anything than return "I don't know" at the moment. Please document this in the LangRef. Nick > Modified: > llvm/trunk/include/llvm/Intrinsics.td > llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp > llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp > > Modified: llvm/trunk/include/llvm/Intrinsics.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=85189&r1=85188&r2=85189&view=diff > > ============================================================================== > --- llvm/trunk/include/llvm/Intrinsics.td (original) > +++ llvm/trunk/include/llvm/Intrinsics.td Mon Oct 26 19:52:25 2009 > @@ -259,6 +259,11 @@ > def int_sigsetjmp : Intrinsic<[llvm_i32_ty] , [llvm_ptr_ty, llvm_i32_ty]>; > def int_siglongjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_i32_ty]>; > > +// Internal interface for object size checking > +def int_objectsize : Intrinsic<[llvm_anyint_ty], [llvm_ptr_ty, llvm_i32_ty], > + [IntrReadArgMem]>, > + GCCBuiltin<"__builtin_object_size">; > + > //===-------------------- Bit Manipulation Intrinsics ---------------------===// > // > > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=85189&r1=85188&r2=85189&view=diff > > ============================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Mon Oct 26 19:52:25 2009 > @@ -4204,6 +4204,18 @@ > DAG.setRoot(Result); > return 0; > } > + case Intrinsic::objectsize: { > + // If we don't know by now, we're never going to know. > + ConstantInt *CI = dyn_cast(I.getOperand(2)); > + > + assert(CI && "Non-constant type in __builtin_object_size?"); > + > + if (CI->getZExtValue() < 2) > + setValue(&I, DAG.getConstant(-1, MVT::i32)); > + else > + setValue(&I, DAG.getConstant(0, MVT::i32)); > + return 0; > + } > case Intrinsic::var_annotation: > // Discard annotate attributes > return 0; > > Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp?rev=85189&r1=85188&r2=85189&view=diff > > ============================================================================== > --- llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Mon Oct 26 19:52:25 2009 > @@ -509,6 +509,27 @@ > } > > //===----------------------------------------------------------------------===// > +// Miscellaneous LibCall/Intrinsic Optimizations > +//===----------------------------------------------------------------------===// > + > +namespace { > +struct SizeOpt : public LibCallOptimization { > + virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { > + // TODO: We can do more with this, but delaying to here should be no change > + // in behavior. > + ConstantInt *Const = dyn_cast(CI->getOperand(2)); > + > + if (!Const) return 0; > + > + if (Const->getZExtValue() < 2) > + return Constant::getAllOnesValue(Const->getType()); > + else > + return ConstantInt::get(Const->getType(), 0); > + } > +}; > +} > + > +//===----------------------------------------------------------------------===// > // String and Memory LibCall Optimizations > //===----------------------------------------------------------------------===// > > @@ -1548,6 +1569,7 @@ > // Formatting and IO Optimizations > SPrintFOpt SPrintF; PrintFOpt PrintF; > FWriteOpt FWrite; FPutsOpt FPuts; FPrintFOpt FPrintF; > + SizeOpt ObjectSize; > > bool Modified; // This is only used by doInitialization. > public: > @@ -1653,6 +1675,9 @@ > Optimizations["fwrite"] = &FWrite; > Optimizations["fputs"] = &FPuts; > Optimizations["fprintf"] = &FPrintF; > + > + // Miscellaneous > + Optimizations["llvm.objectsize"] = &ObjectSize; > } > > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From nicholas at mxc.ca Mon Oct 26 23:54:03 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 26 Oct 2009 21:54:03 -0700 Subject: [llvm-commits] FW: [PATCH] Fix to pass options from Gold plugin to LTO codegen In-Reply-To: References: <3FE2DECEF38F9247AE7C8BC1FD2B015F0817022C@ALLISON>, <6AE1604EE3EC5F4296C096518C6B77EEF11643FF@mail.accesssoftek.com> <6AE1604EE3EC5F4296C096518C6B77EEF1163385@mail.accesssoftek.com> <4AE250D1.4090403@mxc.ca> Message-ID: <4AE67CEB.6010404@mxc.ca> Viktor Kutuzov wrote: > Hello Nick, > Thanks for the review. > > Please find the updated patch attached. > > I didn't remove the lto_codegen_debug_options yet, just marked it as > deprecated. > It is actually used in Ada, in files > > bindings/ada/llvm/llvm_linktimeoptimizer_wrap.cxx > bindings/ada/llvm/llvm_link_time_optimizer-binding.ads Bah, then it's too late. We released 2.6 with this API which means that it's fixed in stone forever. All of the C API is like that, we will never break backwards-compatibility on the C API. Well, given that, why not just call lto_codegen_debug_options? The comment makes it clear that it's "used to pass extra options to the code generator" and that's just what we're doing. > Edward, is this fine to use lto_codegen_set_options there instead? > >> And that would be even better if it took an argc+argv pair > > Gold plug-in gets all arguments from gold one by one. > It is not a big dial to construct argc+argv pair there and pass it down > to the LTO, but LTO internally keeps a vector of char*, so, argc+argv > doesn't make much sense unless we want to replace that vector with > argc+argv pair as well and to change setCodeGenOptions behavior to set > options instead of add them. Sure, given that lto_codegen_debug_options takes one option at a time and we're wedded to this API then we may as well use it. Please send another patch without the new "lto_codegen_set_options" function by calling the "lto_codegen_debug_options" function instead. The changes to gold-plugin.cpp look great to me! Nick > If this is fine with everyone, I can prepare this patch, but would > prefer to make it separately from this one since it would change the API > and will break a backward compatibility. > What do you think? > > Thanks, > Viktor > > ----- Original Message ----- From: "Nick Lewycky" > To: "Viktor Kutuzov" > Cc: "Commit Messages and Patches for LLVM" > Sent: Friday, October 23, 2009 5:56 PM > Subject: Re: [llvm-commits] FW: [PATCH] Fix to pass options from Gold > plugin to LTO codegen > > > Viktor Kutuzov wrote: >> Hello everyone, >> >> Please find the patch attached. >> This should fix the issue when gold plugin doesn't pass the >> -plugin-opt options down to the LTO codegen. >> See the thread "[LLVMdev] getting gold plugin to work?" for more details. >> >> This is the second try. >> It looks like the first one was bounced, not sure why. >> Sorry if anyone will get it twise. > > Hi Viktor, this looks like the same patch I already reviewed here: > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20091019/089467.html > > > To reiterate: > "What's the difference between setCodeGenDebugOptions and > setCodeGenOption? It looks like they should be merged into one then > exposed by lto_codegen_set_option. And that would be even better if it > took an argc+argv pair, even if that's a little harder to construct from > the gold plugin, many option parsing packages work by removing the > options they recognize from argc+argv and leaving the rest in place." > > Nick > > > ------------------------------------------------------------------------ > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Mon Oct 26 23:58:12 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 04:58:12 -0000 Subject: [llvm-commits] [llvm] r85203 - /llvm/trunk/include/llvm/Support/PointerLikeTypeTraits.h Message-ID: <200910270458.n9R4wCp2025211@zion.cs.uiuc.edu> Author: lattner Date: Mon Oct 26 23:58:10 2009 New Revision: 85203 URL: http://llvm.org/viewvc/llvm-project?rev=85203&view=rev Log: lang points out that the comment is out of date with the code. Modified: llvm/trunk/include/llvm/Support/PointerLikeTypeTraits.h Modified: llvm/trunk/include/llvm/Support/PointerLikeTypeTraits.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PointerLikeTypeTraits.h?rev=85203&r1=85202&r2=85203&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/PointerLikeTypeTraits.h (original) +++ llvm/trunk/include/llvm/Support/PointerLikeTypeTraits.h Mon Oct 26 23:58:10 2009 @@ -38,7 +38,7 @@ return static_cast(P); } - /// Note, we assume here that malloc returns objects at least 8-byte aligned. + /// Note, we assume here that malloc returns objects at least 4-byte aligned. /// However, this may be wrong, or pointers may be from something other than /// malloc. In this case, you should specialize this template to reduce this. /// From bob.wilson at apple.com Tue Oct 27 00:21:12 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 26 Oct 2009 22:21:12 -0700 Subject: [llvm-commits] [PATCH] ARM AAPCS-VFP hard float homogeneous struct returns In-Reply-To: <305d6f60910261637t3fcc907fsaf47a4dbb968241a@mail.gmail.com> References: <305d6f60910261637t3fcc907fsaf47a4dbb968241a@mail.gmail.com> Message-ID: <505CC87B-2855-4E20-BE7F-3B76E3A36345@apple.com> Nice! Thanks for doing this. Some comments/questions: * Typo: DESTFIELNO -> DESTFIELDNO in the following comment: +// llvm_arm_extract_mrv_array_element - Helper function that helps extract +// an array element from multiple return value. +// +// Here, SRC is returning multiple values. DEST's DESTFIELNO field is an array. +// Extract SRCFIELDNO's ELEMENO value and store it in DEST's FIELDNO field's +// ELEMENTNO. * Can you add an assertion at the beginning of llvm_arm_extract_mrv_array_element to check that Src->getType() is a StructType? * Likewise, at the beginning of llvm_arm_extract_multiple_return_value, it would be good to assert that all the types you cast match your expectations. * Also in llvm_arm_extract_multiple_return_value, there is a comment: + // Directly access first class values using getresult. but I don't see anything in the code involving "getresult". Just drop the "using getresult"? * Is the following comment in llvm_arm_should_pass_or_return_aggregate_in_regs still relevant with the new containerized vector types? + // Alas, we can't use LLVM Types to figure this out because we need to + // examine unions closely. We'll have to walk the GCC TreeType. If not, please remove it. * Next time keep the whitespace changes separate. It makes it harder to review when you combine them. I read through the patch pretty carefully and it looks good to me, but I'd like to test it out. I'll try to get to that tomorrow. On Oct 26, 2009, at 4:37 PM, Sandeep Patel wrote: > The attached patch to llvm-gcc-4.2 fixes incorrect returns of > homogeneous structures. Instead of using a shadow parameter they are > now register allocated. > > deep > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From bob.wilson at apple.com Tue Oct 27 00:30:49 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 27 Oct 2009 05:30:49 -0000 Subject: [llvm-commits] [llvm] r85204 - /llvm/trunk/test/CodeGen/ARM/alloca.ll Message-ID: <200910270530.n9R5UnbX026415@zion.cs.uiuc.edu> Author: bwilson Date: Tue Oct 27 00:30:47 2009 New Revision: 85204 URL: http://llvm.org/viewvc/llvm-project?rev=85204&view=rev Log: Convert to FileCheck, fixing failure due to tab change in the process. Modified: llvm/trunk/test/CodeGen/ARM/alloca.ll Modified: llvm/trunk/test/CodeGen/ARM/alloca.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/alloca.ll?rev=85204&r1=85203&r2=85204&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/alloca.ll (original) +++ llvm/trunk/test/CodeGen/ARM/alloca.ll Tue Oct 27 00:30:47 2009 @@ -1,13 +1,12 @@ -; RUN: llc < %s -march=arm -mtriple=arm-linux-gnu | \ -; RUN: grep {mov r11, sp} -; RUN: llc < %s -march=arm -mtriple=arm-linux-gnu | \ -; RUN: grep {mov sp, r11} +; RUN: llc < %s -march=arm -mtriple=arm-linux-gnu | FileCheck %s define void @f(i32 %a) { entry: +; CHECK: mov r11, sp %tmp = alloca i8, i32 %a ; [#uses=1] call void @g( i8* %tmp, i32 %a, i32 1, i32 2, i32 3 ) ret void +; CHECK: mov sp, r11 } declare void @g(i8*, i32, i32, i32, i32) From sabre at nondot.org Tue Oct 27 00:35:35 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 05:35:35 -0000 Subject: [llvm-commits] [llvm] r85205 - /llvm/trunk/test/Transforms/Inline/basictest.ll Message-ID: <200910270535.n9R5ZZ78026641@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 00:35:35 2009 New Revision: 85205 URL: http://llvm.org/viewvc/llvm-project?rev=85205&view=rev Log: convert to filecheck. Modified: llvm/trunk/test/Transforms/Inline/basictest.ll Modified: llvm/trunk/test/Transforms/Inline/basictest.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/basictest.ll?rev=85205&r1=85204&r2=85205&view=diff ============================================================================== --- llvm/trunk/test/Transforms/Inline/basictest.ll (original) +++ llvm/trunk/test/Transforms/Inline/basictest.ll Tue Oct 27 00:35:35 2009 @@ -1,12 +1,15 @@ -; RUN: opt < %s -inline -disable-output -print-function 2> /dev/null +; RUN: opt < %s -inline -S | FileCheck %s -define i32 @func(i32 %i) { +define i32 @test1f(i32 %i) { ret i32 %i } -define i32 @main(i32 %argc) { - %X = call i32 @func( i32 7 ) ; [#uses=1] - %Y = add i32 %X, %argc ; [#uses=1] +define i32 @test1(i32 %W) { + %X = call i32 @test1f(i32 7) + %Y = add i32 %X, %W ret i32 %Y +; CHECK: @test1( +; CHECK-NEXT: %Y = add i32 7, %W +; CHECK-NEXT: ret i32 %Y } From sabre at nondot.org Tue Oct 27 00:39:42 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 05:39:42 -0000 Subject: [llvm-commits] [llvm] r85206 - in /llvm/trunk: lib/Transforms/Utils/InlineFunction.cpp test/Transforms/Inline/basictest.ll Message-ID: <200910270539.n9R5dglO026792@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 00:39:41 2009 New Revision: 85206 URL: http://llvm.org/viewvc/llvm-project?rev=85206&view=rev Log: Fix a pretty serious misfeature of the inliner: if it inlines a function with multiple return values it inserts a PHI to merge them all together. However, if the return values are all the same, it ends up with a pointless PHI and this pointless PHI happens to really block SRoA from happening in at least a silly C++ example written by Doug, but probably others. This fixes rdar://7339069. Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp llvm/trunk/test/Transforms/Inline/basictest.ll Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=85206&r1=85205&r2=85206&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Tue Oct 27 00:39:41 2009 @@ -619,8 +619,17 @@ "Ret value not consistent in function!"); PHI->addIncoming(RI->getReturnValue(), RI->getParent()); } + + // Now that we inserted the PHI, check to see if it has a single value + // (e.g. all the entries are the same or undef). If so, remove the PHI so + // it doesn't block other optimizations. + if (Value *V = PHI->hasConstantValue()) { + PHI->replaceAllUsesWith(V); + PHI->eraseFromParent(); + } } + // Add a branch to the merge points and remove return instructions. for (unsigned i = 0, e = Returns.size(); i != e; ++i) { ReturnInst *RI = Returns[i]; Modified: llvm/trunk/test/Transforms/Inline/basictest.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/basictest.ll?rev=85206&r1=85205&r2=85206&view=diff ============================================================================== --- llvm/trunk/test/Transforms/Inline/basictest.ll (original) +++ llvm/trunk/test/Transforms/Inline/basictest.ll Tue Oct 27 00:39:41 2009 @@ -1,4 +1,4 @@ -; RUN: opt < %s -inline -S | FileCheck %s +; RUN: opt < %s -inline -scalarrepl -S | FileCheck %s define i32 @test1f(i32 %i) { ret i32 %i @@ -13,3 +13,34 @@ ; CHECK-NEXT: ret i32 %Y } + + +; rdar://7339069 + +%T = type { i32, i32 } + +; CHECK-NOT: @test2f +define internal %T* @test2f(i1 %cond, %T* %P) { + br i1 %cond, label %T, label %F + +T: + %A = getelementptr %T* %P, i32 0, i32 0 + store i32 42, i32* %A + ret %T* %P + +F: + ret %T* %P +} + +define i32 @test2(i1 %cond) { + %A = alloca %T + + %B = call %T* @test2f(i1 %cond, %T* %A) + %C = getelementptr %T* %B, i32 0, i32 0 + %D = load i32* %C + ret i32 %D + +; CHECK: @test2( +; CHECK-NOT: = alloca +; CHECK: ret i32 42 +} From bob.wilson at apple.com Tue Oct 27 00:50:28 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 27 Oct 2009 05:50:28 -0000 Subject: [llvm-commits] [llvm] r85207 - in /llvm/trunk/test/CodeGen/ARM: arguments.ll arguments_f64_backfill.ll arm-negative-stride.ll bfc.ll call.ll carry.ll constants.ll Message-ID: <200910270550.n9R5oSvb027190@zion.cs.uiuc.edu> Author: bwilson Date: Tue Oct 27 00:50:28 2009 New Revision: 85207 URL: http://llvm.org/viewvc/llvm-project?rev=85207&view=rev Log: Fix some more failures by converting to FileCheck. Modified: llvm/trunk/test/CodeGen/ARM/arguments.ll llvm/trunk/test/CodeGen/ARM/arguments_f64_backfill.ll llvm/trunk/test/CodeGen/ARM/arm-negative-stride.ll llvm/trunk/test/CodeGen/ARM/bfc.ll llvm/trunk/test/CodeGen/ARM/call.ll llvm/trunk/test/CodeGen/ARM/carry.ll llvm/trunk/test/CodeGen/ARM/constants.ll Modified: llvm/trunk/test/CodeGen/ARM/arguments.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/arguments.ll?rev=85207&r1=85206&r2=85207&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/arguments.ll (original) +++ llvm/trunk/test/CodeGen/ARM/arguments.ll Tue Oct 27 00:50:28 2009 @@ -1,9 +1,9 @@ -; RUN: llc < %s -mtriple=arm-linux-gnueabi | \ -; RUN: grep {mov r0, r2} | count 1 -; RUN: llc < %s -mtriple=arm-apple-darwin | \ -; RUN: grep {mov r0, r1} | count 1 +; RUN: llc < %s -mtriple=arm-linux-gnueabi | FileCheck %s -check-prefix=ELF +; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s -check-prefix=DARWIN define i32 @f(i32 %a, i64 %b) { +; ELF: mov r0, r2 +; DARWIN: mov r0, r1 %tmp = call i32 @g(i64 %b) ret i32 %tmp } Modified: llvm/trunk/test/CodeGen/ARM/arguments_f64_backfill.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/arguments_f64_backfill.ll?rev=85207&r1=85206&r2=85207&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/arguments_f64_backfill.ll (original) +++ llvm/trunk/test/CodeGen/ARM/arguments_f64_backfill.ll Tue Oct 27 00:50:28 2009 @@ -1,6 +1,7 @@ -; RUN: llc < %s -mtriple=arm-linux-gnueabi -mattr=+vfp2 -float-abi=hard | grep {fcpys s0, s1} +; RUN: llc < %s -mtriple=arm-linux-gnueabi -mattr=+vfp2 -float-abi=hard | FileCheck %s define float @f(float %z, double %a, float %b) { +; CHECK: fcpys s0, s1 %tmp = call float @g(float %b) ret float %tmp } Modified: llvm/trunk/test/CodeGen/ARM/arm-negative-stride.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/arm-negative-stride.ll?rev=85207&r1=85206&r2=85207&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/arm-negative-stride.ll (original) +++ llvm/trunk/test/CodeGen/ARM/arm-negative-stride.ll Tue Oct 27 00:50:28 2009 @@ -1,7 +1,8 @@ -; RUN: llc < %s -march=arm | grep {str r1, \\\[r.*, -r.*, lsl #2\} +; RUN: llc < %s -march=arm | FileCheck %s define void @test(i32* %P, i32 %A, i32 %i) nounwind { entry: +; CHECK: str r1, [{{r.*}}, -{{r.*}}, lsl #2] icmp eq i32 %i, 0 ; :0 [#uses=1] br i1 %0, label %return, label %bb Modified: llvm/trunk/test/CodeGen/ARM/bfc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/bfc.ll?rev=85207&r1=85206&r2=85207&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/bfc.ll (original) +++ llvm/trunk/test/CodeGen/ARM/bfc.ll Tue Oct 27 00:50:28 2009 @@ -1,19 +1,25 @@ -; RUN: llc < %s -march=arm -mattr=+v6t2 | grep "bfc " | count 3 +; RUN: llc < %s -march=arm -mattr=+v6t2 | FileCheck %s ; 4278190095 = 0xff00000f define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: bfc %tmp = and i32 %a, 4278190095 ret i32 %tmp } ; 4286578688 = 0xff800000 define i32 @f2(i32 %a) { +; CHECK: f2: +; CHECK: bfc %tmp = and i32 %a, 4286578688 ret i32 %tmp } ; 4095 = 0x00000fff define i32 @f3(i32 %a) { +; CHECK: f3: +; CHECK: bfc %tmp = and i32 %a, 4095 ret i32 %tmp } Modified: llvm/trunk/test/CodeGen/ARM/call.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/call.ll?rev=85207&r1=85206&r2=85207&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/call.ll (original) +++ llvm/trunk/test/CodeGen/ARM/call.ll Tue Oct 27 00:50:28 2009 @@ -1,13 +1,16 @@ -; RUN: llc < %s -march=arm | grep {mov lr, pc} -; RUN: llc < %s -march=arm -mattr=+v5t | grep blx +; RUN: llc < %s -march=arm | FileCheck %s -check-prefix=CHECKV4 +; RUN: llc < %s -march=arm -mattr=+v5t | FileCheck %s -check-prefix=CHECKV5 ; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi\ -; RUN: -relocation-model=pic | grep {PLT} +; RUN: -relocation-model=pic | FileCheck %s -check-prefix=CHECKELF @t = weak global i32 ()* null ; [#uses=1] declare void @g(i32, i32, i32, i32) define void @f() { +; CHECKV4: mov lr, pc +; CHECKV5: blx +; CHECKELF: PLT call void @g( i32 1, i32 2, i32 3, i32 4 ) ret void } Modified: llvm/trunk/test/CodeGen/ARM/carry.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/carry.ll?rev=85207&r1=85206&r2=85207&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/carry.ll (original) +++ llvm/trunk/test/CodeGen/ARM/carry.ll Tue Oct 27 00:50:28 2009 @@ -1,14 +1,19 @@ -; RUN: llc < %s -march=arm | grep "subs r" | count 2 -; RUN: llc < %s -march=arm | grep "adc r" -; RUN: llc < %s -march=arm | grep "sbc r" | count 2 +; RUN: llc < %s -march=arm | FileCheck %s define i64 @f1(i64 %a, i64 %b) { +; CHECK: f1: +; CHECK: subs r +; CHECK: sbc r entry: %tmp = sub i64 %a, %b ret i64 %tmp } define i64 @f2(i64 %a, i64 %b) { +; CHECK: f2: +; CHECK: adc r +; CHECK: subs r +; CHECK: sbc r entry: %tmp1 = shl i64 %a, 1 %tmp2 = sub i64 %tmp1, %b Modified: llvm/trunk/test/CodeGen/ARM/constants.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/constants.ll?rev=85207&r1=85206&r2=85207&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/constants.ll (original) +++ llvm/trunk/test/CodeGen/ARM/constants.ll Tue Oct 27 00:50:28 2009 @@ -1,39 +1,44 @@ -; RUN: llc < %s -march=arm | \ -; RUN: grep {mov r0, #0} | count 1 -; RUN: llc < %s -march=arm | \ -; RUN: grep {mov r0, #255$} | count 1 -; RUN: llc < %s -march=arm -asm-verbose | \ -; RUN: grep {mov r0.*256} | count 1 -; RUN: llc < %s -march=arm -asm-verbose | grep {orr.*256} | count 1 -; RUN: llc < %s -march=arm -asm-verbose | grep {mov r0, .*-1073741761} | count 1 -; RUN: llc < %s -march=arm -asm-verbose | grep {mov r0, .*1008} | count 1 -; RUN: llc < %s -march=arm | grep {cmp r0, #1, 16} | count 1 +; RUN: llc < %s -march=arm | FileCheck %s define i32 @f1() { +; CHECK: f1 +; CHECK: mov r0, #0 ret i32 0 } define i32 @f2() { +; CHECK: f2 +; CHECK: mov r0, #255 ret i32 255 } define i32 @f3() { +; CHECK: f3 +; CHECK: mov r0{{.*}}256 ret i32 256 } define i32 @f4() { +; CHECK: f4 +; CHECK: orr{{.*}}256 ret i32 257 } define i32 @f5() { +; CHECK: f5 +; CHECK: mov r0, {{.*}}-1073741761 ret i32 -1073741761 } define i32 @f6() { +; CHECK: f6 +; CHECK: mov r0, {{.*}}1008 ret i32 1008 } define void @f7(i32 %a) { +; CHECK: f7 +; CHECK: cmp r0, #1, 16 %b = icmp ugt i32 %a, 65536 ; [#uses=1] br i1 %b, label %r, label %r From espindola at google.com Tue Oct 27 00:51:29 2009 From: espindola at google.com (Rafael Espindola) Date: Tue, 27 Oct 2009 01:51:29 -0400 Subject: [llvm-commits] [patch]fix argument passing on ARM Message-ID: <38a0d8450910262251g3b84ae47pcc57882843af9909@mail.gmail.com> This patch fixes the include testcase. The problem is that we were not checking the alignment of arguments on the stack, so doubles would end being 4 aligned instead of 8. Cheers, -- Rafael ?vila de Esp?ndola -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-double-align.patch Type: text/x-diff Size: 1225 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091027/261be112/attachment.bin From bob.wilson at apple.com Tue Oct 27 01:16:46 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 27 Oct 2009 06:16:46 -0000 Subject: [llvm-commits] [llvm] r85208 - in /llvm/trunk/test/CodeGen/ARM: fpmem.ll ispositive.ll ldm.ll ldr.ll long.ll str_post.ll tls2.ll Message-ID: <200910270616.n9R6Gkr9028401@zion.cs.uiuc.edu> Author: bwilson Date: Tue Oct 27 01:16:45 2009 New Revision: 85208 URL: http://llvm.org/viewvc/llvm-project?rev=85208&view=rev Log: Fix the rest of the ARM failures by converting them to FileCheck. Modified: llvm/trunk/test/CodeGen/ARM/fpmem.ll llvm/trunk/test/CodeGen/ARM/ispositive.ll llvm/trunk/test/CodeGen/ARM/ldm.ll llvm/trunk/test/CodeGen/ARM/ldr.ll llvm/trunk/test/CodeGen/ARM/long.ll llvm/trunk/test/CodeGen/ARM/str_post.ll llvm/trunk/test/CodeGen/ARM/tls2.ll Modified: llvm/trunk/test/CodeGen/ARM/fpmem.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fpmem.ll?rev=85208&r1=85207&r2=85208&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/fpmem.ll (original) +++ llvm/trunk/test/CodeGen/ARM/fpmem.ll Tue Oct 27 01:16:45 2009 @@ -1,21 +1,22 @@ -; RUN: llc < %s -march=arm | \ -; RUN: grep {mov r0, #0} | count 1 -; RUN: llc < %s -march=arm -mattr=+vfp2 | \ -; RUN: grep {flds.*\\\[} | count 1 -; RUN: llc < %s -march=arm -mattr=+vfp2 | \ -; RUN: grep {fsts.*\\\[} | count 1 +; RUN: llc < %s -march=arm -mattr=+vfp2 | FileCheck %s define float @f1(float %a) { +; CHECK: f1: +; CHECK: mov r0, #0 ret float 0.000000e+00 } define float @f2(float* %v, float %u) { +; CHECK: f2: +; CHECK: flds{{.*}}[ %tmp = load float* %v ; [#uses=1] %tmp1 = fadd float %tmp, %u ; [#uses=1] ret float %tmp1 } define void @f3(float %a, float %b, float* %v) { +; CHECK: f3: +; CHECK: fsts{{.*}}[ %tmp = fadd float %a, %b ; [#uses=1] store float %tmp, float* %v ret void Modified: llvm/trunk/test/CodeGen/ARM/ispositive.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ispositive.ll?rev=85208&r1=85207&r2=85208&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/ispositive.ll (original) +++ llvm/trunk/test/CodeGen/ARM/ispositive.ll Tue Oct 27 01:16:45 2009 @@ -1,6 +1,7 @@ -; RUN: llc < %s -march=arm | grep {mov r0, r0, lsr #31} +; RUN: llc < %s -march=arm | FileCheck %s define i32 @test1(i32 %X) { +; CHECK: mov r0, r0, lsr #31 entry: icmp slt i32 %X, 0 ; :0 [#uses=1] zext i1 %0 to i32 ; :1 [#uses=1] Modified: llvm/trunk/test/CodeGen/ARM/ldm.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ldm.ll?rev=85208&r1=85207&r2=85208&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/ldm.ll (original) +++ llvm/trunk/test/CodeGen/ARM/ldm.ll Tue Oct 27 01:16:45 2009 @@ -1,13 +1,10 @@ -; RUN: llc < %s -march=arm | \ -; RUN: grep ldmia | count 2 -; RUN: llc < %s -march=arm | \ -; RUN: grep ldmib | count 1 -; RUN: llc < %s -mtriple=arm-apple-darwin | \ -; RUN: grep {ldmfd sp\!} | count 3 +; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s @X = external global [0 x i32] ; <[0 x i32]*> [#uses=5] define i32 @t1() { +; CHECK: t1: +; CHECK: ldmia %tmp = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 0) ; [#uses=1] %tmp3 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 1) ; [#uses=1] %tmp4 = tail call i32 @f1( i32 %tmp, i32 %tmp3 ) ; [#uses=1] @@ -15,6 +12,8 @@ } define i32 @t2() { +; CHECK: t2: +; CHECK: ldmia %tmp = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 2) ; [#uses=1] %tmp3 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 3) ; [#uses=1] %tmp5 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 4) ; [#uses=1] @@ -23,6 +22,9 @@ } define i32 @t3() { +; CHECK: t3: +; CHECK: ldmib +; CHECK: ldmfd sp! %tmp = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 1) ; [#uses=1] %tmp3 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 2) ; [#uses=1] %tmp5 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 3) ; [#uses=1] Modified: llvm/trunk/test/CodeGen/ARM/ldr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ldr.ll?rev=85208&r1=85207&r2=85208&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/ldr.ll (original) +++ llvm/trunk/test/CodeGen/ARM/ldr.ll Tue Oct 27 01:16:45 2009 @@ -1,16 +1,16 @@ -; RUN: llc < %s -march=arm | grep {ldr r0} | count 7 -; RUN: llc < %s -march=arm | grep mov | grep 1 -; RUN: llc < %s -march=arm | not grep mvn -; RUN: llc < %s -march=arm | grep ldr | grep lsl -; RUN: llc < %s -march=arm | grep ldr | grep lsr +; RUN: llc < %s -march=arm | FileCheck %s define i32 @f1(i32* %v) { +; CHECK: f1: +; CHECK: ldr r0 entry: %tmp = load i32* %v ret i32 %tmp } define i32 @f2(i32* %v) { +; CHECK: f2: +; CHECK: ldr r0 entry: %tmp2 = getelementptr i32* %v, i32 1023 %tmp = load i32* %tmp2 @@ -18,6 +18,9 @@ } define i32 @f3(i32* %v) { +; CHECK: f3: +; CHECK: mov +; CHECK: ldr r0 entry: %tmp2 = getelementptr i32* %v, i32 1024 %tmp = load i32* %tmp2 @@ -25,6 +28,9 @@ } define i32 @f4(i32 %base) { +; CHECK: f4: +; CHECK-NOT: mvn +; CHECK: ldr r0 entry: %tmp1 = sub i32 %base, 128 %tmp2 = inttoptr i32 %tmp1 to i32* @@ -33,6 +39,8 @@ } define i32 @f5(i32 %base, i32 %offset) { +; CHECK: f5: +; CHECK: ldr r0 entry: %tmp1 = add i32 %base, %offset %tmp2 = inttoptr i32 %tmp1 to i32* @@ -41,6 +49,8 @@ } define i32 @f6(i32 %base, i32 %offset) { +; CHECK: f6: +; CHECK: ldr r0{{.*}}lsl{{.*}} entry: %tmp1 = shl i32 %offset, 2 %tmp2 = add i32 %base, %tmp1 @@ -50,6 +60,8 @@ } define i32 @f7(i32 %base, i32 %offset) { +; CHECK: f7: +; CHECK: ldr r0{{.*}}lsr{{.*}} entry: %tmp1 = lshr i32 %offset, 2 %tmp2 = add i32 %base, %tmp1 Modified: llvm/trunk/test/CodeGen/ARM/long.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/long.ll?rev=85208&r1=85207&r2=85208&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/long.ll (original) +++ llvm/trunk/test/CodeGen/ARM/long.ll Tue Oct 27 01:16:45 2009 @@ -1,47 +1,50 @@ -; RUN: llc < %s -march=arm -asm-verbose | \ -; RUN: grep -- {-2147483648} | count 3 -; RUN: llc < %s -march=arm | grep mvn | count 3 -; RUN: llc < %s -march=arm | grep adds | count 1 -; RUN: llc < %s -march=arm | grep adc | count 1 -; RUN: llc < %s -march=arm | grep {subs } | count 1 -; RUN: llc < %s -march=arm | grep sbc | count 1 -; RUN: llc < %s -march=arm | \ -; RUN: grep smull | count 1 -; RUN: llc < %s -march=arm | \ -; RUN: grep umull | count 1 +; RUN: llc < %s -march=arm | FileCheck %s define i64 @f1() { +; CHECK: f1: entry: ret i64 0 } define i64 @f2() { +; CHECK: f2: entry: ret i64 1 } define i64 @f3() { +; CHECK: f3: +; CHECK: mvn{{.*}}-2147483648 entry: ret i64 2147483647 } define i64 @f4() { +; CHECK: f4: +; CHECK: -2147483648 entry: ret i64 2147483648 } define i64 @f5() { +; CHECK: f5: +; CHECK: mvn +; CHECK: mvn{{.*}}-2147483648 entry: ret i64 9223372036854775807 } define i64 @f6(i64 %x, i64 %y) { +; CHECK: f6: +; CHECK: adds +; CHECK: adc entry: %tmp1 = add i64 %y, 1 ; [#uses=1] ret i64 %tmp1 } define void @f7() { +; CHECK: f7: entry: %tmp = call i64 @f8( ) ; [#uses=0] ret void @@ -50,12 +53,17 @@ declare i64 @f8() define i64 @f9(i64 %a, i64 %b) { +; CHECK: f9: +; CHECK: subs r +; CHECK: sbc entry: %tmp = sub i64 %a, %b ; [#uses=1] ret i64 %tmp } define i64 @f(i32 %a, i32 %b) { +; CHECK: f: +; CHECK: smull entry: %tmp = sext i32 %a to i64 ; [#uses=1] %tmp1 = sext i32 %b to i64 ; [#uses=1] @@ -64,6 +72,8 @@ } define i64 @g(i32 %a, i32 %b) { +; CHECK: g: +; CHECK: umull entry: %tmp = zext i32 %a to i64 ; [#uses=1] %tmp1 = zext i32 %b to i64 ; [#uses=1] @@ -72,9 +82,9 @@ } define i64 @f10() { +; CHECK: f10: entry: %a = alloca i64, align 8 ; [#uses=1] %retval = load i64* %a ; [#uses=1] ret i64 %retval } - Modified: llvm/trunk/test/CodeGen/ARM/str_post.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/str_post.ll?rev=85208&r1=85207&r2=85208&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/str_post.ll (original) +++ llvm/trunk/test/CodeGen/ARM/str_post.ll Tue Oct 27 01:16:45 2009 @@ -1,9 +1,8 @@ -; RUN: llc < %s -march=arm | \ -; RUN: grep {strh .*\\\[.*\], #-4} | count 1 -; RUN: llc < %s -march=arm | \ -; RUN: grep {str .*\\\[.*\],} | count 1 +; RUN: llc < %s -march=arm | FileCheck %s define i16 @test1(i32* %X, i16* %A) { +; CHECK: test1: +; CHECK: strh {{.*}}[{{.*}}], #-4 %Y = load i32* %X ; [#uses=1] %tmp1 = trunc i32 %Y to i16 ; [#uses=1] store i16 %tmp1, i16* %A @@ -13,6 +12,8 @@ } define i32 @test2(i32* %X, i32* %A) { +; CHECK: test2: +; CHECK: str {{.*}}[{{.*}}], %Y = load i32* %X ; [#uses=1] store i32 %Y, i32* %A %tmp1 = ptrtoint i32* %A to i32 ; [#uses=1] Modified: llvm/trunk/test/CodeGen/ARM/tls2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/tls2.ll?rev=85208&r1=85207&r2=85208&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/tls2.ll (original) +++ llvm/trunk/test/CodeGen/ARM/tls2.ll Tue Oct 27 01:16:45 2009 @@ -1,19 +1,27 @@ -; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi | \ -; RUN: grep {i(gottpoff)} -; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi | \ -; RUN: grep {ldr r., \[pc, r.\]} ; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi \ -; RUN: -relocation-model=pic | grep {__tls_get_addr} +; RUN: | FileCheck %s -check-prefix=CHECK-NONPIC +; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi \ +; RUN: -relocation-model=pic | FileCheck %s -check-prefix=CHECK-PIC @i = external thread_local global i32 ; [#uses=2] define i32 @f() { +; CHECK-NONPIC: f: +; CHECK-NONPIC: ldr {{r.}}, [pc, +{{r.}}] +; CHECK-NONPIC: i(gottpoff) +; CHECK-PIC: f: +; CHECK-PIC: __tls_get_addr entry: %tmp1 = load i32* @i ; [#uses=1] ret i32 %tmp1 } define i32* @g() { +; CHECK-NONPIC: g: +; CHECK-NONPIC: ldr {{r.}}, [pc, +{{r.}}] +; CHECK-NONPIC: i(gottpoff) +; CHECK-PIC: g: +; CHECK-PIC: __tls_get_addr entry: ret i32* @i } From bob.wilson at apple.com Tue Oct 27 01:31:02 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 27 Oct 2009 06:31:02 -0000 Subject: [llvm-commits] [llvm] r85210 - in /llvm/trunk/test/CodeGen/Thumb2: thumb2-bfc.ll thumb2-clz.ll thumb2-cmn2.ll thumb2-eor2.ll thumb2-str_post.ll Message-ID: <200910270631.n9R6V2s0029194@zion.cs.uiuc.edu> Author: bwilson Date: Tue Oct 27 01:31:02 2009 New Revision: 85210 URL: http://llvm.org/viewvc/llvm-project?rev=85210&view=rev Log: Fix Thumb2 failures by converting them to FileCheck. Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-bfc.ll llvm/trunk/test/CodeGen/Thumb2/thumb2-clz.ll llvm/trunk/test/CodeGen/Thumb2/thumb2-cmn2.ll llvm/trunk/test/CodeGen/Thumb2/thumb2-eor2.ll llvm/trunk/test/CodeGen/Thumb2/thumb2-str_post.ll Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-bfc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-bfc.ll?rev=85210&r1=85209&r2=85210&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/thumb2-bfc.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/thumb2-bfc.ll Tue Oct 27 01:31:02 2009 @@ -1,25 +1,32 @@ -; RUN: llc < %s -march=thumb -mattr=+thumb2 | grep "bfc " | count 3 +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s ; 4278190095 = 0xff00000f define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: bfc r %tmp = and i32 %a, 4278190095 ret i32 %tmp } ; 4286578688 = 0xff800000 define i32 @f2(i32 %a) { +; CHECK: f2: +; CHECK: bfc r %tmp = and i32 %a, 4286578688 ret i32 %tmp } ; 4095 = 0x00000fff define i32 @f3(i32 %a) { +; CHECK: f3: +; CHECK: bfc r %tmp = and i32 %a, 4095 ret i32 %tmp } ; 2147483646 = 0x7ffffffe not implementable w/ BFC define i32 @f4(i32 %a) { +; CHECK: f4: %tmp = and i32 %a, 2147483646 ret i32 %tmp } Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-clz.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-clz.ll?rev=85210&r1=85209&r2=85210&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/thumb2-clz.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/thumb2-clz.ll Tue Oct 27 01:31:02 2009 @@ -1,6 +1,8 @@ -; RUN: llc < %s -march=thumb -mattr=+thumb2,+v7a | grep "clz " | count 1 +; RUN: llc < %s -march=thumb -mattr=+thumb2,+v7a | FileCheck %s define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: clz r %tmp = tail call i32 @llvm.ctlz.i32(i32 %a) ret i32 %tmp } Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-cmn2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-cmn2.ll?rev=85210&r1=85209&r2=85210&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/thumb2-cmn2.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/thumb2-cmn2.ll Tue Oct 27 01:31:02 2009 @@ -1,25 +1,33 @@ -; RUN: llc < %s -march=thumb -mattr=+thumb2 | grep "cmn\\.w " | grep {#187\\|#11141290\\|#-872363008\\|#1114112} | count 4 +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s ; -0x000000bb = 4294967109 define i1 @f1(i32 %a) { +; CHECK: f1: +; CHECK: cmn.w {{r.*}}, #187 %tmp = icmp ne i32 %a, 4294967109 ret i1 %tmp } ; -0x00aa00aa = 4283826006 define i1 @f2(i32 %a) { +; CHECK: f2: +; CHECK: cmn.w {{r.*}}, #11141290 %tmp = icmp eq i32 %a, 4283826006 ret i1 %tmp } ; -0xcc00cc00 = 872363008 define i1 @f3(i32 %a) { +; CHECK: f3: +; CHECK: cmn.w {{r.*}}, #-872363008 %tmp = icmp ne i32 %a, 872363008 ret i1 %tmp } ; -0x00110000 = 4293853184 define i1 @f4(i32 %a) { +; CHECK: f4: +; CHECK: cmn.w {{r.*}}, #1114112 %tmp = icmp eq i32 %a, 4293853184 ret i1 %tmp } Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-eor2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-eor2.ll?rev=85210&r1=85209&r2=85210&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/thumb2-eor2.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/thumb2-eor2.ll Tue Oct 27 01:31:02 2009 @@ -1,31 +1,41 @@ -; RUN: llc < %s -march=thumb -mattr=+thumb2 | grep "eor " | grep {#187\\|#11141290\\|#-872363008\\|#1114112\\|#-572662307} | count 5 +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s ; 0x000000bb = 187 define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: eor {{.*}}#187 %tmp = xor i32 %a, 187 ret i32 %tmp } ; 0x00aa00aa = 11141290 define i32 @f2(i32 %a) { +; CHECK: f2: +; CHECK: eor {{.*}}#11141290 %tmp = xor i32 %a, 11141290 ret i32 %tmp } ; 0xcc00cc00 = 3422604288 define i32 @f3(i32 %a) { +; CHECK: f3: +; CHECK: eor {{.*}}#-872363008 %tmp = xor i32 %a, 3422604288 ret i32 %tmp } ; 0xdddddddd = 3722304989 define i32 @f4(i32 %a) { +; CHECK: f4: +; CHECK: eor {{.*}}#-572662307 %tmp = xor i32 %a, 3722304989 ret i32 %tmp } ; 0x00110000 = 1114112 define i32 @f5(i32 %a) { +; CHECK: f5: +; CHECK: eor {{.*}}#1114112 %tmp = xor i32 %a, 1114112 ret i32 %tmp } Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-str_post.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-str_post.ll?rev=85210&r1=85209&r2=85210&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/thumb2-str_post.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/thumb2-str_post.ll Tue Oct 27 01:31:02 2009 @@ -1,9 +1,8 @@ -; RUN: llc < %s -march=thumb -mattr=+thumb2 | \ -; RUN: grep {strh .*\\\[.*\], #-4} | count 1 -; RUN: llc < %s -march=thumb -mattr=+thumb2 | \ -; RUN: grep {str .*\\\[.*\],} | count 1 +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s define i16 @test1(i32* %X, i16* %A) { +; CHECK: test1: +; CHECK: strh {{.*}}[{{.*}}], #-4 %Y = load i32* %X ; [#uses=1] %tmp1 = trunc i32 %Y to i16 ; [#uses=1] store i16 %tmp1, i16* %A @@ -13,6 +12,8 @@ } define i32 @test2(i32* %X, i32* %A) { +; CHECK: test2: +; CHECK: str {{.*}}[{{.*}}], %Y = load i32* %X ; [#uses=1] store i32 %Y, i32* %A %tmp1 = ptrtoint i32* %A to i32 ; [#uses=1] From evan.cheng at apple.com Tue Oct 27 01:36:45 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 26 Oct 2009 23:36:45 -0700 Subject: [llvm-commits] [llvm] r85204 - /llvm/trunk/test/CodeGen/ARM/alloca.ll In-Reply-To: <200910270530.n9R5UnbX026415@zion.cs.uiuc.edu> References: <200910270530.n9R5UnbX026415@zion.cs.uiuc.edu> Message-ID: <7577591B-6246-4830-BB2A-7DA1CD47938B@apple.com> Oops. Thanks for fixing the tests. Evan On Oct 26, 2009, at 10:30 PM, Bob Wilson wrote: > Author: bwilson > Date: Tue Oct 27 00:30:47 2009 > New Revision: 85204 > > URL: http://llvm.org/viewvc/llvm-project?rev=85204&view=rev > Log: > Convert to FileCheck, fixing failure due to tab change in the process. > > Modified: > llvm/trunk/test/CodeGen/ARM/alloca.ll > > Modified: llvm/trunk/test/CodeGen/ARM/alloca.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/alloca.ll?rev=85204&r1=85203&r2=85204&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/ARM/alloca.ll (original) > +++ llvm/trunk/test/CodeGen/ARM/alloca.ll Tue Oct 27 00:30:47 2009 > @@ -1,13 +1,12 @@ > -; RUN: llc < %s -march=arm -mtriple=arm-linux-gnu | \ > -; RUN: grep {mov r11, sp} > -; RUN: llc < %s -march=arm -mtriple=arm-linux-gnu | \ > -; RUN: grep {mov sp, r11} > +; RUN: llc < %s -march=arm -mtriple=arm-linux-gnu | FileCheck %s > > define void @f(i32 %a) { > entry: > +; CHECK: mov r11, sp > %tmp = alloca i8, i32 %a ; [#uses=1] > call void @g( i8* %tmp, i32 %a, i32 1, i32 2, i32 3 ) > ret void > +; CHECK: mov sp, r11 > } > > declare void @g(i8*, i32, i32, i32, i32) > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Tue Oct 27 03:33:19 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 27 Oct 2009 09:33:19 +0100 Subject: [llvm-commits] [llvm] r85181 - in /llvm/trunk: include/llvm/Analysis/ lib/Analysis/ lib/Analysis/IPA/ lib/Transforms/IPO/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ In-Reply-To: <200910262358.n9QNwwUP012836@zion.cs.uiuc.edu> References: <200910262358.n9QNwwUP012836@zion.cs.uiuc.edu> Message-ID: <4AE6B04F.8090909@free.fr> Hi Victor, > Rename MallocHelper as MallocFreeHelper, since it now also identifies calls to free() how about naming it MemCallHelper or something like that instead. That way you won't need to change the name if you teach it to recognize calloc, realloc or other mem stuff one day. Ciao, Duncan. From baldrick at free.fr Tue Oct 27 03:47:04 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 27 Oct 2009 09:47:04 +0100 Subject: [llvm-commits] [llvm] r85189 - in /llvm/trunk: include/llvm/Intrinsics.td lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp lib/Transforms/Scalar/SimplifyLibCalls.cpp In-Reply-To: <200910270052.n9R0qPfC015484@zion.cs.uiuc.edu> References: <200910270052.n9R0qPfC015484@zion.cs.uiuc.edu> Message-ID: <4AE6B388.3090909@free.fr> Hi Eric, > Add objectsize intrinsic and hook it up through codegen. Doesn't > do anything than return "I don't know" at the moment. this is maybe the most horrible gcc builtin ever invented! Is it really a good idea to duplicate it in LLVM? I know it's more work, but I'd much rather BUILTIN_OBJECT_SIZE was mapped to a bunch of code and perhaps several LLVM intrinsics, but where the intrinsics each have a clear, clean, sensible and logical definition... Ciao, Duncan. From foldr at codedgers.com Tue Oct 27 04:02:49 2009 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Tue, 27 Oct 2009 09:02:49 -0000 Subject: [llvm-commits] [llvm] r85215 - /llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200910270902.n9R92nHm016480@zion.cs.uiuc.edu> Author: foldr Date: Tue Oct 27 04:02:49 2009 New Revision: 85215 URL: http://llvm.org/viewvc/llvm-project?rev=85215&view=rev Log: 80-col violation. Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=85215&r1=85214&r2=85215&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Tue Oct 27 04:02:49 2009 @@ -1901,7 +1901,8 @@ // For every understood option, emit handling code. if (D.Actions) - EmitCaseConstructHandler(D.Actions, Indent2, EmitActionHandlersCallback(OptDescs), + EmitCaseConstructHandler(D.Actions, Indent2, + EmitActionHandlersCallback(OptDescs), false, OptDescs, O); O << '\n'; From deeppatel1987 at gmail.com Tue Oct 27 04:20:44 2009 From: deeppatel1987 at gmail.com (Sandeep Patel) Date: Tue, 27 Oct 2009 09:20:44 +0000 Subject: [llvm-commits] [patch]fix argument passing on ARM In-Reply-To: <38a0d8450910262251g3b84ae47pcc57882843af9909@mail.gmail.com> References: <38a0d8450910262251g3b84ae47pcc57882843af9909@mail.gmail.com> Message-ID: <305d6f60910270220o349e6c89g775bac4c92a4cc17@mail.gmail.com> I have confirmed that this is correct with the AAPCS ABI doc. Looks like I got this wrong during migration to TableGen calling conventions. deep On Tue, Oct 27, 2009 at 5:51 AM, Rafael Espindola wrote: > This patch fixes the include testcase. The problem is that we were not > checking the alignment of arguments on the stack, so doubles would end > being 4 aligned instead of 8. > > Cheers, > -- > Rafael ?vila de Esp?ndola > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > From baldrick at free.fr Tue Oct 27 05:12:37 2009 From: baldrick at free.fr (Duncan Sands) Date: Tue, 27 Oct 2009 10:12:37 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r85224 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200910271012.n9RACbh8020093@zion.cs.uiuc.edu> Author: baldrick Date: Tue Oct 27 05:12:37 2009 New Revision: 85224 URL: http://llvm.org/viewvc/llvm-project?rev=85224&view=rev Log: Port r85218 (baldrick) from dragonegg: Only perform this somewhat dubious transform if it is known with certainty to be correct for the language. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=85224&r1=85223&r2=85224&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Oct 27 05:12:37 2009 @@ -404,27 +404,17 @@ return false; } - -/// isCompilingCCode - Return true if we are compiling C or Objective-C code. -static bool isCompilingCCode() { +/// LanguageIsC - Return true if we are compiling C or Objective-C. +static bool LanguageIsC() { // If we've already determined this, return it. static unsigned Val = 2; if (Val != 2) return (bool)Val; - + StringRef LanguageName = lang_hooks.name; - + if (LanguageName == "GNU C" || LanguageName == "GNU Objective-C") return (Val = true); - - if (LanguageName == "GNU C++" || - LanguageName == "GNU Ada" || - LanguageName == "GNU F77" || - LanguageName == "GNU Pascal" || - LanguageName == "GNU Java" || - LanguageName == "GNU Objective-C++") - return (Val = false); - - return (Val = true); + return (Val = false); } void TreeToLLVM::StartFunctionBody() { @@ -447,7 +437,7 @@ // // Note that we only do this in C/Objective-C. Doing this in C++ for // functions explicitly declared as taking (...) is bad. - if (TYPE_ARG_TYPES(TREE_TYPE(FnDecl)) == 0 && isCompilingCCode()) { + if (TYPE_ARG_TYPES(TREE_TYPE(FnDecl)) == 0 && LanguageIsC()) { FTy = TheTypeConverter->ConvertArgListToFnType(TREE_TYPE(FnDecl), DECL_ARGUMENTS(FnDecl), static_chain, From brukman at cs.uiuc.edu Tue Oct 27 09:27:03 2009 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue, 27 Oct 2009 09:27:03 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/pubs.js Message-ID: <200910271427.n9RER2aF030482@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: pubs.js updated: 1.69 -> 1.70 --- Log message: * Properly handle paper entries without a URL specified + when missing a URL, add a "search" link to be able to find the paper * Simplified the labeling of the histogram of papers per year --- Diffs of the changes: (+9 -4) pubs.js | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-) Index: llvm-www/pubs/pubs.js diff -u llvm-www/pubs/pubs.js:1.69 llvm-www/pubs/pubs.js:1.70 --- llvm-www/pubs/pubs.js:1.69 Mon Oct 26 01:29:24 2009 +++ llvm-www/pubs/pubs.js Tue Oct 27 09:25:46 2009 @@ -939,8 +939,14 @@ container.appendChild(list); } var item = document.createElement('li'); - item.innerHTML += '"' + htmlEscape(pub.title) + - '"
      '; + if (typeof pub.url != "undefined" && pub.url) { + item.innerHTML += '"' + htmlEscape(pub.title) + + '"
      '; + } else { + item.innerHTML += '"' + htmlEscape(pub.title) + '" ' + + 'search
      '; + } item.innerHTML += htmlEscape(pub.author) + '
      '; if (isDef(pub.published)) { item.innerHTML += '' + pub.published + ''; @@ -1009,8 +1015,7 @@ '?cht=bvs' + // vertical bars '&chs=300x200' + // size '&chco=76A4FB' + // color - '&chtt=Histogram' + // title - '&chdl=Count' + // label in legend + '&chtt=Number of papers per year' + // title '&chxt=x,y' + // axes '&chxl=0:|' + sortedYears.join('|') + // x-axis labels '&chxr=1,0,' + (maxCount + 5) + // y-axis range From eocallaghan at auroraux.org Tue Oct 27 09:54:47 2009 From: eocallaghan at auroraux.org (Edward O'Callaghan) Date: Tue, 27 Oct 2009 14:54:47 -0000 Subject: [llvm-commits] [llvm] r85241 - in /llvm/trunk/test/Analysis/ScalarEvolution: 2007-11-18-OrInstruction.ll 2008-07-29-SGTTripCount.ll 2008-07-29-SMinExpr.ll 2008-08-04-IVOverflow.ll 2008-08-04-LongAddRec.ll Message-ID: <200910271454.n9REslU8031568@zion.cs.uiuc.edu> Author: evocallaghan Date: Tue Oct 27 09:54:46 2009 New Revision: 85241 URL: http://llvm.org/viewvc/llvm-project?rev=85241&view=rev Log: Convert Analysis tests to FileCheck in regards to PR5307. Modified: llvm/trunk/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll llvm/trunk/test/Analysis/ScalarEvolution/2008-07-29-SGTTripCount.ll llvm/trunk/test/Analysis/ScalarEvolution/2008-07-29-SMinExpr.ll llvm/trunk/test/Analysis/ScalarEvolution/2008-08-04-IVOverflow.ll llvm/trunk/test/Analysis/ScalarEvolution/2008-08-04-LongAddRec.ll Modified: llvm/trunk/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll?rev=85241&r1=85240&r2=85241&view=diff ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll (original) +++ llvm/trunk/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll Tue Oct 27 09:54:46 2009 @@ -1,4 +1,4 @@ -; RUN: opt < %s -analyze -scalar-evolution -disable-output | grep -e {--> %b} +; RUN: opt < %s -analyze -scalar-evolution -disable-output | FileCheck %s ; PR1810 define void @fun() { @@ -16,3 +16,6 @@ exit: ret void } + +; CHECK: --> %b + Modified: llvm/trunk/test/Analysis/ScalarEvolution/2008-07-29-SGTTripCount.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-07-29-SGTTripCount.ll?rev=85241&r1=85240&r2=85241&view=diff ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/2008-07-29-SGTTripCount.ll (original) +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-07-29-SGTTripCount.ll Tue Oct 27 09:54:46 2009 @@ -1,6 +1,5 @@ ; RUN: opt < %s -analyze -scalar-evolution -disable-output \ -; RUN: -scalar-evolution-max-iterations=0 | \ -; RUN: grep -F "backedge-taken count is (-1 + (-1 * %j))" +; RUN: -scalar-evolution-max-iterations=0 | FileCheck %s ; PR2607 define i32 @_Z1aj(i32 %j) nounwind { @@ -25,3 +24,5 @@ ret i32 %i.0.lcssa } +; CHECK: backedge-taken count is (-1 + (-1 * %j)) + Modified: llvm/trunk/test/Analysis/ScalarEvolution/2008-07-29-SMinExpr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-07-29-SMinExpr.ll?rev=85241&r1=85240&r2=85241&view=diff ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/2008-07-29-SMinExpr.ll (original) +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-07-29-SMinExpr.ll Tue Oct 27 09:54:46 2009 @@ -1,6 +1,5 @@ ; RUN: opt < %s -analyze -scalar-evolution -disable-output \ -; RUN: -scalar-evolution-max-iterations=0 | \ -; RUN: grep -F "backedge-taken count is (-2147483632 + ((-1 + (-1 * %x)) smax (-1 + (-1 * %y))))" +; RUN: -scalar-evolution-max-iterations=0 | FileCheck %s ; PR2607 define i32 @b(i32 %x, i32 %y) nounwind { @@ -22,3 +21,6 @@ %j.0.lcssa = phi i32 [ -2147483632, %entry ], [ %dec, %forinc ] ret i32 %j.0.lcssa } + +; CHECK: backedge-taken count is (-2147483632 + ((-1 + (-1 * %x)) smax (-1 + (-1 * %y)))) + Modified: llvm/trunk/test/Analysis/ScalarEvolution/2008-08-04-IVOverflow.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-08-04-IVOverflow.ll?rev=85241&r1=85240&r2=85241&view=diff ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/2008-08-04-IVOverflow.ll (original) +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-08-04-IVOverflow.ll Tue Oct 27 09:54:46 2009 @@ -1,5 +1,5 @@ ; RUN: opt < %s -analyze -scalar-evolution -disable-output \ -; RUN: -scalar-evolution-max-iterations=0 | grep -F "Exits: 20028" +; RUN: -scalar-evolution-max-iterations=0 | FileCheck %s ; PR2621 define i32 @a() nounwind { @@ -23,3 +23,5 @@ ret i32 %4 } +; CHECK: Exits: 20028 + Modified: llvm/trunk/test/Analysis/ScalarEvolution/2008-08-04-LongAddRec.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2008-08-04-LongAddRec.ll?rev=85241&r1=85240&r2=85241&view=diff ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/2008-08-04-LongAddRec.ll (original) +++ llvm/trunk/test/Analysis/ScalarEvolution/2008-08-04-LongAddRec.ll Tue Oct 27 09:54:46 2009 @@ -1,5 +1,5 @@ ; RUN: opt < %s -analyze -scalar-evolution -disable-output \ -; RUN: -scalar-evolution-max-iterations=0 | grep -F "Exits: -19168" +; RUN: -scalar-evolution-max-iterations=0 | FileCheck %s ; PR2621 define i32 @a() nounwind { @@ -54,3 +54,5 @@ ret i32 %19 } +; CHECK: Exits: -19168 + From echristo at apple.com Tue Oct 27 11:16:00 2009 From: echristo at apple.com (Eric Christopher) Date: Tue, 27 Oct 2009 09:16:00 -0700 Subject: [llvm-commits] [llvm] r85189 - in /llvm/trunk: include/llvm/Intrinsics.td lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp lib/Transforms/Scalar/SimplifyLibCalls.cpp In-Reply-To: <4AE6B388.3090909@free.fr> References: <200910270052.n9R0qPfC015484@zion.cs.uiuc.edu> <4AE6B388.3090909@free.fr> Message-ID: On Oct 27, 2009, at 1:47 AM, Duncan Sands wrote: > Hi Eric, > >> Add objectsize intrinsic and hook it up through codegen. Doesn't >> do anything than return "I don't know" at the moment. > > this is maybe the most horrible gcc builtin ever invented! Is it > really a good idea to duplicate it in LLVM? I know it's more work, > but I'd much rather BUILTIN_OBJECT_SIZE was mapped to a bunch of > code and perhaps several LLVM intrinsics, but where the intrinsics > each have a clear, clean, sensible and logical definition... It's largely a builtin for library implementers, not for the general public. It will need to be mapped to a bit of code eventually, but I'm not really sure what you want for several intrinsics though. -eric From rafael.espindola at gmail.com Tue Oct 27 09:09:46 2009 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Tue, 27 Oct 2009 14:09:46 -0000 Subject: [llvm-commits] [llvm] r85235 - /llvm/trunk/lib/Target/ARM/ARMCallingConv.td Message-ID: <200910271409.n9RE9kS7029734@zion.cs.uiuc.edu> Author: rafael Date: Tue Oct 27 09:09:44 2009 New Revision: 85235 URL: http://llvm.org/viewvc/llvm-project?rev=85235&view=rev Log: Correctly align double arguments in the stack. Modified: llvm/trunk/lib/Target/ARM/ARMCallingConv.td Modified: llvm/trunk/lib/Target/ARM/ARMCallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCallingConv.td?rev=85235&r1=85234&r2=85235&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMCallingConv.td (original) +++ llvm/trunk/lib/Target/ARM/ARMCallingConv.td Tue Oct 27 09:09:44 2009 @@ -68,6 +68,7 @@ "ArgFlags.getOrigAlign() != 8", CCAssignToReg<[R0, R1, R2, R3]>>>, + CCIfType<[i32], CCIfAlign<"8", CCAssignToStack<4, 8>>>, CCIfType<[i32, f32], CCAssignToStack<4, 4>>, CCIfType<[f64], CCAssignToStack<8, 8>>, CCIfType<[v2f64], CCAssignToStack<16, 8>> From sabre at nondot.org Tue Oct 27 11:49:53 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 16:49:53 -0000 Subject: [llvm-commits] [llvm] r85248 - /llvm/trunk/include/llvm/Instructions.h Message-ID: <200910271649.n9RGnrm1003803@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 11:49:53 2009 New Revision: 85248 URL: http://llvm.org/viewvc/llvm-project?rev=85248&view=rev Log: remove an unneeded #include. Modified: llvm/trunk/include/llvm/Instructions.h Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=85248&r1=85247&r2=85248&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Tue Oct 27 11:49:53 2009 @@ -19,7 +19,6 @@ #include "llvm/InstrTypes.h" #include "llvm/DerivedTypes.h" #include "llvm/Attributes.h" -#include "llvm/BasicBlock.h" #include "llvm/CallingConv.h" #include "llvm/LLVMContext.h" #include "llvm/ADT/SmallVector.h" @@ -1797,7 +1796,7 @@ void setIncomingBlock(unsigned i, BasicBlock *BB) { - setOperand(i*2+1, BB); + setOperand(i*2+1, (Value*)BB); } static unsigned getOperandNumForIncomingBlock(unsigned i) { return i*2+1; @@ -1820,7 +1819,7 @@ // Initialize some new operands. NumOperands = OpNo+2; OperandList[OpNo] = V; - OperandList[OpNo+1] = BB; + OperandList[OpNo+1] = (Value*)BB; } /// removeIncomingValue - Remove an incoming value. This is useful if a @@ -1845,7 +1844,7 @@ int getBasicBlockIndex(const BasicBlock *BB) const { Use *OL = OperandList; for (unsigned i = 0, e = getNumOperands(); i != e; i += 2) - if (OL[i+1].get() == BB) return i/2; + if (OL[i+1].get() == (const Value*)BB) return i/2; return -1; } @@ -2024,7 +2023,7 @@ // targeting the specified block. // FIXME: Eliminate this ugly method. void setUnconditionalDest(BasicBlock *Dest) { - Op<-1>() = Dest; + Op<-1>() = (Value*)Dest; if (isConditional()) { // Convert this to an uncond branch. Op<-2>() = 0; Op<-3>() = 0; @@ -2042,7 +2041,7 @@ void setSuccessor(unsigned idx, BasicBlock *NewSucc) { assert(idx < getNumSuccessors() && "Successor # out of range for Branch!"); - *(&Op<-1>() - idx) = NewSucc; + *(&Op<-1>() - idx) = (Value*)NewSucc; } // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -2184,7 +2183,7 @@ } void setSuccessor(unsigned idx, BasicBlock *NewSucc) { assert(idx < getNumSuccessors() && "Successor # out of range for switch!"); - setOperand(idx*2+1, NewSucc); + setOperand(idx*2+1, (Value*)NewSucc); } // getSuccessorValue - Return the value associated with the specified @@ -2393,11 +2392,11 @@ return cast(getOperand(2)); } void setNormalDest(BasicBlock *B) { - setOperand(1, B); + setOperand(1, (Value*)B); } void setUnwindDest(BasicBlock *B) { - setOperand(2, B); + setOperand(2, (Value*)B); } BasicBlock *getSuccessor(unsigned i) const { @@ -2407,7 +2406,7 @@ void setSuccessor(unsigned idx, BasicBlock *NewSucc) { assert(idx < 2 && "Successor # out of range for invoke!"); - setOperand(idx+1, NewSucc); + setOperand(idx+1, (Value*)NewSucc); } unsigned getNumSuccessors() const { return 2; } From sabre at nondot.org Tue Oct 27 11:53:54 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 16:53:54 -0000 Subject: [llvm-commits] [llvm] r85250 - /llvm/trunk/include/llvm/Instructions.h Message-ID: <200910271653.n9RGrsj3003990@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 11:53:54 2009 New Revision: 85250 URL: http://llvm.org/viewvc/llvm-project?rev=85250&view=rev Log: trim another #include Modified: llvm/trunk/include/llvm/Instructions.h Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=85250&r1=85249&r2=85250&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Tue Oct 27 11:53:54 2009 @@ -20,7 +20,6 @@ #include "llvm/DerivedTypes.h" #include "llvm/Attributes.h" #include "llvm/CallingConv.h" -#include "llvm/LLVMContext.h" #include "llvm/ADT/SmallVector.h" #include From nicholas at mxc.ca Tue Oct 27 11:56:58 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Tue, 27 Oct 2009 16:56:58 -0000 Subject: [llvm-commits] [llvm] r85251 - /llvm/trunk/docs/LangRef.html Message-ID: <200910271656.n9RGuw9R004094@zion.cs.uiuc.edu> Author: nicholas Date: Tue Oct 27 11:56:58 2009 New Revision: 85251 URL: http://llvm.org/viewvc/llvm-project?rev=85251&view=rev Log: Fix reversed logic spotted by Owen Anderson. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=85251&r1=85250&r2=85251&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Tue Oct 27 11:56:58 2009 @@ -6966,8 +6966,8 @@
      Semantics:

      This intrinsic indicates that before this point in the code, the value of the memory pointed to by ptr is dead. This means that it is known to - never be used and has an undefined value. A load from the pointer that is - preceded by this intrinsic can be replaced with + never be used and has an undefined value. A load from the pointer that + precedes this intrinsic can be replaced with 'undef'.

      From sabre at nondot.org Tue Oct 27 12:01:03 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 17:01:03 -0000 Subject: [llvm-commits] [llvm] r85252 - /llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Message-ID: <200910271701.n9RH137s004245@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 12:01:03 2009 New Revision: 85252 URL: http://llvm.org/viewvc/llvm-project?rev=85252&view=rev Log: apparently the X86 JIT isn't fully contextized, it is still using getGlobalContext() :( Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp?rev=85252&r1=85251&r2=85252&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Tue Oct 27 12:01:03 2009 @@ -19,6 +19,7 @@ #include "X86TargetMachine.h" #include "X86Relocations.h" #include "X86.h" +#include "llvm/LLVMContext.h" #include "llvm/PassManager.h" #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/JITCodeEmitter.h" From sabre at nondot.org Tue Oct 27 12:02:08 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 17:02:08 -0000 Subject: [llvm-commits] [llvm] r85253 - in /llvm/trunk/lib/CodeGen: PseudoSourceValue.cpp SelectionDAG/SelectionDAGISel.cpp Message-ID: <200910271702.n9RH28dI004293@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 12:02:08 2009 New Revision: 85253 URL: http://llvm.org/viewvc/llvm-project?rev=85253&view=rev Log: pseudosourcevalue is also still using getGlobalContext(), so it isn't thread safe either. Modified: llvm/trunk/lib/CodeGen/PseudoSourceValue.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/PseudoSourceValue.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PseudoSourceValue.cpp?rev=85253&r1=85252&r2=85253&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PseudoSourceValue.cpp (original) +++ llvm/trunk/lib/CodeGen/PseudoSourceValue.cpp Tue Oct 27 12:02:08 2009 @@ -14,6 +14,7 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/DerivedTypes.h" +#include "llvm/LLVMContext.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=85253&r1=85252&r2=85253&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Oct 27 12:02:08 2009 @@ -26,6 +26,7 @@ #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" #include "llvm/IntrinsicInst.h" +#include "llvm/LLVMContext.h" #include "llvm/CodeGen/FastISel.h" #include "llvm/CodeGen/GCStrategy.h" #include "llvm/CodeGen/GCMetadata.h" From sabre at nondot.org Tue Oct 27 12:08:32 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 17:08:32 -0000 Subject: [llvm-commits] [llvm] r85254 - in /llvm/trunk: include/llvm/Type.h lib/Bitcode/Writer/BitcodeWriter.cpp lib/Bitcode/Writer/ValueEnumerator.cpp lib/VMCore/AsmWriter.cpp unittests/ADT/ValueMapTest.cpp unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp unittests/Support/ValueHandleTest.cpp unittests/Transforms/Utils/Cloning.cpp unittests/VMCore/MetadataTest.cpp Message-ID: <200910271708.n9RH8Wgr004629@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 12:08:31 2009 New Revision: 85254 URL: http://llvm.org/viewvc/llvm-project?rev=85254&view=rev Log: Type.h doesn't need to #include LLVMContext.h Modified: llvm/trunk/include/llvm/Type.h llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp llvm/trunk/lib/VMCore/AsmWriter.cpp llvm/trunk/unittests/ADT/ValueMapTest.cpp llvm/trunk/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp llvm/trunk/unittests/Support/ValueHandleTest.cpp llvm/trunk/unittests/Transforms/Utils/Cloning.cpp llvm/trunk/unittests/VMCore/MetadataTest.cpp Modified: llvm/trunk/include/llvm/Type.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Type.h?rev=85254&r1=85253&r2=85254&view=diff ============================================================================== --- llvm/trunk/include/llvm/Type.h (original) +++ llvm/trunk/include/llvm/Type.h Tue Oct 27 12:08:31 2009 @@ -12,7 +12,6 @@ #define LLVM_TYPE_H #include "llvm/AbstractTypeUser.h" -#include "llvm/LLVMContext.h" #include "llvm/Support/Casting.h" #include "llvm/System/DataTypes.h" #include "llvm/System/Atomic.h" @@ -28,6 +27,7 @@ class TypeMapBase; class raw_ostream; class Module; +class LLVMContext; /// This file contains the declaration of the Type class. For more "Type" type /// stuff, look in DerivedTypes.h. Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=85254&r1=85253&r2=85254&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Tue Oct 27 12:08:31 2009 @@ -19,6 +19,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/InlineAsm.h" #include "llvm/Instructions.h" +#include "llvm/LLVMContext.h" #include "llvm/Metadata.h" #include "llvm/Module.h" #include "llvm/Operator.h" Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp?rev=85254&r1=85253&r2=85254&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp Tue Oct 27 12:08:31 2009 @@ -14,6 +14,7 @@ #include "ValueEnumerator.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/LLVMContext.h" #include "llvm/Metadata.h" #include "llvm/Module.h" #include "llvm/TypeSymbolTable.h" Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=85254&r1=85253&r2=85254&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/AsmWriter.cpp (original) +++ llvm/trunk/lib/VMCore/AsmWriter.cpp Tue Oct 27 12:08:31 2009 @@ -23,6 +23,7 @@ #include "llvm/InlineAsm.h" #include "llvm/Instruction.h" #include "llvm/Instructions.h" +#include "llvm/LLVMContext.h" #include "llvm/Operator.h" #include "llvm/Metadata.h" #include "llvm/Module.h" Modified: llvm/trunk/unittests/ADT/ValueMapTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/ValueMapTest.cpp?rev=85254&r1=85253&r2=85254&view=diff ============================================================================== --- llvm/trunk/unittests/ADT/ValueMapTest.cpp (original) +++ llvm/trunk/unittests/ADT/ValueMapTest.cpp Tue Oct 27 12:08:31 2009 @@ -8,8 +8,8 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/ValueMap.h" - #include "llvm/Instructions.h" +#include "llvm/LLVMContext.h" #include "llvm/ADT/OwningPtr.h" #include "gtest/gtest.h" Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp?rev=85254&r1=85253&r2=85254&view=diff ============================================================================== --- llvm/trunk/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp (original) +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp Tue Oct 27 12:08:31 2009 @@ -13,6 +13,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/GlobalValue.h" +#include "llvm/LLVMContext.h" using namespace llvm; Modified: llvm/trunk/unittests/Support/ValueHandleTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/ValueHandleTest.cpp?rev=85254&r1=85253&r2=85254&view=diff ============================================================================== --- llvm/trunk/unittests/Support/ValueHandleTest.cpp (original) +++ llvm/trunk/unittests/Support/ValueHandleTest.cpp Tue Oct 27 12:08:31 2009 @@ -11,6 +11,7 @@ #include "llvm/Constants.h" #include "llvm/Instructions.h" +#include "llvm/LLVMContext.h" #include "llvm/ADT/OwningPtr.h" #include "gtest/gtest.h" Modified: llvm/trunk/unittests/Transforms/Utils/Cloning.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/Cloning.cpp?rev=85254&r1=85253&r2=85254&view=diff ============================================================================== --- llvm/trunk/unittests/Transforms/Utils/Cloning.cpp (original) +++ llvm/trunk/unittests/Transforms/Utils/Cloning.cpp Tue Oct 27 12:08:31 2009 @@ -10,6 +10,7 @@ #include "gtest/gtest.h" #include "llvm/Argument.h" #include "llvm/Instructions.h" +#include "llvm/LLVMContext.h" using namespace llvm; Modified: llvm/trunk/unittests/VMCore/MetadataTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/VMCore/MetadataTest.cpp?rev=85254&r1=85253&r2=85254&view=diff ============================================================================== --- llvm/trunk/unittests/VMCore/MetadataTest.cpp (original) +++ llvm/trunk/unittests/VMCore/MetadataTest.cpp Tue Oct 27 12:08:31 2009 @@ -10,6 +10,7 @@ #include "gtest/gtest.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" +#include "llvm/LLVMContext.h" #include "llvm/Metadata.h" #include "llvm/Module.h" #include "llvm/Type.h" From bob.wilson at apple.com Tue Oct 27 12:06:45 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 27 Oct 2009 10:06:45 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r85190 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: <200910270053.n9R0rkqP015550@zion.cs.uiuc.edu> References: <200910270053.n9R0rkqP015550@zion.cs.uiuc.edu> Message-ID: <317FD6A5-E55F-4B1A-BD36-1FDF981F115E@apple.com> Eric, my debug build of llvm is failing and it seems to be related to this change: make -C libprofile all llvm[2]: Compiling CommonProfiling.ll to CommonProfiling.bc for Debug build (bytecode) /Users/bwilson/local/llvm/objdir/Debug/bin/opt /Volumes/LocalHD/ bwilson/llvm/objdir/runtime/libprofile/Debug/CommonProfiling.ll -std- compile-opts -strip-debug -o /Volumes/LocalHD/bwilson/llvm/objdir/ runtime/libprofile/Debug/CommonProfiling.bc /Users/bwilson/local/llvm/objdir/Debug/bin/opt: /Volumes/LocalHD/ bwilson/llvm/objdir/runtime/libprofile/Debug/CommonProfiling.ll: 251:19: error: '@llvm.objectsize.i64' defined with type 'i64 (i8**, i32)*' %125 = call i64 @llvm.objectsize.i64(i8* %124, i32 0), !dbg !38 ; [#uses=1] ^ make[2]: *** [/Volumes/LocalHD/bwilson/llvm/objdir/runtime/libprofile/ Debug/CommonProfiling.bc] Error 1 make[1]: *** [libprofile/.makeall] Error 2 make: *** [all] Error 1 This did not happen when the llvm-gcc used to compile CommonProfiling.c did not include this patch. Can you please investigate? Thanks. On Oct 26, 2009, at 5:53 PM, Eric Christopher wrote: > Author: echristo > Date: Mon Oct 26 19:53:46 2009 > New Revision: 85190 > > URL: http://llvm.org/viewvc/llvm-project?rev=85190&view=rev > Log: > Use new objectsize intrinsic for object size checking instead of > folding to "don't know" immediately. > > Modified: > llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp > > Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=85190&r1=85189&r2=85190&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) > +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Oct 26 19:53:46 2009 > @@ -4976,12 +4976,12 @@ > return EmitBuiltinUnwindInit(exp, Result); > > case BUILT_IN_OBJECT_SIZE: { > - tree ArgList = TREE_OPERAND (exp, 1); > - if (!validate_arglist(ArgList, POINTER_TYPE, INTEGER_TYPE, > VOID_TYPE)) { > + tree arglist = TREE_OPERAND (exp, 1); > + if (!validate_arglist(arglist, POINTER_TYPE, INTEGER_TYPE, > VOID_TYPE)) { > error("Invalid builtin_object_size argument types"); > return false; > } > - tree ObjSizeTree = TREE_VALUE (TREE_CHAIN (ArgList)); > + tree ObjSizeTree = TREE_VALUE (TREE_CHAIN (arglist)); > STRIP_NOPS (ObjSizeTree); > if (TREE_CODE (ObjSizeTree) != INTEGER_CST > || tree_int_cst_sgn (ObjSizeTree) < 0 > @@ -4990,12 +4990,24 @@ > return false; > } > > - // This treats everything as unknown, and is minimally > defensible as > - // correct, although completely useless. > - if (tree_low_cst (ObjSizeTree, 0) < 2) > - Result = Constant::getAllOnesValue(TD.getIntPtrType(Context)); > - else > - Result = ConstantInt::get(TD.getIntPtrType(Context), 0); > + tree Object = TREE_VALUE(arglist); > + tree ObjTy = TREE_VALUE(TREE_CHAIN(arglist)); > + > + Value* Args[] = { > + Emit(Object, 0), > + Emit(ObjTy, 0) > + }; > + > + const Type* Ty[3]; > + Ty[0] = ConvertType(TREE_TYPE(exp)); > + Ty[1] = Type::getInt8PtrTy(Context); > + Ty[2] = Type::getInt32Ty(Context); > + > + Result = Builder.CreateCall(Intrinsic::getDeclaration(TheModule, > + Intrinsic::objectsize, > + Ty, > + 1), > + Args, Args + 2); > return true; > } > // Unary bit counting intrinsics. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From bob.wilson at apple.com Tue Oct 27 12:08:32 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 27 Oct 2009 10:08:32 -0700 Subject: [llvm-commits] [llvm] r85235 - /llvm/trunk/lib/Target/ARM/ARMCallingConv.td In-Reply-To: <200910271409.n9RE9kS7029734@zion.cs.uiuc.edu> References: <200910271409.n9RE9kS7029734@zion.cs.uiuc.edu> Message-ID: <770A702D-91C9-421E-B1A7-7E6460EBDAAC@apple.com> What happened to the testcase that was in the patch you sent? On Oct 27, 2009, at 7:09 AM, Rafael Espindola wrote: > Author: rafael > Date: Tue Oct 27 09:09:44 2009 > New Revision: 85235 > > URL: http://llvm.org/viewvc/llvm-project?rev=85235&view=rev > Log: > Correctly align double arguments in the stack. > > Modified: > llvm/trunk/lib/Target/ARM/ARMCallingConv.td > > Modified: llvm/trunk/lib/Target/ARM/ARMCallingConv.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCallingConv.td?rev=85235&r1=85234&r2=85235&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMCallingConv.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMCallingConv.td Tue Oct 27 09:09:44 > 2009 > @@ -68,6 +68,7 @@ > "ArgFlags.getOrigAlign() != 8", > CCAssignToReg<[R0, R1, R2, R3]>>>, > > + CCIfType<[i32], CCIfAlign<"8", CCAssignToStack<4, 8>>>, > CCIfType<[i32, f32], CCAssignToStack<4, 4>>, > CCIfType<[f64], CCAssignToStack<8, 8>>, > CCIfType<[v2f64], CCAssignToStack<16, 8>> > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From johnny.chen at apple.com Tue Oct 27 12:25:15 2009 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 27 Oct 2009 17:25:15 -0000 Subject: [llvm-commits] [llvm] r85255 - /llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Message-ID: <200910271725.n9RHPFOY005276@zion.cs.uiuc.edu> Author: johnny Date: Tue Oct 27 12:25:15 2009 New Revision: 85255 URL: http://llvm.org/viewvc/llvm-project?rev=85255&view=rev Log: Test commit. Added '.' to the comment line. Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=85255&r1=85254&r2=85255&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Tue Oct 27 12:25:15 2009 @@ -284,7 +284,7 @@ } } - // Otherwise this is R +/- [possibly shifted] R + // Otherwise this is R +/- [possibly shifted] R. ARM_AM::AddrOpc AddSub = N.getOpcode() == ISD::ADD ? ARM_AM::add:ARM_AM::sub; ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(1)); unsigned ShAmt = 0; From grosbach at apple.com Tue Oct 27 12:30:05 2009 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 27 Oct 2009 10:30:05 -0700 Subject: [llvm-commits] [llvm] r85184 - in /llvm/trunk/lib/Target/ARM: ARMInstrThumb.td ARMInstrThumb2.td In-Reply-To: <200910270008.n9R08xTj013255@zion.cs.uiuc.edu> References: <200910270008.n9R08xTj013255@zion.cs.uiuc.edu> Message-ID: <6496D214-A96A-4308-9FD4-74A453B5ECD0@apple.com> I was planning on doing this after the unified syntax patch unblocks. As is, doing this (especially the VFP portion) first breaks that patch rather horribly. -j On Oct 26, 2009, at 5:08 PM, Evan Cheng wrote: > Author: evancheng > Date: Mon Oct 26 19:08:59 2009 > New Revision: 85184 > > URL: http://llvm.org/viewvc/llvm-project?rev=85184&view=rev > Log: > Change Thumb1 and Thumb2 instructions to separate opcode from > operands with a tab instead of a space. > > Modified: > llvm/trunk/lib/Target/ARM/ARMInstrThumb.td > llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=85184&r1=85183&r2=85184&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Mon Oct 26 19:08:59 > 2009 > @@ -130,44 +130,44 @@ > // For both thumb1 and thumb2. > let isNotDuplicable = 1 in > def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), > IIC_iALUr, > - "\n$cp:\n\tadd $dst, pc", > + "\n$cp:\n\tadd\t$dst, pc", > [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>; > > // PC relative add. > def tADDrPCi : T1I<(outs tGPR:$dst), (ins i32imm:$rhs), IIC_iALUi, > - "add $dst, pc, $rhs * 4", []>; > + "add\t$dst, pc, $rhs * 4", []>; > > // ADD rd, sp, #imm8 > def tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, i32imm:$rhs), > IIC_iALUi, > - "add $dst, $sp, $rhs * 4", []>; > + "add\t$dst, $sp, $rhs * 4", []>; > > // ADD sp, sp, #imm7 > def tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > IIC_iALUi, > - "add $dst, $rhs * 4", []>; > + "add\t$dst, $rhs * 4", []>; > > // SUB sp, sp, #imm7 > def tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > IIC_iALUi, > - "sub $dst, $rhs * 4", []>; > + "sub\t$dst, $rhs * 4", []>; > > // ADD rm, sp > def tADDrSP : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > IIC_iALUr, > - "add $dst, $rhs", []>; > + "add\t$dst, $rhs", []>; > > // ADD sp, rm > def tADDspr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > IIC_iALUr, > - "add $dst, $rhs", []>; > + "add\t$dst, $rhs", []>; > > // Pseudo instruction that will expand into a tSUBspi + a copy. > let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. > def tSUBspi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, i32imm: > $rhs), > - NoItinerary, "@ sub $dst, $rhs * 4", []>; > + NoItinerary, "@ sub\t$dst, $rhs * 4", []>; > > def tADDspr_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > - NoItinerary, "@ add $dst, $rhs", []>; > + NoItinerary, "@ add\t$dst, $rhs", []>; > > let Defs = [CPSR] in > def tANDsp : PseudoInst<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > - NoItinerary, "@ and $dst, $rhs", []>; > + NoItinerary, "@ and\t$dst, $rhs", []>; > } // usesCustomDAGSchedInserter > > // > = > = > = > ----------------------------------------------------------------------= > ==// > @@ -175,16 +175,16 @@ > // > > let isReturn = 1, isTerminator = 1, isBarrier = 1 in { > - def tBX_RET : TI<(outs), (ins), IIC_Br, "bx lr", [(ARMretflag)]>; > + def tBX_RET : TI<(outs), (ins), IIC_Br, "bx\tlr", [(ARMretflag)]>; > // Alternative return instruction used by vararg functions. > - def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx > $target", []>; > + def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t > $target", []>; > } > > // FIXME: remove when we have a way to marking a MI with these > properties. > let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, > hasExtraDefRegAllocReq = 1 in > def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), > IIC_Br, > - "pop${p} $wb", []>; > + "pop${p}\t$wb", []>; > > let isCall = 1, > Defs = [R0, R1, R2, R3, R12, LR, > @@ -193,25 +193,25 @@ > D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { > // Also used for Thumb2 > def tBL : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, > - "bl ${func:call}", > + "bl\t${func:call}", > [(ARMtcall tglobaladdr:$func)]>, > Requires<[IsThumb, IsNotDarwin]>; > > // ARMv5T and above, also used for Thumb2 > def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, > - "blx ${func:call}", > + "blx\t${func:call}", > [(ARMcall tglobaladdr:$func)]>, > Requires<[IsThumb, HasV5T, IsNotDarwin]>; > > // Also used for Thumb2 > def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, > - "blx $func", > + "blx\t$func", > [(ARMtcall GPR:$func)]>, > Requires<[IsThumb, HasV5T, IsNotDarwin]>; > > // ARMv4T > def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, > - "mov lr, pc\n\tbx $func", > + "mov\tlr, pc\n\tbx\t$func", > [(ARMcall_nolink tGPR:$func)]>, > Requires<[IsThumb1Only, IsNotDarwin]>; > } > @@ -224,25 +224,25 @@ > D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { > // Also used for Thumb2 > def tBLr9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, > - "bl ${func:call}", > + "bl\t${func:call}", > [(ARMtcall tglobaladdr:$func)]>, > Requires<[IsThumb, IsDarwin]>; > > // ARMv5T and above, also used for Thumb2 > def tBLXi_r9 : TIx2<(outs), (ins i32imm:$func, variable_ops), > IIC_Br, > - "blx ${func:call}", > + "blx\t${func:call}", > [(ARMcall tglobaladdr:$func)]>, > Requires<[IsThumb, HasV5T, IsDarwin]>; > > // Also used for Thumb2 > def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, > - "blx $func", > + "blx\t$func", > [(ARMtcall GPR:$func)]>, > Requires<[IsThumb, HasV5T, IsDarwin]>; > > // ARMv4T > def tBXr9 : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, > - "mov lr, pc\n\tbx $func", > + "mov\tlr, pc\n\tbx\t$func", > [(ARMcall_nolink tGPR:$func)]>, > Requires<[IsThumb1Only, IsDarwin]>; > } > @@ -251,16 +251,16 @@ > let isBarrier = 1 in { > let isPredicable = 1 in > def tB : T1I<(outs), (ins brtarget:$target), IIC_Br, > - "b $target", [(br bb:$target)]>; > + "b\t$target", [(br bb:$target)]>; > > // Far jump > let Defs = [LR] in > def tBfar : TIx2<(outs), (ins brtarget:$target), IIC_Br, > - "bl $target\t@ far jump",[]>; > + "bl\t$target\t@ far jump",[]>; > > def tBR_JTr : T1JTI<(outs), > (ins tGPR:$target, jtblock_operand:$jt, i32imm: > $id), > - IIC_Br, "mov pc, $target\n\t.align\t2\n$jt", > + IIC_Br, "mov\tpc, $target\n\t.align\t2\n$jt", > [(ARMbrjt tGPR:$target, tjumptable:$jt, imm: > $id)]>; > } > } > @@ -269,7 +269,7 @@ > // a two-value operand where a dag node expects two operands. :( > let isBranch = 1, isTerminator = 1 in > def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), IIC_Br, > - "b$cc $target", > + "b$cc\t$target", > [/*(ARMbrcond bb:$target, imm:$cc)*/]>; > > // > = > = > = > ----------------------------------------------------------------------= > ==// > @@ -278,70 +278,70 @@ > > let canFoldAsLoad = 1 in > def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), > IIC_iLoadr, > - "ldr", " $dst, $addr", > + "ldr", "\t$dst, $addr", > [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>; > > def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), > IIC_iLoadr, > - "ldrb", " $dst, $addr", > + "ldrb", "\t$dst, $addr", > [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; > > def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), > IIC_iLoadr, > - "ldrh", " $dst, $addr", > + "ldrh", "\t$dst, $addr", > [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>; > > let AddedComplexity = 10 in > def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), > IIC_iLoadr, > - "ldrsb", " $dst, $addr", > + "ldrsb", "\t$dst, $addr", > [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>; > > let AddedComplexity = 10 in > def tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), > IIC_iLoadr, > - "ldrsh", " $dst, $addr", > + "ldrsh", "\t$dst, $addr", > [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))] > >; > > let canFoldAsLoad = 1 in > def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), > IIC_iLoadi, > - "ldr", " $dst, $addr", > + "ldr", "\t$dst, $addr", > [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>; > > // Special instruction for restore. It cannot clobber condition > register > // when it's expanded by eliminateCallFramePseudoInstr(). > let canFoldAsLoad = 1, mayLoad = 1 in > def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), > IIC_iLoadi, > - "ldr", " $dst, $addr", []>; > + "ldr", "\t$dst, $addr", []>; > > // Load tconstpool > let canFoldAsLoad = 1 in > def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, > - "ldr", " $dst, $addr", > + "ldr", "\t$dst, $addr", > [(set tGPR:$dst, (load (ARMWrapper tconstpool: > $addr)))]>; > > // Special LDR for loads from non-pc-relative constpools. > let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in > def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, > - "ldr", " $dst, $addr", []>; > + "ldr", "\t$dst, $addr", []>; > > def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), > IIC_iStorer, > - "str", " $src, $addr", > + "str", "\t$src, $addr", > [(store tGPR:$src, t_addrmode_s4:$addr)]>; > > def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), > IIC_iStorer, > - "strb", " $src, $addr", > + "strb", "\t$src, $addr", > [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>; > > def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), > IIC_iStorer, > - "strh", " $src, $addr", > + "strh", "\t$src, $addr", > [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>; > > def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), > IIC_iStorei, > - "str", " $src, $addr", > + "str", "\t$src, $addr", > [(store tGPR:$src, t_addrmode_sp:$addr)]>; > > let mayStore = 1 in { > // Special instruction for spill. It cannot clobber condition register > // when it's expanded by eliminateCallFramePseudoInstr(). > def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), > IIC_iStorei, > - "str", " $src, $addr", []>; > + "str", "\t$src, $addr", []>; > } > > // > = > = > = > ----------------------------------------------------------------------= > ==// > @@ -353,21 +353,21 @@ > def tLDM : T1I<(outs), > (ins addrmode4:$addr, pred:$p, reglist:$wb, > variable_ops), > IIC_iLoadm, > - "ldm${addr:submode}${p} $addr, $wb", []>; > + "ldm${addr:submode}${p}\t$addr, $wb", []>; > > let mayStore = 1, hasExtraSrcRegAllocReq = 1 in > def tSTM : T1I<(outs), > (ins addrmode4:$addr, pred:$p, reglist:$wb, > variable_ops), > IIC_iStorem, > - "stm${addr:submode}${p} $addr, $wb", []>; > + "stm${addr:submode}${p}\t$addr, $wb", []>; > > let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = > 1 in > def tPOP : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), > IIC_Br, > - "pop${p} $wb", []>; > + "pop${p}\t$wb", []>; > > let mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = > 1 in > def tPUSH : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), > IIC_Br, > - "push${p} $wb", []>; > + "push${p}\t$wb", []>; > > // > = > = > = > ----------------------------------------------------------------------= > ==// > // Arithmetic Instructions. > @@ -376,66 +376,66 @@ > // Add with carry register > let isCommutable = 1, Uses = [CPSR] in > def tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > IIC_iALUr, > - "adc", " $dst, $rhs", > + "adc", "\t$dst, $rhs", > [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>; > > // Add immediate > def tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > IIC_iALUi, > - "add", " $dst, $lhs, $rhs", > + "add", "\t$dst, $lhs, $rhs", > [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>; > > def tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > IIC_iALUi, > - "add", " $dst, $rhs", > + "add", "\t$dst, $rhs", > [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>; > > // Add register > let isCommutable = 1 in > def tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > IIC_iALUr, > - "add", " $dst, $lhs, $rhs", > + "add", "\t$dst, $lhs, $rhs", > [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>; > > let neverHasSideEffects = 1 in > def tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > IIC_iALUr, > - "add", " $dst, $rhs", []>; > + "add", "\t$dst, $rhs", []>; > > // And register > let isCommutable = 1 in > def tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > IIC_iALUr, > - "and", " $dst, $rhs", > + "and", "\t$dst, $rhs", > [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>; > > // ASR immediate > def tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > IIC_iMOVsi, > - "asr", " $dst, $lhs, $rhs", > + "asr", "\t$dst, $lhs, $rhs", > [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>; > > // ASR register > def tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > IIC_iMOVsr, > - "asr", " $dst, $rhs", > + "asr", "\t$dst, $rhs", > [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>; > > // BIC register > def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > IIC_iALUr, > - "bic", " $dst, $rhs", > + "bic", "\t$dst, $rhs", > [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>; > > // CMN register > let Defs = [CPSR] in { > def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, > - "cmn", " $lhs, $rhs", > + "cmn", "\t$lhs, $rhs", > [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>; > def tCMNZ : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, > - "cmn", " $lhs, $rhs", > + "cmn", "\t$lhs, $rhs", > [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>; > } > > // CMP immediate > let Defs = [CPSR] in { > def tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, > - "cmp", " $lhs, $rhs", > + "cmp", "\t$lhs, $rhs", > [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>; > def tCMPzi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, > - "cmp", " $lhs, $rhs", > + "cmp", "\t$lhs, $rhs", > [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>; > > } > @@ -443,48 +443,48 @@ > // CMP register > let Defs = [CPSR] in { > def tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, > - "cmp", " $lhs, $rhs", > + "cmp", "\t$lhs, $rhs", > [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>; > def tCMPzr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, > - "cmp", " $lhs, $rhs", > + "cmp", "\t$lhs, $rhs", > [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>; > > def tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, > - "cmp", " $lhs, $rhs", []>; > + "cmp", "\t$lhs, $rhs", []>; > def tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, > - "cmp", " $lhs, $rhs", []>; > + "cmp", "\t$lhs, $rhs", []>; > } > > > // XOR register > let isCommutable = 1 in > def tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > IIC_iALUr, > - "eor", " $dst, $rhs", > + "eor", "\t$dst, $rhs", > [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>; > > // LSL immediate > def tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > IIC_iMOVsi, > - "lsl", " $dst, $lhs, $rhs", > + "lsl", "\t$dst, $lhs, $rhs", > [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>; > > // LSL register > def tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > IIC_iMOVsr, > - "lsl", " $dst, $rhs", > + "lsl", "\t$dst, $rhs", > [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>; > > // LSR immediate > def tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > IIC_iMOVsi, > - "lsr", " $dst, $lhs, $rhs", > + "lsr", "\t$dst, $lhs, $rhs", > [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>; > > // LSR register > def tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > IIC_iMOVsr, > - "lsr", " $dst, $rhs", > + "lsr", "\t$dst, $rhs", > [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>; > > // move register > def tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src), IIC_iMOVi, > - "mov", " $dst, $src", > + "mov", "\t$dst, $src", > [(set tGPR:$dst, imm0_255:$src)]>; > > // TODO: A7-73: MOV(2) - mov setting flag. > @@ -493,45 +493,45 @@ > let neverHasSideEffects = 1 in { > // FIXME: Make this predicable. > def tMOVr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, > - "mov $dst, $src", []>; > + "mov\t$dst, $src", []>; > let Defs = [CPSR] in > def tMOVSr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, > - "movs $dst, $src", []>; > + "movs\t$dst, $src", []>; > > // FIXME: Make these predicable. > def tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iMOVr, > - "mov $dst, $src", []>; > + "mov\t$dst, $src", []>; > def tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iMOVr, > - "mov $dst, $src", []>; > + "mov\t$dst, $src", []>; > def tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, > - "mov $dst, $src", []>; > + "mov\t$dst, $src", []>; > } // neverHasSideEffects > > // multiply register > let isCommutable = 1 in > def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > IIC_iMUL32, > - "mul", " $dst, $rhs", > + "mul", "\t$dst, $rhs", > [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>; > > // move inverse register > def tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, > - "mvn", " $dst, $src", > + "mvn", "\t$dst, $src", > [(set tGPR:$dst, (not tGPR:$src))]>; > > // bitwise or register > let isCommutable = 1 in > def tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > IIC_iALUr, > - "orr", " $dst, $rhs", > + "orr", "\t$dst, $rhs", > [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>; > > // swaps > def tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, > - "rev", " $dst, $src", > + "rev", "\t$dst, $src", > [(set tGPR:$dst, (bswap tGPR:$src))]>, > Requires<[IsThumb1Only, HasV6]>; > > def tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, > - "rev16", " $dst, $src", > + "rev16", "\t$dst, $src", > [(set tGPR:$dst, > (or (and (srl tGPR:$src, (i32 8)), 0xFF), > (or (and (shl tGPR:$src, (i32 8)), 0xFF00), > @@ -540,7 +540,7 @@ > Requires<[IsThumb1Only, HasV6]>; > > def tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, > - "revsh", " $dst, $src", > + "revsh", "\t$dst, $src", > [(set tGPR:$dst, > (sext_inreg > (or (srl (and tGPR:$src, 0xFF00), (i32 8)), > @@ -549,63 +549,63 @@ > > // rotate right register > def tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > IIC_iMOVsr, > - "ror", " $dst, $rhs", > + "ror", "\t$dst, $rhs", > [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>; > > // negate register > def tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALUi, > - "rsb", " $dst, $src, #0", > + "rsb", "\t$dst, $src, #0", > [(set tGPR:$dst, (ineg tGPR:$src))]>; > > // Subtract with carry register > let Uses = [CPSR] in > def tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > IIC_iALUr, > - "sbc", " $dst, $rhs", > + "sbc", "\t$dst, $rhs", > [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>; > > // Subtract immediate > def tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > IIC_iALUi, > - "sub", " $dst, $lhs, $rhs", > + "sub", "\t$dst, $lhs, $rhs", > [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))] > >; > > def tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), > IIC_iALUi, > - "sub", " $dst, $rhs", > + "sub", "\t$dst, $rhs", > [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg: > $rhs))]>; > > // subtract register > def tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), > IIC_iALUr, > - "sub", " $dst, $lhs, $rhs", > + "sub", "\t$dst, $lhs, $rhs", > [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>; > > // TODO: A7-96: STMIA - store multiple. > > // sign-extend byte > def tSXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, > - "sxtb", " $dst, $src", > + "sxtb", "\t$dst, $src", > [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>, > Requires<[IsThumb1Only, HasV6]>; > > // sign-extend short > def tSXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, > - "sxth", " $dst, $src", > + "sxth", "\t$dst, $src", > [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>, > Requires<[IsThumb1Only, HasV6]>; > > // test > let isCommutable = 1, Defs = [CPSR] in > def tTST : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, > - "tst", " $lhs, $rhs", > + "tst", "\t$lhs, $rhs", > [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>; > > // zero-extend byte > def tUXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, > - "uxtb", " $dst, $src", > + "uxtb", "\t$dst, $src", > [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>, > Requires<[IsThumb1Only, HasV6]>; > > // zero-extend short > def tUXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, > - "uxth", " $dst, $src", > + "uxth", "\t$dst, $src", > [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>, > Requires<[IsThumb1Only, HasV6]>; > > @@ -621,19 +621,19 @@ > > // 16-bit movcc in IT blocks for Thumb2. > def tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > IIC_iCMOVr, > - "mov", " $dst, $rhs", []>; > + "mov", "\t$dst, $rhs", []>; > > def tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > IIC_iCMOVi, > - "mov", " $dst, $rhs", []>; > + "mov", "\t$dst, $rhs", []>; > > // tLEApcrel - Load a pc-relative address into a register without > offending the > // assembler. > def tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label, pred:$p), > IIC_iALUi, > - "adr$p $dst, #$label", []>; > + "adr$p\t$dst, #$label", []>; > > def tLEApcrelJT : T1I<(outs tGPR:$dst), > (ins i32imm:$label, nohash_imm:$id, pred:$p), > - IIC_iALUi, "adr$p $dst, #${label}_${id}", []>; > + IIC_iALUi, "adr$p\t$dst, #${label}_${id}", []>; > > // > = > = > = > ----------------------------------------------------------------------= > ==// > // TLS Instructions > @@ -643,7 +643,7 @@ > let isCall = 1, > Defs = [R0, LR] in { > def tTPsoft : TIx2<(outs), (ins), IIC_Br, > - "bl __aeabi_read_tp", > + "bl\t__aeabi_read_tp", > [(set R0, ARMthread_pointer)]>; > } > > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=85184&r1=85183&r2=85184&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon Oct 26 19:08:59 > 2009 > @@ -153,18 +153,18 @@ > multiclass T2I_un_irs ReMat = 0>{ > // shifted imm > def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi, > - opc, " $dst, $src", > + opc, "\t$dst, $src", > [(set GPR:$dst, (opnode t2_so_imm:$src))]> { > let isAsCheapAsAMove = Cheap; > let isReMaterializable = ReMat; > } > // register > def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, > - opc, ".w $dst, $src", > + opc, ".w\t$dst, $src", > [(set GPR:$dst, (opnode GPR:$src))]>; > // shifted register > def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), IIC_iMOVsi, > - opc, ".w $dst, $src", > + opc, ".w\t$dst, $src", > [(set GPR:$dst, (opnode t2_so_reg:$src))]>; > } > > @@ -175,17 +175,17 @@ > bit Commutable = 0, string wide =""> { > // shifted imm > def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), > IIC_iALUi, > - opc, " $dst, $lhs, $rhs", > + opc, "\t$dst, $lhs, $rhs", > [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; > // register > def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, > - opc, !strconcat(wide, " $dst, $lhs, $rhs"), > + opc, !strconcat(wide, "\t$dst, $lhs, $rhs"), > [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { > let isCommutable = Commutable; > } > // shifted register > def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), > IIC_iALUsi, > - opc, !strconcat(wide, " $dst, $lhs, $rhs"), > + opc, !strconcat(wide, "\t$dst, $lhs, $rhs"), > [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; > } > > @@ -200,11 +200,11 @@ > multiclass T2I_rbin_is { > // shifted imm > def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), > IIC_iALUi, > - opc, ".w $dst, $rhs, $lhs", > + opc, ".w\t$dst, $rhs, $lhs", > [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; > // shifted register > def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), > IIC_iALUsi, > - opc, " $dst, $rhs, $lhs", > + opc, "\t$dst, $rhs, $lhs", > [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>; > } > > @@ -214,17 +214,17 @@ > multiclass T2I_bin_s_irs = 0> { > // shifted imm > def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), > IIC_iALUi, > - !strconcat(opc, "s"), ".w $dst, $lhs, $rhs", > + !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs", > [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; > // register > def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, > - !strconcat(opc, "s"), ".w $dst, $lhs, $rhs", > + !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs", > [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { > let isCommutable = Commutable; > } > // shifted register > def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), > IIC_iALUsi, > - !strconcat(opc, "s"), ".w $dst, $lhs, $rhs", > + !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs", > [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; > } > } > @@ -234,21 +234,21 @@ > multiclass T2I_bin_ii12rs = 0> { > // shifted imm > def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), > IIC_iALUi, > - opc, ".w $dst, $lhs, $rhs", > + opc, ".w\t$dst, $lhs, $rhs", > [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; > // 12-bit imm > def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), > IIC_iALUi, > - !strconcat(opc, "w"), " $dst, $lhs, $rhs", > + !strconcat(opc, "w"), "\t$dst, $lhs, $rhs", > [(set GPR:$dst, (opnode GPR:$lhs, > imm0_4095:$rhs))]>; > // register > def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, > - opc, ".w $dst, $lhs, $rhs", > + opc, ".w\t$dst, $lhs, $rhs", > [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { > let isCommutable = Commutable; > } > // shifted register > def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), > IIC_iALUsi, > - opc, ".w $dst, $lhs, $rhs", > + opc, ".w\t$dst, $lhs, $rhs", > [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; > } > > @@ -259,32 +259,32 @@ > multiclass T2I_adde_sube_irs Commutable = 0> { > // shifted imm > def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), > IIC_iALUi, > - opc, " $dst, $lhs, $rhs", > + opc, "\t$dst, $lhs, $rhs", > [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>, > Requires<[IsThumb2, CarryDefIsUnused]>; > // register > def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, > - opc, ".w $dst, $lhs, $rhs", > + opc, ".w\t$dst, $lhs, $rhs", > [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>, > Requires<[IsThumb2, CarryDefIsUnused]> { > let isCommutable = Commutable; > } > // shifted register > def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), > IIC_iALUsi, > - opc, ".w $dst, $lhs, $rhs", > + opc, ".w\t$dst, $lhs, $rhs", > [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>, > Requires<[IsThumb2, CarryDefIsUnused]>; > // Carry setting variants > // shifted imm > def Sri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), > IIC_iALUi, > - !strconcat(opc, "s $dst, $lhs, $rhs"), > + !strconcat(opc, "s\t$dst, $lhs, $rhs"), > [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))] > >, > Requires<[IsThumb2, CarryDefIsUsed]> { > let Defs = [CPSR]; > } > // register > def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > IIC_iALUr, > - !strconcat(opc, "s.w $dst, $lhs, $rhs"), > + !strconcat(opc, "s.w\t$dst, $lhs, $rhs"), > [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>, > Requires<[IsThumb2, CarryDefIsUsed]> { > let Defs = [CPSR]; > @@ -292,7 +292,7 @@ > } > // shifted register > def Srs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), > IIC_iALUsi, > - !strconcat(opc, "s.w $dst, $lhs, $rhs"), > + !strconcat(opc, "s.w\t$dst, $lhs, $rhs"), > [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))] > >, > Requires<[IsThumb2, CarryDefIsUsed]> { > let Defs = [CPSR]; > @@ -306,12 +306,12 @@ > // shifted imm > def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, > cc_out:$s), > IIC_iALUi, > - !strconcat(opc, "${s}.w $dst, $rhs, $lhs"), > + !strconcat(opc, "${s}.w\t$dst, $rhs, $lhs"), > [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; > // shifted register > def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, > cc_out:$s), > IIC_iALUsi, > - !strconcat(opc, "${s} $dst, $rhs, $lhs"), > + !strconcat(opc, "${s}\t$dst, $rhs, $lhs"), > [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>; > } > } > @@ -321,11 +321,11 @@ > multiclass T2I_sh_ir { > // 5-bit imm > def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), > IIC_iMOVsi, > - opc, ".w $dst, $lhs, $rhs", > + opc, ".w\t$dst, $lhs, $rhs", > [(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]>; > // register > def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), > IIC_iMOVsr, > - opc, ".w $dst, $lhs, $rhs", > + opc, ".w\t$dst, $lhs, $rhs", > [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>; > } > > @@ -336,15 +336,15 @@ > multiclass T2I_cmp_is { > // shifted imm > def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iCMPi, > - opc, ".w $lhs, $rhs", > + opc, ".w\t$lhs, $rhs", > [(opnode GPR:$lhs, t2_so_imm:$rhs)]>; > // register > def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, > - opc, ".w $lhs, $rhs", > + opc, ".w\t$lhs, $rhs", > [(opnode GPR:$lhs, GPR:$rhs)]>; > // shifted register > def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iCMPsi, > - opc, ".w $lhs, $rhs", > + opc, ".w\t$lhs, $rhs", > [(opnode GPR:$lhs, t2_so_reg:$rhs)]>; > } > } > @@ -352,42 +352,42 @@ > /// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load > patterns. > multiclass T2I_ld { > def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), > IIC_iLoadi, > - opc, ".w $dst, $addr", > + opc, ".w\t$dst, $addr", > [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]>; > def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), > IIC_iLoadi, > - opc, " $dst, $addr", > + opc, "\t$dst, $addr", > [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]>; > def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), > IIC_iLoadr, > - opc, ".w $dst, $addr", > + opc, ".w\t$dst, $addr", > [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))] > >; > def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoadi, > - opc, ".w $dst, $addr", > + opc, ".w\t$dst, $addr", > [(set GPR:$dst, (opnode (ARMWrapper tconstpool: > $addr)))]>; > } > > /// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store > patterns. > multiclass T2I_st { > def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), > IIC_iStorei, > - opc, ".w $src, $addr", > + opc, ".w\t$src, $addr", > [(opnode GPR:$src, t2addrmode_imm12:$addr)]>; > def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), > IIC_iStorei, > - opc, " $src, $addr", > + opc, "\t$src, $addr", > [(opnode GPR:$src, t2addrmode_imm8:$addr)]>; > def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), > IIC_iStorer, > - opc, ".w $src, $addr", > + opc, ".w\t$src, $addr", > [(opnode GPR:$src, t2addrmode_so_reg:$addr)]>; > } > > /// T2I_picld - Defines the PIC load pattern. > class T2I_picld : > T2I<(outs GPR:$dst), (ins addrmodepc:$addr), IIC_iLoadi, > - !strconcat("\n${addr:label}:\n\t", opc), " $dst, $addr", > + !strconcat("\n${addr:label}:\n\t", opc), "\t$dst, $addr", > [(set GPR:$dst, (opnode addrmodepc:$addr))]>; > > /// T2I_picst - Defines the PIC store pattern. > class T2I_picst : > T2I<(outs), (ins GPR:$src, addrmodepc:$addr), IIC_iStorer, > - !strconcat("\n${addr:label}:\n\t", opc), " $src, $addr", > + !strconcat("\n${addr:label}:\n\t", opc), "\t$src, $addr", > [(opnode GPR:$src, addrmodepc:$addr)]>; > > > @@ -395,10 +395,10 @@ > /// register and one whose operand is a register rotated by 8/16/24. > multiclass T2I_unary_rrot { > def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, > - opc, ".w $dst, $src", > + opc, ".w\t$dst, $src", > [(set GPR:$dst, (opnode GPR:$src))]>; > def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), > IIC_iUNAsi, > - opc, ".w $dst, $src, ror $rot", > + opc, ".w\t$dst, $src, ror $rot", > [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm: > $rot)))]>; > } > > @@ -406,10 +406,10 @@ > /// register and one whose operand is a register rotated by 8/16/24. > multiclass T2I_bin_rrot { > def rr : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), > IIC_iALUr, > - opc, " $dst, $LHS, $RHS", > + opc, "\t$dst, $LHS, $RHS", > [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>; > def rr_rot : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm: > $rot), > - IIC_iALUsr, opc, " $dst, $LHS, $RHS, ror $rot", > + IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot", > [(set GPR:$dst, (opnode GPR:$LHS, > (rotr GPR:$RHS, rot_imm: > $rot)))]>; > } > @@ -425,42 +425,42 @@ > // LEApcrel - Load a pc-relative address into a register without > offending the > // assembler. > def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred:$p), > IIC_iALUi, > - "adr$p.w $dst, #$label", []>; > + "adr$p.w\t$dst, #$label", []>; > > def t2LEApcrelJT : T2XI<(outs GPR:$dst), > (ins i32imm:$label, nohash_imm:$id, pred: > $p), IIC_iALUi, > - "adr$p.w $dst, #${label}_${id}", []>; > + "adr$p.w\t$dst, #${label}_${id}", []>; > > // ADD r, sp, {so_imm|i12} > def t2ADDrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm), > - IIC_iALUi, "add", ".w $dst, $sp, $imm", []>; > + IIC_iALUi, "add", ".w\t$dst, $sp, $imm", []>; > def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm), > - IIC_iALUi, "addw", " $dst, $sp, $imm", []>; > + IIC_iALUi, "addw", "\t$dst, $sp, $imm", []>; > > // ADD r, sp, so_reg > def t2ADDrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs), > - IIC_iALUsi, "add", ".w $dst, $sp, $rhs", []>; > + IIC_iALUsi, "add", ".w\t$dst, $sp, $rhs", [] > >; > > // SUB r, sp, {so_imm|i12} > def t2SUBrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm), > - IIC_iALUi, "sub", ".w $dst, $sp, $imm", []>; > + IIC_iALUi, "sub", ".w\t$dst, $sp, $imm", []>; > def t2SUBrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm), > - IIC_iALUi, "subw", " $dst, $sp, $imm", []>; > + IIC_iALUi, "subw", "\t$dst, $sp, $imm", []>; > > // SUB r, sp, so_reg > def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs), > IIC_iALUsi, > - "sub", " $dst, $sp, $rhs", []>; > + "sub", "\t$dst, $sp, $rhs", []>; > > > // Pseudo instruction that will expand into a t2SUBrSPi + a copy. > let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. > def t2SUBrSPi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, > t2_so_imm:$imm), > - NoItinerary, "@ sub.w $dst, $sp, $imm", []>; > + NoItinerary, "@ sub.w\t$dst, $sp, $imm", []>; > def t2SUBrSPi12_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, > imm0_4095:$imm), > - NoItinerary, "@ subw $dst, $sp, $imm", []>; > + NoItinerary, "@ subw\t$dst, $sp, $imm", []>; > def t2SUBrSPs_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, > t2_so_reg:$rhs), > - NoItinerary, "@ sub $dst, $sp, $rhs", []>; > + NoItinerary, "@ sub\t$dst, $sp, $rhs", []>; > } // usesCustomDAGSchedInserter > > > @@ -484,10 +484,10 @@ > // Load doubleword > def t2LDRDi8 : T2Ii8s4<(outs GPR:$dst1, GPR:$dst2), > (ins t2addrmode_imm8s4:$addr), > - IIC_iLoadi, "ldrd", " $dst1, $addr", []>; > + IIC_iLoadi, "ldrd", "\t$dst1, $addr", []>; > def t2LDRDpci : T2Ii8s4<(outs GPR:$dst1, GPR:$dst2), > (ins i32imm:$addr), IIC_iLoadi, > - "ldrd", " $dst1, $addr", []>; > + "ldrd", "\t$dst1, $addr", []>; > } > > // zextload i1 -> zextload i8 > @@ -535,57 +535,57 @@ > def t2LDR_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), > (ins t2addrmode_imm8:$addr), > AddrModeT2_i8, IndexModePre, IIC_iLoadiu, > - "ldr", " $dst, $addr!", "$addr.base = > $base_wb", > + "ldr", "\t$dst, $addr!", "$addr.base = > $base_wb", > []>; > > def t2LDR_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), > (ins GPR:$base, t2am_imm8_offset:$offset), > AddrModeT2_i8, IndexModePost, IIC_iLoadiu, > - "ldr", " $dst, [$base], $offset", "$base > = $base_wb", > + "ldr", "\t$dst, [$base], $offset", "$base > = $base_wb", > []>; > > def t2LDRB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), > (ins t2addrmode_imm8:$addr), > AddrModeT2_i8, IndexModePre, IIC_iLoadiu, > - "ldrb", " $dst, $addr!", "$addr.base = > $base_wb", > + "ldrb", "\t$dst, $addr!", "$addr.base = > $base_wb", > []>; > def t2LDRB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), > (ins GPR:$base, t2am_imm8_offset:$offset), > AddrModeT2_i8, IndexModePost, IIC_iLoadiu, > - "ldrb", " $dst, [$base], $offset", "$base > = $base_wb", > + "ldrb", "\t$dst, [$base], $offset", "$base > = $base_wb", > []>; > > def t2LDRH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), > (ins t2addrmode_imm8:$addr), > AddrModeT2_i8, IndexModePre, IIC_iLoadiu, > - "ldrh", " $dst, $addr!", "$addr.base = > $base_wb", > + "ldrh", "\t$dst, $addr!", "$addr.base = > $base_wb", > []>; > def t2LDRH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), > (ins GPR:$base, t2am_imm8_offset:$offset), > AddrModeT2_i8, IndexModePost, IIC_iLoadiu, > - "ldrh", " $dst, [$base], $offset", "$base > = $base_wb", > + "ldrh", "\t$dst, [$base], $offset", "$base > = $base_wb", > []>; > > def t2LDRSB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), > (ins t2addrmode_imm8:$addr), > AddrModeT2_i8, IndexModePre, IIC_iLoadiu, > - "ldrsb", " $dst, $addr!", "$addr.base = > $base_wb", > + "ldrsb", "\t$dst, $addr!", "$addr.base > = $base_wb", > []>; > def t2LDRSB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), > (ins GPR:$base, t2am_imm8_offset:$offset), > AddrModeT2_i8, IndexModePost, IIC_iLoadiu, > - "ldrsb", " $dst, [$base], $offset", "$base > = $base_wb", > + "ldrsb", "\t$dst, [$base], $offset", "$base > = $base_wb", > []>; > > def t2LDRSH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), > (ins t2addrmode_imm8:$addr), > AddrModeT2_i8, IndexModePre, IIC_iLoadiu, > - "ldrsh", " $dst, $addr!", "$addr.base = > $base_wb", > + "ldrsh", "\t$dst, $addr!", "$addr.base > = $base_wb", > []>; > def t2LDRSH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), > (ins GPR:$base, t2am_imm8_offset:$offset), > AddrModeT2_i8, IndexModePost, IIC_iLoadiu, > - "ldrsh", " $dst, [$base], $offset", "$base > = $base_wb", > + "ldrsh", "\t$dst, [$base], $offset", "$base > = $base_wb", > []>; > } > > @@ -598,48 +598,48 @@ > let mayLoad = 1, hasExtraSrcRegAllocReq = 1 in > def t2STRDi8 : T2Ii8s4<(outs), > (ins GPR:$src1, GPR:$src2, > t2addrmode_imm8s4:$addr), > - IIC_iStorer, "strd", " $src1, $addr", []>; > + IIC_iStorer, "strd", "\t$src1, $addr", []>; > > // Indexed stores > def t2STR_PRE : T2Iidxldst<(outs GPR:$base_wb), > (ins GPR:$src, GPR:$base, > t2am_imm8_offset:$offset), > AddrModeT2_i8, IndexModePre, IIC_iStoreiu, > - "str", " $src, [$base, $offset]!", "$base > = $base_wb", > + "str", "\t$src, [$base, $offset]!", "$base > = $base_wb", > [(set GPR:$base_wb, > (pre_store GPR:$src, GPR:$base, t2am_imm8_offset: > $offset))]>; > > def t2STR_POST : T2Iidxldst<(outs GPR:$base_wb), > (ins GPR:$src, GPR:$base, > t2am_imm8_offset:$offset), > AddrModeT2_i8, IndexModePost, > IIC_iStoreiu, > - "str", " $src, [$base], $offset", "$base > = $base_wb", > + "str", "\t$src, [$base], $offset", "$base > = $base_wb", > [(set GPR:$base_wb, > (post_store GPR:$src, GPR:$base, t2am_imm8_offset: > $offset))]>; > > def t2STRH_PRE : T2Iidxldst<(outs GPR:$base_wb), > (ins GPR:$src, GPR:$base, > t2am_imm8_offset:$offset), > AddrModeT2_i8, IndexModePre, IIC_iStoreiu, > - "strh", " $src, [$base, $offset]!", "$base > = $base_wb", > + "strh", "\t$src, [$base, $offset]!", "$base > = $base_wb", > [(set GPR:$base_wb, > (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset: > $offset))]>; > > def t2STRH_POST : T2Iidxldst<(outs GPR:$base_wb), > (ins GPR:$src, GPR:$base, > t2am_imm8_offset:$offset), > AddrModeT2_i8, IndexModePost, > IIC_iStoreiu, > - "strh", " $src, [$base], $offset", "$base > = $base_wb", > + "strh", "\t$src, [$base], $offset", "$base > = $base_wb", > [(set GPR:$base_wb, > (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset: > $offset))]>; > > def t2STRB_PRE : T2Iidxldst<(outs GPR:$base_wb), > (ins GPR:$src, GPR:$base, > t2am_imm8_offset:$offset), > AddrModeT2_i8, IndexModePre, IIC_iStoreiu, > - "strb", " $src, [$base, $offset]!", "$base > = $base_wb", > + "strb", "\t$src, [$base, $offset]!", "$base > = $base_wb", > [(set GPR:$base_wb, > (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset: > $offset))]>; > > def t2STRB_POST : T2Iidxldst<(outs GPR:$base_wb), > (ins GPR:$src, GPR:$base, > t2am_imm8_offset:$offset), > AddrModeT2_i8, IndexModePost, > IIC_iStoreiu, > - "strb", " $src, [$base], $offset", "$base > = $base_wb", > + "strb", "\t$src, [$base], $offset", "$base > = $base_wb", > [(set GPR:$base_wb, > (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset: > $offset))]>; > > @@ -653,12 +653,12 @@ > let mayLoad = 1, hasExtraDefRegAllocReq = 1 in > def t2LDM : T2XI<(outs), > (ins addrmode4:$addr, pred:$p, reglist:$wb, > variable_ops), > - IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide} > $addr, $wb", []>; > + IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide}\t > $addr, $wb", []>; > > let mayStore = 1, hasExtraSrcRegAllocReq = 1 in > def t2STM : T2XI<(outs), > (ins addrmode4:$addr, pred:$p, reglist:$wb, > variable_ops), > - IIC_iStorem, "stm${addr:submode}${p}${addr:wide} > $addr, $wb", []>; > + IIC_iStorem, "stm${addr:submode}${p}${addr:wide}\t > $addr, $wb", []>; > > // > = > = > = > ----------------------------------------------------------------------= > ==// > // Move Instructions. > @@ -666,22 +666,22 @@ > > let neverHasSideEffects = 1 in > def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, > - "mov", ".w $dst, $src", []>; > + "mov", ".w\t$dst, $src", []>; > > // AddedComplexity to ensure isel tries t2MOVi before t2MOVi16. > let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = > 1 in > def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi, > - "mov", ".w $dst, $src", > + "mov", ".w\t$dst, $src", > [(set GPR:$dst, t2_so_imm:$src)]>; > > let isReMaterializable = 1, isAsCheapAsAMove = 1 in > def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi, > - "movw", " $dst, $src", > + "movw", "\t$dst, $src", > [(set GPR:$dst, imm0_65535:$src)]>; > > let Constraints = "$src = $dst" in > def t2MOVTi16 : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), > IIC_iMOVi, > - "movt", " $dst, $imm", > + "movt", "\t$dst, $imm", > [(set GPR:$dst, > (or (and GPR:$src, 0xffff), lo16AllZero: > $imm))]>; > > @@ -760,16 +760,16 @@ > > let Uses = [CPSR] in { > def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, > - "rrx", " $dst, $src", > + "rrx", "\t$dst, $src", > [(set GPR:$dst, (ARMrrx GPR:$src))]>; > } > > let Defs = [CPSR] in { > def t2MOVsrl_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, > - "lsrs.w $dst, $src, #1", > + "lsrs.w\t$dst, $src, #1", > [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>; > def t2MOVsra_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, > - "asrs.w $dst, $src, #1", > + "asrs.w\t$dst, $src, #1", > [(set GPR:$dst, (ARMsra_flag GPR:$src))]>; > } > > @@ -785,14 +785,14 @@ > > let Constraints = "$src = $dst" in > def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm), > - IIC_iALUi, "bfc", " $dst, $imm", > + IIC_iALUi, "bfc", "\t$dst, $imm", > [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm: > $imm))]>; > > def t2SBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, > imm0_31:$width), > - IIC_iALUi, "sbfx", " $dst, $src, $lsb, $width", []>; > + IIC_iALUi, "sbfx", "\t$dst, $src, $lsb, $width", [] > >; > > def t2UBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, > imm0_31:$width), > - IIC_iALUi, "ubfx", " $dst, $src, $lsb, $width", []>; > + IIC_iALUi, "ubfx", "\t$dst, $src, $lsb, $width", [] > >; > > // FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1) > > @@ -819,80 +819,80 @@ > // > let isCommutable = 1 in > def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, > - "mul", " $dst, $a, $b", > + "mul", "\t$dst, $a, $b", > [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>; > > def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), > IIC_iMAC32, > - "mla", " $dst, $a, $b, $c", > + "mla", "\t$dst, $a, $b, $c", > [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>; > > def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), > IIC_iMAC32, > - "mls", " $dst, $a, $b, $c", > + "mls", "\t$dst, $a, $b, $c", > [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>; > > // Extra precision multiplies with low / high results > let neverHasSideEffects = 1 in { > let isCommutable = 1 in { > def t2SMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), > IIC_iMUL64, > - "smull", " $ldst, $hdst, $a, $b", []>; > + "smull", "\t$ldst, $hdst, $a, $b", []>; > > def t2UMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), > IIC_iMUL64, > - "umull", " $ldst, $hdst, $a, $b", []>; > + "umull", "\t$ldst, $hdst, $a, $b", []>; > } > > // Multiply + accumulate > def t2SMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), > IIC_iMAC64, > - "smlal", " $ldst, $hdst, $a, $b", []>; > + "smlal", "\t$ldst, $hdst, $a, $b", []>; > > def t2UMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), > IIC_iMAC64, > - "umlal", " $ldst, $hdst, $a, $b", []>; > + "umlal", "\t$ldst, $hdst, $a, $b", []>; > > def t2UMAAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), > IIC_iMAC64, > - "umaal", " $ldst, $hdst, $a, $b", []>; > + "umaal", "\t$ldst, $hdst, $a, $b", []>; > } // neverHasSideEffects > > // Most significant word multiply > def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, > - "smmul", " $dst, $a, $b", > + "smmul", "\t$dst, $a, $b", > [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>; > > def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), > IIC_iMAC32, > - "smmla", " $dst, $a, $b, $c", > + "smmla", "\t$dst, $a, $b, $c", > [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR: > $c))]>; > > > def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), > IIC_iMAC32, > - "smmls", " $dst, $a, $b, $c", > + "smmls", "\t$dst, $a, $b, $c", > [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR: > $b)))]>; > > multiclass T2I_smul { > def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, > - !strconcat(opc, "bb"), " $dst, $a, $b", > + !strconcat(opc, "bb"), "\t$dst, $a, $b", > [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16), > (sext_inreg GPR:$b, i16)))]>; > > def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, > - !strconcat(opc, "bt"), " $dst, $a, $b", > + !strconcat(opc, "bt"), "\t$dst, $a, $b", > [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16), > (sra GPR:$b, (i32 16))))]>; > > def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, > - !strconcat(opc, "tb"), " $dst, $a, $b", > + !strconcat(opc, "tb"), "\t$dst, $a, $b", > [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)), > (sext_inreg GPR:$b, i16)))]>; > > def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, > - !strconcat(opc, "tt"), " $dst, $a, $b", > + !strconcat(opc, "tt"), "\t$dst, $a, $b", > [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)), > (sra GPR:$b, (i32 16))))]>; > > def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16, > - !strconcat(opc, "wb"), " $dst, $a, $b", > + !strconcat(opc, "wb"), "\t$dst, $a, $b", > [(set GPR:$dst, (sra (opnode GPR:$a, > (sext_inreg GPR:$b, i16)), (i32 > 16)))]>; > > def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16, > - !strconcat(opc, "wt"), " $dst, $a, $b", > + !strconcat(opc, "wt"), "\t$dst, $a, $b", > [(set GPR:$dst, (sra (opnode GPR:$a, > (sra GPR:$b, (i32 16))), (i32 > 16)))]>; > } > @@ -900,33 +900,33 @@ > > multiclass T2I_smla { > def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), > IIC_iMAC16, > - !strconcat(opc, "bb"), " $dst, $a, $b, $acc", > + !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc", > [(set GPR:$dst, (add GPR:$acc, > (opnode (sext_inreg GPR:$a, i16), > (sext_inreg GPR:$b, i16))))]>; > > def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), > IIC_iMAC16, > - !strconcat(opc, "bt"), " $dst, $a, $b, $acc", > + !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc", > [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR: > $a, i16), > (sra GPR:$b, > (i32 16)))))]>; > > def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), > IIC_iMAC16, > - !strconcat(opc, "tb"), " $dst, $a, $b, $acc", > + !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc", > [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, > (i32 16)), > (sext_inreg GPR:$b, > i16))))]>; > > def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), > IIC_iMAC16, > - !strconcat(opc, "tt"), " $dst, $a, $b, $acc", > + !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc", > [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, > (i32 16)), > (sra GPR:$b, > (i32 16)))))]>; > > def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), > IIC_iMAC16, > - !strconcat(opc, "wb"), " $dst, $a, $b, $acc", > + !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc", > [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a, > (sext_inreg GPR:$b, i16)), > (i32 16))))]>; > > def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), > IIC_iMAC16, > - !strconcat(opc, "wt"), " $dst, $a, $b, $acc", > + !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc", > [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a, > (sra GPR:$b, (i32 16))), > (i32 16))))]>; > } > @@ -943,15 +943,15 @@ > // > > def t2CLZ : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, > - "clz", " $dst, $src", > + "clz", "\t$dst, $src", > [(set GPR:$dst, (ctlz GPR:$src))]>; > > def t2REV : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, > - "rev", ".w $dst, $src", > + "rev", ".w\t$dst, $src", > [(set GPR:$dst, (bswap GPR:$src))]>; > > def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, > - "rev16", ".w $dst, $src", > + "rev16", ".w\t$dst, $src", > [(set GPR:$dst, > (or (and (srl GPR:$src, (i32 8)), 0xFF), > (or (and (shl GPR:$src, (i32 8)), 0xFF00), > @@ -959,14 +959,14 @@ > (and (shl GPR:$src, (i32 8)), > 0xFF000000)))))]>; > > def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, > - "revsh", ".w $dst, $src", > + "revsh", ".w\t$dst, $src", > [(set GPR:$dst, > (sext_inreg > (or (srl (and GPR:$src, 0xFF00), (i32 8)), > (shl GPR:$src, (i32 8))), i16))]>; > > def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm: > $shamt), > - IIC_iALUsi, "pkhbt", " $dst, $src1, $src2, LSL > $shamt", > + IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL > $shamt", > [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF), > (and (shl GPR:$src2, (i32 imm: > $shamt)), > 0xFFFF0000)))]>; > @@ -978,7 +978,7 @@ > (t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>; > > def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm: > $shamt), > - IIC_iALUsi, "pkhtb", " $dst, $src1, $src2, ASR > $shamt", > + IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR > $shamt", > [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000), > (and (sra GPR:$src2, > imm16_31:$shamt), > 0xFFFF)))]>; > @@ -1025,26 +1025,26 @@ > // FIXME: should be able to write a pattern for ARMcmov, but can't use > // a two-value operand where a dag node expects two operands. :( > def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true), > IIC_iCMOVr, > - "mov", ".w $dst, $true", > + "mov", ".w\t$dst, $true", > [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR: > $ccr))*/]>, > RegConstraint<"$false = $dst">; > > def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm:$true), > - IIC_iCMOVi, "mov", ".w $dst, $true", > + IIC_iCMOVi, "mov", ".w\t$dst, $true", > [/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_imm:$true, imm:$cc, CCR: > $ccr))*/]>, > RegConstraint<"$false = $dst">; > > def t2MOVCClsl : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, > i32imm:$rhs), > - IIC_iCMOVsi, "lsl", ".w $dst, $true, $rhs", []>, > + IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", []>, > RegConstraint<"$false = $dst">; > def t2MOVCClsr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, > i32imm:$rhs), > - IIC_iCMOVsi, "lsr", ".w $dst, $true, $rhs", []>, > + IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", []>, > RegConstraint<"$false = $dst">; > def t2MOVCCasr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, > i32imm:$rhs), > - IIC_iCMOVsi, "asr", ".w $dst, $true, $rhs", []>, > + IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", []>, > RegConstraint<"$false = $dst">; > def t2MOVCCror : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, > i32imm:$rhs), > - IIC_iCMOVsi, "ror", ".w $dst, $true, $rhs", []>, > + IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", []>, > RegConstraint<"$false = $dst">; > > // > = > = > = > ----------------------------------------------------------------------= > ==// > @@ -1055,7 +1055,7 @@ > let isCall = 1, > Defs = [R0, R12, LR, CPSR] in { > def t2TPsoft : T2XI<(outs), (ins), IIC_Br, > - "bl __aeabi_read_tp", > + "bl\t__aeabi_read_tp", > [(set R0, ARMthread_pointer)]>; > } > > @@ -1078,13 +1078,13 @@ > D31 ] in { > def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src), > AddrModeNone, SizeSpecial, NoItinerary, > - "str.w sp, [$src, #+8] @ eh_setjmp > begin\n" > - "\tadr r12, 0f\n" > - "\torr r12, #1\n" > - "\tstr.w r12, [$src, #+4]\n" > - "\tmovs r0, #0\n" > - "\tb 1f\n" > - "0:\tmovs r0, #1 @ eh_setjmp end\n" > + "str.w\tsp, [$src, #+8] @ eh_setjmp > begin\n" > + "\tadr\tr12, 0f\n" > + "\torr\tr12, #1\n" > + "\tstr.w\tr12, [$src, #+4]\n" > + "\tmovs\tr0, #0\n" > + "\tb\t1f\n" > + "0:\tmovs\tr0, #1 @ eh_setjmp end\n" > "1:", "", > [(set R0, (ARMeh_sjlj_setjmp GPR: > $src))]>; > } > @@ -1103,32 +1103,32 @@ > hasExtraDefRegAllocReq = 1 in > def t2LDM_RET : T2XI<(outs), > (ins addrmode4:$addr, pred:$p, reglist:$wb, > variable_ops), > - IIC_Br, "ldm${addr:submode}${p}${addr:wide} > $addr, $wb", > + IIC_Br, "ldm${addr:submode}${p}${addr:wide}\t > $addr, $wb", > []>; > > let isBranch = 1, isTerminator = 1, isBarrier = 1 in { > let isPredicable = 1 in > def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br, > - "b.w $target", > + "b.w\t$target", > [(br bb:$target)]>; > > let isNotDuplicable = 1, isIndirectBranch = 1 in { > def t2BR_JT : > T2JTI<(outs), > (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm: > $id), > - IIC_Br, "mov pc, $target\n$jt", > + IIC_Br, "mov\tpc, $target\n$jt", > [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm: > $id)]>; > > // FIXME: Add a non-pc based case that can be predicated. > def t2TBB : > T2JTI<(outs), > (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id), > - IIC_Br, "tbb $index\n$jt", []>; > + IIC_Br, "tbb\t$index\n$jt", []>; > > def t2TBH : > T2JTI<(outs), > (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id), > - IIC_Br, "tbh $index\n$jt", []>; > + IIC_Br, "tbh\t$index\n$jt", []>; > } // isNotDuplicable, isIndirectBranch > > } // isBranch, isTerminator, isBarrier > @@ -1137,14 +1137,14 @@ > // a two-value operand where a dag node expects two operands. :( > let isBranch = 1, isTerminator = 1 in > def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br, > - "b", ".w $target", > + "b", ".w\t$target", > [/*(ARMbrcond bb:$target, imm:$cc)*/]>; > > > // IT block > def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask), > AddrModeNone, Size2Bytes, IIC_iALUx, > - "it$mask $cc", "", []>; > + "it$mask\t$cc", "", []>; > > // > = > = > = > ----------------------------------------------------------------------= > ==// > // Non-Instruction Patterns > @@ -1175,5 +1175,5 @@ > // when we can do generalized remat. > let isReMaterializable = 1 in > def t2MOVi32imm : T2Ix2<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi, > - "movw", " $dst, ${src:lo16}\n\tmovt${p} $dst, $ > {src:hi16}", > + "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, $ > {src:hi16}", > [(set GPR:$dst, (i32 imm:$src))]>; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Tue Oct 27 12:40:19 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 17:40:19 -0000 Subject: [llvm-commits] [llvm] r85256 - in /llvm/trunk/test/Feature: switch.ll testswitch.ll Message-ID: <200910271740.n9RHeJLI005771@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 12:40:19 2009 New Revision: 85256 URL: http://llvm.org/viewvc/llvm-project?rev=85256&view=rev Log: rename test. Added: llvm/trunk/test/Feature/switch.ll - copied unchanged from r85247, llvm/trunk/test/Feature/testswitch.ll Removed: llvm/trunk/test/Feature/testswitch.ll Removed: llvm/trunk/test/Feature/testswitch.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/testswitch.ll?rev=85255&view=auto ============================================================================== --- llvm/trunk/test/Feature/testswitch.ll (original) +++ llvm/trunk/test/Feature/testswitch.ll (removed) @@ -1,26 +0,0 @@ -; RUN: llvm-as < %s | llvm-dis > %t1.ll -; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll -; RUN: diff %t1.ll %t2.ll - - %int = type i32 - -define i32 @squared(i32 %i0) { - switch i32 %i0, label %Default [ - i32 1, label %Case1 - i32 2, label %Case2 - i32 4, label %Case4 - ] - -Default: ; preds = %0 - ret i32 -1 - -Case1: ; preds = %0 - ret i32 1 - -Case2: ; preds = %0 - ret i32 4 - -Case4: ; preds = %0 - ret i32 16 -} - From sanjiv.gupta at microchip.com Tue Oct 27 12:40:25 2009 From: sanjiv.gupta at microchip.com (Sanjiv Gupta) Date: Tue, 27 Oct 2009 17:40:25 -0000 Subject: [llvm-commits] [llvm] r85257 - in /llvm/trunk/lib/Target/PIC16: PIC16InstrInfo.cpp PIC16InstrInfo.h Message-ID: <200910271740.n9RHePdE005786@zion.cs.uiuc.edu> Author: sgupta Date: Tue Oct 27 12:40:24 2009 New Revision: 85257 URL: http://llvm.org/viewvc/llvm-project?rev=85257&view=rev Log: Remove unnecessary gotos to fall-thru successors. Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp?rev=85257&r1=85256&r2=85257&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp Tue Oct 27 12:40:24 2009 @@ -214,3 +214,25 @@ // returning NULL. return 0; } + +bool PIC16InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, + MachineBasicBlock *&TBB, + MachineBasicBlock *&FBB, + SmallVectorImpl &Cond, + bool AllowModify) const { + MachineBasicBlock::iterator I = MBB.end(); + if (I == MBB.begin()) + return true; + + // Get the terminator instruction. + --I; + // Handle unconditional branches. If the unconditional branch's target is + // successor basic block then remove the unconditional branch. + if (I->getOpcode() == PIC16::br_uncond && AllowModify) { + if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) { + TBB = 0; + I->eraseFromParent(); + } + } + return true; +} Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h?rev=85257&r1=85256&r2=85257&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h Tue Oct 27 12:40:24 2009 @@ -68,7 +68,10 @@ unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const SmallVectorImpl &Cond) const; - + virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, + MachineBasicBlock *&FBB, + SmallVectorImpl &Cond, + bool AllowModify) const; }; } // namespace llvm From sabre at nondot.org Tue Oct 27 12:40:49 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 17:40:49 -0000 Subject: [llvm-commits] [llvm] r85258 - in /llvm/trunk/test/Feature: switch.ll terminators.ll Message-ID: <200910271740.n9RHenjb005807@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 12:40:49 2009 New Revision: 85258 URL: http://llvm.org/viewvc/llvm-project?rev=85258&view=rev Log: change of mind :) Added: llvm/trunk/test/Feature/terminators.ll - copied unchanged from r85256, llvm/trunk/test/Feature/switch.ll Removed: llvm/trunk/test/Feature/switch.ll Removed: llvm/trunk/test/Feature/switch.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/switch.ll?rev=85257&view=auto ============================================================================== --- llvm/trunk/test/Feature/switch.ll (original) +++ llvm/trunk/test/Feature/switch.ll (removed) @@ -1,26 +0,0 @@ -; RUN: llvm-as < %s | llvm-dis > %t1.ll -; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll -; RUN: diff %t1.ll %t2.ll - - %int = type i32 - -define i32 @squared(i32 %i0) { - switch i32 %i0, label %Default [ - i32 1, label %Case1 - i32 2, label %Case2 - i32 4, label %Case4 - ] - -Default: ; preds = %0 - ret i32 -1 - -Case1: ; preds = %0 - ret i32 1 - -Case2: ; preds = %0 - ret i32 4 - -Case4: ; preds = %0 - ret i32 16 -} - From evan.cheng at apple.com Tue Oct 27 12:43:55 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 27 Oct 2009 10:43:55 -0700 Subject: [llvm-commits] [llvm] r85184 - in /llvm/trunk/lib/Target/ARM: ARMInstrThumb.td ARMInstrThumb2.td In-Reply-To: <6496D214-A96A-4308-9FD4-74A453B5ECD0@apple.com> References: <200910270008.n9R08xTj013255@zion.cs.uiuc.edu> <6496D214-A96A-4308-9FD4-74A453B5ECD0@apple.com> Message-ID: <862B8F7E-CC68-4669-B358-10A0DDC1BD99@apple.com> Ah sorry. The messy assembly was making it difficult to read the assembly. Can you adjust your patch? Or when you are ready to apply the unified syntax change, you can revert the change first. Evan On Oct 27, 2009, at 10:30 AM, Jim Grosbach wrote: > I was planning on doing this after the unified syntax patch > unblocks. As is, doing this (especially the VFP portion) first > breaks that patch rather horribly. > -j > > On Oct 26, 2009, at 5:08 PM, Evan Cheng wrote: > >> Author: evancheng >> Date: Mon Oct 26 19:08:59 2009 >> New Revision: 85184 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=85184&view=rev >> Log: >> Change Thumb1 and Thumb2 instructions to separate opcode from >> operands with a tab instead of a space. >> >> Modified: >> llvm/trunk/lib/Target/ARM/ARMInstrThumb.td >> llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td >> >> Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=85184&r1=85183&r2=85184&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) >> +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Mon Oct 26 19:08:59 >> 2009 >> @@ -130,44 +130,44 @@ >> // For both thumb1 and thumb2. >> let isNotDuplicable = 1 in >> def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), >> IIC_iALUr, >> - "\n$cp:\n\tadd $dst, pc", >> + "\n$cp:\n\tadd\t$dst, pc", >> [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>; >> >> // PC relative add. >> def tADDrPCi : T1I<(outs tGPR:$dst), (ins i32imm:$rhs), IIC_iALUi, >> - "add $dst, pc, $rhs * 4", []>; >> + "add\t$dst, pc, $rhs * 4", []>; >> >> // ADD rd, sp, #imm8 >> def tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, i32imm:$rhs), >> IIC_iALUi, >> - "add $dst, $sp, $rhs * 4", []>; >> + "add\t$dst, $sp, $rhs * 4", []>; >> >> // ADD sp, sp, #imm7 >> def tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), >> IIC_iALUi, >> - "add $dst, $rhs * 4", []>; >> + "add\t$dst, $rhs * 4", []>; >> >> // SUB sp, sp, #imm7 >> def tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), >> IIC_iALUi, >> - "sub $dst, $rhs * 4", []>; >> + "sub\t$dst, $rhs * 4", []>; >> >> // ADD rm, sp >> def tADDrSP : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), >> IIC_iALUr, >> - "add $dst, $rhs", []>; >> + "add\t$dst, $rhs", []>; >> >> // ADD sp, rm >> def tADDspr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), >> IIC_iALUr, >> - "add $dst, $rhs", []>; >> + "add\t$dst, $rhs", []>; >> >> // Pseudo instruction that will expand into a tSUBspi + a copy. >> let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. >> def tSUBspi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, i32imm: >> $rhs), >> - NoItinerary, "@ sub $dst, $rhs * 4", []>; >> + NoItinerary, "@ sub\t$dst, $rhs * 4", []>; >> >> def tADDspr_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), >> - NoItinerary, "@ add $dst, $rhs", []>; >> + NoItinerary, "@ add\t$dst, $rhs", []>; >> >> let Defs = [CPSR] in >> def tANDsp : PseudoInst<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >> - NoItinerary, "@ and $dst, $rhs", []>; >> + NoItinerary, "@ and\t$dst, $rhs", []>; >> } // usesCustomDAGSchedInserter >> >> // >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> @@ -175,16 +175,16 @@ >> // >> >> let isReturn = 1, isTerminator = 1, isBarrier = 1 in { >> - def tBX_RET : TI<(outs), (ins), IIC_Br, "bx lr", [(ARMretflag)]>; >> + def tBX_RET : TI<(outs), (ins), IIC_Br, "bx\tlr", [(ARMretflag)]>; >> // Alternative return instruction used by vararg functions. >> - def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx >> $target", []>; >> + def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t >> $target", []>; >> } >> >> // FIXME: remove when we have a way to marking a MI with these >> properties. >> let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, >> hasExtraDefRegAllocReq = 1 in >> def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$wb, >> variable_ops), IIC_Br, >> - "pop${p} $wb", []>; >> + "pop${p}\t$wb", []>; >> >> let isCall = 1, >> Defs = [R0, R1, R2, R3, R12, LR, >> @@ -193,25 +193,25 @@ >> D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { >> // Also used for Thumb2 >> def tBL : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, >> - "bl ${func:call}", >> + "bl\t${func:call}", >> [(ARMtcall tglobaladdr:$func)]>, >> Requires<[IsThumb, IsNotDarwin]>; >> >> // ARMv5T and above, also used for Thumb2 >> def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, >> - "blx ${func:call}", >> + "blx\t${func:call}", >> [(ARMcall tglobaladdr:$func)]>, >> Requires<[IsThumb, HasV5T, IsNotDarwin]>; >> >> // Also used for Thumb2 >> def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, >> - "blx $func", >> + "blx\t$func", >> [(ARMtcall GPR:$func)]>, >> Requires<[IsThumb, HasV5T, IsNotDarwin]>; >> >> // ARMv4T >> def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, >> - "mov lr, pc\n\tbx $func", >> + "mov\tlr, pc\n\tbx\t$func", >> [(ARMcall_nolink tGPR:$func)]>, >> Requires<[IsThumb1Only, IsNotDarwin]>; >> } >> @@ -224,25 +224,25 @@ >> D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { >> // Also used for Thumb2 >> def tBLr9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, >> - "bl ${func:call}", >> + "bl\t${func:call}", >> [(ARMtcall tglobaladdr:$func)]>, >> Requires<[IsThumb, IsDarwin]>; >> >> // ARMv5T and above, also used for Thumb2 >> def tBLXi_r9 : TIx2<(outs), (ins i32imm:$func, variable_ops), >> IIC_Br, >> - "blx ${func:call}", >> + "blx\t${func:call}", >> [(ARMcall tglobaladdr:$func)]>, >> Requires<[IsThumb, HasV5T, IsDarwin]>; >> >> // Also used for Thumb2 >> def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, >> - "blx $func", >> + "blx\t$func", >> [(ARMtcall GPR:$func)]>, >> Requires<[IsThumb, HasV5T, IsDarwin]>; >> >> // ARMv4T >> def tBXr9 : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, >> - "mov lr, pc\n\tbx $func", >> + "mov\tlr, pc\n\tbx\t$func", >> [(ARMcall_nolink tGPR:$func)]>, >> Requires<[IsThumb1Only, IsDarwin]>; >> } >> @@ -251,16 +251,16 @@ >> let isBarrier = 1 in { >> let isPredicable = 1 in >> def tB : T1I<(outs), (ins brtarget:$target), IIC_Br, >> - "b $target", [(br bb:$target)]>; >> + "b\t$target", [(br bb:$target)]>; >> >> // Far jump >> let Defs = [LR] in >> def tBfar : TIx2<(outs), (ins brtarget:$target), IIC_Br, >> - "bl $target\t@ far jump",[]>; >> + "bl\t$target\t@ far jump",[]>; >> >> def tBR_JTr : T1JTI<(outs), >> (ins tGPR:$target, jtblock_operand:$jt, i32imm: >> $id), >> - IIC_Br, "mov pc, $target\n\t.align\t2\n$jt", >> + IIC_Br, "mov\tpc, $target\n\t.align\t2\n$jt", >> [(ARMbrjt tGPR:$target, tjumptable:$jt, imm: >> $id)]>; >> } >> } >> @@ -269,7 +269,7 @@ >> // a two-value operand where a dag node expects two operands. :( >> let isBranch = 1, isTerminator = 1 in >> def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), IIC_Br, >> - "b$cc $target", >> + "b$cc\t$target", >> [/*(ARMbrcond bb:$target, imm:$cc)*/]>; >> >> // >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> @@ -278,70 +278,70 @@ >> >> let canFoldAsLoad = 1 in >> def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), >> IIC_iLoadr, >> - "ldr", " $dst, $addr", >> + "ldr", "\t$dst, $addr", >> [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>; >> >> def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), >> IIC_iLoadr, >> - "ldrb", " $dst, $addr", >> + "ldrb", "\t$dst, $addr", >> [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; >> >> def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), >> IIC_iLoadr, >> - "ldrh", " $dst, $addr", >> + "ldrh", "\t$dst, $addr", >> [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>; >> >> let AddedComplexity = 10 in >> def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), >> IIC_iLoadr, >> - "ldrsb", " $dst, $addr", >> + "ldrsb", "\t$dst, $addr", >> [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>; >> >> let AddedComplexity = 10 in >> def tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), >> IIC_iLoadr, >> - "ldrsh", " $dst, $addr", >> + "ldrsh", "\t$dst, $addr", >> [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))] >> >; >> >> let canFoldAsLoad = 1 in >> def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), >> IIC_iLoadi, >> - "ldr", " $dst, $addr", >> + "ldr", "\t$dst, $addr", >> [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>; >> >> // Special instruction for restore. It cannot clobber condition >> register >> // when it's expanded by eliminateCallFramePseudoInstr(). >> let canFoldAsLoad = 1, mayLoad = 1 in >> def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), >> IIC_iLoadi, >> - "ldr", " $dst, $addr", []>; >> + "ldr", "\t$dst, $addr", []>; >> >> // Load tconstpool >> let canFoldAsLoad = 1 in >> def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, >> - "ldr", " $dst, $addr", >> + "ldr", "\t$dst, $addr", >> [(set tGPR:$dst, (load (ARMWrapper tconstpool: >> $addr)))]>; >> >> // Special LDR for loads from non-pc-relative constpools. >> let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in >> def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, >> - "ldr", " $dst, $addr", []>; >> + "ldr", "\t$dst, $addr", []>; >> >> def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), >> IIC_iStorer, >> - "str", " $src, $addr", >> + "str", "\t$src, $addr", >> [(store tGPR:$src, t_addrmode_s4:$addr)]>; >> >> def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), >> IIC_iStorer, >> - "strb", " $src, $addr", >> + "strb", "\t$src, $addr", >> [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>; >> >> def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), >> IIC_iStorer, >> - "strh", " $src, $addr", >> + "strh", "\t$src, $addr", >> [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>; >> >> def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), >> IIC_iStorei, >> - "str", " $src, $addr", >> + "str", "\t$src, $addr", >> [(store tGPR:$src, t_addrmode_sp:$addr)]>; >> >> let mayStore = 1 in { >> // Special instruction for spill. It cannot clobber condition >> register >> // when it's expanded by eliminateCallFramePseudoInstr(). >> def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), >> IIC_iStorei, >> - "str", " $src, $addr", []>; >> + "str", "\t$src, $addr", []>; >> } >> >> // >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> @@ -353,21 +353,21 @@ >> def tLDM : T1I<(outs), >> (ins addrmode4:$addr, pred:$p, reglist:$wb, >> variable_ops), >> IIC_iLoadm, >> - "ldm${addr:submode}${p} $addr, $wb", []>; >> + "ldm${addr:submode}${p}\t$addr, $wb", []>; >> >> let mayStore = 1, hasExtraSrcRegAllocReq = 1 in >> def tSTM : T1I<(outs), >> (ins addrmode4:$addr, pred:$p, reglist:$wb, >> variable_ops), >> IIC_iStorem, >> - "stm${addr:submode}${p} $addr, $wb", []>; >> + "stm${addr:submode}${p}\t$addr, $wb", []>; >> >> let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = >> 1 in >> def tPOP : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), >> IIC_Br, >> - "pop${p} $wb", []>; >> + "pop${p}\t$wb", []>; >> >> let mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq >> = 1 in >> def tPUSH : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), >> IIC_Br, >> - "push${p} $wb", []>; >> + "push${p}\t$wb", []>; >> >> // >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> // Arithmetic Instructions. >> @@ -376,66 +376,66 @@ >> // Add with carry register >> let isCommutable = 1, Uses = [CPSR] in >> def tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >> IIC_iALUr, >> - "adc", " $dst, $rhs", >> + "adc", "\t$dst, $rhs", >> [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>; >> >> // Add immediate >> def tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), >> IIC_iALUi, >> - "add", " $dst, $lhs, $rhs", >> + "add", "\t$dst, $lhs, $rhs", >> [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>; >> >> def tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), >> IIC_iALUi, >> - "add", " $dst, $rhs", >> + "add", "\t$dst, $rhs", >> [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>; >> >> // Add register >> let isCommutable = 1 in >> def tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >> IIC_iALUr, >> - "add", " $dst, $lhs, $rhs", >> + "add", "\t$dst, $lhs, $rhs", >> [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>; >> >> let neverHasSideEffects = 1 in >> def tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), >> IIC_iALUr, >> - "add", " $dst, $rhs", []>; >> + "add", "\t$dst, $rhs", []>; >> >> // And register >> let isCommutable = 1 in >> def tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >> IIC_iALUr, >> - "and", " $dst, $rhs", >> + "and", "\t$dst, $rhs", >> [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>; >> >> // ASR immediate >> def tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), >> IIC_iMOVsi, >> - "asr", " $dst, $lhs, $rhs", >> + "asr", "\t$dst, $lhs, $rhs", >> [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>; >> >> // ASR register >> def tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >> IIC_iMOVsr, >> - "asr", " $dst, $rhs", >> + "asr", "\t$dst, $rhs", >> [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>; >> >> // BIC register >> def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >> IIC_iALUr, >> - "bic", " $dst, $rhs", >> + "bic", "\t$dst, $rhs", >> [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>; >> >> // CMN register >> let Defs = [CPSR] in { >> def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, >> - "cmn", " $lhs, $rhs", >> + "cmn", "\t$lhs, $rhs", >> [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>; >> def tCMNZ : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, >> - "cmn", " $lhs, $rhs", >> + "cmn", "\t$lhs, $rhs", >> [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>; >> } >> >> // CMP immediate >> let Defs = [CPSR] in { >> def tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, >> - "cmp", " $lhs, $rhs", >> + "cmp", "\t$lhs, $rhs", >> [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>; >> def tCMPzi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, >> - "cmp", " $lhs, $rhs", >> + "cmp", "\t$lhs, $rhs", >> [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>; >> >> } >> @@ -443,48 +443,48 @@ >> // CMP register >> let Defs = [CPSR] in { >> def tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, >> - "cmp", " $lhs, $rhs", >> + "cmp", "\t$lhs, $rhs", >> [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>; >> def tCMPzr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, >> - "cmp", " $lhs, $rhs", >> + "cmp", "\t$lhs, $rhs", >> [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>; >> >> def tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, >> - "cmp", " $lhs, $rhs", []>; >> + "cmp", "\t$lhs, $rhs", []>; >> def tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, >> - "cmp", " $lhs, $rhs", []>; >> + "cmp", "\t$lhs, $rhs", []>; >> } >> >> >> // XOR register >> let isCommutable = 1 in >> def tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >> IIC_iALUr, >> - "eor", " $dst, $rhs", >> + "eor", "\t$dst, $rhs", >> [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>; >> >> // LSL immediate >> def tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), >> IIC_iMOVsi, >> - "lsl", " $dst, $lhs, $rhs", >> + "lsl", "\t$dst, $lhs, $rhs", >> [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>; >> >> // LSL register >> def tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >> IIC_iMOVsr, >> - "lsl", " $dst, $rhs", >> + "lsl", "\t$dst, $rhs", >> [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>; >> >> // LSR immediate >> def tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), >> IIC_iMOVsi, >> - "lsr", " $dst, $lhs, $rhs", >> + "lsr", "\t$dst, $lhs, $rhs", >> [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>; >> >> // LSR register >> def tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >> IIC_iMOVsr, >> - "lsr", " $dst, $rhs", >> + "lsr", "\t$dst, $rhs", >> [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>; >> >> // move register >> def tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src), IIC_iMOVi, >> - "mov", " $dst, $src", >> + "mov", "\t$dst, $src", >> [(set tGPR:$dst, imm0_255:$src)]>; >> >> // TODO: A7-73: MOV(2) - mov setting flag. >> @@ -493,45 +493,45 @@ >> let neverHasSideEffects = 1 in { >> // FIXME: Make this predicable. >> def tMOVr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, >> - "mov $dst, $src", []>; >> + "mov\t$dst, $src", []>; >> let Defs = [CPSR] in >> def tMOVSr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, >> - "movs $dst, $src", []>; >> + "movs\t$dst, $src", []>; >> >> // FIXME: Make these predicable. >> def tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iMOVr, >> - "mov $dst, $src", []>; >> + "mov\t$dst, $src", []>; >> def tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iMOVr, >> - "mov $dst, $src", []>; >> + "mov\t$dst, $src", []>; >> def tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, >> - "mov $dst, $src", []>; >> + "mov\t$dst, $src", []>; >> } // neverHasSideEffects >> >> // multiply register >> let isCommutable = 1 in >> def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >> IIC_iMUL32, >> - "mul", " $dst, $rhs", >> + "mul", "\t$dst, $rhs", >> [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>; >> >> // move inverse register >> def tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, >> - "mvn", " $dst, $src", >> + "mvn", "\t$dst, $src", >> [(set tGPR:$dst, (not tGPR:$src))]>; >> >> // bitwise or register >> let isCommutable = 1 in >> def tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >> IIC_iALUr, >> - "orr", " $dst, $rhs", >> + "orr", "\t$dst, $rhs", >> [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>; >> >> // swaps >> def tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, >> - "rev", " $dst, $src", >> + "rev", "\t$dst, $src", >> [(set tGPR:$dst, (bswap tGPR:$src))]>, >> Requires<[IsThumb1Only, HasV6]>; >> >> def tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, >> - "rev16", " $dst, $src", >> + "rev16", "\t$dst, $src", >> [(set tGPR:$dst, >> (or (and (srl tGPR:$src, (i32 8)), 0xFF), >> (or (and (shl tGPR:$src, (i32 8)), 0xFF00), >> @@ -540,7 +540,7 @@ >> Requires<[IsThumb1Only, HasV6]>; >> >> def tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, >> - "revsh", " $dst, $src", >> + "revsh", "\t$dst, $src", >> [(set tGPR:$dst, >> (sext_inreg >> (or (srl (and tGPR:$src, 0xFF00), (i32 8)), >> @@ -549,63 +549,63 @@ >> >> // rotate right register >> def tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >> IIC_iMOVsr, >> - "ror", " $dst, $rhs", >> + "ror", "\t$dst, $rhs", >> [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>; >> >> // negate register >> def tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALUi, >> - "rsb", " $dst, $src, #0", >> + "rsb", "\t$dst, $src, #0", >> [(set tGPR:$dst, (ineg tGPR:$src))]>; >> >> // Subtract with carry register >> let Uses = [CPSR] in >> def tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >> IIC_iALUr, >> - "sbc", " $dst, $rhs", >> + "sbc", "\t$dst, $rhs", >> [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>; >> >> // Subtract immediate >> def tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), >> IIC_iALUi, >> - "sub", " $dst, $lhs, $rhs", >> + "sub", "\t$dst, $lhs, $rhs", >> [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))] >> >; >> >> def tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), >> IIC_iALUi, >> - "sub", " $dst, $rhs", >> + "sub", "\t$dst, $rhs", >> [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg: >> $rhs))]>; >> >> // subtract register >> def tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >> IIC_iALUr, >> - "sub", " $dst, $lhs, $rhs", >> + "sub", "\t$dst, $lhs, $rhs", >> [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>; >> >> // TODO: A7-96: STMIA - store multiple. >> >> // sign-extend byte >> def tSXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, >> - "sxtb", " $dst, $src", >> + "sxtb", "\t$dst, $src", >> [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>, >> Requires<[IsThumb1Only, HasV6]>; >> >> // sign-extend short >> def tSXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, >> - "sxth", " $dst, $src", >> + "sxth", "\t$dst, $src", >> [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>, >> Requires<[IsThumb1Only, HasV6]>; >> >> // test >> let isCommutable = 1, Defs = [CPSR] in >> def tTST : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, >> - "tst", " $lhs, $rhs", >> + "tst", "\t$lhs, $rhs", >> [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>; >> >> // zero-extend byte >> def tUXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, >> - "uxtb", " $dst, $src", >> + "uxtb", "\t$dst, $src", >> [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>, >> Requires<[IsThumb1Only, HasV6]>; >> >> // zero-extend short >> def tUXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, >> - "uxth", " $dst, $src", >> + "uxth", "\t$dst, $src", >> [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>, >> Requires<[IsThumb1Only, HasV6]>; >> >> @@ -621,19 +621,19 @@ >> >> // 16-bit movcc in IT blocks for Thumb2. >> def tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), >> IIC_iCMOVr, >> - "mov", " $dst, $rhs", []>; >> + "mov", "\t$dst, $rhs", []>; >> >> def tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), >> IIC_iCMOVi, >> - "mov", " $dst, $rhs", []>; >> + "mov", "\t$dst, $rhs", []>; >> >> // tLEApcrel - Load a pc-relative address into a register without >> offending the >> // assembler. >> def tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label, pred:$p), >> IIC_iALUi, >> - "adr$p $dst, #$label", []>; >> + "adr$p\t$dst, #$label", []>; >> >> def tLEApcrelJT : T1I<(outs tGPR:$dst), >> (ins i32imm:$label, nohash_imm:$id, pred:$p), >> - IIC_iALUi, "adr$p $dst, #${label}_${id}", []>; >> + IIC_iALUi, "adr$p\t$dst, #${label}_${id}", [] >> >; >> >> // >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> // TLS Instructions >> @@ -643,7 +643,7 @@ >> let isCall = 1, >> Defs = [R0, LR] in { >> def tTPsoft : TIx2<(outs), (ins), IIC_Br, >> - "bl __aeabi_read_tp", >> + "bl\t__aeabi_read_tp", >> [(set R0, ARMthread_pointer)]>; >> } >> >> >> Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=85184&r1=85183&r2=85184&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) >> +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon Oct 26 19:08:59 >> 2009 >> @@ -153,18 +153,18 @@ >> multiclass T2I_un_irs> bit ReMat = 0>{ >> // shifted imm >> def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi, >> - opc, " $dst, $src", >> + opc, "\t$dst, $src", >> [(set GPR:$dst, (opnode t2_so_imm:$src))]> { >> let isAsCheapAsAMove = Cheap; >> let isReMaterializable = ReMat; >> } >> // register >> def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, >> - opc, ".w $dst, $src", >> + opc, ".w\t$dst, $src", >> [(set GPR:$dst, (opnode GPR:$src))]>; >> // shifted register >> def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), IIC_iMOVsi, >> - opc, ".w $dst, $src", >> + opc, ".w\t$dst, $src", >> [(set GPR:$dst, (opnode t2_so_reg:$src))]>; >> } >> >> @@ -175,17 +175,17 @@ >> bit Commutable = 0, string wide =""> { >> // shifted imm >> def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), >> IIC_iALUi, >> - opc, " $dst, $lhs, $rhs", >> + opc, "\t$dst, $lhs, $rhs", >> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; >> // register >> def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, >> - opc, !strconcat(wide, " $dst, $lhs, $rhs"), >> + opc, !strconcat(wide, "\t$dst, $lhs, $rhs"), >> [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { >> let isCommutable = Commutable; >> } >> // shifted register >> def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), >> IIC_iALUsi, >> - opc, !strconcat(wide, " $dst, $lhs, $rhs"), >> + opc, !strconcat(wide, "\t$dst, $lhs, $rhs"), >> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; >> } >> >> @@ -200,11 +200,11 @@ >> multiclass T2I_rbin_is { >> // shifted imm >> def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), >> IIC_iALUi, >> - opc, ".w $dst, $rhs, $lhs", >> + opc, ".w\t$dst, $rhs, $lhs", >> [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; >> // shifted register >> def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), >> IIC_iALUsi, >> - opc, " $dst, $rhs, $lhs", >> + opc, "\t$dst, $rhs, $lhs", >> [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>; >> } >> >> @@ -214,17 +214,17 @@ >> multiclass T2I_bin_s_irs> = 0> { >> // shifted imm >> def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), >> IIC_iALUi, >> - !strconcat(opc, "s"), ".w $dst, $lhs, $rhs", >> + !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs", >> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; >> // register >> def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, >> - !strconcat(opc, "s"), ".w $dst, $lhs, $rhs", >> + !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs", >> [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { >> let isCommutable = Commutable; >> } >> // shifted register >> def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), >> IIC_iALUsi, >> - !strconcat(opc, "s"), ".w $dst, $lhs, $rhs", >> + !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs", >> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; >> } >> } >> @@ -234,21 +234,21 @@ >> multiclass T2I_bin_ii12rs> Commutable = 0> { >> // shifted imm >> def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), >> IIC_iALUi, >> - opc, ".w $dst, $lhs, $rhs", >> + opc, ".w\t$dst, $lhs, $rhs", >> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; >> // 12-bit imm >> def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), >> IIC_iALUi, >> - !strconcat(opc, "w"), " $dst, $lhs, $rhs", >> + !strconcat(opc, "w"), "\t$dst, $lhs, $rhs", >> [(set GPR:$dst, (opnode GPR:$lhs, >> imm0_4095:$rhs))]>; >> // register >> def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, >> - opc, ".w $dst, $lhs, $rhs", >> + opc, ".w\t$dst, $lhs, $rhs", >> [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { >> let isCommutable = Commutable; >> } >> // shifted register >> def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), >> IIC_iALUsi, >> - opc, ".w $dst, $lhs, $rhs", >> + opc, ".w\t$dst, $lhs, $rhs", >> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; >> } >> >> @@ -259,32 +259,32 @@ >> multiclass T2I_adde_sube_irs> Commutable = 0> { >> // shifted imm >> def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), >> IIC_iALUi, >> - opc, " $dst, $lhs, $rhs", >> + opc, "\t$dst, $lhs, $rhs", >> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>, >> Requires<[IsThumb2, CarryDefIsUnused]>; >> // register >> def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, >> - opc, ".w $dst, $lhs, $rhs", >> + opc, ".w\t$dst, $lhs, $rhs", >> [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>, >> Requires<[IsThumb2, CarryDefIsUnused]> { >> let isCommutable = Commutable; >> } >> // shifted register >> def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), >> IIC_iALUsi, >> - opc, ".w $dst, $lhs, $rhs", >> + opc, ".w\t$dst, $lhs, $rhs", >> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>, >> Requires<[IsThumb2, CarryDefIsUnused]>; >> // Carry setting variants >> // shifted imm >> def Sri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), >> IIC_iALUi, >> - !strconcat(opc, "s $dst, $lhs, $rhs"), >> + !strconcat(opc, "s\t$dst, $lhs, $rhs"), >> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))] >> >, >> Requires<[IsThumb2, CarryDefIsUsed]> { >> let Defs = [CPSR]; >> } >> // register >> def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), >> IIC_iALUr, >> - !strconcat(opc, "s.w $dst, $lhs, $rhs"), >> + !strconcat(opc, "s.w\t$dst, $lhs, $rhs"), >> [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>, >> Requires<[IsThumb2, CarryDefIsUsed]> { >> let Defs = [CPSR]; >> @@ -292,7 +292,7 @@ >> } >> // shifted register >> def Srs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), >> IIC_iALUsi, >> - !strconcat(opc, "s.w $dst, $lhs, $rhs"), >> + !strconcat(opc, "s.w\t$dst, $lhs, $rhs"), >> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))] >> >, >> Requires<[IsThumb2, CarryDefIsUsed]> { >> let Defs = [CPSR]; >> @@ -306,12 +306,12 @@ >> // shifted imm >> def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, >> cc_out:$s), >> IIC_iALUi, >> - !strconcat(opc, "${s}.w $dst, $rhs, $lhs"), >> + !strconcat(opc, "${s}.w\t$dst, $rhs, $lhs"), >> [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; >> // shifted register >> def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, >> cc_out:$s), >> IIC_iALUsi, >> - !strconcat(opc, "${s} $dst, $rhs, $lhs"), >> + !strconcat(opc, "${s}\t$dst, $rhs, $lhs"), >> [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>; >> } >> } >> @@ -321,11 +321,11 @@ >> multiclass T2I_sh_ir { >> // 5-bit imm >> def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), >> IIC_iMOVsi, >> - opc, ".w $dst, $lhs, $rhs", >> + opc, ".w\t$dst, $lhs, $rhs", >> [(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]>; >> // register >> def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), >> IIC_iMOVsr, >> - opc, ".w $dst, $lhs, $rhs", >> + opc, ".w\t$dst, $lhs, $rhs", >> [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>; >> } >> >> @@ -336,15 +336,15 @@ >> multiclass T2I_cmp_is { >> // shifted imm >> def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iCMPi, >> - opc, ".w $lhs, $rhs", >> + opc, ".w\t$lhs, $rhs", >> [(opnode GPR:$lhs, t2_so_imm:$rhs)]>; >> // register >> def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, >> - opc, ".w $lhs, $rhs", >> + opc, ".w\t$lhs, $rhs", >> [(opnode GPR:$lhs, GPR:$rhs)]>; >> // shifted register >> def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iCMPsi, >> - opc, ".w $lhs, $rhs", >> + opc, ".w\t$lhs, $rhs", >> [(opnode GPR:$lhs, t2_so_reg:$rhs)]>; >> } >> } >> @@ -352,42 +352,42 @@ >> /// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load >> patterns. >> multiclass T2I_ld { >> def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), >> IIC_iLoadi, >> - opc, ".w $dst, $addr", >> + opc, ".w\t$dst, $addr", >> [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]>; >> def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), >> IIC_iLoadi, >> - opc, " $dst, $addr", >> + opc, "\t$dst, $addr", >> [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]>; >> def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), >> IIC_iLoadr, >> - opc, ".w $dst, $addr", >> + opc, ".w\t$dst, $addr", >> [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))] >> >; >> def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoadi, >> - opc, ".w $dst, $addr", >> + opc, ".w\t$dst, $addr", >> [(set GPR:$dst, (opnode (ARMWrapper tconstpool: >> $addr)))]>; >> } >> >> /// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store >> patterns. >> multiclass T2I_st { >> def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), >> IIC_iStorei, >> - opc, ".w $src, $addr", >> + opc, ".w\t$src, $addr", >> [(opnode GPR:$src, t2addrmode_imm12:$addr)]>; >> def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), >> IIC_iStorei, >> - opc, " $src, $addr", >> + opc, "\t$src, $addr", >> [(opnode GPR:$src, t2addrmode_imm8:$addr)]>; >> def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), >> IIC_iStorer, >> - opc, ".w $src, $addr", >> + opc, ".w\t$src, $addr", >> [(opnode GPR:$src, t2addrmode_so_reg:$addr)]>; >> } >> >> /// T2I_picld - Defines the PIC load pattern. >> class T2I_picld : >> T2I<(outs GPR:$dst), (ins addrmodepc:$addr), IIC_iLoadi, >> - !strconcat("\n${addr:label}:\n\t", opc), " $dst, $addr", >> + !strconcat("\n${addr:label}:\n\t", opc), "\t$dst, $addr", >> [(set GPR:$dst, (opnode addrmodepc:$addr))]>; >> >> /// T2I_picst - Defines the PIC store pattern. >> class T2I_picst : >> T2I<(outs), (ins GPR:$src, addrmodepc:$addr), IIC_iStorer, >> - !strconcat("\n${addr:label}:\n\t", opc), " $src, $addr", >> + !strconcat("\n${addr:label}:\n\t", opc), "\t$src, $addr", >> [(opnode GPR:$src, addrmodepc:$addr)]>; >> >> >> @@ -395,10 +395,10 @@ >> /// register and one whose operand is a register rotated by 8/16/24. >> multiclass T2I_unary_rrot { >> def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, >> - opc, ".w $dst, $src", >> + opc, ".w\t$dst, $src", >> [(set GPR:$dst, (opnode GPR:$src))]>; >> def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), >> IIC_iUNAsi, >> - opc, ".w $dst, $src, ror $rot", >> + opc, ".w\t$dst, $src, ror $rot", >> [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm: >> $rot)))]>; >> } >> >> @@ -406,10 +406,10 @@ >> /// register and one whose operand is a register rotated by 8/16/24. >> multiclass T2I_bin_rrot { >> def rr : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), >> IIC_iALUr, >> - opc, " $dst, $LHS, $RHS", >> + opc, "\t$dst, $LHS, $RHS", >> [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>; >> def rr_rot : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm: >> $rot), >> - IIC_iALUsr, opc, " $dst, $LHS, $RHS, ror $rot", >> + IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot", >> [(set GPR:$dst, (opnode GPR:$LHS, >> (rotr GPR:$RHS, rot_imm: >> $rot)))]>; >> } >> @@ -425,42 +425,42 @@ >> // LEApcrel - Load a pc-relative address into a register without >> offending the >> // assembler. >> def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred: >> $p), IIC_iALUi, >> - "adr$p.w $dst, #$label", []>; >> + "adr$p.w\t$dst, #$label", []>; >> >> def t2LEApcrelJT : T2XI<(outs GPR:$dst), >> (ins i32imm:$label, nohash_imm:$id, pred: >> $p), IIC_iALUi, >> - "adr$p.w $dst, #${label}_${id}", []>; >> + "adr$p.w\t$dst, #${label}_${id}", []>; >> >> // ADD r, sp, {so_imm|i12} >> def t2ADDrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm: >> $imm), >> - IIC_iALUi, "add", ".w $dst, $sp, $imm", []>; >> + IIC_iALUi, "add", ".w\t$dst, $sp, $imm", [] >> >; >> def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm), >> - IIC_iALUi, "addw", " $dst, $sp, $imm", []>; >> + IIC_iALUi, "addw", "\t$dst, $sp, $imm", []>; >> >> // ADD r, sp, so_reg >> def t2ADDrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg: >> $rhs), >> - IIC_iALUsi, "add", ".w $dst, $sp, $rhs", [] >> >; >> + IIC_iALUsi, "add", ".w\t$dst, $sp, $rhs", >> []>; >> >> // SUB r, sp, {so_imm|i12} >> def t2SUBrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm: >> $imm), >> - IIC_iALUi, "sub", ".w $dst, $sp, $imm", []>; >> + IIC_iALUi, "sub", ".w\t$dst, $sp, $imm", [] >> >; >> def t2SUBrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm), >> - IIC_iALUi, "subw", " $dst, $sp, $imm", []>; >> + IIC_iALUi, "subw", "\t$dst, $sp, $imm", []>; >> >> // SUB r, sp, so_reg >> def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg: >> $rhs), >> IIC_iALUsi, >> - "sub", " $dst, $sp, $rhs", []>; >> + "sub", "\t$dst, $sp, $rhs", []>; >> >> >> // Pseudo instruction that will expand into a t2SUBrSPi + a copy. >> let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. >> def t2SUBrSPi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, >> t2_so_imm:$imm), >> - NoItinerary, "@ sub.w $dst, $sp, $imm", []>; >> + NoItinerary, "@ sub.w\t$dst, $sp, $imm", []>; >> def t2SUBrSPi12_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, >> imm0_4095:$imm), >> - NoItinerary, "@ subw $dst, $sp, $imm", []>; >> + NoItinerary, "@ subw\t$dst, $sp, $imm", []>; >> def t2SUBrSPs_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, >> t2_so_reg:$rhs), >> - NoItinerary, "@ sub $dst, $sp, $rhs", []>; >> + NoItinerary, "@ sub\t$dst, $sp, $rhs", []>; >> } // usesCustomDAGSchedInserter >> >> >> @@ -484,10 +484,10 @@ >> // Load doubleword >> def t2LDRDi8 : T2Ii8s4<(outs GPR:$dst1, GPR:$dst2), >> (ins t2addrmode_imm8s4:$addr), >> - IIC_iLoadi, "ldrd", " $dst1, $addr", []>; >> + IIC_iLoadi, "ldrd", "\t$dst1, $addr", []>; >> def t2LDRDpci : T2Ii8s4<(outs GPR:$dst1, GPR:$dst2), >> (ins i32imm:$addr), IIC_iLoadi, >> - "ldrd", " $dst1, $addr", []>; >> + "ldrd", "\t$dst1, $addr", []>; >> } >> >> // zextload i1 -> zextload i8 >> @@ -535,57 +535,57 @@ >> def t2LDR_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >> (ins t2addrmode_imm8:$addr), >> AddrModeT2_i8, IndexModePre, IIC_iLoadiu, >> - "ldr", " $dst, $addr!", "$addr.base = >> $base_wb", >> + "ldr", "\t$dst, $addr!", "$addr.base = >> $base_wb", >> []>; >> >> def t2LDR_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >> (ins GPR:$base, t2am_imm8_offset:$offset), >> AddrModeT2_i8, IndexModePost, IIC_iLoadiu, >> - "ldr", " $dst, [$base], $offset", >> "$base = $base_wb", >> + "ldr", "\t$dst, [$base], $offset", >> "$base = $base_wb", >> []>; >> >> def t2LDRB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >> (ins t2addrmode_imm8:$addr), >> AddrModeT2_i8, IndexModePre, IIC_iLoadiu, >> - "ldrb", " $dst, $addr!", "$addr.base = >> $base_wb", >> + "ldrb", "\t$dst, $addr!", "$addr.base >> = $base_wb", >> []>; >> def t2LDRB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >> (ins GPR:$base, t2am_imm8_offset:$offset), >> AddrModeT2_i8, IndexModePost, IIC_iLoadiu, >> - "ldrb", " $dst, [$base], $offset", >> "$base = $base_wb", >> + "ldrb", "\t$dst, [$base], $offset", >> "$base = $base_wb", >> []>; >> >> def t2LDRH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >> (ins t2addrmode_imm8:$addr), >> AddrModeT2_i8, IndexModePre, IIC_iLoadiu, >> - "ldrh", " $dst, $addr!", "$addr.base = >> $base_wb", >> + "ldrh", "\t$dst, $addr!", "$addr.base >> = $base_wb", >> []>; >> def t2LDRH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >> (ins GPR:$base, t2am_imm8_offset:$offset), >> AddrModeT2_i8, IndexModePost, IIC_iLoadiu, >> - "ldrh", " $dst, [$base], $offset", >> "$base = $base_wb", >> + "ldrh", "\t$dst, [$base], $offset", >> "$base = $base_wb", >> []>; >> >> def t2LDRSB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >> (ins t2addrmode_imm8:$addr), >> AddrModeT2_i8, IndexModePre, IIC_iLoadiu, >> - "ldrsb", " $dst, $addr!", "$addr.base >> = $base_wb", >> + "ldrsb", "\t$dst, $addr!", "$addr.base >> = $base_wb", >> []>; >> def t2LDRSB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >> (ins GPR:$base, t2am_imm8_offset:$offset), >> AddrModeT2_i8, IndexModePost, IIC_iLoadiu, >> - "ldrsb", " $dst, [$base], $offset", >> "$base = $base_wb", >> + "ldrsb", "\t$dst, [$base], $offset", >> "$base = $base_wb", >> []>; >> >> def t2LDRSH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >> (ins t2addrmode_imm8:$addr), >> AddrModeT2_i8, IndexModePre, IIC_iLoadiu, >> - "ldrsh", " $dst, $addr!", "$addr.base >> = $base_wb", >> + "ldrsh", "\t$dst, $addr!", "$addr.base >> = $base_wb", >> []>; >> def t2LDRSH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >> (ins GPR:$base, t2am_imm8_offset:$offset), >> AddrModeT2_i8, IndexModePost, IIC_iLoadiu, >> - "ldrsh", " $dst, [$base], $offset", >> "$base = $base_wb", >> + "ldrsh", "\t$dst, [$base], $offset", >> "$base = $base_wb", >> []>; >> } >> >> @@ -598,48 +598,48 @@ >> let mayLoad = 1, hasExtraSrcRegAllocReq = 1 in >> def t2STRDi8 : T2Ii8s4<(outs), >> (ins GPR:$src1, GPR:$src2, >> t2addrmode_imm8s4:$addr), >> - IIC_iStorer, "strd", " $src1, $addr", []>; >> + IIC_iStorer, "strd", "\t$src1, $addr", []>; >> >> // Indexed stores >> def t2STR_PRE : T2Iidxldst<(outs GPR:$base_wb), >> (ins GPR:$src, GPR:$base, >> t2am_imm8_offset:$offset), >> AddrModeT2_i8, IndexModePre, IIC_iStoreiu, >> - "str", " $src, [$base, $offset]!", >> "$base = $base_wb", >> + "str", "\t$src, [$base, $offset]!", >> "$base = $base_wb", >> [(set GPR:$base_wb, >> (pre_store GPR:$src, GPR:$base, t2am_imm8_offset: >> $offset))]>; >> >> def t2STR_POST : T2Iidxldst<(outs GPR:$base_wb), >> (ins GPR:$src, GPR:$base, >> t2am_imm8_offset:$offset), >> AddrModeT2_i8, IndexModePost, >> IIC_iStoreiu, >> - "str", " $src, [$base], $offset", >> "$base = $base_wb", >> + "str", "\t$src, [$base], $offset", >> "$base = $base_wb", >> [(set GPR:$base_wb, >> (post_store GPR:$src, GPR:$base, t2am_imm8_offset: >> $offset))]>; >> >> def t2STRH_PRE : T2Iidxldst<(outs GPR:$base_wb), >> (ins GPR:$src, GPR:$base, >> t2am_imm8_offset:$offset), >> AddrModeT2_i8, IndexModePre, IIC_iStoreiu, >> - "strh", " $src, [$base, $offset]!", >> "$base = $base_wb", >> + "strh", "\t$src, [$base, $offset]!", >> "$base = $base_wb", >> [(set GPR:$base_wb, >> (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset: >> $offset))]>; >> >> def t2STRH_POST : T2Iidxldst<(outs GPR:$base_wb), >> (ins GPR:$src, GPR:$base, >> t2am_imm8_offset:$offset), >> AddrModeT2_i8, IndexModePost, >> IIC_iStoreiu, >> - "strh", " $src, [$base], $offset", >> "$base = $base_wb", >> + "strh", "\t$src, [$base], $offset", >> "$base = $base_wb", >> [(set GPR:$base_wb, >> (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset: >> $offset))]>; >> >> def t2STRB_PRE : T2Iidxldst<(outs GPR:$base_wb), >> (ins GPR:$src, GPR:$base, >> t2am_imm8_offset:$offset), >> AddrModeT2_i8, IndexModePre, IIC_iStoreiu, >> - "strb", " $src, [$base, $offset]!", >> "$base = $base_wb", >> + "strb", "\t$src, [$base, $offset]!", >> "$base = $base_wb", >> [(set GPR:$base_wb, >> (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset: >> $offset))]>; >> >> def t2STRB_POST : T2Iidxldst<(outs GPR:$base_wb), >> (ins GPR:$src, GPR:$base, >> t2am_imm8_offset:$offset), >> AddrModeT2_i8, IndexModePost, >> IIC_iStoreiu, >> - "strb", " $src, [$base], $offset", >> "$base = $base_wb", >> + "strb", "\t$src, [$base], $offset", >> "$base = $base_wb", >> [(set GPR:$base_wb, >> (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset: >> $offset))]>; >> >> @@ -653,12 +653,12 @@ >> let mayLoad = 1, hasExtraDefRegAllocReq = 1 in >> def t2LDM : T2XI<(outs), >> (ins addrmode4:$addr, pred:$p, reglist:$wb, >> variable_ops), >> - IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide} >> $addr, $wb", []>; >> + IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide}\t >> $addr, $wb", []>; >> >> let mayStore = 1, hasExtraSrcRegAllocReq = 1 in >> def t2STM : T2XI<(outs), >> (ins addrmode4:$addr, pred:$p, reglist:$wb, >> variable_ops), >> - IIC_iStorem, "stm${addr:submode}${p}${addr:wide} >> $addr, $wb", []>; >> + IIC_iStorem, "stm${addr:submode}${p}${addr:wide}\t >> $addr, $wb", []>; >> >> // >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> // Move Instructions. >> @@ -666,22 +666,22 @@ >> >> let neverHasSideEffects = 1 in >> def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, >> - "mov", ".w $dst, $src", []>; >> + "mov", ".w\t$dst, $src", []>; >> >> // AddedComplexity to ensure isel tries t2MOVi before t2MOVi16. >> let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = >> 1 in >> def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi, >> - "mov", ".w $dst, $src", >> + "mov", ".w\t$dst, $src", >> [(set GPR:$dst, t2_so_imm:$src)]>; >> >> let isReMaterializable = 1, isAsCheapAsAMove = 1 in >> def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi, >> - "movw", " $dst, $src", >> + "movw", "\t$dst, $src", >> [(set GPR:$dst, imm0_65535:$src)]>; >> >> let Constraints = "$src = $dst" in >> def t2MOVTi16 : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), >> IIC_iMOVi, >> - "movt", " $dst, $imm", >> + "movt", "\t$dst, $imm", >> [(set GPR:$dst, >> (or (and GPR:$src, 0xffff), lo16AllZero: >> $imm))]>; >> >> @@ -760,16 +760,16 @@ >> >> let Uses = [CPSR] in { >> def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, >> - "rrx", " $dst, $src", >> + "rrx", "\t$dst, $src", >> [(set GPR:$dst, (ARMrrx GPR:$src))]>; >> } >> >> let Defs = [CPSR] in { >> def t2MOVsrl_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, >> - "lsrs.w $dst, $src, #1", >> + "lsrs.w\t$dst, $src, #1", >> [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>; >> def t2MOVsra_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, >> - "asrs.w $dst, $src, #1", >> + "asrs.w\t$dst, $src, #1", >> [(set GPR:$dst, (ARMsra_flag GPR:$src))]>; >> } >> >> @@ -785,14 +785,14 @@ >> >> let Constraints = "$src = $dst" in >> def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm: >> $imm), >> - IIC_iALUi, "bfc", " $dst, $imm", >> + IIC_iALUi, "bfc", "\t$dst, $imm", >> [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm: >> $imm))]>; >> >> def t2SBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, >> imm0_31:$width), >> - IIC_iALUi, "sbfx", " $dst, $src, $lsb, $width", [] >> >; >> + IIC_iALUi, "sbfx", "\t$dst, $src, $lsb, $width", >> []>; >> >> def t2UBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, >> imm0_31:$width), >> - IIC_iALUi, "ubfx", " $dst, $src, $lsb, $width", [] >> >; >> + IIC_iALUi, "ubfx", "\t$dst, $src, $lsb, $width", >> []>; >> >> // FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1) >> >> @@ -819,80 +819,80 @@ >> // >> let isCommutable = 1 in >> def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, >> - "mul", " $dst, $a, $b", >> + "mul", "\t$dst, $a, $b", >> [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>; >> >> def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), >> IIC_iMAC32, >> - "mla", " $dst, $a, $b, $c", >> + "mla", "\t$dst, $a, $b, $c", >> [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>; >> >> def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), >> IIC_iMAC32, >> - "mls", " $dst, $a, $b, $c", >> + "mls", "\t$dst, $a, $b, $c", >> [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>; >> >> // Extra precision multiplies with low / high results >> let neverHasSideEffects = 1 in { >> let isCommutable = 1 in { >> def t2SMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR: >> $b), IIC_iMUL64, >> - "smull", " $ldst, $hdst, $a, $b", []>; >> + "smull", "\t$ldst, $hdst, $a, $b", []>; >> >> def t2UMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR: >> $b), IIC_iMUL64, >> - "umull", " $ldst, $hdst, $a, $b", []>; >> + "umull", "\t$ldst, $hdst, $a, $b", []>; >> } >> >> // Multiply + accumulate >> def t2SMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR: >> $b), IIC_iMAC64, >> - "smlal", " $ldst, $hdst, $a, $b", []>; >> + "smlal", "\t$ldst, $hdst, $a, $b", []>; >> >> def t2UMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR: >> $b), IIC_iMAC64, >> - "umlal", " $ldst, $hdst, $a, $b", []>; >> + "umlal", "\t$ldst, $hdst, $a, $b", []>; >> >> def t2UMAAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR: >> $b), IIC_iMAC64, >> - "umaal", " $ldst, $hdst, $a, $b", []>; >> + "umaal", "\t$ldst, $hdst, $a, $b", []>; >> } // neverHasSideEffects >> >> // Most significant word multiply >> def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, >> - "smmul", " $dst, $a, $b", >> + "smmul", "\t$dst, $a, $b", >> [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>; >> >> def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), >> IIC_iMAC32, >> - "smmla", " $dst, $a, $b, $c", >> + "smmla", "\t$dst, $a, $b, $c", >> [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR: >> $c))]>; >> >> >> def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), >> IIC_iMAC32, >> - "smmls", " $dst, $a, $b, $c", >> + "smmls", "\t$dst, $a, $b, $c", >> [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR: >> $b)))]>; >> >> multiclass T2I_smul { >> def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, >> - !strconcat(opc, "bb"), " $dst, $a, $b", >> + !strconcat(opc, "bb"), "\t$dst, $a, $b", >> [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16), >> (sext_inreg GPR:$b, i16)))]>; >> >> def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, >> - !strconcat(opc, "bt"), " $dst, $a, $b", >> + !strconcat(opc, "bt"), "\t$dst, $a, $b", >> [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16), >> (sra GPR:$b, (i32 16))))]>; >> >> def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, >> - !strconcat(opc, "tb"), " $dst, $a, $b", >> + !strconcat(opc, "tb"), "\t$dst, $a, $b", >> [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)), >> (sext_inreg GPR:$b, i16)))]>; >> >> def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, >> - !strconcat(opc, "tt"), " $dst, $a, $b", >> + !strconcat(opc, "tt"), "\t$dst, $a, $b", >> [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)), >> (sra GPR:$b, (i32 16))))]>; >> >> def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16, >> - !strconcat(opc, "wb"), " $dst, $a, $b", >> + !strconcat(opc, "wb"), "\t$dst, $a, $b", >> [(set GPR:$dst, (sra (opnode GPR:$a, >> (sext_inreg GPR:$b, i16)), (i32 >> 16)))]>; >> >> def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16, >> - !strconcat(opc, "wt"), " $dst, $a, $b", >> + !strconcat(opc, "wt"), "\t$dst, $a, $b", >> [(set GPR:$dst, (sra (opnode GPR:$a, >> (sra GPR:$b, (i32 16))), (i32 >> 16)))]>; >> } >> @@ -900,33 +900,33 @@ >> >> multiclass T2I_smla { >> def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), >> IIC_iMAC16, >> - !strconcat(opc, "bb"), " $dst, $a, $b, $acc", >> + !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc", >> [(set GPR:$dst, (add GPR:$acc, >> (opnode (sext_inreg GPR:$a, i16), >> (sext_inreg GPR:$b, i16))))]>; >> >> def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), >> IIC_iMAC16, >> - !strconcat(opc, "bt"), " $dst, $a, $b, $acc", >> + !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc", >> [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR: >> $a, i16), >> (sra GPR:$b, >> (i32 16)))))]>; >> >> def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), >> IIC_iMAC16, >> - !strconcat(opc, "tb"), " $dst, $a, $b, $acc", >> + !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc", >> [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, >> (i32 16)), >> (sext_inreg GPR:$b, >> i16))))]>; >> >> def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), >> IIC_iMAC16, >> - !strconcat(opc, "tt"), " $dst, $a, $b, $acc", >> + !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc", >> [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, >> (i32 16)), >> (sra GPR:$b, >> (i32 16)))))]>; >> >> def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), >> IIC_iMAC16, >> - !strconcat(opc, "wb"), " $dst, $a, $b, $acc", >> + !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc", >> [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a, >> (sext_inreg GPR:$b, i16)), >> (i32 16))))]>; >> >> def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), >> IIC_iMAC16, >> - !strconcat(opc, "wt"), " $dst, $a, $b, $acc", >> + !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc", >> [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a, >> (sra GPR:$b, (i32 16))), >> (i32 16))))]>; >> } >> @@ -943,15 +943,15 @@ >> // >> >> def t2CLZ : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, >> - "clz", " $dst, $src", >> + "clz", "\t$dst, $src", >> [(set GPR:$dst, (ctlz GPR:$src))]>; >> >> def t2REV : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, >> - "rev", ".w $dst, $src", >> + "rev", ".w\t$dst, $src", >> [(set GPR:$dst, (bswap GPR:$src))]>; >> >> def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, >> - "rev16", ".w $dst, $src", >> + "rev16", ".w\t$dst, $src", >> [(set GPR:$dst, >> (or (and (srl GPR:$src, (i32 8)), 0xFF), >> (or (and (shl GPR:$src, (i32 8)), 0xFF00), >> @@ -959,14 +959,14 @@ >> (and (shl GPR:$src, (i32 8)), >> 0xFF000000)))))]>; >> >> def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, >> - "revsh", ".w $dst, $src", >> + "revsh", ".w\t$dst, $src", >> [(set GPR:$dst, >> (sext_inreg >> (or (srl (and GPR:$src, 0xFF00), (i32 8)), >> (shl GPR:$src, (i32 8))), i16))]>; >> >> def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, >> i32imm:$shamt), >> - IIC_iALUsi, "pkhbt", " $dst, $src1, $src2, LSL >> $shamt", >> + IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL >> $shamt", >> [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF), >> (and (shl GPR:$src2, (i32 imm: >> $shamt)), >> 0xFFFF0000)))]>; >> @@ -978,7 +978,7 @@ >> (t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>; >> >> def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, >> i32imm:$shamt), >> - IIC_iALUsi, "pkhtb", " $dst, $src1, $src2, ASR >> $shamt", >> + IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR >> $shamt", >> [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000), >> (and (sra GPR:$src2, >> imm16_31:$shamt), >> 0xFFFF)))]>; >> @@ -1025,26 +1025,26 @@ >> // FIXME: should be able to write a pattern for ARMcmov, but can't >> use >> // a two-value operand where a dag node expects two operands. :( >> def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true), >> IIC_iCMOVr, >> - "mov", ".w $dst, $true", >> + "mov", ".w\t$dst, $true", >> [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR: >> $ccr))*/]>, >> RegConstraint<"$false = $dst">; >> >> def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm: >> $true), >> - IIC_iCMOVi, "mov", ".w $dst, $true", >> + IIC_iCMOVi, "mov", ".w\t$dst, $true", >> [/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_imm:$true, imm:$cc, >> CCR:$ccr))*/]>, >> RegConstraint<"$false = $dst">; >> >> def t2MOVCClsl : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, >> i32imm:$rhs), >> - IIC_iCMOVsi, "lsl", ".w $dst, $true, $rhs", []>, >> + IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", []>, >> RegConstraint<"$false = $dst">; >> def t2MOVCClsr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, >> i32imm:$rhs), >> - IIC_iCMOVsi, "lsr", ".w $dst, $true, $rhs", []>, >> + IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", []>, >> RegConstraint<"$false = $dst">; >> def t2MOVCCasr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, >> i32imm:$rhs), >> - IIC_iCMOVsi, "asr", ".w $dst, $true, $rhs", []>, >> + IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", []>, >> RegConstraint<"$false = $dst">; >> def t2MOVCCror : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, >> i32imm:$rhs), >> - IIC_iCMOVsi, "ror", ".w $dst, $true, $rhs", []>, >> + IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", []>, >> RegConstraint<"$false = $dst">; >> >> // >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> @@ -1055,7 +1055,7 @@ >> let isCall = 1, >> Defs = [R0, R12, LR, CPSR] in { >> def t2TPsoft : T2XI<(outs), (ins), IIC_Br, >> - "bl __aeabi_read_tp", >> + "bl\t__aeabi_read_tp", >> [(set R0, ARMthread_pointer)]>; >> } >> >> @@ -1078,13 +1078,13 @@ >> D31 ] in { >> def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src), >> AddrModeNone, SizeSpecial, NoItinerary, >> - "str.w sp, [$src, #+8] @ eh_setjmp >> begin\n" >> - "\tadr r12, 0f\n" >> - "\torr r12, #1\n" >> - "\tstr.w r12, [$src, #+4]\n" >> - "\tmovs r0, #0\n" >> - "\tb 1f\n" >> - "0:\tmovs r0, #1 @ eh_setjmp end\n" >> + "str.w\tsp, [$src, #+8] @ eh_setjmp >> begin\n" >> + "\tadr\tr12, 0f\n" >> + "\torr\tr12, #1\n" >> + "\tstr.w\tr12, [$src, #+4]\n" >> + "\tmovs\tr0, #0\n" >> + "\tb\t1f\n" >> + "0:\tmovs\tr0, #1 @ eh_setjmp end\n" >> "1:", "", >> [(set R0, (ARMeh_sjlj_setjmp GPR: >> $src))]>; >> } >> @@ -1103,32 +1103,32 @@ >> hasExtraDefRegAllocReq = 1 in >> def t2LDM_RET : T2XI<(outs), >> (ins addrmode4:$addr, pred:$p, reglist:$wb, >> variable_ops), >> - IIC_Br, "ldm${addr:submode}${p}${addr:wide} >> $addr, $wb", >> + IIC_Br, "ldm${addr:submode}${p}${addr:wide}\t >> $addr, $wb", >> []>; >> >> let isBranch = 1, isTerminator = 1, isBarrier = 1 in { >> let isPredicable = 1 in >> def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br, >> - "b.w $target", >> + "b.w\t$target", >> [(br bb:$target)]>; >> >> let isNotDuplicable = 1, isIndirectBranch = 1 in { >> def t2BR_JT : >> T2JTI<(outs), >> (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm: >> $id), >> - IIC_Br, "mov pc, $target\n$jt", >> + IIC_Br, "mov\tpc, $target\n$jt", >> [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm: >> $id)]>; >> >> // FIXME: Add a non-pc based case that can be predicated. >> def t2TBB : >> T2JTI<(outs), >> (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id), >> - IIC_Br, "tbb $index\n$jt", []>; >> + IIC_Br, "tbb\t$index\n$jt", []>; >> >> def t2TBH : >> T2JTI<(outs), >> (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id), >> - IIC_Br, "tbh $index\n$jt", []>; >> + IIC_Br, "tbh\t$index\n$jt", []>; >> } // isNotDuplicable, isIndirectBranch >> >> } // isBranch, isTerminator, isBarrier >> @@ -1137,14 +1137,14 @@ >> // a two-value operand where a dag node expects two operands. :( >> let isBranch = 1, isTerminator = 1 in >> def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br, >> - "b", ".w $target", >> + "b", ".w\t$target", >> [/*(ARMbrcond bb:$target, imm:$cc)*/]>; >> >> >> // IT block >> def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask), >> AddrModeNone, Size2Bytes, IIC_iALUx, >> - "it$mask $cc", "", []>; >> + "it$mask\t$cc", "", []>; >> >> // >> = >> = >> = >> ----------------------------------------------------------------------= >> ==// >> // Non-Instruction Patterns >> @@ -1175,5 +1175,5 @@ >> // when we can do generalized remat. >> let isReMaterializable = 1 in >> def t2MOVi32imm : T2Ix2<(outs GPR:$dst), (ins i32imm:$src), >> IIC_iMOVi, >> - "movw", " $dst, ${src:lo16}\n\tmovt${p} $dst, >> ${src:hi16}", >> + "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, >> ${src:hi16}", >> [(set GPR:$dst, (i32 imm:$src))]>; >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From grosbach at apple.com Tue Oct 27 12:48:04 2009 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 27 Oct 2009 10:48:04 -0700 Subject: [llvm-commits] [llvm] r85184 - in /llvm/trunk/lib/Target/ARM: ARMInstrThumb.td ARMInstrThumb2.td In-Reply-To: <862B8F7E-CC68-4669-B358-10A0DDC1BD99@apple.com> References: <200910270008.n9R08xTj013255@zion.cs.uiuc.edu> <6496D214-A96A-4308-9FD4-74A453B5ECD0@apple.com> <862B8F7E-CC68-4669-B358-10A0DDC1BD99@apple.com> Message-ID: <8089A63D-D39C-4DE2-BAAF-13DD465748BE@apple.com> I can adjust it, yes. It amounts to redoing pretty much all of it, though. And/or redoing all of these. I'll figure it out. Just rather frustrating. On Oct 27, 2009, at 10:43 AM, Evan Cheng wrote: > Ah sorry. The messy assembly was making it difficult to read the > assembly. Can you adjust your patch? Or when you are ready to apply > the unified syntax change, you can revert the change first. > > Evan > > On Oct 27, 2009, at 10:30 AM, Jim Grosbach wrote: > >> I was planning on doing this after the unified syntax patch >> unblocks. As is, doing this (especially the VFP portion) first >> breaks that patch rather horribly. >> -j >> >> On Oct 26, 2009, at 5:08 PM, Evan Cheng wrote: >> >>> Author: evancheng >>> Date: Mon Oct 26 19:08:59 2009 >>> New Revision: 85184 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=85184&view=rev >>> Log: >>> Change Thumb1 and Thumb2 instructions to separate opcode from >>> operands with a tab instead of a space. >>> >>> Modified: >>> llvm/trunk/lib/Target/ARM/ARMInstrThumb.td >>> llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td >>> >>> Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=85184&r1=85183&r2=85184&view=diff >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) >>> +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Mon Oct 26 19:08:59 >>> 2009 >>> @@ -130,44 +130,44 @@ >>> // For both thumb1 and thumb2. >>> let isNotDuplicable = 1 in >>> def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), >>> IIC_iALUr, >>> - "\n$cp:\n\tadd $dst, pc", >>> + "\n$cp:\n\tadd\t$dst, pc", >>> [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>; >>> >>> // PC relative add. >>> def tADDrPCi : T1I<(outs tGPR:$dst), (ins i32imm:$rhs), IIC_iALUi, >>> - "add $dst, pc, $rhs * 4", []>; >>> + "add\t$dst, pc, $rhs * 4", []>; >>> >>> // ADD rd, sp, #imm8 >>> def tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, i32imm:$rhs), >>> IIC_iALUi, >>> - "add $dst, $sp, $rhs * 4", []>; >>> + "add\t$dst, $sp, $rhs * 4", []>; >>> >>> // ADD sp, sp, #imm7 >>> def tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), >>> IIC_iALUi, >>> - "add $dst, $rhs * 4", []>; >>> + "add\t$dst, $rhs * 4", []>; >>> >>> // SUB sp, sp, #imm7 >>> def tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), >>> IIC_iALUi, >>> - "sub $dst, $rhs * 4", []>; >>> + "sub\t$dst, $rhs * 4", []>; >>> >>> // ADD rm, sp >>> def tADDrSP : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), >>> IIC_iALUr, >>> - "add $dst, $rhs", []>; >>> + "add\t$dst, $rhs", []>; >>> >>> // ADD sp, rm >>> def tADDspr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), >>> IIC_iALUr, >>> - "add $dst, $rhs", []>; >>> + "add\t$dst, $rhs", []>; >>> >>> // Pseudo instruction that will expand into a tSUBspi + a copy. >>> let usesCustomDAGSchedInserter = 1 in { // Expanded by the >>> scheduler. >>> def tSUBspi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, i32imm: >>> $rhs), >>> - NoItinerary, "@ sub $dst, $rhs * 4", []>; >>> + NoItinerary, "@ sub\t$dst, $rhs * 4", []>; >>> >>> def tADDspr_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), >>> - NoItinerary, "@ add $dst, $rhs", []>; >>> + NoItinerary, "@ add\t$dst, $rhs", []>; >>> >>> let Defs = [CPSR] in >>> def tANDsp : PseudoInst<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR: >>> $rhs), >>> - NoItinerary, "@ and $dst, $rhs", []>; >>> + NoItinerary, "@ and\t$dst, $rhs", []>; >>> } // usesCustomDAGSchedInserter >>> >>> // >>> = >>> = >>> = >>> ----------------------------------------------------------------------= >>> ==// >>> @@ -175,16 +175,16 @@ >>> // >>> >>> let isReturn = 1, isTerminator = 1, isBarrier = 1 in { >>> - def tBX_RET : TI<(outs), (ins), IIC_Br, "bx lr", [(ARMretflag)]>; >>> + def tBX_RET : TI<(outs), (ins), IIC_Br, "bx\tlr", [(ARMretflag)] >>> >; >>> // Alternative return instruction used by vararg functions. >>> - def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx >>> $target", []>; >>> + def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx >>> \t$target", []>; >>> } >>> >>> // FIXME: remove when we have a way to marking a MI with these >>> properties. >>> let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, >>> hasExtraDefRegAllocReq = 1 in >>> def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$wb, >>> variable_ops), IIC_Br, >>> - "pop${p} $wb", []>; >>> + "pop${p}\t$wb", []>; >>> >>> let isCall = 1, >>> Defs = [R0, R1, R2, R3, R12, LR, >>> @@ -193,25 +193,25 @@ >>> D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { >>> // Also used for Thumb2 >>> def tBL : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, >>> - "bl ${func:call}", >>> + "bl\t${func:call}", >>> [(ARMtcall tglobaladdr:$func)]>, >>> Requires<[IsThumb, IsNotDarwin]>; >>> >>> // ARMv5T and above, also used for Thumb2 >>> def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, >>> - "blx ${func:call}", >>> + "blx\t${func:call}", >>> [(ARMcall tglobaladdr:$func)]>, >>> Requires<[IsThumb, HasV5T, IsNotDarwin]>; >>> >>> // Also used for Thumb2 >>> def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, >>> - "blx $func", >>> + "blx\t$func", >>> [(ARMtcall GPR:$func)]>, >>> Requires<[IsThumb, HasV5T, IsNotDarwin]>; >>> >>> // ARMv4T >>> def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, >>> - "mov lr, pc\n\tbx $func", >>> + "mov\tlr, pc\n\tbx\t$func", >>> [(ARMcall_nolink tGPR:$func)]>, >>> Requires<[IsThumb1Only, IsNotDarwin]>; >>> } >>> @@ -224,25 +224,25 @@ >>> D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { >>> // Also used for Thumb2 >>> def tBLr9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, >>> - "bl ${func:call}", >>> + "bl\t${func:call}", >>> [(ARMtcall tglobaladdr:$func)]>, >>> Requires<[IsThumb, IsDarwin]>; >>> >>> // ARMv5T and above, also used for Thumb2 >>> def tBLXi_r9 : TIx2<(outs), (ins i32imm:$func, variable_ops), >>> IIC_Br, >>> - "blx ${func:call}", >>> + "blx\t${func:call}", >>> [(ARMcall tglobaladdr:$func)]>, >>> Requires<[IsThumb, HasV5T, IsDarwin]>; >>> >>> // Also used for Thumb2 >>> def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, >>> - "blx $func", >>> + "blx\t$func", >>> [(ARMtcall GPR:$func)]>, >>> Requires<[IsThumb, HasV5T, IsDarwin]>; >>> >>> // ARMv4T >>> def tBXr9 : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, >>> - "mov lr, pc\n\tbx $func", >>> + "mov\tlr, pc\n\tbx\t$func", >>> [(ARMcall_nolink tGPR:$func)]>, >>> Requires<[IsThumb1Only, IsDarwin]>; >>> } >>> @@ -251,16 +251,16 @@ >>> let isBarrier = 1 in { >>> let isPredicable = 1 in >>> def tB : T1I<(outs), (ins brtarget:$target), IIC_Br, >>> - "b $target", [(br bb:$target)]>; >>> + "b\t$target", [(br bb:$target)]>; >>> >>> // Far jump >>> let Defs = [LR] in >>> def tBfar : TIx2<(outs), (ins brtarget:$target), IIC_Br, >>> - "bl $target\t@ far jump",[]>; >>> + "bl\t$target\t@ far jump",[]>; >>> >>> def tBR_JTr : T1JTI<(outs), >>> (ins tGPR:$target, jtblock_operand:$jt, i32imm: >>> $id), >>> - IIC_Br, "mov pc, $target\n\t.align\t2\n$jt", >>> + IIC_Br, "mov\tpc, $target\n\t.align\t2\n$jt", >>> [(ARMbrjt tGPR:$target, tjumptable:$jt, imm: >>> $id)]>; >>> } >>> } >>> @@ -269,7 +269,7 @@ >>> // a two-value operand where a dag node expects two operands. :( >>> let isBranch = 1, isTerminator = 1 in >>> def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), IIC_Br, >>> - "b$cc $target", >>> + "b$cc\t$target", >>> [/*(ARMbrcond bb:$target, imm:$cc)*/]>; >>> >>> // >>> = >>> = >>> = >>> ----------------------------------------------------------------------= >>> ==// >>> @@ -278,70 +278,70 @@ >>> >>> let canFoldAsLoad = 1 in >>> def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), >>> IIC_iLoadr, >>> - "ldr", " $dst, $addr", >>> + "ldr", "\t$dst, $addr", >>> [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>; >>> >>> def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), >>> IIC_iLoadr, >>> - "ldrb", " $dst, $addr", >>> + "ldrb", "\t$dst, $addr", >>> [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; >>> >>> def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), >>> IIC_iLoadr, >>> - "ldrh", " $dst, $addr", >>> + "ldrh", "\t$dst, $addr", >>> [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>; >>> >>> let AddedComplexity = 10 in >>> def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), >>> IIC_iLoadr, >>> - "ldrsb", " $dst, $addr", >>> + "ldrsb", "\t$dst, $addr", >>> [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>; >>> >>> let AddedComplexity = 10 in >>> def tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), >>> IIC_iLoadr, >>> - "ldrsh", " $dst, $addr", >>> + "ldrsh", "\t$dst, $addr", >>> [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))] >>> >; >>> >>> let canFoldAsLoad = 1 in >>> def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), >>> IIC_iLoadi, >>> - "ldr", " $dst, $addr", >>> + "ldr", "\t$dst, $addr", >>> [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>; >>> >>> // Special instruction for restore. It cannot clobber condition >>> register >>> // when it's expanded by eliminateCallFramePseudoInstr(). >>> let canFoldAsLoad = 1, mayLoad = 1 in >>> def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), >>> IIC_iLoadi, >>> - "ldr", " $dst, $addr", []>; >>> + "ldr", "\t$dst, $addr", []>; >>> >>> // Load tconstpool >>> let canFoldAsLoad = 1 in >>> def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), >>> IIC_iLoadi, >>> - "ldr", " $dst, $addr", >>> + "ldr", "\t$dst, $addr", >>> [(set tGPR:$dst, (load (ARMWrapper tconstpool: >>> $addr)))]>; >>> >>> // Special LDR for loads from non-pc-relative constpools. >>> let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in >>> def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), >>> IIC_iLoadi, >>> - "ldr", " $dst, $addr", []>; >>> + "ldr", "\t$dst, $addr", []>; >>> >>> def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), >>> IIC_iStorer, >>> - "str", " $src, $addr", >>> + "str", "\t$src, $addr", >>> [(store tGPR:$src, t_addrmode_s4:$addr)]>; >>> >>> def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), >>> IIC_iStorer, >>> - "strb", " $src, $addr", >>> + "strb", "\t$src, $addr", >>> [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>; >>> >>> def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), >>> IIC_iStorer, >>> - "strh", " $src, $addr", >>> + "strh", "\t$src, $addr", >>> [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>; >>> >>> def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), >>> IIC_iStorei, >>> - "str", " $src, $addr", >>> + "str", "\t$src, $addr", >>> [(store tGPR:$src, t_addrmode_sp:$addr)]>; >>> >>> let mayStore = 1 in { >>> // Special instruction for spill. It cannot clobber condition >>> register >>> // when it's expanded by eliminateCallFramePseudoInstr(). >>> def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), >>> IIC_iStorei, >>> - "str", " $src, $addr", []>; >>> + "str", "\t$src, $addr", []>; >>> } >>> >>> // >>> = >>> = >>> = >>> ----------------------------------------------------------------------= >>> ==// >>> @@ -353,21 +353,21 @@ >>> def tLDM : T1I<(outs), >>> (ins addrmode4:$addr, pred:$p, reglist:$wb, >>> variable_ops), >>> IIC_iLoadm, >>> - "ldm${addr:submode}${p} $addr, $wb", []>; >>> + "ldm${addr:submode}${p}\t$addr, $wb", []>; >>> >>> let mayStore = 1, hasExtraSrcRegAllocReq = 1 in >>> def tSTM : T1I<(outs), >>> (ins addrmode4:$addr, pred:$p, reglist:$wb, >>> variable_ops), >>> IIC_iStorem, >>> - "stm${addr:submode}${p} $addr, $wb", []>; >>> + "stm${addr:submode}${p}\t$addr, $wb", []>; >>> >>> let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq >>> = 1 in >>> def tPOP : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), >>> IIC_Br, >>> - "pop${p} $wb", []>; >>> + "pop${p}\t$wb", []>; >>> >>> let mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq >>> = 1 in >>> def tPUSH : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), >>> IIC_Br, >>> - "push${p} $wb", []>; >>> + "push${p}\t$wb", []>; >>> >>> // >>> = >>> = >>> = >>> ----------------------------------------------------------------------= >>> ==// >>> // Arithmetic Instructions. >>> @@ -376,66 +376,66 @@ >>> // Add with carry register >>> let isCommutable = 1, Uses = [CPSR] in >>> def tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >>> IIC_iALUr, >>> - "adc", " $dst, $rhs", >>> + "adc", "\t$dst, $rhs", >>> [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>; >>> >>> // Add immediate >>> def tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), >>> IIC_iALUi, >>> - "add", " $dst, $lhs, $rhs", >>> + "add", "\t$dst, $lhs, $rhs", >>> [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>; >>> >>> def tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), >>> IIC_iALUi, >>> - "add", " $dst, $rhs", >>> + "add", "\t$dst, $rhs", >>> [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>; >>> >>> // Add register >>> let isCommutable = 1 in >>> def tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >>> IIC_iALUr, >>> - "add", " $dst, $lhs, $rhs", >>> + "add", "\t$dst, $lhs, $rhs", >>> [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>; >>> >>> let neverHasSideEffects = 1 in >>> def tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), >>> IIC_iALUr, >>> - "add", " $dst, $rhs", []>; >>> + "add", "\t$dst, $rhs", []>; >>> >>> // And register >>> let isCommutable = 1 in >>> def tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >>> IIC_iALUr, >>> - "and", " $dst, $rhs", >>> + "and", "\t$dst, $rhs", >>> [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>; >>> >>> // ASR immediate >>> def tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), >>> IIC_iMOVsi, >>> - "asr", " $dst, $lhs, $rhs", >>> + "asr", "\t$dst, $lhs, $rhs", >>> [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>; >>> >>> // ASR register >>> def tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >>> IIC_iMOVsr, >>> - "asr", " $dst, $rhs", >>> + "asr", "\t$dst, $rhs", >>> [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>; >>> >>> // BIC register >>> def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >>> IIC_iALUr, >>> - "bic", " $dst, $rhs", >>> + "bic", "\t$dst, $rhs", >>> [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>; >>> >>> // CMN register >>> let Defs = [CPSR] in { >>> def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, >>> - "cmn", " $lhs, $rhs", >>> + "cmn", "\t$lhs, $rhs", >>> [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>; >>> def tCMNZ : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, >>> - "cmn", " $lhs, $rhs", >>> + "cmn", "\t$lhs, $rhs", >>> [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>; >>> } >>> >>> // CMP immediate >>> let Defs = [CPSR] in { >>> def tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, >>> - "cmp", " $lhs, $rhs", >>> + "cmp", "\t$lhs, $rhs", >>> [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>; >>> def tCMPzi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, >>> - "cmp", " $lhs, $rhs", >>> + "cmp", "\t$lhs, $rhs", >>> [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>; >>> >>> } >>> @@ -443,48 +443,48 @@ >>> // CMP register >>> let Defs = [CPSR] in { >>> def tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, >>> - "cmp", " $lhs, $rhs", >>> + "cmp", "\t$lhs, $rhs", >>> [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>; >>> def tCMPzr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, >>> - "cmp", " $lhs, $rhs", >>> + "cmp", "\t$lhs, $rhs", >>> [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>; >>> >>> def tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, >>> - "cmp", " $lhs, $rhs", []>; >>> + "cmp", "\t$lhs, $rhs", []>; >>> def tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, >>> - "cmp", " $lhs, $rhs", []>; >>> + "cmp", "\t$lhs, $rhs", []>; >>> } >>> >>> >>> // XOR register >>> let isCommutable = 1 in >>> def tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >>> IIC_iALUr, >>> - "eor", " $dst, $rhs", >>> + "eor", "\t$dst, $rhs", >>> [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>; >>> >>> // LSL immediate >>> def tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), >>> IIC_iMOVsi, >>> - "lsl", " $dst, $lhs, $rhs", >>> + "lsl", "\t$dst, $lhs, $rhs", >>> [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>; >>> >>> // LSL register >>> def tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >>> IIC_iMOVsr, >>> - "lsl", " $dst, $rhs", >>> + "lsl", "\t$dst, $rhs", >>> [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>; >>> >>> // LSR immediate >>> def tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), >>> IIC_iMOVsi, >>> - "lsr", " $dst, $lhs, $rhs", >>> + "lsr", "\t$dst, $lhs, $rhs", >>> [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>; >>> >>> // LSR register >>> def tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >>> IIC_iMOVsr, >>> - "lsr", " $dst, $rhs", >>> + "lsr", "\t$dst, $rhs", >>> [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>; >>> >>> // move register >>> def tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src), IIC_iMOVi, >>> - "mov", " $dst, $src", >>> + "mov", "\t$dst, $src", >>> [(set tGPR:$dst, imm0_255:$src)]>; >>> >>> // TODO: A7-73: MOV(2) - mov setting flag. >>> @@ -493,45 +493,45 @@ >>> let neverHasSideEffects = 1 in { >>> // FIXME: Make this predicable. >>> def tMOVr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, >>> - "mov $dst, $src", []>; >>> + "mov\t$dst, $src", []>; >>> let Defs = [CPSR] in >>> def tMOVSr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, >>> - "movs $dst, $src", []>; >>> + "movs\t$dst, $src", []>; >>> >>> // FIXME: Make these predicable. >>> def tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iMOVr, >>> - "mov $dst, $src", []>; >>> + "mov\t$dst, $src", []>; >>> def tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iMOVr, >>> - "mov $dst, $src", []>; >>> + "mov\t$dst, $src", []>; >>> def tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, >>> - "mov $dst, $src", []>; >>> + "mov\t$dst, $src", []>; >>> } // neverHasSideEffects >>> >>> // multiply register >>> let isCommutable = 1 in >>> def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >>> IIC_iMUL32, >>> - "mul", " $dst, $rhs", >>> + "mul", "\t$dst, $rhs", >>> [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>; >>> >>> // move inverse register >>> def tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, >>> - "mvn", " $dst, $src", >>> + "mvn", "\t$dst, $src", >>> [(set tGPR:$dst, (not tGPR:$src))]>; >>> >>> // bitwise or register >>> let isCommutable = 1 in >>> def tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >>> IIC_iALUr, >>> - "orr", " $dst, $rhs", >>> + "orr", "\t$dst, $rhs", >>> [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>; >>> >>> // swaps >>> def tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, >>> - "rev", " $dst, $src", >>> + "rev", "\t$dst, $src", >>> [(set tGPR:$dst, (bswap tGPR:$src))]>, >>> Requires<[IsThumb1Only, HasV6]>; >>> >>> def tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, >>> - "rev16", " $dst, $src", >>> + "rev16", "\t$dst, $src", >>> [(set tGPR:$dst, >>> (or (and (srl tGPR:$src, (i32 8)), 0xFF), >>> (or (and (shl tGPR:$src, (i32 8)), 0xFF00), >>> @@ -540,7 +540,7 @@ >>> Requires<[IsThumb1Only, HasV6]>; >>> >>> def tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, >>> - "revsh", " $dst, $src", >>> + "revsh", "\t$dst, $src", >>> [(set tGPR:$dst, >>> (sext_inreg >>> (or (srl (and tGPR:$src, 0xFF00), (i32 8)), >>> @@ -549,63 +549,63 @@ >>> >>> // rotate right register >>> def tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >>> IIC_iMOVsr, >>> - "ror", " $dst, $rhs", >>> + "ror", "\t$dst, $rhs", >>> [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>; >>> >>> // negate register >>> def tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALUi, >>> - "rsb", " $dst, $src, #0", >>> + "rsb", "\t$dst, $src, #0", >>> [(set tGPR:$dst, (ineg tGPR:$src))]>; >>> >>> // Subtract with carry register >>> let Uses = [CPSR] in >>> def tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >>> IIC_iALUr, >>> - "sbc", " $dst, $rhs", >>> + "sbc", "\t$dst, $rhs", >>> [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>; >>> >>> // Subtract immediate >>> def tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), >>> IIC_iALUi, >>> - "sub", " $dst, $lhs, $rhs", >>> + "sub", "\t$dst, $lhs, $rhs", >>> [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))] >>> >; >>> >>> def tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), >>> IIC_iALUi, >>> - "sub", " $dst, $rhs", >>> + "sub", "\t$dst, $rhs", >>> [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg: >>> $rhs))]>; >>> >>> // subtract register >>> def tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), >>> IIC_iALUr, >>> - "sub", " $dst, $lhs, $rhs", >>> + "sub", "\t$dst, $lhs, $rhs", >>> [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>; >>> >>> // TODO: A7-96: STMIA - store multiple. >>> >>> // sign-extend byte >>> def tSXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, >>> - "sxtb", " $dst, $src", >>> + "sxtb", "\t$dst, $src", >>> [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>, >>> Requires<[IsThumb1Only, HasV6]>; >>> >>> // sign-extend short >>> def tSXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, >>> - "sxth", " $dst, $src", >>> + "sxth", "\t$dst, $src", >>> [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>, >>> Requires<[IsThumb1Only, HasV6]>; >>> >>> // test >>> let isCommutable = 1, Defs = [CPSR] in >>> def tTST : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, >>> - "tst", " $lhs, $rhs", >>> + "tst", "\t$lhs, $rhs", >>> [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>; >>> >>> // zero-extend byte >>> def tUXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, >>> - "uxtb", " $dst, $src", >>> + "uxtb", "\t$dst, $src", >>> [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>, >>> Requires<[IsThumb1Only, HasV6]>; >>> >>> // zero-extend short >>> def tUXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, >>> - "uxth", " $dst, $src", >>> + "uxth", "\t$dst, $src", >>> [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>, >>> Requires<[IsThumb1Only, HasV6]>; >>> >>> @@ -621,19 +621,19 @@ >>> >>> // 16-bit movcc in IT blocks for Thumb2. >>> def tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), >>> IIC_iCMOVr, >>> - "mov", " $dst, $rhs", []>; >>> + "mov", "\t$dst, $rhs", []>; >>> >>> def tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), >>> IIC_iCMOVi, >>> - "mov", " $dst, $rhs", []>; >>> + "mov", "\t$dst, $rhs", []>; >>> >>> // tLEApcrel - Load a pc-relative address into a register without >>> offending the >>> // assembler. >>> def tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label, pred: >>> $p), IIC_iALUi, >>> - "adr$p $dst, #$label", []>; >>> + "adr$p\t$dst, #$label", []>; >>> >>> def tLEApcrelJT : T1I<(outs tGPR:$dst), >>> (ins i32imm:$label, nohash_imm:$id, pred:$p), >>> - IIC_iALUi, "adr$p $dst, #${label}_${id}", [] >>> >; >>> + IIC_iALUi, "adr$p\t$dst, #${label}_${id}", >>> []>; >>> >>> // >>> = >>> = >>> = >>> ----------------------------------------------------------------------= >>> ==// >>> // TLS Instructions >>> @@ -643,7 +643,7 @@ >>> let isCall = 1, >>> Defs = [R0, LR] in { >>> def tTPsoft : TIx2<(outs), (ins), IIC_Br, >>> - "bl __aeabi_read_tp", >>> + "bl\t__aeabi_read_tp", >>> [(set R0, ARMthread_pointer)]>; >>> } >>> >>> >>> Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=85184&r1=85183&r2=85184&view=diff >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) >>> +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon Oct 26 >>> 19:08:59 2009 >>> @@ -153,18 +153,18 @@ >>> multiclass T2I_un_irs>> bit ReMat = 0>{ >>> // shifted imm >>> def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi, >>> - opc, " $dst, $src", >>> + opc, "\t$dst, $src", >>> [(set GPR:$dst, (opnode t2_so_imm:$src))]> { >>> let isAsCheapAsAMove = Cheap; >>> let isReMaterializable = ReMat; >>> } >>> // register >>> def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, >>> - opc, ".w $dst, $src", >>> + opc, ".w\t$dst, $src", >>> [(set GPR:$dst, (opnode GPR:$src))]>; >>> // shifted register >>> def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), IIC_iMOVsi, >>> - opc, ".w $dst, $src", >>> + opc, ".w\t$dst, $src", >>> [(set GPR:$dst, (opnode t2_so_reg:$src))]>; >>> } >>> >>> @@ -175,17 +175,17 @@ >>> bit Commutable = 0, string wide =""> { >>> // shifted imm >>> def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), >>> IIC_iALUi, >>> - opc, " $dst, $lhs, $rhs", >>> + opc, "\t$dst, $lhs, $rhs", >>> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; >>> // register >>> def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, >>> - opc, !strconcat(wide, " $dst, $lhs, $rhs"), >>> + opc, !strconcat(wide, "\t$dst, $lhs, $rhs"), >>> [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { >>> let isCommutable = Commutable; >>> } >>> // shifted register >>> def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), >>> IIC_iALUsi, >>> - opc, !strconcat(wide, " $dst, $lhs, $rhs"), >>> + opc, !strconcat(wide, "\t$dst, $lhs, $rhs"), >>> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; >>> } >>> >>> @@ -200,11 +200,11 @@ >>> multiclass T2I_rbin_is { >>> // shifted imm >>> def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), >>> IIC_iALUi, >>> - opc, ".w $dst, $rhs, $lhs", >>> + opc, ".w\t$dst, $rhs, $lhs", >>> [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; >>> // shifted register >>> def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), >>> IIC_iALUsi, >>> - opc, " $dst, $rhs, $lhs", >>> + opc, "\t$dst, $rhs, $lhs", >>> [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>; >>> } >>> >>> @@ -214,17 +214,17 @@ >>> multiclass T2I_bin_s_irs>> Commutable = 0> { >>> // shifted imm >>> def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), >>> IIC_iALUi, >>> - !strconcat(opc, "s"), ".w $dst, $lhs, $rhs", >>> + !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs", >>> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; >>> // register >>> def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, >>> - !strconcat(opc, "s"), ".w $dst, $lhs, $rhs", >>> + !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs", >>> [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { >>> let isCommutable = Commutable; >>> } >>> // shifted register >>> def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), >>> IIC_iALUsi, >>> - !strconcat(opc, "s"), ".w $dst, $lhs, $rhs", >>> + !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs", >>> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; >>> } >>> } >>> @@ -234,21 +234,21 @@ >>> multiclass T2I_bin_ii12rs>> Commutable = 0> { >>> // shifted imm >>> def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), >>> IIC_iALUi, >>> - opc, ".w $dst, $lhs, $rhs", >>> + opc, ".w\t$dst, $lhs, $rhs", >>> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; >>> // 12-bit imm >>> def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), >>> IIC_iALUi, >>> - !strconcat(opc, "w"), " $dst, $lhs, $rhs", >>> + !strconcat(opc, "w"), "\t$dst, $lhs, $rhs", >>> [(set GPR:$dst, (opnode GPR:$lhs, >>> imm0_4095:$rhs))]>; >>> // register >>> def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, >>> - opc, ".w $dst, $lhs, $rhs", >>> + opc, ".w\t$dst, $lhs, $rhs", >>> [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { >>> let isCommutable = Commutable; >>> } >>> // shifted register >>> def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), >>> IIC_iALUsi, >>> - opc, ".w $dst, $lhs, $rhs", >>> + opc, ".w\t$dst, $lhs, $rhs", >>> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; >>> } >>> >>> @@ -259,32 +259,32 @@ >>> multiclass T2I_adde_sube_irs>> Commutable = 0> { >>> // shifted imm >>> def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), >>> IIC_iALUi, >>> - opc, " $dst, $lhs, $rhs", >>> + opc, "\t$dst, $lhs, $rhs", >>> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>, >>> Requires<[IsThumb2, CarryDefIsUnused]>; >>> // register >>> def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, >>> - opc, ".w $dst, $lhs, $rhs", >>> + opc, ".w\t$dst, $lhs, $rhs", >>> [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>, >>> Requires<[IsThumb2, CarryDefIsUnused]> { >>> let isCommutable = Commutable; >>> } >>> // shifted register >>> def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), >>> IIC_iALUsi, >>> - opc, ".w $dst, $lhs, $rhs", >>> + opc, ".w\t$dst, $lhs, $rhs", >>> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>, >>> Requires<[IsThumb2, CarryDefIsUnused]>; >>> // Carry setting variants >>> // shifted imm >>> def Sri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), >>> IIC_iALUi, >>> - !strconcat(opc, "s $dst, $lhs, $rhs"), >>> + !strconcat(opc, "s\t$dst, $lhs, $rhs"), >>> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))] >>> >, >>> Requires<[IsThumb2, CarryDefIsUsed]> { >>> let Defs = [CPSR]; >>> } >>> // register >>> def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), >>> IIC_iALUr, >>> - !strconcat(opc, "s.w $dst, $lhs, $rhs"), >>> + !strconcat(opc, "s.w\t$dst, $lhs, $rhs"), >>> [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>, >>> Requires<[IsThumb2, CarryDefIsUsed]> { >>> let Defs = [CPSR]; >>> @@ -292,7 +292,7 @@ >>> } >>> // shifted register >>> def Srs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), >>> IIC_iALUsi, >>> - !strconcat(opc, "s.w $dst, $lhs, $rhs"), >>> + !strconcat(opc, "s.w\t$dst, $lhs, $rhs"), >>> [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))] >>> >, >>> Requires<[IsThumb2, CarryDefIsUsed]> { >>> let Defs = [CPSR]; >>> @@ -306,12 +306,12 @@ >>> // shifted imm >>> def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, >>> cc_out:$s), >>> IIC_iALUi, >>> - !strconcat(opc, "${s}.w $dst, $rhs, $lhs"), >>> + !strconcat(opc, "${s}.w\t$dst, $rhs, $lhs"), >>> [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; >>> // shifted register >>> def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, >>> cc_out:$s), >>> IIC_iALUsi, >>> - !strconcat(opc, "${s} $dst, $rhs, $lhs"), >>> + !strconcat(opc, "${s}\t$dst, $rhs, $lhs"), >>> [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>; >>> } >>> } >>> @@ -321,11 +321,11 @@ >>> multiclass T2I_sh_ir { >>> // 5-bit imm >>> def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), >>> IIC_iMOVsi, >>> - opc, ".w $dst, $lhs, $rhs", >>> + opc, ".w\t$dst, $lhs, $rhs", >>> [(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]>; >>> // register >>> def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), >>> IIC_iMOVsr, >>> - opc, ".w $dst, $lhs, $rhs", >>> + opc, ".w\t$dst, $lhs, $rhs", >>> [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>; >>> } >>> >>> @@ -336,15 +336,15 @@ >>> multiclass T2I_cmp_is { >>> // shifted imm >>> def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iCMPi, >>> - opc, ".w $lhs, $rhs", >>> + opc, ".w\t$lhs, $rhs", >>> [(opnode GPR:$lhs, t2_so_imm:$rhs)]>; >>> // register >>> def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, >>> - opc, ".w $lhs, $rhs", >>> + opc, ".w\t$lhs, $rhs", >>> [(opnode GPR:$lhs, GPR:$rhs)]>; >>> // shifted register >>> def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iCMPsi, >>> - opc, ".w $lhs, $rhs", >>> + opc, ".w\t$lhs, $rhs", >>> [(opnode GPR:$lhs, t2_so_reg:$rhs)]>; >>> } >>> } >>> @@ -352,42 +352,42 @@ >>> /// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load >>> patterns. >>> multiclass T2I_ld { >>> def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), >>> IIC_iLoadi, >>> - opc, ".w $dst, $addr", >>> + opc, ".w\t$dst, $addr", >>> [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]>; >>> def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), >>> IIC_iLoadi, >>> - opc, " $dst, $addr", >>> + opc, "\t$dst, $addr", >>> [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]>; >>> def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), >>> IIC_iLoadr, >>> - opc, ".w $dst, $addr", >>> + opc, ".w\t$dst, $addr", >>> [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))] >>> >; >>> def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoadi, >>> - opc, ".w $dst, $addr", >>> + opc, ".w\t$dst, $addr", >>> [(set GPR:$dst, (opnode (ARMWrapper tconstpool: >>> $addr)))]>; >>> } >>> >>> /// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store >>> patterns. >>> multiclass T2I_st { >>> def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), >>> IIC_iStorei, >>> - opc, ".w $src, $addr", >>> + opc, ".w\t$src, $addr", >>> [(opnode GPR:$src, t2addrmode_imm12:$addr)]>; >>> def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), >>> IIC_iStorei, >>> - opc, " $src, $addr", >>> + opc, "\t$src, $addr", >>> [(opnode GPR:$src, t2addrmode_imm8:$addr)]>; >>> def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), >>> IIC_iStorer, >>> - opc, ".w $src, $addr", >>> + opc, ".w\t$src, $addr", >>> [(opnode GPR:$src, t2addrmode_so_reg:$addr)]>; >>> } >>> >>> /// T2I_picld - Defines the PIC load pattern. >>> class T2I_picld : >>> T2I<(outs GPR:$dst), (ins addrmodepc:$addr), IIC_iLoadi, >>> - !strconcat("\n${addr:label}:\n\t", opc), " $dst, $addr", >>> + !strconcat("\n${addr:label}:\n\t", opc), "\t$dst, $addr", >>> [(set GPR:$dst, (opnode addrmodepc:$addr))]>; >>> >>> /// T2I_picst - Defines the PIC store pattern. >>> class T2I_picst : >>> T2I<(outs), (ins GPR:$src, addrmodepc:$addr), IIC_iStorer, >>> - !strconcat("\n${addr:label}:\n\t", opc), " $src, $addr", >>> + !strconcat("\n${addr:label}:\n\t", opc), "\t$src, $addr", >>> [(opnode GPR:$src, addrmodepc:$addr)]>; >>> >>> >>> @@ -395,10 +395,10 @@ >>> /// register and one whose operand is a register rotated by 8/16/24. >>> multiclass T2I_unary_rrot { >>> def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, >>> - opc, ".w $dst, $src", >>> + opc, ".w\t$dst, $src", >>> [(set GPR:$dst, (opnode GPR:$src))]>; >>> def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), >>> IIC_iUNAsi, >>> - opc, ".w $dst, $src, ror $rot", >>> + opc, ".w\t$dst, $src, ror $rot", >>> [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm: >>> $rot)))]>; >>> } >>> >>> @@ -406,10 +406,10 @@ >>> /// register and one whose operand is a register rotated by 8/16/24. >>> multiclass T2I_bin_rrot { >>> def rr : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), >>> IIC_iALUr, >>> - opc, " $dst, $LHS, $RHS", >>> + opc, "\t$dst, $LHS, $RHS", >>> [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>; >>> def rr_rot : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm: >>> $rot), >>> - IIC_iALUsr, opc, " $dst, $LHS, $RHS, ror $rot", >>> + IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot", >>> [(set GPR:$dst, (opnode GPR:$LHS, >>> (rotr GPR:$RHS, rot_imm: >>> $rot)))]>; >>> } >>> @@ -425,42 +425,42 @@ >>> // LEApcrel - Load a pc-relative address into a register without >>> offending the >>> // assembler. >>> def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred: >>> $p), IIC_iALUi, >>> - "adr$p.w $dst, #$label", []>; >>> + "adr$p.w\t$dst, #$label", []>; >>> >>> def t2LEApcrelJT : T2XI<(outs GPR:$dst), >>> (ins i32imm:$label, nohash_imm:$id, pred: >>> $p), IIC_iALUi, >>> - "adr$p.w $dst, #${label}_${id}", []>; >>> + "adr$p.w\t$dst, #${label}_${id}", []>; >>> >>> // ADD r, sp, {so_imm|i12} >>> def t2ADDrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm: >>> $imm), >>> - IIC_iALUi, "add", ".w $dst, $sp, $imm", [] >>> >; >>> + IIC_iALUi, "add", ".w\t$dst, $sp, $imm", >>> []>; >>> def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, >>> imm0_4095:$imm), >>> - IIC_iALUi, "addw", " $dst, $sp, $imm", []>; >>> + IIC_iALUi, "addw", "\t$dst, $sp, $imm", []>; >>> >>> // ADD r, sp, so_reg >>> def t2ADDrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg: >>> $rhs), >>> - IIC_iALUsi, "add", ".w $dst, $sp, $rhs", >>> []>; >>> + IIC_iALUsi, "add", ".w\t$dst, $sp, $rhs", >>> []>; >>> >>> // SUB r, sp, {so_imm|i12} >>> def t2SUBrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm: >>> $imm), >>> - IIC_iALUi, "sub", ".w $dst, $sp, $imm", [] >>> >; >>> + IIC_iALUi, "sub", ".w\t$dst, $sp, $imm", >>> []>; >>> def t2SUBrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, >>> imm0_4095:$imm), >>> - IIC_iALUi, "subw", " $dst, $sp, $imm", []>; >>> + IIC_iALUi, "subw", "\t$dst, $sp, $imm", []>; >>> >>> // SUB r, sp, so_reg >>> def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg: >>> $rhs), >>> IIC_iALUsi, >>> - "sub", " $dst, $sp, $rhs", []>; >>> + "sub", "\t$dst, $sp, $rhs", []>; >>> >>> >>> // Pseudo instruction that will expand into a t2SUBrSPi + a copy. >>> let usesCustomDAGSchedInserter = 1 in { // Expanded by the >>> scheduler. >>> def t2SUBrSPi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, >>> t2_so_imm:$imm), >>> - NoItinerary, "@ sub.w $dst, $sp, $imm", []>; >>> + NoItinerary, "@ sub.w\t$dst, $sp, $imm", []>; >>> def t2SUBrSPi12_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, >>> imm0_4095:$imm), >>> - NoItinerary, "@ subw $dst, $sp, $imm", []>; >>> + NoItinerary, "@ subw\t$dst, $sp, $imm", []>; >>> def t2SUBrSPs_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, >>> t2_so_reg:$rhs), >>> - NoItinerary, "@ sub $dst, $sp, $rhs", []>; >>> + NoItinerary, "@ sub\t$dst, $sp, $rhs", []>; >>> } // usesCustomDAGSchedInserter >>> >>> >>> @@ -484,10 +484,10 @@ >>> // Load doubleword >>> def t2LDRDi8 : T2Ii8s4<(outs GPR:$dst1, GPR:$dst2), >>> (ins t2addrmode_imm8s4:$addr), >>> - IIC_iLoadi, "ldrd", " $dst1, $addr", []>; >>> + IIC_iLoadi, "ldrd", "\t$dst1, $addr", []>; >>> def t2LDRDpci : T2Ii8s4<(outs GPR:$dst1, GPR:$dst2), >>> (ins i32imm:$addr), IIC_iLoadi, >>> - "ldrd", " $dst1, $addr", []>; >>> + "ldrd", "\t$dst1, $addr", []>; >>> } >>> >>> // zextload i1 -> zextload i8 >>> @@ -535,57 +535,57 @@ >>> def t2LDR_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >>> (ins t2addrmode_imm8:$addr), >>> AddrModeT2_i8, IndexModePre, IIC_iLoadiu, >>> - "ldr", " $dst, $addr!", "$addr.base = >>> $base_wb", >>> + "ldr", "\t$dst, $addr!", "$addr.base >>> = $base_wb", >>> []>; >>> >>> def t2LDR_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >>> (ins GPR:$base, t2am_imm8_offset:$offset), >>> AddrModeT2_i8, IndexModePost, IIC_iLoadiu, >>> - "ldr", " $dst, [$base], $offset", >>> "$base = $base_wb", >>> + "ldr", "\t$dst, [$base], $offset", >>> "$base = $base_wb", >>> []>; >>> >>> def t2LDRB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >>> (ins t2addrmode_imm8:$addr), >>> AddrModeT2_i8, IndexModePre, IIC_iLoadiu, >>> - "ldrb", " $dst, $addr!", "$addr.base >>> = $base_wb", >>> + "ldrb", "\t$dst, $addr!", "$addr.base >>> = $base_wb", >>> []>; >>> def t2LDRB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >>> (ins GPR:$base, t2am_imm8_offset:$offset), >>> AddrModeT2_i8, IndexModePost, IIC_iLoadiu, >>> - "ldrb", " $dst, [$base], $offset", >>> "$base = $base_wb", >>> + "ldrb", "\t$dst, [$base], $offset", >>> "$base = $base_wb", >>> []>; >>> >>> def t2LDRH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >>> (ins t2addrmode_imm8:$addr), >>> AddrModeT2_i8, IndexModePre, IIC_iLoadiu, >>> - "ldrh", " $dst, $addr!", "$addr.base >>> = $base_wb", >>> + "ldrh", "\t$dst, $addr!", "$addr.base >>> = $base_wb", >>> []>; >>> def t2LDRH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >>> (ins GPR:$base, t2am_imm8_offset:$offset), >>> AddrModeT2_i8, IndexModePost, IIC_iLoadiu, >>> - "ldrh", " $dst, [$base], $offset", >>> "$base = $base_wb", >>> + "ldrh", "\t$dst, [$base], $offset", >>> "$base = $base_wb", >>> []>; >>> >>> def t2LDRSB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >>> (ins t2addrmode_imm8:$addr), >>> AddrModeT2_i8, IndexModePre, IIC_iLoadiu, >>> - "ldrsb", " $dst, $addr!", "$addr.base >>> = $base_wb", >>> + "ldrsb", "\t$dst, $addr!", >>> "$addr.base = $base_wb", >>> []>; >>> def t2LDRSB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >>> (ins GPR:$base, t2am_imm8_offset:$offset), >>> AddrModeT2_i8, IndexModePost, IIC_iLoadiu, >>> - "ldrsb", " $dst, [$base], $offset", >>> "$base = $base_wb", >>> + "ldrsb", "\t$dst, [$base], $offset", >>> "$base = $base_wb", >>> []>; >>> >>> def t2LDRSH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >>> (ins t2addrmode_imm8:$addr), >>> AddrModeT2_i8, IndexModePre, IIC_iLoadiu, >>> - "ldrsh", " $dst, $addr!", "$addr.base >>> = $base_wb", >>> + "ldrsh", "\t$dst, $addr!", >>> "$addr.base = $base_wb", >>> []>; >>> def t2LDRSH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), >>> (ins GPR:$base, t2am_imm8_offset:$offset), >>> AddrModeT2_i8, IndexModePost, IIC_iLoadiu, >>> - "ldrsh", " $dst, [$base], $offset", >>> "$base = $base_wb", >>> + "ldrsh", "\t$dst, [$base], $offset", >>> "$base = $base_wb", >>> []>; >>> } >>> >>> @@ -598,48 +598,48 @@ >>> let mayLoad = 1, hasExtraSrcRegAllocReq = 1 in >>> def t2STRDi8 : T2Ii8s4<(outs), >>> (ins GPR:$src1, GPR:$src2, >>> t2addrmode_imm8s4:$addr), >>> - IIC_iStorer, "strd", " $src1, $addr", []>; >>> + IIC_iStorer, "strd", "\t$src1, $addr", []>; >>> >>> // Indexed stores >>> def t2STR_PRE : T2Iidxldst<(outs GPR:$base_wb), >>> (ins GPR:$src, GPR:$base, >>> t2am_imm8_offset:$offset), >>> AddrModeT2_i8, IndexModePre, IIC_iStoreiu, >>> - "str", " $src, [$base, $offset]!", >>> "$base = $base_wb", >>> + "str", "\t$src, [$base, $offset]!", >>> "$base = $base_wb", >>> [(set GPR:$base_wb, >>> (pre_store GPR:$src, GPR:$base, t2am_imm8_offset: >>> $offset))]>; >>> >>> def t2STR_POST : T2Iidxldst<(outs GPR:$base_wb), >>> (ins GPR:$src, GPR:$base, >>> t2am_imm8_offset:$offset), >>> AddrModeT2_i8, IndexModePost, >>> IIC_iStoreiu, >>> - "str", " $src, [$base], $offset", >>> "$base = $base_wb", >>> + "str", "\t$src, [$base], $offset", >>> "$base = $base_wb", >>> [(set GPR:$base_wb, >>> (post_store GPR:$src, GPR:$base, t2am_imm8_offset: >>> $offset))]>; >>> >>> def t2STRH_PRE : T2Iidxldst<(outs GPR:$base_wb), >>> (ins GPR:$src, GPR:$base, >>> t2am_imm8_offset:$offset), >>> AddrModeT2_i8, IndexModePre, IIC_iStoreiu, >>> - "strh", " $src, [$base, $offset]!", >>> "$base = $base_wb", >>> + "strh", "\t$src, [$base, $offset]!", >>> "$base = $base_wb", >>> [(set GPR:$base_wb, >>> (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset: >>> $offset))]>; >>> >>> def t2STRH_POST : T2Iidxldst<(outs GPR:$base_wb), >>> (ins GPR:$src, GPR:$base, >>> t2am_imm8_offset:$offset), >>> AddrModeT2_i8, IndexModePost, >>> IIC_iStoreiu, >>> - "strh", " $src, [$base], $offset", >>> "$base = $base_wb", >>> + "strh", "\t$src, [$base], $offset", >>> "$base = $base_wb", >>> [(set GPR:$base_wb, >>> (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset: >>> $offset))]>; >>> >>> def t2STRB_PRE : T2Iidxldst<(outs GPR:$base_wb), >>> (ins GPR:$src, GPR:$base, >>> t2am_imm8_offset:$offset), >>> AddrModeT2_i8, IndexModePre, IIC_iStoreiu, >>> - "strb", " $src, [$base, $offset]!", >>> "$base = $base_wb", >>> + "strb", "\t$src, [$base, $offset]!", >>> "$base = $base_wb", >>> [(set GPR:$base_wb, >>> (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset: >>> $offset))]>; >>> >>> def t2STRB_POST : T2Iidxldst<(outs GPR:$base_wb), >>> (ins GPR:$src, GPR:$base, >>> t2am_imm8_offset:$offset), >>> AddrModeT2_i8, IndexModePost, >>> IIC_iStoreiu, >>> - "strb", " $src, [$base], $offset", >>> "$base = $base_wb", >>> + "strb", "\t$src, [$base], $offset", >>> "$base = $base_wb", >>> [(set GPR:$base_wb, >>> (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset: >>> $offset))]>; >>> >>> @@ -653,12 +653,12 @@ >>> let mayLoad = 1, hasExtraDefRegAllocReq = 1 in >>> def t2LDM : T2XI<(outs), >>> (ins addrmode4:$addr, pred:$p, reglist:$wb, >>> variable_ops), >>> - IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide} >>> $addr, $wb", []>; >>> + IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide}\t >>> $addr, $wb", []>; >>> >>> let mayStore = 1, hasExtraSrcRegAllocReq = 1 in >>> def t2STM : T2XI<(outs), >>> (ins addrmode4:$addr, pred:$p, reglist:$wb, >>> variable_ops), >>> - IIC_iStorem, "stm${addr:submode}${p}${addr:wide} >>> $addr, $wb", []>; >>> + IIC_iStorem, "stm${addr:submode}${p}${addr:wide}\t >>> $addr, $wb", []>; >>> >>> // >>> = >>> = >>> = >>> ----------------------------------------------------------------------= >>> ==// >>> // Move Instructions. >>> @@ -666,22 +666,22 @@ >>> >>> let neverHasSideEffects = 1 in >>> def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, >>> - "mov", ".w $dst, $src", []>; >>> + "mov", ".w\t$dst, $src", []>; >>> >>> // AddedComplexity to ensure isel tries t2MOVi before t2MOVi16. >>> let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity >>> = 1 in >>> def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi, >>> - "mov", ".w $dst, $src", >>> + "mov", ".w\t$dst, $src", >>> [(set GPR:$dst, t2_so_imm:$src)]>; >>> >>> let isReMaterializable = 1, isAsCheapAsAMove = 1 in >>> def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi, >>> - "movw", " $dst, $src", >>> + "movw", "\t$dst, $src", >>> [(set GPR:$dst, imm0_65535:$src)]>; >>> >>> let Constraints = "$src = $dst" in >>> def t2MOVTi16 : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), >>> IIC_iMOVi, >>> - "movt", " $dst, $imm", >>> + "movt", "\t$dst, $imm", >>> [(set GPR:$dst, >>> (or (and GPR:$src, 0xffff), lo16AllZero: >>> $imm))]>; >>> >>> @@ -760,16 +760,16 @@ >>> >>> let Uses = [CPSR] in { >>> def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, >>> - "rrx", " $dst, $src", >>> + "rrx", "\t$dst, $src", >>> [(set GPR:$dst, (ARMrrx GPR:$src))]>; >>> } >>> >>> let Defs = [CPSR] in { >>> def t2MOVsrl_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), >>> IIC_iMOVsi, >>> - "lsrs.w $dst, $src, #1", >>> + "lsrs.w\t$dst, $src, #1", >>> [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>; >>> def t2MOVsra_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), >>> IIC_iMOVsi, >>> - "asrs.w $dst, $src, #1", >>> + "asrs.w\t$dst, $src, #1", >>> [(set GPR:$dst, (ARMsra_flag GPR:$src))]>; >>> } >>> >>> @@ -785,14 +785,14 @@ >>> >>> let Constraints = "$src = $dst" in >>> def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm: >>> $imm), >>> - IIC_iALUi, "bfc", " $dst, $imm", >>> + IIC_iALUi, "bfc", "\t$dst, $imm", >>> [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm: >>> $imm))]>; >>> >>> def t2SBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, >>> imm0_31:$width), >>> - IIC_iALUi, "sbfx", " $dst, $src, $lsb, $width", >>> []>; >>> + IIC_iALUi, "sbfx", "\t$dst, $src, $lsb, $width", >>> []>; >>> >>> def t2UBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, >>> imm0_31:$width), >>> - IIC_iALUi, "ubfx", " $dst, $src, $lsb, $width", >>> []>; >>> + IIC_iALUi, "ubfx", "\t$dst, $src, $lsb, $width", >>> []>; >>> >>> // FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1) >>> >>> @@ -819,80 +819,80 @@ >>> // >>> let isCommutable = 1 in >>> def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, >>> - "mul", " $dst, $a, $b", >>> + "mul", "\t$dst, $a, $b", >>> [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>; >>> >>> def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), >>> IIC_iMAC32, >>> - "mla", " $dst, $a, $b, $c", >>> + "mla", "\t$dst, $a, $b, $c", >>> [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>; >>> >>> def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), >>> IIC_iMAC32, >>> - "mls", " $dst, $a, $b, $c", >>> + "mls", "\t$dst, $a, $b, $c", >>> [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>; >>> >>> // Extra precision multiplies with low / high results >>> let neverHasSideEffects = 1 in { >>> let isCommutable = 1 in { >>> def t2SMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR: >>> $b), IIC_iMUL64, >>> - "smull", " $ldst, $hdst, $a, $b", []>; >>> + "smull", "\t$ldst, $hdst, $a, $b", []>; >>> >>> def t2UMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR: >>> $b), IIC_iMUL64, >>> - "umull", " $ldst, $hdst, $a, $b", []>; >>> + "umull", "\t$ldst, $hdst, $a, $b", []>; >>> } >>> >>> // Multiply + accumulate >>> def t2SMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR: >>> $b), IIC_iMAC64, >>> - "smlal", " $ldst, $hdst, $a, $b", []>; >>> + "smlal", "\t$ldst, $hdst, $a, $b", []>; >>> >>> def t2UMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR: >>> $b), IIC_iMAC64, >>> - "umlal", " $ldst, $hdst, $a, $b", []>; >>> + "umlal", "\t$ldst, $hdst, $a, $b", []>; >>> >>> def t2UMAAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR: >>> $b), IIC_iMAC64, >>> - "umaal", " $ldst, $hdst, $a, $b", []>; >>> + "umaal", "\t$ldst, $hdst, $a, $b", []>; >>> } // neverHasSideEffects >>> >>> // Most significant word multiply >>> def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, >>> - "smmul", " $dst, $a, $b", >>> + "smmul", "\t$dst, $a, $b", >>> [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>; >>> >>> def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), >>> IIC_iMAC32, >>> - "smmla", " $dst, $a, $b, $c", >>> + "smmla", "\t$dst, $a, $b, $c", >>> [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR: >>> $c))]>; >>> >>> >>> def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), >>> IIC_iMAC32, >>> - "smmls", " $dst, $a, $b, $c", >>> + "smmls", "\t$dst, $a, $b, $c", >>> [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR: >>> $b)))]>; >>> >>> multiclass T2I_smul { >>> def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, >>> - !strconcat(opc, "bb"), " $dst, $a, $b", >>> + !strconcat(opc, "bb"), "\t$dst, $a, $b", >>> [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16), >>> (sext_inreg GPR:$b, i16)))]>; >>> >>> def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, >>> - !strconcat(opc, "bt"), " $dst, $a, $b", >>> + !strconcat(opc, "bt"), "\t$dst, $a, $b", >>> [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16), >>> (sra GPR:$b, (i32 16))))]>; >>> >>> def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, >>> - !strconcat(opc, "tb"), " $dst, $a, $b", >>> + !strconcat(opc, "tb"), "\t$dst, $a, $b", >>> [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)), >>> (sext_inreg GPR:$b, i16)))]>; >>> >>> def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32, >>> - !strconcat(opc, "tt"), " $dst, $a, $b", >>> + !strconcat(opc, "tt"), "\t$dst, $a, $b", >>> [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)), >>> (sra GPR:$b, (i32 16))))]>; >>> >>> def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16, >>> - !strconcat(opc, "wb"), " $dst, $a, $b", >>> + !strconcat(opc, "wb"), "\t$dst, $a, $b", >>> [(set GPR:$dst, (sra (opnode GPR:$a, >>> (sext_inreg GPR:$b, i16)), (i32 >>> 16)))]>; >>> >>> def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16, >>> - !strconcat(opc, "wt"), " $dst, $a, $b", >>> + !strconcat(opc, "wt"), "\t$dst, $a, $b", >>> [(set GPR:$dst, (sra (opnode GPR:$a, >>> (sra GPR:$b, (i32 16))), (i32 >>> 16)))]>; >>> } >>> @@ -900,33 +900,33 @@ >>> >>> multiclass T2I_smla { >>> def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), >>> IIC_iMAC16, >>> - !strconcat(opc, "bb"), " $dst, $a, $b, $acc", >>> + !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc", >>> [(set GPR:$dst, (add GPR:$acc, >>> (opnode (sext_inreg GPR:$a, i16), >>> (sext_inreg GPR:$b, i16))))]>; >>> >>> def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), >>> IIC_iMAC16, >>> - !strconcat(opc, "bt"), " $dst, $a, $b, $acc", >>> + !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc", >>> [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR: >>> $a, i16), >>> (sra GPR:$b, >>> (i32 16)))))]>; >>> >>> def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), >>> IIC_iMAC16, >>> - !strconcat(opc, "tb"), " $dst, $a, $b, $acc", >>> + !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc", >>> [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, >>> (i32 16)), >>> (sext_inreg GPR:$b, >>> i16))))]>; >>> >>> def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), >>> IIC_iMAC16, >>> - !strconcat(opc, "tt"), " $dst, $a, $b, $acc", >>> + !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc", >>> [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, >>> (i32 16)), >>> (sra GPR:$b, >>> (i32 16)))))]>; >>> >>> def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), >>> IIC_iMAC16, >>> - !strconcat(opc, "wb"), " $dst, $a, $b, $acc", >>> + !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc", >>> [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a, >>> (sext_inreg GPR:$b, i16)), >>> (i32 16))))]>; >>> >>> def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), >>> IIC_iMAC16, >>> - !strconcat(opc, "wt"), " $dst, $a, $b, $acc", >>> + !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc", >>> [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a, >>> (sra GPR:$b, (i32 16))), >>> (i32 16))))]>; >>> } >>> @@ -943,15 +943,15 @@ >>> // >>> >>> def t2CLZ : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, >>> - "clz", " $dst, $src", >>> + "clz", "\t$dst, $src", >>> [(set GPR:$dst, (ctlz GPR:$src))]>; >>> >>> def t2REV : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, >>> - "rev", ".w $dst, $src", >>> + "rev", ".w\t$dst, $src", >>> [(set GPR:$dst, (bswap GPR:$src))]>; >>> >>> def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, >>> - "rev16", ".w $dst, $src", >>> + "rev16", ".w\t$dst, $src", >>> [(set GPR:$dst, >>> (or (and (srl GPR:$src, (i32 8)), 0xFF), >>> (or (and (shl GPR:$src, (i32 8)), 0xFF00), >>> @@ -959,14 +959,14 @@ >>> (and (shl GPR:$src, (i32 8)), >>> 0xFF000000)))))]>; >>> >>> def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, >>> - "revsh", ".w $dst, $src", >>> + "revsh", ".w\t$dst, $src", >>> [(set GPR:$dst, >>> (sext_inreg >>> (or (srl (and GPR:$src, 0xFF00), (i32 8)), >>> (shl GPR:$src, (i32 8))), i16))]>; >>> >>> def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, >>> i32imm:$shamt), >>> - IIC_iALUsi, "pkhbt", " $dst, $src1, $src2, LSL >>> $shamt", >>> + IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL >>> $shamt", >>> [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF), >>> (and (shl GPR:$src2, (i32 imm: >>> $shamt)), >>> 0xFFFF0000)))]>; >>> @@ -978,7 +978,7 @@ >>> (t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>; >>> >>> def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, >>> i32imm:$shamt), >>> - IIC_iALUsi, "pkhtb", " $dst, $src1, $src2, ASR >>> $shamt", >>> + IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR >>> $shamt", >>> [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000), >>> (and (sra GPR:$src2, >>> imm16_31:$shamt), >>> 0xFFFF)))]>; >>> @@ -1025,26 +1025,26 @@ >>> // FIXME: should be able to write a pattern for ARMcmov, but can't >>> use >>> // a two-value operand where a dag node expects two operands. :( >>> def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true), >>> IIC_iCMOVr, >>> - "mov", ".w $dst, $true", >>> + "mov", ".w\t$dst, $true", >>> [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR: >>> $ccr))*/]>, >>> RegConstraint<"$false = $dst">; >>> >>> def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm: >>> $true), >>> - IIC_iCMOVi, "mov", ".w $dst, $true", >>> + IIC_iCMOVi, "mov", ".w\t$dst, $true", >>> [/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_imm:$true, imm:$cc, >>> CCR:$ccr))*/]>, >>> RegConstraint<"$false = $dst">; >>> >>> def t2MOVCClsl : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, >>> i32imm:$rhs), >>> - IIC_iCMOVsi, "lsl", ".w $dst, $true, $rhs", []>, >>> + IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", [] >>> >, >>> RegConstraint<"$false = $dst">; >>> def t2MOVCClsr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, >>> i32imm:$rhs), >>> - IIC_iCMOVsi, "lsr", ".w $dst, $true, $rhs", []>, >>> + IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", [] >>> >, >>> RegConstraint<"$false = $dst">; >>> def t2MOVCCasr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, >>> i32imm:$rhs), >>> - IIC_iCMOVsi, "asr", ".w $dst, $true, $rhs", []>, >>> + IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", [] >>> >, >>> RegConstraint<"$false = $dst">; >>> def t2MOVCCror : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, >>> i32imm:$rhs), >>> - IIC_iCMOVsi, "ror", ".w $dst, $true, $rhs", []>, >>> + IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", [] >>> >, >>> RegConstraint<"$false = $dst">; >>> >>> // >>> = >>> = >>> = >>> ----------------------------------------------------------------------= >>> ==// >>> @@ -1055,7 +1055,7 @@ >>> let isCall = 1, >>> Defs = [R0, R12, LR, CPSR] in { >>> def t2TPsoft : T2XI<(outs), (ins), IIC_Br, >>> - "bl __aeabi_read_tp", >>> + "bl\t__aeabi_read_tp", >>> [(set R0, ARMthread_pointer)]>; >>> } >>> >>> @@ -1078,13 +1078,13 @@ >>> D31 ] in { >>> def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src), >>> AddrModeNone, SizeSpecial, NoItinerary, >>> - "str.w sp, [$src, #+8] @ eh_setjmp >>> begin\n" >>> - "\tadr r12, 0f\n" >>> - "\torr r12, #1\n" >>> - "\tstr.w r12, [$src, #+4]\n" >>> - "\tmovs r0, #0\n" >>> - "\tb 1f\n" >>> - "0:\tmovs r0, #1 @ eh_setjmp end\n" >>> + "str.w\tsp, [$src, #+8] @ >>> eh_setjmp begin\n" >>> + "\tadr\tr12, 0f\n" >>> + "\torr\tr12, #1\n" >>> + "\tstr.w\tr12, [$src, #+4]\n" >>> + "\tmovs\tr0, #0\n" >>> + "\tb\t1f\n" >>> + "0:\tmovs\tr0, #1 @ eh_setjmp end\n" >>> "1:", "", >>> [(set R0, (ARMeh_sjlj_setjmp GPR: >>> $src))]>; >>> } >>> @@ -1103,32 +1103,32 @@ >>> hasExtraDefRegAllocReq = 1 in >>> def t2LDM_RET : T2XI<(outs), >>> (ins addrmode4:$addr, pred:$p, reglist:$wb, >>> variable_ops), >>> - IIC_Br, "ldm${addr:submode}${p}${addr:wide} >>> $addr, $wb", >>> + IIC_Br, "ldm${addr:submode}${p}${addr:wide}\t >>> $addr, $wb", >>> []>; >>> >>> let isBranch = 1, isTerminator = 1, isBarrier = 1 in { >>> let isPredicable = 1 in >>> def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br, >>> - "b.w $target", >>> + "b.w\t$target", >>> [(br bb:$target)]>; >>> >>> let isNotDuplicable = 1, isIndirectBranch = 1 in { >>> def t2BR_JT : >>> T2JTI<(outs), >>> (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm: >>> $id), >>> - IIC_Br, "mov pc, $target\n$jt", >>> + IIC_Br, "mov\tpc, $target\n$jt", >>> [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm: >>> $id)]>; >>> >>> // FIXME: Add a non-pc based case that can be predicated. >>> def t2TBB : >>> T2JTI<(outs), >>> (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id), >>> - IIC_Br, "tbb $index\n$jt", []>; >>> + IIC_Br, "tbb\t$index\n$jt", []>; >>> >>> def t2TBH : >>> T2JTI<(outs), >>> (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id), >>> - IIC_Br, "tbh $index\n$jt", []>; >>> + IIC_Br, "tbh\t$index\n$jt", []>; >>> } // isNotDuplicable, isIndirectBranch >>> >>> } // isBranch, isTerminator, isBarrier >>> @@ -1137,14 +1137,14 @@ >>> // a two-value operand where a dag node expects two operands. :( >>> let isBranch = 1, isTerminator = 1 in >>> def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br, >>> - "b", ".w $target", >>> + "b", ".w\t$target", >>> [/*(ARMbrcond bb:$target, imm:$cc)*/]>; >>> >>> >>> // IT block >>> def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask), >>> AddrModeNone, Size2Bytes, IIC_iALUx, >>> - "it$mask $cc", "", []>; >>> + "it$mask\t$cc", "", []>; >>> >>> // >>> = >>> = >>> = >>> ----------------------------------------------------------------------= >>> ==// >>> // Non-Instruction Patterns >>> @@ -1175,5 +1175,5 @@ >>> // when we can do generalized remat. >>> let isReMaterializable = 1 in >>> def t2MOVi32imm : T2Ix2<(outs GPR:$dst), (ins i32imm:$src), >>> IIC_iMOVi, >>> - "movw", " $dst, ${src:lo16}\n\tmovt${p} >>> $dst, ${src:hi16}", >>> + "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t >>> $dst, ${src:hi16}", >>> [(set GPR:$dst, (i32 imm:$src))]>; >>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > From daniel at zuster.org Tue Oct 27 12:48:37 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 27 Oct 2009 17:48:37 -0000 Subject: [llvm-commits] [compiler-rt] r85259 - /compiler-rt/trunk/.gitignore Message-ID: <200910271748.n9RHmb3P006071@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Oct 27 12:48:37 2009 New Revision: 85259 URL: http://llvm.org/viewvc/llvm-project?rev=85259&view=rev Log: Add .gitignore file. Added: compiler-rt/trunk/.gitignore Added: compiler-rt/trunk/.gitignore URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/.gitignore?rev=85259&view=auto ============================================================================== --- compiler-rt/trunk/.gitignore (added) +++ compiler-rt/trunk/.gitignore Tue Oct 27 12:48:37 2009 @@ -0,0 +1,3 @@ +Debug +Release +Profile From daniel at zuster.org Tue Oct 27 12:48:46 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 27 Oct 2009 17:48:46 -0000 Subject: [llvm-commits] [compiler-rt] r85260 - in /compiler-rt/trunk: lib/endianness.h lib/int_lib.h test/Unit/int_lib.h test/Unit/test Message-ID: <200910271748.n9RHmkeT006092@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Oct 27 12:48:46 2009 New Revision: 85260 URL: http://llvm.org/viewvc/llvm-project?rev=85260&view=rev Log: Remove duplicate copy of int_lib.h, and update test script to find copy inside lib/. Also, fix some brokenness in the test script w.r.t REMOTE. Removed: compiler-rt/trunk/test/Unit/int_lib.h Modified: compiler-rt/trunk/lib/endianness.h compiler-rt/trunk/lib/int_lib.h compiler-rt/trunk/test/Unit/test Modified: compiler-rt/trunk/lib/endianness.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/endianness.h?rev=85260&r1=85259&r2=85260&view=diff ============================================================================== --- compiler-rt/trunk/lib/endianness.h (original) +++ compiler-rt/trunk/lib/endianness.h Tue Oct 27 12:48:46 2009 @@ -1,4 +1,4 @@ -/* ===-- endianness.h - configuration header for libgcc replacement --------=== +/* ===-- endianness.h - configuration header for compiler-rt ---------------=== * * The LLVM Compiler Infrastructure * @@ -7,7 +7,7 @@ * * ===----------------------------------------------------------------------=== * - * This file is a configuration header for libgcc replacement. + * This file is a configuration header for compiler-rt. * This file is not part of the interface of this library. * * ===----------------------------------------------------------------------=== Modified: compiler-rt/trunk/lib/int_lib.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/int_lib.h?rev=85260&r1=85259&r2=85260&view=diff ============================================================================== --- compiler-rt/trunk/lib/int_lib.h (original) +++ compiler-rt/trunk/lib/int_lib.h Tue Oct 27 12:48:46 2009 @@ -1,4 +1,4 @@ -/* ===-- int_lib.h - configuration header for libgcc replacement -----------=== +/* ===-- int_lib.h - configuration header for compiler-rt -----------------=== * * The LLVM Compiler Infrastructure * @@ -7,7 +7,7 @@ * * ===----------------------------------------------------------------------=== * - * This file is a configuration header for libgcc replacement. + * This file is a configuration header for compiler-rt. * This file is not part of the interface of this library. * * ===----------------------------------------------------------------------=== @@ -98,6 +98,20 @@ }s; } utwords; +static inline ti_int make_ti(di_int h, di_int l) { + twords r; + r.s.high = h; + r.s.low = l; + return r.all; +} + +static inline tu_int make_tu(du_int h, du_int l) { + utwords r; + r.s.high = h; + r.s.low = l; + return r.all; +} + #endif /* __x86_64 */ typedef union Removed: compiler-rt/trunk/test/Unit/int_lib.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/int_lib.h?rev=85259&view=auto ============================================================================== --- compiler-rt/trunk/test/Unit/int_lib.h (original) +++ compiler-rt/trunk/test/Unit/int_lib.h (removed) @@ -1,159 +0,0 @@ -/* ===-- int_lib.h - configuration header for libgcc replacement -----------=== - * - * The LLVM Compiler Infrastructure - * - * This file is distributed under the University of Illinois Open Source - * License. See LICENSE.TXT for details. - * - * ===----------------------------------------------------------------------=== - * - * This file is a configuration header for libgcc replacement. - * This file is not part of the interface of this library. - * - * ===----------------------------------------------------------------------=== - */ - -#ifndef INT_LIB_H -#define INT_LIB_H - -/* Assumption: signed integral is 2's complement */ -/* Assumption: right shift of signed negative is arithmetic shift */ - -#include -#include "endianness.h" -#include - -#if !defined(INFINITY) && defined(HUGE_VAL) -#define INFINITY HUGE_VAL -#endif /* INFINITY */ - -typedef int si_int; -typedef unsigned su_int; - -typedef long long di_int; -typedef unsigned long long du_int; - -typedef union -{ - di_int all; - struct - { -#if _YUGA_LITTLE_ENDIAN - su_int low; - si_int high; -#else - si_int high; - su_int low; -#endif /* _YUGA_LITTLE_ENDIAN */ - }s; -} dwords; - -typedef union -{ - du_int all; - struct - { -#if _YUGA_LITTLE_ENDIAN - su_int low; - su_int high; -#else - su_int high; - su_int low; -#endif /* _YUGA_LITTLE_ENDIAN */ - }s; -} udwords; - -#if __x86_64 - -typedef int ti_int __attribute__ ((mode (TI))); -typedef unsigned tu_int __attribute__ ((mode (TI))); - -typedef union -{ - ti_int all; - struct - { -#if _YUGA_LITTLE_ENDIAN - du_int low; - di_int high; -#else - di_int high; - du_int low; -#endif /* _YUGA_LITTLE_ENDIAN */ - }s; -} twords; - -typedef union -{ - tu_int all; - struct - { -#if _YUGA_LITTLE_ENDIAN - du_int low; - du_int high; -#else - du_int high; - du_int low; -#endif /* _YUGA_LITTLE_ENDIAN */ - }s; -} utwords; - -inline -ti_int -make_ti(di_int h, di_int l) -{ - twords r; - r.high = h; - r.low = l; - return r.all; -} - -inline -tu_int -make_tu(du_int h, du_int l) -{ - utwords r; - r.high = h; - r.low = l; - return r.all; -} - -#endif /* __x86_64 */ - -typedef union -{ - su_int u; - float f; -} float_bits; - -typedef union -{ - udwords u; - double f; -} double_bits; - -typedef struct -{ -#if _YUGA_LITTLE_ENDIAN - udwords low; - udwords high; -#else - udwords high; - udwords low; -#endif /* _YUGA_LITTLE_ENDIAN */ -} uqwords; - -typedef union -{ - uqwords u; - long double f; -} long_double_bits; - - -/* for test cases that are only applicable to */ -/* architectures with 80-bit long doubles */ -#if __i386__ || __x86_64__ - #define HAS_80_BIT_LONG_DOUBLE 1 -#endif - -#endif /* INT_LIB_H */ Modified: compiler-rt/trunk/test/Unit/test URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/test?rev=85260&r1=85259&r2=85260&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/test (original) +++ compiler-rt/trunk/test/Unit/test Tue Oct 27 12:48:46 2009 @@ -5,9 +5,9 @@ if test `uname` = "Darwin"; then if test "$1" = "armv6"; then ARCHS="armv6" - LIBS="-lSystem" - REMOTE=1 - mkdir -p remote + LIBS="-lSystem" + REMOTE=1 + mkdir -p remote else ARCHS="i386 x86_64 ppc" LIBS="-lSystem" @@ -17,7 +17,7 @@ fi for ARCH in $ARCHS; do - CFLAGS="-Os -nodefaultlibs" + CFLAGS="-Os -nodefaultlibs -I../../lib" if test "$ARCH" != ''; then CFLAGS="-arch $ARCH $CFLAGS" fi @@ -38,15 +38,15 @@ # this test requires an extra compiler option EXTRA="-fnested-functions" fi - if test $REMOTE - then + if test "$REMOTE" = "1" + then if gcc $CFLAGS $FILE ../../Release/libcompiler_rt.Optimized.a $LIBS $EXTRA -o ./remote/$FILE.exe then echo "Built $FILE.exe for $ARCH" - else + else echo "$FILE failed to compile" - fi - else + fi + else if gcc $CFLAGS $FILE ../../Release/libcompiler_rt.Optimized.a $LIBS $EXTRA then echo "Testing $FILE for $ARCH" @@ -61,7 +61,7 @@ echo "$FILE failed to compile" exit 1 fi - fi + fi done done echo "pass" From daniel at zuster.org Tue Oct 27 12:49:07 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 27 Oct 2009 17:49:07 -0000 Subject: [llvm-commits] [compiler-rt] r85261 - /compiler-rt/trunk/test/Unit/ Message-ID: <200910271749.n9RHnASu006186@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Oct 27 12:49:07 2009 New Revision: 85261 URL: http://llvm.org/viewvc/llvm-project?rev=85261&view=rev Log: Fix tests broken by removal of de-anonyomizing structs. Modified: compiler-rt/trunk/test/Unit/absvti2_test.c compiler-rt/trunk/test/Unit/addvti3_test.c compiler-rt/trunk/test/Unit/ashlti3_test.c compiler-rt/trunk/test/Unit/ashrti3_test.c compiler-rt/trunk/test/Unit/clzti2_test.c compiler-rt/trunk/test/Unit/cmpti2_test.c compiler-rt/trunk/test/Unit/ctzti2_test.c compiler-rt/trunk/test/Unit/divti3_test.c compiler-rt/trunk/test/Unit/ffsti2_test.c compiler-rt/trunk/test/Unit/fixdfti_test.c compiler-rt/trunk/test/Unit/fixsfti_test.c compiler-rt/trunk/test/Unit/fixunsdfti_test.c compiler-rt/trunk/test/Unit/fixunssfti_test.c compiler-rt/trunk/test/Unit/fixunsxfti_test.c compiler-rt/trunk/test/Unit/fixxfti_test.c compiler-rt/trunk/test/Unit/floattidf_test.c compiler-rt/trunk/test/Unit/floattisf_test.c compiler-rt/trunk/test/Unit/floattixf_test.c compiler-rt/trunk/test/Unit/floatuntidf_test.c compiler-rt/trunk/test/Unit/floatuntisf_test.c compiler-rt/trunk/test/Unit/floatuntixf_test.c compiler-rt/trunk/test/Unit/lshrti3_test.c compiler-rt/trunk/test/Unit/modti3_test.c compiler-rt/trunk/test/Unit/multi3_test.c compiler-rt/trunk/test/Unit/mulvti3_test.c compiler-rt/trunk/test/Unit/negti2_test.c compiler-rt/trunk/test/Unit/negvti2_test.c compiler-rt/trunk/test/Unit/parityti2_test.c compiler-rt/trunk/test/Unit/popcountti2_test.c compiler-rt/trunk/test/Unit/subvti3_test.c compiler-rt/trunk/test/Unit/ucmpti2_test.c compiler-rt/trunk/test/Unit/udivmodti4_test.c compiler-rt/trunk/test/Unit/udivti3_test.c compiler-rt/trunk/test/Unit/umodti3_test.c Modified: compiler-rt/trunk/test/Unit/absvti2_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/absvti2_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/absvti2_test.c (original) +++ compiler-rt/trunk/test/Unit/absvti2_test.c Tue Oct 27 12:49:07 2009 @@ -38,7 +38,8 @@ expectedt.all = expected; printf("error in __absvti2(0x%llX%.16llX) = " "0x%llX%.16llX, expected positive 0x%llX%.16llX\n", - at.high, at.low, xt.high, xt.low, expectedt.high, expectedt.low); + at.s.high, at.s.low, xt.s.high, xt.s.low, + expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/addvti3_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/addvti3_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/addvti3_test.c (original) +++ compiler-rt/trunk/test/Unit/addvti3_test.c Tue Oct 27 12:49:07 2009 @@ -38,8 +38,8 @@ expectedt.all = expected; printf("error in test__addvti3(0x%llX%.16llX, 0x%llX%.16llX) = " "0x%llX%.16llX, expected 0x%llX%.16llX\n", - at.high, at.low, bt.high, bt.low, xt.high, xt.low, - expectedt.high, expectedt.low); + at.s.high, at.s.low, bt.s.high, bt.s.low, xt.s.high, xt.s.low, + expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/ashlti3_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/ashlti3_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/ashlti3_test.c (original) +++ compiler-rt/trunk/test/Unit/ashlti3_test.c Tue Oct 27 12:49:07 2009 @@ -37,8 +37,8 @@ expectedt.all = expected; printf("error in __ashlti3: 0x%llX%.16llX << %d = 0x%llX%.16llX," " expected 0x%llX%.16llX\n", - at.high, at.low, b, xt.high, xt.low, - expectedt.high, expectedt.low); + at.s.high, at.s.low, b, xt.s.high, xt.s.low, + expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/ashrti3_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/ashrti3_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/ashrti3_test.c (original) +++ compiler-rt/trunk/test/Unit/ashrti3_test.c Tue Oct 27 12:49:07 2009 @@ -35,8 +35,8 @@ expectedt.all = expected; printf("error in __ashrti3: 0x%llX%.16llX >> %d = 0x%llX%.16llX," " expected 0x%llX%.16llX\n", - at.high, at.low, b, xt.high, xt.low, - expectedt.high, expectedt.low); + at.s.high, at.s.low, b, xt.s.high, xt.s.low, + expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/clzti2_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/clzti2_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/clzti2_test.c (original) +++ compiler-rt/trunk/test/Unit/clzti2_test.c Tue Oct 27 12:49:07 2009 @@ -30,7 +30,7 @@ twords at; at.all = a; printf("error in __clzti2(0x%llX%.16llX) = %d, expected %d\n", - at.high, at.low, x, expected); + at.s.high, at.s.low, x, expected); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/cmpti2_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/cmpti2_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/cmpti2_test.c (original) +++ compiler-rt/trunk/test/Unit/cmpti2_test.c Tue Oct 27 12:49:07 2009 @@ -32,7 +32,7 @@ twords bt; bt.all = b; printf("error in __cmpti2(0x%llX%.16llX, 0x%llX%.16llX) = %d, expected %d\n", - at.high, at.low, bt.high, bt.low, x, expected); + at.s.high, at.s.low, bt.s.high, bt.s.low, x, expected); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/ctzti2_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/ctzti2_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/ctzti2_test.c (original) +++ compiler-rt/trunk/test/Unit/ctzti2_test.c Tue Oct 27 12:49:07 2009 @@ -30,7 +30,7 @@ twords at; at.all = a; printf("error in __ctzti2(0x%llX%.16llX) = %d, expected %d\n", - at.high, at.low, x, expected); + at.s.high, at.s.low, x, expected); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/divti3_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/divti3_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/divti3_test.c (original) +++ compiler-rt/trunk/test/Unit/divti3_test.c Tue Oct 27 12:49:07 2009 @@ -35,8 +35,8 @@ expectedt.all = expected; printf("error in __divti3: 0x%llX%.16llX / 0x%llX%.16llX = " "0x%llX%.16llX, expected 0x%llX%.16llX\n", - at.high, at.low, bt.high, bt.low, xt.high, xt.low, - expectedt.high, expectedt.low); + at.s.high, at.s.low, bt.s.high, bt.s.low, xt.s.high, xt.s.low, + expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/ffsti2_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/ffsti2_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/ffsti2_test.c (original) +++ compiler-rt/trunk/test/Unit/ffsti2_test.c Tue Oct 27 12:49:07 2009 @@ -29,7 +29,7 @@ twords at; at.all = a; printf("error in __ffsti2(0x%llX%.16llX) = %d, expected %d\n", - at.high, at.low, x, expected); + at.s.high, at.s.low, x, expected); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/fixdfti_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/fixdfti_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/fixdfti_test.c (original) +++ compiler-rt/trunk/test/Unit/fixdfti_test.c Tue Oct 27 12:49:07 2009 @@ -36,7 +36,7 @@ twords expectedt; expectedt.all = expected; printf("error in __fixdfti(%A) = 0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n", - a, xt.high, xt.low, expectedt.high, expectedt.low); + a, xt.s.high, xt.s.low, expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/fixsfti_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/fixsfti_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/fixsfti_test.c (original) +++ compiler-rt/trunk/test/Unit/fixsfti_test.c Tue Oct 27 12:49:07 2009 @@ -36,7 +36,7 @@ twords expectedt; expectedt.all = expected; printf("error in __fixsfti(%A) = 0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n", - a, xt.high, xt.low, expectedt.high, expectedt.low); + a, xt.s.high, xt.s.low, expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/fixunsdfti_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/fixunsdfti_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/fixunsdfti_test.c (original) +++ compiler-rt/trunk/test/Unit/fixunsdfti_test.c Tue Oct 27 12:49:07 2009 @@ -38,7 +38,7 @@ utwords expectedt; expectedt.all = expected; printf("error in __fixunsdfti(%A) = 0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n", - a, xt.high, xt.low, expectedt.high, expectedt.low); + a, xt.s.high, xt.s.low, expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/fixunssfti_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/fixunssfti_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/fixunssfti_test.c (original) +++ compiler-rt/trunk/test/Unit/fixunssfti_test.c Tue Oct 27 12:49:07 2009 @@ -38,7 +38,7 @@ utwords expectedt; expectedt.all = expected; printf("error in __fixunssfti(%A) = 0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n", - a, xt.high, xt.low, expectedt.high, expectedt.low); + a, xt.s.high, xt.s.low, expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/fixunsxfti_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/fixunsxfti_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/fixunsxfti_test.c (original) +++ compiler-rt/trunk/test/Unit/fixunsxfti_test.c Tue Oct 27 12:49:07 2009 @@ -39,7 +39,7 @@ utwords expectedt; expectedt.all = expected; printf("error in __fixunsxfti(%LA) = 0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n", - a, xt.high, xt.low, expectedt.high, expectedt.low); + a, xt.s.high, xt.s.low, expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/fixxfti_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/fixxfti_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/fixxfti_test.c (original) +++ compiler-rt/trunk/test/Unit/fixxfti_test.c Tue Oct 27 12:49:07 2009 @@ -37,7 +37,7 @@ utwords expectedt; expectedt.all = expected; printf("error in __fixxfti(%LA) = 0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n", - a, xt.high, xt.low, expectedt.high, expectedt.low); + a, xt.s.high, xt.s.low, expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/floattidf_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/floattidf_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/floattidf_test.c (original) +++ compiler-rt/trunk/test/Unit/floattidf_test.c Tue Oct 27 12:49:07 2009 @@ -34,7 +34,7 @@ twords at; at.all = a; printf("error in __floattidf(0x%.16llX%.16llX) = %a, expected %a\n", - at.high, at.low, x, expected); + at.s.high, at.s.low, x, expected); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/floattisf_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/floattisf_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/floattisf_test.c (original) +++ compiler-rt/trunk/test/Unit/floattisf_test.c Tue Oct 27 12:49:07 2009 @@ -34,7 +34,7 @@ twords at; at.all = a; printf("error in __floattisf(0x%.16llX%.16llX) = %a, expected %a\n", - at.high, at.low, x, expected); + at.s.high, at.s.low, x, expected); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/floattixf_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/floattixf_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/floattixf_test.c (original) +++ compiler-rt/trunk/test/Unit/floattixf_test.c Tue Oct 27 12:49:07 2009 @@ -35,7 +35,7 @@ twords at; at.all = a; printf("error in __floattixf(0x%.16llX%.16llX) = %LA, expected %LA\n", - at.high, at.low, x, expected); + at.s.high, at.s.low, x, expected); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/floatuntidf_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/floatuntidf_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/floatuntidf_test.c (original) +++ compiler-rt/trunk/test/Unit/floatuntidf_test.c Tue Oct 27 12:49:07 2009 @@ -34,7 +34,7 @@ utwords at; at.all = a; printf("error in __floatuntidf(0x%.16llX%.16llX) = %a, expected %a\n", - at.high, at.low, x, expected); + at.s.high, at.s.low, x, expected); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/floatuntisf_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/floatuntisf_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/floatuntisf_test.c (original) +++ compiler-rt/trunk/test/Unit/floatuntisf_test.c Tue Oct 27 12:49:07 2009 @@ -34,7 +34,7 @@ utwords at; at.all = a; printf("error in __floatuntisf(0x%.16llX%.16llX) = %a, expected %a\n", - at.high, at.low, x, expected); + at.s.high, at.s.low, x, expected); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/floatuntixf_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/floatuntixf_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/floatuntixf_test.c (original) +++ compiler-rt/trunk/test/Unit/floatuntixf_test.c Tue Oct 27 12:49:07 2009 @@ -35,7 +35,7 @@ utwords at; at.all = a; printf("error in __floatuntixf(0x%.16llX%.16llX) = %LA, expected %LA\n", - at.high, at.low, x, expected); + at.s.high, at.s.low, x, expected); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/lshrti3_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/lshrti3_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/lshrti3_test.c (original) +++ compiler-rt/trunk/test/Unit/lshrti3_test.c Tue Oct 27 12:49:07 2009 @@ -35,8 +35,8 @@ expectedt.all = expected; printf("error in __lshrti3: 0x%llX%.16llX >> %d = 0x%llX%.16llX," " expected 0x%llX%.16llX\n", - at.high, at.low, b, xt.high, xt.low, - expectedt.high, expectedt.low); + at.s.high, at.s.low, b, xt.s.high, xt.s.low, + expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/modti3_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/modti3_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/modti3_test.c (original) +++ compiler-rt/trunk/test/Unit/modti3_test.c Tue Oct 27 12:49:07 2009 @@ -35,8 +35,8 @@ expectedt.all = expected; printf("error in __modti3: 0x%.16llX%.16llX %% 0x%.16llX%.16llX = " "0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n", - at.high, at.low, bt.high, bt.low, xt.high, xt.low, - expectedt.high, expectedt.low); + at.s.high, at.s.low, bt.s.high, bt.s.low, xt.s.high, xt.s.low, + expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/multi3_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/multi3_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/multi3_test.c (original) +++ compiler-rt/trunk/test/Unit/multi3_test.c Tue Oct 27 12:49:07 2009 @@ -33,8 +33,8 @@ expectedt.all = expected; printf("error in __multi3: 0x%.16llX%.16llX * 0x%.16llX%.16llX = " "0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n", - at.high, at.low, bt.high, bt.low, xt.high, xt.low, - expectedt.high, expectedt.low); + at.s.high, at.s.low, bt.s.high, bt.s.low, xt.s.high, xt.s.low, + expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/mulvti3_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/mulvti3_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/mulvti3_test.c (original) +++ compiler-rt/trunk/test/Unit/mulvti3_test.c Tue Oct 27 12:49:07 2009 @@ -37,8 +37,8 @@ expectedt.all = expected; printf("error in __mulvti3: 0x%.16llX%.16llX * 0x%.16llX%.16llX = " "0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n", - at.high, at.low, bt.high, bt.low, xt.high, xt.low, - expectedt.high, expectedt.low); + at.s.high, at.s.low, bt.s.high, bt.s.low, xt.s.high, xt.s.low, + expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/negti2_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/negti2_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/negti2_test.c (original) +++ compiler-rt/trunk/test/Unit/negti2_test.c Tue Oct 27 12:49:07 2009 @@ -33,7 +33,7 @@ expectedt.all = expected; printf("error in __negti2: -0x%.16llX%.16llX = 0x%.16llX%.16llX, " "expected 0x%.16llX%.16llX\n", - at.high, at.low, xt.high, xt.low, expectedt.high, expectedt.low); + at.s.high, at.s.low, xt.s.high, xt.s.low, expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/negvti2_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/negvti2_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/negvti2_test.c (original) +++ compiler-rt/trunk/test/Unit/negvti2_test.c Tue Oct 27 12:49:07 2009 @@ -37,7 +37,7 @@ expectedt.all = expected; printf("error in __negvti2(0x%.16llX%.16llX) = 0x%.16llX%.16llX, " "expected 0x%.16llX%.16llX\n", - at.high, at.low, xt.high, xt.low, expectedt.high, expectedt.low); + at.s.high, at.s.low, xt.s.high, xt.s.low, expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/parityti2_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/parityti2_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/parityti2_test.c (original) +++ compiler-rt/trunk/test/Unit/parityti2_test.c Tue Oct 27 12:49:07 2009 @@ -38,7 +38,7 @@ twords at; at.all = a; printf("error in __parityti2(0x%.16llX%.16llX) = %d, expected %d\n", - at.high, at.low, x, expected); + at.s.high, at.s.low, x, expected); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/popcountti2_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/popcountti2_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/popcountti2_test.c (original) +++ compiler-rt/trunk/test/Unit/popcountti2_test.c Tue Oct 27 12:49:07 2009 @@ -38,7 +38,7 @@ twords at; at.all = a; printf("error in __popcountti2(0x%.16llX%.16llX) = %d, expected %d\n", - at.high, at.low, x, expected); + at.s.high, at.s.low, x, expected); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/subvti3_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/subvti3_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/subvti3_test.c (original) +++ compiler-rt/trunk/test/Unit/subvti3_test.c Tue Oct 27 12:49:07 2009 @@ -39,8 +39,8 @@ expectedt.all = expected; printf("error in test__subvsi3(0x%.16llX%.16llX, 0x%.16llX%.16llX) = " "0x%.16llX%.16llX, expected 0x%.16llX%.16llX\n", - at.high, at.low, bt.high, bt.low, xt.high, xt.low, - expectedt.high, expectedt.low); + at.s.high, at.s.low, bt.s.high, bt.s.low, xt.s.high, xt.s.low, + expectedt.s.high, expectedt.s.low); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/ucmpti2_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/ucmpti2_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/ucmpti2_test.c (original) +++ compiler-rt/trunk/test/Unit/ucmpti2_test.c Tue Oct 27 12:49:07 2009 @@ -33,7 +33,7 @@ bt.all = b; printf("error in __ucmpti2(0x%.16llX%.16llX, 0x%.16llX%.16llX) = %d, " "expected %d\n", - at.high, at.low, bt.high, bt.low, x, expected); + at.s.high, at.s.low, bt.s.high, bt.s.low, x, expected); } return x != expected; } Modified: compiler-rt/trunk/test/Unit/udivmodti4_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/udivmodti4_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/udivmodti4_test.c (original) +++ compiler-rt/trunk/test/Unit/udivmodti4_test.c Tue Oct 27 12:49:07 2009 @@ -42,9 +42,9 @@ printf("error in __udivmodti4: 0x%.16llX%.16llX / 0x%.16llX%.16llX = " "0x%.16llX%.16llX, R = 0x%.16llX%.16llX, expected 0x%.16llX%.16llX, " "0x%.16llX%.16llX\n", - at.high, at.low, bt.high, bt.low, qt.high, qt.low, - rt.high, rt.low, expected_qt.high, expected_qt.low, - expected_rt.high, expected_rt.low); + at.s.high, at.s.low, bt.s.high, bt.s.low, qt.s.high, qt.s.low, + rt.s.high, rt.s.low, expected_qt.s.high, expected_qt.s.low, + expected_rt.s.high, expected_rt.s.low); } return !(q == expected_q && r == expected_r); } Modified: compiler-rt/trunk/test/Unit/udivti3_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/udivti3_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/udivti3_test.c (original) +++ compiler-rt/trunk/test/Unit/udivti3_test.c Tue Oct 27 12:49:07 2009 @@ -35,8 +35,8 @@ expected_qt.all = expected_q; printf("error in __udivti3: 0x%llX%.16llX / 0x%llX%.16llX = " "0x%llX%.16llX, expected 0x%llX%.16llX\n", - at.high, at.low, bt.high, bt.low, qt.high, qt.low, - expected_qt.high, expected_qt.low); + at.s.high, at.s.low, bt.s.high, bt.s.low, qt.s.high, qt.s.low, + expected_qt.s.high, expected_qt.s.low); } return q != expected_q; } Modified: compiler-rt/trunk/test/Unit/umodti3_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/umodti3_test.c?rev=85261&r1=85260&r2=85261&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/umodti3_test.c (original) +++ compiler-rt/trunk/test/Unit/umodti3_test.c Tue Oct 27 12:49:07 2009 @@ -35,8 +35,8 @@ expected_rt.all = expected_r; printf("error in __umodti3: 0x%llX%.16llX %% 0x%llX%.16llX = " "0x%llX%.16llX, expected 0x%llX%.16llX\n", - at.high, at.low, bt.high, bt.low, rt.high, rt.low, - expected_rt.high, expected_rt.low); + at.s.high, at.s.low, bt.s.high, bt.s.low, rt.s.high, rt.s.low, + expected_rt.s.high, expected_rt.s.low); } return r != expected_r; } From daniel at zuster.org Tue Oct 27 12:49:19 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 27 Oct 2009 17:49:19 -0000 Subject: [llvm-commits] [compiler-rt] r85262 - in /compiler-rt/trunk/lib: i386/floatundidf.S ppc/restFP.S ppc/saveFP.S x86_64/floatundidf.S Message-ID: <200910271749.n9RHnJAH006207@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Oct 27 12:49:19 2009 New Revision: 85262 URL: http://llvm.org/viewvc/llvm-project?rev=85262&view=rev Log: Update some .S file headers. Modified: compiler-rt/trunk/lib/i386/floatundidf.S compiler-rt/trunk/lib/ppc/restFP.S compiler-rt/trunk/lib/ppc/saveFP.S compiler-rt/trunk/lib/x86_64/floatundidf.S Modified: compiler-rt/trunk/lib/i386/floatundidf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatundidf.S?rev=85262&r1=85261&r2=85262&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatundidf.S (original) +++ compiler-rt/trunk/lib/i386/floatundidf.S Tue Oct 27 12:49:19 2009 @@ -1,4 +1,4 @@ -//===-- floatundidf.s - Implement __floatundidf for i386 ------------------===// +//===-- floatundidf.S - Implement __floatundidf for i386 ------------------===// // // The LLVM Compiler Infrastructure // Modified: compiler-rt/trunk/lib/ppc/restFP.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ppc/restFP.S?rev=85262&r1=85261&r2=85262&view=diff ============================================================================== --- compiler-rt/trunk/lib/ppc/restFP.S (original) +++ compiler-rt/trunk/lib/ppc/restFP.S Tue Oct 27 12:49:19 2009 @@ -1,4 +1,4 @@ -//===-- restFP.s - Implement restFP ---------------------------------------===// +//===-- restFP.S - Implement restFP ---------------------------------------===// // // The LLVM Compiler Infrastructure // Modified: compiler-rt/trunk/lib/ppc/saveFP.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ppc/saveFP.S?rev=85262&r1=85261&r2=85262&view=diff ============================================================================== --- compiler-rt/trunk/lib/ppc/saveFP.S (original) +++ compiler-rt/trunk/lib/ppc/saveFP.S Tue Oct 27 12:49:19 2009 @@ -1,4 +1,4 @@ -//===-- saveFP.s - Implement saveFP ---------------------------------------===// +//===-- saveFP.S - Implement saveFP ---------------------------------------===// // // The LLVM Compiler Infrastructure // Modified: compiler-rt/trunk/lib/x86_64/floatundidf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/x86_64/floatundidf.S?rev=85262&r1=85261&r2=85262&view=diff ============================================================================== --- compiler-rt/trunk/lib/x86_64/floatundidf.S (original) +++ compiler-rt/trunk/lib/x86_64/floatundidf.S Tue Oct 27 12:49:19 2009 @@ -1,4 +1,4 @@ -//===-- floatundidf.s - Implement __floatundidf for x86_64 ----------------===// +//===-- floatundidf.S - Implement __floatundidf for x86_64 ----------------===// // // The LLVM Compiler Infrastructure // From daniel at zuster.org Tue Oct 27 12:49:51 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 27 Oct 2009 17:49:51 -0000 Subject: [llvm-commits] [compiler-rt] r85263 - in /compiler-rt/trunk/lib: ./ arm/ i386/ ppc/ x86_64/ Message-ID: <200910271749.n9RHnrbi006293@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Oct 27 12:49:50 2009 New Revision: 85263 URL: http://llvm.org/viewvc/llvm-project?rev=85263&view=rev Log: Add assembly.h for use in .S files. Added: compiler-rt/trunk/lib/assembly.h Modified: compiler-rt/trunk/lib/arm/Makefile.mk compiler-rt/trunk/lib/arm/adddf3vfp.S compiler-rt/trunk/lib/arm/addsf3vfp.S compiler-rt/trunk/lib/arm/bswapdi2.S compiler-rt/trunk/lib/arm/bswapsi2.S compiler-rt/trunk/lib/arm/divdf3vfp.S compiler-rt/trunk/lib/arm/divsf3vfp.S compiler-rt/trunk/lib/arm/eqdf2vfp.S compiler-rt/trunk/lib/arm/eqsf2vfp.S compiler-rt/trunk/lib/arm/extendsfdf2vfp.S compiler-rt/trunk/lib/arm/fixdfsivfp.S compiler-rt/trunk/lib/arm/fixsfsivfp.S compiler-rt/trunk/lib/arm/fixunsdfsivfp.S compiler-rt/trunk/lib/arm/fixunssfsivfp.S compiler-rt/trunk/lib/arm/floatsidfvfp.S compiler-rt/trunk/lib/arm/floatsisfvfp.S compiler-rt/trunk/lib/arm/floatunssidfvfp.S compiler-rt/trunk/lib/arm/floatunssisfvfp.S compiler-rt/trunk/lib/arm/gedf2vfp.S compiler-rt/trunk/lib/arm/gesf2vfp.S compiler-rt/trunk/lib/arm/gtdf2vfp.S compiler-rt/trunk/lib/arm/gtsf2vfp.S compiler-rt/trunk/lib/arm/ledf2vfp.S compiler-rt/trunk/lib/arm/lesf2vfp.S compiler-rt/trunk/lib/arm/ltdf2vfp.S compiler-rt/trunk/lib/arm/ltsf2vfp.S compiler-rt/trunk/lib/arm/muldf3vfp.S compiler-rt/trunk/lib/arm/mulsf3vfp.S compiler-rt/trunk/lib/arm/nedf2vfp.S compiler-rt/trunk/lib/arm/negdf2vfp.S compiler-rt/trunk/lib/arm/negsf2vfp.S compiler-rt/trunk/lib/arm/nesf2vfp.S compiler-rt/trunk/lib/arm/subdf3vfp.S compiler-rt/trunk/lib/arm/subsf3vfp.S compiler-rt/trunk/lib/arm/switch.S compiler-rt/trunk/lib/arm/truncdfsf2vfp.S compiler-rt/trunk/lib/arm/unorddf2vfp.S compiler-rt/trunk/lib/arm/unordsf2vfp.S compiler-rt/trunk/lib/i386/Makefile.mk compiler-rt/trunk/lib/i386/ashldi3.S compiler-rt/trunk/lib/i386/ashrdi3.S compiler-rt/trunk/lib/i386/divdi3.S compiler-rt/trunk/lib/i386/floatdidf.S compiler-rt/trunk/lib/i386/floatdisf.S compiler-rt/trunk/lib/i386/floatdixf.S compiler-rt/trunk/lib/i386/floatundidf.S compiler-rt/trunk/lib/i386/floatundisf.S compiler-rt/trunk/lib/i386/floatundixf.S compiler-rt/trunk/lib/i386/lshrdi3.S compiler-rt/trunk/lib/i386/moddi3.S compiler-rt/trunk/lib/i386/muldi3.S compiler-rt/trunk/lib/i386/udivdi3.S compiler-rt/trunk/lib/i386/umoddi3.S compiler-rt/trunk/lib/ppc/Makefile.mk compiler-rt/trunk/lib/ppc/restFP.S compiler-rt/trunk/lib/ppc/saveFP.S compiler-rt/trunk/lib/x86_64/Makefile.mk compiler-rt/trunk/lib/x86_64/floatundidf.S compiler-rt/trunk/lib/x86_64/floatundisf.S compiler-rt/trunk/lib/x86_64/floatundixf.S Modified: compiler-rt/trunk/lib/arm/Makefile.mk URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/Makefile.mk?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/Makefile.mk (original) +++ compiler-rt/trunk/lib/arm/Makefile.mk Tue Oct 27 12:49:50 2009 @@ -17,6 +17,6 @@ Target := Optimized # FIXME: use automatic dependencies? -Dependencies := $(wildcard $(Dir)/*.h) +Dependencies := $(wildcard lib/*.h $(Dir)/*.h) include make/subdir.mk Modified: compiler-rt/trunk/lib/arm/adddf3vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/adddf3vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/adddf3vfp.S (original) +++ compiler-rt/trunk/lib/arm/adddf3vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // double __adddf3vfp(double a, double b) { return a + b; } Modified: compiler-rt/trunk/lib/arm/addsf3vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/addsf3vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/addsf3vfp.S (original) +++ compiler-rt/trunk/lib/arm/addsf3vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern float __addsf3vfp(float a, float b); Modified: compiler-rt/trunk/lib/arm/bswapdi2.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/bswapdi2.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/bswapdi2.S (original) +++ compiler-rt/trunk/lib/arm/bswapdi2.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern uint64_t __bswapdi2(uint64_t); Modified: compiler-rt/trunk/lib/arm/bswapsi2.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/bswapsi2.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/bswapsi2.S (original) +++ compiler-rt/trunk/lib/arm/bswapsi2.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern uint32_t __bswapsi2(uint32_t); Modified: compiler-rt/trunk/lib/arm/divdf3vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/divdf3vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/divdf3vfp.S (original) +++ compiler-rt/trunk/lib/arm/divdf3vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern double __divdf3vfp(double a, double b); Modified: compiler-rt/trunk/lib/arm/divsf3vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/divsf3vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/divsf3vfp.S (original) +++ compiler-rt/trunk/lib/arm/divsf3vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern float __divsf3vfp(float a, float b); Modified: compiler-rt/trunk/lib/arm/eqdf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/eqdf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/eqdf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/eqdf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern int __eqdf2vfp(double a, double b); Modified: compiler-rt/trunk/lib/arm/eqsf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/eqsf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/eqsf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/eqsf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern int __eqsf2vfp(float a, float b); Modified: compiler-rt/trunk/lib/arm/extendsfdf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/extendsfdf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/extendsfdf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/extendsfdf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern double __extendsfdf2vfp(float a); Modified: compiler-rt/trunk/lib/arm/fixdfsivfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/fixdfsivfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/fixdfsivfp.S (original) +++ compiler-rt/trunk/lib/arm/fixdfsivfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern int __fixdfsivfp(double a); Modified: compiler-rt/trunk/lib/arm/fixsfsivfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/fixsfsivfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/fixsfsivfp.S (original) +++ compiler-rt/trunk/lib/arm/fixsfsivfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern int __fixsfsivfp(float a); Modified: compiler-rt/trunk/lib/arm/fixunsdfsivfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/fixunsdfsivfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/fixunsdfsivfp.S (original) +++ compiler-rt/trunk/lib/arm/fixunsdfsivfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern unsigned int __fixunsdfsivfp(double a); Modified: compiler-rt/trunk/lib/arm/fixunssfsivfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/fixunssfsivfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/fixunssfsivfp.S (original) +++ compiler-rt/trunk/lib/arm/fixunssfsivfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern unsigned int __fixunssfsivfp(float a); Modified: compiler-rt/trunk/lib/arm/floatsidfvfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/floatsidfvfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/floatsidfvfp.S (original) +++ compiler-rt/trunk/lib/arm/floatsidfvfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern double __floatsidfvfp(int a); Modified: compiler-rt/trunk/lib/arm/floatsisfvfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/floatsisfvfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/floatsisfvfp.S (original) +++ compiler-rt/trunk/lib/arm/floatsisfvfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern float __floatsisfvfp(int a); Modified: compiler-rt/trunk/lib/arm/floatunssidfvfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/floatunssidfvfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/floatunssidfvfp.S (original) +++ compiler-rt/trunk/lib/arm/floatunssidfvfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern double __floatunssidfvfp(unsigned int a); Modified: compiler-rt/trunk/lib/arm/floatunssisfvfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/floatunssisfvfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/floatunssisfvfp.S (original) +++ compiler-rt/trunk/lib/arm/floatunssisfvfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern float __floatunssisfvfp(unsigned int a); Modified: compiler-rt/trunk/lib/arm/gedf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/gedf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/gedf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/gedf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern int __gedf2vfp(double a, double b); Modified: compiler-rt/trunk/lib/arm/gesf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/gesf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/gesf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/gesf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern int __gesf2vfp(float a, float b); Modified: compiler-rt/trunk/lib/arm/gtdf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/gtdf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/gtdf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/gtdf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern double __gtdf2vfp(double a, double b); Modified: compiler-rt/trunk/lib/arm/gtsf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/gtsf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/gtsf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/gtsf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern int __gtsf2vfp(float a, float b); Modified: compiler-rt/trunk/lib/arm/ledf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/ledf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/ledf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/ledf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern double __ledf2vfp(double a, double b); Modified: compiler-rt/trunk/lib/arm/lesf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/lesf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/lesf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/lesf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern int __lesf2vfp(float a, float b); Modified: compiler-rt/trunk/lib/arm/ltdf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/ltdf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/ltdf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/ltdf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern double __ltdf2vfp(double a, double b); Modified: compiler-rt/trunk/lib/arm/ltsf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/ltsf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/ltsf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/ltsf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern int __ltsf2vfp(float a, float b); Modified: compiler-rt/trunk/lib/arm/muldf3vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/muldf3vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/muldf3vfp.S (original) +++ compiler-rt/trunk/lib/arm/muldf3vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern double __muldf3vfp(double a, double b); Modified: compiler-rt/trunk/lib/arm/mulsf3vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/mulsf3vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/mulsf3vfp.S (original) +++ compiler-rt/trunk/lib/arm/mulsf3vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern float __mulsf3vfp(float a, float b); Modified: compiler-rt/trunk/lib/arm/nedf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/nedf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/nedf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/nedf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern double __nedf2vfp(double a, double b); Modified: compiler-rt/trunk/lib/arm/negdf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/negdf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/negdf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/negdf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern double __negdf2vfp(double a, double b); Modified: compiler-rt/trunk/lib/arm/negsf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/negsf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/negsf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/negsf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern float __negsf2vfp(float a); Modified: compiler-rt/trunk/lib/arm/nesf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/nesf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/nesf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/nesf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern int __nesf2vfp(float a, float b); Modified: compiler-rt/trunk/lib/arm/subdf3vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/subdf3vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/subdf3vfp.S (original) +++ compiler-rt/trunk/lib/arm/subdf3vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern double __subdf3vfp(double a, double b); Modified: compiler-rt/trunk/lib/arm/subsf3vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/subsf3vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/subsf3vfp.S (original) +++ compiler-rt/trunk/lib/arm/subsf3vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern float __subsf3vfp(float a, float b); Modified: compiler-rt/trunk/lib/arm/switch.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/switch.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/switch.S (original) +++ compiler-rt/trunk/lib/arm/switch.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" + // // When compiling switch statements in thumb mode, the compiler // can use these __switch* helper functions The compiler emits a blx to Modified: compiler-rt/trunk/lib/arm/truncdfsf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/truncdfsf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/truncdfsf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/truncdfsf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern float __truncdfsf2vfp(double a); Modified: compiler-rt/trunk/lib/arm/unorddf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/unorddf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/unorddf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/unorddf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern int __unorddf2vfp(double a, double b); Modified: compiler-rt/trunk/lib/arm/unordsf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/unordsf2vfp.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/unordsf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/unordsf2vfp.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // extern int __unordsf2vfp(float a, float b); Added: compiler-rt/trunk/lib/assembly.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/assembly.h?rev=85263&view=auto ============================================================================== --- compiler-rt/trunk/lib/assembly.h (added) +++ compiler-rt/trunk/lib/assembly.h Tue Oct 27 12:49:50 2009 @@ -0,0 +1,42 @@ +/* ===-- assembly.h - compiler-rt assembler support macros -----------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file defines macros for use in compiler-rt assembler source. + * This file is not part of the interface of this library. + * + * ===----------------------------------------------------------------------=== + */ + +#ifndef COMPILERRT_ASSEMBLY_H +#define COMPILERRT_ASSEMBLY_H + +// Define SYMBOL_NAME to add the appropriate symbol prefix; we can't use +// USER_LABEL_PREFIX directly because of cpp brokenness. +#if defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__) + +#define SYMBOL_NAME(name) name +#define SEPARATOR @ + +#else + +#define SYMBOL_NAME(name) _##name +#define SEPARATOR ; + +#endif + +#define DEFINE_COMPILERRT_FUNCTION(name) \ + .globl SYMBOL_NAME(name) SEPARATOR \ + SYMBOL_NAME(name): + +#define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \ + .globl SYMBOL_NAME(name) SEPARATOR \ + .private_extern SYMBOL_NAME(name) SEPARATOR \ + SYMBOL_NAME(name): + +#endif /* COMPILERRT_ASSEMBLY_H */ Modified: compiler-rt/trunk/lib/i386/Makefile.mk URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/Makefile.mk?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/Makefile.mk (original) +++ compiler-rt/trunk/lib/i386/Makefile.mk Tue Oct 27 12:49:50 2009 @@ -17,6 +17,6 @@ Target := Optimized # FIXME: use automatic dependencies? -Dependencies := $(wildcard $(Dir)/*.h) +Dependencies := $(wildcard lib/*.h $(Dir)/*.h) include make/subdir.mk Modified: compiler-rt/trunk/lib/i386/ashldi3.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/ashldi3.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/ashldi3.S (original) +++ compiler-rt/trunk/lib/i386/ashldi3.S Tue Oct 27 12:49:50 2009 @@ -1,6 +1,8 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. +#include "../assembly.h" + // di_int __ashldi3(di_int input, int count); // This routine has some extra memory traffic, loading the 64-bit input via two Modified: compiler-rt/trunk/lib/i386/ashrdi3.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/ashrdi3.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/ashrdi3.S (original) +++ compiler-rt/trunk/lib/i386/ashrdi3.S Tue Oct 27 12:49:50 2009 @@ -1,6 +1,8 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. +#include "../assembly.h" + // di_int __ashrdi3(di_int input, int count); #ifdef __i386__ Modified: compiler-rt/trunk/lib/i386/divdi3.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/divdi3.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/divdi3.S (original) +++ compiler-rt/trunk/lib/i386/divdi3.S Tue Oct 27 12:49:50 2009 @@ -1,6 +1,8 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. +#include "../assembly.h" + // di_int __divdi3(di_int a, di_int b); // result = a / b. Modified: compiler-rt/trunk/lib/i386/floatdidf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatdidf.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatdidf.S (original) +++ compiler-rt/trunk/lib/i386/floatdidf.S Tue Oct 27 12:49:50 2009 @@ -1,6 +1,8 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. +#include "../assembly.h" + // double __floatundidf(du_int a); #ifdef __i386__ Modified: compiler-rt/trunk/lib/i386/floatdisf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatdisf.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatdisf.S (original) +++ compiler-rt/trunk/lib/i386/floatdisf.S Tue Oct 27 12:49:50 2009 @@ -1,6 +1,8 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. +#include "../assembly.h" + // float __floatdisf(di_int a); // This routine has some extra memory traffic, loading the 64-bit input via two Modified: compiler-rt/trunk/lib/i386/floatdixf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatdixf.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatdixf.S (original) +++ compiler-rt/trunk/lib/i386/floatdixf.S Tue Oct 27 12:49:50 2009 @@ -1,6 +1,8 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. +#include "../assembly.h" + // float __floatdixf(di_int a); #ifdef __i386__ Modified: compiler-rt/trunk/lib/i386/floatundidf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatundidf.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatundidf.S (original) +++ compiler-rt/trunk/lib/i386/floatundidf.S Tue Oct 27 12:49:50 2009 @@ -11,6 +11,8 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" + // double __floatundidf(du_int a); #ifdef __i386__ Modified: compiler-rt/trunk/lib/i386/floatundisf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatundisf.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatundisf.S (original) +++ compiler-rt/trunk/lib/i386/floatundisf.S Tue Oct 27 12:49:50 2009 @@ -1,6 +1,8 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. +#include "../assembly.h" + // float __floatundisf(du_int a); // Note that there is a hardware instruction, fildll, that does most of what Modified: compiler-rt/trunk/lib/i386/floatundixf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatundixf.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatundixf.S (original) +++ compiler-rt/trunk/lib/i386/floatundixf.S Tue Oct 27 12:49:50 2009 @@ -1,6 +1,8 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. +#include "../assembly.h" + // long double __floatundixf(du_int a);16 #ifdef __i386__ Modified: compiler-rt/trunk/lib/i386/lshrdi3.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/lshrdi3.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/lshrdi3.S (original) +++ compiler-rt/trunk/lib/i386/lshrdi3.S Tue Oct 27 12:49:50 2009 @@ -1,6 +1,8 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. +#include "../assembly.h" + // di_int __lshrdi3(di_int input, int count); // This routine has some extra memory traffic, loading the 64-bit input via two Modified: compiler-rt/trunk/lib/i386/moddi3.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/moddi3.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/moddi3.S (original) +++ compiler-rt/trunk/lib/i386/moddi3.S Tue Oct 27 12:49:50 2009 @@ -1,6 +1,8 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. +#include "../assembly.h" + // di_int __moddi3(di_int a, di_int b); // result = remainder of a / b. Modified: compiler-rt/trunk/lib/i386/muldi3.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/muldi3.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/muldi3.S (original) +++ compiler-rt/trunk/lib/i386/muldi3.S Tue Oct 27 12:49:50 2009 @@ -1,6 +1,8 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. +#include "../assembly.h" + // di_int __muldi3(di_int a, di_int b); #ifdef __i386__ Modified: compiler-rt/trunk/lib/i386/udivdi3.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/udivdi3.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/udivdi3.S (original) +++ compiler-rt/trunk/lib/i386/udivdi3.S Tue Oct 27 12:49:50 2009 @@ -1,6 +1,8 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. +#include "../assembly.h" + // du_int __udivdi3(du_int a, du_int b); // result = a / b. Modified: compiler-rt/trunk/lib/i386/umoddi3.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/umoddi3.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/umoddi3.S (original) +++ compiler-rt/trunk/lib/i386/umoddi3.S Tue Oct 27 12:49:50 2009 @@ -1,6 +1,8 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. +#include "../assembly.h" + // du_int __umoddi3(du_int a, du_int b); // result = remainder of a / b. Modified: compiler-rt/trunk/lib/ppc/Makefile.mk URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ppc/Makefile.mk?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/ppc/Makefile.mk (original) +++ compiler-rt/trunk/lib/ppc/Makefile.mk Tue Oct 27 12:49:50 2009 @@ -17,6 +17,6 @@ Target := Optimized # FIXME: use automatic dependencies? -Dependencies := $(wildcard $(Dir)/*.h) +Dependencies := $(wildcard lib/*.h $(Dir)/*.h) include make/subdir.mk Modified: compiler-rt/trunk/lib/ppc/restFP.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ppc/restFP.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/ppc/restFP.S (original) +++ compiler-rt/trunk/lib/ppc/restFP.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // Helper function used by compiler to restore ppc floating point registers at Modified: compiler-rt/trunk/lib/ppc/saveFP.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ppc/saveFP.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/ppc/saveFP.S (original) +++ compiler-rt/trunk/lib/ppc/saveFP.S Tue Oct 27 12:49:50 2009 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" // // Helper function used by compiler to save ppc floating point registers in Modified: compiler-rt/trunk/lib/x86_64/Makefile.mk URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/x86_64/Makefile.mk?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/x86_64/Makefile.mk (original) +++ compiler-rt/trunk/lib/x86_64/Makefile.mk Tue Oct 27 12:49:50 2009 @@ -17,6 +17,6 @@ Target := Optimized # FIXME: use automatic dependencies? -Dependencies := $(wildcard $(Dir)/*.h) +Dependencies := $(wildcard lib/*.h $(Dir)/*.h) include make/subdir.mk Modified: compiler-rt/trunk/lib/x86_64/floatundidf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/x86_64/floatundidf.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/x86_64/floatundidf.S (original) +++ compiler-rt/trunk/lib/x86_64/floatundidf.S Tue Oct 27 12:49:50 2009 @@ -11,6 +11,8 @@ // //===----------------------------------------------------------------------===// +#include "../assembly.h" + // double __floatundidf(du_int a); #ifdef __x86_64__ Modified: compiler-rt/trunk/lib/x86_64/floatundisf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/x86_64/floatundisf.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/x86_64/floatundisf.S (original) +++ compiler-rt/trunk/lib/x86_64/floatundisf.S Tue Oct 27 12:49:50 2009 @@ -1,6 +1,8 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. +#include "../assembly.h" + // float __floatundisf(du_int a); #ifdef __x86_64__ Modified: compiler-rt/trunk/lib/x86_64/floatundixf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/x86_64/floatundixf.S?rev=85263&r1=85262&r2=85263&view=diff ============================================================================== --- compiler-rt/trunk/lib/x86_64/floatundixf.S (original) +++ compiler-rt/trunk/lib/x86_64/floatundixf.S Tue Oct 27 12:49:50 2009 @@ -1,6 +1,8 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. +#include "../assembly.h" + // long double __floatundixf(du_int a); #ifdef __x86_64__ From daniel at zuster.org Tue Oct 27 12:50:22 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 27 Oct 2009 17:50:22 -0000 Subject: [llvm-commits] [compiler-rt] r85264 - in /compiler-rt/trunk/lib: arm/ i386/ ppc/ x86_64/ Message-ID: <200910271750.n9RHoOI1006379@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Oct 27 12:50:21 2009 New Revision: 85264 URL: http://llvm.org/viewvc/llvm-project?rev=85264&view=rev Log: Switch to using DEFINE_COMPILERRT_[PRIVATE_]FUNCTION to define function symbols inside .S files. Modified: compiler-rt/trunk/lib/arm/adddf3vfp.S compiler-rt/trunk/lib/arm/addsf3vfp.S compiler-rt/trunk/lib/arm/bswapdi2.S compiler-rt/trunk/lib/arm/bswapsi2.S compiler-rt/trunk/lib/arm/divdf3vfp.S compiler-rt/trunk/lib/arm/divsf3vfp.S compiler-rt/trunk/lib/arm/eqdf2vfp.S compiler-rt/trunk/lib/arm/eqsf2vfp.S compiler-rt/trunk/lib/arm/extendsfdf2vfp.S compiler-rt/trunk/lib/arm/fixdfsivfp.S compiler-rt/trunk/lib/arm/fixsfsivfp.S compiler-rt/trunk/lib/arm/fixunsdfsivfp.S compiler-rt/trunk/lib/arm/fixunssfsivfp.S compiler-rt/trunk/lib/arm/floatsidfvfp.S compiler-rt/trunk/lib/arm/floatsisfvfp.S compiler-rt/trunk/lib/arm/floatunssidfvfp.S compiler-rt/trunk/lib/arm/floatunssisfvfp.S compiler-rt/trunk/lib/arm/gedf2vfp.S compiler-rt/trunk/lib/arm/gesf2vfp.S compiler-rt/trunk/lib/arm/gtdf2vfp.S compiler-rt/trunk/lib/arm/gtsf2vfp.S compiler-rt/trunk/lib/arm/ledf2vfp.S compiler-rt/trunk/lib/arm/lesf2vfp.S compiler-rt/trunk/lib/arm/ltdf2vfp.S compiler-rt/trunk/lib/arm/ltsf2vfp.S compiler-rt/trunk/lib/arm/muldf3vfp.S compiler-rt/trunk/lib/arm/mulsf3vfp.S compiler-rt/trunk/lib/arm/nedf2vfp.S compiler-rt/trunk/lib/arm/negdf2vfp.S compiler-rt/trunk/lib/arm/negsf2vfp.S compiler-rt/trunk/lib/arm/nesf2vfp.S compiler-rt/trunk/lib/arm/subdf3vfp.S compiler-rt/trunk/lib/arm/subsf3vfp.S compiler-rt/trunk/lib/arm/switch.S compiler-rt/trunk/lib/arm/truncdfsf2vfp.S compiler-rt/trunk/lib/arm/unorddf2vfp.S compiler-rt/trunk/lib/arm/unordsf2vfp.S compiler-rt/trunk/lib/i386/ashldi3.S compiler-rt/trunk/lib/i386/ashrdi3.S compiler-rt/trunk/lib/i386/divdi3.S compiler-rt/trunk/lib/i386/floatdidf.S compiler-rt/trunk/lib/i386/floatdisf.S compiler-rt/trunk/lib/i386/floatdixf.S compiler-rt/trunk/lib/i386/floatundidf.S compiler-rt/trunk/lib/i386/floatundisf.S compiler-rt/trunk/lib/i386/floatundixf.S compiler-rt/trunk/lib/i386/lshrdi3.S compiler-rt/trunk/lib/i386/moddi3.S compiler-rt/trunk/lib/i386/muldi3.S compiler-rt/trunk/lib/i386/udivdi3.S compiler-rt/trunk/lib/i386/umoddi3.S compiler-rt/trunk/lib/ppc/restFP.S compiler-rt/trunk/lib/ppc/saveFP.S compiler-rt/trunk/lib/x86_64/floatundidf.S compiler-rt/trunk/lib/x86_64/floatundisf.S compiler-rt/trunk/lib/x86_64/floatundixf.S Modified: compiler-rt/trunk/lib/arm/adddf3vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/adddf3vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/adddf3vfp.S (original) +++ compiler-rt/trunk/lib/arm/adddf3vfp.S Tue Oct 27 12:50:21 2009 @@ -15,8 +15,7 @@ // Adds two double precision floating point numbers using the Darwin // calling convention where double arguments are passsed in GPR pairs // - .globl ___adddf3vfp -___adddf3vfp: +DEFINE_COMPILERRT_FUNCTION(__adddf3vfp) fmdrr d6, r0, r1 // move first param from r0/r1 pair into d6 fmdrr d7, r2, r3 // move second param from r2/r3 pair into d7 faddd d6, d6, d7 Modified: compiler-rt/trunk/lib/arm/addsf3vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/addsf3vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/addsf3vfp.S (original) +++ compiler-rt/trunk/lib/arm/addsf3vfp.S Tue Oct 27 12:50:21 2009 @@ -15,8 +15,7 @@ // Adds two single precision floating point numbers using the Darwin // calling convention where single arguments are passsed in GPRs // - .globl ___addsf3vfp -___addsf3vfp: +DEFINE_COMPILERRT_FUNCTION(__addsf3vfp) fmsr s14, r0 // move first param from r0 into float register fmsr s15, r1 // move second param from r1 into float register fadds s14, s14, s15 Modified: compiler-rt/trunk/lib/arm/bswapdi2.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/bswapdi2.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/bswapdi2.S (original) +++ compiler-rt/trunk/lib/arm/bswapdi2.S Tue Oct 27 12:50:21 2009 @@ -14,8 +14,7 @@ // // Reverse all the bytes in a 64-bit integer. // - .globl ___bswapdi2 -___bswapdi2: +DEFINE_COMPILERRT_FUNCTION(__bswapdi2) rev r2, r1 // reverse bytes in high 32-bits into temp2 rev r3, r0 // reverse bytes in low 32-bit into temp3 mov r0, r2 // set low 32-bits of result to temp2 Modified: compiler-rt/trunk/lib/arm/bswapsi2.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/bswapsi2.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/bswapsi2.S (original) +++ compiler-rt/trunk/lib/arm/bswapsi2.S Tue Oct 27 12:50:21 2009 @@ -14,7 +14,6 @@ // // Reverse all the bytes in a 32-bit integer. // - .globl ___bswapsi2 -___bswapsi2: +DEFINE_COMPILERRT_FUNCTION(__bswapsi2) rev r0, r0 // reverse bytes in parameter and put into result register bx lr Modified: compiler-rt/trunk/lib/arm/divdf3vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/divdf3vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/divdf3vfp.S (original) +++ compiler-rt/trunk/lib/arm/divdf3vfp.S Tue Oct 27 12:50:21 2009 @@ -15,8 +15,7 @@ // Divides two double precision floating point numbers using the Darwin // calling convention where double arguments are passsed in GPR pairs // - .globl ___divdf3vfp -___divdf3vfp: +DEFINE_COMPILERRT_FUNCTION(__divdf3vfp) fmdrr d6, r0, r1 // move first param from r0/r1 pair into d6 fmdrr d7, r2, r3 // move second param from r2/r3 pair into d7 fdivd d5, d6, d7 Modified: compiler-rt/trunk/lib/arm/divsf3vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/divsf3vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/divsf3vfp.S (original) +++ compiler-rt/trunk/lib/arm/divsf3vfp.S Tue Oct 27 12:50:21 2009 @@ -15,8 +15,7 @@ // Divides two single precision floating point numbers using the Darwin // calling convention where single arguments are passsed like 32-bit ints. // - .globl ___divsf3vfp -___divsf3vfp: +DEFINE_COMPILERRT_FUNCTION(__divsf3vfp) fmsr s14, r0 // move first param from r0 into float register fmsr s15, r1 // move second param from r1 into float register fdivs s13, s14, s15 Modified: compiler-rt/trunk/lib/arm/eqdf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/eqdf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/eqdf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/eqdf2vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where double precision arguments are passsed // like in GPR pairs. // - .globl ___eqdf2vfp -___eqdf2vfp: +DEFINE_COMPILERRT_FUNCTION(__eqdf2vfp) fmdrr d6, r0, r1 // load r0/r1 pair in double register fmdrr d7, r2, r3 // load r2/r3 pair in double register fcmpd d6, d7 Modified: compiler-rt/trunk/lib/arm/eqsf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/eqsf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/eqsf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/eqsf2vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where single precision arguments are passsed // like 32-bit ints // - .globl ___eqsf2vfp -___eqsf2vfp: +DEFINE_COMPILERRT_FUNCTION(__eqsf2vfp) fmsr s14, r0 // move from GPR 0 to float register fmsr s15, r1 // move from GPR 1 to float register fcmps s14, s15 Modified: compiler-rt/trunk/lib/arm/extendsfdf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/extendsfdf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/extendsfdf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/extendsfdf2vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where a single precision parameter is // passed in a GPR and a double precision result is returned in R0/R1 pair. // - .globl ___extendsfdf2vfp -___extendsfdf2vfp: +DEFINE_COMPILERRT_FUNCTION(__extendsfdf2vfp) fmsr s15, r0 // load float register from R0 fcvtds d7, s15 // convert single to double fmrrd r0, r1, d7 // return result in r0/r1 pair Modified: compiler-rt/trunk/lib/arm/fixdfsivfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/fixdfsivfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/fixdfsivfp.S (original) +++ compiler-rt/trunk/lib/arm/fixdfsivfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where a double precision parameter is // passed in GPR register pair. // - .globl ___fixdfsivfp -___fixdfsivfp: +DEFINE_COMPILERRT_FUNCTION(__fixdfsivfp) fmdrr d7, r0, r1 // load double register from R0/R1 ftosizd s15, d7 // convert double to 32-bit int into s15 fmrs r0, s15 // move s15 to result register Modified: compiler-rt/trunk/lib/arm/fixsfsivfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/fixsfsivfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/fixsfsivfp.S (original) +++ compiler-rt/trunk/lib/arm/fixsfsivfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where a single precision parameter is // passed in a GPR.. // - .globl ___fixsfsivfp -___fixsfsivfp: +DEFINE_COMPILERRT_FUNCTION(__fixsfsivfp) fmsr s15, r0 // load float register from R0 ftosizs s15, s15 // convert single to 32-bit int into s15 fmrs r0, s15 // move s15 to result register Modified: compiler-rt/trunk/lib/arm/fixunsdfsivfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/fixunsdfsivfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/fixunsdfsivfp.S (original) +++ compiler-rt/trunk/lib/arm/fixunsdfsivfp.S Tue Oct 27 12:50:21 2009 @@ -17,8 +17,7 @@ // Uses Darwin calling convention where a double precision parameter is // passed in GPR register pair. // - .globl ___fixunsdfsivfp -___fixunsdfsivfp: +DEFINE_COMPILERRT_FUNCTION(__fixunsdfsivfp) fmdrr d7, r0, r1 // load double register from R0/R1 ftouizd s15, d7 // convert double to 32-bit int into s15 fmrs r0, s15 // move s15 to result register Modified: compiler-rt/trunk/lib/arm/fixunssfsivfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/fixunssfsivfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/fixunssfsivfp.S (original) +++ compiler-rt/trunk/lib/arm/fixunssfsivfp.S Tue Oct 27 12:50:21 2009 @@ -17,8 +17,7 @@ // Uses Darwin calling convention where a single precision parameter is // passed in a GPR.. // - .globl ___fixunssfsivfp -___fixunssfsivfp: +DEFINE_COMPILERRT_FUNCTION(__fixunssfsivfp) fmsr s15, r0 // load float register from R0 ftouizs s15, s15 // convert single to 32-bit unsigned into s15 fmrs r0, s15 // move s15 to result register Modified: compiler-rt/trunk/lib/arm/floatsidfvfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/floatsidfvfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/floatsidfvfp.S (original) +++ compiler-rt/trunk/lib/arm/floatsidfvfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where a double precision result is // return in GPR register pair. // - .globl ___floatsidfvfp -___floatsidfvfp: +DEFINE_COMPILERRT_FUNCTION(__floatsidfvfp) fmsr s15, r0 // move int to float register s15 fsitod d7, s15 // convert 32-bit int in s15 to double in d7 fmrrd r0, r1, d7 // move d7 to result register pair r0/r1 Modified: compiler-rt/trunk/lib/arm/floatsisfvfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/floatsisfvfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/floatsisfvfp.S (original) +++ compiler-rt/trunk/lib/arm/floatsisfvfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where a single precision result is // return in a GPR.. // - .globl ___floatsisfvfp -___floatsisfvfp: +DEFINE_COMPILERRT_FUNCTION(__floatsisfvfp) fmsr s15, r0 // move int to float register s15 fsitos s15, s15 // convert 32-bit int in s15 to float in s15 fmrs r0, s15 // move s15 to result register Modified: compiler-rt/trunk/lib/arm/floatunssidfvfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/floatunssidfvfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/floatunssidfvfp.S (original) +++ compiler-rt/trunk/lib/arm/floatunssidfvfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where a double precision result is // return in GPR register pair. // - .globl ___floatunssidfvfp -___floatunssidfvfp: +DEFINE_COMPILERRT_FUNCTION(__floatunssidfvfp) fmsr s15, r0 // move int to float register s15 fuitod d7, s15 // convert 32-bit int in s15 to double in d7 fmrrd r0, r1, d7 // move d7 to result register pair r0/r1 Modified: compiler-rt/trunk/lib/arm/floatunssisfvfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/floatunssisfvfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/floatunssisfvfp.S (original) +++ compiler-rt/trunk/lib/arm/floatunssisfvfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where a single precision result is // return in a GPR.. // - .globl ___floatunssisfvfp -___floatunssisfvfp: +DEFINE_COMPILERRT_FUNCTION(__floatunssisfvfp) fmsr s15, r0 // move int to float register s15 fuitos s15, s15 // convert 32-bit int in s15 to float in s15 fmrs r0, s15 // move s15 to result register Modified: compiler-rt/trunk/lib/arm/gedf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/gedf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/gedf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/gedf2vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where double precision arguments are passsed // like in GPR pairs. // - .globl ___gedf2vfp -___gedf2vfp: +DEFINE_COMPILERRT_FUNCTION(__gedf2vfp) fmdrr d6, r0, r1 // load r0/r1 pair in double register fmdrr d7, r2, r3 // load r2/r3 pair in double register fcmpd d6, d7 Modified: compiler-rt/trunk/lib/arm/gesf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/gesf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/gesf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/gesf2vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where single precision arguments are passsed // like 32-bit ints // - .globl ___gesf2vfp -___gesf2vfp: +DEFINE_COMPILERRT_FUNCTION(__gesf2vfp) fmsr s14, r0 // move from GPR 0 to float register fmsr s15, r1 // move from GPR 1 to float register fcmps s14, s15 Modified: compiler-rt/trunk/lib/arm/gtdf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/gtdf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/gtdf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/gtdf2vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where double precision arguments are passsed // like in GPR pairs. // - .globl ___gtdf2vfp -___gtdf2vfp: +DEFINE_COMPILERRT_FUNCTION(__gtdf2vfp) fmdrr d6, r0, r1 // load r0/r1 pair in double register fmdrr d7, r2, r3 // load r2/r3 pair in double register fcmpd d6, d7 Modified: compiler-rt/trunk/lib/arm/gtsf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/gtsf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/gtsf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/gtsf2vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where single precision arguments are passsed // like 32-bit ints // - .globl ___gtsf2vfp -___gtsf2vfp: +DEFINE_COMPILERRT_FUNCTION(__gtsf2vfp) fmsr s14, r0 // move from GPR 0 to float register fmsr s15, r1 // move from GPR 1 to float register fcmps s14, s15 Modified: compiler-rt/trunk/lib/arm/ledf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/ledf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/ledf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/ledf2vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where double precision arguments are passsed // like in GPR pairs. // - .globl ___ledf2vfp -___ledf2vfp: +DEFINE_COMPILERRT_FUNCTION(__ledf2vfp) fmdrr d6, r0, r1 // load r0/r1 pair in double register fmdrr d7, r2, r3 // load r2/r3 pair in double register fcmpd d6, d7 Modified: compiler-rt/trunk/lib/arm/lesf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/lesf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/lesf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/lesf2vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where single precision arguments are passsed // like 32-bit ints // - .globl ___lesf2vfp -___lesf2vfp: +DEFINE_COMPILERRT_FUNCTION(__lesf2vfp) fmsr s14, r0 // move from GPR 0 to float register fmsr s15, r1 // move from GPR 1 to float register fcmps s14, s15 Modified: compiler-rt/trunk/lib/arm/ltdf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/ltdf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/ltdf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/ltdf2vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where double precision arguments are passsed // like in GPR pairs. // - .globl ___ltdf2vfp -___ltdf2vfp: +DEFINE_COMPILERRT_FUNCTION(__ltdf2vfp) fmdrr d6, r0, r1 // load r0/r1 pair in double register fmdrr d7, r2, r3 // load r2/r3 pair in double register fcmpd d6, d7 Modified: compiler-rt/trunk/lib/arm/ltsf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/ltsf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/ltsf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/ltsf2vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where single precision arguments are passsed // like 32-bit ints // - .globl ___ltsf2vfp -___ltsf2vfp: +DEFINE_COMPILERRT_FUNCTION(__ltsf2vfp) fmsr s14, r0 // move from GPR 0 to float register fmsr s15, r1 // move from GPR 1 to float register fcmps s14, s15 Modified: compiler-rt/trunk/lib/arm/muldf3vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/muldf3vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/muldf3vfp.S (original) +++ compiler-rt/trunk/lib/arm/muldf3vfp.S Tue Oct 27 12:50:21 2009 @@ -15,8 +15,7 @@ // Multiplies two double precision floating point numbers using the Darwin // calling convention where double arguments are passsed in GPR pairs // - .globl ___muldf3vfp -___muldf3vfp: +DEFINE_COMPILERRT_FUNCTION(__muldf3vfp) fmdrr d6, r0, r1 // move first param from r0/r1 pair into d6 fmdrr d7, r2, r3 // move second param from r2/r3 pair into d7 fmuld d6, d6, d7 Modified: compiler-rt/trunk/lib/arm/mulsf3vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/mulsf3vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/mulsf3vfp.S (original) +++ compiler-rt/trunk/lib/arm/mulsf3vfp.S Tue Oct 27 12:50:21 2009 @@ -15,8 +15,7 @@ // Multiplies two single precision floating point numbers using the Darwin // calling convention where single arguments are passsed like 32-bit ints. // - .globl ___mulsf3vfp -___mulsf3vfp: +DEFINE_COMPILERRT_FUNCTION(__mulsf3vfp) fmsr s14, r0 // move first param from r0 into float register fmsr s15, r1 // move second param from r1 into float register fmuls s13, s14, s15 Modified: compiler-rt/trunk/lib/arm/nedf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/nedf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/nedf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/nedf2vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where double precision arguments are passsed // like in GPR pairs. // - .globl ___nedf2vfp -___nedf2vfp: +DEFINE_COMPILERRT_FUNCTION(__nedf2vfp) fmdrr d6, r0, r1 // load r0/r1 pair in double register fmdrr d7, r2, r3 // load r2/r3 pair in double register fcmpd d6, d7 Modified: compiler-rt/trunk/lib/arm/negdf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/negdf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/negdf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/negdf2vfp.S Tue Oct 27 12:50:21 2009 @@ -15,7 +15,6 @@ // Returns the negation a double precision floating point numbers using the // Darwin calling convention where double arguments are passsed in GPR pairs. // - .globl ___negdf2vfp -___negdf2vfp: +DEFINE_COMPILERRT_FUNCTION(__negdf2vfp) eor r1, r1, #-2147483648 // flip sign bit on double in r0/r1 pair bx lr Modified: compiler-rt/trunk/lib/arm/negsf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/negsf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/negsf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/negsf2vfp.S Tue Oct 27 12:50:21 2009 @@ -15,7 +15,6 @@ // Returns the negation of a single precision floating point numbers using the // Darwin calling convention where single arguments are passsed like 32-bit ints // - .globl ___negsf2vfp -___negsf2vfp: +DEFINE_COMPILERRT_FUNCTION(__negsf2vfp) eor r0, r0, #-2147483648 // flip sign bit on float in r0 bx lr Modified: compiler-rt/trunk/lib/arm/nesf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/nesf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/nesf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/nesf2vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where single precision arguments are passsed // like 32-bit ints // - .globl ___nesf2vfp -___nesf2vfp: +DEFINE_COMPILERRT_FUNCTION(__nesf2vfp) fmsr s14, r0 // move from GPR 0 to float register fmsr s15, r1 // move from GPR 1 to float register fcmps s14, s15 Modified: compiler-rt/trunk/lib/arm/subdf3vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/subdf3vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/subdf3vfp.S (original) +++ compiler-rt/trunk/lib/arm/subdf3vfp.S Tue Oct 27 12:50:21 2009 @@ -15,8 +15,7 @@ // Returns difference between two double precision floating point numbers using // the Darwin calling convention where double arguments are passsed in GPR pairs // - .globl ___subdf3vfp -___subdf3vfp: +DEFINE_COMPILERRT_FUNCTION(__subdf3vfp) fmdrr d6, r0, r1 // move first param from r0/r1 pair into d6 fmdrr d7, r2, r3 // move second param from r2/r3 pair into d7 fsubd d6, d6, d7 Modified: compiler-rt/trunk/lib/arm/subsf3vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/subsf3vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/subsf3vfp.S (original) +++ compiler-rt/trunk/lib/arm/subsf3vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // using the Darwin calling convention where single arguments are passsed // like 32-bit ints. // - .globl ___subsf3vfp -___subsf3vfp: +DEFINE_COMPILERRT_FUNCTION(__subsf3vfp) fmsr s14, r0 // move first param from r0 into float register fmsr s15, r1 // move second param from r1 into float register fsubs s14, s14, s15 Modified: compiler-rt/trunk/lib/arm/switch.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/switch.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/switch.S (original) +++ compiler-rt/trunk/lib/arm/switch.S Tue Oct 27 12:50:21 2009 @@ -29,9 +29,7 @@ // The table contains unsigned byte sized elements which are 1/2 the distance // from lr to the target label. // - .globl ___switchu8 - .private_extern ___switchu8 -___switchu8: +DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switchu8) ldrb ip, [lr, #-1] // get first byte in table cmp r0, ip // compare with index ldrbcc r0, [lr, r0] // get indexed byte out of table @@ -45,9 +43,7 @@ // The table contains signed byte sized elements which are 1/2 the distance // from lr to the target label. // - .globl ___switch8 - .private_extern ___switch8 -___switch8: +DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch8) ldrb ip, [lr, #-1] // get first byte in table cmp r0, ip // signed compare with index ldrsbcc r0, [lr, r0] // get indexed byte out of table @@ -60,9 +56,7 @@ // The table contains signed 2-byte sized elements which are 1/2 the distance // from lr to the target label. // - .globl ___switch16 - .private_extern ___switch16 -___switch16: +DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch16) ldrh ip, [lr, #-1] // get first 16-bit word in table cmp r0, ip // compare with index add r0, lr, r0, lsl #1 // compute address of element in table @@ -77,9 +71,7 @@ // The table contains signed 4-byte sized elements which are the distance // from lr to the target label. // - .globl ___switch32 - .private_extern ___switch32 -___switch32: +DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch32) ldr ip, [lr, #-1] // get first 32-bit word in table cmp r0, ip // compare with index add r0, lr, r0, lsl #2 // compute address of element in table Modified: compiler-rt/trunk/lib/arm/truncdfsf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/truncdfsf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/truncdfsf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/truncdfsf2vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where a double precision parameter is // passed in a R0/R1 pair and a signle precision result is returned in R0. // - .globl ___truncdfsf2vfp -___truncdfsf2vfp: +DEFINE_COMPILERRT_FUNCTION(__truncdfsf2vfp) fmdrr d7, r0, r1 // load double from r0/r1 pair fcvtsd s15, d7 // convert double to single (trucate precision) fmrs r0, s15 // return result in r0 Modified: compiler-rt/trunk/lib/arm/unorddf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/unorddf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/unorddf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/unorddf2vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where double precision arguments are passsed // like in GPR pairs. // - .globl ___unorddf2vfp -___unorddf2vfp: +DEFINE_COMPILERRT_FUNCTION(__unorddf2vfp) fmdrr d6, r0, r1 // load r0/r1 pair in double register fmdrr d7, r2, r3 // load r2/r3 pair in double register fcmpd d6, d7 Modified: compiler-rt/trunk/lib/arm/unordsf2vfp.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/arm/unordsf2vfp.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/arm/unordsf2vfp.S (original) +++ compiler-rt/trunk/lib/arm/unordsf2vfp.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ // Uses Darwin calling convention where single precision arguments are passsed // like 32-bit ints // - .globl ___unordsf2vfp -___unordsf2vfp: +DEFINE_COMPILERRT_FUNCTION(__unordsf2vfp) fmsr s14, r0 // move from GPR 0 to float register fmsr s15, r1 // move from GPR 1 to float register fcmps s14, s15 Modified: compiler-rt/trunk/lib/i386/ashldi3.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/ashldi3.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/ashldi3.S (original) +++ compiler-rt/trunk/lib/i386/ashldi3.S Tue Oct 27 12:50:21 2009 @@ -17,8 +17,7 @@ .text .align 4 -.globl ___ashldi3 -___ashldi3: +DEFINE_COMPILERRT_FUNCTION(__ashldi3) movd 12(%esp), %xmm2 // Load count #ifndef TRUST_CALLERS_USE_64_BIT_STORES movd 4(%esp), %xmm0 @@ -37,8 +36,7 @@ .text .align 4 -.globl ___ashldi3 -___ashldi3: +DEFINE_COMPILERRT_FUNCTION(__ashldi3) movl 12(%esp), %ecx // Load count movl 8(%esp), %edx // Load high movl 4(%esp), %eax // Load low Modified: compiler-rt/trunk/lib/i386/ashrdi3.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/ashrdi3.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/ashrdi3.S (original) +++ compiler-rt/trunk/lib/i386/ashrdi3.S Tue Oct 27 12:50:21 2009 @@ -10,8 +10,7 @@ .text .align 4 -.globl ___ashrdi3 -___ashrdi3: +DEFINE_COMPILERRT_FUNCTION(__ashrdi3) movd 12(%esp), %xmm2 // Load count movl 8(%esp), %eax #ifndef TRUST_CALLERS_USE_64_BIT_STORES @@ -47,8 +46,7 @@ .text .align 4 -.globl ___ashrdi3 -___ashrdi3: +DEFINE_COMPILERRT_FUNCTION(__ashrdi3) movl 12(%esp), %ecx // Load count movl 8(%esp), %edx // Load high movl 4(%esp), %eax // Load low Modified: compiler-rt/trunk/lib/i386/divdi3.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/divdi3.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/divdi3.S (original) +++ compiler-rt/trunk/lib/i386/divdi3.S Tue Oct 27 12:50:21 2009 @@ -20,8 +20,7 @@ .text .align 4 -.globl ___divdi3 -___divdi3: +DEFINE_COMPILERRT_FUNCTION(__divdi3) /* This is currently implemented by wrapping the unsigned divide up in an absolute value, then restoring the correct sign at the end of the computation. This could Modified: compiler-rt/trunk/lib/i386/floatdidf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatdidf.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatdidf.S (original) +++ compiler-rt/trunk/lib/i386/floatdidf.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ .text .align 4 -.globl ___floatdidf -___floatdidf: +DEFINE_COMPILERRT_FUNCTION(__floatdidf) cvtsi2sd 8(%esp), %xmm1 movss 4(%esp), %xmm0 // low 32 bits of a calll 0f Modified: compiler-rt/trunk/lib/i386/floatdisf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatdisf.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatdisf.S (original) +++ compiler-rt/trunk/lib/i386/floatdisf.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ .text .align 4 -.globl ___floatdisf -___floatdisf: +DEFINE_COMPILERRT_FUNCTION(__floatdisf) #ifndef TRUST_CALLERS_USE_64_BIT_STORES movd 4(%esp), %xmm0 movd 8(%esp), %xmm1 Modified: compiler-rt/trunk/lib/i386/floatdixf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatdixf.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatdixf.S (original) +++ compiler-rt/trunk/lib/i386/floatdixf.S Tue Oct 27 12:50:21 2009 @@ -16,8 +16,7 @@ .text .align 4 -.globl ___floatdixf -___floatdixf: +DEFINE_COMPILERRT_FUNCTION(__floatdixf) #ifndef TRUST_CALLERS_USE_64_BIT_STORES movd 4(%esp), %xmm0 movd 8(%esp), %xmm1 Modified: compiler-rt/trunk/lib/i386/floatundidf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatundidf.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatundidf.S (original) +++ compiler-rt/trunk/lib/i386/floatundidf.S Tue Oct 27 12:50:21 2009 @@ -28,8 +28,7 @@ .text .align 4 -.globl ___floatundidf -___floatundidf: +DEFINE_COMPILERRT_FUNCTION(__floatundidf) movss 8(%esp), %xmm1 // high 32 bits of a movss 4(%esp), %xmm0 // low 32 bits of a calll 0f Modified: compiler-rt/trunk/lib/i386/floatundisf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatundisf.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatundisf.S (original) +++ compiler-rt/trunk/lib/i386/floatundisf.S Tue Oct 27 12:50:21 2009 @@ -28,8 +28,7 @@ .text .align 4 -.globl ___floatundisf -___floatundisf: +DEFINE_COMPILERRT_FUNCTION(__floatundisf) movl 8(%esp), %eax movd 8(%esp), %xmm1 movd 4(%esp), %xmm0 @@ -65,8 +64,7 @@ .text .align 4 -.globl ___floatundisf -___floatundisf: +DEFINE_COMPILERRT_FUNCTION(__floatundisf) movl 8(%esp), %eax movd 8(%esp), %xmm1 movd 4(%esp), %xmm0 Modified: compiler-rt/trunk/lib/i386/floatundixf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/floatundixf.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/floatundixf.S (original) +++ compiler-rt/trunk/lib/i386/floatundixf.S Tue Oct 27 12:50:21 2009 @@ -18,8 +18,7 @@ .text .align 4 -.globl ___floatundixf -___floatundixf: +DEFINE_COMPILERRT_FUNCTION(__floatundixf) calll 0f 0: popl %eax movss 8(%esp), %xmm0 // hi 32 bits of input Modified: compiler-rt/trunk/lib/i386/lshrdi3.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/lshrdi3.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/lshrdi3.S (original) +++ compiler-rt/trunk/lib/i386/lshrdi3.S Tue Oct 27 12:50:21 2009 @@ -17,8 +17,7 @@ .text .align 4 -.globl ___lshrdi3 -___lshrdi3: +DEFINE_COMPILERRT_FUNCTION(__lshrdi3) movd 12(%esp), %xmm2 // Load count #ifndef TRUST_CALLERS_USE_64_BIT_STORES movd 4(%esp), %xmm0 @@ -37,8 +36,7 @@ .text .align 4 -.globl ___lshrdi3 -___lshrdi3: +DEFINE_COMPILERRT_FUNCTION(__lshrdi3) movl 12(%esp), %ecx // Load count movl 8(%esp), %edx // Load high movl 4(%esp), %eax // Load low Modified: compiler-rt/trunk/lib/i386/moddi3.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/moddi3.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/moddi3.S (original) +++ compiler-rt/trunk/lib/i386/moddi3.S Tue Oct 27 12:50:21 2009 @@ -21,8 +21,7 @@ .text .align 4 -.globl ___moddi3 -___moddi3: +DEFINE_COMPILERRT_FUNCTION(__moddi3) /* This is currently implemented by wrapping the unsigned modulus up in an absolute value. This could certainly be improved upon. */ Modified: compiler-rt/trunk/lib/i386/muldi3.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/muldi3.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/muldi3.S (original) +++ compiler-rt/trunk/lib/i386/muldi3.S Tue Oct 27 12:50:21 2009 @@ -9,8 +9,7 @@ .text .align 4 -.globl ___muldi3 -___muldi3: +DEFINE_COMPILERRT_FUNCTION(__muldi3) pushl %ebx movl 16(%esp), %eax // b.lo movl 12(%esp), %ecx // a.hi Modified: compiler-rt/trunk/lib/i386/udivdi3.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/udivdi3.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/udivdi3.S (original) +++ compiler-rt/trunk/lib/i386/udivdi3.S Tue Oct 27 12:50:21 2009 @@ -20,8 +20,7 @@ .text .align 4 -.globl ___udivdi3 -___udivdi3: +DEFINE_COMPILERRT_FUNCTION(__udivdi3) pushl %ebx movl 20(%esp), %ebx // Find the index i of the leading bit in b. Modified: compiler-rt/trunk/lib/i386/umoddi3.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/i386/umoddi3.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/i386/umoddi3.S (original) +++ compiler-rt/trunk/lib/i386/umoddi3.S Tue Oct 27 12:50:21 2009 @@ -21,8 +21,7 @@ .text .align 4 -.globl ___umoddi3 -___umoddi3: +DEFINE_COMPILERRT_FUNCTION(__umoddi3) pushl %ebx movl 20(%esp), %ebx // Find the index i of the leading bit in b. Modified: compiler-rt/trunk/lib/ppc/restFP.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ppc/restFP.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/ppc/restFP.S (original) +++ compiler-rt/trunk/lib/ppc/restFP.S Tue Oct 27 12:50:21 2009 @@ -19,9 +19,8 @@ // This function should never be exported by a shared library. Each linkage // unit carries its own copy of this function. // - .globl restFP - .private_extern restFP -restFP: stfd f14,-144(r1) +DEFINE_COMPILERRT_PRIVATE_FUNCTION(restFP) + stfd f14,-144(r1) stfd f15,-136(r1) stfd f16,-128(r1) stfd f17,-120(r1) Modified: compiler-rt/trunk/lib/ppc/saveFP.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ppc/saveFP.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/ppc/saveFP.S (original) +++ compiler-rt/trunk/lib/ppc/saveFP.S Tue Oct 27 12:50:21 2009 @@ -17,9 +17,8 @@ // This function should never be exported by a shared library. Each linkage // unit carries its own copy of this function. // - .globl saveFP - .private_extern saveFP -saveFP: stfd f14,-144(r1) +DEFINE_COMPILERRT_PRIVATE_FUNCTION(saveFP) + stfd f14,-144(r1) stfd f15,-136(r1) stfd f16,-128(r1) stfd f17,-120(r1) Modified: compiler-rt/trunk/lib/x86_64/floatundidf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/x86_64/floatundidf.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/x86_64/floatundidf.S (original) +++ compiler-rt/trunk/lib/x86_64/floatundidf.S Tue Oct 27 12:50:21 2009 @@ -28,8 +28,7 @@ .text .align 4 -.globl ___floatundidf -___floatundidf: +DEFINE_COMPILERRT_FUNCTION(__floatundidf) movd %edi, %xmm0 // low 32 bits of a shrq $32, %rdi // high 32 bits of a orq REL_ADDR(twop84), %rdi // 0x1p84 + a_hi (no rounding occurs) Modified: compiler-rt/trunk/lib/x86_64/floatundisf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/x86_64/floatundisf.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/x86_64/floatundisf.S (original) +++ compiler-rt/trunk/lib/x86_64/floatundisf.S Tue Oct 27 12:50:21 2009 @@ -14,8 +14,7 @@ .text .align 4 -.globl ___floatundisf -___floatundisf: +DEFINE_COMPILERRT_FUNCTION(__floatundisf) movq $1, %rsi testq %rdi, %rdi js 1f Modified: compiler-rt/trunk/lib/x86_64/floatundixf.S URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/x86_64/floatundixf.S?rev=85264&r1=85263&r2=85264&view=diff ============================================================================== --- compiler-rt/trunk/lib/x86_64/floatundixf.S (original) +++ compiler-rt/trunk/lib/x86_64/floatundixf.S Tue Oct 27 12:50:21 2009 @@ -15,8 +15,7 @@ .text .align 4 -.globl ___floatundixf -___floatundixf: +DEFINE_COMPILERRT_FUNCTION(__floatundixf) movq %rdi, -8(%rsp) fildq -8(%rsp) test %rdi, %rdi @@ -44,8 +43,7 @@ .text .align 4 -.globl ___floatundixf -___floatundixf: +DEFINE_COMPILERRT_FUNCTION(__floatundixf) movl %edi, %esi // low 32 bits of input shrq $32, %rdi // hi 32 bits of input orq REL_ADDR(twop84), %rdi // 2^84 + hi (as a double) From bob.wilson at apple.com Tue Oct 27 12:47:38 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 27 Oct 2009 10:47:38 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r85190 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: <317FD6A5-E55F-4B1A-BD36-1FDF981F115E@apple.com> References: <200910270053.n9R0rkqP015550@zion.cs.uiuc.edu> <317FD6A5-E55F-4B1A-BD36-1FDF981F115E@apple.com> Message-ID: <65663369-8DA8-46D7-AE83-0D571C941A69@apple.com> It looks like this is causing a bunch of other failures. I'm going to revert this. On Oct 27, 2009, at 10:06 AM, Bob Wilson wrote: > Eric, my debug build of llvm is failing and it seems to be related to > this change: > > make -C libprofile all > llvm[2]: Compiling CommonProfiling.ll to CommonProfiling.bc for Debug > build (bytecode) > /Users/bwilson/local/llvm/objdir/Debug/bin/opt /Volumes/LocalHD/ > bwilson/llvm/objdir/runtime/libprofile/Debug/CommonProfiling.ll -std- > compile-opts -strip-debug -o /Volumes/LocalHD/bwilson/llvm/objdir/ > runtime/libprofile/Debug/CommonProfiling.bc > /Users/bwilson/local/llvm/objdir/Debug/bin/opt: /Volumes/LocalHD/ > bwilson/llvm/objdir/runtime/libprofile/Debug/CommonProfiling.ll: > 251:19: error: '@llvm.objectsize.i64' defined with type 'i64 (i8**, > i32)*' > %125 = call i64 @llvm.objectsize.i64(i8* %124, i32 0), !dbg !38 ; > [#uses=1] > ^ > make[2]: *** [/Volumes/LocalHD/bwilson/llvm/objdir/runtime/libprofile/ > Debug/CommonProfiling.bc] Error 1 > make[1]: *** [libprofile/.makeall] Error 2 > make: *** [all] Error 1 > > This did not happen when the llvm-gcc used to compile > CommonProfiling.c did not include this patch. Can you please > investigate? Thanks. > > On Oct 26, 2009, at 5:53 PM, Eric Christopher wrote: > >> Author: echristo >> Date: Mon Oct 26 19:53:46 2009 >> New Revision: 85190 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=85190&view=rev >> Log: >> Use new objectsize intrinsic for object size checking instead of >> folding to "don't know" immediately. >> >> Modified: >> llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp >> >> Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=85190&r1=85189&r2=85190&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) >> +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Oct 26 19:53:46 2009 >> @@ -4976,12 +4976,12 @@ >> return EmitBuiltinUnwindInit(exp, Result); >> >> case BUILT_IN_OBJECT_SIZE: { >> - tree ArgList = TREE_OPERAND (exp, 1); >> - if (!validate_arglist(ArgList, POINTER_TYPE, INTEGER_TYPE, >> VOID_TYPE)) { >> + tree arglist = TREE_OPERAND (exp, 1); >> + if (!validate_arglist(arglist, POINTER_TYPE, INTEGER_TYPE, >> VOID_TYPE)) { >> error("Invalid builtin_object_size argument types"); >> return false; >> } >> - tree ObjSizeTree = TREE_VALUE (TREE_CHAIN (ArgList)); >> + tree ObjSizeTree = TREE_VALUE (TREE_CHAIN (arglist)); >> STRIP_NOPS (ObjSizeTree); >> if (TREE_CODE (ObjSizeTree) != INTEGER_CST >> || tree_int_cst_sgn (ObjSizeTree) < 0 >> @@ -4990,12 +4990,24 @@ >> return false; >> } >> >> - // This treats everything as unknown, and is minimally >> defensible as >> - // correct, although completely useless. >> - if (tree_low_cst (ObjSizeTree, 0) < 2) >> - Result = Constant::getAllOnesValue(TD.getIntPtrType(Context)); >> - else >> - Result = ConstantInt::get(TD.getIntPtrType(Context), 0); >> + tree Object = TREE_VALUE(arglist); >> + tree ObjTy = TREE_VALUE(TREE_CHAIN(arglist)); >> + >> + Value* Args[] = { >> + Emit(Object, 0), >> + Emit(ObjTy, 0) >> + }; >> + >> + const Type* Ty[3]; >> + Ty[0] = ConvertType(TREE_TYPE(exp)); >> + Ty[1] = Type::getInt8PtrTy(Context); >> + Ty[2] = Type::getInt32Ty(Context); >> + >> + Result = Builder.CreateCall(Intrinsic::getDeclaration(TheModule, >> + Intrinsic::objectsize, >> + Ty, >> + 1), >> + Args, Args + 2); >> return true; >> } >> // Unary bit counting intrinsics. >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From bob.wilson at apple.com Tue Oct 27 12:53:33 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 27 Oct 2009 17:53:33 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r85265 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200910271753.n9RHrYAp006516@zion.cs.uiuc.edu> Author: bwilson Date: Tue Oct 27 12:53:33 2009 New Revision: 85265 URL: http://llvm.org/viewvc/llvm-project?rev=85265&view=rev Log: Revert 85190 change for BUILT_IN_OBJECT_SIZE. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=85265&r1=85264&r2=85265&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Oct 27 12:53:33 2009 @@ -4966,12 +4966,12 @@ return EmitBuiltinUnwindInit(exp, Result); case BUILT_IN_OBJECT_SIZE: { - tree arglist = TREE_OPERAND (exp, 1); - if (!validate_arglist(arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) { + tree ArgList = TREE_OPERAND (exp, 1); + if (!validate_arglist(ArgList, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) { error("Invalid builtin_object_size argument types"); return false; } - tree ObjSizeTree = TREE_VALUE (TREE_CHAIN (arglist)); + tree ObjSizeTree = TREE_VALUE (TREE_CHAIN (ArgList)); STRIP_NOPS (ObjSizeTree); if (TREE_CODE (ObjSizeTree) != INTEGER_CST || tree_int_cst_sgn (ObjSizeTree) < 0 @@ -4980,24 +4980,12 @@ return false; } - tree Object = TREE_VALUE(arglist); - tree ObjTy = TREE_VALUE(TREE_CHAIN(arglist)); - - Value* Args[] = { - Emit(Object, 0), - Emit(ObjTy, 0) - }; - - const Type* Ty[3]; - Ty[0] = ConvertType(TREE_TYPE(exp)); - Ty[1] = Type::getInt8PtrTy(Context); - Ty[2] = Type::getInt32Ty(Context); - - Result = Builder.CreateCall(Intrinsic::getDeclaration(TheModule, - Intrinsic::objectsize, - Ty, - 1), - Args, Args + 2); + // This treats everything as unknown, and is minimally defensible as + // correct, although completely useless. + if (tree_low_cst (ObjSizeTree, 0) < 2) + Result = Constant::getAllOnesValue(TD.getIntPtrType(Context)); + else + Result = ConstantInt::get(TD.getIntPtrType(Context), 0); return true; } // Unary bit counting intrinsics. From rafael.espindola at gmail.com Tue Oct 27 12:59:03 2009 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Tue, 27 Oct 2009 17:59:03 -0000 Subject: [llvm-commits] [llvm] r85266 - /llvm/trunk/test/CodeGen/ARM/2009-10-27-double-align.ll Message-ID: <200910271759.n9RHx3a9006771@zion.cs.uiuc.edu> Author: rafael Date: Tue Oct 27 12:59:03 2009 New Revision: 85266 URL: http://llvm.org/viewvc/llvm-project?rev=85266&view=rev Log: Add missing testcase. Added: llvm/trunk/test/CodeGen/ARM/2009-10-27-double-align.ll Added: llvm/trunk/test/CodeGen/ARM/2009-10-27-double-align.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2009-10-27-double-align.ll?rev=85266&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2009-10-27-double-align.ll (added) +++ llvm/trunk/test/CodeGen/ARM/2009-10-27-double-align.ll Tue Oct 27 12:59:03 2009 @@ -0,0 +1,14 @@ +; RUN: llc < %s -mtriple=arm-linux-gnueabi | FileCheck %s + + at .str = private constant [1 x i8] zeroinitializer, align 1 + +define arm_aapcscc void @g() { +entry: +;CHECK: [sp, #+8] +;CHECK: [sp, #+12] +;CHECK: [sp] + tail call arm_aapcscc void (i8*, ...)* @f(i8* getelementptr ([1 x i8]* @.str, i32 0, i32 0), i32 1, double 2.000000e+00, i32 3, double 4.000000e+00) + ret void +} + +declare arm_aapcscc void @f(i8*, ...) From espindola at google.com Tue Oct 27 12:59:35 2009 From: espindola at google.com (Rafael Espindola) Date: Tue, 27 Oct 2009 13:59:35 -0400 Subject: [llvm-commits] [llvm] r85235 - /llvm/trunk/lib/Target/ARM/ARMCallingConv.td In-Reply-To: <770A702D-91C9-421E-B1A7-7E6460EBDAAC@apple.com> References: <200910271409.n9RE9kS7029734@zion.cs.uiuc.edu> <770A702D-91C9-421E-B1A7-7E6460EBDAAC@apple.com> Message-ID: <38a0d8450910271059q6eb01476wb2e585d3bf80fb6f@mail.gmail.com> 2009/10/27 Bob Wilson : > What happened to the testcase that was in the patch you sent? Forgot to svn add it. Committed now. Thanks, -- Rafael ?vila de Esp?ndola From johnny.chen at apple.com Tue Oct 27 13:22:21 2009 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 27 Oct 2009 11:22:21 -0700 Subject: [llvm-commits] patch: lib/Target/ARM/ARMInstrInfo.td Message-ID: <2E93AD20-9EE8-4EA9-8DF2-FD0170B87FFD@apple.com> Refs: A8-434, A8-440. For multiclass AI_unary_rrot and AI_bin_rrot, explicitly specify 0b00, i.e., zero rotation, as the rotate field for the r/rr fragment. -------------- next part -------------- A non-text attachment was scrubbed... Name: ARMInstrInfo.td.patch3 Type: application/octet-stream Size: 1479 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091027/87bfdeb5/attachment.obj From echristo at apple.com Tue Oct 27 13:30:24 2009 From: echristo at apple.com (Eric Christopher) Date: Tue, 27 Oct 2009 11:30:24 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r85190 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: <65663369-8DA8-46D7-AE83-0D571C941A69@apple.com> References: <200910270053.n9R0rkqP015550@zion.cs.uiuc.edu> <317FD6A5-E55F-4B1A-BD36-1FDF981F115E@apple.com> <65663369-8DA8-46D7-AE83-0D571C941A69@apple.com> Message-ID: <066F7697-0BB6-448B-960A-79E4E2EA4A5A@apple.com> On Oct 27, 2009, at 10:47 AM, Bob Wilson wrote: > It looks like this is causing a bunch of other failures. I'm going to revert this. > Gar. OK. I'll fix and reapply. -eric From echristo at apple.com Tue Oct 27 13:36:59 2009 From: echristo at apple.com (Eric Christopher) Date: Tue, 27 Oct 2009 11:36:59 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r85265 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: <200910271753.n9RHrYAp006516@zion.cs.uiuc.edu> References: <200910271753.n9RHrYAp006516@zion.cs.uiuc.edu> Message-ID: <62704A5F-9B38-4CCC-B694-BD9BD500CFE8@apple.com> On Oct 27, 2009, at 10:53 AM, Bob Wilson wrote: > Log: > Revert 85190 change for BUILT_IN_OBJECT_SIZE. Thanks Bob! -eric From vhernandez at apple.com Tue Oct 27 13:42:16 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Tue, 27 Oct 2009 11:42:16 -0700 Subject: [llvm-commits] [llvm] r85181 - in /llvm/trunk: include/llvm/Analysis/ lib/Analysis/ lib/Analysis/IPA/ lib/Transforms/IPO/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ In-Reply-To: <4AE6B04F.8090909@free.fr> References: <200910262358.n9QNwwUP012836@zion.cs.uiuc.edu> <4AE6B04F.8090909@free.fr> Message-ID: <248FF448-F6AD-4519-8EF8-C44CB60D7982@apple.com> Duncan, Thanks for the suggestion about generalizing the name. I am going to rename it as "MemoryBuiltins". Victor On Oct 27, 2009, at 1:33 AM, Duncan Sands wrote: > Hi Victor, > >> Rename MallocHelper as MallocFreeHelper, since it now also >> identifies calls to free() > > how about naming it MemCallHelper or something like that instead. > That way > you won't need to change the name if you teach it to recognize > calloc, realloc > or other mem stuff one day. > > Ciao, > > Duncan. From johnny.chen at apple.com Tue Oct 27 13:44:25 2009 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 27 Oct 2009 18:44:25 -0000 Subject: [llvm-commits] [llvm] r85271 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Message-ID: <200910271844.n9RIiP5N008719@zion.cs.uiuc.edu> Author: johnny Date: Tue Oct 27 13:44:24 2009 New Revision: 85271 URL: http://llvm.org/viewvc/llvm-project?rev=85271&view=rev Log: Explicitly specify 0b00, i.e, zero rotation, as the rotate filed (Inst{11-10}) for the r/rr fragment of the multiclass AI_unary_rrot/AI_bin_rrot. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=85271&r1=85270&r2=85271&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Oct 27 13:44:24 2009 @@ -459,14 +459,15 @@ IIC_iUNAr, opc, "\t$dst, $src", [(set GPR:$dst, (opnode GPR:$src))]>, Requires<[IsARM, HasV6]> { - let Inst{19-16} = 0b1111; - } + let Inst{11-10} = 0b00; + let Inst{19-16} = 0b1111; + } def r_rot : AExtI, Requires<[IsARM, HasV6]> { - let Inst{19-16} = 0b1111; - } + let Inst{19-16} = 0b1111; + } } /// AI_bin_rrot - A binary operation with two forms: one whose operand is a @@ -475,7 +476,9 @@ def rr : AExtI, - Requires<[IsARM, HasV6]>; + Requires<[IsARM, HasV6]> { + let Inst{11-10} = 0b00; + } def rr_rot : AExtI Author: mrs Date: Tue Oct 27 13:46:23 2009 New Revision: 85272 URL: http://llvm.org/viewvc/llvm-project?rev=85272&view=rev Log: Update to make OS better. Modified: llvm-gcc-4.2/trunk/README.LLVM Modified: llvm-gcc-4.2/trunk/README.LLVM URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/README.LLVM?rev=85272&r1=85271&r2=85272&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/README.LLVM (original) +++ llvm-gcc-4.2/trunk/README.LLVM Tue Oct 27 13:46:23 2009 @@ -86,13 +86,13 @@ TARGETOPTIONS='--with-arch=nocona --with-tune=generic' TRIPLE=i686-apple-darwin8 (Tiger) TRIPLE=i686-apple-darwin9 (Leopard) - TRIPLE=i686-apple-darwin10 (Snow Leopard) + TRIPLE=x86_64-apple-darwin10 (Snow Leopard) If building for Darwin/X86 (32-bit support only): TARGETOPTIONS='--with-arch=pentium-m --with-tune=prescott --disable-multilib' TRIPLE=i686-apple-darwin8 (Tiger) TRIPLE=i686-apple-darwin9 (Leopard) - TRIPLE=i686-apple-darwin10 (Snow Leopard) + TRIPLE=x86_64-apple-darwin10 (Snow Leopard) The Triples are very important, otherwise your llvm-gcc/g++ may not be able to find the header files below. From mrs at apple.com Tue Oct 27 13:50:40 2009 From: mrs at apple.com (Mike Stump) Date: Tue, 27 Oct 2009 18:50:40 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r85273 - /llvm-gcc-4.2/trunk/README.LLVM Message-ID: <200910271850.n9RIofjT008983@zion.cs.uiuc.edu> Author: mrs Date: Tue Oct 27 13:50:40 2009 New Revision: 85273 URL: http://llvm.org/viewvc/llvm-project?rev=85273&view=rev Log: Fixup for 32-bit hosts. Modified: llvm-gcc-4.2/trunk/README.LLVM Modified: llvm-gcc-4.2/trunk/README.LLVM URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/README.LLVM?rev=85273&r1=85272&r2=85273&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/README.LLVM (original) +++ llvm-gcc-4.2/trunk/README.LLVM Tue Oct 27 13:50:40 2009 @@ -86,13 +86,15 @@ TARGETOPTIONS='--with-arch=nocona --with-tune=generic' TRIPLE=i686-apple-darwin8 (Tiger) TRIPLE=i686-apple-darwin9 (Leopard) - TRIPLE=x86_64-apple-darwin10 (Snow Leopard) + TRIPLE=x86_64-apple-darwin10 (Snow Leopard on a 64-bit machine) + TRIPLE=i686-apple-darwin10 (Snow Leopard on a 32-bit machine) If building for Darwin/X86 (32-bit support only): TARGETOPTIONS='--with-arch=pentium-m --with-tune=prescott --disable-multilib' TRIPLE=i686-apple-darwin8 (Tiger) TRIPLE=i686-apple-darwin9 (Leopard) - TRIPLE=x86_64-apple-darwin10 (Snow Leopard) + TRIPLE=x86_64-apple-darwin10 (Snow Leopard on a 64-bit machine) + TRIPLE=i686-apple-darwin10 (Snow Leopard on a 32-bit machine) The Triples are very important, otherwise your llvm-gcc/g++ may not be able to find the header files below. From johnny.chen at apple.com Tue Oct 27 14:01:07 2009 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 27 Oct 2009 12:01:07 -0700 Subject: [llvm-commits] r85173 lib/Target/ARM/ARMInstrInfo.td Message-ID: <9D52A000-B64B-4EE0-82E3-82B7D193A0E6@apple.com> Hi Bob, For RSCri and RSCrs, it looks like the statement: let Inst{20} = 0; might be over-specifying it. The fact that both inherit from sI implies that they are both ${p} and ${s}. Johnny Chen From resistor at mac.com Tue Oct 27 14:08:03 2009 From: resistor at mac.com (Owen Anderson) Date: Tue, 27 Oct 2009 12:08:03 -0700 Subject: [llvm-commits] [llvm] r85253 - in /llvm/trunk/lib/CodeGen: PseudoSourceValue.cpp SelectionDAG/SelectionDAGISel.cpp In-Reply-To: <200910271702.n9RH28dI004293@zion.cs.uiuc.edu> References: <200910271702.n9RH28dI004293@zion.cs.uiuc.edu> Message-ID: On Oct 27, 2009, at 10:02 AM, Chris Lattner wrote: > Author: lattner > Date: Tue Oct 27 12:02:08 2009 > New Revision: 85253 > > URL: http://llvm.org/viewvc/llvm-project?rev=85253&view=rev > Log: > pseudosourcevalue is also still using getGlobalContext(), so it isn't > thread safe either. This is deliberate. PSV uses the things it creates as sentinels, so there's no need to worry about them being uniqued with existing ones. As long as no other value compares equal to them, everything works. --Owen From sabre at nondot.org Tue Oct 27 14:13:17 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 19:13:17 -0000 Subject: [llvm-commits] [llvm] r85274 - in /llvm/trunk: docs/ include/llvm/ include/llvm/Bitcode/ include/llvm/Support/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/CodeGen/SelectionDAG/ lib/VMCore/ test/Feature/ Message-ID: <200910271913.n9RJDHT0010104@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 14:13:16 2009 New Revision: 85274 URL: http://llvm.org/viewvc/llvm-project?rev=85274&view=rev Log: add enough support for indirect branch for the feature test to pass (assembler,asmprinter, bc reader+writer) and document it. Codegen currently aborts on it. Modified: llvm/trunk/docs/LangRef.html llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h llvm/trunk/include/llvm/Instruction.def llvm/trunk/include/llvm/Instructions.h llvm/trunk/include/llvm/Support/InstVisitor.h llvm/trunk/lib/AsmParser/LLLexer.cpp llvm/trunk/lib/AsmParser/LLParser.cpp llvm/trunk/lib/AsmParser/LLParser.h llvm/trunk/lib/AsmParser/LLToken.h llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h llvm/trunk/lib/VMCore/AsmWriter.cpp llvm/trunk/lib/VMCore/Instruction.cpp llvm/trunk/lib/VMCore/Instructions.cpp llvm/trunk/test/Feature/terminators.ll Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Tue Oct 27 14:13:16 2009 @@ -110,6 +110,7 @@
    8. 'ret' Instruction
    9. 'br' Instruction
    10. 'switch' Instruction
    11. +
    12. 'indbr' Instruction
    13. 'invoke' Instruction
    14. 'unwind' Instruction
    15. 'unreachable' Instruction
    16. @@ -2511,6 +2512,7 @@ 'ret' instruction, the 'br' instruction, the 'switch' instruction, the + ''indbr' Instruction, the 'invoke' instruction, the 'unwind' instruction, and the 'unreachable' instruction.

      @@ -2669,6 +2671,54 @@ + + + + +
      + +
      Syntax:
      +
      +  indbr <somety>* <address>, [ label <dest1>, label <dest2>, ... ]
      +
      + +
      Overview:
      + +

      The 'indbr' instruction implements an indirect branch to a label + within the current function, whose address is specified by + "address".

      + +
      Arguments:
      + +

      The 'address' argument is the address of the label to jump to. The + rest of the arguments indicate the full set of possible destinations that the + address may point to. Blocks are allowed to occur multiple times in the + destination list, though this isn't particularly useful.

      + +

      This destination list is required so that dataflow analysis has an accurate + understanding of the CFG.

      + +
      Semantics:
      + +

      Control transfers to the block specified in the address argument. All + possible destination blocks must be listed in the label list, otherwise this + instruction has undefined behavior. This implies that jumps to labels + defined in other functions have undefined behavior as well.

      + +
      Implementation:
      + +

      This is typically implemented with a jump through a register.

      + +
      Example:
      +
      + switch i8* %Addr, [ label %bb1, label %bb2, label %bb3 ]
      +
      + +
      + +
      'invoke' Instruction Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original) +++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Tue Oct 27 14:13:16 2009 @@ -209,7 +209,7 @@ FUNC_CODE_INST_RET = 10, // RET: [opty,opval] FUNC_CODE_INST_BR = 11, // BR: [bb#, bb#, cond] or [bb#] - FUNC_CODE_INST_SWITCH = 12, // SWITCH: [opty, opval, n, n x ops] + FUNC_CODE_INST_SWITCH = 12, // SWITCH: [opty, operands...] FUNC_CODE_INST_INVOKE = 13, // INVOKE: [attr, fnty, op0,op1, ...] FUNC_CODE_INST_UNWIND = 14, // UNWIND FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE @@ -236,7 +236,8 @@ FUNC_CODE_INST_CMP2 = 28, // CMP2: [opty, opval, opval, pred] // new select on i1 or [N x i1] FUNC_CODE_INST_VSELECT = 29, // VSELECT: [ty,opval,opval,predty,pred] - FUNC_CODE_INST_INBOUNDS_GEP = 30 // INBOUNDS_GEP: [n x operands] + FUNC_CODE_INST_INBOUNDS_GEP= 30, // INBOUNDS_GEP: [n x operands] + FUNC_CODE_INST_INDBR = 31 // INDBR: [opty, operands...] }; } // End bitc namespace } // End llvm namespace Modified: llvm/trunk/include/llvm/Instruction.def URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instruction.def?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instruction.def (original) +++ llvm/trunk/include/llvm/Instruction.def Tue Oct 27 14:13:16 2009 @@ -97,78 +97,79 @@ HANDLE_TERM_INST ( 1, Ret , ReturnInst) HANDLE_TERM_INST ( 2, Br , BranchInst) HANDLE_TERM_INST ( 3, Switch , SwitchInst) -HANDLE_TERM_INST ( 4, Invoke , InvokeInst) -HANDLE_TERM_INST ( 5, Unwind , UnwindInst) -HANDLE_TERM_INST ( 6, Unreachable, UnreachableInst) - LAST_TERM_INST ( 6) +HANDLE_TERM_INST ( 4, IndBr , IndBrInst) +HANDLE_TERM_INST ( 5, Invoke , InvokeInst) +HANDLE_TERM_INST ( 6, Unwind , UnwindInst) +HANDLE_TERM_INST ( 7, Unreachable, UnreachableInst) + LAST_TERM_INST ( 7) // Standard binary operators... - FIRST_BINARY_INST( 7) -HANDLE_BINARY_INST( 7, Add , BinaryOperator) -HANDLE_BINARY_INST( 8, FAdd , BinaryOperator) -HANDLE_BINARY_INST( 9, Sub , BinaryOperator) -HANDLE_BINARY_INST(10, FSub , BinaryOperator) -HANDLE_BINARY_INST(11, Mul , BinaryOperator) -HANDLE_BINARY_INST(12, FMul , BinaryOperator) -HANDLE_BINARY_INST(13, UDiv , BinaryOperator) -HANDLE_BINARY_INST(14, SDiv , BinaryOperator) -HANDLE_BINARY_INST(15, FDiv , BinaryOperator) -HANDLE_BINARY_INST(16, URem , BinaryOperator) -HANDLE_BINARY_INST(17, SRem , BinaryOperator) -HANDLE_BINARY_INST(18, FRem , BinaryOperator) + FIRST_BINARY_INST( 8) +HANDLE_BINARY_INST( 8, Add , BinaryOperator) +HANDLE_BINARY_INST( 9, FAdd , BinaryOperator) +HANDLE_BINARY_INST(10, Sub , BinaryOperator) +HANDLE_BINARY_INST(11, FSub , BinaryOperator) +HANDLE_BINARY_INST(12, Mul , BinaryOperator) +HANDLE_BINARY_INST(13, FMul , BinaryOperator) +HANDLE_BINARY_INST(14, UDiv , BinaryOperator) +HANDLE_BINARY_INST(15, SDiv , BinaryOperator) +HANDLE_BINARY_INST(16, FDiv , BinaryOperator) +HANDLE_BINARY_INST(17, URem , BinaryOperator) +HANDLE_BINARY_INST(18, SRem , BinaryOperator) +HANDLE_BINARY_INST(19, FRem , BinaryOperator) // Logical operators (integer operands) -HANDLE_BINARY_INST(19, Shl , BinaryOperator) // Shift left (logical) -HANDLE_BINARY_INST(20, LShr , BinaryOperator) // Shift right (logical) -HANDLE_BINARY_INST(21, AShr , BinaryOperator) // Shift right (arithmetic) -HANDLE_BINARY_INST(22, And , BinaryOperator) -HANDLE_BINARY_INST(23, Or , BinaryOperator) -HANDLE_BINARY_INST(24, Xor , BinaryOperator) - LAST_BINARY_INST(24) +HANDLE_BINARY_INST(20, Shl , BinaryOperator) // Shift left (logical) +HANDLE_BINARY_INST(21, LShr , BinaryOperator) // Shift right (logical) +HANDLE_BINARY_INST(22, AShr , BinaryOperator) // Shift right (arithmetic) +HANDLE_BINARY_INST(23, And , BinaryOperator) +HANDLE_BINARY_INST(24, Or , BinaryOperator) +HANDLE_BINARY_INST(25, Xor , BinaryOperator) + LAST_BINARY_INST(25) // Memory operators... - FIRST_MEMORY_INST(25) -HANDLE_MEMORY_INST(25, Alloca, AllocaInst) // Stack management -HANDLE_MEMORY_INST(26, Load , LoadInst ) // Memory manipulation instrs -HANDLE_MEMORY_INST(27, Store , StoreInst ) -HANDLE_MEMORY_INST(28, GetElementPtr, GetElementPtrInst) - LAST_MEMORY_INST(28) + FIRST_MEMORY_INST(26) +HANDLE_MEMORY_INST(26, Alloca, AllocaInst) // Stack management +HANDLE_MEMORY_INST(27, Load , LoadInst ) // Memory manipulation instrs +HANDLE_MEMORY_INST(28, Store , StoreInst ) +HANDLE_MEMORY_INST(29, GetElementPtr, GetElementPtrInst) + LAST_MEMORY_INST(29) // Cast operators ... // NOTE: The order matters here because CastInst::isEliminableCastPair // NOTE: (see Instructions.cpp) encodes a table based on this ordering. - FIRST_CAST_INST(29) -HANDLE_CAST_INST(29, Trunc , TruncInst ) // Truncate integers -HANDLE_CAST_INST(30, ZExt , ZExtInst ) // Zero extend integers -HANDLE_CAST_INST(31, SExt , SExtInst ) // Sign extend integers -HANDLE_CAST_INST(32, FPToUI , FPToUIInst ) // floating point -> UInt -HANDLE_CAST_INST(33, FPToSI , FPToSIInst ) // floating point -> SInt -HANDLE_CAST_INST(34, UIToFP , UIToFPInst ) // UInt -> floating point -HANDLE_CAST_INST(35, SIToFP , SIToFPInst ) // SInt -> floating point -HANDLE_CAST_INST(36, FPTrunc , FPTruncInst ) // Truncate floating point -HANDLE_CAST_INST(37, FPExt , FPExtInst ) // Extend floating point -HANDLE_CAST_INST(38, PtrToInt, PtrToIntInst) // Pointer -> Integer -HANDLE_CAST_INST(39, IntToPtr, IntToPtrInst) // Integer -> Pointer -HANDLE_CAST_INST(40, BitCast , BitCastInst ) // Type cast - LAST_CAST_INST(40) + FIRST_CAST_INST(30) +HANDLE_CAST_INST(30, Trunc , TruncInst ) // Truncate integers +HANDLE_CAST_INST(31, ZExt , ZExtInst ) // Zero extend integers +HANDLE_CAST_INST(32, SExt , SExtInst ) // Sign extend integers +HANDLE_CAST_INST(33, FPToUI , FPToUIInst ) // floating point -> UInt +HANDLE_CAST_INST(34, FPToSI , FPToSIInst ) // floating point -> SInt +HANDLE_CAST_INST(35, UIToFP , UIToFPInst ) // UInt -> floating point +HANDLE_CAST_INST(36, SIToFP , SIToFPInst ) // SInt -> floating point +HANDLE_CAST_INST(37, FPTrunc , FPTruncInst ) // Truncate floating point +HANDLE_CAST_INST(38, FPExt , FPExtInst ) // Extend floating point +HANDLE_CAST_INST(39, PtrToInt, PtrToIntInst) // Pointer -> Integer +HANDLE_CAST_INST(40, IntToPtr, IntToPtrInst) // Integer -> Pointer +HANDLE_CAST_INST(41, BitCast , BitCastInst ) // Type cast + LAST_CAST_INST(41) // Other operators... - FIRST_OTHER_INST(41) -HANDLE_OTHER_INST(41, ICmp , ICmpInst ) // Integer comparison instruction -HANDLE_OTHER_INST(42, FCmp , FCmpInst ) // Floating point comparison instr. -HANDLE_OTHER_INST(43, PHI , PHINode ) // PHI node instruction -HANDLE_OTHER_INST(44, Call , CallInst ) // Call a function -HANDLE_OTHER_INST(45, Select , SelectInst ) // select instruction -HANDLE_OTHER_INST(46, UserOp1, Instruction) // May be used internally in a pass -HANDLE_OTHER_INST(47, UserOp2, Instruction) // Internal to passes only -HANDLE_OTHER_INST(48, VAArg , VAArgInst ) // vaarg instruction -HANDLE_OTHER_INST(49, ExtractElement, ExtractElementInst)// extract from vector -HANDLE_OTHER_INST(50, InsertElement, InsertElementInst) // insert into vector -HANDLE_OTHER_INST(51, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. -HANDLE_OTHER_INST(52, ExtractValue, ExtractValueInst)// extract from aggregate -HANDLE_OTHER_INST(53, InsertValue, InsertValueInst) // insert into aggregate + FIRST_OTHER_INST(42) +HANDLE_OTHER_INST(42, ICmp , ICmpInst ) // Integer comparison instruction +HANDLE_OTHER_INST(43, FCmp , FCmpInst ) // Floating point comparison instr. +HANDLE_OTHER_INST(44, PHI , PHINode ) // PHI node instruction +HANDLE_OTHER_INST(45, Call , CallInst ) // Call a function +HANDLE_OTHER_INST(46, Select , SelectInst ) // select instruction +HANDLE_OTHER_INST(47, UserOp1, Instruction) // May be used internally in a pass +HANDLE_OTHER_INST(48, UserOp2, Instruction) // Internal to passes only +HANDLE_OTHER_INST(49, VAArg , VAArgInst ) // vaarg instruction +HANDLE_OTHER_INST(50, ExtractElement, ExtractElementInst)// extract from vector +HANDLE_OTHER_INST(51, InsertElement, InsertElementInst) // insert into vector +HANDLE_OTHER_INST(52, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. +HANDLE_OTHER_INST(53, ExtractValue, ExtractValueInst)// extract from aggregate +HANDLE_OTHER_INST(54, InsertValue, InsertValueInst) // insert into aggregate - LAST_OTHER_INST(53) + LAST_OTHER_INST(54) #undef FIRST_TERM_INST #undef HANDLE_TERM_INST Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Tue Oct 27 14:13:16 2009 @@ -2076,7 +2076,7 @@ // Operand[1] = Default basic block destination // Operand[2n ] = Value to match // Operand[2n+1] = BasicBlock to go to on match - SwitchInst(const SwitchInst &RI); + SwitchInst(const SwitchInst &SI); void init(Value *Value, BasicBlock *Default, unsigned NumCases); void resizeOperands(unsigned No); // allocate space for exactly zero operands @@ -2088,7 +2088,7 @@ /// be specified here to make memory allocation more efficient. This /// constructor can also autoinsert before another instruction. SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, - Instruction *InsertBefore = 0); + Instruction *InsertBefore); /// SwitchInst ctor - Create a new switch instruction, specifying a value to /// switch on and a default destination. The number of additional cases can @@ -2214,6 +2214,105 @@ //===----------------------------------------------------------------------===// +// IndBrInst Class +//===----------------------------------------------------------------------===// + +//===--------------------------------------------------------------------------- +/// IndBrInst - Indirect Branch Instruction. +/// +class IndBrInst : public TerminatorInst { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + unsigned ReservedSpace; + // Operand[0] = Value to switch on + // Operand[1] = Default basic block destination + // Operand[2n ] = Value to match + // Operand[2n+1] = BasicBlock to go to on match + IndBrInst(const IndBrInst &IBI); + void init(Value *Address, unsigned NumDests); + void resizeOperands(unsigned No); + // allocate space for exactly zero operands + void *operator new(size_t s) { + return User::operator new(s, 0); + } + /// IndBrInst ctor - Create a new indbr instruction, specifying an Address to + /// jump to. The number of expected destinations can be specified here to + /// make memory allocation more efficient. This constructor can also + /// autoinsert before another instruction. + IndBrInst(Value *Address, unsigned NumDests, Instruction *InsertBefore); + + /// IndBrInst ctor - Create a new indbr instruction, specifying an Address to + /// jump to. The number of expected destinations can be specified here to + /// make memory allocation more efficient. This constructor also autoinserts + /// at the end of the specified BasicBlock. + IndBrInst(Value *Address, unsigned NumDests, BasicBlock *InsertAtEnd); +public: + static IndBrInst *Create(Value *Address, unsigned NumDests, + Instruction *InsertBefore = 0) { + return new IndBrInst(Address, NumDests, InsertBefore); + } + static IndBrInst *Create(Value *Address, unsigned NumDests, + BasicBlock *InsertAtEnd) { + return new IndBrInst(Address, NumDests, InsertAtEnd); + } + ~IndBrInst(); + + /// Provide fast operand accessors. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + // Accessor Methods for IndBr instruction. + Value *getAddress() { return getOperand(0); } + const Value *getAddress() const { return getOperand(0); } + void setAddress(Value *V) { setOperand(0, V); } + + + /// getNumDestinations - return the number of possible destinations in this + /// indbr instruction. + unsigned getNumDestinations() const { return getNumOperands()-1; } + + /// getDestination - Return the specified destination. + BasicBlock *getDestination(unsigned i) { return getSuccessor(i); } + const BasicBlock *getDestination(unsigned i) const { return getSuccessor(i); } + + /// addDestination - Add a destination. + /// + void addDestination(BasicBlock *Dest); + + /// removeDestination - This method removes the specified successor from the + /// indbr instruction. + void removeDestination(unsigned i); + + virtual IndBrInst *clone() const; + + unsigned getNumSuccessors() const { return getNumOperands()-1; } + BasicBlock *getSuccessor(unsigned i) const { + return cast(getOperand(i+1)); + } + void setSuccessor(unsigned i, BasicBlock *NewSucc) { + setOperand(i+1, (Value*)NewSucc); + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const IndBrInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::IndBr; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +private: + virtual BasicBlock *getSuccessorV(unsigned idx) const; + virtual unsigned getNumSuccessorsV() const; + virtual void setSuccessorV(unsigned idx, BasicBlock *B); +}; + +template <> +struct OperandTraits : public HungoffOperandTraits<1> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndBrInst, Value) + + +//===----------------------------------------------------------------------===// // InvokeInst Class //===----------------------------------------------------------------------===// Modified: llvm/trunk/include/llvm/Support/InstVisitor.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/InstVisitor.h?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/InstVisitor.h (original) +++ llvm/trunk/include/llvm/Support/InstVisitor.h Tue Oct 27 14:13:16 2009 @@ -160,6 +160,7 @@ RetTy visitReturnInst(ReturnInst &I) { DELEGATE(TerminatorInst);} RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst);} RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst);} + RetTy visitIndBrInst(IndBrInst &I) { DELEGATE(TerminatorInst);} RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnwindInst(UnwindInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);} Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLLexer.cpp (original) +++ llvm/trunk/lib/AsmParser/LLLexer.cpp Tue Oct 27 14:13:16 2009 @@ -645,6 +645,7 @@ INSTKEYWORD(ret, Ret); INSTKEYWORD(br, Br); INSTKEYWORD(switch, Switch); + INSTKEYWORD(indbr, IndBr); INSTKEYWORD(invoke, Invoke); INSTKEYWORD(unwind, Unwind); INSTKEYWORD(unreachable, Unreachable); Modified: llvm/trunk/lib/AsmParser/LLParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) +++ llvm/trunk/lib/AsmParser/LLParser.cpp Tue Oct 27 14:13:16 2009 @@ -2412,6 +2412,18 @@ ParseValue(T, V, PFS); } +bool LLParser::ParseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc, + PerFunctionState &PFS) { + Value *V; + Loc = Lex.getLoc(); + if (ParseTypeAndValue(V, PFS)) return true; + if (!isa(V)) + return Error(Loc, "expected a basic block"); + BB = cast(V); + return false; +} + + /// FunctionHeader /// ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs /// Type GlobalName '(' ArgList ')' OptFuncAttrs OptSection @@ -2719,6 +2731,7 @@ case lltok::kw_ret: return ParseRet(Inst, BB, PFS); case lltok::kw_br: return ParseBr(Inst, PFS); case lltok::kw_switch: return ParseSwitch(Inst, PFS); + case lltok::kw_indbr: return ParseIndBr(Inst, PFS); case lltok::kw_invoke: return ParseInvoke(Inst, PFS); // Binary Operators. case lltok::kw_add: @@ -2922,7 +2935,8 @@ /// ::= 'br' TypeAndValue ',' TypeAndValue ',' TypeAndValue bool LLParser::ParseBr(Instruction *&Inst, PerFunctionState &PFS) { LocTy Loc, Loc2; - Value *Op0, *Op1, *Op2; + Value *Op0; + BasicBlock *Op1, *Op2; if (ParseTypeAndValue(Op0, Loc, PFS)) return true; if (BasicBlock *BB = dyn_cast(Op0)) { @@ -2934,17 +2948,12 @@ return Error(Loc, "branch condition must have 'i1' type"); if (ParseToken(lltok::comma, "expected ',' after branch condition") || - ParseTypeAndValue(Op1, Loc, PFS) || + ParseTypeAndBasicBlock(Op1, Loc, PFS) || ParseToken(lltok::comma, "expected ',' after true destination") || - ParseTypeAndValue(Op2, Loc2, PFS)) + ParseTypeAndBasicBlock(Op2, Loc2, PFS)) return true; - if (!isa(Op1)) - return Error(Loc, "true destination of branch must be a basic block"); - if (!isa(Op2)) - return Error(Loc2, "true destination of branch must be a basic block"); - - Inst = BranchInst::Create(cast(Op1), cast(Op2), Op0); + Inst = BranchInst::Create(Op1, Op2, Op0); return false; } @@ -2955,50 +2964,87 @@ /// ::= (TypeAndValue ',' TypeAndValue)* bool LLParser::ParseSwitch(Instruction *&Inst, PerFunctionState &PFS) { LocTy CondLoc, BBLoc; - Value *Cond, *DefaultBB; + Value *Cond; + BasicBlock *DefaultBB; if (ParseTypeAndValue(Cond, CondLoc, PFS) || ParseToken(lltok::comma, "expected ',' after switch condition") || - ParseTypeAndValue(DefaultBB, BBLoc, PFS) || + ParseTypeAndBasicBlock(DefaultBB, BBLoc, PFS) || ParseToken(lltok::lsquare, "expected '[' with switch table")) return true; if (!isa(Cond->getType())) return Error(CondLoc, "switch condition must have integer type"); - if (!isa(DefaultBB)) - return Error(BBLoc, "default destination must be a basic block"); // Parse the jump table pairs. SmallPtrSet SeenCases; SmallVector, 32> Table; while (Lex.getKind() != lltok::rsquare) { - Value *Constant, *DestBB; + Value *Constant; + BasicBlock *DestBB; if (ParseTypeAndValue(Constant, CondLoc, PFS) || ParseToken(lltok::comma, "expected ',' after case value") || - ParseTypeAndValue(DestBB, BBLoc, PFS)) + ParseTypeAndBasicBlock(DestBB, PFS)) return true; - + if (!SeenCases.insert(Constant)) return Error(CondLoc, "duplicate case value in switch"); if (!isa(Constant)) return Error(CondLoc, "case value is not a constant integer"); - if (!isa(DestBB)) - return Error(BBLoc, "case destination is not a basic block"); - Table.push_back(std::make_pair(cast(Constant), - cast(DestBB))); + Table.push_back(std::make_pair(cast(Constant), DestBB)); } Lex.Lex(); // Eat the ']'. - SwitchInst *SI = SwitchInst::Create(Cond, cast(DefaultBB), - Table.size()); + SwitchInst *SI = SwitchInst::Create(Cond, DefaultBB, Table.size()); for (unsigned i = 0, e = Table.size(); i != e; ++i) SI->addCase(Table[i].first, Table[i].second); Inst = SI; return false; } +/// ParseIndBr +/// Instruction +/// ::= 'indbr' TypeAndValue ',' '[' LabelList ']' +bool LLParser::ParseIndBr(Instruction *&Inst, PerFunctionState &PFS) { + LocTy AddrLoc; + Value *Address; + if (ParseTypeAndValue(Address, AddrLoc, PFS) || + ParseToken(lltok::comma, "expected ',' after indbr address") || + ParseToken(lltok::lsquare, "expected '[' with indbr")) + return true; + + if (!isa(Address->getType())) + return Error(AddrLoc, "indbr address must have pointer type"); + + // Parse the destination list. + SmallVector DestList; + + if (Lex.getKind() != lltok::rsquare) { + BasicBlock *DestBB; + if (ParseTypeAndBasicBlock(DestBB, PFS)) + return true; + DestList.push_back(DestBB); + + while (EatIfPresent(lltok::comma)) { + if (ParseTypeAndBasicBlock(DestBB, PFS)) + return true; + DestList.push_back(DestBB); + } + } + + if (ParseToken(lltok::rsquare, "expected ']' at end of block list")) + return true; + + IndBrInst *IBI = IndBrInst::Create(Address, DestList.size()); + for (unsigned i = 0, e = DestList.size(); i != e; ++i) + IBI->addDestination(DestList[i]); + Inst = IBI; + return false; +} + + /// ParseInvoke /// ::= 'invoke' OptionalCallingConv OptionalAttrs Type Value ParamList /// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue @@ -3011,7 +3057,7 @@ ValID CalleeID; SmallVector ArgList; - Value *NormalBB, *UnwindBB; + BasicBlock *NormalBB, *UnwindBB; if (ParseOptionalCallingConv(CC) || ParseOptionalAttrs(RetAttrs, 1) || ParseType(RetType, RetTypeLoc, true /*void allowed*/) || @@ -3019,16 +3065,11 @@ ParseParameterList(ArgList, PFS) || ParseOptionalAttrs(FnAttrs, 2) || ParseToken(lltok::kw_to, "expected 'to' in invoke") || - ParseTypeAndValue(NormalBB, PFS) || + ParseTypeAndBasicBlock(NormalBB, PFS) || ParseToken(lltok::kw_unwind, "expected 'unwind' in invoke") || - ParseTypeAndValue(UnwindBB, PFS)) + ParseTypeAndBasicBlock(UnwindBB, PFS)) return true; - if (!isa(NormalBB)) - return Error(CallLoc, "normal destination is not a basic block"); - if (!isa(UnwindBB)) - return Error(CallLoc, "unwind destination is not a basic block"); - // If RetType is a non-function pointer type, then this is the short syntax // for the call, which means that RetType is just the return type. Infer the // rest of the function argument types from the arguments that are present. @@ -3096,8 +3137,7 @@ // Finish off the Attributes and check them AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); - InvokeInst *II = InvokeInst::Create(Callee, cast(NormalBB), - cast(UnwindBB), + InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB, Args.begin(), Args.end()); II->setCallingConv(CC); II->setAttributes(PAL); Modified: llvm/trunk/lib/AsmParser/LLParser.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.h (original) +++ llvm/trunk/lib/AsmParser/LLParser.h Tue Oct 27 14:13:16 2009 @@ -230,7 +230,13 @@ Loc = Lex.getLoc(); return ParseTypeAndValue(V, PFS); } - + bool ParseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc, + PerFunctionState &PFS); + bool ParseTypeAndBasicBlock(BasicBlock *&BB, PerFunctionState &PFS) { + LocTy Loc; + return ParseTypeAndBasicBlock(BB, Loc, PFS); + } + struct ParamInfo { LocTy Loc; Value *V; @@ -264,6 +270,7 @@ bool ParseRet(Instruction *&Inst, BasicBlock *BB, PerFunctionState &PFS); bool ParseBr(Instruction *&Inst, PerFunctionState &PFS); bool ParseSwitch(Instruction *&Inst, PerFunctionState &PFS); + bool ParseIndBr(Instruction *&Inst, PerFunctionState &PFS); bool ParseInvoke(Instruction *&Inst, PerFunctionState &PFS); bool ParseArithmetic(Instruction *&I, PerFunctionState &PFS, unsigned Opc, Modified: llvm/trunk/lib/AsmParser/LLToken.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLToken.h (original) +++ llvm/trunk/lib/AsmParser/LLToken.h Tue Oct 27 14:13:16 2009 @@ -111,7 +111,7 @@ kw_fptoui, kw_fptosi, kw_inttoptr, kw_ptrtoint, kw_bitcast, kw_select, kw_va_arg, - kw_ret, kw_br, kw_switch, kw_invoke, kw_unwind, kw_unreachable, + kw_ret, kw_br, kw_switch, kw_indbr, kw_invoke, kw_unwind, kw_unreachable, kw_malloc, kw_alloca, kw_free, kw_load, kw_store, kw_getelementptr, Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Tue Oct 27 14:13:16 2009 @@ -1951,7 +1951,7 @@ } break; } - case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, opval, n, n x ops] + case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...] if (Record.size() < 3 || (Record.size() & 1) == 0) return Error("Invalid SWITCH record"); const Type *OpTy = getTypeByID(Record[0]); @@ -1975,7 +1975,28 @@ I = SI; break; } - + case bitc::FUNC_CODE_INST_INDBR: { // INDBR: [opty, op0, op1, ...] + if (Record.size() < 2) + return Error("Invalid INDBR record"); + const Type *OpTy = getTypeByID(Record[0]); + Value *Address = getFnValueByID(Record[1], OpTy); + if (OpTy == 0 || Address == 0) + return Error("Invalid INDBR record"); + unsigned NumDests = Record.size()-2; + IndBrInst *IBI = IndBrInst::Create(Address, NumDests); + InstructionList.push_back(IBI); + for (unsigned i = 0, e = NumDests; i != e; ++i) { + if (BasicBlock *DestBB = getBasicBlock(Record[2+i])) { + IBI->addDestination(DestBB); + } else { + delete IBI; + return Error("Invalid INDBR record!"); + } + } + I = IBI; + break; + } + case bitc::FUNC_CODE_INST_INVOKE: { // INVOKE: [attrs, cc, normBB, unwindBB, fnty, op0,op1,op2, ...] if (Record.size() < 4) return Error("Invalid INVOKE record"); Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Tue Oct 27 14:13:16 2009 @@ -1001,7 +1001,7 @@ case Instruction::Br: { Code = bitc::FUNC_CODE_INST_BR; - BranchInst &II(cast(I)); + BranchInst &II = cast(I); Vals.push_back(VE.getValueID(II.getSuccessor(0))); if (II.isConditional()) { Vals.push_back(VE.getValueID(II.getSuccessor(1))); @@ -1015,6 +1015,13 @@ for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) Vals.push_back(VE.getValueID(I.getOperand(i))); break; + case Instruction::IndBr: + Code = bitc::FUNC_CODE_INST_INDBR; + Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); + for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) + Vals.push_back(VE.getValueID(I.getOperand(i))); + break; + case Instruction::Invoke: { const InvokeInst *II = cast(&I); const Value *Callee(II->getCalledValue()); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Tue Oct 27 14:13:16 2009 @@ -2131,6 +2131,11 @@ } } +void SelectionDAGLowering::visitIndBr(IndBrInst &I) { + fprintf(stderr, "indbr codegen not implemented yet"); + abort(); +} + void SelectionDAGLowering::visitFSub(User &I) { // -0.0 - X --> fneg Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h Tue Oct 27 14:13:16 2009 @@ -49,6 +49,7 @@ class GCFunctionInfo; class ICmpInst; class IntToPtrInst; +class IndBrInst; class InvokeInst; class InsertElementInst; class InsertValueInst; @@ -448,6 +449,7 @@ void visitRet(ReturnInst &I); void visitBr(BranchInst &I); void visitSwitch(SwitchInst &I); + void visitIndBr(IndBrInst &I); void visitUnreachable(UnreachableInst &I) { /* noop */ } // Helpers for visitSwitch Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/AsmWriter.cpp (original) +++ llvm/trunk/lib/VMCore/AsmWriter.cpp Tue Oct 27 14:13:16 2009 @@ -1832,7 +1832,7 @@ writeOperand(BI.getSuccessor(1), true); } else if (isa(I)) { - // Special case switch statement to get formatting nice and correct... + // Special case switch instruction to get formatting nice and correct. Out << ' '; writeOperand(Operand , true); Out << ", "; @@ -1846,6 +1846,19 @@ writeOperand(I.getOperand(op+1), true); } Out << "\n ]"; + } else if (isa(I)) { + // Special case indbr instruction to get formatting nice and correct. + Out << ' '; + writeOperand(Operand, true); + Out << ", "; + Out << " ["; + + for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) { + if (i != 1) + Out << ", "; + writeOperand(I.getOperand(i), true); + } + Out << ']'; } else if (isa(I)) { Out << ' '; TypePrinter.print(I.getType(), Out); Modified: llvm/trunk/lib/VMCore/Instruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instruction.cpp (original) +++ llvm/trunk/lib/VMCore/Instruction.cpp Tue Oct 27 14:13:16 2009 @@ -103,6 +103,7 @@ case Ret: return "ret"; case Br: return "br"; case Switch: return "switch"; + case IndBr: return "indbr"; case Invoke: return "invoke"; case Unwind: return "unwind"; case Unreachable: return "unreachable"; Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Tue Oct 27 14:13:16 2009 @@ -3086,6 +3086,118 @@ setSuccessor(idx, B); } +//===----------------------------------------------------------------------===// +// SwitchInst Implementation +//===----------------------------------------------------------------------===// + +void IndBrInst::init(Value *Address, unsigned NumDests) { + assert(Address); + ReservedSpace = 1+NumDests; + NumOperands = 1; + OperandList = allocHungoffUses(ReservedSpace); + + OperandList[0] = Address; +} + + +/// resizeOperands - resize operands - This adjusts the length of the operands +/// list according to the following behavior: +/// 1. If NumOps == 0, grow the operand list in response to a push_back style +/// of operation. This grows the number of ops by 2 times. +/// 2. If NumOps > NumOperands, reserve space for NumOps operands. +/// 3. If NumOps == NumOperands, trim the reserved space. +/// +void IndBrInst::resizeOperands(unsigned NumOps) { + unsigned e = getNumOperands(); + if (NumOps == 0) { + NumOps = e*2; + } else if (NumOps*2 > NumOperands) { + // No resize needed. + if (ReservedSpace >= NumOps) return; + } else if (NumOps == NumOperands) { + if (ReservedSpace == NumOps) return; + } else { + return; + } + + ReservedSpace = NumOps; + Use *NewOps = allocHungoffUses(NumOps); + Use *OldOps = OperandList; + for (unsigned i = 0; i != e; ++i) + NewOps[i] = OldOps[i]; + OperandList = NewOps; + if (OldOps) Use::zap(OldOps, OldOps + e, true); +} + +IndBrInst::IndBrInst(Value *Address, unsigned NumCases, + Instruction *InsertBefore) +: TerminatorInst(Type::getVoidTy(Address->getContext()), Instruction::IndBr, + 0, 0, InsertBefore) { + init(Address, NumCases); +} + +IndBrInst::IndBrInst(Value *Address, unsigned NumCases, BasicBlock *InsertAtEnd) +: TerminatorInst(Type::getVoidTy(Address->getContext()), Instruction::IndBr, + 0, 0, InsertAtEnd) { + init(Address, NumCases); +} + +IndBrInst::IndBrInst(const IndBrInst &IBI) + : TerminatorInst(Type::getVoidTy(IBI.getContext()), Instruction::IndBr, + allocHungoffUses(IBI.getNumOperands()), + IBI.getNumOperands()) { + Use *OL = OperandList, *InOL = IBI.OperandList; + for (unsigned i = 0, E = IBI.getNumOperands(); i != E; ++i) + OL[i] = InOL[i]; + SubclassOptionalData = IBI.SubclassOptionalData; +} + +IndBrInst::~IndBrInst() { + dropHungoffUses(OperandList); +} + +/// addDestination - Add a destination. +/// +void IndBrInst::addDestination(BasicBlock *DestBB) { + unsigned OpNo = NumOperands; + if (OpNo+1 > ReservedSpace) + resizeOperands(0); // Get more space! + // Initialize some new operands. + assert(OpNo < ReservedSpace && "Growing didn't work!"); + NumOperands = OpNo+1; + OperandList[OpNo] = DestBB; +} + +/// removeDestination - This method removes the specified successor from the +/// indbr instruction. +void IndBrInst::removeDestination(unsigned idx) { + assert(idx < getNumOperands()-1 && "Successor index out of range!"); + + unsigned NumOps = getNumOperands(); + Use *OL = OperandList; + + // Replace this value with the last one. + OL[idx+1] = OL[NumOps-1]; + + // Nuke the last value. + OL[NumOps-1].set(0); + NumOperands = NumOps-1; +} + +BasicBlock *IndBrInst::getSuccessorV(unsigned idx) const { + return getSuccessor(idx); +} +unsigned IndBrInst::getNumSuccessorsV() const { + return getNumSuccessors(); +} +void IndBrInst::setSuccessorV(unsigned idx, BasicBlock *B) { + setSuccessor(idx, B); +} + +//===----------------------------------------------------------------------===// +// clone() implementations +//===----------------------------------------------------------------------===// + // Define these methods here so vtables don't get emitted into every translation // unit that uses these classes. @@ -3410,6 +3522,15 @@ return New; } +IndBrInst *IndBrInst::clone() const { + IndBrInst *New = new IndBrInst(*this); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) + getContext().pImpl->TheMetadata.ValueIsCloned(this, New); + return New; +} + + InvokeInst *InvokeInst::clone() const { InvokeInst *New = new(getNumOperands()) InvokeInst(*this); New->SubclassOptionalData = SubclassOptionalData; Modified: llvm/trunk/test/Feature/terminators.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/terminators.ll?rev=85274&r1=85273&r2=85274&view=diff ============================================================================== --- llvm/trunk/test/Feature/terminators.ll (original) +++ llvm/trunk/test/Feature/terminators.ll Tue Oct 27 14:13:16 2009 @@ -24,3 +24,14 @@ ret i32 16 } + + +define i32 @indbrtest(i8* %P, i32* %Q) { + indbr i8* %P, [label %BB1, label %BB2, label %BB3] +BB1: + indbr i32* %Q, [] +BB2: + indbr i32* %Q, [label %BB1, label %BB2] +BB3: + ret i32 2 +} From bob.wilson at apple.com Tue Oct 27 14:46:02 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 27 Oct 2009 12:46:02 -0700 Subject: [llvm-commits] r85173 lib/Target/ARM/ARMInstrInfo.td In-Reply-To: <9D52A000-B64B-4EE0-82E3-82B7D193A0E6@apple.com> References: <9D52A000-B64B-4EE0-82E3-82B7D193A0E6@apple.com> Message-ID: <91C44C1D-2111-456F-9B0B-DB8FBF598A73@apple.com> OK. I will remove that. On Oct 27, 2009, at 12:01 PM, Johnny Chen wrote: > Hi Bob, > > For RSCri and RSCrs, it looks like the statement: > > let Inst{20} = 0; > > might be over-specifying it. The fact that both inherit from sI > implies that > they are both ${p} and ${s}. > > Johnny Chen > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From vkutuzov at accesssoftek.com Tue Oct 27 14:49:55 2009 From: vkutuzov at accesssoftek.com (Viktor Kutuzov) Date: Tue, 27 Oct 2009 12:49:55 -0700 Subject: [llvm-commits] FW: [PATCH] Fix to pass options from Gold plugin to LTO codegen References: <3FE2DECEF38F9247AE7C8BC1FD2B015F0817022C@ALLISON>, <6AE1604EE3EC5F4296C096518C6B77EEF11643FF@mail.accesssoftek.com><6AE1604EE3EC5F4296C096518C6B77EEF1163385@mail.accesssoftek.com><4AE250D1.4090403@mxc.ca> <4AE67CEB.6010404@mxc.ca> Message-ID: <45894BE6012542EF9E5CF87A4A757C5B@andreic6e7fe55> Please find attached the updated patch. Is it Ok to submit? Viktor ----- Original Message ----- From: "Nick Lewycky" To: "Viktor Kutuzov" Cc: "Commit Messages and Patches for LLVM" Sent: Monday, October 26, 2009 9:54 PM Subject: Re: [llvm-commits] FW: [PATCH] Fix to pass options from Gold plugin to LTO codegen Viktor Kutuzov wrote: > Hello Nick, > Thanks for the review. > > Please find the updated patch attached. > > I didn't remove the lto_codegen_debug_options yet, just marked it as > deprecated. > It is actually used in Ada, in files > > bindings/ada/llvm/llvm_linktimeoptimizer_wrap.cxx > bindings/ada/llvm/llvm_link_time_optimizer-binding.ads Bah, then it's too late. We released 2.6 with this API which means that it's fixed in stone forever. All of the C API is like that, we will never break backwards-compatibility on the C API. Well, given that, why not just call lto_codegen_debug_options? The comment makes it clear that it's "used to pass extra options to the code generator" and that's just what we're doing. > Edward, is this fine to use lto_codegen_set_options there instead? > >> And that would be even better if it took an argc+argv pair > > Gold plug-in gets all arguments from gold one by one. > It is not a big dial to construct argc+argv pair there and pass it down > to the LTO, but LTO internally keeps a vector of char*, so, argc+argv > doesn't make much sense unless we want to replace that vector with > argc+argv pair as well and to change setCodeGenOptions behavior to set > options instead of add them. Sure, given that lto_codegen_debug_options takes one option at a time and we're wedded to this API then we may as well use it. Please send another patch without the new "lto_codegen_set_options" function by calling the "lto_codegen_debug_options" function instead. The changes to gold-plugin.cpp look great to me! Nick > If this is fine with everyone, I can prepare this patch, but would > prefer to make it separately from this one since it would change the API > and will break a backward compatibility. > What do you think? > > Thanks, > Viktor > > ----- Original Message ----- From: "Nick Lewycky" > To: "Viktor Kutuzov" > Cc: "Commit Messages and Patches for LLVM" > Sent: Friday, October 23, 2009 5:56 PM > Subject: Re: [llvm-commits] FW: [PATCH] Fix to pass options from Gold > plugin to LTO codegen > > > Viktor Kutuzov wrote: >> Hello everyone, >> >> Please find the patch attached. >> This should fix the issue when gold plugin doesn't pass the >> -plugin-opt options down to the LTO codegen. >> See the thread "[LLVMdev] getting gold plugin to work?" for more details. >> >> This is the second try. >> It looks like the first one was bounced, not sure why. >> Sorry if anyone will get it twise. > > Hi Viktor, this looks like the same patch I already reviewed here: > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20091019/089467.html > > > To reiterate: > "What's the difference between setCodeGenDebugOptions and > setCodeGenOption? It looks like they should be merged into one then > exposed by lto_codegen_set_option. And that would be even better if it > took an argc+argv pair, even if that's a little harder to construct from > the gold plugin, many option parsing packages work by removing the > options they recognize from argc+argv and leaving the rest in place." > > Nick > > > ------------------------------------------------------------------------ > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-gold-plugin-process_command_line.diff Type: application/octet-stream Size: 3902 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091027/84086969/attachment.obj From bob.wilson at apple.com Tue Oct 27 14:52:03 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 27 Oct 2009 19:52:03 -0000 Subject: [llvm-commits] [llvm] r85280 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Message-ID: <200910271952.n9RJq3c8011794@zion.cs.uiuc.edu> Author: bwilson Date: Tue Oct 27 14:52:03 2009 New Revision: 85280 URL: http://llvm.org/viewvc/llvm-project?rev=85280&view=rev Log: Do not clear the "S" bit for RSCri and RSCrs. They inherit from the "sI" instruction format that already takes care of setting this. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=85280&r1=85279&r2=85280&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Oct 27 14:52:03 2009 @@ -1131,7 +1131,6 @@ DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b", [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>, Requires<[IsARM, CarryDefIsUnused]> { - let Inst{20} = 0; let Inst{25} = 1; } def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), @@ -1140,7 +1139,6 @@ Requires<[IsARM, CarryDefIsUnused]> { let Inst{4} = 1; let Inst{7} = 0; - let Inst{20} = 0; let Inst{25} = 0; } } From evan.cheng at apple.com Tue Oct 27 14:56:55 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 27 Oct 2009 19:56:55 -0000 Subject: [llvm-commits] [llvm] r85281 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/TargetLowering.cpp lib/Target/Alpha/AlphaISelLowering.cpp lib/Target/Alpha/AlphaISelLowering.h lib/Target/Mips/MipsISelLowering.cpp lib/Target/Mips/MipsISelLowering.h lib/Target/SystemZ/SystemZISelLowering.cpp lib/Target/SystemZ/SystemZISelLowering.h lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h Message-ID: <200910271956.n9RJuuXU012003@zion.cs.uiuc.edu> Author: evancheng Date: Tue Oct 27 14:56:55 2009 New Revision: 85281 URL: http://llvm.org/viewvc/llvm-project?rev=85281&view=rev Log: Do away with addLegalFPImmediate. Add a target hook isFPImmLegal which returns true if the fp immediate can be natively codegened by target. Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp llvm/trunk/lib/Target/Mips/MipsISelLowering.h llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=85281&r1=85280&r2=85281&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Tue Oct 27 14:56:55 2009 @@ -325,12 +325,11 @@ /// scalarizing vs using the wider vector type. virtual EVT getWidenVectorType(EVT VT) const; - typedef std::vector::const_iterator legal_fpimm_iterator; - legal_fpimm_iterator legal_fpimm_begin() const { - return LegalFPImmediates.begin(); - } - legal_fpimm_iterator legal_fpimm_end() const { - return LegalFPImmediates.end(); + /// isFPImmLegal - Returns true if the target can instruction select the + /// specified FP immediate natively. If false, the legalizer will materialize + /// the FP immediate as a load from a constant pool. + virtual bool isFPImmLegal(const APFloat &Imm) const { + return false; } /// isShuffleMaskLegal - Targets can use this to indicate that they only @@ -1051,12 +1050,6 @@ PromoteToType[std::make_pair(Opc, OrigVT.SimpleTy)] = DestVT.SimpleTy; } - /// addLegalFPImmediate - Indicate that this target can instruction select - /// the specified FP immediate natively. - void addLegalFPImmediate(const APFloat& Imm) { - LegalFPImmediates.push_back(Imm); - } - /// setTargetDAGCombine - Targets should invoke this method for each target /// independent node that they want to provide a custom DAG combiner for by /// implementing the PerformDAGCombine virtual method. @@ -1696,8 +1689,6 @@ ValueTypeActionImpl ValueTypeActions; - std::vector LegalFPImmediates; - std::vector > AvailableRegClasses; /// TargetDAGCombineArray - Targets can specify ISD nodes that they would Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=85281&r1=85280&r2=85281&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Oct 27 14:56:55 2009 @@ -2573,16 +2573,8 @@ case ISD::ConstantFP: { ConstantFPSDNode *CFP = cast(Node); // Check to see if this FP immediate is already legal. - bool isLegal = false; - for (TargetLowering::legal_fpimm_iterator I = TLI.legal_fpimm_begin(), - E = TLI.legal_fpimm_end(); I != E; ++I) { - if (CFP->isExactlyValue(*I)) { - isLegal = true; - break; - } - } // If this is a legal constant, turn it into a TargetConstantFP node. - if (isLegal) + if (TLI.isFPImmLegal(CFP->getValueAPF())) Results.push_back(SDValue(Node, 0)); else Results.push_back(ExpandConstantFP(CFP, true, DAG, TLI)); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=85281&r1=85280&r2=85281&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Tue Oct 27 14:56:55 2009 @@ -481,7 +481,7 @@ setOperationAction(ISD::PREFETCH, MVT::Other, Expand); // ConstantFP nodes default to expand. Targets can either change this to - // Legal, in which case all fp constants are legal, or use addLegalFPImmediate + // Legal, in which case all fp constants are legal, or use isFPImmLegal() // to optimize expansions for certain constants. setOperationAction(ISD::ConstantFP, MVT::f32, Expand); setOperationAction(ISD::ConstantFP, MVT::f64, Expand); Modified: llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp?rev=85281&r1=85280&r2=85281&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp Tue Oct 27 14:56:55 2009 @@ -157,11 +157,6 @@ setStackPointerRegisterToSaveRestore(Alpha::R30); - addLegalFPImmediate(APFloat(+0.0)); //F31 - addLegalFPImmediate(APFloat(+0.0f)); //F31 - addLegalFPImmediate(APFloat(-0.0)); //-F31 - addLegalFPImmediate(APFloat(-0.0f)); //-F31 - setJumpBufSize(272); setJumpBufAlignment(16); @@ -919,3 +914,11 @@ // The Alpha target isn't yet aware of offsets. return false; } + +bool AlphaTargetLowering::isFPImmLegal(const APFloat &Imm) const { + // +0.0 F31 + // +0.0f F31 + // -0.0 -F31 + // -0.0f -F31 + return Imm.isZero() || Imm.isNegZero(); +} Modified: llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h?rev=85281&r1=85280&r2=85281&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h (original) +++ llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h Tue Oct 27 14:56:55 2009 @@ -102,6 +102,11 @@ /// getFunctionAlignment - Return the Log2 alignment of this function. virtual unsigned getFunctionAlignment(const Function *F) const; + /// isFPImmLegal - Returns true if the target can instruction select the + /// specified FP immediate natively. If false, the legalizer will + /// materialize the FP immediate as a load from a constant pool. + virtual bool isFPImmLegal(const APFloat &Imm) const; + private: // Helpers for custom lowering. void LowerVAARG(SDNode *N, SDValue &Chain, SDValue &DataPtr, Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=85281&r1=85280&r2=85281&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Tue Oct 27 14:56:55 2009 @@ -72,9 +72,6 @@ if (!Subtarget->isFP64bit()) addRegisterClass(MVT::f64, Mips::AFGR64RegisterClass); - // Legal fp constants - addLegalFPImmediate(APFloat(+0.0f)); - // Load extented operations for i1 types must be promoted setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); @@ -1224,3 +1221,7 @@ // The Mips target isn't yet aware of offsets. return false; } + +bool MipsTargetLowering::isFPImmLegal(const APFloat &Imm) const { + return Imm.isZero(); +} Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.h?rev=85281&r1=85280&r2=85281&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.h (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.h Tue Oct 27 14:56:55 2009 @@ -146,6 +146,11 @@ EVT VT) const; virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const; + + /// isFPImmLegal - Returns true if the target can instruction select the + /// specified FP immediate natively. If false, the legalizer will + /// materialize the FP immediate as a load from a constant pool. + virtual bool isFPImmLegal(const APFloat &Imm) const; }; } Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp?rev=85281&r1=85280&r2=85281&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp Tue Oct 27 14:56:55 2009 @@ -53,11 +53,6 @@ if (!UseSoftFloat) { addRegisterClass(MVT::f32, SystemZ::FP32RegisterClass); addRegisterClass(MVT::f64, SystemZ::FP64RegisterClass); - - addLegalFPImmediate(APFloat(+0.0)); // lzer - addLegalFPImmediate(APFloat(+0.0f)); // lzdr - addLegalFPImmediate(APFloat(-0.0)); // lzer + lner - addLegalFPImmediate(APFloat(-0.0f)); // lzdr + lndr } // Compute derived properties from the register classes @@ -169,6 +164,17 @@ } } +bool SystemZTargetLowering::isFPImmLegal(const APFloat &Imm) const { + if (UseSoftFloat) + return false; + + // +0.0 lzer + // +0.0f lzdr + // -0.0 lzer + lner + // -0.0f lzdr + lndr + return Imm.isZero() || Imm.isNegZero(); +} + //===----------------------------------------------------------------------===// // SystemZ Inline Assembly Support //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h?rev=85281&r1=85280&r2=85281&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h Tue Oct 27 14:56:55 2009 @@ -89,6 +89,11 @@ MachineBasicBlock *BB, DenseMap *EM) const; + /// isFPImmLegal - Returns true if the target can instruction select the + /// specified FP immediate natively. If false, the legalizer will + /// materialize the FP immediate as a load from a constant pool. + virtual bool isFPImmLegal(const APFloat &Imm) const; + private: SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool isVarArg, Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=85281&r1=85280&r2=85281&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Oct 27 14:56:55 2009 @@ -2310,6 +2310,17 @@ } } +/// isFPImmLegal - Returns true if the target can instruction select the +/// specified FP immediate natively. If false, the legalizer will +/// materialize the FP immediate as a load from a constant pool. +bool X86TargetLowering::isFPImmLegal(const APFloat &Imm) const { + for (unsigned i = 0, e = LegalFPImmediates.size(); i != e; ++i) { + if (Imm.bitwiseIsEqual(LegalFPImmediates[i])) + return true; + } + return false; +} + /// isUndefOrInRange - Return true if Val is undef or if its value falls within /// the specified range (L, H]. static bool isUndefOrInRange(int Val, int Low, int Hi) { Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=85281&r1=85280&r2=85281&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Tue Oct 27 14:56:55 2009 @@ -499,6 +499,11 @@ /// from i32 to i8 but not from i32 to i16. virtual bool isNarrowingProfitable(EVT VT1, EVT VT2) const; + /// isFPImmLegal - Returns true if the target can instruction select the + /// specified FP immediate natively. If false, the legalizer will + /// materialize the FP immediate as a load from a constant pool. + virtual bool isFPImmLegal(const APFloat &Imm) const; + /// isShuffleMaskLegal - Targets can use this to indicate that they only /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask @@ -584,6 +589,15 @@ bool X86ScalarSSEf32; bool X86ScalarSSEf64; + /// LegalFPImmediates - A list of legal fp immediates. + std::vector LegalFPImmediates; + + /// addLegalFPImmediate - Indicate that this x86 target can instruction + /// select the specified FP immediate natively. + void addLegalFPImmediate(const APFloat& Imm) { + LegalFPImmediates.push_back(Imm); + } + SDValue LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Ins, From ofv at wanadoo.es Tue Oct 27 14:57:30 2009 From: ofv at wanadoo.es (Oscar Fuentes) Date: Tue, 27 Oct 2009 19:57:30 -0000 Subject: [llvm-commits] [llvm] r85282 - /llvm/trunk/CMakeLists.txt Message-ID: <200910271957.n9RJvUV7012027@zion.cs.uiuc.edu> Author: ofv Date: Tue Oct 27 14:57:29 2009 New Revision: 85282 URL: http://llvm.org/viewvc/llvm-project?rev=85282&view=rev Log: Rather than excluding quite some things, and still installing CMakeLists.txt, Makefiles, ... it's better to whitelist what we really want to install. Patch by Ingmar Vanhassel! Modified: llvm/trunk/CMakeLists.txt Modified: llvm/trunk/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/CMakeLists.txt?rev=85282&r1=85281&r2=85282&view=diff ============================================================================== --- llvm/trunk/CMakeLists.txt (original) +++ llvm/trunk/CMakeLists.txt Tue Oct 27 14:57:29 2009 @@ -319,16 +319,23 @@ add_subdirectory(examples) endif () -install(DIRECTORY include - DESTINATION . +install(DIRECTORY include/ + DESTINATION include + FILES_MATCHING + PATTERN "*.h" + PATTERN "*.td" PATTERN ".svn" EXCLUDE - PATTERN "*.cmake" EXCLUDE - PATTERN "*.in" EXCLUDE - PATTERN "*.tmp" EXCLUDE ) -install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include - DESTINATION . +install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/ + DESTINATION include + FILES_MATCHING + PATTERN "*.def" + PATTERN "*.h" + PATTERN "*.gen" + # Exclude include/llvm/CMakeFiles/intrinsics_gen.dir, matched by "*.def" + PATTERN "CMakeFiles" EXCLUDE + PATTERN ".svn" EXCLUDE ) # TODO: make and install documentation. From mrs at apple.com Tue Oct 27 14:59:28 2009 From: mrs at apple.com (Mike Stump) Date: Tue, 27 Oct 2009 12:59:28 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r85190 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: <200910270053.n9R0rkqP015550@zion.cs.uiuc.edu> References: <200910270053.n9R0rkqP015550@zion.cs.uiuc.edu> Message-ID: <5A13215A-BF8F-4FF7-99AA-F7D9A762C62D@apple.com> On Oct 26, 2009, at 5:53 PM, Eric Christopher wrote: > Author: echristo > Date: Mon Oct 26 19:53:46 2009 > New Revision: 85190 > > URL: http://llvm.org/viewvc/llvm-project?rev=85190&view=rev > Log: > Use new objectsize intrinsic for object size checking instead of > folding to "don't know" immediately. > + const Type* Ty[3]; > + Ty[0] = ConvertType(TREE_TYPE(exp)); > + Ty[1] = Type::getInt8PtrTy(Context); > + Ty[2] = Type::getInt32Ty(Context); > + > + Result = Builder.CreateCall(Intrinsic::getDeclaration(TheModule, > + Intrinsic::objectsize, > + Ty, > + 1), Given that there is a 1 here, you don't need Ty[1], nor Ty[2] above. From dalej at apple.com Tue Oct 27 15:01:54 2009 From: dalej at apple.com (Dale Johannesen) Date: Tue, 27 Oct 2009 20:01:54 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r85284 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200910272001.n9RK1sBU012222@zion.cs.uiuc.edu> Author: johannes Date: Tue Oct 27 15:01:53 2009 New Revision: 85284 URL: http://llvm.org/viewvc/llvm-project?rev=85284&view=rev Log: We already had a hack to do this: // G++ has various bugs handling {} initializers where it doesn't // synthesize a zero node of the right type. Instead of figuring out G++, // just hack around it by special casing zero and allowing it to be the // wrong size. but the handling was limited to bitfields. It turns out this can happen with non-bitfields as well; extend it to cover that case. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=85284&r1=85283&r2=85284&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Oct 27 15:01:53 2009 @@ -7774,6 +7774,23 @@ uint64_t GCCFieldOffsetInBits = getFieldOffsetInBits(Field); NextField = TREE_CHAIN(Field); + uint64_t FieldSizeInBits = getInt64(DECL_SIZE(Field), true); + uint64_t ValueSizeInBits = Val->getType()->getPrimitiveSizeInBits(); + ConstantInt *ValC = dyn_cast(Val); + if (ValC && ValC->isZero()) { + // G++ has various bugs handling {} initializers where it doesn't + // synthesize a zero node of the right type. Instead of figuring out G++, + // just hack around it by special casing zero and allowing it to be the + // wrong size. + if (ValueSizeInBits != FieldSizeInBits) { + APInt ValAsInt = ValC->getValue(); + ValC = ConstantInt::get(Context, ValueSizeInBits < FieldSizeInBits ? + ValAsInt.zext(FieldSizeInBits) : + ValAsInt.trunc(FieldSizeInBits)); + ValueSizeInBits = FieldSizeInBits; + Val = ValC; + } + } // If this is a non-bitfield value, just slap it onto the end of the struct // with the appropriate padding etc. If it is a bitfield, we have more @@ -7783,20 +7800,7 @@ else { // Bitfields can only be initialized with constants (integer constant // expressions). - ConstantInt *ValC = cast(Val); - uint64_t FieldSizeInBits = getInt64(DECL_SIZE(Field), true); - uint64_t ValueSizeInBits = Val->getType()->getPrimitiveSizeInBits(); - - // G++ has various bugs handling {} initializers where it doesn't - // synthesize a zero node of the right type. Instead of figuring out G++, - // just hack around it by special casing zero and allowing it to be the - // wrong size. - if (ValueSizeInBits < FieldSizeInBits && ValC->isZero()) { - APInt ValAsInt = ValC->getValue(); - ValC = ConstantInt::get(Context, ValAsInt.zext(FieldSizeInBits)); - ValueSizeInBits = FieldSizeInBits; - } - + assert(ValC); assert(ValueSizeInBits >= FieldSizeInBits && "disagreement between LLVM and GCC on bitfield size"); if (ValueSizeInBits != FieldSizeInBits) { From ofv at wanadoo.es Tue Oct 27 15:04:23 2009 From: ofv at wanadoo.es (Oscar Fuentes) Date: Tue, 27 Oct 2009 20:04:23 -0000 Subject: [llvm-commits] [llvm] r85285 - /llvm/trunk/CMakeLists.txt Message-ID: <200910272004.n9RK4Nmi012327@zion.cs.uiuc.edu> Author: ofv Date: Tue Oct 27 15:04:22 2009 New Revision: 85285 URL: http://llvm.org/viewvc/llvm-project?rev=85285&view=rev Log: CMake: Install .inc files too. Modified: llvm/trunk/CMakeLists.txt Modified: llvm/trunk/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/CMakeLists.txt?rev=85285&r1=85284&r2=85285&view=diff ============================================================================== --- llvm/trunk/CMakeLists.txt (original) +++ llvm/trunk/CMakeLists.txt Tue Oct 27 15:04:22 2009 @@ -324,6 +324,7 @@ FILES_MATCHING PATTERN "*.h" PATTERN "*.td" + PATTERN "*.inc" PATTERN ".svn" EXCLUDE ) @@ -333,6 +334,7 @@ PATTERN "*.def" PATTERN "*.h" PATTERN "*.gen" + PATTERN "*.inc" # Exclude include/llvm/CMakeFiles/intrinsics_gen.dir, matched by "*.def" PATTERN "CMakeFiles" EXCLUDE PATTERN ".svn" EXCLUDE From vhernandez at apple.com Tue Oct 27 15:05:50 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Tue, 27 Oct 2009 20:05:50 -0000 Subject: [llvm-commits] [llvm] r85286 - in /llvm/trunk: include/llvm/Analysis/ lib/Analysis/ lib/Analysis/IPA/ lib/Transforms/IPO/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ Message-ID: <200910272005.n9RK5pgR012410@zion.cs.uiuc.edu> Author: hernande Date: Tue Oct 27 15:05:49 2009 New Revision: 85286 URL: http://llvm.org/viewvc/llvm-project?rev=85286&view=rev Log: Rename MallocFreeHelper as MemoryBuiltins Added: llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h - copied, changed from r85266, llvm/trunk/include/llvm/Analysis/MallocFreeHelper.h llvm/trunk/lib/Analysis/MemoryBuiltins.cpp - copied, changed from r85266, llvm/trunk/lib/Analysis/MallocFreeHelper.cpp Removed: llvm/trunk/include/llvm/Analysis/MallocFreeHelper.h llvm/trunk/lib/Analysis/MallocFreeHelper.cpp Modified: llvm/trunk/lib/Analysis/AliasSetTracker.cpp llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp llvm/trunk/lib/Analysis/CMakeLists.txt llvm/trunk/lib/Analysis/CaptureTracking.cpp llvm/trunk/lib/Analysis/IPA/Andersens.cpp llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/Analysis/PointerTracking.cpp llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/lib/Transforms/Scalar/SCCP.cpp llvm/trunk/lib/Transforms/Utils/Local.cpp llvm/trunk/lib/VMCore/Instruction.cpp Removed: llvm/trunk/include/llvm/Analysis/MallocFreeHelper.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MallocFreeHelper.h?rev=85285&view=auto ============================================================================== --- llvm/trunk/include/llvm/Analysis/MallocFreeHelper.h (original) +++ llvm/trunk/include/llvm/Analysis/MallocFreeHelper.h (removed) @@ -1,93 +0,0 @@ -//===- llvm/Analysis/MallocFreeHelper.h - Identify malloc/free --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This family of functions identifies calls to malloc, bitcasts of malloc -// calls, and the types and array sizes associated with them. It also -// identifies calls to the free builtin. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ANALYSIS_MALLOCHELPER_H -#define LLVM_ANALYSIS_MALLOCHELPER_H - -namespace llvm { -class CallInst; -class LLVMContext; -class PointerType; -class TargetData; -class Type; -class Value; - -//===----------------------------------------------------------------------===// -// malloc Call Utility Functions. -// - -/// isMalloc - Returns true if the value is either a malloc call or a bitcast of -/// the result of a malloc call -bool isMalloc(const Value* I); - -/// extractMallocCall - Returns the corresponding CallInst if the instruction -/// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we -/// ignore InvokeInst here. -const CallInst* extractMallocCall(const Value* I); -CallInst* extractMallocCall(Value* I); - -/// extractMallocCallFromBitCast - Returns the corresponding CallInst if the -/// instruction is a bitcast of the result of a malloc call. -const CallInst* extractMallocCallFromBitCast(const Value* I); -CallInst* extractMallocCallFromBitCast(Value* I); - -/// isArrayMalloc - Returns the corresponding CallInst if the instruction -/// matches the malloc call IR generated by CallInst::CreateMalloc(). This -/// means that it is a malloc call with one bitcast use AND the malloc call's -/// size argument is: -/// 1. a constant not equal to the size of the malloced type -/// or -/// 2. the result of a multiplication by the size of the malloced type -/// Otherwise it returns NULL. -/// The unique bitcast is needed to determine the type/size of the array -/// allocation. -CallInst* isArrayMalloc(Value* I, LLVMContext &Context, const TargetData* TD); -const CallInst* isArrayMalloc(const Value* I, LLVMContext &Context, - const TargetData* TD); - -/// getMallocType - Returns the PointerType resulting from the malloc call. -/// This PointerType is the result type of the call's only bitcast use. -/// If there is no unique bitcast use, then return NULL. -const PointerType* getMallocType(const CallInst* CI); - -/// getMallocAllocatedType - Returns the Type allocated by malloc call. This -/// Type is the result type of the call's only bitcast use. If there is no -/// unique bitcast use, then return NULL. -const Type* getMallocAllocatedType(const CallInst* CI); - -/// getMallocArraySize - Returns the array size of a malloc call. For array -/// mallocs, the size is computated in 1 of 3 ways: -/// 1. If the element type is of size 1, then array size is the argument to -/// malloc. -/// 2. Else if the malloc's argument is a constant, the array size is that -/// argument divided by the element type's size. -/// 3. Else the malloc argument must be a multiplication and the array size is -/// the first operand of the multiplication. -/// For non-array mallocs, the computed size is constant 1. -/// This function returns NULL for all mallocs whose array size cannot be -/// determined. -Value* getMallocArraySize(CallInst* CI, LLVMContext &Context, - const TargetData* TD); - -//===----------------------------------------------------------------------===// -// free Call Utility Functions. -// - -/// isFreeCall - Returns true if the the value is a call to the builtin free() -bool isFreeCall(const Value* I); - -} // End llvm namespace - -#endif Copied: llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h (from r85266, llvm/trunk/include/llvm/Analysis/MallocFreeHelper.h) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h?p2=llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h&p1=llvm/trunk/include/llvm/Analysis/MallocFreeHelper.h&r1=85266&r2=85286&rev=85286&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MallocFreeHelper.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h Tue Oct 27 15:05:49 2009 @@ -1,4 +1,4 @@ -//===- llvm/Analysis/MallocFreeHelper.h - Identify malloc/free --*- C++ -*-===// +//===- llvm/Analysis/MemoryBuiltins.h- Calls to memory builtins -*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// // -// This family of functions identifies calls to malloc, bitcasts of malloc -// calls, and the types and array sizes associated with them. It also -// identifies calls to the free builtin. +// This family of functions identifies calls to builtin functions that allocate +// or free memory. // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_MALLOCHELPER_H -#define LLVM_ANALYSIS_MALLOCHELPER_H +#ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H +#define LLVM_ANALYSIS_MEMORYBUILTINS_H namespace llvm { class CallInst; Modified: llvm/trunk/lib/Analysis/AliasSetTracker.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasSetTracker.cpp?rev=85286&r1=85285&r2=85286&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/AliasSetTracker.cpp (original) +++ llvm/trunk/lib/Analysis/AliasSetTracker.cpp Tue Oct 27 15:05:49 2009 @@ -13,7 +13,7 @@ #include "llvm/Analysis/AliasSetTracker.h" #include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Analysis/MallocFreeHelper.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" #include "llvm/Pass.h" Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=85286&r1=85285&r2=85286&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Tue Oct 27 15:05:49 2009 @@ -15,7 +15,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/CaptureTracking.h" -#include "llvm/Analysis/MallocFreeHelper.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/Passes.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" Modified: llvm/trunk/lib/Analysis/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=85286&r1=85285&r2=85286&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/CMakeLists.txt (original) +++ llvm/trunk/lib/Analysis/CMakeLists.txt Tue Oct 27 15:05:49 2009 @@ -23,7 +23,7 @@ LoopDependenceAnalysis.cpp LoopInfo.cpp LoopPass.cpp - MallocFreeHelper.cpp + MemoryBuiltins.cpp MemoryDependenceAnalysis.cpp PointerTracking.cpp PostDominators.cpp Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CaptureTracking.cpp?rev=85286&r1=85285&r2=85286&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/CaptureTracking.cpp (original) +++ llvm/trunk/lib/Analysis/CaptureTracking.cpp Tue Oct 27 15:05:49 2009 @@ -17,7 +17,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/CaptureTracking.h" -#include "llvm/Analysis/MallocFreeHelper.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Instructions.h" #include "llvm/Value.h" #include "llvm/ADT/SmallSet.h" Modified: llvm/trunk/lib/Analysis/IPA/Andersens.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/Andersens.cpp?rev=85286&r1=85285&r2=85286&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/IPA/Andersens.cpp (original) +++ llvm/trunk/lib/Analysis/IPA/Andersens.cpp Tue Oct 27 15:05:49 2009 @@ -63,7 +63,7 @@ #include "llvm/Support/InstIterator.h" #include "llvm/Support/InstVisitor.h" #include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Analysis/MallocFreeHelper.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/Passes.h" #include "llvm/Support/Debug.h" #include "llvm/System/Atomic.h" Modified: llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp?rev=85286&r1=85285&r2=85286&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp (original) +++ llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp Tue Oct 27 15:05:49 2009 @@ -23,7 +23,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/CallGraph.h" -#include "llvm/Analysis/MallocFreeHelper.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/InstIterator.h" #include "llvm/ADT/Statistic.h" Removed: llvm/trunk/lib/Analysis/MallocFreeHelper.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MallocFreeHelper.cpp?rev=85285&view=auto ============================================================================== --- llvm/trunk/lib/Analysis/MallocFreeHelper.cpp (original) +++ llvm/trunk/lib/Analysis/MallocFreeHelper.cpp (removed) @@ -1,296 +0,0 @@ -//===-- MallocFreeHelper.cpp - Identify calls to malloc and free builtins -===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This family of functions identifies calls to malloc, bitcasts of malloc -// calls, and the types and array sizes associated with them. It also -// identifies calls to the free builtin. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Analysis/MallocFreeHelper.h" -#include "llvm/Constants.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/Analysis/ConstantFolding.h" -using namespace llvm; - -//===----------------------------------------------------------------------===// -// malloc Call Utility Functions. -// - -/// isMalloc - Returns true if the the value is either a malloc call or a -/// bitcast of the result of a malloc call. -bool llvm::isMalloc(const Value* I) { - return extractMallocCall(I) || extractMallocCallFromBitCast(I); -} - -static bool isMallocCall(const CallInst *CI) { - if (!CI) - return false; - - const Module* M = CI->getParent()->getParent()->getParent(); - Function *MallocFunc = M->getFunction("malloc"); - - if (CI->getOperand(0) != MallocFunc) - return false; - - // Check malloc prototype. - // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin - // attribute will exist. - const FunctionType *FTy = MallocFunc->getFunctionType(); - if (FTy->getNumParams() != 1) - return false; - if (IntegerType *ITy = dyn_cast(FTy->param_begin()->get())) { - if (ITy->getBitWidth() != 32 && ITy->getBitWidth() != 64) - return false; - return true; - } - - return false; -} - -/// extractMallocCall - Returns the corresponding CallInst if the instruction -/// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we -/// ignore InvokeInst here. -const CallInst* llvm::extractMallocCall(const Value* I) { - const CallInst *CI = dyn_cast(I); - return (isMallocCall(CI)) ? CI : NULL; -} - -CallInst* llvm::extractMallocCall(Value* I) { - CallInst *CI = dyn_cast(I); - return (isMallocCall(CI)) ? CI : NULL; -} - -static bool isBitCastOfMallocCall(const BitCastInst* BCI) { - if (!BCI) - return false; - - return isMallocCall(dyn_cast(BCI->getOperand(0))); -} - -/// extractMallocCallFromBitCast - Returns the corresponding CallInst if the -/// instruction is a bitcast of the result of a malloc call. -CallInst* llvm::extractMallocCallFromBitCast(Value* I) { - BitCastInst *BCI = dyn_cast(I); - return (isBitCastOfMallocCall(BCI)) ? cast(BCI->getOperand(0)) - : NULL; -} - -const CallInst* llvm::extractMallocCallFromBitCast(const Value* I) { - const BitCastInst *BCI = dyn_cast(I); - return (isBitCastOfMallocCall(BCI)) ? cast(BCI->getOperand(0)) - : NULL; -} - -static bool isArrayMallocHelper(const CallInst *CI, LLVMContext &Context, - const TargetData* TD) { - if (!CI) - return false; - - const Type* T = getMallocAllocatedType(CI); - - // We can only indentify an array malloc if we know the type of the malloc - // call. - if (!T) return false; - - Value* MallocArg = CI->getOperand(1); - Constant *ElementSize = ConstantExpr::getSizeOf(T); - ElementSize = ConstantExpr::getTruncOrBitCast(ElementSize, - MallocArg->getType()); - Constant *FoldedElementSize = ConstantFoldConstantExpression( - cast(ElementSize), - Context, TD); - - - if (isa(MallocArg)) - return (MallocArg != ElementSize); - - BinaryOperator *BI = dyn_cast(MallocArg); - if (!BI) - return false; - - if (BI->getOpcode() == Instruction::Mul) - // ArraySize * ElementSize - if (BI->getOperand(1) == ElementSize || - (FoldedElementSize && BI->getOperand(1) == FoldedElementSize)) - return true; - - // TODO: Detect case where MallocArg mul has been transformed to shl. - - return false; -} - -/// isArrayMalloc - Returns the corresponding CallInst if the instruction -/// matches the malloc call IR generated by CallInst::CreateMalloc(). This -/// means that it is a malloc call with one bitcast use AND the malloc call's -/// size argument is: -/// 1. a constant not equal to the size of the malloced type -/// or -/// 2. the result of a multiplication by the size of the malloced type -/// Otherwise it returns NULL. -/// The unique bitcast is needed to determine the type/size of the array -/// allocation. -CallInst* llvm::isArrayMalloc(Value* I, LLVMContext &Context, - const TargetData* TD) { - CallInst *CI = extractMallocCall(I); - return (isArrayMallocHelper(CI, Context, TD)) ? CI : NULL; -} - -const CallInst* llvm::isArrayMalloc(const Value* I, LLVMContext &Context, - const TargetData* TD) { - const CallInst *CI = extractMallocCall(I); - return (isArrayMallocHelper(CI, Context, TD)) ? CI : NULL; -} - -/// getMallocType - Returns the PointerType resulting from the malloc call. -/// This PointerType is the result type of the call's only bitcast use. -/// If there is no unique bitcast use, then return NULL. -const PointerType* llvm::getMallocType(const CallInst* CI) { - assert(isMalloc(CI) && "GetMallocType and not malloc call"); - - const BitCastInst* BCI = NULL; - - // Determine if CallInst has a bitcast use. - for (Value::use_const_iterator UI = CI->use_begin(), E = CI->use_end(); - UI != E; ) - if ((BCI = dyn_cast(cast(*UI++)))) - break; - - // Malloc call has 1 bitcast use and no other uses, so type is the bitcast's - // destination type. - if (BCI && CI->hasOneUse()) - return cast(BCI->getDestTy()); - - // Malloc call was not bitcast, so type is the malloc function's return type. - if (!BCI) - return cast(CI->getType()); - - // Type could not be determined. - return NULL; -} - -/// getMallocAllocatedType - Returns the Type allocated by malloc call. This -/// Type is the result type of the call's only bitcast use. If there is no -/// unique bitcast use, then return NULL. -const Type* llvm::getMallocAllocatedType(const CallInst* CI) { - const PointerType* PT = getMallocType(CI); - return PT ? PT->getElementType() : NULL; -} - -/// isSafeToGetMallocArraySize - Returns true if the array size of a malloc can -/// be determined. It can be determined in these 3 cases of malloc codegen: -/// 1. non-array malloc: The malloc's size argument is a constant and equals the /// size of the type being malloced. -/// 2. array malloc: This is a malloc call with one bitcast use AND the malloc -/// call's size argument is a constant multiple of the size of the malloced -/// type. -/// 3. array malloc: This is a malloc call with one bitcast use AND the malloc -/// call's size argument is the result of a multiplication by the size of the -/// malloced type. -/// Otherwise returns false. -static bool isSafeToGetMallocArraySize(const CallInst *CI, - LLVMContext &Context, - const TargetData* TD) { - if (!CI) - return false; - - // Type must be known to determine array size. - const Type* T = getMallocAllocatedType(CI); - if (!T) return false; - - Value* MallocArg = CI->getOperand(1); - Constant *ElementSize = ConstantExpr::getSizeOf(T); - ElementSize = ConstantExpr::getTruncOrBitCast(ElementSize, - MallocArg->getType()); - - // First, check if it is a non-array malloc. - if (isa(MallocArg) && (MallocArg == ElementSize)) - return true; - - // Second, check if it can be determined that this is an array malloc. - return isArrayMallocHelper(CI, Context, TD); -} - -/// isConstantOne - Return true only if val is constant int 1. -static bool isConstantOne(Value *val) { - return isa(val) && cast(val)->isOne(); -} - -/// getMallocArraySize - Returns the array size of a malloc call. For array -/// mallocs, the size is computated in 1 of 3 ways: -/// 1. If the element type is of size 1, then array size is the argument to -/// malloc. -/// 2. Else if the malloc's argument is a constant, the array size is that -/// argument divided by the element type's size. -/// 3. Else the malloc argument must be a multiplication and the array size is -/// the first operand of the multiplication. -/// For non-array mallocs, the computed size is constant 1. -/// This function returns NULL for all mallocs whose array size cannot be -/// determined. -Value* llvm::getMallocArraySize(CallInst* CI, LLVMContext &Context, - const TargetData* TD) { - if (!isSafeToGetMallocArraySize(CI, Context, TD)) - return NULL; - - // Match CreateMalloc's use of constant 1 array-size for non-array mallocs. - if (!isArrayMalloc(CI, Context, TD)) - return ConstantInt::get(CI->getOperand(1)->getType(), 1); - - Value* MallocArg = CI->getOperand(1); - assert(getMallocAllocatedType(CI) && "getMallocArraySize and no type"); - Constant *ElementSize = ConstantExpr::getSizeOf(getMallocAllocatedType(CI)); - ElementSize = ConstantExpr::getTruncOrBitCast(ElementSize, - MallocArg->getType()); - - Constant* CO = dyn_cast(MallocArg); - BinaryOperator* BO = dyn_cast(MallocArg); - assert((isConstantOne(ElementSize) || CO || BO) && - "getMallocArraySize and malformed malloc IR"); - - if (isConstantOne(ElementSize)) - return MallocArg; - - if (CO) - return CO->getOperand(0); - - // TODO: Detect case where MallocArg mul has been transformed to shl. - - assert(BO && "getMallocArraySize not constant but not multiplication either"); - return BO->getOperand(0); -} - -//===----------------------------------------------------------------------===// -// free Call Utility Functions. -// - -/// isFreeCall - Returns true if the the value is a call to the builtin free() -bool llvm::isFreeCall(const Value* I) { - const CallInst *CI = dyn_cast(I); - if (!CI) - return false; - - const Module* M = CI->getParent()->getParent()->getParent(); - Function *FreeFunc = M->getFunction("free"); - - if (CI->getOperand(0) != FreeFunc) - return false; - - // Check free prototype. - // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin - // attribute will exist. - const FunctionType *FTy = FreeFunc->getFunctionType(); - if (FTy->getReturnType() != Type::getVoidTy(M->getContext())) - return false; - if (FTy->getNumParams() != 1) - return false; - if (FTy->param_begin()->get() != Type::getInt8PtrTy(M->getContext())) - return false; - - return true; -} Copied: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp (from r85266, llvm/trunk/lib/Analysis/MallocFreeHelper.cpp) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryBuiltins.cpp?p2=llvm/trunk/lib/Analysis/MemoryBuiltins.cpp&p1=llvm/trunk/lib/Analysis/MallocFreeHelper.cpp&r1=85266&r2=85286&rev=85286&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MallocFreeHelper.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Tue Oct 27 15:05:49 2009 @@ -1,4 +1,4 @@ -//===-- MallocFreeHelper.cpp - Identify calls to malloc and free builtins -===// +//===------ MemoryBuiltins.cpp - Identify calls to memory builtins --------===// // // The LLVM Compiler Infrastructure // @@ -7,13 +7,12 @@ // //===----------------------------------------------------------------------===// // -// This family of functions identifies calls to malloc, bitcasts of malloc -// calls, and the types and array sizes associated with them. It also -// identifies calls to the free builtin. +// This family of functions identifies calls to builtin functions that allocate +// or free memory. // //===----------------------------------------------------------------------===// -#include "llvm/Analysis/MallocFreeHelper.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/Module.h" Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=85286&r1=85285&r2=85286&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Tue Oct 27 15:05:49 2009 @@ -20,7 +20,7 @@ #include "llvm/IntrinsicInst.h" #include "llvm/Function.h" #include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Analysis/MallocFreeHelper.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/PredIteratorCache.h" Modified: llvm/trunk/lib/Analysis/PointerTracking.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PointerTracking.cpp?rev=85286&r1=85285&r2=85286&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PointerTracking.cpp (original) +++ llvm/trunk/lib/Analysis/PointerTracking.cpp Tue Oct 27 15:05:49 2009 @@ -13,7 +13,7 @@ #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/LoopInfo.h" -#include "llvm/Analysis/MallocFreeHelper.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/PointerTracking.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" Modified: llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp?rev=85286&r1=85285&r2=85286&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp Tue Oct 27 15:05:49 2009 @@ -26,7 +26,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/CaptureTracking.h" -#include "llvm/Analysis/MallocFreeHelper.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/UniqueVector.h" Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=85286&r1=85285&r2=85286&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Tue Oct 27 15:05:49 2009 @@ -24,7 +24,7 @@ #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Analysis/ConstantFolding.h" -#include "llvm/Analysis/MallocFreeHelper.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/Debug.h" Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=85286&r1=85285&r2=85286&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Tue Oct 27 15:05:49 2009 @@ -26,7 +26,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/Dominators.h" -#include "llvm/Analysis/MallocFreeHelper.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/Local.h" Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=85286&r1=85285&r2=85286&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Tue Oct 27 15:05:49 2009 @@ -33,7 +33,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Analysis/MallocFreeHelper.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Support/CFG.h" #include "llvm/Support/CommandLine.h" Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=85286&r1=85285&r2=85286&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Tue Oct 27 15:05:49 2009 @@ -42,7 +42,7 @@ #include "llvm/GlobalVariable.h" #include "llvm/Operator.h" #include "llvm/Analysis/ConstantFolding.h" -#include "llvm/Analysis/MallocFreeHelper.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=85286&r1=85285&r2=85286&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Tue Oct 27 15:05:49 2009 @@ -30,7 +30,7 @@ #include "llvm/LLVMContext.h" #include "llvm/Pass.h" #include "llvm/Analysis/ConstantFolding.h" -#include "llvm/Analysis/MallocFreeHelper.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Support/CallSite.h" Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=85286&r1=85285&r2=85286&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Tue Oct 27 15:05:49 2009 @@ -24,7 +24,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/DebugInfo.h" -#include "llvm/Analysis/MallocFreeHelper.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ProfileInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/GetElementPtrTypeIterator.h" Modified: llvm/trunk/lib/VMCore/Instruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=85286&r1=85285&r2=85286&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instruction.cpp (original) +++ llvm/trunk/lib/VMCore/Instruction.cpp Tue Oct 27 15:05:49 2009 @@ -303,7 +303,7 @@ return false; } -// Code here matches isFreeCall from MallocFreeHelper, which is not in VMCore. +// Code here matches isFreeCall from MemoryBuiltins, which is not in VMCore. static bool isFreeCall(const Value* I) { const CallInst *CI = dyn_cast(I); if (!CI) @@ -408,7 +408,7 @@ } } -// Code here matches isMalloc from MallocFreeHelper, which is not in VMCore. +// Code here matches isMalloc from MemoryBuiltins, which is not in VMCore. static bool isMalloc(const Value* I) { const CallInst *CI = dyn_cast(I); if (!CI) { From dalej at apple.com Tue Oct 27 15:06:05 2009 From: dalej at apple.com (Dale Johannesen) Date: Tue, 27 Oct 2009 20:06:05 -0000 Subject: [llvm-commits] [llvm] r85287 - /llvm/trunk/test/FrontendC++/2009-10-27-crash.cpp Message-ID: <200910272006.n9RK65AU012439@zion.cs.uiuc.edu> Author: johannes Date: Tue Oct 27 15:06:05 2009 New Revision: 85287 URL: http://llvm.org/viewvc/llvm-project?rev=85287&view=rev Log: Testcase for llvm-gcc patch 85284. Added: llvm/trunk/test/FrontendC++/2009-10-27-crash.cpp Added: llvm/trunk/test/FrontendC++/2009-10-27-crash.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC%2B%2B/2009-10-27-crash.cpp?rev=85287&view=auto ============================================================================== --- llvm/trunk/test/FrontendC++/2009-10-27-crash.cpp (added) +++ llvm/trunk/test/FrontendC++/2009-10-27-crash.cpp Tue Oct 27 15:06:05 2009 @@ -0,0 +1,42 @@ +// RUN: %llvmgxx -emit-llvm -S %s + +typedef struct +{ + unsigned short a : 1; + unsigned short b : 2; + unsigned short c : 1; + unsigned short d : 1; + unsigned short e : 1; + unsigned short f : 1; + unsigned short g : 2; + unsigned short : 7; + union + { + struct + { + unsigned char h : 1; + unsigned char i : 1; + unsigned char j : 1; + unsigned char : 5; + }; + struct + { + unsigned char k : 3; + unsigned char : 5; + }; + }; + unsigned char : 8; +} tt; + +typedef struct +{ + unsigned char s; + tt t; + unsigned int u; +} ttt; + +ttt X = { + 4, + { 0 }, + 55, +}; From clattner at apple.com Tue Oct 27 15:08:07 2009 From: clattner at apple.com (Chris Lattner) Date: Tue, 27 Oct 2009 13:08:07 -0700 Subject: [llvm-commits] [llvm] r85281 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/TargetLowering.cpp lib/Target/Alpha/AlphaISelLowering.cpp lib/Target/Alpha/AlphaISelLowering.h lib/Target/Mips/MipsISelLowering.cpp lib/Target/Mips/MipsISelLowering.h lib/Target/SystemZ/SystemZISelLowering.cpp lib/Target/SystemZ/SystemZISelLowering.h lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h In-Reply-To: <200910271956.n9RJuuXU012003@zion.cs.uiuc.edu> References: <200910271956.n9RJuuXU012003@zion.cs.uiuc.edu> Message-ID: <48349B11-D737-44D0-AAA8-11603EDC8164@apple.com> On Oct 27, 2009, at 12:56 PM, Evan Cheng wrote: > Author: evancheng > Date: Tue Oct 27 14:56:55 2009 > New Revision: 85281 > > URL: http://llvm.org/viewvc/llvm-project?rev=85281&view=rev > Log: > Do away with addLegalFPImmediate. Add a target hook isFPImmLegal > which returns true if the fp immediate can be natively codegened by > target. Nice! -Chris From dalej at apple.com Tue Oct 27 15:12:39 2009 From: dalej at apple.com (Dale Johannesen) Date: Tue, 27 Oct 2009 20:12:39 -0000 Subject: [llvm-commits] [llvm] r85290 - /llvm/trunk/test/FrontendC++/2009-10-27-crash.cpp Message-ID: <200910272012.n9RKCd6T012701@zion.cs.uiuc.edu> Author: johannes Date: Tue Oct 27 15:12:38 2009 New Revision: 85290 URL: http://llvm.org/viewvc/llvm-project?rev=85290&view=rev Log: Add radar number. Modified: llvm/trunk/test/FrontendC++/2009-10-27-crash.cpp Modified: llvm/trunk/test/FrontendC++/2009-10-27-crash.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC%2B%2B/2009-10-27-crash.cpp?rev=85290&r1=85289&r2=85290&view=diff ============================================================================== --- llvm/trunk/test/FrontendC++/2009-10-27-crash.cpp (original) +++ llvm/trunk/test/FrontendC++/2009-10-27-crash.cpp Tue Oct 27 15:12:38 2009 @@ -1,4 +1,5 @@ // RUN: %llvmgxx -emit-llvm -S %s +// Radar 7328944 typedef struct { From clattner at apple.com Tue Oct 27 15:13:05 2009 From: clattner at apple.com (Chris Lattner) Date: Tue, 27 Oct 2009 13:13:05 -0700 Subject: [llvm-commits] [compiler-rt] r85264 - in /compiler-rt/trunk/lib: arm/ i386/ ppc/ x86_64/ In-Reply-To: <200910271750.n9RHoOI1006379@zion.cs.uiuc.edu> References: <200910271750.n9RHoOI1006379@zion.cs.uiuc.edu> Message-ID: <3B80F3C4-8F9B-465B-8633-663E3F830911@apple.com> On Oct 27, 2009, at 10:50 AM, Daniel Dunbar wrote: > Author: ddunbar > Date: Tue Oct 27 12:50:21 2009 > New Revision: 85264 > > URL: http://llvm.org/viewvc/llvm-project?rev=85264&view=rev > Log: > Switch to using DEFINE_COMPILERRT_[PRIVATE_]FUNCTION to define > function symbols inside .S files. Doesn't this lose a _ on darwin? I think assembly.h needs to use USER_LABEL_PREFIX -Chris From sabre at nondot.org Tue Oct 27 15:27:24 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 20:27:24 -0000 Subject: [llvm-commits] [llvm] r85294 - /llvm/trunk/docs/LangRef.html Message-ID: <200910272027.n9RKRORl013336@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 15:27:24 2009 New Revision: 85294 URL: http://llvm.org/viewvc/llvm-project?rev=85294&view=rev Log: fix pasto pointed out by Rafael Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=85294&r1=85293&r2=85294&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Tue Oct 27 15:27:24 2009 @@ -2713,7 +2713,7 @@
      Example:
      - switch i8* %Addr, [ label %bb1, label %bb2, label %bb3 ]
      + indbr i8* %Addr, [ label %bb1, label %bb2, label %bb3 ]
       
      From jyasskin at google.com Tue Oct 27 15:30:29 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Tue, 27 Oct 2009 20:30:29 -0000 Subject: [llvm-commits] [llvm] r85295 - in /llvm/trunk: docs/tutorial/LangImpl4.html docs/tutorial/OCamlLangImpl4.html include/llvm/ExecutionEngine/ExecutionEngine.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngine/JIT/JITEmitter.cpp tools/lli/lli.cpp unittests/ExecutionEngine/JIT/JITTest.cpp Message-ID: <200910272030.n9RKUTLG013448@zion.cs.uiuc.edu> Author: jyasskin Date: Tue Oct 27 15:30:28 2009 New Revision: 85295 URL: http://llvm.org/viewvc/llvm-project?rev=85295&view=rev Log: Change the JIT to compile eagerly by default as agreed in http://llvm.org/PR5184, and beef up the comments to describe what both options do and the risks of lazy compilation in the presence of threads. Modified: llvm/trunk/docs/tutorial/LangImpl4.html llvm/trunk/docs/tutorial/OCamlLangImpl4.html llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp llvm/trunk/tools/lli/lli.cpp llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Modified: llvm/trunk/docs/tutorial/LangImpl4.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl4.html?rev=85295&r1=85294&r2=85295&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl4.html (original) +++ llvm/trunk/docs/tutorial/LangImpl4.html Tue Oct 27 15:30:28 2009 @@ -388,24 +388,19 @@
      -

      This illustrates that we can now call user code, but there is something a bit subtle -going on here. Note that we only invoke the JIT on the anonymous functions -that call testfunc, but we never invoked it on testfunc -itself.

      - -

      What actually happened here is that the anonymous function was -JIT'd when requested. When the Kaleidoscope app calls through the function -pointer that is returned, the anonymous function starts executing. It ends up -making the call to the "testfunc" function, and ends up in a stub that invokes -the JIT, lazily, on testfunc. Once the JIT finishes lazily compiling testfunc, -it returns and the code re-executes the call.

      - -

      In summary, the JIT will lazily JIT code, on the fly, as it is needed. The -JIT provides a number of other more advanced interfaces for things like freeing -allocated machine code, rejit'ing functions to update them, etc. However, even -with this simple code, we get some surprisingly powerful capabilities - check -this out (I removed the dump of the anonymous functions, you should get the idea -by now :) :

      +

      This illustrates that we can now call user code, but there is something a bit +subtle going on here. Note that we only invoke the JIT on the anonymous +functions that call testfunc, but we never invoked it +on testfunc itself. What actually happened here is that the JIT +scanned for all non-JIT'd functions transitively called from the anonymous +function and compiled all of them before returning +from getPointerToFunction().

      + +

      The JIT provides a number of other more advanced interfaces for things like +freeing allocated machine code, rejit'ing functions to update them, etc. +However, even with this simple code, we get some surprisingly powerful +capabilities - check this out (I removed the dump of the anonymous functions, +you should get the idea by now :) :

      @@ -453,8 +448,8 @@
       resolved.  It allows you to establish explicit mappings between IR objects and
       addresses (useful for LLVM global variables that you want to map to static
       tables, for example), allows you to dynamically decide on the fly based on the
      -function name, and even allows you to have the JIT abort itself if any lazy
      -compilation is attempted.

      +function name, and even allows you to have the JIT compile functions lazily the +first time they're called.

      One interesting application of this is that we can now extend the language by writing arbitrary C++ code to implement operations. For example, if we add: Modified: llvm/trunk/docs/tutorial/OCamlLangImpl4.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/OCamlLangImpl4.html?rev=85295&r1=85294&r2=85295&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/OCamlLangImpl4.html (original) +++ llvm/trunk/docs/tutorial/OCamlLangImpl4.html Tue Oct 27 15:30:28 2009 @@ -406,22 +406,17 @@

      This illustrates that we can now call user code, but there is something a bit subtle going on here. Note that we only invoke the JIT on the anonymous -functions that call testfunc, but we never invoked it on testfunc -itself.

      - -

      What actually happened here is that the anonymous function was JIT'd when -requested. When the Kaleidoscope app calls through the function pointer that is -returned, the anonymous function starts executing. It ends up making the call -to the "testfunc" function, and ends up in a stub that invokes the JIT, lazily, -on testfunc. Once the JIT finishes lazily compiling testfunc, -it returns and the code re-executes the call.

      - -

      In summary, the JIT will lazily JIT code, on the fly, as it is needed. The -JIT provides a number of other more advanced interfaces for things like freeing -allocated machine code, rejit'ing functions to update them, etc. However, even -with this simple code, we get some surprisingly powerful capabilities - check -this out (I removed the dump of the anonymous functions, you should get the idea -by now :) :

      +functions that call testfunc, but we never invoked it +on testfunc itself. What actually happened here is that the JIT +scanned for all non-JIT'd functions transitively called from the anonymous +function and compiled all of them before returning +from run_function.

      + +

      The JIT provides a number of other more advanced interfaces for things like +freeing allocated machine code, rejit'ing functions to update them, etc. +However, even with this simple code, we get some surprisingly powerful +capabilities - check this out (I removed the dump of the anonymous functions, +you should get the idea by now :) :

      @@ -467,8 +462,8 @@
       get resolved.  It allows you to establish explicit mappings between IR objects
       and addresses (useful for LLVM global variables that you want to map to static
       tables, for example), allows you to dynamically decide on the fly based on the
      -function name, and even allows you to have the JIT abort itself if any lazy
      -compilation is attempted.

      +function name, and even allows you to have the JIT compile functions lazily the +first time they're called.

      One interesting application of this is that we can now extend the language by writing arbitrary C code to implement operations. For example, if we add: Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h?rev=85295&r1=85294&r2=85295&view=diff ============================================================================== --- llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h (original) +++ llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h Tue Oct 27 15:30:28 2009 @@ -88,7 +88,7 @@ class ExecutionEngine { const TargetData *TD; ExecutionEngineState EEState; - bool LazyCompilationDisabled; + bool CompilingLazily; bool GVCompilationDisabled; bool SymbolSearchingDisabled; bool DlsymStubsEnabled; @@ -319,13 +319,24 @@ virtual void RegisterJITEventListener(JITEventListener *) {} virtual void UnregisterJITEventListener(JITEventListener *) {} - /// DisableLazyCompilation - If called, the JIT will abort if lazy compilation - /// is ever attempted. - void DisableLazyCompilation(bool Disabled = true) { - LazyCompilationDisabled = Disabled; + /// EnableLazyCompilation - When lazy compilation is off (the default), the + /// JIT will eagerly compile every function reachable from the argument to + /// getPointerToFunction. If lazy compilation is turned on, the JIT will only + /// compile the one function and emit stubs to compile the rest when they're + /// first called. If lazy compilation is turned off again while some lazy + /// stubs are still around, and one of those stubs is called, the program will + /// abort. + /// + /// In order to safely compile lazily in a threaded program, the user must + /// ensure that 1) only one thread at a time can call any particular lazy + /// stub, and 2) any thread modifying LLVM IR must hold the JIT's lock + /// (ExecutionEngine::lock) or otherwise ensure that no other thread calls a + /// lazy stub. See http://llvm.org/PR5184 for details. + void EnableLazyCompilation(bool Enabled = true) { + CompilingLazily = Enabled; } - bool isLazyCompilationDisabled() const { - return LazyCompilationDisabled; + bool isCompilingLazily() const { + return CompilingLazily; } /// DisableGVCompilation - If called, the JIT will abort if it's asked to Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp?rev=85295&r1=85294&r2=85295&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp Tue Oct 27 15:30:28 2009 @@ -49,7 +49,7 @@ ExecutionEngine::ExecutionEngine(ModuleProvider *P) : EEState(*this), LazyFunctionCreator(0) { - LazyCompilationDisabled = false; + CompilingLazily = false; GVCompilationDisabled = false; SymbolSearchingDisabled = false; DlsymStubsEnabled = false; Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=85295&r1=85294&r2=85295&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Tue Oct 27 15:30:28 2009 @@ -599,7 +599,7 @@ isAlreadyCodeGenerating = false; // If the function referred to another function that had not yet been - // read from bitcode, but we are jitting non-lazily, emit it now. + // read from bitcode, and we are jitting non-lazily, emit it now. while (!jitstate->getPendingFunctions(locked).empty()) { Function *PF = jitstate->getPendingFunctions(locked).back(); jitstate->getPendingFunctions(locked).pop_back(); @@ -616,7 +616,7 @@ // If the JIT is configured to emit info so that dlsym can be used to // rewrite stubs to external globals, do so now. - if (areDlsymStubsEnabled() && isLazyCompilationDisabled()) + if (areDlsymStubsEnabled() && !isCompilingLazily()) updateDlsymStubTable(); } Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=85295&r1=85294&r2=85295&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Tue Oct 27 15:30:28 2009 @@ -295,11 +295,11 @@ void *&Stub = state.getFunctionToStubMap(locked)[F]; if (Stub) return Stub; - // Call the lazy resolver function unless we are JIT'ing non-lazily, in which - // case we must resolve the symbol now. - void *Actual = TheJIT->isLazyCompilationDisabled() - ? (void *)0 : (void *)(intptr_t)LazyResolverFn; - + // Call the lazy resolver function if we are JIT'ing lazily. Otherwise we + // must resolve the symbol now. + void *Actual = TheJIT->isCompilingLazily() + ? (void *)(intptr_t)LazyResolverFn : (void *)0; + // If this is an external declaration, attempt to resolve the address now // to place in the stub. if (F->isDeclaration() && !F->hasNotBeenReadFromBitcode()) { @@ -334,7 +334,7 @@ // If we are JIT'ing non-lazily but need to call a function that does not // exist yet, add it to the JIT's work list so that we can fill in the stub // address later. - if (!Actual && TheJIT->isLazyCompilationDisabled()) + if (!Actual && !TheJIT->isCompilingLazily()) if (!F->isDeclaration() || F->hasNotBeenReadFromBitcode()) TheJIT->addPendingFunction(F); @@ -471,7 +471,7 @@ // Otherwise we don't have it, do lazy compilation now. // If lazy compilation is disabled, emit a useful error message and abort. - if (TheJIT->isLazyCompilationDisabled()) { + if (!TheJIT->isCompilingLazily()) { llvm_report_error("LLVM JIT requested to do lazy compilation of function '" + F->getName() + "' when lazy compiles are disabled!"); } @@ -769,7 +769,7 @@ // mechanism is capable of rewriting the instruction directly, prefer to do // that instead of emitting a stub. This uses the lazy resolver, so is not // legal if lazy compilation is disabled. - if (DoesntNeedStub && !TheJIT->isLazyCompilationDisabled()) + if (DoesntNeedStub && TheJIT->isCompilingLazily()) return Resolver.AddCallbackAtLocation(F, Reference); // Otherwise, we have to emit a stub. Modified: llvm/trunk/tools/lli/lli.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/lli.cpp?rev=85295&r1=85294&r2=85295&view=diff ============================================================================== --- llvm/trunk/tools/lli/lli.cpp (original) +++ llvm/trunk/tools/lli/lli.cpp Tue Oct 27 15:30:28 2009 @@ -165,8 +165,7 @@ EE->RegisterJITEventListener(createOProfileJITEventListener()); - if (NoLazyCompilation) - EE->DisableLazyCompilation(); + EE->EnableLazyCompilation(!NoLazyCompilation); // If the user specifically requested an argv[0] to pass into the program, // do it now. Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=85295&r1=85294&r2=85295&view=diff ============================================================================== --- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original) +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Tue Oct 27 15:30:28 2009 @@ -304,7 +304,7 @@ Builder.CreateRet(result); TheJIT->EnableDlsymStubs(false); - TheJIT->DisableLazyCompilation(); + TheJIT->EnableLazyCompilation(false); int (*TestFunctionPtr)() = reinterpret_cast( (intptr_t)TheJIT->getPointerToFunction(TestFunction)); // This used to crash in trying to call PlusOne(). @@ -314,7 +314,7 @@ #if !defined(__arm__) && !defined(__powerpc__) && !defined(__ppc__) // Test a function C which calls A and B which call each other. TEST_F(JITTest, NonLazyCompilationStillNeedsStubs) { - TheJIT->DisableLazyCompilation(); + TheJIT->EnableLazyCompilation(false); const FunctionType *Func1Ty = cast(TypeBuilder::get(Context)); @@ -370,7 +370,7 @@ // Regression test for PR5162. This used to trigger an AssertingVH inside the // JIT's Function to stub mapping. TEST_F(JITTest, NonLazyLeaksNoStubs) { - TheJIT->DisableLazyCompilation(); + TheJIT->EnableLazyCompilation(false); // Create two functions with a single basic block each. const FunctionType *FuncTy = From sabre at nondot.org Tue Oct 27 15:42:56 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 20:42:56 -0000 Subject: [llvm-commits] [llvm] r85296 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200910272042.n9RKguhG013972@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 15:42:54 2009 New Revision: 85296 URL: http://llvm.org/viewvc/llvm-project?rev=85296&view=rev Log: don't use stdio Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=85296&r1=85295&r2=85296&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Tue Oct 27 15:42:54 2009 @@ -2132,7 +2132,7 @@ } void SelectionDAGLowering::visitIndBr(IndBrInst &I) { - fprintf(stderr, "indbr codegen not implemented yet"); + errs() << "indbr codegen not implemented yet!\n"; abort(); } From johnny.chen at apple.com Tue Oct 27 15:45:15 2009 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 27 Oct 2009 20:45:15 -0000 Subject: [llvm-commits] [llvm] r85297 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Message-ID: <200910272045.n9RKjFb2014119@zion.cs.uiuc.edu> Author: johnny Date: Tue Oct 27 15:45:15 2009 New Revision: 85297 URL: http://llvm.org/viewvc/llvm-project?rev=85297&view=rev Log: Set condition code bits of BL and BLr9 to 0b1110 (ALways) to distinguish between BL_pred and BLr9_pred. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=85297&r1=85296&r2=85297&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Oct 27 15:45:15 2009 @@ -675,7 +675,9 @@ def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops), IIC_Br, "bl\t${func:call}", [(ARMcall tglobaladdr:$func)]>, - Requires<[IsARM, IsNotDarwin]>; + Requires<[IsARM, IsNotDarwin]> { + let Inst{31-28} = 0b1110; + } def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops), IIC_Br, "bl", "\t${func:call}", @@ -711,7 +713,9 @@ D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops), IIC_Br, "bl\t${func:call}", - [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]>; + [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> { + let Inst{31-28} = 0b1110; + } def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops), IIC_Br, "bl", "\t${func:call}", From dpatel at apple.com Tue Oct 27 15:47:17 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 27 Oct 2009 20:47:17 -0000 Subject: [llvm-commits] [llvm] r85298 - in /llvm/trunk/lib/CodeGen/AsmPrinter: DwarfDebug.cpp DwarfDebug.h Message-ID: <200910272047.n9RKlHOf014248@zion.cs.uiuc.edu> Author: dpatel Date: Tue Oct 27 15:47:17 2009 New Revision: 85298 URL: http://llvm.org/viewvc/llvm-project?rev=85298&view=rev Log: Do not held on to DenseMap slot accross map insertion. The insertion may cause the map to grow rending the slot invalid. Use this opportunity to use ValueMap instead of DenseMap. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=85298&r1=85297&r2=85298&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Oct 27 15:47:17 2009 @@ -1304,15 +1304,16 @@ /// DbgScope *DwarfDebug::getDbgScope(MDNode *N, const MachineInstr *MI, MDNode *InlinedAt) { - DbgScope *&Slot = DbgScopeMap[N]; - if (Slot) return Slot; + ValueMap::iterator VI = DbgScopeMap.find(N); + if (VI != DbgScopeMap.end()) + return VI->second; DbgScope *Parent = NULL; if (InlinedAt) { DILocation IL(InlinedAt); assert (!IL.isNull() && "Invalid InlindAt location!"); - DenseMap::iterator DSI = + ValueMap::iterator DSI = DbgScopeMap.find(IL.getScope().getNode()); assert (DSI != DbgScopeMap.end() && "Unable to find InlineAt scope!"); Parent = DSI->second; @@ -1334,17 +1335,18 @@ assert (0 && "Unexpected scope info"); } - Slot = new DbgScope(Parent, DIDescriptor(N), InlinedAt); - Slot->setFirstInsn(MI); + DbgScope *NScope = new DbgScope(Parent, DIDescriptor(N), InlinedAt); + NScope->setFirstInsn(MI); if (Parent) - Parent->AddScope(Slot); + Parent->AddScope(NScope); else // First function is top level function. if (!FunctionDbgScope) - FunctionDbgScope = Slot; + FunctionDbgScope = NScope; - return Slot; + DbgScopeMap.insert(std::make_pair(N, NScope)); + return NScope; } @@ -1812,7 +1814,7 @@ if (DV.isNull()) continue; unsigned VSlot = VI->second; DbgScope *Scope = NULL; - DenseMap::iterator DSI = + ValueMap::iterator DSI = DbgScopeMap.find(DV.getContext().getNode()); if (DSI != DbgScopeMap.end()) Scope = DSI->second; @@ -1884,8 +1886,10 @@ // If a scope's last instruction is not set then use its child scope's // last instruction as this scope's last instrunction. - for (DenseMap::iterator DI = DbgScopeMap.begin(), + for (ValueMap::iterator DI = DbgScopeMap.begin(), DE = DbgScopeMap.end(); DI != DE; ++DI) { + DbgScope *S = DI->second; + if (!S) continue; assert (DI->second->getFirstInsn() && "Invalid first instruction!"); DI->second->FixInstructionMarkers(); assert (DI->second->getLastInsn() && "Invalid last instruction!"); @@ -1895,10 +1899,10 @@ // and end of a scope respectively. Create an inverse map that list scopes // starts (and ends) with an instruction. One instruction may start (or end) // multiple scopes. - for (DenseMap::iterator DI = DbgScopeMap.begin(), + for (ValueMap::iterator DI = DbgScopeMap.begin(), DE = DbgScopeMap.end(); DI != DE; ++DI) { DbgScope *S = DI->second; - assert (S && "DbgScope is missing!"); + if (!S) continue; const MachineInstr *MI = S->getFirstInsn(); assert (MI && "DbgScope does not have first instruction!"); @@ -2172,7 +2176,7 @@ if (!SP.isNull()) { // SP is inserted into DbgAbstractScopeMap when inlined function // start was recorded by RecordInlineFnStart. - DenseMap::iterator + ValueMap::iterator I = DbgAbstractScopeMap.find(SP.getNode()); if (I != DbgAbstractScopeMap.end()) { InlinedVar = true; @@ -2249,7 +2253,7 @@ LexicalScopeStack.back()->AddConcreteInst(ConcreteScope); // Keep track of the concrete scope that's inlined into this function. - DenseMap >::iterator + ValueMap >::iterator SI = DbgConcreteScopeMap.find(Node); if (SI == DbgConcreteScopeMap.end()) @@ -2258,7 +2262,7 @@ SI->second.push_back(ConcreteScope); // Track the start label for this inlined function. - DenseMap >::iterator + ValueMap >::iterator I = InlineInfo.find(Node); if (I == InlineInfo.end()) @@ -2281,7 +2285,7 @@ DebugTimer->startTimer(); MDNode *Node = SP.getNode(); - DenseMap >::iterator + ValueMap >::iterator I = DbgConcreteScopeMap.find(Node); if (I == DbgConcreteScopeMap.end()) { @@ -2989,7 +2993,7 @@ Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("Dwarf Version"); Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)"); - for (DenseMap >::iterator + for (ValueMap >::iterator I = InlineInfo.begin(), E = InlineInfo.end(); I != E; ++I) { MDNode *Node = I->first; SmallVector &Labels = I->second; Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=85298&r1=85297&r2=85298&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Tue Oct 27 15:47:17 2009 @@ -20,7 +20,7 @@ #include "llvm/CodeGen/MachineLocation.h" #include "llvm/Analysis/DebugInfo.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/ValueMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringMap.h" @@ -139,7 +139,7 @@ DbgScope *FunctionDbgScope; /// DbgScopeMap - Tracks the scopes in the current function. - DenseMap DbgScopeMap; + ValueMap DbgScopeMap; /// ScopedGVs - Tracks global variables that are not at file scope. /// For example void f() { static int b = 42; } @@ -156,16 +156,16 @@ /// DbgAbstractScopeMap - Tracks abstract instance scopes in the current /// function. - DenseMap DbgAbstractScopeMap; + ValueMap DbgAbstractScopeMap; /// DbgConcreteScopeMap - Tracks concrete instance scopes in the current /// function. - DenseMap > DbgConcreteScopeMap; /// InlineInfo - Keep track of inlined functions and their location. This /// information is used to populate debug_inlined section. - DenseMap > InlineInfo; + ValueMap > InlineInfo; /// AbstractInstanceRootMap - Map of abstract instance roots of inlined /// functions. These are subroutine entries that contain a DW_AT_inline From johnny.chen at apple.com Tue Oct 27 15:51:49 2009 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 27 Oct 2009 20:51:49 -0000 Subject: [llvm-commits] [llvm] r85299 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Message-ID: <200910272051.n9RKpnvC014400@zion.cs.uiuc.edu> Author: johnny Date: Tue Oct 27 15:51:49 2009 New Revision: 85299 URL: http://llvm.org/viewvc/llvm-project?rev=85299&view=rev Log: Similar to r85280, do not clear the "S" bit for RSBri and RSBrs. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=85299&r1=85298&r2=85299&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Oct 27 15:51:49 2009 @@ -1099,7 +1099,6 @@ def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iALUi, "rsb", "\t$dst, $a, $b", [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> { - let Inst{20} = 0; let Inst{25} = 1; } @@ -1108,7 +1107,6 @@ [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> { let Inst{4} = 1; let Inst{7} = 0; - let Inst{20} = 0; let Inst{25} = 0; } From evan.cheng at apple.com Tue Oct 27 15:54:24 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 27 Oct 2009 13:54:24 -0700 Subject: [llvm-commits] [llvm] r85295 - in /llvm/trunk: docs/tutorial/LangImpl4.html docs/tutorial/OCamlLangImpl4.html include/llvm/ExecutionEngine/ExecutionEngine.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngine/JIT/JITEmitter.cpp tools/lli/lli.cpp unittests/ExecutionEngine/JIT/JITTest.cpp In-Reply-To: <200910272030.n9RKUTLG013448@zion.cs.uiuc.edu> References: <200910272030.n9RKUTLG013448@zion.cs.uiuc.edu> Message-ID: On Oct 27, 2009, at 1:30 PM, Jeffrey Yasskin wrote: > Author: jyasskin > Date: Tue Oct 27 15:30:28 2009 > New Revision: 85295 > > URL: http://llvm.org/viewvc/llvm-project?rev=85295&view=rev > Log: > Change the JIT to compile eagerly by default as agreed in > http://llvm.org/PR5184, and beef up the comments to describe what > both options > do and the risks of lazy compilation in the presence of threads. Hi Jeffrey, In the future I'd prefer API changes be agreed upon by the greater community, not just in a bugzilla report. Lazy compilation is being used by some important clients. They will be caught off guard by this change. Does this change lli default behavior? Evan > > Modified: > llvm/trunk/docs/tutorial/LangImpl4.html > llvm/trunk/docs/tutorial/OCamlLangImpl4.html > llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h > llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp > llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp > llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp > llvm/trunk/tools/lli/lli.cpp > llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp > > Modified: llvm/trunk/docs/tutorial/LangImpl4.html > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl4.html?rev=85295&r1=85294&r2=85295&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/docs/tutorial/LangImpl4.html (original) > +++ llvm/trunk/docs/tutorial/LangImpl4.html Tue Oct 27 15:30:28 2009 > @@ -388,24 +388,19 @@ >

      >
      > > -

      This illustrates that we can now call user code, but there is > something a bit subtle > -going on here. Note that we only invoke the JIT on the anonymous > functions > -that call testfunc, but we never invoked it on testfunc > -itself.

      > - > -

      What actually happened here is that the anonymous function was > -JIT'd when requested. When the Kaleidoscope app calls through the > function > -pointer that is returned, the anonymous function starts executing. > It ends up > -making the call to the "testfunc" function, and ends up in a stub > that invokes > -the JIT, lazily, on testfunc. Once the JIT finishes lazily > compiling testfunc, > -it returns and the code re-executes the call.

      > - > -

      In summary, the JIT will lazily JIT code, on the fly, as it is > needed. The > -JIT provides a number of other more advanced interfaces for things > like freeing > -allocated machine code, rejit'ing functions to update them, etc. > However, even > -with this simple code, we get some surprisingly powerful > capabilities - check > -this out (I removed the dump of the anonymous functions, you should > get the idea > -by now :) :

      > +

      This illustrates that we can now call user code, but there is > something a bit > +subtle going on here. Note that we only invoke the JIT on the > anonymous > +functions that call testfunc, but we never invoked it > +on testfunc itself. What actually happened here is that > the JIT > +scanned for all non-JIT'd functions transitively called from the > anonymous > +function and compiled all of them before returning > +from getPointerToFunction().

      > + > +

      The JIT provides a number of other more advanced interfaces for > things like > +freeing allocated machine code, rejit'ing functions to update them, > etc. > +However, even with this simple code, we get some surprisingly > powerful > +capabilities - check this out (I removed the dump of the anonymous > functions, > +you should get the idea by now :) :

      > >
      >
      > @@ -453,8 +448,8 @@
      > resolved.  It allows you to establish explicit mappings between IR  
      > objects and
      > addresses (useful for LLVM global variables that you want to map to  
      > static
      > tables, for example), allows you to dynamically decide on the fly  
      > based on the
      > -function name, and even allows you to have the JIT abort itself if  
      > any lazy
      > -compilation is attempted.

      > +function name, and even allows you to have the JIT compile > functions lazily the > +first time they're called.

      > >

      One interesting application of this is that we can now extend the > language > by writing arbitrary C++ code to implement operations. For example, > if we add: > > Modified: llvm/trunk/docs/tutorial/OCamlLangImpl4.html > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/OCamlLangImpl4.html?rev=85295&r1=85294&r2=85295&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/docs/tutorial/OCamlLangImpl4.html (original) > +++ llvm/trunk/docs/tutorial/OCamlLangImpl4.html Tue Oct 27 15:30:28 > 2009 > @@ -406,22 +406,17 @@ > >

      This illustrates that we can now call user code, but there is > something a bit > subtle going on here. Note that we only invoke the JIT on the > anonymous > -functions that call testfunc, but we never invoked it on > testfunc > -itself.

      > - > -

      What actually happened here is that the anonymous function was > JIT'd when > -requested. When the Kaleidoscope app calls through the function > pointer that is > -returned, the anonymous function starts executing. It ends up > making the call > -to the "testfunc" function, and ends up in a stub that invokes the > JIT, lazily, > -on testfunc. Once the JIT finishes lazily compiling testfunc, > -it returns and the code re-executes the call.

      > - > -

      In summary, the JIT will lazily JIT code, on the fly, as it is > needed. The > -JIT provides a number of other more advanced interfaces for things > like freeing > -allocated machine code, rejit'ing functions to update them, etc. > However, even > -with this simple code, we get some surprisingly powerful > capabilities - check > -this out (I removed the dump of the anonymous functions, you should > get the idea > -by now :) :

      > +functions that call testfunc, but we never invoked it > +on testfunc itself. What actually happened here is that > the JIT > +scanned for all non-JIT'd functions transitively called from the > anonymous > +function and compiled all of them before returning > +from run_function.

      > + > +

      The JIT provides a number of other more advanced interfaces for > things like > +freeing allocated machine code, rejit'ing functions to update them, > etc. > +However, even with this simple code, we get some surprisingly > powerful > +capabilities - check this out (I removed the dump of the anonymous > functions, > +you should get the idea by now :) :

      > >
      >
      > @@ -467,8 +462,8 @@
      > get resolved.  It allows you to establish explicit mappings between  
      > IR objects
      > and addresses (useful for LLVM global variables that you want to map  
      > to static
      > tables, for example), allows you to dynamically decide on the fly  
      > based on the
      > -function name, and even allows you to have the JIT abort itself if  
      > any lazy
      > -compilation is attempted.

      > +function name, and even allows you to have the JIT compile > functions lazily the > +first time they're called.

      > >

      One interesting application of this is that we can now extend the > language > by writing arbitrary C code to implement operations. For example, > if we add: > > Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h?rev=85295&r1=85294&r2=85295&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h > (original) > +++ llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h Tue > Oct 27 15:30:28 2009 > @@ -88,7 +88,7 @@ > class ExecutionEngine { > const TargetData *TD; > ExecutionEngineState EEState; > - bool LazyCompilationDisabled; > + bool CompilingLazily; > bool GVCompilationDisabled; > bool SymbolSearchingDisabled; > bool DlsymStubsEnabled; > @@ -319,13 +319,24 @@ > virtual void RegisterJITEventListener(JITEventListener *) {} > virtual void UnregisterJITEventListener(JITEventListener *) {} > > - /// DisableLazyCompilation - If called, the JIT will abort if > lazy compilation > - /// is ever attempted. > - void DisableLazyCompilation(bool Disabled = true) { > - LazyCompilationDisabled = Disabled; > + /// EnableLazyCompilation - When lazy compilation is off (the > default), the > + /// JIT will eagerly compile every function reachable from the > argument to > + /// getPointerToFunction. If lazy compilation is turned on, the > JIT will only > + /// compile the one function and emit stubs to compile the rest > when they're > + /// first called. If lazy compilation is turned off again while > some lazy > + /// stubs are still around, and one of those stubs is called, the > program will > + /// abort. > + /// > + /// In order to safely compile lazily in a threaded program, the > user must > + /// ensure that 1) only one thread at a time can call any > particular lazy > + /// stub, and 2) any thread modifying LLVM IR must hold the JIT's > lock > + /// (ExecutionEngine::lock) or otherwise ensure that no other > thread calls a > + /// lazy stub. See http://llvm.org/PR5184 for details. > + void EnableLazyCompilation(bool Enabled = true) { > + CompilingLazily = Enabled; > } > - bool isLazyCompilationDisabled() const { > - return LazyCompilationDisabled; > + bool isCompilingLazily() const { > + return CompilingLazily; > } > > /// DisableGVCompilation - If called, the JIT will abort if it's > asked to > > Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp?rev=85295&r1=85294&r2=85295&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp (original) > +++ llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp Tue Oct 27 > 15:30:28 2009 > @@ -49,7 +49,7 @@ > ExecutionEngine::ExecutionEngine(ModuleProvider *P) > : EEState(*this), > LazyFunctionCreator(0) { > - LazyCompilationDisabled = false; > + CompilingLazily = false; > GVCompilationDisabled = false; > SymbolSearchingDisabled = false; > DlsymStubsEnabled = false; > > Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=85295&r1=85294&r2=85295&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original) > +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Tue Oct 27 15:30:28 > 2009 > @@ -599,7 +599,7 @@ > isAlreadyCodeGenerating = false; > > // If the function referred to another function that had not yet > been > - // read from bitcode, but we are jitting non-lazily, emit it now. > + // read from bitcode, and we are jitting non-lazily, emit it now. > while (!jitstate->getPendingFunctions(locked).empty()) { > Function *PF = jitstate->getPendingFunctions(locked).back(); > jitstate->getPendingFunctions(locked).pop_back(); > @@ -616,7 +616,7 @@ > > // If the JIT is configured to emit info so that dlsym can be used > to > // rewrite stubs to external globals, do so now. > - if (areDlsymStubsEnabled() && isLazyCompilationDisabled()) > + if (areDlsymStubsEnabled() && !isCompilingLazily()) > updateDlsymStubTable(); > } > > > Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=85295&r1=85294&r2=85295&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original) > +++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Tue Oct 27 > 15:30:28 2009 > @@ -295,11 +295,11 @@ > void *&Stub = state.getFunctionToStubMap(locked)[F]; > if (Stub) return Stub; > > - // Call the lazy resolver function unless we are JIT'ing non- > lazily, in which > - // case we must resolve the symbol now. > - void *Actual = TheJIT->isLazyCompilationDisabled() > - ? (void *)0 : (void *)(intptr_t)LazyResolverFn; > - > + // Call the lazy resolver function if we are JIT'ing lazily. > Otherwise we > + // must resolve the symbol now. > + void *Actual = TheJIT->isCompilingLazily() > + ? (void *)(intptr_t)LazyResolverFn : (void *)0; > + > // If this is an external declaration, attempt to resolve the > address now > // to place in the stub. > if (F->isDeclaration() && !F->hasNotBeenReadFromBitcode()) { > @@ -334,7 +334,7 @@ > // If we are JIT'ing non-lazily but need to call a function that > does not > // exist yet, add it to the JIT's work list so that we can fill in > the stub > // address later. > - if (!Actual && TheJIT->isLazyCompilationDisabled()) > + if (!Actual && !TheJIT->isCompilingLazily()) > if (!F->isDeclaration() || F->hasNotBeenReadFromBitcode()) > TheJIT->addPendingFunction(F); > > @@ -471,7 +471,7 @@ > // Otherwise we don't have it, do lazy compilation now. > > // If lazy compilation is disabled, emit a useful error message > and abort. > - if (TheJIT->isLazyCompilationDisabled()) { > + if (!TheJIT->isCompilingLazily()) { > llvm_report_error("LLVM JIT requested to do lazy compilation > of function '" > + F->getName() + "' when lazy compiles are > disabled!"); > } > @@ -769,7 +769,7 @@ > // mechanism is capable of rewriting the instruction directly, > prefer to do > // that instead of emitting a stub. This uses the lazy resolver, > so is not > // legal if lazy compilation is disabled. > - if (DoesntNeedStub && !TheJIT->isLazyCompilationDisabled()) > + if (DoesntNeedStub && TheJIT->isCompilingLazily()) > return Resolver.AddCallbackAtLocation(F, Reference); > > // Otherwise, we have to emit a stub. > > Modified: llvm/trunk/tools/lli/lli.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/lli.cpp?rev=85295&r1=85294&r2=85295&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/tools/lli/lli.cpp (original) > +++ llvm/trunk/tools/lli/lli.cpp Tue Oct 27 15:30:28 2009 > @@ -165,8 +165,7 @@ > > EE->RegisterJITEventListener(createOProfileJITEventListener()); > > - if (NoLazyCompilation) > - EE->DisableLazyCompilation(); > + EE->EnableLazyCompilation(!NoLazyCompilation); > > // If the user specifically requested an argv[0] to pass into the > program, > // do it now. > > Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=85295&r1=85294&r2=85295&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original) > +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Tue Oct 27 > 15:30:28 2009 > @@ -304,7 +304,7 @@ > Builder.CreateRet(result); > > TheJIT->EnableDlsymStubs(false); > - TheJIT->DisableLazyCompilation(); > + TheJIT->EnableLazyCompilation(false); > int (*TestFunctionPtr)() = reinterpret_cast( > (intptr_t)TheJIT->getPointerToFunction(TestFunction)); > // This used to crash in trying to call PlusOne(). > @@ -314,7 +314,7 @@ > #if !defined(__arm__) && !defined(__powerpc__) && !defined(__ppc__) > // Test a function C which calls A and B which call each other. > TEST_F(JITTest, NonLazyCompilationStillNeedsStubs) { > - TheJIT->DisableLazyCompilation(); > + TheJIT->EnableLazyCompilation(false); > > const FunctionType *Func1Ty = > cast(TypeBuilder::get > (Context)); > @@ -370,7 +370,7 @@ > // Regression test for PR5162. This used to trigger an AssertingVH > inside the > // JIT's Function to stub mapping. > TEST_F(JITTest, NonLazyLeaksNoStubs) { > - TheJIT->DisableLazyCompilation(); > + TheJIT->EnableLazyCompilation(false); > > // Create two functions with a single basic block each. > const FunctionType *FuncTy = > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Tue Oct 27 15:56:49 2009 From: dalej at apple.com (Dale Johannesen) Date: Tue, 27 Oct 2009 20:56:49 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r85303 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200910272056.n9RKunFx014693@zion.cs.uiuc.edu> Author: johannes Date: Tue Oct 27 15:56:49 2009 New Revision: 85303 URL: http://llvm.org/viewvc/llvm-project?rev=85303&view=rev Log: Make previous change not crash when size of object is unknown. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=85303&r1=85302&r2=85303&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Oct 27 15:56:49 2009 @@ -7774,10 +7774,12 @@ uint64_t GCCFieldOffsetInBits = getFieldOffsetInBits(Field); NextField = TREE_CHAIN(Field); - uint64_t FieldSizeInBits = getInt64(DECL_SIZE(Field), true); + uint64_t FieldSizeInBits; + if (DECL_SIZE(Field)) + FieldSizeInBits = getInt64(DECL_SIZE(Field), true); uint64_t ValueSizeInBits = Val->getType()->getPrimitiveSizeInBits(); ConstantInt *ValC = dyn_cast(Val); - if (ValC && ValC->isZero()) { + if (ValC && ValC->isZero() && DECL_SIZE(Field)) { // G++ has various bugs handling {} initializers where it doesn't // synthesize a zero node of the right type. Instead of figuring out G++, // just hack around it by special casing zero and allowing it to be the From sabre at nondot.org Tue Oct 27 16:01:34 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 21:01:34 -0000 Subject: [llvm-commits] [llvm] r85306 - /llvm/trunk/docs/LangRef.html Message-ID: <200910272101.n9RL1Y6S014943@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 16:01:34 2009 New Revision: 85306 URL: http://llvm.org/viewvc/llvm-project?rev=85306&view=rev Log: document the forthcoming blockaddress constant. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=85306&r1=85305&r2=85306&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Tue Oct 27 16:01:34 2009 @@ -83,6 +83,7 @@

    17. Complex Constants
    18. Global Variable and Function Addresses
    19. Undefined Values
    20. +
    21. Address of Basic Block
    22. Constant Expressions
    23. Embedded Metadata
    @@ -2171,6 +2172,29 @@ + +
    + +

    blockaddress(@function, %block)

    + +

    The 'blockaddress' constant computes the address of the specified + basic block in the specified function, and always has an i8* type.

    + + +

    This value only has defined behavior when used as an operand to the + 'indbr' instruction or for comparisons + against null. Pointer equality tests between labels addresses is undefined + behavior - though, again, comparison against null is ok, and no label is + equal to the null pointer. Some targets may provide defined semantics when + using the value as the operand to an inline assembly, but that is target + specific. +

    + +
    + + + @@ -2688,7 +2712,8 @@

    The 'indbr' instruction implements an indirect branch to a label within the current function, whose address is specified by - "address".

    + "address". Address must be derived from a blockaddress constant.

    Arguments:
    From jyasskin at google.com Tue Oct 27 16:11:07 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Tue, 27 Oct 2009 14:11:07 -0700 Subject: [llvm-commits] [llvm] r85295 - in /llvm/trunk: docs/tutorial/LangImpl4.html docs/tutorial/OCamlLangImpl4.html include/llvm/ExecutionEngine/ExecutionEngine.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngi Message-ID: On Tue, Oct 27, 2009 at 1:54 PM, Evan Cheng wrote: > > On Oct 27, 2009, at 1:30 PM, Jeffrey Yasskin wrote: > >> Author: jyasskin >> Date: Tue Oct 27 15:30:28 2009 >> New Revision: 85295 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=85295&view=rev >> Log: >> Change the JIT to compile eagerly by default as agreed in >> http://llvm.org/PR5184, and beef up the comments to describe what both >> options >> do and the risks of lazy compilation in the presence of threads. > > Hi Jeffrey, > > In the future I'd prefer API changes be agreed upon by the greater > community, not just in a bugzilla report. Sorry about that. Do you want me to revert this until we can ping llvmdev? > Lazy compilation is being used by some important clients. They will be > caught off guard by this change. Does this change lli default behavior? No, it doesn't change lli's default, although that was an accident on my part (maybe a fortunate accident). I did ping llvmdev last week asking people who use the lazy JIT to look at the bug report, but I can see how people who don't use threads with the JIT would think it didn't apply to them. From gohman at apple.com Tue Oct 27 16:12:44 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 27 Oct 2009 14:12:44 -0700 Subject: [llvm-commits] [llvm] r85306 - /llvm/trunk/docs/LangRef.html In-Reply-To: <200910272101.n9RL1Y6S014943@zion.cs.uiuc.edu> References: <200910272101.n9RL1Y6S014943@zion.cs.uiuc.edu> Message-ID: <7E0045DF-A8BD-4F82-9C8D-39AB5A61DD93@apple.com> Hi Chris, On Oct 27, 2009, at 2:01 PM, Chris Lattner wrote: > Author: lattner > Date: Tue Oct 27 16:01:34 2009 > New Revision: 85306 > > URL: http://llvm.org/viewvc/llvm-project?rev=85306&view=rev > Log: > document the forthcoming blockaddress constant. > > Modified: > llvm/trunk/docs/LangRef.html > > Modified: llvm/trunk/docs/LangRef.html > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=85306&r1=85305&r2=85306&view=diff > > ============================================================================== > --- llvm/trunk/docs/LangRef.html (original) > +++ llvm/trunk/docs/LangRef.html Tue Oct 27 16:01:34 2009 > @@ -83,6 +83,7 @@ >
  • Complex Constants
  • >
  • Global Variable and Function Addresses
  • >
  • Undefined Values
  • > +
  • Address of Basic Block
  • The other items in this list are plural. Should this be "Addresses of Basic Blocks"? >
  • Constant Expressions
  • >
  • Embedded Metadata
  • > > @@ -2171,6 +2172,29 @@ > > > > + > +
    > + > +

    blockaddress(@function, %block)

    > + > +

    The 'blockaddress' constant computes the address of the specified > + basic block in the specified function, and always has an i8* type.

    > + > + > +

    This value only has defined behavior when used as an operand to the > + 'indbr' instruction or for comparisons > + against null. Pointer equality tests between labels addresses is undefined > + behavior - though, again, comparison against null is ok, and no label is > + equal to the null pointer. Some targets may provide defined semantics when > + using the value as the operand to an inline assembly, but that is target > + specific. > +

    This should mention ptrtoint also, for label address differences. Dan From sabre at nondot.org Tue Oct 27 16:19:13 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 21:19:13 -0000 Subject: [llvm-commits] [llvm] r85310 - /llvm/trunk/docs/LangRef.html Message-ID: <200910272119.n9RLJDK0015772@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 16:19:13 2009 New Revision: 85310 URL: http://llvm.org/viewvc/llvm-project?rev=85310&view=rev Log: fix things pointed out by Dan! Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=85310&r1=85309&r2=85310&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Tue Oct 27 16:19:13 2009 @@ -83,7 +83,7 @@
  • Complex Constants
  • Global Variable and Function Addresses
  • Undefined Values
  • -
  • Address of Basic Block
  • +
  • Addresses of Basic Blocks
  • Constant Expressions
  • Embedded Metadata
  • @@ -2172,8 +2172,8 @@
    - +

    blockaddress(@function, %block)

    @@ -2186,7 +2186,12 @@ 'indbr' instruction or for comparisons against null. Pointer equality tests between labels addresses is undefined behavior - though, again, comparison against null is ok, and no label is - equal to the null pointer. Some targets may provide defined semantics when + equal to the null pointer. This may also be passed around as an opaque + pointer sized value as long as the bits are not inspected. This allows + ptrtoint and arithmetic to be performed on these values so long as the + original value is reconsistituted before the indbr.

    + +

    Finally, some targets may provide defined semantics when using the value as the operand to an inline assembly, but that is target specific.

    From sabre at nondot.org Tue Oct 27 16:21:07 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 21:21:07 -0000 Subject: [llvm-commits] [llvm] r85311 - /llvm/trunk/lib/Target/CBackend/CBackend.cpp Message-ID: <200910272121.n9RLL7t1015840@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 16:21:06 2009 New Revision: 85311 URL: http://llvm.org/viewvc/llvm-project?rev=85311&view=rev Log: CBE support for indbr. Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=85311&r1=85310&r2=85311&view=diff ============================================================================== --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Tue Oct 27 16:21:06 2009 @@ -282,6 +282,7 @@ void visitReturnInst(ReturnInst &I); void visitBranchInst(BranchInst &I); void visitSwitchInst(SwitchInst &I); + void visitIndBrInst(IndBrInst &I); void visitInvokeInst(InvokeInst &I) { llvm_unreachable("Lowerinvoke pass didn't work!"); } @@ -2578,6 +2579,12 @@ Out << " }\n"; } +void CWriter::visitIndBrInst(IndBrInst &IBI) { + Out << " goto *(void*)("; + writeOperand(IBI.getOperand(0)); + Out << ");\n"; +} + void CWriter::visitUnreachableInst(UnreachableInst &I) { Out << " /*UNREACHABLE*/;\n"; } From sabre at nondot.org Tue Oct 27 16:24:48 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 21:24:48 -0000 Subject: [llvm-commits] [llvm] r85312 - /llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Message-ID: <200910272124.n9RLOm4B015975@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 16:24:48 2009 New Revision: 85312 URL: http://llvm.org/viewvc/llvm-project?rev=85312&view=rev Log: cppbackend support for indbr Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=85312&r1=85311&r2=85312&view=diff ============================================================================== --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original) +++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Tue Oct 27 16:24:48 2009 @@ -1118,13 +1118,13 @@ break; } case Instruction::Switch: { - const SwitchInst* sw = cast(I); + const SwitchInst *SI = cast(I); Out << "SwitchInst* " << iName << " = SwitchInst::Create(" << opNames[0] << ", " << opNames[1] << ", " - << sw->getNumCases() << ", " << bbname << ");"; + << SI->getNumCases() << ", " << bbname << ");"; nl(Out); - for (unsigned i = 2; i < sw->getNumOperands(); i += 2 ) { + for (unsigned i = 2; i != SI->getNumOperands(); i += 2) { Out << iName << "->addCase(" << opNames[i] << ", " << opNames[i+1] << ");"; @@ -1132,6 +1132,17 @@ } break; } + case Instruction::IndBr: { + const IndBrInst *IBI = cast(I); + Out << "IndBrInst *" << iName << " = IndBrInst::Create(" + << opNames[0] << ", " << IBI->getNumDestinations() << ");"; + nl(Out); + for (unsigned i = 1; i != IBI->getNumOperands(); ++i) { + Out << iName << "->addDestination(" << opNames[i] << ");"; + nl(Out); + } + break; + } case Instruction::Invoke: { const InvokeInst* inv = cast(I); Out << "std::vector " << iName << "_params;"; From sabre at nondot.org Tue Oct 27 16:27:42 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 21:27:42 -0000 Subject: [llvm-commits] [llvm] r85316 - in /llvm/trunk: include/llvm/Bitcode/LLVMBitCodes.h lib/Analysis/InlineCost.cpp lib/Analysis/SparsePropagation.cpp Message-ID: <200910272127.n9RLRhJ3016118@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 16:27:42 2009 New Revision: 85316 URL: http://llvm.org/viewvc/llvm-project?rev=85316&view=rev Log: Random updates to passes for indbr, I need blockaddress before I can do much more. Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h llvm/trunk/lib/Analysis/InlineCost.cpp llvm/trunk/lib/Analysis/SparsePropagation.cpp Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=85316&r1=85315&r2=85316&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original) +++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Tue Oct 27 16:27:42 2009 @@ -209,7 +209,7 @@ FUNC_CODE_INST_RET = 10, // RET: [opty,opval] FUNC_CODE_INST_BR = 11, // BR: [bb#, bb#, cond] or [bb#] - FUNC_CODE_INST_SWITCH = 12, // SWITCH: [opty, operands...] + FUNC_CODE_INST_SWITCH = 12, // SWITCH: [opty, op0, op1, ...] FUNC_CODE_INST_INVOKE = 13, // INVOKE: [attr, fnty, op0,op1, ...] FUNC_CODE_INST_UNWIND = 14, // UNWIND FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE @@ -237,7 +237,7 @@ // new select on i1 or [N x i1] FUNC_CODE_INST_VSELECT = 29, // VSELECT: [ty,opval,opval,predty,pred] FUNC_CODE_INST_INBOUNDS_GEP= 30, // INBOUNDS_GEP: [n x operands] - FUNC_CODE_INST_INDBR = 31 // INDBR: [opty, operands...] + FUNC_CODE_INST_INDBR = 31 // INDBR: [opty, op0, op1, ...] }; } // End bitc namespace } // End llvm namespace Modified: llvm/trunk/lib/Analysis/InlineCost.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InlineCost.cpp?rev=85316&r1=85315&r2=85316&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InlineCost.cpp (original) +++ llvm/trunk/lib/Analysis/InlineCost.cpp Tue Oct 27 16:27:42 2009 @@ -31,6 +31,9 @@ // Eliminating a switch is a big win, proportional to the number of edges // deleted. Reduction += (SI->getNumSuccessors()-1) * 40; + else if (isa(*UI)) + // Eliminating an indirect branch is a big win. + Reduction += 200; else if (CallInst *CI = dyn_cast(*UI)) { // Turning an indirect call into a direct call is a BIG win Reduction += CI->getCalledValue() == V ? 500 : 0; Modified: llvm/trunk/lib/Analysis/SparsePropagation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/SparsePropagation.cpp?rev=85316&r1=85315&r2=85316&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/SparsePropagation.cpp (original) +++ llvm/trunk/lib/Analysis/SparsePropagation.cpp Tue Oct 27 16:27:42 2009 @@ -166,6 +166,11 @@ return; } + if (IndBrInst *IBI = dyn_cast(TI)) { + Succs.assign(Succs.size(), true); + return; + } + SwitchInst &SI = cast(TI); LatticeVal SCValue; if (AggressiveUndef) From evan.cheng at apple.com Tue Oct 27 16:27:50 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 27 Oct 2009 14:27:50 -0700 Subject: [llvm-commits] [llvm] r85295 - in /llvm/trunk: docs/tutorial/LangImpl4.html docs/tutorial/OCamlLangImpl4.html include/llvm/ExecutionEngine/ExecutionEngine.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngi In-Reply-To: References: Message-ID: <9879CBCC-0704-4FC7-8061-94D382FA7587@apple.com> On Oct 27, 2009, at 2:11 PM, Jeffrey Yasskin wrote: > On Tue, Oct 27, 2009 at 1:54 PM, Evan Cheng > wrote: >> >> On Oct 27, 2009, at 1:30 PM, Jeffrey Yasskin wrote: >> >>> Author: jyasskin >>> Date: Tue Oct 27 15:30:28 2009 >>> New Revision: 85295 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=85295&view=rev >>> Log: >>> Change the JIT to compile eagerly by default as agreed in >>> http://llvm.org/PR5184, and beef up the comments to describe what >>> both >>> options >>> do and the risks of lazy compilation in the presence of threads. >> >> Hi Jeffrey, >> >> In the future I'd prefer API changes be agreed upon by the greater >> community, not just in a bugzilla report. > > Sorry about that. Do you want me to revert this until we can ping > llvmdev? > >> Lazy compilation is being used by some important clients. They will >> be >> caught off guard by this change. Does this change lli default >> behavior? > > No, it doesn't change lli's default, although that was an accident on > my part (maybe a fortunate accident). I did ping llvmdev last week > asking people who use the lazy JIT to look at the bug report, but I > can see how people who don't use threads with the JIT would think it > didn't apply to them. Sorry, I have been too busy with other things so I didn't follow the thread. The patch changed DisableLazyCompilation to EnableLazyCompilation, which is minor but it's a API change nevertheless. That means clients which are using 2.6 have to change their code in order to test against tot. Unless this is absolutely necessary, I'd prefer not to change it. Evan From jyasskin at google.com Tue Oct 27 16:34:27 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Tue, 27 Oct 2009 14:34:27 -0700 Subject: [llvm-commits] [llvm] r85295 - in /llvm/trunk: docs/tutorial/LangImpl4.html docs/tutorial/OCamlLangImpl4.html include/llvm/ExecutionEngine/ExecutionEngine.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngi In-Reply-To: <9879CBCC-0704-4FC7-8061-94D382FA7587@apple.com> References: <9879CBCC-0704-4FC7-8061-94D382FA7587@apple.com> Message-ID: On Tue, Oct 27, 2009 at 2:27 PM, Evan Cheng wrote: > > On Oct 27, 2009, at 2:11 PM, Jeffrey Yasskin wrote: > >> On Tue, Oct 27, 2009 at 1:54 PM, Evan Cheng wrote: >>> >>> On Oct 27, 2009, at 1:30 PM, Jeffrey Yasskin wrote: >>> >>>> Author: jyasskin >>>> Date: Tue Oct 27 15:30:28 2009 >>>> New Revision: 85295 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=85295&view=rev >>>> Log: >>>> Change the JIT to compile eagerly by default as agreed in >>>> http://llvm.org/PR5184, and beef up the comments to describe what both >>>> options >>>> do and the risks of lazy compilation in the presence of threads. >>> >>> Hi Jeffrey, >>> >>> In the future I'd prefer API changes be agreed upon by the greater >>> community, not just in a bugzilla report. >> >> Sorry about that. Do you want me to revert this until we can ping llvmdev? >> >>> Lazy compilation is being used by some important clients. They will be >>> caught off guard by this change. Does this change lli default behavior? >> >> No, it doesn't change lli's default, although that was an accident on >> my part (maybe a fortunate accident). I did ping llvmdev last week >> asking people who use the lazy JIT to look at the bug report, but I >> can see how people who don't use threads with the JIT would think it >> didn't apply to them. > > Sorry, I have been too busy with other things so I didn't follow the thread. > > The patch changed DisableLazyCompilation to EnableLazyCompilation, which is > minor but it's a API change nevertheless. ?That means clients which are > using 2.6 have to change their code in order to test against tot. Unless > this is absolutely necessary, I'd prefer not to change it. It's not necessary. I'd like to keep the new query method since it removes some double-negatives inside the JIT, but they can easily live alongside each other for the 2.7 release. I'll send a patch renaming Enable... back to Disable... and adding the old query method back. From evan.cheng at apple.com Tue Oct 27 16:35:43 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 27 Oct 2009 21:35:43 -0000 Subject: [llvm-commits] [llvm] r85318 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/Support/APFloat.cpp Message-ID: <200910272135.n9RLZhXq016402@zion.cs.uiuc.edu> Author: evancheng Date: Tue Oct 27 16:35:42 2009 New Revision: 85318 URL: http://llvm.org/viewvc/llvm-project?rev=85318&view=rev Log: Add new APFloat methods that return sign, exp, and mantissa of ieee float and double values. Modified: llvm/trunk/include/llvm/ADT/APFloat.h llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/include/llvm/ADT/APFloat.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=85318&r1=85317&r2=85318&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APFloat.h (original) +++ llvm/trunk/include/llvm/ADT/APFloat.h Tue Oct 27 16:35:42 2009 @@ -277,6 +277,13 @@ /* Return an arbitrary integer value usable for hashing. */ uint32_t getHashValue() const; + /// getIEEEFloatParts / getIEEEDoubleParts - Return exponent, significant, + /// and sign bit of an IEEE float / IEEE double value. + void getIEEEFloatParts(bool &Sign, uint32_t &Exp, + uint32_t &Significant) const; + void getIEEEDoubleParts(bool &Sign, uint64_t &Exp, + uint64_t &Significant) const; + private: /* Trivial queries. */ Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=85318&r1=85317&r2=85318&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Tue Oct 27 16:35:42 2009 @@ -421,7 +421,7 @@ unsigned int count, partBits; integerPart part, boundary; - assert (bits != 0); + assert(bits != 0); bits--; count = bits / integerPartWidth; @@ -537,7 +537,7 @@ { unsigned int result = count; - assert (count != 0 && count <= integerPartWidth / 4); + assert(count != 0 && count <= integerPartWidth / 4); part >>= (integerPartWidth - 4 * count); while (count--) { @@ -760,7 +760,7 @@ { assert(category == fcNormal || category == fcNaN); - if(partCount() > 1) + if (partCount() > 1) return significand.parts; else return &significand.part; @@ -2289,8 +2289,8 @@ /* Both multiplySignificand and divideSignificand return the result with the integer bit set. */ - assert (APInt::tcExtractBit - (decSig.significandParts(), calcSemantics.precision - 1) == 1); + assert(APInt::tcExtractBit + (decSig.significandParts(), calcSemantics.precision - 1) == 1); HUerr = HUerrBound(calcLostFraction != lfExactlyZero, sigStatus != opOK, powHUerr); @@ -2593,7 +2593,7 @@ q--; *q = hexDigitChars[hexDigitValue (*q) + 1]; } while (*q == '0'); - assert (q >= p); + assert(q >= p); } else { /* Add trailing zeroes. */ memset (dst, '0', outputDigits); @@ -2632,6 +2632,56 @@ } } +void APFloat::getIEEEFloatParts(bool &Sign, uint32_t &Exp, + uint32_t &Significand) const { + assert(semantics == (const llvm::fltSemantics*)&IEEEsingle && + "Float semantics are not IEEEsingle"); + assert(partCount()==1); + + if (category == fcNormal) { + Exp = exponent+127; // bias + Significand = (uint32_t)*significandParts(); + if (Exp == 1 && !(Significand & 0x800000)) + Exp = 0; // denormal + } else if (category==fcZero) { + Exp = 0; + Significand = 0; + } else if (category==fcInfinity) { + Exp = 0xff; + Significand = 0; + } else { + assert(category == fcNaN && "Unknown category!"); + Exp = 0xff; + Significand = (uint32_t)*significandParts(); + } + Sign = sign; +} + +void APFloat::getIEEEDoubleParts(bool &Sign, uint64_t &Exp, + uint64_t &Significand) const { + assert(semantics == (const llvm::fltSemantics*)&IEEEdouble && + "Float semantics are not IEEEdouble"); + assert(partCount()==1); + + if (category == fcNormal) { + Exp = exponent+1023; // bias + Significand = *significandParts(); + if (Exp == 1 && !(Significand & 0x10000000000000LL)) + Exp = 0; // denormal + } else if (category==fcZero) { + Exp = 0; + Significand = 0; + } else if (category==fcInfinity) { + Exp = 0x7ff; + Significand = 0; + } else { + assert(category == fcNaN && "Unknown category!"); + Exp = 0x7ff; + Significand = *significandParts(); + } + Sign = sign; +} + // Conversion from APFloat to/from host float/double. It may eventually be // possible to eliminate these and have everybody deal with APFloats, but that // will take a while. This approach will not easily extend to long double. @@ -2645,7 +2695,7 @@ APFloat::convertF80LongDoubleAPFloatToAPInt() const { assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended); - assert (partCount()==2); + assert(partCount()==2); uint64_t myexponent, mysignificand; @@ -2677,7 +2727,7 @@ APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const { assert(semantics == (const llvm::fltSemantics*)&PPCDoubleDouble); - assert (partCount()==2); + assert(partCount()==2); uint64_t myexponent, mysignificand, myexponent2, mysignificand2; @@ -2722,7 +2772,7 @@ APFloat::convertQuadrupleAPFloatToAPInt() const { assert(semantics == (const llvm::fltSemantics*)&IEEEquad); - assert (partCount()==2); + assert(partCount()==2); uint64_t myexponent, mysignificand, mysignificand2; @@ -2758,7 +2808,7 @@ APFloat::convertDoubleAPFloatToAPInt() const { assert(semantics == (const llvm::fltSemantics*)&IEEEdouble); - assert (partCount()==1); + assert(partCount()==1); uint64_t myexponent, mysignificand; @@ -2788,7 +2838,7 @@ APFloat::convertFloatAPFloatToAPInt() const { assert(semantics == (const llvm::fltSemantics*)&IEEEsingle); - assert (partCount()==1); + assert(partCount()==1); uint32_t myexponent, mysignificand; @@ -2817,7 +2867,7 @@ APFloat::convertHalfAPFloatToAPInt() const { assert(semantics == (const llvm::fltSemantics*)&IEEEhalf); - assert (partCount()==1); + assert(partCount()==1); uint32_t myexponent, mysignificand; From sabre at nondot.org Tue Oct 27 16:43:40 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 21:43:40 -0000 Subject: [llvm-commits] [llvm] r85319 - /llvm/trunk/lib/Analysis/SparsePropagation.cpp Message-ID: <200910272143.n9RLheRA016660@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 16:43:39 2009 New Revision: 85319 URL: http://llvm.org/viewvc/llvm-project?rev=85319&view=rev Log: make the build build. Modified: llvm/trunk/lib/Analysis/SparsePropagation.cpp Modified: llvm/trunk/lib/Analysis/SparsePropagation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/SparsePropagation.cpp?rev=85319&r1=85318&r2=85319&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/SparsePropagation.cpp (original) +++ llvm/trunk/lib/Analysis/SparsePropagation.cpp Tue Oct 27 16:43:39 2009 @@ -166,7 +166,7 @@ return; } - if (IndBrInst *IBI = dyn_cast(TI)) { + if (isa(TI)) { Succs.assign(Succs.size(), true); return; } From sabre at nondot.org Tue Oct 27 16:44:20 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 21:44:20 -0000 Subject: [llvm-commits] [llvm] r85320 - /llvm/trunk/docs/LangRef.html Message-ID: <200910272144.n9RLiKBJ016697@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 16:44:20 2009 New Revision: 85320 URL: http://llvm.org/viewvc/llvm-project?rev=85320&view=rev Log: improvements from gabor. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=85320&r1=85319&r2=85320&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Tue Oct 27 16:44:20 2009 @@ -2188,8 +2188,8 @@ behavior - though, again, comparison against null is ok, and no label is equal to the null pointer. This may also be passed around as an opaque pointer sized value as long as the bits are not inspected. This allows - ptrtoint and arithmetic to be performed on these values so long as the - original value is reconsistituted before the indbr.

    + ptrtoint and arithmetic to be performed on these values so long as + the original value is reconsistituted before the indbr.

    Finally, some targets may provide defined semantics when using the value as the operand to an inline assembly, but that is target From sabre at nondot.org Tue Oct 27 16:49:41 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 21:49:41 -0000 Subject: [llvm-commits] [llvm] r85321 - /llvm/trunk/docs/LangRef.html Message-ID: <200910272149.n9RLnftf016853@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 16:49:40 2009 New Revision: 85321 URL: http://llvm.org/viewvc/llvm-project?rev=85321&view=rev Log: you can't take the address of the entry block of a function. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=85321&r1=85320&r2=85321&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Tue Oct 27 16:49:40 2009 @@ -2179,8 +2179,8 @@

    blockaddress(@function, %block)

    The 'blockaddress' constant computes the address of the specified - basic block in the specified function, and always has an i8* type.

    - + basic block in the specified function, and always has an i8* type. Taking + the address of the entry block is illegal.

    This value only has defined behavior when used as an operand to the 'indbr' instruction or for comparisons From dalej at apple.com Tue Oct 27 16:50:56 2009 From: dalej at apple.com (Dale Johannesen) Date: Tue, 27 Oct 2009 14:50:56 -0700 Subject: [llvm-commits] [llvm] r85318 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/Support/APFloat.cpp In-Reply-To: <200910272135.n9RLZhXq016402@zion.cs.uiuc.edu> References: <200910272135.n9RLZhXq016402@zion.cs.uiuc.edu> Message-ID: On Oct 27, 2009, at 2:35 PMPDT, Evan Cheng wrote: > Author: evancheng > Date: Tue Oct 27 16:35:42 2009 > New Revision: 85318 > > URL: http://llvm.org/viewvc/llvm-project?rev=85318&view=rev > Log: > Add new APFloat methods that return sign, exp, and mantissa of ieee > float and double values. Why do you want to do this? I think there's a good case for keeping these representation details local to APFloat. > Modified: > llvm/trunk/include/llvm/ADT/APFloat.h > llvm/trunk/lib/Support/APFloat.cpp > > Modified: llvm/trunk/include/llvm/ADT/APFloat.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=85318&r1=85317&r2=85318&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/ADT/APFloat.h (original) > +++ llvm/trunk/include/llvm/ADT/APFloat.h Tue Oct 27 16:35:42 2009 > @@ -277,6 +277,13 @@ > /* Return an arbitrary integer value usable for hashing. */ > uint32_t getHashValue() const; > > + /// getIEEEFloatParts / getIEEEDoubleParts - Return exponent, > significant, > + /// and sign bit of an IEEE float / IEEE double value. > + void getIEEEFloatParts(bool &Sign, uint32_t &Exp, > + uint32_t &Significant) const; > + void getIEEEDoubleParts(bool &Sign, uint64_t &Exp, > + uint64_t &Significant) const; > + > private: > > /* Trivial queries. */ > > Modified: llvm/trunk/lib/Support/APFloat.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=85318&r1=85317&r2=85318&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Support/APFloat.cpp (original) > +++ llvm/trunk/lib/Support/APFloat.cpp Tue Oct 27 16:35:42 2009 > @@ -421,7 +421,7 @@ > unsigned int count, partBits; > integerPart part, boundary; > > - assert (bits != 0); > + assert(bits != 0); > > bits--; > count = bits / integerPartWidth; > @@ -537,7 +537,7 @@ > { > unsigned int result = count; > > - assert (count != 0 && count <= integerPartWidth / 4); > + assert(count != 0 && count <= integerPartWidth / 4); > > part >>= (integerPartWidth - 4 * count); > while (count--) { > @@ -760,7 +760,7 @@ > { > assert(category == fcNormal || category == fcNaN); > > - if(partCount() > 1) > + if (partCount() > 1) > return significand.parts; > else > return &significand.part; > @@ -2289,8 +2289,8 @@ > > /* Both multiplySignificand and divideSignificand return the > result with the integer bit set. */ > - assert (APInt::tcExtractBit > - (decSig.significandParts(), calcSemantics.precision - > 1) == 1); > + assert(APInt::tcExtractBit > + (decSig.significandParts(), calcSemantics.precision - 1) > == 1); > > HUerr = HUerrBound(calcLostFraction != lfExactlyZero, sigStatus ! > = opOK, > powHUerr); > @@ -2593,7 +2593,7 @@ > q--; > *q = hexDigitChars[hexDigitValue (*q) + 1]; > } while (*q == '0'); > - assert (q >= p); > + assert(q >= p); > } else { > /* Add trailing zeroes. */ > memset (dst, '0', outputDigits); > @@ -2632,6 +2632,56 @@ > } > } > > +void APFloat::getIEEEFloatParts(bool &Sign, uint32_t &Exp, > + uint32_t &Significand) const { > + assert(semantics == (const llvm::fltSemantics*)&IEEEsingle && > + "Float semantics are not IEEEsingle"); > + assert(partCount()==1); > + > + if (category == fcNormal) { > + Exp = exponent+127; // bias > + Significand = (uint32_t)*significandParts(); > + if (Exp == 1 && !(Significand & 0x800000)) > + Exp = 0; // denormal > + } else if (category==fcZero) { > + Exp = 0; > + Significand = 0; > + } else if (category==fcInfinity) { > + Exp = 0xff; > + Significand = 0; > + } else { > + assert(category == fcNaN && "Unknown category!"); > + Exp = 0xff; > + Significand = (uint32_t)*significandParts(); > + } > + Sign = sign; > +} > + > +void APFloat::getIEEEDoubleParts(bool &Sign, uint64_t &Exp, > + uint64_t &Significand) const { > + assert(semantics == (const llvm::fltSemantics*)&IEEEdouble && > + "Float semantics are not IEEEdouble"); > + assert(partCount()==1); > + > + if (category == fcNormal) { > + Exp = exponent+1023; // bias > + Significand = *significandParts(); > + if (Exp == 1 && !(Significand & 0x10000000000000LL)) > + Exp = 0; // denormal > + } else if (category==fcZero) { > + Exp = 0; > + Significand = 0; > + } else if (category==fcInfinity) { > + Exp = 0x7ff; > + Significand = 0; > + } else { > + assert(category == fcNaN && "Unknown category!"); > + Exp = 0x7ff; > + Significand = *significandParts(); > + } > + Sign = sign; > +} > + > // Conversion from APFloat to/from host float/double. It may > eventually be > // possible to eliminate these and have everybody deal with > APFloats, but that > // will take a while. This approach will not easily extend to long > double. > @@ -2645,7 +2695,7 @@ > APFloat::convertF80LongDoubleAPFloatToAPInt() const > { > assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended); > - assert (partCount()==2); > + assert(partCount()==2); > > uint64_t myexponent, mysignificand; > > @@ -2677,7 +2727,7 @@ > APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const > { > assert(semantics == (const llvm::fltSemantics*)&PPCDoubleDouble); > - assert (partCount()==2); > + assert(partCount()==2); > > uint64_t myexponent, mysignificand, myexponent2, mysignificand2; > > @@ -2722,7 +2772,7 @@ > APFloat::convertQuadrupleAPFloatToAPInt() const > { > assert(semantics == (const llvm::fltSemantics*)&IEEEquad); > - assert (partCount()==2); > + assert(partCount()==2); > > uint64_t myexponent, mysignificand, mysignificand2; > > @@ -2758,7 +2808,7 @@ > APFloat::convertDoubleAPFloatToAPInt() const > { > assert(semantics == (const llvm::fltSemantics*)&IEEEdouble); > - assert (partCount()==1); > + assert(partCount()==1); > > uint64_t myexponent, mysignificand; > > @@ -2788,7 +2838,7 @@ > APFloat::convertFloatAPFloatToAPInt() const > { > assert(semantics == (const llvm::fltSemantics*)&IEEEsingle); > - assert (partCount()==1); > + assert(partCount()==1); > > uint32_t myexponent, mysignificand; > > @@ -2817,7 +2867,7 @@ > APFloat::convertHalfAPFloatToAPInt() const > { > assert(semantics == (const llvm::fltSemantics*)&IEEEhalf); > - assert (partCount()==1); > + assert(partCount()==1); > > uint32_t myexponent, mysignificand; > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Tue Oct 27 16:52:55 2009 From: sabre at nondot.org (Chris Lattner) Date: Tue, 27 Oct 2009 21:52:55 -0000 Subject: [llvm-commits] [llvm] r85322 - /llvm/trunk/docs/LangRef.html Message-ID: <200910272152.n9RLqtxJ016963@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 16:52:54 2009 New Revision: 85322 URL: http://llvm.org/viewvc/llvm-project?rev=85322&view=rev Log: typo Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=85322&r1=85321&r2=85322&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Tue Oct 27 16:52:54 2009 @@ -2189,7 +2189,7 @@ equal to the null pointer. This may also be passed around as an opaque pointer sized value as long as the bits are not inspected. This allows ptrtoint and arithmetic to be performed on these values so long as - the original value is reconsistituted before the indbr.

    + the original value is reconstituted before the indbr.

    Finally, some targets may provide defined semantics when using the value as the operand to an inline assembly, but that is target From gohman at apple.com Tue Oct 27 16:56:26 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 27 Oct 2009 21:56:26 -0000 Subject: [llvm-commits] [llvm] r85323 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200910272156.n9RLuQi7017084@zion.cs.uiuc.edu> Author: djg Date: Tue Oct 27 16:56:26 2009 New Revision: 85323 URL: http://llvm.org/viewvc/llvm-project?rev=85323&view=rev Log: Add CodeGen support for indirect branches. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=85323&r1=85322&r2=85323&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Tue Oct 27 16:56:26 2009 @@ -2132,8 +2132,9 @@ } void SelectionDAGLowering::visitIndBr(IndBrInst &I) { - errs() << "indbr codegen not implemented yet!\n"; - abort(); + DAG.setRoot(DAG.getNode(ISD::BRIND, getCurDebugLoc(), + MVT::Other, getControlRoot(), + getValue(I.getAddress()))); } From evan.cheng at apple.com Tue Oct 27 17:00:21 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 27 Oct 2009 15:00:21 -0700 Subject: [llvm-commits] [llvm] r85318 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/Support/APFloat.cpp In-Reply-To: References: <200910272135.n9RLZhXq016402@zion.cs.uiuc.edu> Message-ID: <4E11886E-E7DE-40BE-ADEE-D8B4D6BEA974@apple.com> On Oct 27, 2009, at 2:50 PM, Dale Johannesen wrote: > > On Oct 27, 2009, at 2:35 PMPDT, Evan Cheng wrote: > >> Author: evancheng >> Date: Tue Oct 27 16:35:42 2009 >> New Revision: 85318 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=85318&view=rev >> Log: >> Add new APFloat methods that return sign, exp, and mantissa of ieee >> float and double values. > > Why do you want to do this? I think there's a good case for keeping > these representation details local to APFloat. ARM has instructions that can materialize some of the fp immediates. It has to examine the parts to determine if an fp immediate can be encoded. Evan > >> Modified: >> llvm/trunk/include/llvm/ADT/APFloat.h >> llvm/trunk/lib/Support/APFloat.cpp >> >> Modified: llvm/trunk/include/llvm/ADT/APFloat.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=85318&r1=85317&r2=85318&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/include/llvm/ADT/APFloat.h (original) >> +++ llvm/trunk/include/llvm/ADT/APFloat.h Tue Oct 27 16:35:42 2009 >> @@ -277,6 +277,13 @@ >> /* Return an arbitrary integer value usable for hashing. */ >> uint32_t getHashValue() const; >> >> + /// getIEEEFloatParts / getIEEEDoubleParts - Return exponent, >> significant, >> + /// and sign bit of an IEEE float / IEEE double value. >> + void getIEEEFloatParts(bool &Sign, uint32_t &Exp, >> + uint32_t &Significant) const; >> + void getIEEEDoubleParts(bool &Sign, uint64_t &Exp, >> + uint64_t &Significant) const; >> + >> private: >> >> /* Trivial queries. */ >> >> Modified: llvm/trunk/lib/Support/APFloat.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=85318&r1=85317&r2=85318&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Support/APFloat.cpp (original) >> +++ llvm/trunk/lib/Support/APFloat.cpp Tue Oct 27 16:35:42 2009 >> @@ -421,7 +421,7 @@ >> unsigned int count, partBits; >> integerPart part, boundary; >> >> - assert (bits != 0); >> + assert(bits != 0); >> >> bits--; >> count = bits / integerPartWidth; >> @@ -537,7 +537,7 @@ >> { >> unsigned int result = count; >> >> - assert (count != 0 && count <= integerPartWidth / 4); >> + assert(count != 0 && count <= integerPartWidth / 4); >> >> part >>= (integerPartWidth - 4 * count); >> while (count--) { >> @@ -760,7 +760,7 @@ >> { >> assert(category == fcNormal || category == fcNaN); >> >> - if(partCount() > 1) >> + if (partCount() > 1) >> return significand.parts; >> else >> return &significand.part; >> @@ -2289,8 +2289,8 @@ >> >> /* Both multiplySignificand and divideSignificand return the >> result with the integer bit set. */ >> - assert (APInt::tcExtractBit >> - (decSig.significandParts(), calcSemantics.precision - >> 1) == 1); >> + assert(APInt::tcExtractBit >> + (decSig.significandParts(), calcSemantics.precision - >> 1) == 1); >> >> HUerr = HUerrBound(calcLostFraction != lfExactlyZero, sigStatus ! >> = opOK, >> powHUerr); >> @@ -2593,7 +2593,7 @@ >> q--; >> *q = hexDigitChars[hexDigitValue (*q) + 1]; >> } while (*q == '0'); >> - assert (q >= p); >> + assert(q >= p); >> } else { >> /* Add trailing zeroes. */ >> memset (dst, '0', outputDigits); >> @@ -2632,6 +2632,56 @@ >> } >> } >> >> +void APFloat::getIEEEFloatParts(bool &Sign, uint32_t &Exp, >> + uint32_t &Significand) const { >> + assert(semantics == (const llvm::fltSemantics*)&IEEEsingle && >> + "Float semantics are not IEEEsingle"); >> + assert(partCount()==1); >> + >> + if (category == fcNormal) { >> + Exp = exponent+127; // bias >> + Significand = (uint32_t)*significandParts(); >> + if (Exp == 1 && !(Significand & 0x800000)) >> + Exp = 0; // denormal >> + } else if (category==fcZero) { >> + Exp = 0; >> + Significand = 0; >> + } else if (category==fcInfinity) { >> + Exp = 0xff; >> + Significand = 0; >> + } else { >> + assert(category == fcNaN && "Unknown category!"); >> + Exp = 0xff; >> + Significand = (uint32_t)*significandParts(); >> + } >> + Sign = sign; >> +} >> + >> +void APFloat::getIEEEDoubleParts(bool &Sign, uint64_t &Exp, >> + uint64_t &Significand) const { >> + assert(semantics == (const llvm::fltSemantics*)&IEEEdouble && >> + "Float semantics are not IEEEdouble"); >> + assert(partCount()==1); >> + >> + if (category == fcNormal) { >> + Exp = exponent+1023; // bias >> + Significand = *significandParts(); >> + if (Exp == 1 && !(Significand & 0x10000000000000LL)) >> + Exp = 0; // denormal >> + } else if (category==fcZero) { >> + Exp = 0; >> + Significand = 0; >> + } else if (category==fcInfinity) { >> + Exp = 0x7ff; >> + Significand = 0; >> + } else { >> + assert(category == fcNaN && "Unknown category!"); >> + Exp = 0x7ff; >> + Significand = *significandParts(); >> + } >> + Sign = sign; >> +} >> + >> // Conversion from APFloat to/from host float/double. It may >> eventually be >> // possible to eliminate these and have everybody deal with >> APFloats, but that >> // will take a while. This approach will not easily extend to long >> double. >> @@ -2645,7 +2695,7 @@ >> APFloat::convertF80LongDoubleAPFloatToAPInt() const >> { >> assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended); >> - assert (partCount()==2); >> + assert(partCount()==2); >> >> uint64_t myexponent, mysignificand; >> >> @@ -2677,7 +2727,7 @@ >> APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const >> { >> assert(semantics == (const llvm::fltSemantics*)&PPCDoubleDouble); >> - assert (partCount()==2); >> + assert(partCount()==2); >> >> uint64_t myexponent, mysignificand, myexponent2, mysignificand2; >> >> @@ -2722,7 +2772,7 @@ >> APFloat::convertQuadrupleAPFloatToAPInt() const >> { >> assert(semantics == (const llvm::fltSemantics*)&IEEEquad); >> - assert (partCount()==2); >> + assert(partCount()==2); >> >> uint64_t myexponent, mysignificand, mysignificand2; >> >> @@ -2758,7 +2808,7 @@ >> APFloat::convertDoubleAPFloatToAPInt() const >> { >> assert(semantics == (const llvm::fltSemantics*)&IEEEdouble); >> - assert (partCount()==1); >> + assert(partCount()==1); >> >> uint64_t myexponent, mysignificand; >> >> @@ -2788,7 +2838,7 @@ >> APFloat::convertFloatAPFloatToAPInt() const >> { >> assert(semantics == (const llvm::fltSemantics*)&IEEEsingle); >> - assert (partCount()==1); >> + assert(partCount()==1); >> >> uint32_t myexponent, mysignificand; >> >> @@ -2817,7 +2867,7 @@ >> APFloat::convertHalfAPFloatToAPInt() const >> { >> assert(semantics == (const llvm::fltSemantics*)&IEEEhalf); >> - assert (partCount()==1); >> + assert(partCount()==1); >> >> uint32_t myexponent, mysignificand; >> >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From jyasskin at google.com Tue Oct 27 17:02:30 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Tue, 27 Oct 2009 15:02:30 -0700 Subject: [llvm-commits] [llvm] r85295 - in /llvm/trunk: docs/tutorial/LangImpl4.html docs/tutorial/OCamlLangImpl4.html include/llvm/ExecutionEngine/ExecutionEngine.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngi In-Reply-To: References: <9879CBCC-0704-4FC7-8061-94D382FA7587@apple.com> Message-ID: Look good? On Tue, Oct 27, 2009 at 2:34 PM, Jeffrey Yasskin wrote: > On Tue, Oct 27, 2009 at 2:27 PM, Evan Cheng wrote: >> >> On Oct 27, 2009, at 2:11 PM, Jeffrey Yasskin wrote: >> >>> On Tue, Oct 27, 2009 at 1:54 PM, Evan Cheng wrote: >>>> >>>> On Oct 27, 2009, at 1:30 PM, Jeffrey Yasskin wrote: >>>> >>>>> Author: jyasskin >>>>> Date: Tue Oct 27 15:30:28 2009 >>>>> New Revision: 85295 >>>>> >>>>> URL: http://llvm.org/viewvc/llvm-project?rev=85295&view=rev >>>>> Log: >>>>> Change the JIT to compile eagerly by default as agreed in >>>>> http://llvm.org/PR5184, and beef up the comments to describe what both >>>>> options >>>>> do and the risks of lazy compilation in the presence of threads. >>>> >>>> Hi Jeffrey, >>>> >>>> In the future I'd prefer API changes be agreed upon by the greater >>>> community, not just in a bugzilla report. >>> >>> Sorry about that. Do you want me to revert this until we can ping llvmdev? >>> >>>> Lazy compilation is being used by some important clients. They will be >>>> caught off guard by this change. Does this change lli default behavior? >>> >>> No, it doesn't change lli's default, although that was an accident on >>> my part (maybe a fortunate accident). I did ping llvmdev last week >>> asking people who use the lazy JIT to look at the bug report, but I >>> can see how people who don't use threads with the JIT would think it >>> didn't apply to them. >> >> Sorry, I have been too busy with other things so I didn't follow the thread. >> >> The patch changed DisableLazyCompilation to EnableLazyCompilation, which is >> minor but it's a API change nevertheless. ?That means clients which are >> using 2.6 have to change their code in order to test against tot. Unless >> this is absolutely necessary, I'd prefer not to change it. > > It's not necessary. I'd like to keep the new query method since it > removes some double-negatives inside the JIT, but they can easily live > alongside each other for the 2.7 release. > > I'll send a patch renaming Enable... back to Disable... and adding the > old query method back. > -------------- next part -------------- A non-text attachment was scrubbed... Name: revert-api-change.diff Type: application/octet-stream Size: 3423 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091027/13badc4f/attachment.obj From gohman at apple.com Tue Oct 27 17:10:35 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 27 Oct 2009 22:10:35 -0000 Subject: [llvm-commits] [llvm] r85325 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Message-ID: <200910272210.n9RMAZoR017800@zion.cs.uiuc.edu> Author: djg Date: Tue Oct 27 17:10:34 2009 New Revision: 85325 URL: http://llvm.org/viewvc/llvm-project?rev=85325&view=rev Log: Update the MachineBasicBlock CFG for an indirect branch. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=85325&r1=85324&r2=85325&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Tue Oct 27 17:10:34 2009 @@ -2132,6 +2132,10 @@ } void SelectionDAGLowering::visitIndBr(IndBrInst &I) { + // Update machine-CFG edges. + for (unsigned i = 0, e = I.getNumSuccessors(); i != e; ++i) + CurMBB->addSuccessor(FuncInfo.MBBMap[I.getSuccessor(i)]); + DAG.setRoot(DAG.getNode(ISD::BRIND, getCurDebugLoc(), MVT::Other, getControlRoot(), getValue(I.getAddress()))); From dpatel at apple.com Tue Oct 27 17:16:30 2009 From: dpatel at apple.com (Devang Patel) Date: Tue, 27 Oct 2009 22:16:30 -0000 Subject: [llvm-commits] [llvm] r85327 - in /llvm/trunk: include/llvm/InstrTypes.h include/llvm/Instruction.h include/llvm/Instructions.h lib/Transforms/Scalar/IndVarSimplify.cpp lib/Transforms/Utils/BasicBlockUtils.cpp lib/VMCore/Instruction.cpp lib/VMCore/Instructions.cpp unittests/Transforms/Utils/Cloning.cpp Message-ID: <200910272216.n9RMGUhi018084@zion.cs.uiuc.edu> Author: dpatel Date: Tue Oct 27 17:16:29 2009 New Revision: 85327 URL: http://llvm.org/viewvc/llvm-project?rev=85327&view=rev Log: Factor out redundancy from clone() implementations. Modified: llvm/trunk/include/llvm/InstrTypes.h llvm/trunk/include/llvm/Instruction.h llvm/trunk/include/llvm/Instructions.h llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/trunk/lib/VMCore/Instruction.cpp llvm/trunk/lib/VMCore/Instructions.cpp llvm/trunk/unittests/Transforms/Utils/Cloning.cpp Modified: llvm/trunk/include/llvm/InstrTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InstrTypes.h?rev=85327&r1=85326&r2=85327&view=diff ============================================================================== --- llvm/trunk/include/llvm/InstrTypes.h (original) +++ llvm/trunk/include/llvm/InstrTypes.h Tue Oct 27 17:16:29 2009 @@ -51,10 +51,9 @@ virtual BasicBlock *getSuccessorV(unsigned idx) const = 0; virtual unsigned getNumSuccessorsV() const = 0; virtual void setSuccessorV(unsigned idx, BasicBlock *B) = 0; + virtual TerminatorInst *clone_impl() const = 0; public: - virtual TerminatorInst *clone() const = 0; - /// getNumSuccessors - Return the number of successors that this terminator /// has. unsigned getNumSuccessors() const { @@ -145,6 +144,7 @@ const Twine &Name, Instruction *InsertBefore); BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd); + virtual BinaryOperator *clone_impl() const; public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -297,8 +297,6 @@ return static_cast(Instruction::getOpcode()); } - virtual BinaryOperator *clone() const; - /// swapOperands - Exchange the two operands to this instruction. /// This instruction is safe to use on any binary instruction and /// does not modify the semantics of the instruction. If the instruction Modified: llvm/trunk/include/llvm/Instruction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instruction.h?rev=85327&r1=85326&r2=85327&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instruction.h (original) +++ llvm/trunk/include/llvm/Instruction.h Tue Oct 27 17:16:29 2009 @@ -38,6 +38,7 @@ Instruction *InsertBefore = 0); Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd); + virtual Instruction *clone_impl() const = 0; public: // Out of line virtual method, so the vtable, etc has a home. ~Instruction(); @@ -47,7 +48,7 @@ /// * The instruction has no parent /// * The instruction has no name /// - virtual Instruction *clone() const = 0; + Instruction *clone() const; /// isIdenticalTo - Return true if the specified instruction is exactly /// identical to the current one. This means that all operands match and any Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=85327&r1=85326&r2=85327&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Tue Oct 27 17:16:29 2009 @@ -38,6 +38,8 @@ /// AllocaInst - an instruction to allocate memory on the stack /// class AllocaInst : public UnaryInstruction { +protected: + virtual AllocaInst *clone_impl() const; public: explicit AllocaInst(const Type *Ty, Value *ArraySize = 0, const Twine &Name = "", Instruction *InsertBefore = 0); @@ -88,8 +90,6 @@ /// into the prolog/epilog code, so it is basically free. bool isStaticAlloca() const; - virtual AllocaInst *clone() const; - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const AllocaInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -110,6 +110,8 @@ /// class LoadInst : public UnaryInstruction { void AssertOK(); +protected: + virtual LoadInst *clone_impl() const; public: LoadInst(Value *Ptr, const Twine &NameStr, Instruction *InsertBefore); LoadInst(Value *Ptr, const Twine &NameStr, BasicBlock *InsertAtEnd); @@ -140,8 +142,6 @@ SubclassData = (SubclassData & ~1) | (V ? 1 : 0); } - virtual LoadInst *clone() const; - /// getAlignment - Return the alignment of the access that is being performed /// unsigned getAlignment() const { @@ -179,6 +179,8 @@ class StoreInst : public Instruction { void *operator new(size_t, unsigned); // DO NOT IMPLEMENT void AssertOK(); +protected: + virtual StoreInst *clone_impl() const; public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -217,8 +219,6 @@ void setAlignment(unsigned Align); - virtual StoreInst *clone() const; - Value *getPointerOperand() { return getOperand(1); } const Value *getPointerOperand() const { return getOperand(1); } static unsigned getPointerOperandIndex() { return 1U; } @@ -327,6 +327,8 @@ Instruction *InsertBefore = 0); GetElementPtrInst(Value *Ptr, Value *Idx, const Twine &NameStr, BasicBlock *InsertAtEnd); +protected: + virtual GetElementPtrInst *clone_impl() const; public: template static GetElementPtrInst *Create(Value *Ptr, InputIterator IdxBegin, @@ -400,8 +402,6 @@ return GEP; } - virtual GetElementPtrInst *clone() const; - /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -548,6 +548,9 @@ /// must be identical types. /// @brief Represent an integer comparison operator. class ICmpInst: public CmpInst { +protected: + /// @brief Clone an indentical ICmpInst + virtual ICmpInst *clone_impl() const; public: /// @brief Constructor with insert-before-instruction semantics. ICmpInst( @@ -676,8 +679,6 @@ Op<0>().swap(Op<1>()); } - virtual ICmpInst *clone() const; - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ICmpInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -698,6 +699,9 @@ /// vectors of floating point values. The operands must be identical types. /// @brief Represents a floating point comparison operator. class FCmpInst: public CmpInst { +protected: + /// @brief Clone an indentical FCmpInst + virtual FCmpInst *clone_impl() const; public: /// @brief Constructor with insert-before-instruction semantics. FCmpInst( @@ -785,8 +789,6 @@ Op<0>().swap(Op<1>()); } - virtual FCmpInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FCmpInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -854,6 +856,8 @@ explicit CallInst(Value *F, const Twine &NameStr, Instruction *InsertBefore); CallInst(Value *F, const Twine &NameStr, BasicBlock *InsertAtEnd); +protected: + virtual CallInst *clone_impl() const; public: template static CallInst *Create(Value *Func, @@ -912,8 +916,6 @@ SubclassData = (SubclassData & ~1) | unsigned(isTC); } - virtual CallInst *clone() const; - /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -1081,6 +1083,8 @@ init(C, S1, S2); setName(NameStr); } +protected: + virtual SelectInst *clone_impl() const; public: static SelectInst *Create(Value *C, Value *S1, Value *S2, const Twine &NameStr = "", @@ -1111,8 +1115,6 @@ return static_cast(Instruction::getOpcode()); } - virtual SelectInst *clone() const; - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SelectInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -1137,6 +1139,9 @@ /// an argument of the specified type given a va_list and increments that list /// class VAArgInst : public UnaryInstruction { +protected: + virtual VAArgInst *clone_impl() const; + public: VAArgInst(Value *List, const Type *Ty, const Twine &NameStr = "", Instruction *InsertBefore = 0) @@ -1149,8 +1154,6 @@ setName(NameStr); } - virtual VAArgInst *clone() const; - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const VAArgInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -1173,6 +1176,9 @@ Instruction *InsertBefore = 0); ExtractElementInst(Value *Vec, Value *Idx, const Twine &NameStr, BasicBlock *InsertAtEnd); +protected: + virtual ExtractElementInst *clone_impl() const; + public: static ExtractElementInst *Create(Value *Vec, Value *Idx, const Twine &NameStr = "", @@ -1189,8 +1195,6 @@ /// formed with the specified operands. static bool isValidOperands(const Value *Vec, const Value *Idx); - virtual ExtractElementInst *clone() const; - Value *getVectorOperand() { return Op<0>(); } Value *getIndexOperand() { return Op<1>(); } const Value *getVectorOperand() const { return Op<0>(); } @@ -1233,6 +1237,9 @@ Instruction *InsertBefore = 0); InsertElementInst(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr, BasicBlock *InsertAtEnd); +protected: + virtual InsertElementInst *clone_impl() const; + public: static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr = "", @@ -1250,8 +1257,6 @@ static bool isValidOperands(const Value *Vec, const Value *NewElt, const Value *Idx); - virtual InsertElementInst *clone() const; - /// getType - Overload to return most specific vector type. /// const VectorType *getType() const { @@ -1285,6 +1290,9 @@ /// input vectors. /// class ShuffleVectorInst : public Instruction { +protected: + virtual ShuffleVectorInst *clone_impl() const; + public: // allocate space for exactly three operands void *operator new(size_t s) { @@ -1301,8 +1309,6 @@ static bool isValidOperands(const Value *V1, const Value *V2, const Value *Mask); - virtual ShuffleVectorInst *clone() const; - /// getType - Overload to return most specific vector type. /// const VectorType *getType() const { @@ -1411,6 +1417,8 @@ void *operator new(size_t s) { return User::operator new(s, 1); } +protected: + virtual ExtractValueInst *clone_impl() const; public: template @@ -1445,8 +1453,6 @@ return new ExtractValueInst(Agg, Idxs, Idxs + 1, NameStr, InsertAtEnd); } - virtual ExtractValueInst *clone() const; - /// getIndexedType - Returns the type of the element that would be extracted /// with an extractvalue instruction with the specified parameters. /// @@ -1578,6 +1584,8 @@ Instruction *InsertBefore = 0); InsertValueInst(Value *Agg, Value *Val, unsigned Idx, const Twine &NameStr, BasicBlock *InsertAtEnd); +protected: + virtual InsertValueInst *clone_impl() const; public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -1615,8 +1623,6 @@ return new InsertValueInst(Agg, Val, Idx, NameStr, InsertAtEnd); } - virtual InsertValueInst *clone() const; - /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -1725,6 +1731,8 @@ ReservedSpace(0) { setName(NameStr); } +protected: + virtual PHINode *clone_impl() const; public: static PHINode *Create(const Type *Ty, const Twine &NameStr = "", Instruction *InsertBefore = 0) { @@ -1744,8 +1752,6 @@ resizeOperands(NumValues*2); } - virtual PHINode *clone() const; - /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -1907,6 +1913,8 @@ Instruction *InsertBefore = 0); ReturnInst(LLVMContext &C, Value *retVal, BasicBlock *InsertAtEnd); explicit ReturnInst(LLVMContext &C, BasicBlock *InsertAtEnd); +protected: + virtual ReturnInst *clone_impl() const; public: static ReturnInst* Create(LLVMContext &C, Value *retVal = 0, Instruction *InsertBefore = 0) { @@ -1921,8 +1929,6 @@ } virtual ~ReturnInst(); - virtual ReturnInst *clone() const; - /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -1982,6 +1988,8 @@ BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd); BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, BasicBlock *InsertAtEnd); +protected: + virtual BranchInst *clone_impl() const; public: static BranchInst *Create(BasicBlock *IfTrue, Instruction *InsertBefore = 0) { return new(1, true) BranchInst(IfTrue, InsertBefore); @@ -2003,8 +2011,6 @@ /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - virtual BranchInst *clone() const; - bool isUnconditional() const { return getNumOperands() == 1; } bool isConditional() const { return getNumOperands() == 3; } @@ -2096,6 +2102,8 @@ /// constructor also autoinserts at the end of the specified BasicBlock. SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, BasicBlock *InsertAtEnd); +protected: + virtual SwitchInst *clone_impl() const; public: static SwitchInst *Create(Value *Value, BasicBlock *Default, unsigned NumCases, Instruction *InsertBefore = 0) { @@ -2173,8 +2181,6 @@ /// void removeCase(unsigned idx); - virtual SwitchInst *clone() const; - unsigned getNumSuccessors() const { return getNumOperands()/2; } BasicBlock *getSuccessor(unsigned idx) const { assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!"); @@ -2245,6 +2251,8 @@ /// make memory allocation more efficient. This constructor also autoinserts /// at the end of the specified BasicBlock. IndBrInst(Value *Address, unsigned NumDests, BasicBlock *InsertAtEnd); +protected: + virtual IndBrInst *clone_impl() const; public: static IndBrInst *Create(Value *Address, unsigned NumDests, Instruction *InsertBefore = 0) { @@ -2281,8 +2289,6 @@ /// indbr instruction. void removeDestination(unsigned i); - virtual IndBrInst *clone() const; - unsigned getNumSuccessors() const { return getNumOperands()-1; } BasicBlock *getSuccessor(unsigned i) const { return cast(getOperand(i+1)); @@ -2364,6 +2370,8 @@ InputIterator ArgBegin, InputIterator ArgEnd, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd); +protected: + virtual InvokeInst *clone_impl() const; public: template static InvokeInst *Create(Value *Func, @@ -2386,8 +2394,6 @@ Values, NameStr, InsertAtEnd); } - virtual InvokeInst *clone() const; - /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -2568,6 +2574,8 @@ /// class UnwindInst : public TerminatorInst { void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +protected: + virtual UnwindInst *clone_impl() const; public: // allocate space for exactly zero operands void *operator new(size_t s) { @@ -2576,8 +2584,6 @@ explicit UnwindInst(LLVMContext &C, Instruction *InsertBefore = 0); explicit UnwindInst(LLVMContext &C, BasicBlock *InsertAtEnd); - virtual UnwindInst *clone() const; - unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -2605,6 +2611,9 @@ /// class UnreachableInst : public TerminatorInst { void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +protected: + virtual UnreachableInst *clone_impl() const; + public: // allocate space for exactly zero operands void *operator new(size_t s) { @@ -2613,8 +2622,6 @@ explicit UnreachableInst(LLVMContext &C, Instruction *InsertBefore = 0); explicit UnreachableInst(LLVMContext &C, BasicBlock *InsertAtEnd); - virtual UnreachableInst *clone() const; - unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -2637,6 +2644,10 @@ /// @brief This class represents a truncation of integer types. class TruncInst : public CastInst { +protected: + /// @brief Clone an identical TruncInst + virtual TruncInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics TruncInst( @@ -2654,9 +2665,6 @@ BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical TruncInst - virtual TruncInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const TruncInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2673,6 +2681,10 @@ /// @brief This class represents zero extension of integer types. class ZExtInst : public CastInst { +protected: + /// @brief Clone an identical ZExtInst + virtual ZExtInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics ZExtInst( @@ -2690,9 +2702,6 @@ BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical ZExtInst - virtual ZExtInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ZExtInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2709,6 +2718,10 @@ /// @brief This class represents a sign extension of integer types. class SExtInst : public CastInst { +protected: + /// @brief Clone an identical SExtInst + virtual SExtInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics SExtInst( @@ -2726,9 +2739,6 @@ BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical SExtInst - virtual SExtInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SExtInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2745,6 +2755,10 @@ /// @brief This class represents a truncation of floating point types. class FPTruncInst : public CastInst { +protected: + /// @brief Clone an identical FPTruncInst + virtual FPTruncInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics FPTruncInst( @@ -2762,9 +2776,6 @@ BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical FPTruncInst - virtual FPTruncInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FPTruncInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2781,6 +2792,10 @@ /// @brief This class represents an extension of floating point types. class FPExtInst : public CastInst { +protected: + /// @brief Clone an identical FPExtInst + virtual FPExtInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics FPExtInst( @@ -2798,9 +2813,6 @@ BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical FPExtInst - virtual FPExtInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FPExtInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2817,6 +2829,10 @@ /// @brief This class represents a cast unsigned integer to floating point. class UIToFPInst : public CastInst { +protected: + /// @brief Clone an identical UIToFPInst + virtual UIToFPInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics UIToFPInst( @@ -2834,9 +2850,6 @@ BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical UIToFPInst - virtual UIToFPInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const UIToFPInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2853,6 +2866,10 @@ /// @brief This class represents a cast from signed integer to floating point. class SIToFPInst : public CastInst { +protected: + /// @brief Clone an identical SIToFPInst + virtual SIToFPInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics SIToFPInst( @@ -2870,9 +2887,6 @@ BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical SIToFPInst - virtual SIToFPInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SIToFPInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2889,6 +2903,10 @@ /// @brief This class represents a cast from floating point to unsigned integer class FPToUIInst : public CastInst { +protected: + /// @brief Clone an identical FPToUIInst + virtual FPToUIInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics FPToUIInst( @@ -2906,9 +2924,6 @@ BasicBlock *InsertAtEnd ///< Where to insert the new instruction ); - /// @brief Clone an identical FPToUIInst - virtual FPToUIInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FPToUIInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2925,6 +2940,10 @@ /// @brief This class represents a cast from floating point to signed integer. class FPToSIInst : public CastInst { +protected: + /// @brief Clone an identical FPToSIInst + virtual FPToSIInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics FPToSIInst( @@ -2942,9 +2961,6 @@ BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical FPToSIInst - virtual FPToSIInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FPToSIInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2979,7 +2995,7 @@ ); /// @brief Clone an identical IntToPtrInst - virtual IntToPtrInst *clone() const; + virtual IntToPtrInst *clone_impl() const; // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const IntToPtrInst *) { return true; } @@ -2997,6 +3013,10 @@ /// @brief This class represents a cast from a pointer to an integer class PtrToIntInst : public CastInst { +protected: + /// @brief Clone an identical PtrToIntInst + virtual PtrToIntInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics PtrToIntInst( @@ -3014,9 +3034,6 @@ BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical PtrToIntInst - virtual PtrToIntInst *clone() const; - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const PtrToIntInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -3033,6 +3050,10 @@ /// @brief This class represents a no-op cast from one type to another. class BitCastInst : public CastInst { +protected: + /// @brief Clone an identical BitCastInst + virtual BitCastInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics BitCastInst( @@ -3050,9 +3071,6 @@ BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical BitCastInst - virtual BitCastInst *clone() const; - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const BitCastInst *) { return true; } static inline bool classof(const Instruction *I) { Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=85327&r1=85326&r2=85327&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Tue Oct 27 17:16:29 2009 @@ -292,7 +292,7 @@ if (NumPreds != 1) { // Clone the PHI and delete the original one. This lets IVUsers and // any other maps purge the original user from their records. - PHINode *NewPN = PN->clone(); + PHINode *NewPN = cast(PN->clone()); NewPN->takeName(PN); NewPN->insertBefore(PN); PN->replaceAllUsesWith(NewPN); Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=85327&r1=85326&r2=85327&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Tue Oct 27 17:16:29 2009 @@ -675,7 +675,7 @@ if (I != I->getParent()->begin()) { BasicBlock::iterator BBI = I; --BBI; if (DbgStopPointInst *DSPI = dyn_cast(BBI)) { - CallInst *newDSPI = DSPI->clone(); + CallInst *newDSPI = cast(DSPI->clone()); newDSPI->insertBefore(InsertPos); } } Modified: llvm/trunk/lib/VMCore/Instruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=85327&r1=85326&r2=85327&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instruction.cpp (original) +++ llvm/trunk/lib/VMCore/Instruction.cpp Tue Oct 27 17:16:29 2009 @@ -492,3 +492,11 @@ return false; // Misc instructions which have effects } } + +Instruction *Instruction::clone() const { + Instruction *New = clone_impl(); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) + getContext().pImpl->TheMetadata.ValueIsCloned(this, New); + return New; +} Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=85327&r1=85326&r2=85327&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Tue Oct 27 17:16:29 2009 @@ -3195,366 +3195,161 @@ } //===----------------------------------------------------------------------===// -// clone() implementations +// clone_impl() implementations //===----------------------------------------------------------------------===// // Define these methods here so vtables don't get emitted into every translation // unit that uses these classes. -GetElementPtrInst *GetElementPtrInst::clone() const { - GetElementPtrInst *New = new(getNumOperands()) GetElementPtrInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -BinaryOperator *BinaryOperator::clone() const { - BinaryOperator *New = Create(getOpcode(), Op<0>(), Op<1>()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -FCmpInst* FCmpInst::clone() const { - FCmpInst *New = new FCmpInst(getPredicate(), Op<0>(), Op<1>()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} -ICmpInst* ICmpInst::clone() const { - ICmpInst *New = new ICmpInst(getPredicate(), Op<0>(), Op<1>()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -ExtractValueInst *ExtractValueInst::clone() const { - ExtractValueInst *New = new ExtractValueInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} -InsertValueInst *InsertValueInst::clone() const { - InsertValueInst *New = new InsertValueInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -AllocaInst *AllocaInst::clone() const { - AllocaInst *New = new AllocaInst(getAllocatedType(), - (Value*)getOperand(0), - getAlignment()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -LoadInst *LoadInst::clone() const { - LoadInst *New = new LoadInst(getOperand(0), - Twine(), isVolatile(), - getAlignment()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -StoreInst *StoreInst::clone() const { - StoreInst *New = new StoreInst(getOperand(0), getOperand(1), - isVolatile(), getAlignment()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -TruncInst *TruncInst::clone() const { - TruncInst *New = new TruncInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -ZExtInst *ZExtInst::clone() const { - ZExtInst *New = new ZExtInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -SExtInst *SExtInst::clone() const { - SExtInst *New = new SExtInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -FPTruncInst *FPTruncInst::clone() const { - FPTruncInst *New = new FPTruncInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -FPExtInst *FPExtInst::clone() const { - FPExtInst *New = new FPExtInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -UIToFPInst *UIToFPInst::clone() const { - UIToFPInst *New = new UIToFPInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -SIToFPInst *SIToFPInst::clone() const { - SIToFPInst *New = new SIToFPInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -FPToUIInst *FPToUIInst::clone() const { - FPToUIInst *New = new FPToUIInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -FPToSIInst *FPToSIInst::clone() const { - FPToSIInst *New = new FPToSIInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -PtrToIntInst *PtrToIntInst::clone() const { - PtrToIntInst *New = new PtrToIntInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -IntToPtrInst *IntToPtrInst::clone() const { - IntToPtrInst *New = new IntToPtrInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -BitCastInst *BitCastInst::clone() const { - BitCastInst *New = new BitCastInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -CallInst *CallInst::clone() const { - CallInst *New = new(getNumOperands()) CallInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -SelectInst *SelectInst::clone() const { - SelectInst *New = SelectInst::Create(getOperand(0), - getOperand(1), - getOperand(2)); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -VAArgInst *VAArgInst::clone() const { - VAArgInst *New = new VAArgInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -ExtractElementInst *ExtractElementInst::clone() const { - ExtractElementInst *New = ExtractElementInst::Create(getOperand(0), - getOperand(1)); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -InsertElementInst *InsertElementInst::clone() const { - InsertElementInst *New = InsertElementInst::Create(getOperand(0), - getOperand(1), - getOperand(2)); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -ShuffleVectorInst *ShuffleVectorInst::clone() const { - ShuffleVectorInst *New = new ShuffleVectorInst(getOperand(0), - getOperand(1), - getOperand(2)); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -PHINode *PHINode::clone() const { - PHINode *New = new PHINode(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -ReturnInst *ReturnInst::clone() const { - ReturnInst *New = new(getNumOperands()) ReturnInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +GetElementPtrInst *GetElementPtrInst::clone_impl() const { + return new (getNumOperands()) GetElementPtrInst(*this); } -BranchInst *BranchInst::clone() const { +BinaryOperator *BinaryOperator::clone_impl() const { + return Create(getOpcode(), Op<0>(), Op<1>()); +} + +FCmpInst* FCmpInst::clone_impl() const { + return new FCmpInst(getPredicate(), Op<0>(), Op<1>()); +} + +ICmpInst* ICmpInst::clone_impl() const { + return new ICmpInst(getPredicate(), Op<0>(), Op<1>()); +} + +ExtractValueInst *ExtractValueInst::clone_impl() const { + return new ExtractValueInst(*this); +} + +InsertValueInst *InsertValueInst::clone_impl() const { + return new InsertValueInst(*this); +} + +AllocaInst *AllocaInst::clone_impl() const { + return new AllocaInst(getAllocatedType(), + (Value*)getOperand(0), + getAlignment()); +} + +LoadInst *LoadInst::clone_impl() const { + return new LoadInst(getOperand(0), + Twine(), isVolatile(), + getAlignment()); +} + +StoreInst *StoreInst::clone_impl() const { + return new StoreInst(getOperand(0), getOperand(1), + isVolatile(), getAlignment()); +} + +TruncInst *TruncInst::clone_impl() const { + return new TruncInst(getOperand(0), getType()); +} + +ZExtInst *ZExtInst::clone_impl() const { + return new ZExtInst(getOperand(0), getType()); +} + +SExtInst *SExtInst::clone_impl() const { + return new SExtInst(getOperand(0), getType()); +} + +FPTruncInst *FPTruncInst::clone_impl() const { + return new FPTruncInst(getOperand(0), getType()); +} + +FPExtInst *FPExtInst::clone_impl() const { + return new FPExtInst(getOperand(0), getType()); +} + +UIToFPInst *UIToFPInst::clone_impl() const { + return new UIToFPInst(getOperand(0), getType()); +} + +SIToFPInst *SIToFPInst::clone_impl() const { + return new SIToFPInst(getOperand(0), getType()); +} + +FPToUIInst *FPToUIInst::clone_impl() const { + return new FPToUIInst(getOperand(0), getType()); +} + +FPToSIInst *FPToSIInst::clone_impl() const { + return new FPToSIInst(getOperand(0), getType()); +} + +PtrToIntInst *PtrToIntInst::clone_impl() const { + return new PtrToIntInst(getOperand(0), getType()); +} + +IntToPtrInst *IntToPtrInst::clone_impl() const { + return new IntToPtrInst(getOperand(0), getType()); +} + +BitCastInst *BitCastInst::clone_impl() const { + return new BitCastInst(getOperand(0), getType()); +} + +CallInst *CallInst::clone_impl() const { + return new(getNumOperands()) CallInst(*this); +} + +SelectInst *SelectInst::clone_impl() const { + return SelectInst::Create(getOperand(0), getOperand(1), getOperand(2)); +} + +VAArgInst *VAArgInst::clone_impl() const { + return new VAArgInst(getOperand(0), getType()); +} + +ExtractElementInst *ExtractElementInst::clone_impl() const { + return ExtractElementInst::Create(getOperand(0), getOperand(1)); +} + +InsertElementInst *InsertElementInst::clone_impl() const { + return InsertElementInst::Create(getOperand(0), + getOperand(1), + getOperand(2)); +} + +ShuffleVectorInst *ShuffleVectorInst::clone_impl() const { + return new ShuffleVectorInst(getOperand(0), + getOperand(1), + getOperand(2)); +} + +PHINode *PHINode::clone_impl() const { + return new PHINode(*this); +} + +ReturnInst *ReturnInst::clone_impl() const { + return new(getNumOperands()) ReturnInst(*this); +} + +BranchInst *BranchInst::clone_impl() const { unsigned Ops(getNumOperands()); - BranchInst *New = new(Ops, Ops == 1) BranchInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -SwitchInst *SwitchInst::clone() const { - SwitchInst *New = new SwitchInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} - -IndBrInst *IndBrInst::clone() const { - IndBrInst *New = new IndBrInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) - getContext().pImpl->TheMetadata.ValueIsCloned(this, New); - return New; + return new(Ops, Ops == 1) BranchInst(*this); +} + +SwitchInst *SwitchInst::clone_impl() const { + return new SwitchInst(*this); +} + +IndBrInst *IndBrInst::clone_impl() const { + return new IndBrInst(*this); } -InvokeInst *InvokeInst::clone() const { - InvokeInst *New = new(getNumOperands()) InvokeInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +InvokeInst *InvokeInst::clone_impl() const { + return new(getNumOperands()) InvokeInst(*this); } -UnwindInst *UnwindInst::clone() const { +UnwindInst *UnwindInst::clone_impl() const { LLVMContext &Context = getContext(); - UnwindInst *New = new UnwindInst(Context); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - return New; + return new UnwindInst(Context); } -UnreachableInst *UnreachableInst::clone() const { +UnreachableInst *UnreachableInst::clone_impl() const { LLVMContext &Context = getContext(); - UnreachableInst *New = new UnreachableInst(Context); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - return New; + return new UnreachableInst(Context); } Modified: llvm/trunk/unittests/Transforms/Utils/Cloning.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/Cloning.cpp?rev=85327&r1=85326&r2=85327&view=diff ============================================================================== --- llvm/trunk/unittests/Transforms/Utils/Cloning.cpp (original) +++ llvm/trunk/unittests/Transforms/Utils/Cloning.cpp Tue Oct 27 17:16:29 2009 @@ -22,45 +22,45 @@ BinaryOperator *Sub = BinaryOperator::Create(Instruction::Sub, V, V); BinaryOperator *Mul = BinaryOperator::Create(Instruction::Mul, V, V); - EXPECT_FALSE(Add->clone()->hasNoUnsignedWrap()); - EXPECT_FALSE(Add->clone()->hasNoSignedWrap()); - EXPECT_FALSE(Sub->clone()->hasNoUnsignedWrap()); - EXPECT_FALSE(Sub->clone()->hasNoSignedWrap()); - EXPECT_FALSE(Mul->clone()->hasNoUnsignedWrap()); - EXPECT_FALSE(Mul->clone()->hasNoSignedWrap()); + EXPECT_FALSE(cast(Add->clone())->hasNoUnsignedWrap()); + EXPECT_FALSE(cast(Add->clone())->hasNoSignedWrap()); + EXPECT_FALSE(cast(Sub->clone())->hasNoUnsignedWrap()); + EXPECT_FALSE(cast(Sub->clone())->hasNoSignedWrap()); + EXPECT_FALSE(cast(Mul->clone())->hasNoUnsignedWrap()); + EXPECT_FALSE(cast(Mul->clone())->hasNoSignedWrap()); Add->setHasNoUnsignedWrap(); Sub->setHasNoUnsignedWrap(); Mul->setHasNoUnsignedWrap(); - EXPECT_TRUE(Add->clone()->hasNoUnsignedWrap()); - EXPECT_FALSE(Add->clone()->hasNoSignedWrap()); - EXPECT_TRUE(Sub->clone()->hasNoUnsignedWrap()); - EXPECT_FALSE(Sub->clone()->hasNoSignedWrap()); - EXPECT_TRUE(Mul->clone()->hasNoUnsignedWrap()); - EXPECT_FALSE(Mul->clone()->hasNoSignedWrap()); + EXPECT_TRUE(cast(Add->clone())->hasNoUnsignedWrap()); + EXPECT_FALSE(cast(Add->clone())->hasNoSignedWrap()); + EXPECT_TRUE(cast(Sub->clone())->hasNoUnsignedWrap()); + EXPECT_FALSE(cast(Sub->clone())->hasNoSignedWrap()); + EXPECT_TRUE(cast(Mul->clone())->hasNoUnsignedWrap()); + EXPECT_FALSE(cast(Mul->clone())->hasNoSignedWrap()); Add->setHasNoSignedWrap(); Sub->setHasNoSignedWrap(); Mul->setHasNoSignedWrap(); - EXPECT_TRUE(Add->clone()->hasNoUnsignedWrap()); - EXPECT_TRUE(Add->clone()->hasNoSignedWrap()); - EXPECT_TRUE(Sub->clone()->hasNoUnsignedWrap()); - EXPECT_TRUE(Sub->clone()->hasNoSignedWrap()); - EXPECT_TRUE(Mul->clone()->hasNoUnsignedWrap()); - EXPECT_TRUE(Mul->clone()->hasNoSignedWrap()); + EXPECT_TRUE(cast(Add->clone())->hasNoUnsignedWrap()); + EXPECT_TRUE(cast(Add->clone())->hasNoSignedWrap()); + EXPECT_TRUE(cast(Sub->clone())->hasNoUnsignedWrap()); + EXPECT_TRUE(cast(Sub->clone())->hasNoSignedWrap()); + EXPECT_TRUE(cast(Mul->clone())->hasNoUnsignedWrap()); + EXPECT_TRUE(cast(Mul->clone())->hasNoSignedWrap()); Add->setHasNoUnsignedWrap(false); Sub->setHasNoUnsignedWrap(false); Mul->setHasNoUnsignedWrap(false); - EXPECT_FALSE(Add->clone()->hasNoUnsignedWrap()); - EXPECT_TRUE(Add->clone()->hasNoSignedWrap()); - EXPECT_FALSE(Sub->clone()->hasNoUnsignedWrap()); - EXPECT_TRUE(Sub->clone()->hasNoSignedWrap()); - EXPECT_FALSE(Mul->clone()->hasNoUnsignedWrap()); - EXPECT_TRUE(Mul->clone()->hasNoSignedWrap()); + EXPECT_FALSE(cast(Add->clone())->hasNoUnsignedWrap()); + EXPECT_TRUE(cast(Add->clone())->hasNoSignedWrap()); + EXPECT_FALSE(cast(Sub->clone())->hasNoUnsignedWrap()); + EXPECT_TRUE(cast(Sub->clone())->hasNoSignedWrap()); + EXPECT_FALSE(cast(Mul->clone())->hasNoUnsignedWrap()); + EXPECT_TRUE(cast(Mul->clone())->hasNoSignedWrap()); } TEST(CloneInstruction, Inbounds) { @@ -70,10 +70,10 @@ std::vector ops; ops.push_back(Z); GetElementPtrInst *GEP = GetElementPtrInst::Create(V, ops.begin(), ops.end()); - EXPECT_FALSE(GEP->clone()->isInBounds()); + EXPECT_FALSE(cast(GEP->clone())->isInBounds()); GEP->setIsInBounds(); - EXPECT_TRUE(GEP->clone()->isInBounds()); + EXPECT_TRUE(cast(GEP->clone())->isInBounds()); } TEST(CloneInstruction, Exact) { @@ -81,8 +81,8 @@ Value *V = new Argument(Type::getInt32Ty(context)); BinaryOperator *SDiv = BinaryOperator::Create(Instruction::SDiv, V, V); - EXPECT_FALSE(SDiv->clone()->isExact()); + EXPECT_FALSE(cast(SDiv->clone())->isExact()); SDiv->setIsExact(true); - EXPECT_TRUE(SDiv->clone()->isExact()); + EXPECT_TRUE(cast(SDiv->clone())->isExact()); } From evan.cheng at apple.com Tue Oct 27 17:21:23 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 27 Oct 2009 15:21:23 -0700 Subject: [llvm-commits] [llvm] r85318 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/Support/APFloat.cpp In-Reply-To: <4E11886E-E7DE-40BE-ADEE-D8B4D6BEA974@apple.com> References: <200910272135.n9RLZhXq016402@zion.cs.uiuc.edu> <4E11886E-E7DE-40BE-ADEE-D8B4D6BEA974@apple.com> Message-ID: On Oct 27, 2009, at 3:00 PM, Evan Cheng wrote: > > On Oct 27, 2009, at 2:50 PM, Dale Johannesen wrote: > >> >> On Oct 27, 2009, at 2:35 PMPDT, Evan Cheng wrote: >> >>> Author: evancheng >>> Date: Tue Oct 27 16:35:42 2009 >>> New Revision: 85318 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=85318&view=rev >>> Log: >>> Add new APFloat methods that return sign, exp, and mantissa of ieee >>> float and double values. >> > >> Why do you want to do this? I think there's a good case for keeping >> these representation details local to APFloat. > > ARM has instructions that can materialize some of the fp immediates. > It has to examine the parts to determine if an fp immediate can be > encoded. What I have checked in so far is wrong. I'm fixing it now. Please scrutinize my next commit carefully. :-) Evan > > Evan > >> >>> Modified: >>> llvm/trunk/include/llvm/ADT/APFloat.h >>> llvm/trunk/lib/Support/APFloat.cpp >>> >>> Modified: llvm/trunk/include/llvm/ADT/APFloat.h >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=85318&r1=85317&r2=85318&view=diff >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/include/llvm/ADT/APFloat.h (original) >>> +++ llvm/trunk/include/llvm/ADT/APFloat.h Tue Oct 27 16:35:42 2009 >>> @@ -277,6 +277,13 @@ >>> /* Return an arbitrary integer value usable for hashing. */ >>> uint32_t getHashValue() const; >>> >>> + /// getIEEEFloatParts / getIEEEDoubleParts - Return exponent, >>> significant, >>> + /// and sign bit of an IEEE float / IEEE double value. >>> + void getIEEEFloatParts(bool &Sign, uint32_t &Exp, >>> + uint32_t &Significant) const; >>> + void getIEEEDoubleParts(bool &Sign, uint64_t &Exp, >>> + uint64_t &Significant) const; >>> + >>> private: >>> >>> /* Trivial queries. */ >>> >>> Modified: llvm/trunk/lib/Support/APFloat.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=85318&r1=85317&r2=85318&view=diff >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/lib/Support/APFloat.cpp (original) >>> +++ llvm/trunk/lib/Support/APFloat.cpp Tue Oct 27 16:35:42 2009 >>> @@ -421,7 +421,7 @@ >>> unsigned int count, partBits; >>> integerPart part, boundary; >>> >>> - assert (bits != 0); >>> + assert(bits != 0); >>> >>> bits--; >>> count = bits / integerPartWidth; >>> @@ -537,7 +537,7 @@ >>> { >>> unsigned int result = count; >>> >>> - assert (count != 0 && count <= integerPartWidth / 4); >>> + assert(count != 0 && count <= integerPartWidth / 4); >>> >>> part >>= (integerPartWidth - 4 * count); >>> while (count--) { >>> @@ -760,7 +760,7 @@ >>> { >>> assert(category == fcNormal || category == fcNaN); >>> >>> - if(partCount() > 1) >>> + if (partCount() > 1) >>> return significand.parts; >>> else >>> return &significand.part; >>> @@ -2289,8 +2289,8 @@ >>> >>> /* Both multiplySignificand and divideSignificand return the >>> result with the integer bit set. */ >>> - assert (APInt::tcExtractBit >>> - (decSig.significandParts(), calcSemantics.precision - >>> 1) == 1); >>> + assert(APInt::tcExtractBit >>> + (decSig.significandParts(), calcSemantics.precision - >>> 1) == 1); >>> >>> HUerr = HUerrBound(calcLostFraction != lfExactlyZero, sigStatus ! >>> = opOK, >>> powHUerr); >>> @@ -2593,7 +2593,7 @@ >>> q--; >>> *q = hexDigitChars[hexDigitValue (*q) + 1]; >>> } while (*q == '0'); >>> - assert (q >= p); >>> + assert(q >= p); >>> } else { >>> /* Add trailing zeroes. */ >>> memset (dst, '0', outputDigits); >>> @@ -2632,6 +2632,56 @@ >>> } >>> } >>> >>> +void APFloat::getIEEEFloatParts(bool &Sign, uint32_t &Exp, >>> + uint32_t &Significand) const { >>> + assert(semantics == (const llvm::fltSemantics*)&IEEEsingle && >>> + "Float semantics are not IEEEsingle"); >>> + assert(partCount()==1); >>> + >>> + if (category == fcNormal) { >>> + Exp = exponent+127; // bias >>> + Significand = (uint32_t)*significandParts(); >>> + if (Exp == 1 && !(Significand & 0x800000)) >>> + Exp = 0; // denormal >>> + } else if (category==fcZero) { >>> + Exp = 0; >>> + Significand = 0; >>> + } else if (category==fcInfinity) { >>> + Exp = 0xff; >>> + Significand = 0; >>> + } else { >>> + assert(category == fcNaN && "Unknown category!"); >>> + Exp = 0xff; >>> + Significand = (uint32_t)*significandParts(); >>> + } >>> + Sign = sign; >>> +} >>> + >>> +void APFloat::getIEEEDoubleParts(bool &Sign, uint64_t &Exp, >>> + uint64_t &Significand) const { >>> + assert(semantics == (const llvm::fltSemantics*)&IEEEdouble && >>> + "Float semantics are not IEEEdouble"); >>> + assert(partCount()==1); >>> + >>> + if (category == fcNormal) { >>> + Exp = exponent+1023; // bias >>> + Significand = *significandParts(); >>> + if (Exp == 1 && !(Significand & 0x10000000000000LL)) >>> + Exp = 0; // denormal >>> + } else if (category==fcZero) { >>> + Exp = 0; >>> + Significand = 0; >>> + } else if (category==fcInfinity) { >>> + Exp = 0x7ff; >>> + Significand = 0; >>> + } else { >>> + assert(category == fcNaN && "Unknown category!"); >>> + Exp = 0x7ff; >>> + Significand = *significandParts(); >>> + } >>> + Sign = sign; >>> +} >>> + >>> // Conversion from APFloat to/from host float/double. It may >>> eventually be >>> // possible to eliminate these and have everybody deal with >>> APFloats, but that >>> // will take a while. This approach will not easily extend to long >>> double. >>> @@ -2645,7 +2695,7 @@ >>> APFloat::convertF80LongDoubleAPFloatToAPInt() const >>> { >>> assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended); >>> - assert (partCount()==2); >>> + assert(partCount()==2); >>> >>> uint64_t myexponent, mysignificand; >>> >>> @@ -2677,7 +2727,7 @@ >>> APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const >>> { >>> assert(semantics == (const llvm::fltSemantics*)&PPCDoubleDouble); >>> - assert (partCount()==2); >>> + assert(partCount()==2); >>> >>> uint64_t myexponent, mysignificand, myexponent2, mysignificand2; >>> >>> @@ -2722,7 +2772,7 @@ >>> APFloat::convertQuadrupleAPFloatToAPInt() const >>> { >>> assert(semantics == (const llvm::fltSemantics*)&IEEEquad); >>> - assert (partCount()==2); >>> + assert(partCount()==2); >>> >>> uint64_t myexponent, mysignificand, mysignificand2; >>> >>> @@ -2758,7 +2808,7 @@ >>> APFloat::convertDoubleAPFloatToAPInt() const >>> { >>> assert(semantics == (const llvm::fltSemantics*)&IEEEdouble); >>> - assert (partCount()==1); >>> + assert(partCount()==1); >>> >>> uint64_t myexponent, mysignificand; >>> >>> @@ -2788,7 +2838,7 @@ >>> APFloat::convertFloatAPFloatToAPInt() const >>> { >>> assert(semantics == (const llvm::fltSemantics*)&IEEEsingle); >>> - assert (partCount()==1); >>> + assert(partCount()==1); >>> >>> uint32_t myexponent, mysignificand; >>> >>> @@ -2817,7 +2867,7 @@ >>> APFloat::convertHalfAPFloatToAPInt() const >>> { >>> assert(semantics == (const llvm::fltSemantics*)&IEEEhalf); >>> - assert (partCount()==1); >>> + assert(partCount()==1); >>> >>> uint32_t myexponent, mysignificand; >>> >>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From ggreif at gmail.com Tue Oct 27 17:30:48 2009 From: ggreif at gmail.com (Gabor Greif) Date: Tue, 27 Oct 2009 15:30:48 -0700 (PDT) Subject: [llvm-commits] [llvm-gcc-4.2] r85273 - /llvm-gcc-4.2/trunk/README.LLVM In-Reply-To: <200910271850.n9RIofjT008983@zion.cs.uiuc.edu> References: <200910271850.n9RIofjT008983@zion.cs.uiuc.edu> Message-ID: On 27 Okt., 19:50, Mike Stump wrote: > Author: mrs > Date: Tue Oct 27 13:50:40 2009 > New Revision: 85273 > > URL:http://llvm.org/viewvc/llvm-project?rev=85273&view=rev > Log: > Fixup for 32-bit hosts. > > Modified: > ? ? llvm-gcc-4.2/trunk/README.LLVM > > Modified: llvm-gcc-4.2/trunk/README.LLVM > URL:http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/README.LLVM?re... > > =========================================================================== === > --- llvm-gcc-4.2/trunk/README.LLVM (original) > +++ llvm-gcc-4.2/trunk/README.LLVM Tue Oct 27 13:50:40 2009 > @@ -86,13 +86,15 @@ > ? ? ?TARGETOPTIONS='--with-arch=nocona --with-tune=generic' > ? ? ?TRIPLE=i686-apple-darwin8 (Tiger) > ? ? ?TRIPLE=i686-apple-darwin9 (Leopard) > - ? ?TRIPLE=x86_64-apple-darwin10 (Snow Leopard) > + ? ?TRIPLE=x86_64-apple-darwin10 (Snow Leopard on a 64-bit machine) > + ? ?TRIPLE=i686-apple-darwin10 (Snow Leopard on a 32-bit machine) > > ?If building for Darwin/X86 (32-bit support only): > ? ? ?TARGETOPTIONS='--with-arch=pentium-m --with-tune=prescott --disable-multilib' > ? ? ?TRIPLE=i686-apple-darwin8 (Tiger) > ? ? ?TRIPLE=i686-apple-darwin9 (Leopard) > - ? ?TRIPLE=x86_64-apple-darwin10 (Snow Leopard) > + ? ?TRIPLE=x86_64-apple-darwin10 (Snow Leopard on a 64-bit machine) > + ? ?TRIPLE=i686-apple-darwin10 (Snow Leopard on a 32-bit machine) Hmmm, this seems to conflict with the "32-bit support only" bit above. Gabor > > ?The Triples are very important, otherwise your llvm-gcc/g++ may not be able > ?to find the header files below. > > _______________________________________________ > llvm-commits mailing list > llvm-comm... at cs.uiuc.eduhttp://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Tue Oct 27 17:32:44 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 27 Oct 2009 15:32:44 -0700 Subject: [llvm-commits] [llvm] r85295 - in /llvm/trunk: docs/tutorial/LangImpl4.html docs/tutorial/OCamlLangImpl4.html include/llvm/ExecutionEngine/ExecutionEngine.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngi In-Reply-To: References: <9879CBCC-0704-4FC7-8061-94D382FA7587@apple.com> Message-ID: Yes thanks. Evan On Oct 27, 2009, at 3:02 PM, Jeffrey Yasskin wrote: > Look good? > > On Tue, Oct 27, 2009 at 2:34 PM, Jeffrey Yasskin > wrote: >> On Tue, Oct 27, 2009 at 2:27 PM, Evan Cheng >> wrote: >>> >>> On Oct 27, 2009, at 2:11 PM, Jeffrey Yasskin wrote: >>> >>>> On Tue, Oct 27, 2009 at 1:54 PM, Evan Cheng >>>> wrote: >>>>> >>>>> On Oct 27, 2009, at 1:30 PM, Jeffrey Yasskin wrote: >>>>> >>>>>> Author: jyasskin >>>>>> Date: Tue Oct 27 15:30:28 2009 >>>>>> New Revision: 85295 >>>>>> >>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=85295&view=rev >>>>>> Log: >>>>>> Change the JIT to compile eagerly by default as agreed in >>>>>> http://llvm.org/PR5184, and beef up the comments to describe >>>>>> what both >>>>>> options >>>>>> do and the risks of lazy compilation in the presence of threads. >>>>> >>>>> Hi Jeffrey, >>>>> >>>>> In the future I'd prefer API changes be agreed upon by the greater >>>>> community, not just in a bugzilla report. >>>> >>>> Sorry about that. Do you want me to revert this until we can ping >>>> llvmdev? >>>> >>>>> Lazy compilation is being used by some important clients. They >>>>> will be >>>>> caught off guard by this change. Does this change lli default >>>>> behavior? >>>> >>>> No, it doesn't change lli's default, although that was an >>>> accident on >>>> my part (maybe a fortunate accident). I did ping llvmdev last week >>>> asking people who use the lazy JIT to look at the bug report, but I >>>> can see how people who don't use threads with the JIT would think >>>> it >>>> didn't apply to them. >>> >>> Sorry, I have been too busy with other things so I didn't follow >>> the thread. >>> >>> The patch changed DisableLazyCompilation to EnableLazyCompilation, >>> which is >>> minor but it's a API change nevertheless. That means clients >>> which are >>> using 2.6 have to change their code in order to test against tot. >>> Unless >>> this is absolutely necessary, I'd prefer not to change it. >> >> It's not necessary. I'd like to keep the new query method since it >> removes some double-negatives inside the JIT, but they can easily >> live >> alongside each other for the 2.7 release. >> >> I'll send a patch renaming Enable... back to Disable... and adding >> the >> old query method back. >> > From isanbard at gmail.com Tue Oct 27 17:34:43 2009 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 27 Oct 2009 22:34:43 -0000 Subject: [llvm-commits] [llvm] r85329 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <200910272234.n9RMYhAh018758@zion.cs.uiuc.edu> Author: void Date: Tue Oct 27 17:34:43 2009 New Revision: 85329 URL: http://llvm.org/viewvc/llvm-project?rev=85329&view=rev Log: Add a note. Modified: llvm/trunk/lib/Target/X86/README.txt Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=85329&r1=85328&r2=85329&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Tue Oct 27 17:34:43 2009 @@ -1952,3 +1952,26 @@ add target specific information to target nodes and have this information carried over to machine instructions. Asm printer (or JIT) can use this information to add the "lock" prefix. + +//===---------------------------------------------------------------------===// + +int func(int a, int b) { if (a & 0x80) b |= 0x80; else b &= 0x80; return b; } + +Current: + + movb %sil, %al + andb $-128, %sil + orb $-128, %al + testb %dil, %dil + js LBB1_2 + movb %sil, %al +LBB1_2: + movsbl %al, %eax + +Better: + movl %esi, %eax + orl $-128, %eax + andl $-128, %esi + testb %dil, %dil + cmovns %esi, %eax + movsbl %al,%eax From jyasskin at google.com Tue Oct 27 17:39:43 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Tue, 27 Oct 2009 22:39:43 -0000 Subject: [llvm-commits] [llvm] r85330 - in /llvm/trunk: include/llvm/ExecutionEngine/ExecutionEngine.h tools/lli/lli.cpp unittests/ExecutionEngine/JIT/JITTest.cpp Message-ID: <200910272239.n9RMdhY0018943@zion.cs.uiuc.edu> Author: jyasskin Date: Tue Oct 27 17:39:42 2009 New Revision: 85330 URL: http://llvm.org/viewvc/llvm-project?rev=85330&view=rev Log: Revert the API changes from r85295 to make it easier for people to build against both 2.6 and HEAD. The default is still changed to eager jitting. Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h llvm/trunk/tools/lli/lli.cpp llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h?rev=85330&r1=85329&r2=85330&view=diff ============================================================================== --- llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h (original) +++ llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h Tue Oct 27 17:39:42 2009 @@ -319,7 +319,7 @@ virtual void RegisterJITEventListener(JITEventListener *) {} virtual void UnregisterJITEventListener(JITEventListener *) {} - /// EnableLazyCompilation - When lazy compilation is off (the default), the + /// DisableLazyCompilation - When lazy compilation is off (the default), the /// JIT will eagerly compile every function reachable from the argument to /// getPointerToFunction. If lazy compilation is turned on, the JIT will only /// compile the one function and emit stubs to compile the rest when they're @@ -332,12 +332,17 @@ /// stub, and 2) any thread modifying LLVM IR must hold the JIT's lock /// (ExecutionEngine::lock) or otherwise ensure that no other thread calls a /// lazy stub. See http://llvm.org/PR5184 for details. - void EnableLazyCompilation(bool Enabled = true) { - CompilingLazily = Enabled; + void DisableLazyCompilation(bool Disabled = true) { + CompilingLazily = !Disabled; } bool isCompilingLazily() const { return CompilingLazily; } + // Deprecated in favor of isCompilingLazily (to reduce double-negatives). + // Remove this in LLVM 2.8. + bool isLazyCompilationDisabled() const { + return !CompilingLazily; + } /// DisableGVCompilation - If called, the JIT will abort if it's asked to /// allocate space and populate a GlobalVariable that is not internal to Modified: llvm/trunk/tools/lli/lli.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/lli.cpp?rev=85330&r1=85329&r2=85330&view=diff ============================================================================== --- llvm/trunk/tools/lli/lli.cpp (original) +++ llvm/trunk/tools/lli/lli.cpp Tue Oct 27 17:39:42 2009 @@ -165,7 +165,7 @@ EE->RegisterJITEventListener(createOProfileJITEventListener()); - EE->EnableLazyCompilation(!NoLazyCompilation); + EE->DisableLazyCompilation(NoLazyCompilation); // If the user specifically requested an argv[0] to pass into the program, // do it now. Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=85330&r1=85329&r2=85330&view=diff ============================================================================== --- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original) +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Tue Oct 27 17:39:42 2009 @@ -304,7 +304,7 @@ Builder.CreateRet(result); TheJIT->EnableDlsymStubs(false); - TheJIT->EnableLazyCompilation(false); + TheJIT->DisableLazyCompilation(true); int (*TestFunctionPtr)() = reinterpret_cast( (intptr_t)TheJIT->getPointerToFunction(TestFunction)); // This used to crash in trying to call PlusOne(). @@ -314,7 +314,7 @@ #if !defined(__arm__) && !defined(__powerpc__) && !defined(__ppc__) // Test a function C which calls A and B which call each other. TEST_F(JITTest, NonLazyCompilationStillNeedsStubs) { - TheJIT->EnableLazyCompilation(false); + TheJIT->DisableLazyCompilation(true); const FunctionType *Func1Ty = cast(TypeBuilder::get(Context)); @@ -370,7 +370,7 @@ // Regression test for PR5162. This used to trigger an AssertingVH inside the // JIT's Function to stub mapping. TEST_F(JITTest, NonLazyLeaksNoStubs) { - TheJIT->EnableLazyCompilation(false); + TheJIT->DisableLazyCompilation(true); // Create two functions with a single basic block each. const FunctionType *FuncTy = From isanbard at gmail.com Tue Oct 27 17:40:45 2009 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 27 Oct 2009 22:40:45 -0000 Subject: [llvm-commits] [llvm] r85331 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <200910272240.n9RMejib019000@zion.cs.uiuc.edu> Author: void Date: Tue Oct 27 17:40:45 2009 New Revision: 85331 URL: http://llvm.org/viewvc/llvm-project?rev=85331&view=rev Log: Modify note. Modified: llvm/trunk/lib/Target/X86/README.txt Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=85331&r1=85330&r2=85331&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Tue Oct 27 17:40:45 2009 @@ -1969,9 +1969,17 @@ movsbl %al, %eax Better: + movl %esi, %eax orl $-128, %eax andl $-128, %esi testb %dil, %dil cmovns %esi, %eax movsbl %al,%eax + +Best (recognize this as 'b = (b & ~0x80) | (a & 0x80)'): + + andb $-128, %dil + andb $127, %sil + orb %dil, %sil + movsbl %sil, %eax From isanbard at gmail.com Tue Oct 27 17:43:24 2009 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 27 Oct 2009 22:43:24 -0000 Subject: [llvm-commits] [llvm] r85332 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <200910272243.n9RMhOnx019100@zion.cs.uiuc.edu> Author: void Date: Tue Oct 27 17:43:24 2009 New Revision: 85332 URL: http://llvm.org/viewvc/llvm-project?rev=85332&view=rev Log: Note corrected. Modified: llvm/trunk/lib/Target/X86/README.txt Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=85332&r1=85331&r2=85332&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Tue Oct 27 17:43:24 2009 @@ -1955,12 +1955,13 @@ //===---------------------------------------------------------------------===// -int func(int a, int b) { if (a & 0x80) b |= 0x80; else b &= 0x80; return b; } +int func(int a, int b) { if (a & 0x80) b |= 0x80; else b &= ~0x80; return b; } Current: + movb %sil, %al - andb $-128, %sil + andb $127, %sil orb $-128, %al testb %dil, %dil js LBB1_2 @@ -1968,11 +1969,12 @@ LBB1_2: movsbl %al, %eax + Better: movl %esi, %eax orl $-128, %eax - andl $-128, %esi + andl $127, %esi testb %dil, %dil cmovns %esi, %eax movsbl %al,%eax From grosbach at apple.com Tue Oct 27 17:45:39 2009 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 27 Oct 2009 22:45:39 -0000 Subject: [llvm-commits] [llvm] r85333 - in /llvm/trunk/lib/Target/ARM: ARMBaseRegisterInfo.cpp ARMBaseRegisterInfo.h Message-ID: <200910272245.n9RMjdlW019188@zion.cs.uiuc.edu> Author: grosbach Date: Tue Oct 27 17:45:39 2009 New Revision: 85333 URL: http://llvm.org/viewvc/llvm-project?rev=85333&view=rev Log: Infrastructure for dynamic stack realignment on ARM. For now, this is off by default behind a command line option. This will enable better performance for vectors on NEON enabled processors. Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=85333&r1=85332&r2=85333&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Tue Oct 27 17:45:39 2009 @@ -29,6 +29,7 @@ #include "llvm/CodeGen/MachineLocation.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetFrameInfo.h" @@ -48,6 +49,10 @@ ReuseFrameIndexVals("arm-reuse-frame-index-vals", cl::Hidden, cl::init(false), cl::desc("Reuse repeated frame index values")); +static cl::opt +ARMDynamicStackAlign("arm-dynamic-stack-alignment", cl::Hidden, cl::init(false), + cl::desc("Dynamically re-align the stack as needed")); + unsigned ARMBaseRegisterInfo::getRegisterNumbering(unsigned RegEnum, bool *isSPVFP) { if (isSPVFP) @@ -466,6 +471,21 @@ } } +static unsigned calculateMaxStackAlignment(const MachineFrameInfo *FFI) { + unsigned MaxAlign = 0; + + for (int i = FFI->getObjectIndexBegin(), + e = FFI->getObjectIndexEnd(); i != e; ++i) { + if (FFI->isDeadObjectIndex(i)) + continue; + + unsigned Align = FFI->getObjectAlignment(i); + MaxAlign = std::max(MaxAlign, Align); + } + + return MaxAlign; +} + /// hasFP - Return true if the specified function should have a dedicated frame /// pointer register. This is true if the function has variable sized allocas /// or if frame pointer elimination is disabled. @@ -473,10 +493,28 @@ bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); return (NoFramePointerElim || + needsStackRealignment(MF) || MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken()); } +bool ARMBaseRegisterInfo:: +needsStackRealignment(const MachineFunction &MF) const { + // Only do this for ARM if explicitly enabled + // FIXME: Once it's passing all the tests, enable by default + if (!ARMDynamicStackAlign) + return false; + + const MachineFrameInfo *MFI = MF.getFrameInfo(); + const ARMFunctionInfo *AFI = MF.getInfo(); + unsigned StackAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); + return (RealignStack && + !AFI->isThumb1OnlyFunction() && + (MFI->getMaxAlignment() > StackAlign) && + !MFI->hasVarSizedObjects()); + +} + bool ARMBaseRegisterInfo::cannotEliminateFrame(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); if (NoFramePointerElim && MFI->hasCalls()) @@ -552,6 +590,16 @@ SmallVector UnspilledCS2GPRs; ARMFunctionInfo *AFI = MF.getInfo(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + + // Calculate and set max stack object alignment early, so we can decide + // whether we will need stack realignment (and thus FP). + if (ARMDynamicStackAlign) { + unsigned MaxAlign = std::max(MFI->getMaxAlignment(), + calculateMaxStackAlignment(MFI)); + MFI->setMaxAlignment(MaxAlign); + } + // Don't spill FP if the frame can be eliminated. This is determined // by scanning the callee-save registers to see if any is used. const unsigned *CSRegs = getCalleeSavedRegs(); @@ -1085,16 +1133,28 @@ int FrameIndex = MI.getOperand(i).getIndex(); int Offset = MFI->getObjectOffset(FrameIndex) + MFI->getStackSize() + SPAdj; + // When doing dynamic stack realignment, all of these need to change(?) if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex)) Offset -= AFI->getGPRCalleeSavedArea1Offset(); else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex)) Offset -= AFI->getGPRCalleeSavedArea2Offset(); else if (AFI->isDPRCalleeSavedAreaFrame(FrameIndex)) Offset -= AFI->getDPRCalleeSavedAreaOffset(); - else if (hasFP(MF) && AFI->hasStackFrame()) { + else if (needsStackRealignment(MF)) { + // When dynamically realigning the stack, use the frame pointer for + // parameters, and the stack pointer for locals. + assert (hasFP(MF) && "dynamic stack realignment without a FP!"); + if (FrameIndex < 0) { + FrameReg = getFrameRegister(MF); + Offset -= AFI->getFramePtrSpillOffset(); + // When referencing from the frame pointer, stack pointer adjustments + // don't matter. + SPAdj = 0; + } + } else if (hasFP(MF) && AFI->hasStackFrame()) { assert(SPAdj == 0 && "Unexpected stack offset!"); // Use frame pointer to reference fixed objects unless this is a - // frameless function, + // frameless function. FrameReg = getFrameRegister(MF); Offset -= AFI->getFramePtrSpillOffset(); } @@ -1303,6 +1363,18 @@ AFI->setGPRCalleeSavedArea1Size(GPRCS1Size); AFI->setGPRCalleeSavedArea2Size(GPRCS2Size); AFI->setDPRCalleeSavedAreaSize(DPRCSSize); + + // If we need dynamic stack realignment, do it here. + if (needsStackRealignment(MF)) { + unsigned Opc; + unsigned MaxAlign = MFI->getMaxAlignment(); + assert (!AFI->isThumb1OnlyFunction()); + Opc = AFI->isThumbFunction() ? ARM::t2BICri : ARM::BICri; + + AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), ARM::SP) + .addReg(ARM::SP, RegState::Kill) + .addImm(MaxAlign-1))); + } } static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) { Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h?rev=85333&r1=85332&r2=85333&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h Tue Oct 27 17:45:39 2009 @@ -96,6 +96,8 @@ bool hasFP(const MachineFunction &MF) const; + bool needsStackRealignment(const MachineFunction &MF) const; + bool cannotEliminateFrame(const MachineFunction &MF) const; void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, From isanbard at gmail.com Tue Oct 27 17:48:32 2009 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 27 Oct 2009 22:48:32 -0000 Subject: [llvm-commits] [llvm] r85334 - in /llvm/trunk/lib/Target: README.txt X86/README.txt Message-ID: <200910272248.n9RMmWOT019287@zion.cs.uiuc.edu> Author: void Date: Tue Oct 27 17:48:31 2009 New Revision: 85334 URL: http://llvm.org/viewvc/llvm-project?rev=85334&view=rev Log: Move and clarify note. Modified: llvm/trunk/lib/Target/README.txt llvm/trunk/lib/Target/X86/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=85334&r1=85333&r2=85334&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Tue Oct 27 17:48:31 2009 @@ -1600,3 +1600,36 @@ //===---------------------------------------------------------------------===// +int func(int a, int b) { if (a & 0x80) b |= 0x80; else b &= ~0x80; return b; } + +Generates this: + +define i32 @func(i32 %a, i32 %b) nounwind readnone ssp { +entry: + %0 = and i32 %a, 128 ; [#uses=1] + %1 = icmp eq i32 %0, 0 ; [#uses=1] + %2 = or i32 %b, 128 ; [#uses=1] + %3 = and i32 %b, -129 ; [#uses=1] + %b_addr.0 = select i1 %1, i32 %3, i32 %2 ; [#uses=1] + ret i32 %b_addr.0 +} + +However, it's functionally equivalent to: + + b = (b & ~0x80) | (a & 0x80); + +Which generates this: + +define i32 @func(i32 %a, i32 %b) nounwind readnone ssp { +entry: + %0 = and i32 %b, -129 ; [#uses=1] + %1 = and i32 %a, 128 ; [#uses=1] + %2 = or i32 %0, %1 ; [#uses=1] + ret i32 %2 +} + +This can be generalized for other forms: + + b = (b & ~0x80) | (a & 0x40) << 1; + +//===---------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=85334&r1=85333&r2=85334&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Tue Oct 27 17:48:31 2009 @@ -1954,34 +1954,3 @@ information to add the "lock" prefix. //===---------------------------------------------------------------------===// - -int func(int a, int b) { if (a & 0x80) b |= 0x80; else b &= ~0x80; return b; } - -Current: - - - movb %sil, %al - andb $127, %sil - orb $-128, %al - testb %dil, %dil - js LBB1_2 - movb %sil, %al -LBB1_2: - movsbl %al, %eax - - -Better: - - movl %esi, %eax - orl $-128, %eax - andl $127, %esi - testb %dil, %dil - cmovns %esi, %eax - movsbl %al,%eax - -Best (recognize this as 'b = (b & ~0x80) | (a & 0x80)'): - - andb $-128, %dil - andb $127, %sil - orb %dil, %sil - movsbl %sil, %eax From grosbach at apple.com Tue Oct 27 17:52:29 2009 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 27 Oct 2009 22:52:29 -0000 Subject: [llvm-commits] [llvm] r85335 - /llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Message-ID: <200910272252.n9RMqT48019425@zion.cs.uiuc.edu> Author: grosbach Date: Tue Oct 27 17:52:29 2009 New Revision: 85335 URL: http://llvm.org/viewvc/llvm-project?rev=85335&view=rev Log: Enable virtual register based frame index scavenging by default for ARM & T2. Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=85335&r1=85334&r2=85335&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Tue Oct 27 17:52:29 2009 @@ -42,11 +42,11 @@ static cl::opt ScavengeFrameIndexVals("arm-virtual-frame-index-vals", cl::Hidden, - cl::init(false), + cl::init(true), cl::desc("Resolve frame index values via scavenging in PEI")); static cl::opt -ReuseFrameIndexVals("arm-reuse-frame-index-vals", cl::Hidden, cl::init(false), +ReuseFrameIndexVals("arm-reuse-frame-index-vals", cl::Hidden, cl::init(true), cl::desc("Reuse repeated frame index values")); static cl::opt From grosbach at apple.com Tue Oct 27 17:53:57 2009 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 27 Oct 2009 22:53:57 -0000 Subject: [llvm-commits] [test-suite] r85336 - /test-suite/trunk/Makefile.programs Message-ID: <200910272253.n9RMrv71019485@zion.cs.uiuc.edu> Author: grosbach Date: Tue Oct 27 17:53:57 2009 New Revision: 85336 URL: http://llvm.org/viewvc/llvm-project?rev=85336&view=rev Log: Make dynamic stack realignment LLCBETA for ARM Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=85336&r1=85335&r2=85336&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Tue Oct 27 17:53:57 2009 @@ -246,12 +246,12 @@ LLCBETAOPTION := -enable-sparc-v9-insts endif ifeq ($(ARCH),ARM) -LLCBETAOPTION := -arm-virtual-frame-index-vals -arm-reuse-frame-index-vals +LLCBETAOPTION := -arm-dynamic-stack-alignment #-combiner-alias-analysis #-schedule-livein-copies endif ifeq ($(ARCH),THUMB) -LLCBETAOPTION := -arm-virtual-frame-index-vals -arm-reuse-frame-index-vals +LLCBETAOPTION := -arm-dynamic-stack-alignment #-combiner-alias-analysis #-enable-thumb-reg-scavenging endif From lhames at gmail.com Tue Oct 27 18:16:58 2009 From: lhames at gmail.com (Lang Hames) Date: Tue, 27 Oct 2009 23:16:58 -0000 Subject: [llvm-commits] [llvm] r85338 - in /llvm/trunk/lib/CodeGen: SimpleRegisterCoalescing.cpp SimpleRegisterCoalescing.h Message-ID: <200910272316.n9RNGwrQ020375@zion.cs.uiuc.edu> Author: lhames Date: Tue Oct 27 18:16:58 2009 New Revision: 85338 URL: http://llvm.org/viewvc/llvm-project?rev=85338&view=rev Log: Fixed a bug in the coalescer where intervals were occasionally merged despite a real interference. This fixes rdar://problem/7157961. Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=85338&r1=85337&r2=85338&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original) +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Tue Oct 27 18:16:58 2009 @@ -1861,6 +1861,21 @@ return false; } + +/// ValueLiveAt - Return true if the LiveRange pointed to by the given +/// iterator, or any subsequent range with the same value number, +/// is live at the given point. +bool SimpleRegisterCoalescing::ValueLiveAt(LiveInterval::iterator LRItr, + LiveIndex defPoint) const { + for (const VNInfo *valno = LRItr->valno; LRItr->valno == valno; ++LRItr) { + if (LRItr->contains(defPoint)) + return true; + } + + return false; +} + + /// SimpleJoin - Attempt to joint the specified interval into this one. The /// caller of this method must guarantee that the RHS only contains a single /// value number and that the RHS is not defined by a copy from this @@ -1907,7 +1922,7 @@ if (!RangeIsDefinedByCopyFromReg(LHS, LHSIt, RHS.reg)) return false; // Nope, bail out. - if (LHSIt->contains(RHSIt->valno->def)) + if (ValueLiveAt(LHSIt, RHSIt->valno->def)) // Here is an interesting situation: // BB1: // vr1025 = copy vr1024 @@ -1945,7 +1960,7 @@ // Otherwise, if this is a copy from the RHS, mark it as being merged // in. if (RangeIsDefinedByCopyFromReg(LHS, LHSIt, RHS.reg)) { - if (LHSIt->contains(RHSIt->valno->def)) + if (ValueLiveAt(LHSIt, RHSIt->valno->def)) // Here is an interesting situation: // BB1: // vr1025 = copy vr1024 Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h?rev=85338&r1=85337&r2=85338&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h (original) +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h Tue Oct 27 18:16:58 2009 @@ -201,6 +201,11 @@ bool CanJoinInsertSubRegToPhysReg(unsigned DstReg, unsigned SrcReg, unsigned SubIdx, unsigned &RealDstReg); + /// ValueLiveAt - Return true if the LiveRange pointed to by the given + /// iterator, or any subsequent range with the same value number, + /// is live at the given point. + bool ValueLiveAt(LiveInterval::iterator LRItr, LiveIndex defPoint) const; + /// RangeIsDefinedByCopyFromReg - Return true if the specified live range of /// the specified live interval is defined by a copy from the specified /// register. From eocallaghan at auroraux.org Tue Oct 27 18:23:42 2009 From: eocallaghan at auroraux.org (Edward O'Callaghan) Date: Tue, 27 Oct 2009 23:23:42 -0000 Subject: [llvm-commits] [compiler-rt] r85339 - in /compiler-rt/trunk: CMakeLists.txt cmake/Modules/MacroAddCheckTest.cmake test/CMakeLists.txt Message-ID: <200910272323.n9RNNgsN020676@zion.cs.uiuc.edu> Author: evocallaghan Date: Tue Oct 27 18:23:41 2009 New Revision: 85339 URL: http://llvm.org/viewvc/llvm-project?rev=85339&view=rev Log: Fix cmake test suit for compiler-rt. Modified: compiler-rt/trunk/CMakeLists.txt compiler-rt/trunk/cmake/Modules/MacroAddCheckTest.cmake compiler-rt/trunk/test/CMakeLists.txt Modified: compiler-rt/trunk/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/CMakeLists.txt?rev=85339&r1=85338&r2=85339&view=diff ============================================================================== --- compiler-rt/trunk/CMakeLists.txt (original) +++ compiler-rt/trunk/CMakeLists.txt Tue Oct 27 18:23:41 2009 @@ -50,5 +50,5 @@ ADD_SUBDIRECTORY( lib ) # Tests are being ignored for until the very basics are working. -#INCLUDE( MacroAddCheckTest ) +INCLUDE( MacroAddCheckTest ) ADD_SUBDIRECTORY( test ) Modified: compiler-rt/trunk/cmake/Modules/MacroAddCheckTest.cmake URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/cmake/Modules/MacroAddCheckTest.cmake?rev=85339&r1=85338&r2=85339&view=diff ============================================================================== --- compiler-rt/trunk/cmake/Modules/MacroAddCheckTest.cmake (original) +++ compiler-rt/trunk/cmake/Modules/MacroAddCheckTest.cmake Tue Oct 27 18:23:41 2009 @@ -7,5 +7,6 @@ macro (MACRO_ADD_CHECK_TEST _testName _testSource) add_executable(${_testName} ${_testSource}) target_link_libraries(${_testName} ${ARGN}) - add_test(${_testName} ${CMAKE_CURRENT_BINARY_DIR}/${_testName}) + get_target_property(_targetLocation ${_testName} LOCATION) + add_test(${_testName} ${_targetLocation}) endmacro (MACRO_ADD_CHECK_TEST) Modified: compiler-rt/trunk/test/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/CMakeLists.txt?rev=85339&r1=85338&r2=85339&view=diff ============================================================================== --- compiler-rt/trunk/test/CMakeLists.txt (original) +++ compiler-rt/trunk/test/CMakeLists.txt Tue Oct 27 18:23:41 2009 @@ -1,6 +1,7 @@ PROJECT( tests C ) SET( CompilerRT_LIBRARY CompilerRT ) +INCLUDE_DIRECTORIES(${CompilerRT_SOURCE_DIR}/lib) # create test library # add_library(${CompilerRT_LIBRARY} STATIC support.c cmdline.c) From isanbard at gmail.com Tue Oct 27 18:30:07 2009 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 27 Oct 2009 23:30:07 -0000 Subject: [llvm-commits] [llvm] r85341 - /llvm/trunk/lib/Target/README.txt Message-ID: <200910272330.n9RNU7ux021088@zion.cs.uiuc.edu> Author: void Date: Tue Oct 27 18:30:07 2009 New Revision: 85341 URL: http://llvm.org/viewvc/llvm-project?rev=85341&view=rev Log: Add new note. Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=85341&r1=85340&r2=85341&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Tue Oct 27 18:30:07 2009 @@ -1633,3 +1633,38 @@ b = (b & ~0x80) | (a & 0x40) << 1; //===---------------------------------------------------------------------===// + +These two functions produce different code. They shouldn't: + +#include + +uint8_t p1(uint8_t b, uint8_t a) { + b = (b & ~0xc0) | (a & 0xc0); + return (b); +} + +uint8_t p2(uint8_t b, uint8_t a) { + b = (b & ~0x40) | (a & 0x40); + b = (b & ~0x80) | (a & 0x80); + return (b); +} + +define zeroext i8 @p1(i8 zeroext %b, i8 zeroext %a) nounwind readnone ssp { +entry: + %0 = and i8 %b, 63 ; [#uses=1] + %1 = and i8 %a, -64 ; [#uses=1] + %2 = or i8 %1, %0 ; [#uses=1] + ret i8 %2 +} + +define zeroext i8 @p2(i8 zeroext %b, i8 zeroext %a) nounwind readnone ssp { +entry: + %0 = and i8 %b, 63 ; [#uses=1] + %.masked = and i8 %a, 64 ; [#uses=1] + %1 = and i8 %a, -128 ; [#uses=1] + %2 = or i8 %1, %0 ; [#uses=1] + %3 = or i8 %2, %.masked ; [#uses=1] + ret i8 %3 +} + +//===---------------------------------------------------------------------===// From jyasskin at google.com Tue Oct 27 18:45:55 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Tue, 27 Oct 2009 23:45:55 -0000 Subject: [llvm-commits] [llvm] r85344 - in /llvm/trunk/lib/VMCore: ConstantsContext.h LLVMContextImpl.h Message-ID: <200910272345.n9RNjudK021738@zion.cs.uiuc.edu> Author: jyasskin Date: Tue Oct 27 18:45:55 2009 New Revision: 85344 URL: http://llvm.org/viewvc/llvm-project?rev=85344&view=rev Log: Rename lib/VMCore/ConstantsContext.h:ValueMap<> to ConstantUniqueMap<> to avoid colliding with llvm/ADT/ValueMap.h:ValueMap<>. Modified: llvm/trunk/lib/VMCore/ConstantsContext.h llvm/trunk/lib/VMCore/LLVMContextImpl.h Modified: llvm/trunk/lib/VMCore/ConstantsContext.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantsContext.h?rev=85344&r1=85343&r2=85344&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ConstantsContext.h (original) +++ llvm/trunk/lib/VMCore/ConstantsContext.h Tue Oct 27 18:45:55 2009 @@ -332,7 +332,7 @@ // The number of operands for each ConstantCreator::create method is // determined by the ConstantTraits template. // ConstantCreator - A class that is used to create constants by -// ValueMap*. This class should be partially specialized if there is +// ConstantUniqueMap*. This class should be partially specialized if there is // something strange that needs to be done to interface to the ctor for the // constant. // @@ -506,7 +506,7 @@ template -class ValueMap : public AbstractTypeUser { +class ConstantUniqueMap : public AbstractTypeUser { public: typedef std::pair MapKey; typedef std::map MapTy; @@ -529,8 +529,8 @@ /// AbstractTypeMapTy AbstractTypeMap; - /// ValueMapLock - Mutex for this map. - sys::SmartMutex ValueMapLock; + /// ConstantUniqueMapLock - Mutex for this map. + sys::SmartMutex ConstantUniqueMapLock; public: // NOTE: This function is not locked. It is the caller's responsibility @@ -619,7 +619,7 @@ /// getOrCreate - Return the specified constant from the map, creating it if /// necessary. ConstantClass *getOrCreate(const TypeClass *Ty, const ValType &V) { - sys::SmartScopedLock Lock(ValueMapLock); + sys::SmartScopedLock Lock(ConstantUniqueMapLock); MapKey Lookup(Ty, V); ConstantClass* Result = 0; @@ -674,7 +674,7 @@ } void remove(ConstantClass *CP) { - sys::SmartScopedLock Lock(ValueMapLock); + sys::SmartScopedLock Lock(ConstantUniqueMapLock); typename MapTy::iterator I = FindExistingElement(CP); assert(I != Map.end() && "Constant not found in constant table!"); assert(I->second == CP && "Didn't find correct element?"); @@ -725,7 +725,7 @@ } void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) { - sys::SmartScopedLock Lock(ValueMapLock); + sys::SmartScopedLock Lock(ConstantUniqueMapLock); typename AbstractTypeMapTy::iterator I = AbstractTypeMap.find(OldTy); assert(I != AbstractTypeMap.end() && @@ -778,7 +778,7 @@ } void dump() const { - DEBUG(errs() << "Constant.cpp: ValueMap\n"); + DEBUG(errs() << "Constant.cpp: ConstantUniqueMap\n"); } }; Modified: llvm/trunk/lib/VMCore/LLVMContextImpl.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/LLVMContextImpl.h?rev=85344&r1=85343&r2=85344&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/LLVMContextImpl.h (original) +++ llvm/trunk/lib/VMCore/LLVMContextImpl.h Tue Oct 27 18:45:55 2009 @@ -108,25 +108,25 @@ FoldingSet MDNodeSet; - ValueMap AggZeroConstants; + ConstantUniqueMap AggZeroConstants; - typedef ValueMap, ArrayType, + typedef ConstantUniqueMap, ArrayType, ConstantArray, true /*largekey*/> ArrayConstantsTy; ArrayConstantsTy ArrayConstants; - typedef ValueMap, StructType, - ConstantStruct, true /*largekey*/> StructConstantsTy; + typedef ConstantUniqueMap, StructType, + ConstantStruct, true /*largekey*/> StructConstantsTy; StructConstantsTy StructConstants; - typedef ValueMap, VectorType, - ConstantVector> VectorConstantsTy; + typedef ConstantUniqueMap, VectorType, + ConstantVector> VectorConstantsTy; VectorConstantsTy VectorConstants; - ValueMap NullPtrConstants; + ConstantUniqueMap NullPtrConstants; - ValueMap UndefValueConstants; + ConstantUniqueMap UndefValueConstants; - ValueMap ExprConstants; + ConstantUniqueMap ExprConstants; ConstantInt *TheTrueVal; ConstantInt *TheFalseVal; From bob.wilson at apple.com Tue Oct 27 18:49:39 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 27 Oct 2009 23:49:39 -0000 Subject: [llvm-commits] [llvm] r85346 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/BranchFolding.cpp lib/CodeGen/BranchFolding.h lib/CodeGen/IfConversion.cpp lib/CodeGen/LLVMTargetMachine.cpp lib/Target/ARM/ARMTargetMachine.cpp Message-ID: <200910272349.n9RNndW8021869@zion.cs.uiuc.edu> Author: bwilson Date: Tue Oct 27 18:49:38 2009 New Revision: 85346 URL: http://llvm.org/viewvc/llvm-project?rev=85346&view=rev Log: Record CodeGen optimization level in the BranchFolding pass so that we can use it to control tail merging when there is a tradeoff between performance and code size. When there is only 1 instruction in the common tail, we have been merging. That can be good for code size but is a definite loss for performance. Now we will avoid tail merging in that case when the optimization level is "Aggressive", i.e., "-O3". Radar 7338114. Since the IfConversion pass invokes BranchFolding, it too needs to know the optimization level. Note that I removed the RegisterPass instantiation for IfConversion because it required a default constructor. If someone wants to keep that for some reason, we can add a default constructor with a hard-wired optimization level. Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/lib/CodeGen/BranchFolding.cpp llvm/trunk/lib/CodeGen/BranchFolding.h llvm/trunk/lib/CodeGen/IfConversion.cpp llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=85346&r1=85345&r2=85346&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Tue Oct 27 18:49:38 2009 @@ -127,10 +127,11 @@ /// optimizations to delete branches to branches, eliminate branches to /// successor blocks (creating fall throughs), and eliminating branches over /// branches. - FunctionPass *createBranchFoldingPass(bool DefaultEnableTailMerge); + FunctionPass *createBranchFoldingPass(bool DefaultEnableTailMerge, + CodeGenOpt::Level OptLevel); - /// IfConverter Pass - This pass performs machine code if conversion. - FunctionPass *createIfConverterPass(); + /// IfConverter Pass - This pass performs machine code if-conversion. + FunctionPass *createIfConverterPass(CodeGenOpt::Level OptLevel); /// Code Placement Pass - This pass optimize code placement and aligns loop /// headers to target specific alignment boundary. Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=85346&r1=85345&r2=85346&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Tue Oct 27 18:49:38 2009 @@ -50,8 +50,9 @@ char BranchFolderPass::ID = 0; -FunctionPass *llvm::createBranchFoldingPass(bool DefaultEnableTailMerge) { - return new BranchFolderPass(DefaultEnableTailMerge); +FunctionPass *llvm::createBranchFoldingPass(bool DefaultEnableTailMerge, + CodeGenOpt::Level OptLevel) { + return new BranchFolderPass(DefaultEnableTailMerge, OptLevel); } bool BranchFolderPass::runOnMachineFunction(MachineFunction &MF) { @@ -63,7 +64,8 @@ -BranchFolder::BranchFolder(bool defaultEnableTailMerge) { +BranchFolder::BranchFolder(bool defaultEnableTailMerge, CodeGenOpt::Level OL) { + OptLevel = OL; switch (FlagEnableTailMerge) { case cl::BOU_UNSET: EnableTailMerge = defaultEnableTailMerge; break; case cl::BOU_TRUE: EnableTailMerge = true; break; @@ -470,7 +472,8 @@ I->second, TrialBBI1, TrialBBI2); // If we will have to split a block, there should be at least - // minCommonTailLength instructions in common; if not, at worst + // minCommonTailLength instructions in common; if not, and if we are not + // optimizing for performance at the expense of code size, at worst // we will be replacing a fallthrough into the common tail with a // branch, which at worst breaks even with falling through into // the duplicated common tail, so 1 instruction in common is enough. @@ -478,7 +481,8 @@ // tail if there is one. // (Empty blocks will get forwarded and need not be considered.) if (CommonTailLen >= minCommonTailLength || - (CommonTailLen > 0 && + (OptLevel != CodeGenOpt::Aggressive && + CommonTailLen > 0 && (TrialBBI1==CurMPIter->second->begin() || TrialBBI2==I->second->begin()))) { if (CommonTailLen > maxCommonTailLength) { Modified: llvm/trunk/lib/CodeGen/BranchFolding.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.h?rev=85346&r1=85345&r2=85346&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.h (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.h Tue Oct 27 18:49:38 2009 @@ -12,6 +12,7 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/Target/TargetMachine.h" #include namespace llvm { @@ -23,7 +24,7 @@ class BranchFolder { public: - explicit BranchFolder(bool defaultEnableTailMerge); + explicit BranchFolder(bool defaultEnableTailMerge, CodeGenOpt::Level OL); bool OptimizeFunction(MachineFunction &MF, const TargetInstrInfo *tii, @@ -37,6 +38,7 @@ typedef std::pair SameTailElt; std::vector SameTails; + CodeGenOpt::Level OptLevel; bool EnableTailMerge; const TargetInstrInfo *TII; const TargetRegisterInfo *TRI; @@ -73,8 +75,10 @@ public BranchFolder { public: static char ID; - explicit BranchFolderPass(bool defaultEnableTailMerge) - : MachineFunctionPass(&ID), BranchFolder(defaultEnableTailMerge) {} + explicit BranchFolderPass(bool defaultEnableTailMerge, + CodeGenOpt::Level OptLevel) + : MachineFunctionPass(&ID), + BranchFolder(defaultEnableTailMerge, OptLevel) {} virtual bool runOnMachineFunction(MachineFunction &MF); virtual const char *getPassName() const { return "Control Flow Optimizer"; } Modified: llvm/trunk/lib/CodeGen/IfConversion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/IfConversion.cpp?rev=85346&r1=85345&r2=85346&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/IfConversion.cpp (original) +++ llvm/trunk/lib/CodeGen/IfConversion.cpp Tue Oct 27 18:49:38 2009 @@ -148,9 +148,11 @@ const TargetInstrInfo *TII; bool MadeChange; int FnNum; + CodeGenOpt::Level OptLevel; public: static char ID; - IfConverter() : MachineFunctionPass(&ID), FnNum(-1) {} + IfConverter(CodeGenOpt::Level OL) : + MachineFunctionPass(&ID), FnNum(-1), OptLevel(OL) {} virtual bool runOnMachineFunction(MachineFunction &MF); virtual const char *getPassName() const { return "If Converter"; } @@ -219,10 +221,9 @@ char IfConverter::ID = 0; } -static RegisterPass -X("if-converter", "If Converter"); - -FunctionPass *llvm::createIfConverterPass() { return new IfConverter(); } +FunctionPass *llvm::createIfConverterPass(CodeGenOpt::Level OptLevel) { + return new IfConverter(OptLevel); +} bool IfConverter::runOnMachineFunction(MachineFunction &MF) { TLI = MF.getTarget().getTargetLowering(); @@ -362,7 +363,7 @@ BBAnalysis.clear(); if (MadeChange) { - BranchFolder BF(false); + BranchFolder BF(false, OptLevel); BF.OptimizeFunction(MF, TII, MF.getTarget().getRegisterInfo(), getAnalysisIfAvailable()); Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=85346&r1=85345&r2=85346&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original) +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Tue Oct 27 18:49:38 2009 @@ -329,7 +329,7 @@ // Branch folding must be run after regalloc and prolog/epilog insertion. if (OptLevel != CodeGenOpt::None) { - PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); + PM.add(createBranchFoldingPass(getEnableTailMergeDefault(), OptLevel)); printAndVerify(PM); } Modified: llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp?rev=85346&r1=85345&r2=85346&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp Tue Oct 27 18:49:38 2009 @@ -113,7 +113,7 @@ CodeGenOpt::Level OptLevel) { // FIXME: temporarily disabling load / store optimization pass for Thumb1. if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only()) - PM.add(createIfConverterPass()); + PM.add(createIfConverterPass(OptLevel)); if (Subtarget.isThumb2()) { PM.add(createThumb2ITBlockPass()); From sabre at nondot.org Tue Oct 27 19:01:45 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 28 Oct 2009 00:01:45 -0000 Subject: [llvm-commits] [llvm] r85349 - in /llvm/trunk: include/llvm/Constants.h include/llvm/Value.h lib/VMCore/Constants.cpp lib/VMCore/LLVMContextImpl.h Message-ID: <200910280001.n9S01jDf022327@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 19:01:44 2009 New Revision: 85349 URL: http://llvm.org/viewvc/llvm-project?rev=85349&view=rev Log: IR support for the new BlockAddress constant kind. This is untested and there is no way to use it, next up: doing battle with asmparser. Modified: llvm/trunk/include/llvm/Constants.h llvm/trunk/include/llvm/Value.h llvm/trunk/lib/VMCore/Constants.cpp llvm/trunk/lib/VMCore/LLVMContextImpl.h Modified: llvm/trunk/include/llvm/Constants.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=85349&r1=85348&r2=85349&view=diff ============================================================================== --- llvm/trunk/include/llvm/Constants.h (original) +++ llvm/trunk/include/llvm/Constants.h Tue Oct 27 19:01:44 2009 @@ -549,7 +549,47 @@ } }; +/// BlockAddress - The address of a basic block. +/// +class BlockAddress : public Constant { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + void *operator new(size_t s) { return User::operator new(s, 2); } + BlockAddress(Function *F, BasicBlock *BB); +public: + /// get - Return a BlockAddress for the specified function and basic block. + static BlockAddress *get(Function *F, BasicBlock *BB); + + /// get - Return a BlockAddress for the specified basic block. The basic + /// block must be embedded into a function. + static BlockAddress *get(BasicBlock *BB); + + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); + + Function *getFunction() const { return (Function*)Op<0>().get(); } + BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); } + + /// isNullValue - Return true if this is the value that would be returned by + /// getNullValue. + virtual bool isNullValue() const { return false; } + + virtual void destroyConstant(); + virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const BlockAddress *) { return true; } + static inline bool classof(const Value *V) { + return V->getValueID() == BlockAddressVal; + } +}; + +template <> +struct OperandTraits : public FixedNumOperandTraits<2> { +}; +DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(BlockAddress, Constant) + +//===----------------------------------------------------------------------===// /// ConstantExpr - a constant value that is initialized with an expression using /// other constant values. /// Modified: llvm/trunk/include/llvm/Value.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Value.h?rev=85349&r1=85348&r2=85349&view=diff ============================================================================== --- llvm/trunk/include/llvm/Value.h (original) +++ llvm/trunk/include/llvm/Value.h Tue Oct 27 19:01:44 2009 @@ -210,6 +210,7 @@ GlobalAliasVal, // This is an instance of GlobalAlias GlobalVariableVal, // This is an instance of GlobalVariable UndefValueVal, // This is an instance of UndefValue + BlockAddressVal, // This is an instance of BlockAddress ConstantExprVal, // This is an instance of ConstantExpr ConstantAggregateZeroVal, // This is an instance of ConstantAggregateNull ConstantIntVal, // This is an instance of ConstantInt Modified: llvm/trunk/lib/VMCore/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=85349&r1=85348&r2=85349&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Constants.cpp (original) +++ llvm/trunk/lib/VMCore/Constants.cpp Tue Oct 27 19:01:44 2009 @@ -987,7 +987,7 @@ return Elt; } -//---- ConstantPointerNull::get() implementation... +//---- ConstantPointerNull::get() implementation. // ConstantPointerNull *ConstantPointerNull::get(const PointerType *Ty) { @@ -1004,23 +1004,90 @@ } -//---- UndefValue::get() implementation... +//---- UndefValue::get() implementation. // UndefValue *UndefValue::get(const Type *Ty) { - // Implicitly locked. return Ty->getContext().pImpl->UndefValueConstants.getOrCreate(Ty, 0); } // destroyConstant - Remove the constant from the constant table. // void UndefValue::destroyConstant() { - // Implicitly locked. getType()->getContext().pImpl->UndefValueConstants.remove(this); destroyConstantImpl(); } -//---- ConstantExpr::get() implementations... +//---- BlockAddress::get() implementation. +// + +BlockAddress *BlockAddress::get(BasicBlock *BB) { + assert(BB->getParent() != 0 && "Block must have a parent"); + return get(BB->getParent(), BB); +} + +BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) { + BlockAddress *&BA = + F->getContext().pImpl->BlockAddresses[std::make_pair(F, BB)]; + if (BA == 0) + BA = new BlockAddress(F, BB); + + assert(BA->getFunction() == F && "Basic block moved between functions"); + return BA; +} + +BlockAddress::BlockAddress(Function *F, BasicBlock *BB) +: Constant(Type::getInt8PtrTy(F->getContext()), Value::BlockAddressVal, + &Op<0>(), 2) { + Op<0>() = F; + Op<1>() = BB; +} + + +// destroyConstant - Remove the constant from the constant table. +// +void BlockAddress::destroyConstant() { + getFunction()->getType()->getContext().pImpl + ->BlockAddresses.erase(std::make_pair(getFunction(), getBasicBlock())); + destroyConstantImpl(); +} + +void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { + // This could be replacing either the Basic Block or the Function. In either + // case, we have to remove the map entry. + Function *NewF = getFunction(); + BasicBlock *NewBB = getBasicBlock(); + + if (U == &Op<0>()) + NewF = cast(To); + else + NewBB = cast(To); + + // See if the 'new' entry already exists, if not, just update this in place + // and return early. + BlockAddress *&NewBA = + getContext().pImpl->BlockAddresses[std::make_pair(NewF, NewBB)]; + if (NewBA == 0) { + // Remove the old entry, this can't cause the map to rehash (just a + // tombstone will get added). + getContext().pImpl->BlockAddresses.erase(std::make_pair(getFunction(), + getBasicBlock())); + NewBA = this; + Op<0>() = NewF; + Op<1>() = NewBB; + return; + } + + // Otherwise, I do need to replace this with an existing value. + assert(NewBA != this && "I didn't contain From!"); + + // Everyone using this now uses the replacement. + uncheckedReplaceAllUsesWith(NewBA); + + destroyConstant(); +} + +//---- ConstantExpr::get() implementations. // /// This is a utility function to handle folding of casts and lookup of the @@ -1838,7 +1905,7 @@ /// single invocation handles all 1000 uses. Handling them one at a time would /// work, but would be really slow because it would have to unique each updated /// array instance. - +/// void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { assert(isa(To) && "Cannot make Constant refer to non-constant!"); Modified: llvm/trunk/lib/VMCore/LLVMContextImpl.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/LLVMContextImpl.h?rev=85349&r1=85348&r2=85349&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/LLVMContextImpl.h (original) +++ llvm/trunk/lib/VMCore/LLVMContextImpl.h Tue Oct 27 19:01:44 2009 @@ -126,6 +126,7 @@ ConstantUniqueMap UndefValueConstants; + DenseMap , BlockAddress*> BlockAddresses; ConstantUniqueMap ExprConstants; ConstantInt *TheTrueVal; From eocallaghan at auroraux.org Tue Oct 27 19:09:42 2009 From: eocallaghan at auroraux.org (Edward O'Callaghan) Date: Wed, 28 Oct 2009 00:09:42 -0000 Subject: [llvm-commits] [compiler-rt] r85350 - in /compiler-rt/trunk: test/CMakeLists.txt www/index.html Message-ID: <200910280009.n9S09g3x022645@zion.cs.uiuc.edu> Author: evocallaghan Date: Tue Oct 27 19:09:30 2009 New Revision: 85350 URL: http://llvm.org/viewvc/llvm-project?rev=85350&view=rev Log: Update web docs for cmake test suit, comment out broken test. Modified: compiler-rt/trunk/test/CMakeLists.txt compiler-rt/trunk/www/index.html Modified: compiler-rt/trunk/test/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/CMakeLists.txt?rev=85350&r1=85349&r2=85350&view=diff ============================================================================== --- compiler-rt/trunk/test/CMakeLists.txt (original) +++ compiler-rt/trunk/test/CMakeLists.txt Tue Oct 27 19:09:30 2009 @@ -28,7 +28,7 @@ MACRO_ADD_CHECK_TEST( negti2_test Unit/negti2_test.c ${TEST_TARGET_LIBRARIES} ) # MACRO_ADD_CHECK_TEST( divsc3_test Unit/divsc3_test.c ${TEST_TARGET_LIBRARIES} ) MACRO_ADD_CHECK_TEST( cmpti2_test Unit/cmpti2_test.c ${TEST_TARGET_LIBRARIES} ) -MACRO_ADD_CHECK_TEST( trampoline_setup_test Unit/trampoline_setup_test.c ${TEST_TARGET_LIBRARIES} ) +# MACRO_ADD_CHECK_TEST( trampoline_setup_test Unit/trampoline_setup_test.c ${TEST_TARGET_LIBRARIES} ) MACRO_ADD_CHECK_TEST( mulvti3_test Unit/mulvti3_test.c ${TEST_TARGET_LIBRARIES} ) MACRO_ADD_CHECK_TEST( fixunsxfdi_test Unit/fixunsxfdi_test.c ${TEST_TARGET_LIBRARIES} ) MACRO_ADD_CHECK_TEST( fixunsxfti_test Unit/fixunsxfti_test.c ${TEST_TARGET_LIBRARIES} ) Modified: compiler-rt/trunk/www/index.html URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/www/index.html?rev=85350&r1=85349&r2=85350&view=diff ============================================================================== --- compiler-rt/trunk/www/index.html (original) +++ compiler-rt/trunk/www/index.html Tue Oct 27 19:09:30 2009 @@ -126,6 +126,9 @@

  • cd build
  • cmake ../compiler-rt
  • make
  • +
  • To run the Compiler-RT Test Suit (recommended):
  • +
  • ctest
  • +
  • To Install:
  • make install
  • From sabre at nondot.org Tue Oct 27 19:19:11 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 28 Oct 2009 00:19:11 -0000 Subject: [llvm-commits] [llvm] r85351 - in /llvm/trunk: docs/ include/llvm/ include/llvm/Bitcode/ include/llvm/Support/ lib/Analysis/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/CodeGen/SelectionDAG/ lib/Target/CBackend/ lib/Target/CppBackend/ lib/VMCore/ test/Feature/ Message-ID: <200910280019.n9S0JCdV022989@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 19:19:10 2009 New Revision: 85351 URL: http://llvm.org/viewvc/llvm-project?rev=85351&view=rev Log: rename indbr -> indirectbr to appease the residents of #llvm. Modified: llvm/trunk/docs/LangRef.html llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h llvm/trunk/include/llvm/Instruction.def llvm/trunk/include/llvm/Instructions.h llvm/trunk/include/llvm/Support/InstVisitor.h llvm/trunk/lib/Analysis/InlineCost.cpp llvm/trunk/lib/Analysis/SparsePropagation.cpp llvm/trunk/lib/AsmParser/LLLexer.cpp llvm/trunk/lib/AsmParser/LLParser.cpp llvm/trunk/lib/AsmParser/LLParser.h llvm/trunk/lib/AsmParser/LLToken.h llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h llvm/trunk/lib/Target/CBackend/CBackend.cpp llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp llvm/trunk/lib/VMCore/AsmWriter.cpp llvm/trunk/lib/VMCore/Instruction.cpp llvm/trunk/lib/VMCore/Instructions.cpp llvm/trunk/test/Feature/terminators.ll Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Tue Oct 27 19:19:10 2009 @@ -111,7 +111,7 @@
  • 'ret' Instruction
  • 'br' Instruction
  • 'switch' Instruction
  • -
  • 'indbr' Instruction
  • +
  • 'indirectbr' Instruction
  • 'invoke' Instruction
  • 'unwind' Instruction
  • 'unreachable' Instruction
  • @@ -2183,13 +2183,13 @@ the address of the entry block is illegal.

    This value only has defined behavior when used as an operand to the - 'indbr' instruction or for comparisons + 'indirectbr' instruction or for comparisons against null. Pointer equality tests between labels addresses is undefined behavior - though, again, comparison against null is ok, and no label is equal to the null pointer. This may also be passed around as an opaque pointer sized value as long as the bits are not inspected. This allows ptrtoint and arithmetic to be performed on these values so long as - the original value is reconstituted before the indbr.

    + the original value is reconstituted before the indirectbr.

    Finally, some targets may provide defined semantics when using the value as the operand to an inline assembly, but that is target @@ -2541,7 +2541,7 @@ 'ret' instruction, the 'br' instruction, the 'switch' instruction, the - ''indbr' Instruction, the + ''indirectbr' Instruction, the 'invoke' instruction, the 'unwind' instruction, and the 'unreachable' instruction.

    @@ -2703,19 +2703,19 @@
    Syntax:
    -  indbr <somety>* <address>, [ label <dest1>, label <dest2>, ... ]
    +  indirectbr <somety>* <address>, [ label <dest1>, label <dest2>, ... ]
     
    Overview:
    -

    The 'indbr' instruction implements an indirect branch to a label +

    The 'indirectbr' instruction implements an indirect branch to a label within the current function, whose address is specified by "address". Address must be derived from a blockaddress constant.

    @@ -2743,7 +2743,7 @@
    Example:
    - indbr i8* %Addr, [ label %bb1, label %bb2, label %bb3 ]
    + indirectbr i8* %Addr, [ label %bb1, label %bb2, label %bb3 ]
     
    Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original) +++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Tue Oct 27 19:19:10 2009 @@ -237,7 +237,7 @@ // new select on i1 or [N x i1] FUNC_CODE_INST_VSELECT = 29, // VSELECT: [ty,opval,opval,predty,pred] FUNC_CODE_INST_INBOUNDS_GEP= 30, // INBOUNDS_GEP: [n x operands] - FUNC_CODE_INST_INDBR = 31 // INDBR: [opty, op0, op1, ...] + FUNC_CODE_INST_INDIRECTBR = 31 // INDIRECTBR: [opty, op0, op1, ...] }; } // End bitc namespace } // End llvm namespace Modified: llvm/trunk/include/llvm/Instruction.def URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instruction.def?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instruction.def (original) +++ llvm/trunk/include/llvm/Instruction.def Tue Oct 27 19:19:10 2009 @@ -97,7 +97,7 @@ HANDLE_TERM_INST ( 1, Ret , ReturnInst) HANDLE_TERM_INST ( 2, Br , BranchInst) HANDLE_TERM_INST ( 3, Switch , SwitchInst) -HANDLE_TERM_INST ( 4, IndBr , IndBrInst) +HANDLE_TERM_INST ( 4, IndirectBr , IndirectBrInst) HANDLE_TERM_INST ( 5, Invoke , InvokeInst) HANDLE_TERM_INST ( 6, Unwind , UnwindInst) HANDLE_TERM_INST ( 7, Unreachable, UnreachableInst) Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Tue Oct 27 19:19:10 2009 @@ -2220,61 +2220,61 @@ //===----------------------------------------------------------------------===// -// IndBrInst Class +// IndirectBrInst Class //===----------------------------------------------------------------------===// //===--------------------------------------------------------------------------- -/// IndBrInst - Indirect Branch Instruction. +/// IndirectBrInst - Indirect Branch Instruction. /// -class IndBrInst : public TerminatorInst { +class IndirectBrInst : public TerminatorInst { void *operator new(size_t, unsigned); // DO NOT IMPLEMENT unsigned ReservedSpace; // Operand[0] = Value to switch on // Operand[1] = Default basic block destination // Operand[2n ] = Value to match // Operand[2n+1] = BasicBlock to go to on match - IndBrInst(const IndBrInst &IBI); + IndirectBrInst(const IndirectBrInst &IBI); void init(Value *Address, unsigned NumDests); void resizeOperands(unsigned No); // allocate space for exactly zero operands void *operator new(size_t s) { return User::operator new(s, 0); } - /// IndBrInst ctor - Create a new indbr instruction, specifying an Address to - /// jump to. The number of expected destinations can be specified here to - /// make memory allocation more efficient. This constructor can also + /// IndirectBrInst ctor - Create a new indirectbr instruction, specifying an + /// Address to jump to. The number of expected destinations can be specified + /// here to make memory allocation more efficient. This constructor can also /// autoinsert before another instruction. - IndBrInst(Value *Address, unsigned NumDests, Instruction *InsertBefore); + IndirectBrInst(Value *Address, unsigned NumDests, Instruction *InsertBefore); - /// IndBrInst ctor - Create a new indbr instruction, specifying an Address to - /// jump to. The number of expected destinations can be specified here to - /// make memory allocation more efficient. This constructor also autoinserts - /// at the end of the specified BasicBlock. - IndBrInst(Value *Address, unsigned NumDests, BasicBlock *InsertAtEnd); + /// IndirectBrInst ctor - Create a new indirectbr instruction, specifying an + /// Address to jump to. The number of expected destinations can be specified + /// here to make memory allocation more efficient. This constructor also + /// autoinserts at the end of the specified BasicBlock. + IndirectBrInst(Value *Address, unsigned NumDests, BasicBlock *InsertAtEnd); protected: - virtual IndBrInst *clone_impl() const; + virtual IndirectBrInst *clone_impl() const; public: - static IndBrInst *Create(Value *Address, unsigned NumDests, - Instruction *InsertBefore = 0) { - return new IndBrInst(Address, NumDests, InsertBefore); + static IndirectBrInst *Create(Value *Address, unsigned NumDests, + Instruction *InsertBefore = 0) { + return new IndirectBrInst(Address, NumDests, InsertBefore); } - static IndBrInst *Create(Value *Address, unsigned NumDests, - BasicBlock *InsertAtEnd) { - return new IndBrInst(Address, NumDests, InsertAtEnd); + static IndirectBrInst *Create(Value *Address, unsigned NumDests, + BasicBlock *InsertAtEnd) { + return new IndirectBrInst(Address, NumDests, InsertAtEnd); } - ~IndBrInst(); + ~IndirectBrInst(); /// Provide fast operand accessors. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - // Accessor Methods for IndBr instruction. + // Accessor Methods for IndirectBrInst instruction. Value *getAddress() { return getOperand(0); } const Value *getAddress() const { return getOperand(0); } void setAddress(Value *V) { setOperand(0, V); } /// getNumDestinations - return the number of possible destinations in this - /// indbr instruction. + /// indirectbr instruction. unsigned getNumDestinations() const { return getNumOperands()-1; } /// getDestination - Return the specified destination. @@ -2286,7 +2286,7 @@ void addDestination(BasicBlock *Dest); /// removeDestination - This method removes the specified successor from the - /// indbr instruction. + /// indirectbr instruction. void removeDestination(unsigned i); unsigned getNumSuccessors() const { return getNumOperands()-1; } @@ -2298,9 +2298,9 @@ } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const IndBrInst *) { return true; } + static inline bool classof(const IndirectBrInst *) { return true; } static inline bool classof(const Instruction *I) { - return I->getOpcode() == Instruction::IndBr; + return I->getOpcode() == Instruction::IndirectBr; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); @@ -2312,10 +2312,10 @@ }; template <> -struct OperandTraits : public HungoffOperandTraits<1> { +struct OperandTraits : public HungoffOperandTraits<1> { }; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndBrInst, Value) +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value) //===----------------------------------------------------------------------===// Modified: llvm/trunk/include/llvm/Support/InstVisitor.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/InstVisitor.h?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/InstVisitor.h (original) +++ llvm/trunk/include/llvm/Support/InstVisitor.h Tue Oct 27 19:19:10 2009 @@ -160,7 +160,7 @@ RetTy visitReturnInst(ReturnInst &I) { DELEGATE(TerminatorInst);} RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst);} RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst);} - RetTy visitIndBrInst(IndBrInst &I) { DELEGATE(TerminatorInst);} + RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);} RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnwindInst(UnwindInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);} Modified: llvm/trunk/lib/Analysis/InlineCost.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InlineCost.cpp?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InlineCost.cpp (original) +++ llvm/trunk/lib/Analysis/InlineCost.cpp Tue Oct 27 19:19:10 2009 @@ -31,7 +31,7 @@ // Eliminating a switch is a big win, proportional to the number of edges // deleted. Reduction += (SI->getNumSuccessors()-1) * 40; - else if (isa(*UI)) + else if (isa(*UI)) // Eliminating an indirect branch is a big win. Reduction += 200; else if (CallInst *CI = dyn_cast(*UI)) { Modified: llvm/trunk/lib/Analysis/SparsePropagation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/SparsePropagation.cpp?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/SparsePropagation.cpp (original) +++ llvm/trunk/lib/Analysis/SparsePropagation.cpp Tue Oct 27 19:19:10 2009 @@ -166,7 +166,7 @@ return; } - if (isa(TI)) { + if (isa(TI)) { Succs.assign(Succs.size(), true); return; } Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLLexer.cpp (original) +++ llvm/trunk/lib/AsmParser/LLLexer.cpp Tue Oct 27 19:19:10 2009 @@ -645,7 +645,7 @@ INSTKEYWORD(ret, Ret); INSTKEYWORD(br, Br); INSTKEYWORD(switch, Switch); - INSTKEYWORD(indbr, IndBr); + INSTKEYWORD(indirectbr, IndirectBr); INSTKEYWORD(invoke, Invoke); INSTKEYWORD(unwind, Unwind); INSTKEYWORD(unreachable, Unreachable); Modified: llvm/trunk/lib/AsmParser/LLParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) +++ llvm/trunk/lib/AsmParser/LLParser.cpp Tue Oct 27 19:19:10 2009 @@ -2731,7 +2731,7 @@ case lltok::kw_ret: return ParseRet(Inst, BB, PFS); case lltok::kw_br: return ParseBr(Inst, PFS); case lltok::kw_switch: return ParseSwitch(Inst, PFS); - case lltok::kw_indbr: return ParseIndBr(Inst, PFS); + case lltok::kw_indirectbr: return ParseIndirectBr(Inst, PFS); case lltok::kw_invoke: return ParseInvoke(Inst, PFS); // Binary Operators. case lltok::kw_add: @@ -3004,19 +3004,19 @@ return false; } -/// ParseIndBr +/// ParseIndirectBr /// Instruction -/// ::= 'indbr' TypeAndValue ',' '[' LabelList ']' -bool LLParser::ParseIndBr(Instruction *&Inst, PerFunctionState &PFS) { +/// ::= 'indirectbr' TypeAndValue ',' '[' LabelList ']' +bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) { LocTy AddrLoc; Value *Address; if (ParseTypeAndValue(Address, AddrLoc, PFS) || - ParseToken(lltok::comma, "expected ',' after indbr address") || - ParseToken(lltok::lsquare, "expected '[' with indbr")) + ParseToken(lltok::comma, "expected ',' after indirectbr address") || + ParseToken(lltok::lsquare, "expected '[' with indirectbr")) return true; if (!isa(Address->getType())) - return Error(AddrLoc, "indbr address must have pointer type"); + return Error(AddrLoc, "indirectbr address must have pointer type"); // Parse the destination list. SmallVector DestList; @@ -3037,7 +3037,7 @@ if (ParseToken(lltok::rsquare, "expected ']' at end of block list")) return true; - IndBrInst *IBI = IndBrInst::Create(Address, DestList.size()); + IndirectBrInst *IBI = IndirectBrInst::Create(Address, DestList.size()); for (unsigned i = 0, e = DestList.size(); i != e; ++i) IBI->addDestination(DestList[i]); Inst = IBI; Modified: llvm/trunk/lib/AsmParser/LLParser.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.h (original) +++ llvm/trunk/lib/AsmParser/LLParser.h Tue Oct 27 19:19:10 2009 @@ -270,7 +270,7 @@ bool ParseRet(Instruction *&Inst, BasicBlock *BB, PerFunctionState &PFS); bool ParseBr(Instruction *&Inst, PerFunctionState &PFS); bool ParseSwitch(Instruction *&Inst, PerFunctionState &PFS); - bool ParseIndBr(Instruction *&Inst, PerFunctionState &PFS); + bool ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS); bool ParseInvoke(Instruction *&Inst, PerFunctionState &PFS); bool ParseArithmetic(Instruction *&I, PerFunctionState &PFS, unsigned Opc, Modified: llvm/trunk/lib/AsmParser/LLToken.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLToken.h (original) +++ llvm/trunk/lib/AsmParser/LLToken.h Tue Oct 27 19:19:10 2009 @@ -111,7 +111,8 @@ kw_fptoui, kw_fptosi, kw_inttoptr, kw_ptrtoint, kw_bitcast, kw_select, kw_va_arg, - kw_ret, kw_br, kw_switch, kw_indbr, kw_invoke, kw_unwind, kw_unreachable, + kw_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_unwind, + kw_unreachable, kw_malloc, kw_alloca, kw_free, kw_load, kw_store, kw_getelementptr, Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Tue Oct 27 19:19:10 2009 @@ -1975,22 +1975,22 @@ I = SI; break; } - case bitc::FUNC_CODE_INST_INDBR: { // INDBR: [opty, op0, op1, ...] + case bitc::FUNC_CODE_INST_INDIRECTBR: { // INDIRECTBR: [opty, op0, op1, ...] if (Record.size() < 2) - return Error("Invalid INDBR record"); + return Error("Invalid INDIRECTBR record"); const Type *OpTy = getTypeByID(Record[0]); Value *Address = getFnValueByID(Record[1], OpTy); if (OpTy == 0 || Address == 0) - return Error("Invalid INDBR record"); + return Error("Invalid INDIRECTBR record"); unsigned NumDests = Record.size()-2; - IndBrInst *IBI = IndBrInst::Create(Address, NumDests); + IndirectBrInst *IBI = IndirectBrInst::Create(Address, NumDests); InstructionList.push_back(IBI); for (unsigned i = 0, e = NumDests; i != e; ++i) { if (BasicBlock *DestBB = getBasicBlock(Record[2+i])) { IBI->addDestination(DestBB); } else { delete IBI; - return Error("Invalid INDBR record!"); + return Error("Invalid INDIRECTBR record!"); } } I = IBI; Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Tue Oct 27 19:19:10 2009 @@ -1015,8 +1015,8 @@ for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) Vals.push_back(VE.getValueID(I.getOperand(i))); break; - case Instruction::IndBr: - Code = bitc::FUNC_CODE_INST_INDBR; + case Instruction::IndirectBr: + Code = bitc::FUNC_CODE_INST_INDIRECTBR; Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) Vals.push_back(VE.getValueID(I.getOperand(i))); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Tue Oct 27 19:19:10 2009 @@ -2131,7 +2131,7 @@ } } -void SelectionDAGLowering::visitIndBr(IndBrInst &I) { +void SelectionDAGLowering::visitIndirectBr(IndirectBrInst &I) { // Update machine-CFG edges. for (unsigned i = 0, e = I.getNumSuccessors(); i != e; ++i) CurMBB->addSuccessor(FuncInfo.MBBMap[I.getSuccessor(i)]); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h Tue Oct 27 19:19:10 2009 @@ -49,7 +49,7 @@ class GCFunctionInfo; class ICmpInst; class IntToPtrInst; -class IndBrInst; +class IndirectBrInst; class InvokeInst; class InsertElementInst; class InsertValueInst; @@ -449,7 +449,7 @@ void visitRet(ReturnInst &I); void visitBr(BranchInst &I); void visitSwitch(SwitchInst &I); - void visitIndBr(IndBrInst &I); + void visitIndirectBr(IndirectBrInst &I); void visitUnreachable(UnreachableInst &I) { /* noop */ } // Helpers for visitSwitch Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Tue Oct 27 19:19:10 2009 @@ -282,7 +282,7 @@ void visitReturnInst(ReturnInst &I); void visitBranchInst(BranchInst &I); void visitSwitchInst(SwitchInst &I); - void visitIndBrInst(IndBrInst &I); + void visitIndirectBrInst(IndirectBrInst &I); void visitInvokeInst(InvokeInst &I) { llvm_unreachable("Lowerinvoke pass didn't work!"); } @@ -2579,7 +2579,7 @@ Out << " }\n"; } -void CWriter::visitIndBrInst(IndBrInst &IBI) { +void CWriter::visitIndirectBrInst(IndirectBrInst &IBI) { Out << " goto *(void*)("; writeOperand(IBI.getOperand(0)); Out << ");\n"; Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original) +++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Tue Oct 27 19:19:10 2009 @@ -1132,9 +1132,9 @@ } break; } - case Instruction::IndBr: { - const IndBrInst *IBI = cast(I); - Out << "IndBrInst *" << iName << " = IndBrInst::Create(" + case Instruction::IndirectBr: { + const IndirectBrInst *IBI = cast(I); + Out << "IndirectBrInst *" << iName << " = IndirectBrInst::Create(" << opNames[0] << ", " << IBI->getNumDestinations() << ");"; nl(Out); for (unsigned i = 1; i != IBI->getNumOperands(); ++i) { Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/AsmWriter.cpp (original) +++ llvm/trunk/lib/VMCore/AsmWriter.cpp Tue Oct 27 19:19:10 2009 @@ -1846,8 +1846,8 @@ writeOperand(I.getOperand(op+1), true); } Out << "\n ]"; - } else if (isa(I)) { - // Special case indbr instruction to get formatting nice and correct. + } else if (isa(I)) { + // Special case indirectbr instruction to get formatting nice and correct. Out << ' '; writeOperand(Operand, true); Out << ", "; Modified: llvm/trunk/lib/VMCore/Instruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instruction.cpp (original) +++ llvm/trunk/lib/VMCore/Instruction.cpp Tue Oct 27 19:19:10 2009 @@ -103,7 +103,7 @@ case Ret: return "ret"; case Br: return "br"; case Switch: return "switch"; - case IndBr: return "indbr"; + case IndirectBr: return "indirectbr"; case Invoke: return "invoke"; case Unwind: return "unwind"; case Unreachable: return "unreachable"; Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Tue Oct 27 19:19:10 2009 @@ -3090,7 +3090,7 @@ // SwitchInst Implementation //===----------------------------------------------------------------------===// -void IndBrInst::init(Value *Address, unsigned NumDests) { +void IndirectBrInst::init(Value *Address, unsigned NumDests) { assert(Address); ReservedSpace = 1+NumDests; NumOperands = 1; @@ -3107,7 +3107,7 @@ /// 2. If NumOps > NumOperands, reserve space for NumOps operands. /// 3. If NumOps == NumOperands, trim the reserved space. /// -void IndBrInst::resizeOperands(unsigned NumOps) { +void IndirectBrInst::resizeOperands(unsigned NumOps) { unsigned e = getNumOperands(); if (NumOps == 0) { NumOps = e*2; @@ -3129,21 +3129,22 @@ if (OldOps) Use::zap(OldOps, OldOps + e, true); } -IndBrInst::IndBrInst(Value *Address, unsigned NumCases, - Instruction *InsertBefore) -: TerminatorInst(Type::getVoidTy(Address->getContext()), Instruction::IndBr, +IndirectBrInst::IndirectBrInst(Value *Address, unsigned NumCases, + Instruction *InsertBefore) +: TerminatorInst(Type::getVoidTy(Address->getContext()),Instruction::IndirectBr, 0, 0, InsertBefore) { init(Address, NumCases); } -IndBrInst::IndBrInst(Value *Address, unsigned NumCases, BasicBlock *InsertAtEnd) -: TerminatorInst(Type::getVoidTy(Address->getContext()), Instruction::IndBr, +IndirectBrInst::IndirectBrInst(Value *Address, unsigned NumCases, + BasicBlock *InsertAtEnd) +: TerminatorInst(Type::getVoidTy(Address->getContext()),Instruction::IndirectBr, 0, 0, InsertAtEnd) { init(Address, NumCases); } -IndBrInst::IndBrInst(const IndBrInst &IBI) - : TerminatorInst(Type::getVoidTy(IBI.getContext()), Instruction::IndBr, +IndirectBrInst::IndirectBrInst(const IndirectBrInst &IBI) + : TerminatorInst(Type::getVoidTy(IBI.getContext()), Instruction::IndirectBr, allocHungoffUses(IBI.getNumOperands()), IBI.getNumOperands()) { Use *OL = OperandList, *InOL = IBI.OperandList; @@ -3152,13 +3153,13 @@ SubclassOptionalData = IBI.SubclassOptionalData; } -IndBrInst::~IndBrInst() { +IndirectBrInst::~IndirectBrInst() { dropHungoffUses(OperandList); } /// addDestination - Add a destination. /// -void IndBrInst::addDestination(BasicBlock *DestBB) { +void IndirectBrInst::addDestination(BasicBlock *DestBB) { unsigned OpNo = NumOperands; if (OpNo+1 > ReservedSpace) resizeOperands(0); // Get more space! @@ -3169,8 +3170,8 @@ } /// removeDestination - This method removes the specified successor from the -/// indbr instruction. -void IndBrInst::removeDestination(unsigned idx) { +/// indirectbr instruction. +void IndirectBrInst::removeDestination(unsigned idx) { assert(idx < getNumOperands()-1 && "Successor index out of range!"); unsigned NumOps = getNumOperands(); @@ -3184,13 +3185,13 @@ NumOperands = NumOps-1; } -BasicBlock *IndBrInst::getSuccessorV(unsigned idx) const { +BasicBlock *IndirectBrInst::getSuccessorV(unsigned idx) const { return getSuccessor(idx); } -unsigned IndBrInst::getNumSuccessorsV() const { +unsigned IndirectBrInst::getNumSuccessorsV() const { return getNumSuccessors(); } -void IndBrInst::setSuccessorV(unsigned idx, BasicBlock *B) { +void IndirectBrInst::setSuccessorV(unsigned idx, BasicBlock *B) { setSuccessor(idx, B); } @@ -3335,8 +3336,8 @@ return new SwitchInst(*this); } -IndBrInst *IndBrInst::clone_impl() const { - return new IndBrInst(*this); +IndirectBrInst *IndirectBrInst::clone_impl() const { + return new IndirectBrInst(*this); } Modified: llvm/trunk/test/Feature/terminators.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/terminators.ll?rev=85351&r1=85350&r2=85351&view=diff ============================================================================== --- llvm/trunk/test/Feature/terminators.ll (original) +++ llvm/trunk/test/Feature/terminators.ll Tue Oct 27 19:19:10 2009 @@ -27,11 +27,11 @@ define i32 @indbrtest(i8* %P, i32* %Q) { - indbr i8* %P, [label %BB1, label %BB2, label %BB3] + indirectbr i8* %P, [label %BB1, label %BB2, label %BB3] BB1: - indbr i32* %Q, [] + indirectbr i32* %Q, [] BB2: - indbr i32* %Q, [label %BB1, label %BB2] + indirectbr i32* %Q, [label %BB1, label %BB2] BB3: ret i32 2 } From jyasskin at google.com Tue Oct 27 19:28:31 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Wed, 28 Oct 2009 00:28:31 -0000 Subject: [llvm-commits] [llvm] r85352 - /llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Message-ID: <200910280028.n9S0SVwG023314@zion.cs.uiuc.edu> Author: jyasskin Date: Tue Oct 27 19:28:31 2009 New Revision: 85352 URL: http://llvm.org/viewvc/llvm-project?rev=85352&view=rev Log: Fix the ModuleDeletion test on PPC and ARM. Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=85352&r1=85351&r2=85352&view=diff ============================================================================== --- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original) +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Tue Oct 27 19:28:31 2009 @@ -410,6 +410,7 @@ #endif TEST_F(JITTest, ModuleDeletion) { + TheJIT->DisableLazyCompilation(false); LoadAssembly("define void @main() { " " call i32 @computeVal() " " ret void " From bob.wilson at apple.com Tue Oct 27 19:37:04 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Wed, 28 Oct 2009 00:37:04 -0000 Subject: [llvm-commits] [llvm] r85355 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Message-ID: <200910280037.n9S0b45H023621@zion.cs.uiuc.edu> Author: bwilson Date: Tue Oct 27 19:37:03 2009 New Revision: 85355 URL: http://llvm.org/viewvc/llvm-project?rev=85355&view=rev Log: Add an indirect branch pattern for ARM. Testcase will be coming soon. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=85355&r1=85354&r2=85355&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Oct 27 19:37:03 2009 @@ -657,6 +657,16 @@ let Inst{27-20} = 0b00010010; } +// Indirect branches +let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { + def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx $dst", + [(brind GPR:$dst)]> { + let Inst{7-4} = 0b0001; + let Inst{19-8} = 0b111111111111; + let Inst{27-20} = 0b00010010; + } +} + // FIXME: remove when we have a way to marking a MI with these properties. // FIXME: Should pc be an implicit operand like PICADD, etc? let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, From gohman at apple.com Tue Oct 27 19:55:58 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 28 Oct 2009 00:55:58 -0000 Subject: [llvm-commits] [llvm] r85357 - in /llvm/trunk/lib/Target/SystemZ: SystemZISelLowering.cpp SystemZInstrFP.td SystemZInstrInfo.td Message-ID: <200910280055.n9S0twZi024341@zion.cs.uiuc.edu> Author: djg Date: Tue Oct 27 19:55:57 2009 New Revision: 85357 URL: http://llvm.org/viewvc/llvm-project?rev=85357&view=rev Log: Update SystemZ to use PSW following the way x86 uses EFLAGS. Besides eliminating a use of MVT::Flag, this is needed for an upcoming CodeGen change. This unfortunately requires SystemZ to switch to the list-burr scheduler, in order to handle the physreg defs properly, however that's what LLVM has available at this time. Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp llvm/trunk/lib/Target/SystemZ/SystemZInstrFP.td llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp?rev=85357&r1=85356&r2=85357&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp Tue Oct 27 19:55:57 2009 @@ -75,7 +75,13 @@ setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand); setStackPointerRegisterToSaveRestore(SystemZ::R15D); - setSchedulingPreference(SchedulingForLatency); + + // TODO: It may be better to default to latency-oriented scheduling, however + // LLVM's current latency-oriented scheduler can't handle physreg definitions + // such as SystemZ has with PSW, so set this to the register-pressure + // scheduler, because it can. + setSchedulingPreference(SchedulingForRegPressure); + setBooleanContents(ZeroOrOneBooleanContent); setOperationAction(ISD::BR_JT, MVT::Other, Expand); @@ -663,7 +669,7 @@ DebugLoc dl = LHS.getDebugLoc(); return DAG.getNode((isUnsigned ? SystemZISD::UCMP : SystemZISD::CMP), - dl, MVT::Flag, LHS, RHS); + dl, MVT::i64, LHS, RHS); } Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrFP.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrFP.td?rev=85357&r1=85356&r2=85357&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZInstrFP.td (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZInstrFP.td Tue Oct 27 19:55:57 2009 @@ -25,15 +25,15 @@ return N->isExactlyValue(-0.0); }]>; -let usesCustomDAGSchedInserter = 1 in { +let Uses = [PSW], usesCustomDAGSchedInserter = 1 in { def SelectF32 : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2, i8imm:$cc), "# SelectF32 PSEUDO", [(set FP32:$dst, - (SystemZselect FP32:$src1, FP32:$src2, imm:$cc))]>; + (SystemZselect FP32:$src1, FP32:$src2, imm:$cc, PSW))]>; def SelectF64 : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2, i8imm:$cc), "# SelectF64 PSEUDO", [(set FP64:$dst, - (SystemZselect FP64:$src1, FP64:$src2, imm:$cc))]>; + (SystemZselect FP64:$src1, FP64:$src2, imm:$cc, PSW))]>; } //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td?rev=85357&r1=85356&r2=85357&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td Tue Oct 27 19:55:57 2009 @@ -32,12 +32,12 @@ def SDT_SystemZCallSeqStart : SDCallSeqStart<[SDTCisI64<0>]>; def SDT_SystemZCallSeqEnd : SDCallSeqEnd<[SDTCisI64<0>, SDTCisI64<1>]>; def SDT_CmpTest : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; -def SDT_BrCond : SDTypeProfile<0, 2, +def SDT_BrCond : SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>, - SDTCisI8<1>]>; -def SDT_SelectCC : SDTypeProfile<1, 3, + SDTCisI8<1>, SDTCisVT<2, i64>]>; +def SDT_SelectCC : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, - SDTCisI8<3>]>; + SDTCisI8<3>, SDTCisVT<4, i64>]>; def SDT_Address : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>; @@ -54,11 +54,11 @@ def SystemZcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SystemZCallSeqEnd, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; -def SystemZcmp : SDNode<"SystemZISD::CMP", SDT_CmpTest, [SDNPOutFlag]>; -def SystemZucmp : SDNode<"SystemZISD::UCMP", SDT_CmpTest, [SDNPOutFlag]>; +def SystemZcmp : SDNode<"SystemZISD::CMP", SDT_CmpTest>; +def SystemZucmp : SDNode<"SystemZISD::UCMP", SDT_CmpTest>; def SystemZbrcond : SDNode<"SystemZISD::BRCOND", SDT_BrCond, - [SDNPHasChain, SDNPInFlag]>; -def SystemZselect : SDNode<"SystemZISD::SELECT", SDT_SelectCC, [SDNPInFlag]>; + [SDNPHasChain]>; +def SystemZselect : SDNode<"SystemZISD::SELECT", SDT_SelectCC>; def SystemZpcrelwrapper : SDNode<"SystemZISD::PCRelativeWrapper", SDT_Address, []>; @@ -74,15 +74,15 @@ "#ADJCALLSTACKUP", [(SystemZcallseq_end timm:$amt1, timm:$amt2)]>; -let usesCustomDAGSchedInserter = 1 in { +let Uses = [PSW], usesCustomDAGSchedInserter = 1 in { def Select32 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2, i8imm:$cc), "# Select32 PSEUDO", [(set GR32:$dst, - (SystemZselect GR32:$src1, GR32:$src2, imm:$cc))]>; + (SystemZselect GR32:$src1, GR32:$src2, imm:$cc, PSW))]>; def Select64 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2, i8imm:$cc), "# Select64 PSEUDO", [(set GR64:$dst, - (SystemZselect GR64:$src1, GR64:$src2, imm:$cc))]>; + (SystemZselect GR64:$src1, GR64:$src2, imm:$cc, PSW))]>; } @@ -106,46 +106,46 @@ let Uses = [PSW] in { def JO : Pseudo<(outs), (ins brtarget:$dst), "jo\t$dst", - [(SystemZbrcond bb:$dst, SYSTEMZ_COND_O)]>; + [(SystemZbrcond bb:$dst, SYSTEMZ_COND_O, PSW)]>; def JH : Pseudo<(outs), (ins brtarget:$dst), "jh\t$dst", - [(SystemZbrcond bb:$dst, SYSTEMZ_COND_H)]>; + [(SystemZbrcond bb:$dst, SYSTEMZ_COND_H, PSW)]>; def JNLE: Pseudo<(outs), (ins brtarget:$dst), "jnle\t$dst", - [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NLE)]>; + [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NLE, PSW)]>; def JL : Pseudo<(outs), (ins brtarget:$dst), "jl\t$dst", - [(SystemZbrcond bb:$dst, SYSTEMZ_COND_L)]>; + [(SystemZbrcond bb:$dst, SYSTEMZ_COND_L, PSW)]>; def JNHE: Pseudo<(outs), (ins brtarget:$dst), "jnhe\t$dst", - [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NHE)]>; + [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NHE, PSW)]>; def JLH : Pseudo<(outs), (ins brtarget:$dst), "jlh\t$dst", - [(SystemZbrcond bb:$dst, SYSTEMZ_COND_LH)]>; + [(SystemZbrcond bb:$dst, SYSTEMZ_COND_LH, PSW)]>; def JNE : Pseudo<(outs), (ins brtarget:$dst), "jne\t$dst", - [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NE)]>; + [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NE, PSW)]>; def JE : Pseudo<(outs), (ins brtarget:$dst), "je\t$dst", - [(SystemZbrcond bb:$dst, SYSTEMZ_COND_E)]>; + [(SystemZbrcond bb:$dst, SYSTEMZ_COND_E, PSW)]>; def JNLH: Pseudo<(outs), (ins brtarget:$dst), "jnlh\t$dst", - [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NLH)]>; + [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NLH, PSW)]>; def JHE : Pseudo<(outs), (ins brtarget:$dst), "jhe\t$dst", - [(SystemZbrcond bb:$dst, SYSTEMZ_COND_HE)]>; + [(SystemZbrcond bb:$dst, SYSTEMZ_COND_HE, PSW)]>; def JNL : Pseudo<(outs), (ins brtarget:$dst), "jnl\t$dst", - [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NL)]>; + [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NL, PSW)]>; def JLE : Pseudo<(outs), (ins brtarget:$dst), "jle\t$dst", - [(SystemZbrcond bb:$dst, SYSTEMZ_COND_LE)]>; + [(SystemZbrcond bb:$dst, SYSTEMZ_COND_LE, PSW)]>; def JNH : Pseudo<(outs), (ins brtarget:$dst), "jnh\t$dst", - [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NH)]>; + [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NH, PSW)]>; def JNO : Pseudo<(outs), (ins brtarget:$dst), "jno\t$dst", - [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NO)]>; + [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NO, PSW)]>; } // Uses = [PSW] } // isBranch = 1 From evan.cheng at apple.com Tue Oct 27 20:08:17 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 28 Oct 2009 01:08:17 -0000 Subject: [llvm-commits] [llvm] r85358 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/Support/APFloat.cpp Message-ID: <200910280108.n9S18IGb024822@zion.cs.uiuc.edu> Author: evancheng Date: Tue Oct 27 20:08:17 2009 New Revision: 85358 URL: http://llvm.org/viewvc/llvm-project?rev=85358&view=rev Log: Remove getIEEEFloatParts and getIEEEDoubleParts. They are not needed. Modified: llvm/trunk/include/llvm/ADT/APFloat.h llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/include/llvm/ADT/APFloat.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=85358&r1=85357&r2=85358&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APFloat.h (original) +++ llvm/trunk/include/llvm/ADT/APFloat.h Tue Oct 27 20:08:17 2009 @@ -277,13 +277,6 @@ /* Return an arbitrary integer value usable for hashing. */ uint32_t getHashValue() const; - /// getIEEEFloatParts / getIEEEDoubleParts - Return exponent, significant, - /// and sign bit of an IEEE float / IEEE double value. - void getIEEEFloatParts(bool &Sign, uint32_t &Exp, - uint32_t &Significant) const; - void getIEEEDoubleParts(bool &Sign, uint64_t &Exp, - uint64_t &Significant) const; - private: /* Trivial queries. */ Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=85358&r1=85357&r2=85358&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Tue Oct 27 20:08:17 2009 @@ -2632,56 +2632,6 @@ } } -void APFloat::getIEEEFloatParts(bool &Sign, uint32_t &Exp, - uint32_t &Significand) const { - assert(semantics == (const llvm::fltSemantics*)&IEEEsingle && - "Float semantics are not IEEEsingle"); - assert(partCount()==1); - - if (category == fcNormal) { - Exp = exponent+127; // bias - Significand = (uint32_t)*significandParts(); - if (Exp == 1 && !(Significand & 0x800000)) - Exp = 0; // denormal - } else if (category==fcZero) { - Exp = 0; - Significand = 0; - } else if (category==fcInfinity) { - Exp = 0xff; - Significand = 0; - } else { - assert(category == fcNaN && "Unknown category!"); - Exp = 0xff; - Significand = (uint32_t)*significandParts(); - } - Sign = sign; -} - -void APFloat::getIEEEDoubleParts(bool &Sign, uint64_t &Exp, - uint64_t &Significand) const { - assert(semantics == (const llvm::fltSemantics*)&IEEEdouble && - "Float semantics are not IEEEdouble"); - assert(partCount()==1); - - if (category == fcNormal) { - Exp = exponent+1023; // bias - Significand = *significandParts(); - if (Exp == 1 && !(Significand & 0x10000000000000LL)) - Exp = 0; // denormal - } else if (category==fcZero) { - Exp = 0; - Significand = 0; - } else if (category==fcInfinity) { - Exp = 0x7ff; - Significand = 0; - } else { - assert(category == fcNaN && "Unknown category!"); - Exp = 0x7ff; - Significand = *significandParts(); - } - Sign = sign; -} - // Conversion from APFloat to/from host float/double. It may eventually be // possible to eliminate these and have everybody deal with APFloats, but that // will take a while. This approach will not easily extend to long double. From gohman at apple.com Tue Oct 27 20:12:17 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 28 Oct 2009 01:12:17 -0000 Subject: [llvm-commits] [llvm] r85359 - in /llvm/trunk: lib/CodeGen/MachineFunction.cpp test/CodeGen/X86/constant-pool-sharing.ll Message-ID: <200910280112.n9S1CHso024991@zion.cs.uiuc.edu> Author: djg Date: Tue Oct 27 20:12:16 2009 New Revision: 85359 URL: http://llvm.org/viewvc/llvm-project?rev=85359&view=rev Log: Allow constants of different types to share constant pool entries if they have compatible encodings. Added: llvm/trunk/test/CodeGen/X86/constant-pool-sharing.ll Modified: llvm/trunk/lib/CodeGen/MachineFunction.cpp Modified: llvm/trunk/lib/CodeGen/MachineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineFunction.cpp?rev=85359&r1=85358&r2=85359&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineFunction.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineFunction.cpp Tue Oct 27 20:12:16 2009 @@ -581,6 +581,47 @@ delete Constants[i].Val.MachineCPVal; } +/// CanShareConstantPoolEntry - Test whether the given two constants +/// can be allocated the same constant pool entry. +static bool CanShareConstantPoolEntry(Constant *A, Constant *B, + const TargetData *TD) { + // Handle the trivial case quickly. + if (A == B) return true; + + // If they have the same type but weren't the same constant, quickly + // reject them. + if (A->getType() == B->getType()) return false; + + // For now, only support constants with the same size. + if (TD->getTypeStoreSize(A->getType()) != TD->getTypeStoreSize(B->getType())) + return false; + + // If a floating-point value and an integer value have the same encoding, + // they can share a constant-pool entry. + if (ConstantFP *AFP = dyn_cast(A)) + if (ConstantInt *BI = dyn_cast(B)) + return AFP->getValueAPF().bitcastToAPInt() == BI->getValue(); + if (ConstantFP *BFP = dyn_cast(B)) + if (ConstantInt *AI = dyn_cast(A)) + return BFP->getValueAPF().bitcastToAPInt() == AI->getValue(); + + // Two vectors can share an entry if each pair of corresponding + // elements could. + if (ConstantVector *AV = dyn_cast(A)) + if (ConstantVector *BV = dyn_cast(B)) { + if (AV->getType()->getNumElements() != BV->getType()->getNumElements()) + return false; + for (unsigned i = 0, e = AV->getType()->getNumElements(); i != e; ++i) + if (!CanShareConstantPoolEntry(AV->getOperand(i), BV->getOperand(i), TD)) + return false; + return true; + } + + // TODO: Handle other cases. + + return false; +} + /// getConstantPoolIndex - Create a new entry in the constant pool or return /// an existing one. User must specify the log2 of the minimum required /// alignment for the object. @@ -589,14 +630,17 @@ unsigned Alignment) { assert(Alignment && "Alignment must be specified!"); if (Alignment > PoolAlignment) PoolAlignment = Alignment; - + // Check to see if we already have this constant. // // FIXME, this could be made much more efficient for large constant pools. for (unsigned i = 0, e = Constants.size(); i != e; ++i) - if (Constants[i].Val.ConstVal == C && - (Constants[i].getAlignment() & (Alignment - 1)) == 0) + if (!Constants[i].isMachineConstantPoolEntry() && + CanShareConstantPoolEntry(Constants[i].Val.ConstVal, C, TD)) { + if ((unsigned)Constants[i].getAlignment() < Alignment) + Constants[i].Alignment = Alignment; return i; + } Constants.push_back(MachineConstantPoolEntry(C, Alignment)); return Constants.size()-1; Added: llvm/trunk/test/CodeGen/X86/constant-pool-sharing.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/constant-pool-sharing.ll?rev=85359&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/constant-pool-sharing.ll (added) +++ llvm/trunk/test/CodeGen/X86/constant-pool-sharing.ll Tue Oct 27 20:12:16 2009 @@ -0,0 +1,19 @@ +; RUN: llc < %s -march=x86-64 | FileCheck %s + +; llc should share constant pool entries between this integer vector +; and this floating-point vector since they have the same encoding. + +; CHECK: LCPI1_0(%rip), %xmm0 +; CHECK: movaps %xmm0, (%rdi) +; CHECK: movaps %xmm0, (%rsi) + +define void @foo(<4 x i32>* %p, <4 x float>* %q, i1 %t) nounwind { +entry: + br label %loop +loop: + store <4 x i32>, <4 x i32>* %p + store <4 x float>, <4 x float>* %q + br i1 %t, label %loop, label %ret +ret: + ret void +} From gohman at apple.com Tue Oct 27 20:13:53 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 28 Oct 2009 01:13:53 -0000 Subject: [llvm-commits] [llvm] r85360 - in /llvm/trunk: lib/CodeGen/SelectionDAG/InstrEmitter.cpp test/CodeGen/X86/sink-hoist.ll Message-ID: <200910280113.n9S1DrxQ025069@zion.cs.uiuc.edu> Author: djg Date: Tue Oct 27 20:13:53 2009 New Revision: 85360 URL: http://llvm.org/viewvc/llvm-project?rev=85360&view=rev Log: Mark dead physregdefs dead immediately. This helps MachineSink and MachineLICM and other things which run before LiveVariables is run. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp llvm/trunk/test/CodeGen/X86/sink-hoist.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp?rev=85360&r1=85359&r2=85360&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp Tue Oct 27 20:13:53 2009 @@ -571,6 +571,8 @@ unsigned Reg = II.getImplicitDefs()[i - II.getNumDefs()]; if (Node->hasAnyUseOfValue(i)) EmitCopyFromReg(Node, i, IsClone, IsCloned, Reg, VRBaseMap); + else + MI->addRegisterDead(Reg, TRI); } } return; Modified: llvm/trunk/test/CodeGen/X86/sink-hoist.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sink-hoist.ll?rev=85360&r1=85359&r2=85360&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/sink-hoist.ll (original) +++ llvm/trunk/test/CodeGen/X86/sink-hoist.ll Tue Oct 27 20:13:53 2009 @@ -41,3 +41,18 @@ return: ret void } + +; Sink instructions with dead EFLAGS defs. + +; CHECK: je +; CHECK-NEXT: orb + +define zeroext i8 @zzz(i8 zeroext %a, i8 zeroext %b) nounwind readnone { +entry: + %tmp = zext i8 %a to i32 ; [#uses=1] + %tmp2 = icmp eq i8 %a, 0 ; [#uses=1] + %tmp3 = or i8 %b, -128 ; [#uses=1] + %tmp4 = and i8 %b, 127 ; [#uses=1] + %b_addr.0 = select i1 %tmp2, i8 %tmp4, i8 %tmp3 ; [#uses=1] + ret i8 %b_addr.0 +} From evan.cheng at apple.com Tue Oct 27 20:15:09 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 27 Oct 2009 18:15:09 -0700 Subject: [llvm-commits] [llvm] r85346 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/BranchFolding.cpp lib/CodeGen/BranchFolding.h lib/CodeGen/IfConversion.cpp lib/CodeGen/LLVMTargetMachine.cpp lib/Target/ARM/ARMTargetMachine.cpp In-Reply-To: <200910272349.n9RNndW8021869@zion.cs.uiuc.edu> References: <200910272349.n9RNndW8021869@zion.cs.uiuc.edu> Message-ID: <08B7FCA0-0A51-4807-9E5E-0E2C021C3246@apple.com> On Oct 27, 2009, at 4:49 PM, Bob Wilson wrote: > Author: bwilson > Date: Tue Oct 27 18:49:38 2009 > New Revision: 85346 > > URL: http://llvm.org/viewvc/llvm-project?rev=85346&view=rev > Log: > Record CodeGen optimization level in the BranchFolding pass so that > we can > use it to control tail merging when there is a tradeoff between > performance > and code size. When there is only 1 instruction in the common tail, > we have > been merging. That can be good for code size but is a definite loss > for > performance. Now we will avoid tail merging in that case when the > optimization level is "Aggressive", i.e., "-O3". Radar 7338114. Just then controlling this with optimization level, we should only do it when the function is marked OptSize. Would that work? Evan > > Since the IfConversion pass invokes BranchFolding, it too needs to > know > the optimization level. Note that I removed the RegisterPass > instantiation > for IfConversion because it required a default constructor. If > someone > wants to keep that for some reason, we can add a default constructor > with > a hard-wired optimization level. > > Modified: > llvm/trunk/include/llvm/CodeGen/Passes.h > llvm/trunk/lib/CodeGen/BranchFolding.cpp > llvm/trunk/lib/CodeGen/BranchFolding.h > llvm/trunk/lib/CodeGen/IfConversion.cpp > llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp > llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp > > Modified: llvm/trunk/include/llvm/CodeGen/Passes.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=85346&r1=85345&r2=85346&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) > +++ llvm/trunk/include/llvm/CodeGen/Passes.h Tue Oct 27 18:49:38 2009 > @@ -127,10 +127,11 @@ > /// optimizations to delete branches to branches, eliminate > branches to > /// successor blocks (creating fall throughs), and eliminating > branches over > /// branches. > - FunctionPass *createBranchFoldingPass(bool DefaultEnableTailMerge); > + FunctionPass *createBranchFoldingPass(bool DefaultEnableTailMerge, > + CodeGenOpt::Level OptLevel); > > - /// IfConverter Pass - This pass performs machine code if > conversion. > - FunctionPass *createIfConverterPass(); > + /// IfConverter Pass - This pass performs machine code if- > conversion. > + FunctionPass *createIfConverterPass(CodeGenOpt::Level OptLevel); > > /// Code Placement Pass - This pass optimize code placement and > aligns loop > /// headers to target specific alignment boundary. > > Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=85346&r1=85345&r2=85346&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) > +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Tue Oct 27 18:49:38 2009 > @@ -50,8 +50,9 @@ > > char BranchFolderPass::ID = 0; > > -FunctionPass *llvm::createBranchFoldingPass(bool > DefaultEnableTailMerge) { > - return new BranchFolderPass(DefaultEnableTailMerge); > +FunctionPass *llvm::createBranchFoldingPass(bool > DefaultEnableTailMerge, > + CodeGenOpt::Level > OptLevel) { > + return new BranchFolderPass(DefaultEnableTailMerge, OptLevel); > } > > bool BranchFolderPass::runOnMachineFunction(MachineFunction &MF) { > @@ -63,7 +64,8 @@ > > > > -BranchFolder::BranchFolder(bool defaultEnableTailMerge) { > +BranchFolder::BranchFolder(bool defaultEnableTailMerge, > CodeGenOpt::Level OL) { > + OptLevel = OL; > switch (FlagEnableTailMerge) { > case cl::BOU_UNSET: EnableTailMerge = defaultEnableTailMerge; break; > case cl::BOU_TRUE: EnableTailMerge = true; break; > @@ -470,7 +472,8 @@ > I->second, > TrialBBI1, TrialBBI2); > // If we will have to split a block, there should be at least > - // minCommonTailLength instructions in common; if not, at worst > + // minCommonTailLength instructions in common; if not, and if > we are not > + // optimizing for performance at the expense of code size, at > worst > // we will be replacing a fallthrough into the common tail > with a > // branch, which at worst breaks even with falling through into > // the duplicated common tail, so 1 instruction in common is > enough. > @@ -478,7 +481,8 @@ > // tail if there is one. > // (Empty blocks will get forwarded and need not be considered.) > if (CommonTailLen >= minCommonTailLength || > - (CommonTailLen > 0 && > + (OptLevel != CodeGenOpt::Aggressive && > + CommonTailLen > 0 && > (TrialBBI1==CurMPIter->second->begin() || > TrialBBI2==I->second->begin()))) { > if (CommonTailLen > maxCommonTailLength) { > > Modified: llvm/trunk/lib/CodeGen/BranchFolding.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.h?rev=85346&r1=85345&r2=85346&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/BranchFolding.h (original) > +++ llvm/trunk/lib/CodeGen/BranchFolding.h Tue Oct 27 18:49:38 2009 > @@ -12,6 +12,7 @@ > > #include "llvm/CodeGen/MachineBasicBlock.h" > #include "llvm/CodeGen/MachineFunctionPass.h" > +#include "llvm/Target/TargetMachine.h" > #include > > namespace llvm { > @@ -23,7 +24,7 @@ > > class BranchFolder { > public: > - explicit BranchFolder(bool defaultEnableTailMerge); > + explicit BranchFolder(bool defaultEnableTailMerge, > CodeGenOpt::Level OL); > > bool OptimizeFunction(MachineFunction &MF, > const TargetInstrInfo *tii, > @@ -37,6 +38,7 @@ > typedef std::pair > SameTailElt; > std::vector SameTails; > > + CodeGenOpt::Level OptLevel; > bool EnableTailMerge; > const TargetInstrInfo *TII; > const TargetRegisterInfo *TRI; > @@ -73,8 +75,10 @@ > public BranchFolder { > public: > static char ID; > - explicit BranchFolderPass(bool defaultEnableTailMerge) > - : MachineFunctionPass(&ID), BranchFolder > (defaultEnableTailMerge) {} > + explicit BranchFolderPass(bool defaultEnableTailMerge, > + CodeGenOpt::Level OptLevel) > + : MachineFunctionPass(&ID), > + BranchFolder(defaultEnableTailMerge, OptLevel) {} > > virtual bool runOnMachineFunction(MachineFunction &MF); > virtual const char *getPassName() const { return "Control Flow > Optimizer"; } > > Modified: llvm/trunk/lib/CodeGen/IfConversion.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/IfConversion.cpp?rev=85346&r1=85345&r2=85346&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/IfConversion.cpp (original) > +++ llvm/trunk/lib/CodeGen/IfConversion.cpp Tue Oct 27 18:49:38 2009 > @@ -148,9 +148,11 @@ > const TargetInstrInfo *TII; > bool MadeChange; > int FnNum; > + CodeGenOpt::Level OptLevel; > public: > static char ID; > - IfConverter() : MachineFunctionPass(&ID), FnNum(-1) {} > + IfConverter(CodeGenOpt::Level OL) : > + MachineFunctionPass(&ID), FnNum(-1), OptLevel(OL) {} > > virtual bool runOnMachineFunction(MachineFunction &MF); > virtual const char *getPassName() const { return "If Converter"; } > @@ -219,10 +221,9 @@ > char IfConverter::ID = 0; > } > > -static RegisterPass > -X("if-converter", "If Converter"); > - > -FunctionPass *llvm::createIfConverterPass() { return new IfConverter > (); } > +FunctionPass *llvm::createIfConverterPass(CodeGenOpt::Level > OptLevel) { > + return new IfConverter(OptLevel); > +} > > bool IfConverter::runOnMachineFunction(MachineFunction &MF) { > TLI = MF.getTarget().getTargetLowering(); > @@ -362,7 +363,7 @@ > BBAnalysis.clear(); > > if (MadeChange) { > - BranchFolder BF(false); > + BranchFolder BF(false, OptLevel); > BF.OptimizeFunction(MF, TII, > MF.getTarget().getRegisterInfo(), > getAnalysisIfAvailable()); > > Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=85346&r1=85345&r2=85346&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original) > +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Tue Oct 27 18:49:38 > 2009 > @@ -329,7 +329,7 @@ > > // Branch folding must be run after regalloc and prolog/epilog > insertion. > if (OptLevel != CodeGenOpt::None) { > - PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); > + PM.add(createBranchFoldingPass(getEnableTailMergeDefault(), > OptLevel)); > printAndVerify(PM); > } > > > Modified: llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp?rev=85346&r1=85345&r2=85346&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp Tue Oct 27 > 18:49:38 2009 > @@ -113,7 +113,7 @@ > CodeGenOpt::Level > OptLevel) { > // FIXME: temporarily disabling load / store optimization pass for > Thumb1. > if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only()) > - PM.add(createIfConverterPass()); > + PM.add(createIfConverterPass(OptLevel)); > > if (Subtarget.isThumb2()) { > PM.add(createThumb2ITBlockPass()); > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Tue Oct 27 20:22:45 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 27 Oct 2009 18:22:45 -0700 Subject: [llvm-commits] [llvm] r85355 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td In-Reply-To: <200910280037.n9S0b45H023621@zion.cs.uiuc.edu> References: <200910280037.n9S0b45H023621@zion.cs.uiuc.edu> Message-ID: Nice. Don't forget to update ARMInstrInfo. e.g. ARMInstrInfo::BlockHasNoFallThrough, ARMBaseInstrInfo::AnalyzeBranch, etc. Evan On Oct 27, 2009, at 5:37 PM, Bob Wilson wrote: > Author: bwilson > Date: Tue Oct 27 19:37:03 2009 > New Revision: 85355 > > URL: http://llvm.org/viewvc/llvm-project?rev=85355&view=rev > Log: > Add an indirect branch pattern for ARM. Testcase will be coming soon. > > Modified: > llvm/trunk/lib/Target/ARM/ARMInstrInfo.td > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=85355&r1=85354&r2=85355&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Oct 27 19:37:03 2009 > @@ -657,6 +657,16 @@ > let Inst{27-20} = 0b00010010; > } > > +// Indirect branches > +let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch > = 1 in { > + def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx > $dst", > + [(brind GPR:$dst)]> { > + let Inst{7-4} = 0b0001; > + let Inst{19-8} = 0b111111111111; > + let Inst{27-20} = 0b00010010; > + } > +} > + > // FIXME: remove when we have a way to marking a MI with these > properties. > // FIXME: Should pc be an implicit operand like PICADD, etc? > let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Tue Oct 27 20:43:29 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 28 Oct 2009 01:43:29 -0000 Subject: [llvm-commits] [llvm] r85361 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/Target/Alpha/AlphaISelLowering.cpp lib/Target/Alpha/AlphaISelLowering.h lib/Target/Mips/MipsISelLowering.cpp lib/Target/Mips/MipsISelLowering.h lib/Target/SystemZ/SystemZISelLowering.cpp lib/Target/SystemZ/SystemZISelLowering.h lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h Message-ID: <200910280143.n9S1hTQh026124@zion.cs.uiuc.edu> Author: evancheng Date: Tue Oct 27 20:43:28 2009 New Revision: 85361 URL: http://llvm.org/viewvc/llvm-project?rev=85361&view=rev Log: Add a second ValueType argument to isFPImmLegal. Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp llvm/trunk/lib/Target/Mips/MipsISelLowering.h llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=85361&r1=85360&r2=85361&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Tue Oct 27 20:43:28 2009 @@ -328,7 +328,7 @@ /// isFPImmLegal - Returns true if the target can instruction select the /// specified FP immediate natively. If false, the legalizer will materialize /// the FP immediate as a load from a constant pool. - virtual bool isFPImmLegal(const APFloat &Imm) const { + virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const { return false; } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=85361&r1=85360&r2=85361&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Oct 27 20:43:28 2009 @@ -2574,7 +2574,7 @@ ConstantFPSDNode *CFP = cast(Node); // Check to see if this FP immediate is already legal. // If this is a legal constant, turn it into a TargetConstantFP node. - if (TLI.isFPImmLegal(CFP->getValueAPF())) + if (TLI.isFPImmLegal(CFP->getValueAPF(), Node->getValueType(0))) Results.push_back(SDValue(Node, 0)); else Results.push_back(ExpandConstantFP(CFP, true, DAG, TLI)); Modified: llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp?rev=85361&r1=85360&r2=85361&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp Tue Oct 27 20:43:28 2009 @@ -915,7 +915,9 @@ return false; } -bool AlphaTargetLowering::isFPImmLegal(const APFloat &Imm) const { +bool AlphaTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { + if (VT != MVT::f32 && VT != MVT::f64) + return false; // +0.0 F31 // +0.0f F31 // -0.0 -F31 Modified: llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h?rev=85361&r1=85360&r2=85361&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h (original) +++ llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h Tue Oct 27 20:43:28 2009 @@ -105,7 +105,7 @@ /// isFPImmLegal - Returns true if the target can instruction select the /// specified FP immediate natively. If false, the legalizer will /// materialize the FP immediate as a load from a constant pool. - virtual bool isFPImmLegal(const APFloat &Imm) const; + virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const; private: // Helpers for custom lowering. Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=85361&r1=85360&r2=85361&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Tue Oct 27 20:43:28 2009 @@ -1222,6 +1222,8 @@ return false; } -bool MipsTargetLowering::isFPImmLegal(const APFloat &Imm) const { +bool MipsTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { + if (VT != MVT::f32 && VT != MVT::f64) + return false; return Imm.isZero(); } Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.h?rev=85361&r1=85360&r2=85361&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.h (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.h Tue Oct 27 20:43:28 2009 @@ -150,7 +150,7 @@ /// isFPImmLegal - Returns true if the target can instruction select the /// specified FP immediate natively. If false, the legalizer will /// materialize the FP immediate as a load from a constant pool. - virtual bool isFPImmLegal(const APFloat &Imm) const; + virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const; }; } Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp?rev=85361&r1=85360&r2=85361&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp Tue Oct 27 20:43:28 2009 @@ -170,8 +170,8 @@ } } -bool SystemZTargetLowering::isFPImmLegal(const APFloat &Imm) const { - if (UseSoftFloat) +bool SystemZTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { + if (UseSoftFloat || (VT != MVT::f32 && VT != MVT::f64)) return false; // +0.0 lzer Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h?rev=85361&r1=85360&r2=85361&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h Tue Oct 27 20:43:28 2009 @@ -92,7 +92,7 @@ /// isFPImmLegal - Returns true if the target can instruction select the /// specified FP immediate natively. If false, the legalizer will /// materialize the FP immediate as a load from a constant pool. - virtual bool isFPImmLegal(const APFloat &Imm) const; + virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const; private: SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee, Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=85361&r1=85360&r2=85361&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Oct 27 20:43:28 2009 @@ -2313,7 +2313,7 @@ /// isFPImmLegal - Returns true if the target can instruction select the /// specified FP immediate natively. If false, the legalizer will /// materialize the FP immediate as a load from a constant pool. -bool X86TargetLowering::isFPImmLegal(const APFloat &Imm) const { +bool X86TargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { for (unsigned i = 0, e = LegalFPImmediates.size(); i != e; ++i) { if (Imm.bitwiseIsEqual(LegalFPImmediates[i])) return true; Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=85361&r1=85360&r2=85361&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Tue Oct 27 20:43:28 2009 @@ -502,7 +502,7 @@ /// isFPImmLegal - Returns true if the target can instruction select the /// specified FP immediate natively. If false, the legalizer will /// materialize the FP immediate as a load from a constant pool. - virtual bool isFPImmLegal(const APFloat &Imm) const; + virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const; /// isShuffleMaskLegal - Targets can use this to indicate that they only /// support *some* VECTOR_SHUFFLE operations, those with specific masks. From evan.cheng at apple.com Tue Oct 27 20:44:26 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 28 Oct 2009 01:44:26 -0000 Subject: [llvm-commits] [llvm] r85362 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/ARM/ARMInstrVFP.td lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp lib/Target/ARM/AsmPrinter/ARMInstPrinter.h test/CodeGen/ARM/fpconsts.ll Message-ID: <200910280144.n9S1iRf5026169@zion.cs.uiuc.edu> Author: evancheng Date: Tue Oct 27 20:44:26 2009 New Revision: 85362 URL: http://llvm.org/viewvc/llvm-project?rev=85362&view=rev Log: Use fconsts and fconstd to materialize small fp constants. Added: llvm/trunk/test/CodeGen/ARM/fpconsts.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/ARM/ARMInstrVFP.td llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=85362&r1=85361&r2=85362&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue Oct 27 20:44:26 2009 @@ -3990,3 +3990,60 @@ // The ARM target isn't yet aware of offsets. return false; } + +int ARM::getVFPf32Imm(const APFloat &FPImm) { + APInt Imm = FPImm.bitcastToAPInt(); + uint32_t Sign = Imm.lshr(31).getZExtValue() & 1; + int32_t Exp = (Imm.lshr(23).getSExtValue() & 0xff) - 127; // -126 to 127 + int64_t Mantissa = Imm.getZExtValue() & 0x7fffff; // 23 bits + + // We can handle 4 bits of mantissa. + // mantissa = (16+UInt(e:f:g:h))/16. + if (Mantissa & 0x7ffff) + return -1; + Mantissa >>= 19; + if ((Mantissa & 0xf) != Mantissa) + return -1; + + // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3 + if (Exp < -3 || Exp > 4) + return -1; + Exp = ((Exp+3) & 0x7) ^ 4; + + return ((int)Sign << 7) | (Exp << 4) | Mantissa; +} + +int ARM::getVFPf64Imm(const APFloat &FPImm) { + APInt Imm = FPImm.bitcastToAPInt(); + uint64_t Sign = Imm.lshr(63).getZExtValue() & 1; + int64_t Exp = (Imm.lshr(52).getSExtValue() & 0x7ff) - 1023; // -1022 to 1023 + uint64_t Mantissa = Imm.getZExtValue() & 0xfffffffffffffLL; + + // We can handle 4 bits of mantissa. + // mantissa = (16+UInt(e:f:g:h))/16. + if (Mantissa & 0xffffffffffffLL) + return -1; + Mantissa >>= 48; + if ((Mantissa & 0xf) != Mantissa) + return -1; + + // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3 + if (Exp < -3 || Exp > 4) + return -1; + Exp = ((Exp+3) & 0x7) ^ 4; + + return ((int)Sign << 7) | (Exp << 4) | Mantissa; +} + +/// isFPImmLegal - Returns true if the target can instruction select the +/// specified FP immediate natively. If false, the legalizer will +/// materialize the FP immediate as a load from a constant pool. +bool ARMTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { + if (!Subtarget->hasVFP3()) + return false; + if (VT == MVT::f32) + return ARM::getVFPf32Imm(Imm) != -1; + if (VT == MVT::f64) + return ARM::getVFPf64Imm(Imm) != -1; + return false; +} Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=85362&r1=85361&r2=85362&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Tue Oct 27 20:44:26 2009 @@ -137,6 +137,13 @@ /// return the constant being splatted. The ByteSize field indicates the /// number of bytes of each element [1248]. SDValue getVMOVImm(SDNode *N, unsigned ByteSize, SelectionDAG &DAG); + + /// getVFPf32Imm / getVFPf64Imm - If the given fp immediate can be + /// materialized with a VMOV.f32 / VMOV.f64 (i.e. fconsts / fconstd) + /// instruction, returns its 8-bit integer representation. Otherwise, + /// returns -1. + int getVFPf32Imm(const APFloat &FPImm); + int getVFPf64Imm(const APFloat &FPImm); } //===--------------------------------------------------------------------===// @@ -224,6 +231,12 @@ bool isShuffleMaskLegal(const SmallVectorImpl &M, EVT VT) const; bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const; + + /// isFPImmLegal - Returns true if the target can instruction select the + /// specified FP immediate natively. If false, the legalizer will + /// materialize the FP immediate as a load from a constant pool. + virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const; + private: /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can /// make the right decision when generating code for different targets. Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=85362&r1=85361&r2=85362&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Tue Oct 27 20:44:26 2009 @@ -31,6 +31,26 @@ def arm_fmdrr : SDNode<"ARMISD::FMDRR", SDT_FMDRR>; //===----------------------------------------------------------------------===// +// Operand Definitions. +// + + +def vfp_f32imm : Operand, + PatLeaf<(f32 fpimm), [{ + return ARM::getVFPf32Imm(N->getValueAPF()) != -1; + }]> { + let PrintMethod = "printVFPf32ImmOperand"; +} + +def vfp_f64imm : Operand, + PatLeaf<(f64 fpimm), [{ + return ARM::getVFPf64Imm(N->getValueAPF()) != -1; + }]> { + let PrintMethod = "printVFPf64ImmOperand"; +} + + +//===----------------------------------------------------------------------===// // Load / store Instructions. // @@ -408,3 +428,27 @@ let Inst{7} = 0; let Inst{4} = 1; } + + +// Materialize FP immediates. VFP3 only. +def FCONSTS : VFPAI<(outs SPR:$dst), (ins vfp_f32imm:$imm), + VFPMiscFrm, IIC_VMOVImm, + "fconsts", "\t$dst, $imm", + [(set SPR:$dst, vfp_f32imm:$imm)]>, Requires<[HasVFP3]> { + let Inst{27-23} = 0b11101; + let Inst{21-20} = 0b11; + let Inst{11-9} = 0b101; + let Inst{8} = 0; + let Inst{7-4} = 0b0000; +} + +def FCONSTD : VFPAI<(outs DPR:$dst), (ins vfp_f64imm:$imm), + VFPMiscFrm, IIC_VMOVImm, + "fconstd", "\t$dst, $imm", + [(set DPR:$dst, vfp_f64imm:$imm)]>, Requires<[HasVFP3]> { + let Inst{27-23} = 0b11101; + let Inst{21-20} = 0b11; + let Inst{11-9} = 0b101; + let Inst{8} = 1; + let Inst{7-4} = 0b0000; +} Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=85362&r1=85361&r2=85362&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Tue Oct 27 20:44:26 2009 @@ -135,6 +135,8 @@ void printJT2BlockOperand(const MachineInstr *MI, int OpNum); void printTBAddrMode(const MachineInstr *MI, int OpNum); void printNoHashImmediate(const MachineInstr *MI, int OpNum); + void printVFPf32ImmOperand(const MachineInstr *MI, int OpNum); + void printVFPf64ImmOperand(const MachineInstr *MI, int OpNum); virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, unsigned AsmVariant, const char *ExtraCode); @@ -393,9 +395,11 @@ if (Rot) { O << "#" << Imm << ", " << Rot; // Pretty printed version. - if (VerboseAsm) - O << ' ' << MAI->getCommentString() - << ' ' << (int)ARM_AM::rotr32(Imm, Rot); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << ' '; + O << (int)ARM_AM::rotr32(Imm, Rot); + } } else { O << "#" << Imm; } @@ -970,6 +974,26 @@ O << MI->getOperand(OpNum).getImm(); } +void ARMAsmPrinter::printVFPf32ImmOperand(const MachineInstr *MI, int OpNum) { + const ConstantFP *FP = MI->getOperand(OpNum).getFPImm(); + O << ARM::getVFPf32Imm(FP->getValueAPF()); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << ' '; + WriteAsOperand(O, FP, /*PrintType=*/false); + } +} + +void ARMAsmPrinter::printVFPf64ImmOperand(const MachineInstr *MI, int OpNum) { + const ConstantFP *FP = MI->getOperand(OpNum).getFPImm(); + O << ARM::getVFPf64Imm(FP->getValueAPF()); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << ' '; + WriteAsOperand(O, FP, /*PrintType=*/false); + } +} + bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, unsigned AsmVariant, const char *ExtraCode){ // Does this asm operand have a single letter operand modifier? @@ -1182,7 +1206,8 @@ EmitAlignment(Align, GVar); O << name << ":"; if (VerboseAsm) { - O << "\t\t\t\t" << MAI->getCommentString() << ' '; + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << ' '; WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); } O << '\n'; @@ -1205,7 +1230,8 @@ O << "," << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align); } if (VerboseAsm) { - O << "\t\t" << MAI->getCommentString() << " "; + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << ' '; WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); } O << "\n"; @@ -1243,7 +1269,8 @@ EmitAlignment(Align, GVar); O << name << ":"; if (VerboseAsm) { - O << "\t\t\t\t" << MAI->getCommentString() << " "; + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << ' '; WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); } O << "\n"; Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h?rev=85362&r1=85361&r2=85362&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h (original) +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h Tue Oct 27 20:44:26 2009 @@ -78,6 +78,8 @@ void printJT2BlockOperand(const MCInst *MI, unsigned OpNum) {} void printTBAddrMode(const MCInst *MI, unsigned OpNum) {} void printNoHashImmediate(const MCInst *MI, unsigned OpNum); + void printVFPf32ImmOperand(const MCInst *MI, int OpNum) {} + void printVFPf64ImmOperand(const MCInst *MI, int OpNum) {} void printPCLabel(const MCInst *MI, unsigned OpNum); // FIXME: Implement. Added: llvm/trunk/test/CodeGen/ARM/fpconsts.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fpconsts.ll?rev=85362&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/fpconsts.ll (added) +++ llvm/trunk/test/CodeGen/ARM/fpconsts.ll Tue Oct 27 20:44:26 2009 @@ -0,0 +1,33 @@ +; RUN: llc < %s -march=arm -mattr=+vfp3 | FileCheck %s + +define arm_apcscc float @t1(float %x) nounwind readnone optsize { +entry: +; CHECK: t1: +; CHECK: fconsts s1, 16 + %0 = fadd float %x, 4.000000e+00 + ret float %0 +} + +define arm_apcscc double @t2(double %x) nounwind readnone optsize { +entry: +; CHECK: t2: +; CHECK: fconstd d1, 8 + %0 = fadd double %x, 3.000000e+00 + ret double %0 +} + +define arm_apcscc double @t3(double %x) nounwind readnone optsize { +entry: +; CHECK: t3: +; CHECK: fconstd d1, 170 + %0 = fmul double %x, -1.300000e+01 + ret double %0 +} + +define arm_apcscc float @t4(float %x) nounwind readnone optsize { +entry: +; CHECK: t4: +; CHECK: fconsts s1, 184 + %0 = fmul float %x, -2.400000e+01 + ret float %0 +} From bob.wilson at apple.com Tue Oct 27 21:19:03 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 27 Oct 2009 19:19:03 -0700 Subject: [llvm-commits] [llvm] r85355 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td In-Reply-To: References: <200910280037.n9S0b45H023621@zion.cs.uiuc.edu> Message-ID: <0E337D63-CD06-41A2-BCD6-2B58B06387CB@apple.com> OK. I didn't know about all of those. I also need to add a Thumb version, I think. On Oct 27, 2009, at 6:22 PM, Evan Cheng wrote: > Nice. Don't forget to update ARMInstrInfo. e.g. ARMInstrInfo::BlockHasNoFallThrough, ARMBaseInstrInfo::AnalyzeBranch, etc. > > Evan > > On Oct 27, 2009, at 5:37 PM, Bob Wilson wrote: > >> Author: bwilson >> Date: Tue Oct 27 19:37:03 2009 >> New Revision: 85355 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=85355&view=rev >> Log: >> Add an indirect branch pattern for ARM. Testcase will be coming soon. >> >> Modified: >> llvm/trunk/lib/Target/ARM/ARMInstrInfo.td >> >> Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=85355&r1=85354&r2=85355&view=diff >> >> ============================================================================== >> --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) >> +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Oct 27 19:37:03 2009 >> @@ -657,6 +657,16 @@ >> let Inst{27-20} = 0b00010010; >> } >> >> +// Indirect branches >> +let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { >> + def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx $dst", >> + [(brind GPR:$dst)]> { >> + let Inst{7-4} = 0b0001; >> + let Inst{19-8} = 0b111111111111; >> + let Inst{27-20} = 0b00010010; >> + } >> +} >> + >> // FIXME: remove when we have a way to marking a MI with these properties. >> // FIXME: Should pc be an implicit operand like PICADD, etc? >> let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From evan.cheng at apple.com Tue Oct 27 21:39:26 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 27 Oct 2009 19:39:26 -0700 Subject: [llvm-commits] [llvm] r85355 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td In-Reply-To: <0E337D63-CD06-41A2-BCD6-2B58B06387CB@apple.com> References: <200910280037.n9S0b45H023621@zion.cs.uiuc.edu> <0E337D63-CD06-41A2-BCD6-2B58B06387CB@apple.com> Message-ID: <9F6B093A-51FB-41E0-BFC3-259456DDD731@apple.com> On Oct 27, 2009, at 7:19 PM, Bob Wilson wrote: > OK. I didn't know about all of those. I also need to add a Thumb > version, I think. Right. Evan > > On Oct 27, 2009, at 6:22 PM, Evan Cheng wrote: > >> Nice. Don't forget to update ARMInstrInfo. e.g. >> ARMInstrInfo::BlockHasNoFallThrough, >> ARMBaseInstrInfo::AnalyzeBranch, etc. >> >> Evan >> >> On Oct 27, 2009, at 5:37 PM, Bob Wilson wrote: >> >>> Author: bwilson >>> Date: Tue Oct 27 19:37:03 2009 >>> New Revision: 85355 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=85355&view=rev >>> Log: >>> Add an indirect branch pattern for ARM. Testcase will be coming >>> soon. >>> >>> Modified: >>> llvm/trunk/lib/Target/ARM/ARMInstrInfo.td >>> >>> Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=85355&r1=85354&r2=85355&view=diff >>> >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) >>> +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Oct 27 19:37:03 >>> 2009 >>> @@ -657,6 +657,16 @@ >>> let Inst{27-20} = 0b00010010; >>> } >>> >>> +// Indirect branches >>> +let isBranch = 1, isTerminator = 1, isBarrier = 1, >>> isIndirectBranch = 1 in { >>> + def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx >>> $dst", >>> + [(brind GPR:$dst)]> { >>> + let Inst{7-4} = 0b0001; >>> + let Inst{19-8} = 0b111111111111; >>> + let Inst{27-20} = 0b00010010; >>> + } >>> +} >>> + >>> // FIXME: remove when we have a way to marking a MI with these >>> properties. >>> // FIXME: Should pc be an implicit operand like PICADD, etc? >>> let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, >>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > From gohman at apple.com Tue Oct 27 22:22:01 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 28 Oct 2009 03:22:01 -0000 Subject: [llvm-commits] [llvm] r85364 - in /llvm/trunk: lib/CodeGen/MachineLICM.cpp test/CodeGen/X86/pic-load-remat.ll test/CodeGen/X86/sink-hoist.ll Message-ID: <200910280322.n9S3M2hg029259@zion.cs.uiuc.edu> Author: djg Date: Tue Oct 27 22:21:57 2009 New Revision: 85364 URL: http://llvm.org/viewvc/llvm-project?rev=85364&view=rev Log: Teach MachineLICM to unfold loads from constant memory from otherwise unhoistable instructions in order to allow the loads to be hoisted. Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp llvm/trunk/test/CodeGen/X86/pic-load-remat.ll llvm/trunk/test/CodeGen/X86/sink-hoist.ll Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=85364&r1=85363&r2=85364&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Tue Oct 27 22:21:57 2009 @@ -24,7 +24,9 @@ #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" @@ -106,7 +108,7 @@ /// Hoist - When an instruction is found to only use loop invariant operands /// that is safe to hoist, this instruction is called to do the dirty work. /// - void Hoist(MachineInstr &MI); + void Hoist(MachineInstr *MI); }; } // end anonymous namespace @@ -185,7 +187,7 @@ MachineBasicBlock::iterator NextMII = MII; ++NextMII; MachineInstr &MI = *MII; - Hoist(MI); + Hoist(&MI); MII = NextMII; } @@ -370,39 +372,103 @@ /// Hoist - When an instruction is found to use only loop invariant operands /// that are safe to hoist, this instruction is called to do the dirty work. /// -void MachineLICM::Hoist(MachineInstr &MI) { - if (!IsLoopInvariantInst(MI)) return; - if (!IsProfitableToHoist(MI)) return; +void MachineLICM::Hoist(MachineInstr *MI) { + // First check whether we should hoist this instruction. + if (!IsLoopInvariantInst(*MI) || !IsProfitableToHoist(*MI)) { + // If not, we may be able to unfold a load and hoist that. + // First test whether the instruction is loading from an amenable + // memory location. + if (!MI->getDesc().mayLoad()) return; + if (!MI->hasOneMemOperand()) return; + MachineMemOperand *MMO = *MI->memoperands_begin(); + if (MMO->isVolatile()) return; + MachineFunction &MF = *MI->getParent()->getParent(); + if (!MMO->getValue()) return; + if (const PseudoSourceValue *PSV = + dyn_cast(MMO->getValue())) { + if (!PSV->isConstant(MF.getFrameInfo())) return; + } else { + if (!AA->pointsToConstantMemory(MMO->getValue())) return; + } + // Next determine the register class for a temporary register. + unsigned NewOpc = + TII->getOpcodeAfterMemoryUnfold(MI->getOpcode(), + /*UnfoldLoad=*/true, + /*UnfoldStore=*/false); + if (NewOpc == 0) return; + const TargetInstrDesc &TID = TII->get(NewOpc); + if (TID.getNumDefs() != 1) return; + const TargetRegisterClass *RC = TID.OpInfo[0].getRegClass(TRI); + // Ok, we're unfolding. Create a temporary register and do the unfold. + unsigned Reg = RegInfo->createVirtualRegister(RC); + SmallVector NewMIs; + bool Success = + TII->unfoldMemoryOperand(MF, MI, Reg, + /*UnfoldLoad=*/true, /*UnfoldStore=*/false, + NewMIs); + (void)Success; + assert(Success && + "unfoldMemoryOperand failed when getOpcodeAfterMemoryUnfold " + "succeeded!"); + assert(NewMIs.size() == 2 && + "Unfolded a load into multiple instructions!"); + MachineBasicBlock *MBB = MI->getParent(); + MBB->insert(MI, NewMIs[0]); + MBB->insert(MI, NewMIs[1]); + MI->eraseFromParent(); + // If unfolding produced a load that wasn't loop-invariant or profitable to + // hoist, re-fold it to undo the damage. + if (!IsLoopInvariantInst(*NewMIs[0]) || !IsProfitableToHoist(*NewMIs[0])) { + SmallVector Ops; + for (unsigned i = 0, e = NewMIs[1]->getNumOperands(); i != e; ++i) { + MachineOperand &MO = NewMIs[1]->getOperand(i); + if (MO.isReg() && MO.getReg() == Reg) { + assert(MO.isUse() && + "Register defined by unfolded load is redefined " + "instead of just used!"); + Ops.push_back(i); + } + } + MI = TII->foldMemoryOperand(MF, NewMIs[1], Ops, NewMIs[0]); + assert(MI && "Re-fold failed!"); + MBB->insert(NewMIs[1], MI); + NewMIs[0]->eraseFromParent(); + NewMIs[1]->eraseFromParent(); + return; + } + // Otherwise we successfully unfolded a load that we can hoist. + MI = NewMIs[0]; + } // Now move the instructions to the predecessor, inserting it before any // terminator instructions. DEBUG({ - errs() << "Hoisting " << MI; + errs() << "Hoisting " << *MI; if (CurPreheader->getBasicBlock()) errs() << " to MachineBasicBlock " << CurPreheader->getBasicBlock()->getName(); - if (MI.getParent()->getBasicBlock()) + if (MI->getParent()->getBasicBlock()) errs() << " from MachineBasicBlock " - << MI.getParent()->getBasicBlock()->getName(); + << MI->getParent()->getBasicBlock()->getName(); errs() << "\n"; }); // Look for opportunity to CSE the hoisted instruction. std::pair BBOpcPair = - std::make_pair(CurPreheader->getNumber(), MI.getOpcode()); + std::make_pair(CurPreheader->getNumber(), MI->getOpcode()); DenseMap, std::vector >::iterator CI = CSEMap.find(BBOpcPair); bool DoneCSE = false; if (CI != CSEMap.end()) { - const MachineInstr *Dup = LookForDuplicate(&MI, CI->second, RegInfo); + const MachineInstr *Dup = LookForDuplicate(MI, CI->second, RegInfo); if (Dup) { - DEBUG(errs() << "CSEing " << MI << " with " << *Dup); - for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI.getOperand(i); + DEBUG(errs() << "CSEing " << *MI << " with " << *Dup); + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); if (MO.isReg() && MO.isDef()) RegInfo->replaceRegWith(MO.getReg(), Dup->getOperand(i).getReg()); } - MI.eraseFromParent(); + MI->eraseFromParent(); DoneCSE = true; ++NumCSEed; } @@ -411,13 +477,13 @@ // Otherwise, splice the instruction to the preheader. if (!DoneCSE) { CurPreheader->splice(CurPreheader->getFirstTerminator(), - MI.getParent(), &MI); + MI->getParent(), MI); // Add to the CSE map. if (CI != CSEMap.end()) - CI->second.push_back(&MI); + CI->second.push_back(MI); else { std::vector CSEMIs; - CSEMIs.push_back(&MI); + CSEMIs.push_back(MI); CSEMap.insert(std::make_pair(BBOpcPair, CSEMIs)); } } Modified: llvm/trunk/test/CodeGen/X86/pic-load-remat.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pic-load-remat.ll?rev=85364&r1=85363&r2=85364&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/pic-load-remat.ll (original) +++ llvm/trunk/test/CodeGen/X86/pic-load-remat.ll Tue Oct 27 22:21:57 2009 @@ -1,4 +1,10 @@ ; RUN: llc < %s -mtriple=i686-apple-darwin -mattr=+sse2 -relocation-model=pic | grep psllw | grep pb +; XFAIL: * + +; This is XFAIL'd because MachineLICM is now hoisting all of the loads, and the pic +; base appears killed in the entry block when remat is making its decisions. Remat's +; simple heuristic decides against rematting because it doesn't want to extend the +; live-range of the pic base; this isn't necessarily optimal. define void @f() nounwind { entry: Modified: llvm/trunk/test/CodeGen/X86/sink-hoist.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sink-hoist.ll?rev=85364&r1=85363&r2=85364&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/sink-hoist.ll (original) +++ llvm/trunk/test/CodeGen/X86/sink-hoist.ll Tue Oct 27 22:21:57 2009 @@ -44,6 +44,7 @@ ; Sink instructions with dead EFLAGS defs. +; CHECK: zzz: ; CHECK: je ; CHECK-NEXT: orb @@ -56,3 +57,66 @@ %b_addr.0 = select i1 %tmp2, i8 %tmp4, i8 %tmp3 ; [#uses=1] ret i8 %b_addr.0 } + +; Codegen should hoist and CSE these constants. + +; CHECK: vv: +; CHECK: LCPI4_0(%rip), %xmm0 +; CHECK: LCPI4_1(%rip), %xmm1 +; CHECK: LCPI4_2(%rip), %xmm2 +; CHECK: align +; CHECK-NOT: LCPI +; CHECK: ret + + at _minusZero.6007 = internal constant <4 x float> ; <<4 x float>*> [#uses=0] + at twoTo23.6008 = internal constant <4 x float> ; <<4 x float>*> [#uses=0] + +define void @vv(float* %y, float* %x, i32* %n) nounwind ssp { +entry: + br label %bb60 + +bb: ; preds = %bb60 + %0 = bitcast float* %x_addr.0 to <4 x float>* ; <<4 x float>*> [#uses=1] + %1 = load <4 x float>* %0, align 16 ; <<4 x float>> [#uses=4] + %tmp20 = bitcast <4 x float> %1 to <4 x i32> ; <<4 x i32>> [#uses=1] + %tmp22 = and <4 x i32> %tmp20, ; <<4 x i32>> [#uses=1] + %tmp23 = bitcast <4 x i32> %tmp22 to <4 x float> ; <<4 x float>> [#uses=1] + %tmp25 = bitcast <4 x float> %1 to <4 x i32> ; <<4 x i32>> [#uses=1] + %tmp27 = and <4 x i32> %tmp25, ; <<4 x i32>> [#uses=2] + %tmp30 = call <4 x float> @llvm.x86.sse.cmp.ps(<4 x float> %tmp23, <4 x float> , i8 5) ; <<4 x float>> [#uses=1] + %tmp34 = bitcast <4 x float> %tmp30 to <4 x i32> ; <<4 x i32>> [#uses=1] + %tmp36 = xor <4 x i32> %tmp34, ; <<4 x i32>> [#uses=1] + %tmp37 = and <4 x i32> %tmp36, ; <<4 x i32>> [#uses=1] + %tmp42 = or <4 x i32> %tmp37, %tmp27 ; <<4 x i32>> [#uses=1] + %tmp43 = bitcast <4 x i32> %tmp42 to <4 x float> ; <<4 x float>> [#uses=2] + %tmp45 = fadd <4 x float> %1, %tmp43 ; <<4 x float>> [#uses=1] + %tmp47 = fsub <4 x float> %tmp45, %tmp43 ; <<4 x float>> [#uses=2] + %tmp49 = call <4 x float> @llvm.x86.sse.cmp.ps(<4 x float> %1, <4 x float> %tmp47, i8 1) ; <<4 x float>> [#uses=1] + %2 = bitcast <4 x float> %tmp49 to <4 x i32> ; <<4 x i32>> [#uses=1] + %3 = call <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32> %2) nounwind readnone ; <<4 x float>> [#uses=1] + %tmp53 = fadd <4 x float> %tmp47, %3 ; <<4 x float>> [#uses=1] + %tmp55 = bitcast <4 x float> %tmp53 to <4 x i32> ; <<4 x i32>> [#uses=1] + %tmp57 = or <4 x i32> %tmp55, %tmp27 ; <<4 x i32>> [#uses=1] + %tmp58 = bitcast <4 x i32> %tmp57 to <4 x float> ; <<4 x float>> [#uses=1] + %4 = bitcast float* %y_addr.0 to <4 x float>* ; <<4 x float>*> [#uses=1] + store <4 x float> %tmp58, <4 x float>* %4, align 16 + %5 = getelementptr float* %x_addr.0, i64 4 ; [#uses=1] + %6 = getelementptr float* %y_addr.0, i64 4 ; [#uses=1] + %7 = add i32 %i.0, 4 ; [#uses=1] + br label %bb60 + +bb60: ; preds = %bb, %entry + %i.0 = phi i32 [ 0, %entry ], [ %7, %bb ] ; [#uses=2] + %x_addr.0 = phi float* [ %x, %entry ], [ %5, %bb ] ; [#uses=2] + %y_addr.0 = phi float* [ %y, %entry ], [ %6, %bb ] ; [#uses=2] + %8 = load i32* %n, align 4 ; [#uses=1] + %9 = icmp sgt i32 %8, %i.0 ; [#uses=1] + br i1 %9, label %bb, label %return + +return: ; preds = %bb60 + ret void +} + +declare <4 x float> @llvm.x86.sse.cmp.ps(<4 x float>, <4 x float>, i8) nounwind readnone + +declare <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32>) nounwind readnone From sabre at nondot.org Tue Oct 27 22:36:46 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 28 Oct 2009 03:36:46 -0000 Subject: [llvm-commits] [llvm] r85365 - /llvm/trunk/include/llvm/BasicBlock.h Message-ID: <200910280336.n9S3akqw029757@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 22:36:44 2009 New Revision: 85365 URL: http://llvm.org/viewvc/llvm-project?rev=85365&view=rev Log: basic blocks can now have non-instruction users. Modified: llvm/trunk/include/llvm/BasicBlock.h Modified: llvm/trunk/include/llvm/BasicBlock.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BasicBlock.h?rev=85365&r1=85364&r2=85365&view=diff ============================================================================== --- llvm/trunk/include/llvm/BasicBlock.h (original) +++ llvm/trunk/include/llvm/BasicBlock.h Tue Oct 27 22:36:44 2009 @@ -108,10 +108,10 @@ Function *getParent() { return Parent; } /// use_back - Specialize the methods defined in Value, as we know that an - /// BasicBlock can only be used by Instructions (specifically PHI nodes and - /// terminators). - Instruction *use_back() { return cast(*use_begin());} - const Instruction *use_back() const { return cast(*use_begin());} + /// BasicBlock can only be used by Users (specifically PHI nodes, terminators, + /// and BlockAddress's). + User *use_back() { return cast(*use_begin());} + const User *use_back() const { return cast(*use_begin());} /// getTerminator() - If this is a well formed basic block, then this returns /// a pointer to the terminator instruction. If it is not, then you get a From sabre at nondot.org Tue Oct 27 22:37:35 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 28 Oct 2009 03:37:35 -0000 Subject: [llvm-commits] [llvm] r85366 - /llvm/trunk/lib/VMCore/Function.cpp Message-ID: <200910280337.n9S3bZZK029788@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 22:37:35 2009 New Revision: 85366 URL: http://llvm.org/viewvc/llvm-project?rev=85366&view=rev Log: when we tear down a module, we need to be careful to zap BlockAddress values. Modified: llvm/trunk/lib/VMCore/Function.cpp Modified: llvm/trunk/lib/VMCore/Function.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Function.cpp?rev=85366&r1=85365&r2=85366&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Function.cpp (original) +++ llvm/trunk/lib/VMCore/Function.cpp Tue Oct 27 22:37:35 2009 @@ -217,7 +217,20 @@ void Function::dropAllReferences() { for (iterator I = begin(), E = end(); I != E; ++I) I->dropAllReferences(); - BasicBlocks.clear(); // Delete all basic blocks... + + // Delete all basic blocks. + while (!BasicBlocks.empty()) { + // If there is still a reference to the block, it must be a 'blockaddress' + // constant pointing to it. Just replace the BlockAddress with undef. + BasicBlock *BB = BasicBlocks.begin(); + if (!BB->use_empty()) { + BlockAddress *BA = cast(BB->use_back()); + BA->replaceAllUsesWith(UndefValue::get(BA->getType())); + BA->destroyConstant(); + } + + BB->eraseFromParent(); + } } void Function::addAttribute(unsigned i, Attributes attr) { From sabre at nondot.org Tue Oct 27 22:38:12 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 28 Oct 2009 03:38:12 -0000 Subject: [llvm-commits] [llvm] r85367 - /llvm/trunk/lib/VMCore/AsmWriter.cpp Message-ID: <200910280338.n9S3cCn0029816@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 22:38:12 2009 New Revision: 85367 URL: http://llvm.org/viewvc/llvm-project?rev=85367&view=rev Log: asmprinter support for BlockAddress. Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=85367&r1=85366&r2=85367&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/AsmWriter.cpp (original) +++ llvm/trunk/lib/VMCore/AsmWriter.cpp Tue Oct 27 22:38:12 2009 @@ -1060,6 +1060,15 @@ Out << "zeroinitializer"; return; } + + if (const BlockAddress *BA = dyn_cast(CV)) { + Out << "blockaddress("; + WriteAsOperandInternal(Out, BA->getFunction(), &TypePrinter, Machine); + Out << ", "; + WriteAsOperandInternal(Out, BA->getBasicBlock(), &TypePrinter, Machine); + Out << ")"; + return; + } if (const ConstantArray *CA = dyn_cast(CV)) { // As a special case, print the array as a string if it is an array of From sabre at nondot.org Tue Oct 27 22:39:23 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 28 Oct 2009 03:39:23 -0000 Subject: [llvm-commits] [llvm] r85368 - in /llvm/trunk/lib/AsmParser: LLLexer.cpp LLParser.cpp LLParser.h LLToken.h Message-ID: <200910280339.n9S3dOUJ029862@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 22:39:23 2009 New Revision: 85368 URL: http://llvm.org/viewvc/llvm-project?rev=85368&view=rev Log: full asmparser support for blockaddress. We can now do: $ llvm-as foo.ll -d -disable-output which reads and prints the .ll file. BC encoding is the next project. Testcase will go in once that works. Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp llvm/trunk/lib/AsmParser/LLParser.cpp llvm/trunk/lib/AsmParser/LLParser.h llvm/trunk/lib/AsmParser/LLToken.h Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=85368&r1=85367&r2=85368&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLLexer.cpp (original) +++ llvm/trunk/lib/AsmParser/LLLexer.cpp Tue Oct 27 22:39:23 2009 @@ -576,6 +576,7 @@ KEYWORD(oge); KEYWORD(ord); KEYWORD(uno); KEYWORD(ueq); KEYWORD(une); KEYWORD(x); + KEYWORD(blockaddress); #undef KEYWORD // Keywords for types. Modified: llvm/trunk/lib/AsmParser/LLParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=85368&r1=85367&r2=85368&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) +++ llvm/trunk/lib/AsmParser/LLParser.cpp Tue Oct 27 22:39:23 2009 @@ -29,34 +29,6 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; -namespace llvm { - /// ValID - Represents a reference of a definition of some sort with no type. - /// There are several cases where we have to parse the value but where the - /// type can depend on later context. This may either be a numeric reference - /// or a symbolic (%var) reference. This is just a discriminated union. - struct ValID { - enum { - t_LocalID, t_GlobalID, // ID in UIntVal. - t_LocalName, t_GlobalName, // Name in StrVal. - t_APSInt, t_APFloat, // Value in APSIntVal/APFloatVal. - t_Null, t_Undef, t_Zero, // No value. - t_EmptyArray, // No value: [] - t_Constant, // Value in ConstantVal. - t_InlineAsm, // Value in StrVal/StrVal2/UIntVal. - t_Metadata // Value in MetadataVal. - } Kind; - - LLParser::LocTy Loc; - unsigned UIntVal; - std::string StrVal, StrVal2; - APSInt APSIntVal; - APFloat APFloatVal; - Constant *ConstantVal; - MetadataBase *MetadataVal; - ValID() : APFloatVal(0.0) {} - }; -} - /// Run: module ::= toplevelentity* bool LLParser::Run() { // Prime the lexer. @@ -77,7 +49,7 @@ // declaration of "malloc". In that case, iterate over all calls to MallocF // and get them to call the declared "malloc" instead. if (MallocF->getName() != "malloc") { - Constant* RealMallocF = M->getFunction("malloc"); + Constant *RealMallocF = M->getFunction("malloc"); if (RealMallocF->getType() != MallocF->getType()) RealMallocF = ConstantExpr::getBitCast(RealMallocF, MallocF->getType()); MallocF->replaceAllUsesWith(RealMallocF); @@ -85,7 +57,32 @@ MallocF = NULL; } } - + + + // If there are entries in ForwardRefBlockAddresses at this point, they are + // references after the function was defined. Resolve those now. + while (!ForwardRefBlockAddresses.empty()) { + // Okay, we are referencing an already-parsed function, resolve them now. + Function *TheFn = 0; + const ValID &Fn = ForwardRefBlockAddresses.begin()->first; + if (Fn.Kind == ValID::t_GlobalName) + TheFn = M->getFunction(Fn.StrVal); + else if (Fn.UIntVal < NumberedVals.size()) + TheFn = dyn_cast(NumberedVals[Fn.UIntVal]); + + if (TheFn == 0) + return Error(Fn.Loc, "unknown function referenced by blockaddress"); + + // Resolve all these references. + if (ResolveForwardRefBlockAddresses(TheFn, + ForwardRefBlockAddresses.begin()->second, + 0)) + return true; + + ForwardRefBlockAddresses.erase(ForwardRefBlockAddresses.begin()); + } + + if (!ForwardRefTypes.empty()) return Error(ForwardRefTypes.begin()->second.second, "use of undefined type named '" + @@ -120,6 +117,38 @@ return false; } +bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn, + std::vector > &Refs, + PerFunctionState *PFS) { + // Loop over all the references, resolving them. + for (unsigned i = 0, e = Refs.size(); i != e; ++i) { + BasicBlock *Res; + if (PFS) { + if (Refs[i].first.Kind == ValID::t_LocalName) + Res = PFS->GetBB(Refs[i].first.StrVal, Refs[i].first.Loc); + else + Res = PFS->GetBB(Refs[i].first.UIntVal, Refs[i].first.Loc); + } else if (Refs[i].first.Kind == ValID::t_LocalID) { + return Error(Refs[i].first.Loc, + "cannot take address of numeric label after it the function is defined"); + } else { + Res = dyn_cast_or_null( + TheFn->getValueSymbolTable().lookup(Refs[i].first.StrVal)); + } + + if (Res == 0) + return Error(Refs[i].first.Loc, + "referenced value is not a basic block"); + + // Get the BlockAddress for this and update references to use it. + BlockAddress *BA = BlockAddress::get(TheFn, Res); + Refs[i].second->replaceAllUsesWith(BA); + Refs[i].second->eraseFromParent(); + } + return false; +} + + //===----------------------------------------------------------------------===// // Top-Level Entities //===----------------------------------------------------------------------===// @@ -1575,8 +1604,9 @@ // Function Semantic Analysis. //===----------------------------------------------------------------------===// -LLParser::PerFunctionState::PerFunctionState(LLParser &p, Function &f) - : P(p), F(f) { +LLParser::PerFunctionState::PerFunctionState(LLParser &p, Function &f, + int functionNumber) + : P(p), F(f), FunctionNumber(functionNumber) { // Insert unnamed arguments into the NumberedVals list. for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end(); @@ -1606,7 +1636,29 @@ } } -bool LLParser::PerFunctionState::VerifyFunctionComplete() { +bool LLParser::PerFunctionState::FinishFunction() { + // Check to see if someone took the address of labels in this block. + if (!P.ForwardRefBlockAddresses.empty()) { + ValID FunctionID; + if (!F.getName().empty()) { + FunctionID.Kind = ValID::t_GlobalName; + FunctionID.StrVal = F.getName(); + } else { + FunctionID.Kind = ValID::t_GlobalID; + FunctionID.UIntVal = FunctionNumber; + } + + std::map > >::iterator + FRBAI = P.ForwardRefBlockAddresses.find(FunctionID); + if (FRBAI != P.ForwardRefBlockAddresses.end()) { + // Resolve all these references. + if (P.ResolveForwardRefBlockAddresses(&F, FRBAI->second, this)) + return true; + + P.ForwardRefBlockAddresses.erase(FRBAI); + } + } + if (!ForwardRefVals.empty()) return P.Error(ForwardRefVals.begin()->second.second, "use of undefined value '%" + ForwardRefVals.begin()->first + @@ -1990,6 +2042,35 @@ return false; } + case lltok::kw_blockaddress: { + // ValID ::= 'blockaddress' '(' @foo ',' %bar ')' + Lex.Lex(); + + ValID Fn, Label; + LocTy FnLoc, LabelLoc; + + if (ParseToken(lltok::lparen, "expected '(' in block address expression") || + ParseValID(Fn) || + ParseToken(lltok::comma, "expected comma in block address expression")|| + ParseValID(Label) || + ParseToken(lltok::rparen, "expected ')' in block address expression")) + return true; + + if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName) + return Error(Fn.Loc, "expected function name in blockaddress"); + if (Label.Kind != ValID::t_LocalID && Label.Kind != ValID::t_LocalName) + return Error(Label.Loc, "expected basic block name in blockaddress"); + + // Make a global variable as a placeholder for this reference. + GlobalVariable *FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context), + false, GlobalValue::InternalLinkage, + 0, ""); + ForwardRefBlockAddresses[Fn].push_back(std::make_pair(Label, FwdRef)); + ID.ConstantVal = FwdRef; + ID.Kind = ValID::t_Constant; + return false; + } + case lltok::kw_trunc: case lltok::kw_zext: case lltok::kw_sext: @@ -2637,7 +2718,10 @@ return TokError("expected '{' in function body"); Lex.Lex(); // eat the {. - PerFunctionState PFS(*this, Fn); + int FunctionNumber = -1; + if (!Fn.hasName()) FunctionNumber = NumberedVals.size()-1; + + PerFunctionState PFS(*this, Fn, FunctionNumber); while (Lex.getKind() != lltok::rbrace && Lex.getKind() != lltok::kw_end) if (ParseBasicBlock(PFS)) return true; @@ -2646,7 +2730,7 @@ Lex.Lex(); // Verify function is ok. - return PFS.VerifyFunctionComplete(); + return PFS.FinishFunction(); } /// ParseBasicBlock Modified: llvm/trunk/lib/AsmParser/LLParser.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=85368&r1=85367&r2=85368&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.h (original) +++ llvm/trunk/lib/AsmParser/LLParser.h Tue Oct 27 22:39:23 2009 @@ -31,8 +31,41 @@ class MetadataBase; class MDString; class MDNode; - struct ValID; + /// ValID - Represents a reference of a definition of some sort with no type. + /// There are several cases where we have to parse the value but where the + /// type can depend on later context. This may either be a numeric reference + /// or a symbolic (%var) reference. This is just a discriminated union. + struct ValID { + enum { + t_LocalID, t_GlobalID, // ID in UIntVal. + t_LocalName, t_GlobalName, // Name in StrVal. + t_APSInt, t_APFloat, // Value in APSIntVal/APFloatVal. + t_Null, t_Undef, t_Zero, // No value. + t_EmptyArray, // No value: [] + t_Constant, // Value in ConstantVal. + t_InlineAsm, // Value in StrVal/StrVal2/UIntVal. + t_Metadata // Value in MetadataVal. + } Kind; + + LLLexer::LocTy Loc; + unsigned UIntVal; + std::string StrVal, StrVal2; + APSInt APSIntVal; + APFloat APFloatVal; + Constant *ConstantVal; + MetadataBase *MetadataVal; + ValID() : APFloatVal(0.0) {} + + bool operator<(const ValID &RHS) const { + if (Kind == t_LocalID || Kind == t_GlobalID) + return UIntVal < RHS.UIntVal; + assert((Kind == t_LocalName || Kind == t_GlobalName) && + "Ordering not defined for this ValID kind yet"); + return StrVal < RHS.StrVal; + } + }; + class LLParser { public: typedef LLLexer::LocTy LocTy; @@ -75,7 +108,13 @@ std::map > ForwardRefVals; std::map > ForwardRefValIDs; std::vector NumberedVals; - Function* MallocF; + + // References to blockaddress. The key is the function ValID, the value is + // a list of references to blocks in that function. + std::map > > + ForwardRefBlockAddresses; + + Function *MallocF; public: LLParser(MemoryBuffer *F, SourceMgr &SM, SMDiagnostic &Err, Module *m) : Context(m->getContext()), Lex(F, SM, Err, m->getContext()), @@ -184,13 +223,17 @@ std::map > ForwardRefVals; std::map > ForwardRefValIDs; std::vector NumberedVals; + + /// FunctionNumber - If this is an unnamed function, this is the slot + /// number of it, otherwise it is -1. + int FunctionNumber; public: - PerFunctionState(LLParser &p, Function &f); + PerFunctionState(LLParser &p, Function &f, int FunctionNumber); ~PerFunctionState(); Function &getFunction() const { return F; } - bool VerifyFunctionComplete(); + bool FinishFunction(); /// GetVal - Get a value with the specified name or ID, creating a /// forward reference record if needed. This can return null if the value @@ -294,6 +337,10 @@ bool ParseGetElementPtr(Instruction *&I, PerFunctionState &PFS); bool ParseExtractValue(Instruction *&I, PerFunctionState &PFS); bool ParseInsertValue(Instruction *&I, PerFunctionState &PFS); + + bool ResolveForwardRefBlockAddresses(Function *TheFn, + std::vector > &Refs, + PerFunctionState *PFS); }; } // End llvm namespace Modified: llvm/trunk/lib/AsmParser/LLToken.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=85368&r1=85367&r2=85368&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLToken.h (original) +++ llvm/trunk/lib/AsmParser/LLToken.h Tue Oct 27 22:39:23 2009 @@ -117,7 +117,7 @@ kw_malloc, kw_alloca, kw_free, kw_load, kw_store, kw_getelementptr, kw_extractelement, kw_insertelement, kw_shufflevector, kw_getresult, - kw_extractvalue, kw_insertvalue, + kw_extractvalue, kw_insertvalue, kw_blockaddress, // Unsigned Valued tokens (UIntVal). GlobalID, // @42 From gohman at apple.com Tue Oct 27 22:44:30 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 28 Oct 2009 03:44:30 -0000 Subject: [llvm-commits] [llvm] r85369 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200910280344.n9S3iUUx030026@zion.cs.uiuc.edu> Author: djg Date: Tue Oct 27 22:44:30 2009 New Revision: 85369 URL: http://llvm.org/viewvc/llvm-project?rev=85369&view=rev Log: Rewrite SelectionDAG::isPredecessorOf to be iterative instead of recursive to avoid consuming extraordinary amounts of stack space when processing tall graphs. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=85369&r1=85368&r2=85369&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Oct 27 22:44:30 2009 @@ -5307,31 +5307,26 @@ return false; } - -static void findPredecessor(SDNode *N, const SDNode *P, bool &found, - SmallPtrSet &Visited) { - if (found || !Visited.insert(N)) - return; - - for (unsigned i = 0, e = N->getNumOperands(); !found && i != e; ++i) { - SDNode *Op = N->getOperand(i).getNode(); - if (Op == P) { - found = true; - return; - } - findPredecessor(Op, P, found, Visited); - } -} - /// isPredecessorOf - Return true if this node is a predecessor of N. This node -/// is either an operand of N or it can be reached by recursively traversing -/// up the operands. +/// is either an operand of N or it can be reached by traversing up the operands. /// NOTE: this is an expensive method. Use it carefully. bool SDNode::isPredecessorOf(SDNode *N) const { SmallPtrSet Visited; - bool found = false; - findPredecessor(N, this, found, Visited); - return found; + SmallVector Worklist; + Worklist.push_back(N); + + do { + N = Worklist.pop_back_val(); + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + SDNode *Op = N->getOperand(i).getNode(); + if (Op == this) + return true; + if (Visited.insert(Op)) + Worklist.push_back(Op); + } + } while (!Worklist.empty()); + + return false; } uint64_t SDNode::getConstantOperandVal(unsigned Num) const { From clattner at apple.com Tue Oct 27 22:55:03 2009 From: clattner at apple.com (Chris Lattner) Date: Tue, 27 Oct 2009 20:55:03 -0700 Subject: [llvm-commits] [llvm] r85369 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp In-Reply-To: <200910280344.n9S3iUUx030026@zion.cs.uiuc.edu> References: <200910280344.n9S3iUUx030026@zion.cs.uiuc.edu> Message-ID: On Oct 27, 2009, at 8:44 PM, Dan Gohman wrote: > Author: djg > Date: Tue Oct 27 22:44:30 2009 > New Revision: 85369 > > URL: http://llvm.org/viewvc/llvm-project?rev=85369&view=rev > Log: > Rewrite SelectionDAG::isPredecessorOf to be iterative instead of > recursive to avoid consuming extraordinary amounts of stack space > when processing tall graphs. Hi Dan, Would it make sense or be possible to make this be a tri-state method that returns "yes, no or don't know"? That way it could bail out if the search depth gets too bad, bounding the amount of work. Better yet would be to fix the clients to not need this of course :) -Chris From sabre at nondot.org Tue Oct 27 23:12:24 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 28 Oct 2009 04:12:24 -0000 Subject: [llvm-commits] [llvm] r85370 - /llvm/trunk/lib/VMCore/Constants.cpp Message-ID: <200910280412.n9S4CPHk031056@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 23:12:16 2009 New Revision: 85370 URL: http://llvm.org/viewvc/llvm-project?rev=85370&view=rev Log: 'static const void *X = &&y' can only be put in the readonly section if a reference to the containing function is valid in the readonly section. Modified: llvm/trunk/lib/VMCore/Constants.cpp Modified: llvm/trunk/lib/VMCore/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=85370&r1=85369&r2=85370&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Constants.cpp (original) +++ llvm/trunk/lib/VMCore/Constants.cpp Tue Oct 27 23:12:16 2009 @@ -182,6 +182,9 @@ return GlobalRelocations; // Global reference. } + if (const BlockAddress *BA = dyn_cast(this)) + return BA->getFunction()->getRelocationInfo(); + PossibleRelocationsTy Result = NoRelocation; for (unsigned i = 0, e = getNumOperands(); i != e; ++i) Result = std::max(Result, getOperand(i)->getRelocationInfo()); From nicholas at mxc.ca Tue Oct 27 23:25:30 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Tue, 27 Oct 2009 21:25:30 -0700 Subject: [llvm-commits] FW: [PATCH] Fix to pass options from Gold plugin to LTO codegen In-Reply-To: <45894BE6012542EF9E5CF87A4A757C5B@andreic6e7fe55> References: <3FE2DECEF38F9247AE7C8BC1FD2B015F0817022C@ALLISON>, <6AE1604EE3EC5F4296C096518C6B77EEF11643FF@mail.accesssoftek.com><6AE1604EE3EC5F4296C096518C6B77EEF1163385@mail.accesssoftek.com><4AE250D1.4090403@mxc.ca> <4AE67CEB.6010404@mxc.ca> <45894BE6012542EF9E5CF87A4A757C5B@andreic6e7fe55> Message-ID: <4AE7C7BA.4080703@mxc.ca> Viktor Kutuzov wrote: > Please find attached the updated patch. > Is it Ok to submit? Looks great, please commit! Nick > Viktor > > ----- Original Message ----- From: "Nick Lewycky" > To: "Viktor Kutuzov" > Cc: "Commit Messages and Patches for LLVM" > Sent: Monday, October 26, 2009 9:54 PM > Subject: Re: [llvm-commits] FW: [PATCH] Fix to pass options from Gold > plugin to LTO codegen > > > Viktor Kutuzov wrote: >> Hello Nick, >> Thanks for the review. >> >> Please find the updated patch attached. >> >> I didn't remove the lto_codegen_debug_options yet, just marked it as >> deprecated. >> It is actually used in Ada, in files >> >> bindings/ada/llvm/llvm_linktimeoptimizer_wrap.cxx >> bindings/ada/llvm/llvm_link_time_optimizer-binding.ads > > Bah, then it's too late. We released 2.6 with this API which means that > it's fixed in stone forever. All of the C API is like that, we will > never break backwards-compatibility on the C API. > > Well, given that, why not just call lto_codegen_debug_options? The > comment makes it clear that it's "used to pass extra options to the code > generator" and that's just what we're doing. > >> Edward, is this fine to use lto_codegen_set_options there instead? >> >>> And that would be even better if it took an argc+argv pair >> >> Gold plug-in gets all arguments from gold one by one. >> It is not a big dial to construct argc+argv pair there and pass it >> down to the LTO, but LTO internally keeps a vector of char*, so, >> argc+argv doesn't make much sense unless we want to replace that >> vector with argc+argv pair as well and to change setCodeGenOptions >> behavior to set options instead of add them. > > Sure, given that lto_codegen_debug_options takes one option at a time > and we're wedded to this API then we may as well use it. > > Please send another patch without the new "lto_codegen_set_options" > function by calling the "lto_codegen_debug_options" function instead. > The changes to gold-plugin.cpp look great to me! > > Nick > >> If this is fine with everyone, I can prepare this patch, but would >> prefer to make it separately from this one since it would change the >> API and will break a backward compatibility. >> What do you think? >> >> Thanks, >> Viktor >> >> ----- Original Message ----- From: "Nick Lewycky" >> To: "Viktor Kutuzov" >> Cc: "Commit Messages and Patches for LLVM" >> Sent: Friday, October 23, 2009 5:56 PM >> Subject: Re: [llvm-commits] FW: [PATCH] Fix to pass options from Gold >> plugin to LTO codegen >> >> >> Viktor Kutuzov wrote: >>> Hello everyone, >>> >>> Please find the patch attached. >>> This should fix the issue when gold plugin doesn't pass the >>> -plugin-opt options down to the LTO codegen. >>> See the thread "[LLVMdev] getting gold plugin to work?" for more >>> details. >>> >>> This is the second try. >>> It looks like the first one was bounced, not sure why. >>> Sorry if anyone will get it twise. >> >> Hi Viktor, this looks like the same patch I already reviewed here: >> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20091019/089467.html >> >> >> To reiterate: >> "What's the difference between setCodeGenDebugOptions and >> setCodeGenOption? It looks like they should be merged into one then >> exposed by lto_codegen_set_option. And that would be even better if it >> took an argc+argv pair, even if that's a little harder to construct from >> the gold plugin, many option parsing packages work by removing the >> options they recognize from argc+argv and leaving the rest in place." >> >> Nick >> >> >> ------------------------------------------------------------------------ >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From gohman at apple.com Tue Oct 27 23:40:00 2009 From: gohman at apple.com (Dan Gohman) Date: Tue, 27 Oct 2009 21:40:00 -0700 Subject: [llvm-commits] [llvm] r85369 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp In-Reply-To: References: <200910280344.n9S3iUUx030026@zion.cs.uiuc.edu> Message-ID: On Oct 27, 2009, at 8:55 PM, Chris Lattner wrote: > > On Oct 27, 2009, at 8:44 PM, Dan Gohman wrote: > >> Author: djg >> Date: Tue Oct 27 22:44:30 2009 >> New Revision: 85369 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=85369&view=rev >> Log: >> Rewrite SelectionDAG::isPredecessorOf to be iterative instead of >> recursive to avoid consuming extraordinary amounts of stack space >> when processing tall graphs. > > Hi Dan, > > Would it make sense or be possible to make this be a tri-state method that returns "yes, no or don't know"? That way it could bail out if the search depth gets too bad, bounding the amount of work. isPredecessorOf is used in contexts where true is a conservative answer. So yes, this could be done, if anyone is interested. Another optimization would be to check if the loads have no chain users. In that case, no searching is necessary. That might be a fairly common case. Dan From nicholas at mxc.ca Tue Oct 27 23:45:16 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Tue, 27 Oct 2009 21:45:16 -0700 Subject: [llvm-commits] [llvm] r85295 - in /llvm/trunk: docs/tutorial/LangImpl4.html docs/tutorial/OCamlLangImpl4.html include/llvm/ExecutionEngine/ExecutionEngine.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngi In-Reply-To: <9879CBCC-0704-4FC7-8061-94D382FA7587@apple.com> References: <9879CBCC-0704-4FC7-8061-94D382FA7587@apple.com> Message-ID: <4AE7CC5C.5040300@mxc.ca> Evan Cheng wrote: > On Oct 27, 2009, at 2:11 PM, Jeffrey Yasskin wrote: > >> On Tue, Oct 27, 2009 at 1:54 PM, Evan Cheng >> wrote: >>> On Oct 27, 2009, at 1:30 PM, Jeffrey Yasskin wrote: >>> >>>> Author: jyasskin >>>> Date: Tue Oct 27 15:30:28 2009 >>>> New Revision: 85295 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=85295&view=rev >>>> Log: >>>> Change the JIT to compile eagerly by default as agreed in >>>> http://llvm.org/PR5184, and beef up the comments to describe what >>>> both >>>> options >>>> do and the risks of lazy compilation in the presence of threads. >>> Hi Jeffrey, >>> >>> In the future I'd prefer API changes be agreed upon by the greater >>> community, not just in a bugzilla report. >> Sorry about that. Do you want me to revert this until we can ping >> llvmdev? >> >>> Lazy compilation is being used by some important clients. They will >>> be >>> caught off guard by this change. Does this change lli default >>> behavior? >> No, it doesn't change lli's default, although that was an accident on >> my part (maybe a fortunate accident). I did ping llvmdev last week >> asking people who use the lazy JIT to look at the bug report, but I >> can see how people who don't use threads with the JIT would think it >> didn't apply to them. > > Sorry, I have been too busy with other things so I didn't follow the > thread. > > The patch changed DisableLazyCompilation to EnableLazyCompilation, > which is minor but it's a API change nevertheless. That means clients > which are using 2.6 have to change their code in order to test against > tot. Unless this is absolutely necessary, I'd prefer not to change it. Hey Evan, since when did "it's an API change" become a reason not to modify LLVM? If your concern is that it wasn't discussed enough in advance or trumpeted/advertised enough after landing, fine -- but if the change is for the better then it should go in, and out of tree users get to update their own code. Does that sound like the LLVM we both know? Nick From sabre at nondot.org Tue Oct 27 23:47:06 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 28 Oct 2009 04:47:06 -0000 Subject: [llvm-commits] [llvm] r85372 - /llvm/trunk/docs/Passes.html Message-ID: <200910280447.n9S4l6Ac032309@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 27 23:47:06 2009 New Revision: 85372 URL: http://llvm.org/viewvc/llvm-project?rev=85372&view=rev Log: doc bug spotted by apinski Modified: llvm/trunk/docs/Passes.html Modified: llvm/trunk/docs/Passes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/Passes.html?rev=85372&r1=85371&r2=85372&view=diff ============================================================================== --- llvm/trunk/docs/Passes.html (original) +++ llvm/trunk/docs/Passes.html Tue Oct 27 23:47:06 2009 @@ -1787,8 +1787,8 @@ integrals f.e.
  • All of the constants in a switch statement are of the correct type.
  • The code is in valid SSA form.
  • -
  • It should be illegal to put a label into any other type (like a - structure) or to return one. [except constant arrays!]
  • +
  • It is illegal to put a label into any other type (like a structure) or + to return one.
  • Only phi nodes can be self referential: %x = add i32 %x, %x is invalid.
  • PHI nodes must have an entry for each predecessor, with no extras.
  • From evan.cheng at apple.com Wed Oct 28 00:03:38 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 27 Oct 2009 22:03:38 -0700 Subject: [llvm-commits] [llvm] r85295 - in /llvm/trunk: docs/tutorial/LangImpl4.html docs/tutorial/OCamlLangImpl4.html include/llvm/ExecutionEngine/ExecutionEngine.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngi In-Reply-To: <4AE7CC5C.5040300@mxc.ca> References: <9879CBCC-0704-4FC7-8061-94D382FA7587@apple.com> <4AE7CC5C.5040300@mxc.ca> Message-ID: <02C5660C-FC69-4B07-B329-784D718E49D2@apple.com> On Oct 27, 2009, at 9:45 PM, Nick Lewycky wrote: > Evan Cheng wrote: >> On Oct 27, 2009, at 2:11 PM, Jeffrey Yasskin wrote: >>> On Tue, Oct 27, 2009 at 1:54 PM, Evan Cheng >>> wrote: >>>> On Oct 27, 2009, at 1:30 PM, Jeffrey Yasskin wrote: >>>> >>>>> Author: jyasskin >>>>> Date: Tue Oct 27 15:30:28 2009 >>>>> New Revision: 85295 >>>>> >>>>> URL: http://llvm.org/viewvc/llvm-project?rev=85295&view=rev >>>>> Log: >>>>> Change the JIT to compile eagerly by default as agreed in >>>>> http://llvm.org/PR5184, and beef up the comments to describe >>>>> what both >>>>> options >>>>> do and the risks of lazy compilation in the presence of threads. >>>> Hi Jeffrey, >>>> >>>> In the future I'd prefer API changes be agreed upon by the greater >>>> community, not just in a bugzilla report. >>> Sorry about that. Do you want me to revert this until we can ping >>> llvmdev? >>> >>>> Lazy compilation is being used by some important clients. They >>>> will be >>>> caught off guard by this change. Does this change lli default >>>> behavior? >>> No, it doesn't change lli's default, although that was an accident >>> on >>> my part (maybe a fortunate accident). I did ping llvmdev last week >>> asking people who use the lazy JIT to look at the bug report, but I >>> can see how people who don't use threads with the JIT would think it >>> didn't apply to them. >> Sorry, I have been too busy with other things so I didn't follow >> the thread. >> The patch changed DisableLazyCompilation to EnableLazyCompilation, >> which is minor but it's a API change nevertheless. That means >> clients which are using 2.6 have to change their code in order to >> test against tot. Unless this is absolutely necessary, I'd prefer >> not to change it. > > Hey Evan, since when did "it's an API change" become a reason not to > modify LLVM? > > If your concern is that it wasn't discussed enough in advance or > trumpeted/advertised enough after landing, fine -- but if the change > is for the better then it should go in, and out of tree users get to > update their own code. Does that sound like the LLVM we both know? I am not opposed to modifying API for a good reason. I am not convinced there is a good one here. I believe lazy compilation should still be the default behavior for JIT. If it's not thread safe, then clients who want JIT safety should fix it. Evan > > Nick From sabre at nondot.org Wed Oct 28 00:14:35 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 28 Oct 2009 05:14:35 -0000 Subject: [llvm-commits] [llvm] r85375 - in /llvm/trunk: include/llvm/Constant.h include/llvm/Constants.h lib/Bitcode/Writer/BitcodeWriter.cpp lib/Target/MSIL/MSILWriter.cpp lib/Transforms/IPO/StripSymbols.cpp lib/VMCore/ConstantFold.cpp lib/VMCore/Constants.cpp Message-ID: <200910280514.n9S5EZGq000883@zion.cs.uiuc.edu> Author: lattner Date: Wed Oct 28 00:14:34 2009 New Revision: 85375 URL: http://llvm.org/viewvc/llvm-project?rev=85375&view=rev Log: Previously, all operands to Constant were themselves constant. In the new world order, BlockAddress can have a BasicBlock operand. This doesn't permute much, because if you have a ConstantExpr (or anything more specific than Constant) we still know the operand has to be a Constant. Modified: llvm/trunk/include/llvm/Constant.h llvm/trunk/include/llvm/Constants.h llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/trunk/lib/Target/MSIL/MSILWriter.cpp llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp llvm/trunk/lib/VMCore/ConstantFold.cpp llvm/trunk/lib/VMCore/Constants.cpp Modified: llvm/trunk/include/llvm/Constant.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constant.h?rev=85375&r1=85374&r2=85375&view=diff ============================================================================== --- llvm/trunk/include/llvm/Constant.h (original) +++ llvm/trunk/include/llvm/Constant.h Wed Oct 28 00:14:34 2009 @@ -48,6 +48,10 @@ : User(ty, vty, Ops, NumOps) {} void destroyConstantImpl(); + + void setOperand(unsigned i, Value *V) { + User::setOperand(i, V); + } public: /// isNullValue - Return true if this is the value that would be returned by /// getNullValue. @@ -83,16 +87,13 @@ /// FIXME: This really should not be in VMCore. PossibleRelocationsTy getRelocationInfo() const; - // Specialize get/setOperand for Constants as their operands are always - // constants as well. - Constant *getOperand(unsigned i) { - return static_cast(User::getOperand(i)); - } - const Constant *getOperand(unsigned i) const { - return static_cast(User::getOperand(i)); + // Specialize get/setOperand for Users as their operands are always + // constants or BasicBlocks as well. + User *getOperand(unsigned i) { + return static_cast(User::getOperand(i)); } - void setOperand(unsigned i, Constant *C) { - User::setOperand(i, C); + const User *getOperand(unsigned i) const { + return static_cast(User::getOperand(i)); } /// getVectorElements - This method, which is only valid on constant of vector Modified: llvm/trunk/include/llvm/Constants.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=85375&r1=85374&r2=85375&view=diff ============================================================================== --- llvm/trunk/include/llvm/Constants.h (original) +++ llvm/trunk/include/llvm/Constants.h Wed Oct 28 00:14:34 2009 @@ -564,7 +564,7 @@ static BlockAddress *get(BasicBlock *BB); /// Transparently provide more efficient getOperand methods. - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); Function *getFunction() const { return (Function*)Op<0>().get(); } BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); } @@ -587,7 +587,7 @@ struct OperandTraits : public FixedNumOperandTraits<2> { }; -DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(BlockAddress, Constant) +DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(BlockAddress, Value) //===----------------------------------------------------------------------===// /// ConstantExpr - a constant value that is initialized with an expression using Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=85375&r1=85374&r2=85375&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Wed Oct 28 00:14:34 2009 @@ -751,10 +751,11 @@ assert (0 && "Unknown FP type!"); } } else if (isa(C) && cast(C)->isString()) { + const ConstantArray *CA = cast(C); // Emit constant strings specially. - unsigned NumOps = C->getNumOperands(); + unsigned NumOps = CA->getNumOperands(); // If this is a null-terminated string, use the denser CSTRING encoding. - if (C->getOperand(NumOps-1)->isNullValue()) { + if (CA->getOperand(NumOps-1)->isNullValue()) { Code = bitc::CST_CODE_CSTRING; --NumOps; // Don't encode the null, which isn't allowed by char6. } else { @@ -764,7 +765,7 @@ bool isCStr7 = Code == bitc::CST_CODE_CSTRING; bool isCStrChar6 = Code == bitc::CST_CODE_CSTRING; for (unsigned i = 0; i != NumOps; ++i) { - unsigned char V = cast(C->getOperand(i))->getZExtValue(); + unsigned char V = cast(CA->getOperand(i))->getZExtValue(); Record.push_back(V); isCStr7 &= (V & 128) == 0; if (isCStrChar6) Modified: llvm/trunk/lib/Target/MSIL/MSILWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSIL/MSILWriter.cpp?rev=85375&r1=85374&r2=85375&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSIL/MSILWriter.cpp (original) +++ llvm/trunk/lib/Target/MSIL/MSILWriter.cpp Wed Oct 28 00:14:34 2009 @@ -1529,7 +1529,7 @@ case Type::StructTyID: for (unsigned I = 0, E = C->getNumOperands(); IgetOperand(I),Offset); + printStaticConstant(cast(C->getOperand(I)), Offset); } break; case Type::PointerTyID: Modified: llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp?rev=85375&r1=85374&r2=85375&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Wed Oct 28 00:14:34 2009 @@ -112,11 +112,11 @@ static void RemoveDeadConstant(Constant *C) { assert(C->use_empty() && "Constant is not dead!"); - SmallPtrSet Operands; + SmallPtrSet Operands; for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) if (isa(C->getOperand(i)->getType()) && OnlyUsedBy(C->getOperand(i), C)) - Operands.insert(C->getOperand(i)); + Operands.insert(cast(C->getOperand(i))); if (GlobalVariable *GV = dyn_cast(C)) { if (!GV->hasLocalLinkage()) return; // Don't delete non static globals. GV->eraseFromParent(); @@ -126,7 +126,7 @@ C->destroyConstant(); // If the constant referenced anything, see if we can delete it as well. - for (SmallPtrSet::iterator OI = Operands.begin(), + for (SmallPtrSet::iterator OI = Operands.begin(), OE = Operands.end(); OI != OE; ++OI) RemoveDeadConstant(*OI); } @@ -305,8 +305,7 @@ if (GlobalVariable *GV = dyn_cast(C)) { if (GV->hasLocalLinkage()) RemoveDeadConstant(GV); - } - else + } else RemoveDeadConstant(C); } Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=85375&r1=85374&r2=85375&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ConstantFold.cpp (original) +++ llvm/trunk/lib/VMCore/ConstantFold.cpp Wed Oct 28 00:14:34 2009 @@ -215,7 +215,7 @@ switch (CE->getOpcode()) { default: return 0; case Instruction::Or: { - Constant *RHS = ExtractConstantBytes(C->getOperand(1), ByteStart, ByteSize); + Constant *RHS = ExtractConstantBytes(CE->getOperand(1), ByteStart,ByteSize); if (RHS == 0) return 0; @@ -224,13 +224,13 @@ if (RHSC->isAllOnesValue()) return RHSC; - Constant *LHS = ExtractConstantBytes(C->getOperand(0), ByteStart, ByteSize); + Constant *LHS = ExtractConstantBytes(CE->getOperand(0), ByteStart,ByteSize); if (LHS == 0) return 0; return ConstantExpr::getOr(LHS, RHS); } case Instruction::And: { - Constant *RHS = ExtractConstantBytes(C->getOperand(1), ByteStart, ByteSize); + Constant *RHS = ExtractConstantBytes(CE->getOperand(1), ByteStart,ByteSize); if (RHS == 0) return 0; @@ -238,7 +238,7 @@ if (RHS->isNullValue()) return RHS; - Constant *LHS = ExtractConstantBytes(C->getOperand(0), ByteStart, ByteSize); + Constant *LHS = ExtractConstantBytes(CE->getOperand(0), ByteStart,ByteSize); if (LHS == 0) return 0; return ConstantExpr::getAnd(LHS, RHS); @@ -259,7 +259,7 @@ ByteSize*8)); // If the extract is known to be fully in the input, extract it. if (ByteStart+ByteSize+ShAmt <= CSize) - return ExtractConstantBytes(C->getOperand(0), ByteStart+ShAmt, ByteSize); + return ExtractConstantBytes(CE->getOperand(0), ByteStart+ShAmt, ByteSize); // TODO: Handle the 'partially zero' case. return 0; @@ -281,7 +281,7 @@ ByteSize*8)); // If the extract is known to be fully in the input, extract it. if (ByteStart >= ShAmt) - return ExtractConstantBytes(C->getOperand(0), ByteStart-ShAmt, ByteSize); + return ExtractConstantBytes(CE->getOperand(0), ByteStart-ShAmt, ByteSize); // TODO: Handle the 'partially zero' case. return 0; @@ -289,7 +289,7 @@ case Instruction::ZExt: { unsigned SrcBitSize = - cast(C->getOperand(0)->getType())->getBitWidth(); + cast(CE->getOperand(0)->getType())->getBitWidth(); // If extracting something that is completely zero, return 0. if (ByteStart*8 >= SrcBitSize) @@ -298,18 +298,18 @@ // If exactly extracting the input, return it. if (ByteStart == 0 && ByteSize*8 == SrcBitSize) - return C->getOperand(0); + return CE->getOperand(0); // If extracting something completely in the input, if if the input is a // multiple of 8 bits, recurse. if ((SrcBitSize&7) == 0 && (ByteStart+ByteSize)*8 <= SrcBitSize) - return ExtractConstantBytes(C->getOperand(0), ByteStart, ByteSize); + return ExtractConstantBytes(CE->getOperand(0), ByteStart, ByteSize); // Otherwise, if extracting a subset of the input, which is not multiple of // 8 bits, do a shift and trunc to get the bits. if ((ByteStart+ByteSize)*8 < SrcBitSize) { assert((SrcBitSize&7) && "Shouldn't get byte sized case here"); - Constant *Res = C->getOperand(0); + Constant *Res = CE->getOperand(0); if (ByteStart) Res = ConstantExpr::getLShr(Res, ConstantInt::get(Res->getType(), ByteStart*8)); @@ -634,7 +634,15 @@ Idxs + NumIdx)); // Otherwise recurse. - return ConstantFoldExtractValueInstruction(Context, Agg->getOperand(*Idxs), + if (ConstantStruct *CS = dyn_cast(Agg)) + return ConstantFoldExtractValueInstruction(Context, CS->getOperand(*Idxs), + Idxs+1, NumIdx-1); + + if (ConstantArray *CA = dyn_cast(Agg)) + return ConstantFoldExtractValueInstruction(Context, CA->getOperand(*Idxs), + Idxs+1, NumIdx-1); + ConstantVector *CV = cast(Agg); + return ConstantFoldExtractValueInstruction(Context, CV->getOperand(*Idxs), Idxs+1, NumIdx-1); } @@ -714,11 +722,10 @@ // Insertion of constant into aggregate constant. std::vector Ops(Agg->getNumOperands()); for (unsigned i = 0; i < Agg->getNumOperands(); ++i) { - Constant *Op = - (*Idxs == i) ? - ConstantFoldInsertValueInstruction(Context, Agg->getOperand(i), - Val, Idxs+1, NumIdx-1) : - Agg->getOperand(i); + Constant *Op = cast(Agg->getOperand(i)); + if (*Idxs == i) + Op = ConstantFoldInsertValueInstruction(Context, Op, + Val, Idxs+1, NumIdx-1); Ops[i] = Op; } Modified: llvm/trunk/lib/VMCore/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=85375&r1=85374&r2=85375&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Constants.cpp (original) +++ llvm/trunk/lib/VMCore/Constants.cpp Wed Oct 28 00:14:34 2009 @@ -140,7 +140,7 @@ // ConstantExpr traps if any operands can trap. for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (getOperand(i)->canTrap()) + if (CE->getOperand(i)->canTrap()) return true; // Otherwise, only specific operations can trap. @@ -154,7 +154,7 @@ case Instruction::SRem: case Instruction::FRem: // Div and rem can trap if the RHS is not known to be non-zero. - if (!isa(getOperand(1)) || getOperand(1)->isNullValue()) + if (!isa(CE->getOperand(1)) ||CE->getOperand(1)->isNullValue()) return true; return false; } @@ -187,7 +187,8 @@ PossibleRelocationsTy Result = NoRelocation; for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - Result = std::max(Result, getOperand(i)->getRelocationInfo()); + Result = std::max(Result, + cast(getOperand(i))->getRelocationInfo()); return Result; } From sabre at nondot.org Wed Oct 28 00:24:48 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 28 Oct 2009 05:24:48 -0000 Subject: [llvm-commits] [llvm] r85376 - in /llvm/trunk: include/llvm/Bitcode/LLVMBitCodes.h lib/Bitcode/Writer/BitcodeWriter.cpp lib/Bitcode/Writer/ValueEnumerator.cpp lib/Bitcode/Writer/ValueEnumerator.h Message-ID: <200910280524.n9S5OoG2001264@zion.cs.uiuc.edu> Author: lattner Date: Wed Oct 28 00:24:40 2009 New Revision: 85376 URL: http://llvm.org/viewvc/llvm-project?rev=85376&view=rev Log: bitcode writer support for blockaddress. Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=85376&r1=85375&r2=85376&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original) +++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Wed Oct 28 00:24:40 2009 @@ -138,7 +138,8 @@ CST_CODE_CE_CMP = 17, // CE_CMP: [opty, opval, opval, pred] CST_CODE_INLINEASM = 18, // INLINEASM: [sideeffect,asmstr,conststr] CST_CODE_CE_SHUFVEC_EX = 19, // SHUFVEC_EX: [opty, opval, opval, opval] - CST_CODE_CE_INBOUNDS_GEP = 20 // INBOUNDS_GEP: [n x operands] + CST_CODE_CE_INBOUNDS_GEP = 20,// INBOUNDS_GEP: [n x operands] + CST_CODE_BLOCKADDRESS = 21 // CST_CODE_BLOCKADDRESS [fnty, fnval, bb#] }; /// CastOpcodes - These are values used in the bitcode files to encode which Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=85376&r1=85375&r2=85376&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Wed Oct 28 00:24:40 2009 @@ -853,6 +853,13 @@ Record.push_back(CE->getPredicate()); break; } + } else if (const BlockAddress *BA = dyn_cast(C)) { + assert(BA->getFunction() == BA->getBasicBlock()->getParent() && + "Malformed blockaddress"); + Code = bitc::CST_CODE_BLOCKADDRESS; + Record.push_back(VE.getTypeID(BA->getFunction()->getType())); + Record.push_back(VE.getValueID(BA->getFunction())); + Record.push_back(VE.getGlobalBasicBlockID(BA->getBasicBlock())); } else { llvm_unreachable("Unknown constant!"); } Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp?rev=85376&r1=85375&r2=85376&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp Wed Oct 28 00:24:40 2009 @@ -223,7 +223,9 @@ EnumerateType(Type::getVoidTy(MD->getContext())); } return; - } else if (const NamedMDNode *N = dyn_cast(MD)) { + } + + if (const NamedMDNode *N = dyn_cast(MD)) { for(NamedMDNode::const_elem_iterator I = N->elem_begin(), E = N->elem_end(); I != E; ++I) { MetadataBase *M = *I; @@ -274,7 +276,8 @@ // graph that don't go through a global variable. for (User::const_op_iterator I = C->op_begin(), E = C->op_end(); I != E; ++I) - EnumerateValue(*I); + if (!isa(*I)) // Don't enumerate BB operand to BlockAddress. + EnumerateValue(*I); // Finally, add the value. Doing this could make the ValueID reference be // dangling, don't reuse it. @@ -320,15 +323,20 @@ // This constant may have operands, make sure to enumerate the types in // them. - for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) - EnumerateOperandType(C->getOperand(i)); + for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { + const User *Op = C->getOperand(i); + + // Don't enumerate basic blocks here, this happens as operands to + // blockaddress. + if (isa(Op)) continue; + + EnumerateOperandType(cast(Op)); + } if (const MDNode *N = dyn_cast(V)) { - for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) { - Value *Elem = N->getElement(i); - if (Elem) + for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) + if (Value *Elem = N->getElement(i)) EnumerateOperandType(Elem); - } } } else if (isa(V) || isa(V)) EnumerateValue(V); @@ -397,3 +405,23 @@ Values.resize(NumModuleValues); BasicBlocks.clear(); } + +static void IncorporateFunctionInfoGlobalBBIDs(const Function *F, + DenseMap &IDMap) { + unsigned Counter = 0; + for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB) + IDMap[BB] = ++Counter; +} + +/// getGlobalBasicBlockID - This returns the function-specific ID for the +/// specified basic block. This is relatively expensive information, so it +/// should only be used by rare constructs such as address-of-label. +unsigned ValueEnumerator::getGlobalBasicBlockID(const BasicBlock *BB) const { + unsigned &Idx = GlobalBasicBlockIDs[BB]; + if (Idx != 0) + return Idx-1; + + IncorporateFunctionInfoGlobalBBIDs(BB->getParent(), GlobalBasicBlockIDs); + return getGlobalBasicBlockID(BB); +} + Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h?rev=85376&r1=85375&r2=85376&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h (original) +++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h Wed Oct 28 00:24:40 2009 @@ -53,6 +53,10 @@ AttributeMapType AttributeMap; std::vector Attributes; + /// GlobalBasicBlockIDs - This map memoizes the basic block ID's referenced by + /// the "getGlobalBasicBlockID" method. + mutable DenseMap GlobalBasicBlockIDs; + typedef DenseMap InstructionMapType; InstructionMapType InstructionMap; unsigned InstructionCount; @@ -106,6 +110,11 @@ const std::vector &getAttributes() const { return Attributes; } + + /// getGlobalBasicBlockID - This returns the function-specific ID for the + /// specified basic block. This is relatively expensive information, so it + /// should only be used by rare constructs such as address-of-label. + unsigned getGlobalBasicBlockID(const BasicBlock *BB) const; /// incorporateFunction/purgeFunction - If you'd like to deal with a function, /// use these two methods to get its data into the ValueEnumerator! From sabre at nondot.org Wed Oct 28 00:53:48 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 28 Oct 2009 05:53:48 -0000 Subject: [llvm-commits] [llvm] r85377 - in /llvm/trunk: lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Reader/BitcodeReader.h test/Feature/terminators.ll Message-ID: <200910280553.n9S5rn3C002305@zion.cs.uiuc.edu> Author: lattner Date: Wed Oct 28 00:53:48 2009 New Revision: 85377 URL: http://llvm.org/viewvc/llvm-project?rev=85377&view=rev Log: add bitcode reader support for blockaddress. We can now fully round trip blockaddress through .ll and .bc files, so add a testcase. There are still a bunch of places in the optimizer and other places that need to be updated to work with these constructs, but at least the basics are in now. Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h llvm/trunk/test/Feature/terminators.ll Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=85377&r1=85376&r2=85377&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Wed Oct 28 00:53:48 2009 @@ -1192,6 +1192,22 @@ AsmStr, ConstrStr, HasSideEffects, IsAlignStack); break; } + case bitc::CST_CODE_BLOCKADDRESS:{ + if (Record.size() < 3) return Error("Invalid CE_BLOCKADDRESS record"); + const Type *FnTy = getTypeByID(Record[0]); + if (FnTy == 0) return Error("Invalid CE_BLOCKADDRESS record"); + Function *Fn = + dyn_cast_or_null(ValueList.getConstantFwdRef(Record[1],FnTy)); + if (Fn == 0) return Error("Invalid CE_BLOCKADDRESS record"); + + GlobalVariable *FwdRef = new GlobalVariable(*Fn->getParent(), + Type::getInt8Ty(Context), + false, GlobalValue::InternalLinkage, + 0, ""); + BlockAddrFwdRefs[Fn].push_back(std::make_pair(Record[2], FwdRef)); + V = FwdRef; + break; + } } ValueList.AssignValue(V, NextCstNo); @@ -2248,6 +2264,27 @@ } } + // See if anything took the address of blocks in this function. If so, + // resolve them now. + /// BlockAddrFwdRefs - These are blockaddr references to basic blocks. These + /// are resolved lazily when functions are loaded. + DenseMap >::iterator BAFRI = + BlockAddrFwdRefs.find(F); + if (BAFRI != BlockAddrFwdRefs.end()) { + std::vector &RefList = BAFRI->second; + for (unsigned i = 0, e = RefList.size(); i != e; ++i) { + unsigned BlockIdx = RefList[i].first; + if (BlockIdx >= FunctionBBs.size()) + return Error("Invalid blockaddress block #"); + + GlobalVariable *FwdRef = RefList[i].second; + FwdRef->replaceAllUsesWith(BlockAddress::get(F, FunctionBBs[BlockIdx])); + FwdRef->eraseFromParent(); + } + + BlockAddrFwdRefs.erase(BAFRI); + } + // Trim the value list down to the size it was before we parsed this function. ValueList.shrinkTo(ModuleValueListSize); std::vector().swap(FunctionBBs); Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h?rev=85377&r1=85376&r2=85377&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h (original) +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h Wed Oct 28 00:53:48 2009 @@ -94,7 +94,7 @@ class BitcodeReaderMDValueList { std::vector MDValuePtrs; - LLVMContext& Context; + LLVMContext &Context; public: BitcodeReaderMDValueList(LLVMContext& C) : Context(C) {} @@ -122,7 +122,7 @@ }; class BitcodeReader : public ModuleProvider { - LLVMContext& Context; + LLVMContext &Context; MemoryBuffer *Buffer; BitstreamReader StreamFile; BitstreamCursor Stream; @@ -163,6 +163,12 @@ /// map contains info about where to find deferred function body (in the /// stream) and what linkage the original function had. DenseMap > DeferredFunctionInfo; + + /// BlockAddrFwdRefs - These are blockaddr references to basic blocks. These + /// are resolved lazily when functions are loaded. + typedef std::pair BlockAddrRefTy; + DenseMap > BlockAddrFwdRefs; + public: explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext& C) : Context(C), Buffer(buffer), ErrorString(0), ValueList(C), MDValueList(C) { Modified: llvm/trunk/test/Feature/terminators.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/terminators.ll?rev=85377&r1=85376&r2=85377&view=diff ============================================================================== --- llvm/trunk/test/Feature/terminators.ll (original) +++ llvm/trunk/test/Feature/terminators.ll Wed Oct 28 00:53:48 2009 @@ -25,13 +25,19 @@ } + at Addr = global i8* blockaddress(@indbrtest, %BB1) + at Addr3 = global i8* blockaddress(@squared, %Case1) + define i32 @indbrtest(i8* %P, i32* %Q) { indirectbr i8* %P, [label %BB1, label %BB2, label %BB3] BB1: indirectbr i32* %Q, [] BB2: - indirectbr i32* %Q, [label %BB1, label %BB2] + %R = bitcast i8* blockaddress(@indbrtest, %BB3) to i8* + indirectbr i8* %R, [label %BB1, label %BB2, label %BB3] BB3: ret i32 2 } + + From jyasskin at google.com Wed Oct 28 01:07:18 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Tue, 27 Oct 2009 23:07:18 -0700 Subject: [llvm-commits] [llvm] r85295 - in /llvm/trunk: docs/tutorial/LangImpl4.html docs/tutorial/OCamlLangImpl4.html include/llvm/ExecutionEngine/ExecutionEngine.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngi In-Reply-To: <02C5660C-FC69-4B07-B329-784D718E49D2@apple.com> References: <9879CBCC-0704-4FC7-8061-94D382FA7587@apple.com> <4AE7CC5C.5040300@mxc.ca> <02C5660C-FC69-4B07-B329-784D718E49D2@apple.com> Message-ID: On Tue, Oct 27, 2009 at 10:03 PM, Evan Cheng wrote: > I believe lazy compilation should still be the > default behavior for JIT. If it's not thread safe, then clients who want JIT > safety should fix it. You say that as if it's an easy thing to do and can be done once and for all. You should probably read the bug (http://llvm.org/PR5184) to see why that's wrong. As to why lazy compilation should not be the default: it has confused users who tried running their JITs under helgrind and got reports inside one of the most confusing parts of the JIT. When the race actually bites users, it's going to be extremely hard to debug, since it happens when a call is first executed and depends on exactly how the call was aligned. And there are other races in the JIT unless you hold the JIT lock around all IR manipulation. I don't think it's a good idea to make the default behavior of LLVM crash randomly in hard-to-debug ways. Finally, I haven't heard of any cases besides lli where the current lazy JIT is actually the right choice for performance. Now, lazy JITting is safe in a single-threaded program. It might make sense to change the default depending on whether llvm_start_multithreaded() has been called, but that seemed more confusing than saying that you always have to enable it if you want it. From resistor at mac.com Wed Oct 28 01:18:43 2009 From: resistor at mac.com (Owen Anderson) Date: Wed, 28 Oct 2009 06:18:43 -0000 Subject: [llvm-commits] [llvm] r85378 - in /llvm/trunk: lib/Analysis/MemoryDependenceAnalysis.cpp test/Transforms/GVN/invariant-simple.ll Message-ID: <200910280618.n9S6Ih17003357@zion.cs.uiuc.edu> Author: resistor Date: Wed Oct 28 01:18:42 2009 New Revision: 85378 URL: http://llvm.org/viewvc/llvm-project?rev=85378&view=rev Log: Add trivial support for the invariance intrinsics to memdep. This logic is purely local for now. Added: llvm/trunk/test/Transforms/GVN/invariant-simple.ll Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=85378&r1=85377&r2=85378&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Wed Oct 28 01:18:42 2009 @@ -171,13 +171,42 @@ /// location depends. If isLoad is true, this routine ignore may-aliases with /// read-only operations. MemDepResult MemoryDependenceAnalysis:: -getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad, +getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad, BasicBlock::iterator ScanIt, BasicBlock *BB) { + Value* invariantTag = 0; + // Walk backwards through the basic block, looking for dependencies. while (ScanIt != BB->begin()) { Instruction *Inst = --ScanIt; + // If we're in an invariant region, no dependencies can be found before + // we pass an invariant-begin marker. + if (invariantTag == Inst) { + invariantTag = 0; + continue; + + // If we pass an invariant-end marker, then we've just entered an invariant + // region and can start ignoring dependencies. + } else if (IntrinsicInst* II = dyn_cast(Inst)) { + if (II->getIntrinsicID() == Intrinsic::invariant_end) { + uint64_t invariantSize = ~0ULL; + if (ConstantInt* CI = dyn_cast(II->getOperand(2))) + invariantSize = CI->getZExtValue(); + + AliasAnalysis::AliasResult R = + AA->alias(II->getOperand(3), invariantSize, MemPtr, MemSize); + if (R == AliasAnalysis::MustAlias) { + invariantTag = II->getOperand(1); + continue; + } + } + } + + // If we're querying on a load and we're in an invariant region, we're done + // at this point. Nothing a load depends on can live in an invariant region. + if (isLoad && invariantTag) continue; + // Debug intrinsics don't cause dependences. if (isa(Inst)) continue; @@ -201,6 +230,11 @@ return MemDepResult::getDef(Inst); } + // If we're querying on a store and we're in an invariant region, we're done + // at this point. The only things that stores depend on that could exist in + // an invariant region are loads, which we've already checked. + if (invariantTag) continue; + if (StoreInst *SI = dyn_cast(Inst)) { // If alias analysis can tell that this store is guaranteed to not modify // the query pointer, ignore it. Use getModRefInfo to handle cases where Added: llvm/trunk/test/Transforms/GVN/invariant-simple.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/invariant-simple.ll?rev=85378&view=auto ============================================================================== --- llvm/trunk/test/Transforms/GVN/invariant-simple.ll (added) +++ llvm/trunk/test/Transforms/GVN/invariant-simple.ll Wed Oct 28 01:18:42 2009 @@ -0,0 +1,21 @@ +; RUN: opt < %s -gvn -S | FileCheck %s + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin7" + +define i8 @test(i8* %P) nounwind { +; CHECK: @test +; CHECK-NOT: load +; CHECK: ret i8 +entry: + store i8 1, i8* %P + %0 = call {}* @llvm.invariant.start(i64 32, i8* %P) + %1 = tail call i32 @foo(i8* %P) + call void @llvm.invariant.end({}* %0, i64 32, i8* %P) + %2 = load i8* %P + ret i8 %2 +} + +declare i32 @foo(i8*) nounwind +declare {}* @llvm.invariant.start(i64 %S, i8* nocapture %P) readonly +declare void @llvm.invariant.end({}* %S, i64 %SS, i8* nocapture %P) \ No newline at end of file From evan.cheng at apple.com Wed Oct 28 01:30:35 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 28 Oct 2009 06:30:35 -0000 Subject: [llvm-commits] [llvm] r85379 - /llvm/trunk/lib/Target/X86/X86InstrSSE.td Message-ID: <200910280630.n9S6UZsa003745@zion.cs.uiuc.edu> Author: evancheng Date: Wed Oct 28 01:30:34 2009 New Revision: 85379 URL: http://llvm.org/viewvc/llvm-project?rev=85379&view=rev Log: X86 palignr intrinsics immediate field is in bits. ISel must transform it into bytes. Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=85379&r1=85378&r2=85379&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Wed Oct 28 01:30:34 2009 @@ -174,7 +174,8 @@ return N->isExactlyValue(+0.0); }]>; -def PSxLDQ_imm : SDNodeXForm> 3 return getI32Imm(N->getZExtValue() >> 3); }]>; @@ -1996,21 +1997,21 @@ let Predicates = [HasSSE2] in { def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2), - (v2i64 (PSLLDQri VR128:$src1, (PSxLDQ_imm imm:$src2)))>; + (v2i64 (PSLLDQri VR128:$src1, (BYTE_imm imm:$src2)))>; def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2), - (v2i64 (PSRLDQri VR128:$src1, (PSxLDQ_imm imm:$src2)))>; + (v2i64 (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2)))>; def : Pat<(int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2), (v2i64 (PSLLDQri VR128:$src1, imm:$src2))>; def : Pat<(int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2), (v2i64 (PSRLDQri VR128:$src1, imm:$src2))>; def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)), - (v2f64 (PSRLDQri VR128:$src1, (PSxLDQ_imm imm:$src2)))>; + (v2f64 (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2)))>; // Shift up / down and insert zero's. def : Pat<(v2i64 (X86vshl VR128:$src, (i8 imm:$amt))), - (v2i64 (PSLLDQri VR128:$src, (PSxLDQ_imm imm:$amt)))>; + (v2i64 (PSLLDQri VR128:$src, (BYTE_imm imm:$amt)))>; def : Pat<(v2i64 (X86vshr VR128:$src, (i8 imm:$amt))), - (v2i64 (PSRLDQri VR128:$src, (PSxLDQ_imm imm:$amt)))>; + (v2i64 (PSRLDQri VR128:$src, (BYTE_imm imm:$amt)))>; } // Logical @@ -2822,37 +2823,41 @@ def PALIGNR64rr : SS3AI<0x0F, MRMSrcReg, (outs VR64:$dst), (ins VR64:$src1, VR64:$src2, i16imm:$src3), "palignr\t{$src3, $src2, $dst|$dst, $src2, $src3}", - [(set VR64:$dst, - (int_x86_ssse3_palign_r - VR64:$src1, VR64:$src2, - imm:$src3))]>; + []>; def PALIGNR64rm : SS3AI<0x0F, MRMSrcMem, (outs VR64:$dst), (ins VR64:$src1, i64mem:$src2, i16imm:$src3), "palignr\t{$src3, $src2, $dst|$dst, $src2, $src3}", - [(set VR64:$dst, - (int_x86_ssse3_palign_r - VR64:$src1, - (bitconvert (memopv2i32 addr:$src2)), - imm:$src3))]>; + []>; def PALIGNR128rr : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32imm:$src3), "palignr\t{$src3, $src2, $dst|$dst, $src2, $src3}", - [(set VR128:$dst, - (int_x86_ssse3_palign_r_128 - VR128:$src1, VR128:$src2, - imm:$src3))]>, OpSize; + []>, OpSize; def PALIGNR128rm : SS3AI<0x0F, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2, i32imm:$src3), "palignr\t{$src3, $src2, $dst|$dst, $src2, $src3}", - [(set VR128:$dst, - (int_x86_ssse3_palign_r_128 - VR128:$src1, - (bitconvert (memopv4i32 addr:$src2)), - imm:$src3))]>, OpSize; + []>, OpSize; } // palignr patterns. +def : Pat<(int_x86_ssse3_palign_r VR64:$src1, VR64:$src2, (i16 imm:$src3)), + (PALIGNR64rr VR64:$src1, VR64:$src2, (BYTE_imm imm:$src3))>, + Requires<[HasSSSE3]>; +def : Pat<(int_x86_ssse3_palign_r VR64:$src1, + (memop64 addr:$src2), + (i16 imm:$src3)), + (PALIGNR64rm VR64:$src1, addr:$src2, (BYTE_imm imm:$src3))>, + Requires<[HasSSSE3]>; + +def : Pat<(int_x86_ssse3_palign_r_128 VR128:$src1, VR128:$src2, (i32 imm:$src3)), + (PALIGNR128rr VR128:$src1, VR128:$src2, (BYTE_imm imm:$src3))>, + Requires<[HasSSSE3]>; +def : Pat<(int_x86_ssse3_palign_r_128 VR128:$src1, + (memopv2i64 addr:$src2), + (i32 imm:$src3)), + (PALIGNR128rm VR128:$src1, addr:$src2, (BYTE_imm imm:$src3))>, + Requires<[HasSSSE3]>; + let AddedComplexity = 5 in { def : Pat<(v4i32 (palign:$src3 VR128:$src1, VR128:$src2)), (PALIGNR128rr VR128:$src2, VR128:$src1, From resistor at mac.com Wed Oct 28 01:30:53 2009 From: resistor at mac.com (Owen Anderson) Date: Wed, 28 Oct 2009 06:30:53 -0000 Subject: [llvm-commits] [llvm] r85380 - in /llvm/trunk: lib/Analysis/MemoryDependenceAnalysis.cpp test/Transforms/GVN/invariant-simple.ll Message-ID: <200910280630.n9S6UrCQ003807@zion.cs.uiuc.edu> Author: resistor Date: Wed Oct 28 01:30:52 2009 New Revision: 85380 URL: http://llvm.org/viewvc/llvm-project?rev=85380&view=rev Log: Be more careful about invariance reasoning on "store" queries. Stores still need to depend on Ref and ModRef calls within the invariant region. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/test/Transforms/GVN/invariant-simple.ll Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=85380&r1=85379&r2=85380&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Wed Oct 28 01:30:52 2009 @@ -230,12 +230,11 @@ return MemDepResult::getDef(Inst); } - // If we're querying on a store and we're in an invariant region, we're done - // at this point. The only things that stores depend on that could exist in - // an invariant region are loads, which we've already checked. - if (invariantTag) continue; - if (StoreInst *SI = dyn_cast(Inst)) { + // There can't be stores to the value we care about inside an + // invariant region. + if (invariantTag) continue; + // If alias analysis can tell that this store is guaranteed to not modify // the query pointer, ignore it. Use getModRefInfo to handle cases where // the query pointer points to constant memory etc. @@ -280,12 +279,16 @@ case AliasAnalysis::NoModRef: // If the call has no effect on the queried pointer, just ignore it. continue; + case AliasAnalysis::Mod: + // If we're in an invariant region, we can ignore calls that ONLY + // modify the pointer. + if (invariantTag) continue; + return MemDepResult::getClobber(Inst); case AliasAnalysis::Ref: // If the call is known to never store to the pointer, and if this is a // load query, we can safely ignore it (scan past it). if (isLoad) continue; - // FALL THROUGH. default: // Otherwise, there is a potential dependence. Return a clobber. return MemDepResult::getClobber(Inst); Modified: llvm/trunk/test/Transforms/GVN/invariant-simple.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/invariant-simple.ll?rev=85380&r1=85379&r2=85380&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GVN/invariant-simple.ll (original) +++ llvm/trunk/test/Transforms/GVN/invariant-simple.ll Wed Oct 28 01:30:52 2009 @@ -16,6 +16,21 @@ ret i8 %2 } +define i8 @test2(i8* %P) nounwind { +; CHECK: @test2 +; CHECK: store i8 1 +; CHECK: store i8 2 +; CHECK: ret i8 0 +entry: + store i8 1, i8* %P + %0 = call {}* @llvm.invariant.start(i64 32, i8* %P) + %1 = tail call i32 @bar(i8* %P) + call void @llvm.invariant.end({}* %0, i64 32, i8* %P) + store i8 2, i8* %P + ret i8 0 +} + declare i32 @foo(i8*) nounwind +declare i32 @bar(i8*) nounwind readonly declare {}* @llvm.invariant.start(i64 %S, i8* nocapture %P) readonly declare void @llvm.invariant.end({}* %S, i64 %SS, i8* nocapture %P) \ No newline at end of file From evan.cheng at apple.com Wed Oct 28 01:47:03 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 27 Oct 2009 23:47:03 -0700 Subject: [llvm-commits] [llvm] r85295 - in /llvm/trunk: docs/tutorial/LangImpl4.html docs/tutorial/OCamlLangImpl4.html include/llvm/ExecutionEngine/ExecutionEngine.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngi In-Reply-To: References: <9879CBCC-0704-4FC7-8061-94D382FA7587@apple.com> <4AE7CC5C.5040300@mxc.ca> <02C5660C-FC69-4B07-B329-784D718E49D2@apple.com> Message-ID: On Oct 27, 2009, at 11:07 PM, Jeffrey Yasskin wrote: > On Tue, Oct 27, 2009 at 10:03 PM, Evan Cheng > wrote: >> I believe lazy compilation should still be the >> default behavior for JIT. If it's not thread safe, then clients who >> want JIT >> safety should fix it. > > You say that as if it's an easy thing to do and can be done once and > for all. You should probably read the bug (http://llvm.org/PR5184) to > see why that's wrong. I am not saying it's easy. There are clients which do use lazy compilation and they don't care about this though. > > As to why lazy compilation should not be the default: it has confused > users who tried running their JITs under helgrind and got reports > inside one of the most confusing parts of the JIT. When the race > actually bites users, it's going to be extremely hard to debug, since > it happens when a call is first executed and depends on exactly how > the call was aligned. And there are other races in the JIT unless you > hold the JIT lock around all IR manipulation. I don't think it's a > good idea to make the default behavior of LLVM crash randomly in > hard-to-debug ways. Finally, I haven't heard of any cases besides lli > where the current lazy JIT is actually the right choice for > performance. To me that's a documentation issue. We're providing lli as the example JIT. It defaults to lazy compilation. That will not change since we're using it as a JIT test harness. I think it's actually more confusing for lli to default to different behavior. Your usage model is different from others. What you feel is the right default behavior is not the same for others. Like I said, there are clients who have been using the JIT who do not care about thread safety. They are using it in a single-threaded program and want the benefit of lazy compilation. LLVM JIT is not a light weighted JIT. It does everything a static compiler code generator would do. Non-lazy compilation may very well be unacceptable to a lot of users. > > Now, lazy JITting is safe in a single-threaded program. It might make > sense to change the default depending on whether > llvm_start_multithreaded() has been called, but that seemed more > confusing than saying that you always have to enable it if you want > it. I don't think that's the right solution. It makes the "default" even more confusing. I'd prefer it just abort with an error stating the non- lazy + multi-threaded configuration being unsupported. Evan From evan.cheng at apple.com Wed Oct 28 01:55:03 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 28 Oct 2009 06:55:03 -0000 Subject: [llvm-commits] [llvm] r85381 - /llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Message-ID: <200910280655.n9S6t316004670@zion.cs.uiuc.edu> Author: evancheng Date: Wed Oct 28 01:55:03 2009 New Revision: 85381 URL: http://llvm.org/viewvc/llvm-project?rev=85381&view=rev Log: Give ARMISD::EH_SJLJ_LONGJMP and EH_SJLJ_SETJMP names. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=85381&r1=85380&r2=85381&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Wed Oct 28 01:55:03 2009 @@ -495,6 +495,9 @@ case ARMISD::FMRRD: return "ARMISD::FMRRD"; case ARMISD::FMDRR: return "ARMISD::FMDRR"; + case ARMISD::EH_SJLJ_SETJMP: return "ARMISD::EH_SJLJ_SETJMP"; + case ARMISD::EH_SJLJ_LONGJMP:return "ARMISD::EH_SJLJ_LONGJMP"; + case ARMISD::THREAD_POINTER:return "ARMISD::THREAD_POINTER"; case ARMISD::DYN_ALLOC: return "ARMISD::DYN_ALLOC"; From nicholas at mxc.ca Wed Oct 28 02:03:22 2009 From: nicholas at mxc.ca (Nick Lewycky) Date: Wed, 28 Oct 2009 07:03:22 -0000 Subject: [llvm-commits] [llvm] r85382 - in /llvm/trunk: include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/ABCD.cpp Message-ID: <200910280703.n9S73NJi005159@zion.cs.uiuc.edu> Author: nicholas Date: Wed Oct 28 02:03:15 2009 New Revision: 85382 URL: http://llvm.org/viewvc/llvm-project?rev=85382&view=rev Log: Add ABCD, a generalized implementation of the Elimination of Array Bounds Checks on Demand algorithm which looks at arbitrary branches instead of loop iterations. This is GSoC work by Andre Tavares with only editorial changes applied! Added: llvm/trunk/lib/Transforms/Scalar/ABCD.cpp Modified: llvm/trunk/include/llvm/LinkAllPasses.h llvm/trunk/include/llvm/Transforms/Scalar.h Modified: llvm/trunk/include/llvm/LinkAllPasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=85382&r1=85381&r2=85382&view=diff ============================================================================== --- llvm/trunk/include/llvm/LinkAllPasses.h (original) +++ llvm/trunk/include/llvm/LinkAllPasses.h Wed Oct 28 02:03:15 2009 @@ -142,6 +142,7 @@ (void) llvm::createSSIEverythingPass(); (void) llvm::createGEPSplitterPass(); (void) llvm::createSCCVNPass(); + (void) llvm::createABCDPass(); (void)new llvm::IntervalPartition(); (void)new llvm::FindUsedTypes(); Modified: llvm/trunk/include/llvm/Transforms/Scalar.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=85382&r1=85381&r2=85382&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Scalar.h (original) +++ llvm/trunk/include/llvm/Transforms/Scalar.h Wed Oct 28 02:03:15 2009 @@ -344,6 +344,12 @@ // FunctionPass *createSCCVNPass(); +//===----------------------------------------------------------------------===// +// +// ABCD - Elimination of Array Bounds Checks on Demand +// +FunctionPass *createABCDPass(); + } // End llvm namespace #endif Added: llvm/trunk/lib/Transforms/Scalar/ABCD.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ABCD.cpp?rev=85382&view=auto ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ABCD.cpp (added) +++ llvm/trunk/lib/Transforms/Scalar/ABCD.cpp Wed Oct 28 02:03:15 2009 @@ -0,0 +1,1108 @@ +//===------- ABCD.cpp - Removes redundant conditional branches ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass removes redundant branch instructions. This algorithm was +// described by Rastislav Bodik, Rajiv Gupta and Vivek Sarkar in their paper +// "ABCD: Eliminating Array Bounds Checks on Demand (2000)". The original +// Algorithm was created to remove array bound checks for strongly typed +// languages. This implementation expands the idea and removes any conditional +// branches that can be proved redundant, not only those used in array bound +// checks. With the SSI representation, each variable has a +// constraint. By analyzing these constraints we can proof that a branch is +// redundant. When a branch is proved redundant it means that +// one direction will always be taken; thus, we can change this branch into an +// unconditional jump. +// It is advisable to run SimplifyCFG and Aggressive Dead Code Elimination +// after ABCD to clean up the code. +// This implementation was created based on the implementation of the ABCD +// algorithm implemented for the compiler Jitrino. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "abcd" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Constants.h" +#include "llvm/Function.h" +#include "llvm/Instructions.h" +#include "llvm/Pass.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Debug.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/SSI.h" + +using namespace llvm; + +STATISTIC(NumBranchTested, "Number of conditional branches analyzed"); +STATISTIC(NumBranchRemoved, "Number of conditional branches removed"); + +//namespace { + +class ABCD : public FunctionPass { + public: + static char ID; // Pass identification, replacement for typeid. + ABCD() : FunctionPass(&ID) {} + + void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + } + + bool runOnFunction(Function &F); + + private: + bool modified; + + enum ProveResult { + False = 0, + Reduced = 1, + True = 2 + }; + + typedef ProveResult (*meet_function)(ProveResult, ProveResult); + static ProveResult max(ProveResult res1, ProveResult res2) { + return (ProveResult) std::max(res1, res2); + } + static ProveResult min(ProveResult res1, ProveResult res2) { + return (ProveResult) std::min(res1, res2); + } + + class Bound { + public: + Bound(APInt v, bool upper) : value(v), upper_bound(upper) {} + Bound(const Bound *b, int cnst) + : value(b->value - cnst), upper_bound(b->upper_bound) {} + Bound(const Bound *b, const APInt &cnst) + : value(b->value - cnst), upper_bound(b->upper_bound) {} + + /// Test if Bound is an upper bound + bool isUpperBound() const { return upper_bound; } + + /// Get the bitwidth of this bound + int32_t getBitWidth() const { return value.getBitWidth(); } + + /// Creates a Bound incrementing the one received + static Bound *createIncrement(const Bound *b) { + return new Bound(b->isUpperBound() ? b->value+1 : b->value-1, + b->upper_bound); + } + + /// Creates a Bound decrementing the one received + static Bound *createDecrement(const Bound *b) { + return new Bound(b->isUpperBound() ? b->value-1 : b->value+1, + b->upper_bound); + } + + /// Test if two bounds are equal + static bool eq(const Bound *a, const Bound *b) { + if (!a || !b) return false; + + assert(a->isUpperBound() == b->isUpperBound()); + return a->value == b->value; + } + + /// Test if val is less than or equal to Bound b + static bool leq(APInt val, const Bound *b) { + if (!b) return false; + return b->isUpperBound() ? val.sle(b->value) : val.sge(b->value); + } + + /// Test if Bound a is less then or equal to Bound + static bool leq(const Bound *a, const Bound *b) { + if (!a || !b) return false; + + assert(a->isUpperBound() == b->isUpperBound()); + return a->isUpperBound() ? a->value.sle(b->value) : + a->value.sge(b->value); + } + + /// Test if Bound a is less then Bound b + static bool lt(const Bound *a, const Bound *b) { + if (!a || !b) return false; + + assert(a->isUpperBound() == b->isUpperBound()); + return a->isUpperBound() ? a->value.slt(b->value) : + a->value.sgt(b->value); + } + + /// Test if Bound b is greater then or equal val + static bool geq(const Bound *b, APInt val) { + return leq(val, b); + } + + /// Test if Bound a is greater then or equal Bound b + static bool geq(const Bound *a, const Bound *b) { + return leq(b, a); + } + + private: + APInt value; + bool upper_bound; + }; + + /// This class is used to store results some parts of the graph, + /// so information does not need to be recalculated. The maximum false, + /// minimum true and minimum reduced results are stored + class MemoizedResultChart { + public: + MemoizedResultChart() : max_false(NULL), min_true(NULL), + min_reduced(NULL) {} + + /// Returns the max false + Bound *getFalse() const { return max_false; } + + /// Returns the min true + Bound *getTrue() const { return min_true; } + + /// Returns the min reduced + Bound *getReduced() const { return min_reduced; } + + /// Return the stored result for this bound + ProveResult getResult(const Bound *bound) const; + + /// Stores a false found + void addFalse(Bound *bound); + + /// Stores a true found + void addTrue(Bound *bound); + + /// Stores a Reduced found + void addReduced(Bound *bound); + + /// Clears redundant reduced + /// If a min_true is smaller than a min_reduced then the min_reduced + /// is unnecessary and then removed. It also works for min_reduced + /// begin smaller than max_false. + void clearRedundantReduced(); + + void clear() { + delete max_false; + delete min_true; + delete min_reduced; + } + + private: + Bound *max_false, *min_true, *min_reduced; + }; + + /// This class stores the result found for a node of the graph, + /// so these results do not need to be recalculate and only searched for. + class MemoizedResult { + public: + /// Test if there is true result stored from b to a + /// that is less then the bound + bool hasTrue(Value *b, const Bound *bound) const { + Bound *trueBound = map.lookup(b).getTrue(); + return trueBound && Bound::leq(trueBound, bound); + } + + /// Test if there is false result stored from b to a + /// that is less then the bound + bool hasFalse(Value *b, const Bound *bound) const { + Bound *falseBound = map.lookup(b).getFalse(); + return falseBound && Bound::leq(falseBound, bound); + } + + /// Test if there is reduced result stored from b to a + /// that is less then the bound + bool hasReduced(Value *b, const Bound *bound) const { + Bound *reducedBound = map.lookup(b).getReduced(); + return reducedBound && Bound::leq(reducedBound, bound); + } + + /// Returns the stored bound for b + ProveResult getBoundResult(Value *b, Bound *bound) { + return map[b].getResult(bound); + } + + /// Clears the map + void clear() { + DenseMapIterator begin = map.begin(); + DenseMapIterator end = map.end(); + for (; begin != end; ++begin) { + begin->second.clear(); + } + map.clear(); + } + + /// Stores the bound found + void updateBound(Value *b, Bound *bound, const ProveResult res); + + private: + // Maps a nod in the graph with its results found. + DenseMap map; + }; + + /// This class represents an edge in the inequality graph used by the + /// ABCD algorithm. An edge connects node v to node u with a value c if + /// we could infer a constraint v <= u + c in the source program. + class Edge { + public: + Edge(Value *V, APInt val, bool upper) : vertex(V), value(val), + upper_bound(upper) + {} + + Value *getVertex() const { return vertex; } + const APInt &getValue() const { return value; } + bool isUpperBound() const { return upper_bound; } + + private: + Value *vertex; + APInt value; + bool upper_bound; + }; + + /// Weighted and Directed graph to represent constraints. + /// There is one type of constraint, a <= b + X, which will generate an + /// edge from b to a with weight X. + class InequalityGraph { + public: + + /// Adds an edge from V_from to V_to with weight value + void addEdge(Value *V_from, Value *V_to, APInt value, bool upper); + + /// Test if there is a node V + bool hasNode(Value *V) const { return graph.count(V); } + + /// Test if there is any edge from V in the upper direction + bool hasEdge(Value *V, bool upper) const; + + /// Returns all edges pointed by vertex V + SmallPtrSet getEdges(Value *V) const { + return graph.lookup(V); + } + + /// Prints the graph in dot format. + /// Blue edges represent upper bound and Red lower bound. + void printGraph(raw_ostream &OS, Function &F) const { + printHeader(OS, F); + printBody(OS); + printFooter(OS); + } + + /// Clear the graph + void clear() { + graph.clear(); + } + + private: + DenseMap > graph; + + /// Adds a Node to the graph. + DenseMap >::iterator addNode(Value *V) { + SmallPtrSet p; + return graph.insert(std::make_pair(V, p)).first; + } + + /// Prints the header of the dot file + void printHeader(raw_ostream &OS, Function &F) const; + + /// Prints the footer of the dot file + void printFooter(raw_ostream &OS) const { + OS << "}\n"; + } + + /// Prints the body of the dot file + void printBody(raw_ostream &OS) const; + + /// Prints vertex source to the dot file + void printVertex(raw_ostream &OS, Value *source) const; + + /// Prints the edge to the dot file + void printEdge(raw_ostream &OS, Value *source, Edge *edge) const; + + void printName(raw_ostream &OS, Value *info) const; + }; + + /// Iterates through all BasicBlocks, if the Terminator Instruction + /// uses an Comparator Instruction, all operands of this comparator + /// are sent to be transformed to SSI. Only Instruction operands are + /// transformed. + void createSSI(Function &F); + + /// Creates the graphs for this function. + /// It will look for all comparators used in branches, and create them. + /// These comparators will create constraints for any instruction as an + /// operand. + void executeABCD(Function &F); + + /// Seeks redundancies in the comparator instruction CI. + /// If the ABCD algorithm can prove that the comparator CI always + /// takes one way, then the Terminator Instruction TI is substituted from + /// a conditional branch to a unconditional one. + /// This code basically receives a comparator, and verifies which kind of + /// instruction it is. Depending on the kind of instruction, we use different + /// strategies to prove its redundancy. + void seekRedundancy(ICmpInst *ICI, TerminatorInst *TI); + + /// Substitutes Terminator Instruction TI, that is a conditional branch, + /// with one unconditional branch. Succ_edge determines if the new + /// unconditional edge will be the first or second edge of the former TI + /// instruction. + void removeRedundancy(TerminatorInst *TI, bool Succ_edge); + + /// When an conditional branch is removed, the BasicBlock that is no longer + /// reachable will have problems in phi functions. This method fixes these + /// phis removing the former BasicBlock from the list of incoming BasicBlocks + /// of all phis. In case the phi remains with no predecessor it will be + /// marked to be removed later. + void fixPhi(BasicBlock *BB, BasicBlock *Succ); + + /// Removes phis that have no predecessor + void removePhis(); + + /// Creates constraints for Instructions. + /// If the constraint for this instruction has already been created + /// nothing is done. + void createConstraintInstruction(Instruction *I); + + /// Creates constraints for Binary Operators. + /// It will create constraints only for addition and subtraction, + /// the other binary operations are not treated by ABCD. + /// For additions in the form a = b + X and a = X + b, where X is a constant, + /// the constraint a <= b + X can be obtained. For this constraint, an edge + /// a->b with weight X is added to the lower bound graph, and an edge + /// b->a with weight -X is added to the upper bound graph. + /// Only subtractions in the format a = b - X is used by ABCD. + /// Edges are created using the same semantic as addition. + void createConstraintBinaryOperator(BinaryOperator *BO); + + /// Creates constraints for Comparator Instructions. + /// Only comparators that have any of the following operators + /// are used to create constraints: >=, >, <=, <. And only if + /// at least one operand is an Instruction. In a Comparator Instruction + /// a op b, there will be 4 sigma functions a_t, a_f, b_t and b_f. Where + /// t and f represent sigma for operands in true and false branches. The + /// following constraints can be obtained. a_t <= a, a_f <= a, b_t <= b and + /// b_f <= b. There are two more constraints that depend on the operator. + /// For the operator <= : a_t <= b_t and b_f <= a_f-1 + /// For the operator < : a_t <= b_t-1 and b_f <= a_f + /// For the operator >= : b_t <= a_t and a_f <= b_f-1 + /// For the operator > : b_t <= a_t-1 and a_f <= b_f + void createConstraintCmpInst(ICmpInst *ICI, TerminatorInst *TI); + + /// Creates constraints for PHI nodes. + /// In a PHI node a = phi(b,c) we can create the constraint + /// a<= max(b,c). With this constraint there will be the edges, + /// b->a and c->a with weight 0 in the lower bound graph, and the edges + /// a->b and a->c with weight 0 in the upper bound graph. + void createConstraintPHINode(PHINode *PN); + + /// Given a binary operator, we are only interest in the case + /// that one operand is an Instruction and the other is a ConstantInt. In + /// this case the method returns true, otherwise false. It also obtains the + /// Instruction and ConstantInt from the BinaryOperator and returns it. + bool createBinaryOperatorInfo(BinaryOperator *BO, Instruction **I1, + Instruction **I2, ConstantInt **C1, + ConstantInt **C2); + + /// This method creates a constraint between a Sigma and an Instruction. + /// These constraints are created as soon as we find a comparator that uses a + /// SSI variable. + void createConstraintSigInst(Instruction *I_op, BasicBlock *BB_succ_t, + BasicBlock *BB_succ_f, PHINode **SIG_op_t, + PHINode **SIG_op_f); + + /// If PN_op1 and PN_o2 are different from NULL, create a constraint + /// PN_op2 -> PN_op1 with value. In case any of them is NULL, replace + /// with the respective V_op#, if V_op# is a ConstantInt. + void createConstraintSigSig(PHINode *SIG_op1, PHINode *SIG_op2, APInt value); + + /// Returns the sigma representing the Instruction I in BasicBlock BB. + /// Returns NULL in case there is no sigma for this Instruction in this + /// Basic Block. This methods assume that sigmas are the first instructions + /// in a block, and that there can be only two sigmas in a block. So it will + /// only look on the first two instructions of BasicBlock BB. + PHINode *findSigma(BasicBlock *BB, Instruction *I); + + /// Original ABCD algorithm to prove redundant checks. + /// This implementation works on any kind of inequality branch. + bool demandProve(Value *a, Value *b, int c, bool upper_bound); + + /// Prove that distance between b and a is <= bound + ProveResult prove(Value *a, Value *b, Bound *bound, unsigned level); + + /// Updates the distance value for a and b + void updateMemDistance(Value *a, Value *b, Bound *bound, unsigned level, + meet_function meet); + + InequalityGraph inequality_graph; + MemoizedResult mem_result; + DenseMap active; + SmallPtrSet created; + SmallVector phis_to_remove; +}; + +//} // end anonymous namespace. + +char ABCD::ID = 0; +static RegisterPass X("abcd", "ABCD: Eliminating Array Bounds Checks on Demand"); + + +bool ABCD::runOnFunction(Function &F) { + modified = false; + createSSI(F); + executeABCD(F); + DEBUG(inequality_graph.printGraph(errs(), F)); + removePhis(); + + inequality_graph.clear(); + mem_result.clear(); + active.clear(); + created.clear(); + phis_to_remove.clear(); + return modified; +} + +/// Iterates through all BasicBlocks, if the Terminator Instruction +/// uses an Comparator Instruction, all operands of this comparator +/// are sent to be transformed to SSI. Only Instruction operands are +/// transformed. +void ABCD::createSSI(Function &F) { + SSI *ssi = &getAnalysis(); + + SmallVector Insts; + + for (Function::iterator begin = F.begin(), end = F.end(); + begin != end; ++begin) { + BasicBlock *BB = begin; + TerminatorInst *TI = BB->getTerminator(); + if (TI->getNumOperands() == 0) + continue; + + if (ICmpInst *ICI = dyn_cast(TI->getOperand(0))) { + if (Instruction *I = dyn_cast(ICI->getOperand(0))) { + modified = true; // XXX: but yet createSSI might do nothing + Insts.push_back(I); + } + if (Instruction *I = dyn_cast(ICI->getOperand(1))) { + modified = true; + Insts.push_back(I); + } + } + } + ssi->createSSI(Insts); +} + +/// Creates the graphs for this function. +/// It will look for all comparators used in branches, and create them. +/// These comparators will create constraints for any instruction as an +/// operand. +void ABCD::executeABCD(Function &F) { + for (Function::iterator begin = F.begin(), end = F.end(); + begin != end; ++begin) { + BasicBlock *BB = begin; + TerminatorInst *TI = BB->getTerminator(); + if (TI->getNumOperands() == 0) + continue; + + ICmpInst *ICI = dyn_cast(TI->getOperand(0)); + if (!ICI || !isa(ICI->getOperand(0)->getType())) + continue; + + createConstraintCmpInst(ICI, TI); + seekRedundancy(ICI, TI); + } +} + +/// Seeks redundancies in the comparator instruction CI. +/// If the ABCD algorithm can prove that the comparator CI always +/// takes one way, then the Terminator Instruction TI is substituted from +/// a conditional branch to a unconditional one. +/// This code basically receives a comparator, and verifies which kind of +/// instruction it is. Depending on the kind of instruction, we use different +/// strategies to prove its redundancy. +void ABCD::seekRedundancy(ICmpInst *ICI, TerminatorInst *TI) { + CmpInst::Predicate Pred = ICI->getPredicate(); + + Value *source, *dest; + int distance1, distance2; + bool upper; + + switch(Pred) { + case CmpInst::ICMP_SGT: // signed greater than + upper = false; + distance1 = 1; + distance2 = 0; + break; + + case CmpInst::ICMP_SGE: // signed greater or equal + upper = false; + distance1 = 0; + distance2 = -1; + break; + + case CmpInst::ICMP_SLT: // signed less than + upper = true; + distance1 = -1; + distance2 = 0; + break; + + case CmpInst::ICMP_SLE: // signed less or equal + upper = true; + distance1 = 0; + distance2 = 1; + break; + + default: + return; + } + + ++NumBranchTested; + source = ICI->getOperand(0); + dest = ICI->getOperand(1); + if (demandProve(dest, source, distance1, upper)) { + removeRedundancy(TI, true); + } else if (demandProve(dest, source, distance2, !upper)) { + removeRedundancy(TI, false); + } +} + +/// Substitutes Terminator Instruction TI, that is a conditional branch, +/// with one unconditional branch. Succ_edge determines if the new +/// unconditional edge will be the first or second edge of the former TI +/// instruction. +void ABCD::removeRedundancy(TerminatorInst *TI, bool Succ_edge) { + BasicBlock *Succ; + if (Succ_edge) { + Succ = TI->getSuccessor(0); + fixPhi(TI->getParent(), TI->getSuccessor(1)); + } else { + Succ = TI->getSuccessor(1); + fixPhi(TI->getParent(), TI->getSuccessor(0)); + } + + BranchInst::Create(Succ, TI); + TI->eraseFromParent(); // XXX: invoke + ++NumBranchRemoved; + modified = true; +} + +/// When an conditional branch is removed, the BasicBlock that is no longer +/// reachable will have problems in phi functions. This method fixes these +/// phis removing the former BasicBlock from the list of incoming BasicBlocks +/// of all phis. In case the phi remains with no predecessor it will be +/// marked to be removed later. +void ABCD::fixPhi(BasicBlock *BB, BasicBlock *Succ) { + BasicBlock::iterator begin = Succ->begin(); + while (PHINode *PN = dyn_cast(begin++)) { + PN->removeIncomingValue(BB, false); + if (PN->getNumIncomingValues() == 0) + phis_to_remove.push_back(PN); + } +} + +/// Removes phis that have no predecessor +void ABCD::removePhis() { + for (unsigned i = 0, end = phis_to_remove.size(); i < end; ++i) { + PHINode *PN = phis_to_remove[i]; + PN->replaceAllUsesWith(UndefValue::get(PN->getType())); + PN->eraseFromParent(); + } +} + +/// Creates constraints for Instructions. +/// If the constraint for this instruction has already been created +/// nothing is done. +void ABCD::createConstraintInstruction(Instruction *I) { + // Test if this instruction has not been created before + if (created.insert(I)) { + if (BinaryOperator *BO = dyn_cast(I)) { + createConstraintBinaryOperator(BO); + } else if (PHINode *PN = dyn_cast(I)) { + createConstraintPHINode(PN); + } + } +} + +/// Creates constraints for Binary Operators. +/// It will create constraints only for addition and subtraction, +/// the other binary operations are not treated by ABCD. +/// For additions in the form a = b + X and a = X + b, where X is a constant, +/// the constraint a <= b + X can be obtained. For this constraint, an edge +/// a->b with weight X is added to the lower bound graph, and an edge +/// b->a with weight -X is added to the upper bound graph. +/// Only subtractions in the format a = b - X is used by ABCD. +/// Edges are created using the same semantic as addition. +void ABCD::createConstraintBinaryOperator(BinaryOperator *BO) { + Instruction *I1 = NULL, *I2 = NULL; + ConstantInt *CI1 = NULL, *CI2 = NULL; + + // Test if an operand is an Instruction and the other is a Constant + if (!createBinaryOperatorInfo(BO, &I1, &I2, &CI1, &CI2)) + return; + + Instruction *I = 0; + APInt value; + + switch (BO->getOpcode()) { + case Instruction::Add: + if (I1) { + I = I1; + value = CI2->getValue(); + } else if (I2) { + I = I2; + value = CI1->getValue(); + } + break; + + case Instruction::Sub: + // Instructions like a = X-b, where X is a constant are not represented + // in the graph. + if (!I1) + return; + + I = I1; + value = -CI2->getValue(); + break; + + default: + return; + } + + APInt MinusOne = APInt::getAllOnesValue(value.getBitWidth()); + inequality_graph.addEdge(I, BO, value, true); + inequality_graph.addEdge(BO, I, value * MinusOne, false); + createConstraintInstruction(I); +} + +/// Given a binary operator, we are only interest in the case +/// that one operand is an Instruction and the other is a ConstantInt. In +/// this case the method returns true, otherwise false. It also obtains the +/// Instruction and ConstantInt from the BinaryOperator and returns it. +bool ABCD::createBinaryOperatorInfo(BinaryOperator *BO, Instruction **I1, + Instruction **I2, ConstantInt **C1, + ConstantInt **C2) { + Value *op1 = BO->getOperand(0); + Value *op2 = BO->getOperand(1); + + if ((*I1 = dyn_cast(op1))) { + if ((*C2 = dyn_cast(op2))) + return true; // First is Instruction and second ConstantInt + + return false; // Both are Instruction + } else { + if ((*C1 = dyn_cast(op1)) && + (*I2 = dyn_cast(op2))) + return true; // First is ConstantInt and second Instruction + + return false; // Both are not Instruction + } +} + +/// Creates constraints for Comparator Instructions. +/// Only comparators that have any of the following operators +/// are used to create constraints: >=, >, <=, <. And only if +/// at least one operand is an Instruction. In a Comparator Instruction +/// a op b, there will be 4 sigma functions a_t, a_f, b_t and b_f. Where +/// t and f represent sigma for operands in true and false branches. The +/// following constraints can be obtained. a_t <= a, a_f <= a, b_t <= b and +/// b_f <= b. There are two more constraints that depend on the operator. +/// For the operator <= : a_t <= b_t and b_f <= a_f-1 +/// For the operator < : a_t <= b_t-1 and b_f <= a_f +/// For the operator >= : b_t <= a_t and a_f <= b_f-1 +/// For the operator > : b_t <= a_t-1 and a_f <= b_f +void ABCD::createConstraintCmpInst(ICmpInst *ICI, TerminatorInst *TI) { + Value *V_op1 = ICI->getOperand(0); + Value *V_op2 = ICI->getOperand(1); + + if (!isa(V_op1->getType())) + return; + + Instruction *I_op1 = dyn_cast(V_op1); + Instruction *I_op2 = dyn_cast(V_op2); + + // Test if at least one operand is an Instruction + if (!I_op1 && !I_op2) + return; + + BasicBlock *BB_succ_t = TI->getSuccessor(0); + BasicBlock *BB_succ_f = TI->getSuccessor(1); + + PHINode *SIG_op1_t = NULL, *SIG_op1_f = NULL, + *SIG_op2_t = NULL, *SIG_op2_f = NULL; + + createConstraintSigInst(I_op1, BB_succ_t, BB_succ_f, + &SIG_op1_t, &SIG_op1_f); + createConstraintSigInst(I_op2, BB_succ_t, BB_succ_f, + &SIG_op2_t, &SIG_op2_f); + + int32_t width = cast(V_op1->getType())->getBitWidth(); + APInt MinusOne = APInt::getAllOnesValue(width); + APInt Zero = APInt::getNullValue(width); + + CmpInst::Predicate Pred = ICI->getPredicate(); + switch (Pred) { + case CmpInst::ICMP_SGT: // signed greater than + createConstraintSigSig(SIG_op2_t, SIG_op1_t, MinusOne); + createConstraintSigSig(SIG_op1_f, SIG_op2_f, Zero); + break; + + case CmpInst::ICMP_SGE: // signed greater or equal + createConstraintSigSig(SIG_op2_t, SIG_op1_t, Zero); + createConstraintSigSig(SIG_op1_f, SIG_op2_f, MinusOne); + break; + + case CmpInst::ICMP_SLT: // signed less than + createConstraintSigSig(SIG_op1_t, SIG_op2_t, MinusOne); + createConstraintSigSig(SIG_op2_f, SIG_op1_f, Zero); + break; + + case CmpInst::ICMP_SLE: // signed less or equal + createConstraintSigSig(SIG_op1_t, SIG_op2_t, Zero); + createConstraintSigSig(SIG_op2_f, SIG_op1_f, MinusOne); + break; + + default: + break; + } + + if (I_op1) + createConstraintInstruction(I_op1); + if (I_op2) + createConstraintInstruction(I_op2); +} + +/// Creates constraints for PHI nodes. +/// In a PHI node a = phi(b,c) we can create the constraint +/// a<= max(b,c). With this constraint there will be the edges, +/// b->a and c->a with weight 0 in the lower bound graph, and the edges +/// a->b and a->c with weight 0 in the upper bound graph. +void ABCD::createConstraintPHINode(PHINode *PN) { + int32_t width = cast(PN->getType())->getBitWidth(); + for (unsigned i = 0, end = PN->getNumIncomingValues(); i < end; ++i) { + Value *V = PN->getIncomingValue(i); + if (Instruction *I = dyn_cast(V)) { + createConstraintInstruction(I); + } + inequality_graph.addEdge(V, PN, APInt(width, 0), true); + inequality_graph.addEdge(V, PN, APInt(width, 0), false); + } +} + +/// This method creates a constraint between a Sigma and an Instruction. +/// These constraints are created as soon as we find a comparator that uses a +/// SSI variable. +void ABCD::createConstraintSigInst(Instruction *I_op, BasicBlock *BB_succ_t, + BasicBlock *BB_succ_f, PHINode **SIG_op_t, + PHINode **SIG_op_f) { + *SIG_op_t = findSigma(BB_succ_t, I_op); + *SIG_op_f = findSigma(BB_succ_f, I_op); + + if (*SIG_op_t) { + int32_t width = cast((*SIG_op_t)->getType())->getBitWidth(); + inequality_graph.addEdge(I_op, *SIG_op_t, APInt(width, 0), true); + inequality_graph.addEdge(*SIG_op_t, I_op, APInt(width, 0), false); + created.insert(*SIG_op_t); + } + if (*SIG_op_f) { + int32_t width = cast((*SIG_op_f)->getType())->getBitWidth(); + inequality_graph.addEdge(I_op, *SIG_op_f, APInt(width, 0), true); + inequality_graph.addEdge(*SIG_op_f, I_op, APInt(width, 0), false); + created.insert(*SIG_op_f); + } +} + +/// If PN_op1 and PN_o2 are different from NULL, create a constraint +/// PN_op2 -> PN_op1 with value. In case any of them is NULL, replace +/// with the respective V_op#, if V_op# is a ConstantInt. +void ABCD::createConstraintSigSig(PHINode *SIG_op1, PHINode *SIG_op2, + APInt value) { + if (SIG_op1 && SIG_op2) { + APInt MinusOne = APInt::getAllOnesValue(value.getBitWidth()); + inequality_graph.addEdge(SIG_op2, SIG_op1, value, true); + inequality_graph.addEdge(SIG_op1, SIG_op2, value * MinusOne, false); + } +} + +/// Returns the sigma representing the Instruction I in BasicBlock BB. +/// Returns NULL in case there is no sigma for this Instruction in this +/// Basic Block. This methods assume that sigmas are the first instructions +/// in a block, and that there can be only two sigmas in a block. So it will +/// only look on the first two instructions of BasicBlock BB. +PHINode *ABCD::findSigma(BasicBlock *BB, Instruction *I) { + // BB has more than one predecessor, BB cannot have sigmas. + if (I == NULL || BB->getSinglePredecessor() == NULL) + return NULL; + + BasicBlock::iterator begin = BB->begin(); + BasicBlock::iterator end = BB->end(); + + for (unsigned i = 0; i < 2 && begin != end; ++i, ++begin) { + Instruction *I_succ = begin; + if (PHINode *PN = dyn_cast(I_succ)) + if (PN->getIncomingValue(0) == I) + return PN; + } + + return NULL; +} + +/// Original ABCD algorithm to prove redundant checks. +/// This implementation works on any kind of inequality branch. +bool ABCD::demandProve(Value *a, Value *b, int c, bool upper_bound) { + int32_t width = cast(a->getType())->getBitWidth(); + Bound *bound = new Bound(APInt(width, c), upper_bound); + + mem_result.clear(); + active.clear(); + + ProveResult res = prove(a, b, bound, 0); + return res != False; +} + +/// Prove that distance between b and a is <= bound +ABCD::ProveResult ABCD::prove(Value *a, Value *b, Bound *bound, + unsigned level) { + // if (C[b-a<=e] == True for some e <= bound + // Same or stronger difference was already proven + if (mem_result.hasTrue(b, bound)) + return True; + + // if (C[b-a<=e] == False for some e >= bound + // Same or weaker difference was already disproved + if (mem_result.hasFalse(b, bound)) + return False; + + // if (C[b-a<=e] == Reduced for some e <= bound + // b is on a cycle that was reduced for same or stronger difference + if (mem_result.hasReduced(b, bound)) + return Reduced; + + // traversal reached the source vertex + if (a == b && Bound::geq(bound, APInt(bound->getBitWidth(), 0, true))) + return True; + + // if b has no predecessor then fail + if (!inequality_graph.hasEdge(b, bound->isUpperBound())) + return False; + + // a cycle was encountered + if (active.count(b)) { + if (Bound::leq(active.lookup(b), bound)) + return Reduced; // a "harmless" cycle + + return False; // an amplifying cycle + } + + active[b] = bound; + PHINode *PN = dyn_cast(b); + + // Test if a Value is a Phi. If it is a PHINode with more than 1 incoming + // value, then it is a phi, if it has 1 incoming value it is a sigma. + if (PN && PN->getNumIncomingValues() > 1) + updateMemDistance(a, b, bound, level, min); + else + updateMemDistance(a, b, bound, level, max); + + active.erase(b); + + ABCD::ProveResult res = mem_result.getBoundResult(b, bound); + return res; +} + +/// Updates the distance value for a and b +void ABCD::updateMemDistance(Value *a, Value *b, Bound *bound, unsigned level, + meet_function meet) { + ABCD::ProveResult res = (meet == max) ? False : True; + + SmallPtrSet Edges = inequality_graph.getEdges(b); + SmallPtrSet::iterator begin = Edges.begin(), end = Edges.end(); + + for (; begin != end ; ++begin) { + if (((res >= Reduced) && (meet == max)) || + ((res == False) && (meet == min))) { + break; + } + Edge *in = *begin; + if (in->isUpperBound() == bound->isUpperBound()) { + Value *succ = in->getVertex(); + res = meet(res, prove(a, succ, new Bound(bound, in->getValue()), + level+1)); + } + } + + mem_result.updateBound(b, bound, res); +} + +/// Return the stored result for this bound +ABCD::ProveResult ABCD::MemoizedResultChart::getResult(const Bound *bound)const{ + if (max_false && Bound::leq(bound, max_false)) + return False; + if (min_true && Bound::leq(min_true, bound)) + return True; + if (min_reduced && Bound::leq(min_reduced, bound)) + return Reduced; + return False; +} + +/// Stores a false found +void ABCD::MemoizedResultChart::addFalse(Bound *bound) { + if (!max_false || Bound::leq(max_false, bound)) + max_false = bound; + + if (Bound::eq(max_false, min_reduced)) + min_reduced = Bound::createIncrement(min_reduced); + if (Bound::eq(max_false, min_true)) + min_true = Bound::createIncrement(min_true); + if (Bound::eq(min_reduced, min_true)) + min_reduced = NULL; + clearRedundantReduced(); +} + +/// Stores a true found +void ABCD::MemoizedResultChart::addTrue(Bound *bound) { + if (!min_true || Bound::leq(bound, min_true)) + min_true = bound; + + if (Bound::eq(min_true, min_reduced)) + min_reduced = Bound::createDecrement(min_reduced); + if (Bound::eq(min_true, max_false)) + max_false = Bound::createDecrement(max_false); + if (Bound::eq(max_false, min_reduced)) + min_reduced = NULL; + clearRedundantReduced(); +} + +/// Stores a Reduced found +void ABCD::MemoizedResultChart::addReduced(Bound *bound) { + if (!min_reduced || Bound::leq(bound, min_reduced)) + min_reduced = bound; + + if (Bound::eq(min_reduced, min_true)) + min_true = Bound::createIncrement(min_true); + if (Bound::eq(min_reduced, max_false)) + max_false = Bound::createDecrement(max_false); +} + +/// Clears redundant reduced +/// If a min_true is smaller than a min_reduced then the min_reduced +/// is unnecessary and then removed. It also works for min_reduced +/// begin smaller than max_false. +void ABCD::MemoizedResultChart::clearRedundantReduced() { + if (min_true && min_reduced && Bound::lt(min_true, min_reduced)) + min_reduced = NULL; + if (max_false && min_reduced && Bound::lt(min_reduced, max_false)) + min_reduced = NULL; +} + +/// Stores the bound found +void ABCD::MemoizedResult::updateBound(Value *b, Bound *bound, + const ProveResult res) { + if (res == False) { + map[b].addFalse(bound); + } else if (res == True) { + map[b].addTrue(bound); + } else { + map[b].addReduced(bound); + } +} + +/// Adds an edge from V_from to V_to with weight value +void ABCD::InequalityGraph::addEdge(Value *V_to, Value *V_from, + APInt value, bool upper) { + assert(V_from->getType() == V_to->getType()); + assert(cast(V_from->getType())->getBitWidth() == + value.getBitWidth()); + + DenseMap >::iterator from; + from = addNode(V_from); + from->second.insert(new Edge(V_to, value, upper)); +} + +/// Test if there is any edge from V in the upper direction +bool ABCD::InequalityGraph::hasEdge(Value *V, bool upper) const { + SmallPtrSet it = graph.lookup(V); + + SmallPtrSet::iterator begin = it.begin(); + SmallPtrSet::iterator end = it.end(); + for (; begin != end; ++begin) { + if ((*begin)->isUpperBound() == upper) { + return true; + } + } + return false; +} + +/// Prints the header of the dot file +void ABCD::InequalityGraph::printHeader(raw_ostream &OS, Function &F) const { + OS << "digraph dotgraph {\n"; + OS << "label=\"Inequality Graph for \'"; + OS << F.getNameStr() << "\' function\";\n"; + OS << "node [shape=record,fontname=\"Times-Roman\",fontsize=14];\n"; +} + +/// Prints the body of the dot file +void ABCD::InequalityGraph::printBody(raw_ostream &OS) const { + DenseMap >::iterator begin = + graph.begin(), end = graph.end(); + + for (; begin != end ; ++begin) { + SmallPtrSet::iterator begin_par = + begin->second.begin(), end_par = begin->second.end(); + Value *source = begin->first; + + printVertex(OS, source); + + for (; begin_par != end_par ; ++begin_par) { + Edge *edge = *begin_par; + printEdge(OS, source, edge); + } + } +} + +/// Prints vertex source to the dot file +/// +void ABCD::InequalityGraph::printVertex(raw_ostream &OS, Value *source) const { + OS << "\""; + printName(OS, source); + OS << "\""; + OS << " [label=\"{"; + printName(OS, source); + OS << "}\"];\n"; +} + +/// Prints the edge to the dot file +void ABCD::InequalityGraph::printEdge(raw_ostream &OS, Value *source, + Edge *edge) const { + Value *dest = edge->getVertex(); + APInt value = edge->getValue(); + bool upper = edge->isUpperBound(); + + OS << "\""; + printName(OS, source); + OS << "\""; + OS << " -> "; + OS << "\""; + printName(OS, dest); + OS << "\""; + OS << " [label=\"" << value << "\""; + if (upper) { + OS << "color=\"blue\""; + } else { + OS << "color=\"red\""; + } + OS << "];\n"; +} + +void ABCD::InequalityGraph::printName(raw_ostream &OS, Value *info) const { + if (ConstantInt *CI = dyn_cast(info)) { + OS << *CI->getValue().getRawData(); + } else { + if (info->getName() == "") { + info->setName("V"); + } + OS << info->getNameStr(); + } +} + +/// createABCDPass - The public interface to this file... +FunctionPass *llvm::createABCDPass() { + return new ABCD(); +} From resistor at mac.com Wed Oct 28 02:05:35 2009 From: resistor at mac.com (Owen Anderson) Date: Wed, 28 Oct 2009 07:05:35 -0000 Subject: [llvm-commits] [llvm] r85383 - in /llvm/trunk: lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/DeadStoreElimination.cpp lib/Transforms/Scalar/GVN.cpp test/Transforms/DeadStoreElimination/lifetime-simple.ll test/Transforms/GVN/lifetime-simple.ll Message-ID: <200910280705.n9S75ZKs005281@zion.cs.uiuc.edu> Author: resistor Date: Wed Oct 28 02:05:35 2009 New Revision: 85383 URL: http://llvm.org/viewvc/llvm-project?rev=85383&view=rev Log: Treat lifetime begin/end markers as allocations/frees respectively for the purposes for GVN/DSE. Added: llvm/trunk/test/Transforms/DeadStoreElimination/lifetime-simple.ll llvm/trunk/test/Transforms/GVN/lifetime-simple.ll Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=85383&r1=85382&r2=85383&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Wed Oct 28 02:05:35 2009 @@ -185,10 +185,9 @@ if (invariantTag == Inst) { invariantTag = 0; continue; - - // If we pass an invariant-end marker, then we've just entered an invariant - // region and can start ignoring dependencies. } else if (IntrinsicInst* II = dyn_cast(Inst)) { + // If we pass an invariant-end marker, then we've just entered an + // invariant region and can start ignoring dependencies. if (II->getIntrinsicID() == Intrinsic::invariant_end) { uint64_t invariantSize = ~0ULL; if (ConstantInt* CI = dyn_cast(II->getOperand(2))) @@ -200,6 +199,19 @@ invariantTag = II->getOperand(1); continue; } + + // If we reach a lifetime begin or end marker, then the query ends here + // because the value is undefined. + } else if (II->getIntrinsicID() == Intrinsic::lifetime_start || + II->getIntrinsicID() == Intrinsic::lifetime_end) { + uint64_t invariantSize = ~0ULL; + if (ConstantInt* CI = dyn_cast(II->getOperand(1))) + invariantSize = CI->getZExtValue(); + + AliasAnalysis::AliasResult R = + AA->alias(II->getOperand(2), invariantSize, MemPtr, MemSize); + if (R == AliasAnalysis::MustAlias) + return MemDepResult::getDef(II); } } Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=85383&r1=85382&r2=85383&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Wed Oct 28 02:05:35 2009 @@ -154,6 +154,26 @@ continue; } } + + // If this is a lifetime end marker, we can throw away the store. + if (IntrinsicInst* II = dyn_cast(InstDep.getInst())) { + if (II->getIntrinsicID() == Intrinsic::lifetime_end) { + // Delete the store and now-dead instructions that feed it. + // DeleteDeadInstruction can delete the current instruction. Save BBI + // in case we need it. + WeakVH NextInst(BBI); + + DeleteDeadInstruction(SI); + + if (NextInst == 0) // Next instruction deleted. + BBI = BB.begin(); + else if (BBI != BB.begin()) // Revisit this instruction if possible. + --BBI; + NumFastStores++; + MadeChange = true; + continue; + } + } } // If this block ends in a return, unwind, or unreachable, all allocas are Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=85383&r1=85382&r2=85383&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Wed Oct 28 02:05:35 2009 @@ -1248,6 +1248,15 @@ UndefValue::get(LI->getType()))); continue; } + + // Loading immediately after lifetime begin or end -> undef. + if (IntrinsicInst* II = dyn_cast(DepInst)) { + if (II->getIntrinsicID() == Intrinsic::lifetime_start || + II->getIntrinsicID() == Intrinsic::lifetime_end) { + ValuesPerBlock.push_back(AvailableValueInBlock::get(DepBB, + UndefValue::get(LI->getType()))); + } + } if (StoreInst *S = dyn_cast(DepInst)) { // Reject loads and stores that are to the same address but are of @@ -1591,6 +1600,18 @@ NumGVNLoad++; return true; } + + // If this load occurs either right after a lifetime begin or a lifetime end, + // then the loaded value is undefined. + if (IntrinsicInst* II = dyn_cast(DepInst)) { + if (II->getIntrinsicID() == Intrinsic::lifetime_start || + II->getIntrinsicID() == Intrinsic::lifetime_end) { + L->replaceAllUsesWith(UndefValue::get(L->getType())); + toErase.push_back(L); + NumGVNLoad++; + return true; + } + } return false; } Added: llvm/trunk/test/Transforms/DeadStoreElimination/lifetime-simple.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/lifetime-simple.ll?rev=85383&view=auto ============================================================================== --- llvm/trunk/test/Transforms/DeadStoreElimination/lifetime-simple.ll (added) +++ llvm/trunk/test/Transforms/DeadStoreElimination/lifetime-simple.ll Wed Oct 28 02:05:35 2009 @@ -0,0 +1,18 @@ +; RUN: opt < %s -dse -S | FileCheck %s + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin7" + +define i8 @test2(i8* %P) nounwind { +; CHECK: @test2 +; CHECK-NOT: store i8 1 +; CHECK: ret i8 0 +entry: + call void @llvm.lifetime.start(i64 32, i8* %P) + call void @llvm.lifetime.end(i64 32, i8* %P) + store i8 1, i8* %P + ret i8 0 +} + +declare {}* @llvm.lifetime.start(i64 %S, i8* nocapture %P) readonly +declare void @llvm.lifetime.end(i64 %S, i8* nocapture %P) \ No newline at end of file Added: llvm/trunk/test/Transforms/GVN/lifetime-simple.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/lifetime-simple.ll?rev=85383&view=auto ============================================================================== --- llvm/trunk/test/Transforms/GVN/lifetime-simple.ll (added) +++ llvm/trunk/test/Transforms/GVN/lifetime-simple.ll Wed Oct 28 02:05:35 2009 @@ -0,0 +1,20 @@ +; RUN: opt < %s -gvn -S | FileCheck %s + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin7" + +define i8 @test(i8* %P) nounwind { +; CHECK: @test +; CHECK-NOT: load +; CHECK: ret i8 undef +entry: + call void @llvm.lifetime.start(i64 32, i8* %P) + %0 = load i8* %P + store i8 1, i8* %P + call void @llvm.lifetime.end(i64 32, i8* %P) + %1 = load i8* %P + ret i8 %1 +} + +declare {}* @llvm.lifetime.start(i64 %S, i8* nocapture %P) readonly +declare void @llvm.lifetime.end(i64 %S, i8* nocapture %P) \ No newline at end of file From anton at korobeynikov.info Wed Oct 28 03:25:58 2009 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Wed, 28 Oct 2009 11:25:58 +0300 Subject: [llvm-commits] [llvm] r85357 - in /llvm/trunk/lib/Target/SystemZ: SystemZISelLowering.cpp SystemZInstrFP.td SystemZInstrInfo.td In-Reply-To: <200910280055.n9S0twZi024341@zion.cs.uiuc.edu> References: <200910280055.n9S0twZi024341@zion.cs.uiuc.edu> Message-ID: > + ?// TODO: It may be better to default to latency-oriented scheduling, however > + ?// LLVM's current latency-oriented scheduler can't handle physreg definitions > + ?// such as SystemZ has with PSW, so set this to the register-pressure > + ?// scheduler, because it can. > + ?setSchedulingPreference(SchedulingForRegPressure); Wording should be changes - it is required to schedule for latency, since s390x is strictly in-order processor. I'm bumping the priority of PR2344. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From baldrick at free.fr Wed Oct 28 04:14:24 2009 From: baldrick at free.fr (Duncan Sands) Date: Wed, 28 Oct 2009 10:14:24 +0100 Subject: [llvm-commits] FW: [PATCH] Fix to pass options from Gold plugin to LTO codegen In-Reply-To: <4AE7C7BA.4080703@mxc.ca> References: <3FE2DECEF38F9247AE7C8BC1FD2B015F0817022C@ALLISON>, <6AE1604EE3EC5F4296C096518C6B77EEF11643FF@mail.accesssoftek.com><6AE1604EE3EC5F4296C096518C6B77EEF1163385@mail.accesssoftek.com><4AE250D1.4090403@mxc.ca> <4AE67CEB.6010404@mxc.ca> <45894BE6012542EF9E5CF87A4A757C5B@andreic6e7fe55> <4AE7C7BA.4080703@mxc.ca> Message-ID: <4AE80B70.7070302@free.fr> Hi, >>> I didn't remove the lto_codegen_debug_options yet, just marked it as >>> deprecated. >>> It is actually used in Ada, in files >>> >>> bindings/ada/llvm/llvm_linktimeoptimizer_wrap.cxx >>> bindings/ada/llvm/llvm_link_time_optimizer-binding.ads >> Bah, then it's too late. We released 2.6 with this API which means that >> it's fixed in stone forever. All of the C API is like that, we will >> never break backwards-compatibility on the C API. yes, but it has to be said that AFAIK no-one is currently using the Ada bindings. Indeed, you can't use them because no-one did the build system for them yet... Ciao, Duncan. From ggreif at gmail.com Wed Oct 28 04:21:32 2009 From: ggreif at gmail.com (Gabor Greif) Date: Wed, 28 Oct 2009 09:21:32 -0000 Subject: [llvm-commits] [llvm] r85385 - /llvm/trunk/docs/LangRef.html Message-ID: <200910280921.n9S9LXBX024394@zion.cs.uiuc.edu> Author: ggreif Date: Wed Oct 28 04:21:30 2009 New Revision: 85385 URL: http://llvm.org/viewvc/llvm-project?rev=85385&view=rev Log: advertise new syntax for unnamed instructions and eliminate confusing double-use of SSA names (work in progress) Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=85385&r1=85384&r2=85385&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Wed Oct 28 04:21:30 2009 @@ -438,8 +438,8 @@
    -add i32 %X, %X           ; yields {i32}:%0
    -add i32 %0, %0           ; yields {i32}:%1
    +%0 = add i32 %X, %X           ; yields {i32}:%0
    +%1 = add i32 %0, %0           ; yields {i32}:%1
     %result = add i32 %1, %1
     
    @@ -4249,7 +4249,7 @@
       %X = trunc i32 257 to i8              ; yields i8:1
       %Y = trunc i32 123 to i1              ; yields i1:true
    -  %Y = trunc i32 122 to i1              ; yields i1:false
    +  %Z = trunc i32 122 to i1              ; yields i1:false
     
    @@ -4433,7 +4433,7 @@
       %X = fptoui double 123.0 to i32      ; yields i32:123
       %Y = fptoui float 1.0E+300 to i1     ; yields undefined:1
    -  %X = fptoui float 1.04E+17 to i8     ; yields undefined:1
    +  %Z = fptoui float 1.04E+17 to i8     ; yields undefined:1
     
    @@ -4471,7 +4471,7 @@
       %X = fptosi double -123.0 to i32      ; yields i32:-123
       %Y = fptosi float 1.0E-247 to i1      ; yields undefined:1
    -  %X = fptosi float 1.04E+17 to i8      ; yields undefined:1
    +  %Z = fptosi float 1.04E+17 to i8      ; yields undefined:1
     
    @@ -4615,8 +4615,8 @@
    Example:
       %X = inttoptr i32 255 to i32*          ; yields zero extension on 64-bit architecture
    -  %X = inttoptr i32 255 to i32*          ; yields no-op on 32-bit architecture
    -  %Y = inttoptr i64 0 to i32*            ; yields truncation on 32-bit architecture
    +  %Y = inttoptr i32 255 to i32*          ; yields no-op on 32-bit architecture
    +  %Z = inttoptr i64 0 to i32*            ; yields truncation on 32-bit architecture
     
    From ggreif at gmail.com Wed Oct 28 08:05:12 2009 From: ggreif at gmail.com (Gabor Greif) Date: Wed, 28 Oct 2009 13:05:12 -0000 Subject: [llvm-commits] [llvm] r85387 - /llvm/trunk/docs/LangRef.html Message-ID: <200910281305.n9SD5G4M032602@zion.cs.uiuc.edu> Author: ggreif Date: Wed Oct 28 08:05:07 2009 New Revision: 85387 URL: http://llvm.org/viewvc/llvm-project?rev=85387&view=rev Log: ooops, SSA name should not be part of the link Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=85387&r1=85386&r2=85387&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Wed Oct 28 08:05:07 2009 @@ -438,8 +438,8 @@
    -%0 = add i32 %X, %X           ; yields {i32}:%0
    -%1 = add i32 %0, %0           ; yields {i32}:%1
    +%0 = add i32 %X, %X           ; yields {i32}:%0
    +%1 = add i32 %0, %0           ; yields {i32}:%1
     %result = add i32 %1, %1
     
    From ggreif at gmail.com Wed Oct 28 08:14:50 2009 From: ggreif at gmail.com (Gabor Greif) Date: Wed, 28 Oct 2009 13:14:50 -0000 Subject: [llvm-commits] [llvm] r85388 - /llvm/trunk/docs/LangRef.html Message-ID: <200910281314.n9SDEopf000761@zion.cs.uiuc.edu> Author: ggreif Date: Wed Oct 28 08:14:50 2009 New Revision: 85388 URL: http://llvm.org/viewvc/llvm-project?rev=85388&view=rev Log: use metavariable instead of SSA name %result for consistency Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=85388&r1=85387&r2=85388&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Wed Oct 28 08:14:50 2009 @@ -3728,7 +3728,7 @@
    Example:
    -  %result = extractelement <4 x i32> %vec, i32 0    ; yields i32
    +  <result> = extractelement <4 x i32> %vec, i32 0    ; yields i32
     
    @@ -3764,7 +3764,7 @@
    Example:
    -  %result = insertelement <4 x i32> %vec, i32 1, i32 0    ; yields <4 x i32>
    +  <result> = insertelement <4 x i32> %vec, i32 1, i32 0    ; yields <4 x i32>
     
    @@ -3805,13 +3805,13 @@
    Example:
    -  %result = shufflevector <4 x i32> %v1, <4 x i32> %v2, 
    +  <result> = shufflevector <4 x i32> %v1, <4 x i32> %v2, 
                               <4 x i32> <i32 0, i32 4, i32 1, i32 5>  ; yields <4 x i32>
    -  %result = shufflevector <4 x i32> %v1, <4 x i32> undef, 
    +  <result> = shufflevector <4 x i32> %v1, <4 x i32> undef, 
                               <4 x i32> <i32 0, i32 1, i32 2, i32 3>  ; yields <4 x i32> - Identity shuffle.
    -  %result = shufflevector <8 x i32> %v1, <8 x i32> undef, 
    +  <result> = shufflevector <8 x i32> %v1, <8 x i32> undef, 
                               <4 x i32> <i32 0, i32 1, i32 2, i32 3>  ; yields <4 x i32>
    -  %result = shufflevector <4 x i32> %v1, <4 x i32> %v2, 
    +  <result> = shufflevector <4 x i32> %v1, <4 x i32> %v2, 
                               <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7 >  ; yields <8 x i32>
     
    @@ -3857,7 +3857,7 @@
    Example:
    -  %result = extractvalue {i32, float} %agg, 0    ; yields i32
    +  <result> = extractvalue {i32, float} %agg, 0    ; yields i32
     
    @@ -3896,7 +3896,7 @@
    Example:
    -  %result = insertvalue {i32, float} %agg, i32 1, 0    ; yields {i32, float}
    +  <result> = insertvalue {i32, float} %agg, i32 1, 0    ; yields {i32, float}
     
    From benny.kra at googlemail.com Wed Oct 28 08:29:19 2009 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Wed, 28 Oct 2009 13:29:19 -0000 Subject: [llvm-commits] [llvm] r85389 - /llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt Message-ID: <200910281329.n9SDTJIF001716@zion.cs.uiuc.edu> Author: d0k Date: Wed Oct 28 08:29:18 2009 New Revision: 85389 URL: http://llvm.org/viewvc/llvm-project?rev=85389&view=rev Log: Update CMake file. Modified: llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt Modified: llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt?rev=85389&r1=85388&r2=85389&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt (original) +++ llvm/trunk/lib/Transforms/Scalar/CMakeLists.txt Wed Oct 28 08:29:18 2009 @@ -1,4 +1,5 @@ add_llvm_library(LLVMScalarOpts + ABCD.cpp ADCE.cpp BasicBlockPlacement.cpp CodeGenLICM.cpp From kennethuil at gmail.com Wed Oct 28 08:54:46 2009 From: kennethuil at gmail.com (Kenneth Uildriks) Date: Wed, 28 Oct 2009 08:54:46 -0500 Subject: [llvm-commits] [llvm] r85295 - in /llvm/trunk: docs/tutorial/LangImpl4.html docs/tutorial/OCamlLangImpl4.html include/llvm/ExecutionEngine/ExecutionEngine.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngi In-Reply-To: References: <9879CBCC-0704-4FC7-8061-94D382FA7587@apple.com> <4AE7CC5C.5040300@mxc.ca> <02C5660C-FC69-4B07-B329-784D718E49D2@apple.com> Message-ID: <400d33ea0910280654h64d62c14o7673b5a8dea1ab22@mail.gmail.com> On Wed, Oct 28, 2009 at 1:47 AM, Evan Cheng wrote: > > On Oct 27, 2009, at 11:07 PM, Jeffrey Yasskin wrote: > >> On Tue, Oct 27, 2009 at 10:03 PM, Evan Cheng >> wrote: >>> I believe lazy compilation should still be the >>> default behavior for JIT. If it's not thread safe, then clients who >>> want JIT >>> safety should fix it. >> >> You say that as if it's an easy thing to do and can be done once and >> for all. You should probably read the bug (http://llvm.org/PR5184) to >> see why that's wrong. > > I am not saying it's easy. There are clients which do use lazy > compilation and they don't care about this though. > >> >> As to why lazy compilation should not be the default: it has confused >> users who tried running their JITs under helgrind and got reports >> inside one of the most confusing parts of the JIT. When the race >> actually bites users, it's going to be extremely hard to debug, since >> it happens when a call is first executed and depends on exactly how >> the call was aligned. And there are other races in the JIT unless you >> hold the JIT lock around all IR manipulation. I don't think it's a >> good idea to make the default behavior of LLVM crash randomly in >> hard-to-debug ways. Finally, I haven't heard of any cases besides lli >> where the current lazy JIT is actually the right choice for >> performance. > > To me that's a documentation issue. We're providing lli as the example > JIT. It defaults to lazy compilation. That will not change since we're > using it as a JIT test harness. I think it's actually more confusing > for lli to default to different behavior. > > Your usage model is different from others. What you feel is the right > default behavior is not the same for others. Like I said, there are > clients who have been using the JIT who do not care about thread > safety. They are using it in a single-threaded program and want the > benefit of lazy compilation. > > LLVM JIT is not a light weighted JIT. It does everything a static > compiler code generator would do. Non-lazy compilation may very well > be unacceptable to a lot of users. > >> >> Now, lazy JITting is safe in a single-threaded program. It might make >> sense to change the default depending on whether >> llvm_start_multithreaded() has been called, but that seemed more >> confusing than saying that you always have to enable it if you want >> it. > > I don't think that's the right solution. It makes the "default" even > more confusing. I'd prefer it just abort with an error stating the non- > lazy + multi-threaded configuration being unsupported. > > Evan > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > What exactly would break if lazy compilation was disabled? The docs say "the JIT will abort if lazy compilation is ever attempted"... what exactly would cause this? From mrs at apple.com Wed Oct 28 10:01:39 2009 From: mrs at apple.com (Mike Stump) Date: Wed, 28 Oct 2009 08:01:39 -0700 Subject: [llvm-commits] [llvm] r85382 - in /llvm/trunk: include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/ABCD.cpp In-Reply-To: <200910280703.n9S73NJi005159@zion.cs.uiuc.edu> References: <200910280703.n9S73NJi005159@zion.cs.uiuc.edu> Message-ID: <4AC114E4-B50B-45B7-BF28-D6485302048A@apple.com> On Oct 28, 2009, at 12:03 AM, Nick Lewycky wrote: > +// constraint. By analyzing these constraints we can proof that a > branch is > +// redundant. When a branch is proved redundant it means that proof --> prove From eocallaghan at auroraux.org Wed Oct 28 10:04:57 2009 From: eocallaghan at auroraux.org (Edward O'Callaghan) Date: Wed, 28 Oct 2009 15:04:57 -0000 Subject: [llvm-commits] [llvm] r85390 - /llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp Message-ID: <200910281504.n9SF4wRT005274@zion.cs.uiuc.edu> Author: evocallaghan Date: Wed Oct 28 10:04:53 2009 New Revision: 85390 URL: http://llvm.org/viewvc/llvm-project?rev=85390&view=rev Log: No newline at end of file. Modified: llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp?rev=85390&r1=85389&r2=85390&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SCCVN.cpp Wed Oct 28 10:04:53 2009 @@ -718,4 +718,4 @@ BBMap.clear(); return changed; -} \ No newline at end of file +} From gohman at apple.com Wed Oct 28 10:23:36 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 28 Oct 2009 15:23:36 -0000 Subject: [llvm-commits] [llvm] r85393 - /llvm/trunk/lib/CodeGen/MachineLICM.cpp Message-ID: <200910281523.n9SFNbXU006063@zion.cs.uiuc.edu> Author: djg Date: Wed Oct 28 10:23:36 2009 New Revision: 85393 URL: http://llvm.org/viewvc/llvm-project?rev=85393&view=rev Log: Simplify this code: if the unfolded load can't be hoisted, just delete the new instructions and leave the old one in place. Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=85393&r1=85392&r2=85393&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Wed Oct 28 10:23:36 2009 @@ -401,7 +401,7 @@ const TargetRegisterClass *RC = TID.OpInfo[0].getRegClass(TRI); // Ok, we're unfolding. Create a temporary register and do the unfold. unsigned Reg = RegInfo->createVirtualRegister(RC); - SmallVector NewMIs; + SmallVector NewMIs; bool Success = TII->unfoldMemoryOperand(MF, MI, Reg, /*UnfoldLoad=*/true, /*UnfoldStore=*/false, @@ -415,28 +415,15 @@ MachineBasicBlock *MBB = MI->getParent(); MBB->insert(MI, NewMIs[0]); MBB->insert(MI, NewMIs[1]); - MI->eraseFromParent(); // If unfolding produced a load that wasn't loop-invariant or profitable to - // hoist, re-fold it to undo the damage. + // hoist, discard the new instructions and bail. if (!IsLoopInvariantInst(*NewMIs[0]) || !IsProfitableToHoist(*NewMIs[0])) { - SmallVector Ops; - for (unsigned i = 0, e = NewMIs[1]->getNumOperands(); i != e; ++i) { - MachineOperand &MO = NewMIs[1]->getOperand(i); - if (MO.isReg() && MO.getReg() == Reg) { - assert(MO.isUse() && - "Register defined by unfolded load is redefined " - "instead of just used!"); - Ops.push_back(i); - } - } - MI = TII->foldMemoryOperand(MF, NewMIs[1], Ops, NewMIs[0]); - assert(MI && "Re-fold failed!"); - MBB->insert(NewMIs[1], MI); NewMIs[0]->eraseFromParent(); NewMIs[1]->eraseFromParent(); return; } // Otherwise we successfully unfolded a load that we can hoist. + MI->eraseFromParent(); MI = NewMIs[0]; } From gohman at apple.com Wed Oct 28 10:28:02 2009 From: gohman at apple.com (Dan Gohman) Date: Wed, 28 Oct 2009 15:28:02 -0000 Subject: [llvm-commits] [llvm] r85394 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200910281528.n9SFS2Q6006292@zion.cs.uiuc.edu> Author: djg Date: Wed Oct 28 10:28:02 2009 New Revision: 85394 URL: http://llvm.org/viewvc/llvm-project?rev=85394&view=rev Log: Don't call SDNode::isPredecessorOf when it isn't necessary. If the load's chains have no users, they can't be predecessors of the condition. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=85394&r1=85393&r2=85394&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Oct 28 10:28:02 2009 @@ -5737,8 +5737,10 @@ if (TheSelect->getOpcode() == ISD::SELECT) { // Check that the condition doesn't reach either load. If so, folding // this will induce a cycle into the DAG. - if (!LLD->isPredecessorOf(TheSelect->getOperand(0).getNode()) && - !RLD->isPredecessorOf(TheSelect->getOperand(0).getNode())) { + if ((!LLD->hasAnyUseOfValue(1) || + !LLD->isPredecessorOf(TheSelect->getOperand(0).getNode())) && + (!RLD->hasAnyUseOfValue(1) || + !RLD->isPredecessorOf(TheSelect->getOperand(0).getNode()))) { Addr = DAG.getNode(ISD::SELECT, TheSelect->getDebugLoc(), LLD->getBasePtr().getValueType(), TheSelect->getOperand(0), LLD->getBasePtr(), @@ -5747,10 +5749,12 @@ } else { // Check that the condition doesn't reach either load. If so, folding // this will induce a cycle into the DAG. - if (!LLD->isPredecessorOf(TheSelect->getOperand(0).getNode()) && - !RLD->isPredecessorOf(TheSelect->getOperand(0).getNode()) && - !LLD->isPredecessorOf(TheSelect->getOperand(1).getNode()) && - !RLD->isPredecessorOf(TheSelect->getOperand(1).getNode())) { + if ((!LLD->hasAnyUseOfValue(1) || + (!LLD->isPredecessorOf(TheSelect->getOperand(0).getNode()) && + !LLD->isPredecessorOf(TheSelect->getOperand(1).getNode()))) && + (!RLD->hasAnyUseOfValue(1) || + (!RLD->isPredecessorOf(TheSelect->getOperand(0).getNode()) && + !RLD->isPredecessorOf(TheSelect->getOperand(1).getNode())))) { Addr = DAG.getNode(ISD::SELECT_CC, TheSelect->getDebugLoc(), LLD->getBasePtr().getValueType(), TheSelect->getOperand(0), From sabre at nondot.org Wed Oct 28 10:32:19 2009 From: sabre at nondot.org (Chris Lattner) Date: Wed, 28 Oct 2009 15:32:19 -0000 Subject: [llvm-commits] [llvm] r85395 - in /llvm/trunk: include/llvm/Support/Debug.h lib/Support/Debug.cpp Message-ID: <200910281532.n9SFWJDd006514@zion.cs.uiuc.edu> Author: lattner Date: Wed Oct 28 10:32:19 2009 New Revision: 85395 URL: http://llvm.org/viewvc/llvm-project?rev=85395&view=rev Log: add a new 'SetCurrentDebugType' API (requested by Andrew Haley for JIT stuff) to programmatically control the current debug flavor. While I'm at it, doxygenate Debug.h and clean it up. Modified: llvm/trunk/include/llvm/Support/Debug.h llvm/trunk/lib/Support/Debug.cpp Modified: llvm/trunk/include/llvm/Support/Debug.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Debug.h?rev=85395&r1=85394&r2=85395&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/Debug.h (original) +++ llvm/trunk/include/llvm/Support/Debug.h Wed Oct 28 10:32:19 2009 @@ -28,39 +28,47 @@ namespace llvm { -// DebugFlag - This boolean is set to true if the '-debug' command line option -// is specified. This should probably not be referenced directly, instead, use -// the DEBUG macro below. -// -#ifndef NDEBUG -extern bool DebugFlag; +/// DEBUG_TYPE macro - Files can specify a DEBUG_TYPE as a string, which causes +/// all of their DEBUG statements to be activatable with -debug-only=thatstring. +#ifndef DEBUG_TYPE +#define DEBUG_TYPE "" #endif - -// isCurrentDebugType - Return true if the specified string is the debug type -// specified on the command line, or if none was specified on the command line -// with the -debug-only=X option. -// + #ifndef NDEBUG +/// DebugFlag - This boolean is set to true if the '-debug' command line option +/// is specified. This should probably not be referenced directly, instead, use +/// the DEBUG macro below. +/// +extern bool DebugFlag; + +/// isCurrentDebugType - Return true if the specified string is the debug type +/// specified on the command line, or if none was specified on the command line +/// with the -debug-only=X option. +/// bool isCurrentDebugType(const char *Type); -#else -#define isCurrentDebugType(X) (false) -#endif - -// DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug -// information. In the '-debug' option is specified on the commandline, and if -// this is a debug build, then the code specified as the option to the macro -// will be executed. Otherwise it will not be. Example: -// -// DEBUG_WITH_TYPE("bitset", errs() << "Bitset contains: " << Bitset << "\n"); -// -// This will emit the debug information if -debug is present, and -debug-only is -// not specified, or is specified as "bitset". -#ifdef NDEBUG -#define DEBUG_WITH_TYPE(TYPE, X) do { } while (0) -#else +/// SetCurrentDebugType - Set the current debug type, as if the -debug-only=X +/// option were specified. Note that DebugFlag also needs to be set to true for +/// debug output to be produced. +/// +void SetCurrentDebugType(const char *Type); + +/// DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug +/// information. In the '-debug' option is specified on the commandline, and if +/// this is a debug build, then the code specified as the option to the macro +/// will be executed. Otherwise it will not be. Example: +/// +/// DEBUG_WITH_TYPE("bitset", errs() << "Bitset contains: " << Bitset << "\n"); +/// +/// This will emit the debug information if -debug is present, and -debug-only +/// is not specified, or is specified as "bitset". #define DEBUG_WITH_TYPE(TYPE, X) \ do { if (DebugFlag && isCurrentDebugType(TYPE)) { X; } } while (0) + +#else +#define isCurrentDebugType(X) (false) +#define SetCurrentDebugType(X) +#define DEBUG_WITH_TYPE(TYPE, X) do { } while (0) #endif // DEBUG macro - This macro should be used by passes to emit debug information. @@ -70,11 +78,6 @@ // // DEBUG(errs() << "Bitset contains: " << Bitset << "\n"); // - -#ifndef DEBUG_TYPE -#define DEBUG_TYPE "" -#endif - #define DEBUG(X) DEBUG_WITH_TYPE(DEBUG_TYPE, X) } // End llvm namespace Modified: llvm/trunk/lib/Support/Debug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Debug.cpp?rev=85395&r1=85394&r2=85395&view=diff ============================================================================== --- llvm/trunk/lib/Support/Debug.cpp (original) +++ llvm/trunk/lib/Support/Debug.cpp Wed Oct 28 10:32:19 2009 @@ -57,7 +57,18 @@ bool llvm::isCurrentDebugType(const char *DebugType) { return CurrentDebugType.empty() || DebugType == CurrentDebugType; } + +/// SetCurrentDebugType - Set the current debug type, as if the -debug-only=X +/// option were specified. Note that DebugFlag also needs to be set to true for +/// debug output to be produced. +/// +void SetCurrentDebugType(const char *Type) { + CurrentDebugType = Type; +} + #else // Avoid "has no symbols" warning. +namespace llvm { int Debug_dummy = 0; +} #endif From ssen at apple.com Wed Oct 28 10:46:10 2009 From: ssen at apple.com (Shantonu Sen) Date: Wed, 28 Oct 2009 15:46:10 -0000 Subject: [llvm-commits] [compiler-rt] r85396 - in /compiler-rt/trunk/test/Unit: absvdi2_test.c absvsi2_test.c absvti2_test.c Message-ID: <200910281546.n9SFkA6n007024@zion.cs.uiuc.edu> Author: ssen Date: Wed Oct 28 10:46:10 2009 New Revision: 85396 URL: http://llvm.org/viewvc/llvm-project?rev=85396&view=rev Log: Add stdlib.h for rand() prototype Modified: compiler-rt/trunk/test/Unit/absvdi2_test.c compiler-rt/trunk/test/Unit/absvsi2_test.c compiler-rt/trunk/test/Unit/absvti2_test.c Modified: compiler-rt/trunk/test/Unit/absvdi2_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/absvdi2_test.c?rev=85396&r1=85395&r2=85396&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/absvdi2_test.c (original) +++ compiler-rt/trunk/test/Unit/absvdi2_test.c Wed Oct 28 10:46:10 2009 @@ -13,6 +13,7 @@ #include "int_lib.h" #include +#include // Returns: absolute value Modified: compiler-rt/trunk/test/Unit/absvsi2_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/absvsi2_test.c?rev=85396&r1=85395&r2=85396&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/absvsi2_test.c (original) +++ compiler-rt/trunk/test/Unit/absvsi2_test.c Wed Oct 28 10:46:10 2009 @@ -13,6 +13,7 @@ #include "int_lib.h" #include +#include // Returns: absolute value Modified: compiler-rt/trunk/test/Unit/absvti2_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/absvti2_test.c?rev=85396&r1=85395&r2=85396&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/absvti2_test.c (original) +++ compiler-rt/trunk/test/Unit/absvti2_test.c Wed Oct 28 10:46:10 2009 @@ -15,6 +15,7 @@ #include "int_lib.h" #include +#include // Returns: absolute value From xerxes at zafena.se Wed Oct 28 10:50:53 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Wed, 28 Oct 2009 16:50:53 +0100 Subject: [llvm-commits] [patch] Make it possible to enable and disable JIT debug dumps dynamically Message-ID: <4AE8685D.2040409@zafena.se> This patch would enable projects that use the LLVM JIT to enable and disable JIT debug dumps dynamically. The patch have been up for discussion on the llvm-dev mailinglist but since it have gotten no attention there im posting it for review here instead. http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-January/019661.html http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-May/022101.html Projects like Icedtea (OpenJDK) that uses the LLVM JIT would benefit from this patch since it would enable us to turn on dumping of JITed machinecode for selected methods. Patch made by Andrew Haley. Ok to push? Cheers Xerxes -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-debugonly-zeroormore.patch Type: text/x-patch Size: 556 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20091028/dd31c818/attachment.bin From ssen at apple.com Wed Oct 28 10:54:05 2009 From: ssen at apple.com (Shantonu Sen) Date: Wed, 28 Oct 2009 15:54:05 -0000 Subject: [llvm-commits] [compiler-rt] r85397 - in /compiler-rt/trunk/test/Unit: clear_cache_test.c enable_execute_stack_test.c Message-ID: <200910281554.n9SFs5Ji007439@zion.cs.uiuc.edu> Author: ssen Date: Wed Oct 28 10:54:04 2009 New Revision: 85397 URL: http://llvm.org/viewvc/llvm-project?rev=85397&view=rev Log: Work around strictness in gcc 4.4.1 casting a function pointer to void * Modified: compiler-rt/trunk/test/Unit/clear_cache_test.c compiler-rt/trunk/test/Unit/enable_execute_stack_test.c Modified: compiler-rt/trunk/test/Unit/clear_cache_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/clear_cache_test.c?rev=85397&r1=85396&r2=85397&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/clear_cache_test.c (original) +++ compiler-rt/trunk/test/Unit/clear_cache_test.c Wed Oct 28 10:54:04 2009 @@ -42,16 +42,16 @@ return 1; // verify you can copy and execute a function - memcpy(execution_buffer, &func1, 128); + memcpy(execution_buffer, (void *)(uintptr_t)&func1, 128); __clear_cache(execution_buffer, &execution_buffer[128]); - pfunc f1 = (pfunc)execution_buffer; + pfunc f1 = (pfunc)(uintptr_t)execution_buffer; if ( (*f1)() != 1 ) return 1; // verify you can overwrite a function with another - memcpy(execution_buffer, &func2, 128); + memcpy(execution_buffer, (void *)(uintptr_t)&func2, 128); __clear_cache(execution_buffer, &execution_buffer[128]); - pfunc f2 = (pfunc)execution_buffer; + pfunc f2 = (pfunc)(uintptr_t)execution_buffer; if ( (*f2)() != 2 ) return 1; Modified: compiler-rt/trunk/test/Unit/enable_execute_stack_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/enable_execute_stack_test.c?rev=85397&r1=85396&r2=85397&view=diff ============================================================================== --- compiler-rt/trunk/test/Unit/enable_execute_stack_test.c (original) +++ compiler-rt/trunk/test/Unit/enable_execute_stack_test.c Wed Oct 28 10:54:04 2009 @@ -35,21 +35,21 @@ int main() { - unsigned char execution_buffer[128]; - // mark stack page containing execution_buffer to be executable - __enable_execute_stack(execution_buffer); + unsigned char execution_buffer[128]; + // mark stack page containing execution_buffer to be executable + __enable_execute_stack(execution_buffer); // verify you can copy and execute a function - memcpy(execution_buffer, &func1, 128); + memcpy(execution_buffer, (void *)(uintptr_t)&func1, 128); __clear_cache(execution_buffer, &execution_buffer[128]); - pfunc f1 = (pfunc)execution_buffer; + pfunc f1 = (pfunc)(uintptr_t)execution_buffer; if ( (*f1)() != 1 ) return 1; // verify you can overwrite a function with another - memcpy(execution_buffer, &func2, 128); + memcpy(execution_buffer, (void *)(uintptr_t)&func2, 128); __clear_cache(execution_buffer, &execution_buffer[128]); - pfunc f2 = (pfunc)execution_buffer; + pfunc f2 = (pfunc)(uintptr_t)execution_buffer; if ( (*f2)() != 2 ) return 1; From clattner at apple.com Wed Oct 28 10:54:22 2009 From: clattner at apple.com (Chris Lattner) Date: Wed, 28 Oct 2009 08:54:22 -0700 Subject: [llvm-commits] [patch] Make it possible to enable and disable JIT debug dumps dynamically In-Reply-To: <4AE8685D.2040409@zafena.se> References: <4AE8685D.2040409@zafena.se> Message-ID: <9906A857-F576-4D30-95AD-6DD0578D127A@apple.com> On Oct 28, 2009, at 8:50 AM, Xerxes R?nby wrote: > This patch would enable projects that use the LLVM JIT to enable and > disable JIT debug dumps dynamically. > The patch have been up for discussion on the llvm-dev mailinglist but > since it have gotten no attention there im posting it for review here > instead. > > http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-January/019661.html > http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-May/022101.html > > Projects like Icedtea (OpenJDK) that uses the LLVM JIT would benefit > from this patch since it would enable us to turn on dumping of JITed > machinecode for selected methods. > > Patch made by Andrew Haley. Hi Xerxes, I spoke with Andrew on IRC and added a new API to do this: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20091026/089863.html Please verify that it works for you guys, -Chris > > Ok to push? > > Cheers > Xerxes > Index: lib/Support/Debug.cpp > =================================================================== > --- lib/Support/Debug.cpp (Revision 71077) > +++ lib/Support/Debug.cpp (Arbeitskopie) > @@ -48,7 +48,7 @@ > static cl::opt > > DebugOnly("debug-only", cl::desc("Enable a specific type of debug > output"), > cl::Hidden, cl::value_desc("debug string"), > - cl::location(DebugOnlyOptLoc), cl::ValueRequired); > + cl::location(DebugOnlyOptLoc), cl::ValueRequired, > cl::ZeroOrMore); > #endif > } > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From clattner at apple.com Wed Oct 28 10:56:54 2009 From: clattner at apple.com (Chris Lattner) Date: Wed, 28 Oct 2009 08:56:54 -0700 Subject: [llvm-commits] [llvm] r85382 - in /llvm/trunk: include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/ABCD.cpp In-Reply-To: <200910280703.n9S73NJi005159@zion.cs.uiuc.edu> References: <200910280703.n9S73NJi005159@zion.cs.uiuc.edu> Message-ID: On Oct 28, 2009, at 12:03 AM, Nick Lewycky wrote: > Author: nicholas > Date: Wed Oct 28 02:03:15 2009 > New Revision: 85382 > > URL: http://llvm.org/viewvc/llvm-project?rev=85382&view=rev > Log: > Add ABCD, a generalized implementation of the Elimination of Array > Bounds > Checks on Demand algorithm which looks at arbitrary branches instead > of loop > iterations. This is GSoC work by Andre Tavares with only editorial > changes > applied! No testcases? -Chris From grosbach at apple.com Wed Oct 28 11:15:41 2009 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 28 Oct 2009 09:15:41 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r85303 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: <200910272056.n9RKunFx014693@zion.cs.uiuc.edu> References: <200910272056.n9RKunFx014693@zion.cs.uiuc.edu> Message-ID: <90DFC6EF-FA27-44DC-A2CC-927496A1B95E@apple.com> Hi Dale, I'm seeing the following when building Apple-style: cc1plus: warnings being treated as errors /Volumes/Home/grosbaj/nightly-llvm/build/llvmgcc.roots/llvmgcc~obj/src/ gcc/llvm-convert.cpp: In static member function 'static llvm::Constant* TreeConstantToLLVM::ConvertRecordCONSTRUCTOR (tree_node*)':/Volumes/Home/grosbaj/nightly-llvm/build/llvmgcc.roots/ llvmgcc~obj/src/gcc/llvm-convert.cpp:7777: warning: 'FieldSizeInBits' may be used uninitialized in this function It seems that might be the case in the conditional starting on 7800. That's just a quick look at the code, though, so very possible I'm missing something. The warning is causing the nightly tester llvm-gcc builds to fail since we're building llvm-gcc with -Werror, so it'd be nice to get that fixed anyway. -Jim On Oct 27, 2009, at 1:56 PM, Dale Johannesen wrote: > Author: johannes > Date: Tue Oct 27 15:56:49 2009 > New Revision: 85303 > > URL: http://llvm.org/viewvc/llvm-project?rev=85303&view=rev > Log: > Make previous change not crash when size of object is unknown. > > > Modified: > llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp > > Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=85303&r1=85302&r2=85303&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) > +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Oct 27 15:56:49 2009 > @@ -7774,10 +7774,12 @@ > uint64_t GCCFieldOffsetInBits = getFieldOffsetInBits(Field); > NextField = TREE_CHAIN(Field); > > - uint64_t FieldSizeInBits = getInt64(DECL_SIZE(Field), true); > + uint64_t FieldSizeInBits; > + if (DECL_SIZE(Field)) > + FieldSizeInBits = getInt64(DECL_SIZE(Field), true); > uint64_t ValueSizeInBits = Val->getType()->getPrimitiveSizeInBits > (); > ConstantInt *ValC = dyn_cast(Val); > - if (ValC && ValC->isZero()) { > + if (ValC && ValC->isZero() && DECL_SIZE(Field)) { > // G++ has various bugs handling {} initializers where it > doesn't > // synthesize a zero node of the right type. Instead of > figuring out G++, > // just hack around it by special casing zero and allowing it > to be the > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dpatel at apple.com Wed Oct 28 11:51:53 2009 From: dpatel at apple.com (Devang Patel) Date: Wed, 28 Oct 2009 16:51:53 -0000 Subject: [llvm-commits] [llvm] r85402 - /llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Message-ID: <200910281651.n9SGprZU009962@zion.cs.uiuc.edu> Author: dpatel Date: Wed Oct 28 11:51:52 2009 New Revision: 85402 URL: http://llvm.org/viewvc/llvm-project?rev=85402&view=rev Log: llvm.dbg.global_variables do not exist anymore. Modified: llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Modified: llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp?rev=85402&r1=85401&r2=85402&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Wed Oct 28 11:51:52 2009 @@ -290,15 +290,6 @@ Declare->eraseFromParent(); } - // Delete all llvm.dbg.global_variables. - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - GlobalVariable *GV = dyn_cast(I); - if (!GV) continue; - if (GV->use_empty() && GV->getName().startswith("llvm.dbg.global_variable")) - DeadConstants.push_back(GV); - } - while (!DeadConstants.empty()) { Constant *C = DeadConstants.back(); DeadConstants.pop_back(); From jyasskin at google.com Wed Oct 28 11:52:54 2009 From: jyasskin at google.com (Jeffrey Yasskin) Date: Wed, 28 Oct 2009 09:52:54 -0700 Subject: [llvm-commits] [llvm] r85295 - in /llvm/trunk: docs/tutorial/LangImpl4.html docs/tutorial/OCamlLangImpl4.html include/llvm/ExecutionEngine/ExecutionEngine.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngi In-Reply-To: <400d33ea0910280654h64d62c14o7673b5a8dea1ab22@mail.gmail.com> References: <9879CBCC-0704-4FC7-8061-94D382FA7587@apple.com> <4AE7CC5C.5040300@mxc.ca> <02C5660C-FC69-4B07-B329-784D718E49D2@apple.com> <400d33ea0910280654h64d62c14o7673b5a8dea1ab22@mail.gmail.com> Message-ID: On Wed, Oct 28, 2009 at 6:54 AM, Kenneth Uildriks wrote: > On Wed, Oct 28, 2009 at 1:47 AM, Evan Cheng wrote: >> >> On Oct 27, 2009, at 11:07 PM, Jeffrey Yasskin wrote: >> >>> On Tue, Oct 27, 2009 at 10:03 PM, Evan Cheng >>> wrote: >>>> I believe lazy compilation should still be the >>>> default behavior for JIT. If it's not thread safe, then clients who >>>> want JIT >>>> safety should fix it. >>> >>> You say that as if it's an easy thing to do and can be done once and >>> for all. You should probably read the bug (http://llvm.org/PR5184) to >>> see why that's wrong. >> >> I am not saying it's easy. There are clients which do use lazy >> compilation and they don't care about this though. >> >>> >>> As to why lazy compilation should not be the default: it has confused >>> users who tried running their JITs under helgrind and got reports >>> inside one of the most confusing parts of the JIT. When the race >>> actually bites users, it's going to be extremely hard to debug, since >>> it happens when a call is first executed and depends on exactly how >>> the call was aligned. And there are other races in the JIT unless you >>> hold the JIT lock around all IR manipulation. I don't think it's a >>> good idea to make the default behavior of LLVM crash randomly in >>> hard-to-debug ways. Finally, I haven't heard of any cases besides lli >>> where the current lazy JIT is actually the right choice for >>> performance. >> >> To me that's a documentation issue. We're providing lli as the example >> JIT. It defaults to lazy compilation. That will not change since we're >> using it as a JIT test harness. I think it's actually more confusing >> for lli to default to different behavior. >> >> Your usage model is different from others. What you feel is the right >> default behavior is not the same for others. Like I said, there are >> clients who have been using the JIT who do not care about thread >> safety. They are using it in a single-threaded program and want the >> benefit of lazy compilation. >> >> LLVM JIT is not a light weighted JIT. It does everything a static >> compiler code generator would do. Non-lazy compilation may very well >> be unacceptable to a lot of users. >> >>> >>> Now, lazy JITting is safe in a single-threaded program. It might make >>> sense to change the default depending on whether >>> llvm_start_multithreaded() has been called, but that seemed more >>> confusing than saying that you always have to enable it if you want >>> it. >> >> I don't think that's the right solution. It makes the "default" even >> more confusing. I'd prefer it just abort with an error stating the non- >> lazy + multi-threaded configuration being unsupported. >> >> Evan >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > What exactly would break if lazy compilation was disabled? ?The docs > say "the JIT will abort if lazy compilation is ever attempted"... what > exactly would cause this? If lazy jitting is turned on, you generate some call stubs, and then you turn it off and call one, the program will abort. It's not an issue if you leave the setting in a consistent state across the lifetime of the program. From clattner at apple.com Wed Oct 28 11:58:55 2009 From: clattner at apple.com (Chris Lattner) Date: Wed, 28 Oct 2009 09:58:55 -0700 Subject: [llvm-commits] [llvm] r85402 - /llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp In-Reply-To: <200910281651.n9SGprZU009962@zion.cs.uiuc.edu> References: <200910281651.n9SGprZU009962@zion.cs.uiuc.edu> Message-ID: <4F6A0DB0-A22A-477B-B1AB-AAFDEDE73743@apple.com> On Oct 28, 2009, at 9:51 AM, Devang Patel wrote: > Author: dpatel > Date: Wed Oct 28 11:51:52 2009 > New Revision: 85402 > > URL: http://llvm.org/viewvc/llvm-project?rev=85402&view=rev > Log: > llvm.dbg.global_variables do not exist anymore. Do dbg.declares point to global variables anymore? If not, can the whole 'DeadConstants' thing be zapped? -Chris > > > Modified: > llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp > > Modified: llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp?rev=85402&r1=85401&r2=85402&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp (original) > +++ llvm/trunk/lib/Transforms/IPO/StripSymbols.cpp Wed Oct 28 > 11:51:52 2009 > @@ -290,15 +290,6 @@ > Declare->eraseFromParent(); > } > > - // Delete all llvm.dbg.global_variables. > - for (Module::global_iterator I = M.global_begin(), E = > M.global_end(); > - I != E; ++I) { > - GlobalVariable *GV = dyn_cast(I); > - if (!GV) continue; > - if (GV->use_empty() && GV- > >getName().startswith("llvm.dbg.global_variable")) > - DeadConstants.push_back(GV); > - } > - > while (!DeadConstants.empty()) { > Constant *C = DeadConstants.back(); > DeadConstants.pop_back(); > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From bob.wilson at apple.com Wed Oct 28 12:02:06 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Wed, 28 Oct 2009 10:02:06 -0700 Subject: [llvm-commits] [llvm] r85346 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/BranchFolding.cpp lib/CodeGen/BranchFolding.h lib/CodeGen/IfConversion.cpp lib/CodeGen/LLVMTargetMachine.cpp lib/Target/ARM/ARMTargetMachine.cpp In-Reply-To: <08B7FCA0-0A51-4807-9E5E-0E2C021C3246@apple.com> References: <200910272349.n9RNndW8021869@zion.cs.uiuc.edu> <08B7FCA0-0A51-4807-9E5E-0E2C021C3246@apple.com> Message-ID: <5A4E31AD-306B-4B10-BA51-3246EF7F7222@apple.com> On Oct 27, 2009, at 6:15 PM, Evan Cheng wrote: > > On Oct 27, 2009, at 4:49 PM, Bob Wilson wrote: > >> Author: bwilson >> Date: Tue Oct 27 18:49:38 2009 >> New Revision: 85346 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=85346&view=rev >> Log: >> Record CodeGen optimization level in the BranchFolding pass so that >> we can >> use it to control tail merging when there is a tradeoff between >> performance >> and code size. When there is only 1 instruction in the common >> tail, we have >> been merging. That can be good for code size but is a definite >> loss for >> performance. Now we will avoid tail merging in that case when the >> optimization level is "Aggressive", i.e., "-O3". Radar 7338114. > Just then controlling this with optimization level, we should only > do it when the function is marked OptSize. Would that work? I'm not sure I understand what you're asking. Are you suggesting that instead of disabling tail merging of 1 instruction for CodeGenOpt level "Aggressive" (-O3) that we change so that case is disabled by default and only enabled for functions with the OptimizeForSize attribute (which is set by the front-end when using -Os)? If so, yes, I think that would work. In fact, I think it would be a good idea. At -O2, that would mean that we would be optimizing for performance at a small cost in code size. That's a more aggressive change than mine, but I think it would be a good idea. Shall I go ahead with that? From dalej at apple.com Wed Oct 28 12:21:05 2009 From: dalej at apple.com (Dale Johannesen) Date: Wed, 28 Oct 2009 10:21:05 -0700 Subject: [llvm-commits] [llvm] r85346 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/BranchFolding.cpp lib/CodeGen/BranchFolding.h lib/CodeGen/IfConversion.cpp lib/CodeGen/LLVMTargetMachine.cpp lib/Target/ARM/ARMTargetMachine.cpp In-Reply-To: <5A4E31AD-306B-4B10-BA51-3246EF7F7222@apple.com> References: <200910272349.n9RNndW8021869@zion.cs.uiuc.edu> <08B7FCA0-0A51-4807-9E5E-0E2C021C3246@apple.com> <5A4E31AD-306B-4B10-BA51-3246EF7F7222@apple.com> Message-ID: <8D1A77A2-996A-4C2C-93A0-1FFA6F99442A@apple.com> On Oct 28, 2009, at 10:02 AMPDT, Bob Wilson wrote: >>> been merging. That can be good for code size but is a definite >>> loss for >>> performance. Now we will avoid tail merging in that case when the >>> optimization level is "Aggressive", i.e., "-O3". Radar 7338114. >> Just then controlling this with optimization level, we should only >> do it when the function is marked OptSize. Would that work? > > I'm not sure I understand what you're asking. Are you suggesting that > instead of disabling tail merging of 1 instruction for CodeGenOpt > level "Aggressive" (-O3) that we change so that case is disabled by > default and only enabled for functions with the OptimizeForSize > attribute (which is set by the front-end when using -Os)? > > If so, yes, I think that would work. In fact, I think it would be a > good idea. At -O2, that would mean that we would be optimizing for > performance at a small cost in code size. That's a more aggressive > change than mine, but I think it would be a good idea. > > Shall I go ahead with that? Branch folding is a size optimization. It would not surprise me if turning it off completely at -O3 was the right thing for performance. My only strong belief is that any change should be based on measurements, not arguments. From grosbach at apple.com Wed Oct 28 12:33:28 2009 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 28 Oct 2009 17:33:28 -0000 Subject: [llvm-commits] [llvm] r85406 - in /llvm/trunk/lib/Target/ARM: ARMBaseRegisterInfo.cpp Thumb1RegisterInfo.cpp Thumb1RegisterInfo.h Thumb2RegisterInfo.cpp Thumb2RegisterInfo.h Message-ID: <200910281733.n9SHXTPR011600@zion.cs.uiuc.edu> Author: grosbach Date: Wed Oct 28 12:33:28 2009 New Revision: 85406 URL: http://llvm.org/viewvc/llvm-project?rev=85406&view=rev Log: Cleanup now that frame index scavenging via post-pass is working for ARM and Thumb2. Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.cpp llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.h Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=85406&r1=85405&r2=85406&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Wed Oct 28 12:33:28 2009 @@ -41,11 +41,6 @@ using namespace llvm; static cl::opt -ScavengeFrameIndexVals("arm-virtual-frame-index-vals", cl::Hidden, - cl::init(true), - cl::desc("Resolve frame index values via scavenging in PEI")); - -static cl::opt ReuseFrameIndexVals("arm-reuse-frame-index-vals", cl::Hidden, cl::init(true), cl::desc("Reuse repeated frame index values")); @@ -1022,7 +1017,7 @@ bool ARMBaseRegisterInfo:: requiresFrameIndexScavenging(const MachineFunction &MF) const { - return ScavengeFrameIndexVals; + return true; } // hasReservedCallFrame - Under normal circumstances, when a frame pointer is @@ -1100,17 +1095,6 @@ MBB.erase(I); } -/// findScratchRegister - Find a 'free' ARM register. If register scavenger -/// is not being used, R12 is available. Otherwise, try for a call-clobbered -/// register first and then a spilled callee-saved register if that fails. -static -unsigned findScratchRegister(RegScavenger *RS, const TargetRegisterClass *RC, - ARMFunctionInfo *AFI) { - unsigned Reg = RS ? RS->FindUnusedReg(RC) : (unsigned) ARM::R12; - assert(!AFI->isThumb1OnlyFunction()); - return Reg; -} - unsigned ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, int *Value, @@ -1186,19 +1170,8 @@ // Must be addrmode4. MI.getOperand(i).ChangeToRegister(FrameReg, false, false, false); else { - if (!ScavengeFrameIndexVals) { - // Insert a set of r12 with the full address: r12 = sp + offset - // If the offset we have is too large to fit into the instruction, we need - // to form it with a series of ADDri's. Do this by taking 8-bit chunks - // out of 'Offset'. - ScratchReg = findScratchRegister(RS, ARM::GPRRegisterClass, AFI); - if (ScratchReg == 0) - // No register is "free". Scavenge a register. - ScratchReg = RS->scavengeRegister(ARM::GPRRegisterClass, II, SPAdj); - } else { - ScratchReg = MF.getRegInfo().createVirtualRegister(ARM::GPRRegisterClass); - *Value = Offset; - } + ScratchReg = MF.getRegInfo().createVirtualRegister(ARM::GPRRegisterClass); + if (Value) *Value = Offset; if (!AFI->isThumbFunction()) emitARMRegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg, Offset, Pred, PredReg, TII); @@ -1208,7 +1181,7 @@ Offset, Pred, PredReg, TII); } MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true); - if (!ReuseFrameIndexVals || !ScavengeFrameIndexVals) + if (!ReuseFrameIndexVals) ScratchReg = 0; } return ScratchReg; Modified: llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp?rev=85406&r1=85405&r2=85406&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp Wed Oct 28 12:33:28 2009 @@ -76,18 +76,6 @@ return TargetRegisterInfo::getPhysicalRegisterRegClass(Reg, VT); } -bool -Thumb1RegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { - return true; -} - -bool -Thumb1RegisterInfo::requiresFrameIndexScavenging(const MachineFunction &MF) - const { - return true; -} - - bool Thumb1RegisterInfo::hasReservedCallFrame(MachineFunction &MF) const { const MachineFrameInfo *FFI = MF.getFrameInfo(); unsigned CFSize = FFI->getMaxCallFrameSize(); Modified: llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h?rev=85406&r1=85405&r2=85406&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h (original) +++ llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h Wed Oct 28 12:33:28 2009 @@ -40,9 +40,6 @@ const TargetRegisterClass * getPhysicalRegisterRegClass(unsigned Reg, EVT VT = MVT::Other) const; - bool requiresRegisterScavenging(const MachineFunction &MF) const; - bool requiresFrameIndexScavenging(const MachineFunction &MF) const; - bool hasReservedCallFrame(MachineFunction &MF) const; void eliminateCallFramePseudoInstr(MachineFunction &MF, Modified: llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.cpp?rev=85406&r1=85405&r2=85406&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.cpp Wed Oct 28 12:33:28 2009 @@ -60,8 +60,3 @@ .addReg(DestReg, getDefRegState(true), SubIdx) .addConstantPoolIndex(Idx).addImm((int64_t)ARMCC::AL).addReg(0); } - -bool Thumb2RegisterInfo:: -requiresRegisterScavenging(const MachineFunction &MF) const { - return true; -} Modified: llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.h?rev=85406&r1=85405&r2=85406&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.h (original) +++ llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.h Wed Oct 28 12:33:28 2009 @@ -35,8 +35,6 @@ unsigned DestReg, unsigned SubIdx, int Val, ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) const; - - bool requiresRegisterScavenging(const MachineFunction &MF) const; }; } From dalej at apple.com Wed Oct 28 12:38:51 2009 From: dalej at apple.com (Dale Johannesen) Date: Wed, 28 Oct 2009 17:38:51 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r85407 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200910281738.n9SHcpoN011805@zion.cs.uiuc.edu> Author: johannes Date: Wed Oct 28 12:38:51 2009 New Revision: 85407 URL: http://llvm.org/viewvc/llvm-project?rev=85407&view=rev Log: Remove used-uninitialized warning. Add an assert to make it clearer to humans there is no uninitialized use, but there's no way a compiler could figure it out. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=85407&r1=85406&r2=85407&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed Oct 28 12:38:51 2009 @@ -7774,7 +7774,7 @@ uint64_t GCCFieldOffsetInBits = getFieldOffsetInBits(Field); NextField = TREE_CHAIN(Field); - uint64_t FieldSizeInBits; + uint64_t FieldSizeInBits = 0; if (DECL_SIZE(Field)) FieldSizeInBits = getInt64(DECL_SIZE(Field), true); uint64_t ValueSizeInBits = Val->getType()->getPrimitiveSizeInBits(); @@ -7803,6 +7803,7 @@ // Bitfields can only be initialized with constants (integer constant // expressions). assert(ValC); + assert(DECL_SIZE(Field)); assert(ValueSizeInBits >= FieldSizeInBits && "disagreement between LLVM and GCC on bitfield size"); if (ValueSizeInBits != FieldSizeInBits) { From clattner at apple.com Wed Oct 28 12:38:45 2009 From: clattner at apple.com (Chris Lattner) Date: Wed, 28 Oct 2009 10:38:45 -0700 Subject: [llvm-commits] [llvm] r85346 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/BranchFolding.cpp lib/CodeGen/BranchFolding.h lib/CodeGen/IfConversion.cpp lib/CodeGen/LLVMTargetMachine.cpp lib/Target/ARM/ARMTargetMachine.cpp In-Reply-To: <8D1A77A2-996A-4C2C-93A0-1FFA6F99442A@apple.com> References: <200910272349.n9RNndW8021869@zion.cs.uiuc.edu> <08B7FCA0-0A51-4807-9E5E-0E2C021C3246@apple.com> <5A4E31AD-306B-4B10-BA51-3246EF7F7222@apple.com> <8D1A77A2-996A-4C2C-93A0-1FFA6F99442A@apple.com> Message-ID: On Oct 28, 2009, at 10:21 AM, Dale Johannesen wrote: >> If so, yes, I think that would work. In fact, I think it would be a >> good idea. At -O2, that would mean that we would be optimizing for >> performance at a small cost in code size. That's a more aggressive >> change than mine, but I think it would be a good idea. >> >> Shall I go ahead with that? > > Branch folding is a size optimization. It would not surprise me if > turning it off completely at > -O3 was the right thing for performance. My only strong belief is > that any change should be based on measurements, not arguments. Doesn't it also do some code layout to encourage better fall-throughs etc? -Chris From dalej at apple.com Wed Oct 28 12:41:45 2009 From: dalej at apple.com (Dale Johannesen) Date: Wed, 28 Oct 2009 10:41:45 -0700 Subject: [llvm-commits] [llvm] r85346 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/BranchFolding.cpp lib/CodeGen/BranchFolding.h lib/CodeGen/IfConversion.cpp lib/CodeGen/LLVMTargetMachine.cpp lib/Target/ARM/ARMTargetMachine.cpp In-Reply-To: References: <200910272349.n9RNndW8021869@zion.cs.uiuc.edu> <08B7FCA0-0A51-4807-9E5E-0E2C021C3246@apple.com> <5A4E31AD-306B-4B10-BA51-3246EF7F7222@apple.com> <8D1A77A2-996A-4C2C-93A0-1FFA6F99442A@apple.com> Message-ID: On Oct 28, 2009, at 10:38 AMPDT, Chris Lattner wrote: > > On Oct 28, 2009, at 10:21 AM, Dale Johannesen wrote: > >>> If so, yes, I think that would work. In fact, I think it would be a >>> good idea. At -O2, that would mean that we would be optimizing for >>> performance at a small cost in code size. That's a more aggressive >>> change than mine, but I think it would be a good idea. >>> >>> Shall I go ahead with that? >> >> Branch folding is a size optimization. It would not surprise me if >> turning it off completely at >> -O3 was the right thing for performance. My only strong belief is >> that any change should be based on measurements, not arguments. > > Doesn't it also do some code layout to encourage better fall- > throughs etc? Yes; I meant tail merging, not all of branch folding, sorry. From grosbach at apple.com Wed Oct 28 12:59:48 2009 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 28 Oct 2009 10:59:48 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r85407 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: <200910281738.n9SHcpoN011805@zion.cs.uiuc.edu> References: <200910281738.n9SHcpoN011805@zion.cs.uiuc.edu> Message-ID: <758AB3F8-3299-4643-987D-BEE7F24977DE@apple.com> Thanks, Dale! -j On Oct 28, 2009, at 10:38 AM, Dale Johannesen wrote: > Author: johannes > Date: Wed Oct 28 12:38:51 2009 > New Revision: 85407 > > URL: http://llvm.org/viewvc/llvm-project?rev=85407&view=rev > Log: > Remove used-uninitialized warning. Add an assert to > make it clearer to humans there is no uninitialized use, > but there's no way a compiler could figure it out. > > > Modified: > llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp > > Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=85407&r1=85406&r2=85407&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) > +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed Oct 28 12:38:51 2009 > @@ -7774,7 +7774,7 @@ > uint64_t GCCFieldOffsetInBits = getFieldOffsetInBits(Field); > NextField = TREE_CHAIN(Field); > > - uint64_t FieldSizeInBits; > + uint64_t FieldSizeInBits = 0; > if (DECL_SIZE(Field)) > FieldSizeInBits = getInt64(DECL_SIZE(Field), true); > uint64_t ValueSizeInBits = Val->getType()->getPrimitiveSizeInBits > (); > @@ -7803,6 +7803,7 @@ > // Bitfields can only be initialized with constants (integer > constant > // expressions). > assert(ValC); > + assert(DECL_SIZE(Field)); > assert(ValueSizeInBits >= FieldSizeInBits && > "disagreement between LLVM and GCC on bitfield size"); > if (ValueSizeInBits != FieldSizeInBits) { > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From bob.wilson at apple.com Wed Oct 28 12:58:16 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Wed, 28 Oct 2009 10:58:16 -0700 Subject: [llvm-commits] [llvm] r85346 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/BranchFolding.cpp lib/CodeGen/BranchFolding.h lib/CodeGen/IfConversion.cpp lib/CodeGen/LLVMTargetMachine.cpp lib/Target/ARM/ARMTargetMachine.cpp In-Reply-To: References: <200910272349.n9RNndW8021869@zion.cs.uiuc.edu> <08B7FCA0-0A51-4807-9E5E-0E2C021C3246@apple.com> <5A4E31AD-306B-4B10-BA51-3246EF7F7222@apple.com> <8D1A77A2-996A-4C2C-93A0-1FFA6F99442A@apple.com> Message-ID: <334A7112-990A-4D8C-AE3A-44CF7F92339D@apple.com> On Oct 28, 2009, at 10:41 AM, Dale Johannesen wrote: > > On Oct 28, 2009, at 10:38 AMPDT, Chris Lattner wrote: > >> >> On Oct 28, 2009, at 10:21 AM, Dale Johannesen wrote: >> >>>> If so, yes, I think that would work. In fact, I think it would >>>> be a >>>> good idea. At -O2, that would mean that we would be optimizing for >>>> performance at a small cost in code size. That's a more aggressive >>>> change than mine, but I think it would be a good idea. >>>> >>>> Shall I go ahead with that? >>> >>> Branch folding is a size optimization. It would not surprise me if >>> turning it off completely at >>> -O3 was the right thing for performance. My only strong belief is >>> that any change should be based on measurements, not arguments. >> >> Doesn't it also do some code layout to encourage better fall- >> throughs etc? > > Yes; I meant tail merging, not all of branch folding, sorry. > We could do a combination of these: -Os: Tail merge even for 1 instruction tails. -O2: Tail merge for > 1 instruction tails. -O3: No tail merging. The more conservative change I made yesterday was indeed based on measurements. I agree that is important. From evan.cheng at apple.com Wed Oct 28 13:10:15 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 28 Oct 2009 11:10:15 -0700 Subject: [llvm-commits] [llvm] r85346 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/BranchFolding.cpp lib/CodeGen/BranchFolding.h lib/CodeGen/IfConversion.cpp lib/CodeGen/LLVMTargetMachine.cpp lib/Target/ARM/ARMTargetMachine.cpp In-Reply-To: References: <200910272349.n9RNndW8021869@zion.cs.uiuc.edu> <08B7FCA0-0A51-4807-9E5E-0E2C021C3246@apple.com> <5A4E31AD-306B-4B10-BA51-3246EF7F7222@apple.com> <8D1A77A2-996A-4C2C-93A0-1FFA6F99442A@apple.com> Message-ID: <4238F010-971E-45BE-8C7B-3F690E02D2CD@apple.com> On Oct 28, 2009, at 10:38 AM, Chris Lattner wrote: > > On Oct 28, 2009, at 10:21 AM, Dale Johannesen wrote: > >>> If so, yes, I think that would work. In fact, I think it would be a >>> good idea. At -O2, that would mean that we would be optimizing for >>> performance at a small cost in code size. That's a more aggressive >>> change than mine, but I think it would be a good idea. >>> >>> Shall I go ahead with that? >> >> Branch folding is a size optimization. It would not surprise me if >> turning it off completely at >> -O3 was the right thing for performance. My only strong belief is >> that any change should be based on measurements, not arguments. > > Doesn't it also do some code layout to encourage better fall-throughs > etc? > That has been removed. The heuristics have shown to do as much harm on x86 as good. On ARM (especially Thumb), it's badness. Block layout optimizations are now done in CodePlacementOpt.cpp. Evan > -Chris > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Wed Oct 28 13:18:37 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 28 Oct 2009 11:18:37 -0700 Subject: [llvm-commits] [llvm] r85346 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/BranchFolding.cpp lib/CodeGen/BranchFolding.h lib/CodeGen/IfConversion.cpp lib/CodeGen/LLVMTargetMachine.cpp lib/Target/ARM/ARMTargetMachine.cpp In-Reply-To: <334A7112-990A-4D8C-AE3A-44CF7F92339D@apple.com> References: <200910272349.n9RNndW8021869@zion.cs.uiuc.edu> <08B7FCA0-0A51-4807-9E5E-0E2C021C3246@apple.com> <5A4E31AD-306B-4B10-BA51-3246EF7F7222@apple.com> <8D1A77A2-996A-4C2C-93A0-1FFA6F99442A@apple.com> <334A7112-990A-4D8C-AE3A-44CF7F92339D@apple.com> Message-ID: <2B5F42E9-17DD-4233-9A0D-A73FC5D770B5@apple.com> On Oct 28, 2009, at 10:58 AM, Bob Wilson wrote: > > On Oct 28, 2009, at 10:41 AM, Dale Johannesen wrote: > >> >> On Oct 28, 2009, at 10:38 AMPDT, Chris Lattner wrote: >> >>> >>> On Oct 28, 2009, at 10:21 AM, Dale Johannesen wrote: >>> >>>>> If so, yes, I think that would work. In fact, I think it would >>>>> be a >>>>> good idea. At -O2, that would mean that we would be optimizing for >>>>> performance at a small cost in code size. That's a more aggressive >>>>> change than mine, but I think it would be a good idea. >>>>> >>>>> Shall I go ahead with that? >>>> >>>> Branch folding is a size optimization. It would not surprise me if >>>> turning it off completely at >>>> -O3 was the right thing for performance. My only strong belief is >>>> that any change should be based on measurements, not arguments. >>> >>> Doesn't it also do some code layout to encourage better fall- >>> throughs etc? >> >> Yes; I meant tail merging, not all of branch folding, sorry. >> > > We could do a combination of these: > > -Os: Tail merge even for 1 instruction tails. > -O2: Tail merge for > 1 instruction tails. > -O3: No tail merging. > > The more conservative change I made yesterday was indeed based on > measurements. I agree that is important. This is tricky. I don't think there is a *right* answer. On x86, I don't believe the extra branch matters. To me, tail merge for 1 instruction tails is not saving much code size and it's potentially bad for performance. We should disable it except for -Os. I don't know if we want to differentiate between -O2 and -O3 here. We either do tail merging or we disable tail merging. Unless we can show it does hurt performance I'd prefer to leave it along. Evan > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From bob.wilson at apple.com Wed Oct 28 13:16:21 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Wed, 28 Oct 2009 11:16:21 -0700 Subject: [llvm-commits] [llvm] r85346 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/BranchFolding.cpp lib/CodeGen/BranchFolding.h lib/CodeGen/IfConversion.cpp lib/CodeGen/LLVMTargetMachine.cpp lib/Target/ARM/ARMTargetMachine.cpp In-Reply-To: <4238F010-971E-45BE-8C7B-3F690E02D2CD@apple.com> References: <200910272349.n9RNndW8021869@zion.cs.uiuc.edu> <08B7FCA0-0A51-4807-9E5E-0E2C021C3246@apple.com> <5A4E31AD-306B-4B10-BA51-3246EF7F7222@apple.com> <8D1A77A2-996A-4C2C-93A0-1FFA6F99442A@apple.com> <4238F010-971E-45BE-8C7B-3F690E02D2CD@apple.com> Message-ID: <105D43A4-5D5C-4080-9297-75A89AAD515E@apple.com> On Oct 28, 2009, at 11:10 AM, Evan Cheng wrote: > > On Oct 28, 2009, at 10:38 AM, Chris Lattner wrote: > >> >> On Oct 28, 2009, at 10:21 AM, Dale Johannesen wrote: >> >>>> If so, yes, I think that would work. In fact, I think it would >>>> be a >>>> good idea. At -O2, that would mean that we would be optimizing for >>>> performance at a small cost in code size. That's a more aggressive >>>> change than mine, but I think it would be a good idea. >>>> >>>> Shall I go ahead with that? >>> >>> Branch folding is a size optimization. It would not surprise me if >>> turning it off completely at >>> -O3 was the right thing for performance. My only strong belief is >>> that any change should be based on measurements, not arguments. >> >> Doesn't it also do some code layout to encourage better fall-throughs >> etc? >> > That has been removed. The heuristics have shown to do as much harm > on x86 as good. On ARM (especially Thumb), it's badness. Block > layout optimizations are now done in CodePlacementOpt.cpp. Some code layout is still done in BranchFolding. For blocks with no successors, we still do the same transformation that we were doing before in BranchFolding. Dan just changed it to not apply to all blocks ending with unconditional branches. This doesn't really matter, since Dale clarified that he was specifically referring to tail merging, and not to all of BranchFolding. From evan.cheng at apple.com Wed Oct 28 13:19:56 2009 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 28 Oct 2009 18:19:56 -0000 Subject: [llvm-commits] [llvm] r85410 - /llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Message-ID: <200910281819.n9SIJvXw013596@zion.cs.uiuc.edu> Author: evancheng Date: Wed Oct 28 13:19:56 2009 New Revision: 85410 URL: http://llvm.org/viewvc/llvm-project?rev=85410&view=rev Log: fconsts and fconstd are obviously re-materializable. Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=85410&r1=85409&r2=85410&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Wed Oct 28 13:19:56 2009 @@ -431,6 +431,7 @@ // Materialize FP immediates. VFP3 only. +let isReMaterializable = 1 in def FCONSTS : VFPAI<(outs SPR:$dst), (ins vfp_f32imm:$imm), VFPMiscFrm, IIC_VMOVImm, "fconsts", "\t$dst, $imm", @@ -442,6 +443,7 @@ let Inst{7-4} = 0b0000; } +let isReMaterializable = 1 in def FCONSTD : VFPAI<(outs DPR:$dst), (ins vfp_f64imm:$imm), VFPMiscFrm, IIC_VMOVImm, "fconstd", "\t$dst, $imm", From bob.wilson at apple.com Wed Oct 28 13:26:41 2009 From: bob.wilson at apple.com (Bob Wilson) Date: Wed, 28 Oct 2009 18:26:41 -0000 Subject: [llvm-commits] [llvm] r85411 - in /llvm/trunk/lib/Target/ARM: ARMBaseInstrInfo.cpp ARMBaseInstrInfo.h ARMInstrInfo.cpp ARMInstrInfo.td ARMInstrThumb.td Thumb1InstrInfo.cpp Thumb2InstrInfo.cpp Message-ID: <200910281826.n9SIQg7o013848@zion.cs.uiuc.edu> Author: bwilson Date: Wed Oct 28 13:26:41 2009 New Revision: 85411 URL: http://llvm.org/viewvc/llvm-project?rev=85411&view=rev Log: Add a Thumb BRIND pattern. Change the ARM BRIND assembly to separate the opcode and operand with a tab. Check for these instructions in the usual places. Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/ARMInstrThumb.td llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.cpp llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.cpp Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=85411&r1=85410&r2=85411&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Wed Oct 28 13:26:41 2009 @@ -249,7 +249,8 @@ // ...likewise if it ends with a branch table followed by an unconditional // branch. The branch folder can create these, and we must get rid of them for // correctness of Thumb constant islands. - if (isJumpTableBranchOpcode(SecondLastOpc) && + if ((isJumpTableBranchOpcode(SecondLastOpc) || + isIndirectBranchOpcode(SecondLastOpc)) && isUncondBranchOpcode(LastOpc)) { I = LastInst; if (AllowModify) Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=85411&r1=85410&r2=85411&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Wed Oct 28 13:26:41 2009 @@ -293,6 +293,11 @@ Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT; } +static inline +bool isIndirectBranchOpcode(int Opc) { + return Opc == ARM::BRIND || Opc == ARM::tBRIND; +} + /// getInstrPredicate - If instruction is predicated, returns its predicate /// condition, otherwise returns AL. It also returns the condition code /// register by reference. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp?rev=85411&r1=85410&r2=85411&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp Wed Oct 28 13:26:41 2009 @@ -67,6 +67,7 @@ case ARM::BX_RET: // Return. case ARM::LDM_RET: case ARM::B: + case ARM::BRIND: case ARM::BR_JTr: // Jumptable branch. case ARM::BR_JTm: // Jumptable branch through mem. case ARM::BR_JTadd: // Jumptable branch add to pc. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=85411&r1=85410&r2=85411&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Wed Oct 28 13:26:41 2009 @@ -659,7 +659,7 @@ // Indirect branches let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { - def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx $dst", + def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst", [(brind GPR:$dst)]> { let Inst{7-4} = 0b0001; let Inst{19-8} = 0b111111111111; Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=85411&r1=85410&r2=85411&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Wed Oct 28 13:26:41 2009 @@ -180,6 +180,12 @@ def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t$target", []>; } +// Indirect branches +let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { + def tBRIND : TI<(outs), (ins GPR:$dst), IIC_Br, "bx\t$dst", + [(brind GPR:$dst)]>; +} + // FIXME: remove when we have a way to marking a MI with these properties. let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, hasExtraDefRegAllocReq = 1 in Modified: llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.cpp?rev=85411&r1=85410&r2=85411&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.cpp Wed Oct 28 13:26:41 2009 @@ -38,6 +38,7 @@ case ARM::tBX_RET_vararg: case ARM::tPOP_RET: case ARM::tB: + case ARM::tBRIND: case ARM::tBR_JTr: return true; default: Modified: llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.cpp?rev=85411&r1=85410&r2=85411&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.cpp Wed Oct 28 13:26:41 2009 @@ -46,6 +46,7 @@ case ARM::tBX_RET_vararg: case ARM::tPOP_RET: case ARM::tB: + case ARM::tBRIND: return true; default: break; From david_goodwin at apple.com Wed Oct 28 13:29:54 2009 From: david_goodwin at apple.com (David Goodwin) Date: Wed, 28 Oct 2009 18:29:54 -0000 Subject: [llvm-commits] [llvm] r85412 - in /llvm/trunk: include/llvm/CodeGen/AntiDepBreaker.h lib/CodeGen/AggressiveAntiDepBreaker.h lib/CodeGen/AntiDepBreaker.h lib/CodeGen/CriticalAntiDepBreaker.h lib/CodeGen/PostRASchedulerList.cpp Message-ID: <200910281829.n9SITt4M013951@zion.cs.uiuc.edu> Author: david_goodwin Date: Wed Oct 28 13:29:54 2009 New Revision: 85412 URL: http://llvm.org/viewvc/llvm-project?rev=85412&view=rev Log: Make AntiDepReg.h internal. Added: llvm/trunk/lib/CodeGen/AntiDepBreaker.h - copied unchanged from r85166, llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Removed: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Modified: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Removed: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h?rev=85411&view=auto ============================================================================== --- llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h (original) +++ llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h (removed) @@ -1,62 +0,0 @@ -//=- llvm/CodeGen/AntiDepBreaker.h - Anti-Dependence Breaking -*- C++ -*-=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the AntiDepBreaker class, which implements -// anti-dependence breaking heuristics for post-register-allocation scheduling. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_ANTIDEPBREAKER_H -#define LLVM_CODEGEN_ANTIDEPBREAKER_H - -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/ScheduleDAG.h" -#include "llvm/Target/TargetRegisterInfo.h" - -namespace llvm { - -/// AntiDepBreaker - This class works into conjunction with the -/// post-RA scheduler to rename registers to break register -/// anti-dependencies. -class AntiDepBreaker { -public: - virtual ~AntiDepBreaker(); - - /// GetMaxTrials - Return the maximum number of anti-dependence - /// breaking attempts that will be made for a block. - virtual unsigned GetMaxTrials() =0; - - /// Start - Initialize anti-dep breaking for a new basic block. - virtual void StartBlock(MachineBasicBlock *BB) =0; - - /// BreakAntiDependencies - Identifiy anti-dependencies within a - /// basic-block region and break them by renaming registers. Return - /// the number of anti-dependencies broken. - /// - virtual unsigned BreakAntiDependencies(std::vector& SUnits, - MachineBasicBlock::iterator& Begin, - MachineBasicBlock::iterator& End, - unsigned InsertPosIndex) =0; - - /// Observe - Update liveness information to account for the current - /// instruction, which will not be scheduled. - /// - virtual void Observe(MachineInstr *MI, unsigned Count, - unsigned InsertPosIndex) =0; - - /// Finish - Finish anti-dep breaking for a basic block. - virtual void FinishBlock() =0; -}; - -} - -#endif Modified: llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h?rev=85412&r1=85411&r2=85412&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h (original) +++ llvm/trunk/lib/CodeGen/AggressiveAntiDepBreaker.h Wed Oct 28 13:29:54 2009 @@ -17,7 +17,7 @@ #ifndef LLVM_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H #define LLVM_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H -#include "llvm/CodeGen/AntiDepBreaker.h" +#include "AntiDepBreaker.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" Modified: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h?rev=85412&r1=85411&r2=85412&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h (original) +++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h Wed Oct 28 13:29:54 2009 @@ -16,7 +16,7 @@ #ifndef LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H #define LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H -#include "llvm/CodeGen/AntiDepBreaker.h" +#include "AntiDepBreaker.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=85412&r1=85411&r2=85412&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Wed Oct 28 13:29:54 2009 @@ -19,12 +19,12 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "post-RA-sched" +#include "AntiDepBreaker.h" #include "AggressiveAntiDepBreaker.h" #include "CriticalAntiDepBreaker.h" #include "ExactHazardRecognizer.h" #include "SimpleHazardRecognizer.h" #include "ScheduleDAGInstrs.h" -#include "llvm/CodeGen/AntiDepBreaker.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/LatencyPriorityQueue.h" #include "llvm/CodeGen/SchedulerRegistry.h" From benny.kra at googlemail.com Wed Oct 28 13:37:32 2009 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Wed, 28 Oct 2009 18:37:32 -0000 Subject: [llvm-commits] [llvm] r85414 - /llvm/trunk/cmake/config-ix.cmake Message-ID: <200910281837.n9SIbWo5014189@zion.cs.uiuc.edu> Author: d0k Date: Wed Oct 28 13:37:31 2009 New Revision: 85414 URL: http://llvm.org/viewvc/llvm-project?rev=85414&view=rev Log: Teach cmake that mk[sd]temp is defined in stdlib.h on some systems. This fixes parallel build with clang on glibc platforms. Modified: llvm/trunk/cmake/config-ix.cmake Modified: llvm/trunk/cmake/config-ix.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/config-ix.cmake?rev=85414&r1=85413&r2=85414&view=diff ============================================================================== --- llvm/trunk/cmake/config-ix.cmake (original) +++ llvm/trunk/cmake/config-ix.cmake Wed Oct 28 13:37:31 2009 @@ -83,9 +83,9 @@ check_symbol_exists(mallinfo malloc.h HAVE_MALLINFO) check_symbol_exists(malloc_zone_statistics malloc/malloc.h HAVE_MALLOC_ZONE_STATISTICS) -check_symbol_exists(mkdtemp unistd.h HAVE_MKDTEMP) -check_symbol_exists(mkstemp unistd.h HAVE_MKSTEMP) -check_symbol_exists(mktemp unistd.h HAVE_MKTEMP) +check_symbol_exists(mkdtemp "stdlib.h;unistd.h" HAVE_MKDTEMP) +check_symbol_exists(mkstemp "stdlib.h;unistd.h" HAVE_MKSTEMP) +check_symbol_exists(mktemp "stdlib.h;unistd.h" HAVE_MKTEMP) check_symbol_exists(pthread_mutex_lock pthread.h HAVE_PTHREAD_MUTEX_LOCK) check_symbol_exists(sbrk unistd.h HAVE_SBRK) check_symbol_exists(strtoll stdlib.h HAVE_STRTOLL) From vkutuzov at accesssoftek.com Wed Oct 28 13:55:55 2009 From: vkutuzov at accesssoftek.com (Viktor Kutuzov) Date: Wed, 28 Oct 2009 18:55:55 -0000 Subject: [llvm-commits] [llvm] r85419 - /llvm/trunk/tools/gold/gold-plugin.cpp Message-ID: <200910281855.n9SItt4r014991@zion.cs.uiuc.edu> Author: vkutuzov Date: Wed Oct 28 13:55:55 2009 New Revision: 85419 URL: http://llvm.org/viewvc/llvm-project?rev=85419&view=rev Log: Fix to pass options from Gold plugin to LTO codegen Modified: llvm/trunk/tools/gold/gold-plugin.cpp Modified: llvm/trunk/tools/gold/gold-plugin.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/gold/gold-plugin.cpp?rev=85419&r1=85418&r2=85419&view=diff ============================================================================== --- llvm/trunk/tools/gold/gold-plugin.cpp (original) +++ llvm/trunk/tools/gold/gold-plugin.cpp Wed Oct 28 13:55:55 2009 @@ -46,9 +46,6 @@ int api_version = 0; int gold_version = 0; - bool generate_api_file = false; - const char *as_path = NULL; - struct claimed_file { lto_module_t M; void *handle; @@ -60,6 +57,37 @@ std::vector Cleanup; } +namespace options { + bool generate_api_file = false; + const char *as_path = NULL; + // Additional options to pass into the code generator. + // Note: This array will contain all plugin options which are not claimed + // as plugin exclusive to pass to the code generator. + // For example, "generate-api-file" and "as"options are for the plugin + // use only and will not be passed. + std::vector extra; + + void process_plugin_option(const char* opt) + { + if (opt == NULL) + return; + + if (strcmp("generate-api-file", opt) == 0) { + generate_api_file = true; + } else if (strncmp("as=", opt, 3) == 0) { + if (as_path) { + (*message)(LDPL_WARNING, "Path to as specified twice. " + "Discarding %s", opt); + } else { + as_path = strdup(opt + 3); + } + } else { + // Save this option to pass to the code generator. + extra.push_back(std::string(opt)); + } + } +} + ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, int *claimed); ld_plugin_status all_symbols_read_hook(void); @@ -103,18 +131,7 @@ //output_type = LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC; break; case LDPT_OPTION: - if (strcmp("generate-api-file", tv->tv_u.tv_string) == 0) { - generate_api_file = true; - } else if (strncmp("as=", tv->tv_u.tv_string, 3) == 0) { - if (as_path) { - (*message)(LDPL_WARNING, "Path to as specified twice. " - "Discarding %s", tv->tv_u.tv_string); - } else { - as_path = strdup(tv->tv_u.tv_string + 3); - } - } else { - (*message)(LDPL_WARNING, "Ignoring flag %s", tv->tv_u.tv_string); - } + options::process_plugin_option(tv->tv_u.tv_string); break; case LDPT_REGISTER_CLAIM_FILE_HOOK: { ld_plugin_register_claim_file callback; @@ -307,7 +324,7 @@ lto_codegen_add_module(cg, I->M); std::ofstream api_file; - if (generate_api_file) { + if (options::generate_api_file) { api_file.open("apifile.txt", std::ofstream::out | std::ofstream::trunc); if (!api_file.is_open()) { (*message)(LDPL_FATAL, "Unable to open apifile.txt for writing."); @@ -329,13 +346,13 @@ lto_codegen_add_must_preserve_symbol(cg, I->syms[i].name); anySymbolsPreserved = true; - if (generate_api_file) + if (options::generate_api_file) api_file << I->syms[i].name << "\n"; } } } - if (generate_api_file) + if (options::generate_api_file) api_file.close(); if (!anySymbolsPreserved) { @@ -347,10 +364,17 @@ lto_codegen_set_pic_model(cg, output_type); lto_codegen_set_debug_model(cg, LTO_DEBUG_MODEL_DWARF); - if (as_path) { - sys::Path p = sys::Program::FindProgramByName(as_path); + if (options::as_path) { + sys::Path p = sys::Program::FindProgramByName(options::as_path); lto_codegen_set_assembler_path(cg, p.c_str()); } + // Pass through extra options to the code generator. + if (!options::extra.empty()) { + for (std::vector::iterator it = options::extra.begin(); + it != options::extra.end(); ++it) { + lto_codegen_debug_options(cg, (*it).c_str()); + } + } size_t bufsize = 0; const char *buffer = static_cast(lto_codegen_compile(cg, From tonic at nondot.org Wed Oct 28 15:13:57 2009 From: tonic at nondot.org (Tanya Lattner) Date: Wed, 28 Oct 2009 15:13:57 -0500 Subject: [llvm-commits] CVS: llvm-www/releases/download.html Message-ID: <200910282013.n9SKDv2l018201@zion.cs.uiuc.edu> Changes in directory llvm-www/releases: download.html updated: 1.64 -> 1.65 --- Log message: Remove extra space --- Diffs of the changes: (+1 -2) download.html | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm-www/releases/download.html diff -u llvm-www/releases/download.html:1.64 llvm-www/releases/download.html:1.65 --- llvm-www/releases/download.html:1.64 Fri Oct 23 23:48:37 2009 +++ llvm-www/releases/download.html Wed Oct 28 15:12:57 2009 @@ -37,8 +37,7 @@
    • LLVM source code (7.4M)
    • LLVM Test Suite (67M)
    • -
    • LLVM-GCC 4.2 Front End Source Code (46M)< -/li> +
    • LLVM-GCC 4.2 Front End Source Code (46M)
    • Clang source code (3.7M)
    • Clang Binaries for FreeBSD8/x86 (52M)
    • Clang Binaries for FreeBSD8/x86_64 (55M)
    • From vhernandez at apple.com Wed Oct 28 15:18:56 2009 From: vhernandez at apple.com (Victor Hernandez) Date: Wed, 28 Oct 2009 20:18:56 -0000 Subject: [llvm-commits] [llvm] r85421 - in /llvm/trunk: include/llvm/Analysis/MemoryBuiltins.h lib/Analysis/MemoryBuiltins.cpp lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/heap-sra-3.ll test/Transforms/GlobalOpt/heap-sra-4.ll Message-ID: <200910282018.n9SKIuC3018458@zion.cs.uiuc.edu> Author: hernande Date: Wed Oct 28 15:18:55 2009 New Revision: 85421 URL: http://llvm.org/viewvc/llvm-project?rev=85421&view=rev Log: Extend getMallocArraySize() to determine the array size if the malloc argument is: ArraySize * ElementSize ElementSize * ArraySize ArraySize << log2(ElementSize) ElementSize << log2(ArraySize) Refactor isArrayMallocHelper and delete isSafeToGetMallocArraySize, so that there is only 1 copy of the malloc array determining logic. Update users of getMallocArraySize() to not bother calling isArrayMalloc() as well. Added: llvm/trunk/test/Transforms/GlobalOpt/heap-sra-3.ll llvm/trunk/test/Transforms/GlobalOpt/heap-sra-4.ll Modified: llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h llvm/trunk/lib/Analysis/MemoryBuiltins.cpp llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h?rev=85421&r1=85420&r2=85421&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h Wed Oct 28 15:18:55 2009 @@ -43,15 +43,8 @@ CallInst* extractMallocCallFromBitCast(Valu