Home | History | Annotate | Line # | Download | only in compiler
aslcompile.c revision 1.9
      1 /******************************************************************************
      2  *
      3  * Module Name: aslcompile - top level compile module
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2016, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "aslcompiler.h"
     45 #include "dtcompiler.h"
     46 #include "acnamesp.h"
     47 
     48 #include <stdio.h>
     49 #include <time.h>
     50 #include <acapps.h>
     51 
     52 #define _COMPONENT          ACPI_COMPILER
     53         ACPI_MODULE_NAME    ("aslcompile")
     54 
     55 /*
     56  * Main parser entry
     57  * External is here in case the parser emits the same external in the
     58  * generated header. (Newer versions of Bison)
     59  */
     60 int
     61 AslCompilerparse(
     62     void);
     63 
     64 /* Local prototypes */
     65 
     66 static void
     67 CmFlushSourceCode (
     68     void);
     69 
     70 static void
     71 CmDumpAllEvents (
     72     void);
     73 
     74 
     75 /*******************************************************************************
     76  *
     77  * FUNCTION:    CmDoCompile
     78  *
     79  * PARAMETERS:  None
     80  *
     81  * RETURN:      Status (0 = OK)
     82  *
     83  * DESCRIPTION: This procedure performs the entire compile
     84  *
     85  ******************************************************************************/
     86 
     87 int
     88 CmDoCompile (
     89     void)
     90 {
     91     ACPI_STATUS             Status;
     92     UINT8                   FullCompile;
     93     UINT8                   Event;
     94 
     95 
     96     FullCompile = UtBeginEvent ("*** Total Compile time ***");
     97     Event = UtBeginEvent ("Open input and output files");
     98     UtEndEvent (Event);
     99 
    100     Event = UtBeginEvent ("Preprocess input file");
    101     if (Gbl_PreprocessFlag)
    102     {
    103         /* Enter compiler name as a #define */
    104 
    105         PrAddDefine (ASL_DEFINE, "", FALSE);
    106 
    107         /* Preprocessor */
    108 
    109         PrDoPreprocess ();
    110         Gbl_CurrentLineNumber = 1;
    111         Gbl_LogicalLineNumber = 1;
    112 
    113         if (Gbl_PreprocessOnly)
    114         {
    115             UtEndEvent (Event);
    116             CmCleanupAndExit ();
    117             return (0);
    118         }
    119     }
    120     UtEndEvent (Event);
    121 
    122 
    123     /* Build the parse tree */
    124 
    125     Event = UtBeginEvent ("Parse source code and build parse tree");
    126     AslCompilerparse();
    127     UtEndEvent (Event);
    128 
    129     /* Check for parser-detected syntax errors */
    130 
    131     if (Gbl_SyntaxError)
    132     {
    133         fprintf (stderr,
    134             "Compiler aborting due to parser-detected syntax error(s)\n");
    135         LsDumpParseTree ();
    136         goto ErrorExit;
    137     }
    138 
    139     /* Did the parse tree get successfully constructed? */
    140 
    141     if (!Gbl_ParseTreeRoot)
    142     {
    143         /*
    144          * If there are no errors, then we have some sort of
    145          * internal problem.
    146          */
    147         AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
    148             NULL, "- Could not resolve parse tree root node");
    149 
    150         goto ErrorExit;
    151     }
    152 
    153     /* Flush out any remaining source after parse tree is complete */
    154 
    155     Event = UtBeginEvent ("Flush source input");
    156     CmFlushSourceCode ();
    157 
    158     /* Prune the parse tree if requested (debug purposes only) */
    159 
    160     if (Gbl_PruneParseTree)
    161     {
    162         AslPruneParseTree (Gbl_PruneDepth, Gbl_PruneType);
    163     }
    164 
    165     /* Optional parse tree dump, compiler debug output only */
    166 
    167     LsDumpParseTree ();
    168 
    169     OpcGetIntegerWidth (Gbl_ParseTreeRoot->Asl.Child);
    170     UtEndEvent (Event);
    171 
    172     /* Pre-process parse tree for any operator transforms */
    173 
    174     Event = UtBeginEvent ("Parse tree transforms");
    175     DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
    176     TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
    177         TrAmlTransformWalkBegin, TrAmlTransformWalkEnd, NULL);
    178     UtEndEvent (Event);
    179 
    180     /* Generate AML opcodes corresponding to the parse tokens */
    181 
    182     Event = UtBeginEvent ("Generate AML opcodes");
    183     DbgPrint (ASL_DEBUG_OUTPUT, "Generating AML opcodes\n\n");
    184     TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
    185         OpcAmlOpcodeWalk, NULL);
    186     UtEndEvent (Event);
    187 
    188     /*
    189      * Now that the input is parsed, we can open the AML output file.
    190      * Note: by default, the name of this file comes from the table
    191      * descriptor within the input file.
    192      */
    193     Event = UtBeginEvent ("Open AML output file");
    194     Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
    195     UtEndEvent (Event);
    196     if (ACPI_FAILURE (Status))
    197     {
    198         AePrintErrorLog (ASL_FILE_STDERR);
    199         return (-1);
    200     }
    201 
    202     /* Interpret and generate all compile-time constants */
    203 
    204     Event = UtBeginEvent ("Constant folding via AML interpreter");
    205     DbgPrint (ASL_DEBUG_OUTPUT,
    206         "Interpreting compile-time constant expressions\n\n");
    207 
    208     if (Gbl_FoldConstants)
    209     {
    210         TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
    211             NULL, OpcAmlConstantWalk, NULL);
    212     }
    213     else
    214     {
    215         DbgPrint (ASL_PARSE_OUTPUT, "    Optional folding disabled\n");
    216     }
    217     UtEndEvent (Event);
    218 
    219     /* Update AML opcodes if necessary, after constant folding */
    220 
    221     Event = UtBeginEvent ("Updating AML opcodes after constant folding");
    222     DbgPrint (ASL_DEBUG_OUTPUT,
    223         "Updating AML opcodes after constant folding\n\n");
    224     TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
    225         NULL, OpcAmlOpcodeUpdateWalk, NULL);
    226     UtEndEvent (Event);
    227 
    228     /* Calculate all AML package lengths */
    229 
    230     Event = UtBeginEvent ("Generate AML package lengths");
    231     DbgPrint (ASL_DEBUG_OUTPUT, "Generating Package lengths\n\n");
    232     TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
    233         LnPackageLengthWalk, NULL);
    234     UtEndEvent (Event);
    235 
    236     if (Gbl_ParseOnlyFlag)
    237     {
    238         AePrintErrorLog (ASL_FILE_STDERR);
    239         UtDisplaySummary (ASL_FILE_STDERR);
    240         if (Gbl_DebugFlag)
    241         {
    242             /* Print error summary to the stdout also */
    243 
    244             AePrintErrorLog (ASL_FILE_STDOUT);
    245             UtDisplaySummary (ASL_FILE_STDOUT);
    246         }
    247         UtEndEvent (FullCompile);
    248         return (0);
    249     }
    250 
    251     /*
    252      * Create an internal namespace and use it as a symbol table
    253      */
    254 
    255     /* Namespace loading */
    256 
    257     Event = UtBeginEvent ("Create ACPI Namespace");
    258     DbgPrint (ASL_DEBUG_OUTPUT, "Creating ACPI Namespace\n\n");
    259     Status = LdLoadNamespace (Gbl_ParseTreeRoot);
    260     UtEndEvent (Event);
    261     if (ACPI_FAILURE (Status))
    262     {
    263         goto ErrorExit;
    264     }
    265 
    266     /* Namespace cross-reference */
    267 
    268     AslGbl_NamespaceEvent = UtBeginEvent (
    269         "Cross reference parse tree and Namespace");
    270     DbgPrint (ASL_DEBUG_OUTPUT, "Cross referencing namespace\n\n");
    271     Status = XfCrossReferenceNamespace ();
    272     if (ACPI_FAILURE (Status))
    273     {
    274         goto ErrorExit;
    275     }
    276 
    277     /* Namespace - Check for non-referenced objects */
    278 
    279     LkFindUnreferencedObjects ();
    280     UtEndEvent (AslGbl_NamespaceEvent);
    281 
    282     /* Resolve External Declarations */
    283 
    284     if (Gbl_DoExternals)
    285     {
    286         Event = UtBeginEvent ("Resolve all Externals");
    287         DbgPrint (ASL_DEBUG_OUTPUT, "\nResolve Externals\n\n");
    288         TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
    289             ExAmlExternalWalkBegin, ExAmlExternalWalkEnd, NULL);
    290         UtEndEvent (Event);
    291     }
    292 
    293     /*
    294      * Semantic analysis. This can happen only after the
    295      * namespace has been loaded and cross-referenced.
    296      *
    297      * part one - check control methods
    298      */
    299     Event = UtBeginEvent ("Analyze control method return types");
    300     AnalysisWalkInfo.MethodStack = NULL;
    301 
    302     DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Method analysis\n\n");
    303 
    304     if (Gbl_CrossReferenceOutput)
    305     {
    306         OtPrintHeaders ("Part 1: Object Reference Map "
    307             "(Object references from within each control method)");
    308     }
    309 
    310     TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
    311         MtMethodAnalysisWalkBegin,
    312         MtMethodAnalysisWalkEnd, &AnalysisWalkInfo);
    313     UtEndEvent (Event);
    314 
    315     /* Generate the object cross-reference file if requested */
    316 
    317     Event = UtBeginEvent ("Generate cross-reference file");
    318     OtCreateXrefFile ();
    319     UtEndEvent (Event);
    320 
    321     /* Semantic error checking part two - typing of method returns */
    322 
    323     Event = UtBeginEvent ("Determine object types returned by methods");
    324     DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Method typing\n\n");
    325     TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
    326         NULL, AnMethodTypingWalkEnd, NULL);
    327     UtEndEvent (Event);
    328 
    329     /* Semantic error checking part three - operand type checking */
    330 
    331     Event = UtBeginEvent ("Analyze AML operand types");
    332     DbgPrint (ASL_DEBUG_OUTPUT,
    333         "Semantic analysis - Operand type checking\n\n");
    334     if (Gbl_DoTypechecking)
    335     {
    336         TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
    337             NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
    338     }
    339     UtEndEvent (Event);
    340 
    341     /* Semantic error checking part four - other miscellaneous checks */
    342 
    343     Event = UtBeginEvent ("Miscellaneous analysis");
    344     DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - miscellaneous\n\n");
    345     TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
    346         AnOtherSemanticAnalysisWalkBegin,
    347         NULL, &AnalysisWalkInfo);
    348     UtEndEvent (Event);
    349 
    350     /* Calculate all AML package lengths */
    351 
    352     Event = UtBeginEvent ("Finish AML package length generation");
    353     DbgPrint (ASL_DEBUG_OUTPUT, "Generating Package lengths\n\n");
    354     TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
    355         LnInitLengthsWalk, NULL);
    356     TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
    357         LnPackageLengthWalk, NULL);
    358     UtEndEvent (Event);
    359 
    360     /* Code generation - emit the AML */
    361 
    362     Event = UtBeginEvent ("Generate AML code and write output files");
    363     DbgPrint (ASL_DEBUG_OUTPUT, "Writing AML byte code\n\n");
    364     CgGenerateAmlOutput ();
    365     UtEndEvent (Event);
    366 
    367     Event = UtBeginEvent ("Write optional output files");
    368     CmDoOutputFiles ();
    369     UtEndEvent (Event);
    370 
    371     UtEndEvent (FullCompile);
    372     CmCleanupAndExit ();
    373     return (0);
    374 
    375 ErrorExit:
    376     UtEndEvent (FullCompile);
    377     CmCleanupAndExit ();
    378     return (-1);
    379 }
    380 
    381 
    382 /*******************************************************************************
    383  *
    384  * FUNCTION:    AslCompilerSignon
    385  *
    386  * PARAMETERS:  FileId      - ID of the output file
    387  *
    388  * RETURN:      None
    389  *
    390  * DESCRIPTION: Display compiler signon
    391  *
    392  ******************************************************************************/
    393 
    394 void
    395 AslCompilerSignon (
    396     UINT32                  FileId)
    397 {
    398     char                    *Prefix = "";
    399     char                    *UtilityName;
    400 
    401 
    402     /* Set line prefix depending on the destination file type */
    403 
    404     switch (FileId)
    405     {
    406     case ASL_FILE_ASM_SOURCE_OUTPUT:
    407     case ASL_FILE_ASM_INCLUDE_OUTPUT:
    408 
    409         Prefix = "; ";
    410         break;
    411 
    412     case ASL_FILE_HEX_OUTPUT:
    413 
    414         if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
    415         {
    416             Prefix = "; ";
    417         }
    418         else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
    419                  (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
    420         {
    421             FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n");
    422             Prefix = " * ";
    423         }
    424         break;
    425 
    426     case ASL_FILE_C_SOURCE_OUTPUT:
    427     case ASL_FILE_C_OFFSET_OUTPUT:
    428     case ASL_FILE_C_INCLUDE_OUTPUT:
    429 
    430         Prefix = " * ";
    431         break;
    432 
    433     default:
    434 
    435         /* No other output types supported */
    436 
    437         break;
    438     }
    439 
    440     /* Running compiler or disassembler? */
    441 
    442     if (Gbl_DisasmFlag)
    443     {
    444         UtilityName = AML_DISASSEMBLER_NAME;
    445     }
    446     else
    447     {
    448         UtilityName = ASL_COMPILER_NAME;
    449     }
    450 
    451     /* Compiler signon with copyright */
    452 
    453     FlPrintFile (FileId, "%s\n", Prefix);
    454     FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix));
    455 }
    456 
    457 
    458 /*******************************************************************************
    459  *
    460  * FUNCTION:    AslCompilerFileHeader
    461  *
    462  * PARAMETERS:  FileId      - ID of the output file
    463  *
    464  * RETURN:      None
    465  *
    466  * DESCRIPTION: Header used at the beginning of output files
    467  *
    468  ******************************************************************************/
    469 
    470 void
    471 AslCompilerFileHeader (
    472     UINT32                  FileId)
    473 {
    474     struct tm               *NewTime;
    475     time_t                  Aclock;
    476     char                    *Prefix = "";
    477 
    478 
    479     /* Set line prefix depending on the destination file type */
    480 
    481     switch (FileId)
    482     {
    483     case ASL_FILE_ASM_SOURCE_OUTPUT:
    484     case ASL_FILE_ASM_INCLUDE_OUTPUT:
    485 
    486         Prefix = "; ";
    487         break;
    488 
    489     case ASL_FILE_HEX_OUTPUT:
    490 
    491         if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
    492         {
    493             Prefix = "; ";
    494         }
    495         else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
    496                  (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
    497         {
    498             Prefix = " * ";
    499         }
    500         break;
    501 
    502     case ASL_FILE_C_SOURCE_OUTPUT:
    503     case ASL_FILE_C_OFFSET_OUTPUT:
    504     case ASL_FILE_C_INCLUDE_OUTPUT:
    505 
    506         Prefix = " * ";
    507         break;
    508 
    509     default:
    510 
    511         /* No other output types supported */
    512 
    513         break;
    514     }
    515 
    516     /* Compilation header with timestamp */
    517 
    518     (void) time (&Aclock);
    519     NewTime = localtime (&Aclock);
    520 
    521     FlPrintFile (FileId,
    522         "%sCompilation of \"%s\" - %s%s\n",
    523         Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime),
    524         Prefix);
    525 
    526     switch (FileId)
    527     {
    528     case ASL_FILE_C_SOURCE_OUTPUT:
    529     case ASL_FILE_C_OFFSET_OUTPUT:
    530     case ASL_FILE_C_INCLUDE_OUTPUT:
    531 
    532         FlPrintFile (FileId, " */\n");
    533         break;
    534 
    535     default:
    536 
    537         /* Nothing to do for other output types */
    538 
    539         break;
    540     }
    541 }
    542 
    543 
    544 /*******************************************************************************
    545  *
    546  * FUNCTION:    CmFlushSourceCode
    547  *
    548  * PARAMETERS:  None
    549  *
    550  * RETURN:      None
    551  *
    552  * DESCRIPTION: Read in any remaining source code after the parse tree
    553  *              has been constructed.
    554  *
    555  ******************************************************************************/
    556 
    557 static void
    558 CmFlushSourceCode (
    559     void)
    560 {
    561     char                    Buffer;
    562 
    563 
    564     while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
    565     {
    566         AslInsertLineBuffer ((int) Buffer);
    567     }
    568 
    569     AslResetCurrentLineBuffer ();
    570 }
    571 
    572 
    573 /*******************************************************************************
    574  *
    575  * FUNCTION:    CmDoOutputFiles
    576  *
    577  * PARAMETERS:  None
    578  *
    579  * RETURN:      None.
    580  *
    581  * DESCRIPTION: Create all "listing" type files
    582  *
    583  ******************************************************************************/
    584 
    585 void
    586 CmDoOutputFiles (
    587     void)
    588 {
    589 
    590     /* Create listings and hex files */
    591 
    592     LsDoListings ();
    593     HxDoHexOutput ();
    594 
    595     /* Dump the namespace to the .nsp file if requested */
    596 
    597     (void) NsDisplayNamespace ();
    598 
    599     /* Dump the device mapping file */
    600 
    601     MpEmitMappingInfo ();
    602 }
    603 
    604 
    605 /*******************************************************************************
    606  *
    607  * FUNCTION:    CmDumpAllEvents
    608  *
    609  * PARAMETERS:  None
    610  *
    611  * RETURN:      None.
    612  *
    613  * DESCRIPTION: Dump all compiler events
    614  *
    615  ******************************************************************************/
    616 
    617 static void
    618 CmDumpAllEvents (
    619     void)
    620 {
    621     ASL_EVENT_INFO          *Event;
    622     UINT32                  Delta;
    623     UINT32                  MicroSeconds;
    624     UINT32                  MilliSeconds;
    625     UINT32                  i;
    626 
    627 
    628     Event = AslGbl_Events;
    629 
    630     DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
    631     if (Gbl_CompileTimesFlag)
    632     {
    633         printf ("\nElapsed time for major events\n\n");
    634     }
    635 
    636     for (i = 0; i < AslGbl_NextEvent; i++)
    637     {
    638         if (Event->Valid)
    639         {
    640             /* Delta will be in 100-nanosecond units */
    641 
    642             Delta = (UINT32) (Event->EndTime - Event->StartTime);
    643 
    644             MicroSeconds = Delta / ACPI_100NSEC_PER_USEC;
    645             MilliSeconds = Delta / ACPI_100NSEC_PER_MSEC;
    646 
    647             /* Round milliseconds up */
    648 
    649             if ((MicroSeconds - (MilliSeconds * ACPI_USEC_PER_MSEC)) >= 500)
    650             {
    651                 MilliSeconds++;
    652             }
    653 
    654             DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
    655                 MicroSeconds, MilliSeconds, Event->EventName);
    656 
    657             if (Gbl_CompileTimesFlag)
    658             {
    659                 printf ("%8u usec %8u msec - %s\n",
    660                     MicroSeconds, MilliSeconds, Event->EventName);
    661             }
    662         }
    663 
    664         Event++;
    665     }
    666 }
    667 
    668 
    669 /*******************************************************************************
    670  *
    671  * FUNCTION:    CmCleanupAndExit
    672  *
    673  * PARAMETERS:  None
    674  *
    675  * RETURN:      None.
    676  *
    677  * DESCRIPTION: Close all open files and exit the compiler
    678  *
    679  ******************************************************************************/
    680 
    681 void
    682 CmCleanupAndExit (
    683     void)
    684 {
    685     UINT32                  i;
    686     BOOLEAN                 DeleteAmlFile = FALSE;
    687 
    688 
    689     AePrintErrorLog (ASL_FILE_STDERR);
    690     if (Gbl_DebugFlag)
    691     {
    692         /* Print error summary to stdout also */
    693 
    694         AePrintErrorLog (ASL_FILE_STDOUT);
    695     }
    696 
    697     /* Emit compile times if enabled */
    698 
    699     CmDumpAllEvents ();
    700 
    701     if (Gbl_CompileTimesFlag)
    702     {
    703         printf ("\nMiscellaneous compile statistics\n\n");
    704         printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
    705         printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
    706         printf ("%11u : %s\n", TotalNamedObjects, "Named objects");
    707         printf ("%11u : %s\n", TotalMethods, "Control methods");
    708         printf ("%11u : %s\n", TotalAllocations, "Memory Allocations");
    709         printf ("%11u : %s\n", TotalAllocated, "Total allocated memory");
    710         printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded");
    711         printf ("\n");
    712     }
    713 
    714     if (Gbl_NsLookupCount)
    715     {
    716         DbgPrint (ASL_DEBUG_OUTPUT,
    717             "\n\nMiscellaneous compile statistics\n\n");
    718 
    719         DbgPrint (ASL_DEBUG_OUTPUT,
    720             "%32s : %u\n", "Total Namespace searches",
    721             Gbl_NsLookupCount);
    722 
    723         DbgPrint (ASL_DEBUG_OUTPUT,
    724             "%32s : %u usec\n", "Time per search", ((UINT32)
    725             (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
    726                 AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
    727                 Gbl_NsLookupCount);
    728     }
    729 
    730     if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
    731     {
    732         printf ("\nMaximum error count (%u) exceeded\n",
    733             ASL_MAX_ERROR_COUNT);
    734     }
    735 
    736     UtDisplaySummary (ASL_FILE_STDOUT);
    737 
    738     /*
    739      * We will delete the AML file if there are errors and the
    740      * force AML output option has not been used.
    741      */
    742     if ((Gbl_ExceptionCount[ASL_ERROR] > 0) &&
    743         (!Gbl_IgnoreErrors) &&
    744         Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
    745     {
    746         DeleteAmlFile = TRUE;
    747     }
    748 
    749     /* Close all open files */
    750 
    751     /*
    752      * Take care with the preprocessor file (.pre), it might be the same
    753      * as the "input" file, depending on where the compiler has terminated
    754      * or aborted. Prevent attempt to close the same file twice in
    755      * loop below.
    756      */
    757     if (Gbl_Files[ASL_FILE_PREPROCESSOR].Handle ==
    758         Gbl_Files[ASL_FILE_INPUT].Handle)
    759     {
    760         Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL;
    761     }
    762 
    763     /* Close the standard I/O files */
    764 
    765     for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
    766     {
    767         FlCloseFile (i);
    768     }
    769 
    770     /* Delete AML file if there are errors */
    771 
    772     if (DeleteAmlFile)
    773     {
    774         FlDeleteFile (ASL_FILE_AML_OUTPUT);
    775     }
    776 
    777     /* Delete the preprocessor temp file unless full debug was specified */
    778 
    779     if (Gbl_PreprocessFlag && !Gbl_KeepPreprocessorTempFile)
    780     {
    781         FlDeleteFile (ASL_FILE_PREPROCESSOR);
    782     }
    783 
    784     /*
    785      * Delete intermediate ("combined") source file (if -ls flag not set)
    786      * This file is created during normal ASL/AML compiles. It is not
    787      * created by the data table compiler.
    788      *
    789      * If the -ls flag is set, then the .SRC file should not be deleted.
    790      * In this case, Gbl_SourceOutputFlag is set to TRUE.
    791      *
    792      * Note: Handles are cleared by FlCloseFile above, so we look at the
    793      * filename instead, to determine if the .SRC file was actually
    794      * created.
    795      */
    796     if (!Gbl_SourceOutputFlag)
    797     {
    798         FlDeleteFile (ASL_FILE_SOURCE_OUTPUT);
    799     }
    800 
    801     /* Final cleanup after compiling one file */
    802 
    803     CmDeleteCaches ();
    804 }
    805 
    806 
    807 /*******************************************************************************
    808  *
    809  * FUNCTION:    CmDeleteCaches
    810  *
    811  * PARAMETERS:  None
    812  *
    813  * RETURN:      None
    814  *
    815  * DESCRIPTION: Delete all local cache buffer blocks
    816  *
    817  ******************************************************************************/
    818 
    819 void
    820 CmDeleteCaches (
    821     void)
    822 {
    823     UINT32                  BufferCount;
    824     ASL_CACHE_INFO          *Next;
    825 
    826 
    827     /* Parse Op cache */
    828 
    829     BufferCount = 0;
    830     while (Gbl_ParseOpCacheList)
    831     {
    832         Next = Gbl_ParseOpCacheList->Next;
    833         ACPI_FREE (Gbl_ParseOpCacheList);
    834         Gbl_ParseOpCacheList = Next;
    835         BufferCount++;
    836     }
    837 
    838     DbgPrint (ASL_DEBUG_OUTPUT,
    839         "%u ParseOps, Buffer size: %u ops (%u bytes), %u Buffers\n",
    840         Gbl_ParseOpCount, ASL_PARSEOP_CACHE_SIZE,
    841         (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE), BufferCount);
    842 
    843     Gbl_ParseOpCount = 0;
    844     Gbl_ParseOpCacheNext = NULL;
    845     Gbl_ParseOpCacheLast = NULL;
    846     Gbl_ParseTreeRoot = NULL;
    847 
    848     /* Generic string cache */
    849 
    850     BufferCount = 0;
    851     while (Gbl_StringCacheList)
    852     {
    853         Next = Gbl_StringCacheList->Next;
    854         ACPI_FREE (Gbl_StringCacheList);
    855         Gbl_StringCacheList = Next;
    856         BufferCount++;
    857     }
    858 
    859     DbgPrint (ASL_DEBUG_OUTPUT,
    860         "%u Strings (%u bytes), Buffer size: %u bytes, %u Buffers\n",
    861         Gbl_StringCount, Gbl_StringSize, ASL_STRING_CACHE_SIZE, BufferCount);
    862 
    863     Gbl_StringSize = 0;
    864     Gbl_StringCount = 0;
    865     Gbl_StringCacheNext = NULL;
    866     Gbl_StringCacheLast = NULL;
    867 }
    868