[gcc-python-plugin] Add "operand" field to gcc.MemRef; document gcc.MemRef, along with gcc.FieldDecl, gcc.ComponentRefer
by David Hugh Malcolm
commit 44d9e08883be7fb79ae275d343098d1a27634480
Author: David Malcolm <dmalcolm(a)redhat.com>
Date: Thu Jul 7 17:59:49 2011 -0400
Add "operand" field to gcc.MemRef; document gcc.MemRef, along with gcc.FieldDecl, gcc.ComponentReference
docs/tree.rst | 59 +++++++++++++++++++++++++++++++++++++++++++++++++--
generate-tree-c.py | 9 ++++++-
2 files changed, 63 insertions(+), 5 deletions(-)
---
diff --git a/docs/tree.rst b/docs/tree.rst
index 40fcfd8..8a5ec18 100644
--- a/docs/tree.rst
+++ b/docs/tree.rst
@@ -166,6 +166,17 @@ Declarations
The :py:class:`gcc.Location` for this declaration
+
+.. py:class:: gcc.FieldDecl
+
+ A subclass of `gcc.Declaration` indicating the declaration of a field within
+ a structure.
+
+ .. py:attribute:: name
+
+ (string) The name of this field
+
+
.. py:class:: gcc.FunctionDecl
A subclass of `gcc.Declaration` indicating the declaration of a function.
@@ -595,7 +606,51 @@ References to storage
The :py:class:`gcc.Location` for this storage reference
- Subclasses include:
+.. py:class:: gcc.ComponentReference
+
+ A subclass of `gcc.Reference` for expressions involving a field lookup.
+
+ This can mean either a direct field lookup, as in:
+
+ .. code-block:: c
+
+ struct mystruct s;
+ ...
+ s.idx = 42;
+
+ or dereferenced field lookup:
+
+ .. code-block:: c
+
+ struct mystruct *p;
+ ...
+ p->idx = 42;
+
+ .. py:attribute:: target
+
+ The `gcc.Tree` for the container of the field (either `s` or `*p` in the
+ examples above)
+
+ .. py:attribute:: field
+
+ The `gcc.FieldDecl` for the field within the target.
+
+.. py:class:: gcc.MemRef
+
+ A subclass of `gcc.Reference` for expressions involving dereferencing a
+ pointer:
+
+ .. code-block:: c
+
+ int p, *q;
+ ...
+ p = *q;
+
+ .. py:attribute:: operand
+
+ The `gcc.Tree` for the expression describing the target of the pointer
+
+Other subclasses of `gcc.Reference` include:
===================================== ======================
Subclass C/C++ operators
@@ -604,10 +659,8 @@ References to storage
.. py:class:: ArrayRef
.. py:class:: AttrAddrExpr
.. py:class:: BitFieldRef
- .. py:class:: ComponentRef
.. py:class:: ImagpartExpr
.. py:class:: IndirectRef
- .. py:class:: MemRef
.. py:class:: MemberRef
.. py:class:: OffsetRef
.. py:class:: RealpartExpr
diff --git a/generate-tree-c.py b/generate-tree-c.py
index 8b32d8e..cc11034 100644
--- a/generate-tree-c.py
+++ b/generate-tree-c.py
@@ -371,10 +371,15 @@ def generate_tree_code_classes():
if tree_type.SYM == 'COMPONENT_REF':
add_simple_getter('target',
'gcc_python_make_wrapper_tree(TREE_OPERAND(self->t, 0))',
- "The gcc.Node that for the container of the field'")
+ "The gcc.Tree that for the container of the field'")
add_simple_getter('field',
'gcc_python_make_wrapper_tree(TREE_OPERAND(self->t, 1))',
- "The gcc.Node for the field within the referenced thing'")
+ "The gcc.FieldDecl for the field within the target'")
+
+ if tree_type.SYM == 'MEM_REF':
+ add_simple_getter('operand',
+ 'gcc_python_make_wrapper_tree(TREE_OPERAND(self->t, 0))',
+ "The gcc.Tree that for the pointer expression'")
if tree_type.SYM in ('RECORD_TYPE', 'UNION_TYPE', 'QUAL_UNION_TYPE'):
add_simple_getter('fields',
12 years, 11 months
[gcc-python-plugin] Add a high-level overview of the insides of GCC
by David Hugh Malcolm
commit 0eb69afc6082af75c48f38f715587fa73c38f1f7
Author: David Malcolm <dmalcolm(a)redhat.com>
Date: Thu Jul 7 14:18:25 2011 -0400
Add a high-level overview of the insides of GCC
docs/gcc-overview.rst | 183 ++++++++++++++++++++++++++++++++++++++++
docs/index.rst | 1 +
docs/sample-cfg.png | Bin 91222 -> 0 bytes
docs/sample-gimple-cfg.png | Bin 0 -> 96753 bytes
docs/sample-gimple-ssa-cfg.png | Bin 0 -> 103929 bytes
5 files changed, 184 insertions(+), 0 deletions(-)
---
diff --git a/docs/gcc-overview.rst b/docs/gcc-overview.rst
new file mode 100644
index 0000000..2b0f991
--- /dev/null
+++ b/docs/gcc-overview.rst
@@ -0,0 +1,183 @@
+.. Copyright 2011 David Malcolm <dmalcolm(a)redhat.com>
+ Copyright 2011 Red Hat, Inc.
+
+ This 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 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, see
+ <http://www.gnu.org/licenses/>.
+
+Overview of GCC's internals
+===========================
+
+.. TODO: Subprocesses
+
+.. TODO: Passes
+
+.. TODO: could use a diagram here showing all the passes
+
+To add a new compiler warning to GCC, it's helpful to have a high-level
+understanding of how GCC works, so here's the 10,000 foot view of how GCC turns
+source code into machine code.
+
+The short version is that GCC applies a series of optimization passes to your
+code, gradually converting it from a high-level representation into machine
+code, via several different internal representations.
+
+Each programming language supported by GCC has a "frontend", which parses the
+source files.
+
+For the case of C and C++, the preprocessor manipulates the code first
+before the frontend sees it. You can see the preprocessor output with the
+`-E` option.
+
+Exactly what happens in each frontend varies by language: some language
+frontends emit language-specific trees, and some convert to a
+language-independent tree representation known as `GENERIC`. In any case, we
+eventually we reach a representation known as `GIMPLE`. The GIMPLE
+representation contains simplified operations, with temporary variables added as
+necessary to avoid nested sub-expressions.
+
+For example, given this C code:
+
+ .. literalinclude:: ../test.c
+ :lines: 33-48
+ :language: c
+
+we can see a dump of a C-like representation of the GIMPLE form by passing
+`-fdump-tree-gimple` to the command-line:
+
+ .. code-block:: bash
+
+ $ gcc -fdump-tree-gimple test.c
+ $ cat test.c.004t.gimple
+
+giving something like this:
+
+.. code-block:: c
+
+ main (int argc, char * * argv)
+ {
+ const char * restrict D.3258;
+ long unsigned int D.3259;
+ long unsigned int D.3260;
+ char * * D.3261;
+ char * D.3262;
+ const char * restrict D.3263;
+ int D.3264;
+ int i;
+
+ D.3258 = (const char * restrict) &"argc: %i\n"[0];
+ printf (D.3258, argc);
+ i = 0;
+ goto <D.2050>;
+ <D.2049>:
+ D.3259 = (long unsigned int) i;
+ D.3260 = D.3259 * 8;
+ D.3261 = argv + D.3260;
+ D.3262 = *D.3261;
+ D.3263 = (const char * restrict) &"argv[%i]: %s\n"[0];
+ printf (D.3263, D.3262);
+ i = i + 1;
+ <D.2050>:
+ if (i < argc) goto <D.2049>; else goto <D.2051>;
+ <D.2051>:
+ helper_function ();
+ D.3264 = 0;
+ return D.3264;
+ }
+
+It's far easier to see the GIMPLE using:
+
+.. code-block:: bash
+
+ ./gcc-with-python show-gimple.py test.c
+
+which generates bitmaps showing the "control flow graph" of the functions in
+the file, with source on the left-hand side, and GIMPLE on the right-hand side:
+
+ .. figure:: sample-gimple-cfg.png
+ :scale: 50 %
+ :alt: image of a control flow graph in GIMPLE form
+
+Each function is divided into "basic blocks". Each basic block consists of a
+straight-line sequence of code with a single entrypoint and exit: all branching
+happens between basic blocks, not within them. The basic blocks form a
+"control flow graph" of basic blocks, linked together by edges. Each block
+can contain a list of :py:class:`gcc.Gimple` statements.
+
+You can work with this representation from Python using :py:class:`gcc.Cfg`
+
+Once the code is in GIMPLE form, GCC then attempts a series of optimizations on
+it.
+
+Some of these optimizations are listed here:
+http://gcc.gnu.org/onlinedocs/gccint/Tree-SSA-passes.html
+
+If you're looking to add new compiler warnings, it's probably best to hook
+your code into these early passes.
+
+The GIMPLE form is actually in two parts: an initial form, and an SSA form. In
+SSA form ("Static Single Assignment"), every variable is assigned to at most
+once, with additional versions of variables added to help track the impact of
+assignments on the data flowing through a function.
+
+See http://gcc.gnu.org/onlinedocs/gccint/SSA.html
+
+Here's our example function, after conversion to GIMPLE SSA:
+
+.. code-block:: bash
+
+ ./gcc-with-python show-ssa.py test.c
+
+.. figure:: sample-gimple-ssa-cfg.png
+ :scale: 50 %
+ :alt: image of a control flow graph in GIMPLE SSA form
+
+You can see that the local variable `i` has been split into three versions:
+
+ * `i_4`, assigned to in block 2
+ * `i_11`, assigned to at the end of block 3
+ * `i_1`, assigned to at the top of block 4.
+
+As is normal with SSA, GCC inserts fake functions known as "PHI" at the start
+of basic blocks where needed in order to merge the multiple possible values of
+a variable. You can see one in our example at the top of the loop in block 4:
+
+.. code-block:: c
+
+ i_1 = PHI <i_4(2), i_11(3)>
+
+where i_1 either gets the value of i_4, or of i_11, depending on whether we
+reach here via block 2 (at the start of the iteration) or block 3 (continuing
+the "for" loop).
+
+After these optimizations passes are done, GCC converts the GIMPLE SSA
+representation into a lower-level representation known as Register Transfer
+Language (RTL). This is probably too low-level to be of interest to those
+seeking to add new compiler warnings: at this point it's attempting to work
+with the available opcodes and registers on the target CPU with the aim of
+generating efficient machine code.
+
+See http://gcc.gnu.org/onlinedocs/gccint/RTL.html
+
+The RTL form uses the same Control Flow Graph machinery as the GIMPLE
+representation, but with RTL expressions within the basic blocks.
+
+Once in RTL, GCC applies a series of further optimizations, before finally
+generating assembly language (which it submits to `as`, the GNU assembler):
+http://gcc.gnu.org/onlinedocs/gccint/RTL-passes.html
+You can see the assembly language using the `-S` command line option.
+
+.. code-block:: bash
+
+ $ ./gcc -S test.c
+ $ cat test.s
diff --git a/docs/index.rst b/docs/index.rst
index 4027663..eb04fe0 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -29,6 +29,7 @@ Contents:
:maxdepth: 2
basics.rst
+ gcc-overview.rst
examples.rst
cfg.rst
tree.rst
diff --git a/docs/sample-gimple-cfg.png b/docs/sample-gimple-cfg.png
new file mode 100644
index 0000000..91bc194
Binary files /dev/null and b/docs/sample-gimple-cfg.png differ
diff --git a/docs/sample-gimple-ssa-cfg.png b/docs/sample-gimple-ssa-cfg.png
new file mode 100644
index 0000000..b0a86d1
Binary files /dev/null and b/docs/sample-gimple-ssa-cfg.png differ
12 years, 11 months