Merge from vendor branch TCPDUMP:
[dragonfly.git] / sys / contrib / dev / acpica-unix-20031203 / compiler / aslopt.c
1 /******************************************************************************
2  *
3  * Module Name: aslopt- Compiler optimizations
4  *              $Revision: 12 $
5  *
6  *****************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp.
13  * All rights reserved.
14  *
15  * 2. License
16  *
17  * 2.1. This is your license from Intel Corp. under its intellectual property
18  * rights.  You may have additional license terms from the party that provided
19  * you this software, covering your right to use that party's intellectual
20  * property rights.
21  *
22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23  * copy of the source code appearing in this file ("Covered Code") an
24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25  * base code distributed originally by Intel ("Original Intel Code") to copy,
26  * make derivatives, distribute, use and display any portion of the Covered
27  * Code in any form, with the right to sublicense such rights; and
28  *
29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30  * license (with the right to sublicense), under only those claims of Intel
31  * patents that are infringed by the Original Intel Code, to make, use, sell,
32  * offer to sell, and import the Covered Code and derivative works thereof
33  * solely to the minimum extent necessary to exercise the above copyright
34  * license, and in no event shall the patent license extend to any additions
35  * to or modifications of the Original Intel Code.  No other license or right
36  * is granted directly or by implication, estoppel or otherwise;
37  *
38  * The above copyright and patent license is granted only if the following
39  * conditions are met:
40  *
41  * 3. Conditions
42  *
43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44  * Redistribution of source code of any substantial portion of the Covered
45  * Code or modification with rights to further distribute source must include
46  * the above Copyright Notice, the above License, this list of Conditions,
47  * and the following Disclaimer and Export Compliance provision.  In addition,
48  * Licensee must cause all Covered Code to which Licensee contributes to
49  * contain a file documenting the changes Licensee made to create that Covered
50  * Code and the date of any change.  Licensee must include in that file the
51  * documentation of any changes made by any predecessor Licensee.  Licensee
52  * must include a prominent statement that the modification is derived,
53  * directly or indirectly, from Original Intel Code.
54  *
55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56  * Redistribution of source code of any substantial portion of the Covered
57  * Code or modification without rights to further distribute source must
58  * include the following Disclaimer and Export Compliance provision in the
59  * documentation and/or other materials provided with distribution.  In
60  * addition, Licensee may not authorize further sublicense of source of any
61  * portion of the Covered Code, and must include terms to the effect that the
62  * license from Licensee to its licensee is limited to the intellectual
63  * property embodied in the software Licensee provides to its licensee, and
64  * not to intellectual property embodied in modifications its licensee may
65  * make.
66  *
67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
68  * substantial portion of the Covered Code or modification must reproduce the
69  * above Copyright Notice, and the following Disclaimer and Export Compliance
70  * provision in the documentation and/or other materials provided with the
71  * distribution.
72  *
73  * 3.4. Intel retains all right, title, and interest in and to the Original
74  * Intel Code.
75  *
76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77  * Intel shall be used in advertising or otherwise to promote the sale, use or
78  * other dealings in products derived from or relating to the Covered Code
79  * without prior written authorization from Intel.
80  *
81  * 4. Disclaimer and Export Compliance
82  *
83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89  * PARTICULAR PURPOSE.
90  *
91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98  * LIMITED REMEDY.
99  *
100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
101  * software or system incorporating such software without first obtaining any
102  * required license or other approval from the U. S. Department of Commerce or
103  * any other agency or department of the United States Government.  In the
104  * event Licensee exports any such software from the United States or
105  * re-exports any such software from a foreign destination, Licensee shall
106  * ensure that the distribution and export/re-export of the software is in
107  * compliance with all laws, regulations, orders, or other restrictions of the
108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109  * any of its subsidiaries will export/re-export any technical data, process,
110  * software, or service, directly or indirectly, to any country for which the
111  * United States government or any agency thereof requires an export license,
112  * other governmental approval, or letter of assurance, without first obtaining
113  * such license, approval or letter.
114  *
115  *****************************************************************************/
116
117
118 #include "aslcompiler.h"
119 #include "aslcompiler.y.h"
120
121 #include "acparser.h"
122 #include "amlcode.h"
123 #include "acnamesp.h"
124
125
126 #define _COMPONENT          ACPI_COMPILER
127         ACPI_MODULE_NAME    ("aslopt")
128
129
130 UINT32 OptTotal = 0;
131
132
133 /*******************************************************************************
134  *
135  * FUNCTION:    OptSearchToRoot
136  *
137  * PARAMETERS:  Op                  - Current parser op
138  *              WalkState           - Current state
139  *              CurrentNode         - Where we are in the namespace
140  *              TargetNode          - Node to which we are referring
141  *              TargetPath          - External full path to the target node
142  *              NewPath             - Where the optimized path is returned
143  *
144  * RETURN:      Status
145  *
146  * DESCRIPTION: Attempt to optimize a reference to a single 4-character ACPI
147  *              name utilizing the search-to-root name resolution algorithm
148  *              that is used by AML interpreters.
149  *
150  ******************************************************************************/
151
152 ACPI_STATUS
153 OptSearchToRoot (
154     ACPI_PARSE_OBJECT       *Op,
155     ACPI_WALK_STATE         *WalkState,
156     ACPI_NAMESPACE_NODE     *CurrentNode,
157     ACPI_NAMESPACE_NODE     *TargetNode,
158     ACPI_BUFFER             *TargetPath,
159     char                    **NewPath)
160 {
161     ACPI_NAMESPACE_NODE     *Node;
162     ACPI_GENERIC_STATE      ScopeInfo;
163     ACPI_STATUS             Status;
164     char                    *Path;
165
166
167     ACPI_FUNCTION_NAME ("OptSearchToRoot");
168
169
170     /*
171      * Check if search-to-root can be utilized.  Use the last NameSeg of
172      * the NamePath and 1) See if can be found and 2) If found, make
173      * sure that it is the same node that we want.  If there is another
174      * name in the search path before the one we want, the nodes will
175      * not match, and we cannot use this optimization.
176      */
177     Path = &(((char *) TargetPath->Pointer)[TargetPath->Length - ACPI_NAME_SIZE]),
178     ScopeInfo.Scope.Node = CurrentNode;
179
180     /* Lookup the NameSeg using SEARCH_PARENT (search-to-root) */
181
182     Status = AcpiNsLookup (&ScopeInfo, Path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
183                     ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
184                     WalkState, &(Node));
185     if (ACPI_FAILURE (Status))
186     {
187         return (Status);
188     }
189
190     /*
191      * We found the name, but we must check to make sure that the node
192      * matches.  Otherwise, there is another identical name in the search
193      * path that precludes the use of this optimization.
194      */
195     if (Node != TargetNode)
196     {
197         /*
198          * This means that another object with the same name was found first,
199          * and we cannot use this optimization.
200          */
201         return (AE_NOT_FOUND);
202     }
203
204     /* Found the node, we can use this optimization */
205
206     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
207         "NAMESEG:   %-24s", Path));
208
209     /* We must allocate a new string for the name (TargetPath gets deleted) */
210
211     *NewPath = ACPI_MEM_CALLOCATE (ACPI_NAME_SIZE + 1);
212     ACPI_STRCPY (*NewPath, Path);
213
214     AslError (ASL_OPTIMIZATION, ASL_MSG_SINGLE_NAME_OPTIMIZATION, Op,
215             *NewPath);
216
217     return (AE_OK);
218 }
219
220
221 /*******************************************************************************
222  *
223  * FUNCTION:    OptBuildShortestPath
224  *
225  * PARAMETERS:  Op                  - Current parser op
226  *              WalkState           - Current state
227  *              CurrentNode         - Where we are in the namespace
228  *              TargetNode          - Node to which we are referring
229  *              CurrentPath         - External full path to the current node
230  *              TargetPath          - External full path to the target node
231  *              AmlNameStringLength - Length of the original namepath
232  *              IsDeclaration       - TRUE for declaration, FALSE for reference
233  *              ReturnNewPath       - Where the optimized path is returned
234  *
235  * RETURN:      Status
236  *
237  * DESCRIPTION: Build an optimal NamePath using carats
238  *
239  ******************************************************************************/
240
241 ACPI_STATUS
242 OptBuildShortestPath (
243     ACPI_PARSE_OBJECT       *Op,
244     ACPI_WALK_STATE         *WalkState,
245     ACPI_NAMESPACE_NODE     *CurrentNode,
246     ACPI_NAMESPACE_NODE     *TargetNode,
247     ACPI_BUFFER             *CurrentPath,
248     ACPI_BUFFER             *TargetPath,
249     ACPI_SIZE               AmlNameStringLength,
250     UINT8                   IsDeclaration,
251     char                    **ReturnNewPath)
252 {
253     UINT32                  NumCommonSegments;
254     UINT32                  MaxCommonSegments;
255     ACPI_NATIVE_UINT        Index;
256     UINT32                  NumCarats;
257     ACPI_NATIVE_UINT        i;
258     char                    *NewPath;
259     char                    *NewPathExternal;
260     ACPI_NAMESPACE_NODE     *Node;
261     ACPI_GENERIC_STATE      ScopeInfo;
262     ACPI_STATUS             Status;
263     BOOLEAN                 SubPath = FALSE;
264
265
266     ACPI_FUNCTION_NAME ("OptBuildShortestPath");
267
268
269     ScopeInfo.Scope.Node = CurrentNode;
270
271     /*
272      * Determine the maximum number of NameSegs that the Target and Current paths
273      * can possibly have in common.  (To optimize, we have to have at least 1)
274      *
275      * Note: The external NamePath string lengths are always a multiple of 5
276      * (ACPI_NAME_SIZE + separator)
277      */
278     MaxCommonSegments = TargetPath->Length / ACPI_PATH_SEGMENT_LENGTH;
279     if (CurrentPath->Length < TargetPath->Length)
280     {
281         MaxCommonSegments = CurrentPath->Length / ACPI_PATH_SEGMENT_LENGTH;
282     }
283
284     /*
285      * Determine how many NameSegs the two paths have in common.
286      * (Starting from the root)
287      */
288     for (NumCommonSegments = 0;
289          NumCommonSegments < MaxCommonSegments;
290          NumCommonSegments++)
291     {
292         /* Compare two single NameSegs */
293
294         if (ACPI_STRNCMP (
295             &((char *) TargetPath->Pointer)[(NumCommonSegments * ACPI_PATH_SEGMENT_LENGTH) + 1],
296             &((char *) CurrentPath->Pointer)[(NumCommonSegments * ACPI_PATH_SEGMENT_LENGTH) + 1],
297             ACPI_NAME_SIZE))
298         {
299             /* Mismatch */
300
301             break;
302         }
303     }
304
305     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " COMMON: %d", NumCommonSegments));
306
307     /* There must be at least 1 common NameSeg in order to optimize */
308
309     if (NumCommonSegments == 0)
310     {
311         return (AE_NOT_FOUND);
312     }
313
314     if (NumCommonSegments == MaxCommonSegments)
315     {
316         if (CurrentPath->Length == TargetPath->Length)
317         {
318             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " SAME PATH"));
319             return (AE_NOT_FOUND);
320         }
321         else
322         {
323             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " SUBPATH"));
324             SubPath = TRUE;
325         }
326     }
327
328     /* Determine how many prefix Carats are required */
329
330     NumCarats = (CurrentPath->Length / ACPI_PATH_SEGMENT_LENGTH) - NumCommonSegments;
331
332     /*
333      * Construct a new target string
334      */
335     NewPathExternal = ACPI_MEM_CALLOCATE (TargetPath->Length + NumCarats);
336
337     /* Insert the Carats into the Target string */
338
339     for (i = 0; i < NumCarats; i++)
340     {
341         NewPathExternal[i] = '^';
342     }
343
344     /* Copy only the necessary (optimal) segments from the original target string */
345
346     Index = (NumCommonSegments * ACPI_PATH_SEGMENT_LENGTH) + 1;
347
348     /* Special handling for exact subpath in a name declaration */
349
350     if (IsDeclaration && SubPath && (CurrentPath->Length > TargetPath->Length))
351     {
352         /*
353          * The current path is longer than the target, and the target is a subpath
354          * of the current path.  We must include one more NameSeg of the target path
355          */
356         Index -= ACPI_PATH_SEGMENT_LENGTH;
357     }
358
359     ACPI_STRCPY (&NewPathExternal[i], &((char *) TargetPath->Pointer)[Index]);
360     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " %-24s", NewPathExternal));
361
362     /*
363      * Internalize the new target string and check it against the original string
364      * to make sure that this is in fact an optimization.  If the original string
365      * is already optimal, there is no point in continuing.
366      */
367     Status = AcpiNsInternalizeName (NewPathExternal, &NewPath);
368
369     if (ACPI_FAILURE (Status))
370     {
371         AslCoreSubsystemError (Op, Status, "Internalizing new NamePath", ASL_NO_ABORT);
372         ACPI_MEM_FREE (NewPathExternal);
373         return (Status);
374     }
375
376     if (ACPI_STRLEN (NewPath) >= AmlNameStringLength)
377     {
378         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " NOT SHORTER (New %d old %d)",
379             ACPI_STRLEN (NewPath), AmlNameStringLength));
380         ACPI_MEM_FREE (NewPathExternal);
381         return (AE_NOT_FOUND);
382     }
383
384     /*
385      * Check to make sure that the optimization finds the node we are
386      * looking for.  This is simply a sanity check on the new
387      * path that has been created.
388      */
389     Status = AcpiNsLookup (&ScopeInfo,  NewPath,
390                     ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
391                     ACPI_NS_DONT_OPEN_SCOPE, WalkState, &(Node));
392     if (ACPI_SUCCESS (Status))
393     {
394         /* Found the namepath, but make sure the node is correct */
395
396         if (Node == TargetNode)
397         {
398             /* The lookup matched the node, accept this optimization */
399
400             AslError (ASL_OPTIMIZATION, ASL_MSG_NAME_OPTIMIZATION,
401                 Op, NewPathExternal);
402             *ReturnNewPath = NewPath;
403         }
404         else
405         {
406             /* Node is not correct, do not use this optimization */
407
408             Status = AE_NOT_FOUND;
409             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** WRONG NODE"));
410             AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op,
411                 "Not using optimized name - found wrong node");
412         }
413     }
414     else
415     {
416         /* The lookup failed, we obviously cannot use this optimization */
417
418         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** NOT FOUND"));
419         AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op,
420             "Not using optimized name - did not find node");
421     }
422
423     ACPI_MEM_FREE (NewPathExternal);
424     return (Status);
425 }
426
427
428 /*******************************************************************************
429  *
430  * FUNCTION:    OptOptimizeNameDeclaration
431  *
432  * PARAMETERS:  Op                  - Current parser op
433  *              WalkState           - Current state
434  *              CurrentNode         - Where we are in the namespace
435  *              AmlNameString       - Unoptimized namepath
436  *              NewPath             - Where the optimized path is returned
437  *
438  * RETURN:      Status. AE_OK If path is optimized
439  *
440  * DESCRIPTION: Perform a simple optimization of removing an extraneous
441  *              backslash prefix if we are already at the root scope.
442  *
443  ******************************************************************************/
444
445 ACPI_STATUS
446 OptOptimizeNameDeclaration (
447     ACPI_PARSE_OBJECT       *Op,
448     ACPI_WALK_STATE         *WalkState,
449     ACPI_NAMESPACE_NODE     *CurrentNode,
450     ACPI_NAMESPACE_NODE     *TargetNode,
451     char                    *AmlNameString,
452     char                    **NewPath)
453 {
454     ACPI_STATUS             Status;
455     char                    *NewPathExternal;
456     ACPI_GENERIC_STATE      ScopeInfo;
457     ACPI_NAMESPACE_NODE     *Node;
458
459
460     ACPI_FUNCTION_TRACE ("OptOptimizeNameDeclaration");
461
462
463     if (((CurrentNode == AcpiGbl_RootNode) ||
464         (Op->Common.Parent->Asl.ParseOpcode == PARSEOP_DEFINITIONBLOCK)) &&
465             (AmlNameString[0] == '\\'))
466     {
467         /*
468          * The current scope is the root, and the namepath has a root prefix
469          * that is therefore extraneous.  Remove it.
470          */
471         *NewPath = &AmlNameString[1];
472
473         /* Debug output */
474
475         Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, *NewPath,
476                     NULL, &NewPathExternal);
477         if (ACPI_FAILURE (Status))
478         {
479             AslCoreSubsystemError (Op, Status, "Externalizing NamePath", ASL_NO_ABORT);
480             return (Status);
481         }
482
483         /*
484          * Check to make sure that the optimization finds the node we are
485          * looking for.  This is simply a sanity check on the new
486          * path that has been created.
487          */
488         ScopeInfo.Scope.Node = CurrentNode;
489         Status = AcpiNsLookup (&ScopeInfo, *NewPath,
490                         ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
491                         ACPI_NS_DONT_OPEN_SCOPE, WalkState, &(Node));
492         if (ACPI_SUCCESS (Status))
493         {
494             /* Found the namepath, but make sure the node is correct */
495
496             if (Node == TargetNode)
497             {
498                 /* The lookup matched the node, accept this optimization */
499
500                 AslError (ASL_OPTIMIZATION, ASL_MSG_NAME_OPTIMIZATION,
501                     Op, NewPathExternal);
502
503                 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
504                     "AT ROOT:   %-24s", NewPathExternal));
505             }
506             else
507             {
508                 /* Node is not correct, do not use this optimization */
509
510                 Status = AE_NOT_FOUND;
511                 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** WRONG NODE"));
512                 AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op,
513                     "Not using optimized name - found wrong node");
514             }
515         }
516         else
517         {
518             /* The lookup failed, we obviously cannot use this optimization */
519
520             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** NOT FOUND"));
521             AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op,
522                 "Not using optimized name - did not find node");
523         }
524
525         ACPI_MEM_FREE (NewPathExternal);
526         return (Status);
527     }
528
529     /* Could not optimize */
530
531     return (AE_NOT_FOUND);
532 }
533
534
535 /*******************************************************************************
536  *
537  * FUNCTION:    OptOptimizeNamePath
538  *
539  * PARAMETERS:  Op                  - Current parser op
540  *              Flags               - Opcode info flags
541  *              WalkState           - Current state
542  *              AmlNameString       - Unoptimized namepath
543  *              TargetNode          - Node to which AmlNameString refers
544  *
545  * RETURN:      None.  If path is optimized, the Op is updated with new path
546  *
547  * DESCRIPTION: Optimize a Named Declaration or Reference to the minimal length.
548  *              Must take into account both the current location in the
549  *              namespace and the actual reference path.
550  *
551  ******************************************************************************/
552
553 void
554 OptOptimizeNamePath (
555     ACPI_PARSE_OBJECT       *Op,
556     UINT32                  Flags,
557     ACPI_WALK_STATE         *WalkState,
558     char                    *AmlNameString,
559     ACPI_NAMESPACE_NODE     *TargetNode)
560 {
561     ACPI_STATUS             Status;
562     ACPI_BUFFER             TargetPath;
563     ACPI_BUFFER             CurrentPath;
564     ACPI_SIZE               AmlNameStringLength;
565     ACPI_NAMESPACE_NODE     *CurrentNode;
566     char                    *ExternalNameString;
567     char                    *NewPath = NULL;
568     ACPI_SIZE               HowMuchShorter;
569     ACPI_PARSE_OBJECT       *NextOp;
570
571
572     ACPI_FUNCTION_TRACE ("OptOptimizeNamePath");
573
574
575     /* This is an optional optimization */
576
577     if (!Gbl_ReferenceOptimizationFlag)
578     {
579         return_VOID;
580     }
581
582     /* Various required items */
583
584     if (!TargetNode || !WalkState || !Op->Common.Parent)
585     {
586         return_VOID;
587     }
588
589     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "%5d [%12.12s] [%12.12s] ",
590         Op->Asl.LogicalLineNumber,
591         AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode),
592         AcpiPsGetOpcodeName (Op->Common.AmlOpcode)));
593
594     if (!(Flags & (AML_NAMED | AML_CREATE)))
595     {
596         if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
597         {
598             /* We don't want to fuss with actual name declaration nodes here */
599
600             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
601                 "******* NAME DECLARATION\n"));
602             return_VOID;
603         }
604     }
605
606     /*
607      * The original path must be longer than one NameSeg (4 chars) for there
608      * to be any possibility that it can be optimized to a shorter string
609      */
610     AmlNameStringLength = ACPI_STRLEN (AmlNameString);
611     if (AmlNameStringLength <= ACPI_NAME_SIZE)
612     {
613         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
614             "NAMESEG %4.4s\n", AmlNameString));
615         return_VOID;
616     }
617
618     /*
619      * We need to obtain the node that represents the current scope -- where
620      * we are right now in the namespace.  We will compare this path
621      * against the Namepath, looking for commonality.
622      */
623     CurrentNode = AcpiGbl_RootNode;
624     if (WalkState->ScopeInfo)
625     {
626         CurrentNode = WalkState->ScopeInfo->Scope.Node;
627     }
628
629     if (Flags & (AML_NAMED | AML_CREATE))
630     {
631         /* This is the declaration of a new name */
632
633         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "NAME"));
634
635         /* The node of interest is the parent of this node (the containing scope) */
636
637         CurrentNode = Op->Asl.Parent->Asl.Node;
638         if (!CurrentNode)
639         {
640             CurrentNode = AcpiGbl_RootNode;
641         }
642     }
643     else
644     {
645         /* This is a reference to an existing named object */
646
647         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "REF "));
648     }
649
650     /*
651      * Obtain the full paths to the two nodes that we are interested in
652      * (Target and current namespace location) in external
653      * format -- something we can easily manipulate
654      */
655     TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
656     Status = AcpiNsHandleToPathname (TargetNode, &TargetPath);
657     if (ACPI_FAILURE (Status))
658     {
659         AslCoreSubsystemError (Op, Status, "Getting Target NamePath", ASL_NO_ABORT);
660         return_VOID;
661     }
662     TargetPath.Length--;    /* Subtract one for null terminator */
663
664     /* CurrentPath is the path to this scope (where we are in the namespace) */
665
666     CurrentPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
667     Status = AcpiNsHandleToPathname (CurrentNode, &CurrentPath);
668     if (ACPI_FAILURE (Status))
669     {
670         AslCoreSubsystemError (Op, Status, "Getting Current NamePath", ASL_NO_ABORT);
671         return_VOID;
672     }
673     CurrentPath.Length--;   /* Subtract one for null terminator */
674
675     /* Debug output only */
676
677     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, AmlNameString,
678                 NULL, &ExternalNameString);
679     if (ACPI_FAILURE (Status))
680     {
681         AslCoreSubsystemError (Op, Status, "Externalizing NamePath", ASL_NO_ABORT);
682         return_VOID;
683     }
684
685     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
686         "%37s (%2d) ==> %-32s(%2d) %-32s",
687         (char *) CurrentPath.Pointer, CurrentPath.Length,
688         (char *) TargetPath.Pointer, TargetPath.Length, ExternalNameString));
689
690     ACPI_MEM_FREE (ExternalNameString);
691
692     /*
693      * Attempt an optmization depending on the type of namepath
694      */
695     if (Flags & (AML_NAMED | AML_CREATE))
696     {
697         /*
698          * This is a named opcode and the namepath is a name declaration, not
699          * a reference.
700          */
701         Status = OptOptimizeNameDeclaration (Op, WalkState, CurrentNode,
702                     TargetNode, AmlNameString, &NewPath);
703         if (ACPI_FAILURE (Status))
704         {
705             /*
706              * 2) now attempt to
707              *    optimize the namestring with carats (up-arrow)
708              */
709             Status = OptBuildShortestPath (Op, WalkState, CurrentNode,
710                             TargetNode, &CurrentPath, &TargetPath,
711                             AmlNameStringLength, 1, &NewPath);
712         }
713     }
714     else
715     {
716         /*
717          * This is a reference to an existing named object
718          *
719          * 1) Check if search-to-root can be utilized using the last
720          *    NameSeg of the NamePath
721          */
722         Status = OptSearchToRoot (Op, WalkState, CurrentNode,
723                         TargetNode, &TargetPath, &NewPath);
724         if (ACPI_FAILURE (Status))
725         {
726             /*
727              * 2) Search-to-root could not be used, now attempt to
728              *    optimize the namestring with carats (up-arrow)
729              */
730             Status = OptBuildShortestPath (Op, WalkState, CurrentNode,
731                             TargetNode, &CurrentPath, &TargetPath,
732                             AmlNameStringLength, 0, &NewPath);
733         }
734     }
735
736     /*
737      * Success from above indicates that the NamePath was successfully
738      * optimized.  We need to update the parse op with the new name
739      */
740     if (ACPI_SUCCESS (Status))
741     {
742         HowMuchShorter = (AmlNameStringLength - ACPI_STRLEN (NewPath));
743         OptTotal += HowMuchShorter;
744
745         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " REDUCED %2d (%d)",
746             HowMuchShorter, OptTotal));
747
748         if (Flags & AML_NAMED)
749         {
750             if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
751             {
752                 /*
753                  * ALIAS is the only oddball opcode, the name declaration
754                  * (alias name) is the second operand
755                  */
756                 Op->Asl.Child->Asl.Next->Asl.Value.String = NewPath;
757                 Op->Asl.Child->Asl.Next->Asl.AmlLength = ACPI_STRLEN (NewPath);
758             }
759             else
760             {
761                 Op->Asl.Child->Asl.Value.String = NewPath;
762                 Op->Asl.Child->Asl.AmlLength = ACPI_STRLEN (NewPath);
763             }
764         }
765         else if (Flags & AML_CREATE)
766         {
767             /* Name must appear as the last parameter */
768
769             NextOp = Op->Asl.Child;
770             while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
771             {
772                 NextOp = NextOp->Asl.Next;
773             }
774             /* Update the parse node with the new NamePath */
775
776             NextOp->Asl.Value.String = NewPath;
777             NextOp->Asl.AmlLength = ACPI_STRLEN (NewPath);
778         }
779         else
780         {
781             /* Update the parse node with the new NamePath */
782
783             Op->Asl.Value.String = NewPath;
784             Op->Asl.AmlLength = ACPI_STRLEN (NewPath);
785         }
786     }
787     else
788     {
789         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ALREADY OPTIMAL"));
790     }
791
792     /* Cleanup path buffers */
793
794     ACPI_MEM_FREE (TargetPath.Pointer);
795     ACPI_MEM_FREE (CurrentPath.Pointer);
796
797     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "\n"));
798     return_VOID;
799 }
800