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