⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ffe.texi

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 TEXI
📖 第 1 页 / 共 5 页
字号:
(and hopefully over shorter timeframes),for some of these other facilities.@node Two-pass Design@section Two-pass DesignThe FFE does not tell the GBE anything about a program unituntil after the last statement in that unit has been parsed.(A program unit is a Fortran concept that corresponds, in the C world,mostly closely to functions definitions in ISO C.That is, a program unit in Fortran is like a top-level function in C.Nested functions, found among the extensions offered by GNU C,correspond roughly to Fortran's statement functions.)So, while parsing the code in a program unit,the FFE saves up all the informationon statements, expressions, names, and so on,until it has seen the last statement.At that point, the FFE revisits the saved information(in what amounts to a second @dfn{pass} over the program unit)to perform the actual translation of the program unit into GBEL,ultimating in the generation of assembly code for it.Some lookahead is performed during this second pass,so the FFE could be viewed as a ``two-plus-pass'' design.@menu* Two-pass Code::* Why Two Passes::@end menu@node Two-pass Code@subsection Two-pass CodeMost of the code that turns the first pass (parsing)into a second pass for code generationis in @file{@value{path-g77}/std.c}.It has external functions,called mainly by siblings in @file{@value{path-g77}/stc.c},that record the information on statements and expressionsin the order they are seen in the source code.These functions save that information.It also has an external function that revisits that information,calling the siblings in @file{@value{path-g77}/ste.c},which handles the actual code generation(by generating GBEL code,that is, by calling GBE routinesto represent and specify expressions, statements, and so on).@node Why Two Passes@subsection Why Two PassesThe need for two passes was not immediately evidentduring the design and implementation of the code in the FFEthat was to produce GBEL.Only after a few kludges,to handle things like incorrectly-guessed @code{ASSIGN} label nature,had been implemented,did enough evidence pile up to make it clearthat @file{std.c} had to be introduced to intercept,save, then revisit as part of a second pass,the digested contents of a program unit.Other such missteps have occurred during the evolution of the FFE,because of the different goals of the FFE and the GBE.Because the GBE's original, and still primary, goalwas to directly support the GNU C language,the GBEL, and the GBE itself,requires more complexityon the part of most front endsthan it requires of @code{gcc}'s.For example,the GBEL offers an interface that permits the @code{gcc} front endto implement most, or all, of the language features it supports,without the front end having tomake use of non-user-defined variables.(It's almost certainly the case that all of K&R C,and probably ANSI C as well,is handled by the @code{gcc} front endwithout declaring such variables.)The FFE, on the other hand, must resort to a variety of ``tricks''to achieve its goals.Consider the following C code:@smallexampleintfoo (int a, int b)@{  int c = 0;  if ((c = bar (c)) == 0)    goto done;  quux (c << 1);done:  return c;@}@end smallexampleNote what kinds of objects are declared, or defined, before their use,and before any actual code generation involving themwould normally take place:@itemize @bullet@itemReturn type of function@itemEntry point(s) of function@itemDummy arguments@itemVariables@itemInitial values for variables@end itemizeWhereas, the following items can, and do,suddenly appear ``out of the blue'' in C:@itemize @bullet@itemLabel references@itemFunction references@end itemizeNot surprisingly, the GBE faithfully permits the latter set of itemsto be ``discovered'' partway through GBEL ``programs'',just as they are permitted to in C.Yet, the GBE has tended, at least in the past,to be reticent to fully support similar ``late'' discoveryof items in the former set.This makes Fortran a poor fit for the ``safe'' subset of GBEL.Consider:@smallexample      FUNCTION X (A, ARRAY, ID1)      CHARACTER*(*) A      DOUBLE PRECISION X, Y, Z, TMP, EE, PI      REAL ARRAY(ID1*ID2)      COMMON ID2      EXTERNAL FRED      ASSIGN 100 TO J      CALL FOO (I)      IF (I .EQ. 0) PRINT *, A(0)      GOTO 200      ENTRY Y (Z)      ASSIGN 101 TO J200   PRINT *, A(1)      READ *, TMP      GOTO J100   X = TMP * EE      RETURN101   Y = TMP * PI      CALL FRED      DATA EE, PI /2.71D0, 3.14D0/      END@end smallexampleHere are some observations about the above code,which, while somewhat contrived,conforms to the FORTRAN 77 and Fortran 90 standards:@itemize @bullet@itemThe return type of function @samp{X} is not knownuntil the @samp{DOUBLE PRECISION} line has been parsed.@itemWhether @samp{A} is a function or a variableis not known until the @samp{PRINT *, A(0)} statementhas been parsed.@itemThe bounds of the array of argument @samp{ARRAY}depend on a computation involvingthe subsequent argument @samp{ID1}and the blank-common member @samp{ID2}.@itemWhether @samp{Y} and @samp{Z} are local variables,additional function entry points,or dummy arguments to additional entry pointsis not knownuntil the @code{ENTRY} statement is parsed.@itemSimilarly, whether @samp{TMP} is a local variable is not knownuntil the @samp{READ *, TMP} statement is parsed.@itemThe initial values for @samp{EE} and @samp{PI}are not known until after the @code{DATA} statement is parsed.@itemWhether @samp{FRED} is a function returning type @code{REAL}or a subroutine(which can be thought of as returning type @code{void}@emph{or}, to support alternate returns in a simple way,type @code{int})is not knownuntil the @samp{CALL FRED} statement is parsed.@itemWhether @samp{100} is a @code{FORMAT} labelor the label of an executable statementis not knownuntil the @samp{X =} statement is parsed.(These two types of labels get @emph{very} different treatment,especially when @code{ASSIGN}'ed.)@itemThat @samp{J} is a local variable is not knownuntil the first @code{ASSIGN} statement is parsed.(This happens @emph{after} executable code has been seen.)@end itemizeVery few of these ``discoveries''can be accommodated by the GBE as it has evolved over the years.The GBEL doesn't support several of them,and those it might appear to supportdon't always work properly,especially in combination with other GBEL and GBE features,as implemented in the GBE.(Had the GBE and its GBEL originally evolved to support @code{g77},the shoe would be on the other foot, so to speak---most, if not all,of the above would be directly supported by the GBEL,and a few C constructs would probably not, as they are in reality,be supported.Both this mythical, and today's real, GBE caters to its GBELby, sometimes, scrambling around, cleaning up after itself---afterdiscovering that assumptions it made earlier during code generationare incorrect.)So, the FFE handles these discrepancies---between the order in whichit discovers facts about the code it is compiling,and the order in which the GBEL and GBE support such discoveries---byperforming what amounts to twopasses over each program unit.(A few ambiguities can remain at that point,such as whether, given @samp{EXTERNAL BAZ}and no other reference to @samp{BAZ} in the program unit,it is a subroutine, a function, or a block-data---which, in C-speak,governs its declared return type.Fortunately, these distinctions are easily finessedfor the procedure, library, and object-file interfacessupported by @code{g77}.)@node Challenges Posed@section Challenges PosedConsider the following Fortran code, which uses various extensions(including some to Fortran 90):@smallexampleSUBROUTINE X(A)CHARACTER*(*) ACOMPLEX CFUNCINTEGER*2 CLOCKS(200)INTEGER IFUNCCALL SYSTEM_CLOCK (CLOCKS (IFUNC (CFUNC ('('//A//')'))))@end smallexampleThe above poses the following challenges to any Fortran compilerthat uses run-time interfaces, and a run-time library, roughly similarto those used by @code{g77}:@itemize @bullet@itemAssuming the library routine that supports @code{SYSTEM_CLOCK}expects to set an @code{INTEGER*4} variable via its @code{COUNT} argument,the compiler must make available to it a temporary variable of that type.@itemFurther, after the @code{SYSTEM_CLOCK} library routine returns,the compiler must ensure that the temporary variable it wroteis copied into the appropriate element of the @samp{CLOCKS} array.(This assumes the compiler doesn't just reject the code,which it should if it is compiling under some kind of a ``strict'' option.)@itemTo determine the correct index into the @samp{CLOCKS} array,(putting aside the fact that the index, in this particular case,need not be computed until afterthe @code{SYSTEM_CLOCK} library routine returns),the compiler must ensure that the @code{IFUNC} function is called.That requires evaluating its argument,which requires, for @code{g77}(assuming @code{-ff2c} is in force),reserving a temporary variable of type @code{COMPLEX}for use as a repository for the return valuebeing computed by @samp{CFUNC}.@itemBefore invoking @samp{CFUNC},is argument must be evaluated,which requires allocating, at run time,a temporary large enough to hold the result of the concatenation,as well as actually performing the concatenation.@itemThe large temporary needed during invocation of @code{CFUNC}should, ideally, be deallocated(or, at least, left to the GBE to dispose of, as it sees fit)as soon as @code{CFUNC} returns,which means before @code{IFUNC} is called(as it might need a lot of dynamically allocated memory).@end itemize@code{g77} currently doesn't support all of the above,but, so that it might someday, it has evolved to handleat least some of the above requirements.Meeting the above requirements is made more challengingby conforming to the requirements of the GBEL/GBE combination.@node Transforming Statements@section Transforming StatementsMost Fortran statements are given their own block,and, for temporary variables they might need, their own scope.(A block is what distinguishes @samp{@{ foo (); @}}from just @samp{foo ();} in C.A scope is included with every such block,providing a distinct name space for local variables.)Label definitions for the statement precede this block,so @samp{10 PRINT *, I} is handled more like@samp{fl10: @{ @dots{} @}} than @samp{@{ fl10: @dots{} @}}(where @samp{fl10} is just a notation meaning ``Fortran Label 10''for the purposes of this document).@menu* Statements Needing Temporaries::* Transforming DO WHILE::* Transforming Iterative DO::* Transforming Block IF::* Transforming SELECT CASE::@end menu@node Statements Needing Temporaries@subsection Statements Needing TemporariesAny temporaries needed during, but not beyond,execution of a Fortran statement,are made local to the scope of that statement's block.This allows the GBE to share storage for these temporariesamong the various statements without the FFEhaving to manage that itself.(The GBE could, of course, decide to optimize management of these temporaries.For example, it could, theoretically,schedule some of the computations involving these temporariesto occur in parallel.More practically, it might leave the storage for some temporaries``live'' beyond their scopes, to reduce the number ofmanipulations of the stack pointer at run time.)Temporaries needed across distinct statement boundaries usuallyare associated with Fortran blocks (such as @code{DO}/@code{END DO}).(Also, there might be temporaries not associated with blocks at all---thesewould be in the scope of the entire program unit.)Each Fortran block @emph{should} get its own block/scope in the GBE.This is best, because it allows temporaries to be more naturally handled.However, it might pose problems when handling labels(in particular, when they're the targets of @code{GOTO}s outside the Fortranblock), and generally just hassling with replicatingparts of the @code{gcc} front end(because the FFE needs to supportan arbitrary number of nested back-end blocksif each Fortran block gets one).So, there might still be a need for top-level temporaries, whose``owning'' scope is that of the containing procedure.Also, there seems to be problems declaring new variables aftergenerating code (within a block) in the back end, leading to, e.g.,@samp{label not defined before binding contour} or similar messages,when compiling with @samp{-fstack-check} orwhen compiling for certain targets.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -