Compare commits
No commits in common. "dev" and "master" have entirely different histories.
BIN
.DS_Store
vendored
Normal file
BIN
.DS_Store
vendored
Normal file
Binary file not shown.
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,12 +1,9 @@
|
|||||||
#
|
#
|
||||||
!*/testcase/main.c
|
!*/testcase/main.c
|
||||||
*/src/rap_plugin/*.o
|
|
||||||
*/src/rap_plugin/*.so
|
|
||||||
tags
|
tags
|
||||||
*.o
|
*.o
|
||||||
*.out
|
*.out
|
||||||
*.s
|
*.s
|
||||||
|
*.S
|
||||||
*.dump
|
*.dump
|
||||||
*.swp
|
|
||||||
*.so
|
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# RAP-optimizations
|
# ARM64-RAP-explore
|
||||||
|
|
||||||
This is a research project. It is Alpha version now.
|
This is a research project. It is Alpha version now.
|
||||||
Much of the project may be changed, including the algorithms.
|
Much of the project may be changed, including the algorithms.
|
||||||
@ -15,8 +15,3 @@ RAP( Return address protection) is the most powerful kernel CFI implementation i
|
|||||||
* [RAP: RIP ROP](https://pax.grsecurity.net/docs/PaXTeam-H2HC15-RAP-RIP-ROP.pdf)
|
* [RAP: RIP ROP](https://pax.grsecurity.net/docs/PaXTeam-H2HC15-RAP-RIP-ROP.pdf)
|
||||||
* [FAQ RAP](https://grsecurity.net/rap_faq.php)
|
* [FAQ RAP](https://grsecurity.net/rap_faq.php)
|
||||||
* [Close, but No Cigar: On the Effectiveness of Intel's CET Against Code Reuse Attacks](https://grsecurity.net/effectiveness_of_intel_cet_against_code_reuse_attacks.php)
|
* [Close, but No Cigar: On the Effectiveness of Intel's CET Against Code Reuse Attacks](https://grsecurity.net/effectiveness_of_intel_cet_against_code_reuse_attacks.php)
|
||||||
|
|
||||||
|
|
||||||
## Epilogue
|
|
||||||
|
|
||||||
[RAP-optimization summary and ending](https://github.com/hardenedlinux/RAP-optimizations/issues/2), Oct 2 2019
|
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
|
|
||||||
-因为不论是PAX_RAP还是hl-cfi都是针对linux kernel而设计的,所以这两个plugin挂在
|
|
||||||
gcc上测试bench很多测试程序不能运行,hash计算就assert过了只能是function_type的
|
|
||||||
tree.
|
|
||||||
|
|
||||||
-对比的具体过程是只是采用了PAX_RAP的call检测,也就是forward cfi,而hl-cfi只有
|
|
||||||
forward cfi所以检测结果应该是可以作为一个性能比较参考的。
|
|
||||||
|
|
||||||
-intspeed的结果和fpspeed的结果差不多。
|
|
Binary file not shown.
Binary file not shown.
@ -1,29 +0,0 @@
|
|||||||
all: pdf
|
|
||||||
|
|
||||||
pdf: paper.pdf
|
|
||||||
docx: paper.docx
|
|
||||||
|
|
||||||
paper.pdf: paper.md references.bib
|
|
||||||
pandoc \
|
|
||||||
-s \
|
|
||||||
--pdf-engine=xelatex \
|
|
||||||
--bibliography references.bib \
|
|
||||||
--filter pandoc-fignos \
|
|
||||||
--filter pandoc-tablenos \
|
|
||||||
--filter pandoc-eqnos \
|
|
||||||
--filter pandoc-citeproc \
|
|
||||||
paper.md -o paper.pdf
|
|
||||||
|
|
||||||
paper.docx: paper.md references.bib
|
|
||||||
pandoc \
|
|
||||||
-s \
|
|
||||||
--bibliography references.bib \
|
|
||||||
--filter pandoc-fignos \
|
|
||||||
--filter pandoc-tablenos \
|
|
||||||
--filter pandoc-eqnos \
|
|
||||||
--filter pandoc-citeproc \
|
|
||||||
paper.md -o paper.docx
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
${RM} paper.pdf paper.docx
|
|
@ -1,39 +0,0 @@
|
|||||||
# PAX RAP and its optimizations
|
|
||||||
|
|
||||||
## Compiling the paper
|
|
||||||
|
|
||||||
By default, a PDF version will be produced. Simply run
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make
|
|
||||||
```
|
|
||||||
|
|
||||||
This will produce `paper.pdf`. To build a DOCX file, run
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make docx
|
|
||||||
```
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
* [pandoc](https://pandoc.org/): converting Markdown to PDF via LaTeX
|
|
||||||
* [pandoc-citeproc](https://github.com/jgm/pandoc-citeproc): reference/citation support
|
|
||||||
* [pandoc-fignos](https://github.com/tomduck/pandoc-fignos): numbering and referencing of figures
|
|
||||||
* [pandoc-tablenos](https://github.com/tomduck/pandoc-tablenos): numbering and referencing of tables
|
|
||||||
* [pandoc-eqnos](https://github.com/tomduck/pandoc-eqnos): numbering and referencing of equations
|
|
||||||
* `make` (optional)
|
|
||||||
|
|
||||||
### Installation
|
|
||||||
|
|
||||||
One way, using `stack` and `pip`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
stack install pandoc
|
|
||||||
stack install pandoc-citeproc
|
|
||||||
sudo pip install pandoc-fignos pandoc-tablenos pandoc-eqnos
|
|
||||||
```
|
|
||||||
|
|
||||||
## Attribution
|
|
||||||
|
|
||||||
* `nature.csl` obtained from https://github.com/citation-style-language/styles
|
|
||||||
* figure taken from https://xkcd.com/688/
|
|
Binary file not shown.
Before Width: | Height: | Size: 36 KiB |
@ -1,123 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="sort-only" default-locale="en-GB">
|
|
||||||
<info>
|
|
||||||
<title>Nature</title>
|
|
||||||
<id>http://www.zotero.org/styles/nature</id>
|
|
||||||
<link href="http://www.zotero.org/styles/nature" rel="self"/>
|
|
||||||
<link href="http://www.nature.com/nature/authors/gta/index.html#a5.4" rel="documentation"/>
|
|
||||||
<link href="http://www.nature.com/srep/publish/guidelines#references" rel="documentation"/>
|
|
||||||
<author>
|
|
||||||
<name>Michael Berkowitz</name>
|
|
||||||
<email>mberkowi@gmu.edu</email>
|
|
||||||
</author>
|
|
||||||
<category citation-format="numeric"/>
|
|
||||||
<category field="science"/>
|
|
||||||
<category field="generic-base"/>
|
|
||||||
<issn>0028-0836</issn>
|
|
||||||
<eissn>1476-4687</eissn>
|
|
||||||
<updated>2018-10-24T14:53:43+00:00</updated>
|
|
||||||
<rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
|
|
||||||
</info>
|
|
||||||
<macro name="title">
|
|
||||||
<choose>
|
|
||||||
<if type="bill book graphic legal_case legislation motion_picture report song" match="any">
|
|
||||||
<text variable="title" font-style="italic"/>
|
|
||||||
</if>
|
|
||||||
<else>
|
|
||||||
<text variable="title"/>
|
|
||||||
</else>
|
|
||||||
</choose>
|
|
||||||
</macro>
|
|
||||||
<macro name="author">
|
|
||||||
<names variable="author">
|
|
||||||
<name sort-separator=", " delimiter=", " and="symbol" initialize-with=". " delimiter-precedes-last="never" name-as-sort-order="all"/>
|
|
||||||
<label form="short" prefix=", "/>
|
|
||||||
<et-al font-style="italic"/>
|
|
||||||
</names>
|
|
||||||
</macro>
|
|
||||||
<macro name="access">
|
|
||||||
<choose>
|
|
||||||
<if variable="volume"/>
|
|
||||||
<else-if variable="DOI">
|
|
||||||
<text variable="DOI" prefix="doi:"/>
|
|
||||||
</else-if>
|
|
||||||
<else-if type="webpage" variable="URL" match="all">
|
|
||||||
<text term="available at" text-case="capitalize-first" suffix=": "/>
|
|
||||||
<text variable="URL" suffix=". "/>
|
|
||||||
<group prefix="(" suffix=")" delimiter=": ">
|
|
||||||
<text term="accessed" text-case="capitalize-first"/>
|
|
||||||
<date variable="accessed">
|
|
||||||
<date-part name="day" suffix=" " form="ordinal"/>
|
|
||||||
<date-part name="month" suffix=" "/>
|
|
||||||
<date-part name="year"/>
|
|
||||||
</date>
|
|
||||||
</group>
|
|
||||||
</else-if>
|
|
||||||
</choose>
|
|
||||||
</macro>
|
|
||||||
<macro name="issuance">
|
|
||||||
<choose>
|
|
||||||
<if type="bill book graphic legal_case legislation motion_picture report song thesis chapter paper-conference" match="any">
|
|
||||||
<group delimiter=", " prefix="(" suffix=").">
|
|
||||||
<text variable="publisher" form="long"/>
|
|
||||||
<date variable="issued">
|
|
||||||
<date-part name="year"/>
|
|
||||||
</date>
|
|
||||||
</group>
|
|
||||||
</if>
|
|
||||||
<else>
|
|
||||||
<date prefix="(" suffix=")." variable="issued">
|
|
||||||
<date-part name="year"/>
|
|
||||||
</date>
|
|
||||||
</else>
|
|
||||||
</choose>
|
|
||||||
</macro>
|
|
||||||
<macro name="container-title">
|
|
||||||
<choose>
|
|
||||||
<if type="article-journal">
|
|
||||||
<text variable="container-title" font-style="italic" form="short"/>
|
|
||||||
</if>
|
|
||||||
<else>
|
|
||||||
<text variable="container-title" font-style="italic"/>
|
|
||||||
</else>
|
|
||||||
</choose>
|
|
||||||
</macro>
|
|
||||||
<macro name="editor">
|
|
||||||
<choose>
|
|
||||||
<if type="chapter paper-conference" match="any">
|
|
||||||
<names variable="editor" prefix="(" suffix=")">
|
|
||||||
<label form="short" suffix=" "/>
|
|
||||||
<name and="symbol" delimiter-precedes-last="never" initialize-with=". " name-as-sort-order="all"/>
|
|
||||||
</names>
|
|
||||||
</if>
|
|
||||||
</choose>
|
|
||||||
</macro>
|
|
||||||
<citation collapse="citation-number">
|
|
||||||
<sort>
|
|
||||||
<key variable="citation-number"/>
|
|
||||||
</sort>
|
|
||||||
<layout vertical-align="sup" delimiter=",">
|
|
||||||
<text variable="citation-number"/>
|
|
||||||
</layout>
|
|
||||||
</citation>
|
|
||||||
<bibliography et-al-min="6" et-al-use-first="1" second-field-align="flush" entry-spacing="0" line-spacing="2">
|
|
||||||
<layout>
|
|
||||||
<text variable="citation-number" suffix="."/>
|
|
||||||
<group delimiter=" ">
|
|
||||||
<text macro="author" suffix="."/>
|
|
||||||
<text macro="title" suffix="."/>
|
|
||||||
<choose>
|
|
||||||
<if type="chapter paper-conference" match="any">
|
|
||||||
<text term="in"/>
|
|
||||||
</if>
|
|
||||||
</choose>
|
|
||||||
<text macro="container-title"/>
|
|
||||||
<text macro="editor"/>
|
|
||||||
<text variable="volume" font-weight="bold" suffix=","/>
|
|
||||||
<text variable="page"/>
|
|
||||||
<text macro="issuance"/>
|
|
||||||
<text macro="access"/>
|
|
||||||
</group>
|
|
||||||
</layout>
|
|
||||||
</bibliography>
|
|
||||||
</style>
|
|
@ -1,264 +0,0 @@
|
|||||||
---
|
|
||||||
documentclass:
|
|
||||||
- ctexart
|
|
||||||
---
|
|
||||||
|
|
||||||
# PaX/Grsecurity RAP及其优化
|
|
||||||
|
|
||||||
### zet
|
|
||||||
|
|
||||||
*zet ([feqin1023@gmail.com](mailto:feqin1023@gmail.com)), HardenedLinux.org, GuangZhou, China*
|
|
||||||
|
|
||||||
## 简介
|
|
||||||
|
|
||||||
Return-Oriented Programming (ROP)是一种比较高级攻击的方式,能够利用现有代码通过找到的gadgets串来执行攻击者想进行的
|
|
||||||
任何操作,现有的防御手段只有Control-flow integrity(CFI)是针对这种攻击进行防御的。此外常规针对存储破坏的防御canary,
|
|
||||||
NX, ASLR等,对于这种攻击无效。
|
|
||||||
|
|
||||||
PaX/Grsecurity RAP是一种CFI的实现方式,本文描述了RAP的实现,以及针对RAP的优化,以及重新实现的hl-cfi的实现。
|
|
||||||
|
|
||||||
## 1 导引
|
|
||||||
|
|
||||||
Return-Oriented Programming (ROP)[@Krahmer05]是一种比较高级攻击的方式,是code-reuse attack的一种,能够利用现有代码通过找
|
|
||||||
到的gadgets串来执行攻击者想进行的任何操作,已经有研究者表明gadgets是图灵完备的[@Shacham07]。现有的防御手段只有
|
|
||||||
Control-flow integrity(CFI)是针对这种攻击进行防御的。此外常规针对存储破坏的防御canary, NX, ASLR等,对于这种攻击无效。
|
|
||||||
|
|
||||||
自从CFI[@Abadi05]提出以来,各种实现层出不群,包括gcc upstream里的vtv以及LLVM cfi。不过这些实现有明显的硬伤,vtv防御
|
|
||||||
virtual table,LLVM cfi只是一个forward cfi实现,没有backward部分。比较而言,PaX/Grsecurity RAP[@PaX18]对于kernel级别的
|
|
||||||
防护是最理想的选择,不经包括forward而且包括backward实现,backward cfi的实现应该是业界第一个也是为数不多的可以进入生产环境
|
|
||||||
的。
|
|
||||||
|
|
||||||
### 贡献
|
|
||||||
本文主要是贡献是从编译器角度分析PaX RAP以及HardenedLinux hl-cfi[@Hardenedlinux18]的改进以及实现。
|
|
||||||
|
|
||||||
### 内容
|
|
||||||
本文的内容安排包括:2 背景,3 算法与实现,4 结论以及未来工作。
|
|
||||||
|
|
||||||
## 2 背景
|
|
||||||
Return-Oriented Programming (ROP)[@Krahmer05]是return-into-libc[@Pincus04]的一种一般形式,也就是最终的目标不是进入libc。
|
|
||||||
ROP的攻击由串接执行一连串的gadgets进行,gadgets是一些几条汇编语言的代码片段,一般来说以 __ret__ 指令结尾,因为ROP gadgets
|
|
||||||
是图灵完备的[@Shacham07],理论上来说,ROP可以按照攻击者的目的来做任何计算。
|
|
||||||
|
|
||||||
下图简要描述了一个常规的ROP攻击图示,图片来源于[@Carlini14]。左边的Stack是用户stack初始化为gadgets的地址,右边的
|
|
||||||
Instructions以ret结尾就是gadgets由左边stack处的地址实线指向。这个攻击的结果是将数0x32400加到地址0x4a304120所存储的值。
|
|
||||||
|
|
||||||
![ROP图示](figures/rop-case.png){图1: ROP图示}
|
|
||||||
|
|
||||||
由于这个攻击可以看到ROP发生的根本原因:就是 __call/jmp/ret__ 违反了原始代码控制流。基于这个因素所以有研究者提出了
|
|
||||||
Control-flow integrity(CFI)[@Abadi05]。原理就是在编译器编译最开始的未经过破坏的源代码的时候就分析控制流,
|
|
||||||
在 __call/jmp/ret__ 发生的地方插入检测代码,在代码运行的时候来判断报错是否有攻击行为发生。
|
|
||||||
|
|
||||||
关于ROP更详细的描述可以参考[@Krahmer05][@Shacham07][@Carlini14]。
|
|
||||||
|
|
||||||
|
|
||||||
## 3 算法与实现
|
|
||||||
|
|
||||||
根据公开的文献记载,PaX RAP针对ROP的威胁建模和初始设计[@paxfuture]在2003年时已经存在。下面将描述PaX RAP的算法及其实现,分析这种方式带来的性能损耗,和HardenedLinux社区所做的优化改进。
|
|
||||||
|
|
||||||
由上一节背景的描述可知,ROP发生的根源就是因为违反了原始代码的控制流。所以对于相应的检测防御也很简单:在原始控制流转移的
|
|
||||||
地方由编译器插入检测代码。这其中就会有一个trade-off的考虑:怎么样在保证一定精度的情况下作出防御?
|
|
||||||
|
|
||||||
对于控制流的转移可以分为:
|
|
||||||
|
|
||||||
1) 直接调用的call/jmp
|
|
||||||
2) 间接调用的call/jmp - RAP forward cfi
|
|
||||||
3) 返回 - RAP backward cfi
|
|
||||||
|
|
||||||
对于情况1来说不需要考虑,因为直接调用都是位于 _.text_ 段,只读的section不会发生控制流ROP的攻击。所以ROP的防御就是针对情况2和3。
|
|
||||||
|
|
||||||
理论上来说最理想的防御当然是:对于每个会被间接调用的函数在进入该函数的时候作出检测,对于每个 __ret__ 作出检测。对于情况3的
|
|
||||||
__ret__ 来说可以确定有 __ret__ 就意味着返回,也就是我们必须处理的检测点,也就是backward cfi的实现点,也就是对于所有 __ret__
|
|
||||||
都需要处理。但是对于情况2来说复杂了许多,所有优化以及考虑都在于情况2里面。对于会被间接调用的函数这个问题是一个NP问题,是
|
|
||||||
一个典型的pointer analysis的问题,也就是求解一个函数指针的指向范围是什么,相对地也就是求一个函数是不是会被间接调用也就是
|
|
||||||
有没有被函数指针所指向,这个问题在编译器领域大概伴随着优化编译器的最开始研究(大约是1970年)一直进行到现在。
|
|
||||||
|
|
||||||
PaX RAP是使用gcc plugin[@gccinternals]来实现的,gcc plugin是gcc提供给第三方程序的一个钩子,可以回调第三方的代码,可以在
|
|
||||||
gcc内部满足条件的时候输出信息,可以在gcc某个pass之后输出信息也可以调用第三方的代码作为某个pass,只要根据规范提供给gcc想
|
|
||||||
插入的pass点就行了。其他的详细功能请参考gcc-internals[@gccinternals]或者gcc代码。
|
|
||||||
|
|
||||||
### RAP forward cfi
|
|
||||||
|
|
||||||
RAP的实现是做为几个gcc pass通过gcc plugin插入gcc来进行的。由上一段的分析知道求解精确的函数是否被间接调用以及函数指针的指
|
|
||||||
向范围是一个NP问题,所以学术界和工程界有数不清的学术paper以及实现出现,在gcc内部的实现来说有一个flow-insensitive analysis
|
|
||||||
和一个比较精确的flow-sensitive的算法,insensitive的算法非常简单,就是根据编译器的分析以及函数的声明来判断函数有没有可能
|
|
||||||
被间接调用,代码如下:比如判断是不是static有没有取过函数的地址。
|
|
||||||
|
|
||||||
_flow-insensitive analysis :_
|
|
||||||
|
|
||||||
```
|
|
||||||
static inline bool
|
|
||||||
may_be_aliased (const_tree var) {
|
|
||||||
return (TREE_CODE (var) != CONST_DECL
|
|
||||||
&& !((TREE_STATIC (var) || TREE_PUBLIC (var) || DECL_EXTERNAL (var))
|
|
||||||
&& TREE_READONLY (var)
|
|
||||||
&& !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (var)))
|
|
||||||
&& (TREE_PUBLIC (var) || DECL_EXTERNAL (var) || TREE_ADDRESSABLE (var)));
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
flow-sensitive analysis算法无数,gcc的实现基本上是描述于paper[@Hardekopf09]里的算法,在gcc summit也有开发者的
|
|
||||||
paper[@Berlin05]描述。是基于Constraint set的一类算法,只不过是在gcc中间代码tree-ssa的基础上,针对ssa做了改进,这样基于
|
|
||||||
ssa的一个稀疏算法。详细的实现参考[@Hardekopf09][@Berlin05]。这是一个流敏感的算法,也就是对于block内部的语句有分析,也会
|
|
||||||
进入函数的内部。总是是一个比较精确的算法。
|
|
||||||
|
|
||||||
介绍完,RAP遇到的难点,接着介绍RAP对间接函数的处理,RAP做了一个更粗略的trade-off,当函数被间接调用的时候当前的调用点,
|
|
||||||
除了函数指针没有任何信息,这里dereference函数指针会得到函数类型,函数类型和函数指针的指向是静态分析唯一能够知道的信息,
|
|
||||||
RAP放弃了函数指针的指向,只抽取了函数的类型,对得到的函数类型做hash运算,然后得到一个hash值,这个hash值就是RAP间接检测
|
|
||||||
的标准。hash值的计算算法是SipHash-2-4[@Aumasson12],函数类型则是按照标准规范包括返回值和参数[@C11-standard]。接着在间接
|
|
||||||
调用的地方插入检测代码。RAP的检测代码插入在gcc tree-ssa[@Novillo03][@Novillo04]的表示层,在gcc内部表示来说tree-ssa之前是
|
|
||||||
tree-ast[@Merrill03],而之后是rtl[@gccinternals]。tree-ssa是几乎整个gcc重要优化pass的实现点。
|
|
||||||
|
|
||||||
_PaX RAP forward cfi alogrithms:_
|
|
||||||
|
|
||||||
```
|
|
||||||
for all gimple code of all function
|
|
||||||
hashValue = computeHash(currentFunctionType);
|
|
||||||
insertHashValueBeforeCurrentFunction(hashValue);
|
|
||||||
if (isFunctionPointer(currentPointer))
|
|
||||||
functionType = *currentPointer;
|
|
||||||
hashValue = computeHash(functionType);
|
|
||||||
insertHashValueCheckBeforeCurrentIndirectCall(currentPointer, hashValue);
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
insertHashValueBeforeCurrentFunction(hashValue)
|
|
||||||
fprintf(asm_out_file, "\t.quad %#llx", hashValue);
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
insertHashValueCheckBeforeCurrentIndirectCall(currentPointer, hashValue);
|
|
||||||
value = (long)*((long *)currentPointer - 8);
|
|
||||||
if (value == hashValue)
|
|
||||||
currentPointer();
|
|
||||||
else
|
|
||||||
catchAttack();
|
|
||||||
```
|
|
||||||
|
|
||||||
上面给出的是RAP forward cfi实现的算法伪代码,在RAP的实现上有三个问题:
|
|
||||||
|
|
||||||
1) 因为RAP没有使用pointer analysis,所以会对全部函数都输出hash值。
|
|
||||||
2) 上面的伪代码在RAP的实现上是在tree-ssa表示层,所以其实是几条gimple等效的伪代码,但是RAP的实现上这些gimple代码是作为一个整体插入gcc的,而且插入的位置是gcc的所有tree-ssa优化pass之后,也就是gcc根本不会感知到这些代码的存在,也就是说gcc不会去分析这些代码,也不会去优化这些代码。
|
|
||||||
3) 安全上的考虑,RAP的实现是针对函数类型编码hash,所有函数类型都是同一个hash值,所以这是一个可能的漏洞利用平面。
|
|
||||||
|
|
||||||
基于以上的三个问题所以我们给出了HardenedLinux hl-cfi的实现(hl的意思high level)。
|
|
||||||
|
|
||||||
_hl-cfi alogrithms:_
|
|
||||||
|
|
||||||
```
|
|
||||||
for all gimple code of all function
|
|
||||||
hashValue = computeHash(currentFunctionType);
|
|
||||||
if (isCurrentFunctionMaybeAttacked(currentFunction))
|
|
||||||
insertHashValueBeforeCurrentFunction(hashValue);
|
|
||||||
if (isFunctionPointer(currentPointer))
|
|
||||||
functionType = *currentPointer;
|
|
||||||
hashValue = computeHash(functionType);
|
|
||||||
insertHashValueCheckBeforeCurrentIndirectCall(currentPointer, hashValue);
|
|
||||||
```
|
|
||||||
|
|
||||||
_解决RAP实现上的问题1_
|
|
||||||
|
|
||||||
```
|
|
||||||
isCurrentFunctionMaybeAttacked(currentFunction)
|
|
||||||
lookupPointerAnalysis(currentFunction)
|
|
||||||
```
|
|
||||||
|
|
||||||
_解决RAP实现上的问题2_
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
insertHashValueCheckBeforeCurrentIndirectCall(currentPointer, hashValue)
|
|
||||||
|
|
||||||
+-------
|
|
||||||
stmt1;
|
|
||||||
call fptr;
|
|
||||||
+-------
|
|
||||||
|
|
||||||
change to =>
|
|
||||||
|
|
||||||
// insertHashValueCheckBeforeCurrentIndirectCall(currentPointer, hashValue)
|
|
||||||
+-------
|
|
||||||
stmt1;
|
|
||||||
lhs_1 = t_;
|
|
||||||
ne_expr (lhs_1, s_); // hsahValueCheck()
|
|
||||||
// FALLTHRU
|
|
||||||
<bb ???> # true
|
|
||||||
cfi_catch();
|
|
||||||
<bb ???> # false
|
|
||||||
call fptr;
|
|
||||||
+--------
|
|
||||||
```
|
|
||||||
|
|
||||||
insertHashValueCheckBeforeCurrentIndirectCall(currentPointer, hashValue)的插入实现为block级别的gimple code,而且hl-cfi
|
|
||||||
的插入点是在tree-ssa pass的最开始处,在pass_build_ssa_passes之前,所以这里需要实现上的处理,需要模拟gcc已经跑过的所有代
|
|
||||||
码对于一个假想的检测insertHashValueCheckBeforeCurrentIndirectCall()函数的表示在当前pass点是个什么样子,然后插入对应的代
|
|
||||||
码。而且对于hl-cfi来说我们需要使用gcc pointer analysis,所以对于isCurrentFunctionMaybeAttacked()的调用又得保证在
|
|
||||||
pass_ipa_pta(gcc flow-sensitive analysis)之后。cfi的检测代码的优化是一个复杂的问题,因为这是一个运行时才能知道的函数指针
|
|
||||||
值,常规静态分析优化[@Gupta93]基本上没有用。所以hl-cfi的实现相对来说考虑的只能是尽可能利用gcc现有的优化,检测代码的hash
|
|
||||||
常数可以被gcc做register promotion[@Makarov07],以及分析信息传播到整个fucntion里面[@Novillo05]进一步给其他pass提供机会。
|
|
||||||
在hl-cfi构建block以及edge的时候给gcc提供profile信息[@Hubicka05][@Ramasamy08],使用profile的相关基础代码。给后续的优化
|
|
||||||
pass比如code placement以及cache优化的pass提供信息。
|
|
||||||
|
|
||||||
_解决RAP实现问题3_
|
|
||||||
|
|
||||||
```
|
|
||||||
// 这部分代码因为复杂度的原因,并没有在hl-cfi里面实现,下面只是提供算法。
|
|
||||||
|
|
||||||
for all gimple code of all function
|
|
||||||
if (isCurrentFunctionMaybeAttacked(currentFunction))
|
|
||||||
insertHashValueBeforeCurrentFunction(hashValue);
|
|
||||||
if (isFunctionPointer(currentPointer))
|
|
||||||
if (pointerAliasSetChanged(currentPointer, currentCodePlace))
|
|
||||||
functionType = *currentPointer;
|
|
||||||
// 根据当前的代码分析结果来给一个变化的seed来得到一个
|
|
||||||
// 跟当前函数指针和函数类型相关的hash值。
|
|
||||||
hashValue = computeHash(functionType, seed);
|
|
||||||
insertCurrentHashValue(currentPointer, functionType, currentCodePlace);
|
|
||||||
else
|
|
||||||
hashValue = lookupHashValue(currentPointer, fucntionType, currentCodePlace);
|
|
||||||
insertHashValueCheckBeforeCurrentIndirectCall(currentPointer, hashValue);
|
|
||||||
```
|
|
||||||
|
|
||||||
为了解决问题3,计算一个动态的hash值,根据函数指针的变化而变化。
|
|
||||||
|
|
||||||
### RAP backward cfi
|
|
||||||
|
|
||||||
为了解决 __ret__ 的问题,PaX Team提出了backward cfi的软件实现方案。
|
|
||||||
|
|
||||||
```
|
|
||||||
for all rtl code of all function
|
|
||||||
if (isCurrentRTLIsRet(currentRTL))
|
|
||||||
// 调用gcc内置函数,得到返回地址。
|
|
||||||
retAddress = __builtin_return_address();
|
|
||||||
// 在gcc里,这个函数类型通过分析可以知道的。
|
|
||||||
hashValue = getHash(functionType);
|
|
||||||
insertRetCheck(retAddress,hashValue);
|
|
||||||
```
|
|
||||||
|
|
||||||
对于这个检测函数的描述跟RAP实现略有差异,RAP比较的是一个hashValue的取反的值。
|
|
||||||
|
|
||||||
```
|
|
||||||
insertRetCheck(retAddress, hashValue)
|
|
||||||
if (long*((long *)retAddress - 8) != hashValue)
|
|
||||||
catchAttack();
|
|
||||||
```
|
|
||||||
|
|
||||||
对于backward cfi来说这大概是业界仅有的几个的实现,而且跟RAP forward cfi的一样,也是一串没有经过编译器优化的代码直接出现
|
|
||||||
在输出的object里,不过想不到优化的方案,只能期待硬件更新支持backward cfi,比如类似ARMv8.3的PA[@zet17], ARMv8.5的MTE[@armmte]以及未来的Intel CET[@intelcet]等。
|
|
||||||
|
|
||||||
## 4 结论
|
|
||||||
|
|
||||||
对于hl-cfi的实现和RAP的实现在spec CPU2017上做了一个对比测试,因为RAP本身是为了linux kernel防御,在优化RAP以及开发hl-cfi
|
|
||||||
的时候,为了方便测试以及开发,我们抽取出了RAP作为一个独立的项目,hl-cfi也是如此,正因为这是两个针对kernel的项目,因为应
|
|
||||||
用代码外部library依赖的问题,CPU2017的很多测试跑不过,跑过的数据如下:
|
|
||||||
|
|
||||||
RAP | hl-cfi | hl-cfi - RAP / RAP
|
|
||||||
--- | --- | ---
|
|
||||||
2.15| 2.35| 9.3%
|
|
||||||
|
|
||||||
大约有9.3%的性能提升。
|
|
||||||
|
|
||||||
由于hl-cfi的实现依赖于pointer analysis,如果使用lto[@Glek10]来编译linux kernel,相信hl-cfi应该会有一个更佳的表现。lto模
|
|
||||||
式更好的一个特点是只需要修改linux kernel的编译构建脚本,对于hl-cfi本身不需要做改变。期待未来lto的编译能够普及。
|
|
||||||
|
|
||||||
## 引用
|
|
Binary file not shown.
@ -1,189 +0,0 @@
|
|||||||
@Article{Abadi05,
|
|
||||||
Author="M. Abadi, M. Budiu, Ú. Erlingsson, and J. Ligatti",
|
|
||||||
Title={"Control-flow integrity: Principles, implementations, and applications"},
|
|
||||||
Journal="Proceedings of the 12th ACM conference on Computer and communications security",
|
|
||||||
Year="2005",
|
|
||||||
Pages="i340-i353",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Aumasson12,
|
|
||||||
Author="JP. Aumasson, D.J. Bernstein",
|
|
||||||
Title="{SipHash: A Fast Short-Input PRF}",
|
|
||||||
Journal="Progress in Cryptology - INDOCRYPT",
|
|
||||||
Year="2012",
|
|
||||||
Pages="i489-i508",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Berlin05,
|
|
||||||
Author="D. Berlin",
|
|
||||||
Title="{Structure aliasing in GCC}",
|
|
||||||
Journal="In Proceedings of the 2005 GCC Summit",
|
|
||||||
Year="2005",
|
|
||||||
Pages="i25-i36",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{C11-standard,
|
|
||||||
Author="ISO/IEC",
|
|
||||||
Title="{Information technology — Programming languages — C}",
|
|
||||||
Journal="ISO/IEC 9899:2011",
|
|
||||||
Year="2011",
|
|
||||||
Pages="i42",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Carlini14,
|
|
||||||
Author="N. Carlini, D. Wagner",
|
|
||||||
Title="{ROP is still dangerous: Breaking modern defenses.}",
|
|
||||||
Journal="In USENIX Security Symposium",
|
|
||||||
Year="2014",
|
|
||||||
Pages="i385-i399",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Gupta93,
|
|
||||||
Author="R. Gupta",
|
|
||||||
Title="{Optimizing array bound checks using flow analysis}",
|
|
||||||
Journal="ACM Letters on Programming Languages and Systems",
|
|
||||||
Year="1993",
|
|
||||||
Pages="i135-i150",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Glek10,
|
|
||||||
Author="T. Glek, J. Hubicka",
|
|
||||||
Title="{Optimizing real-world applications with GCC Link Time Optimization}",
|
|
||||||
Journal="In Proceedings of the 2010 GCC Summit",
|
|
||||||
Year="2010",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{gccinternals,
|
|
||||||
Author="GCC-internals",
|
|
||||||
Title="{Chapter rtl and plugins}",
|
|
||||||
Journal="GNU Compiler Collection (GCC) Internals",
|
|
||||||
Year="2017",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Hubicka05,
|
|
||||||
Author="J. Hubicka",
|
|
||||||
Title="{Profile driven optimisations in GCC}",
|
|
||||||
Journal="In Proceedings of the 2005 GCC Summit",
|
|
||||||
Year="2005",
|
|
||||||
Pages="i107-i124",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Hardenedlinux18,
|
|
||||||
Author="zet",
|
|
||||||
Title="{hl-cfi project}",
|
|
||||||
Journal="https://github.com/hardenedlinux/RAP-optimizations",
|
|
||||||
Year="2018",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Hardekopf09,
|
|
||||||
Author="B. Hardekopf, C. Lin",
|
|
||||||
Title="{Semi-sparse flow-sensitive pointer analysis}",
|
|
||||||
Journal="Proceedings of the 36th annual ACM SIGPLAN-SIGACT symposium on Principles of programming languages",
|
|
||||||
Year="2009",
|
|
||||||
Pages="i226-i238",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Krahmer05,
|
|
||||||
Author="S. Krahmer",
|
|
||||||
Title="{x86-64 buffer overflow exploits and the borrowed code chunks exploitation technique}",
|
|
||||||
Year="2005",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Merrill03,
|
|
||||||
Author="J. Merrill",
|
|
||||||
Title="{GENERIC and GIMPLE: A New Tree Representation for Entire Functions}",
|
|
||||||
Journal="In Proceedings of the 2003 GCC Summit",
|
|
||||||
Year="2003",
|
|
||||||
Pages="i171-i180",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Makarov07,
|
|
||||||
Author="V N. Makarov",
|
|
||||||
Title="{The integrated register allocator for GCC}",
|
|
||||||
Journal="In Proceedings of the 2007 GCC Summit",
|
|
||||||
Year="2007",
|
|
||||||
Pages="i77-i90",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Novillo03,
|
|
||||||
Author="D. Novillo",
|
|
||||||
Title="{Tree SSA – A New Optimization Infrastructure for GCC}",
|
|
||||||
Journal="In Proceedings of the 2003 GCC Summit",
|
|
||||||
Year="2003",
|
|
||||||
Pages="i181-i194",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Novillo04,
|
|
||||||
Author="D. Novillo",
|
|
||||||
Title="{Design and Implementation of Tree SSA}",
|
|
||||||
Journal="In Proceedings of the 2004 GCC Summit",
|
|
||||||
Year="2004",
|
|
||||||
Pages="i119-i130",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Novillo05,
|
|
||||||
Author="D. Novillo",
|
|
||||||
Title="{A Propagation Engine for GCC}",
|
|
||||||
Journal="In Proceedings of the 2005 GCC Summit",
|
|
||||||
Year="2005",
|
|
||||||
Pages="i175-i184",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{PaX18,
|
|
||||||
Author="PaX",
|
|
||||||
Title="{Frequently Asked Questions About RAP}",
|
|
||||||
Journal="https://www.grsecurity.net/rap_faq",
|
|
||||||
Year="2018",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Pincus04,
|
|
||||||
Author="J. Pincus, B. Baker",
|
|
||||||
Title="{Beyond stack smashing: Recent advances in exploiting buffer overruns}",
|
|
||||||
Journal="Security & Privacy, IEEE.",
|
|
||||||
Year="2004",
|
|
||||||
Pages="i20-i27",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Ramasamy08,
|
|
||||||
Author="V. Ramasamy, P. Yuan, D. Chen, and R. Hundt",
|
|
||||||
Title="{Feedback-Directed Optimizations in GCC with Estimated Edge Profiles from Hardware Event Sampling}",
|
|
||||||
Journal="In Proceedings of the 2008 GCC Summit",
|
|
||||||
Year="2008",
|
|
||||||
Pages="i87-i101",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{Shacham07,
|
|
||||||
Author="H. Shacham",
|
|
||||||
Title="{structural variant discovery by integrated paired-end and split-read analysis}",
|
|
||||||
Journal="Proceedings of the 14th ACM conference on Computer and communications security",
|
|
||||||
Year="2007",
|
|
||||||
Pages="i552-i561",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{zet17,
|
|
||||||
Author="zet",
|
|
||||||
Title="{ARMv8.3-A PA在GCC里的相关实现}",
|
|
||||||
Journal="https://hardenedlinux.github.io/gnu/toolchains/security/2017/06/13/ARM_PA.html",
|
|
||||||
Year="2017",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{armmte,
|
|
||||||
Author="WikiChip",
|
|
||||||
Title="{ARMv8.5的MTE}",
|
|
||||||
Journal="https://en.wikichip.org/wiki/arm/mte",
|
|
||||||
Year="2018",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{paxfuture,
|
|
||||||
Author="PaX",
|
|
||||||
Title="{PaX RAP针对ROP的威胁建模和初始设计}",
|
|
||||||
Journal="https://pax.grsecurity.net/docs/pax-future.txt",
|
|
||||||
Year="2003",
|
|
||||||
}
|
|
||||||
|
|
||||||
@Article{intelcet,
|
|
||||||
Author="Intel",
|
|
||||||
Title="{未来的Intel CET}",
|
|
||||||
Journal="https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf",
|
|
||||||
Year="2019",
|
|
||||||
}
|
|
40
src/Makefile
Normal file → Executable file
40
src/Makefile
Normal file → Executable file
@ -1,42 +1,6 @@
|
|||||||
GCC_PLUGINS_DIR := $(shell $(CC) -print-file-name=plugin)
|
$(HOSTLIBS)-$(CONFIG_PAX_RAP) += rap_plugin.so
|
||||||
|
|
||||||
ifeq ($(PLUGINCC),$(HOSTCC))
|
|
||||||
HOSTLIBS := hostlibs
|
|
||||||
HOST_EXTRACFLAGS += -I$(GCC_PLUGINS_DIR)/include -I$(src)
|
|
||||||
HOST_EXTRACFLAGS += -std=gnu99 -ggdb -fvisibility=hidden
|
|
||||||
HOST_EXTRACFLAGS += -Wall -W
|
|
||||||
export HOST_EXTRACFLAGS
|
|
||||||
else
|
|
||||||
HOSTLIBS := hostcxxlibs
|
|
||||||
HOST_EXTRACXXFLAGS += -I$(GCC_PLUGINS_DIR)/include -I$(src)
|
|
||||||
HOST_EXTRACXXFLAGS += -std=gnu++98 -ggdb -fvisibility=hidden
|
|
||||||
HOST_EXTRACXXFLAGS += -fno-rtti -fno-exceptions -fasynchronous-unwind-tables
|
|
||||||
HOST_EXTRACXXFLAGS += -Wall -W
|
|
||||||
HOST_EXTRACXXFLAGS += -Wno-unused-parameter -Wno-narrowing -Wno-unused-variable
|
|
||||||
export HOST_EXTRACXXFLAGS
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(CFLAGS_KCOV), $(SANCOV_PLUGIN))
|
|
||||||
GCC_PLUGIN := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGIN))
|
|
||||||
endif
|
|
||||||
|
|
||||||
export HOSTLIBS
|
|
||||||
|
|
||||||
$(HOSTLIBS)-y := $(foreach p,$(GCC_PLUGIN),$(if $(findstring /,$(p)),,$(p)))
|
|
||||||
always := $($(HOSTLIBS)-y)
|
always := $($(HOSTLIBS)-y)
|
||||||
$(foreach p,$($(HOSTLIBS)-y:%.so=%),$(eval $(p)-objs := $(p).o))
|
|
||||||
|
|
||||||
$(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h
|
rap_plugin-objs := $(patsubst $(srctree)/$(src)/%.c,%.o,$(wildcard $(srctree)/$(src)/*.c))
|
||||||
|
|
||||||
quiet_cmd_create_randomize_layout_seed = GENSEED $@
|
|
||||||
cmd_create_randomize_layout_seed = \
|
|
||||||
$(CONFIG_SHELL) $(srctree)/$(src)/gen-random-seed.sh $@ $(objtree)/include/generated/randomize_layout_hash.h
|
|
||||||
$(objtree)/$(obj)/randomize_layout_seed.h: FORCE
|
|
||||||
$(call if_changed,create_randomize_layout_seed)
|
|
||||||
|
|
||||||
targets += randomize_layout_seed.h randomize_layout_hash.h
|
|
||||||
|
|
||||||
subdir-y := $(GCC_PLUGIN_SUBDIR)
|
|
||||||
subdir- += $(GCC_PLUGIN_SUBDIR)
|
|
||||||
|
|
||||||
clean-files += *.so
|
clean-files += *.so
|
||||||
|
@ -1,491 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011-2017 by the PaX Team <pageexec@freemail.hu>
|
|
||||||
* Licensed under the GPL v2
|
|
||||||
*
|
|
||||||
* Note: the choice of the license means that the compilation process is
|
|
||||||
* NOT 'eligible' as defined by gcc's library exception to the GPL v3,
|
|
||||||
* but for the kernel it doesn't matter since it doesn't link against
|
|
||||||
* any of the gcc libraries
|
|
||||||
*
|
|
||||||
* gcc plugin to implement various sparse (source code checker) features
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
* - define separate __iomem, __percpu and __rcu address spaces (lots of code to patch)
|
|
||||||
*
|
|
||||||
* BUGS:
|
|
||||||
* - none known
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "gcc-common.h"
|
|
||||||
|
|
||||||
extern void c_register_addr_space (const char *str, addr_space_t as);
|
|
||||||
extern enum machine_mode default_addr_space_pointer_mode (addr_space_t);
|
|
||||||
extern enum machine_mode default_addr_space_address_mode (addr_space_t);
|
|
||||||
extern bool default_addr_space_valid_pointer_mode(enum machine_mode mode, addr_space_t as);
|
|
||||||
extern bool default_addr_space_legitimate_address_p(enum machine_mode mode, rtx mem, bool strict, addr_space_t as);
|
|
||||||
extern rtx default_addr_space_legitimize_address(rtx x, rtx oldx, enum machine_mode mode, addr_space_t as);
|
|
||||||
|
|
||||||
__visible int plugin_is_GPL_compatible;
|
|
||||||
|
|
||||||
static struct plugin_info checker_plugin_info = {
|
|
||||||
.version = "201602181345",
|
|
||||||
.help = "user\tturn on user/kernel address space checking\n"
|
|
||||||
"context\tturn on locking context checking\n"
|
|
||||||
};
|
|
||||||
|
|
||||||
#define ADDR_SPACE_KERNEL 0
|
|
||||||
#define ADDR_SPACE_FORCE_KERNEL 1
|
|
||||||
#define ADDR_SPACE_USER 2
|
|
||||||
#define ADDR_SPACE_FORCE_USER 3
|
|
||||||
#define ADDR_SPACE_IOMEM 0
|
|
||||||
#define ADDR_SPACE_FORCE_IOMEM 0
|
|
||||||
#define ADDR_SPACE_PERCPU 0
|
|
||||||
#define ADDR_SPACE_FORCE_PERCPU 0
|
|
||||||
#define ADDR_SPACE_RCU 0
|
|
||||||
#define ADDR_SPACE_FORCE_RCU 0
|
|
||||||
|
|
||||||
static enum machine_mode checker_addr_space_pointer_mode(addr_space_t addrspace)
|
|
||||||
{
|
|
||||||
return default_addr_space_pointer_mode(ADDR_SPACE_GENERIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum machine_mode checker_addr_space_address_mode(addr_space_t addrspace)
|
|
||||||
{
|
|
||||||
return default_addr_space_address_mode(ADDR_SPACE_GENERIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool checker_addr_space_valid_pointer_mode(enum machine_mode mode, addr_space_t as)
|
|
||||||
{
|
|
||||||
return default_addr_space_valid_pointer_mode(mode, as);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool checker_addr_space_legitimate_address_p(enum machine_mode mode, rtx mem, bool strict, addr_space_t as)
|
|
||||||
{
|
|
||||||
return default_addr_space_legitimate_address_p(mode, mem, strict, ADDR_SPACE_GENERIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
static rtx checker_addr_space_legitimize_address(rtx x, rtx oldx, enum machine_mode mode, addr_space_t as)
|
|
||||||
{
|
|
||||||
return default_addr_space_legitimize_address(x, oldx, mode, as);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool checker_addr_space_subset_p(addr_space_t subset, addr_space_t superset)
|
|
||||||
{
|
|
||||||
if (subset == ADDR_SPACE_FORCE_KERNEL && superset == ADDR_SPACE_KERNEL)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (subset == ADDR_SPACE_FORCE_USER && superset == ADDR_SPACE_USER)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (subset == ADDR_SPACE_FORCE_IOMEM && superset == ADDR_SPACE_IOMEM)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (subset == ADDR_SPACE_KERNEL && superset == ADDR_SPACE_FORCE_USER)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (subset == ADDR_SPACE_KERNEL && superset == ADDR_SPACE_FORCE_IOMEM)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (subset == ADDR_SPACE_USER && superset == ADDR_SPACE_FORCE_KERNEL)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (subset == ADDR_SPACE_IOMEM && superset == ADDR_SPACE_FORCE_KERNEL)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return subset == superset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static rtx checker_addr_space_convert(rtx op, tree from_type, tree to_type)
|
|
||||||
{
|
|
||||||
// addr_space_t from_as = TYPE_ADDR_SPACE(TREE_TYPE(from_type));
|
|
||||||
// addr_space_t to_as = TYPE_ADDR_SPACE(TREE_TYPE(to_type));
|
|
||||||
|
|
||||||
return op;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void register_checker_address_spaces(void *event_data, void *data)
|
|
||||||
{
|
|
||||||
c_register_addr_space("__kernel", ADDR_SPACE_KERNEL);
|
|
||||||
c_register_addr_space("__force_kernel", ADDR_SPACE_FORCE_KERNEL);
|
|
||||||
c_register_addr_space("__user", ADDR_SPACE_USER);
|
|
||||||
c_register_addr_space("__force_user", ADDR_SPACE_FORCE_USER);
|
|
||||||
// c_register_addr_space("__iomem", ADDR_SPACE_IOMEM);
|
|
||||||
// c_register_addr_space("__force_iomem", ADDR_SPACE_FORCE_IOMEM);
|
|
||||||
// c_register_addr_space("__percpu", ADDR_SPACE_PERCPU);
|
|
||||||
// c_register_addr_space("__force_percpu", ADDR_SPACE_FORCE_PERCPU);
|
|
||||||
// c_register_addr_space("__rcu", ADDR_SPACE_RCU);
|
|
||||||
// c_register_addr_space("__force_rcu", ADDR_SPACE_FORCE_RCU);
|
|
||||||
|
|
||||||
targetm.addr_space.pointer_mode = checker_addr_space_pointer_mode;
|
|
||||||
targetm.addr_space.address_mode = checker_addr_space_address_mode;
|
|
||||||
targetm.addr_space.valid_pointer_mode = checker_addr_space_valid_pointer_mode;
|
|
||||||
targetm.addr_space.legitimate_address_p = checker_addr_space_legitimate_address_p;
|
|
||||||
// targetm.addr_space.legitimize_address = checker_addr_space_legitimize_address;
|
|
||||||
targetm.addr_space.subset_p = checker_addr_space_subset_p;
|
|
||||||
targetm.addr_space.convert = checker_addr_space_convert;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool split_context_attribute(tree args, tree *lock, tree *in, tree *out)
|
|
||||||
{
|
|
||||||
*in = TREE_VALUE(args);
|
|
||||||
|
|
||||||
if (TREE_CODE(*in) != INTEGER_CST) {
|
|
||||||
*lock = *in;
|
|
||||||
args = TREE_CHAIN(args);
|
|
||||||
*in = TREE_VALUE(args);
|
|
||||||
} else
|
|
||||||
*lock = NULL_TREE;
|
|
||||||
|
|
||||||
args = TREE_CHAIN(args);
|
|
||||||
if (*lock && !args)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*out = TREE_VALUE(args);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static tree handle_context_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs)
|
|
||||||
{
|
|
||||||
*no_add_attrs = true;
|
|
||||||
tree lock, in, out;
|
|
||||||
|
|
||||||
if (TREE_CODE(*node) != FUNCTION_DECL) {
|
|
||||||
error("%qE attribute applies to functions only (%qD)", name, *node);
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!split_context_attribute(args, &lock, &in, &out)) {
|
|
||||||
error("%qE attribute needs two integers after the lock expression", name);
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TREE_CODE(in) != INTEGER_CST) {
|
|
||||||
error("the 'in' argument of the %qE attribute must be an integer (%qE)", name, in);
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TREE_CODE(out) != INTEGER_CST) {
|
|
||||||
error("the 'out' argument of the %qE attribute must be an integer (%qE)", name, out);
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*no_add_attrs = false;
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct attribute_spec context_attr = {
|
|
||||||
.name = "context",
|
|
||||||
.min_length = 2,
|
|
||||||
.max_length = 3,
|
|
||||||
.decl_required = true,
|
|
||||||
.type_required = false,
|
|
||||||
.function_type_required = false,
|
|
||||||
.handler = handle_context_attribute,
|
|
||||||
#if BUILDING_GCC_VERSION >= 4007
|
|
||||||
.affects_type_identity = true
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
static void register_attributes(void *event_data, void *data)
|
|
||||||
{
|
|
||||||
register_attribute(&context_attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char context_function[] = "__context__";
|
|
||||||
static GTY(()) tree context_function_decl;
|
|
||||||
|
|
||||||
static const char context_error[] = "__context_error__";
|
|
||||||
static GTY(()) tree context_error_decl;
|
|
||||||
|
|
||||||
static void context_start_unit(void __unused *gcc_data, void __unused *user_data)
|
|
||||||
{
|
|
||||||
tree fntype, attr;
|
|
||||||
|
|
||||||
// void __context__(void *, int);
|
|
||||||
fntype = build_function_type_list(void_type_node, ptr_type_node, integer_type_node, NULL_TREE);
|
|
||||||
context_function_decl = build_fn_decl(context_function, fntype);
|
|
||||||
|
|
||||||
TREE_PUBLIC(context_function_decl) = 1;
|
|
||||||
TREE_USED(context_function_decl) = 1;
|
|
||||||
DECL_EXTERNAL(context_function_decl) = 1;
|
|
||||||
DECL_ARTIFICIAL(context_function_decl) = 1;
|
|
||||||
DECL_PRESERVE_P(context_function_decl) = 1;
|
|
||||||
// TREE_NOTHROW(context_function_decl) = 1;
|
|
||||||
// DECL_UNINLINABLE(context_function_decl) = 1;
|
|
||||||
DECL_ASSEMBLER_NAME(context_function_decl); // for LTO
|
|
||||||
lang_hooks.decls.pushdecl(context_function_decl);
|
|
||||||
|
|
||||||
// void __context_error__(const void *, int) __attribute__((error("context error")));
|
|
||||||
fntype = build_function_type_list(void_type_node, const_ptr_type_node, integer_type_node, NULL_TREE);
|
|
||||||
context_error_decl = build_fn_decl(context_error, fntype);
|
|
||||||
|
|
||||||
TREE_PUBLIC(context_error_decl) = 1;
|
|
||||||
TREE_USED(context_error_decl) = 1;
|
|
||||||
DECL_EXTERNAL(context_error_decl) = 1;
|
|
||||||
DECL_ARTIFICIAL(context_error_decl) = 1;
|
|
||||||
DECL_PRESERVE_P(context_error_decl) = 1;
|
|
||||||
// TREE_NOTHROW(context_error_decl) = 1;
|
|
||||||
// DECL_UNINLINABLE(context_error_decl) = 1;
|
|
||||||
TREE_THIS_VOLATILE(context_error_decl) = 1;
|
|
||||||
DECL_ASSEMBLER_NAME(context_error_decl);
|
|
||||||
|
|
||||||
attr = tree_cons(NULL, build_const_char_string(14, "context error"), NULL);
|
|
||||||
attr = tree_cons(get_identifier("error"), attr, NULL);
|
|
||||||
decl_attributes(&context_error_decl, attr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool context_gate(void)
|
|
||||||
{
|
|
||||||
tree context_attr;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
context_attr = lookup_attribute("context", DECL_ATTRIBUTES(current_function_decl));
|
|
||||||
return context_attr != NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static basic_block verify_context_before(gimple_stmt_iterator *gsi, tree context, tree inout, tree error)
|
|
||||||
{
|
|
||||||
gimple stmt;
|
|
||||||
basic_block cond_bb, join_bb, true_bb;
|
|
||||||
edge e;
|
|
||||||
location_t loc;
|
|
||||||
const char *file;
|
|
||||||
int line;
|
|
||||||
size_t len;
|
|
||||||
tree filename;
|
|
||||||
|
|
||||||
stmt = gsi_stmt(*gsi);
|
|
||||||
if (gimple_has_location(stmt)) {
|
|
||||||
loc = gimple_location(stmt);
|
|
||||||
file = gimple_filename(stmt);
|
|
||||||
line = gimple_lineno(stmt);
|
|
||||||
} else {
|
|
||||||
loc = DECL_SOURCE_LOCATION(current_function_decl);
|
|
||||||
file = DECL_SOURCE_FILE(current_function_decl);
|
|
||||||
line = DECL_SOURCE_LINE(current_function_decl);
|
|
||||||
}
|
|
||||||
gcc_assert(file);
|
|
||||||
|
|
||||||
// if (context != count) __context_error__(__FILE__, __LINE__);
|
|
||||||
stmt = gimple_build_cond(NE_EXPR, context, inout, NULL_TREE, NULL_TREE);
|
|
||||||
gimple_set_location(stmt, loc);
|
|
||||||
gsi_insert_before(gsi, stmt, GSI_NEW_STMT);
|
|
||||||
|
|
||||||
cond_bb = gsi_bb(*gsi);
|
|
||||||
gcc_assert(!gsi_end_p(*gsi));
|
|
||||||
gcc_assert(stmt == gsi_stmt(*gsi));
|
|
||||||
|
|
||||||
e = split_block(cond_bb, gsi_stmt(*gsi));
|
|
||||||
cond_bb = e->src;
|
|
||||||
join_bb = e->dest;
|
|
||||||
e->flags = EDGE_FALSE_VALUE;
|
|
||||||
e->probability = REG_BR_PROB_BASE;
|
|
||||||
|
|
||||||
true_bb = create_empty_bb(EXIT_BLOCK_PTR_FOR_FN(cfun)->prev_bb);
|
|
||||||
make_edge(cond_bb, true_bb, EDGE_TRUE_VALUE);
|
|
||||||
make_edge(true_bb, join_bb, EDGE_FALLTHRU);
|
|
||||||
|
|
||||||
set_immediate_dominator(CDI_DOMINATORS, true_bb, cond_bb);
|
|
||||||
set_immediate_dominator(CDI_DOMINATORS, join_bb, cond_bb);
|
|
||||||
|
|
||||||
gcc_assert(cond_bb->loop_father == join_bb->loop_father);
|
|
||||||
add_bb_to_loop(true_bb, cond_bb->loop_father);
|
|
||||||
|
|
||||||
// insert call to builtin_trap or __context_error__
|
|
||||||
*gsi = gsi_start_bb(true_bb);
|
|
||||||
|
|
||||||
// stmt = gimple_build_call(builtin_decl_implicit(BUILT_IN_TRAP), 0);
|
|
||||||
len = strlen(file) + 1;
|
|
||||||
filename = build_const_char_string(len, file);
|
|
||||||
filename = build1(ADDR_EXPR, const_ptr_type_node, filename);
|
|
||||||
stmt = gimple_build_call(error, 2, filename, build_int_cst(NULL_TREE, line));
|
|
||||||
gimple_set_location(stmt, loc);
|
|
||||||
gsi_insert_after(gsi, stmt, GSI_CONTINUE_LINKING);
|
|
||||||
|
|
||||||
*gsi = gsi_start_nondebug_bb(join_bb);
|
|
||||||
return join_bb;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void update_context(gimple_stmt_iterator *gsi, tree context, int diff)
|
|
||||||
{
|
|
||||||
gimple assign;
|
|
||||||
tree op;
|
|
||||||
|
|
||||||
op = fold_build2_loc(UNKNOWN_LOCATION, PLUS_EXPR, integer_type_node, context, build_int_cst(integer_type_node, diff));
|
|
||||||
assign = gimple_build_assign(context, op);
|
|
||||||
gsi_insert_after(gsi, assign, GSI_NEW_STMT);
|
|
||||||
update_stmt(assign);
|
|
||||||
}
|
|
||||||
|
|
||||||
static basic_block track_context(basic_block bb, tree context)
|
|
||||||
{
|
|
||||||
gimple_stmt_iterator gsi;
|
|
||||||
gimple assign;
|
|
||||||
|
|
||||||
// adjust context according to the context information on any call stmt
|
|
||||||
for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
|
|
||||||
gimple stmt = gsi_stmt(gsi);
|
|
||||||
tree fndecl, context_attr;
|
|
||||||
tree lock, in, out;
|
|
||||||
int incount, outcount;
|
|
||||||
|
|
||||||
if (!is_gimple_call(stmt))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
fndecl = gimple_call_fndecl(stmt);
|
|
||||||
if (!fndecl)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (fndecl == context_function_decl) {
|
|
||||||
unsigned int num_ops = gimple_num_ops(stmt);
|
|
||||||
int diff = tree_to_shwi(gimple_op(stmt, num_ops - 1));
|
|
||||||
|
|
||||||
gcc_assert(diff);
|
|
||||||
update_context(&gsi, context, diff);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
context_attr = lookup_attribute("context", DECL_ATTRIBUTES(fndecl));
|
|
||||||
if (!context_attr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
gcc_assert(split_context_attribute(TREE_VALUE(context_attr), &lock, &in, &out));
|
|
||||||
incount = tree_to_shwi(in);
|
|
||||||
outcount = tree_to_shwi(out);
|
|
||||||
bb = verify_context_before(&gsi, context, in, context_error_decl);
|
|
||||||
update_context(&gsi, context, outcount - incount);
|
|
||||||
}
|
|
||||||
|
|
||||||
return bb;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool bb_any_loop(basic_block bb)
|
|
||||||
{
|
|
||||||
return bb_loop_depth(bb) || (bb->flags & BB_IRREDUCIBLE_LOOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int context_execute(void)
|
|
||||||
{
|
|
||||||
basic_block bb;
|
|
||||||
gimple assign;
|
|
||||||
gimple_stmt_iterator gsi;
|
|
||||||
tree context_attr, context;
|
|
||||||
tree lock, in, out;
|
|
||||||
|
|
||||||
loop_optimizer_init(LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
|
|
||||||
gcc_assert(current_loops);
|
|
||||||
|
|
||||||
calculate_dominance_info(CDI_DOMINATORS);
|
|
||||||
calculate_dominance_info(CDI_POST_DOMINATORS);
|
|
||||||
|
|
||||||
context_attr = lookup_attribute("context", DECL_ATTRIBUTES(current_function_decl));
|
|
||||||
if (context_attr) {
|
|
||||||
gcc_assert(split_context_attribute(TREE_VALUE(context_attr), &lock, &in, &out));
|
|
||||||
} else {
|
|
||||||
in = out = integer_zero_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. create local context variable
|
|
||||||
context = create_tmp_var(integer_type_node, "context");
|
|
||||||
add_referenced_var(context);
|
|
||||||
mark_sym_for_renaming(context);
|
|
||||||
|
|
||||||
// 2. initialize local context variable
|
|
||||||
gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun)));
|
|
||||||
bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun));
|
|
||||||
if (!single_pred_p(bb)) {
|
|
||||||
gcc_assert(bb_any_loop(bb));
|
|
||||||
split_edge(single_succ_edge(ENTRY_BLOCK_PTR_FOR_FN(cfun)));
|
|
||||||
bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun));
|
|
||||||
}
|
|
||||||
gsi = gsi_start_bb(bb);
|
|
||||||
assign = gimple_build_assign(context, in);
|
|
||||||
gsi_insert_before(&gsi, assign, GSI_NEW_STMT);
|
|
||||||
update_stmt(assign);
|
|
||||||
|
|
||||||
// 3. instrument each BB to track the local context variable
|
|
||||||
FOR_EACH_BB_FN(bb, cfun) {
|
|
||||||
bb = track_context(bb, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. verify the local context variable against the expected state
|
|
||||||
if (EDGE_COUNT(EXIT_BLOCK_PTR_FOR_FN(cfun)->preds)) {
|
|
||||||
gcc_assert(single_pred_p(EXIT_BLOCK_PTR_FOR_FN(cfun)));
|
|
||||||
gsi = gsi_last_nondebug_bb(single_pred(EXIT_BLOCK_PTR_FOR_FN(cfun)));
|
|
||||||
verify_context_before(&gsi, context, out, context_error_decl);
|
|
||||||
}
|
|
||||||
|
|
||||||
free_dominance_info(CDI_DOMINATORS);
|
|
||||||
free_dominance_info(CDI_POST_DOMINATORS);
|
|
||||||
loop_optimizer_finalize();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PASS_NAME context
|
|
||||||
#define PROPERTIES_REQUIRED PROP_gimple_leh | PROP_cfg
|
|
||||||
//#define TODO_FLAGS_START TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts
|
|
||||||
#define TODO_FLAGS_FINISH TODO_verify_ssa | TODO_verify_stmts | TODO_dump_func | TODO_verify_flow | TODO_update_ssa
|
|
||||||
#include "gcc-generate-gimple-pass.h"
|
|
||||||
|
|
||||||
__visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
|
|
||||||
{
|
|
||||||
const char * const plugin_name = plugin_info->base_name;
|
|
||||||
const int argc = plugin_info->argc;
|
|
||||||
const struct plugin_argument * const argv = plugin_info->argv;
|
|
||||||
int i;
|
|
||||||
bool enable_user, enable_context;
|
|
||||||
|
|
||||||
static const struct ggc_root_tab gt_ggc_r_gt_checker[] = {
|
|
||||||
{
|
|
||||||
.base = &context_function_decl,
|
|
||||||
.nelt = 1,
|
|
||||||
.stride = sizeof(context_function_decl),
|
|
||||||
.cb = >_ggc_mx_tree_node,
|
|
||||||
.pchw = >_pch_nx_tree_node
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.base = &context_error_decl,
|
|
||||||
.nelt = 1,
|
|
||||||
.stride = sizeof(context_error_decl),
|
|
||||||
.cb = >_ggc_mx_tree_node,
|
|
||||||
.pchw = >_pch_nx_tree_node
|
|
||||||
},
|
|
||||||
LAST_GGC_ROOT_TAB
|
|
||||||
};
|
|
||||||
|
|
||||||
// PASS_INFO(context, "ssa", 1, PASS_POS_INSERT_AFTER);
|
|
||||||
PASS_INFO(context, "phiprop", 1, PASS_POS_INSERT_AFTER);
|
|
||||||
|
|
||||||
if (!plugin_default_version_check(version, &gcc_version)) {
|
|
||||||
error_gcc_version(version);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
register_callback(plugin_name, PLUGIN_INFO, NULL, &checker_plugin_info);
|
|
||||||
|
|
||||||
enable_user = false;
|
|
||||||
enable_context = false;
|
|
||||||
for (i = 0; i < argc; ++i) {
|
|
||||||
if (!strcmp(argv[i].key, "user")) {
|
|
||||||
enable_user = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(argv[i].key, "context")) {
|
|
||||||
enable_context = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enable_user)
|
|
||||||
register_callback(plugin_name, PLUGIN_PRAGMAS, register_checker_address_spaces, NULL);
|
|
||||||
if (enable_context) {
|
|
||||||
register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL);
|
|
||||||
register_callback(plugin_name, PLUGIN_START_UNIT, context_start_unit, NULL);
|
|
||||||
register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, (void *)>_ggc_r_gt_checker);
|
|
||||||
register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &context_pass_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,158 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012-2017 by PaX Team <pageexec@freemail.hu>
|
|
||||||
* Licensed under the GPL v2
|
|
||||||
*
|
|
||||||
* Note: the choice of the license means that the compilation process is
|
|
||||||
* NOT 'eligible' as defined by gcc's library exception to the GPL v3,
|
|
||||||
* but for the kernel it doesn't matter since it doesn't link against
|
|
||||||
* any of the gcc libraries
|
|
||||||
*
|
|
||||||
* gcc plugin to colorize diagnostic output
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "gcc-common.h"
|
|
||||||
|
|
||||||
__visible int plugin_is_GPL_compatible;
|
|
||||||
|
|
||||||
static struct plugin_info colorize_plugin_info = {
|
|
||||||
.version = "201602181345",
|
|
||||||
.help = "color=[never|always|auto]\tdetermine when to colorize\n",
|
|
||||||
};
|
|
||||||
|
|
||||||
#define GREEN "\033[32m\033[K"
|
|
||||||
#define LIGHTGREEN "\033[1;32m\033[K"
|
|
||||||
#define YELLOW "\033[33m\033[K"
|
|
||||||
#define LIGHTYELLOW "\033[1;33m\033[K"
|
|
||||||
#define RED "\033[31m\033[K"
|
|
||||||
#define LIGHTRED "\033[1;31m\033[K"
|
|
||||||
#define BLUE "\033[34m\033[K"
|
|
||||||
#define LIGHTBLUE "\033[1;34m\033[K"
|
|
||||||
#define BRIGHT "\033[1;m\033[K"
|
|
||||||
#define NORMAL "\033[m\033[K"
|
|
||||||
|
|
||||||
static diagnostic_starter_fn old_starter;
|
|
||||||
static diagnostic_finalizer_fn old_finalizer;
|
|
||||||
|
|
||||||
static void start_colorize(diagnostic_context *context, diagnostic_info *diagnostic)
|
|
||||||
{
|
|
||||||
const char *color;
|
|
||||||
char *newprefix;
|
|
||||||
|
|
||||||
switch (diagnostic->kind) {
|
|
||||||
case DK_NOTE:
|
|
||||||
color = LIGHTBLUE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DK_PEDWARN:
|
|
||||||
case DK_WARNING:
|
|
||||||
color = LIGHTYELLOW;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DK_ERROR:
|
|
||||||
case DK_FATAL:
|
|
||||||
case DK_ICE:
|
|
||||||
case DK_PERMERROR:
|
|
||||||
case DK_SORRY:
|
|
||||||
color = LIGHTRED;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
color = NORMAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
old_starter(context, diagnostic);
|
|
||||||
if (-1 == asprintf(&newprefix, "%s%s" NORMAL, color, context->printer->prefix))
|
|
||||||
return;
|
|
||||||
pp_destroy_prefix(context->printer);
|
|
||||||
pp_set_prefix(context->printer, newprefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void finalize_colorize(diagnostic_context *context, diagnostic_info *diagnostic)
|
|
||||||
{
|
|
||||||
old_finalizer(context, diagnostic);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void colorize_arm(void)
|
|
||||||
{
|
|
||||||
old_starter = diagnostic_starter(global_dc);
|
|
||||||
old_finalizer = diagnostic_finalizer(global_dc);
|
|
||||||
|
|
||||||
diagnostic_starter(global_dc) = start_colorize;
|
|
||||||
diagnostic_finalizer(global_dc) = finalize_colorize;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int colorize_rearm_execute(void)
|
|
||||||
{
|
|
||||||
if (diagnostic_starter(global_dc) == start_colorize)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
colorize_arm();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PASS_NAME colorize_rearm
|
|
||||||
#define NO_GATE
|
|
||||||
#include "gcc-generate-simple_ipa-pass.h"
|
|
||||||
|
|
||||||
static void colorize_start_unit(void *gcc_data __unused, void *user_data __unused)
|
|
||||||
{
|
|
||||||
colorize_arm();
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool should_colorize(void)
|
|
||||||
{
|
|
||||||
#if BUILDING_GCC_VERSION >= 4009
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
char const *t = getenv("TERM");
|
|
||||||
|
|
||||||
return t && strcmp(t, "dumb") && isatty(STDERR_FILENO);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
__visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
|
|
||||||
{
|
|
||||||
const char * const plugin_name = plugin_info->base_name;
|
|
||||||
const int argc = plugin_info->argc;
|
|
||||||
const struct plugin_argument * const argv = plugin_info->argv;
|
|
||||||
int i;
|
|
||||||
bool colorize;
|
|
||||||
|
|
||||||
PASS_INFO(colorize_rearm, "*free_lang_data", 1, PASS_POS_INSERT_AFTER);
|
|
||||||
|
|
||||||
if (!plugin_default_version_check(version, &gcc_version)) {
|
|
||||||
error_gcc_version(version);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
register_callback(plugin_name, PLUGIN_INFO, NULL, &colorize_plugin_info);
|
|
||||||
|
|
||||||
colorize = getenv("GCC_COLORS") ? should_colorize() : false;
|
|
||||||
|
|
||||||
for (i = 0; i < argc; ++i) {
|
|
||||||
if (!strcmp(argv[i].key, "color")) {
|
|
||||||
if (!argv[i].value) {
|
|
||||||
error(G_("no value supplied for option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(argv[i].value, "always"))
|
|
||||||
colorize = true;
|
|
||||||
else if (!strcmp(argv[i].value, "never"))
|
|
||||||
colorize = false;
|
|
||||||
else if (!strcmp(argv[i].value, "auto"))
|
|
||||||
colorize = should_colorize();
|
|
||||||
else
|
|
||||||
error(G_("invalid option argument '-fplugin-arg-%s-%s=%s'"), plugin_name, argv[i].key, argv[i].value);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colorize) {
|
|
||||||
// TODO: parse GCC_COLORS as used by gcc 4.9+
|
|
||||||
register_callback(plugin_name, PLUGIN_START_UNIT, &colorize_start_unit, NULL);
|
|
||||||
register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &colorize_rearm_pass_info);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,577 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011 by Emese Revfy <re.emese@gmail.com>
|
|
||||||
* Copyright 2011-2017 by PaX Team <pageexec@freemail.hu>
|
|
||||||
* Licensed under the GPL v2, or (at your option) v3
|
|
||||||
*
|
|
||||||
* This gcc plugin constifies all structures which contain only function pointers or are explicitly marked for constification.
|
|
||||||
*
|
|
||||||
* Homepage:
|
|
||||||
* http://www.grsecurity.net/~ephox/const_plugin/
|
|
||||||
*
|
|
||||||
* Usage:
|
|
||||||
* $ gcc -I`gcc -print-file-name=plugin`/include -fPIC -shared -O2 -o constify_plugin.so constify_plugin.c
|
|
||||||
* $ gcc -fplugin=constify_plugin.so test.c -O2
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "gcc-common.h"
|
|
||||||
|
|
||||||
// unused C type flag in all versions 4.5-6
|
|
||||||
#define TYPE_CONSTIFY_VISITED(TYPE) TYPE_LANG_FLAG_4(TYPE)
|
|
||||||
|
|
||||||
__visible int plugin_is_GPL_compatible;
|
|
||||||
|
|
||||||
static bool enabled = true;
|
|
||||||
|
|
||||||
static struct plugin_info const_plugin_info = {
|
|
||||||
.version = "201607241840",
|
|
||||||
.help = "disable\tturn off constification\n",
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
const char *name;
|
|
||||||
const char *asm_op;
|
|
||||||
} const_sections[] = {
|
|
||||||
{".init.rodata", "\t.section\t.init.rodata,\"a\""},
|
|
||||||
{".ref.rodata", "\t.section\t.ref.rodata,\"a\""},
|
|
||||||
{".devinit.rodata", "\t.section\t.devinit.rodata,\"a\""},
|
|
||||||
{".devexit.rodata", "\t.section\t.devexit.rodata,\"a\""},
|
|
||||||
{".cpuinit.rodata", "\t.section\t.cpuinit.rodata,\"a\""},
|
|
||||||
{".cpuexit.rodata", "\t.section\t.cpuexit.rodata,\"a\""},
|
|
||||||
{".meminit.rodata", "\t.section\t.meminit.rodata,\"a\""},
|
|
||||||
{".memexit.rodata", "\t.section\t.memexit.rodata,\"a\""},
|
|
||||||
{".data..read_only", "\t.section\t.data..read_only,\"a\""},
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
bool has_fptr_field;
|
|
||||||
bool has_writable_field;
|
|
||||||
bool has_do_const_field;
|
|
||||||
bool has_no_const_field;
|
|
||||||
} constify_info;
|
|
||||||
|
|
||||||
static const_tree get_field_type(const_tree field)
|
|
||||||
{
|
|
||||||
return strip_array_types(TREE_TYPE(field));
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_fptr(const_tree field)
|
|
||||||
{
|
|
||||||
const_tree ptr = get_field_type(field);
|
|
||||||
|
|
||||||
if (TREE_CODE(ptr) != POINTER_TYPE)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return TREE_CODE(TREE_TYPE(ptr)) == FUNCTION_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* determine whether the given structure type meets the requirements for automatic constification,
|
|
||||||
* including the constification attributes on nested structure types
|
|
||||||
*/
|
|
||||||
static void constifiable(const_tree node, constify_info *cinfo)
|
|
||||||
{
|
|
||||||
const_tree field;
|
|
||||||
|
|
||||||
gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE);
|
|
||||||
|
|
||||||
// e.g., pointer to structure fields while still constructing the structure type
|
|
||||||
if (TYPE_FIELDS(node) == NULL_TREE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (field = TYPE_FIELDS(node); field; field = TREE_CHAIN(field)) {
|
|
||||||
const_tree type = get_field_type(field);
|
|
||||||
enum tree_code code = TREE_CODE(type);
|
|
||||||
|
|
||||||
if (node == type)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (is_fptr(field))
|
|
||||||
cinfo->has_fptr_field = true;
|
|
||||||
else if (code == RECORD_TYPE || code == UNION_TYPE) {
|
|
||||||
if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type)))
|
|
||||||
cinfo->has_do_const_field = true;
|
|
||||||
else if (lookup_attribute("no_const", TYPE_ATTRIBUTES(type)))
|
|
||||||
cinfo->has_no_const_field = true;
|
|
||||||
else
|
|
||||||
constifiable(type, cinfo);
|
|
||||||
} else if (!TREE_READONLY(field))
|
|
||||||
cinfo->has_writable_field = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool constified(const_tree node)
|
|
||||||
{
|
|
||||||
constify_info cinfo = {
|
|
||||||
.has_fptr_field = false,
|
|
||||||
.has_writable_field = false,
|
|
||||||
.has_do_const_field = false,
|
|
||||||
.has_no_const_field = false
|
|
||||||
};
|
|
||||||
|
|
||||||
gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE);
|
|
||||||
|
|
||||||
if (lookup_attribute("no_const", TYPE_ATTRIBUTES(node))) {
|
|
||||||
// gcc_assert(!TYPE_READONLY(node));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lookup_attribute("do_const", TYPE_ATTRIBUTES(node))) {
|
|
||||||
gcc_assert(TYPE_READONLY(node));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
constifiable(node, &cinfo);
|
|
||||||
if ((!cinfo.has_fptr_field || cinfo.has_writable_field || cinfo.has_no_const_field) && !cinfo.has_do_const_field)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return TYPE_READONLY(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void deconstify_tree(tree node);
|
|
||||||
|
|
||||||
static void deconstify_type(tree type)
|
|
||||||
{
|
|
||||||
tree field;
|
|
||||||
|
|
||||||
gcc_assert(TREE_CODE(type) == RECORD_TYPE || TREE_CODE(type) == UNION_TYPE);
|
|
||||||
|
|
||||||
for (field = TYPE_FIELDS(type); field; field = TREE_CHAIN(field)) {
|
|
||||||
const_tree fieldtype = get_field_type(field);
|
|
||||||
|
|
||||||
// special case handling of simple ptr-to-same-array-type members
|
|
||||||
if (TREE_CODE(TREE_TYPE(field)) == POINTER_TYPE) {
|
|
||||||
tree ptrtype = TREE_TYPE(TREE_TYPE(field));
|
|
||||||
|
|
||||||
if (TREE_TYPE(TREE_TYPE(field)) == type)
|
|
||||||
continue;
|
|
||||||
if (TREE_CODE(ptrtype) != RECORD_TYPE && TREE_CODE(ptrtype) != UNION_TYPE)
|
|
||||||
continue;
|
|
||||||
if (!constified(ptrtype))
|
|
||||||
continue;
|
|
||||||
if (TYPE_MAIN_VARIANT(ptrtype) == TYPE_MAIN_VARIANT(type))
|
|
||||||
TREE_TYPE(field) = build_pointer_type(build_qualified_type(type, TYPE_QUALS(ptrtype) & ~TYPE_QUAL_CONST));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (TREE_CODE(fieldtype) != RECORD_TYPE && TREE_CODE(fieldtype) != UNION_TYPE)
|
|
||||||
continue;
|
|
||||||
if (!constified(fieldtype))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
deconstify_tree(field);
|
|
||||||
TREE_READONLY(field) = 0;
|
|
||||||
}
|
|
||||||
TYPE_READONLY(type) = 0;
|
|
||||||
C_TYPE_FIELDS_READONLY(type) = 0;
|
|
||||||
if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) {
|
|
||||||
TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type));
|
|
||||||
TYPE_ATTRIBUTES(type) = remove_attribute("do_const", TYPE_ATTRIBUTES(type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void deconstify_tree(tree node)
|
|
||||||
{
|
|
||||||
tree old_type, new_type, field;
|
|
||||||
|
|
||||||
old_type = TREE_TYPE(node);
|
|
||||||
while (TREE_CODE(old_type) == ARRAY_TYPE && TREE_CODE(TREE_TYPE(old_type)) != ARRAY_TYPE) {
|
|
||||||
node = TREE_TYPE(node) = copy_node(old_type);
|
|
||||||
old_type = TREE_TYPE(old_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
gcc_assert(TREE_CODE(old_type) == RECORD_TYPE || TREE_CODE(old_type) == UNION_TYPE);
|
|
||||||
gcc_assert(TYPE_READONLY(old_type) && (TYPE_QUALS(old_type) & TYPE_QUAL_CONST));
|
|
||||||
|
|
||||||
new_type = build_qualified_type(old_type, TYPE_QUALS(old_type) & ~TYPE_QUAL_CONST);
|
|
||||||
TYPE_FIELDS(new_type) = copy_list(TYPE_FIELDS(new_type));
|
|
||||||
for (field = TYPE_FIELDS(new_type); field; field = TREE_CHAIN(field))
|
|
||||||
DECL_FIELD_CONTEXT(field) = new_type;
|
|
||||||
|
|
||||||
deconstify_type(new_type);
|
|
||||||
|
|
||||||
TREE_TYPE(node) = new_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
static tree handle_no_const_attribute(tree *node, tree name, tree args __unused, int flags __unused, bool *no_add_attrs)
|
|
||||||
{
|
|
||||||
tree type;
|
|
||||||
constify_info cinfo = {
|
|
||||||
.has_fptr_field = false,
|
|
||||||
.has_writable_field = false,
|
|
||||||
.has_do_const_field = false,
|
|
||||||
.has_no_const_field = false
|
|
||||||
};
|
|
||||||
|
|
||||||
*no_add_attrs = true;
|
|
||||||
if (TREE_CODE(*node) == FUNCTION_DECL) {
|
|
||||||
error("%qE attribute does not apply to functions (%qF)", name, *node);
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TREE_CODE(*node) == PARM_DECL) {
|
|
||||||
error("%qE attribute does not apply to function parameters (%qD)", name, *node);
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TREE_CODE(*node) == VAR_DECL) {
|
|
||||||
error("%qE attribute does not apply to variables (%qD)", name, *node);
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TYPE_P(*node)) {
|
|
||||||
type = *node;
|
|
||||||
} else {
|
|
||||||
if (TREE_CODE(*node) != TYPE_DECL) {
|
|
||||||
error("%qE attribute does not apply to %qD (%qT)", name, *node, TREE_TYPE(*node));
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
type = TREE_TYPE(*node);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) {
|
|
||||||
error("%qE attribute used on %qT applies to struct and union types only", name, type);
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lookup_attribute(IDENTIFIER_POINTER(name), TYPE_ATTRIBUTES(type))) {
|
|
||||||
error("%qE attribute is already applied to the type %qT", name, type);
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TYPE_P(*node)) {
|
|
||||||
if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type)))
|
|
||||||
error("%qE attribute used on type %qT is incompatible with 'do_const'", name, type);
|
|
||||||
else
|
|
||||||
*no_add_attrs = false;
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
constifiable(type, &cinfo);
|
|
||||||
if ((cinfo.has_fptr_field && !cinfo.has_writable_field && !cinfo.has_no_const_field) || lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) {
|
|
||||||
if (enabled) {
|
|
||||||
if TYPE_P(*node)
|
|
||||||
deconstify_type(*node);
|
|
||||||
else
|
|
||||||
deconstify_tree(*node);
|
|
||||||
}
|
|
||||||
if (TYPE_P(*node))
|
|
||||||
TYPE_CONSTIFY_VISITED(*node) = 1;
|
|
||||||
else
|
|
||||||
TYPE_CONSTIFY_VISITED(TREE_TYPE(*node)) = 1;
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enabled && TYPE_FIELDS(type))
|
|
||||||
error("%qE attribute used on type %qT that is not constified", name, type);
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void constify_type(tree type)
|
|
||||||
{
|
|
||||||
gcc_assert(type == TYPE_MAIN_VARIANT(type));
|
|
||||||
TYPE_READONLY(type) = 1;
|
|
||||||
C_TYPE_FIELDS_READONLY(type) = 1;
|
|
||||||
TYPE_CONSTIFY_VISITED(type) = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static tree handle_do_const_attribute(tree *node, tree name, tree args __unused, int flags __unused, bool *no_add_attrs)
|
|
||||||
{
|
|
||||||
*no_add_attrs = true;
|
|
||||||
if (!TYPE_P(*node)) {
|
|
||||||
error("%qE attribute applies to types only (%qD)", name, *node);
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TREE_CODE(*node) != RECORD_TYPE && TREE_CODE(*node) != UNION_TYPE) {
|
|
||||||
error("%qE attribute used on %qT applies to struct and union types only", name, *node);
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lookup_attribute(IDENTIFIER_POINTER(name), TYPE_ATTRIBUTES(*node))) {
|
|
||||||
error("%qE attribute used on %qT is already applied to the type", name, *node);
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lookup_attribute("no_const", TYPE_ATTRIBUTES(*node))) {
|
|
||||||
error("%qE attribute used on %qT is incompatible with 'no_const'", name, *node);
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*no_add_attrs = false;
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct attribute_spec no_const_attr = {
|
|
||||||
.name = "no_const",
|
|
||||||
.min_length = 0,
|
|
||||||
.max_length = 0,
|
|
||||||
.decl_required = false,
|
|
||||||
.type_required = false,
|
|
||||||
.function_type_required = false,
|
|
||||||
.handler = handle_no_const_attribute,
|
|
||||||
#if BUILDING_GCC_VERSION >= 4007
|
|
||||||
.affects_type_identity = true
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct attribute_spec do_const_attr = {
|
|
||||||
.name = "do_const",
|
|
||||||
.min_length = 0,
|
|
||||||
.max_length = 0,
|
|
||||||
.decl_required = false,
|
|
||||||
.type_required = false,
|
|
||||||
.function_type_required = false,
|
|
||||||
.handler = handle_do_const_attribute,
|
|
||||||
#if BUILDING_GCC_VERSION >= 4007
|
|
||||||
.affects_type_identity = true
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
static void register_attributes(void *event_data, void *data)
|
|
||||||
{
|
|
||||||
register_attribute(&no_const_attr);
|
|
||||||
register_attribute(&do_const_attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void finish_type(void *event_data, void *data __unused)
|
|
||||||
{
|
|
||||||
tree type = (tree)event_data;
|
|
||||||
constify_info cinfo = {
|
|
||||||
.has_fptr_field = false,
|
|
||||||
.has_writable_field = false,
|
|
||||||
.has_do_const_field = false,
|
|
||||||
.has_no_const_field = false
|
|
||||||
};
|
|
||||||
|
|
||||||
if (type == NULL_TREE || type == error_mark_node)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION >= 5000
|
|
||||||
if (TREE_CODE(type) == ENUMERAL_TYPE)
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (TYPE_FIELDS(type) == NULL_TREE || TYPE_CONSTIFY_VISITED(type))
|
|
||||||
return;
|
|
||||||
|
|
||||||
constifiable(type, &cinfo);
|
|
||||||
|
|
||||||
if (lookup_attribute("no_const", TYPE_ATTRIBUTES(type))) {
|
|
||||||
if ((cinfo.has_fptr_field && !cinfo.has_writable_field && !cinfo.has_no_const_field) || cinfo.has_do_const_field) {
|
|
||||||
deconstify_type(type);
|
|
||||||
TYPE_CONSTIFY_VISITED(type) = 1;
|
|
||||||
} else
|
|
||||||
error("'no_const' attribute used on type %qT that is not constified", type);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) {
|
|
||||||
if (!cinfo.has_writable_field && !cinfo.has_no_const_field) {
|
|
||||||
error("'do_const' attribute used on type %qT that is%sconstified", type, cinfo.has_fptr_field ? " " : " not ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
constify_type(type);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cinfo.has_fptr_field && !cinfo.has_writable_field && !cinfo.has_no_const_field) {
|
|
||||||
if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) {
|
|
||||||
error("'do_const' attribute used on type %qT that is constified", type);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
constify_type(type);
|
|
||||||
// TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type));
|
|
||||||
// TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("do_const"), NULL_TREE, TYPE_ATTRIBUTES(type));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
deconstify_type(type);
|
|
||||||
TYPE_CONSTIFY_VISITED(type) = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_constified_var(varpool_node_ptr node)
|
|
||||||
{
|
|
||||||
tree var = NODE_DECL(node);
|
|
||||||
tree type = TREE_TYPE(var);
|
|
||||||
|
|
||||||
if (node->alias)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (DECL_EXTERNAL(var))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// XXX handle more complex nesting of arrays/structs
|
|
||||||
if (TREE_CODE(type) == ARRAY_TYPE)
|
|
||||||
type = TREE_TYPE(type);
|
|
||||||
|
|
||||||
if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!TYPE_READONLY(type) || !C_TYPE_FIELDS_READONLY(type))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!TYPE_CONSTIFY_VISITED(type))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void check_section_mismatch(varpool_node_ptr node)
|
|
||||||
{
|
|
||||||
tree var, section;
|
|
||||||
size_t i;
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
var = NODE_DECL(node);
|
|
||||||
name = get_decl_section_name(var);
|
|
||||||
section = lookup_attribute("section", DECL_ATTRIBUTES(var));
|
|
||||||
if (!section) {
|
|
||||||
if (name) {
|
|
||||||
fprintf(stderr, "DECL_SECTION [%s] ", name);
|
|
||||||
dump_varpool_node(stderr, node);
|
|
||||||
gcc_unreachable();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else
|
|
||||||
gcc_assert(name);
|
|
||||||
|
|
||||||
//fprintf(stderr, "SECTIONAME: [%s] ", get_decl_section_name(var));
|
|
||||||
//debug_tree(var);
|
|
||||||
|
|
||||||
gcc_assert(!TREE_CHAIN(section));
|
|
||||||
gcc_assert(TREE_VALUE(section));
|
|
||||||
|
|
||||||
section = TREE_VALUE(TREE_VALUE(section));
|
|
||||||
gcc_assert(!strcmp(TREE_STRING_POINTER(section), name));
|
|
||||||
//debug_tree(section);
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(const_sections); i++)
|
|
||||||
if (!strcmp(const_sections[i].name, name))
|
|
||||||
return;
|
|
||||||
|
|
||||||
error_at(DECL_SOURCE_LOCATION(var), "constified variable %qD placed into writable section %E", var, section);
|
|
||||||
}
|
|
||||||
|
|
||||||
// this works around a gcc bug/feature where uninitialized globals
|
|
||||||
// are moved into the .bss section regardless of any constification
|
|
||||||
// see gcc/varasm.c:bss_initializer_p()
|
|
||||||
static void fix_initializer(varpool_node_ptr node)
|
|
||||||
{
|
|
||||||
tree var = NODE_DECL(node);
|
|
||||||
tree type = TREE_TYPE(var);
|
|
||||||
|
|
||||||
if (DECL_INITIAL(var))
|
|
||||||
return;
|
|
||||||
|
|
||||||
DECL_INITIAL(var) = build_constructor(type, NULL);
|
|
||||||
// inform(DECL_SOURCE_LOCATION(var), "constified variable %qE moved into .rodata", var);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void check_global_variables(void *event_data __unused, void *data __unused)
|
|
||||||
{
|
|
||||||
varpool_node_ptr node;
|
|
||||||
|
|
||||||
FOR_EACH_VARIABLE(node) {
|
|
||||||
if (!is_constified_var(node))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
check_section_mismatch(node);
|
|
||||||
fix_initializer(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int check_local_variables_execute(void)
|
|
||||||
{
|
|
||||||
unsigned int ret = 0;
|
|
||||||
tree var;
|
|
||||||
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
FOR_EACH_LOCAL_DECL(cfun, i, var) {
|
|
||||||
tree type = TREE_TYPE(var);
|
|
||||||
|
|
||||||
gcc_assert(DECL_P(var));
|
|
||||||
if (is_global_var(var))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!TYPE_READONLY(type) || !C_TYPE_FIELDS_READONLY(type))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!TYPE_CONSTIFY_VISITED(type))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
error_at(DECL_SOURCE_LOCATION(var), "constified variable %qE cannot be local", var);
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PASS_NAME check_local_variables
|
|
||||||
#define NO_GATE
|
|
||||||
#include "gcc-generate-gimple-pass.h"
|
|
||||||
|
|
||||||
static unsigned int (*old_section_type_flags)(tree decl, const char *name, int reloc);
|
|
||||||
|
|
||||||
static unsigned int constify_section_type_flags(tree decl, const char *name, int reloc)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(const_sections); i++)
|
|
||||||
if (!strcmp(const_sections[i].name, name))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return old_section_type_flags(decl, name, reloc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void constify_start_unit(void *gcc_data __unused, void *user_data __unused)
|
|
||||||
{
|
|
||||||
// size_t i;
|
|
||||||
|
|
||||||
// for (i = 0; i < ARRAY_SIZE(const_sections); i++)
|
|
||||||
// const_sections[i].section = get_unnamed_section(0, output_section_asm_op, const_sections[i].asm_op);
|
|
||||||
// const_sections[i].section = get_section(const_sections[i].name, 0, NULL);
|
|
||||||
|
|
||||||
old_section_type_flags = targetm.section_type_flags;
|
|
||||||
targetm.section_type_flags = constify_section_type_flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
__visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
|
|
||||||
{
|
|
||||||
const char * const plugin_name = plugin_info->base_name;
|
|
||||||
const int argc = plugin_info->argc;
|
|
||||||
const struct plugin_argument * const argv = plugin_info->argv;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
PASS_INFO(check_local_variables, "ssa", 1, PASS_POS_INSERT_BEFORE);
|
|
||||||
|
|
||||||
if (!plugin_default_version_check(version, &gcc_version)) {
|
|
||||||
error_gcc_version(version);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < argc; ++i) {
|
|
||||||
if (!(strcmp(argv[i].key, "disable"))) {
|
|
||||||
enabled = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp(lang_hooks.name, "GNU C", 5) && !strncmp(lang_hooks.name, "GNU C+", 6)) {
|
|
||||||
inform(UNKNOWN_LOCATION, G_("%s supports C only, not %s"), plugin_name, lang_hooks.name);
|
|
||||||
enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
register_callback(plugin_name, PLUGIN_INFO, NULL, &const_plugin_info);
|
|
||||||
if (enabled) {
|
|
||||||
register_callback(plugin_name, PLUGIN_ALL_IPA_PASSES_START, check_global_variables, NULL);
|
|
||||||
register_callback(plugin_name, PLUGIN_FINISH_TYPE, finish_type, NULL);
|
|
||||||
register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &check_local_variables_pass_info);
|
|
||||||
register_callback(plugin_name, PLUGIN_START_UNIT, constify_start_unit, NULL);
|
|
||||||
}
|
|
||||||
register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011-2017 by Emese Revfy <re.emese@gmail.com>
|
|
||||||
* Licensed under the GPL v2, or (at your option) v3
|
|
||||||
*
|
|
||||||
* Homepage:
|
|
||||||
* https://github.com/ephox-gcc-plugins/cyclomatic_complexity
|
|
||||||
*
|
|
||||||
* http://en.wikipedia.org/wiki/Cyclomatic_complexity
|
|
||||||
* The complexity M is then defined as:
|
|
||||||
* M = E - N + 2P
|
|
||||||
* where
|
|
||||||
*
|
|
||||||
* E = the number of edges of the graph
|
|
||||||
* N = the number of nodes of the graph
|
|
||||||
* P = the number of connected components (exit nodes).
|
|
||||||
*
|
|
||||||
* Usage (4.5 - 5):
|
|
||||||
* $ make clean; make run
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "gcc-common.h"
|
|
||||||
|
|
||||||
__visible int plugin_is_GPL_compatible;
|
|
||||||
|
|
||||||
static struct plugin_info cyc_complexity_plugin_info = {
|
|
||||||
.version = "20160225",
|
|
||||||
.help = "Cyclomatic Complexity\n",
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned int cyc_complexity_execute(void)
|
|
||||||
{
|
|
||||||
int complexity;
|
|
||||||
expanded_location xloc;
|
|
||||||
|
|
||||||
/* M = E - N + 2P */
|
|
||||||
complexity = n_edges_for_fn(cfun) - n_basic_blocks_for_fn(cfun) + 2;
|
|
||||||
|
|
||||||
xloc = expand_location(DECL_SOURCE_LOCATION(current_function_decl));
|
|
||||||
fprintf(stderr, "Cyclomatic Complexity %d %s:%s\n", complexity,
|
|
||||||
xloc.file, DECL_NAME_POINTER(current_function_decl));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PASS_NAME cyc_complexity
|
|
||||||
|
|
||||||
#define NO_GATE
|
|
||||||
#define TODO_FLAGS_FINISH TODO_dump_func
|
|
||||||
|
|
||||||
#include "gcc-generate-gimple-pass.h"
|
|
||||||
|
|
||||||
__visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
|
|
||||||
{
|
|
||||||
const char * const plugin_name = plugin_info->base_name;
|
|
||||||
|
|
||||||
PASS_INFO(cyc_complexity, "ssa", 1, PASS_POS_INSERT_AFTER);
|
|
||||||
|
|
||||||
if (!plugin_default_version_check(version, &gcc_version)) {
|
|
||||||
error_gcc_version(version);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
register_callback(plugin_name, PLUGIN_INFO, NULL,
|
|
||||||
&cyc_complexity_plugin_info);
|
|
||||||
register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
|
|
||||||
&cyc_complexity_pass_info);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
136
src/gcc-common.h
Normal file → Executable file
136
src/gcc-common.h
Normal file → Executable file
@ -21,22 +21,14 @@
|
|||||||
#include "rtl.h"
|
#include "rtl.h"
|
||||||
#include "tm_p.h"
|
#include "tm_p.h"
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
//#include "insn-attr.h"
|
|
||||||
//#include "insn-config.h"
|
|
||||||
//#include "insn-flags.h"
|
|
||||||
#include "hard-reg-set.h"
|
#include "hard-reg-set.h"
|
||||||
//#include "recog.h"
|
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "except.h"
|
#include "except.h"
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
#include "toplev.h"
|
#include "toplev.h"
|
||||||
#if BUILDING_GCC_VERSION >= 5000
|
|
||||||
#include "expr.h"
|
|
||||||
#endif
|
|
||||||
#include "basic-block.h"
|
#include "basic-block.h"
|
||||||
#include "intl.h"
|
#include "intl.h"
|
||||||
#include "ggc.h"
|
#include "ggc.h"
|
||||||
//#include "regs.h"
|
|
||||||
#include "timevar.h"
|
#include "timevar.h"
|
||||||
|
|
||||||
#include "params.h"
|
#include "params.h"
|
||||||
@ -51,18 +43,12 @@
|
|||||||
#include "memmodel.h"
|
#include "memmodel.h"
|
||||||
#endif
|
#endif
|
||||||
#include "emit-rtl.h"
|
#include "emit-rtl.h"
|
||||||
//#include "reload.h"
|
|
||||||
//#include "ira.h"
|
|
||||||
//#include "dwarf2asm.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "langhooks.h"
|
#include "langhooks.h"
|
||||||
#include "cfgloop.h"
|
#include "cfgloop.h"
|
||||||
//#include "hosthooks.h"
|
|
||||||
#include "cgraph.h"
|
#include "cgraph.h"
|
||||||
#include "opts.h"
|
#include "opts.h"
|
||||||
//#include "coverage.h"
|
|
||||||
//#include "value-prof.h"
|
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION == 4005
|
#if BUILDING_GCC_VERSION == 4005
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
@ -74,8 +60,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION >= 4006
|
#if BUILDING_GCC_VERSION >= 4006
|
||||||
//#include "c-tree.h"
|
|
||||||
//#include "cp/cp-tree.h"
|
|
||||||
#include "c-family/c-common.h"
|
#include "c-family/c-common.h"
|
||||||
#else
|
#else
|
||||||
#include "c-common.h"
|
#include "c-common.h"
|
||||||
@ -94,13 +78,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "diagnostic.h"
|
#include "diagnostic.h"
|
||||||
//#include "tree-diagnostic.h"
|
|
||||||
#include "tree-dump.h"
|
#include "tree-dump.h"
|
||||||
#include "tree-pass.h"
|
#include "tree-pass.h"
|
||||||
#if BUILDING_GCC_VERSION >= 4009
|
|
||||||
#include "pass_manager.h"
|
|
||||||
#endif
|
|
||||||
//#include "df.h"
|
|
||||||
#include "predict.h"
|
#include "predict.h"
|
||||||
#include "ipa-utils.h"
|
#include "ipa-utils.h"
|
||||||
|
|
||||||
@ -111,7 +90,6 @@
|
|||||||
#include "internal-fn.h"
|
#include "internal-fn.h"
|
||||||
#include "gimple-expr.h"
|
#include "gimple-expr.h"
|
||||||
#include "gimple-fold.h"
|
#include "gimple-fold.h"
|
||||||
//#include "diagnostic-color.h"
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "tree-ssa-alias.h"
|
#include "tree-ssa-alias.h"
|
||||||
#include "tree-ssa.h"
|
#include "tree-ssa.h"
|
||||||
@ -137,34 +115,28 @@
|
|||||||
#include "ssa-iterators.h"
|
#include "ssa-iterators.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#include "lto/lto.h"
|
|
||||||
#if BUILDING_GCC_VERSION >= 4007
|
|
||||||
//#include "data-streamer.h"
|
|
||||||
#else
|
|
||||||
//#include "lto-streamer.h"
|
|
||||||
#endif
|
|
||||||
//#include "lto-compress.h"
|
|
||||||
#if BUILDING_GCC_VERSION >= 5000
|
#if BUILDING_GCC_VERSION >= 5000
|
||||||
//#include "lto-section-names.h"
|
|
||||||
#include "builtins.h"
|
#include "builtins.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* #include "expr.h" where are you... */
|
||||||
|
extern rtx emit_move_insn(rtx x, rtx y);
|
||||||
|
|
||||||
/* missing from basic_block.h... */
|
/* missing from basic_block.h... */
|
||||||
void debug_dominance_info(enum cdi_direction dir);
|
extern void debug_dominance_info(enum cdi_direction dir);
|
||||||
void debug_dominance_tree(enum cdi_direction dir, basic_block root);
|
extern void debug_dominance_tree(enum cdi_direction dir, basic_block root);
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION == 4006
|
#if BUILDING_GCC_VERSION == 4006
|
||||||
void debug_gimple_stmt(gimple);
|
extern void debug_gimple_stmt(gimple);
|
||||||
void debug_gimple_seq(gimple_seq);
|
extern void debug_gimple_seq(gimple_seq);
|
||||||
void print_gimple_seq(FILE *, gimple_seq, int, int);
|
extern void print_gimple_seq(FILE *, gimple_seq, int, int);
|
||||||
void print_gimple_stmt(FILE *, gimple, int, int);
|
extern void print_gimple_stmt(FILE *, gimple, int, int);
|
||||||
void print_gimple_expr(FILE *, gimple, int, int);
|
extern void print_gimple_expr(FILE *, gimple, int, int);
|
||||||
void dump_gimple_stmt(pretty_printer *, gimple, int, int);
|
extern void dump_gimple_stmt(pretty_printer *, gimple, int, int);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define __unused __attribute__((unused))
|
#define __unused __attribute__((__unused__))
|
||||||
#define __visible __attribute__((visibility("default")))
|
#define __visible __attribute__((visibility("default")))
|
||||||
#define __weak __attribute__((weak))
|
|
||||||
|
|
||||||
#define DECL_NAME_POINTER(node) IDENTIFIER_POINTER(DECL_NAME(node))
|
#define DECL_NAME_POINTER(node) IDENTIFIER_POINTER(DECL_NAME(node))
|
||||||
#define DECL_NAME_LENGTH(node) IDENTIFIER_LENGTH(DECL_NAME(node))
|
#define DECL_NAME_LENGTH(node) IDENTIFIER_LENGTH(DECL_NAME(node))
|
||||||
@ -174,36 +146,6 @@ void dump_gimple_stmt(pretty_printer *, gimple, int, int);
|
|||||||
/* should come from c-tree.h if only it were installed for gcc 4.5... */
|
/* should come from c-tree.h if only it were installed for gcc 4.5... */
|
||||||
#define C_TYPE_FIELDS_READONLY(TYPE) TREE_LANG_FLAG_1(TYPE)
|
#define C_TYPE_FIELDS_READONLY(TYPE) TREE_LANG_FLAG_1(TYPE)
|
||||||
|
|
||||||
static inline tree build_const_char_string(int len, const char *str)
|
|
||||||
{
|
|
||||||
tree cstr, elem, index, type;
|
|
||||||
|
|
||||||
cstr = build_string(len, str);
|
|
||||||
elem = build_type_variant(char_type_node, 1, 0);
|
|
||||||
index = build_index_type(size_int(len - 1));
|
|
||||||
type = build_array_type(elem, index);
|
|
||||||
TREE_TYPE(cstr) = type;
|
|
||||||
TREE_CONSTANT(cstr) = 1;
|
|
||||||
TREE_READONLY(cstr) = 1;
|
|
||||||
TREE_STATIC(cstr) = 1;
|
|
||||||
return cstr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void error_gcc_version(struct plugin_gcc_version *version)
|
|
||||||
{
|
|
||||||
error(G_("incompatible gcc/plugin versions: need %s %s %s %s but have %s %s %s %s"),
|
|
||||||
gcc_version.basever, gcc_version.datestamp, gcc_version.devphase, gcc_version.revision,
|
|
||||||
version->basever, version->datestamp, version->devphase, version->revision);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PASS_INFO(NAME, REF, ID, POS) \
|
|
||||||
struct register_pass_info NAME##_pass_info = { \
|
|
||||||
.pass = make_##NAME##_pass(), \
|
|
||||||
.reference_pass_name = REF, \
|
|
||||||
.ref_pass_instance_number = ID, \
|
|
||||||
.pos_op = POS, \
|
|
||||||
}
|
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION == 4005
|
#if BUILDING_GCC_VERSION == 4005
|
||||||
#define FOR_EACH_LOCAL_DECL(FUN, I, D) \
|
#define FOR_EACH_LOCAL_DECL(FUN, I, D) \
|
||||||
for (tree vars = (FUN)->local_decls, (I) = 0; \
|
for (tree vars = (FUN)->local_decls, (I) = 0; \
|
||||||
@ -230,7 +172,6 @@ static inline bool gimple_call_builtin_p(gimple stmt, enum built_in_function cod
|
|||||||
fndecl = gimple_call_fndecl(stmt);
|
fndecl = gimple_call_fndecl(stmt);
|
||||||
if (!fndecl || DECL_BUILT_IN_CLASS(fndecl) != BUILT_IN_NORMAL)
|
if (!fndecl || DECL_BUILT_IN_CLASS(fndecl) != BUILT_IN_NORMAL)
|
||||||
return false;
|
return false;
|
||||||
// print_node(stderr, "pax", fndecl, 4);
|
|
||||||
return DECL_FUNCTION_CODE(fndecl) == code;
|
return DECL_FUNCTION_CODE(fndecl) == code;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,23 +345,6 @@ static inline bool gimple_store_p(gimple gs)
|
|||||||
static inline void gimple_init_singleton(gimple g __unused)
|
static inline void gimple_init_singleton(gimple g __unused)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
enum expand_modifier {
|
|
||||||
EXPAND_NORMAL = 0,
|
|
||||||
EXPAND_STACK_PARM,
|
|
||||||
EXPAND_SUM,
|
|
||||||
EXPAND_CONST_ADDRESS,
|
|
||||||
EXPAND_INITIALIZER,
|
|
||||||
EXPAND_WRITE,
|
|
||||||
EXPAND_MEMORY
|
|
||||||
};
|
|
||||||
|
|
||||||
rtx expand_expr_real(tree, rtx, enum machine_mode, enum expand_modifier, rtx *);
|
|
||||||
|
|
||||||
static inline rtx expand_expr(tree exp, rtx target, enum machine_mode mode, enum expand_modifier modifier)
|
|
||||||
{
|
|
||||||
return expand_expr_real(exp, target, mode, modifier, NULL);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION == 4007 || BUILDING_GCC_VERSION == 4008
|
#if BUILDING_GCC_VERSION == 4007 || BUILDING_GCC_VERSION == 4008
|
||||||
@ -594,28 +518,6 @@ static inline const greturn *as_a_const_greturn(const_gimple stmt)
|
|||||||
#define create_var_ann(var)
|
#define create_var_ann(var)
|
||||||
#define TODO_dump_func 0
|
#define TODO_dump_func 0
|
||||||
#define TODO_dump_cgraph 0
|
#define TODO_dump_cgraph 0
|
||||||
|
|
||||||
#define VEC(T, A) vec<T, va_##A>
|
|
||||||
#define VEC_safe_push(T, A, V, O) vec_safe_push((V), (O));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION == 4008 || BUILDING_GCC_VERSION == 4009
|
|
||||||
enum expand_modifier {
|
|
||||||
EXPAND_NORMAL = 0,
|
|
||||||
EXPAND_STACK_PARM,
|
|
||||||
EXPAND_SUM,
|
|
||||||
EXPAND_CONST_ADDRESS,
|
|
||||||
EXPAND_INITIALIZER,
|
|
||||||
EXPAND_WRITE,
|
|
||||||
EXPAND_MEMORY
|
|
||||||
};
|
|
||||||
|
|
||||||
rtx expand_expr_real(tree, rtx, enum machine_mode, enum expand_modifier, rtx *, bool);
|
|
||||||
|
|
||||||
static inline rtx expand_expr(tree exp, rtx target, enum machine_mode mode, enum expand_modifier modifier)
|
|
||||||
{
|
|
||||||
return expand_expr_real(exp, target, mode, modifier, NULL, false);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION <= 4009
|
#if BUILDING_GCC_VERSION <= 4009
|
||||||
@ -625,8 +527,6 @@ static inline rtx expand_expr(tree exp, rtx target, enum machine_mode mode, enum
|
|||||||
#define section_name_prefix LTO_SECTION_NAME_PREFIX
|
#define section_name_prefix LTO_SECTION_NAME_PREFIX
|
||||||
#define fatal_error(loc, gmsgid, ...) fatal_error((gmsgid), __VA_ARGS__)
|
#define fatal_error(loc, gmsgid, ...) fatal_error((gmsgid), __VA_ARGS__)
|
||||||
|
|
||||||
rtx emit_move_insn(rtx x, rtx y);
|
|
||||||
|
|
||||||
typedef struct rtx_def rtx_insn;
|
typedef struct rtx_def rtx_insn;
|
||||||
|
|
||||||
static inline const char *get_decl_section_name(const_tree decl)
|
static inline const char *get_decl_section_name(const_tree decl)
|
||||||
@ -743,11 +643,6 @@ static inline const greturn *as_a_const_greturn(const_gimple stmt)
|
|||||||
#define NODE_DECL(node) (node)->decl
|
#define NODE_DECL(node) (node)->decl
|
||||||
#define cgraph_node_name(node) (node)->name()
|
#define cgraph_node_name(node) (node)->name()
|
||||||
#define NODE_IMPLICIT_ALIAS(node) (node)->cpp_implicit_alias
|
#define NODE_IMPLICIT_ALIAS(node) (node)->cpp_implicit_alias
|
||||||
|
|
||||||
static inline opt_pass *get_pass_for_id(int id)
|
|
||||||
{
|
|
||||||
return g->get_passes()->get_pass_for_id(id);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION >= 5000 && BUILDING_GCC_VERSION < 6000
|
#if BUILDING_GCC_VERSION >= 5000 && BUILDING_GCC_VERSION < 6000
|
||||||
@ -766,8 +661,6 @@ inline bool is_a_helper<const gassign *>::test(const_gimple gs)
|
|||||||
#define TODO_verify_stmts TODO_verify_il
|
#define TODO_verify_stmts TODO_verify_il
|
||||||
#define TODO_verify_rtl_sharing TODO_verify_il
|
#define TODO_verify_rtl_sharing TODO_verify_il
|
||||||
|
|
||||||
//#define TREE_INT_CST_HIGH(NODE) ({ TREE_INT_CST_EXT_NUNITS(NODE) > 1 ? (unsigned HOST_WIDE_INT)TREE_INT_CST_ELT(NODE, 1) : 0; })
|
|
||||||
|
|
||||||
#define INSN_DELETED_P(insn) (insn)->deleted()
|
#define INSN_DELETED_P(insn) (insn)->deleted()
|
||||||
|
|
||||||
static inline const char *get_decl_section_name(const_tree decl)
|
static inline const char *get_decl_section_name(const_tree decl)
|
||||||
@ -1015,11 +908,6 @@ static inline void debug_gimple_stmt(const_gimple s)
|
|||||||
#define debug_gimple_stmt(s) debug_gimple_stmt(CONST_CAST_GIMPLE(s))
|
#define debug_gimple_stmt(s) debug_gimple_stmt(CONST_CAST_GIMPLE(s))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION < 7001
|
|
||||||
#define SET_DECL_ALIGN(n, a) ({ DECL_ALIGN(n) = (a); })
|
|
||||||
#define SET_DECL_MODE(n, m) ({ DECL_MODE(n) = (m); })
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION >= 7000
|
#if BUILDING_GCC_VERSION >= 7000
|
||||||
#define get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep, keep_aligning) \
|
#define get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep, keep_aligning) \
|
||||||
get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep)
|
get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep)
|
||||||
|
3
src/gcc-generate-gimple-pass.h
Normal file → Executable file
3
src/gcc-generate-gimple-pass.h
Normal file → Executable file
@ -119,7 +119,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual opt_pass *clone() { return new _PASS_NAME_PASS(); }
|
virtual opt_pass * clone () { return new _PASS_NAME_PASS(); }
|
||||||
|
|
||||||
#ifndef NO_EXECUTE
|
#ifndef NO_EXECUTE
|
||||||
#if BUILDING_GCC_VERSION >= 5000
|
#if BUILDING_GCC_VERSION >= 5000
|
||||||
@ -136,7 +136,6 @@ opt_pass *_MAKE_PASS_NAME_PASS(void)
|
|||||||
return new _PASS_NAME_PASS();
|
return new _PASS_NAME_PASS();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
struct opt_pass *_MAKE_PASS_NAME_PASS(void);
|
|
||||||
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
|
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
|
||||||
{
|
{
|
||||||
return &_PASS_NAME_PASS.pass;
|
return &_PASS_NAME_PASS.pass;
|
||||||
|
1
src/gcc-generate-ipa-pass.h
Normal file → Executable file
1
src/gcc-generate-ipa-pass.h
Normal file → Executable file
@ -225,7 +225,6 @@ opt_pass *_MAKE_PASS_NAME_PASS(void)
|
|||||||
return new _PASS_NAME_PASS();
|
return new _PASS_NAME_PASS();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
struct opt_pass *_MAKE_PASS_NAME_PASS(void);
|
|
||||||
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
|
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
|
||||||
{
|
{
|
||||||
return &_PASS_NAME_PASS.pass;
|
return &_PASS_NAME_PASS.pass;
|
||||||
|
1
src/gcc-generate-rtl-pass.h
Normal file → Executable file
1
src/gcc-generate-rtl-pass.h
Normal file → Executable file
@ -136,7 +136,6 @@ opt_pass *_MAKE_PASS_NAME_PASS(void)
|
|||||||
return new _PASS_NAME_PASS();
|
return new _PASS_NAME_PASS();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
struct opt_pass *_MAKE_PASS_NAME_PASS(void);
|
|
||||||
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
|
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
|
||||||
{
|
{
|
||||||
return &_PASS_NAME_PASS.pass;
|
return &_PASS_NAME_PASS.pass;
|
||||||
|
1
src/gcc-generate-simple_ipa-pass.h
Normal file → Executable file
1
src/gcc-generate-simple_ipa-pass.h
Normal file → Executable file
@ -136,7 +136,6 @@ opt_pass *_MAKE_PASS_NAME_PASS(void)
|
|||||||
return new _PASS_NAME_PASS();
|
return new _PASS_NAME_PASS();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
struct opt_pass *_MAKE_PASS_NAME_PASS(void);
|
|
||||||
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
|
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
|
||||||
{
|
{
|
||||||
return &_PASS_NAME_PASS.pass;
|
return &_PASS_NAME_PASS.pass;
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
if [ ! -f "$1" ]; then
|
|
||||||
SEED=`od -A n -t x8 -N 32 /dev/urandom | tr -d ' \n'`
|
|
||||||
echo "const char *randstruct_seed = \"$SEED\";" > "$1"
|
|
||||||
HASH=`echo -n "$SEED" | sha256sum | cut -d" " -f1 | tr -d ' \n'`
|
|
||||||
echo "#define RANDSTRUCT_HASHED_SEED \"$HASH\"" > "$2"
|
|
||||||
fi
|
|
@ -1,74 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* *
|
|
||||||
* GNAT COMPILER COMPONENTS *
|
|
||||||
* *
|
|
||||||
* GNAT-SPECIFIC GCC TREE CODES *
|
|
||||||
* *
|
|
||||||
* Specification *
|
|
||||||
* *
|
|
||||||
* Copyright (C) 1992-2009, Free Software Foundation, Inc. *
|
|
||||||
* *
|
|
||||||
* GNAT is free software; you can redistribute it and/or modify it under *
|
|
||||||
* terms of the GNU General Public License as published by the Free Soft- *
|
|
||||||
* ware Foundation; either version 3, or (at your option) any later ver- *
|
|
||||||
* sion. GNAT is distributed in the hope that it will be useful, but WITH- *
|
|
||||||
* OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
|
|
||||||
* for more details. You should have received a copy of the GNU General *
|
|
||||||
* Public License along with GCC; see the file COPYING3. If not see *
|
|
||||||
* <http://www.gnu.org/licenses/>. *
|
|
||||||
* *
|
|
||||||
* GNAT was originally developed by the GNAT team at New York University. *
|
|
||||||
* Extensive contributions were provided by Ada Core Technologies Inc. *
|
|
||||||
* *
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/* A type that is an unconstrained array. This node is never passed to GCC.
|
|
||||||
TREE_TYPE is the type of the fat pointer and TYPE_OBJECT_RECORD_TYPE is
|
|
||||||
the type of a record containing the template and data. */
|
|
||||||
DEFTREECODE (UNCONSTRAINED_ARRAY_TYPE, "unconstrained_array_type", tcc_type, 0)
|
|
||||||
|
|
||||||
/* A reference to an unconstrained array. This node only exists as an
|
|
||||||
intermediate node during the translation of a GNAT tree to a GCC tree;
|
|
||||||
it is never passed to GCC. The only field used is operand 0, which
|
|
||||||
is the fat pointer object. */
|
|
||||||
DEFTREECODE (UNCONSTRAINED_ARRAY_REF, "unconstrained_array_ref",
|
|
||||||
tcc_reference, 1)
|
|
||||||
|
|
||||||
/* An expression that returns an RTL suitable for its type. Operand 0
|
|
||||||
is an expression to be evaluated for side effects only. */
|
|
||||||
DEFTREECODE (NULL_EXPR, "null_expr", tcc_expression, 1)
|
|
||||||
|
|
||||||
/* Same as PLUS_EXPR, except that no modulo reduction is applied.
|
|
||||||
This is used for loops and never shows up in the tree. */
|
|
||||||
DEFTREECODE (PLUS_NOMOD_EXPR, "plus_nomod_expr", tcc_binary, 2)
|
|
||||||
|
|
||||||
/* Same as MINUS_EXPR, except that no modulo reduction is applied.
|
|
||||||
This is used for loops and never shows up in the tree. */
|
|
||||||
DEFTREECODE (MINUS_NOMOD_EXPR, "minus_nomod_expr", tcc_binary, 2)
|
|
||||||
|
|
||||||
/* Same as ADDR_EXPR, except that if the operand represents a bit field,
|
|
||||||
return the address of the byte containing the bit. This is used
|
|
||||||
for the Address attribute and never shows up in the tree. */
|
|
||||||
DEFTREECODE (ATTR_ADDR_EXPR, "attr_addr_expr", tcc_reference, 1)
|
|
||||||
|
|
||||||
/* Here are the tree codes for the statement types known to Ada. These
|
|
||||||
must be at the end of this file to allow IS_ADA_STMT to work. */
|
|
||||||
|
|
||||||
/* This is how record_code_position and insert_code_for work. The former
|
|
||||||
makes this tree node, whose operand is a statement. The latter inserts
|
|
||||||
the actual statements into this node. Gimplification consists of
|
|
||||||
just returning the inner statement. */
|
|
||||||
DEFTREECODE (STMT_STMT, "stmt_stmt", tcc_statement, 1)
|
|
||||||
|
|
||||||
/* A loop. LOOP_STMT_COND is the test to exit the loop. LOOP_STMT_UPDATE
|
|
||||||
is the statement to update the loop iteration variable at the continue
|
|
||||||
point. LOOP_STMT_BODY are the statements in the body of the loop. And
|
|
||||||
LOOP_STMT_LABEL points to the LABEL_DECL of the end label of the loop. */
|
|
||||||
DEFTREECODE (LOOP_STMT, "loop_stmt", tcc_statement, 4)
|
|
||||||
|
|
||||||
/* Conditionally exit a loop. EXIT_STMT_COND is the condition, which, if
|
|
||||||
true, will cause the loop to be exited. If no condition is specified,
|
|
||||||
the loop is unconditionally exited. EXIT_STMT_LABEL is the end label
|
|
||||||
corresponding to the loop to exit. */
|
|
||||||
DEFTREECODE (EXIT_STMT, "exit_stmt", tcc_statement, 2)
|
|
@ -1,51 +0,0 @@
|
|||||||
/* Exported functions from alias.c
|
|
||||||
Copyright (C) 2004-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_ALIAS_H
|
|
||||||
#define GCC_ALIAS_H
|
|
||||||
|
|
||||||
/* The type of an alias set. Code currently assumes that variables of
|
|
||||||
this type can take the values 0 (the alias set which aliases
|
|
||||||
everything) and -1 (sometimes indicating that the alias set is
|
|
||||||
unknown, sometimes indicating a memory barrier) and -2 (indicating
|
|
||||||
that the alias set should be set to a unique value but has not been
|
|
||||||
set yet). */
|
|
||||||
typedef int alias_set_type;
|
|
||||||
|
|
||||||
extern alias_set_type new_alias_set (void);
|
|
||||||
extern alias_set_type get_alias_set (tree);
|
|
||||||
extern alias_set_type get_deref_alias_set (tree);
|
|
||||||
extern alias_set_type get_varargs_alias_set (void);
|
|
||||||
extern alias_set_type get_frame_alias_set (void);
|
|
||||||
extern bool component_uses_parent_alias_set (const_tree);
|
|
||||||
extern bool alias_set_subset_of (alias_set_type, alias_set_type);
|
|
||||||
extern void record_alias_subset (alias_set_type, alias_set_type);
|
|
||||||
extern void record_component_aliases (tree);
|
|
||||||
extern int alias_sets_conflict_p (alias_set_type, alias_set_type);
|
|
||||||
extern int alias_sets_must_conflict_p (alias_set_type, alias_set_type);
|
|
||||||
extern int objects_must_conflict_p (tree, tree);
|
|
||||||
extern int nonoverlapping_memrefs_p (const_rtx, const_rtx, bool);
|
|
||||||
|
|
||||||
/* This alias set can be used to force a memory to conflict with all
|
|
||||||
other memories, creating a barrier across which no memory reference
|
|
||||||
can move. Note that there are other legacy ways to create such
|
|
||||||
memory barriers, including an address of SCRATCH. */
|
|
||||||
#define ALIAS_SET_MEMORY_BARRIER ((alias_set_type) -1)
|
|
||||||
|
|
||||||
#endif /* GCC_ALIAS_H */
|
|
@ -1,7 +0,0 @@
|
|||||||
#include "tree.def"
|
|
||||||
END_OF_BASE_TREE_CODES
|
|
||||||
#include "c-family/c-common.def"
|
|
||||||
#include "ada/gcc-interface/ada-tree.def"
|
|
||||||
#include "cp/cp-tree.def"
|
|
||||||
#include "java/java-tree.def"
|
|
||||||
#include "objc/objc-tree.def"
|
|
@ -1,66 +0,0 @@
|
|||||||
/* Functions to support a pool of allocatable objects
|
|
||||||
Copyright (C) 1997-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Daniel Berlin <dan@cgsoftware.com>
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
#ifndef ALLOC_POOL_H
|
|
||||||
#define ALLOC_POOL_H
|
|
||||||
|
|
||||||
typedef unsigned long ALLOC_POOL_ID_TYPE;
|
|
||||||
|
|
||||||
typedef struct alloc_pool_list_def
|
|
||||||
{
|
|
||||||
struct alloc_pool_list_def *next;
|
|
||||||
}
|
|
||||||
*alloc_pool_list;
|
|
||||||
|
|
||||||
typedef struct alloc_pool_def
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
#ifdef ENABLE_CHECKING
|
|
||||||
ALLOC_POOL_ID_TYPE id;
|
|
||||||
#endif
|
|
||||||
size_t elts_per_block;
|
|
||||||
|
|
||||||
/* These are the elements that have been allocated at least once and freed. */
|
|
||||||
alloc_pool_list returned_free_list;
|
|
||||||
|
|
||||||
/* These are the elements that have not yet been allocated out of
|
|
||||||
the last block obtained from XNEWVEC. */
|
|
||||||
char* virgin_free_list;
|
|
||||||
|
|
||||||
/* The number of elements in the virgin_free_list that can be
|
|
||||||
allocated before needing another block. */
|
|
||||||
size_t virgin_elts_remaining;
|
|
||||||
|
|
||||||
size_t elts_allocated;
|
|
||||||
size_t elts_free;
|
|
||||||
size_t blocks_allocated;
|
|
||||||
alloc_pool_list block_list;
|
|
||||||
size_t block_size;
|
|
||||||
size_t elt_size;
|
|
||||||
}
|
|
||||||
*alloc_pool;
|
|
||||||
|
|
||||||
extern alloc_pool create_alloc_pool (const char *, size_t, size_t);
|
|
||||||
extern void free_alloc_pool (alloc_pool);
|
|
||||||
extern void empty_alloc_pool (alloc_pool);
|
|
||||||
extern void free_alloc_pool_if_empty (alloc_pool *);
|
|
||||||
extern void *pool_alloc (alloc_pool) ATTRIBUTE_MALLOC;
|
|
||||||
extern void pool_free (alloc_pool, void *);
|
|
||||||
extern void dump_alloc_pool_statistics (void);
|
|
||||||
#endif
|
|
@ -1,441 +0,0 @@
|
|||||||
/* ANSI and traditional C compatability macros
|
|
||||||
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
|
||||||
2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
|
|
||||||
Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
|
||||||
|
|
||||||
/* ANSI and traditional C compatibility macros
|
|
||||||
|
|
||||||
ANSI C is assumed if __STDC__ is #defined.
|
|
||||||
|
|
||||||
Macro ANSI C definition Traditional C definition
|
|
||||||
----- ---- - ---------- ----------- - ----------
|
|
||||||
ANSI_PROTOTYPES 1 not defined
|
|
||||||
PTR `void *' `char *'
|
|
||||||
PTRCONST `void *const' `char *'
|
|
||||||
LONG_DOUBLE `long double' `double'
|
|
||||||
const not defined `'
|
|
||||||
volatile not defined `'
|
|
||||||
signed not defined `'
|
|
||||||
VA_START(ap, var) va_start(ap, var) va_start(ap)
|
|
||||||
|
|
||||||
Note that it is safe to write "void foo();" indicating a function
|
|
||||||
with no return value, in all K+R compilers we have been able to test.
|
|
||||||
|
|
||||||
For declaring functions with prototypes, we also provide these:
|
|
||||||
|
|
||||||
PARAMS ((prototype))
|
|
||||||
-- for functions which take a fixed number of arguments. Use this
|
|
||||||
when declaring the function. When defining the function, write a
|
|
||||||
K+R style argument list. For example:
|
|
||||||
|
|
||||||
char *strcpy PARAMS ((char *dest, char *source));
|
|
||||||
...
|
|
||||||
char *
|
|
||||||
strcpy (dest, source)
|
|
||||||
char *dest;
|
|
||||||
char *source;
|
|
||||||
{ ... }
|
|
||||||
|
|
||||||
|
|
||||||
VPARAMS ((prototype, ...))
|
|
||||||
-- for functions which take a variable number of arguments. Use
|
|
||||||
PARAMS to declare the function, VPARAMS to define it. For example:
|
|
||||||
|
|
||||||
int printf PARAMS ((const char *format, ...));
|
|
||||||
...
|
|
||||||
int
|
|
||||||
printf VPARAMS ((const char *format, ...))
|
|
||||||
{
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
For writing functions which take variable numbers of arguments, we
|
|
||||||
also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros. These
|
|
||||||
hide the differences between K+R <varargs.h> and C89 <stdarg.h> more
|
|
||||||
thoroughly than the simple VA_START() macro mentioned above.
|
|
||||||
|
|
||||||
VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end.
|
|
||||||
Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls
|
|
||||||
corresponding to the list of fixed arguments. Then use va_arg
|
|
||||||
normally to get the variable arguments, or pass your va_list object
|
|
||||||
around. You do not declare the va_list yourself; VA_OPEN does it
|
|
||||||
for you.
|
|
||||||
|
|
||||||
Here is a complete example:
|
|
||||||
|
|
||||||
int
|
|
||||||
printf VPARAMS ((const char *format, ...))
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
VA_OPEN (ap, format);
|
|
||||||
VA_FIXEDARG (ap, const char *, format);
|
|
||||||
|
|
||||||
result = vfprintf (stdout, format, ap);
|
|
||||||
VA_CLOSE (ap);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
You can declare variables either before or after the VA_OPEN,
|
|
||||||
VA_FIXEDARG sequence. Also, VA_OPEN and VA_CLOSE are the beginning
|
|
||||||
and end of a block. They must appear at the same nesting level,
|
|
||||||
and any variables declared after VA_OPEN go out of scope at
|
|
||||||
VA_CLOSE. Unfortunately, with a K+R compiler, that includes the
|
|
||||||
argument list. You can have multiple instances of VA_OPEN/VA_CLOSE
|
|
||||||
pairs in a single function in case you need to traverse the
|
|
||||||
argument list more than once.
|
|
||||||
|
|
||||||
For ease of writing code which uses GCC extensions but needs to be
|
|
||||||
portable to other compilers, we provide the GCC_VERSION macro that
|
|
||||||
simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various
|
|
||||||
wrappers around __attribute__. Also, __extension__ will be #defined
|
|
||||||
to nothing if it doesn't work. See below.
|
|
||||||
|
|
||||||
This header also defines a lot of obsolete macros:
|
|
||||||
CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID,
|
|
||||||
AND, DOTS, NOARGS. Don't use them. */
|
|
||||||
|
|
||||||
#ifndef _ANSIDECL_H
|
|
||||||
#define _ANSIDECL_H 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Every source file includes this file,
|
|
||||||
so they will all get the switch for lint. */
|
|
||||||
/* LINTLIBRARY */
|
|
||||||
|
|
||||||
/* Using MACRO(x,y) in cpp #if conditionals does not work with some
|
|
||||||
older preprocessors. Thus we can't define something like this:
|
|
||||||
|
|
||||||
#define HAVE_GCC_VERSION(MAJOR, MINOR) \
|
|
||||||
(__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR)))
|
|
||||||
|
|
||||||
and then test "#if HAVE_GCC_VERSION(2,7)".
|
|
||||||
|
|
||||||
So instead we use the macro below and test it against specific values. */
|
|
||||||
|
|
||||||
/* This macro simplifies testing whether we are using gcc, and if it
|
|
||||||
is of a particular minimum version. (Both major & minor numbers are
|
|
||||||
significant.) This macro will evaluate to 0 if we are not using
|
|
||||||
gcc at all. */
|
|
||||||
#ifndef GCC_VERSION
|
|
||||||
#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
|
|
||||||
#endif /* GCC_VERSION */
|
|
||||||
|
|
||||||
#if defined (__STDC__) || defined(__cplusplus) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32)
|
|
||||||
/* All known AIX compilers implement these things (but don't always
|
|
||||||
define __STDC__). The RISC/OS MIPS compiler defines these things
|
|
||||||
in SVR4 mode, but does not define __STDC__. */
|
|
||||||
/* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other
|
|
||||||
C++ compilers, does not define __STDC__, though it acts as if this
|
|
||||||
was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */
|
|
||||||
|
|
||||||
#define ANSI_PROTOTYPES 1
|
|
||||||
#define PTR void *
|
|
||||||
#define PTRCONST void *const
|
|
||||||
#define LONG_DOUBLE long double
|
|
||||||
|
|
||||||
/* PARAMS is often defined elsewhere (e.g. by libintl.h), so wrap it in
|
|
||||||
a #ifndef. */
|
|
||||||
#ifndef PARAMS
|
|
||||||
#define PARAMS(ARGS) ARGS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define VPARAMS(ARGS) ARGS
|
|
||||||
#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR)
|
|
||||||
|
|
||||||
/* variadic function helper macros */
|
|
||||||
/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's
|
|
||||||
use without inhibiting further decls and without declaring an
|
|
||||||
actual variable. */
|
|
||||||
#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP, VAR); { struct Qdmy
|
|
||||||
#define VA_CLOSE(AP) } va_end(AP); }
|
|
||||||
#define VA_FIXEDARG(AP, T, N) struct Qdmy
|
|
||||||
|
|
||||||
#undef const
|
|
||||||
#undef volatile
|
|
||||||
#undef signed
|
|
||||||
|
|
||||||
/* inline requires special treatment; it's in C99, and GCC >=2.7 supports
|
|
||||||
it too, but it's not in C89. */
|
|
||||||
#undef inline
|
|
||||||
#if __STDC_VERSION__ >= 199901L || defined(__cplusplus) || (defined(__SUNPRO_C) && defined(__C99FEATURES__))
|
|
||||||
/* it's a keyword */
|
|
||||||
#else
|
|
||||||
# if GCC_VERSION >= 2007
|
|
||||||
# define inline __inline__ /* __inline__ prevents -pedantic warnings */
|
|
||||||
# else
|
|
||||||
# define inline /* nothing */
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* These are obsolete. Do not use. */
|
|
||||||
#ifndef IN_GCC
|
|
||||||
#define CONST const
|
|
||||||
#define VOLATILE volatile
|
|
||||||
#define SIGNED signed
|
|
||||||
|
|
||||||
#define PROTO(type, name, arglist) type name arglist
|
|
||||||
#define EXFUN(name, proto) name proto
|
|
||||||
#define DEFUN(name, arglist, args) name(args)
|
|
||||||
#define DEFUN_VOID(name) name(void)
|
|
||||||
#define AND ,
|
|
||||||
#define DOTS , ...
|
|
||||||
#define NOARGS void
|
|
||||||
#endif /* ! IN_GCC */
|
|
||||||
|
|
||||||
#else /* Not ANSI C. */
|
|
||||||
|
|
||||||
#undef ANSI_PROTOTYPES
|
|
||||||
#define PTR char *
|
|
||||||
#define PTRCONST PTR
|
|
||||||
#define LONG_DOUBLE double
|
|
||||||
|
|
||||||
#define PARAMS(args) ()
|
|
||||||
#define VPARAMS(args) (va_alist) va_dcl
|
|
||||||
#define VA_START(va_list, var) va_start(va_list)
|
|
||||||
|
|
||||||
#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP); { struct Qdmy
|
|
||||||
#define VA_CLOSE(AP) } va_end(AP); }
|
|
||||||
#define VA_FIXEDARG(AP, TYPE, NAME) TYPE NAME = va_arg(AP, TYPE)
|
|
||||||
|
|
||||||
/* some systems define these in header files for non-ansi mode */
|
|
||||||
#undef const
|
|
||||||
#undef volatile
|
|
||||||
#undef signed
|
|
||||||
#undef inline
|
|
||||||
#define const
|
|
||||||
#define volatile
|
|
||||||
#define signed
|
|
||||||
#define inline
|
|
||||||
|
|
||||||
#ifndef IN_GCC
|
|
||||||
#define CONST
|
|
||||||
#define VOLATILE
|
|
||||||
#define SIGNED
|
|
||||||
|
|
||||||
#define PROTO(type, name, arglist) type name ()
|
|
||||||
#define EXFUN(name, proto) name()
|
|
||||||
#define DEFUN(name, arglist, args) name arglist args;
|
|
||||||
#define DEFUN_VOID(name) name()
|
|
||||||
#define AND ;
|
|
||||||
#define DOTS
|
|
||||||
#define NOARGS
|
|
||||||
#endif /* ! IN_GCC */
|
|
||||||
|
|
||||||
#endif /* ANSI C. */
|
|
||||||
|
|
||||||
/* Define macros for some gcc attributes. This permits us to use the
|
|
||||||
macros freely, and know that they will come into play for the
|
|
||||||
version of gcc in which they are supported. */
|
|
||||||
|
|
||||||
#if (GCC_VERSION < 2007)
|
|
||||||
# define __attribute__(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Attribute __malloc__ on functions was valid as of gcc 2.96. */
|
|
||||||
#ifndef ATTRIBUTE_MALLOC
|
|
||||||
# if (GCC_VERSION >= 2096)
|
|
||||||
# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
|
|
||||||
# else
|
|
||||||
# define ATTRIBUTE_MALLOC
|
|
||||||
# endif /* GNUC >= 2.96 */
|
|
||||||
#endif /* ATTRIBUTE_MALLOC */
|
|
||||||
|
|
||||||
/* Attributes on labels were valid as of gcc 2.93 and g++ 4.5. For
|
|
||||||
g++ an attribute on a label must be followed by a semicolon. */
|
|
||||||
#ifndef ATTRIBUTE_UNUSED_LABEL
|
|
||||||
# ifndef __cplusplus
|
|
||||||
# if GCC_VERSION >= 2093
|
|
||||||
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
|
|
||||||
# else
|
|
||||||
# define ATTRIBUTE_UNUSED_LABEL
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
# if GCC_VERSION >= 4005
|
|
||||||
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED ;
|
|
||||||
# else
|
|
||||||
# define ATTRIBUTE_UNUSED_LABEL
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Similarly to ARG_UNUSED below. Prior to GCC 3.4, the C++ frontend
|
|
||||||
couldn't parse attributes placed after the identifier name, and now
|
|
||||||
the entire compiler is built with C++. */
|
|
||||||
#ifndef ATTRIBUTE_UNUSED
|
|
||||||
#if GCC_VERSION >= 3004
|
|
||||||
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
|
|
||||||
#else
|
|
||||||
#define ATTRIBUTE_UNUSED
|
|
||||||
#endif
|
|
||||||
#endif /* ATTRIBUTE_UNUSED */
|
|
||||||
|
|
||||||
/* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the
|
|
||||||
identifier name. */
|
|
||||||
#if ! defined(__cplusplus) || (GCC_VERSION >= 3004)
|
|
||||||
# define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED
|
|
||||||
#else /* !__cplusplus || GNUC >= 3.4 */
|
|
||||||
# define ARG_UNUSED(NAME) NAME
|
|
||||||
#endif /* !__cplusplus || GNUC >= 3.4 */
|
|
||||||
|
|
||||||
#ifndef ATTRIBUTE_NORETURN
|
|
||||||
#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
|
|
||||||
#endif /* ATTRIBUTE_NORETURN */
|
|
||||||
|
|
||||||
/* Attribute `nonnull' was valid as of gcc 3.3. */
|
|
||||||
#ifndef ATTRIBUTE_NONNULL
|
|
||||||
# if (GCC_VERSION >= 3003)
|
|
||||||
# define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m)))
|
|
||||||
# else
|
|
||||||
# define ATTRIBUTE_NONNULL(m)
|
|
||||||
# endif /* GNUC >= 3.3 */
|
|
||||||
#endif /* ATTRIBUTE_NONNULL */
|
|
||||||
|
|
||||||
/* Attribute `pure' was valid as of gcc 3.0. */
|
|
||||||
#ifndef ATTRIBUTE_PURE
|
|
||||||
# if (GCC_VERSION >= 3000)
|
|
||||||
# define ATTRIBUTE_PURE __attribute__ ((__pure__))
|
|
||||||
# else
|
|
||||||
# define ATTRIBUTE_PURE
|
|
||||||
# endif /* GNUC >= 3.0 */
|
|
||||||
#endif /* ATTRIBUTE_PURE */
|
|
||||||
|
|
||||||
/* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL.
|
|
||||||
This was the case for the `printf' format attribute by itself
|
|
||||||
before GCC 3.3, but as of 3.3 we need to add the `nonnull'
|
|
||||||
attribute to retain this behavior. */
|
|
||||||
#ifndef ATTRIBUTE_PRINTF
|
|
||||||
#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m)
|
|
||||||
#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
|
|
||||||
#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
|
|
||||||
#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4)
|
|
||||||
#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5)
|
|
||||||
#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6)
|
|
||||||
#endif /* ATTRIBUTE_PRINTF */
|
|
||||||
|
|
||||||
/* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on
|
|
||||||
a function pointer. Format attributes were allowed on function
|
|
||||||
pointers as of gcc 3.1. */
|
|
||||||
#ifndef ATTRIBUTE_FPTR_PRINTF
|
|
||||||
# if (GCC_VERSION >= 3001)
|
|
||||||
# define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n)
|
|
||||||
# else
|
|
||||||
# define ATTRIBUTE_FPTR_PRINTF(m, n)
|
|
||||||
# endif /* GNUC >= 3.1 */
|
|
||||||
# define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2)
|
|
||||||
# define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3)
|
|
||||||
# define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4)
|
|
||||||
# define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5)
|
|
||||||
# define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6)
|
|
||||||
#endif /* ATTRIBUTE_FPTR_PRINTF */
|
|
||||||
|
|
||||||
/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A
|
|
||||||
NULL format specifier was allowed as of gcc 3.3. */
|
|
||||||
#ifndef ATTRIBUTE_NULL_PRINTF
|
|
||||||
# if (GCC_VERSION >= 3003)
|
|
||||||
# define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
|
|
||||||
# else
|
|
||||||
# define ATTRIBUTE_NULL_PRINTF(m, n)
|
|
||||||
# endif /* GNUC >= 3.3 */
|
|
||||||
# define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2)
|
|
||||||
# define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3)
|
|
||||||
# define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4)
|
|
||||||
# define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5)
|
|
||||||
# define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6)
|
|
||||||
#endif /* ATTRIBUTE_NULL_PRINTF */
|
|
||||||
|
|
||||||
/* Attribute `sentinel' was valid as of gcc 3.5. */
|
|
||||||
#ifndef ATTRIBUTE_SENTINEL
|
|
||||||
# if (GCC_VERSION >= 3005)
|
|
||||||
# define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__))
|
|
||||||
# else
|
|
||||||
# define ATTRIBUTE_SENTINEL
|
|
||||||
# endif /* GNUC >= 3.5 */
|
|
||||||
#endif /* ATTRIBUTE_SENTINEL */
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef ATTRIBUTE_ALIGNED_ALIGNOF
|
|
||||||
# if (GCC_VERSION >= 3000)
|
|
||||||
# define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m))))
|
|
||||||
# else
|
|
||||||
# define ATTRIBUTE_ALIGNED_ALIGNOF(m)
|
|
||||||
# endif /* GNUC >= 3.0 */
|
|
||||||
#endif /* ATTRIBUTE_ALIGNED_ALIGNOF */
|
|
||||||
|
|
||||||
/* Useful for structures whose layout must much some binary specification
|
|
||||||
regardless of the alignment and padding qualities of the compiler. */
|
|
||||||
#ifndef ATTRIBUTE_PACKED
|
|
||||||
# define ATTRIBUTE_PACKED __attribute__ ((packed))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Attribute `hot' and `cold' was valid as of gcc 4.3. */
|
|
||||||
#ifndef ATTRIBUTE_COLD
|
|
||||||
# if (GCC_VERSION >= 4003)
|
|
||||||
# define ATTRIBUTE_COLD __attribute__ ((__cold__))
|
|
||||||
# else
|
|
||||||
# define ATTRIBUTE_COLD
|
|
||||||
# endif /* GNUC >= 4.3 */
|
|
||||||
#endif /* ATTRIBUTE_COLD */
|
|
||||||
#ifndef ATTRIBUTE_HOT
|
|
||||||
# if (GCC_VERSION >= 4003)
|
|
||||||
# define ATTRIBUTE_HOT __attribute__ ((__hot__))
|
|
||||||
# else
|
|
||||||
# define ATTRIBUTE_HOT
|
|
||||||
# endif /* GNUC >= 4.3 */
|
|
||||||
#endif /* ATTRIBUTE_HOT */
|
|
||||||
|
|
||||||
/* We use __extension__ in some places to suppress -pedantic warnings
|
|
||||||
about GCC extensions. This feature didn't work properly before
|
|
||||||
gcc 2.8. */
|
|
||||||
#if GCC_VERSION < 2008
|
|
||||||
#define __extension__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This is used to declare a const variable which should be visible
|
|
||||||
outside of the current compilation unit. Use it as
|
|
||||||
EXPORTED_CONST int i = 1;
|
|
||||||
This is because the semantics of const are different in C and C++.
|
|
||||||
"extern const" is permitted in C but it looks strange, and gcc
|
|
||||||
warns about it when -Wc++-compat is not used. */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#define EXPORTED_CONST extern const
|
|
||||||
#else
|
|
||||||
#define EXPORTED_CONST const
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Be conservative and only use enum bitfields with C++ or GCC.
|
|
||||||
FIXME: provide a complete autoconf test for buggy enum bitfields. */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#define ENUM_BITFIELD(TYPE) enum TYPE
|
|
||||||
#elif (GCC_VERSION > 2000)
|
|
||||||
#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
|
|
||||||
#else
|
|
||||||
#define ENUM_BITFIELD(TYPE) unsigned int
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ansidecl.h */
|
|
File diff suppressed because it is too large
Load Diff
@ -1,121 +0,0 @@
|
|||||||
USER_H=xsaveoptintrin.h mm_malloc.h
|
|
||||||
HASHTAB_H=hashtab.h
|
|
||||||
OBSTACK_H=obstack.h
|
|
||||||
SPLAY_TREE_H=splay-tree.h
|
|
||||||
FIBHEAP_H=fibheap.h
|
|
||||||
PARTITION_H=partition.h
|
|
||||||
DWARF2_H=dwarf2.def
|
|
||||||
XREGEX_H=xregex.h
|
|
||||||
FNMATCH_H=fnmatch.h
|
|
||||||
LINKER_PLUGIN_API_H=plugin-api.h
|
|
||||||
LTO_SYMTAB_H=lto-symtab.h
|
|
||||||
BCONFIG_H=bconfig.h auto-host.h ansidecl.h
|
|
||||||
CONFIG_H=config.h auto-host.h ansidecl.h
|
|
||||||
TCONFIG_H=tconfig.h auto-host.h ansidecl.h
|
|
||||||
TM_P_H=tm_p.h config/i386/i386-protos.h tm-preds.h
|
|
||||||
GTM_H=tm.h options.h config/vxworks-dummy.h defaults.h insn-constants.h
|
|
||||||
TM_H=tm.h options.h config/vxworks-dummy.h i386-opts.h
|
|
||||||
VEC_H=vec.h statistics.h ggc.h gtype-desc.h statistics.h
|
|
||||||
HASH_TABLE_H=hashtab.h hash-table.h
|
|
||||||
EXCEPT_H=except.h hashtab.h
|
|
||||||
TARGET_H=tm.h options.h config/vxworks-dummy.h i386-opts.h target.h target.def target-hooks-macros.h insn-modes.h
|
|
||||||
C_TARGET_H=c-family/c-target.h c-family/c-target.def target-hooks-macros.h
|
|
||||||
COMMON_TARGET_H=common/common-target.h common-target.def target-hooks-macros.h
|
|
||||||
MACHMODE_H=machmode.h mode-classes.def insn-modes.h
|
|
||||||
HOOKS_H=hooks.h machmode.h mode-classes.def insn-modes.h
|
|
||||||
HOSTHOOKS_DEF_H=hosthooks-def.h hooks.h machmode.h mode-classes.def insn-modes.h
|
|
||||||
LANGHOOKS_DEF_H=langhooks-def.h hooks.h machmode.h mode-classes.def insn-modes.h
|
|
||||||
TARGET_DEF_H=target-def.h target-hooks-def.h hooks.h machmode.h mode-classes.def insn-modes.h targhooks.h
|
|
||||||
C_TARGET_DEF_H=c-family/c-target-def.h c-family/c-target-hooks-def.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def common-targhooks.h
|
|
||||||
COMMON_TARGET_DEF_H=common/common-target-def.h common/common-target-hooks-def.h hooks.h machmode.h mode-classes.def insn-modes.h
|
|
||||||
RTL_BASE_H=coretypes.h rtl.h rtl.def machmode.h mode-classes.def insn-modes.h reg-notes.def insn-notes.def hashtab.h
|
|
||||||
FIXED_VALUE_H=fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
|
||||||
RTL_H=coretypes.h rtl.h rtl.def machmode.h mode-classes.def insn-modes.h reg-notes.def insn-notes.def i386-opts.h genrtl.h
|
|
||||||
RTL_ERROR_H=rtl-error.h coretypes.h rtl.h rtl.def machmode.h mode-classes.def insn-modes.h reg-notes.def insn-notes.def line-map.h input.h bversion.h diagnostic.def
|
|
||||||
READ_MD_H=hashtab.h read-md.h
|
|
||||||
PARAMS_H=params.h params.def
|
|
||||||
INTERNAL_FN_H=internal-fn.h internal-fn.def
|
|
||||||
TREE_H=coretypes.h tree.h all-tree.def tree.def c-family/c-common.def i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
|
||||||
REGSET_H=regset.h bitmap.h hashtab.h statistics.h hard-reg-set.h
|
|
||||||
BASIC_BLOCK_H=basic-block.h predict.h predict.def vec.h statistics.h ggc.h gtype-desc.h statistics.h function.h line-map.h input.h machmode.h mode-classes.def insn-modes.h cfg-flags.def cfghooks.h
|
|
||||||
GIMPLE_H=gimple.h gimple.def gsstruct.def pointer-set.h vec.h statistics.h ggc.h gtype-desc.h statistics.h ggc.h gtype-desc.h statistics.h basic-block.h predict.h predict.def vec.h statistics.h ggc.h gtype-desc.h statistics.h function.h i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h tree-ssa-operands.h tree-ssa-alias.h internal-fn.h internal-fn.def
|
|
||||||
TRANS_MEM_H=trans-mem.h
|
|
||||||
GCOV_IO_H=gcov-io.h gcov-iov.h auto-host.h
|
|
||||||
COVERAGE_H=coverage.h gcov-io.h gcov-iov.h auto-host.h
|
|
||||||
DEMANGLE_H=demangle.h
|
|
||||||
RECOG_H=recog.h
|
|
||||||
ALIAS_H=alias.h
|
|
||||||
EMIT_RTL_H=emit-rtl.h
|
|
||||||
FLAGS_H=flags.h flag-types.h options.h flag-types.h config/i386/i386-opts.h
|
|
||||||
OPTIONS_H=options.h flag-types.h config/i386/i386-opts.h
|
|
||||||
FUNCTION_H=function.h line-map.h input.h machmode.h mode-classes.def insn-modes.h
|
|
||||||
EXPR_H=expr.h insn-config.h function.h i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h machmode.h mode-classes.def insn-modes.h emit-rtl.h
|
|
||||||
OPTABS_H=optabs.h insn-codes.h insn-opinit.h
|
|
||||||
REGS_H=regs.h machmode.h mode-classes.def insn-modes.h hard-reg-set.h
|
|
||||||
SCHED_INT_H=sched-int.h insn-attr.h insn-attr-common.h hashtab.h statistics.h hard-reg-set.h
|
|
||||||
SEL_SCHED_IR_H=sel-sched-ir.h insn-attr.h insn-attr-common.h hashtab.h statistics.h hard-reg-set.h
|
|
||||||
SEL_SCHED_DUMP_H=sel-sched-dump.h sel-sched-ir.h insn-attr.h insn-attr-common.h hashtab.h statistics.h hard-reg-set.h
|
|
||||||
CFGLOOP_H=cfgloop.h basic-block.h predict.h predict.def vec.h statistics.h ggc.h gtype-desc.h statistics.h function.h hashtab.h statistics.h sbitmap.h
|
|
||||||
IPA_UTILS_H=ipa-utils.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def plugin-api.h is-a.h
|
|
||||||
IPA_REFERENCE_H=ipa-reference.h bitmap.h i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
|
||||||
CGRAPH_H=cgraph.h vec.h statistics.h ggc.h gtype-desc.h statistics.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def plugin-api.h is-a.h
|
|
||||||
DF_H=df.h bitmap.h line-map.h input.h machmode.h mode-classes.def insn-modes.h cfg-flags.def cfghooks.h alloc-pool.h timevar.h timevar.def
|
|
||||||
VALTRACK_H=valtrack.h bitmap.h hashtab.h hash-table.h
|
|
||||||
RESOURCE_H=resource.h hard-reg-set.h df.h bitmap.h line-map.h input.h machmode.h mode-classes.def insn-modes.h cfg-flags.def cfghooks.h alloc-pool.h timevar.h timevar.def
|
|
||||||
DDG_H=ddg.h sbitmap.h df.h bitmap.h line-map.h input.h machmode.h mode-classes.def insn-modes.h cfg-flags.def cfghooks.h alloc-pool.h timevar.h timevar.def
|
|
||||||
GCC_H=gcc.h version.h diagnostic-core.h line-map.h input.h bversion.h diagnostic.def
|
|
||||||
GGC_H=ggc.h gtype-desc.h statistics.h
|
|
||||||
GGC_INTERNAL_H=ggc-internal.h ggc.h gtype-desc.h statistics.h
|
|
||||||
TIMEVAR_H=timevar.h timevar.def
|
|
||||||
INSN_ATTR_H=insn-attr.h insn-attr-common.h insn-addr.h
|
|
||||||
INSN_ADDR_H=insn-addr.h
|
|
||||||
C_COMMON_H=c-family/c-common.h c-family/c-common.def coretypes.h tree.h all-tree.def tree.def c-family/c-common.def line-map.h input.h bversion.h diagnostic.def
|
|
||||||
C_PRAGMA_H=c-family/c-pragma.h cpplib.h
|
|
||||||
C_TREE_H=c/c-tree.h c-family/c-common.h c-family/c-common.def coretypes.h tree.h all-tree.def tree.def c-family/c-common.def obstack.h
|
|
||||||
SYSTEM_H=system.h hwint.h filenames.h
|
|
||||||
PREDICT_H=predict.h predict.def
|
|
||||||
CPPLIB_H=cpplib.h
|
|
||||||
INPUT_H=line-map.h input.h
|
|
||||||
OPTS_H=obstack.h
|
|
||||||
DECNUM_H=decimal128Local.h
|
|
||||||
BACKTRACE_H=backtrace.h
|
|
||||||
MKDEPS_H=mkdeps.h
|
|
||||||
SYMTAB_H=obstack.h
|
|
||||||
CPP_ID_DATA_H=cpp-id-data.h
|
|
||||||
CPP_INTERNAL_H=cpp-id-data.h
|
|
||||||
TREE_DUMP_H=tree-dump.h splay-tree.h dumpfile.h
|
|
||||||
TREE_PASS_H=tree-pass.h timevar.h timevar.def dumpfile.h
|
|
||||||
TREE_FLOW_H=tree-flow.h tree-flow-inline.h tree-ssa-operands.h bitmap.h i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h tree-ssa-alias.h
|
|
||||||
TREE_SSA_LIVE_H=tree-ssa-live.h partition.h
|
|
||||||
SSAEXPAND_H=ssaexpand.h tree-ssa-live.h partition.h
|
|
||||||
PRETTY_PRINT_H=pretty-print.h obstack.h
|
|
||||||
TREE_PRETTY_PRINT_H=tree-pretty-print.h pretty-print.h obstack.h
|
|
||||||
GIMPLE_PRETTY_PRINT_H=gimple-pretty-print.h tree-pretty-print.h pretty-print.h obstack.h
|
|
||||||
DIAGNOSTIC_CORE_H=diagnostic-core.h line-map.h input.h bversion.h diagnostic.def
|
|
||||||
DIAGNOSTIC_H=diagnostic.h diagnostic-core.h obstack.h
|
|
||||||
DWARF2OUT_H=dwarf2out.h dwarf2.def
|
|
||||||
C_PRETTY_PRINT_H=c-family/c-pretty-print.h pretty-print.h i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
|
||||||
SCEV_H=tree-scalar-evolution.h ggc.h gtype-desc.h statistics.h tree-chrec.h params.h params.def
|
|
||||||
OMEGA_H=omega.h params.h params.def
|
|
||||||
TREE_DATA_REF_H=tree-data-ref.h omega.h params.h params.def graphds.h tree-scalar-evolution.h ggc.h gtype-desc.h statistics.h tree-chrec.h params.h params.def
|
|
||||||
TREE_INLINE_H=tree-inline.h
|
|
||||||
REAL_H=real.h machmode.h mode-classes.def insn-modes.h
|
|
||||||
IRA_INT_H=ira.h ira-int.h cfgloop.h basic-block.h predict.h predict.def vec.h statistics.h ggc.h gtype-desc.h statistics.h function.h hashtab.h statistics.h sbitmap.h alloc-pool.h
|
|
||||||
LRA_INT_H=lra.h bitmap.h insn-addr.h insn-codes.h lra-int.h
|
|
||||||
DBGCNT_H=dbgcnt.h dbgcnt.def
|
|
||||||
LTO_STREAMER_H=lto-streamer.h obstack.h alloc-pool.h
|
|
||||||
DATA_STREAMER_H=data-streamer.h vec.h statistics.h ggc.h gtype-desc.h statistics.h lto-streamer.h obstack.h alloc-pool.h
|
|
||||||
GIMPLE_STREAMER_H=gimple-streamer.h lto-streamer.h line-map.h input.h machmode.h mode-classes.def insn-modes.h
|
|
||||||
TREE_STREAMER_H=tree-streamer.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
|
||||||
STREAMER_HOOKS_H=streamer-hooks.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
|
||||||
TREE_VECTORIZER_H=tree-vectorizer.h tree-data-ref.h omega.h params.h params.def graphds.h tree-scalar-evolution.h ggc.h gtype-desc.h statistics.h tree-chrec.h params.h params.def tm.h options.h config/vxworks-dummy.h i386-opts.h target.h target.def target-hooks-macros.h insn-modes.h
|
|
||||||
IPA_PROP_H=ipa-prop.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h tree-ssa-operands.h tree-ssa-alias.h internal-fn.h internal-fn.def alloc-pool.h
|
|
||||||
IPA_INLINE_H=ipa-inline.h ipa-prop.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h tree-ssa-operands.h tree-ssa-alias.h internal-fn.h internal-fn.def alloc-pool.h
|
|
||||||
GSTAB_H=gstab.h stab.def
|
|
||||||
BITMAP_H=bitmap.h hashtab.h statistics.h
|
|
||||||
GCC_PLUGIN_H=gcc-plugin.h highlev-plugin-common.h plugin.def config.h auto-host.h hashtab.h
|
|
||||||
PLUGIN_H=plugin.h gcc-plugin.h highlev-plugin-common.h plugin.def config.h auto-host.h hashtab.h
|
|
||||||
PLUGIN_VERSION_H=plugin-version.h configargs.h
|
|
||||||
LIBFUNCS_H=libfuncs.h hashtab.h
|
|
||||||
GTFILES_H=gt-coverage.h gt-caller-save.h gt-symtab.h gt-alias.h gt-bitmap.h gt-cselib.h gt-cgraph.h gt-ipa-prop.h gt-ipa-cp.h gt-dbxout.h gt-dwarf2asm.h gt-dwarf2cfi.h gt-dwarf2out.h gt-tree-vect-generic.h gt-dojump.h gt-emit-rtl.h gt-explow.h gt-expr.h gt-function.h gt-except.h gt-gcse.h gt-godump.h gt-lists.h gt-optabs.h gt-profile.h gt-mcf.h gt-reg-stack.h gt-cfgrtl.h gt-sdbout.h gt-stor-layout.h gt-stringpool.h gt-tree.h gt-varasm.h gt-gimple.h gt-tree-mudflap.h gt-tree-ssanames.h gt-tree-eh.h gt-tree-ssa-address.h gt-tree-cfg.h gt-tree-dfa.h gt-tree-iterator.h gt-gimplify.h gt-tree-scalar-evolution.h gt-tree-profile.h gt-tree-nested.h gt-tree-parloops.h gt-omp-low.h gt-targhooks.h gt-i386.h gt-passes.h gt-cgraphunit.h gt-cgraphclones.h gt-tree-ssa-propagate.h gt-tree-phinodes.h gt-lto-symtab.h gt-trans-mem.h gt-asan.h gt-tsan.h gt-ada-decl.h gt-ada-trans.h gt-ada-utils.h gt-ada-misc.h gt-c-c-lang.h gt-c-c-decl.h gt-c-family-c-common.h gt-c-family-c-cppbuiltin.h gt-c-family-c-pragma.h gt-c-c-objc-common.h gt-c-c-parser.h gt-cp-rtti.h gt-cp-mangle.h gt-cp-name-lookup.h gt-cp-call.h gt-cp-decl.h gt-cp-decl2.h gt-cp-pt.h gt-cp-repo.h gt-cp-semantics.h gt-cp-tree.h gt-cp-parser.h gt-cp-method.h gt-cp-typeck2.h gt-c-family-c-common.h gt-c-family-c-lex.h gt-c-family-c-pragma.h gt-cp-class.h gt-cp-cp-objcp-common.h gt-cp-cp-lang.h gt-cp-except.h gt-fortran-f95-lang.h gt-fortran-trans-decl.h gt-fortran-trans-intrinsic.h gt-fortran-trans-io.h gt-fortran-trans-stmt.h gt-fortran-trans-types.h gt-go-go-lang.h gt-java-builtins.h gt-java-class.h gt-java-constants.h gt-java-decl.h gt-java-expr.h gt-java-jcf-parse.h gt-java-lang.h gt-java-mangle.h gt-java-resource.h gt-lto-lto-lang.h gt-lto-lto.h gt-objc-objc-act.h gt-objc-objc-runtime-shared-support.h gt-objc-objc-gnu-runtime-abi-01.h gt-objc-objc-next-runtime-abi-01.h gt-objc-objc-next-runtime-abi-02.h gt-c-c-parser.h gt-c-c-decl.h gt-c-c-objc-common.h gt-c-family-c-common.h gt-c-family-c-cppbuiltin.h gt-c-family-c-pragma.h gt-cp-rtti.h gt-cp-mangle.h gt-cp-name-lookup.h gt-cp-call.h gt-cp-decl.h gt-cp-decl2.h gt-cp-pt.h gt-cp-repo.h gt-cp-semantics.h gt-cp-tree.h gt-cp-parser.h gt-cp-method.h gt-cp-typeck2.h gt-c-family-c-common.h gt-c-family-c-lex.h gt-c-family-c-pragma.h gt-cp-class.h gt-cp-cp-objcp-common.h gt-objc-objc-act.h gt-objc-objc-runtime-shared-support.h gt-objc-objc-gnu-runtime-abi-01.h gt-objc-objc-next-runtime-abi-01.h gt-objc-objc-next-runtime-abi-02.h gt-c-family-c-cppbuiltin.h
|
|
||||||
GTFILES_LANG_H=gtype-ada.h gtype-c.h gtype-cp.h gtype-fortran.h gtype-go.h gtype-java.h gtype-lto.h gtype-objc.h gtype-objcp.h
|
|
@ -1,974 +0,0 @@
|
|||||||
/* Define control flow data structures for the CFG.
|
|
||||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_BASIC_BLOCK_H
|
|
||||||
#define GCC_BASIC_BLOCK_H
|
|
||||||
|
|
||||||
#include "predict.h"
|
|
||||||
#include "vec.h"
|
|
||||||
#include "function.h"
|
|
||||||
|
|
||||||
/* Type we use to hold basic block counters. Should be at least
|
|
||||||
64bit. Although a counter cannot be negative, we use a signed
|
|
||||||
type, because erroneous negative counts can be generated when the
|
|
||||||
flow graph is manipulated by various optimizations. A signed type
|
|
||||||
makes those easy to detect. */
|
|
||||||
typedef HOST_WIDEST_INT gcov_type;
|
|
||||||
typedef unsigned HOST_WIDEST_INT gcov_type_unsigned;
|
|
||||||
|
|
||||||
/* Control flow edge information. */
|
|
||||||
struct GTY((user)) edge_def {
|
|
||||||
/* The two blocks at the ends of the edge. */
|
|
||||||
basic_block src;
|
|
||||||
basic_block dest;
|
|
||||||
|
|
||||||
/* Instructions queued on the edge. */
|
|
||||||
union edge_def_insns {
|
|
||||||
gimple_seq g;
|
|
||||||
rtx r;
|
|
||||||
} insns;
|
|
||||||
|
|
||||||
/* Auxiliary info specific to a pass. */
|
|
||||||
PTR aux;
|
|
||||||
|
|
||||||
/* Location of any goto implicit in the edge. */
|
|
||||||
location_t goto_locus;
|
|
||||||
|
|
||||||
/* The index number corresponding to this edge in the edge vector
|
|
||||||
dest->preds. */
|
|
||||||
unsigned int dest_idx;
|
|
||||||
|
|
||||||
int flags; /* see cfg-flags.def */
|
|
||||||
int probability; /* biased by REG_BR_PROB_BASE */
|
|
||||||
gcov_type count; /* Expected number of executions calculated
|
|
||||||
in profile.c */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Garbage collection and PCH support for edge_def. */
|
|
||||||
extern void gt_ggc_mx (edge_def *e);
|
|
||||||
extern void gt_pch_nx (edge_def *e);
|
|
||||||
extern void gt_pch_nx (edge_def *e, gt_pointer_operator, void *);
|
|
||||||
|
|
||||||
/* Masks for edge.flags. */
|
|
||||||
#define DEF_EDGE_FLAG(NAME,IDX) EDGE_##NAME = 1 << IDX ,
|
|
||||||
enum cfg_edge_flags {
|
|
||||||
#include "cfg-flags.def"
|
|
||||||
LAST_CFG_EDGE_FLAG /* this is only used for EDGE_ALL_FLAGS */
|
|
||||||
};
|
|
||||||
#undef DEF_EDGE_FLAG
|
|
||||||
|
|
||||||
/* Bit mask for all edge flags. */
|
|
||||||
#define EDGE_ALL_FLAGS ((LAST_CFG_EDGE_FLAG - 1) * 2 - 1)
|
|
||||||
|
|
||||||
/* The following four flags all indicate something special about an edge.
|
|
||||||
Test the edge flags on EDGE_COMPLEX to detect all forms of "strange"
|
|
||||||
control flow transfers. */
|
|
||||||
#define EDGE_COMPLEX \
|
|
||||||
(EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_PRESERVE)
|
|
||||||
|
|
||||||
/* Counter summary from the last set of coverage counts read by
|
|
||||||
profile.c. */
|
|
||||||
extern const struct gcov_ctr_summary *profile_info;
|
|
||||||
|
|
||||||
/* Working set size statistics for a given percentage of the entire
|
|
||||||
profile (sum_all from the counter summary). */
|
|
||||||
typedef struct gcov_working_set_info
|
|
||||||
{
|
|
||||||
/* Number of hot counters included in this working set. */
|
|
||||||
unsigned num_counters;
|
|
||||||
/* Smallest counter included in this working set. */
|
|
||||||
gcov_type min_counter;
|
|
||||||
} gcov_working_set_t;
|
|
||||||
|
|
||||||
/* Structure to gather statistic about profile consistency, per pass.
|
|
||||||
An array of this structure, indexed by pass static number, is allocated
|
|
||||||
in passes.c. The structure is defined here so that different CFG modes
|
|
||||||
can do their book-keeping via CFG hooks.
|
|
||||||
|
|
||||||
For every field[2], field[0] is the count before the pass runs, and
|
|
||||||
field[1] is the post-pass count. This allows us to monitor the effect
|
|
||||||
of each individual pass on the profile consistency.
|
|
||||||
|
|
||||||
This structure is not supposed to be used by anything other than passes.c
|
|
||||||
and one CFG hook per CFG mode. */
|
|
||||||
struct profile_record
|
|
||||||
{
|
|
||||||
/* The number of basic blocks where sum(freq) of the block's predecessors
|
|
||||||
doesn't match reasonably well with the incoming frequency. */
|
|
||||||
int num_mismatched_freq_in[2];
|
|
||||||
/* Likewise for a basic block's successors. */
|
|
||||||
int num_mismatched_freq_out[2];
|
|
||||||
/* The number of basic blocks where sum(count) of the block's predecessors
|
|
||||||
doesn't match reasonably well with the incoming frequency. */
|
|
||||||
int num_mismatched_count_in[2];
|
|
||||||
/* Likewise for a basic block's successors. */
|
|
||||||
int num_mismatched_count_out[2];
|
|
||||||
/* A weighted cost of the run-time of the function body. */
|
|
||||||
gcov_type time[2];
|
|
||||||
/* A weighted cost of the size of the function body. */
|
|
||||||
int size[2];
|
|
||||||
/* True iff this pass actually was run. */
|
|
||||||
bool run;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Declared in cfgloop.h. */
|
|
||||||
struct loop;
|
|
||||||
|
|
||||||
struct GTY(()) rtl_bb_info {
|
|
||||||
/* The first insn of the block is embedded into bb->il.x. */
|
|
||||||
/* The last insn of the block. */
|
|
||||||
rtx end_;
|
|
||||||
|
|
||||||
/* In CFGlayout mode points to insn notes/jumptables to be placed just before
|
|
||||||
and after the block. */
|
|
||||||
rtx header_;
|
|
||||||
rtx footer_;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GTY(()) gimple_bb_info {
|
|
||||||
/* Sequence of statements in this block. */
|
|
||||||
gimple_seq seq;
|
|
||||||
|
|
||||||
/* PHI nodes for this block. */
|
|
||||||
gimple_seq phi_nodes;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* A basic block is a sequence of instructions with only one entry and
|
|
||||||
only one exit. If any one of the instructions are executed, they
|
|
||||||
will all be executed, and in sequence from first to last.
|
|
||||||
|
|
||||||
There may be COND_EXEC instructions in the basic block. The
|
|
||||||
COND_EXEC *instructions* will be executed -- but if the condition
|
|
||||||
is false the conditionally executed *expressions* will of course
|
|
||||||
not be executed. We don't consider the conditionally executed
|
|
||||||
expression (which might have side-effects) to be in a separate
|
|
||||||
basic block because the program counter will always be at the same
|
|
||||||
location after the COND_EXEC instruction, regardless of whether the
|
|
||||||
condition is true or not.
|
|
||||||
|
|
||||||
Basic blocks need not start with a label nor end with a jump insn.
|
|
||||||
For example, a previous basic block may just "conditionally fall"
|
|
||||||
into the succeeding basic block, and the last basic block need not
|
|
||||||
end with a jump insn. Block 0 is a descendant of the entry block.
|
|
||||||
|
|
||||||
A basic block beginning with two labels cannot have notes between
|
|
||||||
the labels.
|
|
||||||
|
|
||||||
Data for jump tables are stored in jump_insns that occur in no
|
|
||||||
basic block even though these insns can follow or precede insns in
|
|
||||||
basic blocks. */
|
|
||||||
|
|
||||||
/* Basic block information indexed by block number. */
|
|
||||||
struct GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb"))) basic_block_def {
|
|
||||||
/* The edges into and out of the block. */
|
|
||||||
vec<edge, va_gc> *preds;
|
|
||||||
vec<edge, va_gc> *succs;
|
|
||||||
|
|
||||||
/* Auxiliary info specific to a pass. */
|
|
||||||
PTR GTY ((skip (""))) aux;
|
|
||||||
|
|
||||||
/* Innermost loop containing the block. */
|
|
||||||
struct loop *loop_father;
|
|
||||||
|
|
||||||
/* The dominance and postdominance information node. */
|
|
||||||
struct et_node * GTY ((skip (""))) dom[2];
|
|
||||||
|
|
||||||
/* Previous and next blocks in the chain. */
|
|
||||||
basic_block prev_bb;
|
|
||||||
basic_block next_bb;
|
|
||||||
|
|
||||||
union basic_block_il_dependent {
|
|
||||||
struct gimple_bb_info GTY ((tag ("0"))) gimple;
|
|
||||||
struct {
|
|
||||||
rtx head_;
|
|
||||||
struct rtl_bb_info * rtl;
|
|
||||||
} GTY ((tag ("1"))) x;
|
|
||||||
} GTY ((desc ("((%1.flags & BB_RTL) != 0)"))) il;
|
|
||||||
|
|
||||||
/* Various flags. See cfg-flags.def. */
|
|
||||||
int flags;
|
|
||||||
|
|
||||||
/* The index of this block. */
|
|
||||||
int index;
|
|
||||||
|
|
||||||
/* Expected number of executions: calculated in profile.c. */
|
|
||||||
gcov_type count;
|
|
||||||
|
|
||||||
/* Expected frequency. Normalized to be in range 0 to BB_FREQ_MAX. */
|
|
||||||
int frequency;
|
|
||||||
|
|
||||||
/* The discriminator for this block. The discriminator distinguishes
|
|
||||||
among several basic blocks that share a common locus, allowing for
|
|
||||||
more accurate sample-based profiling. */
|
|
||||||
int discriminator;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This ensures that struct gimple_bb_info is smaller than
|
|
||||||
struct rtl_bb_info, so that inlining the former into basic_block_def
|
|
||||||
is the better choice. */
|
|
||||||
typedef int __assert_gimple_bb_smaller_rtl_bb
|
|
||||||
[(int)sizeof(struct rtl_bb_info)
|
|
||||||
- (int)sizeof (struct gimple_bb_info)];
|
|
||||||
|
|
||||||
|
|
||||||
#define BB_FREQ_MAX 10000
|
|
||||||
|
|
||||||
/* Masks for basic_block.flags. */
|
|
||||||
#define DEF_BASIC_BLOCK_FLAG(NAME,IDX) BB_##NAME = 1 << IDX ,
|
|
||||||
enum cfg_bb_flags
|
|
||||||
{
|
|
||||||
#include "cfg-flags.def"
|
|
||||||
LAST_CFG_BB_FLAG /* this is only used for BB_ALL_FLAGS */
|
|
||||||
};
|
|
||||||
#undef DEF_BASIC_BLOCK_FLAG
|
|
||||||
|
|
||||||
/* Bit mask for all basic block flags. */
|
|
||||||
#define BB_ALL_FLAGS ((LAST_CFG_BB_FLAG - 1) * 2 - 1)
|
|
||||||
|
|
||||||
/* Bit mask for all basic block flags that must be preserved. These are
|
|
||||||
the bit masks that are *not* cleared by clear_bb_flags. */
|
|
||||||
#define BB_FLAGS_TO_PRESERVE \
|
|
||||||
(BB_DISABLE_SCHEDULE | BB_RTL | BB_NON_LOCAL_GOTO_TARGET \
|
|
||||||
| BB_HOT_PARTITION | BB_COLD_PARTITION)
|
|
||||||
|
|
||||||
/* Dummy bitmask for convenience in the hot/cold partitioning code. */
|
|
||||||
#define BB_UNPARTITIONED 0
|
|
||||||
|
|
||||||
/* Partitions, to be used when partitioning hot and cold basic blocks into
|
|
||||||
separate sections. */
|
|
||||||
#define BB_PARTITION(bb) ((bb)->flags & (BB_HOT_PARTITION|BB_COLD_PARTITION))
|
|
||||||
#define BB_SET_PARTITION(bb, part) do { \
|
|
||||||
basic_block bb_ = (bb); \
|
|
||||||
bb_->flags = ((bb_->flags & ~(BB_HOT_PARTITION|BB_COLD_PARTITION)) \
|
|
||||||
| (part)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define BB_COPY_PARTITION(dstbb, srcbb) \
|
|
||||||
BB_SET_PARTITION (dstbb, BB_PARTITION (srcbb))
|
|
||||||
|
|
||||||
/* State of dominance information. */
|
|
||||||
|
|
||||||
enum dom_state
|
|
||||||
{
|
|
||||||
DOM_NONE, /* Not computed at all. */
|
|
||||||
DOM_NO_FAST_QUERY, /* The data is OK, but the fast query data are not usable. */
|
|
||||||
DOM_OK /* Everything is ok. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* What sort of profiling information we have. */
|
|
||||||
enum profile_status_d
|
|
||||||
{
|
|
||||||
PROFILE_ABSENT,
|
|
||||||
PROFILE_GUESSED,
|
|
||||||
PROFILE_READ,
|
|
||||||
PROFILE_LAST /* Last value, used by profile streaming. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* A structure to group all the per-function control flow graph data.
|
|
||||||
The x_* prefixing is necessary because otherwise references to the
|
|
||||||
fields of this struct are interpreted as the defines for backward
|
|
||||||
source compatibility following the definition of this struct. */
|
|
||||||
struct GTY(()) control_flow_graph {
|
|
||||||
/* Block pointers for the exit and entry of a function.
|
|
||||||
These are always the head and tail of the basic block list. */
|
|
||||||
basic_block x_entry_block_ptr;
|
|
||||||
basic_block x_exit_block_ptr;
|
|
||||||
|
|
||||||
/* Index by basic block number, get basic block struct info. */
|
|
||||||
vec<basic_block, va_gc> *x_basic_block_info;
|
|
||||||
|
|
||||||
/* Number of basic blocks in this flow graph. */
|
|
||||||
int x_n_basic_blocks;
|
|
||||||
|
|
||||||
/* Number of edges in this flow graph. */
|
|
||||||
int x_n_edges;
|
|
||||||
|
|
||||||
/* The first free basic block number. */
|
|
||||||
int x_last_basic_block;
|
|
||||||
|
|
||||||
/* UIDs for LABEL_DECLs. */
|
|
||||||
int last_label_uid;
|
|
||||||
|
|
||||||
/* Mapping of labels to their associated blocks. At present
|
|
||||||
only used for the gimple CFG. */
|
|
||||||
vec<basic_block, va_gc> *x_label_to_block_map;
|
|
||||||
|
|
||||||
enum profile_status_d x_profile_status;
|
|
||||||
|
|
||||||
/* Whether the dominators and the postdominators are available. */
|
|
||||||
enum dom_state x_dom_computed[2];
|
|
||||||
|
|
||||||
/* Number of basic blocks in the dominance tree. */
|
|
||||||
unsigned x_n_bbs_in_dom_tree[2];
|
|
||||||
|
|
||||||
/* Maximal number of entities in the single jumptable. Used to estimate
|
|
||||||
final flowgraph size. */
|
|
||||||
int max_jumptable_ents;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Defines for accessing the fields of the CFG structure for function FN. */
|
|
||||||
#define ENTRY_BLOCK_PTR_FOR_FUNCTION(FN) ((FN)->cfg->x_entry_block_ptr)
|
|
||||||
#define EXIT_BLOCK_PTR_FOR_FUNCTION(FN) ((FN)->cfg->x_exit_block_ptr)
|
|
||||||
#define basic_block_info_for_function(FN) ((FN)->cfg->x_basic_block_info)
|
|
||||||
#define n_basic_blocks_for_function(FN) ((FN)->cfg->x_n_basic_blocks)
|
|
||||||
#define n_edges_for_function(FN) ((FN)->cfg->x_n_edges)
|
|
||||||
#define last_basic_block_for_function(FN) ((FN)->cfg->x_last_basic_block)
|
|
||||||
#define label_to_block_map_for_function(FN) ((FN)->cfg->x_label_to_block_map)
|
|
||||||
#define profile_status_for_function(FN) ((FN)->cfg->x_profile_status)
|
|
||||||
|
|
||||||
#define BASIC_BLOCK_FOR_FUNCTION(FN,N) \
|
|
||||||
((*basic_block_info_for_function(FN))[(N)])
|
|
||||||
#define SET_BASIC_BLOCK_FOR_FUNCTION(FN,N,BB) \
|
|
||||||
((*basic_block_info_for_function(FN))[(N)] = (BB))
|
|
||||||
|
|
||||||
/* Defines for textual backward source compatibility. */
|
|
||||||
#define ENTRY_BLOCK_PTR (cfun->cfg->x_entry_block_ptr)
|
|
||||||
#define EXIT_BLOCK_PTR (cfun->cfg->x_exit_block_ptr)
|
|
||||||
#define basic_block_info (cfun->cfg->x_basic_block_info)
|
|
||||||
#define n_basic_blocks (cfun->cfg->x_n_basic_blocks)
|
|
||||||
#define n_edges (cfun->cfg->x_n_edges)
|
|
||||||
#define last_basic_block (cfun->cfg->x_last_basic_block)
|
|
||||||
#define label_to_block_map (cfun->cfg->x_label_to_block_map)
|
|
||||||
#define profile_status (cfun->cfg->x_profile_status)
|
|
||||||
|
|
||||||
#define BASIC_BLOCK(N) ((*basic_block_info)[(N)])
|
|
||||||
#define SET_BASIC_BLOCK(N,BB) ((*basic_block_info)[(N)] = (BB))
|
|
||||||
|
|
||||||
/* For iterating over basic blocks. */
|
|
||||||
#define FOR_BB_BETWEEN(BB, FROM, TO, DIR) \
|
|
||||||
for (BB = FROM; BB != TO; BB = BB->DIR)
|
|
||||||
|
|
||||||
#define FOR_EACH_BB_FN(BB, FN) \
|
|
||||||
FOR_BB_BETWEEN (BB, (FN)->cfg->x_entry_block_ptr->next_bb, (FN)->cfg->x_exit_block_ptr, next_bb)
|
|
||||||
|
|
||||||
#define FOR_EACH_BB(BB) FOR_EACH_BB_FN (BB, cfun)
|
|
||||||
|
|
||||||
#define FOR_EACH_BB_REVERSE_FN(BB, FN) \
|
|
||||||
FOR_BB_BETWEEN (BB, (FN)->cfg->x_exit_block_ptr->prev_bb, (FN)->cfg->x_entry_block_ptr, prev_bb)
|
|
||||||
|
|
||||||
#define FOR_EACH_BB_REVERSE(BB) FOR_EACH_BB_REVERSE_FN(BB, cfun)
|
|
||||||
|
|
||||||
/* For iterating over insns in basic block. */
|
|
||||||
#define FOR_BB_INSNS(BB, INSN) \
|
|
||||||
for ((INSN) = BB_HEAD (BB); \
|
|
||||||
(INSN) && (INSN) != NEXT_INSN (BB_END (BB)); \
|
|
||||||
(INSN) = NEXT_INSN (INSN))
|
|
||||||
|
|
||||||
/* For iterating over insns in basic block when we might remove the
|
|
||||||
current insn. */
|
|
||||||
#define FOR_BB_INSNS_SAFE(BB, INSN, CURR) \
|
|
||||||
for ((INSN) = BB_HEAD (BB), (CURR) = (INSN) ? NEXT_INSN ((INSN)): NULL; \
|
|
||||||
(INSN) && (INSN) != NEXT_INSN (BB_END (BB)); \
|
|
||||||
(INSN) = (CURR), (CURR) = (INSN) ? NEXT_INSN ((INSN)) : NULL)
|
|
||||||
|
|
||||||
#define FOR_BB_INSNS_REVERSE(BB, INSN) \
|
|
||||||
for ((INSN) = BB_END (BB); \
|
|
||||||
(INSN) && (INSN) != PREV_INSN (BB_HEAD (BB)); \
|
|
||||||
(INSN) = PREV_INSN (INSN))
|
|
||||||
|
|
||||||
#define FOR_BB_INSNS_REVERSE_SAFE(BB, INSN, CURR) \
|
|
||||||
for ((INSN) = BB_END (BB),(CURR) = (INSN) ? PREV_INSN ((INSN)) : NULL; \
|
|
||||||
(INSN) && (INSN) != PREV_INSN (BB_HEAD (BB)); \
|
|
||||||
(INSN) = (CURR), (CURR) = (INSN) ? PREV_INSN ((INSN)) : NULL)
|
|
||||||
|
|
||||||
/* Cycles through _all_ basic blocks, even the fake ones (entry and
|
|
||||||
exit block). */
|
|
||||||
|
|
||||||
#define FOR_ALL_BB(BB) \
|
|
||||||
for (BB = ENTRY_BLOCK_PTR; BB; BB = BB->next_bb)
|
|
||||||
|
|
||||||
#define FOR_ALL_BB_FN(BB, FN) \
|
|
||||||
for (BB = ENTRY_BLOCK_PTR_FOR_FUNCTION (FN); BB; BB = BB->next_bb)
|
|
||||||
|
|
||||||
|
|
||||||
/* Stuff for recording basic block info. */
|
|
||||||
|
|
||||||
#define BB_HEAD(B) (B)->il.x.head_
|
|
||||||
#define BB_END(B) (B)->il.x.rtl->end_
|
|
||||||
#define BB_HEADER(B) (B)->il.x.rtl->header_
|
|
||||||
#define BB_FOOTER(B) (B)->il.x.rtl->footer_
|
|
||||||
|
|
||||||
/* Special block numbers [markers] for entry and exit.
|
|
||||||
Neither of them is supposed to hold actual statements. */
|
|
||||||
#define ENTRY_BLOCK (0)
|
|
||||||
#define EXIT_BLOCK (1)
|
|
||||||
|
|
||||||
/* The two blocks that are always in the cfg. */
|
|
||||||
#define NUM_FIXED_BLOCKS (2)
|
|
||||||
|
|
||||||
#define set_block_for_insn(INSN, BB) (BLOCK_FOR_INSN (INSN) = BB)
|
|
||||||
|
|
||||||
extern void compute_bb_for_insn (void);
|
|
||||||
extern unsigned int free_bb_for_insn (void);
|
|
||||||
extern void update_bb_for_insn (basic_block);
|
|
||||||
|
|
||||||
extern void insert_insn_on_edge (rtx, edge);
|
|
||||||
basic_block split_edge_and_insert (edge, rtx);
|
|
||||||
|
|
||||||
extern void commit_one_edge_insertion (edge e);
|
|
||||||
extern void commit_edge_insertions (void);
|
|
||||||
|
|
||||||
extern edge unchecked_make_edge (basic_block, basic_block, int);
|
|
||||||
extern edge cached_make_edge (sbitmap, basic_block, basic_block, int);
|
|
||||||
extern edge make_edge (basic_block, basic_block, int);
|
|
||||||
extern edge make_single_succ_edge (basic_block, basic_block, int);
|
|
||||||
extern void remove_edge_raw (edge);
|
|
||||||
extern void redirect_edge_succ (edge, basic_block);
|
|
||||||
extern edge redirect_edge_succ_nodup (edge, basic_block);
|
|
||||||
extern void redirect_edge_pred (edge, basic_block);
|
|
||||||
extern basic_block create_basic_block_structure (rtx, rtx, rtx, basic_block);
|
|
||||||
extern void clear_bb_flags (void);
|
|
||||||
extern void dump_bb_info (FILE *, basic_block, int, int, bool, bool);
|
|
||||||
extern void dump_edge_info (FILE *, edge, int, int);
|
|
||||||
extern void brief_dump_cfg (FILE *, int);
|
|
||||||
extern void clear_edges (void);
|
|
||||||
extern void scale_bbs_frequencies_int (basic_block *, int, int, int);
|
|
||||||
extern void scale_bbs_frequencies_gcov_type (basic_block *, int, gcov_type,
|
|
||||||
gcov_type);
|
|
||||||
|
|
||||||
/* Structure to group all of the information to process IF-THEN and
|
|
||||||
IF-THEN-ELSE blocks for the conditional execution support. This
|
|
||||||
needs to be in a public file in case the IFCVT macros call
|
|
||||||
functions passing the ce_if_block data structure. */
|
|
||||||
|
|
||||||
typedef struct ce_if_block
|
|
||||||
{
|
|
||||||
basic_block test_bb; /* First test block. */
|
|
||||||
basic_block then_bb; /* THEN block. */
|
|
||||||
basic_block else_bb; /* ELSE block or NULL. */
|
|
||||||
basic_block join_bb; /* Join THEN/ELSE blocks. */
|
|
||||||
basic_block last_test_bb; /* Last bb to hold && or || tests. */
|
|
||||||
int num_multiple_test_blocks; /* # of && and || basic blocks. */
|
|
||||||
int num_and_and_blocks; /* # of && blocks. */
|
|
||||||
int num_or_or_blocks; /* # of || blocks. */
|
|
||||||
int num_multiple_test_insns; /* # of insns in && and || blocks. */
|
|
||||||
int and_and_p; /* Complex test is &&. */
|
|
||||||
int num_then_insns; /* # of insns in THEN block. */
|
|
||||||
int num_else_insns; /* # of insns in ELSE block. */
|
|
||||||
int pass; /* Pass number. */
|
|
||||||
} ce_if_block_t;
|
|
||||||
|
|
||||||
/* This structure maintains an edge list vector. */
|
|
||||||
/* FIXME: Make this a vec<edge>. */
|
|
||||||
struct edge_list
|
|
||||||
{
|
|
||||||
int num_edges;
|
|
||||||
edge *index_to_edge;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The base value for branch probability notes and edge probabilities. */
|
|
||||||
#define REG_BR_PROB_BASE 10000
|
|
||||||
|
|
||||||
/* This is the value which indicates no edge is present. */
|
|
||||||
#define EDGE_INDEX_NO_EDGE -1
|
|
||||||
|
|
||||||
/* EDGE_INDEX returns an integer index for an edge, or EDGE_INDEX_NO_EDGE
|
|
||||||
if there is no edge between the 2 basic blocks. */
|
|
||||||
#define EDGE_INDEX(el, pred, succ) (find_edge_index ((el), (pred), (succ)))
|
|
||||||
|
|
||||||
/* INDEX_EDGE_PRED_BB and INDEX_EDGE_SUCC_BB return a pointer to the basic
|
|
||||||
block which is either the pred or succ end of the indexed edge. */
|
|
||||||
#define INDEX_EDGE_PRED_BB(el, index) ((el)->index_to_edge[(index)]->src)
|
|
||||||
#define INDEX_EDGE_SUCC_BB(el, index) ((el)->index_to_edge[(index)]->dest)
|
|
||||||
|
|
||||||
/* INDEX_EDGE returns a pointer to the edge. */
|
|
||||||
#define INDEX_EDGE(el, index) ((el)->index_to_edge[(index)])
|
|
||||||
|
|
||||||
/* Number of edges in the compressed edge list. */
|
|
||||||
#define NUM_EDGES(el) ((el)->num_edges)
|
|
||||||
|
|
||||||
/* BB is assumed to contain conditional jump. Return the fallthru edge. */
|
|
||||||
#define FALLTHRU_EDGE(bb) (EDGE_SUCC ((bb), 0)->flags & EDGE_FALLTHRU \
|
|
||||||
? EDGE_SUCC ((bb), 0) : EDGE_SUCC ((bb), 1))
|
|
||||||
|
|
||||||
/* BB is assumed to contain conditional jump. Return the branch edge. */
|
|
||||||
#define BRANCH_EDGE(bb) (EDGE_SUCC ((bb), 0)->flags & EDGE_FALLTHRU \
|
|
||||||
? EDGE_SUCC ((bb), 1) : EDGE_SUCC ((bb), 0))
|
|
||||||
|
|
||||||
#define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
|
|
||||||
/* Return expected execution frequency of the edge E. */
|
|
||||||
#define EDGE_FREQUENCY(e) RDIV ((e)->src->frequency * (e)->probability, \
|
|
||||||
REG_BR_PROB_BASE)
|
|
||||||
|
|
||||||
/* Return nonzero if edge is critical. */
|
|
||||||
#define EDGE_CRITICAL_P(e) (EDGE_COUNT ((e)->src->succs) >= 2 \
|
|
||||||
&& EDGE_COUNT ((e)->dest->preds) >= 2)
|
|
||||||
|
|
||||||
#define EDGE_COUNT(ev) vec_safe_length (ev)
|
|
||||||
#define EDGE_I(ev,i) (*ev)[(i)]
|
|
||||||
#define EDGE_PRED(bb,i) (*(bb)->preds)[(i)]
|
|
||||||
#define EDGE_SUCC(bb,i) (*(bb)->succs)[(i)]
|
|
||||||
|
|
||||||
/* Returns true if BB has precisely one successor. */
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
single_succ_p (const_basic_block bb)
|
|
||||||
{
|
|
||||||
return EDGE_COUNT (bb->succs) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns true if BB has precisely one predecessor. */
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
single_pred_p (const_basic_block bb)
|
|
||||||
{
|
|
||||||
return EDGE_COUNT (bb->preds) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns the single successor edge of basic block BB. Aborts if
|
|
||||||
BB does not have exactly one successor. */
|
|
||||||
|
|
||||||
static inline edge
|
|
||||||
single_succ_edge (const_basic_block bb)
|
|
||||||
{
|
|
||||||
gcc_checking_assert (single_succ_p (bb));
|
|
||||||
return EDGE_SUCC (bb, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns the single predecessor edge of basic block BB. Aborts
|
|
||||||
if BB does not have exactly one predecessor. */
|
|
||||||
|
|
||||||
static inline edge
|
|
||||||
single_pred_edge (const_basic_block bb)
|
|
||||||
{
|
|
||||||
gcc_checking_assert (single_pred_p (bb));
|
|
||||||
return EDGE_PRED (bb, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns the single successor block of basic block BB. Aborts
|
|
||||||
if BB does not have exactly one successor. */
|
|
||||||
|
|
||||||
static inline basic_block
|
|
||||||
single_succ (const_basic_block bb)
|
|
||||||
{
|
|
||||||
return single_succ_edge (bb)->dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns the single predecessor block of basic block BB. Aborts
|
|
||||||
if BB does not have exactly one predecessor.*/
|
|
||||||
|
|
||||||
static inline basic_block
|
|
||||||
single_pred (const_basic_block bb)
|
|
||||||
{
|
|
||||||
return single_pred_edge (bb)->src;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Iterator object for edges. */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned index;
|
|
||||||
vec<edge, va_gc> **container;
|
|
||||||
} edge_iterator;
|
|
||||||
|
|
||||||
static inline vec<edge, va_gc> *
|
|
||||||
ei_container (edge_iterator i)
|
|
||||||
{
|
|
||||||
gcc_checking_assert (i.container);
|
|
||||||
return *i.container;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ei_start(iter) ei_start_1 (&(iter))
|
|
||||||
#define ei_last(iter) ei_last_1 (&(iter))
|
|
||||||
|
|
||||||
/* Return an iterator pointing to the start of an edge vector. */
|
|
||||||
static inline edge_iterator
|
|
||||||
ei_start_1 (vec<edge, va_gc> **ev)
|
|
||||||
{
|
|
||||||
edge_iterator i;
|
|
||||||
|
|
||||||
i.index = 0;
|
|
||||||
i.container = ev;
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return an iterator pointing to the last element of an edge
|
|
||||||
vector. */
|
|
||||||
static inline edge_iterator
|
|
||||||
ei_last_1 (vec<edge, va_gc> **ev)
|
|
||||||
{
|
|
||||||
edge_iterator i;
|
|
||||||
|
|
||||||
i.index = EDGE_COUNT (*ev) - 1;
|
|
||||||
i.container = ev;
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Is the iterator `i' at the end of the sequence? */
|
|
||||||
static inline bool
|
|
||||||
ei_end_p (edge_iterator i)
|
|
||||||
{
|
|
||||||
return (i.index == EDGE_COUNT (ei_container (i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Is the iterator `i' at one position before the end of the
|
|
||||||
sequence? */
|
|
||||||
static inline bool
|
|
||||||
ei_one_before_end_p (edge_iterator i)
|
|
||||||
{
|
|
||||||
return (i.index + 1 == EDGE_COUNT (ei_container (i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance the iterator to the next element. */
|
|
||||||
static inline void
|
|
||||||
ei_next (edge_iterator *i)
|
|
||||||
{
|
|
||||||
gcc_checking_assert (i->index < EDGE_COUNT (ei_container (*i)));
|
|
||||||
i->index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move the iterator to the previous element. */
|
|
||||||
static inline void
|
|
||||||
ei_prev (edge_iterator *i)
|
|
||||||
{
|
|
||||||
gcc_checking_assert (i->index > 0);
|
|
||||||
i->index--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the edge pointed to by the iterator `i'. */
|
|
||||||
static inline edge
|
|
||||||
ei_edge (edge_iterator i)
|
|
||||||
{
|
|
||||||
return EDGE_I (ei_container (i), i.index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return an edge pointed to by the iterator. Do it safely so that
|
|
||||||
NULL is returned when the iterator is pointing at the end of the
|
|
||||||
sequence. */
|
|
||||||
static inline edge
|
|
||||||
ei_safe_edge (edge_iterator i)
|
|
||||||
{
|
|
||||||
return !ei_end_p (i) ? ei_edge (i) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return 1 if we should continue to iterate. Return 0 otherwise.
|
|
||||||
*Edge P is set to the next edge if we are to continue to iterate
|
|
||||||
and NULL otherwise. */
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
ei_cond (edge_iterator ei, edge *p)
|
|
||||||
{
|
|
||||||
if (!ei_end_p (ei))
|
|
||||||
{
|
|
||||||
*p = ei_edge (ei);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*p = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This macro serves as a convenient way to iterate each edge in a
|
|
||||||
vector of predecessor or successor edges. It must not be used when
|
|
||||||
an element might be removed during the traversal, otherwise
|
|
||||||
elements will be missed. Instead, use a for-loop like that shown
|
|
||||||
in the following pseudo-code:
|
|
||||||
|
|
||||||
FOR (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
|
|
||||||
{
|
|
||||||
IF (e != taken_edge)
|
|
||||||
remove_edge (e);
|
|
||||||
ELSE
|
|
||||||
ei_next (&ei);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define FOR_EACH_EDGE(EDGE,ITER,EDGE_VEC) \
|
|
||||||
for ((ITER) = ei_start ((EDGE_VEC)); \
|
|
||||||
ei_cond ((ITER), &(EDGE)); \
|
|
||||||
ei_next (&(ITER)))
|
|
||||||
|
|
||||||
#define CLEANUP_EXPENSIVE 1 /* Do relatively expensive optimizations
|
|
||||||
except for edge forwarding */
|
|
||||||
#define CLEANUP_CROSSJUMP 2 /* Do crossjumping. */
|
|
||||||
#define CLEANUP_POST_REGSTACK 4 /* We run after reg-stack and need
|
|
||||||
to care REG_DEAD notes. */
|
|
||||||
#define CLEANUP_THREADING 8 /* Do jump threading. */
|
|
||||||
#define CLEANUP_NO_INSN_DEL 16 /* Do not try to delete trivially dead
|
|
||||||
insns. */
|
|
||||||
#define CLEANUP_CFGLAYOUT 32 /* Do cleanup in cfglayout mode. */
|
|
||||||
#define CLEANUP_CFG_CHANGED 64 /* The caller changed the CFG. */
|
|
||||||
|
|
||||||
/* In cfganal.c */
|
|
||||||
extern void bitmap_intersection_of_succs (sbitmap, sbitmap *, basic_block);
|
|
||||||
extern void bitmap_intersection_of_preds (sbitmap, sbitmap *, basic_block);
|
|
||||||
extern void bitmap_union_of_succs (sbitmap, sbitmap *, basic_block);
|
|
||||||
extern void bitmap_union_of_preds (sbitmap, sbitmap *, basic_block);
|
|
||||||
|
|
||||||
/* In lcm.c */
|
|
||||||
extern struct edge_list *pre_edge_lcm (int, sbitmap *, sbitmap *,
|
|
||||||
sbitmap *, sbitmap *, sbitmap **,
|
|
||||||
sbitmap **);
|
|
||||||
extern struct edge_list *pre_edge_rev_lcm (int, sbitmap *,
|
|
||||||
sbitmap *, sbitmap *,
|
|
||||||
sbitmap *, sbitmap **,
|
|
||||||
sbitmap **);
|
|
||||||
extern void compute_available (sbitmap *, sbitmap *, sbitmap *, sbitmap *);
|
|
||||||
|
|
||||||
/* In predict.c */
|
|
||||||
extern bool maybe_hot_bb_p (struct function *, const_basic_block);
|
|
||||||
extern bool maybe_hot_edge_p (edge);
|
|
||||||
extern bool probably_never_executed_bb_p (struct function *, const_basic_block);
|
|
||||||
extern bool optimize_bb_for_size_p (const_basic_block);
|
|
||||||
extern bool optimize_bb_for_speed_p (const_basic_block);
|
|
||||||
extern bool optimize_edge_for_size_p (edge);
|
|
||||||
extern bool optimize_edge_for_speed_p (edge);
|
|
||||||
extern bool optimize_loop_for_size_p (struct loop *);
|
|
||||||
extern bool optimize_loop_for_speed_p (struct loop *);
|
|
||||||
extern bool optimize_loop_nest_for_size_p (struct loop *);
|
|
||||||
extern bool optimize_loop_nest_for_speed_p (struct loop *);
|
|
||||||
extern bool gimple_predicted_by_p (const_basic_block, enum br_predictor);
|
|
||||||
extern bool rtl_predicted_by_p (const_basic_block, enum br_predictor);
|
|
||||||
extern void gimple_predict_edge (edge, enum br_predictor, int);
|
|
||||||
extern void rtl_predict_edge (edge, enum br_predictor, int);
|
|
||||||
extern void predict_edge_def (edge, enum br_predictor, enum prediction);
|
|
||||||
extern void guess_outgoing_edge_probabilities (basic_block);
|
|
||||||
extern void remove_predictions_associated_with_edge (edge);
|
|
||||||
extern bool edge_probability_reliable_p (const_edge);
|
|
||||||
extern bool br_prob_note_reliable_p (const_rtx);
|
|
||||||
extern bool predictable_edge_p (edge);
|
|
||||||
|
|
||||||
/* In cfg.c */
|
|
||||||
extern void init_flow (struct function *);
|
|
||||||
extern void debug_bb (basic_block);
|
|
||||||
extern basic_block debug_bb_n (int);
|
|
||||||
extern void dump_flow_info (FILE *, int);
|
|
||||||
extern void expunge_block (basic_block);
|
|
||||||
extern void link_block (basic_block, basic_block);
|
|
||||||
extern void unlink_block (basic_block);
|
|
||||||
extern void compact_blocks (void);
|
|
||||||
extern basic_block alloc_block (void);
|
|
||||||
extern void alloc_aux_for_blocks (int);
|
|
||||||
extern void clear_aux_for_blocks (void);
|
|
||||||
extern void free_aux_for_blocks (void);
|
|
||||||
extern void alloc_aux_for_edge (edge, int);
|
|
||||||
extern void alloc_aux_for_edges (int);
|
|
||||||
extern void clear_aux_for_edges (void);
|
|
||||||
extern void free_aux_for_edges (void);
|
|
||||||
|
|
||||||
/* In cfganal.c */
|
|
||||||
extern void find_unreachable_blocks (void);
|
|
||||||
extern bool mark_dfs_back_edges (void);
|
|
||||||
struct edge_list * create_edge_list (void);
|
|
||||||
void free_edge_list (struct edge_list *);
|
|
||||||
void print_edge_list (FILE *, struct edge_list *);
|
|
||||||
void verify_edge_list (FILE *, struct edge_list *);
|
|
||||||
int find_edge_index (struct edge_list *, basic_block, basic_block);
|
|
||||||
edge find_edge (basic_block, basic_block);
|
|
||||||
extern void remove_fake_edges (void);
|
|
||||||
extern void remove_fake_exit_edges (void);
|
|
||||||
extern void add_noreturn_fake_exit_edges (void);
|
|
||||||
extern void connect_infinite_loops_to_exit (void);
|
|
||||||
extern int post_order_compute (int *, bool, bool);
|
|
||||||
extern basic_block dfs_find_deadend (basic_block);
|
|
||||||
extern int inverted_post_order_compute (int *);
|
|
||||||
extern int pre_and_rev_post_order_compute (int *, int *, bool);
|
|
||||||
extern int dfs_enumerate_from (basic_block, int,
|
|
||||||
bool (*)(const_basic_block, const void *),
|
|
||||||
basic_block *, int, const void *);
|
|
||||||
extern void compute_dominance_frontiers (struct bitmap_head_def *);
|
|
||||||
extern bitmap compute_idf (bitmap, struct bitmap_head_def *);
|
|
||||||
|
|
||||||
/* In cfgrtl.c */
|
|
||||||
extern rtx block_label (basic_block);
|
|
||||||
extern rtx bb_note (basic_block);
|
|
||||||
extern bool purge_all_dead_edges (void);
|
|
||||||
extern bool purge_dead_edges (basic_block);
|
|
||||||
extern bool fixup_abnormal_edges (void);
|
|
||||||
extern basic_block force_nonfallthru_and_redirect (edge, basic_block, rtx);
|
|
||||||
extern bool contains_no_active_insn_p (const_basic_block);
|
|
||||||
extern bool forwarder_block_p (const_basic_block);
|
|
||||||
extern bool can_fallthru (basic_block, basic_block);
|
|
||||||
|
|
||||||
/* In cfgbuild.c. */
|
|
||||||
extern void find_many_sub_basic_blocks (sbitmap);
|
|
||||||
extern void rtl_make_eh_edge (sbitmap, basic_block, rtx);
|
|
||||||
|
|
||||||
enum replace_direction { dir_none, dir_forward, dir_backward, dir_both };
|
|
||||||
|
|
||||||
/* In cfgcleanup.c. */
|
|
||||||
extern bool cleanup_cfg (int);
|
|
||||||
extern int flow_find_cross_jump (basic_block, basic_block, rtx *, rtx *,
|
|
||||||
enum replace_direction*);
|
|
||||||
extern int flow_find_head_matching_sequence (basic_block, basic_block,
|
|
||||||
rtx *, rtx *, int);
|
|
||||||
|
|
||||||
extern bool delete_unreachable_blocks (void);
|
|
||||||
|
|
||||||
extern void update_br_prob_note (basic_block);
|
|
||||||
extern bool inside_basic_block_p (const_rtx);
|
|
||||||
extern bool control_flow_insn_p (const_rtx);
|
|
||||||
extern rtx get_last_bb_insn (basic_block);
|
|
||||||
|
|
||||||
/* In dominance.c */
|
|
||||||
|
|
||||||
enum cdi_direction
|
|
||||||
{
|
|
||||||
CDI_DOMINATORS = 1,
|
|
||||||
CDI_POST_DOMINATORS = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
extern enum dom_state dom_info_state (enum cdi_direction);
|
|
||||||
extern void set_dom_info_availability (enum cdi_direction, enum dom_state);
|
|
||||||
extern bool dom_info_available_p (enum cdi_direction);
|
|
||||||
extern void calculate_dominance_info (enum cdi_direction);
|
|
||||||
extern void free_dominance_info (enum cdi_direction);
|
|
||||||
extern basic_block nearest_common_dominator (enum cdi_direction,
|
|
||||||
basic_block, basic_block);
|
|
||||||
extern basic_block nearest_common_dominator_for_set (enum cdi_direction,
|
|
||||||
bitmap);
|
|
||||||
extern void set_immediate_dominator (enum cdi_direction, basic_block,
|
|
||||||
basic_block);
|
|
||||||
extern basic_block get_immediate_dominator (enum cdi_direction, basic_block);
|
|
||||||
extern bool dominated_by_p (enum cdi_direction, const_basic_block, const_basic_block);
|
|
||||||
extern vec<basic_block> get_dominated_by (enum cdi_direction, basic_block);
|
|
||||||
extern vec<basic_block> get_dominated_by_region (enum cdi_direction,
|
|
||||||
basic_block *,
|
|
||||||
unsigned);
|
|
||||||
extern vec<basic_block> get_dominated_to_depth (enum cdi_direction,
|
|
||||||
basic_block, int);
|
|
||||||
extern vec<basic_block> get_all_dominated_blocks (enum cdi_direction,
|
|
||||||
basic_block);
|
|
||||||
extern void add_to_dominance_info (enum cdi_direction, basic_block);
|
|
||||||
extern void delete_from_dominance_info (enum cdi_direction, basic_block);
|
|
||||||
basic_block recompute_dominator (enum cdi_direction, basic_block);
|
|
||||||
extern void redirect_immediate_dominators (enum cdi_direction, basic_block,
|
|
||||||
basic_block);
|
|
||||||
extern void iterate_fix_dominators (enum cdi_direction,
|
|
||||||
vec<basic_block> , bool);
|
|
||||||
extern void verify_dominators (enum cdi_direction);
|
|
||||||
extern basic_block first_dom_son (enum cdi_direction, basic_block);
|
|
||||||
extern basic_block next_dom_son (enum cdi_direction, basic_block);
|
|
||||||
unsigned bb_dom_dfs_in (enum cdi_direction, basic_block);
|
|
||||||
unsigned bb_dom_dfs_out (enum cdi_direction, basic_block);
|
|
||||||
|
|
||||||
extern edge try_redirect_by_replacing_jump (edge, basic_block, bool);
|
|
||||||
extern void break_superblocks (void);
|
|
||||||
extern void relink_block_chain (bool);
|
|
||||||
extern void update_bb_profile_for_threading (basic_block, int, gcov_type, edge);
|
|
||||||
extern void init_rtl_bb_info (basic_block);
|
|
||||||
|
|
||||||
extern void initialize_original_copy_tables (void);
|
|
||||||
extern void free_original_copy_tables (void);
|
|
||||||
extern void set_bb_original (basic_block, basic_block);
|
|
||||||
extern basic_block get_bb_original (basic_block);
|
|
||||||
extern void set_bb_copy (basic_block, basic_block);
|
|
||||||
extern basic_block get_bb_copy (basic_block);
|
|
||||||
void set_loop_copy (struct loop *, struct loop *);
|
|
||||||
struct loop *get_loop_copy (struct loop *);
|
|
||||||
|
|
||||||
#include "cfghooks.h"
|
|
||||||
|
|
||||||
/* Return true when one of the predecessor edges of BB is marked with EDGE_EH. */
|
|
||||||
static inline bool
|
|
||||||
bb_has_eh_pred (basic_block bb)
|
|
||||||
{
|
|
||||||
edge e;
|
|
||||||
edge_iterator ei;
|
|
||||||
|
|
||||||
FOR_EACH_EDGE (e, ei, bb->preds)
|
|
||||||
{
|
|
||||||
if (e->flags & EDGE_EH)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return true when one of the predecessor edges of BB is marked with EDGE_ABNORMAL. */
|
|
||||||
static inline bool
|
|
||||||
bb_has_abnormal_pred (basic_block bb)
|
|
||||||
{
|
|
||||||
edge e;
|
|
||||||
edge_iterator ei;
|
|
||||||
|
|
||||||
FOR_EACH_EDGE (e, ei, bb->preds)
|
|
||||||
{
|
|
||||||
if (e->flags & EDGE_ABNORMAL)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the fallthru edge in EDGES if it exists, NULL otherwise. */
|
|
||||||
static inline edge
|
|
||||||
find_fallthru_edge (vec<edge, va_gc> *edges)
|
|
||||||
{
|
|
||||||
edge e;
|
|
||||||
edge_iterator ei;
|
|
||||||
|
|
||||||
FOR_EACH_EDGE (e, ei, edges)
|
|
||||||
if (e->flags & EDGE_FALLTHRU)
|
|
||||||
break;
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In cfgloopmanip.c. */
|
|
||||||
extern edge mfb_kj_edge;
|
|
||||||
extern bool mfb_keep_just (edge);
|
|
||||||
|
|
||||||
/* In cfgexpand.c. */
|
|
||||||
extern void rtl_profile_for_bb (basic_block);
|
|
||||||
extern void rtl_profile_for_edge (edge);
|
|
||||||
extern void default_rtl_profile (void);
|
|
||||||
|
|
||||||
/* In profile.c. */
|
|
||||||
extern gcov_working_set_t *find_working_set(unsigned pct_times_10);
|
|
||||||
|
|
||||||
/* Check tha probability is sane. */
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
check_probability (int prob)
|
|
||||||
{
|
|
||||||
gcc_checking_assert (prob >= 0 && prob <= REG_BR_PROB_BASE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Given PROB1 and PROB2, return PROB1*PROB2/REG_BR_PROB_BASE.
|
|
||||||
Used to combine BB probabilities. */
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
combine_probabilities (int prob1, int prob2)
|
|
||||||
{
|
|
||||||
check_probability (prob1);
|
|
||||||
check_probability (prob2);
|
|
||||||
return RDIV (prob1 * prob2, REG_BR_PROB_BASE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Apply probability PROB on frequency or count FREQ. */
|
|
||||||
|
|
||||||
static inline gcov_type
|
|
||||||
apply_probability (gcov_type freq, int prob)
|
|
||||||
{
|
|
||||||
check_probability (prob);
|
|
||||||
return RDIV (freq * prob, REG_BR_PROB_BASE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return inverse probability for PROB. */
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
inverse_probability (int prob1)
|
|
||||||
{
|
|
||||||
check_probability (prob1);
|
|
||||||
return REG_BR_PROB_BASE - prob1;
|
|
||||||
}
|
|
||||||
#endif /* GCC_BASIC_BLOCK_H */
|
|
@ -1,713 +0,0 @@
|
|||||||
/* Functions to support general ended bitmaps.
|
|
||||||
Copyright (C) 1997-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_BITMAP_H
|
|
||||||
#define GCC_BITMAP_H
|
|
||||||
|
|
||||||
/* Implementation of sparse integer sets as a linked list.
|
|
||||||
|
|
||||||
This sparse set representation is suitable for sparse sets with an
|
|
||||||
unknown (a priori) universe. The set is represented as a double-linked
|
|
||||||
list of container nodes (struct bitmap_element_def). Each node consists
|
|
||||||
of an index for the first member that could be held in the container,
|
|
||||||
a small array of integers that represent the members in the container,
|
|
||||||
and pointers to the next and previous element in the linked list. The
|
|
||||||
elements in the list are sorted in ascending order, i.e. the head of
|
|
||||||
the list holds the element with the smallest member of the set.
|
|
||||||
|
|
||||||
For a given member I in the set:
|
|
||||||
- the element for I will have index is I / (bits per element)
|
|
||||||
- the position for I within element is I % (bits per element)
|
|
||||||
|
|
||||||
This representation is very space-efficient for large sparse sets, and
|
|
||||||
the size of the set can be changed dynamically without much overhead.
|
|
||||||
An important parameter is the number of bits per element. In this
|
|
||||||
implementation, there are 128 bits per element. This results in a
|
|
||||||
high storage overhead *per element*, but a small overall overhead if
|
|
||||||
the set is very sparse.
|
|
||||||
|
|
||||||
The downside is that many operations are relatively slow because the
|
|
||||||
linked list has to be traversed to test membership (i.e. member_p/
|
|
||||||
add_member/remove_member). To improve the performance of this set
|
|
||||||
representation, the last accessed element and its index are cached.
|
|
||||||
For membership tests on members close to recently accessed members,
|
|
||||||
the cached last element improves membership test to a constant-time
|
|
||||||
operation.
|
|
||||||
|
|
||||||
The following operations can always be performed in O(1) time:
|
|
||||||
|
|
||||||
* clear : bitmap_clear
|
|
||||||
* choose_one : (not implemented, but could be
|
|
||||||
implemented in constant time)
|
|
||||||
|
|
||||||
The following operations can be performed in O(E) time worst-case (with
|
|
||||||
E the number of elements in the linked list), but in O(1) time with a
|
|
||||||
suitable access patterns:
|
|
||||||
|
|
||||||
* member_p : bitmap_bit_p
|
|
||||||
* add_member : bitmap_set_bit
|
|
||||||
* remove_member : bitmap_clear_bit
|
|
||||||
|
|
||||||
The following operations can be performed in O(E) time:
|
|
||||||
|
|
||||||
* cardinality : bitmap_count_bits
|
|
||||||
* set_size : bitmap_last_set_bit (but this could
|
|
||||||
in constant time with a pointer to
|
|
||||||
the last element in the chain)
|
|
||||||
|
|
||||||
Additionally, the linked-list sparse set representation supports
|
|
||||||
enumeration of the members in O(E) time:
|
|
||||||
|
|
||||||
* forall : EXECUTE_IF_SET_IN_BITMAP
|
|
||||||
* set_copy : bitmap_copy
|
|
||||||
* set_intersection : bitmap_intersect_p /
|
|
||||||
bitmap_and / bitmap_and_into /
|
|
||||||
EXECUTE_IF_AND_IN_BITMAP
|
|
||||||
* set_union : bitmap_ior / bitmap_ior_into
|
|
||||||
* set_difference : bitmap_intersect_compl_p /
|
|
||||||
bitmap_and_comp / bitmap_and_comp_into /
|
|
||||||
EXECUTE_IF_AND_COMPL_IN_BITMAP
|
|
||||||
* set_disjuction : bitmap_xor_comp / bitmap_xor_comp_into
|
|
||||||
* set_compare : bitmap_equal_p
|
|
||||||
|
|
||||||
Some operations on 3 sets that occur frequently in in data flow problems
|
|
||||||
are also implemented:
|
|
||||||
|
|
||||||
* A | (B & C) : bitmap_ior_and_into
|
|
||||||
* A | (B & ~C) : bitmap_ior_and_compl /
|
|
||||||
bitmap_ior_and_compl_into
|
|
||||||
|
|
||||||
The storage requirements for linked-list sparse sets are O(E), with E->N
|
|
||||||
in the worst case (a sparse set with large distances between the values
|
|
||||||
of the set members).
|
|
||||||
|
|
||||||
The linked-list set representation works well for problems involving very
|
|
||||||
sparse sets. The canonical example in GCC is, of course, the "set of
|
|
||||||
sets" for some CFG-based data flow problems (liveness analysis, dominance
|
|
||||||
frontiers, etc.).
|
|
||||||
|
|
||||||
This representation also works well for data flow problems where the size
|
|
||||||
of the set may grow dynamically, but care must be taken that the member_p,
|
|
||||||
add_member, and remove_member operations occur with a suitable access
|
|
||||||
pattern.
|
|
||||||
|
|
||||||
For random-access sets with a known, relatively small universe size, the
|
|
||||||
SparseSet or simple bitmap representations may be more efficient than a
|
|
||||||
linked-list set. For random-access sets of unknown universe, a hash table
|
|
||||||
or a balanced binary tree representation is likely to be a more suitable
|
|
||||||
choice.
|
|
||||||
|
|
||||||
Traversing linked lists is usually cache-unfriendly, even with the last
|
|
||||||
accessed element cached.
|
|
||||||
|
|
||||||
Cache performance can be improved by keeping the elements in the set
|
|
||||||
grouped together in memory, using a dedicated obstack for a set (or group
|
|
||||||
of related sets). Elements allocated on obstacks are released to a
|
|
||||||
free-list and taken off the free list. If multiple sets are allocated on
|
|
||||||
the same obstack, elements freed from one set may be re-used for one of
|
|
||||||
the other sets. This usually helps avoid cache misses.
|
|
||||||
|
|
||||||
A single free-list is used for all sets allocated in GGC space. This is
|
|
||||||
bad for persistent sets, so persistent sets should be allocated on an
|
|
||||||
obstack whenever possible. */
|
|
||||||
|
|
||||||
#include "hashtab.h"
|
|
||||||
#include "statistics.h"
|
|
||||||
#include "obstack.h"
|
|
||||||
|
|
||||||
/* Fundamental storage type for bitmap. */
|
|
||||||
|
|
||||||
typedef unsigned long BITMAP_WORD;
|
|
||||||
/* BITMAP_WORD_BITS needs to be unsigned, but cannot contain casts as
|
|
||||||
it is used in preprocessor directives -- hence the 1u. */
|
|
||||||
#define BITMAP_WORD_BITS (CHAR_BIT * SIZEOF_LONG * 1u)
|
|
||||||
|
|
||||||
/* Number of words to use for each element in the linked list. */
|
|
||||||
|
|
||||||
#ifndef BITMAP_ELEMENT_WORDS
|
|
||||||
#define BITMAP_ELEMENT_WORDS ((128 + BITMAP_WORD_BITS - 1) / BITMAP_WORD_BITS)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Number of bits in each actual element of a bitmap. */
|
|
||||||
|
|
||||||
#define BITMAP_ELEMENT_ALL_BITS (BITMAP_ELEMENT_WORDS * BITMAP_WORD_BITS)
|
|
||||||
|
|
||||||
/* Obstack for allocating bitmaps and elements from. */
|
|
||||||
typedef struct GTY (()) bitmap_obstack {
|
|
||||||
struct bitmap_element_def *elements;
|
|
||||||
struct bitmap_head_def *heads;
|
|
||||||
struct obstack GTY ((skip)) obstack;
|
|
||||||
} bitmap_obstack;
|
|
||||||
|
|
||||||
/* Bitmap set element. We use a linked list to hold only the bits that
|
|
||||||
are set. This allows for use to grow the bitset dynamically without
|
|
||||||
having to realloc and copy a giant bit array.
|
|
||||||
|
|
||||||
The free list is implemented as a list of lists. There is one
|
|
||||||
outer list connected together by prev fields. Each element of that
|
|
||||||
outer is an inner list (that may consist only of the outer list
|
|
||||||
element) that are connected by the next fields. The prev pointer
|
|
||||||
is undefined for interior elements. This allows
|
|
||||||
bitmap_elt_clear_from to be implemented in unit time rather than
|
|
||||||
linear in the number of elements to be freed. */
|
|
||||||
|
|
||||||
typedef struct GTY((chain_next ("%h.next"), chain_prev ("%h.prev"))) bitmap_element_def {
|
|
||||||
struct bitmap_element_def *next; /* Next element. */
|
|
||||||
struct bitmap_element_def *prev; /* Previous element. */
|
|
||||||
unsigned int indx; /* regno/BITMAP_ELEMENT_ALL_BITS. */
|
|
||||||
BITMAP_WORD bits[BITMAP_ELEMENT_WORDS]; /* Bits that are set. */
|
|
||||||
} bitmap_element;
|
|
||||||
|
|
||||||
/* Head of bitmap linked list. The 'current' member points to something
|
|
||||||
already pointed to by the chain started by first, so GTY((skip)) it. */
|
|
||||||
|
|
||||||
typedef struct GTY(()) bitmap_head_def {
|
|
||||||
unsigned int indx; /* Index of last element looked at. */
|
|
||||||
unsigned int descriptor_id; /* Unique identifier for the allocation
|
|
||||||
site of this bitmap, for detailed
|
|
||||||
statistics gathering. */
|
|
||||||
bitmap_element *first; /* First element in linked list. */
|
|
||||||
bitmap_element * GTY((skip(""))) current; /* Last element looked at. */
|
|
||||||
bitmap_obstack *obstack; /* Obstack to allocate elements from.
|
|
||||||
If NULL, then use GGC allocation. */
|
|
||||||
} bitmap_head;
|
|
||||||
|
|
||||||
/* Global data */
|
|
||||||
extern bitmap_element bitmap_zero_bits; /* Zero bitmap element */
|
|
||||||
extern bitmap_obstack bitmap_default_obstack; /* Default bitmap obstack */
|
|
||||||
|
|
||||||
/* Clear a bitmap by freeing up the linked list. */
|
|
||||||
extern void bitmap_clear (bitmap);
|
|
||||||
|
|
||||||
/* Copy a bitmap to another bitmap. */
|
|
||||||
extern void bitmap_copy (bitmap, const_bitmap);
|
|
||||||
|
|
||||||
/* True if two bitmaps are identical. */
|
|
||||||
extern bool bitmap_equal_p (const_bitmap, const_bitmap);
|
|
||||||
|
|
||||||
/* True if the bitmaps intersect (their AND is non-empty). */
|
|
||||||
extern bool bitmap_intersect_p (const_bitmap, const_bitmap);
|
|
||||||
|
|
||||||
/* True if the complement of the second intersects the first (their
|
|
||||||
AND_COMPL is non-empty). */
|
|
||||||
extern bool bitmap_intersect_compl_p (const_bitmap, const_bitmap);
|
|
||||||
|
|
||||||
/* True if MAP is an empty bitmap. */
|
|
||||||
inline bool bitmap_empty_p (const_bitmap map)
|
|
||||||
{
|
|
||||||
return !map->first;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* True if the bitmap has only a single bit set. */
|
|
||||||
extern bool bitmap_single_bit_set_p (const_bitmap);
|
|
||||||
|
|
||||||
/* Count the number of bits set in the bitmap. */
|
|
||||||
extern unsigned long bitmap_count_bits (const_bitmap);
|
|
||||||
|
|
||||||
/* Boolean operations on bitmaps. The _into variants are two operand
|
|
||||||
versions that modify the first source operand. The other variants
|
|
||||||
are three operand versions that to not destroy the source bitmaps.
|
|
||||||
The operations supported are &, & ~, |, ^. */
|
|
||||||
extern void bitmap_and (bitmap, const_bitmap, const_bitmap);
|
|
||||||
extern bool bitmap_and_into (bitmap, const_bitmap);
|
|
||||||
extern bool bitmap_and_compl (bitmap, const_bitmap, const_bitmap);
|
|
||||||
extern bool bitmap_and_compl_into (bitmap, const_bitmap);
|
|
||||||
#define bitmap_compl_and(DST, A, B) bitmap_and_compl (DST, B, A)
|
|
||||||
extern void bitmap_compl_and_into (bitmap, const_bitmap);
|
|
||||||
extern void bitmap_clear_range (bitmap, unsigned int, unsigned int);
|
|
||||||
extern void bitmap_set_range (bitmap, unsigned int, unsigned int);
|
|
||||||
extern bool bitmap_ior (bitmap, const_bitmap, const_bitmap);
|
|
||||||
extern bool bitmap_ior_into (bitmap, const_bitmap);
|
|
||||||
extern void bitmap_xor (bitmap, const_bitmap, const_bitmap);
|
|
||||||
extern void bitmap_xor_into (bitmap, const_bitmap);
|
|
||||||
|
|
||||||
/* DST = A | (B & C). Return true if DST changes. */
|
|
||||||
extern bool bitmap_ior_and_into (bitmap DST, const_bitmap B, const_bitmap C);
|
|
||||||
/* DST = A | (B & ~C). Return true if DST changes. */
|
|
||||||
extern bool bitmap_ior_and_compl (bitmap DST, const_bitmap A,
|
|
||||||
const_bitmap B, const_bitmap C);
|
|
||||||
/* A |= (B & ~C). Return true if A changes. */
|
|
||||||
extern bool bitmap_ior_and_compl_into (bitmap A,
|
|
||||||
const_bitmap B, const_bitmap C);
|
|
||||||
|
|
||||||
/* Clear a single bit in a bitmap. Return true if the bit changed. */
|
|
||||||
extern bool bitmap_clear_bit (bitmap, int);
|
|
||||||
|
|
||||||
/* Set a single bit in a bitmap. Return true if the bit changed. */
|
|
||||||
extern bool bitmap_set_bit (bitmap, int);
|
|
||||||
|
|
||||||
/* Return true if a register is set in a register set. */
|
|
||||||
extern int bitmap_bit_p (bitmap, int);
|
|
||||||
|
|
||||||
/* Debug functions to print a bitmap linked list. */
|
|
||||||
extern void debug_bitmap (const_bitmap);
|
|
||||||
extern void debug_bitmap_file (FILE *, const_bitmap);
|
|
||||||
|
|
||||||
/* Print a bitmap. */
|
|
||||||
extern void bitmap_print (FILE *, const_bitmap, const char *, const char *);
|
|
||||||
|
|
||||||
/* Initialize and release a bitmap obstack. */
|
|
||||||
extern void bitmap_obstack_initialize (bitmap_obstack *);
|
|
||||||
extern void bitmap_obstack_release (bitmap_obstack *);
|
|
||||||
extern void bitmap_register (bitmap MEM_STAT_DECL);
|
|
||||||
extern void dump_bitmap_statistics (void);
|
|
||||||
|
|
||||||
/* Initialize a bitmap header. OBSTACK indicates the bitmap obstack
|
|
||||||
to allocate from, NULL for GC'd bitmap. */
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
bitmap_initialize_stat (bitmap head, bitmap_obstack *obstack MEM_STAT_DECL)
|
|
||||||
{
|
|
||||||
head->first = head->current = NULL;
|
|
||||||
head->obstack = obstack;
|
|
||||||
if (GATHER_STATISTICS)
|
|
||||||
bitmap_register (head PASS_MEM_STAT);
|
|
||||||
}
|
|
||||||
#define bitmap_initialize(h,o) bitmap_initialize_stat (h,o MEM_STAT_INFO)
|
|
||||||
|
|
||||||
/* Allocate and free bitmaps from obstack, malloc and gc'd memory. */
|
|
||||||
extern bitmap bitmap_obstack_alloc_stat (bitmap_obstack *obstack MEM_STAT_DECL);
|
|
||||||
#define bitmap_obstack_alloc(t) bitmap_obstack_alloc_stat (t MEM_STAT_INFO)
|
|
||||||
extern bitmap bitmap_gc_alloc_stat (ALONE_MEM_STAT_DECL);
|
|
||||||
#define bitmap_gc_alloc() bitmap_gc_alloc_stat (ALONE_MEM_STAT_INFO)
|
|
||||||
extern void bitmap_obstack_free (bitmap);
|
|
||||||
|
|
||||||
/* A few compatibility/functions macros for compatibility with sbitmaps */
|
|
||||||
inline void dump_bitmap (FILE *file, const_bitmap map)
|
|
||||||
{
|
|
||||||
bitmap_print (file, map, "", "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
extern unsigned bitmap_first_set_bit (const_bitmap);
|
|
||||||
extern unsigned bitmap_last_set_bit (const_bitmap);
|
|
||||||
|
|
||||||
/* Compute bitmap hash (for purposes of hashing etc.) */
|
|
||||||
extern hashval_t bitmap_hash(const_bitmap);
|
|
||||||
|
|
||||||
/* Allocate a bitmap from a bit obstack. */
|
|
||||||
#define BITMAP_ALLOC(OBSTACK) bitmap_obstack_alloc (OBSTACK)
|
|
||||||
|
|
||||||
/* Allocate a gc'd bitmap. */
|
|
||||||
#define BITMAP_GGC_ALLOC() bitmap_gc_alloc ()
|
|
||||||
|
|
||||||
/* Do any cleanup needed on a bitmap when it is no longer used. */
|
|
||||||
#define BITMAP_FREE(BITMAP) \
|
|
||||||
((void) (bitmap_obstack_free ((bitmap) BITMAP), (BITMAP) = (bitmap) NULL))
|
|
||||||
|
|
||||||
/* Iterator for bitmaps. */
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
/* Pointer to the current bitmap element. */
|
|
||||||
bitmap_element *elt1;
|
|
||||||
|
|
||||||
/* Pointer to 2nd bitmap element when two are involved. */
|
|
||||||
bitmap_element *elt2;
|
|
||||||
|
|
||||||
/* Word within the current element. */
|
|
||||||
unsigned word_no;
|
|
||||||
|
|
||||||
/* Contents of the actually processed word. When finding next bit
|
|
||||||
it is shifted right, so that the actual bit is always the least
|
|
||||||
significant bit of ACTUAL. */
|
|
||||||
BITMAP_WORD bits;
|
|
||||||
} bitmap_iterator;
|
|
||||||
|
|
||||||
/* Initialize a single bitmap iterator. START_BIT is the first bit to
|
|
||||||
iterate from. */
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
bmp_iter_set_init (bitmap_iterator *bi, const_bitmap map,
|
|
||||||
unsigned start_bit, unsigned *bit_no)
|
|
||||||
{
|
|
||||||
bi->elt1 = map->first;
|
|
||||||
bi->elt2 = NULL;
|
|
||||||
|
|
||||||
/* Advance elt1 until it is not before the block containing start_bit. */
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (!bi->elt1)
|
|
||||||
{
|
|
||||||
bi->elt1 = &bitmap_zero_bits;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bi->elt1->indx >= start_bit / BITMAP_ELEMENT_ALL_BITS)
|
|
||||||
break;
|
|
||||||
bi->elt1 = bi->elt1->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We might have gone past the start bit, so reinitialize it. */
|
|
||||||
if (bi->elt1->indx != start_bit / BITMAP_ELEMENT_ALL_BITS)
|
|
||||||
start_bit = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
|
||||||
|
|
||||||
/* Initialize for what is now start_bit. */
|
|
||||||
bi->word_no = start_bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
|
|
||||||
bi->bits = bi->elt1->bits[bi->word_no];
|
|
||||||
bi->bits >>= start_bit % BITMAP_WORD_BITS;
|
|
||||||
|
|
||||||
/* If this word is zero, we must make sure we're not pointing at the
|
|
||||||
first bit, otherwise our incrementing to the next word boundary
|
|
||||||
will fail. It won't matter if this increment moves us into the
|
|
||||||
next word. */
|
|
||||||
start_bit += !bi->bits;
|
|
||||||
|
|
||||||
*bit_no = start_bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize an iterator to iterate over the intersection of two
|
|
||||||
bitmaps. START_BIT is the bit to commence from. */
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
bmp_iter_and_init (bitmap_iterator *bi, const_bitmap map1, const_bitmap map2,
|
|
||||||
unsigned start_bit, unsigned *bit_no)
|
|
||||||
{
|
|
||||||
bi->elt1 = map1->first;
|
|
||||||
bi->elt2 = map2->first;
|
|
||||||
|
|
||||||
/* Advance elt1 until it is not before the block containing
|
|
||||||
start_bit. */
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (!bi->elt1)
|
|
||||||
{
|
|
||||||
bi->elt2 = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bi->elt1->indx >= start_bit / BITMAP_ELEMENT_ALL_BITS)
|
|
||||||
break;
|
|
||||||
bi->elt1 = bi->elt1->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance elt2 until it is not before elt1. */
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (!bi->elt2)
|
|
||||||
{
|
|
||||||
bi->elt1 = bi->elt2 = &bitmap_zero_bits;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bi->elt2->indx >= bi->elt1->indx)
|
|
||||||
break;
|
|
||||||
bi->elt2 = bi->elt2->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we're at the same index, then we have some intersecting bits. */
|
|
||||||
if (bi->elt1->indx == bi->elt2->indx)
|
|
||||||
{
|
|
||||||
/* We might have advanced beyond the start_bit, so reinitialize
|
|
||||||
for that. */
|
|
||||||
if (bi->elt1->indx != start_bit / BITMAP_ELEMENT_ALL_BITS)
|
|
||||||
start_bit = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
|
||||||
|
|
||||||
bi->word_no = start_bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
|
|
||||||
bi->bits = bi->elt1->bits[bi->word_no] & bi->elt2->bits[bi->word_no];
|
|
||||||
bi->bits >>= start_bit % BITMAP_WORD_BITS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Otherwise we must immediately advance elt1, so initialize for
|
|
||||||
that. */
|
|
||||||
bi->word_no = BITMAP_ELEMENT_WORDS - 1;
|
|
||||||
bi->bits = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If this word is zero, we must make sure we're not pointing at the
|
|
||||||
first bit, otherwise our incrementing to the next word boundary
|
|
||||||
will fail. It won't matter if this increment moves us into the
|
|
||||||
next word. */
|
|
||||||
start_bit += !bi->bits;
|
|
||||||
|
|
||||||
*bit_no = start_bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize an iterator to iterate over the bits in MAP1 & ~MAP2.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
bmp_iter_and_compl_init (bitmap_iterator *bi,
|
|
||||||
const_bitmap map1, const_bitmap map2,
|
|
||||||
unsigned start_bit, unsigned *bit_no)
|
|
||||||
{
|
|
||||||
bi->elt1 = map1->first;
|
|
||||||
bi->elt2 = map2->first;
|
|
||||||
|
|
||||||
/* Advance elt1 until it is not before the block containing start_bit. */
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (!bi->elt1)
|
|
||||||
{
|
|
||||||
bi->elt1 = &bitmap_zero_bits;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bi->elt1->indx >= start_bit / BITMAP_ELEMENT_ALL_BITS)
|
|
||||||
break;
|
|
||||||
bi->elt1 = bi->elt1->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance elt2 until it is not before elt1. */
|
|
||||||
while (bi->elt2 && bi->elt2->indx < bi->elt1->indx)
|
|
||||||
bi->elt2 = bi->elt2->next;
|
|
||||||
|
|
||||||
/* We might have advanced beyond the start_bit, so reinitialize for
|
|
||||||
that. */
|
|
||||||
if (bi->elt1->indx != start_bit / BITMAP_ELEMENT_ALL_BITS)
|
|
||||||
start_bit = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
|
||||||
|
|
||||||
bi->word_no = start_bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
|
|
||||||
bi->bits = bi->elt1->bits[bi->word_no];
|
|
||||||
if (bi->elt2 && bi->elt1->indx == bi->elt2->indx)
|
|
||||||
bi->bits &= ~bi->elt2->bits[bi->word_no];
|
|
||||||
bi->bits >>= start_bit % BITMAP_WORD_BITS;
|
|
||||||
|
|
||||||
/* If this word is zero, we must make sure we're not pointing at the
|
|
||||||
first bit, otherwise our incrementing to the next word boundary
|
|
||||||
will fail. It won't matter if this increment moves us into the
|
|
||||||
next word. */
|
|
||||||
start_bit += !bi->bits;
|
|
||||||
|
|
||||||
*bit_no = start_bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance to the next bit in BI. We don't advance to the next
|
|
||||||
nonzero bit yet. */
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
bmp_iter_next (bitmap_iterator *bi, unsigned *bit_no)
|
|
||||||
{
|
|
||||||
bi->bits >>= 1;
|
|
||||||
*bit_no += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance to first set bit in BI. */
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
bmp_iter_next_bit (bitmap_iterator * bi, unsigned *bit_no)
|
|
||||||
{
|
|
||||||
#if (GCC_VERSION >= 3004)
|
|
||||||
{
|
|
||||||
unsigned int n = __builtin_ctzl (bi->bits);
|
|
||||||
gcc_assert (sizeof (unsigned long) == sizeof (BITMAP_WORD));
|
|
||||||
bi->bits >>= n;
|
|
||||||
*bit_no += n;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
while (!(bi->bits & 1))
|
|
||||||
{
|
|
||||||
bi->bits >>= 1;
|
|
||||||
*bit_no += 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance to the next nonzero bit of a single bitmap, we will have
|
|
||||||
already advanced past the just iterated bit. Return true if there
|
|
||||||
is a bit to iterate. */
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
bmp_iter_set (bitmap_iterator *bi, unsigned *bit_no)
|
|
||||||
{
|
|
||||||
/* If our current word is nonzero, it contains the bit we want. */
|
|
||||||
if (bi->bits)
|
|
||||||
{
|
|
||||||
next_bit:
|
|
||||||
bmp_iter_next_bit (bi, bit_no);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Round up to the word boundary. We might have just iterated past
|
|
||||||
the end of the last word, hence the -1. It is not possible for
|
|
||||||
bit_no to point at the beginning of the now last word. */
|
|
||||||
*bit_no = ((*bit_no + BITMAP_WORD_BITS - 1)
|
|
||||||
/ BITMAP_WORD_BITS * BITMAP_WORD_BITS);
|
|
||||||
bi->word_no++;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
/* Find the next nonzero word in this elt. */
|
|
||||||
while (bi->word_no != BITMAP_ELEMENT_WORDS)
|
|
||||||
{
|
|
||||||
bi->bits = bi->elt1->bits[bi->word_no];
|
|
||||||
if (bi->bits)
|
|
||||||
goto next_bit;
|
|
||||||
*bit_no += BITMAP_WORD_BITS;
|
|
||||||
bi->word_no++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance to the next element. */
|
|
||||||
bi->elt1 = bi->elt1->next;
|
|
||||||
if (!bi->elt1)
|
|
||||||
return false;
|
|
||||||
*bit_no = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
|
||||||
bi->word_no = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance to the next nonzero bit of an intersecting pair of
|
|
||||||
bitmaps. We will have already advanced past the just iterated bit.
|
|
||||||
Return true if there is a bit to iterate. */
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
bmp_iter_and (bitmap_iterator *bi, unsigned *bit_no)
|
|
||||||
{
|
|
||||||
/* If our current word is nonzero, it contains the bit we want. */
|
|
||||||
if (bi->bits)
|
|
||||||
{
|
|
||||||
next_bit:
|
|
||||||
bmp_iter_next_bit (bi, bit_no);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Round up to the word boundary. We might have just iterated past
|
|
||||||
the end of the last word, hence the -1. It is not possible for
|
|
||||||
bit_no to point at the beginning of the now last word. */
|
|
||||||
*bit_no = ((*bit_no + BITMAP_WORD_BITS - 1)
|
|
||||||
/ BITMAP_WORD_BITS * BITMAP_WORD_BITS);
|
|
||||||
bi->word_no++;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
/* Find the next nonzero word in this elt. */
|
|
||||||
while (bi->word_no != BITMAP_ELEMENT_WORDS)
|
|
||||||
{
|
|
||||||
bi->bits = bi->elt1->bits[bi->word_no] & bi->elt2->bits[bi->word_no];
|
|
||||||
if (bi->bits)
|
|
||||||
goto next_bit;
|
|
||||||
*bit_no += BITMAP_WORD_BITS;
|
|
||||||
bi->word_no++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance to the next identical element. */
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/* Advance elt1 while it is less than elt2. We always want
|
|
||||||
to advance one elt. */
|
|
||||||
do
|
|
||||||
{
|
|
||||||
bi->elt1 = bi->elt1->next;
|
|
||||||
if (!bi->elt1)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
while (bi->elt1->indx < bi->elt2->indx);
|
|
||||||
|
|
||||||
/* Advance elt2 to be no less than elt1. This might not
|
|
||||||
advance. */
|
|
||||||
while (bi->elt2->indx < bi->elt1->indx)
|
|
||||||
{
|
|
||||||
bi->elt2 = bi->elt2->next;
|
|
||||||
if (!bi->elt2)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (bi->elt1->indx != bi->elt2->indx);
|
|
||||||
|
|
||||||
*bit_no = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
|
||||||
bi->word_no = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance to the next nonzero bit in the intersection of
|
|
||||||
complemented bitmaps. We will have already advanced past the just
|
|
||||||
iterated bit. */
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
bmp_iter_and_compl (bitmap_iterator *bi, unsigned *bit_no)
|
|
||||||
{
|
|
||||||
/* If our current word is nonzero, it contains the bit we want. */
|
|
||||||
if (bi->bits)
|
|
||||||
{
|
|
||||||
next_bit:
|
|
||||||
bmp_iter_next_bit (bi, bit_no);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Round up to the word boundary. We might have just iterated past
|
|
||||||
the end of the last word, hence the -1. It is not possible for
|
|
||||||
bit_no to point at the beginning of the now last word. */
|
|
||||||
*bit_no = ((*bit_no + BITMAP_WORD_BITS - 1)
|
|
||||||
/ BITMAP_WORD_BITS * BITMAP_WORD_BITS);
|
|
||||||
bi->word_no++;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
/* Find the next nonzero word in this elt. */
|
|
||||||
while (bi->word_no != BITMAP_ELEMENT_WORDS)
|
|
||||||
{
|
|
||||||
bi->bits = bi->elt1->bits[bi->word_no];
|
|
||||||
if (bi->elt2 && bi->elt2->indx == bi->elt1->indx)
|
|
||||||
bi->bits &= ~bi->elt2->bits[bi->word_no];
|
|
||||||
if (bi->bits)
|
|
||||||
goto next_bit;
|
|
||||||
*bit_no += BITMAP_WORD_BITS;
|
|
||||||
bi->word_no++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance to the next element of elt1. */
|
|
||||||
bi->elt1 = bi->elt1->next;
|
|
||||||
if (!bi->elt1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* Advance elt2 until it is no less than elt1. */
|
|
||||||
while (bi->elt2 && bi->elt2->indx < bi->elt1->indx)
|
|
||||||
bi->elt2 = bi->elt2->next;
|
|
||||||
|
|
||||||
*bit_no = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
|
||||||
bi->word_no = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop over all bits set in BITMAP, starting with MIN and setting
|
|
||||||
BITNUM to the bit number. ITER is a bitmap iterator. BITNUM
|
|
||||||
should be treated as a read-only variable as it contains loop
|
|
||||||
state. */
|
|
||||||
|
|
||||||
#ifndef EXECUTE_IF_SET_IN_BITMAP
|
|
||||||
/* See sbitmap.h for the other definition of EXECUTE_IF_SET_IN_BITMAP. */
|
|
||||||
#define EXECUTE_IF_SET_IN_BITMAP(BITMAP, MIN, BITNUM, ITER) \
|
|
||||||
for (bmp_iter_set_init (&(ITER), (BITMAP), (MIN), &(BITNUM)); \
|
|
||||||
bmp_iter_set (&(ITER), &(BITNUM)); \
|
|
||||||
bmp_iter_next (&(ITER), &(BITNUM)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Loop over all the bits set in BITMAP1 & BITMAP2, starting with MIN
|
|
||||||
and setting BITNUM to the bit number. ITER is a bitmap iterator.
|
|
||||||
BITNUM should be treated as a read-only variable as it contains
|
|
||||||
loop state. */
|
|
||||||
|
|
||||||
#define EXECUTE_IF_AND_IN_BITMAP(BITMAP1, BITMAP2, MIN, BITNUM, ITER) \
|
|
||||||
for (bmp_iter_and_init (&(ITER), (BITMAP1), (BITMAP2), (MIN), \
|
|
||||||
&(BITNUM)); \
|
|
||||||
bmp_iter_and (&(ITER), &(BITNUM)); \
|
|
||||||
bmp_iter_next (&(ITER), &(BITNUM)))
|
|
||||||
|
|
||||||
/* Loop over all the bits set in BITMAP1 & ~BITMAP2, starting with MIN
|
|
||||||
and setting BITNUM to the bit number. ITER is a bitmap iterator.
|
|
||||||
BITNUM should be treated as a read-only variable as it contains
|
|
||||||
loop state. */
|
|
||||||
|
|
||||||
#define EXECUTE_IF_AND_COMPL_IN_BITMAP(BITMAP1, BITMAP2, MIN, BITNUM, ITER) \
|
|
||||||
for (bmp_iter_and_compl_init (&(ITER), (BITMAP1), (BITMAP2), (MIN), \
|
|
||||||
&(BITNUM)); \
|
|
||||||
bmp_iter_and_compl (&(ITER), &(BITNUM)); \
|
|
||||||
bmp_iter_next (&(ITER), &(BITNUM)))
|
|
||||||
|
|
||||||
#endif /* GCC_BITMAP_H */
|
|
@ -1,842 +0,0 @@
|
|||||||
/* This file contains the definitions and documentation for the
|
|
||||||
builtins used in the GNU compiler.
|
|
||||||
Copyright (C) 2000-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Before including this file, you should define a macro:
|
|
||||||
|
|
||||||
DEF_BUILTIN (ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P,
|
|
||||||
FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT, COND)
|
|
||||||
|
|
||||||
This macro will be called once for each builtin function. The
|
|
||||||
ENUM will be of type `enum built_in_function', and will indicate
|
|
||||||
which builtin function is being processed. The NAME of the builtin
|
|
||||||
function (which will always start with `__builtin_') is a string
|
|
||||||
literal. The CLASS is of type `enum built_in_class' and indicates
|
|
||||||
what kind of builtin is being processed.
|
|
||||||
|
|
||||||
Some builtins are actually two separate functions. For example,
|
|
||||||
for `strcmp' there are two builtin functions; `__builtin_strcmp'
|
|
||||||
and `strcmp' itself. Both behave identically. Other builtins
|
|
||||||
define only the `__builtin' variant. If BOTH_P is TRUE, then this
|
|
||||||
builtin has both variants; otherwise, it is has only the first
|
|
||||||
variant.
|
|
||||||
|
|
||||||
TYPE indicates the type of the function. The symbols correspond to
|
|
||||||
enumerals from builtin-types.def. If BOTH_P is true, then LIBTYPE
|
|
||||||
is the type of the non-`__builtin_' variant. Otherwise, LIBTYPE
|
|
||||||
should be ignored.
|
|
||||||
|
|
||||||
If FALLBACK_P is true then, if for some reason, the compiler cannot
|
|
||||||
expand the builtin function directly, it will call the
|
|
||||||
corresponding library function (which does not have the
|
|
||||||
`__builtin_' prefix.
|
|
||||||
|
|
||||||
If NONANSI_P is true, then the non-`__builtin_' variant is not an
|
|
||||||
ANSI/ISO library function, and so we should pretend it does not
|
|
||||||
exist when compiling in ANSI conformant mode.
|
|
||||||
|
|
||||||
ATTRs is an attribute list as defined in builtin-attrs.def that
|
|
||||||
describes the attributes of this builtin function.
|
|
||||||
|
|
||||||
IMPLICIT specifies condition when the builtin can be produced by
|
|
||||||
compiler. For instance C90 reserves floorf function, but does not
|
|
||||||
define it's meaning. When user uses floorf we may assume that the
|
|
||||||
floorf has the meaning we expect, but we can't produce floorf by
|
|
||||||
simplifying floor((double)float) since the runtime need not implement
|
|
||||||
it.
|
|
||||||
|
|
||||||
The builtins is registered only if COND is true. */
|
|
||||||
|
|
||||||
/* A GCC builtin (like __builtin_saveregs) is provided by the
|
|
||||||
compiler, but does not correspond to a function in the standard
|
|
||||||
library. */
|
|
||||||
#undef DEF_GCC_BUILTIN
|
|
||||||
#define DEF_GCC_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
|
||||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, BT_LAST, \
|
|
||||||
false, false, false, ATTRS, true, true)
|
|
||||||
|
|
||||||
/* Like DEF_GCC_BUILTIN, except we don't prepend "__builtin_". */
|
|
||||||
#undef DEF_SYNC_BUILTIN
|
|
||||||
#define DEF_SYNC_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
|
||||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, BT_LAST, \
|
|
||||||
false, false, false, ATTRS, true, true)
|
|
||||||
|
|
||||||
/* A library builtin (like __builtin_strchr) is a builtin equivalent
|
|
||||||
of an ANSI/ISO standard library function. In addition to the
|
|
||||||
`__builtin' version, we will create an ordinary version (e.g,
|
|
||||||
`strchr') as well. If we cannot compute the answer using the
|
|
||||||
builtin function, we will fall back to the standard library
|
|
||||||
version. */
|
|
||||||
#undef DEF_LIB_BUILTIN
|
|
||||||
#define DEF_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
|
||||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
|
||||||
true, true, false, ATTRS, true, true)
|
|
||||||
|
|
||||||
/* Like DEF_LIB_BUILTIN, except that the function is not one that is
|
|
||||||
specified by ANSI/ISO C. So, when we're being fully conformant we
|
|
||||||
ignore the version of these builtins that does not begin with
|
|
||||||
__builtin. */
|
|
||||||
#undef DEF_EXT_LIB_BUILTIN
|
|
||||||
#define DEF_EXT_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
|
||||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
|
||||||
true, true, true, ATTRS, false, true)
|
|
||||||
|
|
||||||
/* Like DEF_LIB_BUILTIN, except that the function is only a part of
|
|
||||||
the standard in C94 or above. */
|
|
||||||
#undef DEF_C94_BUILTIN
|
|
||||||
#define DEF_C94_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
|
||||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
|
||||||
true, true, !flag_isoc94, ATTRS, TARGET_C99_FUNCTIONS, true)
|
|
||||||
|
|
||||||
/* Like DEF_LIB_BUILTIN, except that the function is only a part of
|
|
||||||
the standard in C99 or above. */
|
|
||||||
#undef DEF_C99_BUILTIN
|
|
||||||
#define DEF_C99_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
|
||||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
|
||||||
true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
|
|
||||||
|
|
||||||
/* Builtin that is specified by C99 and C90 reserve the name for future use.
|
|
||||||
We can still recognize the builtin in C90 mode but we can't produce it
|
|
||||||
implicitly. */
|
|
||||||
#undef DEF_C99_C90RES_BUILTIN
|
|
||||||
#define DEF_C99_C90RES_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
|
||||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
|
||||||
true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
|
|
||||||
|
|
||||||
/* Builtin that C99 reserve the name for future use. We can still recognize
|
|
||||||
the builtin in C99 mode but we can't produce it implicitly. */
|
|
||||||
#undef DEF_EXT_C99RES_BUILTIN
|
|
||||||
#define DEF_EXT_C99RES_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
|
||||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
|
||||||
true, true, true, ATTRS, false, true)
|
|
||||||
|
|
||||||
/* Allocate the enum and the name for a builtin, but do not actually
|
|
||||||
define it here at all. */
|
|
||||||
#undef DEF_BUILTIN_STUB
|
|
||||||
#define DEF_BUILTIN_STUB(ENUM, NAME) \
|
|
||||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, BT_LAST, BT_LAST, false, false, \
|
|
||||||
false, ATTR_LAST, false, false)
|
|
||||||
|
|
||||||
/* Builtin used by the implementation of GNU OpenMP. None of these are
|
|
||||||
actually implemented in the compiler; they're all in libgomp. */
|
|
||||||
#undef DEF_GOMP_BUILTIN
|
|
||||||
#define DEF_GOMP_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
|
||||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
|
||||||
false, true, true, ATTRS, false, \
|
|
||||||
(flag_openmp || flag_tree_parallelize_loops))
|
|
||||||
|
|
||||||
/* Builtin used by the implementation of GNU TM. These
|
|
||||||
functions are mapped to the actual implementation of the STM library. */
|
|
||||||
#undef DEF_TM_BUILTIN
|
|
||||||
#define DEF_TM_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
|
||||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
|
||||||
true, true, true, ATTRS, false, flag_tm)
|
|
||||||
|
|
||||||
/* Builtin used by the implementation of libsanitizer. These
|
|
||||||
functions are mapped to the actual implementation of the
|
|
||||||
libtsan library. */
|
|
||||||
#undef DEF_SANITIZER_BUILTIN
|
|
||||||
#define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
|
||||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
|
||||||
true, true, true, ATTRS, true, \
|
|
||||||
(flag_asan || flag_tsan))
|
|
||||||
|
|
||||||
/* Define an attribute list for math functions that are normally
|
|
||||||
"impure" because some of them may write into global memory for
|
|
||||||
`errno'. If !flag_errno_math they are instead "const". */
|
|
||||||
#undef ATTR_MATHFN_ERRNO
|
|
||||||
#define ATTR_MATHFN_ERRNO (flag_errno_math ? \
|
|
||||||
ATTR_NOTHROW_LEAF_LIST : ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
|
|
||||||
/* Define an attribute list for math functions that are normally
|
|
||||||
"const" but if flag_rounding_math is set they are instead "pure".
|
|
||||||
This distinction accounts for the fact that some math functions
|
|
||||||
check the rounding mode which is akin to examining global
|
|
||||||
memory. */
|
|
||||||
#undef ATTR_MATHFN_FPROUNDING
|
|
||||||
#define ATTR_MATHFN_FPROUNDING (flag_rounding_math ? \
|
|
||||||
ATTR_PURE_NOTHROW_LEAF_LIST : ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
|
|
||||||
/* Define an attribute list for math functions that are normally
|
|
||||||
"impure" because some of them may write into global memory for
|
|
||||||
`errno'. If !flag_errno_math, we can possibly use "pure" or
|
|
||||||
"const" depending on whether we care about FP rounding. */
|
|
||||||
#undef ATTR_MATHFN_FPROUNDING_ERRNO
|
|
||||||
#define ATTR_MATHFN_FPROUNDING_ERRNO (flag_errno_math ? \
|
|
||||||
ATTR_NOTHROW_LEAF_LIST : ATTR_MATHFN_FPROUNDING)
|
|
||||||
|
|
||||||
/* Define an attribute list for math functions that need to mind FP
|
|
||||||
rounding, but because they store into memory they are never "const"
|
|
||||||
or "pure". Use of this macro is mainly for documentation and
|
|
||||||
maintenance purposes. */
|
|
||||||
#undef ATTR_MATHFN_FPROUNDING_STORE
|
|
||||||
#define ATTR_MATHFN_FPROUNDING_STORE ATTR_NOTHROW_LEAF_LIST
|
|
||||||
|
|
||||||
/* Make sure 0 is not a legitimate builtin. */
|
|
||||||
DEF_BUILTIN_STUB(BUILT_IN_NONE, (const char *)0)
|
|
||||||
|
|
||||||
/* Category: math builtins. */
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ACOS, "acos", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ACOSF, "acosf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ACOSH, "acosh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ACOSHF, "acoshf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ACOSHL, "acoshl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ACOSL, "acosl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ASIN, "asin", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ASINF, "asinf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ASINH, "asinh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ASINHF, "asinhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ASINHL, "asinhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ASINL, "asinl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ATAN, "atan", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ATAN2, "atan2", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ATAN2F, "atan2f", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ATAN2L, "atan2l", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ATANF, "atanf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ATANH, "atanh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ATANHF, "atanhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ATANHL, "atanhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ATANL, "atanl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CBRT, "cbrt", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CBRTF, "cbrtf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CBRTL, "cbrtl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_CEIL, "ceil", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_CEILF, "ceilf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_CEILL, "ceill", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_COPYSIGN, "copysign", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_COPYSIGNF, "copysignf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_COPYSIGNL, "copysignl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_COS, "cos", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_COSF, "cosf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_COSH, "cosh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_COSHF, "coshf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_COSHL, "coshl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_COSL, "cosl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_DREM, "drem", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_DREMF, "dremf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_DREML, "dreml", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ERF, "erf", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ERFC, "erfc", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ERFCF, "erfcf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ERFCL, "erfcl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ERFF, "erff", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ERFL, "erfl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_EXP, "exp", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXP10, "exp10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXP10F, "exp10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXP10L, "exp10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_EXP2, "exp2", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_EXP2F, "exp2f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_EXP2L, "exp2l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_EXPF, "expf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_EXPL, "expl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_EXPM1, "expm1", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_EXPM1F, "expm1f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_EXPM1L, "expm1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_FABS, "fabs", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSF, "fabsf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSL, "fabsl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_FABSD32, "fabsd32", BT_FN_DFLOAT32_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_FABSD64, "fabsd64", BT_FN_DFLOAT64_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_FABSD128, "fabsd128", BT_FN_DFLOAT128_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_FDIM, "fdim", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_FDIMF, "fdimf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_FDIML, "fdiml", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_FLOOR, "floor", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FLOORF, "floorf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FLOORL, "floorl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_FMA, "fma", BT_FN_DOUBLE_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_FMAF, "fmaf", BT_FN_FLOAT_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_FMAL, "fmal", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_FMAX, "fmax", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_FMAXF, "fmaxf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_FMAXL, "fmaxl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_FMIN, "fmin", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_FMINF, "fminf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_FMINL, "fminl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_FMOD, "fmod", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODF, "fmodf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODL, "fmodl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_FREXP, "frexp", BT_FN_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FREXPF, "frexpf", BT_FN_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FREXPL, "frexpl", BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMA, "gamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAF, "gammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAL, "gammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMA_R, "gamma_r", BT_FN_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAF_R, "gammaf_r", BT_FN_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAL_R, "gammal_r", BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_HUGE_VAL, "huge_val", BT_FN_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_HUGE_VALF, "huge_valf", BT_FN_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_HUGE_VALL, "huge_vall", BT_FN_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_HYPOT, "hypot", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_HYPOTF, "hypotf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_HYPOTL, "hypotl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_ICEIL, "iceil", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_ICEILF, "iceilf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_ICEILL, "iceill", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_IFLOOR, "ifloor", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_IFLOORF, "ifloorf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_IFLOORL, "ifloorl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ILOGB, "ilogb", BT_FN_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ILOGBF, "ilogbf", BT_FN_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ILOGBL, "ilogbl", BT_FN_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_INF, "inf", BT_FN_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_INFF, "inff", BT_FN_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_INFL, "infl", BT_FN_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_INFD32, "infd32", BT_FN_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_INFD64, "infd64", BT_FN_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_INFD128, "infd128", BT_FN_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_IRINT, "irint", BT_FN_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_IRINTF, "irintf", BT_FN_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_IRINTL, "irintl", BT_FN_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_IROUND, "iround", BT_FN_INT_DOUBLE, ATTR_MATHFN_ERRNO)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_IROUNDF, "iroundf", BT_FN_INT_FLOAT, ATTR_MATHFN_ERRNO)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_IROUNDL, "iroundl", BT_FN_INT_LONGDOUBLE, ATTR_MATHFN_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_J0, "j0", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_J0F, "j0f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_J0L, "j0l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_J1, "j1", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_J1F, "j1f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_J1L, "j1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_JN, "jn", BT_FN_DOUBLE_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_JNF, "jnf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_JNL, "jnl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_LCEIL, "lceil", BT_FN_LONG_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_LCEILF, "lceilf", BT_FN_LONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_LCEILL, "lceill", BT_FN_LONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_LDEXP, "ldexp", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_LDEXPF, "ldexpf", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_LDEXPL, "ldexpl", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_LFLOOR, "lfloor", BT_FN_LONG_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_LFLOORF, "lfloorf", BT_FN_LONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_LFLOORL, "lfloorl", BT_FN_LONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LGAMMA, "lgamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LGAMMAF, "lgammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LGAMMAL, "lgammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_LGAMMA_R, "lgamma_r", BT_FN_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_LGAMMAF_R, "lgammaf_r", BT_FN_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_LGAMMAL_R, "lgammal_r", BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_LLCEIL, "llceil", BT_FN_LONGLONG_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_LLCEILF, "llceilf", BT_FN_LONGLONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_LLCEILL, "llceill", BT_FN_LONGLONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_LLFLOOR, "llfloor", BT_FN_LONGLONG_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_LLFLOORF, "llfloorf", BT_FN_LONGLONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_LLFLOORL, "llfloorl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LLRINT, "llrint", BT_FN_LONGLONG_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LLRINTF, "llrintf", BT_FN_LONGLONG_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LLRINTL, "llrintl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LLROUND, "llround", BT_FN_LONGLONG_DOUBLE, ATTR_MATHFN_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LLROUNDF, "llroundf", BT_FN_LONGLONG_FLOAT, ATTR_MATHFN_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LLROUNDL, "llroundl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_MATHFN_ERRNO)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_LOG, "log", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_LOG10, "log10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_LOG10F, "log10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_LOG10L, "log10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LOG1P, "log1p", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LOG1PF, "log1pf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LOG1PL, "log1pl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LOG2, "log2", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LOG2F, "log2f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LOG2L, "log2l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LOGB, "logb", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LOGBF, "logbf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LOGBL, "logbl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_LOGF, "logf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_LOGL, "logl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LRINT, "lrint", BT_FN_LONG_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LRINTF, "lrintf", BT_FN_LONG_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LRINTL, "lrintl", BT_FN_LONG_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LROUND, "lround", BT_FN_LONG_DOUBLE, ATTR_MATHFN_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LROUNDF, "lroundf", BT_FN_LONG_FLOAT, ATTR_MATHFN_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LROUNDL, "lroundl", BT_FN_LONG_LONGDOUBLE, ATTR_MATHFN_ERRNO)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_MODF, "modf", BT_FN_DOUBLE_DOUBLE_DOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_MODFF, "modff", BT_FN_FLOAT_FLOAT_FLOATPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_MODFL, "modfl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_NAN, "nan", BT_FN_DOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_NANF, "nanf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_NANL, "nanl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_NAND32, "nand32", BT_FN_DFLOAT32_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_NAND64, "nand64", BT_FN_DFLOAT64_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_NAND128, "nand128", BT_FN_DFLOAT128_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_NANS, "nans", BT_FN_DOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_NANSF, "nansf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_NANSL, "nansl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_NEARBYINT, "nearbyint", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_NEARBYINTF, "nearbyintf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_NEARBYINTL, "nearbyintl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_NEXTAFTER, "nextafter", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_NEXTAFTERF, "nextafterf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_NEXTAFTERL, "nextafterl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_NEXTTOWARD, "nexttoward", BT_FN_DOUBLE_DOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_NEXTTOWARDF, "nexttowardf", BT_FN_FLOAT_FLOAT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_NEXTTOWARDL, "nexttowardl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_POW, "pow", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10, "pow10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10F, "pow10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10L, "pow10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_POWF, "powf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_POWI, "powi", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_POWIF, "powif", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_POWIL, "powil", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_POWL, "powl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_REMAINDER, "remainder", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_REMAINDERF, "remainderf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_REMAINDERL, "remainderl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_REMQUO, "remquo", BT_FN_DOUBLE_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_REMQUOF, "remquof", BT_FN_FLOAT_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_REMQUOL, "remquol", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_RINT, "rint", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_RINTF, "rintf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_RINTL, "rintl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ROUND, "round", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ROUNDF, "roundf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ROUNDL, "roundl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALB, "scalb", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALBF, "scalbf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALBL, "scalbl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_SCALBLN, "scalbln", BT_FN_DOUBLE_DOUBLE_LONG, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_SCALBLNF, "scalblnf", BT_FN_FLOAT_FLOAT_LONG, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_SCALBLNL, "scalblnl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONG, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_SCALBN, "scalbn", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_SCALBNF, "scalbnf", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_SCALBNL, "scalbnl", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBIT, "signbit", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITF, "signbitf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITL, "signbitl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITD32, "signbitd32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITD64, "signbitd64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITD128, "signbitd128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICAND, "significand", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICANDF, "significandf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICANDL, "significandl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_SIN, "sin", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOS, "sincos", BT_FN_VOID_DOUBLE_DOUBLEPTR_DOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOSF, "sincosf", BT_FN_VOID_FLOAT_FLOATPTR_FLOATPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOSL, "sincosl", BT_FN_VOID_LONGDOUBLE_LONGDOUBLEPTR_LONGDOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_SINF, "sinf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_SINH, "sinh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_SINHF, "sinhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_SINHL, "sinhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_SINL, "sinl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_SQRT, "sqrt", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTF, "sqrtf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTL, "sqrtl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_TAN, "tan", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_TANF, "tanf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_TANH, "tanh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_TANHF, "tanhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_TANHL, "tanhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_TANL, "tanl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_TGAMMA, "tgamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_TGAMMAF, "tgammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_TGAMMAL, "tgammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_TRUNC, "trunc", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_TRUNCF, "truncf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_TRUNCL, "truncl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y0, "y0", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y0F, "y0f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y0L, "y0l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y1, "y1", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y1F, "y1f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y1L, "y1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_YN, "yn", BT_FN_DOUBLE_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_YNF, "ynf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_YNL, "ynl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
|
||||||
|
|
||||||
/* Category: _Complex math builtins. */
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CEXPI, "cexpi", BT_FN_COMPLEX_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CEXPIF, "cexpif", BT_FN_COMPLEX_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CEXPIL, "cexpil", BT_FN_COMPLEX_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10, "clog10", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10F, "clog10f", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10L, "clog10l", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
|
||||||
|
|
||||||
/* Category: string/memory builtins. */
|
|
||||||
/* bcmp, bcopy and bzero have traditionally accepted NULL pointers
|
|
||||||
when the length parameter is zero, so don't apply attribute "nonnull". */
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_BCMP, "bcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_BCOPY, "bcopy", BT_FN_VOID_CONST_PTR_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_BZERO, "bzero", BT_FN_VOID_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_INDEX, "index", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_MEMCHR, "memchr", BT_FN_PTR_CONST_PTR_INT_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_MEMCMP, "memcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_MEMCPY, "memcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_MEMMOVE, "memmove", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY, "mempcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_MEMSET, "memset", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_RINDEX, "rindex", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STPCPY, "stpcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STPNCPY, "stpncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCASECMP, "strcasecmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_STRCAT, "strcat", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_STRCHR, "strchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_STRCMP, "strcmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_STRCPY, "strcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_STRCSPN, "strcspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRDUP, "strdup", BT_FN_STRING_CONST_STRING, ATTR_MALLOC_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNDUP, "strndup", BT_FN_STRING_CONST_STRING_SIZE, ATTR_MALLOC_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_STRLEN, "strlen", BT_FN_SIZE_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCASECMP, "strncasecmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_STRNCAT, "strncat", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_STRNCMP, "strncmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_STRNCPY, "strncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_STRPBRK, "strpbrk", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_STRRCHR, "strrchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_STRSPN, "strspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_STRSTR, "strstr", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
|
||||||
|
|
||||||
/* Category: stdio builtins. */
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_FPRINTF, "fprintf", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPRINTF_UNLOCKED, "fprintf_unlocked", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_PUTC, "putc", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTC_UNLOCKED, "putc_unlocked", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_FPUTC, "fputc", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPUTC_UNLOCKED, "fputc_unlocked", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_FPUTS, "fputs", BT_FN_INT_CONST_STRING_FILEPTR, ATTR_NONNULL_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPUTS_UNLOCKED, "fputs_unlocked", BT_FN_INT_CONST_STRING_FILEPTR, ATTR_NONNULL_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_FSCANF, "fscanf", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_SCANF_2_3)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_FWRITE, "fwrite", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR, ATTR_NONNULL_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FWRITE_UNLOCKED, "fwrite_unlocked", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR, ATTR_NONNULL_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_PRINTF, "printf", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_1_2)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PRINTF_UNLOCKED, "printf_unlocked", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_1_2)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_PUTCHAR, "putchar", BT_FN_INT_INT, ATTR_NULL)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTCHAR_UNLOCKED, "putchar_unlocked", BT_FN_INT_INT, ATTR_NULL)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_PUTS, "puts", BT_FN_INT_CONST_STRING, ATTR_NONNULL_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTS_UNLOCKED, "puts_unlocked", BT_FN_INT_CONST_STRING, ATTR_NONNULL_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_SCANF, "scanf", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_SCANF_1_2)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_SNPRINTF, "snprintf", BT_FN_INT_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_3_4)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_SPRINTF, "sprintf", BT_FN_INT_STRING_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_2_3)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_SSCANF, "sscanf", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_FORMAT_SCANF_NOTHROW_2_3)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_VFPRINTF, "vfprintf", BT_FN_INT_FILEPTR_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_VFSCANF, "vfscanf", BT_FN_INT_FILEPTR_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_2_0)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_VPRINTF, "vprintf", BT_FN_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_1_0)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_VSCANF, "vscanf", BT_FN_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_1_0)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_VSNPRINTF, "vsnprintf", BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_3_0)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_VSPRINTF, "vsprintf", BT_FN_INT_STRING_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_2_0)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_VSSCANF, "vsscanf", BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_NOTHROW_2_0)
|
|
||||||
|
|
||||||
/* Category: ctype builtins. */
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ISALNUM, "isalnum", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ISALPHA, "isalpha", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISASCII, "isascii", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ISBLANK, "isblank", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ISCNTRL, "iscntrl", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ISDIGIT, "isdigit", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ISGRAPH, "isgraph", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ISLOWER, "islower", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ISPRINT, "isprint", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ISPUNCT, "ispunct", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ISSPACE, "isspace", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ISUPPER, "isupper", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ISXDIGIT, "isxdigit", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_TOASCII, "toascii", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_TOLOWER, "tolower", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_TOUPPER, "toupper", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
|
|
||||||
/* Category: wctype builtins. */
|
|
||||||
DEF_C94_BUILTIN (BUILT_IN_ISWALNUM, "iswalnum", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C94_BUILTIN (BUILT_IN_ISWALPHA, "iswalpha", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_ISWBLANK, "iswblank", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C94_BUILTIN (BUILT_IN_ISWCNTRL, "iswcntrl", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C94_BUILTIN (BUILT_IN_ISWDIGIT, "iswdigit", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C94_BUILTIN (BUILT_IN_ISWGRAPH, "iswgraph", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C94_BUILTIN (BUILT_IN_ISWLOWER, "iswlower", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C94_BUILTIN (BUILT_IN_ISWPRINT, "iswprint", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C94_BUILTIN (BUILT_IN_ISWPUNCT, "iswpunct", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C94_BUILTIN (BUILT_IN_ISWSPACE, "iswspace", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C94_BUILTIN (BUILT_IN_ISWUPPER, "iswupper", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C94_BUILTIN (BUILT_IN_ISWXDIGIT, "iswxdigit", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C94_BUILTIN (BUILT_IN_TOWLOWER, "towlower", BT_FN_WINT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C94_BUILTIN (BUILT_IN_TOWUPPER, "towupper", BT_FN_WINT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
|
|
||||||
/* Category: miscellaneous builtins. */
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ABORT, "abort", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_ABS, "abs", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_AGGREGATE_INCOMING_ADDRESS, "aggregate_incoming_address", BT_FN_PTR_VAR, ATTR_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ALLOCA, "alloca", BT_FN_PTR_SIZE, ATTR_MALLOC_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_APPLY, "apply", BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE, ATTR_NULL)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_APPLY_ARGS, "apply_args", BT_FN_PTR_VAR, ATTR_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_BSWAP16, "bswap16", BT_FN_UINT16_UINT16, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_BSWAP32, "bswap32", BT_FN_UINT32_UINT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_BSWAP64, "bswap64", BT_FN_UINT64_UINT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_CLEAR_CACHE, "__clear_cache", BT_FN_VOID_PTR_PTR, ATTR_NOTHROW_LEAF_LIST)
|
|
||||||
/* [trans-mem]: Adjust BUILT_IN_TM_CALLOC if BUILT_IN_CALLOC is changed. */
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_CALLOC, "calloc", BT_FN_PTR_SIZE_SIZE, ATTR_MALLOC_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CLASSIFY_TYPE, "classify_type", BT_FN_INT_VAR, ATTR_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CLZ, "clz", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CLZIMAX, "clzimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CLZL, "clzl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CLZLL, "clzll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CONSTANT_P, "constant_p", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CTZ, "ctz", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CTZIMAX, "ctzimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CTZL, "ctzl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CTZLL, "ctzll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CLRSB, "clrsb", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CLRSBIMAX, "clrsbimax", BT_FN_INT_INTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CLRSBL, "clrsbl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_CLRSBLL, "clrsbll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_DCGETTEXT, "dcgettext", BT_FN_STRING_CONST_STRING_CONST_STRING_INT, ATTR_FORMAT_ARG_2)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_DGETTEXT, "dgettext", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_FORMAT_ARG_2)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_DWARF_CFA, "dwarf_cfa", BT_FN_PTR, ATTR_NULL)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_DWARF_SP_COLUMN, "dwarf_sp_column", BT_FN_UINT, ATTR_NULL)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_EH_RETURN, "eh_return", BT_FN_VOID_PTRMODE_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_EH_RETURN_DATA_REGNO, "eh_return_data_regno", BT_FN_INT_INT, ATTR_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECL, "execl", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_SENTINEL_NOTHROW_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECLP, "execlp", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_SENTINEL_NOTHROW_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECLE, "execle", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_NOTHROW_SENTINEL_1)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECV, "execv", BT_FN_INT_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECVP, "execvp", BT_FN_INT_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECVE, "execve", BT_FN_INT_CONST_STRING_PTR_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_EXIT, "exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_EXPECT, "expect", BT_FN_LONG_LONG_LONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_ASSUME_ALIGNED, "assume_aligned", BT_FN_PTR_CONST_PTR_SIZE_VAR, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_EXTEND_POINTER, "extend_pointer", BT_FN_UNWINDWORD_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_EXTRACT_RETURN_ADDR, "extract_return_addr", BT_FN_PTR_PTR, ATTR_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFS, "ffs", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSIMAX, "ffsimax", BT_FN_INT_INTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSL, "ffsl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSLL, "ffsll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FORK, "fork", BT_FN_PID, ATTR_NOTHROW_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_FRAME_ADDRESS, "frame_address", BT_FN_PTR_UINT, ATTR_NULL)
|
|
||||||
/* [trans-mem]: Adjust BUILT_IN_TM_FREE if BUILT_IN_FREE is changed. */
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_FREE, "free", BT_FN_VOID_PTR, ATTR_NOTHROW_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_FROB_RETURN_ADDR, "frob_return_addr", BT_FN_PTR_PTR, ATTR_NULL)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GETTEXT, "gettext", BT_FN_STRING_CONST_STRING, ATTR_FORMAT_ARG_1)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_IMAXABS, "imaxabs", BT_FN_INTMAX_INTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_INIT_DWARF_REG_SIZES, "init_dwarf_reg_size_table", BT_FN_VOID_PTR, ATTR_NULL)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITE, "finite", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEF, "finitef", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEL, "finitel", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED32, "finited32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED64, "finited64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED128, "finited128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_FPCLASSIFY, "fpclassify", BT_FN_INT_INT_INT_INT_INT_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_ISFINITE, "isfinite", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_ISINF_SIGN, "isinf_sign", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ISINF, "isinf", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFF, "isinff", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFL, "isinfl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD32, "isinfd32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD64, "isinfd64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD128, "isinfd128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ISNAN, "isnan", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANF, "isnanf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANL, "isnanl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND32, "isnand32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND64, "isnand64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND128, "isnand128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_ISNORMAL, "isnormal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_ISGREATER, "isgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_ISGREATEREQUAL, "isgreaterequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_ISLESS, "isless", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_ISLESSEQUAL, "islessequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_ISLESSGREATER, "islessgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_ISUNORDERED, "isunordered", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_LABS, "labs", BT_FN_LONG_LONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN_LLABS, "llabs", BT_FN_LONGLONG_LONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_LONGJMP, "longjmp", BT_FN_VOID_PTR_INT, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
|
||||||
/* [trans-mem]: Adjust BUILT_IN_TM_MALLOC if BUILT_IN_MALLOC is changed. */
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_MALLOC, "malloc", BT_FN_PTR_SIZE, ATTR_MALLOC_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_NEXT_ARG, "next_arg", BT_FN_PTR_VAR, ATTR_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_PARITY, "parity", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_PARITYIMAX, "parityimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_PARITYL, "parityl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_PARITYLL, "parityll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNT, "popcount", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTIMAX, "popcountimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTL, "popcountl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTLL, "popcountll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_PREFETCH, "prefetch", BT_FN_VOID_CONST_PTR_VAR, ATTR_NOVOPS_LEAF_LIST)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_REALLOC, "realloc", BT_FN_PTR_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UINT, ATTR_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_NULL)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_NOTHROW_3_4)
|
|
||||||
DEF_LIB_BUILTIN (BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, ATTR_FORMAT_STRFTIME_NOTHROW_3_0)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_TRAP, "trap", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_UNREACHABLE, "unreachable", BT_FN_VOID, ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_UNWIND_INIT, "unwind_init", BT_FN_VOID, ATTR_NULL)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_UPDATE_SETJMP_BUF, "update_setjmp_buf", BT_FN_VOID_PTR_INT, ATTR_NULL)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_VA_COPY, "va_copy", BT_FN_VOID_VALIST_REF_VALIST_ARG, ATTR_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_VA_END, "va_end", BT_FN_VOID_VALIST_REF, ATTR_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_VA_START, "va_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_VA_ARG_PACK, "va_arg_pack", BT_FN_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_VA_ARG_PACK_LEN, "va_arg_pack_len", BT_FN_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN__EXIT, "_exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_C99_BUILTIN (BUILT_IN__EXIT2, "_Exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
|
||||||
|
|
||||||
/* Implementing nested functions. */
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_INIT_TRAMPOLINE, "__builtin_init_trampoline")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_INIT_HEAP_TRAMPOLINE, "__builtin_init_heap_trampoline")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_ADJUST_TRAMPOLINE, "__builtin_adjust_trampoline")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_NONLOCAL_GOTO, "__builtin_nonlocal_goto")
|
|
||||||
|
|
||||||
/* Implementing __builtin_setjmp. */
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_SETJMP_SETUP, "__builtin_setjmp_setup")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_SETJMP_DISPATCHER, "__builtin_setjmp_dispatcher")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_SETJMP_RECEIVER, "__builtin_setjmp_receiver")
|
|
||||||
|
|
||||||
/* Implementing variable sized local variables. */
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_STACK_SAVE, "__builtin_stack_save")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_STACK_RESTORE, "__builtin_stack_restore")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_ALLOCA_WITH_ALIGN, "__builtin_alloca_with_align")
|
|
||||||
|
|
||||||
/* Object size checking builtins. */
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_OBJECT_SIZE, "object_size", BT_FN_SIZE_CONST_PTR_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMCPY_CHK, "__memcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMMOVE_CHK, "__memmove_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY_CHK, "__mempcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMSET_CHK, "__memset_chk", BT_FN_PTR_PTR_INT_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STPCPY_CHK, "__stpcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STPNCPY_CHK, "__stpncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCAT_CHK, "__strcat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCPY_CHK, "__strcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCAT_CHK, "__strncat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCPY_CHK, "__strncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SNPRINTF_CHK, "__snprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_5_6)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SPRINTF_CHK, "__sprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_4_5)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_VSNPRINTF_CHK, "__vsnprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_5_0)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_VSPRINTF_CHK, "__vsprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_4_0)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPRINTF_CHK, "__fprintf_chk", BT_FN_INT_FILEPTR_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_3_4)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PRINTF_CHK, "__printf_chk", BT_FN_INT_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_VFPRINTF_CHK, "__vfprintf_chk", BT_FN_INT_FILEPTR_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_3_0)
|
|
||||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_VPRINTF_CHK, "__vprintf_chk", BT_FN_INT_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0)
|
|
||||||
|
|
||||||
/* Profiling hooks. */
|
|
||||||
DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_ENTER, "__cyg_profile_func_enter", BUILT_IN_NORMAL, BT_FN_VOID_PTR_PTR, BT_LAST,
|
|
||||||
false, false, false, ATTR_NULL, true, true)
|
|
||||||
DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_EXIT, "__cyg_profile_func_exit", BUILT_IN_NORMAL, BT_FN_VOID_PTR_PTR, BT_LAST,
|
|
||||||
false, false, false, ATTR_NULL, true, true)
|
|
||||||
|
|
||||||
/* TLS thread pointer related builtins. */
|
|
||||||
DEF_BUILTIN (BUILT_IN_THREAD_POINTER, "__builtin_thread_pointer",
|
|
||||||
BUILT_IN_NORMAL, BT_FN_PTR, BT_LAST,
|
|
||||||
false, false, true, ATTR_CONST_NOTHROW_LIST, true,
|
|
||||||
targetm.have_tls)
|
|
||||||
|
|
||||||
DEF_BUILTIN (BUILT_IN_SET_THREAD_POINTER, "__builtin_set_thread_pointer",
|
|
||||||
BUILT_IN_NORMAL, BT_FN_VOID_PTR, BT_LAST,
|
|
||||||
false, false, true, ATTR_NOTHROW_LIST, true,
|
|
||||||
targetm.have_tls)
|
|
||||||
|
|
||||||
/* TLS emulation. */
|
|
||||||
DEF_BUILTIN (BUILT_IN_EMUTLS_GET_ADDRESS, targetm.emutls.get_address,
|
|
||||||
BUILT_IN_NORMAL,
|
|
||||||
BT_FN_PTR_PTR, BT_FN_PTR_PTR,
|
|
||||||
true, true, true, ATTR_CONST_NOTHROW_NONNULL_LEAF, false,
|
|
||||||
!targetm.have_tls)
|
|
||||||
DEF_BUILTIN (BUILT_IN_EMUTLS_REGISTER_COMMON,
|
|
||||||
targetm.emutls.register_common, BUILT_IN_NORMAL,
|
|
||||||
BT_FN_VOID_PTR_WORD_WORD_PTR, BT_FN_VOID_PTR_WORD_WORD_PTR,
|
|
||||||
true, true, true, ATTR_NOTHROW_LEAF_LIST, false,
|
|
||||||
!targetm.have_tls)
|
|
||||||
|
|
||||||
/* Exception support. */
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_UNWIND_RESUME, "__builtin_unwind_resume")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_CXA_END_CLEANUP, "__builtin_cxa_end_cleanup")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_EH_POINTER, "__builtin_eh_pointer")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_EH_FILTER, "__builtin_eh_filter")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_EH_COPY_VALUES, "__builtin_eh_copy_values")
|
|
||||||
|
|
||||||
/* __FILE__, __LINE__, __FUNCTION__ as builtins. */
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_FILE, "FILE", BT_FN_CONST_STRING, ATTR_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_FUNCTION, "FUNCTION", BT_FN_CONST_STRING, ATTR_NOTHROW_LEAF_LIST)
|
|
||||||
DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST)
|
|
||||||
|
|
||||||
/* Synchronization Primitives. */
|
|
||||||
#include "sync-builtins.def"
|
|
||||||
|
|
||||||
/* OpenMP builtins. */
|
|
||||||
#include "omp-builtins.def"
|
|
||||||
|
|
||||||
/* GTM builtins. */
|
|
||||||
#include "gtm-builtins.def"
|
|
||||||
|
|
||||||
/* Sanitizer builtins. */
|
|
||||||
#include "sanitizer.def"
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
|||||||
#define BUILDING_GCC_MAJOR 4
|
|
||||||
#define BUILDING_GCC_MINOR 8
|
|
||||||
#define BUILDING_GCC_PATCHLEVEL 5
|
|
||||||
#define BUILDING_GCC_VERSION (BUILDING_GCC_MAJOR * 1000 + BUILDING_GCC_MINOR)
|
|
@ -1,62 +0,0 @@
|
|||||||
/* This file contains the definitions and documentation for the
|
|
||||||
additional tree codes used in the GNU C compiler (see tree.def
|
|
||||||
for the standard codes).
|
|
||||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
|
||||||
Written by Benjamin Chelf <chelf@codesourcery.com>
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Tree nodes used in the C frontend. These are also shared with the
|
|
||||||
C++ and Objective C frontends. */
|
|
||||||
|
|
||||||
/* A C_MAYBE_CONST_EXPR, currently only used for C and Objective C,
|
|
||||||
tracks information about constancy of an expression and VLA type
|
|
||||||
sizes or VM expressions from typeof that need to be evaluated
|
|
||||||
before the main expression. It is used during parsing and removed
|
|
||||||
in c_fully_fold. C_MAYBE_CONST_EXPR_PRE is the expression to
|
|
||||||
evaluate first, if not NULL; C_MAYBE_CONST_EXPR_EXPR is the main
|
|
||||||
expression. If C_MAYBE_CONST_EXPR_INT_OPERANDS is set then the
|
|
||||||
expression may be used in an unevaluated part of an integer
|
|
||||||
constant expression, but not in an evaluated part. If
|
|
||||||
C_MAYBE_CONST_EXPR_NON_CONST is set then the expression contains
|
|
||||||
something that cannot occur in an evaluated part of a constant
|
|
||||||
expression (or outside of sizeof in C90 mode); otherwise it does
|
|
||||||
not. */
|
|
||||||
DEFTREECODE (C_MAYBE_CONST_EXPR, "c_maybe_const_expr", tcc_expression, 2)
|
|
||||||
|
|
||||||
/* An EXCESS_PRECISION_EXPR, currently only used for C and Objective
|
|
||||||
C, represents an expression evaluated in greater range or precision
|
|
||||||
than its type. The type of the EXCESS_PRECISION_EXPR is the
|
|
||||||
semantic type while the operand represents what is actually being
|
|
||||||
evaluated. */
|
|
||||||
DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", tcc_expression, 1)
|
|
||||||
|
|
||||||
/* Used to represent a user-defined literal.
|
|
||||||
The operands are an IDENTIFIER for the suffix, the VALUE of the literal,
|
|
||||||
and for numeric literals the original string representation of the
|
|
||||||
number. */
|
|
||||||
DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3)
|
|
||||||
|
|
||||||
/* Represents a 'sizeof' expression during C++ template expansion,
|
|
||||||
or for the purpose of -Wsizeof-pointer-memaccess warning. */
|
|
||||||
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Local variables:
|
|
||||||
mode:c
|
|
||||||
End:
|
|
||||||
*/
|
|
File diff suppressed because it is too large
Load Diff
@ -1,114 +0,0 @@
|
|||||||
/* Definitions of Objective-C front-end entry points used for C and C++.
|
|
||||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_C_COMMON_OBJC_H
|
|
||||||
#define GCC_C_COMMON_OBJC_H
|
|
||||||
|
|
||||||
/* ObjC ivar visibility types. */
|
|
||||||
typedef enum objc_ivar_visibility_kind {
|
|
||||||
OBJC_IVAR_VIS_PROTECTED = 0,
|
|
||||||
OBJC_IVAR_VIS_PUBLIC = 1,
|
|
||||||
OBJC_IVAR_VIS_PRIVATE = 2,
|
|
||||||
OBJC_IVAR_VIS_PACKAGE = 3
|
|
||||||
} objc_ivar_visibility_kind;
|
|
||||||
|
|
||||||
/* Objective-C / Objective-C++ entry points. */
|
|
||||||
|
|
||||||
/* The following ObjC/ObjC++ functions are called by the C and/or C++
|
|
||||||
front-ends; they all must have corresponding stubs in stub-objc.c. */
|
|
||||||
extern void objc_write_global_declarations (void);
|
|
||||||
extern tree objc_is_class_name (tree);
|
|
||||||
extern tree objc_is_object_ptr (tree);
|
|
||||||
extern void objc_check_decl (tree);
|
|
||||||
extern void objc_check_global_decl (tree);
|
|
||||||
extern tree objc_common_type (tree, tree);
|
|
||||||
extern bool objc_compare_types (tree, tree, int, tree);
|
|
||||||
extern bool objc_have_common_type (tree, tree, int, tree);
|
|
||||||
extern bool objc_diagnose_private_ivar (tree);
|
|
||||||
extern void objc_volatilize_decl (tree);
|
|
||||||
extern tree objc_rewrite_function_call (tree, tree);
|
|
||||||
extern tree objc_message_selector (void);
|
|
||||||
extern tree objc_lookup_ivar (tree, tree);
|
|
||||||
extern void objc_clear_super_receiver (void);
|
|
||||||
extern int objc_is_public (tree, tree);
|
|
||||||
extern tree objc_is_id (tree);
|
|
||||||
extern void objc_declare_alias (tree, tree);
|
|
||||||
extern void objc_declare_class (tree);
|
|
||||||
extern void objc_declare_protocol (tree, tree);
|
|
||||||
extern tree objc_build_message_expr (tree, tree);
|
|
||||||
extern tree objc_finish_message_expr (tree, tree, tree, tree*);
|
|
||||||
extern tree objc_build_selector_expr (location_t, tree);
|
|
||||||
extern tree objc_build_protocol_expr (tree);
|
|
||||||
extern tree objc_build_encode_expr (tree);
|
|
||||||
extern tree objc_build_string_object (tree);
|
|
||||||
extern tree objc_get_protocol_qualified_type (tree, tree);
|
|
||||||
extern tree objc_get_class_reference (tree);
|
|
||||||
extern tree objc_get_class_ivars (tree);
|
|
||||||
extern bool objc_detect_field_duplicates (bool);
|
|
||||||
extern void objc_start_class_interface (tree, tree, tree, tree);
|
|
||||||
extern void objc_start_category_interface (tree, tree, tree, tree);
|
|
||||||
extern void objc_start_protocol (tree, tree, tree);
|
|
||||||
extern void objc_continue_interface (void);
|
|
||||||
extern void objc_finish_interface (void);
|
|
||||||
extern void objc_start_class_implementation (tree, tree);
|
|
||||||
extern void objc_start_category_implementation (tree, tree);
|
|
||||||
extern void objc_continue_implementation (void);
|
|
||||||
extern void objc_finish_implementation (void);
|
|
||||||
extern void objc_set_visibility (objc_ivar_visibility_kind);
|
|
||||||
extern tree objc_build_method_signature (bool, tree, tree, tree, bool);
|
|
||||||
extern void objc_add_method_declaration (bool, tree, tree);
|
|
||||||
extern bool objc_start_method_definition (bool, tree, tree, tree);
|
|
||||||
extern void objc_finish_method_definition (tree);
|
|
||||||
extern void objc_add_instance_variable (tree);
|
|
||||||
extern tree objc_build_keyword_decl (tree, tree, tree, tree);
|
|
||||||
extern tree objc_build_throw_stmt (location_t, tree);
|
|
||||||
extern void objc_begin_try_stmt (location_t, tree);
|
|
||||||
extern tree objc_finish_try_stmt (void);
|
|
||||||
extern void objc_begin_catch_clause (tree);
|
|
||||||
extern void objc_finish_catch_clause (void);
|
|
||||||
extern void objc_build_finally_clause (location_t, tree);
|
|
||||||
extern tree objc_build_synchronized (location_t, tree, tree);
|
|
||||||
extern int objc_static_init_needed_p (void);
|
|
||||||
extern tree objc_generate_static_init_call (tree);
|
|
||||||
extern tree objc_generate_write_barrier (tree, enum tree_code, tree);
|
|
||||||
extern void objc_set_method_opt (bool);
|
|
||||||
extern void objc_finish_foreach_loop (location_t, tree, tree, tree, tree, tree);
|
|
||||||
extern bool objc_method_decl (enum tree_code);
|
|
||||||
extern void objc_add_property_declaration (location_t, tree, bool, bool, bool,
|
|
||||||
bool, bool, bool, tree, tree);
|
|
||||||
extern tree objc_maybe_build_component_ref (tree, tree);
|
|
||||||
extern tree objc_build_class_component_ref (tree, tree);
|
|
||||||
extern tree objc_maybe_build_modify_expr (tree, tree);
|
|
||||||
extern tree objc_build_incr_expr_for_property_ref (location_t, enum tree_code,
|
|
||||||
tree, tree);
|
|
||||||
extern void objc_add_synthesize_declaration (location_t, tree);
|
|
||||||
extern void objc_add_dynamic_declaration (location_t, tree);
|
|
||||||
extern const char * objc_maybe_printable_name (tree, int);
|
|
||||||
extern bool objc_is_property_ref (tree);
|
|
||||||
extern bool objc_string_ref_type_p (tree);
|
|
||||||
extern void objc_check_format_arg (tree, tree);
|
|
||||||
extern void objc_finish_function (void);
|
|
||||||
extern void objc_maybe_warn_exceptions (location_t);
|
|
||||||
|
|
||||||
/* The following are provided by the C and C++ front-ends, and called by
|
|
||||||
ObjC/ObjC++. */
|
|
||||||
extern void *objc_get_current_scope (void);
|
|
||||||
extern void objc_mark_locals_volatile (void *);
|
|
||||||
|
|
||||||
#endif /* ! GCC_C_COMMON_OBJC_H */
|
|
@ -1,150 +0,0 @@
|
|||||||
/* Pragma related interfaces.
|
|
||||||
Copyright (C) 1995-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_C_PRAGMA_H
|
|
||||||
#define GCC_C_PRAGMA_H
|
|
||||||
|
|
||||||
#include "cpplib.h" /* For enum cpp_ttype. */
|
|
||||||
|
|
||||||
/* Pragma identifiers built in to the front end parsers. Identifiers
|
|
||||||
for ancillary handlers will follow these. */
|
|
||||||
typedef enum pragma_kind {
|
|
||||||
PRAGMA_NONE = 0,
|
|
||||||
|
|
||||||
PRAGMA_OMP_ATOMIC,
|
|
||||||
PRAGMA_OMP_BARRIER,
|
|
||||||
PRAGMA_OMP_CRITICAL,
|
|
||||||
PRAGMA_OMP_FLUSH,
|
|
||||||
PRAGMA_OMP_FOR,
|
|
||||||
PRAGMA_OMP_MASTER,
|
|
||||||
PRAGMA_OMP_ORDERED,
|
|
||||||
PRAGMA_OMP_PARALLEL,
|
|
||||||
PRAGMA_OMP_PARALLEL_FOR,
|
|
||||||
PRAGMA_OMP_PARALLEL_SECTIONS,
|
|
||||||
PRAGMA_OMP_SECTION,
|
|
||||||
PRAGMA_OMP_SECTIONS,
|
|
||||||
PRAGMA_OMP_SINGLE,
|
|
||||||
PRAGMA_OMP_TASK,
|
|
||||||
PRAGMA_OMP_TASKWAIT,
|
|
||||||
PRAGMA_OMP_TASKYIELD,
|
|
||||||
PRAGMA_OMP_THREADPRIVATE,
|
|
||||||
|
|
||||||
PRAGMA_GCC_PCH_PREPROCESS,
|
|
||||||
|
|
||||||
PRAGMA_FIRST_EXTERNAL
|
|
||||||
} pragma_kind;
|
|
||||||
|
|
||||||
|
|
||||||
/* All clauses defined by OpenMP 2.5 and 3.0.
|
|
||||||
Used internally by both C and C++ parsers. */
|
|
||||||
typedef enum pragma_omp_clause {
|
|
||||||
PRAGMA_OMP_CLAUSE_NONE = 0,
|
|
||||||
|
|
||||||
PRAGMA_OMP_CLAUSE_COLLAPSE,
|
|
||||||
PRAGMA_OMP_CLAUSE_COPYIN,
|
|
||||||
PRAGMA_OMP_CLAUSE_COPYPRIVATE,
|
|
||||||
PRAGMA_OMP_CLAUSE_DEFAULT,
|
|
||||||
PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
|
|
||||||
PRAGMA_OMP_CLAUSE_IF,
|
|
||||||
PRAGMA_OMP_CLAUSE_LASTPRIVATE,
|
|
||||||
PRAGMA_OMP_CLAUSE_NOWAIT,
|
|
||||||
PRAGMA_OMP_CLAUSE_NUM_THREADS,
|
|
||||||
PRAGMA_OMP_CLAUSE_ORDERED,
|
|
||||||
PRAGMA_OMP_CLAUSE_PRIVATE,
|
|
||||||
PRAGMA_OMP_CLAUSE_REDUCTION,
|
|
||||||
PRAGMA_OMP_CLAUSE_SCHEDULE,
|
|
||||||
PRAGMA_OMP_CLAUSE_SHARED,
|
|
||||||
PRAGMA_OMP_CLAUSE_UNTIED,
|
|
||||||
PRAGMA_OMP_CLAUSE_FINAL,
|
|
||||||
PRAGMA_OMP_CLAUSE_MERGEABLE
|
|
||||||
} pragma_omp_clause;
|
|
||||||
|
|
||||||
extern struct cpp_reader* parse_in;
|
|
||||||
|
|
||||||
/* It's safe to always leave visibility pragma enabled as if
|
|
||||||
visibility is not supported on the host OS platform the
|
|
||||||
statements are ignored. */
|
|
||||||
extern void push_visibility (const char *, int);
|
|
||||||
extern bool pop_visibility (int);
|
|
||||||
|
|
||||||
extern void init_pragma (void);
|
|
||||||
|
|
||||||
/* Front-end wrappers for pragma registration. */
|
|
||||||
typedef void (*pragma_handler_1arg)(struct cpp_reader *);
|
|
||||||
/* A second pragma handler, which adds a void * argument allowing to pass extra
|
|
||||||
data to the handler. */
|
|
||||||
typedef void (*pragma_handler_2arg)(struct cpp_reader *, void *);
|
|
||||||
|
|
||||||
/* This union allows to abstract the different handlers. */
|
|
||||||
union gen_pragma_handler {
|
|
||||||
pragma_handler_1arg handler_1arg;
|
|
||||||
pragma_handler_2arg handler_2arg;
|
|
||||||
};
|
|
||||||
/* Internally used to keep the data of the handler. */
|
|
||||||
struct internal_pragma_handler_d {
|
|
||||||
union gen_pragma_handler handler;
|
|
||||||
/* Permits to know if handler is a pragma_handler_1arg (extra_data is false)
|
|
||||||
or a pragma_handler_2arg (extra_data is true). */
|
|
||||||
bool extra_data;
|
|
||||||
/* A data field which can be used when extra_data is true. */
|
|
||||||
void * data;
|
|
||||||
};
|
|
||||||
typedef struct internal_pragma_handler_d internal_pragma_handler;
|
|
||||||
|
|
||||||
extern void c_register_pragma (const char *space, const char *name,
|
|
||||||
pragma_handler_1arg handler);
|
|
||||||
extern void c_register_pragma_with_data (const char *space, const char *name,
|
|
||||||
pragma_handler_2arg handler,
|
|
||||||
void *data);
|
|
||||||
|
|
||||||
extern void c_register_pragma_with_expansion (const char *space,
|
|
||||||
const char *name,
|
|
||||||
pragma_handler_1arg handler);
|
|
||||||
extern void c_register_pragma_with_expansion_and_data (const char *space,
|
|
||||||
const char *name,
|
|
||||||
pragma_handler_2arg handler,
|
|
||||||
void *data);
|
|
||||||
extern void c_invoke_pragma_handler (unsigned int);
|
|
||||||
|
|
||||||
extern void maybe_apply_pragma_weak (tree);
|
|
||||||
extern void maybe_apply_pending_pragma_weaks (void);
|
|
||||||
extern tree maybe_apply_renaming_pragma (tree, tree);
|
|
||||||
extern void add_to_renaming_pragma_list (tree, tree);
|
|
||||||
|
|
||||||
extern enum cpp_ttype pragma_lex (tree *);
|
|
||||||
|
|
||||||
/* Flags for use with c_lex_with_flags. The values here were picked
|
|
||||||
so that 0 means to translate and join strings. */
|
|
||||||
#define C_LEX_STRING_NO_TRANSLATE 1 /* Do not lex strings into
|
|
||||||
execution character set. */
|
|
||||||
#define C_LEX_STRING_NO_JOIN 2 /* Do not concatenate strings
|
|
||||||
nor translate them into execution
|
|
||||||
character set. */
|
|
||||||
|
|
||||||
/* This is not actually available to pragma parsers. It's merely a
|
|
||||||
convenient location to declare this function for c-lex, after
|
|
||||||
having enum cpp_ttype declared. */
|
|
||||||
extern enum cpp_ttype c_lex_with_flags (tree *, location_t *, unsigned char *,
|
|
||||||
int);
|
|
||||||
|
|
||||||
extern void c_pp_lookup_pragma (unsigned int, const char **, const char **);
|
|
||||||
|
|
||||||
extern GTY(()) tree pragma_extern_prefix;
|
|
||||||
|
|
||||||
#endif /* GCC_C_PRAGMA_H */
|
|
@ -1,215 +0,0 @@
|
|||||||
/* Various declarations for the C and C++ pretty-printers.
|
|
||||||
Copyright (C) 2002-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_C_PRETTY_PRINTER
|
|
||||||
#define GCC_C_PRETTY_PRINTER
|
|
||||||
|
|
||||||
#include "tree.h"
|
|
||||||
#include "c-family/c-common.h"
|
|
||||||
#include "pretty-print.h"
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
pp_c_flag_abstract = 1 << 1,
|
|
||||||
pp_c_flag_gnu_v3 = 1 << 2,
|
|
||||||
pp_c_flag_last_bit = 3
|
|
||||||
} pp_c_pretty_print_flags;
|
|
||||||
|
|
||||||
|
|
||||||
/* The data type used to bundle information necessary for pretty-printing
|
|
||||||
a C or C++ entity. */
|
|
||||||
typedef struct c_pretty_print_info c_pretty_printer;
|
|
||||||
|
|
||||||
/* The type of a C pretty-printer 'member' function. */
|
|
||||||
typedef void (*c_pretty_print_fn) (c_pretty_printer *, tree);
|
|
||||||
|
|
||||||
/* The datatype that contains information necessary for pretty-printing
|
|
||||||
a tree that represents a C construct. Any pretty-printer for a
|
|
||||||
language using C/c++ syntax can derive from this datatype and reuse
|
|
||||||
facilities provided here. It can do so by having a subobject of type
|
|
||||||
c_pretty_printer and override the macro pp_c_base to return a pointer
|
|
||||||
to that subobject. Such a pretty-printer has the responsibility to
|
|
||||||
initialize the pp_base() part, then call pp_c_pretty_printer_init
|
|
||||||
to set up the components that are specific to the C pretty-printer.
|
|
||||||
A derived pretty-printer can override any function listed in the
|
|
||||||
vtable below. See cp/cxx-pretty-print.h and cp/cxx-pretty-print.c
|
|
||||||
for an example of derivation. */
|
|
||||||
struct c_pretty_print_info
|
|
||||||
{
|
|
||||||
pretty_printer base;
|
|
||||||
/* Points to the first element of an array of offset-list.
|
|
||||||
Not used yet. */
|
|
||||||
int *offset_list;
|
|
||||||
|
|
||||||
pp_flags flags;
|
|
||||||
|
|
||||||
/* These must be overridden by each of the C and C++ front-end to
|
|
||||||
reflect their understanding of syntactic productions when they differ. */
|
|
||||||
c_pretty_print_fn declaration;
|
|
||||||
c_pretty_print_fn declaration_specifiers;
|
|
||||||
c_pretty_print_fn declarator;
|
|
||||||
c_pretty_print_fn abstract_declarator;
|
|
||||||
c_pretty_print_fn direct_abstract_declarator;
|
|
||||||
c_pretty_print_fn type_specifier_seq;
|
|
||||||
c_pretty_print_fn direct_declarator;
|
|
||||||
c_pretty_print_fn ptr_operator;
|
|
||||||
c_pretty_print_fn parameter_list;
|
|
||||||
c_pretty_print_fn type_id;
|
|
||||||
c_pretty_print_fn simple_type_specifier;
|
|
||||||
c_pretty_print_fn function_specifier;
|
|
||||||
c_pretty_print_fn storage_class_specifier;
|
|
||||||
c_pretty_print_fn initializer;
|
|
||||||
|
|
||||||
c_pretty_print_fn statement;
|
|
||||||
|
|
||||||
c_pretty_print_fn constant;
|
|
||||||
c_pretty_print_fn id_expression;
|
|
||||||
c_pretty_print_fn primary_expression;
|
|
||||||
c_pretty_print_fn postfix_expression;
|
|
||||||
c_pretty_print_fn unary_expression;
|
|
||||||
c_pretty_print_fn multiplicative_expression;
|
|
||||||
c_pretty_print_fn conditional_expression;
|
|
||||||
c_pretty_print_fn assignment_expression;
|
|
||||||
c_pretty_print_fn expression;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Override the pp_base macro. Derived pretty-printers should not
|
|
||||||
touch this macro. Instead they should override pp_c_base instead. */
|
|
||||||
#undef pp_base
|
|
||||||
#define pp_base(PP) (&pp_c_base (PP)->base)
|
|
||||||
|
|
||||||
|
|
||||||
#define pp_c_tree_identifier(PPI, ID) \
|
|
||||||
pp_c_identifier (PPI, IDENTIFIER_POINTER (ID))
|
|
||||||
|
|
||||||
#define pp_declaration(PPI, T) \
|
|
||||||
pp_c_base (PPI)->declaration (pp_c_base (PPI), T)
|
|
||||||
#define pp_declaration_specifiers(PPI, D) \
|
|
||||||
pp_c_base (PPI)->declaration_specifiers (pp_c_base (PPI), D)
|
|
||||||
#define pp_abstract_declarator(PP, D) \
|
|
||||||
pp_c_base (PP)->abstract_declarator (pp_c_base (PP), D)
|
|
||||||
#define pp_type_specifier_seq(PPI, D) \
|
|
||||||
pp_c_base (PPI)->type_specifier_seq (pp_c_base (PPI), D)
|
|
||||||
#define pp_declarator(PPI, D) \
|
|
||||||
pp_c_base (PPI)->declarator (pp_c_base (PPI), D)
|
|
||||||
#define pp_direct_declarator(PPI, D) \
|
|
||||||
pp_c_base (PPI)->direct_declarator (pp_c_base (PPI), D)
|
|
||||||
#define pp_direct_abstract_declarator(PP, D) \
|
|
||||||
pp_c_base (PP)->direct_abstract_declarator (pp_c_base (PP), D)
|
|
||||||
#define pp_ptr_operator(PP, D) \
|
|
||||||
pp_c_base (PP)->ptr_operator (pp_c_base (PP), D)
|
|
||||||
#define pp_parameter_list(PPI, T) \
|
|
||||||
pp_c_base (PPI)->parameter_list (pp_c_base (PPI), T)
|
|
||||||
#define pp_type_id(PPI, D) \
|
|
||||||
pp_c_base (PPI)->type_id (pp_c_base (PPI), D)
|
|
||||||
#define pp_simple_type_specifier(PP, T) \
|
|
||||||
pp_c_base (PP)->simple_type_specifier (pp_c_base (PP), T)
|
|
||||||
#define pp_function_specifier(PP, D) \
|
|
||||||
pp_c_base (PP)->function_specifier (pp_c_base (PP), D)
|
|
||||||
#define pp_storage_class_specifier(PP, D) \
|
|
||||||
pp_c_base (PP)->storage_class_specifier (pp_c_base (PP), D);
|
|
||||||
|
|
||||||
#define pp_statement(PPI, S) \
|
|
||||||
pp_c_base (PPI)->statement (pp_c_base (PPI), S)
|
|
||||||
|
|
||||||
#define pp_constant(PP, E) \
|
|
||||||
pp_c_base (PP)->constant (pp_c_base (PP), E)
|
|
||||||
#define pp_id_expression(PP, E) \
|
|
||||||
pp_c_base (PP)->id_expression (pp_c_base (PP), E)
|
|
||||||
#define pp_primary_expression(PPI, E) \
|
|
||||||
pp_c_base (PPI)->primary_expression (pp_c_base (PPI), E)
|
|
||||||
#define pp_postfix_expression(PPI, E) \
|
|
||||||
pp_c_base (PPI)->postfix_expression (pp_c_base (PPI), E)
|
|
||||||
#define pp_unary_expression(PPI, E) \
|
|
||||||
pp_c_base (PPI)->unary_expression (pp_c_base (PPI), E)
|
|
||||||
#define pp_initializer(PPI, E) \
|
|
||||||
pp_c_base (PPI)->initializer (pp_c_base (PPI), E)
|
|
||||||
#define pp_multiplicative_expression(PPI, E) \
|
|
||||||
pp_c_base (PPI)->multiplicative_expression (pp_c_base (PPI), E)
|
|
||||||
#define pp_conditional_expression(PPI, E) \
|
|
||||||
pp_c_base (PPI)->conditional_expression (pp_c_base (PPI), E)
|
|
||||||
#define pp_assignment_expression(PPI, E) \
|
|
||||||
pp_c_base (PPI)->assignment_expression (pp_c_base (PPI), E)
|
|
||||||
#define pp_expression(PP, E) \
|
|
||||||
pp_c_base (PP)->expression (pp_c_base (PP), E)
|
|
||||||
|
|
||||||
|
|
||||||
/* Returns the c_pretty_printer base object of PRETTY-PRINTER. This
|
|
||||||
macro must be overridden by any subclass of c_pretty_print_info. */
|
|
||||||
#define pp_c_base(PP) (PP)
|
|
||||||
|
|
||||||
extern void pp_c_pretty_printer_init (c_pretty_printer *);
|
|
||||||
void pp_c_whitespace (c_pretty_printer *);
|
|
||||||
void pp_c_left_paren (c_pretty_printer *);
|
|
||||||
void pp_c_right_paren (c_pretty_printer *);
|
|
||||||
void pp_c_left_brace (c_pretty_printer *);
|
|
||||||
void pp_c_right_brace (c_pretty_printer *);
|
|
||||||
void pp_c_left_bracket (c_pretty_printer *);
|
|
||||||
void pp_c_right_bracket (c_pretty_printer *);
|
|
||||||
void pp_c_dot (c_pretty_printer *);
|
|
||||||
void pp_c_ampersand (c_pretty_printer *);
|
|
||||||
void pp_c_star (c_pretty_printer *);
|
|
||||||
void pp_c_arrow (c_pretty_printer *);
|
|
||||||
void pp_c_semicolon (c_pretty_printer *);
|
|
||||||
void pp_c_complement (c_pretty_printer *);
|
|
||||||
void pp_c_exclamation (c_pretty_printer *);
|
|
||||||
void pp_c_space_for_pointer_operator (c_pretty_printer *, tree);
|
|
||||||
|
|
||||||
/* Declarations. */
|
|
||||||
void pp_c_tree_decl_identifier (c_pretty_printer *, tree);
|
|
||||||
void pp_c_function_definition (c_pretty_printer *, tree);
|
|
||||||
void pp_c_attributes (c_pretty_printer *, tree);
|
|
||||||
void pp_c_attributes_display (c_pretty_printer *, tree);
|
|
||||||
void pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool func_type);
|
|
||||||
void pp_c_type_qualifier_list (c_pretty_printer *, tree);
|
|
||||||
void pp_c_parameter_type_list (c_pretty_printer *, tree);
|
|
||||||
void pp_c_declaration (c_pretty_printer *, tree);
|
|
||||||
void pp_c_declaration_specifiers (c_pretty_printer *, tree);
|
|
||||||
void pp_c_declarator (c_pretty_printer *, tree);
|
|
||||||
void pp_c_direct_declarator (c_pretty_printer *, tree);
|
|
||||||
void pp_c_specifier_qualifier_list (c_pretty_printer *, tree);
|
|
||||||
void pp_c_function_specifier (c_pretty_printer *, tree);
|
|
||||||
void pp_c_type_id (c_pretty_printer *, tree);
|
|
||||||
void pp_c_direct_abstract_declarator (c_pretty_printer *, tree);
|
|
||||||
void pp_c_type_specifier (c_pretty_printer *, tree);
|
|
||||||
void pp_c_storage_class_specifier (c_pretty_printer *, tree);
|
|
||||||
/* Statements. */
|
|
||||||
void pp_c_statement (c_pretty_printer *, tree);
|
|
||||||
/* Expressions. */
|
|
||||||
void pp_c_expression (c_pretty_printer *, tree);
|
|
||||||
void pp_c_logical_or_expression (c_pretty_printer *, tree);
|
|
||||||
void pp_c_expression_list (c_pretty_printer *, tree);
|
|
||||||
void pp_c_constructor_elts (c_pretty_printer *, vec<constructor_elt, va_gc> *);
|
|
||||||
void pp_c_call_argument_list (c_pretty_printer *, tree);
|
|
||||||
void pp_c_unary_expression (c_pretty_printer *, tree);
|
|
||||||
void pp_c_cast_expression (c_pretty_printer *, tree);
|
|
||||||
void pp_c_postfix_expression (c_pretty_printer *, tree);
|
|
||||||
void pp_c_primary_expression (c_pretty_printer *, tree);
|
|
||||||
void pp_c_init_declarator (c_pretty_printer *, tree);
|
|
||||||
void pp_c_constant (c_pretty_printer *, tree);
|
|
||||||
void pp_c_id_expression (c_pretty_printer *, tree);
|
|
||||||
void pp_c_ws_string (c_pretty_printer *, const char *);
|
|
||||||
void pp_c_identifier (c_pretty_printer *, const char *);
|
|
||||||
void pp_c_string_literal (c_pretty_printer *, tree);
|
|
||||||
|
|
||||||
void print_c_tree (FILE *file, tree t);
|
|
||||||
|
|
||||||
#endif /* GCC_C_PRETTY_PRINTER */
|
|
@ -1,673 +0,0 @@
|
|||||||
/* Definitions for C parsing and type checking.
|
|
||||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_C_TREE_H
|
|
||||||
#define GCC_C_TREE_H
|
|
||||||
|
|
||||||
#include "c-family/c-common.h"
|
|
||||||
#include "diagnostic.h"
|
|
||||||
|
|
||||||
/* struct lang_identifier is private to c-decl.c, but langhooks.c needs to
|
|
||||||
know how big it is. This is sanity-checked in c-decl.c. */
|
|
||||||
#define C_SIZEOF_STRUCT_LANG_IDENTIFIER \
|
|
||||||
(sizeof (struct c_common_identifier) + 3 * sizeof (void *))
|
|
||||||
|
|
||||||
/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */
|
|
||||||
#define C_TYPE_FIELDS_READONLY(TYPE) TREE_LANG_FLAG_1 (TYPE)
|
|
||||||
|
|
||||||
/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is volatile. */
|
|
||||||
#define C_TYPE_FIELDS_VOLATILE(TYPE) TREE_LANG_FLAG_2 (TYPE)
|
|
||||||
|
|
||||||
/* In a RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE
|
|
||||||
nonzero if the definition of the type has already started. */
|
|
||||||
#define C_TYPE_BEING_DEFINED(TYPE) TYPE_LANG_FLAG_0 (TYPE)
|
|
||||||
|
|
||||||
/* In an incomplete RECORD_TYPE or UNION_TYPE, a list of variable
|
|
||||||
declarations whose type would be completed by completing that type. */
|
|
||||||
#define C_TYPE_INCOMPLETE_VARS(TYPE) TYPE_VFIELD (TYPE)
|
|
||||||
|
|
||||||
/* In an IDENTIFIER_NODE, nonzero if this identifier is actually a
|
|
||||||
keyword. C_RID_CODE (node) is then the RID_* value of the keyword,
|
|
||||||
and C_RID_YYCODE is the token number wanted by Yacc. */
|
|
||||||
#define C_IS_RESERVED_WORD(ID) TREE_LANG_FLAG_0 (ID)
|
|
||||||
|
|
||||||
/* Record whether a type or decl was written with nonconstant size.
|
|
||||||
Note that TYPE_SIZE may have simplified to a constant. */
|
|
||||||
#define C_TYPE_VARIABLE_SIZE(TYPE) TYPE_LANG_FLAG_1 (TYPE)
|
|
||||||
#define C_DECL_VARIABLE_SIZE(TYPE) DECL_LANG_FLAG_0 (TYPE)
|
|
||||||
|
|
||||||
/* Record whether a type is defined inside a struct or union type.
|
|
||||||
This is used for -Wc++-compat. */
|
|
||||||
#define C_TYPE_DEFINED_IN_STRUCT(TYPE) TYPE_LANG_FLAG_2 (TYPE)
|
|
||||||
|
|
||||||
/* Record whether a typedef for type `int' was actually `signed int'. */
|
|
||||||
#define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP)
|
|
||||||
|
|
||||||
/* For a FUNCTION_DECL, nonzero if it was defined without an explicit
|
|
||||||
return type. */
|
|
||||||
#define C_FUNCTION_IMPLICIT_INT(EXP) DECL_LANG_FLAG_1 (EXP)
|
|
||||||
|
|
||||||
/* For a FUNCTION_DECL, nonzero if it was an implicit declaration. */
|
|
||||||
#define C_DECL_IMPLICIT(EXP) DECL_LANG_FLAG_2 (EXP)
|
|
||||||
|
|
||||||
/* For FUNCTION_DECLs, evaluates true if the decl is built-in but has
|
|
||||||
been declared. */
|
|
||||||
#define C_DECL_DECLARED_BUILTIN(EXP) \
|
|
||||||
DECL_LANG_FLAG_3 (FUNCTION_DECL_CHECK (EXP))
|
|
||||||
|
|
||||||
/* For FUNCTION_DECLs, evaluates true if the decl is built-in, has a
|
|
||||||
built-in prototype and does not have a non-built-in prototype. */
|
|
||||||
#define C_DECL_BUILTIN_PROTOTYPE(EXP) \
|
|
||||||
DECL_LANG_FLAG_6 (FUNCTION_DECL_CHECK (EXP))
|
|
||||||
|
|
||||||
/* Record whether a decl was declared register. This is strictly a
|
|
||||||
front-end flag, whereas DECL_REGISTER is used for code generation;
|
|
||||||
they may differ for structures with volatile fields. */
|
|
||||||
#define C_DECL_REGISTER(EXP) DECL_LANG_FLAG_4 (EXP)
|
|
||||||
|
|
||||||
/* Record whether a decl was used in an expression anywhere except an
|
|
||||||
unevaluated operand of sizeof / typeof / alignof. This is only
|
|
||||||
used for functions declared static but not defined, though outside
|
|
||||||
sizeof and typeof it is set for other function decls as well. */
|
|
||||||
#define C_DECL_USED(EXP) DECL_LANG_FLAG_5 (FUNCTION_DECL_CHECK (EXP))
|
|
||||||
|
|
||||||
/* Record whether a variable has been declared threadprivate by
|
|
||||||
#pragma omp threadprivate. */
|
|
||||||
#define C_DECL_THREADPRIVATE_P(DECL) DECL_LANG_FLAG_3 (VAR_DECL_CHECK (DECL))
|
|
||||||
|
|
||||||
/* Nonzero for a decl which either doesn't exist or isn't a prototype.
|
|
||||||
N.B. Could be simplified if all built-in decls had complete prototypes
|
|
||||||
(but this is presently difficult because some of them need FILE*). */
|
|
||||||
#define C_DECL_ISNT_PROTOTYPE(EXP) \
|
|
||||||
(EXP == 0 \
|
|
||||||
|| (!prototype_p (TREE_TYPE (EXP)) \
|
|
||||||
&& !DECL_BUILT_IN (EXP)))
|
|
||||||
|
|
||||||
/* For FUNCTION_TYPE, a hidden list of types of arguments. The same as
|
|
||||||
TYPE_ARG_TYPES for functions with prototypes, but created for functions
|
|
||||||
without prototypes. */
|
|
||||||
#define TYPE_ACTUAL_ARG_TYPES(NODE) TYPE_LANG_SLOT_1 (NODE)
|
|
||||||
|
|
||||||
/* For a CONSTRUCTOR, whether some initializer contains a
|
|
||||||
subexpression meaning it is not a constant expression. */
|
|
||||||
#define CONSTRUCTOR_NON_CONST(EXPR) TREE_LANG_FLAG_1 (CONSTRUCTOR_CHECK (EXPR))
|
|
||||||
|
|
||||||
/* Record parser information about an expression that is irrelevant
|
|
||||||
for code generation alongside a tree representing its value. */
|
|
||||||
struct c_expr
|
|
||||||
{
|
|
||||||
/* The value of the expression. */
|
|
||||||
tree value;
|
|
||||||
/* Record the original unary/binary operator of an expression, which may
|
|
||||||
have been changed by fold, STRING_CST for unparenthesized string
|
|
||||||
constants, C_MAYBE_CONST_EXPR for __builtin_constant_p calls
|
|
||||||
(even if parenthesized), for subexpressions, and for non-constant
|
|
||||||
initializers, or ERROR_MARK for other expressions (including
|
|
||||||
parenthesized expressions). */
|
|
||||||
enum tree_code original_code;
|
|
||||||
/* If not NULL, the original type of an expression. This will
|
|
||||||
differ from the type of the value field for an enum constant.
|
|
||||||
The type of an enum constant is a plain integer type, but this
|
|
||||||
field will be the enum type. */
|
|
||||||
tree original_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Type alias for struct c_expr. This allows to use the structure
|
|
||||||
inside the VEC types. */
|
|
||||||
typedef struct c_expr c_expr_t;
|
|
||||||
|
|
||||||
/* A varray of c_expr_t. */
|
|
||||||
|
|
||||||
/* Append a new c_expr_t element to V. */
|
|
||||||
#define C_EXPR_APPEND(V, ELEM) \
|
|
||||||
do { \
|
|
||||||
c_expr_t __elem = (ELEM); \
|
|
||||||
vec_safe_push (V, __elem); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* A kind of type specifier. Note that this information is currently
|
|
||||||
only used to distinguish tag definitions, tag references and typeof
|
|
||||||
uses. */
|
|
||||||
enum c_typespec_kind {
|
|
||||||
/* No typespec. This appears only in struct c_declspec. */
|
|
||||||
ctsk_none,
|
|
||||||
/* A reserved keyword type specifier. */
|
|
||||||
ctsk_resword,
|
|
||||||
/* A reference to a tag, previously declared, such as "struct foo".
|
|
||||||
This includes where the previous declaration was as a different
|
|
||||||
kind of tag, in which case this is only valid if shadowing that
|
|
||||||
tag in an inner scope. */
|
|
||||||
ctsk_tagref,
|
|
||||||
/* A reference to a tag, not previously declared in a visible
|
|
||||||
scope. */
|
|
||||||
ctsk_tagfirstref,
|
|
||||||
/* A definition of a tag such as "struct foo { int a; }". */
|
|
||||||
ctsk_tagdef,
|
|
||||||
/* A typedef name. */
|
|
||||||
ctsk_typedef,
|
|
||||||
/* An ObjC-specific kind of type specifier. */
|
|
||||||
ctsk_objc,
|
|
||||||
/* A typeof specifier. */
|
|
||||||
ctsk_typeof
|
|
||||||
};
|
|
||||||
|
|
||||||
/* A type specifier: this structure is created in the parser and
|
|
||||||
passed to declspecs_add_type only. */
|
|
||||||
struct c_typespec {
|
|
||||||
/* What kind of type specifier this is. */
|
|
||||||
enum c_typespec_kind kind;
|
|
||||||
/* Whether the expression has operands suitable for use in constant
|
|
||||||
expressions. */
|
|
||||||
bool expr_const_operands;
|
|
||||||
/* The specifier itself. */
|
|
||||||
tree spec;
|
|
||||||
/* An expression to be evaluated before the type specifier, in the
|
|
||||||
case of typeof specifiers, or NULL otherwise or if no such
|
|
||||||
expression is required for a particular typeof specifier. In
|
|
||||||
particular, when typeof is applied to an expression of variably
|
|
||||||
modified type, that expression must be evaluated in order to
|
|
||||||
determine array sizes that form part of the type, but the
|
|
||||||
expression itself (as opposed to the array sizes) forms no part
|
|
||||||
of the type and so needs to be recorded separately. */
|
|
||||||
tree expr;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* A storage class specifier. */
|
|
||||||
enum c_storage_class {
|
|
||||||
csc_none,
|
|
||||||
csc_auto,
|
|
||||||
csc_extern,
|
|
||||||
csc_register,
|
|
||||||
csc_static,
|
|
||||||
csc_typedef
|
|
||||||
};
|
|
||||||
|
|
||||||
/* A type specifier keyword "void", "_Bool", "char", "int", "float",
|
|
||||||
"double", "_Decimal32", "_Decimal64", "_Decimal128", "_Fract", "_Accum",
|
|
||||||
or none of these. */
|
|
||||||
enum c_typespec_keyword {
|
|
||||||
cts_none,
|
|
||||||
cts_void,
|
|
||||||
cts_bool,
|
|
||||||
cts_char,
|
|
||||||
cts_int,
|
|
||||||
cts_float,
|
|
||||||
cts_int128,
|
|
||||||
cts_double,
|
|
||||||
cts_dfloat32,
|
|
||||||
cts_dfloat64,
|
|
||||||
cts_dfloat128,
|
|
||||||
cts_fract,
|
|
||||||
cts_accum
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This enum lists all the possible declarator specifiers, storage
|
|
||||||
class or attribute that a user can write. There is at least one
|
|
||||||
enumerator per possible declarator specifier in the struct
|
|
||||||
c_declspecs below.
|
|
||||||
|
|
||||||
It is used to index the array of declspec locations in struct
|
|
||||||
c_declspecs. */
|
|
||||||
enum c_declspec_word {
|
|
||||||
cdw_typespec /* A catch-all for a typespec. */,
|
|
||||||
cdw_storage_class /* A catch-all for a storage class */,
|
|
||||||
cdw_attributes,
|
|
||||||
cdw_typedef,
|
|
||||||
cdw_explicit_signed,
|
|
||||||
cdw_deprecated,
|
|
||||||
cdw_default_int,
|
|
||||||
cdw_long,
|
|
||||||
cdw_long_long,
|
|
||||||
cdw_short,
|
|
||||||
cdw_signed,
|
|
||||||
cdw_unsigned,
|
|
||||||
cdw_complex,
|
|
||||||
cdw_inline,
|
|
||||||
cdw_noreturn,
|
|
||||||
cdw_thread,
|
|
||||||
cdw_const,
|
|
||||||
cdw_volatile,
|
|
||||||
cdw_restrict,
|
|
||||||
cdw_saturating,
|
|
||||||
cdw_alignas,
|
|
||||||
cdw_address_space,
|
|
||||||
cdw_number_of_elements /* This one must always be the last
|
|
||||||
enumerator. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* A sequence of declaration specifiers in C. When a new declaration
|
|
||||||
specifier is added, please update the enum c_declspec_word above
|
|
||||||
accordingly. */
|
|
||||||
struct c_declspecs {
|
|
||||||
source_location locations[cdw_number_of_elements];
|
|
||||||
/* The type specified, if a single type specifier such as a struct,
|
|
||||||
union or enum specifier, typedef name or typeof specifies the
|
|
||||||
whole type, or NULL_TREE if none or a keyword such as "void" or
|
|
||||||
"char" is used. Does not include qualifiers. */
|
|
||||||
tree type;
|
|
||||||
/* Any expression to be evaluated before the type, from a typeof
|
|
||||||
specifier. */
|
|
||||||
tree expr;
|
|
||||||
/* The attributes from a typedef decl. */
|
|
||||||
tree decl_attr;
|
|
||||||
/* When parsing, the attributes. Outside the parser, this will be
|
|
||||||
NULL; attributes (possibly from multiple lists) will be passed
|
|
||||||
separately. */
|
|
||||||
tree attrs;
|
|
||||||
/* The base-2 log of the greatest alignment required by an _Alignas
|
|
||||||
specifier, in bytes, or -1 if no such specifiers with nonzero
|
|
||||||
alignment. */
|
|
||||||
int align_log;
|
|
||||||
/* The storage class specifier, or csc_none if none. */
|
|
||||||
enum c_storage_class storage_class;
|
|
||||||
/* Any type specifier keyword used such as "int", not reflecting
|
|
||||||
modifiers such as "short", or cts_none if none. */
|
|
||||||
ENUM_BITFIELD (c_typespec_keyword) typespec_word : 8;
|
|
||||||
/* The kind of type specifier if one has been seen, ctsk_none
|
|
||||||
otherwise. */
|
|
||||||
ENUM_BITFIELD (c_typespec_kind) typespec_kind : 3;
|
|
||||||
/* Whether any expressions in typeof specifiers may appear in
|
|
||||||
constant expressions. */
|
|
||||||
BOOL_BITFIELD expr_const_operands : 1;
|
|
||||||
/* Whether any declaration specifiers have been seen at all. */
|
|
||||||
BOOL_BITFIELD declspecs_seen_p : 1;
|
|
||||||
/* Whether something other than a storage class specifier or
|
|
||||||
attribute has been seen. This is used to warn for the
|
|
||||||
obsolescent usage of storage class specifiers other than at the
|
|
||||||
start of the list. (Doing this properly would require function
|
|
||||||
specifiers to be handled separately from storage class
|
|
||||||
specifiers.) */
|
|
||||||
BOOL_BITFIELD non_sc_seen_p : 1;
|
|
||||||
/* Whether the type is specified by a typedef or typeof name. */
|
|
||||||
BOOL_BITFIELD typedef_p : 1;
|
|
||||||
/* Whether the type is explicitly "signed" or specified by a typedef
|
|
||||||
whose type is explicitly "signed". */
|
|
||||||
BOOL_BITFIELD explicit_signed_p : 1;
|
|
||||||
/* Whether the specifiers include a deprecated typedef. */
|
|
||||||
BOOL_BITFIELD deprecated_p : 1;
|
|
||||||
/* Whether the type defaulted to "int" because there were no type
|
|
||||||
specifiers. */
|
|
||||||
BOOL_BITFIELD default_int_p : 1;
|
|
||||||
/* Whether "long" was specified. */
|
|
||||||
BOOL_BITFIELD long_p : 1;
|
|
||||||
/* Whether "long" was specified more than once. */
|
|
||||||
BOOL_BITFIELD long_long_p : 1;
|
|
||||||
/* Whether "short" was specified. */
|
|
||||||
BOOL_BITFIELD short_p : 1;
|
|
||||||
/* Whether "signed" was specified. */
|
|
||||||
BOOL_BITFIELD signed_p : 1;
|
|
||||||
/* Whether "unsigned" was specified. */
|
|
||||||
BOOL_BITFIELD unsigned_p : 1;
|
|
||||||
/* Whether "complex" was specified. */
|
|
||||||
BOOL_BITFIELD complex_p : 1;
|
|
||||||
/* Whether "inline" was specified. */
|
|
||||||
BOOL_BITFIELD inline_p : 1;
|
|
||||||
/* Whether "_Noreturn" was speciied. */
|
|
||||||
BOOL_BITFIELD noreturn_p : 1;
|
|
||||||
/* Whether "__thread" was specified. */
|
|
||||||
BOOL_BITFIELD thread_p : 1;
|
|
||||||
/* Whether "const" was specified. */
|
|
||||||
BOOL_BITFIELD const_p : 1;
|
|
||||||
/* Whether "volatile" was specified. */
|
|
||||||
BOOL_BITFIELD volatile_p : 1;
|
|
||||||
/* Whether "restrict" was specified. */
|
|
||||||
BOOL_BITFIELD restrict_p : 1;
|
|
||||||
/* Whether "_Sat" was specified. */
|
|
||||||
BOOL_BITFIELD saturating_p : 1;
|
|
||||||
/* Whether any alignment specifier (even with zero alignment) was
|
|
||||||
specified. */
|
|
||||||
BOOL_BITFIELD alignas_p : 1;
|
|
||||||
/* The address space that the declaration belongs to. */
|
|
||||||
addr_space_t address_space;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The various kinds of declarators in C. */
|
|
||||||
enum c_declarator_kind {
|
|
||||||
/* An identifier. */
|
|
||||||
cdk_id,
|
|
||||||
/* A function. */
|
|
||||||
cdk_function,
|
|
||||||
/* An array. */
|
|
||||||
cdk_array,
|
|
||||||
/* A pointer. */
|
|
||||||
cdk_pointer,
|
|
||||||
/* Parenthesized declarator with nested attributes. */
|
|
||||||
cdk_attrs
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct c_arg_tag_d {
|
|
||||||
/* The argument name. */
|
|
||||||
tree id;
|
|
||||||
/* The type of the argument. */
|
|
||||||
tree type;
|
|
||||||
} c_arg_tag;
|
|
||||||
|
|
||||||
|
|
||||||
/* Information about the parameters in a function declarator. */
|
|
||||||
struct c_arg_info {
|
|
||||||
/* A list of parameter decls. */
|
|
||||||
tree parms;
|
|
||||||
/* A list of structure, union and enum tags defined. */
|
|
||||||
vec<c_arg_tag, va_gc> *tags;
|
|
||||||
/* A list of argument types to go in the FUNCTION_TYPE. */
|
|
||||||
tree types;
|
|
||||||
/* A list of non-parameter decls (notably enumeration constants)
|
|
||||||
defined with the parameters. */
|
|
||||||
tree others;
|
|
||||||
/* A compound expression of VLA sizes from the parameters, or NULL.
|
|
||||||
In a function definition, these are used to ensure that
|
|
||||||
side-effects in sizes of arrays converted to pointers (such as a
|
|
||||||
parameter int i[n++]) take place; otherwise, they are
|
|
||||||
ignored. */
|
|
||||||
tree pending_sizes;
|
|
||||||
/* True when these arguments had [*]. */
|
|
||||||
BOOL_BITFIELD had_vla_unspec : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* A declarator. */
|
|
||||||
struct c_declarator {
|
|
||||||
/* The kind of declarator. */
|
|
||||||
enum c_declarator_kind kind;
|
|
||||||
location_t id_loc; /* Currently only set for cdk_id, cdk_array. */
|
|
||||||
/* Except for cdk_id, the contained declarator. For cdk_id, NULL. */
|
|
||||||
struct c_declarator *declarator;
|
|
||||||
union {
|
|
||||||
/* For identifiers, an IDENTIFIER_NODE or NULL_TREE if an abstract
|
|
||||||
declarator. */
|
|
||||||
tree id;
|
|
||||||
/* For functions. */
|
|
||||||
struct c_arg_info *arg_info;
|
|
||||||
/* For arrays. */
|
|
||||||
struct {
|
|
||||||
/* The array dimension, or NULL for [] and [*]. */
|
|
||||||
tree dimen;
|
|
||||||
/* The qualifiers inside []. */
|
|
||||||
int quals;
|
|
||||||
/* The attributes (currently ignored) inside []. */
|
|
||||||
tree attrs;
|
|
||||||
/* Whether [static] was used. */
|
|
||||||
BOOL_BITFIELD static_p : 1;
|
|
||||||
/* Whether [*] was used. */
|
|
||||||
BOOL_BITFIELD vla_unspec_p : 1;
|
|
||||||
} array;
|
|
||||||
/* For pointers, the qualifiers on the pointer type. */
|
|
||||||
int pointer_quals;
|
|
||||||
/* For attributes. */
|
|
||||||
tree attrs;
|
|
||||||
} u;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* A type name. */
|
|
||||||
struct c_type_name {
|
|
||||||
/* The declaration specifiers. */
|
|
||||||
struct c_declspecs *specs;
|
|
||||||
/* The declarator. */
|
|
||||||
struct c_declarator *declarator;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* A parameter. */
|
|
||||||
struct c_parm {
|
|
||||||
/* The declaration specifiers, minus any prefix attributes. */
|
|
||||||
struct c_declspecs *specs;
|
|
||||||
/* The attributes. */
|
|
||||||
tree attrs;
|
|
||||||
/* The declarator. */
|
|
||||||
struct c_declarator *declarator;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Used when parsing an enum. Initialized by start_enum. */
|
|
||||||
struct c_enum_contents
|
|
||||||
{
|
|
||||||
/* While defining an enum type, this is 1 plus the last enumerator
|
|
||||||
constant value. */
|
|
||||||
tree enum_next_value;
|
|
||||||
|
|
||||||
/* Nonzero means that there was overflow computing enum_next_value. */
|
|
||||||
int enum_overflow;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* A type of reference to a static identifier in an inline
|
|
||||||
function. */
|
|
||||||
enum c_inline_static_type {
|
|
||||||
/* Identifier with internal linkage used in function that may be an
|
|
||||||
inline definition (i.e., file-scope static). */
|
|
||||||
csi_internal,
|
|
||||||
/* Modifiable object with static storage duration defined in
|
|
||||||
function that may be an inline definition (i.e., local
|
|
||||||
static). */
|
|
||||||
csi_modifiable
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* in c-parser.c */
|
|
||||||
extern void c_parse_init (void);
|
|
||||||
|
|
||||||
/* in c-aux-info.c */
|
|
||||||
extern void gen_aux_info_record (tree, int, int, int);
|
|
||||||
|
|
||||||
/* in c-decl.c */
|
|
||||||
struct c_spot_bindings;
|
|
||||||
struct c_struct_parse_info;
|
|
||||||
extern struct obstack parser_obstack;
|
|
||||||
extern tree c_break_label;
|
|
||||||
extern tree c_cont_label;
|
|
||||||
|
|
||||||
extern bool global_bindings_p (void);
|
|
||||||
extern void push_scope (void);
|
|
||||||
extern tree pop_scope (void);
|
|
||||||
extern void c_bindings_start_stmt_expr (struct c_spot_bindings *);
|
|
||||||
extern void c_bindings_end_stmt_expr (struct c_spot_bindings *);
|
|
||||||
|
|
||||||
extern void record_inline_static (location_t, tree, tree,
|
|
||||||
enum c_inline_static_type);
|
|
||||||
extern void c_init_decl_processing (void);
|
|
||||||
extern void c_print_identifier (FILE *, tree, int);
|
|
||||||
extern int quals_from_declspecs (const struct c_declspecs *);
|
|
||||||
extern struct c_declarator *build_array_declarator (location_t, tree,
|
|
||||||
struct c_declspecs *,
|
|
||||||
bool, bool);
|
|
||||||
extern tree build_enumerator (location_t, location_t, struct c_enum_contents *,
|
|
||||||
tree, tree);
|
|
||||||
extern tree check_for_loop_decls (location_t, bool);
|
|
||||||
extern void mark_forward_parm_decls (void);
|
|
||||||
extern void declare_parm_level (void);
|
|
||||||
extern void undeclared_variable (location_t, tree);
|
|
||||||
extern tree lookup_label_for_goto (location_t, tree);
|
|
||||||
extern tree declare_label (tree);
|
|
||||||
extern tree define_label (location_t, tree);
|
|
||||||
extern struct c_spot_bindings *c_get_switch_bindings (void);
|
|
||||||
extern void c_release_switch_bindings (struct c_spot_bindings *);
|
|
||||||
extern bool c_check_switch_jump_warnings (struct c_spot_bindings *,
|
|
||||||
location_t, location_t);
|
|
||||||
extern void finish_decl (tree, location_t, tree, tree, tree);
|
|
||||||
extern tree finish_enum (tree, tree, tree);
|
|
||||||
extern void finish_function (void);
|
|
||||||
extern tree finish_struct (location_t, tree, tree, tree,
|
|
||||||
struct c_struct_parse_info *);
|
|
||||||
extern struct c_arg_info *build_arg_info (void);
|
|
||||||
extern struct c_arg_info *get_parm_info (bool, tree);
|
|
||||||
extern tree grokfield (location_t, struct c_declarator *,
|
|
||||||
struct c_declspecs *, tree, tree *);
|
|
||||||
extern tree groktypename (struct c_type_name *, tree *, bool *);
|
|
||||||
extern tree grokparm (const struct c_parm *, tree *);
|
|
||||||
extern tree implicitly_declare (location_t, tree);
|
|
||||||
extern void keep_next_level (void);
|
|
||||||
extern void pending_xref_error (void);
|
|
||||||
extern void c_push_function_context (void);
|
|
||||||
extern void c_pop_function_context (void);
|
|
||||||
extern void push_parm_decl (const struct c_parm *, tree *);
|
|
||||||
extern struct c_declarator *set_array_declarator_inner (struct c_declarator *,
|
|
||||||
struct c_declarator *);
|
|
||||||
extern tree c_builtin_function (tree);
|
|
||||||
extern tree c_builtin_function_ext_scope (tree);
|
|
||||||
extern void shadow_tag (const struct c_declspecs *);
|
|
||||||
extern void shadow_tag_warned (const struct c_declspecs *, int);
|
|
||||||
extern tree start_enum (location_t, struct c_enum_contents *, tree);
|
|
||||||
extern int start_function (struct c_declspecs *, struct c_declarator *, tree);
|
|
||||||
extern tree start_decl (struct c_declarator *, struct c_declspecs *, bool,
|
|
||||||
tree);
|
|
||||||
extern tree start_struct (location_t, enum tree_code, tree,
|
|
||||||
struct c_struct_parse_info **);
|
|
||||||
extern void store_parm_decls (void);
|
|
||||||
extern void store_parm_decls_from (struct c_arg_info *);
|
|
||||||
extern tree xref_tag (enum tree_code, tree);
|
|
||||||
extern struct c_typespec parser_xref_tag (location_t, enum tree_code, tree);
|
|
||||||
extern struct c_parm *build_c_parm (struct c_declspecs *, tree,
|
|
||||||
struct c_declarator *);
|
|
||||||
extern struct c_declarator *build_attrs_declarator (tree,
|
|
||||||
struct c_declarator *);
|
|
||||||
extern struct c_declarator *build_function_declarator (struct c_arg_info *,
|
|
||||||
struct c_declarator *);
|
|
||||||
extern struct c_declarator *build_id_declarator (tree);
|
|
||||||
extern struct c_declarator *make_pointer_declarator (struct c_declspecs *,
|
|
||||||
struct c_declarator *);
|
|
||||||
extern struct c_declspecs *build_null_declspecs (void);
|
|
||||||
extern struct c_declspecs *declspecs_add_qual (source_location,
|
|
||||||
struct c_declspecs *, tree);
|
|
||||||
extern struct c_declspecs *declspecs_add_type (location_t,
|
|
||||||
struct c_declspecs *,
|
|
||||||
struct c_typespec);
|
|
||||||
extern struct c_declspecs *declspecs_add_scspec (source_location,
|
|
||||||
struct c_declspecs *, tree);
|
|
||||||
extern struct c_declspecs *declspecs_add_attrs (source_location,
|
|
||||||
struct c_declspecs *, tree);
|
|
||||||
extern struct c_declspecs *declspecs_add_addrspace (source_location,
|
|
||||||
struct c_declspecs *,
|
|
||||||
addr_space_t);
|
|
||||||
extern struct c_declspecs *declspecs_add_alignas (source_location,
|
|
||||||
struct c_declspecs *, tree);
|
|
||||||
extern struct c_declspecs *finish_declspecs (struct c_declspecs *);
|
|
||||||
|
|
||||||
/* in c-objc-common.c */
|
|
||||||
extern bool c_objc_common_init (void);
|
|
||||||
extern bool c_missing_noreturn_ok_p (tree);
|
|
||||||
extern bool c_warn_unused_global_decl (const_tree);
|
|
||||||
extern void c_initialize_diagnostics (diagnostic_context *);
|
|
||||||
extern bool c_vla_unspec_p (tree x, tree fn);
|
|
||||||
|
|
||||||
/* in c-typeck.c */
|
|
||||||
extern int in_alignof;
|
|
||||||
extern int in_sizeof;
|
|
||||||
extern int in_typeof;
|
|
||||||
|
|
||||||
extern tree c_last_sizeof_arg;
|
|
||||||
|
|
||||||
extern struct c_switch *c_switch_stack;
|
|
||||||
|
|
||||||
extern tree c_objc_common_truthvalue_conversion (location_t, tree);
|
|
||||||
extern tree require_complete_type (tree);
|
|
||||||
extern int same_translation_unit_p (const_tree, const_tree);
|
|
||||||
extern int comptypes (tree, tree);
|
|
||||||
extern int comptypes_check_different_types (tree, tree, bool *);
|
|
||||||
extern bool c_vla_type_p (const_tree);
|
|
||||||
extern bool c_mark_addressable (tree);
|
|
||||||
extern void c_incomplete_type_error (const_tree, const_tree);
|
|
||||||
extern tree c_type_promotes_to (tree);
|
|
||||||
extern struct c_expr default_function_array_conversion (location_t,
|
|
||||||
struct c_expr);
|
|
||||||
extern struct c_expr default_function_array_read_conversion (location_t,
|
|
||||||
struct c_expr);
|
|
||||||
extern void mark_exp_read (tree);
|
|
||||||
extern tree composite_type (tree, tree);
|
|
||||||
extern tree build_component_ref (location_t, tree, tree);
|
|
||||||
extern tree build_array_ref (location_t, tree, tree);
|
|
||||||
extern tree build_external_ref (location_t, tree, int, tree *);
|
|
||||||
extern void pop_maybe_used (bool);
|
|
||||||
extern struct c_expr c_expr_sizeof_expr (location_t, struct c_expr);
|
|
||||||
extern struct c_expr c_expr_sizeof_type (location_t, struct c_type_name *);
|
|
||||||
extern struct c_expr parser_build_unary_op (location_t, enum tree_code,
|
|
||||||
struct c_expr);
|
|
||||||
extern struct c_expr parser_build_binary_op (location_t,
|
|
||||||
enum tree_code, struct c_expr,
|
|
||||||
struct c_expr);
|
|
||||||
extern tree build_conditional_expr (location_t, tree, bool, tree, tree,
|
|
||||||
tree, tree);
|
|
||||||
extern tree build_compound_expr (location_t, tree, tree);
|
|
||||||
extern tree c_cast_expr (location_t, struct c_type_name *, tree);
|
|
||||||
extern tree build_c_cast (location_t, tree, tree);
|
|
||||||
extern void store_init_value (location_t, tree, tree, tree);
|
|
||||||
extern void error_init (const char *);
|
|
||||||
extern void pedwarn_init (location_t, int opt, const char *);
|
|
||||||
extern void maybe_warn_string_init (tree, struct c_expr);
|
|
||||||
extern void start_init (tree, tree, int);
|
|
||||||
extern void finish_init (void);
|
|
||||||
extern void really_start_incremental_init (tree);
|
|
||||||
extern void push_init_level (int, struct obstack *);
|
|
||||||
extern struct c_expr pop_init_level (int, struct obstack *);
|
|
||||||
extern void set_init_index (tree, tree, struct obstack *);
|
|
||||||
extern void set_init_label (tree, struct obstack *);
|
|
||||||
extern void process_init_element (struct c_expr, bool, struct obstack *);
|
|
||||||
extern tree build_compound_literal (location_t, tree, tree, bool);
|
|
||||||
extern void check_compound_literal_type (location_t, struct c_type_name *);
|
|
||||||
extern tree c_start_case (location_t, location_t, tree);
|
|
||||||
extern void c_finish_case (tree);
|
|
||||||
extern tree build_asm_expr (location_t, tree, tree, tree, tree, tree, bool);
|
|
||||||
extern tree build_asm_stmt (tree, tree);
|
|
||||||
extern int c_types_compatible_p (tree, tree);
|
|
||||||
extern tree c_begin_compound_stmt (bool);
|
|
||||||
extern tree c_end_compound_stmt (location_t, tree, bool);
|
|
||||||
extern void c_finish_if_stmt (location_t, tree, tree, tree, bool);
|
|
||||||
extern void c_finish_loop (location_t, tree, tree, tree, tree, tree, bool);
|
|
||||||
extern tree c_begin_stmt_expr (void);
|
|
||||||
extern tree c_finish_stmt_expr (location_t, tree);
|
|
||||||
extern tree c_process_expr_stmt (location_t, tree);
|
|
||||||
extern tree c_finish_expr_stmt (location_t, tree);
|
|
||||||
extern tree c_finish_return (location_t, tree, tree);
|
|
||||||
extern tree c_finish_bc_stmt (location_t, tree *, bool);
|
|
||||||
extern tree c_finish_goto_label (location_t, tree);
|
|
||||||
extern tree c_finish_goto_ptr (location_t, tree);
|
|
||||||
extern tree c_expr_to_decl (tree, bool *, bool *);
|
|
||||||
extern tree c_begin_omp_parallel (void);
|
|
||||||
extern tree c_finish_omp_parallel (location_t, tree, tree);
|
|
||||||
extern tree c_begin_omp_task (void);
|
|
||||||
extern tree c_finish_omp_task (location_t, tree, tree);
|
|
||||||
extern tree c_finish_omp_clauses (tree);
|
|
||||||
extern tree c_build_va_arg (location_t, tree, tree);
|
|
||||||
extern tree c_finish_transaction (location_t, tree, int);
|
|
||||||
extern tree c_build_function_call_vec (location_t, tree, vec<tree, va_gc> *,
|
|
||||||
vec<tree, va_gc> *);
|
|
||||||
|
|
||||||
/* Set to 0 at beginning of a function definition, set to 1 if
|
|
||||||
a return statement that specifies a return value is seen. */
|
|
||||||
|
|
||||||
extern int current_function_returns_value;
|
|
||||||
|
|
||||||
/* Set to 0 at beginning of a function definition, set to 1 if
|
|
||||||
a return statement with no argument is seen. */
|
|
||||||
|
|
||||||
extern int current_function_returns_null;
|
|
||||||
|
|
||||||
/* Set to 0 at beginning of a function definition, set to 1 if
|
|
||||||
a call to a noreturn function is seen. */
|
|
||||||
|
|
||||||
extern int current_function_returns_abnormally;
|
|
||||||
|
|
||||||
/* Mode used to build pointers (VOIDmode means ptr_mode). */
|
|
||||||
|
|
||||||
extern enum machine_mode c_default_pointer_mode;
|
|
||||||
|
|
||||||
/* In c-decl.c */
|
|
||||||
extern void c_finish_incomplete_decl (tree);
|
|
||||||
extern void c_write_global_declarations (void);
|
|
||||||
|
|
||||||
/* In c-errors.c */
|
|
||||||
extern void pedwarn_c90 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
|
|
||||||
extern void pedwarn_c99 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
|
|
||||||
|
|
||||||
#endif /* ! GCC_C_TREE_H */
|
|
@ -1,186 +0,0 @@
|
|||||||
/* Flags on basic blocks and edges.
|
|
||||||
Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* This file defines flags that may appear on basic blocks or on
|
|
||||||
edges. Source files define DEF_BASIC_BLOCK_FLAG or DEF_EDGE_FLAG
|
|
||||||
appropriately before including this file. */
|
|
||||||
|
|
||||||
#if !defined(DEF_BASIC_BLOCK_FLAG) && !defined(DEF_EDGE_FLAG)
|
|
||||||
#error "You must define DEF_BASIC_BLOCK_FLAG or DEF_EDGE_FLAG"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEF_BASIC_BLOCK_FLAG
|
|
||||||
|
|
||||||
/* Masks for basic_block.flags.
|
|
||||||
|
|
||||||
The format of this file is: DEF_BASIC_BLOCK_FLAG(NAME, IDX).
|
|
||||||
NAME is the name of the basic block flag. A flag BB_#NAME will be
|
|
||||||
created and the name is used in dump_edge_info.
|
|
||||||
IDX is a sequence number that is used to determine the value
|
|
||||||
of the flag, which is 1 << IDX).
|
|
||||||
|
|
||||||
BB_HOT_PARTITION and BB_COLD_PARTITION should be preserved throughout
|
|
||||||
the compilation, so they are never cleared.
|
|
||||||
|
|
||||||
All other flags may be cleared by clear_bb_flags(). It is generally
|
|
||||||
a bad idea to rely on any flags being up-to-date. */
|
|
||||||
|
|
||||||
/* Only set on blocks that have just been created by create_bb. */
|
|
||||||
DEF_BASIC_BLOCK_FLAG(NEW, 0)
|
|
||||||
|
|
||||||
/* Set by find_unreachable_blocks. Do not rely on this being set in any
|
|
||||||
pass. */
|
|
||||||
DEF_BASIC_BLOCK_FLAG(REACHABLE, 1)
|
|
||||||
|
|
||||||
/* Set for blocks in an irreducible loop by loop analysis. */
|
|
||||||
DEF_BASIC_BLOCK_FLAG(IRREDUCIBLE_LOOP, 2)
|
|
||||||
|
|
||||||
/* Set on blocks that may actually not be single-entry single-exit block. */
|
|
||||||
DEF_BASIC_BLOCK_FLAG(SUPERBLOCK, 3)
|
|
||||||
|
|
||||||
/* Set on basic blocks that the scheduler should not touch. This is used
|
|
||||||
by SMS to prevent other schedulers from messing with the loop schedule. */
|
|
||||||
DEF_BASIC_BLOCK_FLAG(DISABLE_SCHEDULE, 4)
|
|
||||||
|
|
||||||
/* Set on blocks that should be put in a hot section. */
|
|
||||||
DEF_BASIC_BLOCK_FLAG(HOT_PARTITION, 5)
|
|
||||||
|
|
||||||
/* Set on blocks that should be put in a cold section. */
|
|
||||||
DEF_BASIC_BLOCK_FLAG(COLD_PARTITION, 6)
|
|
||||||
|
|
||||||
/* Set on block that was duplicated. */
|
|
||||||
DEF_BASIC_BLOCK_FLAG(DUPLICATED, 7)
|
|
||||||
|
|
||||||
/* Set if the label at the top of this block is the target of a non-local goto. */
|
|
||||||
DEF_BASIC_BLOCK_FLAG(NON_LOCAL_GOTO_TARGET, 8)
|
|
||||||
|
|
||||||
/* Set on blocks that are in RTL format. */
|
|
||||||
DEF_BASIC_BLOCK_FLAG(RTL, 9)
|
|
||||||
|
|
||||||
/* Set on blocks that are forwarder blocks.
|
|
||||||
Only used in cfgcleanup.c. */
|
|
||||||
DEF_BASIC_BLOCK_FLAG(FORWARDER_BLOCK, 10)
|
|
||||||
|
|
||||||
/* Set on blocks that cannot be threaded through.
|
|
||||||
Only used in cfgcleanup.c. */
|
|
||||||
DEF_BASIC_BLOCK_FLAG(NONTHREADABLE_BLOCK, 11)
|
|
||||||
|
|
||||||
/* Set on blocks that were modified in some way. This bit is set in
|
|
||||||
df_set_bb_dirty, but not cleared by df_analyze, so it can be used
|
|
||||||
to test whether a block has been modified prior to a df_analyze call. */
|
|
||||||
DEF_BASIC_BLOCK_FLAG(MODIFIED, 12)
|
|
||||||
|
|
||||||
/* A general visited flag for passes to use. */
|
|
||||||
DEF_BASIC_BLOCK_FLAG(VISITED, 13)
|
|
||||||
|
|
||||||
/* Set on blocks that are in a transaction. This is calculated on
|
|
||||||
demand, and is available after calling compute_transaction_bits(). */
|
|
||||||
DEF_BASIC_BLOCK_FLAG(IN_TRANSACTION, 14)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEF_EDGE_FLAG
|
|
||||||
|
|
||||||
/* Masks for edge.flags.
|
|
||||||
|
|
||||||
The format of this file is: DEF_EDGE_FLAG(NAME, IDX, STRING).
|
|
||||||
NAME is the name of the edge flag. A flag EDGE_#NAME will be
|
|
||||||
created and the name is used in dump_edge_info.
|
|
||||||
IDX is a sequence number that is used to determine the value
|
|
||||||
of the flag, which is 1 << IDX). */
|
|
||||||
|
|
||||||
/* 'Straight line' flow. In GIMPLE and in cfglayout mode, all normal
|
|
||||||
edges are fallthru edges. In cfgrtl mode, this flag really means
|
|
||||||
that control flow falls through to the next basic block in the line. */
|
|
||||||
DEF_EDGE_FLAG(FALLTHRU, 0)
|
|
||||||
|
|
||||||
/* Strange flow, like a computed jump or exception handling. Usually
|
|
||||||
this means that the edge cannot be split. */
|
|
||||||
DEF_EDGE_FLAG(ABNORMAL, 1)
|
|
||||||
|
|
||||||
/* Edge out of a basic block that ends with a CALL_INSN with abnormal
|
|
||||||
exit, like an exception or a non-local goto.
|
|
||||||
ABNORMAL_CALL edges also have ABNORMAL set.
|
|
||||||
This flag is only used for the RTL CFG. */
|
|
||||||
DEF_EDGE_FLAG(ABNORMAL_CALL, 2)
|
|
||||||
|
|
||||||
/* Exception edge. Exception handling edges represent possible control
|
|
||||||
transfers from a trapping instruction to an exception handler.
|
|
||||||
EH edges also have ABNORMAL set for the RTL CFG. */
|
|
||||||
DEF_EDGE_FLAG(EH, 3)
|
|
||||||
|
|
||||||
/* Never merge blocks via this edge. This is used for exception handling,
|
|
||||||
to prevent merging away edges to the post-landing-pad basic block.
|
|
||||||
This flag is only used for the RTL CFG. */
|
|
||||||
DEF_EDGE_FLAG(PRESERVE, 4)
|
|
||||||
|
|
||||||
/* Not a real edge. This is used to connect parts of the CFG that do
|
|
||||||
not halt, such as infinite loops and noreturn functions, to the
|
|
||||||
EXIT_BLOCK, so that traversing of the reverse CFG is possible. */
|
|
||||||
DEF_EDGE_FLAG(FAKE, 5)
|
|
||||||
|
|
||||||
/* A back edge, marked in a depth-first search of the CFG. Back edges
|
|
||||||
are hints that this edge may be part of a loop in the CFG. */
|
|
||||||
DEF_EDGE_FLAG(DFS_BACK, 6)
|
|
||||||
|
|
||||||
/* Edge in a part of the CFG that is an irreducible loop. */
|
|
||||||
DEF_EDGE_FLAG(IRREDUCIBLE_LOOP, 7)
|
|
||||||
|
|
||||||
/* Edge taken when controlling predicate is nonzero.
|
|
||||||
This is only used for the GIMPLE CFG. */
|
|
||||||
DEF_EDGE_FLAG(TRUE_VALUE, 8)
|
|
||||||
|
|
||||||
/* Edge taken when controlling predicate is zero.
|
|
||||||
This is only used for the GIMPLE CFG. */
|
|
||||||
DEF_EDGE_FLAG(FALSE_VALUE, 9)
|
|
||||||
|
|
||||||
/* Edge is executable. This is only used in GIMPLE SSA-CCP and VRP.
|
|
||||||
This is only used for the GIMPLE CFG. */
|
|
||||||
DEF_EDGE_FLAG(EXECUTABLE, 10)
|
|
||||||
|
|
||||||
/* Edge crosses between hot and cold sections, when we do partitioning.
|
|
||||||
This flag is only used for the RTL CFG. */
|
|
||||||
DEF_EDGE_FLAG(CROSSING, 11)
|
|
||||||
|
|
||||||
/* Edge from a sibcall CALL_INSN to exit.
|
|
||||||
SIBCALL edges also have ABNORMAL set.
|
|
||||||
This flag is only used for the RTL CFG. */
|
|
||||||
DEF_EDGE_FLAG(SIBCALL, 12)
|
|
||||||
|
|
||||||
/* Candidate for straight line flow. Only used in bb-reorder.c.
|
|
||||||
This flag is only used for the RTL CFG. */
|
|
||||||
DEF_EDGE_FLAG(CAN_FALLTHRU, 13)
|
|
||||||
|
|
||||||
/* Exit of a loop. This is only used in ifcvt.c.
|
|
||||||
This flag is only used for the RTL CFG. */
|
|
||||||
DEF_EDGE_FLAG(LOOP_EXIT, 14)
|
|
||||||
|
|
||||||
/* Uninstrumented edge out of a GIMPLE_TRANSACTION statement. */
|
|
||||||
DEF_EDGE_FLAG(TM_UNINSTRUMENTED, 15)
|
|
||||||
|
|
||||||
/* Abort (over) edge out of a GIMPLE_TRANSACTION statement. */
|
|
||||||
DEF_EDGE_FLAG(TM_ABORT, 16)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
Local variables:
|
|
||||||
mode:c
|
|
||||||
End:
|
|
||||||
*/
|
|
@ -1,223 +0,0 @@
|
|||||||
/* Hooks for cfg representation specific functions.
|
|
||||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Sebastian Pop <s.pop@laposte.net>
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Only basic-block.h includes this. */
|
|
||||||
|
|
||||||
struct cfg_hooks
|
|
||||||
{
|
|
||||||
/* Name of the corresponding ir. */
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
/* Debugging. */
|
|
||||||
int (*verify_flow_info) (void);
|
|
||||||
void (*dump_bb) (FILE *, basic_block, int, int);
|
|
||||||
void (*dump_bb_for_graph) (pretty_printer *, basic_block);
|
|
||||||
|
|
||||||
/* Basic CFG manipulation. */
|
|
||||||
|
|
||||||
/* Return new basic block. */
|
|
||||||
basic_block (*create_basic_block) (void *head, void *end, basic_block after);
|
|
||||||
|
|
||||||
/* Redirect edge E to the given basic block B and update underlying program
|
|
||||||
representation. Returns edge representing redirected branch (that may not
|
|
||||||
be equivalent to E in the case of duplicate edges being removed) or NULL
|
|
||||||
if edge is not easily redirectable for whatever reason. */
|
|
||||||
edge (*redirect_edge_and_branch) (edge e, basic_block b);
|
|
||||||
|
|
||||||
/* Same as the above but allows redirecting of fallthru edges. In that case
|
|
||||||
newly created forwarder basic block is returned. The edge must
|
|
||||||
not be abnormal. */
|
|
||||||
basic_block (*redirect_edge_and_branch_force) (edge, basic_block);
|
|
||||||
|
|
||||||
/* Returns true if it is possible to remove the edge by redirecting it
|
|
||||||
to the destination of the other edge going from its source. */
|
|
||||||
bool (*can_remove_branch_p) (const_edge);
|
|
||||||
|
|
||||||
/* Remove statements corresponding to a given basic block. */
|
|
||||||
void (*delete_basic_block) (basic_block);
|
|
||||||
|
|
||||||
/* Creates a new basic block just after basic block B by splitting
|
|
||||||
everything after specified instruction I. */
|
|
||||||
basic_block (*split_block) (basic_block b, void * i);
|
|
||||||
|
|
||||||
/* Move block B immediately after block A. */
|
|
||||||
bool (*move_block_after) (basic_block b, basic_block a);
|
|
||||||
|
|
||||||
/* Return true when blocks A and B can be merged into single basic block. */
|
|
||||||
bool (*can_merge_blocks_p) (basic_block a, basic_block b);
|
|
||||||
|
|
||||||
/* Merge blocks A and B. */
|
|
||||||
void (*merge_blocks) (basic_block a, basic_block b);
|
|
||||||
|
|
||||||
/* Predict edge E using PREDICTOR to given PROBABILITY. */
|
|
||||||
void (*predict_edge) (edge e, enum br_predictor predictor, int probability);
|
|
||||||
|
|
||||||
/* Return true if the one of outgoing edges is already predicted by
|
|
||||||
PREDICTOR. */
|
|
||||||
bool (*predicted_by_p) (const_basic_block bb, enum br_predictor predictor);
|
|
||||||
|
|
||||||
/* Return true when block A can be duplicated. */
|
|
||||||
bool (*can_duplicate_block_p) (const_basic_block a);
|
|
||||||
|
|
||||||
/* Duplicate block A. */
|
|
||||||
basic_block (*duplicate_block) (basic_block a);
|
|
||||||
|
|
||||||
/* Higher level functions representable by primitive operations above if
|
|
||||||
we didn't have some oddities in RTL and Tree representations. */
|
|
||||||
basic_block (*split_edge) (edge);
|
|
||||||
void (*make_forwarder_block) (edge);
|
|
||||||
|
|
||||||
/* Try to make the edge fallthru. */
|
|
||||||
void (*tidy_fallthru_edge) (edge);
|
|
||||||
|
|
||||||
/* Make the edge non-fallthru. */
|
|
||||||
basic_block (*force_nonfallthru) (edge);
|
|
||||||
|
|
||||||
/* Say whether a block ends with a call, possibly followed by some
|
|
||||||
other code that must stay with the call. */
|
|
||||||
bool (*block_ends_with_call_p) (basic_block);
|
|
||||||
|
|
||||||
/* Say whether a block ends with a conditional branch. Switches
|
|
||||||
and unconditional branches do not qualify. */
|
|
||||||
bool (*block_ends_with_condjump_p) (const_basic_block);
|
|
||||||
|
|
||||||
/* Add fake edges to the function exit for any non constant and non noreturn
|
|
||||||
calls, volatile inline assembly in the bitmap of blocks specified by
|
|
||||||
BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks
|
|
||||||
that were split.
|
|
||||||
|
|
||||||
The goal is to expose cases in which entering a basic block does not imply
|
|
||||||
that all subsequent instructions must be executed. */
|
|
||||||
int (*flow_call_edges_add) (sbitmap);
|
|
||||||
|
|
||||||
/* This function is called immediately after edge E is added to the
|
|
||||||
edge vector E->dest->preds. */
|
|
||||||
void (*execute_on_growing_pred) (edge);
|
|
||||||
|
|
||||||
/* This function is called immediately before edge E is removed from
|
|
||||||
the edge vector E->dest->preds. */
|
|
||||||
void (*execute_on_shrinking_pred) (edge);
|
|
||||||
|
|
||||||
/* A hook for duplicating loop in CFG, currently this is used
|
|
||||||
in loop versioning. */
|
|
||||||
bool (*cfg_hook_duplicate_loop_to_header_edge) (struct loop *, edge,
|
|
||||||
unsigned, sbitmap,
|
|
||||||
edge, vec<edge> *,
|
|
||||||
int);
|
|
||||||
|
|
||||||
/* Add condition to new basic block and update CFG used in loop
|
|
||||||
versioning. */
|
|
||||||
void (*lv_add_condition_to_bb) (basic_block, basic_block, basic_block,
|
|
||||||
void *);
|
|
||||||
/* Update the PHI nodes in case of loop versioning. */
|
|
||||||
void (*lv_adjust_loop_header_phi) (basic_block, basic_block,
|
|
||||||
basic_block, edge);
|
|
||||||
|
|
||||||
/* Given a condition BB extract the true/false taken/not taken edges
|
|
||||||
(depending if we are on tree's or RTL). */
|
|
||||||
void (*extract_cond_bb_edges) (basic_block, edge *, edge *);
|
|
||||||
|
|
||||||
|
|
||||||
/* Add PHI arguments queued in PENDINT_STMT list on edge E to edge
|
|
||||||
E->dest (only in tree-ssa loop versioning. */
|
|
||||||
void (*flush_pending_stmts) (edge);
|
|
||||||
|
|
||||||
/* True if a block contains no executable instructions. */
|
|
||||||
bool (*empty_block_p) (basic_block);
|
|
||||||
|
|
||||||
/* Split a basic block if it ends with a conditional branch and if
|
|
||||||
the other part of the block is not empty. */
|
|
||||||
basic_block (*split_block_before_cond_jump) (basic_block);
|
|
||||||
|
|
||||||
/* Do book-keeping of a basic block for the profile consistency checker. */
|
|
||||||
void (*account_profile_record) (basic_block, int, struct profile_record *);
|
|
||||||
};
|
|
||||||
|
|
||||||
extern void verify_flow_info (void);
|
|
||||||
extern void dump_bb (FILE *, basic_block, int, int);
|
|
||||||
extern void dump_bb_for_graph (pretty_printer *, basic_block);
|
|
||||||
|
|
||||||
extern edge redirect_edge_and_branch (edge, basic_block);
|
|
||||||
extern basic_block redirect_edge_and_branch_force (edge, basic_block);
|
|
||||||
extern bool can_remove_branch_p (const_edge);
|
|
||||||
extern void remove_branch (edge);
|
|
||||||
extern void remove_edge (edge);
|
|
||||||
extern edge split_block (basic_block, void *);
|
|
||||||
extern edge split_block_after_labels (basic_block);
|
|
||||||
extern bool move_block_after (basic_block, basic_block);
|
|
||||||
extern void delete_basic_block (basic_block);
|
|
||||||
extern basic_block split_edge (edge);
|
|
||||||
extern basic_block create_basic_block (void *, void *, basic_block);
|
|
||||||
extern basic_block create_empty_bb (basic_block);
|
|
||||||
extern bool can_merge_blocks_p (basic_block, basic_block);
|
|
||||||
extern void merge_blocks (basic_block, basic_block);
|
|
||||||
extern edge make_forwarder_block (basic_block, bool (*)(edge),
|
|
||||||
void (*) (basic_block));
|
|
||||||
extern basic_block force_nonfallthru (edge);
|
|
||||||
extern void tidy_fallthru_edge (edge);
|
|
||||||
extern void tidy_fallthru_edges (void);
|
|
||||||
extern void predict_edge (edge e, enum br_predictor predictor, int probability);
|
|
||||||
extern bool predicted_by_p (const_basic_block bb, enum br_predictor predictor);
|
|
||||||
extern bool can_duplicate_block_p (const_basic_block);
|
|
||||||
extern basic_block duplicate_block (basic_block, edge, basic_block);
|
|
||||||
extern bool block_ends_with_call_p (basic_block bb);
|
|
||||||
extern bool empty_block_p (basic_block);
|
|
||||||
extern basic_block split_block_before_cond_jump (basic_block);
|
|
||||||
extern bool block_ends_with_condjump_p (const_basic_block bb);
|
|
||||||
extern int flow_call_edges_add (sbitmap);
|
|
||||||
extern void execute_on_growing_pred (edge);
|
|
||||||
extern void execute_on_shrinking_pred (edge);
|
|
||||||
extern bool cfg_hook_duplicate_loop_to_header_edge (struct loop *loop, edge,
|
|
||||||
unsigned int ndupl,
|
|
||||||
sbitmap wont_exit,
|
|
||||||
edge orig,
|
|
||||||
vec<edge> *to_remove,
|
|
||||||
int flags);
|
|
||||||
|
|
||||||
extern void lv_flush_pending_stmts (edge);
|
|
||||||
extern void extract_cond_bb_edges (basic_block, edge *, edge*);
|
|
||||||
extern void lv_adjust_loop_header_phi (basic_block, basic_block, basic_block,
|
|
||||||
edge);
|
|
||||||
extern void lv_add_condition_to_bb (basic_block, basic_block, basic_block,
|
|
||||||
void *);
|
|
||||||
|
|
||||||
extern bool can_copy_bbs_p (basic_block *, unsigned);
|
|
||||||
extern void copy_bbs (basic_block *, unsigned, basic_block *,
|
|
||||||
edge *, unsigned, edge *, struct loop *,
|
|
||||||
basic_block);
|
|
||||||
|
|
||||||
void account_profile_record (struct profile_record *, int);
|
|
||||||
|
|
||||||
extern void cfg_layout_initialize (unsigned int);
|
|
||||||
extern void cfg_layout_finalize (void);
|
|
||||||
|
|
||||||
/* Hooks containers. */
|
|
||||||
extern struct cfg_hooks gimple_cfg_hooks;
|
|
||||||
extern struct cfg_hooks rtl_cfg_hooks;
|
|
||||||
extern struct cfg_hooks cfg_layout_rtl_cfg_hooks;
|
|
||||||
|
|
||||||
/* Declarations. */
|
|
||||||
extern enum ir_type current_ir_type (void);
|
|
||||||
extern void rtl_register_cfg_hooks (void);
|
|
||||||
extern void cfg_layout_rtl_register_cfg_hooks (void);
|
|
||||||
extern void gimple_register_cfg_hooks (void);
|
|
||||||
extern struct cfg_hooks get_cfg_hooks (void);
|
|
||||||
extern void set_cfg_hooks (struct cfg_hooks);
|
|
||||||
|
|
@ -1,733 +0,0 @@
|
|||||||
/* Natural loop functions
|
|
||||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_CFGLOOP_H
|
|
||||||
#define GCC_CFGLOOP_H
|
|
||||||
|
|
||||||
#include "basic-block.h"
|
|
||||||
#include "double-int.h"
|
|
||||||
|
|
||||||
#include "bitmap.h"
|
|
||||||
#include "sbitmap.h"
|
|
||||||
|
|
||||||
/* Structure to hold decision about unrolling/peeling. */
|
|
||||||
enum lpt_dec
|
|
||||||
{
|
|
||||||
LPT_NONE,
|
|
||||||
LPT_PEEL_COMPLETELY,
|
|
||||||
LPT_PEEL_SIMPLE,
|
|
||||||
LPT_UNROLL_CONSTANT,
|
|
||||||
LPT_UNROLL_RUNTIME,
|
|
||||||
LPT_UNROLL_STUPID
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GTY (()) lpt_decision {
|
|
||||||
enum lpt_dec decision;
|
|
||||||
unsigned times;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The type of extend applied to an IV. */
|
|
||||||
enum iv_extend_code
|
|
||||||
{
|
|
||||||
IV_SIGN_EXTEND,
|
|
||||||
IV_ZERO_EXTEND,
|
|
||||||
IV_UNKNOWN_EXTEND
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The structure describing a bound on number of iterations of a loop. */
|
|
||||||
|
|
||||||
struct GTY ((chain_next ("%h.next"))) nb_iter_bound {
|
|
||||||
/* The statement STMT is executed at most ... */
|
|
||||||
gimple stmt;
|
|
||||||
|
|
||||||
/* ... BOUND + 1 times (BOUND must be an unsigned constant).
|
|
||||||
The + 1 is added for the following reasons:
|
|
||||||
|
|
||||||
a) 0 would otherwise be unused, while we would need to care more about
|
|
||||||
overflows (as MAX + 1 is sometimes produced as the estimate on number
|
|
||||||
of executions of STMT).
|
|
||||||
b) it is consistent with the result of number_of_iterations_exit. */
|
|
||||||
double_int bound;
|
|
||||||
|
|
||||||
/* True if the statement will cause the loop to be leaved the (at most)
|
|
||||||
BOUND + 1-st time it is executed, that is, all the statements after it
|
|
||||||
are executed at most BOUND times. */
|
|
||||||
bool is_exit;
|
|
||||||
|
|
||||||
/* The next bound in the list. */
|
|
||||||
struct nb_iter_bound *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Description of the loop exit. */
|
|
||||||
|
|
||||||
struct GTY (()) loop_exit {
|
|
||||||
/* The exit edge. */
|
|
||||||
edge e;
|
|
||||||
|
|
||||||
/* Previous and next exit in the list of the exits of the loop. */
|
|
||||||
struct loop_exit *prev;
|
|
||||||
struct loop_exit *next;
|
|
||||||
|
|
||||||
/* Next element in the list of loops from that E exits. */
|
|
||||||
struct loop_exit *next_e;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct loop *loop_p;
|
|
||||||
|
|
||||||
/* An integer estimation of the number of iterations. Estimate_state
|
|
||||||
describes what is the state of the estimation. */
|
|
||||||
enum loop_estimation
|
|
||||||
{
|
|
||||||
/* Estimate was not computed yet. */
|
|
||||||
EST_NOT_COMPUTED,
|
|
||||||
/* Estimate is ready. */
|
|
||||||
EST_AVAILABLE
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Structure to hold information for each natural loop. */
|
|
||||||
struct GTY ((chain_next ("%h.next"))) loop {
|
|
||||||
/* Index into loops array. */
|
|
||||||
int num;
|
|
||||||
|
|
||||||
/* Number of loop insns. */
|
|
||||||
unsigned ninsns;
|
|
||||||
|
|
||||||
/* Basic block of loop header. */
|
|
||||||
basic_block header;
|
|
||||||
|
|
||||||
/* Basic block of loop latch. */
|
|
||||||
basic_block latch;
|
|
||||||
|
|
||||||
/* For loop unrolling/peeling decision. */
|
|
||||||
struct lpt_decision lpt_decision;
|
|
||||||
|
|
||||||
/* Average number of executed insns per iteration. */
|
|
||||||
unsigned av_ninsns;
|
|
||||||
|
|
||||||
/* Number of blocks contained within the loop. */
|
|
||||||
unsigned num_nodes;
|
|
||||||
|
|
||||||
/* Superloops of the loop, starting with the outermost loop. */
|
|
||||||
vec<loop_p, va_gc> *superloops;
|
|
||||||
|
|
||||||
/* The first inner (child) loop or NULL if innermost loop. */
|
|
||||||
struct loop *inner;
|
|
||||||
|
|
||||||
/* Link to the next (sibling) loop. */
|
|
||||||
struct loop *next;
|
|
||||||
|
|
||||||
/* Auxiliary info specific to a pass. */
|
|
||||||
PTR GTY ((skip (""))) aux;
|
|
||||||
|
|
||||||
/* The number of times the latch of the loop is executed. This can be an
|
|
||||||
INTEGER_CST, or a symbolic expression representing the number of
|
|
||||||
iterations like "N - 1", or a COND_EXPR containing the runtime
|
|
||||||
conditions under which the number of iterations is non zero.
|
|
||||||
|
|
||||||
Don't access this field directly: number_of_latch_executions
|
|
||||||
computes and caches the computed information in this field. */
|
|
||||||
tree nb_iterations;
|
|
||||||
|
|
||||||
/* An integer guaranteed to be greater or equal to nb_iterations. Only
|
|
||||||
valid if any_upper_bound is true. */
|
|
||||||
double_int nb_iterations_upper_bound;
|
|
||||||
|
|
||||||
/* An integer giving an estimate on nb_iterations. Unlike
|
|
||||||
nb_iterations_upper_bound, there is no guarantee that it is at least
|
|
||||||
nb_iterations. */
|
|
||||||
double_int nb_iterations_estimate;
|
|
||||||
|
|
||||||
bool any_upper_bound;
|
|
||||||
bool any_estimate;
|
|
||||||
|
|
||||||
/* True if the loop can be parallel. */
|
|
||||||
bool can_be_parallel;
|
|
||||||
|
|
||||||
/* True if -Waggressive-loop-optimizations warned about this loop
|
|
||||||
already. */
|
|
||||||
bool warned_aggressive_loop_optimizations;
|
|
||||||
|
|
||||||
/* An integer estimation of the number of iterations. Estimate_state
|
|
||||||
describes what is the state of the estimation. */
|
|
||||||
enum loop_estimation estimate_state;
|
|
||||||
|
|
||||||
/* Upper bound on number of iterations of a loop. */
|
|
||||||
struct nb_iter_bound *bounds;
|
|
||||||
|
|
||||||
/* Head of the cyclic list of the exits of the loop. */
|
|
||||||
struct loop_exit *exits;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Flags for state of loop structure. */
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
LOOPS_HAVE_PREHEADERS = 1,
|
|
||||||
LOOPS_HAVE_SIMPLE_LATCHES = 2,
|
|
||||||
LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS = 4,
|
|
||||||
LOOPS_HAVE_RECORDED_EXITS = 8,
|
|
||||||
LOOPS_MAY_HAVE_MULTIPLE_LATCHES = 16,
|
|
||||||
LOOP_CLOSED_SSA = 32,
|
|
||||||
LOOPS_NEED_FIXUP = 64,
|
|
||||||
LOOPS_HAVE_FALLTHRU_PREHEADERS = 128
|
|
||||||
};
|
|
||||||
|
|
||||||
#define LOOPS_NORMAL (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES \
|
|
||||||
| LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
|
|
||||||
#define AVOID_CFG_MODIFICATIONS (LOOPS_MAY_HAVE_MULTIPLE_LATCHES)
|
|
||||||
|
|
||||||
/* Structure to hold CFG information about natural loops within a function. */
|
|
||||||
struct GTY (()) loops {
|
|
||||||
/* State of loops. */
|
|
||||||
int state;
|
|
||||||
|
|
||||||
/* Array of the loops. */
|
|
||||||
vec<loop_p, va_gc> *larray;
|
|
||||||
|
|
||||||
/* Maps edges to the list of their descriptions as loop exits. Edges
|
|
||||||
whose sources or destinations have loop_father == NULL (which may
|
|
||||||
happen during the cfg manipulations) should not appear in EXITS. */
|
|
||||||
htab_t GTY((param_is (struct loop_exit))) exits;
|
|
||||||
|
|
||||||
/* Pointer to root of loop hierarchy tree. */
|
|
||||||
struct loop *tree_root;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Loop recognition. */
|
|
||||||
bool bb_loop_header_p (basic_block);
|
|
||||||
extern struct loops *flow_loops_find (struct loops *);
|
|
||||||
extern void disambiguate_loops_with_multiple_latches (void);
|
|
||||||
extern void flow_loops_free (struct loops *);
|
|
||||||
extern void flow_loops_dump (FILE *,
|
|
||||||
void (*)(const struct loop *, FILE *, int), int);
|
|
||||||
extern void flow_loop_dump (const struct loop *, FILE *,
|
|
||||||
void (*)(const struct loop *, FILE *, int), int);
|
|
||||||
struct loop *alloc_loop (void);
|
|
||||||
extern void flow_loop_free (struct loop *);
|
|
||||||
int flow_loop_nodes_find (basic_block, struct loop *);
|
|
||||||
unsigned fix_loop_structure (bitmap changed_bbs);
|
|
||||||
bool mark_irreducible_loops (void);
|
|
||||||
void release_recorded_exits (void);
|
|
||||||
void record_loop_exits (void);
|
|
||||||
void rescan_loop_exit (edge, bool, bool);
|
|
||||||
|
|
||||||
/* Loop data structure manipulation/querying. */
|
|
||||||
extern void flow_loop_tree_node_add (struct loop *, struct loop *);
|
|
||||||
extern void flow_loop_tree_node_remove (struct loop *);
|
|
||||||
extern void add_loop (struct loop *, struct loop *);
|
|
||||||
extern bool flow_loop_nested_p (const struct loop *, const struct loop *);
|
|
||||||
extern bool flow_bb_inside_loop_p (const struct loop *, const_basic_block);
|
|
||||||
extern struct loop * find_common_loop (struct loop *, struct loop *);
|
|
||||||
struct loop *superloop_at_depth (struct loop *, unsigned);
|
|
||||||
struct eni_weights_d;
|
|
||||||
extern unsigned tree_num_loop_insns (struct loop *, struct eni_weights_d *);
|
|
||||||
extern int num_loop_insns (const struct loop *);
|
|
||||||
extern int average_num_loop_insns (const struct loop *);
|
|
||||||
extern unsigned get_loop_level (const struct loop *);
|
|
||||||
extern bool loop_exit_edge_p (const struct loop *, const_edge);
|
|
||||||
extern bool loop_exits_to_bb_p (struct loop *, basic_block);
|
|
||||||
extern bool loop_exits_from_bb_p (struct loop *, basic_block);
|
|
||||||
extern void mark_loop_exit_edges (void);
|
|
||||||
extern location_t get_loop_location (struct loop *loop);
|
|
||||||
|
|
||||||
/* Loops & cfg manipulation. */
|
|
||||||
extern basic_block *get_loop_body (const struct loop *);
|
|
||||||
extern unsigned get_loop_body_with_size (const struct loop *, basic_block *,
|
|
||||||
unsigned);
|
|
||||||
extern basic_block *get_loop_body_in_dom_order (const struct loop *);
|
|
||||||
extern basic_block *get_loop_body_in_bfs_order (const struct loop *);
|
|
||||||
extern basic_block *get_loop_body_in_custom_order (const struct loop *,
|
|
||||||
int (*) (const void *, const void *));
|
|
||||||
|
|
||||||
extern vec<edge> get_loop_exit_edges (const struct loop *);
|
|
||||||
extern edge single_exit (const struct loop *);
|
|
||||||
extern edge single_likely_exit (struct loop *loop);
|
|
||||||
extern unsigned num_loop_branches (const struct loop *);
|
|
||||||
|
|
||||||
extern edge loop_preheader_edge (const struct loop *);
|
|
||||||
extern edge loop_latch_edge (const struct loop *);
|
|
||||||
|
|
||||||
extern void add_bb_to_loop (basic_block, struct loop *);
|
|
||||||
extern void remove_bb_from_loops (basic_block);
|
|
||||||
|
|
||||||
extern void cancel_loop_tree (struct loop *);
|
|
||||||
extern void delete_loop (struct loop *);
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
CP_SIMPLE_PREHEADERS = 1,
|
|
||||||
CP_FALLTHRU_PREHEADERS = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
basic_block create_preheader (struct loop *, int);
|
|
||||||
extern void create_preheaders (int);
|
|
||||||
extern void force_single_succ_latches (void);
|
|
||||||
|
|
||||||
extern void verify_loop_structure (void);
|
|
||||||
|
|
||||||
/* Loop analysis. */
|
|
||||||
extern bool just_once_each_iteration_p (const struct loop *, const_basic_block);
|
|
||||||
gcov_type expected_loop_iterations_unbounded (const struct loop *);
|
|
||||||
extern unsigned expected_loop_iterations (const struct loop *);
|
|
||||||
extern rtx doloop_condition_get (rtx);
|
|
||||||
|
|
||||||
void estimate_numbers_of_iterations_loop (struct loop *);
|
|
||||||
void record_niter_bound (struct loop *, double_int, bool, bool);
|
|
||||||
bool estimated_loop_iterations (struct loop *, double_int *);
|
|
||||||
bool max_loop_iterations (struct loop *, double_int *);
|
|
||||||
HOST_WIDE_INT estimated_loop_iterations_int (struct loop *);
|
|
||||||
HOST_WIDE_INT max_loop_iterations_int (struct loop *);
|
|
||||||
bool max_stmt_executions (struct loop *, double_int *);
|
|
||||||
bool estimated_stmt_executions (struct loop *, double_int *);
|
|
||||||
HOST_WIDE_INT max_stmt_executions_int (struct loop *);
|
|
||||||
HOST_WIDE_INT estimated_stmt_executions_int (struct loop *);
|
|
||||||
|
|
||||||
/* Loop manipulation. */
|
|
||||||
extern bool can_duplicate_loop_p (const struct loop *loop);
|
|
||||||
|
|
||||||
#define DLTHE_FLAG_UPDATE_FREQ 1 /* Update frequencies in
|
|
||||||
duplicate_loop_to_header_edge. */
|
|
||||||
#define DLTHE_RECORD_COPY_NUMBER 2 /* Record copy number in the aux
|
|
||||||
field of newly create BB. */
|
|
||||||
#define DLTHE_FLAG_COMPLETTE_PEEL 4 /* Update frequencies expecting
|
|
||||||
a complete peeling. */
|
|
||||||
|
|
||||||
extern edge create_empty_if_region_on_edge (edge, tree);
|
|
||||||
extern struct loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree,
|
|
||||||
tree *, tree *, struct loop *);
|
|
||||||
extern struct loop * duplicate_loop (struct loop *, struct loop *);
|
|
||||||
extern void copy_loop_info (struct loop *loop, struct loop *target);
|
|
||||||
extern void duplicate_subloops (struct loop *, struct loop *);
|
|
||||||
extern bool duplicate_loop_to_header_edge (struct loop *, edge,
|
|
||||||
unsigned, sbitmap, edge,
|
|
||||||
vec<edge> *, int);
|
|
||||||
extern struct loop *loopify (edge, edge,
|
|
||||||
basic_block, edge, edge, bool,
|
|
||||||
unsigned, unsigned);
|
|
||||||
struct loop * loop_version (struct loop *, void *,
|
|
||||||
basic_block *, unsigned, unsigned, unsigned, bool);
|
|
||||||
extern bool remove_path (edge);
|
|
||||||
extern void unloop (struct loop *, bool *, bitmap);
|
|
||||||
extern void scale_loop_frequencies (struct loop *, int, int);
|
|
||||||
|
|
||||||
/* Induction variable analysis. */
|
|
||||||
|
|
||||||
/* The description of induction variable. The things are a bit complicated
|
|
||||||
due to need to handle subregs and extends. The value of the object described
|
|
||||||
by it can be obtained as follows (all computations are done in extend_mode):
|
|
||||||
|
|
||||||
Value in i-th iteration is
|
|
||||||
delta + mult * extend_{extend_mode} (subreg_{mode} (base + i * step)).
|
|
||||||
|
|
||||||
If first_special is true, the value in the first iteration is
|
|
||||||
delta + mult * base
|
|
||||||
|
|
||||||
If extend = UNKNOWN, first_special must be false, delta 0, mult 1 and value is
|
|
||||||
subreg_{mode} (base + i * step)
|
|
||||||
|
|
||||||
The get_iv_value function can be used to obtain these expressions.
|
|
||||||
|
|
||||||
??? Add a third mode field that would specify the mode in that inner
|
|
||||||
computation is done, which would enable it to be different from the
|
|
||||||
outer one? */
|
|
||||||
|
|
||||||
struct rtx_iv
|
|
||||||
{
|
|
||||||
/* Its base and step (mode of base and step is supposed to be extend_mode,
|
|
||||||
see the description above). */
|
|
||||||
rtx base, step;
|
|
||||||
|
|
||||||
/* The type of extend applied to it (IV_SIGN_EXTEND, IV_ZERO_EXTEND,
|
|
||||||
or IV_UNKNOWN_EXTEND). */
|
|
||||||
enum iv_extend_code extend;
|
|
||||||
|
|
||||||
/* Operations applied in the extended mode. */
|
|
||||||
rtx delta, mult;
|
|
||||||
|
|
||||||
/* The mode it is extended to. */
|
|
||||||
enum machine_mode extend_mode;
|
|
||||||
|
|
||||||
/* The mode the variable iterates in. */
|
|
||||||
enum machine_mode mode;
|
|
||||||
|
|
||||||
/* Whether the first iteration needs to be handled specially. */
|
|
||||||
unsigned first_special : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The description of an exit from the loop and of the number of iterations
|
|
||||||
till we take the exit. */
|
|
||||||
|
|
||||||
struct niter_desc
|
|
||||||
{
|
|
||||||
/* The edge out of the loop. */
|
|
||||||
edge out_edge;
|
|
||||||
|
|
||||||
/* The other edge leading from the condition. */
|
|
||||||
edge in_edge;
|
|
||||||
|
|
||||||
/* True if we are able to say anything about number of iterations of the
|
|
||||||
loop. */
|
|
||||||
bool simple_p;
|
|
||||||
|
|
||||||
/* True if the loop iterates the constant number of times. */
|
|
||||||
bool const_iter;
|
|
||||||
|
|
||||||
/* Number of iterations if constant. */
|
|
||||||
unsigned HOST_WIDEST_INT niter;
|
|
||||||
|
|
||||||
/* Assumptions under that the rest of the information is valid. */
|
|
||||||
rtx assumptions;
|
|
||||||
|
|
||||||
/* Assumptions under that the loop ends before reaching the latch,
|
|
||||||
even if value of niter_expr says otherwise. */
|
|
||||||
rtx noloop_assumptions;
|
|
||||||
|
|
||||||
/* Condition under that the loop is infinite. */
|
|
||||||
rtx infinite;
|
|
||||||
|
|
||||||
/* Whether the comparison is signed. */
|
|
||||||
bool signed_p;
|
|
||||||
|
|
||||||
/* The mode in that niter_expr should be computed. */
|
|
||||||
enum machine_mode mode;
|
|
||||||
|
|
||||||
/* The number of iterations of the loop. */
|
|
||||||
rtx niter_expr;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern void iv_analysis_loop_init (struct loop *);
|
|
||||||
extern bool iv_analyze (rtx, rtx, struct rtx_iv *);
|
|
||||||
extern bool iv_analyze_result (rtx, rtx, struct rtx_iv *);
|
|
||||||
extern bool iv_analyze_expr (rtx, rtx, enum machine_mode, struct rtx_iv *);
|
|
||||||
extern rtx get_iv_value (struct rtx_iv *, rtx);
|
|
||||||
extern bool biv_p (rtx, rtx);
|
|
||||||
extern void find_simple_exit (struct loop *, struct niter_desc *);
|
|
||||||
extern void iv_analysis_done (void);
|
|
||||||
|
|
||||||
extern struct niter_desc *get_simple_loop_desc (struct loop *loop);
|
|
||||||
extern void free_simple_loop_desc (struct loop *loop);
|
|
||||||
|
|
||||||
static inline struct niter_desc *
|
|
||||||
simple_loop_desc (struct loop *loop)
|
|
||||||
{
|
|
||||||
return (struct niter_desc *) loop->aux;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Accessors for the loop structures. */
|
|
||||||
|
|
||||||
/* Returns the loop with index NUM from current_loops. */
|
|
||||||
|
|
||||||
static inline struct loop *
|
|
||||||
get_loop (unsigned num)
|
|
||||||
{
|
|
||||||
return (*current_loops->larray)[num];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns the number of superloops of LOOP. */
|
|
||||||
|
|
||||||
static inline unsigned
|
|
||||||
loop_depth (const struct loop *loop)
|
|
||||||
{
|
|
||||||
return vec_safe_length (loop->superloops);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns the loop depth of the loop BB belongs to. */
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
bb_loop_depth (const_basic_block bb)
|
|
||||||
{
|
|
||||||
return bb->loop_father ? loop_depth (bb->loop_father) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns the immediate superloop of LOOP, or NULL if LOOP is the outermost
|
|
||||||
loop. */
|
|
||||||
|
|
||||||
static inline struct loop *
|
|
||||||
loop_outer (const struct loop *loop)
|
|
||||||
{
|
|
||||||
unsigned n = vec_safe_length (loop->superloops);
|
|
||||||
|
|
||||||
if (n == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return (*loop->superloops)[n - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns true if LOOP has at least one exit edge. */
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
loop_has_exit_edges (const struct loop *loop)
|
|
||||||
{
|
|
||||||
return loop->exits->next->e != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns the list of loops in current_loops. */
|
|
||||||
|
|
||||||
static inline vec<loop_p, va_gc> *
|
|
||||||
get_loops (void)
|
|
||||||
{
|
|
||||||
if (!current_loops)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return current_loops->larray;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns the number of loops in current_loops (including the removed
|
|
||||||
ones and the fake loop that forms the root of the loop tree). */
|
|
||||||
|
|
||||||
static inline unsigned
|
|
||||||
number_of_loops (void)
|
|
||||||
{
|
|
||||||
if (!current_loops)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return vec_safe_length (current_loops->larray);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns true if state of the loops satisfies all properties
|
|
||||||
described by FLAGS. */
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
loops_state_satisfies_p (unsigned flags)
|
|
||||||
{
|
|
||||||
return (current_loops->state & flags) == flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sets FLAGS to the loops state. */
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
loops_state_set (unsigned flags)
|
|
||||||
{
|
|
||||||
current_loops->state |= flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clears FLAGS from the loops state. */
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
loops_state_clear (unsigned flags)
|
|
||||||
{
|
|
||||||
if (!current_loops)
|
|
||||||
return;
|
|
||||||
current_loops->state &= ~flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop iterators. */
|
|
||||||
|
|
||||||
/* Flags for loop iteration. */
|
|
||||||
|
|
||||||
enum li_flags
|
|
||||||
{
|
|
||||||
LI_INCLUDE_ROOT = 1, /* Include the fake root of the loop tree. */
|
|
||||||
LI_FROM_INNERMOST = 2, /* Iterate over the loops in the reverse order,
|
|
||||||
starting from innermost ones. */
|
|
||||||
LI_ONLY_INNERMOST = 4 /* Iterate only over innermost loops. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The iterator for loops. */
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
/* The list of loops to visit. */
|
|
||||||
vec<int> to_visit;
|
|
||||||
|
|
||||||
/* The index of the actual loop. */
|
|
||||||
unsigned idx;
|
|
||||||
} loop_iterator;
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
fel_next (loop_iterator *li, loop_p *loop)
|
|
||||||
{
|
|
||||||
int anum;
|
|
||||||
|
|
||||||
while (li->to_visit.iterate (li->idx, &anum))
|
|
||||||
{
|
|
||||||
li->idx++;
|
|
||||||
*loop = get_loop (anum);
|
|
||||||
if (*loop)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
li->to_visit.release ();
|
|
||||||
*loop = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
fel_init (loop_iterator *li, loop_p *loop, unsigned flags)
|
|
||||||
{
|
|
||||||
struct loop *aloop;
|
|
||||||
unsigned i;
|
|
||||||
int mn;
|
|
||||||
|
|
||||||
li->idx = 0;
|
|
||||||
if (!current_loops)
|
|
||||||
{
|
|
||||||
li->to_visit.create (0);
|
|
||||||
*loop = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
li->to_visit.create (number_of_loops ());
|
|
||||||
mn = (flags & LI_INCLUDE_ROOT) ? 0 : 1;
|
|
||||||
|
|
||||||
if (flags & LI_ONLY_INNERMOST)
|
|
||||||
{
|
|
||||||
for (i = 0; vec_safe_iterate (current_loops->larray, i, &aloop); i++)
|
|
||||||
if (aloop != NULL
|
|
||||||
&& aloop->inner == NULL
|
|
||||||
&& aloop->num >= mn)
|
|
||||||
li->to_visit.quick_push (aloop->num);
|
|
||||||
}
|
|
||||||
else if (flags & LI_FROM_INNERMOST)
|
|
||||||
{
|
|
||||||
/* Push the loops to LI->TO_VISIT in postorder. */
|
|
||||||
for (aloop = current_loops->tree_root;
|
|
||||||
aloop->inner != NULL;
|
|
||||||
aloop = aloop->inner)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (aloop->num >= mn)
|
|
||||||
li->to_visit.quick_push (aloop->num);
|
|
||||||
|
|
||||||
if (aloop->next)
|
|
||||||
{
|
|
||||||
for (aloop = aloop->next;
|
|
||||||
aloop->inner != NULL;
|
|
||||||
aloop = aloop->inner)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (!loop_outer (aloop))
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
aloop = loop_outer (aloop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Push the loops to LI->TO_VISIT in preorder. */
|
|
||||||
aloop = current_loops->tree_root;
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (aloop->num >= mn)
|
|
||||||
li->to_visit.quick_push (aloop->num);
|
|
||||||
|
|
||||||
if (aloop->inner != NULL)
|
|
||||||
aloop = aloop->inner;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (aloop != NULL && aloop->next == NULL)
|
|
||||||
aloop = loop_outer (aloop);
|
|
||||||
if (aloop == NULL)
|
|
||||||
break;
|
|
||||||
aloop = aloop->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fel_next (li, loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FOR_EACH_LOOP(LI, LOOP, FLAGS) \
|
|
||||||
for (fel_init (&(LI), &(LOOP), FLAGS); \
|
|
||||||
(LOOP); \
|
|
||||||
fel_next (&(LI), &(LOOP)))
|
|
||||||
|
|
||||||
#define FOR_EACH_LOOP_BREAK(LI) \
|
|
||||||
{ \
|
|
||||||
(LI).to_visit.release (); \
|
|
||||||
break; \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The properties of the target. */
|
|
||||||
struct target_cfgloop {
|
|
||||||
/* Number of available registers. */
|
|
||||||
unsigned x_target_avail_regs;
|
|
||||||
|
|
||||||
/* Number of available registers that are call-clobbered. */
|
|
||||||
unsigned x_target_clobbered_regs;
|
|
||||||
|
|
||||||
/* Number of registers reserved for temporary expressions. */
|
|
||||||
unsigned x_target_res_regs;
|
|
||||||
|
|
||||||
/* The cost for register when there still is some reserve, but we are
|
|
||||||
approaching the number of available registers. */
|
|
||||||
unsigned x_target_reg_cost[2];
|
|
||||||
|
|
||||||
/* The cost for register when we need to spill. */
|
|
||||||
unsigned x_target_spill_cost[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct target_cfgloop default_target_cfgloop;
|
|
||||||
#if SWITCHABLE_TARGET
|
|
||||||
extern struct target_cfgloop *this_target_cfgloop;
|
|
||||||
#else
|
|
||||||
#define this_target_cfgloop (&default_target_cfgloop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define target_avail_regs \
|
|
||||||
(this_target_cfgloop->x_target_avail_regs)
|
|
||||||
#define target_clobbered_regs \
|
|
||||||
(this_target_cfgloop->x_target_clobbered_regs)
|
|
||||||
#define target_res_regs \
|
|
||||||
(this_target_cfgloop->x_target_res_regs)
|
|
||||||
#define target_reg_cost \
|
|
||||||
(this_target_cfgloop->x_target_reg_cost)
|
|
||||||
#define target_spill_cost \
|
|
||||||
(this_target_cfgloop->x_target_spill_cost)
|
|
||||||
|
|
||||||
/* Register pressure estimation for induction variable optimizations & loop
|
|
||||||
invariant motion. */
|
|
||||||
extern unsigned estimate_reg_pressure_cost (unsigned, unsigned, bool, bool);
|
|
||||||
extern void init_set_costs (void);
|
|
||||||
|
|
||||||
/* Loop optimizer initialization. */
|
|
||||||
extern void loop_optimizer_init (unsigned);
|
|
||||||
extern void loop_optimizer_finalize (void);
|
|
||||||
|
|
||||||
/* Optimization passes. */
|
|
||||||
extern void unswitch_loops (void);
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
UAP_PEEL = 1, /* Enables loop peeling. */
|
|
||||||
UAP_UNROLL = 2, /* Enables unrolling of loops if it seems profitable. */
|
|
||||||
UAP_UNROLL_ALL = 4 /* Enables unrolling of all loops. */
|
|
||||||
};
|
|
||||||
|
|
||||||
extern void unroll_and_peel_loops (int);
|
|
||||||
extern void doloop_optimize_loops (void);
|
|
||||||
extern void move_loop_invariants (void);
|
|
||||||
extern bool finite_loop_p (struct loop *);
|
|
||||||
extern void scale_loop_profile (struct loop *loop, int scale, gcov_type iteration_bound);
|
|
||||||
extern vec<basic_block> get_loop_hot_path (const struct loop *loop);
|
|
||||||
|
|
||||||
/* Returns the outermost loop of the loop nest that contains LOOP.*/
|
|
||||||
static inline struct loop *
|
|
||||||
loop_outermost (struct loop *loop)
|
|
||||||
{
|
|
||||||
unsigned n = vec_safe_length (loop->superloops);
|
|
||||||
|
|
||||||
if (n <= 1)
|
|
||||||
return loop;
|
|
||||||
|
|
||||||
return (*loop->superloops)[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* GCC_CFGLOOP_H */
|
|
1371
src/include/cgraph.h
1371
src/include/cgraph.h
File diff suppressed because it is too large
Load Diff
@ -1,105 +0,0 @@
|
|||||||
/* This file contains the definitions of the cgraph_inline_failed_t
|
|
||||||
enums used in GCC.
|
|
||||||
|
|
||||||
Copyright (C) 2008-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Doug Kwan <dougkwan@google.com>
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* The format of this file is
|
|
||||||
DEFCIFCODE(code, string).
|
|
||||||
|
|
||||||
Where symbol is the enumeration name without the ``''.
|
|
||||||
The argument STRING is a explain the failure. Except for OK,
|
|
||||||
which is a NULL pointer. */
|
|
||||||
|
|
||||||
/* Inlining successful. This must be the first code. */
|
|
||||||
DEFCIFCODE(OK , NULL)
|
|
||||||
|
|
||||||
/* Inlining failed for an unspecified reason. */
|
|
||||||
DEFCIFCODE(UNSPECIFIED , "")
|
|
||||||
|
|
||||||
/* Function has not be considered for inlining. This is the code for
|
|
||||||
functions that have not been rejected for inlining yet. */
|
|
||||||
DEFCIFCODE(FUNCTION_NOT_CONSIDERED, N_("function not considered for inlining"))
|
|
||||||
|
|
||||||
/* Inlining failed owing to unavailable function body. */
|
|
||||||
DEFCIFCODE(BODY_NOT_AVAILABLE, N_("function body not available"))
|
|
||||||
|
|
||||||
/* Extern inline function that has been redefined. */
|
|
||||||
DEFCIFCODE(REDEFINED_EXTERN_INLINE,
|
|
||||||
N_("redefined extern inline functions are not considered for "
|
|
||||||
"inlining"))
|
|
||||||
|
|
||||||
/* Function is not inlinable. */
|
|
||||||
DEFCIFCODE(FUNCTION_NOT_INLINABLE, N_("function not inlinable"))
|
|
||||||
|
|
||||||
/* Function is not overwritable. */
|
|
||||||
DEFCIFCODE(OVERWRITABLE, N_("function body can be overwritten at link time"))
|
|
||||||
|
|
||||||
/* Function is not an inlining candidate. */
|
|
||||||
DEFCIFCODE(FUNCTION_NOT_INLINE_CANDIDATE, N_("function not inline candidate"))
|
|
||||||
|
|
||||||
/* Inlining failed because of various limit parameters. */
|
|
||||||
DEFCIFCODE(LARGE_FUNCTION_GROWTH_LIMIT,
|
|
||||||
N_("--param large-function-growth limit reached"))
|
|
||||||
DEFCIFCODE(LARGE_STACK_FRAME_GROWTH_LIMIT,
|
|
||||||
N_("--param large-stack-frame-growth limit reached"))
|
|
||||||
DEFCIFCODE(MAX_INLINE_INSNS_SINGLE_LIMIT,
|
|
||||||
N_("--param max-inline-insns-single limit reached"))
|
|
||||||
DEFCIFCODE(MAX_INLINE_INSNS_AUTO_LIMIT,
|
|
||||||
N_("--param max-inline-insns-auto limit reached"))
|
|
||||||
DEFCIFCODE(INLINE_UNIT_GROWTH_LIMIT,
|
|
||||||
N_("--param inline-unit-growth limit reached"))
|
|
||||||
|
|
||||||
/* Recursive inlining. */
|
|
||||||
DEFCIFCODE(RECURSIVE_INLINING, N_("recursive inlining"))
|
|
||||||
|
|
||||||
/* Call is unlikely. */
|
|
||||||
DEFCIFCODE(UNLIKELY_CALL, N_("call is unlikely and code size would grow"))
|
|
||||||
|
|
||||||
/* Function is not declared as inline. */
|
|
||||||
DEFCIFCODE(NOT_DECLARED_INLINED,
|
|
||||||
N_("function not declared inline and code size would grow"))
|
|
||||||
|
|
||||||
/* Inlining suppressed due to size optimization. */
|
|
||||||
DEFCIFCODE(OPTIMIZING_FOR_SIZE,
|
|
||||||
N_("optimizing for size and code size would grow"))
|
|
||||||
|
|
||||||
/* Caller and callee disagree on the arguments. */
|
|
||||||
DEFCIFCODE(MISMATCHED_ARGUMENTS, N_("mismatched arguments"))
|
|
||||||
|
|
||||||
/* Call was originally indirect. */
|
|
||||||
DEFCIFCODE(ORIGINALLY_INDIRECT_CALL,
|
|
||||||
N_("originally indirect function call not considered for inlining"))
|
|
||||||
|
|
||||||
/* Ths edge represents an indirect edge with a yet-undetermined callee . */
|
|
||||||
DEFCIFCODE(INDIRECT_UNKNOWN_CALL,
|
|
||||||
N_("indirect function call with a yet undetermined callee"))
|
|
||||||
|
|
||||||
/* We can't inline different EH personalities together. */
|
|
||||||
DEFCIFCODE(EH_PERSONALITY, N_("exception handling personality mismatch"))
|
|
||||||
|
|
||||||
/* We can't inline if the callee can throw non-call exceptions but the
|
|
||||||
caller cannot. */
|
|
||||||
DEFCIFCODE(NON_CALL_EXCEPTIONS, N_("non-call exception handling mismatch"))
|
|
||||||
|
|
||||||
/* We can't inline because of mismatched target specific options. */
|
|
||||||
DEFCIFCODE(TARGET_OPTION_MISMATCH, N_("target specific option mismatch"))
|
|
||||||
|
|
||||||
/* We can't inline because of mismatched optimization levels. */
|
|
||||||
DEFCIFCODE(OPTIMIZATION_MISMATCH, N_("optimization level attribute mismatch"))
|
|
@ -1,10 +0,0 @@
|
|||||||
#ifndef GCC_CONFIG_H
|
|
||||||
#define GCC_CONFIG_H
|
|
||||||
#ifdef GENERATOR_FILE
|
|
||||||
#error config.h is for the host, not build, machine.
|
|
||||||
#endif
|
|
||||||
#include "auto-host.h"
|
|
||||||
#ifdef IN_GCC
|
|
||||||
# include "ansidecl.h"
|
|
||||||
#endif
|
|
||||||
#endif /* GCC_CONFIG_H */
|
|
@ -1,68 +0,0 @@
|
|||||||
/* Definitions needed when using stabs embedded in ELF sections.
|
|
||||||
Copyright (C) 1999-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
Under Section 7 of GPL version 3, you are granted additional
|
|
||||||
permissions described in the GCC Runtime Library Exception, version
|
|
||||||
3.1, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License and
|
|
||||||
a copy of the GCC Runtime Library Exception along with this program;
|
|
||||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* This file may be included by any ELF target which wishes to
|
|
||||||
support -gstabs generating stabs in sections, as produced by gas
|
|
||||||
and understood by gdb. */
|
|
||||||
|
|
||||||
#ifndef GCC_DBX_ELF_H
|
|
||||||
#define GCC_DBX_ELF_H
|
|
||||||
|
|
||||||
/* Output DBX (stabs) debugging information if doing -gstabs. */
|
|
||||||
|
|
||||||
#define DBX_DEBUGGING_INFO 1
|
|
||||||
|
|
||||||
/* Make LBRAC and RBRAC addresses relative to the start of the
|
|
||||||
function. The native Solaris stabs debugging format works this
|
|
||||||
way, gdb expects it, and it reduces the number of relocation
|
|
||||||
entries... */
|
|
||||||
|
|
||||||
#define DBX_BLOCKS_FUNCTION_RELATIVE 1
|
|
||||||
|
|
||||||
/* ... but, to make this work, functions must appear prior to line info. */
|
|
||||||
|
|
||||||
#define DBX_FUNCTION_FIRST
|
|
||||||
|
|
||||||
/* When generating stabs debugging, use N_BINCL entries. */
|
|
||||||
|
|
||||||
#define DBX_USE_BINCL
|
|
||||||
|
|
||||||
/* There is no limit to the length of stabs strings. */
|
|
||||||
|
|
||||||
#ifndef DBX_CONTIN_LENGTH
|
|
||||||
#define DBX_CONTIN_LENGTH 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Like block addresses, stabs line numbers are relative to the
|
|
||||||
current function. */
|
|
||||||
|
|
||||||
#define DBX_LINES_FUNCTION_RELATIVE 1
|
|
||||||
|
|
||||||
/* Generate a blank trailing N_SO to mark the end of the .o file, since
|
|
||||||
we can't depend upon the linker to mark .o file boundaries with
|
|
||||||
embedded stabs. */
|
|
||||||
|
|
||||||
#define DBX_OUTPUT_NULL_N_SO_AT_MAIN_SOURCE_FILE_END
|
|
||||||
|
|
||||||
#endif /* ! GCC_DBX_ELF_H */
|
|
@ -1,435 +0,0 @@
|
|||||||
/* elfos.h -- operating system specific defines to be used when
|
|
||||||
targeting GCC for some generic ELF system
|
|
||||||
Copyright (C) 1991-2013 Free Software Foundation, Inc.
|
|
||||||
Based on svr4.h contributed by Ron Guilmette (rfg@netcom.com).
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
Under Section 7 of GPL version 3, you are granted additional
|
|
||||||
permissions described in the GCC Runtime Library Exception, version
|
|
||||||
3.1, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License and
|
|
||||||
a copy of the GCC Runtime Library Exception along with this program;
|
|
||||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#define TARGET_OBJFMT_CPP_BUILTINS() \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
builtin_define ("__ELF__"); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
/* Define a symbol indicating that we are using elfos.h.
|
|
||||||
Some CPU specific configuration files use this. */
|
|
||||||
#define USING_ELFOS_H
|
|
||||||
|
|
||||||
/* The prefix to add to user-visible assembler symbols.
|
|
||||||
|
|
||||||
For ELF systems the convention is *not* to prepend a leading
|
|
||||||
underscore onto user-level symbol names. */
|
|
||||||
|
|
||||||
#undef USER_LABEL_PREFIX
|
|
||||||
#define USER_LABEL_PREFIX ""
|
|
||||||
|
|
||||||
/* The biggest alignment supported by ELF in bits. 32-bit ELF
|
|
||||||
supports section alignment up to (0x80000000 * 8), while
|
|
||||||
64-bit ELF supports (0x8000000000000000 * 8). If this macro
|
|
||||||
is not defined, the default is the largest alignment supported
|
|
||||||
by 32-bit ELF and representable on a 32-bit host. Use this
|
|
||||||
macro to limit the alignment which can be specified using
|
|
||||||
the `__attribute__ ((aligned (N)))' construct. */
|
|
||||||
#ifndef MAX_OFILE_ALIGNMENT
|
|
||||||
#define MAX_OFILE_ALIGNMENT (((unsigned int) 1 << 28) * 8)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Use periods rather than dollar signs in special g++ assembler names. */
|
|
||||||
|
|
||||||
#define NO_DOLLAR_IN_LABEL
|
|
||||||
|
|
||||||
/* Writing `int' for a bit-field forces int alignment for the structure. */
|
|
||||||
|
|
||||||
#ifndef PCC_BITFIELD_TYPE_MATTERS
|
|
||||||
#define PCC_BITFIELD_TYPE_MATTERS 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* All ELF targets can support DWARF-2. */
|
|
||||||
|
|
||||||
#define DWARF2_DEBUGGING_INFO 1
|
|
||||||
|
|
||||||
/* The GNU tools operate better with dwarf2, and it is required by some
|
|
||||||
psABI's. Since we don't have any native tools to be compatible with,
|
|
||||||
default to dwarf2. */
|
|
||||||
|
|
||||||
#ifndef PREFERRED_DEBUGGING_TYPE
|
|
||||||
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* All SVR4 targets use the ELF object file format. */
|
|
||||||
#define OBJECT_FORMAT_ELF
|
|
||||||
|
|
||||||
|
|
||||||
/* Output #ident as a .ident. */
|
|
||||||
|
|
||||||
#undef TARGET_ASM_OUTPUT_IDENT
|
|
||||||
#define TARGET_ASM_OUTPUT_IDENT default_asm_output_ident_directive
|
|
||||||
|
|
||||||
#undef SET_ASM_OP
|
|
||||||
#define SET_ASM_OP "\t.set\t"
|
|
||||||
|
|
||||||
/* Most svr4 assemblers want a .file directive at the beginning of
|
|
||||||
their input file. */
|
|
||||||
#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
|
|
||||||
|
|
||||||
/* This is how to allocate empty space in some section. The .zero
|
|
||||||
pseudo-op is used for this on most svr4 assemblers. */
|
|
||||||
|
|
||||||
#define SKIP_ASM_OP "\t.zero\t"
|
|
||||||
|
|
||||||
#undef ASM_OUTPUT_SKIP
|
|
||||||
#define ASM_OUTPUT_SKIP(FILE, SIZE) \
|
|
||||||
fprintf ((FILE), "%s"HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
|
|
||||||
SKIP_ASM_OP, (SIZE))
|
|
||||||
|
|
||||||
/* This is how to store into the string LABEL
|
|
||||||
the symbol_ref name of an internal numbered label where
|
|
||||||
PREFIX is the class of label and NUM is the number within the class.
|
|
||||||
This is suitable for output with `assemble_name'.
|
|
||||||
|
|
||||||
For most svr4 systems, the convention is that any symbol which begins
|
|
||||||
with a period is not put into the linker symbol table by the assembler. */
|
|
||||||
|
|
||||||
#undef ASM_GENERATE_INTERNAL_LABEL
|
|
||||||
#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
char *__p; \
|
|
||||||
(LABEL)[0] = '*'; \
|
|
||||||
(LABEL)[1] = '.'; \
|
|
||||||
__p = stpcpy (&(LABEL)[2], PREFIX); \
|
|
||||||
sprint_ul (__p, (unsigned long) (NUM)); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
/* Output the label which precedes a jumptable. Note that for all svr4
|
|
||||||
systems where we actually generate jumptables (which is to say every
|
|
||||||
svr4 target except i386, where we use casesi instead) we put the jump-
|
|
||||||
tables into the .rodata section and since other stuff could have been
|
|
||||||
put into the .rodata section prior to any given jumptable, we have to
|
|
||||||
make sure that the location counter for the .rodata section gets pro-
|
|
||||||
perly re-aligned prior to the actual beginning of the jump table. */
|
|
||||||
|
|
||||||
#undef ALIGN_ASM_OP
|
|
||||||
#define ALIGN_ASM_OP "\t.align\t"
|
|
||||||
|
|
||||||
#ifndef ASM_OUTPUT_BEFORE_CASE_LABEL
|
|
||||||
#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE, PREFIX, NUM, TABLE) \
|
|
||||||
ASM_OUTPUT_ALIGN ((FILE), 2);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef ASM_OUTPUT_CASE_LABEL
|
|
||||||
#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, JUMPTABLE) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
ASM_OUTPUT_BEFORE_CASE_LABEL (FILE, PREFIX, NUM, JUMPTABLE) \
|
|
||||||
(*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
/* The standard SVR4 assembler seems to require that certain builtin
|
|
||||||
library routines (e.g. .udiv) be explicitly declared as .globl
|
|
||||||
in each assembly file where they are referenced. */
|
|
||||||
|
|
||||||
#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
|
|
||||||
(*targetm.asm_out.globalize_label) (FILE, XSTR (FUN, 0))
|
|
||||||
|
|
||||||
/* This says how to output assembler code to declare an
|
|
||||||
uninitialized external linkage data object. Under SVR4,
|
|
||||||
the linker seems to want the alignment of data objects
|
|
||||||
to depend on their types. We do exactly that here. */
|
|
||||||
|
|
||||||
#define COMMON_ASM_OP "\t.comm\t"
|
|
||||||
|
|
||||||
#undef ASM_OUTPUT_ALIGNED_COMMON
|
|
||||||
#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
fprintf ((FILE), "%s", COMMON_ASM_OP); \
|
|
||||||
assemble_name ((FILE), (NAME)); \
|
|
||||||
fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", \
|
|
||||||
(SIZE), (ALIGN) / BITS_PER_UNIT); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
/* This says how to output assembler code to declare an
|
|
||||||
uninitialized internal linkage data object. Under SVR4,
|
|
||||||
the linker seems to want the alignment of data objects
|
|
||||||
to depend on their types. We do exactly that here. */
|
|
||||||
|
|
||||||
#define LOCAL_ASM_OP "\t.local\t"
|
|
||||||
|
|
||||||
#undef ASM_OUTPUT_ALIGNED_LOCAL
|
|
||||||
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
fprintf ((FILE), "%s", LOCAL_ASM_OP); \
|
|
||||||
assemble_name ((FILE), (NAME)); \
|
|
||||||
fprintf ((FILE), "\n"); \
|
|
||||||
ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
/* This is the pseudo-op used to generate a contiguous sequence of byte
|
|
||||||
values from a double-quoted string WITHOUT HAVING A TERMINATING NUL
|
|
||||||
AUTOMATICALLY APPENDED. This is the same for most svr4 assemblers. */
|
|
||||||
|
|
||||||
#undef ASCII_DATA_ASM_OP
|
|
||||||
#define ASCII_DATA_ASM_OP "\t.ascii\t"
|
|
||||||
|
|
||||||
/* Support a read-only data section. */
|
|
||||||
#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata"
|
|
||||||
|
|
||||||
/* On svr4, we *do* have support for the .init and .fini sections, and we
|
|
||||||
can put stuff in there to be executed before and after `main'. We let
|
|
||||||
crtstuff.c and other files know this by defining the following symbols.
|
|
||||||
The definitions say how to change sections to the .init and .fini
|
|
||||||
sections. This is the same for all known svr4 assemblers. */
|
|
||||||
|
|
||||||
#define INIT_SECTION_ASM_OP "\t.section\t.init"
|
|
||||||
#define FINI_SECTION_ASM_OP "\t.section\t.fini"
|
|
||||||
|
|
||||||
/* Output assembly directive to move to the beginning of current section. */
|
|
||||||
#ifdef HAVE_GAS_SUBSECTION_ORDERING
|
|
||||||
# define ASM_SECTION_START_OP "\t.subsection\t-1"
|
|
||||||
# define ASM_OUTPUT_SECTION_START(FILE) \
|
|
||||||
fprintf ((FILE), "%s\n", ASM_SECTION_START_OP)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
|
|
||||||
|
|
||||||
/* Switch into a generic section. */
|
|
||||||
#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
|
|
||||||
|
|
||||||
#undef TARGET_ASM_SELECT_RTX_SECTION
|
|
||||||
#define TARGET_ASM_SELECT_RTX_SECTION default_elf_select_rtx_section
|
|
||||||
#undef TARGET_ASM_SELECT_SECTION
|
|
||||||
#define TARGET_ASM_SELECT_SECTION default_elf_select_section
|
|
||||||
#undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
|
|
||||||
#define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS true
|
|
||||||
|
|
||||||
/* Define the strings used for the special svr4 .type and .size directives.
|
|
||||||
These strings generally do not vary from one system running svr4 to
|
|
||||||
another, but if a given system (e.g. m88k running svr) needs to use
|
|
||||||
different pseudo-op names for these, they may be overridden in the
|
|
||||||
file which includes this one. */
|
|
||||||
|
|
||||||
#define TYPE_ASM_OP "\t.type\t"
|
|
||||||
#define SIZE_ASM_OP "\t.size\t"
|
|
||||||
|
|
||||||
/* This is how we tell the assembler that a symbol is weak. */
|
|
||||||
|
|
||||||
#define ASM_WEAKEN_LABEL(FILE, NAME) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
fputs ("\t.weak\t", (FILE)); \
|
|
||||||
assemble_name ((FILE), (NAME)); \
|
|
||||||
fputc ('\n', (FILE)); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
/* The following macro defines the format used to output the second
|
|
||||||
operand of the .type assembler directive. Different svr4 assemblers
|
|
||||||
expect various different forms for this operand. The one given here
|
|
||||||
is just a default. You may need to override it in your machine-
|
|
||||||
specific tm.h file (depending upon the particulars of your assembler). */
|
|
||||||
|
|
||||||
#define TYPE_OPERAND_FMT "@%s"
|
|
||||||
|
|
||||||
/* Write the extra assembler code needed to declare a function's result.
|
|
||||||
Most svr4 assemblers don't require any special declaration of the
|
|
||||||
result value, but there are exceptions. */
|
|
||||||
|
|
||||||
#ifndef ASM_DECLARE_RESULT
|
|
||||||
#define ASM_DECLARE_RESULT(FILE, RESULT)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* These macros generate the special .type and .size directives which
|
|
||||||
are used to set the corresponding fields of the linker symbol table
|
|
||||||
entries in an ELF object file under SVR4. These macros also output
|
|
||||||
the starting labels for the relevant functions/objects. */
|
|
||||||
|
|
||||||
/* Write the extra assembler code needed to declare a function properly.
|
|
||||||
Some svr4 assemblers need to also have something extra said about the
|
|
||||||
function's return value. We allow for that here. */
|
|
||||||
|
|
||||||
#ifndef ASM_DECLARE_FUNCTION_NAME
|
|
||||||
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
|
|
||||||
ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
|
|
||||||
ASM_OUTPUT_FUNCTION_LABEL (FILE, NAME, DECL); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Write the extra assembler code needed to declare an object properly. */
|
|
||||||
|
|
||||||
#ifdef HAVE_GAS_GNU_UNIQUE_OBJECT
|
|
||||||
#define USE_GNU_UNIQUE_OBJECT flag_gnu_unique
|
|
||||||
#else
|
|
||||||
#define USE_GNU_UNIQUE_OBJECT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
HOST_WIDE_INT size; \
|
|
||||||
\
|
|
||||||
/* For template static data member instantiations or \
|
|
||||||
inline fn local statics and their guard variables, use \
|
|
||||||
gnu_unique_object so that they will be combined even under \
|
|
||||||
RTLD_LOCAL. Don't use gnu_unique_object for typeinfo, \
|
|
||||||
vtables and other read-only artificial decls. */ \
|
|
||||||
if (USE_GNU_UNIQUE_OBJECT && DECL_ONE_ONLY (DECL) \
|
|
||||||
&& (!DECL_ARTIFICIAL (DECL) || !TREE_READONLY (DECL))) \
|
|
||||||
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "gnu_unique_object"); \
|
|
||||||
else \
|
|
||||||
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
|
|
||||||
\
|
|
||||||
size_directive_output = 0; \
|
|
||||||
if (!flag_inhibit_size_directive \
|
|
||||||
&& (DECL) && DECL_SIZE (DECL)) \
|
|
||||||
{ \
|
|
||||||
size_directive_output = 1; \
|
|
||||||
size = int_size_in_bytes (TREE_TYPE (DECL)); \
|
|
||||||
ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, size); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
ASM_OUTPUT_LABEL (FILE, NAME); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
/* Output the size directive for a decl in rest_of_decl_compilation
|
|
||||||
in the case where we did not do so before the initializer.
|
|
||||||
Once we find the error_mark_node, we know that the value of
|
|
||||||
size_directive_output was set
|
|
||||||
by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */
|
|
||||||
|
|
||||||
#undef ASM_FINISH_DECLARE_OBJECT
|
|
||||||
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END)\
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
const char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
|
|
||||||
HOST_WIDE_INT size; \
|
|
||||||
\
|
|
||||||
if (!flag_inhibit_size_directive \
|
|
||||||
&& DECL_SIZE (DECL) \
|
|
||||||
&& ! AT_END && TOP_LEVEL \
|
|
||||||
&& DECL_INITIAL (DECL) == error_mark_node \
|
|
||||||
&& !size_directive_output) \
|
|
||||||
{ \
|
|
||||||
size_directive_output = 1; \
|
|
||||||
size = int_size_in_bytes (TREE_TYPE (DECL)); \
|
|
||||||
ASM_OUTPUT_SIZE_DIRECTIVE (FILE, name, size); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
/* This is how to declare the size of a function. */
|
|
||||||
#ifndef ASM_DECLARE_FUNCTION_SIZE
|
|
||||||
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if (!flag_inhibit_size_directive) \
|
|
||||||
ASM_OUTPUT_MEASURED_SIZE (FILE, FNAME); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* A table of bytes codes used by the ASM_OUTPUT_ASCII and
|
|
||||||
ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table
|
|
||||||
corresponds to a particular byte value [0..255]. For any
|
|
||||||
given byte value, if the value in the corresponding table
|
|
||||||
position is zero, the given character can be output directly.
|
|
||||||
If the table value is 1, the byte must be output as a \ooo
|
|
||||||
octal escape. If the tables value is anything else, then the
|
|
||||||
byte value should be output as a \ followed by the value
|
|
||||||
in the table. Note that we can use standard UN*X escape
|
|
||||||
sequences for many control characters, but we don't use
|
|
||||||
\a to represent BEL because some svr4 assemblers (e.g. on
|
|
||||||
the i386) don't know about that. Also, we don't use \v
|
|
||||||
since some versions of gas, such as 2.2 did not accept it. */
|
|
||||||
|
|
||||||
#define ELF_ASCII_ESCAPES \
|
|
||||||
"\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
|
|
||||||
\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
|
|
||||||
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\
|
|
||||||
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\
|
|
||||||
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
|
|
||||||
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
|
|
||||||
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
|
|
||||||
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"
|
|
||||||
|
|
||||||
/* Some svr4 assemblers have a limit on the number of characters which
|
|
||||||
can appear in the operand of a .string directive. If your assembler
|
|
||||||
has such a limitation, you should define STRING_LIMIT to reflect that
|
|
||||||
limit. Note that at least some svr4 assemblers have a limit on the
|
|
||||||
actual number of bytes in the double-quoted string, and that they
|
|
||||||
count each character in an escape sequence as one byte. Thus, an
|
|
||||||
escape sequence like \377 would count as four bytes.
|
|
||||||
|
|
||||||
If your target assembler doesn't support the .string directive, you
|
|
||||||
should define this to zero.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define ELF_STRING_LIMIT ((unsigned) 256)
|
|
||||||
|
|
||||||
#define STRING_ASM_OP "\t.string\t"
|
|
||||||
|
|
||||||
/* The routine used to output NUL terminated strings. We use a special
|
|
||||||
version of this for most svr4 targets because doing so makes the
|
|
||||||
generated assembly code more compact (and thus faster to assemble)
|
|
||||||
as well as more readable, especially for targets like the i386
|
|
||||||
(where the only alternative is to output character sequences as
|
|
||||||
comma separated lists of numbers). */
|
|
||||||
|
|
||||||
#define ASM_OUTPUT_LIMITED_STRING(FILE, STR) \
|
|
||||||
default_elf_asm_output_limited_string ((FILE), (STR))
|
|
||||||
|
|
||||||
/* The routine used to output sequences of byte values. We use a special
|
|
||||||
version of this for most svr4 targets because doing so makes the
|
|
||||||
generated assembly code more compact (and thus faster to assemble)
|
|
||||||
as well as more readable. Note that if we find subparts of the
|
|
||||||
character sequence which end with NUL (and which are shorter than
|
|
||||||
STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
|
|
||||||
|
|
||||||
#undef ASM_OUTPUT_ASCII
|
|
||||||
#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \
|
|
||||||
default_elf_asm_output_ascii ((FILE), (STR), (LENGTH));
|
|
||||||
|
|
||||||
/* Allow the use of the -frecord-gcc-switches switch via the
|
|
||||||
elf_record_gcc_switches function defined in varasm.c. */
|
|
||||||
#undef TARGET_ASM_RECORD_GCC_SWITCHES
|
|
||||||
#define TARGET_ASM_RECORD_GCC_SWITCHES elf_record_gcc_switches
|
|
||||||
|
|
||||||
/* A C statement (sans semicolon) to output to the stdio stream STREAM
|
|
||||||
any text necessary for declaring the name of an external symbol
|
|
||||||
named NAME which is referenced in this compilation but not defined.
|
|
||||||
It is needed to properly support non-default visibility. */
|
|
||||||
|
|
||||||
#ifndef ASM_OUTPUT_EXTERNAL
|
|
||||||
#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
|
|
||||||
default_elf_asm_output_external (FILE, DECL, NAME)
|
|
||||||
#endif
|
|
@ -1,55 +0,0 @@
|
|||||||
/* Definitions for <stdint.h> types on systems using GNU libc or uClibc.
|
|
||||||
Copyright (C) 2008-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
Under Section 7 of GPL version 3, you are granted additional
|
|
||||||
permissions described in the GCC Runtime Library Exception, version
|
|
||||||
3.1, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License and
|
|
||||||
a copy of the GCC Runtime Library Exception along with this program;
|
|
||||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#define SIG_ATOMIC_TYPE "int"
|
|
||||||
|
|
||||||
#define INT8_TYPE "signed char"
|
|
||||||
#define INT16_TYPE "short int"
|
|
||||||
#define INT32_TYPE "int"
|
|
||||||
#define INT64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
|
|
||||||
#define UINT8_TYPE "unsigned char"
|
|
||||||
#define UINT16_TYPE "short unsigned int"
|
|
||||||
#define UINT32_TYPE "unsigned int"
|
|
||||||
#define UINT64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
|
|
||||||
|
|
||||||
#define INT_LEAST8_TYPE "signed char"
|
|
||||||
#define INT_LEAST16_TYPE "short int"
|
|
||||||
#define INT_LEAST32_TYPE "int"
|
|
||||||
#define INT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
|
|
||||||
#define UINT_LEAST8_TYPE "unsigned char"
|
|
||||||
#define UINT_LEAST16_TYPE "short unsigned int"
|
|
||||||
#define UINT_LEAST32_TYPE "unsigned int"
|
|
||||||
#define UINT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
|
|
||||||
|
|
||||||
#define INT_FAST8_TYPE "signed char"
|
|
||||||
#define INT_FAST16_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
|
|
||||||
#define INT_FAST32_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
|
|
||||||
#define INT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
|
|
||||||
#define UINT_FAST8_TYPE "unsigned char"
|
|
||||||
#define UINT_FAST16_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "unsigned int")
|
|
||||||
#define UINT_FAST32_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "unsigned int")
|
|
||||||
#define UINT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
|
|
||||||
|
|
||||||
#define INTPTR_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
|
|
||||||
#define UINTPTR_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "unsigned int")
|
|
@ -1,123 +0,0 @@
|
|||||||
/* Definitions for systems using, at least optionally, a GNU
|
|
||||||
(glibc-based) userspace or other userspace with libc derived from
|
|
||||||
glibc (e.g. uClibc) or for which similar specs are appropriate.
|
|
||||||
Copyright (C) 1995-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Eric Youngdale.
|
|
||||||
Modified for stabs-in-ELF by H.J. Lu (hjl@lucon.org).
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
Under Section 7 of GPL version 3, you are granted additional
|
|
||||||
permissions described in the GCC Runtime Library Exception, version
|
|
||||||
3.1, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License and
|
|
||||||
a copy of the GCC Runtime Library Exception along with this program;
|
|
||||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Don't assume anything about the header files. */
|
|
||||||
#define NO_IMPLICIT_EXTERN_C
|
|
||||||
|
|
||||||
#undef ASM_APP_ON
|
|
||||||
#define ASM_APP_ON "#APP\n"
|
|
||||||
|
|
||||||
#undef ASM_APP_OFF
|
|
||||||
#define ASM_APP_OFF "#NO_APP\n"
|
|
||||||
|
|
||||||
/* Provide a STARTFILE_SPEC appropriate for GNU userspace. Here we add
|
|
||||||
the GNU userspace magical crtbegin.o file (see crtstuff.c) which
|
|
||||||
provides part of the support for getting C++ file-scope static
|
|
||||||
object constructed before entering `main'. */
|
|
||||||
|
|
||||||
#if defined HAVE_LD_PIE
|
|
||||||
#define GNU_USER_TARGET_STARTFILE_SPEC \
|
|
||||||
"%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} \
|
|
||||||
crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
|
|
||||||
#else
|
|
||||||
#define GNU_USER_TARGET_STARTFILE_SPEC \
|
|
||||||
"%{!shared: %{pg|p|profile:gcrt1.o%s;:crt1.o%s}} \
|
|
||||||
crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
|
|
||||||
#endif
|
|
||||||
#undef STARTFILE_SPEC
|
|
||||||
#define STARTFILE_SPEC GNU_USER_TARGET_STARTFILE_SPEC
|
|
||||||
|
|
||||||
/* Provide a ENDFILE_SPEC appropriate for GNU userspace. Here we tack on
|
|
||||||
the GNU userspace magical crtend.o file (see crtstuff.c) which
|
|
||||||
provides part of the support for getting C++ file-scope static
|
|
||||||
object constructed before entering `main', followed by a normal
|
|
||||||
GNU userspace "finalizer" file, `crtn.o'. */
|
|
||||||
|
|
||||||
#define GNU_USER_TARGET_ENDFILE_SPEC \
|
|
||||||
"%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
|
|
||||||
#undef ENDFILE_SPEC
|
|
||||||
#define ENDFILE_SPEC GNU_USER_TARGET_ENDFILE_SPEC
|
|
||||||
|
|
||||||
/* This is for -profile to use -lc_p instead of -lc. */
|
|
||||||
#define GNU_USER_TARGET_CC1_SPEC "%{profile:-p}"
|
|
||||||
#ifndef CC1_SPEC
|
|
||||||
#define CC1_SPEC GNU_USER_TARGET_CC1_SPEC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The GNU C++ standard library requires that these macros be defined. */
|
|
||||||
#undef CPLUSPLUS_CPP_SPEC
|
|
||||||
#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
|
|
||||||
|
|
||||||
#define GNU_USER_TARGET_LIB_SPEC \
|
|
||||||
"%{pthread:-lpthread} \
|
|
||||||
%{shared:-lc} \
|
|
||||||
%{!shared:%{mieee-fp:-lieee} %{profile:-lc_p}%{!profile:-lc}}"
|
|
||||||
#undef LIB_SPEC
|
|
||||||
#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC
|
|
||||||
|
|
||||||
#if defined(HAVE_LD_EH_FRAME_HDR)
|
|
||||||
#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef LINK_GCC_C_SEQUENCE_SPEC
|
|
||||||
#define LINK_GCC_C_SEQUENCE_SPEC \
|
|
||||||
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
|
|
||||||
|
|
||||||
/* Use --as-needed -lgcc_s for eh support. */
|
|
||||||
#ifdef HAVE_LD_AS_NEEDED
|
|
||||||
#define USE_LD_AS_NEEDED 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define TARGET_POSIX_IO
|
|
||||||
|
|
||||||
#define TARGET_C99_FUNCTIONS 1
|
|
||||||
#define TARGET_HAS_SINCOS 1
|
|
||||||
|
|
||||||
/* Link -lasan early on the command line. For -static-libasan, don't link
|
|
||||||
it for -shared link, the executable should be compiled with -static-libasan
|
|
||||||
in that case, and for executable link link with --{,no-}whole-archive around
|
|
||||||
it to force everything into the executable. And similarly for -ltsan. */
|
|
||||||
#if defined(HAVE_LD_STATIC_DYNAMIC)
|
|
||||||
#undef LIBASAN_EARLY_SPEC
|
|
||||||
#define LIBASAN_EARLY_SPEC "%{!shared:libasan_preinit%O%s} " \
|
|
||||||
"%{static-libasan:%{!shared:" \
|
|
||||||
LD_STATIC_OPTION " --whole-archive -lasan --no-whole-archive " \
|
|
||||||
LD_DYNAMIC_OPTION "}}%{!static-libasan:-lasan}"
|
|
||||||
#undef LIBTSAN_EARLY_SPEC
|
|
||||||
#define LIBTSAN_EARLY_SPEC "%{static-libtsan:%{!shared:" \
|
|
||||||
LD_STATIC_OPTION " --whole-archive -ltsan --no-whole-archive " \
|
|
||||||
LD_DYNAMIC_OPTION "}}%{!static-libtsan:-ltsan}"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Additional libraries needed by -static-libasan. */
|
|
||||||
#undef STATIC_LIBASAN_LIBS
|
|
||||||
#define STATIC_LIBASAN_LIBS "-ldl -lpthread"
|
|
||||||
|
|
||||||
/* Additional libraries needed by -static-libtsan. */
|
|
||||||
#undef STATIC_LIBTSAN_LIBS
|
|
||||||
#define STATIC_LIBTSAN_LIBS "-ldl -lpthread"
|
|
@ -1,91 +0,0 @@
|
|||||||
/* Definitions for AT&T assembler syntax for the Intel 80386.
|
|
||||||
Copyright (C) 1988-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
Under Section 7 of GPL version 3, you are granted additional
|
|
||||||
permissions described in the GCC Runtime Library Exception, version
|
|
||||||
3.1, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License and
|
|
||||||
a copy of the GCC Runtime Library Exception along with this program;
|
|
||||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
|
|
||||||
/* Define the syntax of instructions and addresses. */
|
|
||||||
|
|
||||||
/* Prefix for internally generated assembler labels. */
|
|
||||||
#define LPREFIX ".L"
|
|
||||||
|
|
||||||
/* Assembler pseudos to introduce constants of various size. */
|
|
||||||
|
|
||||||
#define ASM_BYTE "\t.byte\t"
|
|
||||||
#define ASM_SHORT "\t.value\t"
|
|
||||||
#define ASM_LONG "\t.long\t"
|
|
||||||
#define ASM_QUAD "\t.quad\t" /* Should not be used for 32bit compilation. */
|
|
||||||
|
|
||||||
/* How to output an ASCII string constant. */
|
|
||||||
|
|
||||||
#undef ASM_OUTPUT_ASCII
|
|
||||||
#define ASM_OUTPUT_ASCII(FILE, PTR, SIZE) \
|
|
||||||
do \
|
|
||||||
{ size_t i = 0, limit = (SIZE); \
|
|
||||||
while (i < limit) \
|
|
||||||
{ if (i%10 == 0) { if (i!=0) putc ('\n', (FILE)); \
|
|
||||||
fputs (ASM_BYTE, (FILE)); } \
|
|
||||||
else putc (',', (FILE)); \
|
|
||||||
fprintf ((FILE), "0x%x", ((PTR)[i++] & 0377)) ;} \
|
|
||||||
putc ('\n', (FILE)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* Output at beginning of assembler file. */
|
|
||||||
#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
|
|
||||||
|
|
||||||
/* This is how to output an assembler line
|
|
||||||
that says to advance the location counter
|
|
||||||
to a multiple of 2**LOG bytes. */
|
|
||||||
|
|
||||||
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
|
|
||||||
if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
|
|
||||||
|
|
||||||
/* This is how to output an assembler line
|
|
||||||
that says to advance the location counter by SIZE bytes. */
|
|
||||||
|
|
||||||
#undef ASM_OUTPUT_SKIP
|
|
||||||
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
|
|
||||||
fprintf ((FILE), "\t.set .,.+%u\n", (int)(SIZE))
|
|
||||||
|
|
||||||
/* Can't use ASM_OUTPUT_SKIP in text section; it doesn't leave 0s. */
|
|
||||||
|
|
||||||
#define ASM_NO_SKIP_IN_TEXT 1
|
|
||||||
|
|
||||||
/* Define the syntax of labels and symbol definitions/declarations. */
|
|
||||||
|
|
||||||
/* The prefix to add for compiler private assembler symbols. */
|
|
||||||
#undef LOCAL_LABEL_PREFIX
|
|
||||||
#define LOCAL_LABEL_PREFIX "."
|
|
||||||
|
|
||||||
/* This is how to store into the string BUF
|
|
||||||
the symbol_ref name of an internal numbered label where
|
|
||||||
PREFIX is the class of label and NUM is the number within the class.
|
|
||||||
This is suitable for output with `assemble_name'. */
|
|
||||||
|
|
||||||
#undef ASM_GENERATE_INTERNAL_LABEL
|
|
||||||
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
|
|
||||||
sprintf ((BUF), LOCAL_LABEL_PREFIX "%s%ld", (PREFIX), (long)(NUMBER))
|
|
||||||
|
|
||||||
/* The prefix to add to user-visible assembler symbols. */
|
|
||||||
|
|
||||||
#undef USER_LABEL_PREFIX
|
|
||||||
#define USER_LABEL_PREFIX ""
|
|
@ -1,29 +0,0 @@
|
|||||||
/* Make configure files to produce biarch compiler defaulting to 64bit mode.
|
|
||||||
This file must be included very first, while the OS specific file later
|
|
||||||
to overwrite otherwise wrong defaults.
|
|
||||||
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Bo Thorsen <bo@suse.de>.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
Under Section 7 of GPL version 3, you are granted additional
|
|
||||||
permissions described in the GCC Runtime Library Exception, version
|
|
||||||
3.1, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License and
|
|
||||||
a copy of the GCC Runtime Library Exception along with this program;
|
|
||||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#define TARGET_64BIT_DEFAULT (OPTION_MASK_ISA_64BIT | OPTION_MASK_ABI_64)
|
|
||||||
#define TARGET_BI_ARCH 1
|
|
@ -1,72 +0,0 @@
|
|||||||
/* Common definitions for Intel 386 and AMD x86-64 systems using
|
|
||||||
GNU userspace. Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Ilya Enkovich.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* The svr4 ABI for the i386 says that records and unions are returned
|
|
||||||
in memory. In the 64bit compilation we will turn this flag off in
|
|
||||||
ix86_option_override_internal, as we never do pcc_struct_return
|
|
||||||
scheme on this target. */
|
|
||||||
#undef DEFAULT_PCC_STRUCT_RETURN
|
|
||||||
#define DEFAULT_PCC_STRUCT_RETURN 1
|
|
||||||
|
|
||||||
/* We arrange for the whole %fs segment to map the tls area. */
|
|
||||||
#undef TARGET_TLS_DIRECT_SEG_REFS_DEFAULT
|
|
||||||
#define TARGET_TLS_DIRECT_SEG_REFS_DEFAULT MASK_TLS_DIRECT_SEG_REFS
|
|
||||||
|
|
||||||
#define TARGET_OS_CPP_BUILTINS() \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
GNU_USER_TARGET_OS_CPP_BUILTINS(); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
#undef CPP_SPEC
|
|
||||||
#define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}"
|
|
||||||
|
|
||||||
#undef GNU_USER_TARGET_CC1_SPEC
|
|
||||||
#define GNU_USER_TARGET_CC1_SPEC "%(cc1_cpu) %{profile:-p}"
|
|
||||||
|
|
||||||
#undef CC1_SPEC
|
|
||||||
#define CC1_SPEC GNU_USER_TARGET_CC1_SPEC
|
|
||||||
|
|
||||||
/* Similar to standard GNU userspace, but adding -ffast-math support. */
|
|
||||||
#define GNU_USER_TARGET_MATHFILE_SPEC \
|
|
||||||
"%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
|
|
||||||
%{mpc32:crtprec32.o%s} \
|
|
||||||
%{mpc64:crtprec64.o%s} \
|
|
||||||
%{mpc80:crtprec80.o%s}"
|
|
||||||
|
|
||||||
#undef ENDFILE_SPEC
|
|
||||||
#define ENDFILE_SPEC \
|
|
||||||
GNU_USER_TARGET_MATHFILE_SPEC " " \
|
|
||||||
GNU_USER_TARGET_ENDFILE_SPEC
|
|
||||||
|
|
||||||
/* Put all *tf routines in libgcc. */
|
|
||||||
#undef LIBGCC2_HAS_TF_MODE
|
|
||||||
#define LIBGCC2_HAS_TF_MODE 1
|
|
||||||
#define LIBGCC2_TF_CEXT q
|
|
||||||
#define TF_SIZE 113
|
|
||||||
|
|
||||||
#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
|
|
||||||
|
|
||||||
/* The stack pointer needs to be moved while checking the stack. */
|
|
||||||
#define STACK_CHECK_MOVING_SP 1
|
|
||||||
|
|
||||||
/* Static stack checking is supported by means of probes. */
|
|
||||||
#define STACK_CHECK_STATIC_BUILTIN 1
|
|
@ -1,99 +0,0 @@
|
|||||||
/* Definitions for AMD x86-64 using GNU userspace.
|
|
||||||
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Jan Hubicka <jh@suse.cz>, based on linux.h.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
Under Section 7 of GPL version 3, you are granted additional
|
|
||||||
permissions described in the GCC Runtime Library Exception, version
|
|
||||||
3.1, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License and
|
|
||||||
a copy of the GCC Runtime Library Exception along with this program;
|
|
||||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Provide a LINK_SPEC. Here we provide support for the special GCC
|
|
||||||
options -static and -shared, which allow us to link things in one
|
|
||||||
of these three modes by applying the appropriate combinations of
|
|
||||||
options at link-time.
|
|
||||||
|
|
||||||
When the -shared link option is used a final link is not being
|
|
||||||
done. */
|
|
||||||
|
|
||||||
#if TARGET_64BIT_DEFAULT
|
|
||||||
#define SPEC_32 "m32"
|
|
||||||
#if TARGET_BI_ARCH == 2
|
|
||||||
#define SPEC_64 "m64"
|
|
||||||
#define SPEC_X32 "m32|m64:;"
|
|
||||||
#else
|
|
||||||
#define SPEC_64 "m32|mx32:;"
|
|
||||||
#define SPEC_X32 "mx32"
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define SPEC_32 "m64|mx32:;"
|
|
||||||
#define SPEC_64 "m64"
|
|
||||||
#define SPEC_X32 "mx32"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef ASM_SPEC
|
|
||||||
#define ASM_SPEC "%{" SPEC_32 ":--32} \
|
|
||||||
%{" SPEC_64 ":--64} \
|
|
||||||
%{" SPEC_X32 ":--x32} \
|
|
||||||
%{!mno-sse2avx:%{mavx:-msse2avx}} %{msse2avx:%{!mavx:-msse2avx}}"
|
|
||||||
|
|
||||||
#define GNU_USER_TARGET_LINK_SPEC \
|
|
||||||
"%{" SPEC_64 ":-m " GNU_USER_LINK_EMULATION64 "} \
|
|
||||||
%{" SPEC_32 ":-m " GNU_USER_LINK_EMULATION32 "} \
|
|
||||||
%{" SPEC_X32 ":-m " GNU_USER_LINK_EMULATIONX32 "} \
|
|
||||||
%{shared:-shared} \
|
|
||||||
%{!shared: \
|
|
||||||
%{!static: \
|
|
||||||
%{rdynamic:-export-dynamic} \
|
|
||||||
%{" SPEC_32 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "} \
|
|
||||||
%{" SPEC_64 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "} \
|
|
||||||
%{" SPEC_X32 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKERX32 "}} \
|
|
||||||
%{static:-static}}"
|
|
||||||
|
|
||||||
#undef LINK_SPEC
|
|
||||||
#define LINK_SPEC GNU_USER_TARGET_LINK_SPEC
|
|
||||||
|
|
||||||
#if TARGET_64BIT_DEFAULT
|
|
||||||
#if TARGET_BI_ARCH == 2
|
|
||||||
#define MULTILIB_DEFAULTS { "mx32" }
|
|
||||||
#else
|
|
||||||
#define MULTILIB_DEFAULTS { "m64" }
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define MULTILIB_DEFAULTS { "m32" }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef TARGET_LIBC_PROVIDES_SSP
|
|
||||||
/* i386 glibc provides __stack_chk_guard in %gs:0x14,
|
|
||||||
x32 glibc provides it in %fs:0x18.
|
|
||||||
x86_64 glibc provides it in %fs:0x28. */
|
|
||||||
#define TARGET_THREAD_SSP_OFFSET \
|
|
||||||
(TARGET_64BIT ? (TARGET_X32 ? 0x18 : 0x28) : 0x14)
|
|
||||||
|
|
||||||
/* We only build the -fsplit-stack support in libgcc if the
|
|
||||||
assembler has full support for the CFI directives. */
|
|
||||||
#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE
|
|
||||||
#define TARGET_CAN_SPLIT_STACK
|
|
||||||
#endif
|
|
||||||
/* We steal the last transactional memory word. */
|
|
||||||
#define TARGET_THREAD_SPLIT_STACK_OFFSET \
|
|
||||||
(TARGET_64BIT ? (TARGET_X32 ? 0x40 : 0x70) : 0x30)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef WCHAR_TYPE
|
|
||||||
#define WCHAR_TYPE (TARGET_LP64 ? "int" : "long int")
|
|
@ -1,88 +0,0 @@
|
|||||||
/* Definitions for option handling for IA-32.
|
|
||||||
Copyright (C) 1988-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
Under Section 7 of GPL version 3, you are granted additional
|
|
||||||
permissions described in the GCC Runtime Library Exception, version
|
|
||||||
3.1, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License and
|
|
||||||
a copy of the GCC Runtime Library Exception along with this program;
|
|
||||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef I386_OPTS_H
|
|
||||||
#define I386_OPTS_H
|
|
||||||
|
|
||||||
/* Algorithm to expand string function with. */
|
|
||||||
enum stringop_alg
|
|
||||||
{
|
|
||||||
no_stringop,
|
|
||||||
libcall,
|
|
||||||
rep_prefix_1_byte,
|
|
||||||
rep_prefix_4_byte,
|
|
||||||
rep_prefix_8_byte,
|
|
||||||
loop_1_byte,
|
|
||||||
loop,
|
|
||||||
unrolled_loop
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Available call abi. */
|
|
||||||
enum calling_abi
|
|
||||||
{
|
|
||||||
SYSV_ABI = 0,
|
|
||||||
MS_ABI = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
enum fpmath_unit
|
|
||||||
{
|
|
||||||
FPMATH_387 = 1,
|
|
||||||
FPMATH_SSE = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
enum tls_dialect
|
|
||||||
{
|
|
||||||
TLS_DIALECT_GNU,
|
|
||||||
TLS_DIALECT_GNU2,
|
|
||||||
TLS_DIALECT_SUN
|
|
||||||
};
|
|
||||||
|
|
||||||
enum cmodel {
|
|
||||||
CM_32, /* The traditional 32-bit ABI. */
|
|
||||||
CM_SMALL, /* Assumes all code and data fits in the low 31 bits. */
|
|
||||||
CM_KERNEL, /* Assumes all code and data fits in the high 31 bits. */
|
|
||||||
CM_MEDIUM, /* Assumes code fits in the low 31 bits; data unlimited. */
|
|
||||||
CM_LARGE, /* No assumptions. */
|
|
||||||
CM_SMALL_PIC, /* Assumes code+data+got/plt fits in a 31 bit region. */
|
|
||||||
CM_MEDIUM_PIC,/* Assumes code+got/plt fits in a 31 bit region. */
|
|
||||||
CM_LARGE_PIC /* No assumptions. */
|
|
||||||
};
|
|
||||||
|
|
||||||
enum pmode {
|
|
||||||
PMODE_SI, /* Pmode == SImode. */
|
|
||||||
PMODE_DI /* Pmode == DImode. */
|
|
||||||
};
|
|
||||||
|
|
||||||
enum asm_dialect {
|
|
||||||
ASM_ATT,
|
|
||||||
ASM_INTEL
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ix86_veclibabi {
|
|
||||||
ix86_veclibabi_type_none,
|
|
||||||
ix86_veclibabi_type_svml,
|
|
||||||
ix86_veclibabi_type_acml
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,326 +0,0 @@
|
|||||||
/* Definitions of target machine for GCC for IA-32.
|
|
||||||
Copyright (C) 1988-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* In i386-common.c. */
|
|
||||||
extern bool ix86_handle_option (struct gcc_options *opts,
|
|
||||||
struct gcc_options *opts_set ATTRIBUTE_UNUSED,
|
|
||||||
const struct cl_decoded_option *decoded,
|
|
||||||
location_t loc);
|
|
||||||
|
|
||||||
/* Functions in i386.c */
|
|
||||||
extern bool ix86_target_stack_probe (void);
|
|
||||||
extern bool ix86_can_use_return_insn_p (void);
|
|
||||||
extern void ix86_setup_frame_addresses (void);
|
|
||||||
|
|
||||||
extern HOST_WIDE_INT ix86_initial_elimination_offset (int, int);
|
|
||||||
extern void ix86_expand_prologue (void);
|
|
||||||
extern void ix86_maybe_emit_epilogue_vzeroupper (void);
|
|
||||||
extern void ix86_expand_epilogue (int);
|
|
||||||
extern void ix86_expand_split_stack_prologue (void);
|
|
||||||
|
|
||||||
extern void ix86_output_addr_vec_elt (FILE *, int);
|
|
||||||
extern void ix86_output_addr_diff_elt (FILE *, int, int);
|
|
||||||
|
|
||||||
extern enum calling_abi ix86_cfun_abi (void);
|
|
||||||
extern enum calling_abi ix86_function_type_abi (const_tree);
|
|
||||||
|
|
||||||
#ifdef RTX_CODE
|
|
||||||
extern int standard_80387_constant_p (rtx);
|
|
||||||
extern const char *standard_80387_constant_opcode (rtx);
|
|
||||||
extern rtx standard_80387_constant_rtx (int);
|
|
||||||
extern int standard_sse_constant_p (rtx);
|
|
||||||
extern const char *standard_sse_constant_opcode (rtx, rtx);
|
|
||||||
extern bool symbolic_reference_mentioned_p (rtx);
|
|
||||||
extern bool extended_reg_mentioned_p (rtx);
|
|
||||||
extern bool x86_extended_QIreg_mentioned_p (rtx);
|
|
||||||
extern bool x86_extended_reg_mentioned_p (rtx);
|
|
||||||
extern bool x86_maybe_negate_const_int (rtx *, enum machine_mode);
|
|
||||||
extern enum machine_mode ix86_cc_mode (enum rtx_code, rtx, rtx);
|
|
||||||
|
|
||||||
extern int avx_vpermilp_parallel (rtx par, enum machine_mode mode);
|
|
||||||
extern int avx_vperm2f128_parallel (rtx par, enum machine_mode mode);
|
|
||||||
|
|
||||||
extern bool ix86_expand_movmem (rtx, rtx, rtx, rtx, rtx, rtx);
|
|
||||||
extern bool ix86_expand_setmem (rtx, rtx, rtx, rtx, rtx, rtx);
|
|
||||||
extern bool ix86_expand_strlen (rtx, rtx, rtx, rtx);
|
|
||||||
|
|
||||||
extern bool constant_address_p (rtx);
|
|
||||||
extern bool legitimate_pic_operand_p (rtx);
|
|
||||||
extern bool legitimate_pic_address_disp_p (rtx);
|
|
||||||
extern bool ix86_legitimize_reload_address (rtx, enum machine_mode,
|
|
||||||
int, int, int);
|
|
||||||
extern void print_reg (rtx, int, FILE*);
|
|
||||||
extern void ix86_print_operand (FILE *, rtx, int);
|
|
||||||
|
|
||||||
extern void split_double_mode (enum machine_mode, rtx[], int, rtx[], rtx[]);
|
|
||||||
|
|
||||||
extern const char *output_set_got (rtx, rtx);
|
|
||||||
extern const char *output_387_binary_op (rtx, rtx*);
|
|
||||||
extern const char *output_387_reg_move (rtx, rtx*);
|
|
||||||
extern const char *output_fix_trunc (rtx, rtx*, bool);
|
|
||||||
extern const char *output_fp_compare (rtx, rtx*, bool, bool);
|
|
||||||
extern const char *output_adjust_stack_and_probe (rtx);
|
|
||||||
extern const char *output_probe_stack_range (rtx, rtx);
|
|
||||||
|
|
||||||
extern void ix86_expand_clear (rtx);
|
|
||||||
extern void ix86_expand_move (enum machine_mode, rtx[]);
|
|
||||||
extern void ix86_expand_vector_move (enum machine_mode, rtx[]);
|
|
||||||
extern void ix86_expand_vector_move_misalign (enum machine_mode, rtx[]);
|
|
||||||
extern void ix86_expand_push (enum machine_mode, rtx);
|
|
||||||
extern rtx ix86_fixup_binary_operands (enum rtx_code,
|
|
||||||
enum machine_mode, rtx[]);
|
|
||||||
extern void ix86_fixup_binary_operands_no_copy (enum rtx_code,
|
|
||||||
enum machine_mode, rtx[]);
|
|
||||||
extern void ix86_expand_binary_operator (enum rtx_code,
|
|
||||||
enum machine_mode, rtx[]);
|
|
||||||
extern void ix86_expand_vector_logical_operator (enum rtx_code,
|
|
||||||
enum machine_mode, rtx[]);
|
|
||||||
extern bool ix86_binary_operator_ok (enum rtx_code, enum machine_mode, rtx[]);
|
|
||||||
extern bool ix86_avoid_lea_for_add (rtx, rtx[]);
|
|
||||||
extern bool ix86_use_lea_for_mov (rtx, rtx[]);
|
|
||||||
extern bool ix86_avoid_lea_for_addr (rtx, rtx[]);
|
|
||||||
extern void ix86_split_lea_for_addr (rtx, rtx[], enum machine_mode);
|
|
||||||
extern bool ix86_lea_for_add_ok (rtx, rtx[]);
|
|
||||||
extern bool ix86_vec_interleave_v2df_operator_ok (rtx operands[3], bool high);
|
|
||||||
extern bool ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn);
|
|
||||||
extern bool ix86_agi_dependent (rtx set_insn, rtx use_insn);
|
|
||||||
extern void ix86_expand_unary_operator (enum rtx_code, enum machine_mode,
|
|
||||||
rtx[]);
|
|
||||||
extern rtx ix86_build_const_vector (enum machine_mode, bool, rtx);
|
|
||||||
extern rtx ix86_build_signbit_mask (enum machine_mode, bool, bool);
|
|
||||||
extern void ix86_split_convert_uns_si_sse (rtx[]);
|
|
||||||
extern void ix86_expand_convert_uns_didf_sse (rtx, rtx);
|
|
||||||
extern void ix86_expand_convert_uns_sixf_sse (rtx, rtx);
|
|
||||||
extern void ix86_expand_convert_uns_sidf_sse (rtx, rtx);
|
|
||||||
extern void ix86_expand_convert_uns_sisf_sse (rtx, rtx);
|
|
||||||
extern void ix86_expand_convert_sign_didf_sse (rtx, rtx);
|
|
||||||
extern void ix86_expand_vector_convert_uns_vsivsf (rtx, rtx);
|
|
||||||
extern rtx ix86_expand_adjust_ufix_to_sfix_si (rtx, rtx *);
|
|
||||||
extern enum ix86_fpcmp_strategy ix86_fp_comparison_strategy (enum rtx_code);
|
|
||||||
extern void ix86_expand_fp_absneg_operator (enum rtx_code, enum machine_mode,
|
|
||||||
rtx[]);
|
|
||||||
extern void ix86_expand_copysign (rtx []);
|
|
||||||
extern void ix86_split_copysign_const (rtx []);
|
|
||||||
extern void ix86_split_copysign_var (rtx []);
|
|
||||||
extern bool ix86_unary_operator_ok (enum rtx_code, enum machine_mode, rtx[]);
|
|
||||||
extern bool ix86_match_ccmode (rtx, enum machine_mode);
|
|
||||||
extern void ix86_expand_branch (enum rtx_code, rtx, rtx, rtx);
|
|
||||||
extern void ix86_expand_setcc (rtx, enum rtx_code, rtx, rtx);
|
|
||||||
extern bool ix86_expand_int_movcc (rtx[]);
|
|
||||||
extern bool ix86_expand_fp_movcc (rtx[]);
|
|
||||||
extern bool ix86_expand_fp_vcond (rtx[]);
|
|
||||||
extern bool ix86_expand_int_vcond (rtx[]);
|
|
||||||
extern void ix86_expand_vec_perm (rtx[]);
|
|
||||||
extern bool ix86_expand_vec_perm_const (rtx[]);
|
|
||||||
extern void ix86_expand_sse_unpack (rtx, rtx, bool, bool);
|
|
||||||
extern bool ix86_expand_int_addcc (rtx[]);
|
|
||||||
extern rtx ix86_expand_call (rtx, rtx, rtx, rtx, rtx, bool);
|
|
||||||
extern void ix86_split_call_vzeroupper (rtx, rtx);
|
|
||||||
extern void x86_initialize_trampoline (rtx, rtx, rtx);
|
|
||||||
extern rtx ix86_zero_extend_to_Pmode (rtx);
|
|
||||||
extern void ix86_split_long_move (rtx[]);
|
|
||||||
extern void ix86_split_ashl (rtx *, rtx, enum machine_mode);
|
|
||||||
extern void ix86_split_ashr (rtx *, rtx, enum machine_mode);
|
|
||||||
extern void ix86_split_lshr (rtx *, rtx, enum machine_mode);
|
|
||||||
extern rtx ix86_find_base_term (rtx);
|
|
||||||
extern bool ix86_check_movabs (rtx, int);
|
|
||||||
extern void ix86_split_idivmod (enum machine_mode, rtx[], bool);
|
|
||||||
|
|
||||||
extern rtx assign_386_stack_local (enum machine_mode, enum ix86_stack_slot);
|
|
||||||
extern int ix86_attr_length_immediate_default (rtx, bool);
|
|
||||||
extern int ix86_attr_length_address_default (rtx);
|
|
||||||
extern int ix86_attr_length_vex_default (rtx, bool, bool);
|
|
||||||
|
|
||||||
extern enum machine_mode ix86_fp_compare_mode (enum rtx_code);
|
|
||||||
|
|
||||||
extern rtx ix86_libcall_value (enum machine_mode);
|
|
||||||
extern bool ix86_function_arg_regno_p (int);
|
|
||||||
extern void ix86_asm_output_function_label (FILE *, const char *, tree);
|
|
||||||
extern rtx ix86_force_to_memory (enum machine_mode, rtx);
|
|
||||||
extern void ix86_free_from_memory (enum machine_mode);
|
|
||||||
extern void ix86_call_abi_override (const_tree);
|
|
||||||
extern int ix86_reg_parm_stack_space (const_tree);
|
|
||||||
|
|
||||||
extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx,
|
|
||||||
rtx, rtx, rtx, rtx);
|
|
||||||
extern bool ix86_hard_regno_mode_ok (int, enum machine_mode);
|
|
||||||
extern bool ix86_modes_tieable_p (enum machine_mode, enum machine_mode);
|
|
||||||
extern bool ix86_secondary_memory_needed (enum reg_class, enum reg_class,
|
|
||||||
enum machine_mode, int);
|
|
||||||
extern bool ix86_cannot_change_mode_class (enum machine_mode,
|
|
||||||
enum machine_mode, enum reg_class);
|
|
||||||
|
|
||||||
extern int ix86_mode_needed (int, rtx);
|
|
||||||
extern int ix86_mode_after (int, int, rtx);
|
|
||||||
extern int ix86_mode_entry (int);
|
|
||||||
extern int ix86_mode_exit (int);
|
|
||||||
|
|
||||||
#ifdef HARD_CONST
|
|
||||||
extern void ix86_emit_mode_set (int, int, HARD_REG_SET);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void x86_order_regs_for_local_alloc (void);
|
|
||||||
extern void x86_function_profiler (FILE *, int);
|
|
||||||
extern void x86_emit_floatuns (rtx [2]);
|
|
||||||
extern void ix86_emit_fp_unordered_jump (rtx);
|
|
||||||
|
|
||||||
extern void ix86_emit_i387_log1p (rtx, rtx);
|
|
||||||
extern void ix86_emit_i387_round (rtx, rtx);
|
|
||||||
extern void ix86_emit_swdivsf (rtx, rtx, rtx, enum machine_mode);
|
|
||||||
extern void ix86_emit_swsqrtsf (rtx, rtx, enum machine_mode, bool);
|
|
||||||
|
|
||||||
extern enum rtx_code ix86_reverse_condition (enum rtx_code, enum machine_mode);
|
|
||||||
|
|
||||||
extern void ix86_expand_lround (rtx, rtx);
|
|
||||||
extern void ix86_expand_lfloorceil (rtx, rtx, bool);
|
|
||||||
extern void ix86_expand_rint (rtx, rtx);
|
|
||||||
extern void ix86_expand_floorceil (rtx, rtx, bool);
|
|
||||||
extern void ix86_expand_floorceildf_32 (rtx, rtx, bool);
|
|
||||||
extern void ix86_expand_round_sse4 (rtx, rtx);
|
|
||||||
extern void ix86_expand_round (rtx, rtx);
|
|
||||||
extern void ix86_expand_rounddf_32 (rtx, rtx);
|
|
||||||
extern void ix86_expand_trunc (rtx, rtx);
|
|
||||||
extern void ix86_expand_truncdf_32 (rtx, rtx);
|
|
||||||
|
|
||||||
extern void ix86_expand_vecop_qihi (enum rtx_code, rtx, rtx, rtx);
|
|
||||||
|
|
||||||
#ifdef TREE_CODE
|
|
||||||
extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int);
|
|
||||||
#endif /* TREE_CODE */
|
|
||||||
|
|
||||||
#endif /* RTX_CODE */
|
|
||||||
|
|
||||||
#ifdef TREE_CODE
|
|
||||||
extern int ix86_data_alignment (tree, int);
|
|
||||||
extern unsigned int ix86_local_alignment (tree, enum machine_mode,
|
|
||||||
unsigned int);
|
|
||||||
extern unsigned int ix86_minimum_alignment (tree, enum machine_mode,
|
|
||||||
unsigned int);
|
|
||||||
extern int ix86_constant_alignment (tree, int);
|
|
||||||
extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *);
|
|
||||||
extern tree ix86_handle_selectany_attribute (tree *, tree, tree, int, bool *);
|
|
||||||
extern int x86_field_alignment (tree, int);
|
|
||||||
extern tree ix86_valid_target_attribute_tree (tree);
|
|
||||||
extern unsigned int ix86_get_callcvt (const_tree);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern rtx ix86_tls_module_base (void);
|
|
||||||
|
|
||||||
extern void ix86_expand_vector_init (bool, rtx, rtx);
|
|
||||||
extern void ix86_expand_vector_set (bool, rtx, rtx, int);
|
|
||||||
extern void ix86_expand_vector_extract (bool, rtx, rtx, int);
|
|
||||||
extern void ix86_expand_reduc (rtx (*)(rtx, rtx, rtx), rtx, rtx);
|
|
||||||
|
|
||||||
extern void ix86_expand_vec_extract_even_odd (rtx, rtx, rtx, unsigned);
|
|
||||||
extern bool ix86_expand_pinsr (rtx *);
|
|
||||||
extern void ix86_expand_mul_widen_evenodd (rtx, rtx, rtx, bool, bool);
|
|
||||||
extern void ix86_expand_mul_widen_hilo (rtx, rtx, rtx, bool, bool);
|
|
||||||
extern void ix86_expand_sse2_mulv4si3 (rtx, rtx, rtx);
|
|
||||||
extern void ix86_expand_sse2_mulvxdi3 (rtx, rtx, rtx);
|
|
||||||
|
|
||||||
/* In i386-c.c */
|
|
||||||
extern void ix86_target_macros (void);
|
|
||||||
extern void ix86_register_pragmas (void);
|
|
||||||
|
|
||||||
/* In winnt.c */
|
|
||||||
extern void i386_pe_unique_section (tree, int);
|
|
||||||
extern void i386_pe_declare_function_type (FILE *, const char *, int);
|
|
||||||
extern void i386_pe_record_external_function (tree, const char *);
|
|
||||||
extern void i386_pe_maybe_record_exported_symbol (tree, const char *, int);
|
|
||||||
extern void i386_pe_encode_section_info (tree, rtx, int);
|
|
||||||
extern bool i386_pe_binds_local_p (const_tree);
|
|
||||||
extern const char *i386_pe_strip_name_encoding_full (const char *);
|
|
||||||
extern bool i386_pe_valid_dllimport_attribute_p (const_tree);
|
|
||||||
extern unsigned int i386_pe_section_type_flags (tree, const char *, int);
|
|
||||||
extern void i386_pe_asm_named_section (const char *, unsigned int, tree);
|
|
||||||
extern void i386_pe_asm_output_aligned_decl_common (FILE *, tree,
|
|
||||||
const char *,
|
|
||||||
HOST_WIDE_INT,
|
|
||||||
HOST_WIDE_INT);
|
|
||||||
extern void i386_pe_file_end (void);
|
|
||||||
extern void i386_pe_start_function (FILE *, const char *, tree);
|
|
||||||
extern void i386_pe_end_function (FILE *, const char *, tree);
|
|
||||||
extern void i386_pe_assemble_visibility (tree, int);
|
|
||||||
extern tree i386_pe_mangle_decl_assembler_name (tree, tree);
|
|
||||||
extern tree i386_pe_mangle_assembler_name (const char *);
|
|
||||||
|
|
||||||
extern void i386_pe_seh_init (FILE *);
|
|
||||||
extern void i386_pe_seh_end_prologue (FILE *);
|
|
||||||
extern void i386_pe_seh_unwind_emit (FILE *, rtx);
|
|
||||||
extern void i386_pe_seh_emit_except_personality (rtx);
|
|
||||||
extern void i386_pe_seh_init_sections (void);
|
|
||||||
|
|
||||||
/* In winnt-cxx.c and winnt-stubs.c */
|
|
||||||
extern void i386_pe_adjust_class_at_definition (tree);
|
|
||||||
extern bool i386_pe_type_dllimport_p (tree);
|
|
||||||
extern bool i386_pe_type_dllexport_p (tree);
|
|
||||||
|
|
||||||
extern int i386_pe_reloc_rw_mask (void);
|
|
||||||
|
|
||||||
extern rtx maybe_get_pool_constant (rtx);
|
|
||||||
|
|
||||||
extern char internal_label_prefix[16];
|
|
||||||
extern int internal_label_prefix_len;
|
|
||||||
|
|
||||||
enum ix86_address_seg { SEG_DEFAULT, SEG_FS, SEG_GS };
|
|
||||||
struct ix86_address
|
|
||||||
{
|
|
||||||
rtx base, index, disp;
|
|
||||||
HOST_WIDE_INT scale;
|
|
||||||
enum ix86_address_seg seg;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern int ix86_decompose_address (rtx, struct ix86_address *);
|
|
||||||
extern int memory_address_length (rtx, bool);
|
|
||||||
extern void x86_output_aligned_bss (FILE *, tree, const char *,
|
|
||||||
unsigned HOST_WIDE_INT, int);
|
|
||||||
extern void x86_elf_aligned_common (FILE *, const char *,
|
|
||||||
unsigned HOST_WIDE_INT, int);
|
|
||||||
|
|
||||||
#ifdef RTX_CODE
|
|
||||||
extern void ix86_fp_comparison_codes (enum rtx_code code, enum rtx_code *,
|
|
||||||
enum rtx_code *, enum rtx_code *);
|
|
||||||
extern enum rtx_code ix86_fp_compare_code_to_integer (enum rtx_code);
|
|
||||||
#endif
|
|
||||||
extern int asm_preferred_eh_data_format (int, int);
|
|
||||||
|
|
||||||
#ifdef HAVE_ATTR_cpu
|
|
||||||
extern enum attr_cpu ix86_schedule;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern const char * ix86_output_call_insn (rtx insn, rtx call_op);
|
|
||||||
|
|
||||||
#ifdef RTX_CODE
|
|
||||||
/* Target data for multipass lookahead scheduling.
|
|
||||||
Currently used for Core 2/i7 tuning. */
|
|
||||||
struct ix86_first_cycle_multipass_data_
|
|
||||||
{
|
|
||||||
/* The length (in bytes) of ifetch block in this solution. */
|
|
||||||
int ifetch_block_len;
|
|
||||||
/* Number of instructions in ifetch block in this solution. */
|
|
||||||
int ifetch_block_n_insns;
|
|
||||||
/* Bitmap to remember changes to ready_try for backtracking. */
|
|
||||||
sbitmap ready_try_change;
|
|
||||||
/* Size of the bitmap. */
|
|
||||||
int ready_try_change_size;
|
|
||||||
};
|
|
||||||
# define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DATA_T \
|
|
||||||
struct ix86_first_cycle_multipass_data_
|
|
||||||
#endif /* RTX_CODE */
|
|
File diff suppressed because it is too large
Load Diff
@ -1,55 +0,0 @@
|
|||||||
/* Definitions for Intel 386 running Linux-based GNU systems with ELF format.
|
|
||||||
Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Ilya Enkovich.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#undef TARGET_OS_CPP_BUILTINS
|
|
||||||
#define TARGET_OS_CPP_BUILTINS() \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
GNU_USER_TARGET_OS_CPP_BUILTINS(); \
|
|
||||||
ANDROID_TARGET_OS_CPP_BUILTINS(); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
#undef CC1_SPEC
|
|
||||||
#define CC1_SPEC \
|
|
||||||
LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC, \
|
|
||||||
GNU_USER_TARGET_CC1_SPEC " " ANDROID_CC1_SPEC)
|
|
||||||
|
|
||||||
#undef LINK_SPEC
|
|
||||||
#define LINK_SPEC \
|
|
||||||
LINUX_OR_ANDROID_LD (GNU_USER_TARGET_LINK_SPEC, \
|
|
||||||
GNU_USER_TARGET_LINK_SPEC " " ANDROID_LINK_SPEC)
|
|
||||||
|
|
||||||
#undef LIB_SPEC
|
|
||||||
#define LIB_SPEC \
|
|
||||||
LINUX_OR_ANDROID_LD (GNU_USER_TARGET_LIB_SPEC, \
|
|
||||||
GNU_USER_TARGET_LIB_SPEC " " ANDROID_LIB_SPEC)
|
|
||||||
|
|
||||||
#undef STARTFILE_SPEC
|
|
||||||
#define STARTFILE_SPEC \
|
|
||||||
LINUX_OR_ANDROID_LD (GNU_USER_TARGET_STARTFILE_SPEC, \
|
|
||||||
ANDROID_STARTFILE_SPEC)
|
|
||||||
|
|
||||||
#undef ENDFILE_SPEC
|
|
||||||
#define ENDFILE_SPEC \
|
|
||||||
LINUX_OR_ANDROID_LD (GNU_USER_TARGET_MATHFILE_SPEC " " \
|
|
||||||
GNU_USER_TARGET_ENDFILE_SPEC, \
|
|
||||||
GNU_USER_TARGET_MATHFILE_SPEC " " \
|
|
||||||
ANDROID_ENDFILE_SPEC)
|
|
@ -1,32 +0,0 @@
|
|||||||
/* Definitions for AMD x86-64 running Linux-based GNU systems with ELF format.
|
|
||||||
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Jan Hubicka <jh@suse.cz>, based on linux.h.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
Under Section 7 of GPL version 3, you are granted additional
|
|
||||||
permissions described in the GCC Runtime Library Exception, version
|
|
||||||
3.1, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License and
|
|
||||||
a copy of the GCC Runtime Library Exception along with this program;
|
|
||||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#define GNU_USER_LINK_EMULATION32 "elf_i386"
|
|
||||||
#define GNU_USER_LINK_EMULATION64 "elf_x86_64"
|
|
||||||
#define GNU_USER_LINK_EMULATIONX32 "elf32_x86_64"
|
|
||||||
|
|
||||||
#define GLIBC_DYNAMIC_LINKER32 "/lib/ld-linux.so.2"
|
|
||||||
#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux-x86-64.so.2"
|
|
||||||
#define GLIBC_DYNAMIC_LINKERX32 "/libx32/ld-linux-x32.so.2"
|
|
@ -1,80 +0,0 @@
|
|||||||
/* Definitions for Unix assembler syntax for the Intel 80386.
|
|
||||||
Copyright (C) 1988-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
Under Section 7 of GPL version 3, you are granted additional
|
|
||||||
permissions described in the GCC Runtime Library Exception, version
|
|
||||||
3.1, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License and
|
|
||||||
a copy of the GCC Runtime Library Exception along with this program;
|
|
||||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* This file defines the aspects of assembler syntax
|
|
||||||
that are the same for all the i386 Unix systems
|
|
||||||
(though they may differ in non-Unix systems). */
|
|
||||||
|
|
||||||
/* Define macro used to output shift-double opcodes when the shift
|
|
||||||
count is in %cl. Some assemblers require %cl as an argument;
|
|
||||||
some don't. This macro controls what to do: by default, don't
|
|
||||||
print %cl. */
|
|
||||||
#define SHIFT_DOUBLE_OMITS_COUNT 1
|
|
||||||
|
|
||||||
/* Define the syntax of pseudo-ops, labels and comments. */
|
|
||||||
|
|
||||||
/* String containing the assembler's comment-starter.
|
|
||||||
Note the trailing space is necessary in case the character
|
|
||||||
that immediately follows the comment is '*'. If this happens
|
|
||||||
and the space is not there the assembler will interpret this
|
|
||||||
as the start of a C-like slash-star comment and complain when
|
|
||||||
there is no terminator. */
|
|
||||||
|
|
||||||
#define ASM_COMMENT_START "/ "
|
|
||||||
|
|
||||||
/* Output to assembler file text saying following lines
|
|
||||||
may contain character constants, extra white space, comments, etc. */
|
|
||||||
|
|
||||||
#define ASM_APP_ON "/APP\n"
|
|
||||||
|
|
||||||
/* Output to assembler file text saying following lines
|
|
||||||
no longer contain unusual constructs. */
|
|
||||||
|
|
||||||
#define ASM_APP_OFF "/NO_APP\n"
|
|
||||||
|
|
||||||
/* Output before read-only data. */
|
|
||||||
|
|
||||||
#define TEXT_SECTION_ASM_OP "\t.text"
|
|
||||||
|
|
||||||
/* Output before writable (initialized) data. */
|
|
||||||
|
|
||||||
#define DATA_SECTION_ASM_OP "\t.data"
|
|
||||||
|
|
||||||
/* Output before writable (uninitialized) data. */
|
|
||||||
|
|
||||||
#define BSS_SECTION_ASM_OP "\t.bss"
|
|
||||||
|
|
||||||
/* Globalizing directive for a label. */
|
|
||||||
#define GLOBAL_ASM_OP "\t.globl\t"
|
|
||||||
|
|
||||||
/* By default, target has a 80387, uses IEEE compatible arithmetic,
|
|
||||||
and returns float values in the 387. */
|
|
||||||
#undef TARGET_SUBTARGET_DEFAULT
|
|
||||||
#define TARGET_SUBTARGET_DEFAULT \
|
|
||||||
(MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS)
|
|
||||||
|
|
||||||
/* By default, 64-bit mode uses 128-bit long double. */
|
|
||||||
#undef TARGET_SUBTARGET64_DEFAULT
|
|
||||||
#define TARGET_SUBTARGET64_DEFAULT \
|
|
||||||
MASK_128BIT_LONG_DOUBLE
|
|
@ -1,108 +0,0 @@
|
|||||||
/* OS independent definitions for AMD x86-64.
|
|
||||||
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Bo Thorsen <bo@suse.de>.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
Under Section 7 of GPL version 3, you are granted additional
|
|
||||||
permissions described in the GCC Runtime Library Exception, version
|
|
||||||
3.1, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License and
|
|
||||||
a copy of the GCC Runtime Library Exception along with this program;
|
|
||||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#undef ASM_COMMENT_START
|
|
||||||
#define ASM_COMMENT_START "#"
|
|
||||||
|
|
||||||
#undef DBX_REGISTER_NUMBER
|
|
||||||
#define DBX_REGISTER_NUMBER(n) \
|
|
||||||
(TARGET_64BIT ? dbx64_register_map[n] : svr4_dbx_register_map[n])
|
|
||||||
|
|
||||||
/* Output assembler code to FILE to call the profiler. */
|
|
||||||
#define NO_PROFILE_COUNTERS 1
|
|
||||||
|
|
||||||
#undef MCOUNT_NAME
|
|
||||||
#define MCOUNT_NAME "mcount"
|
|
||||||
|
|
||||||
#undef SIZE_TYPE
|
|
||||||
#define SIZE_TYPE (TARGET_LP64 ? "long unsigned int" : "unsigned int")
|
|
||||||
|
|
||||||
#undef PTRDIFF_TYPE
|
|
||||||
#define PTRDIFF_TYPE (TARGET_LP64 ? "long int" : "int")
|
|
||||||
|
|
||||||
#undef WCHAR_TYPE
|
|
||||||
#define WCHAR_TYPE "int"
|
|
||||||
|
|
||||||
#undef WCHAR_TYPE_SIZE
|
|
||||||
#define WCHAR_TYPE_SIZE 32
|
|
||||||
|
|
||||||
#undef ASM_SPEC
|
|
||||||
#define ASM_SPEC "%{m32:--32} %{m64:--64}"
|
|
||||||
|
|
||||||
#undef ASM_OUTPUT_ALIGNED_BSS
|
|
||||||
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
|
|
||||||
x86_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
|
|
||||||
|
|
||||||
#undef ASM_OUTPUT_ALIGNED_COMMON
|
|
||||||
#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
|
|
||||||
x86_elf_aligned_common (FILE, NAME, SIZE, ALIGN);
|
|
||||||
|
|
||||||
/* This is used to align code labels according to Intel recommendations. */
|
|
||||||
|
|
||||||
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
|
|
||||||
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
|
|
||||||
do { \
|
|
||||||
if ((LOG) != 0) { \
|
|
||||||
if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
|
|
||||||
else { \
|
|
||||||
fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
|
|
||||||
/* Make sure that we have at least 8 byte alignment if > 8 byte \
|
|
||||||
alignment is preferred. */ \
|
|
||||||
if ((LOG) > 3 \
|
|
||||||
&& (1 << (LOG)) > ((MAX_SKIP) + 1) \
|
|
||||||
&& (MAX_SKIP) >= 7) \
|
|
||||||
fputs ("\t.p2align 3\n", (FILE)); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
#undef ASM_OUTPUT_MAX_SKIP_PAD
|
|
||||||
#define ASM_OUTPUT_MAX_SKIP_PAD(FILE, LOG, MAX_SKIP) \
|
|
||||||
if ((LOG) != 0) \
|
|
||||||
{ \
|
|
||||||
if ((MAX_SKIP) == 0) \
|
|
||||||
fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
|
|
||||||
else \
|
|
||||||
fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* i386 System V Release 4 uses DWARF debugging info.
|
|
||||||
x86-64 ABI specifies DWARF2. */
|
|
||||||
|
|
||||||
#define DWARF2_DEBUGGING_INFO 1
|
|
||||||
#define DWARF2_UNWIND_INFO 1
|
|
||||||
|
|
||||||
#undef PREFERRED_DEBUGGING_TYPE
|
|
||||||
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
|
|
||||||
|
|
||||||
#undef TARGET_ASM_SELECT_SECTION
|
|
||||||
#define TARGET_ASM_SELECT_SECTION x86_64_elf_select_section
|
|
||||||
|
|
||||||
#undef TARGET_ASM_UNIQUE_SECTION
|
|
||||||
#define TARGET_ASM_UNIQUE_SECTION x86_64_elf_unique_section
|
|
||||||
|
|
||||||
#undef TARGET_SECTION_TYPE_FLAGS
|
|
||||||
#define TARGET_SECTION_TYPE_FLAGS x86_64_elf_section_type_flags
|
|
@ -1,40 +0,0 @@
|
|||||||
/* Definitions for ELF systems with .init_array/.fini_array section
|
|
||||||
support.
|
|
||||||
Copyright (C) 2011-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published
|
|
||||||
by the Free Software Foundation; either version 3, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
|
||||||
License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifdef HAVE_INITFINI_ARRAY_SUPPORT
|
|
||||||
|
|
||||||
#define USE_INITFINI_ARRAY
|
|
||||||
|
|
||||||
#undef INIT_SECTION_ASM_OP
|
|
||||||
#undef FINI_SECTION_ASM_OP
|
|
||||||
|
|
||||||
#undef INIT_ARRAY_SECTION_ASM_OP
|
|
||||||
#define INIT_ARRAY_SECTION_ASM_OP
|
|
||||||
|
|
||||||
#undef FINI_ARRAY_SECTION_ASM_OP
|
|
||||||
#define FINI_ARRAY_SECTION_ASM_OP
|
|
||||||
|
|
||||||
/* Use .init_array/.fini_array section for constructors and destructors. */
|
|
||||||
#undef TARGET_ASM_CONSTRUCTOR
|
|
||||||
#define TARGET_ASM_CONSTRUCTOR default_elf_init_array_asm_out_constructor
|
|
||||||
#undef TARGET_ASM_DESTRUCTOR
|
|
||||||
#define TARGET_ASM_DESTRUCTOR default_elf_fini_array_asm_out_destructor
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,59 +0,0 @@
|
|||||||
/* Configuration file for Linux Android targets.
|
|
||||||
Copyright (C) 2008-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Doug Kwan (dougkwan@google.com)
|
|
||||||
Rewritten by CodeSourcery, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published
|
|
||||||
by the Free Software Foundation; either version 3, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
|
||||||
License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#define ANDROID_TARGET_OS_CPP_BUILTINS() \
|
|
||||||
do { \
|
|
||||||
if (TARGET_ANDROID) \
|
|
||||||
builtin_define ("__ANDROID__"); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#if ANDROID_DEFAULT
|
|
||||||
# define NOANDROID "mno-android"
|
|
||||||
#else
|
|
||||||
# define NOANDROID "!mandroid"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LINUX_OR_ANDROID_CC(LINUX_SPEC, ANDROID_SPEC) \
|
|
||||||
"%{" NOANDROID "|tno-android-cc:" LINUX_SPEC ";:" ANDROID_SPEC "}"
|
|
||||||
|
|
||||||
#define LINUX_OR_ANDROID_LD(LINUX_SPEC, ANDROID_SPEC) \
|
|
||||||
"%{" NOANDROID "|tno-android-ld:" LINUX_SPEC ";:" ANDROID_SPEC "}"
|
|
||||||
|
|
||||||
#define ANDROID_LINK_SPEC \
|
|
||||||
"%{shared: -Bsymbolic}"
|
|
||||||
|
|
||||||
#define ANDROID_CC1_SPEC \
|
|
||||||
"%{!mglibc:%{!muclibc:%{!mbionic: -mbionic}}} " \
|
|
||||||
"%{!fno-pic:%{!fno-PIC:%{!fpic:%{!fPIC: -fPIC}}}}"
|
|
||||||
|
|
||||||
#define ANDROID_CC1PLUS_SPEC \
|
|
||||||
"%{!fexceptions:%{!fno-exceptions: -fno-exceptions}} " \
|
|
||||||
"%{!frtti:%{!fno-rtti: -fno-rtti}}"
|
|
||||||
|
|
||||||
#define ANDROID_LIB_SPEC \
|
|
||||||
"%{!static: -ldl}"
|
|
||||||
|
|
||||||
#define ANDROID_STARTFILE_SPEC \
|
|
||||||
"%{shared: crtbegin_so%O%s;:" \
|
|
||||||
" %{static: crtbegin_static%O%s;: crtbegin_dynamic%O%s}}"
|
|
||||||
|
|
||||||
#define ANDROID_ENDFILE_SPEC \
|
|
||||||
"%{shared: crtend_so%O%s;: crtend_android%O%s}"
|
|
@ -1,109 +0,0 @@
|
|||||||
/* Definitions for systems using the Linux kernel, with or without
|
|
||||||
MMU, using ELF at the compiler level but possibly FLT for final
|
|
||||||
linked executables and shared libraries in some no-MMU cases, and
|
|
||||||
possibly with a choice of libc implementations.
|
|
||||||
Copyright (C) 1995-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Eric Youngdale.
|
|
||||||
Modified for stabs-in-ELF by H.J. Lu (hjl@lucon.org).
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
Under Section 7 of GPL version 3, you are granted additional
|
|
||||||
permissions described in the GCC Runtime Library Exception, version
|
|
||||||
3.1, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License and
|
|
||||||
a copy of the GCC Runtime Library Exception along with this program;
|
|
||||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* C libraries supported on Linux. */
|
|
||||||
#ifdef SINGLE_LIBC
|
|
||||||
#define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC)
|
|
||||||
#define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC)
|
|
||||||
#define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC)
|
|
||||||
#else
|
|
||||||
#define OPTION_GLIBC (linux_libc == LIBC_GLIBC)
|
|
||||||
#define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC)
|
|
||||||
#define OPTION_BIONIC (linux_libc == LIBC_BIONIC)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GNU_USER_TARGET_OS_CPP_BUILTINS() \
|
|
||||||
do { \
|
|
||||||
if (OPTION_GLIBC) \
|
|
||||||
builtin_define ("__gnu_linux__"); \
|
|
||||||
builtin_define_std ("linux"); \
|
|
||||||
builtin_define_std ("unix"); \
|
|
||||||
builtin_assert ("system=linux"); \
|
|
||||||
builtin_assert ("system=unix"); \
|
|
||||||
builtin_assert ("system=posix"); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* Determine which dynamic linker to use depending on whether GLIBC or
|
|
||||||
uClibc or Bionic is the default C library and whether
|
|
||||||
-muclibc or -mglibc or -mbionic has been passed to change the default. */
|
|
||||||
|
|
||||||
#define CHOOSE_DYNAMIC_LINKER1(LIBC1, LIBC2, LIBC3, LD1, LD2, LD3) \
|
|
||||||
"%{" LIBC2 ":" LD2 ";:%{" LIBC3 ":" LD3 ";:" LD1 "}}"
|
|
||||||
|
|
||||||
#if DEFAULT_LIBC == LIBC_GLIBC
|
|
||||||
#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
|
|
||||||
CHOOSE_DYNAMIC_LINKER1 ("mglibc", "muclibc", "mbionic", G, U, B)
|
|
||||||
#elif DEFAULT_LIBC == LIBC_UCLIBC
|
|
||||||
#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
|
|
||||||
CHOOSE_DYNAMIC_LINKER1 ("muclibc", "mglibc", "mbionic", U, G, B)
|
|
||||||
#elif DEFAULT_LIBC == LIBC_BIONIC
|
|
||||||
#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
|
|
||||||
CHOOSE_DYNAMIC_LINKER1 ("mbionic", "mglibc", "muclibc", B, G, U)
|
|
||||||
#else
|
|
||||||
#error "Unsupported DEFAULT_LIBC"
|
|
||||||
#endif /* DEFAULT_LIBC */
|
|
||||||
|
|
||||||
/* For most targets the following definitions suffice;
|
|
||||||
GLIBC_DYNAMIC_LINKER must be defined for each target using them, or
|
|
||||||
GLIBC_DYNAMIC_LINKER32 and GLIBC_DYNAMIC_LINKER64 for targets
|
|
||||||
supporting both 32-bit and 64-bit compilation. */
|
|
||||||
#define UCLIBC_DYNAMIC_LINKER "/lib/ld-uClibc.so.0"
|
|
||||||
#define UCLIBC_DYNAMIC_LINKER32 "/lib/ld-uClibc.so.0"
|
|
||||||
#define UCLIBC_DYNAMIC_LINKER64 "/lib/ld64-uClibc.so.0"
|
|
||||||
#define UCLIBC_DYNAMIC_LINKERX32 "/lib/ldx32-uClibc.so.0"
|
|
||||||
#define BIONIC_DYNAMIC_LINKER "/system/bin/linker"
|
|
||||||
#define BIONIC_DYNAMIC_LINKER32 "/system/bin/linker"
|
|
||||||
#define BIONIC_DYNAMIC_LINKER64 "/system/bin/linker64"
|
|
||||||
#define BIONIC_DYNAMIC_LINKERX32 "/system/bin/linkerx32"
|
|
||||||
|
|
||||||
#define GNU_USER_DYNAMIC_LINKER \
|
|
||||||
CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER, \
|
|
||||||
BIONIC_DYNAMIC_LINKER)
|
|
||||||
#define GNU_USER_DYNAMIC_LINKER32 \
|
|
||||||
CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32, \
|
|
||||||
BIONIC_DYNAMIC_LINKER32)
|
|
||||||
#define GNU_USER_DYNAMIC_LINKER64 \
|
|
||||||
CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64, \
|
|
||||||
BIONIC_DYNAMIC_LINKER64)
|
|
||||||
#define GNU_USER_DYNAMIC_LINKERX32 \
|
|
||||||
CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERX32, UCLIBC_DYNAMIC_LINKERX32, \
|
|
||||||
BIONIC_DYNAMIC_LINKERX32)
|
|
||||||
|
|
||||||
/* Determine whether the entire c99 runtime
|
|
||||||
is present in the runtime library. */
|
|
||||||
#undef TARGET_C99_FUNCTIONS
|
|
||||||
#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
|
|
||||||
|
|
||||||
/* Whether we have sincos that follows the GNU extension. */
|
|
||||||
#undef TARGET_HAS_SINCOS
|
|
||||||
#define TARGET_HAS_SINCOS (OPTION_GLIBC || OPTION_BIONIC)
|
|
||||||
|
|
||||||
/* Whether we have Bionic libc runtime */
|
|
||||||
#undef TARGET_HAS_BIONIC
|
|
||||||
#define TARGET_HAS_BIONIC (OPTION_BIONIC)
|
|
@ -1,40 +0,0 @@
|
|||||||
/* Dummy definitions of VxWorks-related macros
|
|
||||||
Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
Under Section 7 of GPL version 3, you are granted additional
|
|
||||||
permissions described in the GCC Runtime Library Exception, version
|
|
||||||
3.1, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License and
|
|
||||||
a copy of the GCC Runtime Library Exception along with this program;
|
|
||||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* True if we're targeting VxWorks. */
|
|
||||||
#ifndef TARGET_VXWORKS
|
|
||||||
#define TARGET_VXWORKS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* True if generating code for a VxWorks RTP. */
|
|
||||||
#ifndef TARGET_VXWORKS_RTP
|
|
||||||
#define TARGET_VXWORKS_RTP false
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The symbol that points to an RTP's table of GOTs. */
|
|
||||||
#define VXWORKS_GOTT_BASE (gcc_unreachable (), "")
|
|
||||||
|
|
||||||
/* The symbol that holds the index of the current module's GOT in
|
|
||||||
VXWORKS_GOTT_BASE. */
|
|
||||||
#define VXWORKS_GOTT_INDEX (gcc_unreachable (), "")
|
|
@ -1,7 +0,0 @@
|
|||||||
/* Generated automatically. */
|
|
||||||
static const char configuration_arguments[] = "../configure --prefix=/home/zet/bin/gcc-48 --disable-bootstrap --enable-languages=c,c++ --enable-shared --enable-threads=posix --enable-lto --enable-plugin --enable-gold=yes --without-included-gettext --enable-nls --disable-libmudflap --disable-browser-plugin --disable-werror";
|
|
||||||
static const char thread_model[] = "posix";
|
|
||||||
|
|
||||||
static const struct {
|
|
||||||
const char *name, *value;
|
|
||||||
} configure_default_options[] = { { "cpu", "generic" }, { "arch", "x86-64" } };
|
|
@ -1,208 +0,0 @@
|
|||||||
/* GCC core type declarations.
|
|
||||||
Copyright (C) 2002-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
Under Section 7 of GPL version 3, you are granted additional
|
|
||||||
permissions described in the GCC Runtime Library Exception, version
|
|
||||||
3.1, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License and
|
|
||||||
a copy of the GCC Runtime Library Exception along with this program;
|
|
||||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* Provide forward declarations of core types which are referred to by
|
|
||||||
most of the compiler. This allows header files to use these types
|
|
||||||
(e.g. in function prototypes) without concern for whether the full
|
|
||||||
definitions are visible. Some other declarations that need to be
|
|
||||||
universally visible are here, too.
|
|
||||||
|
|
||||||
In the context of tconfig.h, most of these have special definitions
|
|
||||||
which prevent them from being used except in further type
|
|
||||||
declarations. This is a kludge; the right thing is to avoid
|
|
||||||
including the "tm.h" header set in the context of tconfig.h, but
|
|
||||||
we're not there yet. */
|
|
||||||
|
|
||||||
#ifndef GCC_CORETYPES_H
|
|
||||||
#define GCC_CORETYPES_H
|
|
||||||
|
|
||||||
#ifndef GTY
|
|
||||||
#define GTY(x) /* nothing - marker for gengtype */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef USED_FOR_TARGET
|
|
||||||
|
|
||||||
struct bitmap_head_def;
|
|
||||||
typedef struct bitmap_head_def *bitmap;
|
|
||||||
typedef const struct bitmap_head_def *const_bitmap;
|
|
||||||
struct simple_bitmap_def;
|
|
||||||
typedef struct simple_bitmap_def *sbitmap;
|
|
||||||
typedef const struct simple_bitmap_def *const_sbitmap;
|
|
||||||
struct rtx_def;
|
|
||||||
typedef struct rtx_def *rtx;
|
|
||||||
typedef const struct rtx_def *const_rtx;
|
|
||||||
struct rtvec_def;
|
|
||||||
typedef struct rtvec_def *rtvec;
|
|
||||||
typedef const struct rtvec_def *const_rtvec;
|
|
||||||
union tree_node;
|
|
||||||
typedef union tree_node *tree;
|
|
||||||
typedef const union tree_node *const_tree;
|
|
||||||
union gimple_statement_d;
|
|
||||||
typedef union gimple_statement_d *gimple;
|
|
||||||
typedef const union gimple_statement_d *const_gimple;
|
|
||||||
typedef gimple gimple_seq;
|
|
||||||
union section;
|
|
||||||
typedef union section section;
|
|
||||||
struct gcc_options;
|
|
||||||
struct cl_target_option;
|
|
||||||
struct cl_optimization;
|
|
||||||
struct cl_option;
|
|
||||||
struct cl_decoded_option;
|
|
||||||
struct cl_option_handlers;
|
|
||||||
struct diagnostic_context;
|
|
||||||
typedef struct diagnostic_context diagnostic_context;
|
|
||||||
struct pretty_print_info;
|
|
||||||
typedef struct pretty_print_info pretty_printer;
|
|
||||||
|
|
||||||
/* Address space number for named address space support. */
|
|
||||||
typedef unsigned char addr_space_t;
|
|
||||||
|
|
||||||
/* The value of addr_space_t that represents the generic address space. */
|
|
||||||
#define ADDR_SPACE_GENERIC 0
|
|
||||||
#define ADDR_SPACE_GENERIC_P(AS) ((AS) == ADDR_SPACE_GENERIC)
|
|
||||||
|
|
||||||
/* The major intermediate representations of GCC. */
|
|
||||||
enum ir_type {
|
|
||||||
IR_GIMPLE,
|
|
||||||
IR_RTL_CFGRTL,
|
|
||||||
IR_RTL_CFGLAYOUT
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Provide forward struct declaration so that we don't have to include
|
|
||||||
all of cpplib.h whenever a random prototype includes a pointer.
|
|
||||||
Note that the cpp_reader and cpp_token typedefs remain part of
|
|
||||||
cpplib.h. */
|
|
||||||
|
|
||||||
struct cpp_reader;
|
|
||||||
struct cpp_token;
|
|
||||||
|
|
||||||
/* The thread-local storage model associated with a given VAR_DECL
|
|
||||||
or SYMBOL_REF. This isn't used much, but both trees and RTL refer
|
|
||||||
to it, so it's here. */
|
|
||||||
enum tls_model {
|
|
||||||
TLS_MODEL_NONE,
|
|
||||||
TLS_MODEL_EMULATED,
|
|
||||||
TLS_MODEL_REAL,
|
|
||||||
TLS_MODEL_GLOBAL_DYNAMIC = TLS_MODEL_REAL,
|
|
||||||
TLS_MODEL_LOCAL_DYNAMIC,
|
|
||||||
TLS_MODEL_INITIAL_EXEC,
|
|
||||||
TLS_MODEL_LOCAL_EXEC
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Types of unwind/exception handling info that can be generated. */
|
|
||||||
|
|
||||||
enum unwind_info_type
|
|
||||||
{
|
|
||||||
UI_NONE,
|
|
||||||
UI_SJLJ,
|
|
||||||
UI_DWARF2,
|
|
||||||
UI_TARGET,
|
|
||||||
UI_SEH
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Callgraph node profile representation. */
|
|
||||||
enum node_frequency {
|
|
||||||
/* This function most likely won't be executed at all.
|
|
||||||
(set only when profile feedback is available or via function attribute). */
|
|
||||||
NODE_FREQUENCY_UNLIKELY_EXECUTED,
|
|
||||||
/* For functions that are known to be executed once (i.e. constructors, destructors
|
|
||||||
and main function. */
|
|
||||||
NODE_FREQUENCY_EXECUTED_ONCE,
|
|
||||||
/* The default value. */
|
|
||||||
NODE_FREQUENCY_NORMAL,
|
|
||||||
/* Optimize this function hard
|
|
||||||
(set only when profile feedback is available or via function attribute). */
|
|
||||||
NODE_FREQUENCY_HOT
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Possible initialization status of a variable. When requested
|
|
||||||
by the user, this information is tracked and recorded in the DWARF
|
|
||||||
debug information, along with the variable's location. */
|
|
||||||
enum var_init_status
|
|
||||||
{
|
|
||||||
VAR_INIT_STATUS_UNKNOWN,
|
|
||||||
VAR_INIT_STATUS_UNINITIALIZED,
|
|
||||||
VAR_INIT_STATUS_INITIALIZED
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct edge_def;
|
|
||||||
typedef struct edge_def *edge;
|
|
||||||
typedef const struct edge_def *const_edge;
|
|
||||||
struct basic_block_def;
|
|
||||||
typedef struct basic_block_def *basic_block;
|
|
||||||
typedef const struct basic_block_def *const_basic_block;
|
|
||||||
|
|
||||||
#define obstack_chunk_alloc ((void *(*) (long)) xmalloc)
|
|
||||||
#define obstack_chunk_free ((void (*) (void *)) free)
|
|
||||||
#define OBSTACK_CHUNK_SIZE 0
|
|
||||||
#define gcc_obstack_init(OBSTACK) \
|
|
||||||
_obstack_begin ((OBSTACK), OBSTACK_CHUNK_SIZE, 0, \
|
|
||||||
obstack_chunk_alloc, \
|
|
||||||
obstack_chunk_free)
|
|
||||||
|
|
||||||
/* enum reg_class is target specific, so it should not appear in
|
|
||||||
target-independent code or interfaces, like the target hook declarations
|
|
||||||
in target.h. */
|
|
||||||
typedef int reg_class_t;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
struct _dont_use_rtx_here_;
|
|
||||||
struct _dont_use_rtvec_here_;
|
|
||||||
union _dont_use_tree_here_;
|
|
||||||
#define rtx struct _dont_use_rtx_here_ *
|
|
||||||
#define const_rtx struct _dont_use_rtx_here_ *
|
|
||||||
#define rtvec struct _dont_use_rtvec_here *
|
|
||||||
#define const_rtvec struct _dont_use_rtvec_here *
|
|
||||||
#define tree union _dont_use_tree_here_ *
|
|
||||||
#define const_tree union _dont_use_tree_here_ *
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Memory model types for the __atomic* builtins.
|
|
||||||
This must match the order in libstdc++-v3/include/bits/atomic_base.h. */
|
|
||||||
enum memmodel
|
|
||||||
{
|
|
||||||
MEMMODEL_RELAXED = 0,
|
|
||||||
MEMMODEL_CONSUME = 1,
|
|
||||||
MEMMODEL_ACQUIRE = 2,
|
|
||||||
MEMMODEL_RELEASE = 3,
|
|
||||||
MEMMODEL_ACQ_REL = 4,
|
|
||||||
MEMMODEL_SEQ_CST = 5,
|
|
||||||
MEMMODEL_LAST = 6
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Suppose that higher bits are target dependant. */
|
|
||||||
#define MEMMODEL_MASK ((1<<16)-1)
|
|
||||||
|
|
||||||
/* Support for user-provided GGC and PCH markers. The first parameter
|
|
||||||
is a pointer to a pointer, the second a cookie. */
|
|
||||||
typedef void (*gt_pointer_operator) (void *, void *);
|
|
||||||
|
|
||||||
#if !defined (HAVE_UCHAR)
|
|
||||||
typedef unsigned char uchar;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* coretypes.h */
|
|
@ -1,479 +0,0 @@
|
|||||||
/* This file contains the definitions and documentation for the
|
|
||||||
additional tree codes used in the GNU C++ compiler (see tree.def
|
|
||||||
for the standard codes).
|
|
||||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
|
||||||
Hacked by Michael Tiemann (tiemann@cygnus.com)
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
|
|
||||||
/* An OFFSET_REF is used in two situations:
|
|
||||||
|
|
||||||
1. An expression of the form `A::m' where `A' is a class and `m' is
|
|
||||||
a non-static member. In this case, operand 0 will be a TYPE
|
|
||||||
(corresponding to `A') and operand 1 will be a FIELD_DECL,
|
|
||||||
BASELINK, or TEMPLATE_ID_EXPR (corresponding to `m').
|
|
||||||
|
|
||||||
The expression is a pointer-to-member if its address is taken,
|
|
||||||
but simply denotes a member of the object if its address is not
|
|
||||||
taken.
|
|
||||||
|
|
||||||
This form is only used during the parsing phase; once semantic
|
|
||||||
analysis has taken place they are eliminated.
|
|
||||||
|
|
||||||
2. An expression of the form `x.*p'. In this case, operand 0 will
|
|
||||||
be an expression corresponding to `x' and operand 1 will be an
|
|
||||||
expression with pointer-to-member type. */
|
|
||||||
DEFTREECODE (OFFSET_REF, "offset_ref", tcc_reference, 2)
|
|
||||||
|
|
||||||
/* A pointer-to-member constant. For a pointer-to-member constant
|
|
||||||
`X::Y' The PTRMEM_CST_CLASS is the RECORD_TYPE for `X' and the
|
|
||||||
PTRMEM_CST_MEMBER is the _DECL for `Y'. */
|
|
||||||
DEFTREECODE (PTRMEM_CST, "ptrmem_cst", tcc_constant, 0)
|
|
||||||
|
|
||||||
/* For NEW_EXPR, operand 0 is the placement list.
|
|
||||||
Operand 1 is the new-declarator.
|
|
||||||
Operand 2 is the number of elements in the array.
|
|
||||||
Operand 3 is the initializer. */
|
|
||||||
DEFTREECODE (NEW_EXPR, "nw_expr", tcc_expression, 4)
|
|
||||||
DEFTREECODE (VEC_NEW_EXPR, "vec_nw_expr", tcc_expression, 3)
|
|
||||||
|
|
||||||
/* For DELETE_EXPR, operand 0 is the store to be destroyed.
|
|
||||||
Operand 1 is the value to pass to the destroying function
|
|
||||||
saying whether the store should be deallocated as well. */
|
|
||||||
DEFTREECODE (DELETE_EXPR, "dl_expr", tcc_expression, 2)
|
|
||||||
DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", tcc_expression, 2)
|
|
||||||
|
|
||||||
/* Value is reference to particular overloaded class method.
|
|
||||||
Operand 0 is the class, operand 1 is the field
|
|
||||||
The COMPLEXITY field holds the class level (usually 0). */
|
|
||||||
DEFTREECODE (SCOPE_REF, "scope_ref", tcc_reference, 2)
|
|
||||||
|
|
||||||
/* When composing an object with a member, this is the result.
|
|
||||||
Operand 0 is the object. Operand 1 is the member (usually
|
|
||||||
a dereferenced pointer to member). */
|
|
||||||
DEFTREECODE (MEMBER_REF, "member_ref", tcc_reference, 2)
|
|
||||||
|
|
||||||
/* Type conversion operator in C++. TREE_TYPE is type that this
|
|
||||||
operator converts to. Operand is expression to be converted. */
|
|
||||||
DEFTREECODE (TYPE_EXPR, "type_expr", tcc_expression, 1)
|
|
||||||
|
|
||||||
/* AGGR_INIT_EXPRs have a variably-sized representation similar to
|
|
||||||
that of CALL_EXPRs. Operand 0 is an INTEGER_CST node containing the
|
|
||||||
operand count, operand 1 is the function which performs initialization,
|
|
||||||
operand 2 is the slot which was allocated for this expression, and
|
|
||||||
the remaining operands are the arguments to the initialization function. */
|
|
||||||
DEFTREECODE (AGGR_INIT_EXPR, "aggr_init_expr", tcc_vl_exp, 3)
|
|
||||||
|
|
||||||
/* Initialization of an array from another array, expressed at a high level
|
|
||||||
so that it works with TARGET_EXPR. Operand 0 is the target, operand 1
|
|
||||||
is the initializer. */
|
|
||||||
DEFTREECODE (VEC_INIT_EXPR, "vec_init_expr", tcc_expression, 2)
|
|
||||||
|
|
||||||
/* A throw expression. operand 0 is the expression, if there was one,
|
|
||||||
else it is NULL_TREE. */
|
|
||||||
DEFTREECODE (THROW_EXPR, "throw_expr", tcc_expression, 1)
|
|
||||||
|
|
||||||
/* An empty class object. The TREE_TYPE gives the class type. We use
|
|
||||||
these to avoid actually creating instances of the empty classes. */
|
|
||||||
DEFTREECODE (EMPTY_CLASS_EXPR, "empty_class_expr", tcc_expression, 0)
|
|
||||||
|
|
||||||
/* A reference to a member function or member functions from a base
|
|
||||||
class. BASELINK_FUNCTIONS gives the FUNCTION_DECL,
|
|
||||||
TEMPLATE_DECL, OVERLOAD, or TEMPLATE_ID_EXPR corresponding to the
|
|
||||||
functions. BASELINK_BINFO gives the base from which the functions
|
|
||||||
come, i.e., the base to which the `this' pointer must be converted
|
|
||||||
before the functions are called. BASELINK_ACCESS_BINFO gives the
|
|
||||||
base used to name the functions.
|
|
||||||
|
|
||||||
A BASELINK is an expression; the TREE_TYPE of the BASELINK gives
|
|
||||||
the type of the expression. This type is either a FUNCTION_TYPE,
|
|
||||||
METHOD_TYPE, or `unknown_type_node' indicating that the function is
|
|
||||||
overloaded. */
|
|
||||||
DEFTREECODE (BASELINK, "baselink", tcc_exceptional, 0)
|
|
||||||
|
|
||||||
/* Template definition. The following fields have the specified uses,
|
|
||||||
although there are other macros in cp-tree.h that should be used for
|
|
||||||
accessing this data.
|
|
||||||
DECL_ARGUMENTS template parm vector
|
|
||||||
DECL_TEMPLATE_INFO template text &c
|
|
||||||
DECL_VINDEX list of instantiations already produced;
|
|
||||||
only done for functions so far
|
|
||||||
For class template:
|
|
||||||
DECL_INITIAL associated templates (methods &c)
|
|
||||||
DECL_TEMPLATE_RESULT null
|
|
||||||
For non-class templates:
|
|
||||||
TREE_TYPE type of object to be constructed
|
|
||||||
DECL_TEMPLATE_RESULT decl for object to be created
|
|
||||||
(e.g., FUNCTION_DECL with tmpl parms used)
|
|
||||||
*/
|
|
||||||
DEFTREECODE (TEMPLATE_DECL, "template_decl", tcc_declaration, 0)
|
|
||||||
|
|
||||||
/* Index into a template parameter list. The TEMPLATE_PARM_IDX gives
|
|
||||||
the index (from 0) of the parameter, while the TEMPLATE_PARM_LEVEL
|
|
||||||
gives the level (from 1) of the parameter.
|
|
||||||
|
|
||||||
Here's an example:
|
|
||||||
|
|
||||||
template <class T> // Index 0, Level 1.
|
|
||||||
struct S
|
|
||||||
{
|
|
||||||
template <class U, // Index 0, Level 2.
|
|
||||||
class V> // Index 1, Level 2.
|
|
||||||
void f();
|
|
||||||
};
|
|
||||||
|
|
||||||
The DESCENDANTS will be a chain of TEMPLATE_PARM_INDEXs descended
|
|
||||||
from this one. The first descendant will have the same IDX, but
|
|
||||||
its LEVEL will be one less. The TREE_CHAIN field is used to chain
|
|
||||||
together the descendants. The TEMPLATE_PARM_DECL is the
|
|
||||||
declaration of this parameter, either a TYPE_DECL or CONST_DECL.
|
|
||||||
The TEMPLATE_PARM_ORIG_LEVEL is the LEVEL of the most distant
|
|
||||||
parent, i.e., the LEVEL that the parameter originally had when it
|
|
||||||
was declared. For example, if we instantiate S<int>, we will have:
|
|
||||||
|
|
||||||
struct S<int>
|
|
||||||
{
|
|
||||||
template <class U, // Index 0, Level 1, Orig Level 2
|
|
||||||
class V> // Index 1, Level 1, Orig Level 2
|
|
||||||
void f();
|
|
||||||
};
|
|
||||||
|
|
||||||
The LEVEL is the level of the parameter when we are worrying about
|
|
||||||
the types of things; the ORIG_LEVEL is the level when we are
|
|
||||||
worrying about instantiating things. */
|
|
||||||
DEFTREECODE (TEMPLATE_PARM_INDEX, "template_parm_index", tcc_exceptional, 0)
|
|
||||||
|
|
||||||
/* Index into a template parameter list for template template parameters.
|
|
||||||
This parameter must be a type. The TYPE_FIELDS value will be a
|
|
||||||
TEMPLATE_PARM_INDEX.
|
|
||||||
|
|
||||||
It is used without template arguments like TT in C<TT>,
|
|
||||||
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO is NULL_TREE
|
|
||||||
and TYPE_NAME is a TEMPLATE_DECL. */
|
|
||||||
DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "template_template_parm", tcc_type, 0)
|
|
||||||
|
|
||||||
/* The ordering of the following codes is optimized for the checking
|
|
||||||
macros in tree.h. Changing the order will degrade the speed of the
|
|
||||||
compiler. TEMPLATE_TYPE_PARM, TYPENAME_TYPE, TYPEOF_TYPE,
|
|
||||||
BOUND_TEMPLATE_TEMPLATE_PARM. */
|
|
||||||
|
|
||||||
/* Index into a template parameter list. This parameter must be a type.
|
|
||||||
The type.values field will be a TEMPLATE_PARM_INDEX. */
|
|
||||||
DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", tcc_type, 0)
|
|
||||||
|
|
||||||
/* A type designated by `typename T::t'. TYPE_CONTEXT is `T',
|
|
||||||
TYPE_NAME is an IDENTIFIER_NODE for `t'. If the type was named via
|
|
||||||
template-id, TYPENAME_TYPE_FULLNAME will hold the TEMPLATE_ID_EXPR.
|
|
||||||
TREE_TYPE is always NULL. */
|
|
||||||
DEFTREECODE (TYPENAME_TYPE, "typename_type", tcc_type, 0)
|
|
||||||
|
|
||||||
/* A type designated by `__typeof (expr)'. TYPEOF_TYPE_EXPR is the
|
|
||||||
expression in question. */
|
|
||||||
DEFTREECODE (TYPEOF_TYPE, "typeof_type", tcc_type, 0)
|
|
||||||
|
|
||||||
/* Like TEMPLATE_TEMPLATE_PARM it is used with bound template arguments
|
|
||||||
like TT<int>.
|
|
||||||
In this case, TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO contains the
|
|
||||||
template name and its bound arguments. TYPE_NAME is a TYPE_DECL. */
|
|
||||||
DEFTREECODE (BOUND_TEMPLATE_TEMPLATE_PARM, "bound_template_template_parm",
|
|
||||||
tcc_type, 0)
|
|
||||||
|
|
||||||
/* For template template argument of the form `T::template C'.
|
|
||||||
TYPE_CONTEXT is `T', the template parameter dependent object.
|
|
||||||
TYPE_NAME is an IDENTIFIER_NODE for `C', the member class template. */
|
|
||||||
DEFTREECODE (UNBOUND_CLASS_TEMPLATE, "unbound_class_template", tcc_type, 0)
|
|
||||||
|
|
||||||
/* A using declaration. USING_DECL_SCOPE contains the specified
|
|
||||||
scope. In a member using decl, unless DECL_DEPENDENT_P is true,
|
|
||||||
USING_DECL_DECLS contains the _DECL or OVERLOAD so named. This is
|
|
||||||
not an alias, but is later expanded into multiple aliases. */
|
|
||||||
DEFTREECODE (USING_DECL, "using_decl", tcc_declaration, 0)
|
|
||||||
|
|
||||||
/* A using directive. The operand is USING_STMT_NAMESPACE. */
|
|
||||||
DEFTREECODE (USING_STMT, "using_stmt", tcc_statement, 1)
|
|
||||||
|
|
||||||
/* An un-parsed default argument. Holds a vector of input tokens and
|
|
||||||
a vector of places where the argument was instantiated before
|
|
||||||
parsing had occurred. */
|
|
||||||
DEFTREECODE (DEFAULT_ARG, "default_arg", tcc_exceptional, 0)
|
|
||||||
|
|
||||||
/* An uninstantiated noexcept-specification. DEFERRED_NOEXCEPT_PATTERN is
|
|
||||||
the pattern from the template, and DEFERRED_NOEXCEPT_ARGS are the
|
|
||||||
template arguments to substitute into the pattern when needed. */
|
|
||||||
DEFTREECODE (DEFERRED_NOEXCEPT, "deferred_noexcept", tcc_exceptional, 0)
|
|
||||||
|
|
||||||
/* A template-id, like foo<int>. The first operand is the template.
|
|
||||||
The second is NULL if there are no explicit arguments, or a
|
|
||||||
TREE_VEC of arguments. The template will be a FUNCTION_DECL,
|
|
||||||
TEMPLATE_DECL, or an OVERLOAD. If the template-id refers to a
|
|
||||||
member template, the template may be an IDENTIFIER_NODE. */
|
|
||||||
DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", tcc_expression, 2)
|
|
||||||
|
|
||||||
/* A list-like node for chaining overloading candidates. TREE_TYPE is
|
|
||||||
the original name, and the parameter is the FUNCTION_DECL. */
|
|
||||||
DEFTREECODE (OVERLOAD, "overload", tcc_exceptional, 0)
|
|
||||||
|
|
||||||
/* A pseudo-destructor, of the form "OBJECT.~DESTRUCTOR" or
|
|
||||||
"OBJECT.SCOPE::~DESTRUCTOR. The first operand is the OBJECT. The
|
|
||||||
second operand (if non-NULL) is the SCOPE. The third operand is
|
|
||||||
the TYPE node corresponding to the DESTRUCTOR. The type of the
|
|
||||||
first operand will always be a scalar type.
|
|
||||||
|
|
||||||
The type of a PSEUDO_DTOR_EXPR is always "void", even though it can
|
|
||||||
be used as if it were a zero-argument function. We handle the
|
|
||||||
function-call case specially, and giving it "void" type prevents it
|
|
||||||
being used in expressions in ways that are not permitted. */
|
|
||||||
DEFTREECODE (PSEUDO_DTOR_EXPR, "pseudo_dtor_expr", tcc_expression, 3)
|
|
||||||
|
|
||||||
/* A whole bunch of tree codes for the initial, superficial parsing of
|
|
||||||
templates. */
|
|
||||||
DEFTREECODE (MODOP_EXPR, "modop_expr", tcc_expression, 3)
|
|
||||||
DEFTREECODE (CAST_EXPR, "cast_expr", tcc_unary, 1)
|
|
||||||
DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", tcc_unary, 1)
|
|
||||||
DEFTREECODE (CONST_CAST_EXPR, "const_cast_expr", tcc_unary, 1)
|
|
||||||
DEFTREECODE (STATIC_CAST_EXPR, "static_cast_expr", tcc_unary, 1)
|
|
||||||
DEFTREECODE (DYNAMIC_CAST_EXPR, "dynamic_cast_expr", tcc_unary, 1)
|
|
||||||
DEFTREECODE (IMPLICIT_CONV_EXPR, "implicit_conv_expr", tcc_unary, 1)
|
|
||||||
DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", tcc_expression, 2)
|
|
||||||
DEFTREECODE (TYPEID_EXPR, "typeid_expr", tcc_expression, 1)
|
|
||||||
DEFTREECODE (NOEXCEPT_EXPR, "noexcept_expr", tcc_unary, 1)
|
|
||||||
|
|
||||||
/* A placeholder for an expression that is not type-dependent, but
|
|
||||||
does occur in a template. When an expression that is not
|
|
||||||
type-dependent appears in a larger expression, we must compute the
|
|
||||||
type of that larger expression. That computation would normally
|
|
||||||
modify the original expression, which would change the mangling of
|
|
||||||
that expression if it appeared in a template argument list. In
|
|
||||||
that situation, we create a NON_DEPENDENT_EXPR to take the place of
|
|
||||||
the original expression. The expression is the only operand -- it
|
|
||||||
is only needed for diagnostics. */
|
|
||||||
DEFTREECODE (NON_DEPENDENT_EXPR, "non_dependent_expr", tcc_expression, 1)
|
|
||||||
|
|
||||||
/* CTOR_INITIALIZER is a placeholder in template code for a call to
|
|
||||||
setup_vtbl_pointer (and appears in all functions, not just ctors). */
|
|
||||||
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", tcc_expression, 1)
|
|
||||||
|
|
||||||
DEFTREECODE (TRY_BLOCK, "try_block", tcc_statement, 2)
|
|
||||||
|
|
||||||
DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", tcc_statement, 2)
|
|
||||||
|
|
||||||
/* A HANDLER wraps a catch handler for the HANDLER_TYPE. If this is
|
|
||||||
CATCH_ALL_TYPE, then the handler catches all types. The declaration of
|
|
||||||
the catch variable is in HANDLER_PARMS, and the body block in
|
|
||||||
HANDLER_BODY. */
|
|
||||||
DEFTREECODE (HANDLER, "handler", tcc_statement, 2)
|
|
||||||
|
|
||||||
/* A MUST_NOT_THROW_EXPR wraps an expression that may not
|
|
||||||
throw, and must call terminate if it does. The second argument
|
|
||||||
is a condition, used in templates to express noexcept (condition). */
|
|
||||||
DEFTREECODE (MUST_NOT_THROW_EXPR, "must_not_throw_expr", tcc_expression, 2)
|
|
||||||
|
|
||||||
/* A CLEANUP_STMT marks the point at which a declaration is fully
|
|
||||||
constructed. The CLEANUP_EXPR is run on behalf of CLEANUP_DECL
|
|
||||||
when CLEANUP_BODY completes. */
|
|
||||||
DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", tcc_statement, 3)
|
|
||||||
|
|
||||||
/* Represents an 'if' statement. The operands are IF_COND,
|
|
||||||
THEN_CLAUSE, and ELSE_CLAUSE, and the current scope, respectively. */
|
|
||||||
/* ??? It is currently still necessary to distinguish between IF_STMT
|
|
||||||
and COND_EXPR for the benefit of templates. */
|
|
||||||
DEFTREECODE (IF_STMT, "if_stmt", tcc_statement, 4)
|
|
||||||
|
|
||||||
/* Used to represent a `for' statement. The operands are
|
|
||||||
FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively. */
|
|
||||||
DEFTREECODE (FOR_STMT, "for_stmt", tcc_statement, 5)
|
|
||||||
|
|
||||||
/* Used to represent a range-based `for' statement. The operands are
|
|
||||||
RANGE_FOR_DECL, RANGE_FOR_EXPR, RANGE_FOR_BODY, and RANGE_FOR_SCOPE,
|
|
||||||
respectively. Only used in templates. */
|
|
||||||
DEFTREECODE (RANGE_FOR_STMT, "range_for_stmt", tcc_statement, 4)
|
|
||||||
|
|
||||||
/* Used to represent a 'while' statement. The operands are WHILE_COND
|
|
||||||
and WHILE_BODY, respectively. */
|
|
||||||
DEFTREECODE (WHILE_STMT, "while_stmt", tcc_statement, 2)
|
|
||||||
|
|
||||||
/* Used to represent a 'do' statement. The operands are DO_BODY and
|
|
||||||
DO_COND, respectively. */
|
|
||||||
DEFTREECODE (DO_STMT, "do_stmt", tcc_statement, 2)
|
|
||||||
|
|
||||||
/* Used to represent a 'break' statement. */
|
|
||||||
DEFTREECODE (BREAK_STMT, "break_stmt", tcc_statement, 0)
|
|
||||||
|
|
||||||
/* Used to represent a 'continue' statement. */
|
|
||||||
DEFTREECODE (CONTINUE_STMT, "continue_stmt", tcc_statement, 0)
|
|
||||||
|
|
||||||
/* Used to represent a 'switch' statement. The operands are
|
|
||||||
SWITCH_STMT_COND, SWITCH_STMT_BODY, SWITCH_STMT_TYPE, and
|
|
||||||
SWITCH_STMT_SCOPE, respectively. */
|
|
||||||
DEFTREECODE (SWITCH_STMT, "switch_stmt", tcc_statement, 4)
|
|
||||||
|
|
||||||
/* Used to represent an expression statement. Use `EXPR_STMT_EXPR' to
|
|
||||||
obtain the expression. */
|
|
||||||
DEFTREECODE (EXPR_STMT, "expr_stmt", tcc_expression, 1)
|
|
||||||
|
|
||||||
DEFTREECODE (TAG_DEFN, "tag_defn", tcc_expression, 0)
|
|
||||||
|
|
||||||
/* Represents an 'offsetof' expression during template expansion. */
|
|
||||||
DEFTREECODE (OFFSETOF_EXPR, "offsetof_expr", tcc_expression, 1)
|
|
||||||
|
|
||||||
/* Represents the -> operator during template expansion. */
|
|
||||||
DEFTREECODE (ARROW_EXPR, "arrow_expr", tcc_expression, 1)
|
|
||||||
|
|
||||||
/* Represents an '__alignof__' expression during template
|
|
||||||
expansion. */
|
|
||||||
DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", tcc_expression, 1)
|
|
||||||
|
|
||||||
/* Represents an Objective-C++ '@encode' expression during template
|
|
||||||
expansion. */
|
|
||||||
DEFTREECODE (AT_ENCODE_EXPR, "at_encode_expr", tcc_expression, 1)
|
|
||||||
|
|
||||||
/* A STMT_EXPR represents a statement-expression during template
|
|
||||||
expansion. This is the GCC extension { ( ... ) }. The
|
|
||||||
STMT_EXPR_STMT is the statement given by the expression. */
|
|
||||||
DEFTREECODE (STMT_EXPR, "stmt_expr", tcc_expression, 1)
|
|
||||||
|
|
||||||
/* Unary plus. Operand 0 is the expression to which the unary plus
|
|
||||||
is applied. */
|
|
||||||
DEFTREECODE (UNARY_PLUS_EXPR, "unary_plus_expr", tcc_unary, 1)
|
|
||||||
|
|
||||||
/** C++0x extensions. */
|
|
||||||
|
|
||||||
/* A static assertion. This is a C++0x extension.
|
|
||||||
STATIC_ASSERT_CONDITION contains the condition that is being
|
|
||||||
checked. STATIC_ASSERT_MESSAGE contains the message (a string
|
|
||||||
literal) to be displayed if the condition fails to hold. */
|
|
||||||
DEFTREECODE (STATIC_ASSERT, "static_assert", tcc_exceptional, 0)
|
|
||||||
|
|
||||||
/* Represents an argument pack of types (or templates). An argument
|
|
||||||
pack stores zero or more arguments that will be used to instantiate
|
|
||||||
a parameter pack.
|
|
||||||
|
|
||||||
ARGUMENT_PACK_ARGS retrieves the arguments stored in the argument
|
|
||||||
pack.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
template<typename... Values>
|
|
||||||
class tuple { ... };
|
|
||||||
|
|
||||||
tuple<int, float, double> t;
|
|
||||||
|
|
||||||
Values is a (template) parameter pack. When tuple<int, float,
|
|
||||||
double> is instantiated, the Values parameter pack is instantiated
|
|
||||||
with the argument pack <int, float, double>. ARGUMENT_PACK_ARGS will
|
|
||||||
be a TREE_VEC containing int, float, and double. */
|
|
||||||
DEFTREECODE (TYPE_ARGUMENT_PACK, "type_argument_pack", tcc_type, 0)
|
|
||||||
|
|
||||||
/* Represents an argument pack of values, which can be used either for
|
|
||||||
non-type template arguments or function call arguments.
|
|
||||||
|
|
||||||
NONTYPE_ARGUMENT_PACK plays precisely the same role as
|
|
||||||
TYPE_ARGUMENT_PACK, but will be used for packing non-type template
|
|
||||||
arguments (e.g., "int... Dimensions") or function arguments ("const
|
|
||||||
Args&... args"). */
|
|
||||||
DEFTREECODE (NONTYPE_ARGUMENT_PACK, "nontype_argument_pack", tcc_expression, 1)
|
|
||||||
|
|
||||||
/* Represents a type expression that will be expanded into a list of
|
|
||||||
types when instantiated with one or more argument packs.
|
|
||||||
|
|
||||||
PACK_EXPANSION_PATTERN retrieves the expansion pattern. This is
|
|
||||||
the type or expression that we will substitute into with each
|
|
||||||
argument in an argument pack.
|
|
||||||
|
|
||||||
SET_PACK_EXPANSION_PATTERN sets the expansion pattern.
|
|
||||||
|
|
||||||
PACK_EXPANSION_PARAMETER_PACKS contains a TREE_LIST of the parameter
|
|
||||||
packs that are used in this pack expansion.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
template<typename... Values>
|
|
||||||
struct tied : tuple<Values&...> {
|
|
||||||
// ...
|
|
||||||
};
|
|
||||||
|
|
||||||
The derivation from tuple contains a TYPE_PACK_EXPANSION for the
|
|
||||||
template arguments. Its PACK_EXPANSION_PATTERN is "Values&" and its
|
|
||||||
PACK_EXPANSION_PARAMETER_PACKS will contain "Values". */
|
|
||||||
DEFTREECODE (TYPE_PACK_EXPANSION, "type_pack_expansion", tcc_type, 0)
|
|
||||||
|
|
||||||
/* Represents an expression that will be expanded into a list of
|
|
||||||
expressions when instantiated with one or more argument packs.
|
|
||||||
|
|
||||||
EXPR_PACK_EXPANSION plays precisely the same role as TYPE_PACK_EXPANSION,
|
|
||||||
but will be used for expressions. */
|
|
||||||
DEFTREECODE (EXPR_PACK_EXPANSION, "expr_pack_expansion", tcc_expression, 3)
|
|
||||||
|
|
||||||
/* Selects the Ith parameter out of an argument pack. This node will
|
|
||||||
be used when instantiating pack expansions; see
|
|
||||||
tsubst_pack_expansion.
|
|
||||||
|
|
||||||
ARGUMENT_PACK_SELECT_FROM_PACK contains the *_ARGUMENT_PACK node
|
|
||||||
from which the argument will be selected.
|
|
||||||
|
|
||||||
ARGUMENT_PACK_SELECT_INDEX contains the index into the argument
|
|
||||||
pack that will be returned by this ARGUMENT_PACK_SELECT node. The
|
|
||||||
index is a machine integer. */
|
|
||||||
DEFTREECODE (ARGUMENT_PACK_SELECT, "argument_pack_select", tcc_exceptional, 0)
|
|
||||||
|
|
||||||
/** C++ extensions. */
|
|
||||||
|
|
||||||
/* Represents a trait expression during template expansion. */
|
|
||||||
DEFTREECODE (TRAIT_EXPR, "trait_expr", tcc_exceptional, 0)
|
|
||||||
|
|
||||||
/* A lambda expression. This is a C++0x extension.
|
|
||||||
LAMBDA_EXPR_DEFAULT_CAPTURE_MODE is an enum for the default, which may be
|
|
||||||
none.
|
|
||||||
LAMBDA_EXPR_CAPTURE_LIST holds the capture-list, including `this'.
|
|
||||||
LAMBDA_EXPR_THIS_CAPTURE goes straight to the capture of `this', if it exists.
|
|
||||||
LAMBDA_EXPR_PENDING_PROXIES is a vector of capture proxies which need to
|
|
||||||
be pushed once scope returns to the lambda.
|
|
||||||
LAMBDA_EXPR_MUTABLE_P signals whether this lambda was declared mutable.
|
|
||||||
LAMBDA_EXPR_RETURN_TYPE holds the return type, if it was specified. */
|
|
||||||
DEFTREECODE (LAMBDA_EXPR, "lambda_expr", tcc_exceptional, 0)
|
|
||||||
|
|
||||||
/* The declared type of an expression. This is a C++0x extension.
|
|
||||||
DECLTYPE_TYPE_EXPR is the expression whose type we are computing.
|
|
||||||
DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P states whether the
|
|
||||||
expression was parsed as an id-expression or a member access
|
|
||||||
expression. When false, it was parsed as a full expression.
|
|
||||||
DECLTYPE_FOR_LAMBDA_CAPTURE is set if we want lambda capture semantics.
|
|
||||||
DECLTYPE_FOR_LAMBDA_RETURN is set if we want lambda return deduction. */
|
|
||||||
DEFTREECODE (DECLTYPE_TYPE, "decltype_type", tcc_type, 0)
|
|
||||||
|
|
||||||
/* A type designated by `__underlying_type (type)'.
|
|
||||||
UNDERLYING_TYPE_TYPE is the type in question. */
|
|
||||||
DEFTREECODE (UNDERLYING_TYPE, "underlying_type", tcc_type, 0)
|
|
||||||
|
|
||||||
/* A type designated by one of the bases type traits.
|
|
||||||
BASES_TYPE is the type in question. */
|
|
||||||
DEFTREECODE (BASES, "bases", tcc_type, 0)
|
|
||||||
|
|
||||||
/* Used to represent the template information stored by template
|
|
||||||
specializations.
|
|
||||||
The accessors are:
|
|
||||||
TI_TEMPLATE the template declaration associated to the specialization
|
|
||||||
TI_ARGS the arguments of the template specialization
|
|
||||||
TI_TYPEDEFS_NEEDING_ACCESS_CHECKING the vector of typedefs used in
|
|
||||||
the pattern of the template for which access check is needed at template
|
|
||||||
instantiation time. */
|
|
||||||
DEFTREECODE (TEMPLATE_INFO, "template_info", tcc_exceptional, 0)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Local variables:
|
|
||||||
mode:c
|
|
||||||
End:
|
|
||||||
*/
|
|
File diff suppressed because it is too large
Load Diff
@ -1,79 +0,0 @@
|
|||||||
/* Interface for the GNU C++ pretty-printer.
|
|
||||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_CXX_PRETTY_PRINT_H
|
|
||||||
#define GCC_CXX_PRETTY_PRINT_H
|
|
||||||
|
|
||||||
#include "c-family/c-pretty-print.h"
|
|
||||||
|
|
||||||
#undef pp_c_base
|
|
||||||
#define pp_c_base(PP) (&(PP)->c_base)
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
/* Ask for a qualified-id. */
|
|
||||||
pp_cxx_flag_default_argument = 1 << pp_c_flag_last_bit
|
|
||||||
|
|
||||||
} cxx_pretty_printer_flags;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
c_pretty_printer c_base;
|
|
||||||
/* This is the enclosing scope of the entity being pretty-printed. */
|
|
||||||
tree enclosing_scope;
|
|
||||||
} cxx_pretty_printer;
|
|
||||||
|
|
||||||
#define pp_cxx_cv_qualifier_seq(PP, T) \
|
|
||||||
pp_c_type_qualifier_list (pp_c_base (PP), T)
|
|
||||||
|
|
||||||
#define pp_cxx_whitespace(PP) pp_c_whitespace (pp_c_base (PP))
|
|
||||||
#define pp_cxx_left_paren(PP) pp_c_left_paren (pp_c_base (PP))
|
|
||||||
#define pp_cxx_right_paren(PP) pp_c_right_paren (pp_c_base (PP))
|
|
||||||
#define pp_cxx_left_brace(PP) pp_c_left_brace (pp_c_base (PP))
|
|
||||||
#define pp_cxx_right_brace(PP) pp_c_right_brace (pp_c_base (PP))
|
|
||||||
#define pp_cxx_left_bracket(PP) pp_c_left_bracket (pp_c_base (PP))
|
|
||||||
#define pp_cxx_right_bracket(PP) pp_c_right_bracket (pp_c_base (PP))
|
|
||||||
#define pp_cxx_dot(PP) pp_c_dot (pp_c_base (PP))
|
|
||||||
#define pp_cxx_ampersand(PP) pp_c_ampersand (pp_c_base (PP))
|
|
||||||
#define pp_cxx_star(PP) pp_c_star (pp_c_base (PP))
|
|
||||||
#define pp_cxx_arrow(PP) pp_c_arrow (pp_c_base (PP))
|
|
||||||
#define pp_cxx_semicolon(PP) pp_c_semicolon (pp_c_base (PP))
|
|
||||||
#define pp_cxx_complement(PP) pp_c_complement (pp_c_base (PP))
|
|
||||||
|
|
||||||
#define pp_cxx_ws_string(PP, I) pp_c_ws_string (pp_c_base (PP), I)
|
|
||||||
#define pp_cxx_identifier(PP, I) pp_c_identifier (pp_c_base (PP), I)
|
|
||||||
#define pp_cxx_tree_identifier(PP, T) \
|
|
||||||
pp_c_tree_identifier (pp_c_base (PP), T)
|
|
||||||
|
|
||||||
void pp_cxx_pretty_printer_init (cxx_pretty_printer *);
|
|
||||||
void pp_cxx_begin_template_argument_list (cxx_pretty_printer *);
|
|
||||||
void pp_cxx_end_template_argument_list (cxx_pretty_printer *);
|
|
||||||
void pp_cxx_colon_colon (cxx_pretty_printer *);
|
|
||||||
void pp_cxx_separate_with (cxx_pretty_printer *, int);
|
|
||||||
|
|
||||||
void pp_cxx_declaration (cxx_pretty_printer *, tree);
|
|
||||||
void pp_cxx_canonical_template_parameter (cxx_pretty_printer *, tree);
|
|
||||||
void pp_cxx_trait_expression (cxx_pretty_printer *, tree);
|
|
||||||
void pp_cxx_va_arg_expression (cxx_pretty_printer *, tree);
|
|
||||||
void pp_cxx_offsetof_expression (cxx_pretty_printer *, tree);
|
|
||||||
void pp_cxx_userdef_literal (cxx_pretty_printer *, tree);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* GCC_CXX_PRETTY_PRINT_H */
|
|
@ -1,369 +0,0 @@
|
|||||||
/* Declarations for C++ name lookup routines.
|
|
||||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_CP_NAME_LOOKUP_H
|
|
||||||
#define GCC_CP_NAME_LOOKUP_H
|
|
||||||
|
|
||||||
#include "c-family/c-common.h"
|
|
||||||
|
|
||||||
/* The type of dictionary used to map names to types declared at
|
|
||||||
a given scope. */
|
|
||||||
typedef struct binding_table_s *binding_table;
|
|
||||||
typedef struct binding_entry_s *binding_entry;
|
|
||||||
|
|
||||||
/* The type of a routine repeatedly called by binding_table_foreach. */
|
|
||||||
typedef void (*bt_foreach_proc) (binding_entry, void *);
|
|
||||||
|
|
||||||
struct GTY(()) binding_entry_s {
|
|
||||||
binding_entry chain;
|
|
||||||
tree name;
|
|
||||||
tree type;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* These macros indicate the initial chains count for binding_table. */
|
|
||||||
#define SCOPE_DEFAULT_HT_SIZE (1 << 3)
|
|
||||||
#define CLASS_SCOPE_HT_SIZE (1 << 3)
|
|
||||||
#define NAMESPACE_ORDINARY_HT_SIZE (1 << 5)
|
|
||||||
#define NAMESPACE_STD_HT_SIZE (1 << 8)
|
|
||||||
#define GLOBAL_SCOPE_HT_SIZE (1 << 8)
|
|
||||||
|
|
||||||
extern void binding_table_foreach (binding_table, bt_foreach_proc, void *);
|
|
||||||
extern binding_entry binding_table_find (binding_table, tree);
|
|
||||||
|
|
||||||
/* Datatype that represents binding established by a declaration between
|
|
||||||
a name and a C++ entity. */
|
|
||||||
typedef struct cxx_binding cxx_binding;
|
|
||||||
|
|
||||||
/* The datatype used to implement C++ scope. */
|
|
||||||
typedef struct cp_binding_level cp_binding_level;
|
|
||||||
|
|
||||||
/* Nonzero if this binding is for a local scope, as opposed to a class
|
|
||||||
or namespace scope. */
|
|
||||||
#define LOCAL_BINDING_P(NODE) ((NODE)->is_local)
|
|
||||||
|
|
||||||
/* True if NODE->value is from a base class of the class which is
|
|
||||||
currently being defined. */
|
|
||||||
#define INHERITED_VALUE_BINDING_P(NODE) ((NODE)->value_is_inherited)
|
|
||||||
|
|
||||||
struct GTY(()) cxx_binding {
|
|
||||||
/* Link to chain together various bindings for this name. */
|
|
||||||
cxx_binding *previous;
|
|
||||||
/* The non-type entity this name is bound to. */
|
|
||||||
tree value;
|
|
||||||
/* The type entity this name is bound to. */
|
|
||||||
tree type;
|
|
||||||
/* The scope at which this binding was made. */
|
|
||||||
cp_binding_level *scope;
|
|
||||||
unsigned value_is_inherited : 1;
|
|
||||||
unsigned is_local : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Datatype used to temporarily save C++ bindings (for implicit
|
|
||||||
instantiations purposes and like). Implemented in decl.c. */
|
|
||||||
typedef struct GTY(()) cxx_saved_binding {
|
|
||||||
/* The name of the current binding. */
|
|
||||||
tree identifier;
|
|
||||||
/* The binding we're saving. */
|
|
||||||
cxx_binding *binding;
|
|
||||||
tree real_type_value;
|
|
||||||
} cxx_saved_binding;
|
|
||||||
|
|
||||||
|
|
||||||
extern tree identifier_type_value (tree);
|
|
||||||
extern void set_identifier_type_value (tree, tree);
|
|
||||||
extern void pop_binding (tree, tree);
|
|
||||||
extern tree constructor_name (tree);
|
|
||||||
extern bool constructor_name_p (tree, tree);
|
|
||||||
|
|
||||||
/* The kinds of scopes we recognize. */
|
|
||||||
typedef enum scope_kind {
|
|
||||||
sk_block = 0, /* An ordinary block scope. This enumerator must
|
|
||||||
have the value zero because "cp_binding_level"
|
|
||||||
is initialized by using "memset" to set the
|
|
||||||
contents to zero, and the default scope kind
|
|
||||||
is "sk_block". */
|
|
||||||
sk_cleanup, /* A scope for (pseudo-)scope for cleanup. It is
|
|
||||||
pseudo in that it is transparent to name lookup
|
|
||||||
activities. */
|
|
||||||
sk_try, /* A try-block. */
|
|
||||||
sk_catch, /* A catch-block. */
|
|
||||||
sk_for, /* The scope of the variable declared in a
|
|
||||||
for-init-statement. */
|
|
||||||
sk_cond, /* The scope of the variable declared in the condition
|
|
||||||
of an if or switch statement. */
|
|
||||||
sk_function_parms, /* The scope containing function parameters. */
|
|
||||||
sk_class, /* The scope containing the members of a class. */
|
|
||||||
sk_scoped_enum, /* The scope containing the enumertors of a C++0x
|
|
||||||
scoped enumeration. */
|
|
||||||
sk_namespace, /* The scope containing the members of a
|
|
||||||
namespace, including the global scope. */
|
|
||||||
sk_template_parms, /* A scope for template parameters. */
|
|
||||||
sk_template_spec, /* Like sk_template_parms, but for an explicit
|
|
||||||
specialization. Since, by definition, an
|
|
||||||
explicit specialization is introduced by
|
|
||||||
"template <>", this scope is always empty. */
|
|
||||||
sk_omp /* An OpenMP structured block. */
|
|
||||||
} scope_kind;
|
|
||||||
|
|
||||||
/* The scope where the class/struct/union/enum tag applies. */
|
|
||||||
typedef enum tag_scope {
|
|
||||||
ts_current = 0, /* Current scope only. This is for the
|
|
||||||
class-key identifier;
|
|
||||||
case mentioned in [basic.lookup.elab]/2,
|
|
||||||
or the class/enum definition
|
|
||||||
class-key identifier { ... }; */
|
|
||||||
ts_global = 1, /* All scopes. This is the 3.4.1
|
|
||||||
[basic.lookup.unqual] lookup mentioned
|
|
||||||
in [basic.lookup.elab]/2. */
|
|
||||||
ts_within_enclosing_non_class = 2, /* Search within enclosing non-class
|
|
||||||
only, for friend class lookup
|
|
||||||
according to [namespace.memdef]/3
|
|
||||||
and [class.friend]/9. */
|
|
||||||
ts_lambda = 3 /* Declaring a lambda closure. */
|
|
||||||
} tag_scope;
|
|
||||||
|
|
||||||
typedef struct GTY(()) cp_class_binding {
|
|
||||||
cxx_binding *base;
|
|
||||||
/* The bound name. */
|
|
||||||
tree identifier;
|
|
||||||
} cp_class_binding;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct GTY(()) cp_label_binding {
|
|
||||||
/* The bound LABEL_DECL. */
|
|
||||||
tree label;
|
|
||||||
/* The previous IDENTIFIER_LABEL_VALUE. */
|
|
||||||
tree prev_value;
|
|
||||||
} cp_label_binding;
|
|
||||||
|
|
||||||
|
|
||||||
/* For each binding contour we allocate a binding_level structure
|
|
||||||
which records the names defined in that contour.
|
|
||||||
Contours include:
|
|
||||||
0) the global one
|
|
||||||
1) one for each function definition,
|
|
||||||
where internal declarations of the parameters appear.
|
|
||||||
2) one for each compound statement,
|
|
||||||
to record its declarations.
|
|
||||||
|
|
||||||
The current meaning of a name can be found by searching the levels
|
|
||||||
from the current one out to the global one.
|
|
||||||
|
|
||||||
Off to the side, may be the class_binding_level. This exists only
|
|
||||||
to catch class-local declarations. It is otherwise nonexistent.
|
|
||||||
|
|
||||||
Also there may be binding levels that catch cleanups that must be
|
|
||||||
run when exceptions occur. Thus, to see whether a name is bound in
|
|
||||||
the current scope, it is not enough to look in the
|
|
||||||
CURRENT_BINDING_LEVEL. You should use lookup_name_current_level
|
|
||||||
instead. */
|
|
||||||
|
|
||||||
/* Note that the information in the `names' component of the global contour
|
|
||||||
is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
|
|
||||||
|
|
||||||
struct GTY(()) cp_binding_level {
|
|
||||||
/* A chain of _DECL nodes for all variables, constants, functions,
|
|
||||||
and typedef types. These are in the reverse of the order
|
|
||||||
supplied. There may be OVERLOADs on this list, too, but they
|
|
||||||
are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */
|
|
||||||
tree names;
|
|
||||||
|
|
||||||
/* A chain of NAMESPACE_DECL nodes. */
|
|
||||||
tree namespaces;
|
|
||||||
|
|
||||||
/* An array of static functions and variables (for namespaces only) */
|
|
||||||
vec<tree, va_gc> *static_decls;
|
|
||||||
|
|
||||||
/* A list of USING_DECL nodes. */
|
|
||||||
tree usings;
|
|
||||||
|
|
||||||
/* A list of used namespaces. PURPOSE is the namespace,
|
|
||||||
VALUE the common ancestor with this binding_level's namespace. */
|
|
||||||
tree using_directives;
|
|
||||||
|
|
||||||
/* For the binding level corresponding to a class, the entities
|
|
||||||
declared in the class or its base classes. */
|
|
||||||
vec<cp_class_binding, va_gc> *class_shadowed;
|
|
||||||
|
|
||||||
/* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and
|
|
||||||
is used for all binding levels. The TREE_PURPOSE is the name of
|
|
||||||
the entity, the TREE_TYPE is the associated type. In addition
|
|
||||||
the TREE_VALUE is the IDENTIFIER_TYPE_VALUE before we entered
|
|
||||||
the class. */
|
|
||||||
tree type_shadowed;
|
|
||||||
|
|
||||||
/* Similar to class_shadowed, but for IDENTIFIER_LABEL_VALUE, and
|
|
||||||
used for all binding levels. */
|
|
||||||
vec<cp_label_binding, va_gc> *shadowed_labels;
|
|
||||||
|
|
||||||
/* For each level (except not the global one),
|
|
||||||
a chain of BLOCK nodes for all the levels
|
|
||||||
that were entered and exited one level down. */
|
|
||||||
tree blocks;
|
|
||||||
|
|
||||||
/* The entity (namespace, class, function) the scope of which this
|
|
||||||
binding contour corresponds to. Otherwise NULL. */
|
|
||||||
tree this_entity;
|
|
||||||
|
|
||||||
/* The binding level which this one is contained in (inherits from). */
|
|
||||||
cp_binding_level *level_chain;
|
|
||||||
|
|
||||||
/* List of VAR_DECLS saved from a previous for statement.
|
|
||||||
These would be dead in ISO-conforming code, but might
|
|
||||||
be referenced in ARM-era code. */
|
|
||||||
vec<tree, va_gc> *dead_vars_from_for;
|
|
||||||
|
|
||||||
/* STATEMENT_LIST for statements in this binding contour.
|
|
||||||
Only used at present for SK_CLEANUP temporary bindings. */
|
|
||||||
tree statement_list;
|
|
||||||
|
|
||||||
/* Binding depth at which this level began. */
|
|
||||||
int binding_depth;
|
|
||||||
|
|
||||||
/* The kind of scope that this object represents. However, a
|
|
||||||
SK_TEMPLATE_SPEC scope is represented with KIND set to
|
|
||||||
SK_TEMPLATE_PARMS and EXPLICIT_SPEC_P set to true. */
|
|
||||||
ENUM_BITFIELD (scope_kind) kind : 4;
|
|
||||||
|
|
||||||
/* True if this scope is an SK_TEMPLATE_SPEC scope. This field is
|
|
||||||
only valid if KIND == SK_TEMPLATE_PARMS. */
|
|
||||||
BOOL_BITFIELD explicit_spec_p : 1;
|
|
||||||
|
|
||||||
/* true means make a BLOCK for this level regardless of all else. */
|
|
||||||
unsigned keep : 1;
|
|
||||||
|
|
||||||
/* Nonzero if this level can safely have additional
|
|
||||||
cleanup-needing variables added to it. */
|
|
||||||
unsigned more_cleanups_ok : 1;
|
|
||||||
unsigned have_cleanups : 1;
|
|
||||||
|
|
||||||
/* 24 bits left to fill a 32-bit word. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The binding level currently in effect. */
|
|
||||||
|
|
||||||
#define current_binding_level \
|
|
||||||
(*(cfun && cp_function_chain && cp_function_chain->bindings \
|
|
||||||
? &cp_function_chain->bindings \
|
|
||||||
: &scope_chain->bindings))
|
|
||||||
|
|
||||||
/* The binding level of the current class, if any. */
|
|
||||||
|
|
||||||
#define class_binding_level scope_chain->class_bindings
|
|
||||||
|
|
||||||
/* The tree node representing the global scope. */
|
|
||||||
extern GTY(()) tree global_namespace;
|
|
||||||
extern GTY(()) tree global_scope_name;
|
|
||||||
|
|
||||||
/* Indicates that there is a type value in some namespace, although
|
|
||||||
that is not necessarily in scope at the moment. */
|
|
||||||
|
|
||||||
extern GTY(()) tree global_type_node;
|
|
||||||
|
|
||||||
/* True if SCOPE designates the global scope binding contour. */
|
|
||||||
#define global_scope_p(SCOPE) \
|
|
||||||
((SCOPE) == NAMESPACE_LEVEL (global_namespace))
|
|
||||||
|
|
||||||
extern cp_binding_level *leave_scope (void);
|
|
||||||
extern bool kept_level_p (void);
|
|
||||||
extern bool global_bindings_p (void);
|
|
||||||
extern bool toplevel_bindings_p (void);
|
|
||||||
extern bool namespace_bindings_p (void);
|
|
||||||
extern bool local_bindings_p (void);
|
|
||||||
extern bool template_parm_scope_p (void);
|
|
||||||
extern scope_kind innermost_scope_kind (void);
|
|
||||||
extern cp_binding_level *begin_scope (scope_kind, tree);
|
|
||||||
extern void print_binding_stack (void);
|
|
||||||
extern void push_to_top_level (void);
|
|
||||||
extern void pop_from_top_level (void);
|
|
||||||
extern void pop_everything (void);
|
|
||||||
extern void keep_next_level (bool);
|
|
||||||
extern bool is_ancestor (tree, tree);
|
|
||||||
extern tree push_scope (tree);
|
|
||||||
extern void pop_scope (tree);
|
|
||||||
extern tree push_inner_scope (tree);
|
|
||||||
extern void pop_inner_scope (tree, tree);
|
|
||||||
extern void push_binding_level (cp_binding_level *);
|
|
||||||
|
|
||||||
extern void push_namespace (tree);
|
|
||||||
extern void pop_namespace (void);
|
|
||||||
extern void push_nested_namespace (tree);
|
|
||||||
extern void pop_nested_namespace (tree);
|
|
||||||
extern bool handle_namespace_attrs (tree, tree);
|
|
||||||
extern void pushlevel_class (void);
|
|
||||||
extern void poplevel_class (void);
|
|
||||||
extern tree pushdecl_with_scope (tree, cp_binding_level *, bool);
|
|
||||||
extern tree lookup_name_prefer_type (tree, int);
|
|
||||||
extern tree lookup_name_real (tree, int, int, bool, int, int);
|
|
||||||
extern tree lookup_type_scope (tree, tag_scope);
|
|
||||||
extern tree namespace_binding (tree, tree);
|
|
||||||
extern void set_namespace_binding (tree, tree, tree);
|
|
||||||
extern bool hidden_name_p (tree);
|
|
||||||
extern tree remove_hidden_names (tree);
|
|
||||||
extern tree lookup_qualified_name (tree, tree, bool, bool);
|
|
||||||
extern tree lookup_name_nonclass (tree);
|
|
||||||
extern tree lookup_name_innermost_nonclass_level (tree);
|
|
||||||
extern bool is_local_extern (tree);
|
|
||||||
extern tree lookup_function_nonclass (tree, vec<tree, va_gc> *, bool);
|
|
||||||
extern void push_local_binding (tree, tree, int);
|
|
||||||
extern bool pushdecl_class_level (tree);
|
|
||||||
extern tree pushdecl_namespace_level (tree, bool);
|
|
||||||
extern bool push_class_level_binding (tree, tree);
|
|
||||||
extern tree getdecls (void);
|
|
||||||
extern int function_parm_depth (void);
|
|
||||||
extern tree cp_namespace_decls (tree);
|
|
||||||
extern void set_decl_namespace (tree, tree, bool);
|
|
||||||
extern void push_decl_namespace (tree);
|
|
||||||
extern void pop_decl_namespace (void);
|
|
||||||
extern void do_namespace_alias (tree, tree);
|
|
||||||
extern void do_toplevel_using_decl (tree, tree, tree);
|
|
||||||
extern void do_local_using_decl (tree, tree, tree);
|
|
||||||
extern tree do_class_using_decl (tree, tree);
|
|
||||||
extern void do_using_directive (tree);
|
|
||||||
extern tree lookup_arg_dependent (tree, tree, vec<tree, va_gc> *, bool);
|
|
||||||
extern bool is_associated_namespace (tree, tree);
|
|
||||||
extern void parse_using_directive (tree, tree);
|
|
||||||
extern tree innermost_non_namespace_value (tree);
|
|
||||||
extern cxx_binding *outer_binding (tree, cxx_binding *, bool);
|
|
||||||
extern void cp_emit_debug_info_for_using (tree, tree);
|
|
||||||
|
|
||||||
/* Set *DECL to the (non-hidden) declaration for ID at global scope,
|
|
||||||
if present and return true; otherwise return false. */
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
get_global_value_if_present (tree id, tree *decl)
|
|
||||||
{
|
|
||||||
tree global_value = namespace_binding (id, global_namespace);
|
|
||||||
if (global_value)
|
|
||||||
*decl = global_value;
|
|
||||||
return global_value != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* True is the binding of IDENTIFIER at global scope names a type. */
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
is_typename_at_global_scope (tree id)
|
|
||||||
{
|
|
||||||
tree global_value = namespace_binding (id, global_namespace);
|
|
||||||
|
|
||||||
return global_value && TREE_CODE (global_value) == TYPE_DECL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* GCC_CP_NAME_LOOKUP_H */
|
|
@ -1,71 +0,0 @@
|
|||||||
/* CPP Library.
|
|
||||||
Copyright (C) 1986-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Per Bothner, 1994-95.
|
|
||||||
Based on CCCP program by Paul Rubin, June 1986
|
|
||||||
Adapted to ANSI C, Richard Stallman, Jan 1987
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 3, or (at your option) any
|
|
||||||
later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_CPPDEFAULT_H
|
|
||||||
#define GCC_CPPDEFAULT_H
|
|
||||||
|
|
||||||
/* This is the default list of directories to search for include files.
|
|
||||||
It may be overridden by the various -I and -ixxx options.
|
|
||||||
|
|
||||||
#include "file" looks in the same directory as the current file,
|
|
||||||
then this list.
|
|
||||||
#include <file> just looks in this list.
|
|
||||||
|
|
||||||
All these directories are treated as `system' include directories
|
|
||||||
(they are not subject to pedantic warnings in some cases). */
|
|
||||||
|
|
||||||
struct default_include
|
|
||||||
{
|
|
||||||
const char *const fname; /* The name of the directory. */
|
|
||||||
const char *const component; /* The component containing the directory
|
|
||||||
(see update_path in prefix.c) */
|
|
||||||
const char cplusplus; /* Only look here if we're compiling C++. */
|
|
||||||
const char cxx_aware; /* Includes in this directory don't need to
|
|
||||||
be wrapped in extern "C" when compiling
|
|
||||||
C++. */
|
|
||||||
const char add_sysroot; /* FNAME should be prefixed by
|
|
||||||
cpp_SYSROOT. */
|
|
||||||
const char multilib; /* FNAME should have appended
|
|
||||||
- the multilib path specified with -imultilib
|
|
||||||
when set to 1,
|
|
||||||
- the multiarch path specified with
|
|
||||||
-imultiarch, when set to 2. */
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const struct default_include cpp_include_defaults[];
|
|
||||||
extern const char cpp_GCC_INCLUDE_DIR[];
|
|
||||||
extern const size_t cpp_GCC_INCLUDE_DIR_len;
|
|
||||||
|
|
||||||
/* The configure-time prefix, i.e., the value supplied as the argument
|
|
||||||
to --prefix=. */
|
|
||||||
extern const char cpp_PREFIX[];
|
|
||||||
/* The length of the configure-time prefix. */
|
|
||||||
extern const size_t cpp_PREFIX_len;
|
|
||||||
/* The configure-time execution prefix. This is typically the lib/gcc
|
|
||||||
subdirectory of cpp_PREFIX. */
|
|
||||||
extern const char cpp_EXEC_PREFIX[];
|
|
||||||
/* The run-time execution prefix. This is typically the lib/gcc
|
|
||||||
subdirectory of the actual installation. */
|
|
||||||
extern const char *gcc_exec_prefix;
|
|
||||||
|
|
||||||
/* Return true if the toolchain is relocated. */
|
|
||||||
bool cpp_relocated (void);
|
|
||||||
|
|
||||||
#endif /* ! GCC_CPPDEFAULT_H */
|
|
1059
src/include/cpplib.h
1059
src/include/cpplib.h
File diff suppressed because it is too large
Load Diff
@ -1,195 +0,0 @@
|
|||||||
/* Debug hooks for GCC.
|
|
||||||
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 3, or (at your option) any
|
|
||||||
later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_DEBUG_H
|
|
||||||
#define GCC_DEBUG_H
|
|
||||||
|
|
||||||
/* This structure contains hooks for the debug information output
|
|
||||||
functions, accessed through the global instance debug_hooks set in
|
|
||||||
toplev.c according to command line options. */
|
|
||||||
struct gcc_debug_hooks
|
|
||||||
{
|
|
||||||
/* Initialize debug output. MAIN_FILENAME is the name of the main
|
|
||||||
input file. */
|
|
||||||
void (* init) (const char *main_filename);
|
|
||||||
|
|
||||||
/* Output debug symbols. */
|
|
||||||
void (* finish) (const char *main_filename);
|
|
||||||
|
|
||||||
/* Called from cgraph_optimize before starting to assemble
|
|
||||||
functions/variables/toplevel asms. */
|
|
||||||
void (* assembly_start) (void);
|
|
||||||
|
|
||||||
/* Macro defined on line LINE with name and expansion TEXT. */
|
|
||||||
void (* define) (unsigned int line, const char *text);
|
|
||||||
|
|
||||||
/* MACRO undefined on line LINE. */
|
|
||||||
void (* undef) (unsigned int line, const char *macro);
|
|
||||||
|
|
||||||
/* Record the beginning of a new source file FILE from LINE number
|
|
||||||
in the previous one. */
|
|
||||||
void (* start_source_file) (unsigned int line, const char *file);
|
|
||||||
|
|
||||||
/* Record the resumption of a source file. LINE is the line number
|
|
||||||
in the source file we are returning to. */
|
|
||||||
void (* end_source_file) (unsigned int line);
|
|
||||||
|
|
||||||
/* Record the beginning of block N, counting from 1 and not
|
|
||||||
including the function-scope block, at LINE. */
|
|
||||||
void (* begin_block) (unsigned int line, unsigned int n);
|
|
||||||
|
|
||||||
/* Record the end of a block. Arguments as for begin_block. */
|
|
||||||
void (* end_block) (unsigned int line, unsigned int n);
|
|
||||||
|
|
||||||
/* Returns nonzero if it is appropriate not to emit any debugging
|
|
||||||
information for BLOCK, because it doesn't contain any
|
|
||||||
instructions. This may not be the case for blocks containing
|
|
||||||
nested functions, since we may actually call such a function even
|
|
||||||
though the BLOCK information is messed up. Defaults to true. */
|
|
||||||
bool (* ignore_block) (const_tree);
|
|
||||||
|
|
||||||
/* Record a source file location at (FILE, LINE, DISCRIMINATOR). */
|
|
||||||
void (* source_line) (unsigned int line, const char *file,
|
|
||||||
int discriminator, bool is_stmt);
|
|
||||||
|
|
||||||
/* Called at start of prologue code. LINE is the first line in the
|
|
||||||
function. */
|
|
||||||
void (* begin_prologue) (unsigned int line, const char *file);
|
|
||||||
|
|
||||||
/* Called at end of prologue code. LINE is the first line in the
|
|
||||||
function. */
|
|
||||||
void (* end_prologue) (unsigned int line, const char *file);
|
|
||||||
|
|
||||||
/* Called at beginning of epilogue code. */
|
|
||||||
void (* begin_epilogue) (unsigned int line, const char *file);
|
|
||||||
|
|
||||||
/* Record end of epilogue code. */
|
|
||||||
void (* end_epilogue) (unsigned int line, const char *file);
|
|
||||||
|
|
||||||
/* Called at start of function DECL, before it is declared. */
|
|
||||||
void (* begin_function) (tree decl);
|
|
||||||
|
|
||||||
/* Record end of function. LINE is highest line number in function. */
|
|
||||||
void (* end_function) (unsigned int line);
|
|
||||||
|
|
||||||
/* Debug information for a function DECL. This might include the
|
|
||||||
function name (a symbol), its parameters, and the block that
|
|
||||||
makes up the function's body, and the local variables of the
|
|
||||||
function. */
|
|
||||||
void (* function_decl) (tree decl);
|
|
||||||
|
|
||||||
/* Debug information for a global DECL. Called from toplev.c after
|
|
||||||
compilation proper has finished. */
|
|
||||||
void (* global_decl) (tree decl);
|
|
||||||
|
|
||||||
/* Debug information for a type DECL. Called from toplev.c after
|
|
||||||
compilation proper, also from various language front ends to
|
|
||||||
record built-in types. The second argument is properly a
|
|
||||||
boolean, which indicates whether or not the type is a "local"
|
|
||||||
type as determined by the language. (It's not a boolean for
|
|
||||||
legacy reasons.) */
|
|
||||||
void (* type_decl) (tree decl, int local);
|
|
||||||
|
|
||||||
/* Debug information for imported modules and declarations. */
|
|
||||||
void (* imported_module_or_decl) (tree decl, tree name,
|
|
||||||
tree context, bool child);
|
|
||||||
|
|
||||||
/* DECL is an inline function, whose body is present, but which is
|
|
||||||
not being output at this point. */
|
|
||||||
void (* deferred_inline_function) (tree decl);
|
|
||||||
|
|
||||||
/* DECL is an inline function which is about to be emitted out of
|
|
||||||
line. The hook is useful to, e.g., emit abstract debug info for
|
|
||||||
the inline before it gets mangled by optimization. */
|
|
||||||
void (* outlining_inline_function) (tree decl);
|
|
||||||
|
|
||||||
/* Called from final_scan_insn for any CODE_LABEL insn whose
|
|
||||||
LABEL_NAME is non-null. */
|
|
||||||
void (* label) (rtx);
|
|
||||||
|
|
||||||
/* Called after the start and before the end of writing a PCH file.
|
|
||||||
The parameter is 0 if after the start, 1 if before the end. */
|
|
||||||
void (* handle_pch) (unsigned int);
|
|
||||||
|
|
||||||
/* Called from final_scan_insn for any NOTE_INSN_VAR_LOCATION note. */
|
|
||||||
void (* var_location) (rtx);
|
|
||||||
|
|
||||||
/* Called from final_scan_insn if there is a switch between hot and cold
|
|
||||||
text sections. */
|
|
||||||
void (* switch_text_section) (void);
|
|
||||||
|
|
||||||
/* Called from grokdeclarator. Replaces the anonymous name with the
|
|
||||||
type name. */
|
|
||||||
void (* set_name) (tree, tree);
|
|
||||||
|
|
||||||
/* This is 1 if the debug writer wants to see start and end commands for the
|
|
||||||
main source files, and 0 otherwise. */
|
|
||||||
int start_end_main_source_file;
|
|
||||||
|
|
||||||
/* The type of symtab field used by these debug hooks. This is one
|
|
||||||
of the TYPE_SYMTAB_IS_xxx values defined in tree.h. */
|
|
||||||
int tree_type_symtab_field;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const struct gcc_debug_hooks *debug_hooks;
|
|
||||||
|
|
||||||
/* The do-nothing hooks. */
|
|
||||||
extern void debug_nothing_void (void);
|
|
||||||
extern void debug_nothing_charstar (const char *);
|
|
||||||
extern void debug_nothing_int_charstar (unsigned int, const char *);
|
|
||||||
extern void debug_nothing_int_charstar_int_bool (unsigned int, const char *,
|
|
||||||
int, bool);
|
|
||||||
extern void debug_nothing_int (unsigned int);
|
|
||||||
extern void debug_nothing_int_int (unsigned int, unsigned int);
|
|
||||||
extern void debug_nothing_tree (tree);
|
|
||||||
extern void debug_nothing_tree_tree (tree, tree);
|
|
||||||
extern void debug_nothing_tree_int (tree, int);
|
|
||||||
extern void debug_nothing_tree_tree_tree_bool (tree, tree, tree, bool);
|
|
||||||
extern bool debug_true_const_tree (const_tree);
|
|
||||||
extern void debug_nothing_rtx (rtx);
|
|
||||||
extern void debug_nothing_rtx_rtx (rtx, rtx);
|
|
||||||
|
|
||||||
/* Hooks for various debug formats. */
|
|
||||||
extern const struct gcc_debug_hooks do_nothing_debug_hooks;
|
|
||||||
extern const struct gcc_debug_hooks dbx_debug_hooks;
|
|
||||||
extern const struct gcc_debug_hooks sdb_debug_hooks;
|
|
||||||
extern const struct gcc_debug_hooks xcoff_debug_hooks;
|
|
||||||
extern const struct gcc_debug_hooks dwarf2_debug_hooks;
|
|
||||||
extern const struct gcc_debug_hooks vmsdbg_debug_hooks;
|
|
||||||
|
|
||||||
/* Dwarf2 frame information. */
|
|
||||||
|
|
||||||
extern void dwarf2out_begin_prologue (unsigned int, const char *);
|
|
||||||
extern void dwarf2out_vms_end_prologue (unsigned int, const char *);
|
|
||||||
extern void dwarf2out_vms_begin_epilogue (unsigned int, const char *);
|
|
||||||
extern void dwarf2out_end_epilogue (unsigned int, const char *);
|
|
||||||
extern void dwarf2out_frame_finish (void);
|
|
||||||
/* Decide whether we want to emit frame unwind information for the current
|
|
||||||
translation unit. */
|
|
||||||
extern bool dwarf2out_do_frame (void);
|
|
||||||
extern bool dwarf2out_do_cfi_asm (void);
|
|
||||||
extern void dwarf2out_switch_text_section (void);
|
|
||||||
|
|
||||||
const char *remap_debug_filename (const char *);
|
|
||||||
void add_debug_prefix_map (const char *);
|
|
||||||
|
|
||||||
/* For -fdump-go-spec. */
|
|
||||||
|
|
||||||
extern const struct gcc_debug_hooks *
|
|
||||||
dump_go_spec_init (const char *, const struct gcc_debug_hooks *);
|
|
||||||
|
|
||||||
#endif /* !GCC_DEBUG_H */
|
|
File diff suppressed because it is too large
Load Diff
@ -1,89 +0,0 @@
|
|||||||
/* Declarations of core diagnostic functionality for code that does
|
|
||||||
not need to deal with diagnostic contexts or diagnostic info
|
|
||||||
structures.
|
|
||||||
Copyright (C) 1998-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_DIAGNOSTIC_CORE_H
|
|
||||||
#define GCC_DIAGNOSTIC_CORE_H
|
|
||||||
|
|
||||||
#include "input.h"
|
|
||||||
#include "bversion.h"
|
|
||||||
|
|
||||||
/* Constants used to discriminate diagnostics. */
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
#define DEFINE_DIAGNOSTIC_KIND(K, msgid) K,
|
|
||||||
#include "diagnostic.def"
|
|
||||||
#undef DEFINE_DIAGNOSTIC_KIND
|
|
||||||
DK_LAST_DIAGNOSTIC_KIND,
|
|
||||||
/* This is used for tagging pragma pops in the diagnostic
|
|
||||||
classification history chain. */
|
|
||||||
DK_POP
|
|
||||||
} diagnostic_t;
|
|
||||||
|
|
||||||
extern const char *progname;
|
|
||||||
|
|
||||||
extern const char *trim_filename (const char *);
|
|
||||||
|
|
||||||
/* If we haven't already defined a front-end-specific diagnostics
|
|
||||||
style, use the generic one. */
|
|
||||||
#ifndef GCC_DIAG_STYLE
|
|
||||||
#define GCC_DIAG_STYLE __gcc_tdiag__
|
|
||||||
#endif
|
|
||||||
/* None of these functions are suitable for ATTRIBUTE_PRINTF, because
|
|
||||||
each language front end can extend them with its own set of format
|
|
||||||
specifiers. We must use custom format checks. */
|
|
||||||
#if (ENABLE_CHECKING && GCC_VERSION >= 4001) || GCC_VERSION == BUILDING_GCC_VERSION
|
|
||||||
#define ATTRIBUTE_GCC_DIAG(m, n) __attribute__ ((__format__ (GCC_DIAG_STYLE, m, n))) ATTRIBUTE_NONNULL(m)
|
|
||||||
#else
|
|
||||||
#define ATTRIBUTE_GCC_DIAG(m, n) ATTRIBUTE_NONNULL(m)
|
|
||||||
#endif
|
|
||||||
extern void internal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
|
|
||||||
ATTRIBUTE_NORETURN;
|
|
||||||
/* Pass one of the OPT_W* from options.h as the first parameter. */
|
|
||||||
extern bool warning (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
|
|
||||||
extern bool warning_at (location_t, int, const char *, ...)
|
|
||||||
ATTRIBUTE_GCC_DIAG(3,4);
|
|
||||||
extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
|
|
||||||
extern void error_n (location_t, int, const char *, const char *, ...)
|
|
||||||
ATTRIBUTE_GCC_DIAG(3,5) ATTRIBUTE_GCC_DIAG(4,5);
|
|
||||||
extern void error_at (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
|
|
||||||
extern void fatal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
|
|
||||||
ATTRIBUTE_NORETURN;
|
|
||||||
/* Pass one of the OPT_W* from options.h as the second parameter. */
|
|
||||||
extern bool pedwarn (location_t, int, const char *, ...)
|
|
||||||
ATTRIBUTE_GCC_DIAG(3,4);
|
|
||||||
extern bool permerror (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
|
|
||||||
extern void sorry (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
|
|
||||||
extern void inform (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
|
|
||||||
extern void inform_n (location_t, int, const char *, const char *, ...)
|
|
||||||
ATTRIBUTE_GCC_DIAG(3,5) ATTRIBUTE_GCC_DIAG(4,5);
|
|
||||||
extern void verbatim (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
|
|
||||||
extern bool emit_diagnostic (diagnostic_t, location_t, int,
|
|
||||||
const char *, ...) ATTRIBUTE_GCC_DIAG(4,5);
|
|
||||||
extern bool seen_error (void);
|
|
||||||
|
|
||||||
#ifdef BUFSIZ
|
|
||||||
/* N.B. Unlike all the others, fnotice is just gettext+fprintf, and
|
|
||||||
therefore it can have ATTRIBUTE_PRINTF. */
|
|
||||||
extern void fnotice (FILE *, const char *, ...)
|
|
||||||
ATTRIBUTE_PRINTF_2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ! GCC_DIAGNOSTIC_CORE_H */
|
|
@ -1,45 +0,0 @@
|
|||||||
/* Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* DK_UNSPECIFIED must be first so it has a value of zero. We never
|
|
||||||
assign this kind to an actual diagnostic, we only use this in
|
|
||||||
variables that can hold a kind, to mean they have yet to have a
|
|
||||||
kind specified. I.e. they're uninitialized. Within the diagnostic
|
|
||||||
machinery, this kind also means "don't change the existing kind",
|
|
||||||
meaning "no change is specified". */
|
|
||||||
DEFINE_DIAGNOSTIC_KIND (DK_UNSPECIFIED, "")
|
|
||||||
|
|
||||||
/* If a diagnostic is set to DK_IGNORED, it won't get reported at all.
|
|
||||||
This is used by the diagnostic machinery when it wants to disable a
|
|
||||||
diagnostic without disabling the option which causes it. */
|
|
||||||
DEFINE_DIAGNOSTIC_KIND (DK_IGNORED, "")
|
|
||||||
|
|
||||||
/* The remainder are real diagnostic types. */
|
|
||||||
DEFINE_DIAGNOSTIC_KIND (DK_FATAL, "fatal error: ")
|
|
||||||
DEFINE_DIAGNOSTIC_KIND (DK_ICE, "internal compiler error: ")
|
|
||||||
DEFINE_DIAGNOSTIC_KIND (DK_ERROR, "error: ")
|
|
||||||
DEFINE_DIAGNOSTIC_KIND (DK_SORRY, "sorry, unimplemented: ")
|
|
||||||
DEFINE_DIAGNOSTIC_KIND (DK_WARNING, "warning: ")
|
|
||||||
DEFINE_DIAGNOSTIC_KIND (DK_ANACHRONISM, "anachronism: ")
|
|
||||||
DEFINE_DIAGNOSTIC_KIND (DK_NOTE, "note: ")
|
|
||||||
DEFINE_DIAGNOSTIC_KIND (DK_DEBUG, "debug: ")
|
|
||||||
/* These two would be re-classified as DK_WARNING or DK_ERROR, so the
|
|
||||||
prefix does not matter. */
|
|
||||||
DEFINE_DIAGNOSTIC_KIND (DK_PEDWARN, "pedwarn: ")
|
|
||||||
DEFINE_DIAGNOSTIC_KIND (DK_PERMERROR, "permerror: ")
|
|
||||||
|
|
@ -1,296 +0,0 @@
|
|||||||
/* Various declarations for language-independent diagnostics subroutines.
|
|
||||||
Copyright (C) 2000-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_DIAGNOSTIC_H
|
|
||||||
#define GCC_DIAGNOSTIC_H
|
|
||||||
|
|
||||||
#include "pretty-print.h"
|
|
||||||
#include "diagnostic-core.h"
|
|
||||||
|
|
||||||
/* A diagnostic is described by the MESSAGE to send, the FILE and LINE of
|
|
||||||
its context and its KIND (ice, error, warning, note, ...) See complete
|
|
||||||
list in diagnostic.def. */
|
|
||||||
typedef struct diagnostic_info
|
|
||||||
{
|
|
||||||
text_info message;
|
|
||||||
location_t location;
|
|
||||||
unsigned int override_column;
|
|
||||||
/* Auxiliary data for client. */
|
|
||||||
void *x_data;
|
|
||||||
/* The kind of diagnostic it is about. */
|
|
||||||
diagnostic_t kind;
|
|
||||||
/* Which OPT_* directly controls this diagnostic. */
|
|
||||||
int option_index;
|
|
||||||
} diagnostic_info;
|
|
||||||
|
|
||||||
/* Each time a diagnostic's classification is changed with a pragma,
|
|
||||||
we record the change and the location of the change in an array of
|
|
||||||
these structs. */
|
|
||||||
typedef struct diagnostic_classification_change_t
|
|
||||||
{
|
|
||||||
location_t location;
|
|
||||||
int option;
|
|
||||||
diagnostic_t kind;
|
|
||||||
} diagnostic_classification_change_t;
|
|
||||||
|
|
||||||
/* Forward declarations. */
|
|
||||||
typedef void (*diagnostic_starter_fn) (diagnostic_context *,
|
|
||||||
diagnostic_info *);
|
|
||||||
typedef diagnostic_starter_fn diagnostic_finalizer_fn;
|
|
||||||
|
|
||||||
/* This data structure bundles altogether any information relevant to
|
|
||||||
the context of a diagnostic message. */
|
|
||||||
struct diagnostic_context
|
|
||||||
{
|
|
||||||
/* Where most of the diagnostic formatting work is done. */
|
|
||||||
pretty_printer *printer;
|
|
||||||
|
|
||||||
/* The number of times we have issued diagnostics. */
|
|
||||||
int diagnostic_count[DK_LAST_DIAGNOSTIC_KIND];
|
|
||||||
|
|
||||||
/* True if we should display the "warnings are being tread as error"
|
|
||||||
message, usually displayed once per compiler run. */
|
|
||||||
bool some_warnings_are_errors;
|
|
||||||
|
|
||||||
/* True if it has been requested that warnings be treated as errors. */
|
|
||||||
bool warning_as_error_requested;
|
|
||||||
|
|
||||||
/* The number of option indexes that can be passed to warning() et
|
|
||||||
al. */
|
|
||||||
int n_opts;
|
|
||||||
|
|
||||||
/* For each option index that can be passed to warning() et al
|
|
||||||
(OPT_* from options.h when using this code with the core GCC
|
|
||||||
options), this array may contain a new kind that the diagnostic
|
|
||||||
should be changed to before reporting, or DK_UNSPECIFIED to leave
|
|
||||||
it as the reported kind, or DK_IGNORED to not report it at
|
|
||||||
all. */
|
|
||||||
diagnostic_t *classify_diagnostic;
|
|
||||||
|
|
||||||
/* History of all changes to the classifications above. This list
|
|
||||||
is stored in location-order, so we can search it, either
|
|
||||||
binary-wise or end-to-front, to find the most recent
|
|
||||||
classification for a given diagnostic, given the location of the
|
|
||||||
diagnostic. */
|
|
||||||
diagnostic_classification_change_t *classification_history;
|
|
||||||
|
|
||||||
/* The size of the above array. */
|
|
||||||
int n_classification_history;
|
|
||||||
|
|
||||||
/* For pragma push/pop. */
|
|
||||||
int *push_list;
|
|
||||||
int n_push;
|
|
||||||
|
|
||||||
/* True if we should print the source line with a caret indicating
|
|
||||||
the location. */
|
|
||||||
bool show_caret;
|
|
||||||
|
|
||||||
/* Maximum width of the source line printed. */
|
|
||||||
int caret_max_width;
|
|
||||||
|
|
||||||
/* True if we should print the command line option which controls
|
|
||||||
each diagnostic, if known. */
|
|
||||||
bool show_option_requested;
|
|
||||||
|
|
||||||
/* True if we should raise a SIGABRT on errors. */
|
|
||||||
bool abort_on_error;
|
|
||||||
|
|
||||||
/* True if we should show the column number on diagnostics. */
|
|
||||||
bool show_column;
|
|
||||||
|
|
||||||
/* True if pedwarns are errors. */
|
|
||||||
bool pedantic_errors;
|
|
||||||
|
|
||||||
/* True if permerrors are warnings. */
|
|
||||||
bool permissive;
|
|
||||||
|
|
||||||
/* The index of the option to associate with turning permerrors into
|
|
||||||
warnings. */
|
|
||||||
int opt_permissive;
|
|
||||||
|
|
||||||
/* True if errors are fatal. */
|
|
||||||
bool fatal_errors;
|
|
||||||
|
|
||||||
/* True if all warnings should be disabled. */
|
|
||||||
bool dc_inhibit_warnings;
|
|
||||||
|
|
||||||
/* True if warnings should be given in system headers. */
|
|
||||||
bool dc_warn_system_headers;
|
|
||||||
|
|
||||||
/* Maximum number of errors to report. */
|
|
||||||
unsigned int max_errors;
|
|
||||||
|
|
||||||
/* This function is called before any message is printed out. It is
|
|
||||||
responsible for preparing message prefix and such. For example, it
|
|
||||||
might say:
|
|
||||||
In file included from "/usr/local/include/curses.h:5:
|
|
||||||
from "/home/gdr/src/nifty_printer.h:56:
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
diagnostic_starter_fn begin_diagnostic;
|
|
||||||
|
|
||||||
/* This function is called after the diagnostic message is printed. */
|
|
||||||
diagnostic_finalizer_fn end_diagnostic;
|
|
||||||
|
|
||||||
/* Client hook to report an internal error. */
|
|
||||||
void (*internal_error) (diagnostic_context *, const char *, va_list *);
|
|
||||||
|
|
||||||
/* Client hook to say whether the option controlling a diagnostic is
|
|
||||||
enabled. Returns nonzero if enabled, zero if disabled. */
|
|
||||||
int (*option_enabled) (int, void *);
|
|
||||||
|
|
||||||
/* Client information to pass as second argument to
|
|
||||||
option_enabled. */
|
|
||||||
void *option_state;
|
|
||||||
|
|
||||||
/* Client hook to return the name of an option that controls a
|
|
||||||
diagnostic. Returns malloced memory. The first diagnostic_t
|
|
||||||
argument is the kind of diagnostic before any reclassification
|
|
||||||
(of warnings as errors, etc.); the second is the kind after any
|
|
||||||
reclassification. May return NULL if no name is to be printed.
|
|
||||||
May be passed 0 as well as the index of a particular option. */
|
|
||||||
char *(*option_name) (diagnostic_context *, int, diagnostic_t, diagnostic_t);
|
|
||||||
|
|
||||||
/* Auxiliary data for client. */
|
|
||||||
void *x_data;
|
|
||||||
|
|
||||||
/* Used to detect that the last caret was printed at the same location. */
|
|
||||||
location_t last_location;
|
|
||||||
|
|
||||||
/* Used to detect when the input file stack has changed since last
|
|
||||||
described. */
|
|
||||||
const struct line_map *last_module;
|
|
||||||
|
|
||||||
int lock;
|
|
||||||
|
|
||||||
bool inhibit_notes_p;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
diagnostic_inhibit_notes (diagnostic_context * context)
|
|
||||||
{
|
|
||||||
context->inhibit_notes_p = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Client supplied function to announce a diagnostic. */
|
|
||||||
#define diagnostic_starter(DC) (DC)->begin_diagnostic
|
|
||||||
|
|
||||||
/* Client supplied function called after a diagnostic message is
|
|
||||||
displayed. */
|
|
||||||
#define diagnostic_finalizer(DC) (DC)->end_diagnostic
|
|
||||||
|
|
||||||
/* Extension hooks for client. */
|
|
||||||
#define diagnostic_context_auxiliary_data(DC) (DC)->x_data
|
|
||||||
#define diagnostic_info_auxiliary_data(DI) (DI)->x_data
|
|
||||||
|
|
||||||
/* Same as pp_format_decoder. Works on 'diagnostic_context *'. */
|
|
||||||
#define diagnostic_format_decoder(DC) ((DC)->printer->format_decoder)
|
|
||||||
|
|
||||||
/* Same as output_prefixing_rule. Works on 'diagnostic_context *'. */
|
|
||||||
#define diagnostic_prefixing_rule(DC) ((DC)->printer->wrapping.rule)
|
|
||||||
|
|
||||||
/* Maximum characters per line in automatic line wrapping mode.
|
|
||||||
Zero means don't wrap lines. */
|
|
||||||
#define diagnostic_line_cutoff(DC) ((DC)->printer->wrapping.line_cutoff)
|
|
||||||
|
|
||||||
#define diagnostic_flush_buffer(DC) pp_base_flush ((DC)->printer)
|
|
||||||
|
|
||||||
/* True if the last module or file in which a diagnostic was reported is
|
|
||||||
different from the current one. */
|
|
||||||
#define diagnostic_last_module_changed(DC, MAP) \
|
|
||||||
((DC)->last_module != MAP)
|
|
||||||
|
|
||||||
/* Remember the current module or file as being the last one in which we
|
|
||||||
report a diagnostic. */
|
|
||||||
#define diagnostic_set_last_module(DC, MAP) \
|
|
||||||
(DC)->last_module = MAP
|
|
||||||
|
|
||||||
/* Raise SIGABRT on any diagnostic of severity DK_ERROR or higher. */
|
|
||||||
#define diagnostic_abort_on_error(DC) \
|
|
||||||
(DC)->abort_on_error = true
|
|
||||||
|
|
||||||
/* This diagnostic_context is used by front-ends that directly output
|
|
||||||
diagnostic messages without going through `error', `warning',
|
|
||||||
and similar functions. */
|
|
||||||
extern diagnostic_context *global_dc;
|
|
||||||
|
|
||||||
/* The total count of a KIND of diagnostics emitted so far. */
|
|
||||||
#define diagnostic_kind_count(DC, DK) (DC)->diagnostic_count[(int) (DK)]
|
|
||||||
|
|
||||||
/* The number of errors that have been issued so far. Ideally, these
|
|
||||||
would take a diagnostic_context as an argument. */
|
|
||||||
#define errorcount diagnostic_kind_count (global_dc, DK_ERROR)
|
|
||||||
/* Similarly, but for warnings. */
|
|
||||||
#define warningcount diagnostic_kind_count (global_dc, DK_WARNING)
|
|
||||||
/* Similarly, but for sorrys. */
|
|
||||||
#define sorrycount diagnostic_kind_count (global_dc, DK_SORRY)
|
|
||||||
|
|
||||||
/* Returns nonzero if warnings should be emitted. */
|
|
||||||
#define diagnostic_report_warnings_p(DC, LOC) \
|
|
||||||
(!(DC)->dc_inhibit_warnings \
|
|
||||||
&& !(in_system_header_at (LOC) && !(DC)->dc_warn_system_headers))
|
|
||||||
|
|
||||||
#define report_diagnostic(D) diagnostic_report_diagnostic (global_dc, D)
|
|
||||||
|
|
||||||
/* Override the column number to be used for reporting a
|
|
||||||
diagnostic. */
|
|
||||||
#define diagnostic_override_column(DI, COL) (DI)->override_column = (COL)
|
|
||||||
|
|
||||||
/* Override the option index to be used for reporting a
|
|
||||||
diagnostic. */
|
|
||||||
#define diagnostic_override_option_index(DI, OPTIDX) \
|
|
||||||
((DI)->option_index = (OPTIDX))
|
|
||||||
|
|
||||||
/* Diagnostic related functions. */
|
|
||||||
extern void diagnostic_initialize (diagnostic_context *, int);
|
|
||||||
extern void diagnostic_finish (diagnostic_context *);
|
|
||||||
extern void diagnostic_report_current_module (diagnostic_context *, location_t);
|
|
||||||
extern void diagnostic_show_locus (diagnostic_context *, const diagnostic_info *);
|
|
||||||
|
|
||||||
/* Force diagnostics controlled by OPTIDX to be kind KIND. */
|
|
||||||
extern diagnostic_t diagnostic_classify_diagnostic (diagnostic_context *,
|
|
||||||
int /* optidx */,
|
|
||||||
diagnostic_t /* kind */,
|
|
||||||
location_t);
|
|
||||||
extern void diagnostic_push_diagnostics (diagnostic_context *, location_t);
|
|
||||||
extern void diagnostic_pop_diagnostics (diagnostic_context *, location_t);
|
|
||||||
extern bool diagnostic_report_diagnostic (diagnostic_context *,
|
|
||||||
diagnostic_info *);
|
|
||||||
#ifdef ATTRIBUTE_GCC_DIAG
|
|
||||||
extern void diagnostic_set_info (diagnostic_info *, const char *, va_list *,
|
|
||||||
location_t, diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0);
|
|
||||||
extern void diagnostic_set_info_translated (diagnostic_info *, const char *,
|
|
||||||
va_list *, location_t,
|
|
||||||
diagnostic_t)
|
|
||||||
ATTRIBUTE_GCC_DIAG(2,0);
|
|
||||||
extern void diagnostic_append_note (diagnostic_context *, location_t,
|
|
||||||
const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
|
|
||||||
#endif
|
|
||||||
extern char *diagnostic_build_prefix (diagnostic_context *, const diagnostic_info *);
|
|
||||||
void default_diagnostic_starter (diagnostic_context *, diagnostic_info *);
|
|
||||||
void default_diagnostic_finalizer (diagnostic_context *, diagnostic_info *);
|
|
||||||
void diagnostic_set_caret_max_width (diagnostic_context *context, int value);
|
|
||||||
|
|
||||||
|
|
||||||
/* Pure text formatting support functions. */
|
|
||||||
extern char *file_name_as_prefix (const char *);
|
|
||||||
|
|
||||||
#endif /* ! GCC_DIAGNOSTIC_H */
|
|
@ -1,457 +0,0 @@
|
|||||||
/* Operations with long integers.
|
|
||||||
Copyright (C) 2006-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 3, or (at your option) any
|
|
||||||
later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef DOUBLE_INT_H
|
|
||||||
#define DOUBLE_INT_H
|
|
||||||
|
|
||||||
/* A large integer is currently represented as a pair of HOST_WIDE_INTs.
|
|
||||||
It therefore represents a number with precision of
|
|
||||||
2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the
|
|
||||||
internal representation will change, if numbers with greater precision
|
|
||||||
are needed, so the users should not rely on it). The representation does
|
|
||||||
not contain any information about signedness of the represented value, so
|
|
||||||
it can be used to represent both signed and unsigned numbers. For
|
|
||||||
operations where the results depend on signedness (division, comparisons),
|
|
||||||
it must be specified separately. For each such operation, there are three
|
|
||||||
versions of the function -- double_int_op, that takes an extra UNS argument
|
|
||||||
giving the signedness of the values, and double_int_sop and double_int_uop
|
|
||||||
that stand for its specializations for signed and unsigned values.
|
|
||||||
|
|
||||||
You may also represent with numbers in smaller precision using double_int.
|
|
||||||
You however need to use double_int_ext (that fills in the bits of the
|
|
||||||
number over the prescribed precision with zeros or with the sign bit) before
|
|
||||||
operations that do not perform arithmetics modulo 2^precision (comparisons,
|
|
||||||
division), and possibly before storing the results, if you want to keep
|
|
||||||
them in some canonical form). In general, the signedness of double_int_ext
|
|
||||||
should match the signedness of the operation.
|
|
||||||
|
|
||||||
??? The components of double_int differ in signedness mostly for
|
|
||||||
historical reasons (they replace an older structure used to represent
|
|
||||||
numbers with precision higher than HOST_WIDE_INT). It might be less
|
|
||||||
confusing to have them both signed or both unsigned. */
|
|
||||||
|
|
||||||
struct double_int
|
|
||||||
{
|
|
||||||
/* Normally, we would define constructors to create instances.
|
|
||||||
Two things prevent us from doing so.
|
|
||||||
First, defining a constructor makes the class non-POD in C++03,
|
|
||||||
and we certainly want double_int to be a POD.
|
|
||||||
Second, the GCC conding conventions prefer explicit conversion,
|
|
||||||
and explicit conversion operators are not available until C++11. */
|
|
||||||
|
|
||||||
static double_int from_uhwi (unsigned HOST_WIDE_INT cst);
|
|
||||||
static double_int from_shwi (HOST_WIDE_INT cst);
|
|
||||||
static double_int from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low);
|
|
||||||
|
|
||||||
/* Construct from a fuffer of length LEN. BUFFER will be read according
|
|
||||||
to byte endianess and word endianess. */
|
|
||||||
static double_int from_buffer (const unsigned char *buffer, int len);
|
|
||||||
|
|
||||||
/* No copy assignment operator or destructor to keep the type a POD. */
|
|
||||||
|
|
||||||
/* There are some special value-creation static member functions. */
|
|
||||||
|
|
||||||
static double_int mask (unsigned prec);
|
|
||||||
static double_int max_value (unsigned int prec, bool uns);
|
|
||||||
static double_int min_value (unsigned int prec, bool uns);
|
|
||||||
|
|
||||||
/* The following functions are mutating operations. */
|
|
||||||
|
|
||||||
double_int &operator ++ (); // prefix
|
|
||||||
double_int &operator -- (); // prefix
|
|
||||||
double_int &operator *= (double_int);
|
|
||||||
double_int &operator += (double_int);
|
|
||||||
double_int &operator -= (double_int);
|
|
||||||
double_int &operator &= (double_int);
|
|
||||||
double_int &operator ^= (double_int);
|
|
||||||
double_int &operator |= (double_int);
|
|
||||||
|
|
||||||
/* The following functions are non-mutating operations. */
|
|
||||||
|
|
||||||
/* Conversion functions. */
|
|
||||||
|
|
||||||
HOST_WIDE_INT to_shwi () const;
|
|
||||||
unsigned HOST_WIDE_INT to_uhwi () const;
|
|
||||||
|
|
||||||
/* Conversion query functions. */
|
|
||||||
|
|
||||||
bool fits_uhwi () const;
|
|
||||||
bool fits_shwi () const;
|
|
||||||
bool fits_hwi (bool uns) const;
|
|
||||||
|
|
||||||
/* Attribute query functions. */
|
|
||||||
|
|
||||||
int trailing_zeros () const;
|
|
||||||
int popcount () const;
|
|
||||||
|
|
||||||
/* Arithmetic query operations. */
|
|
||||||
|
|
||||||
bool multiple_of (double_int, bool, double_int *) const;
|
|
||||||
|
|
||||||
/* Arithmetic operation functions. */
|
|
||||||
|
|
||||||
/* The following operations perform arithmetics modulo 2^precision, so you
|
|
||||||
do not need to call .ext between them, even if you are representing
|
|
||||||
numbers with precision less than HOST_BITS_PER_DOUBLE_INT bits. */
|
|
||||||
|
|
||||||
double_int set_bit (unsigned) const;
|
|
||||||
double_int mul_with_sign (double_int, bool unsigned_p, bool *overflow) const;
|
|
||||||
double_int wide_mul_with_sign (double_int, bool unsigned_p,
|
|
||||||
double_int *higher, bool *overflow) const;
|
|
||||||
double_int add_with_sign (double_int, bool unsigned_p, bool *overflow) const;
|
|
||||||
double_int sub_with_overflow (double_int, bool *overflow) const;
|
|
||||||
double_int neg_with_overflow (bool *overflow) const;
|
|
||||||
|
|
||||||
double_int operator * (double_int) const;
|
|
||||||
double_int operator + (double_int) const;
|
|
||||||
double_int operator - (double_int) const;
|
|
||||||
double_int operator - () const;
|
|
||||||
double_int operator ~ () const;
|
|
||||||
double_int operator & (double_int) const;
|
|
||||||
double_int operator | (double_int) const;
|
|
||||||
double_int operator ^ (double_int) const;
|
|
||||||
double_int and_not (double_int) const;
|
|
||||||
|
|
||||||
double_int lshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const;
|
|
||||||
double_int rshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const;
|
|
||||||
double_int alshift (HOST_WIDE_INT count, unsigned int prec) const;
|
|
||||||
double_int arshift (HOST_WIDE_INT count, unsigned int prec) const;
|
|
||||||
double_int llshift (HOST_WIDE_INT count, unsigned int prec) const;
|
|
||||||
double_int lrshift (HOST_WIDE_INT count, unsigned int prec) const;
|
|
||||||
double_int lrotate (HOST_WIDE_INT count, unsigned int prec) const;
|
|
||||||
double_int rrotate (HOST_WIDE_INT count, unsigned int prec) const;
|
|
||||||
|
|
||||||
/* You must ensure that double_int::ext is called on the operands
|
|
||||||
of the following operations, if the precision of the numbers
|
|
||||||
is less than HOST_BITS_PER_DOUBLE_INT bits. */
|
|
||||||
|
|
||||||
double_int div (double_int, bool, unsigned) const;
|
|
||||||
double_int sdiv (double_int, unsigned) const;
|
|
||||||
double_int udiv (double_int, unsigned) const;
|
|
||||||
double_int mod (double_int, bool, unsigned) const;
|
|
||||||
double_int smod (double_int, unsigned) const;
|
|
||||||
double_int umod (double_int, unsigned) const;
|
|
||||||
double_int divmod_with_overflow (double_int, bool, unsigned,
|
|
||||||
double_int *, bool *) const;
|
|
||||||
double_int divmod (double_int, bool, unsigned, double_int *) const;
|
|
||||||
double_int sdivmod (double_int, unsigned, double_int *) const;
|
|
||||||
double_int udivmod (double_int, unsigned, double_int *) const;
|
|
||||||
|
|
||||||
/* Precision control functions. */
|
|
||||||
|
|
||||||
double_int ext (unsigned prec, bool uns) const;
|
|
||||||
double_int zext (unsigned prec) const;
|
|
||||||
double_int sext (unsigned prec) const;
|
|
||||||
|
|
||||||
/* Comparative functions. */
|
|
||||||
|
|
||||||
bool is_zero () const;
|
|
||||||
bool is_one () const;
|
|
||||||
bool is_minus_one () const;
|
|
||||||
bool is_negative () const;
|
|
||||||
|
|
||||||
int cmp (double_int b, bool uns) const;
|
|
||||||
int ucmp (double_int b) const;
|
|
||||||
int scmp (double_int b) const;
|
|
||||||
|
|
||||||
bool ult (double_int b) const;
|
|
||||||
bool ule (double_int b) const;
|
|
||||||
bool ugt (double_int b) const;
|
|
||||||
bool slt (double_int b) const;
|
|
||||||
bool sle (double_int b) const;
|
|
||||||
bool sgt (double_int b) const;
|
|
||||||
|
|
||||||
double_int max (double_int b, bool uns);
|
|
||||||
double_int smax (double_int b);
|
|
||||||
double_int umax (double_int b);
|
|
||||||
|
|
||||||
double_int min (double_int b, bool uns);
|
|
||||||
double_int smin (double_int b);
|
|
||||||
double_int umin (double_int b);
|
|
||||||
|
|
||||||
bool operator == (double_int cst2) const;
|
|
||||||
bool operator != (double_int cst2) const;
|
|
||||||
|
|
||||||
/* Please migrate away from using these member variables publically. */
|
|
||||||
|
|
||||||
unsigned HOST_WIDE_INT low;
|
|
||||||
HOST_WIDE_INT high;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#define HOST_BITS_PER_DOUBLE_INT (2 * HOST_BITS_PER_WIDE_INT)
|
|
||||||
|
|
||||||
/* Constructors and conversions. */
|
|
||||||
|
|
||||||
/* Constructs double_int from integer CST. The bits over the precision of
|
|
||||||
HOST_WIDE_INT are filled with the sign bit. */
|
|
||||||
|
|
||||||
inline double_int
|
|
||||||
double_int::from_shwi (HOST_WIDE_INT cst)
|
|
||||||
{
|
|
||||||
double_int r;
|
|
||||||
r.low = (unsigned HOST_WIDE_INT) cst;
|
|
||||||
r.high = cst < 0 ? -1 : 0;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Some useful constants. */
|
|
||||||
/* FIXME(crowl): Maybe remove after converting callers?
|
|
||||||
The problem is that a named constant would not be as optimizable,
|
|
||||||
while the functional syntax is more verbose. */
|
|
||||||
|
|
||||||
#define double_int_minus_one (double_int::from_shwi (-1))
|
|
||||||
#define double_int_zero (double_int::from_shwi (0))
|
|
||||||
#define double_int_one (double_int::from_shwi (1))
|
|
||||||
#define double_int_two (double_int::from_shwi (2))
|
|
||||||
#define double_int_ten (double_int::from_shwi (10))
|
|
||||||
|
|
||||||
/* Constructs double_int from unsigned integer CST. The bits over the
|
|
||||||
precision of HOST_WIDE_INT are filled with zeros. */
|
|
||||||
|
|
||||||
inline double_int
|
|
||||||
double_int::from_uhwi (unsigned HOST_WIDE_INT cst)
|
|
||||||
{
|
|
||||||
double_int r;
|
|
||||||
r.low = cst;
|
|
||||||
r.high = 0;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double_int
|
|
||||||
double_int::from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low)
|
|
||||||
{
|
|
||||||
double_int r;
|
|
||||||
r.low = low;
|
|
||||||
r.high = high;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double_int &
|
|
||||||
double_int::operator ++ ()
|
|
||||||
{
|
|
||||||
*this += double_int_one;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double_int &
|
|
||||||
double_int::operator -- ()
|
|
||||||
{
|
|
||||||
*this -= double_int_one;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double_int &
|
|
||||||
double_int::operator *= (double_int b)
|
|
||||||
{
|
|
||||||
*this = *this * b;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double_int &
|
|
||||||
double_int::operator += (double_int b)
|
|
||||||
{
|
|
||||||
*this = *this + b;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double_int &
|
|
||||||
double_int::operator -= (double_int b)
|
|
||||||
{
|
|
||||||
*this = *this - b;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double_int &
|
|
||||||
double_int::operator &= (double_int b)
|
|
||||||
{
|
|
||||||
*this = *this & b;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double_int &
|
|
||||||
double_int::operator ^= (double_int b)
|
|
||||||
{
|
|
||||||
*this = *this ^ b;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double_int &
|
|
||||||
double_int::operator |= (double_int b)
|
|
||||||
{
|
|
||||||
*this = *this | b;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns value of CST as a signed number. CST must satisfy
|
|
||||||
double_int::fits_signed. */
|
|
||||||
|
|
||||||
inline HOST_WIDE_INT
|
|
||||||
double_int::to_shwi () const
|
|
||||||
{
|
|
||||||
return (HOST_WIDE_INT) low;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns value of CST as an unsigned number. CST must satisfy
|
|
||||||
double_int::fits_unsigned. */
|
|
||||||
|
|
||||||
inline unsigned HOST_WIDE_INT
|
|
||||||
double_int::to_uhwi () const
|
|
||||||
{
|
|
||||||
return low;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns true if CST fits in unsigned HOST_WIDE_INT. */
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
double_int::fits_uhwi () const
|
|
||||||
{
|
|
||||||
return high == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Logical operations. */
|
|
||||||
|
|
||||||
/* Returns ~A. */
|
|
||||||
|
|
||||||
inline double_int
|
|
||||||
double_int::operator ~ () const
|
|
||||||
{
|
|
||||||
double_int result;
|
|
||||||
result.low = ~low;
|
|
||||||
result.high = ~high;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns A | B. */
|
|
||||||
|
|
||||||
inline double_int
|
|
||||||
double_int::operator | (double_int b) const
|
|
||||||
{
|
|
||||||
double_int result;
|
|
||||||
result.low = low | b.low;
|
|
||||||
result.high = high | b.high;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns A & B. */
|
|
||||||
|
|
||||||
inline double_int
|
|
||||||
double_int::operator & (double_int b) const
|
|
||||||
{
|
|
||||||
double_int result;
|
|
||||||
result.low = low & b.low;
|
|
||||||
result.high = high & b.high;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns A & ~B. */
|
|
||||||
|
|
||||||
inline double_int
|
|
||||||
double_int::and_not (double_int b) const
|
|
||||||
{
|
|
||||||
double_int result;
|
|
||||||
result.low = low & ~b.low;
|
|
||||||
result.high = high & ~b.high;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns A ^ B. */
|
|
||||||
|
|
||||||
inline double_int
|
|
||||||
double_int::operator ^ (double_int b) const
|
|
||||||
{
|
|
||||||
double_int result;
|
|
||||||
result.low = low ^ b.low;
|
|
||||||
result.high = high ^ b.high;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_double_int (FILE *, double_int, bool);
|
|
||||||
|
|
||||||
#define ALL_ONES (~((unsigned HOST_WIDE_INT) 0))
|
|
||||||
|
|
||||||
/* The operands of the following comparison functions must be processed
|
|
||||||
with double_int_ext, if their precision is less than
|
|
||||||
HOST_BITS_PER_DOUBLE_INT bits. */
|
|
||||||
|
|
||||||
/* Returns true if CST is zero. */
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
double_int::is_zero () const
|
|
||||||
{
|
|
||||||
return low == 0 && high == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns true if CST is one. */
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
double_int::is_one () const
|
|
||||||
{
|
|
||||||
return low == 1 && high == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns true if CST is minus one. */
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
double_int::is_minus_one () const
|
|
||||||
{
|
|
||||||
return low == ALL_ONES && high == -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns true if CST is negative. */
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
double_int::is_negative () const
|
|
||||||
{
|
|
||||||
return high < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns true if CST1 == CST2. */
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
double_int::operator == (double_int cst2) const
|
|
||||||
{
|
|
||||||
return low == cst2.low && high == cst2.high;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns true if CST1 != CST2. */
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
double_int::operator != (double_int cst2) const
|
|
||||||
{
|
|
||||||
return low != cst2.low || high != cst2.high;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return number of set bits of CST. */
|
|
||||||
|
|
||||||
inline int
|
|
||||||
double_int::popcount () const
|
|
||||||
{
|
|
||||||
return popcount_hwi (high) + popcount_hwi (low);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef GENERATOR_FILE
|
|
||||||
/* Conversion to and from GMP integer representations. */
|
|
||||||
|
|
||||||
void mpz_set_double_int (mpz_t, double_int, bool);
|
|
||||||
double_int mpz_get_double_int (const_tree, mpz_t, bool);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* DOUBLE_INT_H */
|
|
@ -1,166 +0,0 @@
|
|||||||
/* Definitions for the shared dumpfile.
|
|
||||||
Copyright (C) 2004-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef GCC_DUMPFILE_H
|
|
||||||
#define GCC_DUMPFILE_H 1
|
|
||||||
|
|
||||||
#include "line-map.h"
|
|
||||||
|
|
||||||
/* Different tree dump places. When you add new tree dump places,
|
|
||||||
extend the DUMP_FILES array in dumpfile.c. */
|
|
||||||
enum tree_dump_index
|
|
||||||
{
|
|
||||||
TDI_none, /* No dump */
|
|
||||||
TDI_cgraph, /* dump function call graph. */
|
|
||||||
TDI_tu, /* dump the whole translation unit. */
|
|
||||||
TDI_class, /* dump class hierarchy. */
|
|
||||||
TDI_original, /* dump each function before optimizing it */
|
|
||||||
TDI_generic, /* dump each function after genericizing it */
|
|
||||||
TDI_nested, /* dump each function after unnesting it */
|
|
||||||
TDI_tree_all, /* enable all the GENERIC/GIMPLE dumps. */
|
|
||||||
TDI_rtl_all, /* enable all the RTL dumps. */
|
|
||||||
TDI_ipa_all, /* enable all the IPA dumps. */
|
|
||||||
|
|
||||||
TDI_end
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Bit masks to control dumping. Not all values are applicable to all
|
|
||||||
dumps. Add new ones at the end. When you define new values, extend
|
|
||||||
the DUMP_OPTIONS array in dumpfile.c. The TDF_* flags coexist with
|
|
||||||
MSG_* flags (for -fopt-info) and the bit values must be chosen to
|
|
||||||
allow that. */
|
|
||||||
#define TDF_ADDRESS (1 << 0) /* dump node addresses */
|
|
||||||
#define TDF_SLIM (1 << 1) /* don't go wild following links */
|
|
||||||
#define TDF_RAW (1 << 2) /* don't unparse the function */
|
|
||||||
#define TDF_DETAILS (1 << 3) /* show more detailed info about
|
|
||||||
each pass */
|
|
||||||
#define TDF_STATS (1 << 4) /* dump various statistics about
|
|
||||||
each pass */
|
|
||||||
#define TDF_BLOCKS (1 << 5) /* display basic block boundaries */
|
|
||||||
#define TDF_VOPS (1 << 6) /* display virtual operands */
|
|
||||||
#define TDF_LINENO (1 << 7) /* display statement line numbers */
|
|
||||||
#define TDF_UID (1 << 8) /* display decl UIDs */
|
|
||||||
|
|
||||||
#define TDF_TREE (1 << 9) /* is a tree dump */
|
|
||||||
#define TDF_RTL (1 << 10) /* is a RTL dump */
|
|
||||||
#define TDF_IPA (1 << 11) /* is an IPA dump */
|
|
||||||
#define TDF_STMTADDR (1 << 12) /* Address of stmt. */
|
|
||||||
|
|
||||||
#define TDF_GRAPH (1 << 13) /* a graph dump is being emitted */
|
|
||||||
#define TDF_MEMSYMS (1 << 14) /* display memory symbols in expr.
|
|
||||||
Implies TDF_VOPS. */
|
|
||||||
|
|
||||||
#define TDF_DIAGNOSTIC (1 << 15) /* A dump to be put in a diagnostic
|
|
||||||
message. */
|
|
||||||
#define TDF_VERBOSE (1 << 16) /* A dump that uses the full tree
|
|
||||||
dumper to print stmts. */
|
|
||||||
#define TDF_RHS_ONLY (1 << 17) /* a flag to only print the RHS of
|
|
||||||
a gimple stmt. */
|
|
||||||
#define TDF_ASMNAME (1 << 18) /* display asm names of decls */
|
|
||||||
#define TDF_EH (1 << 19) /* display EH region number
|
|
||||||
holding this gimple statement. */
|
|
||||||
#define TDF_NOUID (1 << 20) /* omit UIDs from dumps. */
|
|
||||||
#define TDF_ALIAS (1 << 21) /* display alias information */
|
|
||||||
#define TDF_ENUMERATE_LOCALS (1 << 22) /* Enumerate locals by uid. */
|
|
||||||
#define TDF_CSELIB (1 << 23) /* Dump cselib details. */
|
|
||||||
#define TDF_SCEV (1 << 24) /* Dump SCEV details. */
|
|
||||||
#define TDF_COMMENT (1 << 25) /* Dump lines with prefix ";;" */
|
|
||||||
#define MSG_OPTIMIZED_LOCATIONS (1 << 26) /* -fopt-info optimized sources */
|
|
||||||
#define MSG_MISSED_OPTIMIZATION (1 << 27) /* missed opportunities */
|
|
||||||
#define MSG_NOTE (1 << 28) /* general optimization info */
|
|
||||||
#define MSG_ALL (MSG_OPTIMIZED_LOCATIONS | MSG_MISSED_OPTIMIZATION \
|
|
||||||
| MSG_NOTE)
|
|
||||||
|
|
||||||
|
|
||||||
/* Flags to control high-level -fopt-info dumps. Usually these flags
|
|
||||||
define a group of passes. An optimization pass can be part of
|
|
||||||
multiple groups. */
|
|
||||||
#define OPTGROUP_NONE (0)
|
|
||||||
#define OPTGROUP_IPA (1 << 1) /* IPA optimization passes */
|
|
||||||
#define OPTGROUP_LOOP (1 << 2) /* Loop optimization passes */
|
|
||||||
#define OPTGROUP_INLINE (1 << 3) /* Inlining passes */
|
|
||||||
#define OPTGROUP_VEC (1 << 4) /* Vectorization passes */
|
|
||||||
#define OPTGROUP_ALL (OPTGROUP_IPA | OPTGROUP_LOOP | OPTGROUP_INLINE \
|
|
||||||
| OPTGROUP_VEC)
|
|
||||||
|
|
||||||
/* Define a tree dump switch. */
|
|
||||||
struct dump_file_info
|
|
||||||
{
|
|
||||||
const char *suffix; /* suffix to give output file. */
|
|
||||||
const char *swtch; /* command line dump switch */
|
|
||||||
const char *glob; /* command line glob */
|
|
||||||
const char *pfilename; /* filename for the pass-specific stream */
|
|
||||||
const char *alt_filename; /* filename for the -fopt-info stream */
|
|
||||||
FILE *pstream; /* pass-specific dump stream */
|
|
||||||
FILE *alt_stream; /* -fopt-info stream */
|
|
||||||
int pflags; /* dump flags */
|
|
||||||
int optgroup_flags; /* optgroup flags for -fopt-info */
|
|
||||||
int alt_flags; /* flags for opt-info */
|
|
||||||
int pstate; /* state of pass-specific stream */
|
|
||||||
int alt_state; /* state of the -fopt-info stream */
|
|
||||||
int num; /* dump file number */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* In dumpfile.c */
|
|
||||||
extern char *get_dump_file_name (int);
|
|
||||||
extern int dump_initialized_p (int);
|
|
||||||
extern FILE *dump_begin (int, int *);
|
|
||||||
extern void dump_end (int, FILE *);
|
|
||||||
extern int dump_start (int, int *);
|
|
||||||
extern void dump_finish (int);
|
|
||||||
extern void dump_node (const_tree, int, FILE *);
|
|
||||||
extern int dump_switch_p (const char *);
|
|
||||||
extern int opt_info_switch_p (const char *);
|
|
||||||
extern const char *dump_flag_name (int);
|
|
||||||
extern void dump_printf (int, const char *, ...) ATTRIBUTE_PRINTF_2;
|
|
||||||
extern void dump_printf_loc (int, source_location,
|
|
||||||
const char *, ...) ATTRIBUTE_PRINTF_3;
|
|
||||||
extern void dump_basic_block (int, basic_block, int);
|
|
||||||
extern void dump_generic_expr_loc (int, source_location, int, tree);
|
|
||||||
extern void dump_generic_expr (int, int, tree);
|
|
||||||
extern void dump_gimple_stmt_loc (int, source_location, int, gimple, int);
|
|
||||||
extern void dump_gimple_stmt (int, int, gimple, int);
|
|
||||||
extern void print_combine_total_stats (void);
|
|
||||||
extern unsigned int dump_register (const char *, const char *, const char *,
|
|
||||||
int, int);
|
|
||||||
extern bool enable_rtl_dump_file (void);
|
|
||||||
|
|
||||||
/* In combine.c */
|
|
||||||
extern void dump_combine_total_stats (FILE *);
|
|
||||||
/* In cfghooks.c */
|
|
||||||
extern void dump_bb (FILE *, basic_block, int, int);
|
|
||||||
|
|
||||||
/* Global variables used to communicate with passes. */
|
|
||||||
extern FILE *dump_file;
|
|
||||||
extern FILE *alt_dump_file;
|
|
||||||
extern int dump_flags;
|
|
||||||
extern const char *dump_file_name;
|
|
||||||
|
|
||||||
/* Return the dump_file_info for the given phase. */
|
|
||||||
extern struct dump_file_info *get_dump_file_info (int);
|
|
||||||
|
|
||||||
/* Return true if any of the dumps is enabled, false otherwise. */
|
|
||||||
static inline bool
|
|
||||||
dump_enabled_p (void)
|
|
||||||
{
|
|
||||||
return (dump_file || alt_dump_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* GCC_DUMPFILE_H */
|
|
@ -1,119 +0,0 @@
|
|||||||
/* Exported functions from emit-rtl.c
|
|
||||||
Copyright (C) 2004-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_EMIT_RTL_H
|
|
||||||
#define GCC_EMIT_RTL_H
|
|
||||||
|
|
||||||
/* Return whether two MEM_ATTRs are equal. */
|
|
||||||
bool mem_attrs_eq_p (const struct mem_attrs *, const struct mem_attrs *);
|
|
||||||
|
|
||||||
/* Set the alias set of MEM to SET. */
|
|
||||||
extern void set_mem_alias_set (rtx, alias_set_type);
|
|
||||||
|
|
||||||
/* Set the alignment of MEM to ALIGN bits. */
|
|
||||||
extern void set_mem_align (rtx, unsigned int);
|
|
||||||
|
|
||||||
/* Set the address space of MEM to ADDRSPACE. */
|
|
||||||
extern void set_mem_addr_space (rtx, addr_space_t);
|
|
||||||
|
|
||||||
/* Set the expr for MEM to EXPR. */
|
|
||||||
extern void set_mem_expr (rtx, tree);
|
|
||||||
|
|
||||||
/* Set the offset for MEM to OFFSET. */
|
|
||||||
extern void set_mem_offset (rtx, HOST_WIDE_INT);
|
|
||||||
|
|
||||||
/* Clear the offset recorded for MEM. */
|
|
||||||
extern void clear_mem_offset (rtx);
|
|
||||||
|
|
||||||
/* Set the size for MEM to SIZE. */
|
|
||||||
extern void set_mem_size (rtx, HOST_WIDE_INT);
|
|
||||||
|
|
||||||
/* Clear the size recorded for MEM. */
|
|
||||||
extern void clear_mem_size (rtx);
|
|
||||||
|
|
||||||
/* Set the attributes for MEM appropriate for a spill slot. */
|
|
||||||
extern void set_mem_attrs_for_spill (rtx);
|
|
||||||
extern tree get_spill_slot_decl (bool);
|
|
||||||
|
|
||||||
/* Return a memory reference like MEMREF, but with its address changed to
|
|
||||||
ADDR. The caller is asserting that the actual piece of memory pointed
|
|
||||||
to is the same, just the form of the address is being changed, such as
|
|
||||||
by putting something into a register. */
|
|
||||||
extern rtx replace_equiv_address (rtx, rtx);
|
|
||||||
|
|
||||||
/* Likewise, but the reference is not required to be valid. */
|
|
||||||
extern rtx replace_equiv_address_nv (rtx, rtx);
|
|
||||||
|
|
||||||
extern rtx gen_blockage (void);
|
|
||||||
extern rtvec gen_rtvec (int, ...);
|
|
||||||
extern rtx copy_insn_1 (rtx);
|
|
||||||
extern rtx copy_insn (rtx);
|
|
||||||
extern rtx copy_delay_slot_insn (rtx);
|
|
||||||
extern rtx gen_int_mode (HOST_WIDE_INT, enum machine_mode);
|
|
||||||
extern rtx emit_copy_of_insn_after (rtx, rtx);
|
|
||||||
extern void set_reg_attrs_from_value (rtx, rtx);
|
|
||||||
extern void set_reg_attrs_for_parm (rtx, rtx);
|
|
||||||
extern void set_reg_attrs_for_decl_rtl (tree t, rtx x);
|
|
||||||
extern void adjust_reg_mode (rtx, enum machine_mode);
|
|
||||||
extern int mem_expr_equal_p (const_tree, const_tree);
|
|
||||||
|
|
||||||
extern bool need_atomic_barrier_p (enum memmodel, bool);
|
|
||||||
|
|
||||||
/* Return the first insn of the current sequence or current function. */
|
|
||||||
|
|
||||||
static inline rtx
|
|
||||||
get_insns (void)
|
|
||||||
{
|
|
||||||
return crtl->emit.x_first_insn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Specify a new insn as the first in the chain. */
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
set_first_insn (rtx insn)
|
|
||||||
{
|
|
||||||
gcc_checking_assert (!insn || !PREV_INSN (insn));
|
|
||||||
crtl->emit.x_first_insn = insn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the last insn emitted in current sequence or current function. */
|
|
||||||
|
|
||||||
static inline rtx
|
|
||||||
get_last_insn (void)
|
|
||||||
{
|
|
||||||
return crtl->emit.x_last_insn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Specify a new insn as the last in the chain. */
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
set_last_insn (rtx insn)
|
|
||||||
{
|
|
||||||
gcc_checking_assert (!insn || !NEXT_INSN (insn));
|
|
||||||
crtl->emit.x_last_insn = insn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return a number larger than any instruction's uid in this function. */
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
get_max_uid (void)
|
|
||||||
{
|
|
||||||
return crtl->emit.x_cur_insn_uid;
|
|
||||||
}
|
|
||||||
#endif /* GCC_EMIT_RTL_H */
|
|
@ -1,335 +0,0 @@
|
|||||||
/* Exception Handling interface routines.
|
|
||||||
Copyright (C) 1996-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Mike Stump <mrs@cygnus.com>.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* No include guards here, but define an include file marker anyway, so
|
|
||||||
that the compiler can keep track of where this file is included. This
|
|
||||||
is e.g. used to avoid including this file in front-end specific files. */
|
|
||||||
#ifndef GCC_EXCEPT_H
|
|
||||||
# define GCC_EXCEPT_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "hashtab.h"
|
|
||||||
|
|
||||||
struct function;
|
|
||||||
struct eh_region_d;
|
|
||||||
struct pointer_map_t;
|
|
||||||
|
|
||||||
/* The type of an exception region. */
|
|
||||||
enum eh_region_type
|
|
||||||
{
|
|
||||||
/* CLEANUP regions implement e.g. destructors run when exiting a block.
|
|
||||||
They can be generated from both GIMPLE_TRY_FINALLY and GIMPLE_TRY_CATCH
|
|
||||||
nodes. It is expected by the runtime that cleanup regions will *not*
|
|
||||||
resume normal program flow, but will continue propagation of the
|
|
||||||
exception. */
|
|
||||||
ERT_CLEANUP,
|
|
||||||
|
|
||||||
/* TRY regions implement catching an exception. The list of types associated
|
|
||||||
with the attached catch handlers is examined in order by the runtime and
|
|
||||||
control is transferred to the appropriate handler. Note that a NULL type
|
|
||||||
list is a catch-all handler, and that it will catch *all* exceptions
|
|
||||||
including those originating from a different language. */
|
|
||||||
ERT_TRY,
|
|
||||||
|
|
||||||
/* ALLOWED_EXCEPTIONS regions implement exception filtering, e.g. the
|
|
||||||
throw(type-list) specification that can be added to C++ functions.
|
|
||||||
The runtime examines the thrown exception vs the type list, and if
|
|
||||||
the exception does not match, transfers control to the handler. The
|
|
||||||
normal handler for C++ calls __cxa_call_unexpected. */
|
|
||||||
ERT_ALLOWED_EXCEPTIONS,
|
|
||||||
|
|
||||||
/* MUST_NOT_THROW regions prevent all exceptions from propagating. This
|
|
||||||
region type is used in C++ to surround destructors being run inside a
|
|
||||||
CLEANUP region. This differs from an ALLOWED_EXCEPTIONS region with
|
|
||||||
an empty type list in that the runtime is prepared to terminate the
|
|
||||||
program directly. We only generate code for MUST_NOT_THROW regions
|
|
||||||
along control paths that are already handling an exception within the
|
|
||||||
current function. */
|
|
||||||
ERT_MUST_NOT_THROW
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* A landing pad for a given exception region. Any transfer of control
|
|
||||||
from the EH runtime to the function happens at a landing pad. */
|
|
||||||
|
|
||||||
struct GTY(()) eh_landing_pad_d
|
|
||||||
{
|
|
||||||
/* The linked list of all landing pads associated with the region. */
|
|
||||||
struct eh_landing_pad_d *next_lp;
|
|
||||||
|
|
||||||
/* The region with which this landing pad is associated. */
|
|
||||||
struct eh_region_d *region;
|
|
||||||
|
|
||||||
/* At the gimple level, the location to which control will be transferred
|
|
||||||
for this landing pad. There can be both EH and normal edges into the
|
|
||||||
block containing the post-landing-pad label. */
|
|
||||||
tree post_landing_pad;
|
|
||||||
|
|
||||||
/* At the rtl level, the location to which the runtime will transfer
|
|
||||||
control. This differs from the post-landing-pad in that the target's
|
|
||||||
EXCEPTION_RECEIVER pattern will be expanded here, as well as other
|
|
||||||
bookkeeping specific to exceptions. There must not be normal edges
|
|
||||||
into the block containing the landing-pad label. */
|
|
||||||
rtx landing_pad;
|
|
||||||
|
|
||||||
/* The index of this landing pad within fun->eh->lp_array. */
|
|
||||||
int index;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* A catch handler associated with an ERT_TRY region. */
|
|
||||||
|
|
||||||
struct GTY(()) eh_catch_d
|
|
||||||
{
|
|
||||||
/* The double-linked list of all catch handlers for the region. */
|
|
||||||
struct eh_catch_d *next_catch;
|
|
||||||
struct eh_catch_d *prev_catch;
|
|
||||||
|
|
||||||
/* A TREE_LIST of runtime type objects that this catch handler
|
|
||||||
will catch, or NULL if all exceptions are caught. */
|
|
||||||
tree type_list;
|
|
||||||
|
|
||||||
/* A TREE_LIST of INTEGER_CSTs that correspond to the type_list entries,
|
|
||||||
having been mapped by assign_filter_values. These integers are to be
|
|
||||||
compared against the __builtin_eh_filter value. */
|
|
||||||
tree filter_list;
|
|
||||||
|
|
||||||
/* The code that should be executed if this catch handler matches the
|
|
||||||
thrown exception. This label is only maintained until
|
|
||||||
pass_lower_eh_dispatch, at which point it is cleared. */
|
|
||||||
tree label;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Describes one exception region. */
|
|
||||||
|
|
||||||
struct GTY(()) eh_region_d
|
|
||||||
{
|
|
||||||
/* The immediately surrounding region. */
|
|
||||||
struct eh_region_d *outer;
|
|
||||||
|
|
||||||
/* The list of immediately contained regions. */
|
|
||||||
struct eh_region_d *inner;
|
|
||||||
struct eh_region_d *next_peer;
|
|
||||||
|
|
||||||
/* The index of this region within fun->eh->region_array. */
|
|
||||||
int index;
|
|
||||||
|
|
||||||
/* Each region does exactly one thing. */
|
|
||||||
enum eh_region_type type;
|
|
||||||
|
|
||||||
/* Holds the action to perform based on the preceding type. */
|
|
||||||
union eh_region_u {
|
|
||||||
struct eh_region_u_try {
|
|
||||||
/* The double-linked list of all catch handlers for this region. */
|
|
||||||
struct eh_catch_d *first_catch;
|
|
||||||
struct eh_catch_d *last_catch;
|
|
||||||
} GTY ((tag ("ERT_TRY"))) eh_try;
|
|
||||||
|
|
||||||
struct eh_region_u_allowed {
|
|
||||||
/* A TREE_LIST of runtime type objects allowed to pass. */
|
|
||||||
tree type_list;
|
|
||||||
/* The code that should be executed if the thrown exception does
|
|
||||||
not match the type list. This label is only maintained until
|
|
||||||
pass_lower_eh_dispatch, at which point it is cleared. */
|
|
||||||
tree label;
|
|
||||||
/* The integer that will be passed by the runtime to signal that
|
|
||||||
we should execute the code at LABEL. This integer is assigned
|
|
||||||
by assign_filter_values and is to be compared against the
|
|
||||||
__builtin_eh_filter value. */
|
|
||||||
int filter;
|
|
||||||
} GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;
|
|
||||||
|
|
||||||
struct eh_region_u_must_not_throw {
|
|
||||||
/* A function decl to be invoked if this region is actually reachable
|
|
||||||
from within the function, rather than implementable from the runtime.
|
|
||||||
The normal way for this to happen is for there to be a CLEANUP region
|
|
||||||
contained within this MUST_NOT_THROW region. Note that if the
|
|
||||||
runtime handles the MUST_NOT_THROW region, we have no control over
|
|
||||||
what termination function is called; it will be decided by the
|
|
||||||
personality function in effect for this CIE. */
|
|
||||||
tree failure_decl;
|
|
||||||
/* The location assigned to the call of FAILURE_DECL, if expanded. */
|
|
||||||
location_t failure_loc;
|
|
||||||
} GTY ((tag ("ERT_MUST_NOT_THROW"))) must_not_throw;
|
|
||||||
} GTY ((desc ("%0.type"))) u;
|
|
||||||
|
|
||||||
/* The list of landing pads associated with this region. */
|
|
||||||
struct eh_landing_pad_d *landing_pads;
|
|
||||||
|
|
||||||
/* EXC_PTR and FILTER values copied from the runtime for this region.
|
|
||||||
Each region gets its own psuedos so that if there are nested exceptions
|
|
||||||
we do not overwrite the values of the first exception. */
|
|
||||||
rtx exc_ptr_reg, filter_reg;
|
|
||||||
|
|
||||||
/* True if this region should use __cxa_end_cleanup instead
|
|
||||||
of _Unwind_Resume. */
|
|
||||||
bool use_cxa_end_cleanup;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct eh_landing_pad_d *eh_landing_pad;
|
|
||||||
typedef struct eh_catch_d *eh_catch;
|
|
||||||
typedef struct eh_region_d *eh_region;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* The exception status for each function. */
|
|
||||||
|
|
||||||
struct GTY(()) eh_status
|
|
||||||
{
|
|
||||||
/* The tree of all regions for this function. */
|
|
||||||
eh_region region_tree;
|
|
||||||
|
|
||||||
/* The same information as an indexable array. */
|
|
||||||
vec<eh_region, va_gc> *region_array;
|
|
||||||
|
|
||||||
/* The landing pads as an indexable array. */
|
|
||||||
vec<eh_landing_pad, va_gc> *lp_array;
|
|
||||||
|
|
||||||
/* At the gimple level, a mapping from gimple statement to landing pad
|
|
||||||
or must-not-throw region. See record_stmt_eh_region. */
|
|
||||||
htab_t GTY((param_is (struct throw_stmt_node))) throw_stmt_table;
|
|
||||||
|
|
||||||
/* All of the runtime type data used by the function. These objects
|
|
||||||
are emitted to the lang-specific-data-area for the function. */
|
|
||||||
vec<tree, va_gc> *ttype_data;
|
|
||||||
|
|
||||||
/* The table of all action chains. These encode the eh_region tree in
|
|
||||||
a compact form for use by the runtime, and is also emitted to the
|
|
||||||
lang-specific-data-area. Note that the ARM EABI uses a different
|
|
||||||
format for the encoding than all other ports. */
|
|
||||||
union eh_status_u {
|
|
||||||
vec<tree, va_gc> *GTY((tag ("1"))) arm_eabi;
|
|
||||||
vec<uchar, va_gc> *GTY((tag ("0"))) other;
|
|
||||||
} GTY ((desc ("targetm.arm_eabi_unwinder"))) ehspec_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Invokes CALLBACK for every exception handler label. Only used by old
|
|
||||||
loop hackery; should not be used by new code. */
|
|
||||||
extern void for_each_eh_label (void (*) (rtx));
|
|
||||||
|
|
||||||
extern void init_eh_for_function (void);
|
|
||||||
|
|
||||||
extern void remove_eh_landing_pad (eh_landing_pad);
|
|
||||||
extern void remove_eh_handler (eh_region);
|
|
||||||
extern void remove_unreachable_eh_regions (sbitmap);
|
|
||||||
|
|
||||||
extern bool current_function_has_exception_handlers (void);
|
|
||||||
extern void output_function_exception_table (const char *);
|
|
||||||
|
|
||||||
extern rtx expand_builtin_eh_pointer (tree);
|
|
||||||
extern rtx expand_builtin_eh_filter (tree);
|
|
||||||
extern rtx expand_builtin_eh_copy_values (tree);
|
|
||||||
extern void expand_builtin_unwind_init (void);
|
|
||||||
extern rtx expand_builtin_eh_return_data_regno (tree);
|
|
||||||
extern rtx expand_builtin_extract_return_addr (tree);
|
|
||||||
extern void expand_builtin_init_dwarf_reg_sizes (tree);
|
|
||||||
extern rtx expand_builtin_frob_return_addr (tree);
|
|
||||||
extern rtx expand_builtin_dwarf_sp_column (void);
|
|
||||||
extern void expand_builtin_eh_return (tree, tree);
|
|
||||||
extern void expand_eh_return (void);
|
|
||||||
extern rtx expand_builtin_extend_pointer (tree);
|
|
||||||
extern void expand_dw2_landing_pad_for_region (eh_region);
|
|
||||||
|
|
||||||
typedef tree (*duplicate_eh_regions_map) (tree, void *);
|
|
||||||
extern struct pointer_map_t *duplicate_eh_regions
|
|
||||||
(struct function *, eh_region, int, duplicate_eh_regions_map, void *);
|
|
||||||
|
|
||||||
extern void sjlj_emit_function_exit_after (rtx);
|
|
||||||
|
|
||||||
extern eh_region gen_eh_region_cleanup (eh_region);
|
|
||||||
extern eh_region gen_eh_region_try (eh_region);
|
|
||||||
extern eh_region gen_eh_region_allowed (eh_region, tree);
|
|
||||||
extern eh_region gen_eh_region_must_not_throw (eh_region);
|
|
||||||
|
|
||||||
extern eh_catch gen_eh_region_catch (eh_region, tree);
|
|
||||||
extern eh_landing_pad gen_eh_landing_pad (eh_region);
|
|
||||||
|
|
||||||
extern eh_region get_eh_region_from_number_fn (struct function *, int);
|
|
||||||
extern eh_region get_eh_region_from_number (int);
|
|
||||||
extern eh_landing_pad get_eh_landing_pad_from_number_fn (struct function*,int);
|
|
||||||
extern eh_landing_pad get_eh_landing_pad_from_number (int);
|
|
||||||
extern eh_region get_eh_region_from_lp_number_fn (struct function *, int);
|
|
||||||
extern eh_region get_eh_region_from_lp_number (int);
|
|
||||||
|
|
||||||
extern eh_region eh_region_outermost (struct function *, eh_region, eh_region);
|
|
||||||
|
|
||||||
extern void make_reg_eh_region_note (rtx insn, int ecf_flags, int lp_nr);
|
|
||||||
extern void make_reg_eh_region_note_nothrow_nononlocal (rtx);
|
|
||||||
|
|
||||||
extern void verify_eh_tree (struct function *);
|
|
||||||
extern void dump_eh_tree (FILE *, struct function *);
|
|
||||||
void debug_eh_tree (struct function *);
|
|
||||||
extern void add_type_for_runtime (tree);
|
|
||||||
extern tree lookup_type_for_runtime (tree);
|
|
||||||
extern void assign_filter_values (void);
|
|
||||||
|
|
||||||
extern eh_region get_eh_region_from_rtx (const_rtx);
|
|
||||||
extern eh_landing_pad get_eh_landing_pad_from_rtx (const_rtx);
|
|
||||||
|
|
||||||
extern void finish_eh_generation (void);
|
|
||||||
|
|
||||||
struct GTY(()) throw_stmt_node {
|
|
||||||
gimple stmt;
|
|
||||||
int lp_nr;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct htab *get_eh_throw_stmt_table (struct function *);
|
|
||||||
extern void set_eh_throw_stmt_table (struct function *, struct htab *);
|
|
||||||
|
|
||||||
enum eh_personality_kind {
|
|
||||||
eh_personality_none,
|
|
||||||
eh_personality_any,
|
|
||||||
eh_personality_lang
|
|
||||||
};
|
|
||||||
|
|
||||||
extern enum eh_personality_kind
|
|
||||||
function_needs_eh_personality (struct function *);
|
|
||||||
|
|
||||||
/* Pre-order iteration within the eh_region tree. */
|
|
||||||
|
|
||||||
static inline eh_region
|
|
||||||
ehr_next (eh_region r, eh_region start)
|
|
||||||
{
|
|
||||||
if (r->inner)
|
|
||||||
r = r->inner;
|
|
||||||
else if (r->next_peer && r != start)
|
|
||||||
r = r->next_peer;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
r = r->outer;
|
|
||||||
if (r == start)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
while (r->next_peer == NULL);
|
|
||||||
r = r->next_peer;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FOR_ALL_EH_REGION_AT(R, START) \
|
|
||||||
for ((R) = (START); (R) != NULL; (R) = ehr_next (R, START))
|
|
||||||
|
|
||||||
#define FOR_ALL_EH_REGION_FN(R, FN) \
|
|
||||||
for ((R) = (FN)->eh->region_tree; (R) != NULL; (R) = ehr_next (R, NULL))
|
|
||||||
|
|
||||||
#define FOR_ALL_EH_REGION(R) FOR_ALL_EH_REGION_FN (R, cfun)
|
|
@ -1,97 +0,0 @@
|
|||||||
/* Macros for taking apart, interpreting and processing file names.
|
|
||||||
|
|
||||||
These are here because some non-Posix (a.k.a. DOSish) systems have
|
|
||||||
drive letter brain-damage at the beginning of an absolute file name,
|
|
||||||
use forward- and back-slash in path names interchangeably, and
|
|
||||||
some of them have case-insensitive file names.
|
|
||||||
|
|
||||||
Copyright 2000, 2001, 2007, 2010 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of BFD, the Binary File Descriptor library.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
|
||||||
|
|
||||||
#ifndef FILENAMES_H
|
|
||||||
#define FILENAMES_H
|
|
||||||
|
|
||||||
#include "hashtab.h" /* for hashval_t */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__)
|
|
||||||
# ifndef HAVE_DOS_BASED_FILE_SYSTEM
|
|
||||||
# define HAVE_DOS_BASED_FILE_SYSTEM 1
|
|
||||||
# endif
|
|
||||||
# ifndef HAVE_CASE_INSENSITIVE_FILE_SYSTEM
|
|
||||||
# define HAVE_CASE_INSENSITIVE_FILE_SYSTEM 1
|
|
||||||
# endif
|
|
||||||
# define HAS_DRIVE_SPEC(f) HAS_DOS_DRIVE_SPEC (f)
|
|
||||||
# define IS_DIR_SEPARATOR(c) IS_DOS_DIR_SEPARATOR (c)
|
|
||||||
# define IS_ABSOLUTE_PATH(f) IS_DOS_ABSOLUTE_PATH (f)
|
|
||||||
#else /* not DOSish */
|
|
||||||
# if defined(__APPLE__)
|
|
||||||
# ifndef HAVE_CASE_INSENSITIVE_FILE_SYSTEM
|
|
||||||
# define HAVE_CASE_INSENSITIVE_FILE_SYSTEM 1
|
|
||||||
# endif
|
|
||||||
# endif /* __APPLE__ */
|
|
||||||
# define HAS_DRIVE_SPEC(f) (0)
|
|
||||||
# define IS_DIR_SEPARATOR(c) IS_UNIX_DIR_SEPARATOR (c)
|
|
||||||
# define IS_ABSOLUTE_PATH(f) IS_UNIX_ABSOLUTE_PATH (f)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define IS_DIR_SEPARATOR_1(dos_based, c) \
|
|
||||||
(((c) == '/') \
|
|
||||||
|| (((c) == '\\') && (dos_based)))
|
|
||||||
|
|
||||||
#define HAS_DRIVE_SPEC_1(dos_based, f) \
|
|
||||||
((f)[0] && ((f)[1] == ':') && (dos_based))
|
|
||||||
|
|
||||||
/* Remove the drive spec from F, assuming HAS_DRIVE_SPEC (f).
|
|
||||||
The result is a pointer to the remainder of F. */
|
|
||||||
#define STRIP_DRIVE_SPEC(f) ((f) + 2)
|
|
||||||
|
|
||||||
#define IS_DOS_DIR_SEPARATOR(c) IS_DIR_SEPARATOR_1 (1, c)
|
|
||||||
#define IS_DOS_ABSOLUTE_PATH(f) IS_ABSOLUTE_PATH_1 (1, f)
|
|
||||||
#define HAS_DOS_DRIVE_SPEC(f) HAS_DRIVE_SPEC_1 (1, f)
|
|
||||||
|
|
||||||
#define IS_UNIX_DIR_SEPARATOR(c) IS_DIR_SEPARATOR_1 (0, c)
|
|
||||||
#define IS_UNIX_ABSOLUTE_PATH(f) IS_ABSOLUTE_PATH_1 (0, f)
|
|
||||||
|
|
||||||
/* Note that when DOS_BASED is true, IS_ABSOLUTE_PATH accepts d:foo as
|
|
||||||
well, although it is only semi-absolute. This is because the users
|
|
||||||
of IS_ABSOLUTE_PATH want to know whether to prepend the current
|
|
||||||
working directory to a file name, which should not be done with a
|
|
||||||
name like d:foo. */
|
|
||||||
#define IS_ABSOLUTE_PATH_1(dos_based, f) \
|
|
||||||
(IS_DIR_SEPARATOR_1 (dos_based, (f)[0]) \
|
|
||||||
|| HAS_DRIVE_SPEC_1 (dos_based, f))
|
|
||||||
|
|
||||||
extern int filename_cmp (const char *s1, const char *s2);
|
|
||||||
#define FILENAME_CMP(s1, s2) filename_cmp(s1, s2)
|
|
||||||
|
|
||||||
extern int filename_ncmp (const char *s1, const char *s2,
|
|
||||||
size_t n);
|
|
||||||
|
|
||||||
extern hashval_t filename_hash (const void *s);
|
|
||||||
|
|
||||||
extern int filename_eq (const void *s1, const void *s2);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* FILENAMES_H */
|
|
@ -1,116 +0,0 @@
|
|||||||
/* Fixed-point arithmetic support.
|
|
||||||
Copyright (C) 2006-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_FIXED_VALUE_H
|
|
||||||
#define GCC_FIXED_VALUE_H
|
|
||||||
|
|
||||||
#include "machmode.h"
|
|
||||||
#include "real.h"
|
|
||||||
#include "double-int.h"
|
|
||||||
|
|
||||||
struct GTY(()) fixed_value
|
|
||||||
{
|
|
||||||
double_int data; /* Store data up to 2 wide integers. */
|
|
||||||
enum machine_mode mode; /* Use machine mode to know IBIT and FBIT. */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define FIXED_VALUE_TYPE struct fixed_value
|
|
||||||
|
|
||||||
#define MAX_FCONST0 18 /* For storing 18 fixed-point zeros per
|
|
||||||
fract, ufract, accum, and uaccum modes . */
|
|
||||||
#define MAX_FCONST1 8 /* For storing 8 fixed-point ones per accum
|
|
||||||
and uaccum modes. */
|
|
||||||
/* Constant fixed-point values 0 and 1. */
|
|
||||||
extern FIXED_VALUE_TYPE fconst0[MAX_FCONST0];
|
|
||||||
extern FIXED_VALUE_TYPE fconst1[MAX_FCONST1];
|
|
||||||
|
|
||||||
/* Macros to access fconst0 and fconst1 via machine modes. */
|
|
||||||
#define FCONST0(mode) fconst0[mode - QQmode]
|
|
||||||
#define FCONST1(mode) fconst1[mode - HAmode]
|
|
||||||
|
|
||||||
/* Return a CONST_FIXED with value R and mode M. */
|
|
||||||
#define CONST_FIXED_FROM_FIXED_VALUE(r, m) \
|
|
||||||
const_fixed_from_fixed_value (r, m)
|
|
||||||
extern rtx const_fixed_from_fixed_value (FIXED_VALUE_TYPE, enum machine_mode);
|
|
||||||
|
|
||||||
/* Construct a FIXED_VALUE from a bit payload and machine mode MODE.
|
|
||||||
The bits in PAYLOAD are sign-extended/zero-extended according to MODE. */
|
|
||||||
extern FIXED_VALUE_TYPE fixed_from_double_int (double_int,
|
|
||||||
enum machine_mode);
|
|
||||||
|
|
||||||
/* Return a CONST_FIXED from a bit payload and machine mode MODE.
|
|
||||||
The bits in PAYLOAD are sign-extended/zero-extended according to MODE. */
|
|
||||||
static inline rtx
|
|
||||||
const_fixed_from_double_int (double_int payload,
|
|
||||||
enum machine_mode mode)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
const_fixed_from_fixed_value (fixed_from_double_int (payload, mode),
|
|
||||||
mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize from a decimal or hexadecimal string. */
|
|
||||||
extern void fixed_from_string (FIXED_VALUE_TYPE *, const char *,
|
|
||||||
enum machine_mode);
|
|
||||||
|
|
||||||
/* In tree.c: wrap up a FIXED_VALUE_TYPE in a tree node. */
|
|
||||||
extern tree build_fixed (tree, FIXED_VALUE_TYPE);
|
|
||||||
|
|
||||||
/* Extend or truncate to a new mode. */
|
|
||||||
extern bool fixed_convert (FIXED_VALUE_TYPE *, enum machine_mode,
|
|
||||||
const FIXED_VALUE_TYPE *, bool);
|
|
||||||
|
|
||||||
/* Convert to a fixed-point mode from an integer. */
|
|
||||||
extern bool fixed_convert_from_int (FIXED_VALUE_TYPE *, enum machine_mode,
|
|
||||||
double_int, bool, bool);
|
|
||||||
|
|
||||||
/* Convert to a fixed-point mode from a real. */
|
|
||||||
extern bool fixed_convert_from_real (FIXED_VALUE_TYPE *, enum machine_mode,
|
|
||||||
const REAL_VALUE_TYPE *, bool);
|
|
||||||
|
|
||||||
/* Convert to a real mode from a fixed-point. */
|
|
||||||
extern void real_convert_from_fixed (REAL_VALUE_TYPE *, enum machine_mode,
|
|
||||||
const FIXED_VALUE_TYPE *);
|
|
||||||
|
|
||||||
/* Compare two fixed-point objects for bitwise identity. */
|
|
||||||
extern bool fixed_identical (const FIXED_VALUE_TYPE *, const FIXED_VALUE_TYPE *);
|
|
||||||
|
|
||||||
/* Calculate a hash value. */
|
|
||||||
extern unsigned int fixed_hash (const FIXED_VALUE_TYPE *);
|
|
||||||
|
|
||||||
#define FIXED_VALUES_IDENTICAL(x, y) fixed_identical (&(x), &(y))
|
|
||||||
|
|
||||||
/* Determine whether a fixed-point value X is negative. */
|
|
||||||
#define FIXED_VALUE_NEGATIVE(x) fixed_isneg (&(x))
|
|
||||||
|
|
||||||
/* Render F as a decimal floating point constant. */
|
|
||||||
extern void fixed_to_decimal (char *str, const FIXED_VALUE_TYPE *, size_t);
|
|
||||||
|
|
||||||
/* Binary or unary arithmetic on tree_code. */
|
|
||||||
extern bool fixed_arithmetic (FIXED_VALUE_TYPE *, int, const FIXED_VALUE_TYPE *,
|
|
||||||
const FIXED_VALUE_TYPE *, bool);
|
|
||||||
|
|
||||||
/* Compare fixed-point values by tree_code. */
|
|
||||||
extern bool fixed_compare (int, const FIXED_VALUE_TYPE *,
|
|
||||||
const FIXED_VALUE_TYPE *);
|
|
||||||
|
|
||||||
/* Determine whether a fixed-point value X is negative. */
|
|
||||||
extern bool fixed_isneg (const FIXED_VALUE_TYPE *);
|
|
||||||
|
|
||||||
#endif /* GCC_FIXED_VALUE_H */
|
|
@ -1,194 +0,0 @@
|
|||||||
/* Compilation switch flag type definitions for GCC.
|
|
||||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_FLAG_TYPES_H
|
|
||||||
#define GCC_FLAG_TYPES_H
|
|
||||||
|
|
||||||
enum debug_info_type
|
|
||||||
{
|
|
||||||
NO_DEBUG, /* Write no debug info. */
|
|
||||||
DBX_DEBUG, /* Write BSD .stabs for DBX (using dbxout.c). */
|
|
||||||
SDB_DEBUG, /* Write COFF for (old) SDB (using sdbout.c). */
|
|
||||||
DWARF2_DEBUG, /* Write Dwarf v2 debug info (using dwarf2out.c). */
|
|
||||||
XCOFF_DEBUG, /* Write IBM/Xcoff debug info (using dbxout.c). */
|
|
||||||
VMS_DEBUG, /* Write VMS debug info (using vmsdbgout.c). */
|
|
||||||
VMS_AND_DWARF2_DEBUG /* Write VMS debug info (using vmsdbgout.c).
|
|
||||||
and DWARF v2 debug info (using dwarf2out.c). */
|
|
||||||
};
|
|
||||||
|
|
||||||
enum debug_info_levels
|
|
||||||
{
|
|
||||||
DINFO_LEVEL_NONE, /* Write no debugging info. */
|
|
||||||
DINFO_LEVEL_TERSE, /* Write minimal info to support tracebacks only. */
|
|
||||||
DINFO_LEVEL_NORMAL, /* Write info for all declarations (and line table). */
|
|
||||||
DINFO_LEVEL_VERBOSE /* Write normal info plus #define/#undef info. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* A major contribution to object and executable size is debug
|
|
||||||
information size. A major contribution to debug information
|
|
||||||
size is struct descriptions replicated in several object files.
|
|
||||||
The following function determines whether or not debug information
|
|
||||||
should be generated for a given struct. The indirect parameter
|
|
||||||
indicates that the struct is being handled indirectly, via
|
|
||||||
a pointer. See opts.c for the implementation. */
|
|
||||||
|
|
||||||
enum debug_info_usage
|
|
||||||
{
|
|
||||||
DINFO_USAGE_DFN, /* A struct definition. */
|
|
||||||
DINFO_USAGE_DIR_USE, /* A direct use, such as the type of a variable. */
|
|
||||||
DINFO_USAGE_IND_USE, /* An indirect use, such as through a pointer. */
|
|
||||||
DINFO_USAGE_NUM_ENUMS /* The number of enumerators. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* A major contribution to object and executable size is debug
|
|
||||||
information size. A major contribution to debug information size
|
|
||||||
is struct descriptions replicated in several object files. The
|
|
||||||
following flags attempt to reduce this information. The basic
|
|
||||||
idea is to not emit struct debugging information in the current
|
|
||||||
compilation unit when that information will be generated by
|
|
||||||
another compilation unit.
|
|
||||||
|
|
||||||
Debug information for a struct defined in the current source
|
|
||||||
file should be generated in the object file. Likewise the
|
|
||||||
debug information for a struct defined in a header should be
|
|
||||||
generated in the object file of the corresponding source file.
|
|
||||||
Both of these case are handled when the base name of the file of
|
|
||||||
the struct definition matches the base name of the source file
|
|
||||||
of the current compilation unit. This matching emits minimal
|
|
||||||
struct debugging information.
|
|
||||||
|
|
||||||
The base file name matching rule above will fail to emit debug
|
|
||||||
information for structs defined in system headers. So a second
|
|
||||||
category of files includes system headers in addition to files
|
|
||||||
with matching bases.
|
|
||||||
|
|
||||||
The remaining types of files are library headers and application
|
|
||||||
headers. We cannot currently distinguish these two types. */
|
|
||||||
|
|
||||||
enum debug_struct_file
|
|
||||||
{
|
|
||||||
DINFO_STRUCT_FILE_NONE, /* Debug no structs. */
|
|
||||||
DINFO_STRUCT_FILE_BASE, /* Debug structs defined in files with the
|
|
||||||
same base name as the compilation unit. */
|
|
||||||
DINFO_STRUCT_FILE_SYS, /* Also debug structs defined in system
|
|
||||||
header files. */
|
|
||||||
DINFO_STRUCT_FILE_ANY /* Debug structs defined in all files. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Enumerate visibility settings. This is deliberately ordered from most
|
|
||||||
to least visibility. */
|
|
||||||
#ifndef SYMBOL_VISIBILITY_DEFINED
|
|
||||||
#define SYMBOL_VISIBILITY_DEFINED
|
|
||||||
enum symbol_visibility
|
|
||||||
{
|
|
||||||
VISIBILITY_DEFAULT,
|
|
||||||
VISIBILITY_PROTECTED,
|
|
||||||
VISIBILITY_HIDDEN,
|
|
||||||
VISIBILITY_INTERNAL
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The stack reuse level. */
|
|
||||||
enum stack_reuse_level
|
|
||||||
{
|
|
||||||
SR_NONE,
|
|
||||||
SR_NAMED_VARS,
|
|
||||||
SR_ALL
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The algorithm used for the integrated register allocator (IRA). */
|
|
||||||
enum ira_algorithm
|
|
||||||
{
|
|
||||||
IRA_ALGORITHM_CB,
|
|
||||||
IRA_ALGORITHM_PRIORITY
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The regions used for the integrated register allocator (IRA). */
|
|
||||||
enum ira_region
|
|
||||||
{
|
|
||||||
IRA_REGION_ONE,
|
|
||||||
IRA_REGION_ALL,
|
|
||||||
IRA_REGION_MIXED,
|
|
||||||
/* This value means that there were no options -fira-region on the
|
|
||||||
command line and that we should choose a value depending on the
|
|
||||||
used -O option. */
|
|
||||||
IRA_REGION_AUTODETECT
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The options for excess precision. */
|
|
||||||
enum excess_precision
|
|
||||||
{
|
|
||||||
EXCESS_PRECISION_DEFAULT,
|
|
||||||
EXCESS_PRECISION_FAST,
|
|
||||||
EXCESS_PRECISION_STANDARD
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Type of stack check. */
|
|
||||||
enum stack_check_type
|
|
||||||
{
|
|
||||||
/* Do not check the stack. */
|
|
||||||
NO_STACK_CHECK = 0,
|
|
||||||
|
|
||||||
/* Check the stack generically, i.e. assume no specific support
|
|
||||||
from the target configuration files. */
|
|
||||||
GENERIC_STACK_CHECK,
|
|
||||||
|
|
||||||
/* Check the stack and rely on the target configuration files to
|
|
||||||
check the static frame of functions, i.e. use the generic
|
|
||||||
mechanism only for dynamic stack allocations. */
|
|
||||||
STATIC_BUILTIN_STACK_CHECK,
|
|
||||||
|
|
||||||
/* Check the stack and entirely rely on the target configuration
|
|
||||||
files, i.e. do not use the generic mechanism at all. */
|
|
||||||
FULL_BUILTIN_STACK_CHECK
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Names for the different levels of -Wstrict-overflow=N. The numeric
|
|
||||||
values here correspond to N. */
|
|
||||||
|
|
||||||
enum warn_strict_overflow_code
|
|
||||||
{
|
|
||||||
/* Overflow warning that should be issued with -Wall: a questionable
|
|
||||||
construct that is easy to avoid even when using macros. Example:
|
|
||||||
folding (x + CONSTANT > x) to 1. */
|
|
||||||
WARN_STRICT_OVERFLOW_ALL = 1,
|
|
||||||
/* Overflow warning about folding a comparison to a constant because
|
|
||||||
of undefined signed overflow, other than cases covered by
|
|
||||||
WARN_STRICT_OVERFLOW_ALL. Example: folding (abs (x) >= 0) to 1
|
|
||||||
(this is false when x == INT_MIN). */
|
|
||||||
WARN_STRICT_OVERFLOW_CONDITIONAL = 2,
|
|
||||||
/* Overflow warning about changes to comparisons other than folding
|
|
||||||
them to a constant. Example: folding (x + 1 > 1) to (x > 0). */
|
|
||||||
WARN_STRICT_OVERFLOW_COMPARISON = 3,
|
|
||||||
/* Overflow warnings not covered by the above cases. Example:
|
|
||||||
folding ((x * 10) / 5) to (x * 2). */
|
|
||||||
WARN_STRICT_OVERFLOW_MISC = 4,
|
|
||||||
/* Overflow warnings about reducing magnitude of constants in
|
|
||||||
comparison. Example: folding (x + 2 > y) to (x + 1 >= y). */
|
|
||||||
WARN_STRICT_OVERFLOW_MAGNITUDE = 5
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Floating-point contraction mode. */
|
|
||||||
enum fp_contract_mode {
|
|
||||||
FP_CONTRACT_OFF = 0,
|
|
||||||
FP_CONTRACT_ON = 1,
|
|
||||||
FP_CONTRACT_FAST = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* ! GCC_FLAG_TYPES_H */
|
|
@ -1,101 +0,0 @@
|
|||||||
/* Compilation switch flag definitions for GCC.
|
|
||||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_FLAGS_H
|
|
||||||
#define GCC_FLAGS_H
|
|
||||||
|
|
||||||
#include "flag-types.h"
|
|
||||||
#include "options.h"
|
|
||||||
|
|
||||||
#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)
|
|
||||||
|
|
||||||
/* Names of debug_info_type, for error messages. */
|
|
||||||
extern const char *const debug_type_names[];
|
|
||||||
|
|
||||||
extern void strip_off_ending (char *, int);
|
|
||||||
extern int base_of_path (const char *path, const char **base_out);
|
|
||||||
|
|
||||||
/* Return true iff flags are set as if -ffast-math. */
|
|
||||||
extern bool fast_math_flags_set_p (const struct gcc_options *);
|
|
||||||
extern bool fast_math_flags_struct_set_p (struct cl_optimization *);
|
|
||||||
|
|
||||||
|
|
||||||
/* Now the symbols that are set with `-f' switches. */
|
|
||||||
|
|
||||||
/* True if printing into -fdump-final-insns= dump. */
|
|
||||||
|
|
||||||
extern bool final_insns_dump_p;
|
|
||||||
|
|
||||||
|
|
||||||
/* Other basic status info about current function. */
|
|
||||||
|
|
||||||
/* Target-dependent global state. */
|
|
||||||
struct target_flag_state {
|
|
||||||
/* Values of the -falign-* flags: how much to align labels in code.
|
|
||||||
0 means `use default', 1 means `don't align'.
|
|
||||||
For each variable, there is an _log variant which is the power
|
|
||||||
of two not less than the variable, for .align output. */
|
|
||||||
int x_align_loops_log;
|
|
||||||
int x_align_loops_max_skip;
|
|
||||||
int x_align_jumps_log;
|
|
||||||
int x_align_jumps_max_skip;
|
|
||||||
int x_align_labels_log;
|
|
||||||
int x_align_labels_max_skip;
|
|
||||||
int x_align_functions_log;
|
|
||||||
|
|
||||||
/* The excess precision currently in effect. */
|
|
||||||
enum excess_precision x_flag_excess_precision;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct target_flag_state default_target_flag_state;
|
|
||||||
#if SWITCHABLE_TARGET
|
|
||||||
extern struct target_flag_state *this_target_flag_state;
|
|
||||||
#else
|
|
||||||
#define this_target_flag_state (&default_target_flag_state)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define align_loops_log \
|
|
||||||
(this_target_flag_state->x_align_loops_log)
|
|
||||||
#define align_loops_max_skip \
|
|
||||||
(this_target_flag_state->x_align_loops_max_skip)
|
|
||||||
#define align_jumps_log \
|
|
||||||
(this_target_flag_state->x_align_jumps_log)
|
|
||||||
#define align_jumps_max_skip \
|
|
||||||
(this_target_flag_state->x_align_jumps_max_skip)
|
|
||||||
#define align_labels_log \
|
|
||||||
(this_target_flag_state->x_align_labels_log)
|
|
||||||
#define align_labels_max_skip \
|
|
||||||
(this_target_flag_state->x_align_labels_max_skip)
|
|
||||||
#define align_functions_log \
|
|
||||||
(this_target_flag_state->x_align_functions_log)
|
|
||||||
#define flag_excess_precision \
|
|
||||||
(this_target_flag_state->x_flag_excess_precision)
|
|
||||||
|
|
||||||
/* Returns TRUE if generated code should match ABI version N or
|
|
||||||
greater is in use. */
|
|
||||||
|
|
||||||
#define abi_version_at_least(N) \
|
|
||||||
(flag_abi_version == 0 || flag_abi_version >= (N))
|
|
||||||
|
|
||||||
/* Whether to emit an overflow warning whose code is C. */
|
|
||||||
#define issue_strict_overflow_warning(c) (warn_strict_overflow >= (int) (c))
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ! GCC_FLAGS_H */
|
|
@ -1,782 +0,0 @@
|
|||||||
/* Structure for saving state for a nested function.
|
|
||||||
Copyright (C) 1989-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_FUNCTION_H
|
|
||||||
#define GCC_FUNCTION_H
|
|
||||||
|
|
||||||
#include "hashtab.h"
|
|
||||||
#include "vec.h"
|
|
||||||
#include "machmode.h"
|
|
||||||
#include "tm.h" /* For CUMULATIVE_ARGS. */
|
|
||||||
#include "hard-reg-set.h" /* For HARD_REG_SET in struct rtl_data. */
|
|
||||||
#include "input.h" /* For location_t. */
|
|
||||||
|
|
||||||
/* Stack of pending (incomplete) sequences saved by `start_sequence'.
|
|
||||||
Each element describes one pending sequence.
|
|
||||||
The main insn-chain is saved in the last element of the chain,
|
|
||||||
unless the chain is empty. */
|
|
||||||
|
|
||||||
struct GTY(()) sequence_stack {
|
|
||||||
/* First and last insns in the chain of the saved sequence. */
|
|
||||||
rtx first;
|
|
||||||
rtx last;
|
|
||||||
struct sequence_stack *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GTY(()) emit_status {
|
|
||||||
/* This is reset to LAST_VIRTUAL_REGISTER + 1 at the start of each function.
|
|
||||||
After rtl generation, it is 1 plus the largest register number used. */
|
|
||||||
int x_reg_rtx_no;
|
|
||||||
|
|
||||||
/* Lowest label number in current function. */
|
|
||||||
int x_first_label_num;
|
|
||||||
|
|
||||||
/* The ends of the doubly-linked chain of rtl for the current function.
|
|
||||||
Both are reset to null at the start of rtl generation for the function.
|
|
||||||
|
|
||||||
start_sequence saves both of these on `sequence_stack' and then starts
|
|
||||||
a new, nested sequence of insns. */
|
|
||||||
rtx x_first_insn;
|
|
||||||
rtx x_last_insn;
|
|
||||||
|
|
||||||
/* Stack of pending (incomplete) sequences saved by `start_sequence'.
|
|
||||||
Each element describes one pending sequence.
|
|
||||||
The main insn-chain is saved in the last element of the chain,
|
|
||||||
unless the chain is empty. */
|
|
||||||
struct sequence_stack *sequence_stack;
|
|
||||||
|
|
||||||
/* INSN_UID for next insn emitted.
|
|
||||||
Reset to 1 for each function compiled. */
|
|
||||||
int x_cur_insn_uid;
|
|
||||||
|
|
||||||
/* INSN_UID for next debug insn emitted. Only used if
|
|
||||||
--param min-nondebug-insn-uid=<value> is given with nonzero value. */
|
|
||||||
int x_cur_debug_insn_uid;
|
|
||||||
|
|
||||||
/* The length of the regno_pointer_align, regno_decl, and x_regno_reg_rtx
|
|
||||||
vectors. Since these vectors are needed during the expansion phase when
|
|
||||||
the total number of registers in the function is not yet known, the
|
|
||||||
vectors are copied and made bigger when necessary. */
|
|
||||||
int regno_pointer_align_length;
|
|
||||||
|
|
||||||
/* Indexed by pseudo register number, if nonzero gives the known alignment
|
|
||||||
for that pseudo (if REG_POINTER is set in x_regno_reg_rtx).
|
|
||||||
Allocated in parallel with x_regno_reg_rtx. */
|
|
||||||
unsigned char * GTY((skip)) regno_pointer_align;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Indexed by register number, gives an rtx for that register (and only
|
|
||||||
that register). For pseudo registers, it is the unique rtx for
|
|
||||||
that pseudo. For hard registers, it is an rtx of the mode specified
|
|
||||||
by reg_raw_mode.
|
|
||||||
|
|
||||||
FIXME: We could put it into emit_status struct, but gengtype is not
|
|
||||||
able to deal with length attribute nested in top level structures. */
|
|
||||||
|
|
||||||
extern GTY ((length ("crtl->emit.x_reg_rtx_no"))) rtx * regno_reg_rtx;
|
|
||||||
|
|
||||||
/* For backward compatibility... eventually these should all go away. */
|
|
||||||
#define reg_rtx_no (crtl->emit.x_reg_rtx_no)
|
|
||||||
#define seq_stack (crtl->emit.sequence_stack)
|
|
||||||
|
|
||||||
#define REGNO_POINTER_ALIGN(REGNO) (crtl->emit.regno_pointer_align[REGNO])
|
|
||||||
|
|
||||||
struct GTY(()) expr_status {
|
|
||||||
/* Number of units that we should eventually pop off the stack.
|
|
||||||
These are the arguments to function calls that have already returned. */
|
|
||||||
int x_pending_stack_adjust;
|
|
||||||
|
|
||||||
/* Under some ABIs, it is the caller's responsibility to pop arguments
|
|
||||||
pushed for function calls. A naive implementation would simply pop
|
|
||||||
the arguments immediately after each call. However, if several
|
|
||||||
function calls are made in a row, it is typically cheaper to pop
|
|
||||||
all the arguments after all of the calls are complete since a
|
|
||||||
single pop instruction can be used. Therefore, GCC attempts to
|
|
||||||
defer popping the arguments until absolutely necessary. (For
|
|
||||||
example, at the end of a conditional, the arguments must be popped,
|
|
||||||
since code outside the conditional won't know whether or not the
|
|
||||||
arguments need to be popped.)
|
|
||||||
|
|
||||||
When INHIBIT_DEFER_POP is nonzero, however, the compiler does not
|
|
||||||
attempt to defer pops. Instead, the stack is popped immediately
|
|
||||||
after each call. Rather then setting this variable directly, use
|
|
||||||
NO_DEFER_POP and OK_DEFER_POP. */
|
|
||||||
int x_inhibit_defer_pop;
|
|
||||||
|
|
||||||
/* If PREFERRED_STACK_BOUNDARY and PUSH_ROUNDING are defined, the stack
|
|
||||||
boundary can be momentarily unaligned while pushing the arguments.
|
|
||||||
Record the delta since last aligned boundary here in order to get
|
|
||||||
stack alignment in the nested function calls working right. */
|
|
||||||
int x_stack_pointer_delta;
|
|
||||||
|
|
||||||
/* Nonzero means __builtin_saveregs has already been done in this function.
|
|
||||||
The value is the pseudoreg containing the value __builtin_saveregs
|
|
||||||
returned. */
|
|
||||||
rtx x_saveregs_value;
|
|
||||||
|
|
||||||
/* Similarly for __builtin_apply_args. */
|
|
||||||
rtx x_apply_args_value;
|
|
||||||
|
|
||||||
/* List of labels that must never be deleted. */
|
|
||||||
rtx x_forced_labels;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct call_site_record_d *call_site_record;
|
|
||||||
|
|
||||||
/* RTL representation of exception handling. */
|
|
||||||
struct GTY(()) rtl_eh {
|
|
||||||
rtx ehr_stackadj;
|
|
||||||
rtx ehr_handler;
|
|
||||||
rtx ehr_label;
|
|
||||||
|
|
||||||
rtx sjlj_fc;
|
|
||||||
rtx sjlj_exit_after;
|
|
||||||
|
|
||||||
vec<uchar, va_gc> *action_record_data;
|
|
||||||
|
|
||||||
vec<call_site_record, va_gc> *call_site_record_v[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define pending_stack_adjust (crtl->expr.x_pending_stack_adjust)
|
|
||||||
#define inhibit_defer_pop (crtl->expr.x_inhibit_defer_pop)
|
|
||||||
#define saveregs_value (crtl->expr.x_saveregs_value)
|
|
||||||
#define apply_args_value (crtl->expr.x_apply_args_value)
|
|
||||||
#define forced_labels (crtl->expr.x_forced_labels)
|
|
||||||
#define stack_pointer_delta (crtl->expr.x_stack_pointer_delta)
|
|
||||||
|
|
||||||
struct gimple_df;
|
|
||||||
struct temp_slot;
|
|
||||||
typedef struct temp_slot *temp_slot_p;
|
|
||||||
struct call_site_record_d;
|
|
||||||
struct dw_fde_struct;
|
|
||||||
|
|
||||||
struct ipa_opt_pass_d;
|
|
||||||
typedef struct ipa_opt_pass_d *ipa_opt_pass;
|
|
||||||
|
|
||||||
|
|
||||||
struct GTY(()) varasm_status {
|
|
||||||
/* If we're using a per-function constant pool, this is it. */
|
|
||||||
struct rtx_constant_pool *pool;
|
|
||||||
|
|
||||||
/* Number of tree-constants deferred during the expansion of this
|
|
||||||
function. */
|
|
||||||
unsigned int deferred_constants;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Information mainlined about RTL representation of incoming arguments. */
|
|
||||||
struct GTY(()) incoming_args {
|
|
||||||
/* Number of bytes of args popped by function being compiled on its return.
|
|
||||||
Zero if no bytes are to be popped.
|
|
||||||
May affect compilation of return insn or of function epilogue. */
|
|
||||||
int pops_args;
|
|
||||||
|
|
||||||
/* If function's args have a fixed size, this is that size, in bytes.
|
|
||||||
Otherwise, it is -1.
|
|
||||||
May affect compilation of return insn or of function epilogue. */
|
|
||||||
int size;
|
|
||||||
|
|
||||||
/* # bytes the prologue should push and pretend that the caller pushed them.
|
|
||||||
The prologue must do this, but only if parms can be passed in
|
|
||||||
registers. */
|
|
||||||
int pretend_args_size;
|
|
||||||
|
|
||||||
/* This is the offset from the arg pointer to the place where the first
|
|
||||||
anonymous arg can be found, if there is one. */
|
|
||||||
rtx arg_offset_rtx;
|
|
||||||
|
|
||||||
/* Quantities of various kinds of registers
|
|
||||||
used for the current function's args. */
|
|
||||||
CUMULATIVE_ARGS info;
|
|
||||||
|
|
||||||
/* The arg pointer hard register, or the pseudo into which it was copied. */
|
|
||||||
rtx internal_arg_pointer;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Data for function partitioning. */
|
|
||||||
struct GTY(()) function_subsections {
|
|
||||||
/* Assembly labels for the hot and cold text sections, to
|
|
||||||
be used by debugger functions for determining the size of text
|
|
||||||
sections. */
|
|
||||||
|
|
||||||
const char *hot_section_label;
|
|
||||||
const char *cold_section_label;
|
|
||||||
const char *hot_section_end_label;
|
|
||||||
const char *cold_section_end_label;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Describe an empty area of space in the stack frame. These can be chained
|
|
||||||
into a list; this is used to keep track of space wasted for alignment
|
|
||||||
reasons. */
|
|
||||||
struct GTY(()) frame_space
|
|
||||||
{
|
|
||||||
struct frame_space *next;
|
|
||||||
|
|
||||||
HOST_WIDE_INT start;
|
|
||||||
HOST_WIDE_INT length;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Datastructures maintained for currently processed function in RTL form. */
|
|
||||||
struct GTY(()) rtl_data {
|
|
||||||
struct expr_status expr;
|
|
||||||
struct emit_status emit;
|
|
||||||
struct varasm_status varasm;
|
|
||||||
struct incoming_args args;
|
|
||||||
struct function_subsections subsections;
|
|
||||||
struct rtl_eh eh;
|
|
||||||
|
|
||||||
/* For function.c */
|
|
||||||
|
|
||||||
/* # of bytes of outgoing arguments. If ACCUMULATE_OUTGOING_ARGS is
|
|
||||||
defined, the needed space is pushed by the prologue. */
|
|
||||||
int outgoing_args_size;
|
|
||||||
|
|
||||||
/* If nonzero, an RTL expression for the location at which the current
|
|
||||||
function returns its result. If the current function returns its
|
|
||||||
result in a register, current_function_return_rtx will always be
|
|
||||||
the hard register containing the result. */
|
|
||||||
rtx return_rtx;
|
|
||||||
|
|
||||||
/* Vector of initial-value pairs. Each pair consists of a pseudo
|
|
||||||
register of approprite mode that stores the initial value a hard
|
|
||||||
register REGNO, and that hard register itself. */
|
|
||||||
/* ??? This could be a VEC but there is currently no way to define an
|
|
||||||
opaque VEC type. */
|
|
||||||
struct initial_value_struct *hard_reg_initial_vals;
|
|
||||||
|
|
||||||
/* A variable living at the top of the frame that holds a known value.
|
|
||||||
Used for detecting stack clobbers. */
|
|
||||||
tree stack_protect_guard;
|
|
||||||
|
|
||||||
/* List (chain of EXPR_LIST) of labels heading the current handlers for
|
|
||||||
nonlocal gotos. */
|
|
||||||
rtx x_nonlocal_goto_handler_labels;
|
|
||||||
|
|
||||||
/* Label that will go on function epilogue.
|
|
||||||
Jumping to this label serves as a "return" instruction
|
|
||||||
on machines which require execution of the epilogue on all returns. */
|
|
||||||
rtx x_return_label;
|
|
||||||
|
|
||||||
/* Label that will go on the end of function epilogue.
|
|
||||||
Jumping to this label serves as a "naked return" instruction
|
|
||||||
on machines which require execution of the epilogue on all returns. */
|
|
||||||
rtx x_naked_return_label;
|
|
||||||
|
|
||||||
/* List (chain of EXPR_LISTs) of all stack slots in this function.
|
|
||||||
Made for the sake of unshare_all_rtl. */
|
|
||||||
rtx x_stack_slot_list;
|
|
||||||
|
|
||||||
/* List of empty areas in the stack frame. */
|
|
||||||
struct frame_space *frame_space_list;
|
|
||||||
|
|
||||||
/* Place after which to insert the tail_recursion_label if we need one. */
|
|
||||||
rtx x_stack_check_probe_note;
|
|
||||||
|
|
||||||
/* Location at which to save the argument pointer if it will need to be
|
|
||||||
referenced. There are two cases where this is done: if nonlocal gotos
|
|
||||||
exist, or if vars stored at an offset from the argument pointer will be
|
|
||||||
needed by inner routines. */
|
|
||||||
rtx x_arg_pointer_save_area;
|
|
||||||
|
|
||||||
/* Dynamic Realign Argument Pointer used for realigning stack. */
|
|
||||||
rtx drap_reg;
|
|
||||||
|
|
||||||
/* Offset to end of allocated area of stack frame.
|
|
||||||
If stack grows down, this is the address of the last stack slot allocated.
|
|
||||||
If stack grows up, this is the address for the next slot. */
|
|
||||||
HOST_WIDE_INT x_frame_offset;
|
|
||||||
|
|
||||||
/* Insn after which register parms and SAVE_EXPRs are born, if nonopt. */
|
|
||||||
rtx x_parm_birth_insn;
|
|
||||||
|
|
||||||
/* List of all used temporaries allocated, by level. */
|
|
||||||
vec<temp_slot_p, va_gc> *x_used_temp_slots;
|
|
||||||
|
|
||||||
/* List of available temp slots. */
|
|
||||||
struct temp_slot *x_avail_temp_slots;
|
|
||||||
|
|
||||||
/* Current nesting level for temporaries. */
|
|
||||||
int x_temp_slot_level;
|
|
||||||
|
|
||||||
/* The largest alignment needed on the stack, including requirement
|
|
||||||
for outgoing stack alignment. */
|
|
||||||
unsigned int stack_alignment_needed;
|
|
||||||
|
|
||||||
/* Preferred alignment of the end of stack frame, which is preferred
|
|
||||||
to call other functions. */
|
|
||||||
unsigned int preferred_stack_boundary;
|
|
||||||
|
|
||||||
/* The minimum alignment of parameter stack. */
|
|
||||||
unsigned int parm_stack_boundary;
|
|
||||||
|
|
||||||
/* The largest alignment of slot allocated on the stack. */
|
|
||||||
unsigned int max_used_stack_slot_alignment;
|
|
||||||
|
|
||||||
/* The stack alignment estimated before reload, with consideration of
|
|
||||||
following factors:
|
|
||||||
1. Alignment of local stack variables (max_used_stack_slot_alignment)
|
|
||||||
2. Alignment requirement to call other functions
|
|
||||||
(preferred_stack_boundary)
|
|
||||||
3. Alignment of non-local stack variables but might be spilled in
|
|
||||||
local stack. */
|
|
||||||
unsigned int stack_alignment_estimated;
|
|
||||||
|
|
||||||
/* For reorg. */
|
|
||||||
|
|
||||||
/* Nonzero if function being compiled called builtin_return_addr or
|
|
||||||
builtin_frame_address with nonzero count. */
|
|
||||||
bool accesses_prior_frames;
|
|
||||||
|
|
||||||
/* Nonzero if the function calls __builtin_eh_return. */
|
|
||||||
bool calls_eh_return;
|
|
||||||
|
|
||||||
/* Nonzero if function saves all registers, e.g. if it has a nonlocal
|
|
||||||
label that can reach the exit block via non-exceptional paths. */
|
|
||||||
bool saves_all_registers;
|
|
||||||
|
|
||||||
/* Nonzero if function being compiled has nonlocal gotos to parent
|
|
||||||
function. */
|
|
||||||
bool has_nonlocal_goto;
|
|
||||||
|
|
||||||
/* Nonzero if function being compiled has an asm statement. */
|
|
||||||
bool has_asm_statement;
|
|
||||||
|
|
||||||
/* This bit is used by the exception handling logic. It is set if all
|
|
||||||
calls (if any) are sibling calls. Such functions do not have to
|
|
||||||
have EH tables generated, as they cannot throw. A call to such a
|
|
||||||
function, however, should be treated as throwing if any of its callees
|
|
||||||
can throw. */
|
|
||||||
bool all_throwers_are_sibcalls;
|
|
||||||
|
|
||||||
/* Nonzero if stack limit checking should be enabled in the current
|
|
||||||
function. */
|
|
||||||
bool limit_stack;
|
|
||||||
|
|
||||||
/* Nonzero if profiling code should be generated. */
|
|
||||||
bool profile;
|
|
||||||
|
|
||||||
/* Nonzero if the current function uses the constant pool. */
|
|
||||||
bool uses_const_pool;
|
|
||||||
|
|
||||||
/* Nonzero if the current function uses pic_offset_table_rtx. */
|
|
||||||
bool uses_pic_offset_table;
|
|
||||||
|
|
||||||
/* Nonzero if the current function needs an lsda for exception handling. */
|
|
||||||
bool uses_eh_lsda;
|
|
||||||
|
|
||||||
/* Set when the tail call has been produced. */
|
|
||||||
bool tail_call_emit;
|
|
||||||
|
|
||||||
/* Nonzero if code to initialize arg_pointer_save_area has been emitted. */
|
|
||||||
bool arg_pointer_save_area_init;
|
|
||||||
|
|
||||||
/* Nonzero if current function must be given a frame pointer.
|
|
||||||
Set in reload1.c or lra-eliminations.c if anything is allocated
|
|
||||||
on the stack there. */
|
|
||||||
bool frame_pointer_needed;
|
|
||||||
|
|
||||||
/* When set, expand should optimize for speed. */
|
|
||||||
bool maybe_hot_insn_p;
|
|
||||||
|
|
||||||
/* Nonzero if function stack realignment is needed. This flag may be
|
|
||||||
set twice: before and after reload. It is set before reload wrt
|
|
||||||
stack alignment estimation before reload. It will be changed after
|
|
||||||
reload if by then criteria of stack realignment is different.
|
|
||||||
The value set after reload is the accurate one and is finalized. */
|
|
||||||
bool stack_realign_needed;
|
|
||||||
|
|
||||||
/* Nonzero if function stack realignment is tried. This flag is set
|
|
||||||
only once before reload. It affects register elimination. This
|
|
||||||
is used to generate DWARF debug info for stack variables. */
|
|
||||||
bool stack_realign_tried;
|
|
||||||
|
|
||||||
/* Nonzero if function being compiled needs dynamic realigned
|
|
||||||
argument pointer (drap) if stack needs realigning. */
|
|
||||||
bool need_drap;
|
|
||||||
|
|
||||||
/* Nonzero if function stack realignment estimation is done, namely
|
|
||||||
stack_realign_needed flag has been set before reload wrt estimated
|
|
||||||
stack alignment info. */
|
|
||||||
bool stack_realign_processed;
|
|
||||||
|
|
||||||
/* Nonzero if function stack realignment has been finalized, namely
|
|
||||||
stack_realign_needed flag has been set and finalized after reload. */
|
|
||||||
bool stack_realign_finalized;
|
|
||||||
|
|
||||||
/* True if dbr_schedule has already been called for this function. */
|
|
||||||
bool dbr_scheduled_p;
|
|
||||||
|
|
||||||
/* True if current function can not throw. Unlike
|
|
||||||
TREE_NOTHROW (current_function_decl) it is set even for overwritable
|
|
||||||
function where currently compiled version of it is nothrow. */
|
|
||||||
bool nothrow;
|
|
||||||
|
|
||||||
/* True if we performed shrink-wrapping for the current function. */
|
|
||||||
bool shrink_wrapped;
|
|
||||||
|
|
||||||
/* Nonzero if function being compiled doesn't modify the stack pointer
|
|
||||||
(ignoring the prologue and epilogue). This is only valid after
|
|
||||||
pass_stack_ptr_mod has run. */
|
|
||||||
bool sp_is_unchanging;
|
|
||||||
|
|
||||||
/* Nonzero if function being compiled doesn't contain any calls
|
|
||||||
(ignoring the prologue and epilogue). This is set prior to
|
|
||||||
local register allocation and is valid for the remaining
|
|
||||||
compiler passes. */
|
|
||||||
bool is_leaf;
|
|
||||||
|
|
||||||
/* Nonzero if the function being compiled is a leaf function which only
|
|
||||||
uses leaf registers. This is valid after reload (specifically after
|
|
||||||
sched2) and is useful only if the port defines LEAF_REGISTERS. */
|
|
||||||
bool uses_only_leaf_regs;
|
|
||||||
|
|
||||||
/* Like regs_ever_live, but 1 if a reg is set or clobbered from an
|
|
||||||
asm. Unlike regs_ever_live, elements of this array corresponding
|
|
||||||
to eliminable regs (like the frame pointer) are set if an asm
|
|
||||||
sets them. */
|
|
||||||
HARD_REG_SET asm_clobbers;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define return_label (crtl->x_return_label)
|
|
||||||
#define naked_return_label (crtl->x_naked_return_label)
|
|
||||||
#define stack_slot_list (crtl->x_stack_slot_list)
|
|
||||||
#define parm_birth_insn (crtl->x_parm_birth_insn)
|
|
||||||
#define frame_offset (crtl->x_frame_offset)
|
|
||||||
#define stack_check_probe_note (crtl->x_stack_check_probe_note)
|
|
||||||
#define arg_pointer_save_area (crtl->x_arg_pointer_save_area)
|
|
||||||
#define used_temp_slots (crtl->x_used_temp_slots)
|
|
||||||
#define avail_temp_slots (crtl->x_avail_temp_slots)
|
|
||||||
#define temp_slot_level (crtl->x_temp_slot_level)
|
|
||||||
#define nonlocal_goto_handler_labels (crtl->x_nonlocal_goto_handler_labels)
|
|
||||||
#define frame_pointer_needed (crtl->frame_pointer_needed)
|
|
||||||
#define stack_realign_fp (crtl->stack_realign_needed && !crtl->need_drap)
|
|
||||||
#define stack_realign_drap (crtl->stack_realign_needed && crtl->need_drap)
|
|
||||||
|
|
||||||
extern GTY(()) struct rtl_data x_rtl;
|
|
||||||
|
|
||||||
/* Accessor to RTL datastructures. We keep them statically allocated now since
|
|
||||||
we never keep multiple functions. For threaded compiler we might however
|
|
||||||
want to do differently. */
|
|
||||||
#define crtl (&x_rtl)
|
|
||||||
|
|
||||||
struct GTY(()) stack_usage
|
|
||||||
{
|
|
||||||
/* # of bytes of static stack space allocated by the function. */
|
|
||||||
HOST_WIDE_INT static_stack_size;
|
|
||||||
|
|
||||||
/* # of bytes of dynamic stack space allocated by the function. This is
|
|
||||||
meaningful only if has_unbounded_dynamic_stack_size is zero. */
|
|
||||||
HOST_WIDE_INT dynamic_stack_size;
|
|
||||||
|
|
||||||
/* # of bytes of space pushed onto the stack after the prologue. If
|
|
||||||
!ACCUMULATE_OUTGOING_ARGS, it contains the outgoing arguments. */
|
|
||||||
int pushed_stack_size;
|
|
||||||
|
|
||||||
/* Nonzero if the amount of stack space allocated dynamically cannot
|
|
||||||
be bounded at compile-time. */
|
|
||||||
unsigned int has_unbounded_dynamic_stack_size : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define current_function_static_stack_size (cfun->su->static_stack_size)
|
|
||||||
#define current_function_dynamic_stack_size (cfun->su->dynamic_stack_size)
|
|
||||||
#define current_function_pushed_stack_size (cfun->su->pushed_stack_size)
|
|
||||||
#define current_function_has_unbounded_dynamic_stack_size \
|
|
||||||
(cfun->su->has_unbounded_dynamic_stack_size)
|
|
||||||
#define current_function_allocates_dynamic_stack_space \
|
|
||||||
(current_function_dynamic_stack_size != 0 \
|
|
||||||
|| current_function_has_unbounded_dynamic_stack_size)
|
|
||||||
|
|
||||||
/* This structure can save all the important global and static variables
|
|
||||||
describing the status of the current function. */
|
|
||||||
|
|
||||||
struct GTY(()) function {
|
|
||||||
struct eh_status *eh;
|
|
||||||
|
|
||||||
/* The control flow graph for this function. */
|
|
||||||
struct control_flow_graph *cfg;
|
|
||||||
|
|
||||||
/* GIMPLE body for this function. */
|
|
||||||
gimple_seq gimple_body;
|
|
||||||
|
|
||||||
/* SSA and dataflow information. */
|
|
||||||
struct gimple_df *gimple_df;
|
|
||||||
|
|
||||||
/* The loops in this function. */
|
|
||||||
struct loops *x_current_loops;
|
|
||||||
|
|
||||||
/* The stack usage of this function. */
|
|
||||||
struct stack_usage *su;
|
|
||||||
|
|
||||||
/* Value histograms attached to particular statements. */
|
|
||||||
htab_t GTY((skip)) value_histograms;
|
|
||||||
|
|
||||||
/* For function.c. */
|
|
||||||
|
|
||||||
/* Points to the FUNCTION_DECL of this function. */
|
|
||||||
tree decl;
|
|
||||||
|
|
||||||
/* A PARM_DECL that should contain the static chain for this function.
|
|
||||||
It will be initialized at the beginning of the function. */
|
|
||||||
tree static_chain_decl;
|
|
||||||
|
|
||||||
/* An expression that contains the non-local goto save area. The first
|
|
||||||
word is the saved frame pointer and the second is the saved stack
|
|
||||||
pointer. */
|
|
||||||
tree nonlocal_goto_save_area;
|
|
||||||
|
|
||||||
/* Vector of function local variables, functions, types and constants. */
|
|
||||||
vec<tree, va_gc> *local_decls;
|
|
||||||
|
|
||||||
/* For md files. */
|
|
||||||
|
|
||||||
/* tm.h can use this to store whatever it likes. */
|
|
||||||
struct machine_function * GTY ((maybe_undef)) machine;
|
|
||||||
|
|
||||||
/* Language-specific code can use this to store whatever it likes. */
|
|
||||||
struct language_function * language;
|
|
||||||
|
|
||||||
/* Used types hash table. */
|
|
||||||
htab_t GTY ((param_is (union tree_node))) used_types_hash;
|
|
||||||
|
|
||||||
/* Dwarf2 Frame Description Entry, containing the Call Frame Instructions
|
|
||||||
used for unwinding. Only set when either dwarf2 unwinding or dwarf2
|
|
||||||
debugging is enabled. */
|
|
||||||
struct dw_fde_struct *fde;
|
|
||||||
|
|
||||||
/* Last statement uid. */
|
|
||||||
int last_stmt_uid;
|
|
||||||
|
|
||||||
/* Function sequence number for profiling, debugging, etc. */
|
|
||||||
int funcdef_no;
|
|
||||||
|
|
||||||
/* Line number of the start of the function for debugging purposes. */
|
|
||||||
location_t function_start_locus;
|
|
||||||
|
|
||||||
/* Line number of the end of the function. */
|
|
||||||
location_t function_end_locus;
|
|
||||||
|
|
||||||
/* Properties used by the pass manager. */
|
|
||||||
unsigned int curr_properties;
|
|
||||||
unsigned int last_verified;
|
|
||||||
|
|
||||||
/* Non-null if the function does something that would prevent it from
|
|
||||||
being copied; this applies to both versioning and inlining. Set to
|
|
||||||
a string describing the reason for failure. */
|
|
||||||
const char * GTY((skip)) cannot_be_copied_reason;
|
|
||||||
|
|
||||||
/* Collected bit flags. */
|
|
||||||
|
|
||||||
/* Number of units of general registers that need saving in stdarg
|
|
||||||
function. What unit is depends on the backend, either it is number
|
|
||||||
of bytes, or it can be number of registers. */
|
|
||||||
unsigned int va_list_gpr_size : 8;
|
|
||||||
|
|
||||||
/* Number of units of floating point registers that need saving in stdarg
|
|
||||||
function. */
|
|
||||||
unsigned int va_list_fpr_size : 8;
|
|
||||||
|
|
||||||
/* Nonzero if function being compiled can call setjmp. */
|
|
||||||
unsigned int calls_setjmp : 1;
|
|
||||||
|
|
||||||
/* Nonzero if function being compiled can call alloca,
|
|
||||||
either as a subroutine or builtin. */
|
|
||||||
unsigned int calls_alloca : 1;
|
|
||||||
|
|
||||||
/* Nonzero if function being compiled receives nonlocal gotos
|
|
||||||
from nested functions. */
|
|
||||||
unsigned int has_nonlocal_label : 1;
|
|
||||||
|
|
||||||
/* Nonzero if we've set cannot_be_copied_reason. I.e. if
|
|
||||||
(cannot_be_copied_set && !cannot_be_copied_reason), the function
|
|
||||||
can in fact be copied. */
|
|
||||||
unsigned int cannot_be_copied_set : 1;
|
|
||||||
|
|
||||||
/* Nonzero if current function uses stdarg.h or equivalent. */
|
|
||||||
unsigned int stdarg : 1;
|
|
||||||
|
|
||||||
unsigned int after_inlining : 1;
|
|
||||||
unsigned int always_inline_functions_inlined : 1;
|
|
||||||
|
|
||||||
/* Nonzero if function being compiled can throw synchronous non-call
|
|
||||||
exceptions. */
|
|
||||||
unsigned int can_throw_non_call_exceptions : 1;
|
|
||||||
|
|
||||||
/* Nonzero if instructions that may throw exceptions but don't otherwise
|
|
||||||
contribute to the execution of the program can be deleted. */
|
|
||||||
unsigned int can_delete_dead_exceptions : 1;
|
|
||||||
|
|
||||||
/* Fields below this point are not set for abstract functions; see
|
|
||||||
allocate_struct_function. */
|
|
||||||
|
|
||||||
/* Nonzero if function being compiled needs to be given an address
|
|
||||||
where the value should be stored. */
|
|
||||||
unsigned int returns_struct : 1;
|
|
||||||
|
|
||||||
/* Nonzero if function being compiled needs to
|
|
||||||
return the address of where it has put a structure value. */
|
|
||||||
unsigned int returns_pcc_struct : 1;
|
|
||||||
|
|
||||||
/* Nonzero if this function has local DECL_HARD_REGISTER variables.
|
|
||||||
In this case code motion has to be done more carefully. */
|
|
||||||
unsigned int has_local_explicit_reg_vars : 1;
|
|
||||||
|
|
||||||
/* Nonzero if the current function is a thunk, i.e., a lightweight
|
|
||||||
function implemented by the output_mi_thunk hook) that just
|
|
||||||
adjusts one of its arguments and forwards to another
|
|
||||||
function. */
|
|
||||||
unsigned int is_thunk : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Add the decl D to the local_decls list of FUN. */
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
add_local_decl (struct function *fun, tree d)
|
|
||||||
{
|
|
||||||
vec_safe_push (fun->local_decls, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FOR_EACH_LOCAL_DECL(FUN, I, D) \
|
|
||||||
FOR_EACH_VEC_SAFE_ELT_REVERSE ((FUN)->local_decls, I, D)
|
|
||||||
|
|
||||||
/* If va_list_[gf]pr_size is set to this, it means we don't know how
|
|
||||||
many units need to be saved. */
|
|
||||||
#define VA_LIST_MAX_GPR_SIZE 255
|
|
||||||
#define VA_LIST_MAX_FPR_SIZE 255
|
|
||||||
|
|
||||||
/* The function currently being compiled. */
|
|
||||||
extern GTY(()) struct function *cfun;
|
|
||||||
|
|
||||||
/* In order to ensure that cfun is not set directly, we redefine it so
|
|
||||||
that it is not an lvalue. Rather than assign to cfun, use
|
|
||||||
push_cfun or set_cfun. */
|
|
||||||
#define cfun (cfun + 0)
|
|
||||||
|
|
||||||
/* Nonzero if we've already converted virtual regs to hard regs. */
|
|
||||||
extern int virtuals_instantiated;
|
|
||||||
|
|
||||||
/* Nonzero if at least one trampoline has been created. */
|
|
||||||
extern int trampolines_created;
|
|
||||||
|
|
||||||
struct GTY(()) types_used_by_vars_entry {
|
|
||||||
tree type;
|
|
||||||
tree var_decl;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Hash table making the relationship between a global variable
|
|
||||||
and the types it references in its initializer. The key of the
|
|
||||||
entry is a referenced type, and the value is the DECL of the global
|
|
||||||
variable. types_use_by_vars_do_hash and types_used_by_vars_eq below are
|
|
||||||
the hash and equality functions to use for this hash table. */
|
|
||||||
extern GTY((param_is (struct types_used_by_vars_entry))) htab_t
|
|
||||||
types_used_by_vars_hash;
|
|
||||||
|
|
||||||
hashval_t types_used_by_vars_do_hash (const void*);
|
|
||||||
int types_used_by_vars_eq (const void *, const void *);
|
|
||||||
void types_used_by_var_decl_insert (tree type, tree var_decl);
|
|
||||||
|
|
||||||
/* During parsing of a global variable, this vector contains the types
|
|
||||||
referenced by the global variable. */
|
|
||||||
extern GTY(()) vec<tree, va_gc> *types_used_by_cur_var_decl;
|
|
||||||
|
|
||||||
/* cfun shouldn't be set directly; use one of these functions instead. */
|
|
||||||
extern void set_cfun (struct function *new_cfun);
|
|
||||||
extern void push_cfun (struct function *new_cfun);
|
|
||||||
extern void pop_cfun (void);
|
|
||||||
extern void instantiate_decl_rtl (rtx x);
|
|
||||||
|
|
||||||
/* For backward compatibility... eventually these should all go away. */
|
|
||||||
#define current_function_funcdef_no (cfun->funcdef_no)
|
|
||||||
|
|
||||||
#define current_loops (cfun->x_current_loops)
|
|
||||||
#define dom_computed (cfun->cfg->x_dom_computed)
|
|
||||||
#define n_bbs_in_dom_tree (cfun->cfg->x_n_bbs_in_dom_tree)
|
|
||||||
#define VALUE_HISTOGRAMS(fun) (fun)->value_histograms
|
|
||||||
|
|
||||||
/* Identify BLOCKs referenced by more than one NOTE_INSN_BLOCK_{BEG,END},
|
|
||||||
and create duplicate blocks. */
|
|
||||||
extern void reorder_blocks (void);
|
|
||||||
|
|
||||||
/* Set BLOCK_NUMBER for all the blocks in FN. */
|
|
||||||
extern void number_blocks (tree);
|
|
||||||
|
|
||||||
extern void clear_block_marks (tree);
|
|
||||||
extern tree blocks_nreverse (tree);
|
|
||||||
extern tree block_chainon (tree, tree);
|
|
||||||
|
|
||||||
/* Return size needed for stack frame based on slots so far allocated.
|
|
||||||
This size counts from zero. It is not rounded to STACK_BOUNDARY;
|
|
||||||
the caller may have to do that. */
|
|
||||||
extern HOST_WIDE_INT get_frame_size (void);
|
|
||||||
|
|
||||||
/* Issue an error message and return TRUE if frame OFFSET overflows in
|
|
||||||
the signed target pointer arithmetics for function FUNC. Otherwise
|
|
||||||
return FALSE. */
|
|
||||||
extern bool frame_offset_overflow (HOST_WIDE_INT, tree);
|
|
||||||
|
|
||||||
/* A pointer to a function to create target specific, per-function
|
|
||||||
data structures. */
|
|
||||||
extern struct machine_function * (*init_machine_status) (void);
|
|
||||||
|
|
||||||
/* Save and restore status information for a nested function. */
|
|
||||||
extern void free_after_parsing (struct function *);
|
|
||||||
extern void free_after_compilation (struct function *);
|
|
||||||
|
|
||||||
extern void init_varasm_status (void);
|
|
||||||
|
|
||||||
#ifdef RTX_CODE
|
|
||||||
extern void diddle_return_value (void (*)(rtx, void*), void*);
|
|
||||||
extern void clobber_return_register (void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern rtx get_arg_pointer_save_area (void);
|
|
||||||
|
|
||||||
/* Returns the name of the current function. */
|
|
||||||
extern const char *fndecl_name (tree);
|
|
||||||
extern const char *function_name (struct function *);
|
|
||||||
extern const char *current_function_name (void);
|
|
||||||
|
|
||||||
extern void do_warn_unused_parameter (tree);
|
|
||||||
|
|
||||||
extern bool pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
|
||||||
tree, bool);
|
|
||||||
extern bool reference_callee_copied (CUMULATIVE_ARGS *, enum machine_mode,
|
|
||||||
tree, bool);
|
|
||||||
|
|
||||||
extern void used_types_insert (tree);
|
|
||||||
|
|
||||||
extern int get_next_funcdef_no (void);
|
|
||||||
extern int get_last_funcdef_no (void);
|
|
||||||
|
|
||||||
#ifdef HAVE_simple_return
|
|
||||||
extern bool requires_stack_frame_p (rtx, HARD_REG_SET, HARD_REG_SET);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern rtx get_hard_reg_initial_val (enum machine_mode, unsigned int);
|
|
||||||
extern rtx has_hard_reg_initial_val (enum machine_mode, unsigned int);
|
|
||||||
extern rtx get_hard_reg_initial_reg (rtx);
|
|
||||||
extern bool initial_value_entry (int i, rtx *, rtx *);
|
|
||||||
|
|
||||||
/* Called from gimple_expand_cfg. */
|
|
||||||
extern unsigned int emit_initial_value_sets (void);
|
|
||||||
|
|
||||||
/* In predict.c */
|
|
||||||
extern bool optimize_function_for_size_p (struct function *);
|
|
||||||
extern bool optimize_function_for_speed_p (struct function *);
|
|
||||||
|
|
||||||
#endif /* GCC_FUNCTION_H */
|
|
@ -1,166 +0,0 @@
|
|||||||
/* Public header file for plugins to include.
|
|
||||||
Copyright (C) 2009-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_PLUGIN_H
|
|
||||||
#define GCC_PLUGIN_H
|
|
||||||
|
|
||||||
#ifndef IN_GCC
|
|
||||||
#define IN_GCC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "system.h"
|
|
||||||
#include "coretypes.h"
|
|
||||||
#include "highlev-plugin-common.h"
|
|
||||||
#include "hashtab.h"
|
|
||||||
|
|
||||||
/* Event names. */
|
|
||||||
enum plugin_event
|
|
||||||
{
|
|
||||||
# define DEFEVENT(NAME) NAME,
|
|
||||||
# include "plugin.def"
|
|
||||||
# undef DEFEVENT
|
|
||||||
PLUGIN_EVENT_FIRST_DYNAMIC
|
|
||||||
};
|
|
||||||
|
|
||||||
/* All globals declared here have C linkage to reduce link compatibility
|
|
||||||
issues with implementation language choice and mangling. */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern const char **plugin_event_name;
|
|
||||||
|
|
||||||
struct plugin_argument
|
|
||||||
{
|
|
||||||
char *key; /* key of the argument. */
|
|
||||||
char *value; /* value is optional and can be NULL. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Additional information about the plugin. Used by --help and --version. */
|
|
||||||
|
|
||||||
struct plugin_info
|
|
||||||
{
|
|
||||||
const char *version;
|
|
||||||
const char *help;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Represents the gcc version. Used to avoid using an incompatible plugin. */
|
|
||||||
|
|
||||||
struct plugin_gcc_version
|
|
||||||
{
|
|
||||||
const char *basever;
|
|
||||||
const char *datestamp;
|
|
||||||
const char *devphase;
|
|
||||||
const char *revision;
|
|
||||||
const char *configuration_arguments;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Object that keeps track of the plugin name and its arguments. */
|
|
||||||
struct plugin_name_args
|
|
||||||
{
|
|
||||||
char *base_name; /* Short name of the plugin (filename without
|
|
||||||
.so suffix). */
|
|
||||||
const char *full_name; /* Path to the plugin as specified with
|
|
||||||
-fplugin=. */
|
|
||||||
int argc; /* Number of arguments specified with
|
|
||||||
-fplugin-arg-... */
|
|
||||||
struct plugin_argument *argv; /* Array of ARGC key-value pairs. */
|
|
||||||
const char *version; /* Version string provided by plugin. */
|
|
||||||
const char *help; /* Help string provided by plugin. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The default version check. Compares every field in VERSION. */
|
|
||||||
|
|
||||||
extern bool plugin_default_version_check (struct plugin_gcc_version *,
|
|
||||||
struct plugin_gcc_version *);
|
|
||||||
|
|
||||||
/* Function type for the plugin initialization routine. Each plugin module
|
|
||||||
should define this as an externally-visible function with name
|
|
||||||
"plugin_init."
|
|
||||||
|
|
||||||
PLUGIN_INFO - plugin invocation information.
|
|
||||||
VERSION - the plugin_gcc_version symbol of GCC.
|
|
||||||
|
|
||||||
Returns 0 if initialization finishes successfully. */
|
|
||||||
|
|
||||||
typedef int (*plugin_init_func) (struct plugin_name_args *plugin_info,
|
|
||||||
struct plugin_gcc_version *version);
|
|
||||||
|
|
||||||
/* Declaration for "plugin_init" function so that it doesn't need to be
|
|
||||||
duplicated in every plugin. */
|
|
||||||
extern int plugin_init (struct plugin_name_args *plugin_info,
|
|
||||||
struct plugin_gcc_version *version);
|
|
||||||
|
|
||||||
/* Function type for a plugin callback routine.
|
|
||||||
|
|
||||||
GCC_DATA - event-specific data provided by GCC
|
|
||||||
USER_DATA - plugin-specific data provided by the plugin */
|
|
||||||
|
|
||||||
typedef void (*plugin_callback_func) (void *gcc_data, void *user_data);
|
|
||||||
|
|
||||||
/* Called from the plugin's initialization code. Register a single callback.
|
|
||||||
This function can be called multiple times.
|
|
||||||
|
|
||||||
PLUGIN_NAME - display name for this plugin
|
|
||||||
EVENT - which event the callback is for
|
|
||||||
CALLBACK - the callback to be called at the event
|
|
||||||
USER_DATA - plugin-provided data.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Number of event ids / names registered so far. */
|
|
||||||
|
|
||||||
extern int get_event_last (void);
|
|
||||||
|
|
||||||
int get_named_event_id (const char *name, enum insert_option insert);
|
|
||||||
|
|
||||||
/* This is also called without a callback routine for the
|
|
||||||
PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, PLUGIN_REGISTER_GGC_ROOTS and
|
|
||||||
PLUGIN_REGISTER_GGC_CACHES pseudo-events, with a specific user_data.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern void register_callback (const char *plugin_name,
|
|
||||||
int event,
|
|
||||||
plugin_callback_func callback,
|
|
||||||
void *user_data);
|
|
||||||
|
|
||||||
extern int unregister_callback (const char *plugin_name, int event);
|
|
||||||
|
|
||||||
|
|
||||||
/* Retrieve the plugin directory name, as returned by the
|
|
||||||
-fprint-file-name=plugin argument to the gcc program, which is the
|
|
||||||
-iplugindir program argument to cc1. */
|
|
||||||
extern const char* default_plugin_dir_name (void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* In case the C++ compiler does name mangling for globals, declare
|
|
||||||
plugin_is_GPL_compatible extern "C" so that a later definition
|
|
||||||
in a plugin file will have this linkage. */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
extern int plugin_is_GPL_compatible;
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* GCC_PLUGIN_H */
|
|
1219
src/include/genrtl.h
1219
src/include/genrtl.h
File diff suppressed because it is too large
Load Diff
@ -1,279 +0,0 @@
|
|||||||
/* Garbage collection for the GNU compiler.
|
|
||||||
|
|
||||||
Copyright (C) 1998-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_GGC_H
|
|
||||||
#define GCC_GGC_H
|
|
||||||
#include "statistics.h"
|
|
||||||
|
|
||||||
/* Symbols are marked with `ggc' for `gcc gc' so as not to interfere with
|
|
||||||
an external gc library that might be linked in. */
|
|
||||||
|
|
||||||
/* Constants for general use. */
|
|
||||||
extern const char empty_string[]; /* empty string */
|
|
||||||
|
|
||||||
/* Internal functions and data structures used by the GTY
|
|
||||||
machinery, including the generated gt*.[hc] files. */
|
|
||||||
|
|
||||||
#include "gtype-desc.h"
|
|
||||||
|
|
||||||
/* One of these applies its third parameter (with cookie in the fourth
|
|
||||||
parameter) to each pointer in the object pointed to by the first
|
|
||||||
parameter, using the second parameter. */
|
|
||||||
typedef void (*gt_note_pointers) (void *, void *, gt_pointer_operator,
|
|
||||||
void *);
|
|
||||||
|
|
||||||
/* One of these is called before objects are re-ordered in memory.
|
|
||||||
The first parameter is the original object, the second is the
|
|
||||||
subobject that has had its pointers reordered, the third parameter
|
|
||||||
can compute the new values of a pointer when given the cookie in
|
|
||||||
the fourth parameter. */
|
|
||||||
typedef void (*gt_handle_reorder) (void *, void *, gt_pointer_operator,
|
|
||||||
void *);
|
|
||||||
|
|
||||||
/* Used by the gt_pch_n_* routines. Register an object in the hash table. */
|
|
||||||
extern int gt_pch_note_object (void *, void *, gt_note_pointers);
|
|
||||||
|
|
||||||
/* Used by the gt_pch_n_* routines. Register that an object has a reorder
|
|
||||||
function. */
|
|
||||||
extern void gt_pch_note_reorder (void *, void *, gt_handle_reorder);
|
|
||||||
|
|
||||||
/* Mark the object in the first parameter and anything it points to. */
|
|
||||||
typedef void (*gt_pointer_walker) (void *);
|
|
||||||
|
|
||||||
/* Structures for the easy way to mark roots.
|
|
||||||
In an array, terminated by having base == NULL. */
|
|
||||||
struct ggc_root_tab {
|
|
||||||
void *base;
|
|
||||||
size_t nelt;
|
|
||||||
size_t stride;
|
|
||||||
gt_pointer_walker cb;
|
|
||||||
gt_pointer_walker pchw;
|
|
||||||
};
|
|
||||||
#define LAST_GGC_ROOT_TAB { NULL, 0, 0, NULL, NULL }
|
|
||||||
/* Pointers to arrays of ggc_root_tab, terminated by NULL. */
|
|
||||||
extern const struct ggc_root_tab * const gt_ggc_rtab[];
|
|
||||||
extern const struct ggc_root_tab * const gt_ggc_deletable_rtab[];
|
|
||||||
extern const struct ggc_root_tab * const gt_pch_cache_rtab[];
|
|
||||||
extern const struct ggc_root_tab * const gt_pch_scalar_rtab[];
|
|
||||||
|
|
||||||
/* Structure for hash table cache marking. */
|
|
||||||
struct htab;
|
|
||||||
struct ggc_cache_tab {
|
|
||||||
struct htab * *base;
|
|
||||||
size_t nelt;
|
|
||||||
size_t stride;
|
|
||||||
gt_pointer_walker cb;
|
|
||||||
gt_pointer_walker pchw;
|
|
||||||
int (*marked_p) (const void *);
|
|
||||||
};
|
|
||||||
#define LAST_GGC_CACHE_TAB { NULL, 0, 0, NULL, NULL, NULL }
|
|
||||||
/* Pointers to arrays of ggc_cache_tab, terminated by NULL. */
|
|
||||||
extern const struct ggc_cache_tab * const gt_ggc_cache_rtab[];
|
|
||||||
|
|
||||||
/* If EXPR is not NULL and previously unmarked, mark it and evaluate
|
|
||||||
to true. Otherwise evaluate to false. */
|
|
||||||
#define ggc_test_and_set_mark(EXPR) \
|
|
||||||
((EXPR) != NULL && ((void *) (EXPR)) != (void *) 1 && ! ggc_set_mark (EXPR))
|
|
||||||
|
|
||||||
#define ggc_mark(EXPR) \
|
|
||||||
do { \
|
|
||||||
const void *const a__ = (EXPR); \
|
|
||||||
if (a__ != NULL && a__ != (void *) 1) \
|
|
||||||
ggc_set_mark (a__); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* Actually set the mark on a particular region of memory, but don't
|
|
||||||
follow pointers. This function is called by ggc_mark_*. It
|
|
||||||
returns zero if the object was not previously marked; nonzero if
|
|
||||||
the object was already marked, or if, for any other reason,
|
|
||||||
pointers in this data structure should not be traversed. */
|
|
||||||
extern int ggc_set_mark (const void *);
|
|
||||||
|
|
||||||
/* Return 1 if P has been marked, zero otherwise.
|
|
||||||
P must have been allocated by the GC allocator; it mustn't point to
|
|
||||||
static objects, stack variables, or memory allocated with malloc. */
|
|
||||||
extern int ggc_marked_p (const void *);
|
|
||||||
|
|
||||||
/* PCH and GGC handling for strings, mostly trivial. */
|
|
||||||
extern void gt_pch_n_S (const void *);
|
|
||||||
extern void gt_ggc_m_S (const void *);
|
|
||||||
|
|
||||||
/* End of GTY machinery API. */
|
|
||||||
|
|
||||||
/* Initialize the string pool. */
|
|
||||||
extern void init_stringpool (void);
|
|
||||||
|
|
||||||
/* Initialize the garbage collector. */
|
|
||||||
extern void init_ggc (void);
|
|
||||||
|
|
||||||
/* When true, identifier nodes are considered as GC roots. When
|
|
||||||
false, identifier nodes are treated like any other GC-allocated
|
|
||||||
object, and the identifier hash table is treated as a weak
|
|
||||||
hash. */
|
|
||||||
extern bool ggc_protect_identifiers;
|
|
||||||
|
|
||||||
/* Write out all GCed objects to F. */
|
|
||||||
extern void gt_pch_save (FILE *f);
|
|
||||||
|
|
||||||
|
|
||||||
/* Allocation. */
|
|
||||||
|
|
||||||
/* The internal primitive. */
|
|
||||||
extern void *ggc_internal_alloc_stat (size_t MEM_STAT_DECL)
|
|
||||||
ATTRIBUTE_MALLOC;
|
|
||||||
|
|
||||||
extern size_t ggc_round_alloc_size (size_t requested_size);
|
|
||||||
|
|
||||||
#define ggc_internal_alloc(s) ggc_internal_alloc_stat (s MEM_STAT_INFO)
|
|
||||||
|
|
||||||
/* Allocates cleared memory. */
|
|
||||||
extern void *ggc_internal_cleared_alloc_stat (size_t MEM_STAT_DECL)
|
|
||||||
ATTRIBUTE_MALLOC;
|
|
||||||
|
|
||||||
/* Resize a block. */
|
|
||||||
extern void *ggc_realloc_stat (void *, size_t MEM_STAT_DECL);
|
|
||||||
|
|
||||||
/* Free a block. To be used when known for certain it's not reachable. */
|
|
||||||
extern void ggc_free (void *);
|
|
||||||
|
|
||||||
extern void dump_ggc_loc_statistics (bool);
|
|
||||||
|
|
||||||
/* Reallocators. */
|
|
||||||
#define GGC_RESIZEVEC(T, P, N) \
|
|
||||||
((T *) ggc_realloc_stat ((P), (N) * sizeof (T) MEM_STAT_INFO))
|
|
||||||
|
|
||||||
#define GGC_RESIZEVAR(T, P, N) \
|
|
||||||
((T *) ggc_realloc_stat ((P), (N) MEM_STAT_INFO))
|
|
||||||
|
|
||||||
static inline void *
|
|
||||||
ggc_internal_vec_alloc_stat (size_t s, size_t c MEM_STAT_DECL)
|
|
||||||
{
|
|
||||||
return ggc_internal_alloc_stat (c * s PASS_MEM_STAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void *
|
|
||||||
ggc_internal_cleared_vec_alloc_stat (size_t s, size_t c MEM_STAT_DECL)
|
|
||||||
{
|
|
||||||
return ggc_internal_cleared_alloc_stat (c * s PASS_MEM_STAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ggc_internal_cleared_vec_alloc(s, c) \
|
|
||||||
(ggc_internal_cleared_vec_alloc_stat ((s), (c) MEM_STAT_INFO))
|
|
||||||
|
|
||||||
static inline void *
|
|
||||||
ggc_alloc_atomic_stat (size_t s MEM_STAT_DECL)
|
|
||||||
{
|
|
||||||
return ggc_internal_alloc_stat (s PASS_MEM_STAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ggc_alloc_atomic(S) (ggc_alloc_atomic_stat ((S) MEM_STAT_INFO))
|
|
||||||
|
|
||||||
#define ggc_alloc_cleared_atomic(S) \
|
|
||||||
(ggc_internal_cleared_alloc_stat ((S) MEM_STAT_INFO))
|
|
||||||
|
|
||||||
extern void *ggc_cleared_alloc_htab_ignore_args (size_t, size_t)
|
|
||||||
ATTRIBUTE_MALLOC;
|
|
||||||
|
|
||||||
extern void *ggc_cleared_alloc_ptr_array_two_args (size_t, size_t)
|
|
||||||
ATTRIBUTE_MALLOC;
|
|
||||||
|
|
||||||
#define htab_create_ggc(SIZE, HASH, EQ, DEL) \
|
|
||||||
htab_create_typed_alloc (SIZE, HASH, EQ, DEL, \
|
|
||||||
ggc_cleared_alloc_htab_ignore_args, \
|
|
||||||
ggc_cleared_alloc_ptr_array_two_args, \
|
|
||||||
ggc_free)
|
|
||||||
|
|
||||||
#define splay_tree_new_ggc(COMPARE, ALLOC_TREE, ALLOC_NODE) \
|
|
||||||
splay_tree_new_typed_alloc (COMPARE, NULL, NULL, &ALLOC_TREE, &ALLOC_NODE, \
|
|
||||||
&ggc_splay_dont_free, NULL)
|
|
||||||
|
|
||||||
extern void *ggc_splay_alloc (int, void *)
|
|
||||||
ATTRIBUTE_MALLOC;
|
|
||||||
|
|
||||||
extern void ggc_splay_dont_free (void *, void *);
|
|
||||||
|
|
||||||
/* Allocate a gc-able string, and fill it with LENGTH bytes from CONTENTS.
|
|
||||||
If LENGTH is -1, then CONTENTS is assumed to be a
|
|
||||||
null-terminated string and the memory sized accordingly. */
|
|
||||||
extern const char *ggc_alloc_string_stat (const char *contents, int length
|
|
||||||
MEM_STAT_DECL);
|
|
||||||
|
|
||||||
#define ggc_alloc_string(c, l) ggc_alloc_string_stat (c, l MEM_STAT_INFO)
|
|
||||||
|
|
||||||
/* Make a copy of S, in GC-able memory. */
|
|
||||||
#define ggc_strdup(S) ggc_alloc_string_stat ((S), -1 MEM_STAT_INFO)
|
|
||||||
|
|
||||||
/* Invoke the collector. Garbage collection occurs only when this
|
|
||||||
function is called, not during allocations. */
|
|
||||||
extern void ggc_collect (void);
|
|
||||||
|
|
||||||
/* Register an additional root table. This can be useful for some
|
|
||||||
plugins. Does nothing if the passed pointer is NULL. */
|
|
||||||
extern void ggc_register_root_tab (const struct ggc_root_tab *);
|
|
||||||
|
|
||||||
/* Register an additional cache table. This can be useful for some
|
|
||||||
plugins. Does nothing if the passed pointer is NULL. */
|
|
||||||
extern void ggc_register_cache_tab (const struct ggc_cache_tab *);
|
|
||||||
|
|
||||||
/* Read objects previously saved with gt_pch_save from F. */
|
|
||||||
extern void gt_pch_restore (FILE *f);
|
|
||||||
|
|
||||||
/* Statistics. */
|
|
||||||
|
|
||||||
/* Print allocation statistics. */
|
|
||||||
extern void ggc_print_statistics (void);
|
|
||||||
|
|
||||||
extern void stringpool_statistics (void);
|
|
||||||
|
|
||||||
/* Heuristics. */
|
|
||||||
extern void init_ggc_heuristics (void);
|
|
||||||
|
|
||||||
#define ggc_alloc_rtvec_sized(NELT) \
|
|
||||||
ggc_alloc_rtvec_def (sizeof (struct rtvec_def) \
|
|
||||||
+ ((NELT) - 1) * sizeof (rtx)) \
|
|
||||||
|
|
||||||
/* Memory statistics passing versions of some allocators. Too few of them to
|
|
||||||
make gengtype produce them, so just define the needed ones here. */
|
|
||||||
static inline struct rtx_def *
|
|
||||||
ggc_alloc_rtx_def_stat (size_t s MEM_STAT_DECL)
|
|
||||||
{
|
|
||||||
return (struct rtx_def *) ggc_internal_alloc_stat (s PASS_MEM_STAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline union tree_node *
|
|
||||||
ggc_alloc_tree_node_stat (size_t s MEM_STAT_DECL)
|
|
||||||
{
|
|
||||||
return (union tree_node *) ggc_internal_alloc_stat (s PASS_MEM_STAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline union tree_node *
|
|
||||||
ggc_alloc_cleared_tree_node_stat (size_t s MEM_STAT_DECL)
|
|
||||||
{
|
|
||||||
return (union tree_node *) ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline union gimple_statement_d *
|
|
||||||
ggc_alloc_cleared_gimple_statement_d_stat (size_t s MEM_STAT_DECL)
|
|
||||||
{
|
|
||||||
return (union gimple_statement_d *)
|
|
||||||
ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,36 +0,0 @@
|
|||||||
/* Various declarations for pretty formatting of GIMPLE statements and
|
|
||||||
expressions.
|
|
||||||
Copyright (C) 2000-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_GIMPLE_PRETTY_PRINT_H
|
|
||||||
#define GCC_GIMPLE_PRETTY_PRINT_H
|
|
||||||
|
|
||||||
#include "pretty-print.h"
|
|
||||||
#include "tree-pretty-print.h"
|
|
||||||
|
|
||||||
/* In gimple-pretty-print.c */
|
|
||||||
extern void debug_gimple_stmt (gimple);
|
|
||||||
extern void debug_gimple_seq (gimple_seq);
|
|
||||||
extern void print_gimple_seq (FILE *, gimple_seq, int, int);
|
|
||||||
extern void print_gimple_stmt (FILE *, gimple, int, int);
|
|
||||||
extern void print_gimple_expr (FILE *, gimple, int, int);
|
|
||||||
extern void pp_gimple_stmt_1 (pretty_printer *, gimple, int, int);
|
|
||||||
extern void gimple_dump_bb_for_graph (pretty_printer *, basic_block);
|
|
||||||
|
|
||||||
#endif /* ! GCC_GIMPLE_PRETTY_PRINT_H */
|
|
@ -1,364 +0,0 @@
|
|||||||
/* This file contains the definitions of the GIMPLE IR tuples used in GCC.
|
|
||||||
|
|
||||||
Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Aldy Hernandez <aldyh@redhat.com>
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* The format of this file is
|
|
||||||
DEFGSCODE(GIMPLE_symbol, printable name, GSS_symbol). */
|
|
||||||
|
|
||||||
|
|
||||||
/* Error marker. This is used in similar ways as ERROR_MARK in tree.def. */
|
|
||||||
DEFGSCODE(GIMPLE_ERROR_MARK, "gimple_error_mark", GSS_BASE)
|
|
||||||
|
|
||||||
/* IMPORTANT. Do not rearrange the codes between GIMPLE_COND and
|
|
||||||
GIMPLE_RETURN. The ordering is exposed by gimple_has_ops calls.
|
|
||||||
These are all the GIMPLE statements with register operands. */
|
|
||||||
|
|
||||||
/* GIMPLE_COND <COND_CODE, OP1, OP2, TRUE_LABEL, FALSE_LABEL>
|
|
||||||
represents the conditional jump:
|
|
||||||
|
|
||||||
if (OP1 COND_CODE OP2) goto TRUE_LABEL else goto FALSE_LABEL
|
|
||||||
|
|
||||||
COND_CODE is the tree code used as the comparison predicate. It
|
|
||||||
must be of class tcc_comparison.
|
|
||||||
|
|
||||||
OP1 and OP2 are the operands used in the comparison. They must be
|
|
||||||
accepted by is_gimple_operand.
|
|
||||||
|
|
||||||
TRUE_LABEL and FALSE_LABEL are the LABEL_DECL nodes used as the
|
|
||||||
jump target for the comparison. */
|
|
||||||
DEFGSCODE(GIMPLE_COND, "gimple_cond", GSS_WITH_OPS)
|
|
||||||
|
|
||||||
/* GIMPLE_DEBUG represents a debug statement. */
|
|
||||||
DEFGSCODE(GIMPLE_DEBUG, "gimple_debug", GSS_WITH_OPS)
|
|
||||||
|
|
||||||
/* GIMPLE_GOTO <TARGET> represents unconditional jumps.
|
|
||||||
TARGET is a LABEL_DECL or an expression node for computed GOTOs. */
|
|
||||||
DEFGSCODE(GIMPLE_GOTO, "gimple_goto", GSS_WITH_OPS)
|
|
||||||
|
|
||||||
/* GIMPLE_LABEL <LABEL> represents label statements. LABEL is a
|
|
||||||
LABEL_DECL representing a jump target. */
|
|
||||||
DEFGSCODE(GIMPLE_LABEL, "gimple_label", GSS_WITH_OPS)
|
|
||||||
|
|
||||||
/* GIMPLE_SWITCH <INDEX, DEFAULT_LAB, LAB1, ..., LABN> represents the
|
|
||||||
multiway branch:
|
|
||||||
|
|
||||||
switch (INDEX)
|
|
||||||
{
|
|
||||||
case LAB1: ...; break;
|
|
||||||
...
|
|
||||||
case LABN: ...; break;
|
|
||||||
default: ...
|
|
||||||
}
|
|
||||||
|
|
||||||
INDEX is the variable evaluated to decide which label to jump to.
|
|
||||||
|
|
||||||
DEFAULT_LAB, LAB1 ... LABN are the tree nodes representing case labels.
|
|
||||||
They must be CASE_LABEL_EXPR nodes. */
|
|
||||||
DEFGSCODE(GIMPLE_SWITCH, "gimple_switch", GSS_WITH_OPS)
|
|
||||||
|
|
||||||
/* IMPORTANT.
|
|
||||||
|
|
||||||
Do not rearrange the codes between GIMPLE_ASSIGN and GIMPLE_RETURN.
|
|
||||||
It's exposed by GIMPLE_RANGE_CHECK calls. These are all the GIMPLE
|
|
||||||
statements with memory and register operands. */
|
|
||||||
|
|
||||||
/* GIMPLE_ASSIGN <SUBCODE, LHS, RHS1[, RHS2]> represents the assignment
|
|
||||||
statement
|
|
||||||
|
|
||||||
LHS = RHS1 SUBCODE RHS2.
|
|
||||||
|
|
||||||
SUBCODE is the tree code for the expression computed by the RHS of the
|
|
||||||
assignment. It must be one of the tree codes accepted by
|
|
||||||
get_gimple_rhs_class. If LHS is not a gimple register according to
|
|
||||||
is_gimple_reg, SUBCODE must be of class GIMPLE_SINGLE_RHS.
|
|
||||||
|
|
||||||
LHS is the operand on the LHS of the assignment. It must be a tree node
|
|
||||||
accepted by is_gimple_lvalue.
|
|
||||||
|
|
||||||
RHS1 is the first operand on the RHS of the assignment. It must always be
|
|
||||||
present. It must be a tree node accepted by is_gimple_val.
|
|
||||||
|
|
||||||
RHS2 is the second operand on the RHS of the assignment. It must be a tree
|
|
||||||
node accepted by is_gimple_val. This argument exists only if SUBCODE is
|
|
||||||
of class GIMPLE_BINARY_RHS. */
|
|
||||||
DEFGSCODE(GIMPLE_ASSIGN, "gimple_assign", GSS_WITH_MEM_OPS)
|
|
||||||
|
|
||||||
/* GIMPLE_ASM <STRING, I1, ..., IN, O1, ... OM, C1, ..., CP>
|
|
||||||
represents inline assembly statements.
|
|
||||||
|
|
||||||
STRING is the string containing the assembly statements.
|
|
||||||
I1 ... IN are the N input operands.
|
|
||||||
O1 ... OM are the M output operands.
|
|
||||||
C1 ... CP are the P clobber operands.
|
|
||||||
L1 ... LQ are the Q label operands. */
|
|
||||||
DEFGSCODE(GIMPLE_ASM, "gimple_asm", GSS_ASM)
|
|
||||||
|
|
||||||
/* GIMPLE_CALL <FN, LHS, ARG1, ..., ARGN[, CHAIN]> represents function
|
|
||||||
calls.
|
|
||||||
|
|
||||||
FN is the callee. It must be accepted by is_gimple_call_addr.
|
|
||||||
|
|
||||||
LHS is the operand where the return value from FN is stored. It may
|
|
||||||
be NULL.
|
|
||||||
|
|
||||||
ARG1 ... ARGN are the arguments. They must all be accepted by
|
|
||||||
is_gimple_operand.
|
|
||||||
|
|
||||||
CHAIN is the optional static chain link for nested functions. */
|
|
||||||
DEFGSCODE(GIMPLE_CALL, "gimple_call", GSS_CALL)
|
|
||||||
|
|
||||||
/* GIMPLE_TRANSACTION <BODY, LABEL> represents __transaction_atomic and
|
|
||||||
__transaction_relaxed blocks.
|
|
||||||
BODY is the sequence of statements inside the transaction.
|
|
||||||
LABEL is a label for the statement immediately following the
|
|
||||||
transaction. This is before RETURN so that it has MEM_OPS,
|
|
||||||
so that it can clobber global memory. */
|
|
||||||
DEFGSCODE(GIMPLE_TRANSACTION, "gimple_transaction", GSS_TRANSACTION)
|
|
||||||
|
|
||||||
/* GIMPLE_RETURN <RETVAL> represents return statements.
|
|
||||||
|
|
||||||
RETVAL is the value to return or NULL. If a value is returned it
|
|
||||||
must be accepted by is_gimple_operand. */
|
|
||||||
DEFGSCODE(GIMPLE_RETURN, "gimple_return", GSS_WITH_MEM_OPS)
|
|
||||||
|
|
||||||
/* GIMPLE_BIND <VARS, BLOCK, BODY> represents a lexical scope.
|
|
||||||
VARS is the set of variables declared in that scope.
|
|
||||||
BLOCK is the symbol binding block used for debug information.
|
|
||||||
BODY is the sequence of statements in the scope. */
|
|
||||||
DEFGSCODE(GIMPLE_BIND, "gimple_bind", GSS_BIND)
|
|
||||||
|
|
||||||
/* GIMPLE_CATCH <TYPES, HANDLER> represents a typed exception handler.
|
|
||||||
TYPES is the type (or list of types) handled. HANDLER is the
|
|
||||||
sequence of statements that handle these types. */
|
|
||||||
DEFGSCODE(GIMPLE_CATCH, "gimple_catch", GSS_CATCH)
|
|
||||||
|
|
||||||
/* GIMPLE_EH_FILTER <TYPES, FAILURE> represents an exception
|
|
||||||
specification. TYPES is a list of allowed types and FAILURE is the
|
|
||||||
sequence of statements to execute on failure. */
|
|
||||||
DEFGSCODE(GIMPLE_EH_FILTER, "gimple_eh_filter", GSS_EH_FILTER)
|
|
||||||
|
|
||||||
/* GIMPLE_EH_MUST_NOT_THROW <DECL> represents an exception barrier.
|
|
||||||
DECL is a noreturn function decl taking no arguments that will
|
|
||||||
be invoked if an exception propagates to this point. */
|
|
||||||
DEFGSCODE(GIMPLE_EH_MUST_NOT_THROW, "gimple_eh_must_not_throw", GSS_EH_MNT)
|
|
||||||
|
|
||||||
/* GIMPLE_EH_ELSE <N_BODY, E_BODY> must be the sole contents of
|
|
||||||
a GIMPLE_TRY_FINALLY node. For all normal exits from the try block,
|
|
||||||
N_BODY is run; for all exception exits from the try block,
|
|
||||||
E_BODY is run. */
|
|
||||||
DEFGSCODE(GIMPLE_EH_ELSE, "gimple_eh_else", GSS_EH_ELSE)
|
|
||||||
|
|
||||||
/* GIMPLE_RESX resumes execution after an exception. */
|
|
||||||
DEFGSCODE(GIMPLE_RESX, "gimple_resx", GSS_EH_CTRL)
|
|
||||||
|
|
||||||
/* GIMPLE_EH_DISPATCH demultiplexes an exception edge based on
|
|
||||||
the FILTER argument. */
|
|
||||||
DEFGSCODE(GIMPLE_EH_DISPATCH, "gimple_eh_dispatch", GSS_EH_CTRL)
|
|
||||||
|
|
||||||
/* GIMPLE_PHI <RESULT, ARG1, ..., ARGN> represents the PHI node
|
|
||||||
|
|
||||||
RESULT = PHI <ARG1, ..., ARGN>
|
|
||||||
|
|
||||||
RESULT is the SSA name created by this PHI node.
|
|
||||||
|
|
||||||
ARG1 ... ARGN are the arguments to the PHI node. N must be
|
|
||||||
exactly the same as the number of incoming edges to the basic block
|
|
||||||
holding the PHI node. Every argument is either an SSA name or a
|
|
||||||
tree node of class tcc_constant. */
|
|
||||||
DEFGSCODE(GIMPLE_PHI, "gimple_phi", GSS_PHI)
|
|
||||||
|
|
||||||
/* GIMPLE_TRY <TRY_KIND, EVAL, CLEANUP>
|
|
||||||
represents a try/catch or a try/finally statement.
|
|
||||||
|
|
||||||
TRY_KIND is either GIMPLE_TRY_CATCH or GIMPLE_TRY_FINALLY.
|
|
||||||
|
|
||||||
EVAL is the sequence of statements to execute on entry to GIMPLE_TRY.
|
|
||||||
|
|
||||||
CLEANUP is the sequence of statements to execute according to
|
|
||||||
TRY_KIND. If TRY_KIND is GIMPLE_TRY_CATCH, CLEANUP is only exected
|
|
||||||
if an exception is thrown during execution of EVAL. If TRY_KIND is
|
|
||||||
GIMPLE_TRY_FINALLY, CLEANUP is always executed after executing EVAL
|
|
||||||
(regardless of whether EVAL finished normally, or jumped out or an
|
|
||||||
exception was thrown). */
|
|
||||||
DEFGSCODE(GIMPLE_TRY, "gimple_try", GSS_TRY)
|
|
||||||
|
|
||||||
/* GIMPLE_NOP represents the "do nothing" statement. */
|
|
||||||
DEFGSCODE(GIMPLE_NOP, "gimple_nop", GSS_BASE)
|
|
||||||
|
|
||||||
|
|
||||||
/* IMPORTANT.
|
|
||||||
|
|
||||||
Do not rearrange any of the GIMPLE_OMP_* codes. This ordering is
|
|
||||||
exposed by the range check in gimple_omp_subcode(). */
|
|
||||||
|
|
||||||
|
|
||||||
/* Tuples used for lowering of OMP_ATOMIC. Although the form of the OMP_ATOMIC
|
|
||||||
expression is very simple (just in form mem op= expr), various implicit
|
|
||||||
conversions may cause the expression to become more complex, so that it does
|
|
||||||
not fit the gimple grammar very well. To overcome this problem, OMP_ATOMIC
|
|
||||||
is rewritten as a sequence of two codes in gimplification:
|
|
||||||
|
|
||||||
GIMPLE_OMP_LOAD (tmp, mem)
|
|
||||||
val = some computations involving tmp;
|
|
||||||
GIMPLE_OMP_STORE (val). */
|
|
||||||
DEFGSCODE(GIMPLE_OMP_ATOMIC_LOAD, "gimple_omp_atomic_load",
|
|
||||||
GSS_OMP_ATOMIC_LOAD)
|
|
||||||
DEFGSCODE(GIMPLE_OMP_ATOMIC_STORE, "gimple_omp_atomic_store",
|
|
||||||
GSS_OMP_ATOMIC_STORE)
|
|
||||||
|
|
||||||
/* GIMPLE_OMP_CONTINUE marks the location of the loop or sections
|
|
||||||
iteration in partially lowered OpenMP code. */
|
|
||||||
DEFGSCODE(GIMPLE_OMP_CONTINUE, "gimple_omp_continue", GSS_OMP_CONTINUE)
|
|
||||||
|
|
||||||
/* GIMPLE_OMP_CRITICAL <NAME, BODY> represents
|
|
||||||
|
|
||||||
#pragma omp critical [name]
|
|
||||||
|
|
||||||
NAME is the name given to the critical section.
|
|
||||||
BODY is the sequence of statements that are inside the critical section. */
|
|
||||||
DEFGSCODE(GIMPLE_OMP_CRITICAL, "gimple_omp_critical", GSS_OMP_CRITICAL)
|
|
||||||
|
|
||||||
/* GIMPLE_OMP_FOR <BODY, CLAUSES, INDEX, INITIAL, FINAL, COND, INCR, PRE_BODY>
|
|
||||||
represents
|
|
||||||
|
|
||||||
PRE_BODY
|
|
||||||
#pragma omp for [clause1 ... clauseN]
|
|
||||||
for (INDEX = INITIAL; INDEX COND FINAL; INDEX {+=,-=} INCR)
|
|
||||||
BODY
|
|
||||||
|
|
||||||
BODY is the loop body.
|
|
||||||
|
|
||||||
CLAUSES is the list of clauses.
|
|
||||||
|
|
||||||
INDEX must be an integer or pointer variable, which is implicitly thread
|
|
||||||
private. It must be accepted by is_gimple_operand.
|
|
||||||
|
|
||||||
INITIAL is the initial value given to INDEX. It must be
|
|
||||||
accepted by is_gimple_operand.
|
|
||||||
|
|
||||||
FINAL is the final value that INDEX should take. It must
|
|
||||||
be accepted by is_gimple_operand.
|
|
||||||
|
|
||||||
COND is the condition code for the controlling predicate. It must
|
|
||||||
be one of { <, >, <=, >= }
|
|
||||||
|
|
||||||
INCR is the loop index increment. It must be tree node of type
|
|
||||||
tcc_constant.
|
|
||||||
|
|
||||||
PRE_BODY is a landing pad filled by the gimplifier with things from
|
|
||||||
INIT, COND, and INCR that are technically part of the OMP_FOR
|
|
||||||
structured block, but are evaluated before the loop body begins.
|
|
||||||
|
|
||||||
INITIAL, FINAL and INCR are required to be loop invariant integer
|
|
||||||
expressions that are evaluated without any synchronization.
|
|
||||||
The evaluation order, frequency of evaluation and side-effects are
|
|
||||||
unspecified by the standard. */
|
|
||||||
DEFGSCODE(GIMPLE_OMP_FOR, "gimple_omp_for", GSS_OMP_FOR)
|
|
||||||
|
|
||||||
/* GIMPLE_OMP_MASTER <BODY> represents #pragma omp master.
|
|
||||||
BODY is the sequence of statements to execute in the master section. */
|
|
||||||
DEFGSCODE(GIMPLE_OMP_MASTER, "gimple_omp_master", GSS_OMP)
|
|
||||||
|
|
||||||
/* GIMPLE_OMP_ORDERED <BODY> represents #pragma omp ordered.
|
|
||||||
BODY is the sequence of statements to execute in the ordered section. */
|
|
||||||
DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", GSS_OMP)
|
|
||||||
|
|
||||||
/* GIMPLE_OMP_PARALLEL <BODY, CLAUSES, CHILD_FN, DATA_ARG> represents
|
|
||||||
|
|
||||||
#pragma omp parallel [CLAUSES]
|
|
||||||
BODY
|
|
||||||
|
|
||||||
BODY is a the sequence of statements to be executed by all threads.
|
|
||||||
|
|
||||||
CLAUSES is a TREE_LIST node with all the clauses.
|
|
||||||
|
|
||||||
CHILD_FN is set when outlining the body of the parallel region.
|
|
||||||
All the statements in BODY are moved into this newly created
|
|
||||||
function when converting OMP constructs into low-GIMPLE.
|
|
||||||
|
|
||||||
DATA_ARG is a local variable in the parent function containing data
|
|
||||||
to be shared with CHILD_FN. This is used to implement all the data
|
|
||||||
sharing clauses. */
|
|
||||||
DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL)
|
|
||||||
|
|
||||||
/* GIMPLE_OMP_TASK <BODY, CLAUSES, CHILD_FN, DATA_ARG, COPY_FN,
|
|
||||||
ARG_SIZE, ARG_ALIGN> represents
|
|
||||||
|
|
||||||
#pragma omp task [CLAUSES]
|
|
||||||
BODY
|
|
||||||
|
|
||||||
BODY is a the sequence of statements to be executed by all threads.
|
|
||||||
|
|
||||||
CLAUSES is a TREE_LIST node with all the clauses.
|
|
||||||
|
|
||||||
CHILD_FN is set when outlining the body of the explicit task region.
|
|
||||||
All the statements in BODY are moved into this newly created
|
|
||||||
function when converting OMP constructs into low-GIMPLE.
|
|
||||||
|
|
||||||
DATA_ARG is a local variable in the parent function containing data
|
|
||||||
to be shared with CHILD_FN. This is used to implement all the data
|
|
||||||
sharing clauses.
|
|
||||||
|
|
||||||
COPY_FN is set when outlining the firstprivate var initialization.
|
|
||||||
All the needed statements are emitted into the newly created
|
|
||||||
function, or when only memcpy is needed, it is NULL.
|
|
||||||
|
|
||||||
ARG_SIZE and ARG_ALIGN are the size and alignment of the incoming
|
|
||||||
data area allocated by GOMP_task and passed to CHILD_FN. */
|
|
||||||
DEFGSCODE(GIMPLE_OMP_TASK, "gimple_omp_task", GSS_OMP_TASK)
|
|
||||||
|
|
||||||
/* OMP_RETURN marks the end of an OpenMP directive. */
|
|
||||||
DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_BASE)
|
|
||||||
|
|
||||||
/* OMP_SECTION <BODY> represents #pragma omp section.
|
|
||||||
BODY is the sequence of statements in the section body. */
|
|
||||||
DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", GSS_OMP)
|
|
||||||
|
|
||||||
/* OMP_SECTIONS <BODY, CLAUSES, CONTROL> represents #pragma omp sections.
|
|
||||||
|
|
||||||
BODY is the sequence of statements in the sections body.
|
|
||||||
CLAUSES is a TREE_LIST node holding the list of associated clauses.
|
|
||||||
CONTROL is a VAR_DECL used for deciding which of the sections
|
|
||||||
to execute. */
|
|
||||||
DEFGSCODE(GIMPLE_OMP_SECTIONS, "gimple_omp_sections", GSS_OMP_SECTIONS)
|
|
||||||
|
|
||||||
/* GIMPLE_OMP_SECTIONS_SWITCH is a marker placed immediately after
|
|
||||||
OMP_SECTIONS. It represents the GIMPLE_SWITCH used to decide which
|
|
||||||
branch is taken. */
|
|
||||||
DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", GSS_BASE)
|
|
||||||
|
|
||||||
/* GIMPLE_OMP_SINGLE <BODY, CLAUSES> represents #pragma omp single
|
|
||||||
BODY is the sequence of statements inside the single section.
|
|
||||||
CLAUSES is a TREE_LIST node holding the associated clauses. */
|
|
||||||
DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE)
|
|
||||||
|
|
||||||
/* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction.
|
|
||||||
|
|
||||||
PREDICT is one of the predictors from predict.def.
|
|
||||||
|
|
||||||
OUTCOME is NOT_TAKEN or TAKEN. */
|
|
||||||
DEFGSCODE(GIMPLE_PREDICT, "gimple_predict", GSS_BASE)
|
|
||||||
|
|
||||||
/* This node represents a cleanup expression. It is ONLY USED INTERNALLY
|
|
||||||
by the gimplifier as a placeholder for cleanups, and its uses will be
|
|
||||||
cleaned up by the time gimplification is done.
|
|
||||||
|
|
||||||
This tuple should not exist outside of the gimplifier proper. */
|
|
||||||
DEFGSCODE(GIMPLE_WITH_CLEANUP_EXPR, "gimple_with_cleanup_expr", GSS_WCE)
|
|
5350
src/include/gimple.h
5350
src/include/gimple.h
File diff suppressed because it is too large
Load Diff
@ -1,53 +0,0 @@
|
|||||||
/* This file contains the definitions for the gimple IR structure
|
|
||||||
enumeration used in GCC.
|
|
||||||
|
|
||||||
Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
|
||||||
Contributed by Aldy Hernandez <aldyh@redhat.com>
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* The format of this file is
|
|
||||||
DEFGSSTRUCT(GSS enumeration value, structure name, has-tree-operands).
|
|
||||||
Each enum value should correspond with a single member of the union
|
|
||||||
gimple_statement_d. */
|
|
||||||
|
|
||||||
DEFGSSTRUCT(GSS_BASE, gimple_statement_base, false)
|
|
||||||
DEFGSSTRUCT(GSS_WITH_OPS, gimple_statement_with_ops, true)
|
|
||||||
DEFGSSTRUCT(GSS_WITH_MEM_OPS_BASE, gimple_statement_with_memory_ops_base, false)
|
|
||||||
DEFGSSTRUCT(GSS_WITH_MEM_OPS, gimple_statement_with_memory_ops, true)
|
|
||||||
DEFGSSTRUCT(GSS_CALL, gimple_statement_call, true)
|
|
||||||
DEFGSSTRUCT(GSS_ASM, gimple_statement_asm, true)
|
|
||||||
DEFGSSTRUCT(GSS_BIND, gimple_statement_bind, false)
|
|
||||||
DEFGSSTRUCT(GSS_PHI, gimple_statement_phi, false)
|
|
||||||
DEFGSSTRUCT(GSS_TRY, gimple_statement_try, false)
|
|
||||||
DEFGSSTRUCT(GSS_CATCH, gimple_statement_catch, false)
|
|
||||||
DEFGSSTRUCT(GSS_EH_FILTER, gimple_statement_eh_filter, false)
|
|
||||||
DEFGSSTRUCT(GSS_EH_MNT, gimple_statement_eh_mnt, false)
|
|
||||||
DEFGSSTRUCT(GSS_EH_CTRL, gimple_statement_eh_ctrl, false)
|
|
||||||
DEFGSSTRUCT(GSS_EH_ELSE, gimple_statement_eh_else, false)
|
|
||||||
DEFGSSTRUCT(GSS_WCE, gimple_statement_wce, false)
|
|
||||||
DEFGSSTRUCT(GSS_OMP, gimple_statement_omp, false)
|
|
||||||
DEFGSSTRUCT(GSS_OMP_CRITICAL, gimple_statement_omp_critical, false)
|
|
||||||
DEFGSSTRUCT(GSS_OMP_FOR, gimple_statement_omp_for, false)
|
|
||||||
DEFGSSTRUCT(GSS_OMP_PARALLEL, gimple_statement_omp_parallel, false)
|
|
||||||
DEFGSSTRUCT(GSS_OMP_TASK, gimple_statement_omp_task, false)
|
|
||||||
DEFGSSTRUCT(GSS_OMP_SECTIONS, gimple_statement_omp_sections, false)
|
|
||||||
DEFGSSTRUCT(GSS_OMP_SINGLE, gimple_statement_omp_single, false)
|
|
||||||
DEFGSSTRUCT(GSS_OMP_CONTINUE, gimple_statement_omp_continue, false)
|
|
||||||
DEFGSSTRUCT(GSS_OMP_ATOMIC_LOAD, gimple_statement_omp_atomic_load, false)
|
|
||||||
DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE, gimple_statement_omp_atomic_store, false)
|
|
||||||
DEFGSSTRUCT(GSS_TRANSACTION, gimple_statement_transaction, false)
|
|
@ -1,208 +0,0 @@
|
|||||||
DEF_TM_BUILTIN (BUILT_IN_TM_START, "_ITM_beginTransaction",
|
|
||||||
BT_FN_UINT32_UINT32_VAR, ATTR_TM_NOTHROW_RT_LIST)
|
|
||||||
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_COMMIT, "_ITM_commitTransaction",
|
|
||||||
BT_FN_VOID, ATTR_TM_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_COMMIT_EH, "_ITM_commitTransactionEH",
|
|
||||||
BT_FN_VOID_PTR, ATTR_TM_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_ABORT, "_ITM_abortTransaction",
|
|
||||||
BT_FN_VOID_INT, ATTR_TM_NORETURN_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_IRREVOCABLE, "_ITM_changeTransactionMode",
|
|
||||||
BT_FN_VOID_INT, ATTR_TM_NOTHROW_LIST)
|
|
||||||
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_MEMCPY, "_ITM_memcpyRtWt",
|
|
||||||
BT_FN_VOID_PTR_CONST_PTR_SIZE, ATTR_TM_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_MEMMOVE, "_ITM_memmoveRtWt",
|
|
||||||
BT_FN_VOID_PTR_CONST_PTR_SIZE, ATTR_TM_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_MEMSET, "_ITM_memsetW",
|
|
||||||
BT_FN_VOID_PTR_INT_SIZE, ATTR_TM_TMPURE_NOTHROW_LIST)
|
|
||||||
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_GETTMCLONE_IRR, "_ITM_getTMCloneOrIrrevocable",
|
|
||||||
BT_FN_PTR_PTR, ATTR_TM_CONST_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_GETTMCLONE_SAFE, "_ITM_getTMCloneSafe",
|
|
||||||
BT_FN_PTR_PTR, ATTR_TM_CONST_NOTHROW_LIST)
|
|
||||||
|
|
||||||
/* Memory allocation builtins. */
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_MALLOC, "_ITM_malloc",
|
|
||||||
BT_FN_PTR_SIZE, ATTR_TMPURE_MALLOC_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_CALLOC, "_ITM_calloc",
|
|
||||||
BT_FN_PTR_SIZE_SIZE, ATTR_TMPURE_MALLOC_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_FREE, "_ITM_free",
|
|
||||||
BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LIST)
|
|
||||||
|
|
||||||
/* Logging builtins. */
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_1, "_ITM_LU1",
|
|
||||||
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_2, "_ITM_LU2",
|
|
||||||
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_4, "_ITM_LU4",
|
|
||||||
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_8, "_ITM_LU8",
|
|
||||||
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_FLOAT, "_ITM_LF",
|
|
||||||
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_DOUBLE, "_ITM_LD",
|
|
||||||
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_LDOUBLE, "_ITM_LE",
|
|
||||||
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOG, "_ITM_LB",
|
|
||||||
BT_FN_VOID_VPTR_SIZE, ATTR_TM_TMPURE_NOTHROW_LIST)
|
|
||||||
|
|
||||||
/* These stubs should get defined in the backend if applicable. */
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOG_M64, "__builtin__ITM_LM64")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOG_M128, "__builtin__ITM_LM128")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOG_M256, "__builtin__ITM_LM256")
|
|
||||||
|
|
||||||
/* Writes.
|
|
||||||
|
|
||||||
Note: The writes must follow the following order: STORE, WAR, WAW.
|
|
||||||
The TM optimizations depend on this order.
|
|
||||||
|
|
||||||
BUILT_IN_TM_STORE_1 must be the first builtin.
|
|
||||||
BUILTIN_TM_LOAD_STORE_P depends on this. */
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_1, "_ITM_WU1",
|
|
||||||
BT_FN_VOID_VPTR_I1, ATTR_TM_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_1, "_ITM_WaRU1",
|
|
||||||
BT_FN_VOID_VPTR_I1, ATTR_TM_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_1, "_ITM_WaWU1",
|
|
||||||
BT_FN_VOID_VPTR_I1, ATTR_TM_NOTHROW_LIST)
|
|
||||||
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_2, "_ITM_WU2",
|
|
||||||
BT_FN_VOID_VPTR_I2, ATTR_TM_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_2, "_ITM_WaRU2",
|
|
||||||
BT_FN_VOID_VPTR_I2, ATTR_TM_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_2, "_ITM_WaWU2",
|
|
||||||
BT_FN_VOID_VPTR_I2, ATTR_TM_NOTHROW_LIST)
|
|
||||||
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_4, "_ITM_WU4",
|
|
||||||
BT_FN_VOID_VPTR_I4, ATTR_TM_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_4, "_ITM_WaRU4",
|
|
||||||
BT_FN_VOID_VPTR_I4, ATTR_TM_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_4, "_ITM_WaWU4",
|
|
||||||
BT_FN_VOID_VPTR_I4, ATTR_TM_NOTHROW_LIST)
|
|
||||||
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_8, "_ITM_WU8",
|
|
||||||
BT_FN_VOID_VPTR_I8, ATTR_TM_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_8, "_ITM_WaRU8",
|
|
||||||
BT_FN_VOID_VPTR_I8, ATTR_TM_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_8, "_ITM_WaWU8",
|
|
||||||
BT_FN_VOID_VPTR_I8, ATTR_TM_NOTHROW_LIST)
|
|
||||||
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_FLOAT, "_ITM_WF",
|
|
||||||
BT_FN_VOID_VPTR_FLOAT, ATTR_TM_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_FLOAT, "_ITM_WaRF",
|
|
||||||
BT_FN_VOID_VPTR_FLOAT, ATTR_TM_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_FLOAT, "_ITM_WaWF",
|
|
||||||
BT_FN_VOID_VPTR_FLOAT, ATTR_TM_NOTHROW_LIST)
|
|
||||||
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_DOUBLE, "_ITM_WD",
|
|
||||||
BT_FN_VOID_VPTR_DOUBLE, ATTR_TM_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_DOUBLE, "_ITM_WaRD",
|
|
||||||
BT_FN_VOID_VPTR_DOUBLE, ATTR_TM_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_DOUBLE, "_ITM_WaWD",
|
|
||||||
BT_FN_VOID_VPTR_DOUBLE, ATTR_TM_NOTHROW_LIST)
|
|
||||||
|
|
||||||
/* These stubs should get defined in the backend if applicable. */
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_M64, "__builtin__ITM_WM64")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAR_M64, "__builtin__ITM_WaRM64")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAW_M64, "__builtin__ITM_WaWM64")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_M128, "__builtin__ITM_WM128")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAR_M128, "__builtin__ITM_WaRM128")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAW_M128, "__builtin__ITM_WaWM128")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_M256, "__builtin__ITM_WM256")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAR_M256, "__builtin__ITM_WaRM256")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAW_M256, "__builtin__ITM_WaWM256")
|
|
||||||
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_LDOUBLE, "_ITM_WE",
|
|
||||||
BT_FN_VOID_VPTR_LDOUBLE, ATTR_TM_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_LDOUBLE, "_ITM_WaRE",
|
|
||||||
BT_FN_VOID_VPTR_LDOUBLE, ATTR_TM_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_LDOUBLE, "_ITM_WaWE",
|
|
||||||
BT_FN_VOID_VPTR_LDOUBLE, ATTR_TM_NOTHROW_LIST)
|
|
||||||
/* Note: BUILT_IN_TM_STORE_WAW_LDOUBLE must be the last TM store.
|
|
||||||
BUILTIN_TM_STORE_P depends on this. */
|
|
||||||
|
|
||||||
/* Reads.
|
|
||||||
|
|
||||||
Note: The reads must follow the following order: LOAD, RAR, RAW, RFW.
|
|
||||||
The TM optimizations depend on this order. */
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_1, "_ITM_RU1",
|
|
||||||
BT_FN_I1_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_1, "_ITM_RaRU1",
|
|
||||||
BT_FN_I1_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_1, "_ITM_RaWU1",
|
|
||||||
BT_FN_I1_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_1, "_ITM_RfWU1",
|
|
||||||
BT_FN_I1_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_2, "_ITM_RU2",
|
|
||||||
BT_FN_I2_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_2, "_ITM_RaRU2",
|
|
||||||
BT_FN_I2_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_2, "_ITM_RaWU2",
|
|
||||||
BT_FN_I2_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_2, "_ITM_RfWU2",
|
|
||||||
BT_FN_I2_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_4, "_ITM_RU4",
|
|
||||||
BT_FN_I4_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_4, "_ITM_RaRU4",
|
|
||||||
BT_FN_I4_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_4, "_ITM_RaWU4",
|
|
||||||
BT_FN_I4_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_4, "_ITM_RfWU4",
|
|
||||||
BT_FN_I4_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_8, "_ITM_RU8",
|
|
||||||
BT_FN_I8_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_8, "_ITM_RaRU8",
|
|
||||||
BT_FN_I8_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_8, "_ITM_RaWU8",
|
|
||||||
BT_FN_I8_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_8, "_ITM_RfWU8",
|
|
||||||
BT_FN_I8_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_FLOAT, "_ITM_RF",
|
|
||||||
BT_FN_FLOAT_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_FLOAT, "_ITM_RaRF",
|
|
||||||
BT_FN_FLOAT_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_FLOAT, "_ITM_RaWF",
|
|
||||||
BT_FN_FLOAT_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_FLOAT, "_ITM_RfWF",
|
|
||||||
BT_FN_FLOAT_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_DOUBLE, "_ITM_RD",
|
|
||||||
BT_FN_DOUBLE_CONST_DOUBLE_PTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_DOUBLE, "_ITM_RaRD",
|
|
||||||
BT_FN_DOUBLE_CONST_DOUBLE_PTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_DOUBLE, "_ITM_RaWD",
|
|
||||||
BT_FN_DOUBLE_CONST_DOUBLE_PTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_DOUBLE, "_ITM_RfWD",
|
|
||||||
BT_FN_DOUBLE_CONST_DOUBLE_PTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
|
|
||||||
/* These stubs should get defined in the backend if applicable. */
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_M64, "__builtin__ITM_RM64")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAR_M64, "__builtin__ITM_RaRM64")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAW_M64, "__builtin__ITM_RaRM64")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RFW_M64, "__builtin__ITM_RfWM64")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_M128, "__builtin__ITM_RM128")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAR_M128, "__builtin__ITM_RaRM128")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAW_M128, "__builtin__ITM_RaRM128")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RFW_M128, "__builtin__ITM_RfWM128")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_M256, "__builtin__ITM_RM256")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAR_M256, "__builtin__ITM_RaRM256")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAW_M256, "__builtin__ITM_RaRM256")
|
|
||||||
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RFW_M256, "__builtin__ITM_RfWM256")
|
|
||||||
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_LDOUBLE, "_ITM_RE",
|
|
||||||
BT_FN_LDOUBLE_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_LDOUBLE, "_ITM_RaRE",
|
|
||||||
BT_FN_LDOUBLE_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_LDOUBLE, "_ITM_RaWE",
|
|
||||||
BT_FN_LDOUBLE_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_LDOUBLE, "_ITM_RfWE",
|
|
||||||
BT_FN_LDOUBLE_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
|
||||||
|
|
||||||
/* Note: BUILT_IN_TM_LOAD_RFW_LDOUBLE must be the last TM load as well
|
|
||||||
as the last builtin. BUILTIN_TM_LOAD_STORE_P and BUILTIN_TM_LOAD_P
|
|
||||||
depend on this. */
|
|
File diff suppressed because it is too large
Load Diff
@ -1,724 +0,0 @@
|
|||||||
/* Sets (bit vectors) of hard registers, and operations on them.
|
|
||||||
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GCC
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef GCC_HARD_REG_SET_H
|
|
||||||
#define GCC_HARD_REG_SET_H
|
|
||||||
|
|
||||||
/* Define the type of a set of hard registers. */
|
|
||||||
|
|
||||||
/* HARD_REG_ELT_TYPE is a typedef of the unsigned integral type which
|
|
||||||
will be used for hard reg sets, either alone or in an array.
|
|
||||||
|
|
||||||
If HARD_REG_SET is a macro, its definition is HARD_REG_ELT_TYPE,
|
|
||||||
and it has enough bits to represent all the target machine's hard
|
|
||||||
registers. Otherwise, it is a typedef for a suitably sized array
|
|
||||||
of HARD_REG_ELT_TYPEs. HARD_REG_SET_LONGS is defined as how many.
|
|
||||||
|
|
||||||
Note that lots of code assumes that the first part of a regset is
|
|
||||||
the same format as a HARD_REG_SET. To help make sure this is true,
|
|
||||||
we only try the widest fast integer mode (HOST_WIDEST_FAST_INT)
|
|
||||||
instead of all the smaller types. This approach loses only if
|
|
||||||
there are very few registers and then only in the few cases where
|
|
||||||
we have an array of HARD_REG_SETs, so it needn't be as complex as
|
|
||||||
it used to be. */
|
|
||||||
|
|
||||||
typedef unsigned HOST_WIDEST_FAST_INT HARD_REG_ELT_TYPE;
|
|
||||||
|
|
||||||
#if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDEST_FAST_INT
|
|
||||||
|
|
||||||
#define HARD_REG_SET HARD_REG_ELT_TYPE
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define HARD_REG_SET_LONGS \
|
|
||||||
((FIRST_PSEUDO_REGISTER + HOST_BITS_PER_WIDEST_FAST_INT - 1) \
|
|
||||||
/ HOST_BITS_PER_WIDEST_FAST_INT)
|
|
||||||
typedef HARD_REG_ELT_TYPE HARD_REG_SET[HARD_REG_SET_LONGS];
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* HARD_REG_SET wrapped into a structure, to make it possible to
|
|
||||||
use HARD_REG_SET even in APIs that should not include
|
|
||||||
hard-reg-set.h. */
|
|
||||||
struct hard_reg_set_container
|
|
||||||
{
|
|
||||||
HARD_REG_SET set;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* HARD_CONST is used to cast a constant to the appropriate type
|
|
||||||
for use with a HARD_REG_SET. */
|
|
||||||
|
|
||||||
#define HARD_CONST(X) ((HARD_REG_ELT_TYPE) (X))
|
|
||||||
|
|
||||||
/* Define macros SET_HARD_REG_BIT, CLEAR_HARD_REG_BIT and TEST_HARD_REG_BIT
|
|
||||||
to set, clear or test one bit in a hard reg set of type HARD_REG_SET.
|
|
||||||
All three take two arguments: the set and the register number.
|
|
||||||
|
|
||||||
In the case where sets are arrays of longs, the first argument
|
|
||||||
is actually a pointer to a long.
|
|
||||||
|
|
||||||
Define two macros for initializing a set:
|
|
||||||
CLEAR_HARD_REG_SET and SET_HARD_REG_SET.
|
|
||||||
These take just one argument.
|
|
||||||
|
|
||||||
Also define macros for copying hard reg sets:
|
|
||||||
COPY_HARD_REG_SET and COMPL_HARD_REG_SET.
|
|
||||||
These take two arguments TO and FROM; they read from FROM
|
|
||||||
and store into TO. COMPL_HARD_REG_SET complements each bit.
|
|
||||||
|
|
||||||
Also define macros for combining hard reg sets:
|
|
||||||
IOR_HARD_REG_SET and AND_HARD_REG_SET.
|
|
||||||
These take two arguments TO and FROM; they read from FROM
|
|
||||||
and combine bitwise into TO. Define also two variants
|
|
||||||
IOR_COMPL_HARD_REG_SET and AND_COMPL_HARD_REG_SET
|
|
||||||
which use the complement of the set FROM.
|
|
||||||
|
|
||||||
Also define:
|
|
||||||
|
|
||||||
hard_reg_set_subset_p (X, Y), which returns true if X is a subset of Y.
|
|
||||||
hard_reg_set_equal_p (X, Y), which returns true if X and Y are equal.
|
|
||||||
hard_reg_set_intersect_p (X, Y), which returns true if X and Y intersect.
|
|
||||||
hard_reg_set_empty_p (X), which returns true if X is empty. */
|
|
||||||
|
|
||||||
#define UHOST_BITS_PER_WIDE_INT ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT)
|
|
||||||
|
|
||||||
#ifdef HARD_REG_SET
|
|
||||||
|
|
||||||
#define SET_HARD_REG_BIT(SET, BIT) \
|
|
||||||
((SET) |= HARD_CONST (1) << (BIT))
|
|
||||||
#define CLEAR_HARD_REG_BIT(SET, BIT) \
|
|
||||||
((SET) &= ~(HARD_CONST (1) << (BIT)))
|
|
||||||
#define TEST_HARD_REG_BIT(SET, BIT) \
|
|
||||||
(!!((SET) & (HARD_CONST (1) << (BIT))))
|
|
||||||
|
|
||||||
#define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0))
|
|
||||||
#define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0))
|
|
||||||
|
|
||||||
#define COPY_HARD_REG_SET(TO, FROM) ((TO) = (FROM))
|
|
||||||
#define COMPL_HARD_REG_SET(TO, FROM) ((TO) = ~(FROM))
|
|
||||||
|
|
||||||
#define IOR_HARD_REG_SET(TO, FROM) ((TO) |= (FROM))
|
|
||||||
#define IOR_COMPL_HARD_REG_SET(TO, FROM) ((TO) |= ~ (FROM))
|
|
||||||
#define AND_HARD_REG_SET(TO, FROM) ((TO) &= (FROM))
|
|
||||||
#define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM))
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
|
||||||
{
|
|
||||||
return (x & ~y) == HARD_CONST (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
|
||||||
{
|
|
||||||
return x == y;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
|
||||||
{
|
|
||||||
return (x & y) != HARD_CONST (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_empty_p (const HARD_REG_SET x)
|
|
||||||
{
|
|
||||||
return x == HARD_CONST (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define SET_HARD_REG_BIT(SET, BIT) \
|
|
||||||
((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \
|
|
||||||
|= HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))
|
|
||||||
|
|
||||||
#define CLEAR_HARD_REG_BIT(SET, BIT) \
|
|
||||||
((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \
|
|
||||||
&= ~(HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT)))
|
|
||||||
|
|
||||||
#define TEST_HARD_REG_BIT(SET, BIT) \
|
|
||||||
(!!((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \
|
|
||||||
& (HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))))
|
|
||||||
|
|
||||||
#if FIRST_PSEUDO_REGISTER <= 2*HOST_BITS_PER_WIDEST_FAST_INT
|
|
||||||
#define CLEAR_HARD_REG_SET(TO) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
|
||||||
scan_tp_[0] = 0; \
|
|
||||||
scan_tp_[1] = 0; } while (0)
|
|
||||||
|
|
||||||
#define SET_HARD_REG_SET(TO) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
|
||||||
scan_tp_[0] = -1; \
|
|
||||||
scan_tp_[1] = -1; } while (0)
|
|
||||||
|
|
||||||
#define COPY_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] = scan_fp_[0]; \
|
|
||||||
scan_tp_[1] = scan_fp_[1]; } while (0)
|
|
||||||
|
|
||||||
#define COMPL_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] = ~ scan_fp_[0]; \
|
|
||||||
scan_tp_[1] = ~ scan_fp_[1]; } while (0)
|
|
||||||
|
|
||||||
#define AND_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] &= scan_fp_[0]; \
|
|
||||||
scan_tp_[1] &= scan_fp_[1]; } while (0)
|
|
||||||
|
|
||||||
#define AND_COMPL_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] &= ~ scan_fp_[0]; \
|
|
||||||
scan_tp_[1] &= ~ scan_fp_[1]; } while (0)
|
|
||||||
|
|
||||||
#define IOR_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] |= scan_fp_[0]; \
|
|
||||||
scan_tp_[1] |= scan_fp_[1]; } while (0)
|
|
||||||
|
|
||||||
#define IOR_COMPL_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] |= ~ scan_fp_[0]; \
|
|
||||||
scan_tp_[1] |= ~ scan_fp_[1]; } while (0)
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
|
||||||
{
|
|
||||||
return (x[0] & ~y[0]) == 0 && (x[1] & ~y[1]) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
|
||||||
{
|
|
||||||
return x[0] == y[0] && x[1] == y[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
|
||||||
{
|
|
||||||
return (x[0] & y[0]) != 0 || (x[1] & y[1]) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_empty_p (const HARD_REG_SET x)
|
|
||||||
{
|
|
||||||
return x[0] == 0 && x[1] == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
#if FIRST_PSEUDO_REGISTER <= 3*HOST_BITS_PER_WIDEST_FAST_INT
|
|
||||||
#define CLEAR_HARD_REG_SET(TO) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
|
||||||
scan_tp_[0] = 0; \
|
|
||||||
scan_tp_[1] = 0; \
|
|
||||||
scan_tp_[2] = 0; } while (0)
|
|
||||||
|
|
||||||
#define SET_HARD_REG_SET(TO) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
|
||||||
scan_tp_[0] = -1; \
|
|
||||||
scan_tp_[1] = -1; \
|
|
||||||
scan_tp_[2] = -1; } while (0)
|
|
||||||
|
|
||||||
#define COPY_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] = scan_fp_[0]; \
|
|
||||||
scan_tp_[1] = scan_fp_[1]; \
|
|
||||||
scan_tp_[2] = scan_fp_[2]; } while (0)
|
|
||||||
|
|
||||||
#define COMPL_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] = ~ scan_fp_[0]; \
|
|
||||||
scan_tp_[1] = ~ scan_fp_[1]; \
|
|
||||||
scan_tp_[2] = ~ scan_fp_[2]; } while (0)
|
|
||||||
|
|
||||||
#define AND_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] &= scan_fp_[0]; \
|
|
||||||
scan_tp_[1] &= scan_fp_[1]; \
|
|
||||||
scan_tp_[2] &= scan_fp_[2]; } while (0)
|
|
||||||
|
|
||||||
#define AND_COMPL_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] &= ~ scan_fp_[0]; \
|
|
||||||
scan_tp_[1] &= ~ scan_fp_[1]; \
|
|
||||||
scan_tp_[2] &= ~ scan_fp_[2]; } while (0)
|
|
||||||
|
|
||||||
#define IOR_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] |= scan_fp_[0]; \
|
|
||||||
scan_tp_[1] |= scan_fp_[1]; \
|
|
||||||
scan_tp_[2] |= scan_fp_[2]; } while (0)
|
|
||||||
|
|
||||||
#define IOR_COMPL_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] |= ~ scan_fp_[0]; \
|
|
||||||
scan_tp_[1] |= ~ scan_fp_[1]; \
|
|
||||||
scan_tp_[2] |= ~ scan_fp_[2]; } while (0)
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
|
||||||
{
|
|
||||||
return ((x[0] & ~y[0]) == 0
|
|
||||||
&& (x[1] & ~y[1]) == 0
|
|
||||||
&& (x[2] & ~y[2]) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
|
||||||
{
|
|
||||||
return x[0] == y[0] && x[1] == y[1] && x[2] == y[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
|
||||||
{
|
|
||||||
return ((x[0] & y[0]) != 0
|
|
||||||
|| (x[1] & y[1]) != 0
|
|
||||||
|| (x[2] & y[2]) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_empty_p (const HARD_REG_SET x)
|
|
||||||
{
|
|
||||||
return x[0] == 0 && x[1] == 0 && x[2] == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
#if FIRST_PSEUDO_REGISTER <= 4*HOST_BITS_PER_WIDEST_FAST_INT
|
|
||||||
#define CLEAR_HARD_REG_SET(TO) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
|
||||||
scan_tp_[0] = 0; \
|
|
||||||
scan_tp_[1] = 0; \
|
|
||||||
scan_tp_[2] = 0; \
|
|
||||||
scan_tp_[3] = 0; } while (0)
|
|
||||||
|
|
||||||
#define SET_HARD_REG_SET(TO) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
|
||||||
scan_tp_[0] = -1; \
|
|
||||||
scan_tp_[1] = -1; \
|
|
||||||
scan_tp_[2] = -1; \
|
|
||||||
scan_tp_[3] = -1; } while (0)
|
|
||||||
|
|
||||||
#define COPY_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] = scan_fp_[0]; \
|
|
||||||
scan_tp_[1] = scan_fp_[1]; \
|
|
||||||
scan_tp_[2] = scan_fp_[2]; \
|
|
||||||
scan_tp_[3] = scan_fp_[3]; } while (0)
|
|
||||||
|
|
||||||
#define COMPL_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] = ~ scan_fp_[0]; \
|
|
||||||
scan_tp_[1] = ~ scan_fp_[1]; \
|
|
||||||
scan_tp_[2] = ~ scan_fp_[2]; \
|
|
||||||
scan_tp_[3] = ~ scan_fp_[3]; } while (0)
|
|
||||||
|
|
||||||
#define AND_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] &= scan_fp_[0]; \
|
|
||||||
scan_tp_[1] &= scan_fp_[1]; \
|
|
||||||
scan_tp_[2] &= scan_fp_[2]; \
|
|
||||||
scan_tp_[3] &= scan_fp_[3]; } while (0)
|
|
||||||
|
|
||||||
#define AND_COMPL_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] &= ~ scan_fp_[0]; \
|
|
||||||
scan_tp_[1] &= ~ scan_fp_[1]; \
|
|
||||||
scan_tp_[2] &= ~ scan_fp_[2]; \
|
|
||||||
scan_tp_[3] &= ~ scan_fp_[3]; } while (0)
|
|
||||||
|
|
||||||
#define IOR_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] |= scan_fp_[0]; \
|
|
||||||
scan_tp_[1] |= scan_fp_[1]; \
|
|
||||||
scan_tp_[2] |= scan_fp_[2]; \
|
|
||||||
scan_tp_[3] |= scan_fp_[3]; } while (0)
|
|
||||||
|
|
||||||
#define IOR_COMPL_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
scan_tp_[0] |= ~ scan_fp_[0]; \
|
|
||||||
scan_tp_[1] |= ~ scan_fp_[1]; \
|
|
||||||
scan_tp_[2] |= ~ scan_fp_[2]; \
|
|
||||||
scan_tp_[3] |= ~ scan_fp_[3]; } while (0)
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
|
||||||
{
|
|
||||||
return ((x[0] & ~y[0]) == 0
|
|
||||||
&& (x[1] & ~y[1]) == 0
|
|
||||||
&& (x[2] & ~y[2]) == 0
|
|
||||||
&& (x[3] & ~y[3]) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
|
||||||
{
|
|
||||||
return x[0] == y[0] && x[1] == y[1] && x[2] == y[2] && x[3] == y[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
|
||||||
{
|
|
||||||
return ((x[0] & y[0]) != 0
|
|
||||||
|| (x[1] & y[1]) != 0
|
|
||||||
|| (x[2] & y[2]) != 0
|
|
||||||
|| (x[3] & y[3]) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_empty_p (const HARD_REG_SET x)
|
|
||||||
{
|
|
||||||
return x[0] == 0 && x[1] == 0 && x[2] == 0 && x[3] == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* FIRST_PSEUDO_REGISTER > 4*HOST_BITS_PER_WIDEST_FAST_INT */
|
|
||||||
|
|
||||||
#define CLEAR_HARD_REG_SET(TO) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
|
||||||
int i; \
|
|
||||||
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
|
||||||
*scan_tp_++ = 0; } while (0)
|
|
||||||
|
|
||||||
#define SET_HARD_REG_SET(TO) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
|
||||||
int i; \
|
|
||||||
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
|
||||||
*scan_tp_++ = -1; } while (0)
|
|
||||||
|
|
||||||
#define COPY_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
int i; \
|
|
||||||
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
|
||||||
*scan_tp_++ = *scan_fp_++; } while (0)
|
|
||||||
|
|
||||||
#define COMPL_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
int i; \
|
|
||||||
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
|
||||||
*scan_tp_++ = ~ *scan_fp_++; } while (0)
|
|
||||||
|
|
||||||
#define AND_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
int i; \
|
|
||||||
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
|
||||||
*scan_tp_++ &= *scan_fp_++; } while (0)
|
|
||||||
|
|
||||||
#define AND_COMPL_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
int i; \
|
|
||||||
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
|
||||||
*scan_tp_++ &= ~ *scan_fp_++; } while (0)
|
|
||||||
|
|
||||||
#define IOR_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
int i; \
|
|
||||||
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
|
||||||
*scan_tp_++ |= *scan_fp_++; } while (0)
|
|
||||||
|
|
||||||
#define IOR_COMPL_HARD_REG_SET(TO, FROM) \
|
|
||||||
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
|
||||||
int i; \
|
|
||||||
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
|
||||||
*scan_tp_++ |= ~ *scan_fp_++; } while (0)
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < HARD_REG_SET_LONGS; i++)
|
|
||||||
if ((x[i] & ~y[i]) != 0)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < HARD_REG_SET_LONGS; i++)
|
|
||||||
if (x[i] != y[i])
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < HARD_REG_SET_LONGS; i++)
|
|
||||||
if ((x[i] & y[i]) != 0)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_empty_p (const HARD_REG_SET x)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < HARD_REG_SET_LONGS; i++)
|
|
||||||
if (x[i] != 0)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Iterator for hard register sets. */
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
/* Pointer to the current element. */
|
|
||||||
HARD_REG_ELT_TYPE *pelt;
|
|
||||||
|
|
||||||
/* The length of the set. */
|
|
||||||
unsigned short length;
|
|
||||||
|
|
||||||
/* Word within the current element. */
|
|
||||||
unsigned short word_no;
|
|
||||||
|
|
||||||
/* Contents of the actually processed word. When finding next bit
|
|
||||||
it is shifted right, so that the actual bit is always the least
|
|
||||||
significant bit of ACTUAL. */
|
|
||||||
HARD_REG_ELT_TYPE bits;
|
|
||||||
} hard_reg_set_iterator;
|
|
||||||
|
|
||||||
#define HARD_REG_ELT_BITS UHOST_BITS_PER_WIDE_INT
|
|
||||||
|
|
||||||
/* The implementation of the iterator functions is fully analogous to
|
|
||||||
the bitmap iterators. */
|
|
||||||
static inline void
|
|
||||||
hard_reg_set_iter_init (hard_reg_set_iterator *iter, HARD_REG_SET set,
|
|
||||||
unsigned min, unsigned *regno)
|
|
||||||
{
|
|
||||||
#ifdef HARD_REG_SET_LONGS
|
|
||||||
iter->pelt = set;
|
|
||||||
iter->length = HARD_REG_SET_LONGS;
|
|
||||||
#else
|
|
||||||
iter->pelt = &set;
|
|
||||||
iter->length = 1;
|
|
||||||
#endif
|
|
||||||
iter->word_no = min / HARD_REG_ELT_BITS;
|
|
||||||
if (iter->word_no < iter->length)
|
|
||||||
{
|
|
||||||
iter->bits = iter->pelt[iter->word_no];
|
|
||||||
iter->bits >>= min % HARD_REG_ELT_BITS;
|
|
||||||
|
|
||||||
/* This is required for correct search of the next bit. */
|
|
||||||
min += !iter->bits;
|
|
||||||
}
|
|
||||||
*regno = min;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
hard_reg_set_iter_set (hard_reg_set_iterator *iter, unsigned *regno)
|
|
||||||
{
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
/* Return false when we're advanced past the end of the set. */
|
|
||||||
if (iter->word_no >= iter->length)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (iter->bits)
|
|
||||||
{
|
|
||||||
/* Find the correct bit and return it. */
|
|
||||||
while (!(iter->bits & 1))
|
|
||||||
{
|
|
||||||
iter->bits >>= 1;
|
|
||||||
*regno += 1;
|
|
||||||
}
|
|
||||||
return (*regno < FIRST_PSEUDO_REGISTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Round to the beginning of the next word. */
|
|
||||||
*regno = (*regno + HARD_REG_ELT_BITS - 1);
|
|
||||||
*regno -= *regno % HARD_REG_ELT_BITS;
|
|
||||||
|
|
||||||
/* Find the next non-zero word. */
|
|
||||||
while (++iter->word_no < iter->length)
|
|
||||||
{
|
|
||||||
iter->bits = iter->pelt[iter->word_no];
|
|
||||||
if (iter->bits)
|
|
||||||
break;
|
|
||||||
*regno += HARD_REG_ELT_BITS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
hard_reg_set_iter_next (hard_reg_set_iterator *iter, unsigned *regno)
|
|
||||||
{
|
|
||||||
iter->bits >>= 1;
|
|
||||||
*regno += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define EXECUTE_IF_SET_IN_HARD_REG_SET(SET, MIN, REGNUM, ITER) \
|
|
||||||
for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM)); \
|
|
||||||
hard_reg_set_iter_set (&(ITER), &(REGNUM)); \
|
|
||||||
hard_reg_set_iter_next (&(ITER), &(REGNUM)))
|
|
||||||
|
|
||||||
|
|
||||||
/* Define some standard sets of registers. */
|
|
||||||
|
|
||||||
/* Indexed by hard register number, contains 1 for registers
|
|
||||||
that are being used for global register decls.
|
|
||||||
These must be exempt from ordinary flow analysis
|
|
||||||
and are also considered fixed. */
|
|
||||||
|
|
||||||
extern char global_regs[FIRST_PSEUDO_REGISTER];
|
|
||||||
|
|
||||||
struct target_hard_regs {
|
|
||||||
/* The set of registers that actually exist on the current target. */
|
|
||||||
HARD_REG_SET x_accessible_reg_set;
|
|
||||||
|
|
||||||
/* The set of registers that should be considered to be register
|
|
||||||
operands. It is a subset of x_accessible_reg_set. */
|
|
||||||
HARD_REG_SET x_operand_reg_set;
|
|
||||||
|
|
||||||
/* Indexed by hard register number, contains 1 for registers
|
|
||||||
that are fixed use (stack pointer, pc, frame pointer, etc.;.
|
|
||||||
These are the registers that cannot be used to allocate
|
|
||||||
a pseudo reg whose life does not cross calls. */
|
|
||||||
char x_fixed_regs[FIRST_PSEUDO_REGISTER];
|
|
||||||
|
|
||||||
/* The same info as a HARD_REG_SET. */
|
|
||||||
HARD_REG_SET x_fixed_reg_set;
|
|
||||||
|
|
||||||
/* Indexed by hard register number, contains 1 for registers
|
|
||||||
that are fixed use or are clobbered by function calls.
|
|
||||||
These are the registers that cannot be used to allocate
|
|
||||||
a pseudo reg whose life crosses calls. */
|
|
||||||
char x_call_used_regs[FIRST_PSEUDO_REGISTER];
|
|
||||||
|
|
||||||
char x_call_really_used_regs[FIRST_PSEUDO_REGISTER];
|
|
||||||
|
|
||||||
/* The same info as a HARD_REG_SET. */
|
|
||||||
HARD_REG_SET x_call_used_reg_set;
|
|
||||||
|
|
||||||
/* Contains registers that are fixed use -- i.e. in fixed_reg_set -- or
|
|
||||||
a function value return register or TARGET_STRUCT_VALUE_RTX or
|
|
||||||
STATIC_CHAIN_REGNUM. These are the registers that cannot hold quantities
|
|
||||||
across calls even if we are willing to save and restore them. */
|
|
||||||
HARD_REG_SET x_call_fixed_reg_set;
|
|
||||||
|
|
||||||
/* Contains 1 for registers that are set or clobbered by calls. */
|
|
||||||
/* ??? Ideally, this would be just call_used_regs plus global_regs, but
|
|
||||||
for someone's bright idea to have call_used_regs strictly include
|
|
||||||
fixed_regs. Which leaves us guessing as to the set of fixed_regs
|
|
||||||
that are actually preserved. We know for sure that those associated
|
|
||||||
with the local stack frame are safe, but scant others. */
|
|
||||||
HARD_REG_SET x_regs_invalidated_by_call;
|
|
||||||
|
|
||||||
/* Call used hard registers which can not be saved because there is no
|
|
||||||
insn for this. */
|
|
||||||
HARD_REG_SET x_no_caller_save_reg_set;
|
|
||||||
|
|
||||||
/* Table of register numbers in the order in which to try to use them. */
|
|
||||||
int x_reg_alloc_order[FIRST_PSEUDO_REGISTER];
|
|
||||||
|
|
||||||
/* The inverse of reg_alloc_order. */
|
|
||||||
int x_inv_reg_alloc_order[FIRST_PSEUDO_REGISTER];
|
|
||||||
|
|
||||||
/* For each reg class, a HARD_REG_SET saying which registers are in it. */
|
|
||||||
HARD_REG_SET x_reg_class_contents[N_REG_CLASSES];
|
|
||||||
|
|
||||||
/* For each reg class, a boolean saying whether the class contains only
|
|
||||||
fixed registers. */
|
|
||||||
bool x_class_only_fixed_regs[N_REG_CLASSES];
|
|
||||||
|
|
||||||
/* For each reg class, number of regs it contains. */
|
|
||||||
unsigned int x_reg_class_size[N_REG_CLASSES];
|
|
||||||
|
|
||||||
/* For each reg class, table listing all the classes contained in it. */
|
|
||||||
enum reg_class x_reg_class_subclasses[N_REG_CLASSES][N_REG_CLASSES];
|
|
||||||
|
|
||||||
/* For each pair of reg classes,
|
|
||||||
a largest reg class contained in their union. */
|
|
||||||
enum reg_class x_reg_class_subunion[N_REG_CLASSES][N_REG_CLASSES];
|
|
||||||
|
|
||||||
/* For each pair of reg classes,
|
|
||||||
the smallest reg class that contains their union. */
|
|
||||||
enum reg_class x_reg_class_superunion[N_REG_CLASSES][N_REG_CLASSES];
|
|
||||||
|
|
||||||
/* Vector indexed by hardware reg giving its name. */
|
|
||||||
const char *x_reg_names[FIRST_PSEUDO_REGISTER];
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct target_hard_regs default_target_hard_regs;
|
|
||||||
#if SWITCHABLE_TARGET
|
|
||||||
extern struct target_hard_regs *this_target_hard_regs;
|
|
||||||
#else
|
|
||||||
#define this_target_hard_regs (&default_target_hard_regs)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define accessible_reg_set \
|
|
||||||
(this_target_hard_regs->x_accessible_reg_set)
|
|
||||||
#define operand_reg_set \
|
|
||||||
(this_target_hard_regs->x_operand_reg_set)
|
|
||||||
#define fixed_regs \
|
|
||||||
(this_target_hard_regs->x_fixed_regs)
|
|
||||||
#define fixed_reg_set \
|
|
||||||
(this_target_hard_regs->x_fixed_reg_set)
|
|
||||||
#define call_used_regs \
|
|
||||||
(this_target_hard_regs->x_call_used_regs)
|
|
||||||
#define call_really_used_regs \
|
|
||||||
(this_target_hard_regs->x_call_really_used_regs)
|
|
||||||
#define call_used_reg_set \
|
|
||||||
(this_target_hard_regs->x_call_used_reg_set)
|
|
||||||
#define call_fixed_reg_set \
|
|
||||||
(this_target_hard_regs->x_call_fixed_reg_set)
|
|
||||||
#define regs_invalidated_by_call \
|
|
||||||
(this_target_hard_regs->x_regs_invalidated_by_call)
|
|
||||||
#define no_caller_save_reg_set \
|
|
||||||
(this_target_hard_regs->x_no_caller_save_reg_set)
|
|
||||||
#define reg_alloc_order \
|
|
||||||
(this_target_hard_regs->x_reg_alloc_order)
|
|
||||||
#define inv_reg_alloc_order \
|
|
||||||
(this_target_hard_regs->x_inv_reg_alloc_order)
|
|
||||||
#define reg_class_contents \
|
|
||||||
(this_target_hard_regs->x_reg_class_contents)
|
|
||||||
#define class_only_fixed_regs \
|
|
||||||
(this_target_hard_regs->x_class_only_fixed_regs)
|
|
||||||
#define reg_class_size \
|
|
||||||
(this_target_hard_regs->x_reg_class_size)
|
|
||||||
#define reg_class_subclasses \
|
|
||||||
(this_target_hard_regs->x_reg_class_subclasses)
|
|
||||||
#define reg_class_subunion \
|
|
||||||
(this_target_hard_regs->x_reg_class_subunion)
|
|
||||||
#define reg_class_superunion \
|
|
||||||
(this_target_hard_regs->x_reg_class_superunion)
|
|
||||||
#define reg_names \
|
|
||||||
(this_target_hard_regs->x_reg_names)
|
|
||||||
|
|
||||||
/* Vector indexed by reg class giving its name. */
|
|
||||||
|
|
||||||
extern const char * reg_class_names[];
|
|
||||||
|
|
||||||
/* Given a hard REGN a FROM mode and a TO mode, return nonzero if
|
|
||||||
REGN cannot change modes between the specified modes. */
|
|
||||||
#define REG_CANNOT_CHANGE_MODE_P(REGN, FROM, TO) \
|
|
||||||
CANNOT_CHANGE_MODE_CLASS (FROM, TO, REGNO_REG_CLASS (REGN))
|
|
||||||
|
|
||||||
#endif /* ! GCC_HARD_REG_SET_H */
|
|
@ -1,209 +0,0 @@
|
|||||||
/* An expandable hash tables datatype.
|
|
||||||
Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2009, 2010
|
|
||||||
Free Software Foundation, Inc.
|
|
||||||
Contributed by Vladimir Makarov (vmakarov@cygnus.com).
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
|
||||||
|
|
||||||
/* This package implements basic hash table functionality. It is possible
|
|
||||||
to search for an entry, create an entry and destroy an entry.
|
|
||||||
|
|
||||||
Elements in the table are generic pointers.
|
|
||||||
|
|
||||||
The size of the table is not fixed; if the occupancy of the table
|
|
||||||
grows too high the hash table will be expanded.
|
|
||||||
|
|
||||||
The abstract data implementation is based on generalized Algorithm D
|
|
||||||
from Knuth's book "The art of computer programming". Hash table is
|
|
||||||
expanded by creation of new hash table and transferring elements from
|
|
||||||
the old table to the new table. */
|
|
||||||
|
|
||||||
#ifndef __HASHTAB_H__
|
|
||||||
#define __HASHTAB_H__
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#include "ansidecl.h"
|
|
||||||
|
|
||||||
#ifndef GTY
|
|
||||||
#define GTY(X)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The type for a hash code. */
|
|
||||||
typedef unsigned int hashval_t;
|
|
||||||
|
|
||||||
/* Callback function pointer types. */
|
|
||||||
|
|
||||||
/* Calculate hash of a table entry. */
|
|
||||||
typedef hashval_t (*htab_hash) (const void *);
|
|
||||||
|
|
||||||
/* Compare a table entry with a possible entry. The entry already in
|
|
||||||
the table always comes first, so the second element can be of a
|
|
||||||
different type (but in this case htab_find and htab_find_slot
|
|
||||||
cannot be used; instead the variants that accept a hash value
|
|
||||||
must be used). */
|
|
||||||
typedef int (*htab_eq) (const void *, const void *);
|
|
||||||
|
|
||||||
/* Cleanup function called whenever a live element is removed from
|
|
||||||
the hash table. */
|
|
||||||
typedef void (*htab_del) (void *);
|
|
||||||
|
|
||||||
/* Function called by htab_traverse for each live element. The first
|
|
||||||
arg is the slot of the element (which can be passed to htab_clear_slot
|
|
||||||
if desired), the second arg is the auxiliary pointer handed to
|
|
||||||
htab_traverse. Return 1 to continue scan, 0 to stop. */
|
|
||||||
typedef int (*htab_trav) (void **, void *);
|
|
||||||
|
|
||||||
/* Memory-allocation function, with the same functionality as calloc().
|
|
||||||
Iff it returns NULL, the hash table implementation will pass an error
|
|
||||||
code back to the user, so if your code doesn't handle errors,
|
|
||||||
best if you use xcalloc instead. */
|
|
||||||
typedef void *(*htab_alloc) (size_t, size_t);
|
|
||||||
|
|
||||||
/* We also need a free() routine. */
|
|
||||||
typedef void (*htab_free) (void *);
|
|
||||||
|
|
||||||
/* Memory allocation and deallocation; variants which take an extra
|
|
||||||
argument. */
|
|
||||||
typedef void *(*htab_alloc_with_arg) (void *, size_t, size_t);
|
|
||||||
typedef void (*htab_free_with_arg) (void *, void *);
|
|
||||||
|
|
||||||
/* This macro defines reserved value for empty table entry. */
|
|
||||||
|
|
||||||
#define HTAB_EMPTY_ENTRY ((PTR) 0)
|
|
||||||
|
|
||||||
/* This macro defines reserved value for table entry which contained
|
|
||||||
a deleted element. */
|
|
||||||
|
|
||||||
#define HTAB_DELETED_ENTRY ((PTR) 1)
|
|
||||||
|
|
||||||
/* Hash tables are of the following type. The structure
|
|
||||||
(implementation) of this type is not needed for using the hash
|
|
||||||
tables. All work with hash table should be executed only through
|
|
||||||
functions mentioned below. The size of this structure is subject to
|
|
||||||
change. */
|
|
||||||
|
|
||||||
struct GTY(()) htab {
|
|
||||||
/* Pointer to hash function. */
|
|
||||||
htab_hash hash_f;
|
|
||||||
|
|
||||||
/* Pointer to comparison function. */
|
|
||||||
htab_eq eq_f;
|
|
||||||
|
|
||||||
/* Pointer to cleanup function. */
|
|
||||||
htab_del del_f;
|
|
||||||
|
|
||||||
/* Table itself. */
|
|
||||||
void ** GTY ((use_param, length ("%h.size"))) entries;
|
|
||||||
|
|
||||||
/* Current size (in entries) of the hash table. */
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
/* Current number of elements including also deleted elements. */
|
|
||||||
size_t n_elements;
|
|
||||||
|
|
||||||
/* Current number of deleted elements in the table. */
|
|
||||||
size_t n_deleted;
|
|
||||||
|
|
||||||
/* The following member is used for debugging. Its value is number
|
|
||||||
of all calls of `htab_find_slot' for the hash table. */
|
|
||||||
unsigned int searches;
|
|
||||||
|
|
||||||
/* The following member is used for debugging. Its value is number
|
|
||||||
of collisions fixed for time of work with the hash table. */
|
|
||||||
unsigned int collisions;
|
|
||||||
|
|
||||||
/* Pointers to allocate/free functions. */
|
|
||||||
htab_alloc alloc_f;
|
|
||||||
htab_free free_f;
|
|
||||||
|
|
||||||
/* Alternate allocate/free functions, which take an extra argument. */
|
|
||||||
void * GTY((skip)) alloc_arg;
|
|
||||||
htab_alloc_with_arg alloc_with_arg_f;
|
|
||||||
htab_free_with_arg free_with_arg_f;
|
|
||||||
|
|
||||||
/* Current size (in entries) of the hash table, as an index into the
|
|
||||||
table of primes. */
|
|
||||||
unsigned int size_prime_index;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct htab *htab_t;
|
|
||||||
|
|
||||||
/* An enum saying whether we insert into the hash table or not. */
|
|
||||||
enum insert_option {NO_INSERT, INSERT};
|
|
||||||
|
|
||||||
/* The prototypes of the package functions. */
|
|
||||||
|
|
||||||
extern htab_t htab_create_alloc (size_t, htab_hash,
|
|
||||||
htab_eq, htab_del,
|
|
||||||
htab_alloc, htab_free);
|
|
||||||
|
|
||||||
extern htab_t htab_create_alloc_ex (size_t, htab_hash,
|
|
||||||
htab_eq, htab_del,
|
|
||||||
void *, htab_alloc_with_arg,
|
|
||||||
htab_free_with_arg);
|
|
||||||
|
|
||||||
extern htab_t htab_create_typed_alloc (size_t, htab_hash, htab_eq, htab_del,
|
|
||||||
htab_alloc, htab_alloc, htab_free);
|
|
||||||
|
|
||||||
/* Backward-compatibility functions. */
|
|
||||||
extern htab_t htab_create (size_t, htab_hash, htab_eq, htab_del);
|
|
||||||
extern htab_t htab_try_create (size_t, htab_hash, htab_eq, htab_del);
|
|
||||||
|
|
||||||
extern void htab_set_functions_ex (htab_t, htab_hash,
|
|
||||||
htab_eq, htab_del,
|
|
||||||
void *, htab_alloc_with_arg,
|
|
||||||
htab_free_with_arg);
|
|
||||||
|
|
||||||
extern void htab_delete (htab_t);
|
|
||||||
extern void htab_empty (htab_t);
|
|
||||||
|
|
||||||
extern void * htab_find (htab_t, const void *);
|
|
||||||
extern void ** htab_find_slot (htab_t, const void *, enum insert_option);
|
|
||||||
extern void * htab_find_with_hash (htab_t, const void *, hashval_t);
|
|
||||||
extern void ** htab_find_slot_with_hash (htab_t, const void *,
|
|
||||||
hashval_t, enum insert_option);
|
|
||||||
extern void htab_clear_slot (htab_t, void **);
|
|
||||||
extern void htab_remove_elt (htab_t, void *);
|
|
||||||
extern void htab_remove_elt_with_hash (htab_t, void *, hashval_t);
|
|
||||||
|
|
||||||
extern void htab_traverse (htab_t, htab_trav, void *);
|
|
||||||
extern void htab_traverse_noresize (htab_t, htab_trav, void *);
|
|
||||||
|
|
||||||
extern size_t htab_size (htab_t);
|
|
||||||
extern size_t htab_elements (htab_t);
|
|
||||||
extern double htab_collisions (htab_t);
|
|
||||||
|
|
||||||
/* A hash function for pointers. */
|
|
||||||
extern htab_hash htab_hash_pointer;
|
|
||||||
|
|
||||||
/* An equality function for pointers. */
|
|
||||||
extern htab_eq htab_eq_pointer;
|
|
||||||
|
|
||||||
/* A hash function for null-terminated strings. */
|
|
||||||
extern hashval_t htab_hash_string (const void *);
|
|
||||||
|
|
||||||
/* An iterative hash function for arbitrary data. */
|
|
||||||
extern hashval_t iterative_hash (const void *, size_t, hashval_t);
|
|
||||||
/* Shorthand for hashing something with an intrinsic size. */
|
|
||||||
#define iterative_hash_object(OB,INIT) iterative_hash (&OB, sizeof (OB), INIT)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#endif /* __HASHTAB_H */
|
|
@ -1,33 +0,0 @@
|
|||||||
/* Interface for high-level plugins in GCC - Parts common between GCC,
|
|
||||||
ICI and high-level plugins.
|
|
||||||
|
|
||||||
Copyright (C) 2009-2013 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
Contributed by INRIA.
|
|
||||||
|
|
||||||
This file is part of GCC.
|
|
||||||
|
|
||||||
GCC is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free
|
|
||||||
Software Foundation; either version 3, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with GCC; see the file COPYING3. If not see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#ifndef HIGHLEV_PLUGIN_COMMON_H
|
|
||||||
#define HIGHLEV_PLUGIN_COMMON_H
|
|
||||||
|
|
||||||
/* Return codes for invoke_plugin_callbacks / call_plugin_event . */
|
|
||||||
#define PLUGEVT_SUCCESS 0
|
|
||||||
#define PLUGEVT_NO_EVENTS 1
|
|
||||||
#define PLUGEVT_NO_SUCH_EVENT 2
|
|
||||||
#define PLUGEVT_NO_CALLBACK 3
|
|
||||||
|
|
||||||
#endif /* HIGHLEV_PLUGIN_COMMON_H */
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user