1 /*
  2  * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_OPTO_PHASETYPE_HPP
 26 #define SHARE_OPTO_PHASETYPE_HPP
 27 
 28 #include "utilities/bitMap.inline.hpp"
 29 #include "utilities/stringUtils.hpp"
 30 
 31 #define COMPILER_PHASES(flags) \
 32   flags(BEFORE_STRINGOPTS,              "Before StringOpts") \
 33   flags(AFTER_STRINGOPTS,               "After StringOpts") \
 34   flags(BEFORE_REMOVEUSELESS,           "Before RemoveUseless") \
 35   flags(AFTER_PARSING,                  "After Parsing") \
 36   flags(BEFORE_ITER_GVN,                "Before Iter GVN") \
 37   flags(ITER_GVN1,                      "Iter GVN 1") \
 38   flags(AFTER_ITER_GVN_STEP,            "After Iter GVN Step") \
 39   flags(AFTER_ITER_GVN,                 "After Iter GVN") \
 40   flags(INCREMENTAL_INLINE_STEP,        "Incremental Inline Step") \
 41   flags(INCREMENTAL_INLINE_CLEANUP,     "Incremental Inline Cleanup") \
 42   flags(INCREMENTAL_INLINE,             "Incremental Inline") \
 43   flags(INCREMENTAL_BOXING_INLINE,      "Incremental Boxing Inline") \
 44   flags(EXPAND_VUNBOX,                  "Expand VectorUnbox") \
 45   flags(SCALARIZE_VBOX,                 "Scalarize VectorBox") \
 46   flags(INLINE_VECTOR_REBOX,            "Inline Vector Rebox Calls") \
 47   flags(EXPAND_VBOX,                    "Expand VectorBox") \
 48   flags(ELIMINATE_VBOX_ALLOC,           "Eliminate VectorBoxAllocate") \
 49   flags(ITER_GVN_BEFORE_EA,             "Iter GVN before EA") \
 50   flags(ITER_GVN_AFTER_VECTOR,          "Iter GVN after vector box elimination") \
 51   flags(BEFORE_BEAUTIFY_LOOPS,          "Before beautify loops") \
 52   flags(AFTER_BEAUTIFY_LOOPS,           "After beautify loops") \
 53   flags(BEFORE_LOOP_UNROLLING,          "Before Loop Unrolling") \
 54   flags(AFTER_LOOP_UNROLLING,           "After Loop Unrolling") \
 55   flags(BEFORE_SPLIT_IF,                "Before Split-If") \
 56   flags(AFTER_SPLIT_IF,                 "After Split-If") \
 57   flags(BEFORE_LOOP_PREDICATION_IC,     "Before Loop Predication IC") \
 58   flags(AFTER_LOOP_PREDICATION_IC,      "After Loop Predication IC") \
 59   flags(BEFORE_LOOP_PREDICATION_RC,     "Before Loop Predication RC") \
 60   flags(AFTER_LOOP_PREDICATION_RC,      "After Loop Predication RC") \
 61   flags(BEFORE_PARTIAL_PEELING,         "Before Partial Peeling") \
 62   flags(AFTER_PARTIAL_PEELING,          "After Partial Peeling") \
 63   flags(BEFORE_LOOP_PEELING,            "Before Loop Peeling") \
 64   flags(AFTER_LOOP_PEELING,             "After Loop Peeling") \
 65   flags(BEFORE_LOOP_UNSWITCHING,        "Before Loop Unswitching") \
 66   flags(AFTER_LOOP_UNSWITCHING,         "After Loop Unswitching") \
 67   flags(BEFORE_RANGE_CHECK_ELIMINATION, "Before Range Check Elimination") \
 68   flags(AFTER_RANGE_CHECK_ELIMINATION,  "After Range Check Elimination") \
 69   flags(BEFORE_PRE_MAIN_POST,           "Before Pre/Main/Post Loops") \
 70   flags(AFTER_PRE_MAIN_POST,            "After Pre/Main/Post Loops") \
 71   flags(AUTO_VECTORIZATION1_BEFORE_APPLY,       "AutoVectorization 1, Before Apply") \
 72   flags(AUTO_VECTORIZATION2_AFTER_REORDER,      "AutoVectorization 2, After Apply Memop Reordering") \
 73   flags(AUTO_VECTORIZATION3_AFTER_ADJUST_LIMIT, "AutoVectorization 3, After Adjusting Pre-Loop Limit") \
 74   flags(AUTO_VECTORIZATION4_AFTER_APPLY,        "AutoVectorization 4, After Apply") \
 75   flags(BEFORE_CLOOPS,                  "Before CountedLoop") \
 76   flags(AFTER_CLOOPS,                   "After CountedLoop") \
 77   flags(PHASEIDEAL_BEFORE_EA,           "PhaseIdealLoop before EA") \
 78   flags(AFTER_EA,                       "After Escape Analysis") \
 79   flags(ITER_GVN_AFTER_EA,              "Iter GVN after EA") \
 80   flags(ITER_GVN_AFTER_ELIMINATION,     "Iter GVN after eliminating allocations and locks") \
 81   flags(PHASEIDEALLOOP1,                "PhaseIdealLoop 1") \
 82   flags(PHASEIDEALLOOP2,                "PhaseIdealLoop 2") \
 83   flags(PHASEIDEALLOOP3,                "PhaseIdealLoop 3") \
 84   flags(BEFORE_CCP1,                    "Before PhaseCCP 1") \
 85   flags(CCP1,                           "PhaseCCP 1") \
 86   flags(ITER_GVN2,                      "Iter GVN 2") \
 87   flags(PHASEIDEALLOOP_ITERATIONS,      "PhaseIdealLoop iterations") \
 88   flags(BEFORE_MACRO_EXPANSION ,        "Before Macro Expansion") \
 89   flags(AFTER_MACRO_EXPANSION_STEP,     "After Macro Expansion Step") \
 90   flags(AFTER_MACRO_EXPANSION,          "After Macro Expansion") \
 91   flags(BARRIER_EXPANSION,              "Barrier expand") \
 92   flags(OPTIMIZE_FINISHED,              "Optimize finished") \
 93   flags(BEFORE_MATCHING,                "Before matching") \
 94   flags(MATCHING,                       "After matching") \
 95   flags(GLOBAL_CODE_MOTION,             "Global code motion") \
 96   flags(REGISTER_ALLOCATION,            "Register Allocation") \
 97   flags(BLOCK_ORDERING,                 "Block Ordering") \
 98   flags(PEEPHOLE,                       "Peephole") \
 99   flags(POSTALLOC_EXPAND,               "Post-Allocation Expand") \
100   flags(MACH_ANALYSIS,                  "After mach analysis") \
101   flags(FINAL_CODE,                     "Final Code") \
102   flags(END,                            "End") \
103   flags(FAILURE,                        "Failure") \
104   flags(ALL,                            "All") \
105   flags(DEBUG,                          "Debug")
106 
107 #define table_entry(name, description) PHASE_##name,
108 enum CompilerPhaseType {
109   COMPILER_PHASES(table_entry)
110   PHASE_NUM_TYPES,
111   PHASE_NONE
112 };
113 #undef table_entry
114 
115 static const char* phase_descriptions[] = {
116 #define array_of_labels(name, description) description,
117        COMPILER_PHASES(array_of_labels)
118 #undef array_of_labels
119 };
120 
121 static const char* phase_names[] = {
122 #define array_of_labels(name, description) #name,
123        COMPILER_PHASES(array_of_labels)
124 #undef array_of_labels
125 };
126 
127 class CompilerPhaseTypeHelper {
128   public:
129   static const char* to_name(CompilerPhaseType cpt) {
130     return phase_names[cpt];
131   }
132   static const char* to_description(CompilerPhaseType cpt) {
133     return phase_descriptions[cpt];
134   }
135 };
136 
137 static CompilerPhaseType find_phase(const char* str) {
138   for (int i = 0; i < PHASE_NUM_TYPES; i++) {
139     if (strcmp(phase_names[i], str) == 0) {
140       return (CompilerPhaseType)i;
141     }
142   }
143   return PHASE_NONE;
144 }
145 
146 class PhaseNameValidator {
147  private:
148   CHeapBitMap _phase_name_set;
149   bool _valid;
150   char* _bad;
151 
152  public:
153   PhaseNameValidator(ccstrlist option) :
154     _phase_name_set(PHASE_NUM_TYPES, mtCompiler),
155     _valid(true),
156     _bad(nullptr)
157   {
158     for (StringUtils::CommaSeparatedStringIterator iter(option); *iter != nullptr && _valid; ++iter) {
159 
160       CompilerPhaseType cpt = find_phase(*iter);
161       if (PHASE_NONE == cpt) {
162         const size_t len = MIN2<size_t>(strlen(*iter), 63) + 1;  // cap len to a value we know is enough for all phase descriptions
163         _bad = NEW_C_HEAP_ARRAY(char, len, mtCompiler);
164         // strncpy always writes len characters. If the source string is shorter, the function fills the remaining bytes with nulls.
165         strncpy(_bad, *iter, len);
166         _valid = false;
167       } else if (PHASE_ALL == cpt) {
168         _phase_name_set.set_range(0, PHASE_NUM_TYPES);
169       } else {
170         assert(cpt < PHASE_NUM_TYPES, "out of bounds");
171         _phase_name_set.set_bit(cpt);
172       }
173     }
174   }
175 
176   ~PhaseNameValidator() {
177     if (_bad != nullptr) {
178       FREE_C_HEAP_ARRAY(char, _bad);
179     }
180   }
181 
182   const BitMap& phase_name_set() const {
183     assert(is_valid(), "Use of invalid phase name set");
184     return _phase_name_set;
185   }
186 
187   bool is_valid() const {
188     return _valid;
189   }
190 
191   const char* what() const {
192     return _bad;
193   }
194 };
195 
196 #endif // SHARE_OPTO_PHASETYPE_HPP