This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Language-independent functions-as-trees representation


I'd like to return to the discussion of a language-independent
functions-as-trees representation that was going on in January.  At this
point I'd like to ignore the question of representation within a particular
frontend (INITIAL?), and focus on what the frontend hands off to the
middle-end (GENERIC?) and the simplified form which is used in
optimization (SIMPLE).

Previous threads on the subject include:

  http://gcc.gnu.org/ml/gcc-patches/2000-06/threads.html#00460
  http://gcc.gnu.org/ml/gcc-patches/2001-11/threads.html#01332
  http://gcc.gnu.org/ml/gcc/2002-01/threads.html#00082

In each of these threads, rth and Per have disagreed over the EXPR/STMT
duality.  My oversimplified summary:

Per argues that having (for example) both IF_STMT and COND_EXPR is
gratuitous duplication.  rth argues that at the SIMPLE level we want to
distinguish statements (which have side effects/affect control flow) and
expressions (which don't).  Per points out that we don't need different
tree codes to get that distinction; we can just say that in SIMPLE a
COND_EXPR always has void type, so it only affects control flow.

Although I've argued with Per in the past, while working on the tree-ssa
branch I've largely come around to his point of view.  In SIMPLE, we deal
with lists of (let's call them) statements.  If one of these statements
affects control flow, we can tell that by the top tree code; it doesn't
matter whether it's spelled IF_STMT or COND_EXPR.  In GENERIC, we can't
tell anything from the top tree code, since expressions can contain
statements, so again the segregation of tree codes doesn't matter.

Working on SIMPLE has made this clearer to me because simplification
basically involves turning expressions into statements.  Sometimes an
expression is wrapped in another expression node, and I want to preserve
that nesting at the statement level.  But we can't currently nest _STMTs
inside _EXPRs, so we end up jumping through hoops.  For instance, to
simplify an EXPR_WITH_FILE_LOCATION, we create new _STMTs, set their line
numbers, and add FILE_STMTs as necessary.  It would be simpler if we could
just leave everything under the EXPR_WITH_FILE_LOCATION, and add it to the
list of tree codes which can contain other SIMPLE statements.  And I'm
looking at the same sort of thing when I start dealing with exception
handling constructs.  If I simplify something out from under a
TRY_CATCH_EXPR, I don't want to have to replace it with a TRY_BLOCK.

Furthermore, defining expressions to have no side-effects at all would seem
to exclude CALL_EXPRs, trapping arithmetic, and volatile accesses.  rth,
what exactly is the distinction you want to express?

-----
Other notes:

We still need to address the issue of expressing ordering requirements in
SIMPLE, as discussed in the third thread above.  For instance, currently
the tree-ssa branch always simplifies function arguments in left-to-right
order, which is not required for C and is inefficient on PUSH_ROUNDING
targets.  We need more tree codes to express these things.  Perhaps
SEQUENCE_POINT and UNORDERED_LIST would be sufficient.  I guess it's
reasonable to defer dealing with this until the basic infrastructure is
done, but I haven't seen an actual decision to that effect, it just seems
to have been dropped.

In a previous thread, Diego has suggested that inlining would be done on
language-dependent trees.  I think this is a mistake; IMO it should be done
at the SIMPLE level.  Requiring the inliner to know about frontend trees is
wrong.

Per (or other Java folk), why does the Java frontend use BLOCK as an
expression rather than use BIND_EXPR, which seems to serve the same
purpose?

The current TARGET_EXPR/WITH_CLEANUP_EXPR/CLEANUP_POINT_EXPR structure is
unsuited to a structured tree representation; it relies on bookkeeping
outside of the trees (i.e. expand_decl_cleanup/expand_cleanups).  I think
we should move some of those into the C++ frontend, as they are useful for
building up the C++ INITIAL representation, but that when we get to GENERIC 
they should be replaced with nested TRY_FINALLY_EXPRs.

SCOPE_STMT and DECL_STMT have no place in GENERIC, either.  The BIND_EXPR
abstraction is essentially the same as the LET_STMT in the McGill SIMPLE
document; it expresses a block which contains declarations and code for
which those decls are in scope.  This is a much more structured
representation, though again the others are a useful shorthand for INITIAL.

Jason


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]