Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ShTransformerImpl.hpp

00001 // Sh: A GPU metaprogramming language.
00002 //
00003 // Copyright 2003-2005 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 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     // get eval op
00046     const ShEvalOpInfo* evalInfo = ShEval::instance()->getEvalOpInfo(stmt);  
00047 
00048     // handle sources
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     // handle dest
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); // since we might be adding temps
00094     ShDefaultTransformer<CastExtractorBase<CanCast> > ce;
00095     ce.transform(m_program);
00096     m_changed |= ce.changed();
00097   ShContext::current()->exit(); // since we might be adding temps
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     // for multiple arguments, upswizzle all arguments to  
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

Generated on Thu Jul 28 17:33:06 2005 for Sh by  doxygen 1.4.3-20050530