static bool canRemoveAliveOut(analysis::DataflowGraph& dfg, iterator block, const Register& aliveOut) { for(BlockPointerSet::iterator successor = block->targets().begin(); successor != block->targets().end(); ++successor) { for(RegisterSet::iterator aliveIn = (*successor)->aliveIn().begin(); aliveIn != (*successor)->aliveIn().end(); ++aliveIn) { // A target successor uses the value if(aliveIn->id == aliveOut.id) return false; } } if(block->fallthrough() != dfg.end()) { iterator successor = block->fallthrough(); for(RegisterSet::iterator aliveIn = successor->aliveIn().begin(); aliveIn != successor->aliveIn().end(); ++aliveIn) { // A fallthrough successor uses the value if(aliveIn->id == aliveOut.id) return false; } } // No successors use the value return true; }
bool TestDataflowGraph::_verifyIdentities( analysis::DataflowGraph& graph ) { analysis::DataflowGraph::Block::RegisterSet global; analysis::InstructionConverter converter; analysis::DataflowGraph::iterator block1 = graph.begin(); for( ; block1 != graph.end(); ++block1 ) { analysis::DataflowGraph::iterator block2 = graph.begin(); for( ; block2 != graph.end(); ++block2 ) { if (block1 != block2) { analysis::DataflowGraph::InstructionVector::const_iterator inst1 = block1->instructions().begin(); analysis::DataflowGraph::InstructionVector::const_iterator inst2 = block2->instructions().begin(); while((inst1 != block1->instructions().end()) && (inst2 != block2->instructions().end())) { ir::PTXInstruction* ptxInst1 = static_cast< ir::PTXInstruction* >(inst1->i); ir::PTXInstruction* ptxInst2 = static_cast< ir::PTXInstruction* >(inst2->i); std::cout << ptxInst1->toString() << ": " << hydrazine::toFormattedString( inst1->d.begin(), inst1->d.end(), Double() ) << " <- " << hydrazine::toFormattedString( inst1->s.begin(), inst1->s.end(), Double() ) << " | "; std::cout << ptxInst2->toString() << ": " << hydrazine::toFormattedString( inst2->d.begin(), inst2->d.end(), Double() ) << " <- " << hydrazine::toFormattedString( inst2->s.begin(), inst2->s.end(), Double() ) << std::endl; // try to match inst1 and inst2 analysis::DataflowGraph::Instruction matchedInst1; analysis::DataflowGraph::Instruction matchedInst2; bool matched = converter.normalize(matchedInst1, matchedInst2, *inst1, *inst2); if (matched) { ir::PTXInstruction* matchedPtx1 = static_cast< ir::PTXInstruction* >(matchedInst1.i); ir::PTXInstruction* matchedPtx2 = static_cast< ir::PTXInstruction* >(matchedInst2.i); std::cout << "matched:" << std::endl; std::cout << matchedPtx1->toString() << ": " << hydrazine::toFormattedString( matchedInst1.d.begin(), matchedInst1.d.end(), Double() ) << " <- " << hydrazine::toFormattedString( matchedInst1.s.begin(), matchedInst1.s.end(), Double() ) << " | "; std::cout << matchedPtx2->toString() << ": " << hydrazine::toFormattedString( matchedInst2.d.begin(), matchedInst2.d.end(), Double() ) << " <- " << hydrazine::toFormattedString( matchedInst2.s.begin(), matchedInst2.s.end(), Double() ) << std::endl; } std::cout << "-----------" << std::endl; ++inst1; ++inst2; } // while } // if } // for } // for return true; }
bool TestDataflowGraph::_verify( const analysis::DataflowGraph& graph ) { for( analysis::DataflowGraph::const_iterator block = graph.begin(); block != graph.end(); ++block ) { analysis::DataflowGraph::Block::RegisterSet defined; report( " Alive in registers:" ); for( analysis::DataflowGraph::Block::RegisterSet::const_iterator reg = block->aliveIn().begin(); reg != block->aliveIn().end(); ++reg ) { report( " " << reg->id ); defined.insert( *reg ); } if( !block->phis().empty() ) { status << " Block " << block->label() << " has " << block->phis().size() << " phi instructions." << std::endl; return false; } for( analysis::DataflowGraph::InstructionVector::const_iterator instruction = block->instructions().begin(); instruction != block->instructions().end(); ++instruction ) { report( " " << instruction->label << ": " << hydrazine::toFormattedString( instruction->d.begin(), instruction->d.end(), Double() ) << " <- " << hydrazine::toFormattedString( instruction->s.begin(), instruction->s.end(), Double() ) ); analysis::DataflowGraph::RegisterPointerVector::const_iterator reg = instruction->s.begin(); for( ; reg != instruction->s.end(); ++reg ) { if( !defined.count( *reg ) ) { status << " Register " << *reg->pointer << " in instruction " << instruction->label << " in block " << block->label() << " used uninitialized." << std::endl; return false; } } reg = instruction->d.begin(); for( ; reg != instruction->d.end(); ++reg ) { defined.insert( *reg ); } } for( analysis::DataflowGraph::Block::RegisterSet::const_iterator reg = block->aliveOut().begin(); reg != block->aliveOut().end(); ++reg ) { if( !defined.count( *reg ) ) { status << " Register " << reg->id << " out set of block " << block->label() << " used uninitialized." << std::endl; return false; } } } return true; }
bool TestDataflowGraph::_verifySsa( const analysis::DataflowGraph& graph ) { analysis::DataflowGraph::Block::RegisterSet global; for( analysis::DataflowGraph::const_iterator block = graph.begin(); block != graph.end(); ++block ) { analysis::DataflowGraph::Block::RegisterSet defined; report( block->label() ); report( " Alive in registers:" ); for( analysis::DataflowGraph::Block::RegisterSet::const_iterator reg = block->aliveIn().begin(); reg != block->aliveIn().end(); ++reg ) { report( " " << reg->id ); defined.insert( *reg ); } for( analysis::DataflowGraph::PhiInstructionVector::const_iterator phi = block->phis().begin(); phi != block->phis().end(); ++phi ) { report( " phi " << phi->d.id << " <- " << hydrazine::toFormattedString( phi->s.begin(), phi->s.end(), ToId() ) ); for( analysis::DataflowGraph::RegisterVector::const_iterator reg = phi->s.begin(); reg != phi->s.end(); ++reg ) { if( !defined.count( *reg ) ) { status << " Register " << reg->id << " in phi instruction " << std::distance( block->phis().begin(), phi ) << " in " << block->label() << " used uninitialized." << std::endl; return false; } } defined.insert( phi->d ); if( !global.insert( phi->d ).second ) { status << " In " << block->label() << ", instruction phi " << std::distance( block->phis().begin(), phi ) << ", reg " << phi->d.id << " already defined globally." << std::endl; return false; } } for( analysis::DataflowGraph::InstructionVector::const_iterator instruction = block->instructions().begin(); instruction != block->instructions().end(); ++instruction ) { report( " " << instruction->label << ": " << hydrazine::toFormattedString( instruction->d.begin(), instruction->d.end(), Double() ) << " <- " << hydrazine::toFormattedString( instruction->s.begin(), instruction->s.end(), Double() ) ); analysis::DataflowGraph::RegisterPointerVector::const_iterator reg = instruction->s.begin(); for( ; reg != instruction->s.end(); ++reg ) { if( !defined.count( *reg ) ) { status << " Register " << *reg->pointer << " in instruction " << instruction->label << " in " << block->label() << " used uninitialized." << std::endl; return false; } } for( reg = instruction->d.begin(); reg != instruction->d.end(); ++reg ) { defined.insert( *reg ); if( !global.insert( *reg ).second ) { status << " In " << block->label() << ", instruction " << instruction->label << ", reg " << *reg->pointer << " already defined globally." << std::endl; return false; } } } for( analysis::DataflowGraph::Block::RegisterSet::const_iterator reg = block->aliveOut().begin(); reg != block->aliveOut().end(); ++reg ) { if( !defined.count( *reg ) ) { status << " Register " << reg->id << " out set of block " << block->label() << " used uninitialized." << std::endl; return false; } } } return true; }