Beispiel #1
0
DivergenceAnalysis::block_set
	DivergenceAnalysis::_getDivergentBlocksInPostdominanceFrontier(
	const DataflowGraph::iterator &block) {
	
	const Analysis* dfgAnalysis = getAnalysis("DataflowGraphAnalysis");
	assert(dfgAnalysis != 0);

	const DataflowGraph &cdfg =
		static_cast<const DataflowGraph&>(*dfgAnalysis);
	DataflowGraph &dfg = const_cast<DataflowGraph&>(cdfg);
	
	PostdominatorTree* dtree = (PostdominatorTree*)
		(getAnalysis("PostDominatorTreeAnalysis"));
	
	auto postDominator = dfg.getCFGtoDFGMap()[
		dtree->getPostDominator(block->block())];

	block_set divergentBlocks;

	for (auto successor = block->successors().begin();
		successor != block->successors().end(); ++successor) {
		if (*successor == postDominator) continue;
		
		block_set allDivergentPaths;
		
		buildDivergentSubgraph(allDivergentPaths, *successor, postDominator);
		
		divergentBlocks.insert(allDivergentPaths.begin(),
			allDivergentPaths.end());
	}
	
	return divergentBlocks;
}
Beispiel #2
0
static bool buildDivergentSubgraph(
	DivergenceAnalysis::block_set& graph,
	const DataflowGraph::iterator &block,
	const DataflowGraph::iterator &postDominator) {

	bool hitPostDominator = false;

	// don't include blocks with barriers
	if(hasBarrier(block)) return false;
	
	// skip loops
	if(!graph.insert(block).second) return false;
	
	for (auto successor = block->successors().begin();
		successor != block->successors().end(); ++successor) {
		
		// stop at the post dominator
		if (*successor == postDominator)
		{
			hitPostDominator = true;

			continue;
		}
		
		hitPostDominator |= buildDivergentSubgraph(graph,
			*successor, postDominator);
	}
	
	return hitPostDominator;
}
Beispiel #3
0
bool DivergenceAnalysis::_hasTrivialPathToExit(
	const DataflowGraph::iterator &block) const {

	// We can ignore divergent threads that immediately exit
	unsigned int exitingPaths = 0;
	
	const Analysis* dfgAnalysis = getAnalysis("DataflowGraphAnalysis");
	assert(dfgAnalysis != 0);

	const DataflowGraph &dfg =
		static_cast<const DataflowGraph&>(*dfgAnalysis);

	auto exit = --dfg.end();

	for (auto successor = block->successors().begin();
		successor != block->successors().end(); ++successor) {
		auto path = *successor;
		
		while (true) {
			if (path == exit) {
				++exitingPaths;
				break;
			}
			if (path->successors().size() != 1) {
				break;
			}
			if (!path->instructions().empty()) {
				if (path->instructions().size() == 1) {
					const ir::PTXInstruction &ptxI =
						*(static_cast<ir::PTXInstruction *> (
						path->instructions().back().i));
				
					if (ptxI.isExit()) {
						++exitingPaths;
					}
				}
				break;
			}
			path = *path->successors().begin();
		}
	}

	if (block->successors().size() - exitingPaths < 2) {
		return true;
	}
	
	return false;
}
Beispiel #4
0
unsigned int DivergenceAnalysis::_numberOfDivergentPathsToPostDominator(
	const DataflowGraph::iterator &block) const {
	
	const Analysis* dfgAnalysis = getAnalysis("DataflowGraphAnalysis");
	assert(dfgAnalysis != 0);

	const DataflowGraph &cdfg =
		static_cast<const DataflowGraph&>(*dfgAnalysis);
	DataflowGraph &dfg = const_cast<DataflowGraph&>(cdfg);
	
	PostdominatorTree* dtree = (PostdominatorTree*)
		(getAnalysis("PostDominatorTreeAnalysis"));
	
	auto postDominator = dfg.getCFGtoDFGMap()[
		dtree->getPostDominator(block->block())];

	unsigned int divergentPaths = 0;

	for (auto successor = block->successors().begin();
		successor != block->successors().end(); ++successor) {
		if (*successor == postDominator) {
			++divergentPaths;
			continue;
		}
		
		block_set allDivergentPaths;
		
		if (doAnyDivergentPathsReachThePostDominator(allDivergentPaths,
			*successor, postDominator)) {
			++divergentPaths;
		}
	}
	
	report("  There are " << divergentPaths << " divergent paths from "
		<< block->label() << " to post-dominator " << postDominator->label());

	return divergentPaths;
}