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 software is provided 'as-is', without any express or implied
00006 // warranty. In no event will the authors be held liable for any damages
00007 // arising from the use of this software.
00008 // 
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it
00011 // freely, subject to the following restrictions:
00012 // 
00013 // 1. The origin of this software must not be misrepresented; you must
00014 // not claim that you wrote the original software. If you use this
00015 // software in a product, an acknowledgment in the product documentation
00016 // would be appreciated but is not required.
00017 // 
00018 // 2. Altered source versions must be plainly marked as such, and must
00019 // not be misrepresented as being the original software.
00020 // 
00021 // 3. This notice may not be removed or altered from any source
00022 // distribution.
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     // get eval op
00050     const ShEvalOpInfo* evalInfo = ShEval::instance()->getEvalOpInfo(stmt);  
00051 
00052     // handle sources
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     // handle dest
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); // since we might be adding temps
00098     ShDefaultTransformer<CastExtractorBase<CanCast> > ce;
00099     ce.transform(m_program);
00100     m_changed |= ce.changed();
00101   ShContext::current()->exit(); // since we might be adding temps
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     // for multiple arguments, upswizzle all arguments to  
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

Generated on Thu Apr 21 17:32:49 2005 for Sh by  doxygen 1.4.2