00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00020 #ifndef SH_TRANSFORMERIMPL_HPP
00021 #define SH_TRANSFORMERIMPL_HPP
00022
00023 #include <algorithm>
00024 #include <sstream>
00025 #include <map>
00026 #include <list>
00027 #include "ShContext.hpp"
00028 #include "ShDebug.hpp"
00029 #include "ShEval.hpp"
00030 #include "ShTypeInfo.hpp"
00031 #include "ShTransformer.hpp"
00032
00033 #define SH_DBG_TRANSFORMER
00034
00035 namespace SH {
00036 #if 0
00037 template<class CanCast>
00038 struct CastExtractorBase: public ShTransformerParent
00039 {
00040 bool handleStmt(ShBasicBlock::ShStmtList::iterator& I, ShCtrlGraphNodePtr node)
00041 {
00042 ShStatement &stmt = *I;
00043 if(stmt.dest.null()) return false;
00044
00045
00046 const ShEvalOpInfo* evalInfo = ShEval::instance()->getEvalOpInfo(stmt);
00047
00048
00049 for(int i = 0; i < opInfo[stmt.op].arity; ++i) {
00050 ShValueType from = stmt.src[i].valueType();
00051 ShValueType to = evalInfo->m_src[i];
00052 if(from == to) continue;
00053 if(!CanCast::checkSrc(stmt.op, from, to)) {
00054 #ifdef SH_DBG_TRANSFORMER
00055 SH_DEBUG_PRINT("Turning src[" << i << "] into ASN for cast "
00056 << shValueTypeName(from) << "->"
00057 << shValueTypeName(to) << " on stmt=" << stmt);
00058 #endif
00059 ShVariable temp(stmt.src[i].node()->clone(SH_TEMP, 0, to));
00060 node->block->m_statements.insert(I, ShStatement(temp, SH_OP_ASN, stmt.src[i]));
00061 stmt.src[i] = temp;
00062 m_changed = true;
00063 }
00064 }
00065
00066
00067 ShValueType from = stmt.dest.valueType();
00068 ShValueType to = evalInfo->m_dest;
00069 if(from != to && !CanCast::checkDest(stmt.op, from, to)) {
00070 #ifdef SH_DBG_TRANSFORMER
00071 SH_DEBUG_PRINT("Turning dest into ASN for cast "
00072 << shValueTypeName(from) << "->"
00073 << shValueTypeName(to) << " on stmt=" << stmt);
00074 #endif
00075 ShVariable temp(stmt.dest.node()->clone(SH_TEMP, 0, to));
00076 ShBasicBlock::ShStmtList::iterator J = I;
00077 ++J;
00078 node->block->m_statements.insert(J, ShStatement(stmt.dest, SH_OP_ASN, temp));
00079 stmt.dest = temp;
00080 m_changed = true;
00081 }
00082 return false;
00083 }
00084 };
00085
00086
00087 template<class CanCast>
00088 void ShTransformer::extractCasts()
00089 {
00090 #ifdef SH_DBG_TRANSFORMER
00091 m_program->dump("extcast_start");
00092 #endif
00093 ShContext::current()->enter(m_program);
00094 ShDefaultTransformer<CastExtractorBase<CanCast> > ce;
00095 ce.transform(m_program);
00096 m_changed |= ce.changed();
00097 ShContext::current()->exit();
00098 #ifdef SH_DBG_TRANSFORMER
00099 m_program->dump("extcast_done");
00100 #endif
00101 }
00102
00103 template<class DoVec>
00104 struct ScalarVectorizerBase: public ShTransformerParent
00105 {
00106 bool handleStmt(ShBasicBlock::ShStmtList::iterator& I, ShCtrlGraphNodePtr node) {
00107 ShStatement& stmt = *I;
00108
00109 if(!DoVec::check(stmt.op)) return false;
00110 if(opInfo[stmt.op].arity < 2) return false;
00111 if(opInfo[stmt.op].result_source == ShOperationInfo::EXTERNAL ||
00112 opInfo[stmt.op].result_source == ShOperationInfo::IGNORE) return false;
00113
00114
00115 int maxSize = 0;
00116 for(int i = 0; i < opInfo[stmt.op].arity; ++i){
00117 maxSize = std::max(maxSize, stmt.src[i].size());
00118 }
00119
00120 if(maxSize == 1) return false;
00121
00122 #ifdef SH_DBG_TRANSFORMER
00123 SH_DEBUG_PRINT("Vectorizing to size=" << maxSize << " on stmt=" << stmt);
00124 #endif
00125 for(int i = 0; i < opInfo[stmt.op].arity; ++i) {
00126 if(stmt.src[i].size() == 1) {
00127 stmt.src[i] = ShVariable(stmt.src[i].node(),
00128 ShSwizzle(stmt.src[i].swizzle(), maxSize), stmt.src[i].neg());
00129 }
00130 }
00131 return false;
00132 }
00133 };
00134
00135 template<class DoVec>
00136 void ShTransformer::vectorizeScalars()
00137 {
00138 #ifdef SH_DBG_TRANSFORMER
00139 m_program->dump("vectscal_start");
00140 #endif
00141 ShDefaultTransformer<ScalarVectorizerBase<DoVec> > sv;
00142 sv.transform(m_program);
00143 m_changed |= sv.changed();
00144 #ifdef SH_DBG_TRANSFORMER
00145 m_program->dump("vectscal_done");
00146 #endif
00147 }
00148 #endif
00149
00150 template<typename T>
00151 void ShDefaultTransformer<T>::operator()(ShCtrlGraphNodePtr node) {
00152 if (!node) return;
00153 ShBasicBlockPtr block = node->block;
00154 if (!block) return;
00155
00156 for (ShBasicBlock::ShStmtList::iterator I = block->begin(); I != block->end();) {
00157 if(!T::handleStmt(I, node)) ++I;
00158 }
00159 }
00160
00161 template<typename T>
00162 bool ShDefaultTransformer<T>::transform(ShProgramNodePtr p) {
00163 T::start(p);
00164
00165 T::handleVarList(p->inputs, SH_INPUT);
00166 T::handleVarList(p->outputs, SH_OUTPUT);
00167 T::handleVarList(p->temps, SH_TEMP);
00168 T::handleVarList(p->constants, SH_CONST);
00169 T::handleVarList(p->uniforms, SH_TEMP);
00170
00171 T::handleTexList(p->textures);
00172 T::handleChannelList(p->channels);
00173 T::handlePaletteList(p->palettes);
00174
00175 p->ctrlGraph->dfs(*this);
00176
00177 T::finish();
00178 return T::changed();
00179 }
00180
00181 }
00182
00183 #undef SH_DBG_TRANSFORMER
00184
00185 #endif