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