ShOptimizations.hpp

00001 // Sh: A GPU metaprogramming language.
00002 //
00003 // Copyright 2003-2006 Serious Hack Inc.
00004 // 
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
00018 // MA  02110-1301, USA
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 // Uncomment this to turn on optimizer debugging using dot.
00032 // Warning: This is very verbose!
00033 //#define SH_DEBUG_OPTIMIZER
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 // Internal stuff.
00051 
00052 // Add value tracking information to the given program's CFG
00053 // statements.
00054 // If it already exists, overwrite it.
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 /* per statement uddu chains */
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(const 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(const 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; // source variable
00166     int index; // tuple index (swizzled)
00167   };
00168 
00169   // For each tuple element, track all of the uses of our definition.
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   // For each tuple element in each of our sources, track all the
00177   // definition points.
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 /* du chains for all inputs in a program */
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 /* ud chains for all outputs in a program */
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

Generated on Thu Feb 16 14:51:36 2006 for Sh by  doxygen 1.4.6