00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024 #ifndef SHOPTIMIZATIONS_HPP
00025 #define SHOPTIMIZATIONS_HPP
00026
00027 #include <iosfwd>
00028 #include <vector>
00029 #include <set>
00030 #include <map>
00031 #include "ShProgram.hpp"
00032 #include "ShInfo.hpp"
00033 #include "ShStatement.hpp"
00034
00035
00036
00037
00038
00039 namespace SH {
00040
00042 SH_DLLEXPORT
00043 void optimize(ShProgram& p, int level);
00044 SH_DLLEXPORT
00045 void optimize(const ShProgramNodePtr& p, int level);
00046
00049 SH_DLLEXPORT
00050 void optimize(ShProgram& p);
00051 SH_DLLEXPORT
00052 void optimize(const ShProgramNodePtr& p);
00053
00054
00055
00056
00057
00058
00059 SH_DLLEXPORT
00060 void add_value_tracking(ShProgram& prg);
00061
00063 SH_DLLEXPORT
00064 void insert_branch_instructions(ShProgram& prg);
00065
00067 SH_DLLEXPORT
00068 void remove_branch_instructions(ShProgram& prg);
00069
00071 SH_DLLEXPORT
00072 void straighten(ShProgram& p, bool& changed);
00073
00075 SH_DLLEXPORT
00076 void remove_dead_code(ShProgram& p, bool& changed);
00077
00079 SH_DLLEXPORT
00080 void propagate_constants(ShProgram& p);
00081
00082
00083 struct
00084 SH_DLLEXPORT
00085 ValueTracking : public ShInfo {
00086 ValueTracking(ShStatement* stmt);
00087
00088 ShInfo* clone() const;
00089
00090
00091 struct Def {
00092 enum Kind {
00093 INPUT,
00094 STMT
00095 };
00096
00097 Def(ShStatement* stmt, int index)
00098 : kind(STMT), node(0), stmt(stmt), index(index)
00099 {
00100 }
00101
00102 Def(ShVariableNodePtr node, int index)
00103 : kind(INPUT), node(node), stmt(0), index(index)
00104 {}
00105
00106 Kind kind;
00107 ShVariableNodePtr node;
00108 ShStatement* stmt;
00109 int index;
00110
00111 bool operator<(const Def& other) const
00112 {
00113 return kind < other.kind ||
00114 (kind == other.kind &&
00115 (node < other.node ||
00116 (node == other.node &&
00117 (stmt < other.stmt ||
00118 (stmt == other.stmt && index < other.index)))));
00119 }
00120
00121 int absIndex() const
00122 {
00123 if(kind == INPUT) return index;
00124 return stmt->dest.swizzle()[index];
00125 }
00126
00127 friend std::ostream& operator<<(std::ostream& out, const Def& def);
00128 };
00129
00130 struct Use {
00131 enum Kind {
00132 OUTPUT,
00133 STMT
00134 };
00135
00136 Use(ShStatement* stmt, int source, int index)
00137 : kind(STMT), node(0), stmt(stmt), source(source), index(index)
00138 {
00139 }
00140
00141 Use(ShVariableNodePtr node, int index)
00142 : kind(OUTPUT), node(node), stmt(0), source(0), index(index)
00143 {
00144 }
00145
00146 bool operator<(const Use& other) const
00147 {
00148 return kind < other.kind ||
00149 (kind == other.kind &&
00150 (node < other.node ||
00151 (node == other.node &&
00152 (stmt < other.stmt ||
00153 (stmt == other.stmt &&
00154 (source < other.source ||
00155 (source == other.source && index < other.index)))))));
00156 }
00157
00158 int absIndex() const
00159 {
00160 if(kind == OUTPUT) return index;
00161 return stmt->src[source].swizzle()[index];
00162 }
00163
00164 friend std::ostream& operator<<(std::ostream& out, const Use& use);
00165
00166 Kind kind;
00167 ShVariableNodePtr node;
00168 ShStatement* stmt;
00169 int source;
00170 int index;
00171 };
00172
00173
00174 typedef std::set<Use> DefUseChain;
00175 typedef std::vector<DefUseChain> TupleDefUseChain;
00176 TupleDefUseChain uses;
00177
00178 friend std::ostream& operator<<(std::ostream& out, const TupleDefUseChain& tdu);
00179
00180
00181
00182 typedef std::set<Def> UseDefChain;
00183 typedef std::vector<UseDefChain> TupleUseDefChain;
00184 typedef std::vector<TupleUseDefChain> TupleUseDefChainVec;
00185 TupleUseDefChainVec defs;
00186
00187 friend std::ostream& operator<<(std::ostream& out, const TupleUseDefChain& tud);
00188 };
00189
00190
00191 struct InputValueTracking: public ShInfo
00192 {
00193 ShInfo* clone() const;
00194
00195 friend std::ostream& operator<<(std::ostream& out, const InputValueTracking& ivt);
00196
00197 typedef std::map<ShVariableNodePtr, ValueTracking::TupleDefUseChain> InputTupleDefUseChain;
00198 InputTupleDefUseChain inputUses;
00199 };
00200
00201
00202 struct OutputValueTracking: public ShInfo
00203 {
00204 ShInfo* clone() const;
00205
00206 friend std::ostream& operator<<(std::ostream& out, const OutputValueTracking& ovt);
00207
00208 typedef std::map<ShVariableNodePtr, ValueTracking::TupleUseDefChain> OutputTupleUseDefChain;
00209 OutputTupleUseDefChain outputDefs;
00210 };
00211
00212 }
00213
00214 #endif