blob: 73e49ec4f0d1af548e12e0ff1d7e30e535884f2d [file] [log] [blame]
James C Scott4f596682014-05-01 05:52:04 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_COMPILER_DEX_PASS_ME_H_
18#define ART_COMPILER_DEX_PASS_ME_H_
19
20#include <string>
Andreas Gampe0b9203e2015-01-22 20:39:27 -080021
22#include "base/logging.h"
James C Scott4f596682014-05-01 05:52:04 -070023#include "pass.h"
Andreas Gampe0b9203e2015-01-22 20:39:27 -080024#include "safe_map.h"
James C Scott4f596682014-05-01 05:52:04 -070025
26namespace art {
27
28// Forward declarations.
Ian Rogers6a3c1fc2014-10-31 00:33:20 -070029class BasicBlock;
James C Scott4f596682014-05-01 05:52:04 -070030struct CompilationUnit;
James C Scott4f596682014-05-01 05:52:04 -070031
32/**
33 * @brief OptimizationFlag is an enumeration to perform certain tasks for a given pass.
34 * @details Each enum should be a power of 2 to be correctly used.
35 */
36enum OptimizationFlag {
Ian Rogers6a3c1fc2014-10-31 00:33:20 -070037 kOptimizationBasicBlockChange = 1, /// @brief Has there been a change to a BasicBlock?
38 kOptimizationDefUsesChange = 2, /// @brief Has there been a change to a def-use?
39 kLoopStructureChange = 4, /// @brief Has there been a loop structural change?
James C Scott4f596682014-05-01 05:52:04 -070040};
Ian Rogers6a3c1fc2014-10-31 00:33:20 -070041std::ostream& operator<<(std::ostream& os, const OptimizationFlag& rhs);
James C Scott4f596682014-05-01 05:52:04 -070042
43// Data holder class.
44class PassMEDataHolder: public PassDataHolder {
45 public:
46 CompilationUnit* c_unit;
47 BasicBlock* bb;
Jean Christophe Beyler09321df2014-07-18 15:33:57 -070048 void* data; /**< @brief Any data the pass wants to use */
49 bool dirty; /**< @brief Has the pass rendered the CFG dirty, requiring post-opt? */
James C Scott4f596682014-05-01 05:52:04 -070050};
51
52enum DataFlowAnalysisMode {
Ian Rogers6a3c1fc2014-10-31 00:33:20 -070053 kAllNodes = 0, /// @brief All nodes.
54 kPreOrderDFSTraversal, /// @brief Depth-First-Search / Pre-Order.
55 kRepeatingPreOrderDFSTraversal, /// @brief Depth-First-Search / Repeating Pre-Order.
56 kReversePostOrderDFSTraversal, /// @brief Depth-First-Search / Reverse Post-Order.
57 kRepeatingPostOrderDFSTraversal, /// @brief Depth-First-Search / Repeating Post-Order.
58 kRepeatingReversePostOrderDFSTraversal, /// @brief Depth-First-Search / Repeating Reverse Post-Order.
59 kPostOrderDOMTraversal, /// @brief Dominator tree / Post-Order.
60 kTopologicalSortTraversal, /// @brief Topological Order traversal.
61 kLoopRepeatingTopologicalSortTraversal, /// @brief Loop-repeating Topological Order traversal.
62 kNoNodes, /// @brief Skip BasicBlock traversal.
James C Scott4f596682014-05-01 05:52:04 -070063};
Ian Rogers6a3c1fc2014-10-31 00:33:20 -070064std::ostream& operator<<(std::ostream& os, const DataFlowAnalysisMode& rhs);
James C Scott4f596682014-05-01 05:52:04 -070065
66/**
67 * @class Pass
68 * @brief Pass is the Pass structure for the optimizations.
69 * @details The following structure has the different optimization passes that we are going to do.
70 */
Ian Rogers6a3c1fc2014-10-31 00:33:20 -070071class PassME : public Pass {
James C Scott4f596682014-05-01 05:52:04 -070072 public:
73 explicit PassME(const char* name, DataFlowAnalysisMode type = kAllNodes,
74 unsigned int flags = 0u, const char* dump = "")
75 : Pass(name), traversal_type_(type), flags_(flags), dump_cfg_folder_(dump) {
76 }
77
78 PassME(const char* name, DataFlowAnalysisMode type, const char* dump)
79 : Pass(name), traversal_type_(type), flags_(0), dump_cfg_folder_(dump) {
80 }
81
82 PassME(const char* name, const char* dump)
83 : Pass(name), traversal_type_(kAllNodes), flags_(0), dump_cfg_folder_(dump) {
84 }
85
86 ~PassME() {
Razvan A Lupusorubd25d4b2014-07-02 18:16:51 -070087 default_options_.clear();
James C Scott4f596682014-05-01 05:52:04 -070088 }
89
90 virtual DataFlowAnalysisMode GetTraversal() const {
91 return traversal_type_;
92 }
93
Razvan A Lupusorubd25d4b2014-07-02 18:16:51 -070094 /**
95 * @return Returns whether the pass has any configurable options.
96 */
97 bool HasOptions() const {
98 return default_options_.size() != 0;
99 }
100
101 /**
102 * @brief Prints the pass options along with default settings if there are any.
103 * @details The printing is done using LOG(INFO).
104 */
105 void PrintPassDefaultOptions() const {
106 for (auto option_it = default_options_.begin(); option_it != default_options_.end(); option_it++) {
107 LOG(INFO) << "\t" << option_it->first << ":" << std::dec << option_it->second;
108 }
109 }
110
111 /**
112 * @brief Prints the pass options along with either default or overridden setting.
113 * @param overridden_options The overridden settings for this pass.
114 */
115 void PrintPassOptions(SafeMap<const std::string, int>& overridden_options) const {
116 // We walk through the default options only to get the pass names. We use GetPassOption to
117 // also consider the overridden ones.
118 for (auto option_it = default_options_.begin(); option_it != default_options_.end(); option_it++) {
119 LOG(INFO) << "\t" << option_it->first << ":" << std::dec << GetPassOption(option_it->first, overridden_options);
120 }
121 }
122
James C Scott4f596682014-05-01 05:52:04 -0700123 const char* GetDumpCFGFolder() const {
124 return dump_cfg_folder_;
125 }
126
127 bool GetFlag(OptimizationFlag flag) const {
128 return (flags_ & flag);
129 }
130
131 protected:
Razvan A Lupusorubd25d4b2014-07-02 18:16:51 -0700132 int GetPassOption(const char* option_name, const SafeMap<const std::string, int>& overridden_options) const {
133 // First check if there are any overridden settings.
134 auto overridden_it = overridden_options.find(std::string(option_name));
135 if (overridden_it != overridden_options.end()) {
136 return overridden_it->second;
137 }
138
139 // Next check the default options.
140 auto default_it = default_options_.find(option_name);
141
142 if (default_it == default_options_.end()) {
143 // An invalid option is being requested.
144 DCHECK(false);
145 return 0;
146 }
147
148 return default_it->second;
149 }
150
James C Scott4f596682014-05-01 05:52:04 -0700151 /** @brief Type of traversal: determines the order to execute the pass on the BasicBlocks. */
152 const DataFlowAnalysisMode traversal_type_;
153
Jean Christophe Beyler2469e602014-05-06 20:36:55 -0700154 /** @brief Flags for additional directives: used to determine if a particular post-optimization pass is necessary. */
James C Scott4f596682014-05-01 05:52:04 -0700155 const unsigned int flags_;
156
157 /** @brief CFG Dump Folder: what sub-folder to use for dumping the CFGs post pass. */
158 const char* const dump_cfg_folder_;
Razvan A Lupusorubd25d4b2014-07-02 18:16:51 -0700159
160 /**
161 * @brief Contains a map of options with the default settings.
162 * @details The constructor of the specific pass instance should fill this
163 * with default options.
164 * */
165 SafeMap<const char*, int> default_options_;
James C Scott4f596682014-05-01 05:52:04 -0700166};
167} // namespace art
168#endif // ART_COMPILER_DEX_PASS_ME_H_