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