bool run()
    {
        ASSERT(m_graph.m_form != SSA);
        
        BlockSet blocksThatNeedInvalidationPoints;
        
        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
            BasicBlock* block = m_graph.block(blockIndex);
            if (!block)
                continue;
            
            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex)
                handle(nodeIndex, block->at(nodeIndex));
            
            // Note: this assumes that control flow occurs at bytecode instruction boundaries.
            if (m_originThatHadFire.isSet()) {
                for (unsigned i = block->numSuccessors(); i--;)
                    blocksThatNeedInvalidationPoints.add(block->successor(i));
            }
            
            m_insertionSet.execute(block);
        }
        
        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
            BasicBlock* block = m_graph.block(blockIndex);

            if (!blocksThatNeedInvalidationPoints.contains(block))
                continue;
            
            insertInvalidationCheck(0, block->at(0));
            m_insertionSet.execute(block);
        }
        
        return true;
    }
示例#2
0
void ReplayAudioIngest::emit_frame(channel_entry &ch) {
    BlockSet bset;
    size_t i;
    if (ch.fifo->fill_samples( ) < fft_size) {
        throw std::runtime_error("cannot emit frame, not enough samples");
    }

    /* take FFT of ch.fifo->data( ) into ch.current_frame */
    fft->compute(ch.current_frame, ch.fifo->data( ));

    /* subtract phase of last_frame from phase of current_frame to get output_frame */
    for (i = 0; i < fft_size; i++) {
        output_frame[i] = std::polar(
            std::abs(ch.current_frame[i]),
            std::arg(ch.current_frame[i]) - std::arg(ch.last_frame[i])
        );
    }

    /* 
     * swap last_frame and current_frame pointers 
     * (this makes current_frame the next last_frame)
     */
    std::swap(ch.last_frame, ch.current_frame);

    /* write output_frame to buffer */
    bset.add_block(REPLAY_PVOC_BLOCK, output_frame, fft_size);
    bset.add_block("Debug001", ch.fifo->data( ), fft_size);
    ch.buffer->write_blockset(bset);
    ch.fifo->pop_samples(fft_hop);
}
示例#3
0
timecode_t ReplayBuffer::write_frame(const ReplayFrameData &data) {
    BlockSet blkset;

    if (data.video_size == 0) {
        throw std::runtime_error("Tried to write empty frame");
    }

    if (data.video_size > 0) {
        blkset.add_block(
            REPLAY_VIDEO_BLOCK,
            data.video_data,
            data.video_size
        );
    }
    if (data.thumbnail_size > 0) {
        blkset.add_block(
            REPLAY_THUMBNAIL_BLOCK,
            data.thumbnail_data,
            data.thumbnail_size
        );
    }
    if (data.audio != NULL) {
        blkset.add_object(REPLAY_AUDIO_BLOCK, *(data.audio));
    }

    return write_blockset(blkset);
}
static BlockSet getBlocksWithCallsToFuctionsThatObserveSideEffects(
	ir::IRKernel& k)
{
	BlockSet blocks;

	report(" Getting functions that can observe side-effects");
	
	for(auto block = k.cfg()->begin(); block != k.cfg()->end(); ++block)
	{
		for(auto instruction : block->instructions)
		{
			auto ptxInstruction = static_cast<ir::PTXInstruction*>(instruction);
		
			// TODO: Check that the target can observe side effects
			if(ptxInstruction->isCall())
			{
				report("  " << ptxInstruction->toString());

				blocks.insert(block);
				break;
			}
		}
	}
	
	return blocks;
}
static BlockSet getBlocksWithBranchesThatDependOn(
	const BlockSet& blocksWithBackwardsBranches,
	const InstructionSet& instructionsThatCanObserveSideEffects,
	DependenceAnalysis* dependenceAnalysis,
	ControlDependenceAnalysis* controlDependenceAnalysis)
{
	BlockSet blocksWithDependentBranches;
	
	report(" Getting blocks with branches that can observe side-effects");
	
	for(auto blockWithBranch : blocksWithBackwardsBranches)
	{
		auto branch = getBranch(blockWithBranch);
		
		if(branch == nullptr) continue;
	
		auto controlDependentInstructions = getControlDependentInstructions(
			branch, instructionsThatCanObserveSideEffects,
			controlDependenceAnalysis);
	
		for(auto instruction : controlDependentInstructions)
		{
			if(dependenceAnalysis->dependsOn(instruction, branch))
			{
				report("  " << blockWithBranch->label());
				
				blocksWithDependentBranches.insert(blockWithBranch);
				break;
			}
		}
	}
	
	return blocksWithDependentBranches;
}
示例#6
0
Layer Layer::getSubgraphConnectedToTheseOutputs(
	const NeuronSet& outputs) const
{
	typedef std::set<size_t> BlockSet;
	
	BlockSet blocks;

	// TODO: eliminate the reundant inserts
	for(auto& output : outputs)
	{
		size_t block = (output / getOutputBlockingFactor()) % this->blocks();

		blocks.insert(block);
	}
	
	Layer layer(blocks.size(), getInputBlockingFactor(),
		getOutputBlockingFactor(), blockStep());
	
	for(auto& block : blocks)
	{
		size_t blockIndex = block - *blocks.begin();
		
		layer[blockIndex] = (*this)[block];
		layer.at_bias(blockIndex) = at_bias(block);
	}
	
	return layer;
}
Udm::Object MatLabUdmChart::distinguish( Udm::Object udmParent ) {

	SLSF::State state;

	static boost::regex stateflowRegex( "stateflow", boost::regex_constants::perl | boost::regex_constants::icase );
	boost::match_results<std::string::const_iterator> results;

	SLSF::Subsystem subsystemParent = SLSF::Subsystem::Cast( udmParent );

	BlockSet blockSet = subsystemParent.Block_kind_children();

	Udm::Object chartParent = udmParent;
	for( BlockSet::iterator blsItr = blockSet.begin() ; blsItr != blockSet.end() ; ++blsItr ) {
		Block block = *blsItr;
		std::string tag( block.Tag() );
		if (  regex_search( tag, results, stateflowRegex )  ) {
			chartParent = block;
			break;
		}
	}

#if PARADIGM == CyberComposition_PARADIGM
	state = SLSF::State::Create( chartParent );
#else
	state = SLSF::State::Create( UdmEngine::get_singleton().getTopLevelState() );
	SLSF::ConnectorRef connectorRef = SLSF::ConnectorRef::Create( chartParent );
	connectorRef.ref() = state;
#endif

	return state;
}
示例#8
0
BlockSet Drainer::GetBestBlocks() const
{
    BlockSet set;
    set.reserve(m_RootMacro->m_BestBlocks.size());
    for (auto blk : m_RootMacro->m_BestBlocks)
        set.push_back(m_Blocks[blk]);
    return set;
}
示例#9
0
ControlFlowGraph::BlockPointerVector
	ControlFlowGraph::reverse_topological_sequence() {
	typedef std::set<iterator, BlockSetCompare> BlockSet;
	typedef std::queue<iterator> Queue;
	
	report("Creating reverse topological order traversal");
	BlockSet visited;
	BlockPointerVector sequence;
	Queue queue;
	
	queue.push(get_exit_block());

	while (sequence.size() != size()) {
		if(queue.empty()) {
			for (pointer_iterator block = sequence.begin();
				block != sequence.end(); ++block) {
				for (pointer_iterator pred = (*block)->predecessors.begin();
					pred != (*block)->predecessors.end(); ++pred) {
					
					if (visited.count(*pred) == 0) {
						queue.push(*pred);
						break;
					}		
				}
				if(!queue.empty()) {
					break;
				}
			}
			
			if(queue.empty()) break; // The remaining blocks are unreachable
		}
		
		iterator current = queue.front();
		queue.pop();
		if(!visited.insert(current).second) continue;
		sequence.push_back(current);
		report(" Adding block " << current->label());

		for (pointer_iterator block = current->predecessors.begin();
			block != current->predecessors.end(); ++block) {
			bool noDependencies = true;
		
			for (pointer_iterator successor = (*block)->successors.begin(); 
				successor != (*block)->successors.end(); ++successor) {
				if (visited.count(*successor) == 0) {
					noDependencies = false;
					break;
				}
			}
			
			if(noDependencies) {
				queue.push(*block);
			}
		}
	}

	return sequence;
}
示例#10
0
void TotalGenerator::Fill(BlockSet &data)
{
    std::vector<int_fast8_t> set(data.FullSize(), false);
    for (auto i = 0; i < m_Total; i++)
        set[i] = true;

    std::shuffle(set.begin(), set.end(), m_Random);

    for (auto i = 0; i < data.FullSize(); i++)
        if (set[i])
            data += i;
}
示例#11
0
 void FindLive(Block *Root) {
   BlockList ToInvestigate;
   ToInvestigate.push_back(Root);
   while (ToInvestigate.size() > 0) {
     Block *Curr = ToInvestigate.front();
     ToInvestigate.pop_front();
     if (Live.find(Curr) != Live.end()) continue;
     Live.insert(Curr);
     for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) {
       ToInvestigate.push_back(iter->first);
     }
   }
 }
void TextAutosizer::FingerprintMapper::assertMapsAreConsistent()
{
    // For each fingerprint -> block mapping in m_blocksForFingerprint we should have an associated
    // map from block -> fingerprint in m_fingerprints.
    ReverseFingerprintMap::iterator end = m_blocksForFingerprint.end();
    for (ReverseFingerprintMap::iterator fingerprintIt = m_blocksForFingerprint.begin(); fingerprintIt != end; ++fingerprintIt) {
        Fingerprint fingerprint = fingerprintIt->key;
        BlockSet* blocks = fingerprintIt->value.get();
        for (BlockSet::iterator blockIt = blocks->begin(); blockIt != blocks->end(); ++blockIt) {
            const LayoutBlock* block = (*blockIt);
            ASSERT(m_fingerprints.get(block) == fingerprint);
        }
    }
}
示例#13
0
/**
 * Generate side walks
 */
void VBOPmBlocks::generateSideWalk(VBORenderManager* renderManager, BlockSet& blocks) {
	for (int i = 0; i < blocks.size(); ++i) {
		if (!blocks[i].valid) continue;

		BBox3D bbox;
		blocks[i].sidewalkContour.getBBox3D(bbox.minPt, bbox.maxPt);

		// If the block is too narrow, make it invalid.
		if (blocks[i].sidewalkContour.isTooNarrow(8.0f, 18.0f) || blocks[i].sidewalkContour.isTooNarrow(1.0f, 3.0f)) {
			blocks[i].valid = false;
			continue;
		}

		// If the block is close or under waterlevel, or on a steep terain, make it invalid.
		float min_z = std::numeric_limits<float>::max();
		float max_z = 0.0f;
		for (int pi = 0; pi < blocks[i].sidewalkContour.contour.size(); ++pi) {
			int next_pi = (pi + 1) % blocks[i].sidewalkContour.contour.size();
			for (int k = 0; k <= 20; ++k) {
				QVector3D pt = blocks[i].sidewalkContour.contour[pi] * (float)(20 - k) * 0.05 + blocks[i].sidewalkContour.contour[next_pi] * (float)k * 0.05;
				float z = renderManager->getTerrainHeight(pt.x(), pt.y());
				min_z = std::min(min_z, z);
				max_z = std::max(max_z, z);
			}
			//float z = renderManager->getTerrainHeight(blocks[i].sidewalkContour.contour[pi].x(), blocks[i].sidewalkContour.contour[pi].y());
			//min_z = std::min(min_z, z);
			//max_z = std::max(max_z, z);
		}
		if (min_z < 40.0f) {
			blocks[i].valid = false;
			continue;
		} else if (max_z - min_z > 20.0f) {
			blocks[i].isPark = true;
			continue;
		}
	}

	// Compute the block contour (the outer part becomes sidewalks)
	for (int i = 0; i < blocks.size(); ++i) {
		if (!blocks[i].valid) continue;
		//if (blocks[i].isPark) continue;

		Loop3D blockContourInset;
		float sidewalk_width = G::getFloat("sidewalk_width");
		blocks[i].sidewalkContour.computeInset(sidewalk_width, blockContourInset, false);
		blocks[i].blockContour.contour = blockContourInset;
		//blocks[i].blockContour.getBBox3D(blocks[i].bbox.minPt, blocks[i].bbox.maxPt);
	}
}
示例#14
0
SILValue
StackAllocationPromoter::getLiveOutValue(BlockSet &PhiBlocks,
                                         SILBasicBlock *StartBB) {
  DEBUG(llvm::dbgs() << "*** Searching for a value definition.\n");
  // Walk the Dom tree in search of a defining value:
  for (DomTreeNode *Node = DT->getNode(StartBB); Node; Node = Node->getIDom()) {
    SILBasicBlock *BB = Node->getBlock();

    // If there is a store (that must come after the phi), use its value.
    BlockToInstMap::iterator it = LastStoreInBlock.find(BB);
    if (it != LastStoreInBlock.end())
      if (auto *St = dyn_cast_or_null<StoreInst>(it->second)) {
        DEBUG(llvm::dbgs() << "*** Found Store def " << *St->getSrc());
        return St->getSrc();
      }

    // If there is a Phi definition in this block:
    if (PhiBlocks.count(BB)) {
      // Return the dummy instruction that represents the new value that we will
      // add to the basic block.
      SILValue Phi = BB->getArgument(BB->getNumArguments() - 1);
      DEBUG(llvm::dbgs() << "*** Found a dummy Phi def " << *Phi);
      return Phi;
    }

    // Move to the next dominating block.
    DEBUG(llvm::dbgs() << "*** Walking up the iDOM.\n");
  }
  DEBUG(llvm::dbgs() << "*** Could not find a Def. Using Undef.\n");
  return SILUndef::get(ASI->getElementType(), ASI->getModule());
}
static bool allPreviousDefinitionsDominateMove(instruction_iterator move,
	block_iterator block, BlockSet& visited)
{
	if(!visited.insert(block->id()).second) return true;
	
	assert(move->d.size() == 1);

	auto destination = *move->d.front().pointer;
	
	// If the value is defined by a phi with multiple sources, then the
	//  previous definition does not dominate the move
	for(auto phi = block->phis().begin(); phi != block->phis().end(); ++phi)
	{
		if(phi->d == destination)
		{
			return false;
		}
	}
	
	// Check all predecessors with the value live out
	for(auto predecessor = block->predecessors().begin();
		predecessor != block->predecessors().end(); ++predecessor)
	{
		if((*predecessor)->aliveOut().count(destination) == 0) continue;
		
		if(!allPreviousDefinitionsDominateMove(move, *predecessor, visited))
		{
			return false;
		}
	}
	
	return true;
}
static void chaseDownPredecessors(iterator node, Register value,
	DataflowGraph* dfg,
	dataflow_iterator block, NodeList& nodes,
	InstructionToNodeMap& instructionToNodes, BlockSet& visited)
{
	if(!visited.insert(block).second) return;
	
	assert(block->aliveIn().count(value) != 0);

	for(auto predecessor : block->predecessors())
	{
		if(predecessor->aliveOut().count(value) == 0) continue;
		
		bool foundAnyDefinitions = false;
		
		// check the body for a definition
		for(auto instruction = predecessor->instructions().rbegin();
			instruction != predecessor->instructions().rend(); ++instruction)
		{
			for(auto destination : instruction->d)
			{
				if(*destination.pointer == value)
				{
					auto producer = nodes.end();
					
					auto ptx = static_cast<PTXInstruction*>(instruction->i);
					
					auto existingNode = instructionToNodes.find(ptx);
		
					if(existingNode == instructionToNodes.end())
					{
						producer = nodes.insert(nodes.end(), Node(ptx));
						
						instructionToNodes.insert(
							std::make_pair(ptx, producer));
					}
					else
					{
						producer = existingNode->second;
					}
					
					report(" " << producer->instruction->toString() << " -> "
						<< node->instruction->toString());
					
					node->predecessors.push_back(producer);
					producer->successors.push_back(node);
					
					foundAnyDefinitions = true;
					break;
				}
			}
		}
		
		if(foundAnyDefinitions) continue;
		
		// if no definitions were found, recurse through predecessors
		chaseDownPredecessors(node, value, dfg, predecessor, nodes,
			instructionToNodes, visited);
	}
}
示例#17
0
 // Create a list of entries from a block. If LimitTo is provided, only results in that set
 // will appear
 void GetBlocksOut(Block *Source, BlockSet& Entries, BlockSet *LimitTo=NULL) {
   for (BlockBranchMap::iterator iter = Source->BranchesOut.begin(); iter != Source->BranchesOut.end(); iter++) {
     if (!LimitTo || LimitTo->find(iter->first) != LimitTo->end()) {
       Entries.insert(iter->first);
     }
   }
 }
    bool isValidFlushLocation(BasicBlock* startingBlock, unsigned index, VirtualRegister operand)
    {
        // This code is not meant to be fast. We just use it for assertions. If we got liveness wrong,
        // this function would return false for a Flush that we insert.
        Vector<BasicBlock*, 4> worklist;
        BlockSet seen;

        auto addPredecessors = [&] (BasicBlock* block) {
            for (BasicBlock* predecessor : block->predecessors) {
                bool isNewEntry = seen.add(predecessor);
                if (isNewEntry)
                    worklist.append(predecessor);
            }
        };

        auto flushIsDefinitelyInvalid = [&] (BasicBlock* block, unsigned index) {
            bool allGood = false;
            for (unsigned i = index; i--; ) {
                if (block->at(i)->accessesStack(m_graph) && block->at(i)->local() == operand) {
                    allGood = true;
                    break;
                }
            }

            if (allGood)
                return false;

            if (block->predecessors.isEmpty()) {
                // This is a root block. We proved we reached here, therefore we can't Flush, as
                // it'll make this local live at the start of a root block, which is invalid IR.
                return true;
            }

            addPredecessors(block);
            return false;
        };

        if (flushIsDefinitelyInvalid(startingBlock, index))
            return false;

        while (!worklist.isEmpty()) {
            BasicBlock* block = worklist.takeLast();
            if (flushIsDefinitelyInvalid(block, block->size()))
                return false;
        }
        return true;
    }
示例#19
0
 Shape *MakeMultiple(BlockSet &Blocks, BlockSet& Entries, BlockBlockSetMap& IndependentGroups, Shape *Prev, BlockSet &NextEntries) {
   PrintDebug("creating multiple block with %d inner groups\n", IndependentGroups.size());
   bool Fused = !!(Shape::IsSimple(Prev));
   MultipleShape *Multiple = new MultipleShape();
   Notice(Multiple);
   BlockSet CurrEntries;
   for (BlockBlockSetMap::iterator iter = IndependentGroups.begin(); iter != IndependentGroups.end(); iter++) {
     Block *CurrEntry = iter->first;
     BlockSet &CurrBlocks = iter->second;
     PrintDebug("  multiple group with entry %d:\n", CurrEntry->Id);
     DebugDump(CurrBlocks, "    ");
     // Create inner block
     CurrEntries.clear();
     CurrEntries.insert(CurrEntry);
     for (BlockSet::iterator iter = CurrBlocks.begin(); iter != CurrBlocks.end(); iter++) {
       Block *CurrInner = *iter;
       // Remove the block from the remaining blocks
       Blocks.erase(CurrInner);
       // Find new next entries and fix branches to them
       for (BlockBranchMap::iterator iter = CurrInner->BranchesOut.begin(); iter != CurrInner->BranchesOut.end();) {
         Block *CurrTarget = iter->first;
         BlockBranchMap::iterator Next = iter;
         Next++;
         if (!contains(CurrBlocks, CurrTarget)) {
           NextEntries.insert(CurrTarget);
           Solipsize(CurrTarget, Branch::Break, Multiple, CurrBlocks); 
         }
         iter = Next; // increment carefully because Solipsize can remove us
       }
     }
     Multiple->InnerMap[CurrEntry] = Process(CurrBlocks, CurrEntries, NULL);
     // If we are not fused, then our entries will actually be checked
     if (!Fused) {
       CurrEntry->IsCheckedMultipleEntry = true;
     }
   }
   DebugDump(Blocks, "  remaining blocks after multiple:");
   // Add entries not handled as next entries, they are deferred
   for (BlockSet::iterator iter = Entries.begin(); iter != Entries.end(); iter++) {
     Block *Entry = *iter;
     if (!contains(IndependentGroups, Entry)) {
       NextEntries.insert(Entry);
     }
   }
   return Multiple;
 }
示例#20
0
 Shape *MakeSimple(BlockSet &Blocks, Block *Inner, BlockSet &NextEntries) {
   PrintDebug("creating simple block with block #%d\n", Inner->Id);
   SimpleShape *Simple = new SimpleShape;
   Notice(Simple);
   Simple->Inner = Inner;
   Inner->Parent = Simple;
   if (Blocks.size() > 1) {
     Blocks.erase(Inner);
     GetBlocksOut(Inner, NextEntries, &Blocks);
     BlockSet JustInner;
     JustInner.insert(Inner);
     for (BlockSet::iterator iter = NextEntries.begin(); iter != NextEntries.end(); iter++) {
       Solipsize(*iter, Branch::Direct, Simple, JustInner);
     }
   }
   return Simple;
 }
示例#21
0
ControlFlowGraph::BlockPointerVector ControlFlowGraph::pre_order_sequence() {
	typedef std::unordered_set<iterator> BlockSet;
	typedef std::stack<iterator> Stack;
	
	BlockSet visited;
	BlockPointerVector sequence;
	Stack stack;
	
	if (!empty()) {
		stack.push(get_entry_block());
		visited.insert(get_entry_block());
	}
	
	while (!stack.empty()) {
		iterator current = stack.top();
		stack.pop();
		
		sequence.push_back(current);
		
		// favor the fallthrough
		iterator fallthrough = end();
		
		if (current->has_fallthrough_edge()) {
			edge_iterator fallthroughEdge 	
				= sequence.back()->get_fallthrough_edge();
			
			if (visited.insert(fallthroughEdge->tail).second) {
				fallthrough = fallthroughEdge->tail;
			}
		}
		
		for (pointer_iterator block = current->successors.begin(); 
			block != current->successors.end(); ++block) {
			if (visited.insert(*block).second) {
				stack.push(*block);
			}
		}
		
		if (fallthrough != end()) {
			stack.push(fallthrough);
		}
	}
	
	return sequence;
}
TextAutosizer::Supercluster* TextAutosizer::getSupercluster(const LayoutBlock* block)
{
    Fingerprint fingerprint = m_fingerprintMapper.get(block);
    if (!fingerprint)
        return nullptr;

    BlockSet* roots = m_fingerprintMapper.getTentativeClusterRoots(fingerprint);
    if (!roots || roots->size() < 2 || !roots->contains(block))
        return nullptr;

    SuperclusterMap::AddResult addResult = m_superclusters.add(fingerprint, PassOwnPtr<Supercluster>());
    if (!addResult.isNewEntry)
        return addResult.storedValue->value.get();

    Supercluster* supercluster = new Supercluster(roots);
    addResult.storedValue->value = adoptPtr(supercluster);
    return supercluster;
}
示例#23
0
void StackAllocationPromoter::pruneAllocStackUsage() {
  DEBUG(llvm::dbgs() << "*** Pruning : " << *ASI);
  BlockSet Blocks;

  // Insert all of the blocks that ASI is live in.
  for (auto UI = ASI->use_begin(), E = ASI->use_end(); UI != E; ++UI)
    Blocks.insert(UI->getUser()->getParent());

  // Clear AllocStack state.
  LastStoreInBlock.clear();

  for (auto Block : Blocks) {
    StoreInst *SI = promoteAllocationInBlock(Block);
    LastStoreInBlock[Block] = SI;
  }

  DEBUG(llvm::dbgs() << "*** Finished pruning : " << *ASI);
}
示例#24
0
ControlFlowGraph::BlockPointerVector ControlFlowGraph::post_order_sequence() {
	typedef std::unordered_set<iterator> BlockSet;
	typedef std::stack<iterator> Stack;
	
	report("Creating post order traversal");
	BlockSet visited;
	BlockPointerVector sequence;
	Stack stack;
	
	if (!empty()) {
		for (pointer_iterator 
			block = get_entry_block()->successors.begin(); 
			block != get_entry_block()->successors.end(); ++block) {
			if (visited.insert(*block).second) {
				stack.push(*block);
			}
		}
	}
	
	while (!stack.empty()) {
		iterator current = stack.top();

		bool one = false;
		for (pointer_iterator block = current->successors.begin(); 
			block != current->successors.end(); ++block) {
			if (visited.insert(*block).second) {
				stack.push(*block);
				one = true;
			}
		}
		
		if(!one) {
			stack.pop();
			sequence.push_back(current);
			report(" Adding block " << current->label());
		}
	}

	report(" Adding block " << get_entry_block()->label());
	sequence.push_back(get_entry_block());

	return sequence;
}
示例#25
0
void DeadCodeEliminationPass::runOnKernel(ir::IRKernel& k)
{
	report("Running dead code elimination on kernel " << k.name);
	reportE(REPORT_PTX, k);
	
	Analysis* dfgAnalysis = getAnalysis(Analysis::DataflowGraphAnalysis);
	assert(dfgAnalysis != 0);

	analysis::DataflowGraph& dfg =
		*static_cast<analysis::DataflowGraph*>(dfgAnalysis);
	
	assert(dfg.ssa() != analysis::DataflowGraph::SsaType::None);
	
	BlockSet blocks;
	
	report(" Starting by scanning all basic blocks");
	
	for(iterator block = dfg.begin(); block != dfg.end(); ++block)
	{
		report("  Queueing up BB_" << block->id());
		blocks.insert(block);
	}
	
	while(!blocks.empty())
	{
		iterator block = *blocks.begin();
		blocks.erase(blocks.begin());
	
		eliminateDeadInstructions(dfg, blocks, block);
	}
	
	report("Finished running dead code elimination on kernel " << k.name);
	reportE(REPORT_PTX, k);
}
示例#26
0
    // If a block has multiple entries but no exits, and it is small enough, it is useful to split it.
    // A common example is a C++ function where everything ends up at a final exit block and does some
    // RAII cleanup. Without splitting, we will be forced to introduce labelled loops to allow
    // reaching the final block
    void SplitDeadEnds() {
      int TotalCodeSize = 0;
      for (BlockSet::iterator iter = Live.begin(); iter != Live.end(); iter++) {
        Block *Curr = *iter;
        TotalCodeSize += strlen(Curr->Code);
      }

      for (BlockSet::iterator iter = Live.begin(); iter != Live.end(); iter++) {
        Block *Original = *iter;
        if (Original->BranchesIn.size() <= 1 || Original->BranchesOut.size() > 0) continue;
        if (strlen(Original->Code)*(Original->BranchesIn.size()-1) > TotalCodeSize/5) continue; // if splitting increases raw code size by a significant amount, abort
        // Split the node (for simplicity, we replace all the blocks, even though we could have reused the original)
        for (BlockBranchMap::iterator iter = Original->BranchesIn.begin(); iter != Original->BranchesIn.end(); iter++) {
          Block *Prior = iter->first;
          Block *Split = new Block(Original->Code);
          Split->BranchesIn[Prior] = new Branch(NULL);
          Prior->BranchesOut[Split] = new Branch(Prior->BranchesOut[Original]->Condition, Prior->BranchesOut[Original]->Code);
          Prior->BranchesOut.erase(Original);
          Parent->AddBlock(Split);
          Live.insert(Split);
        }
      }
    }
static BlockSet getBlocksWithBackwardsBranches(CycleAnalysis* cycleAnalysis)
{
	auto edges = cycleAnalysis->getAllBackEdges();
	
	report(" Getting blocks with backwards branches");
	
	BlockSet backwardsBranchBlocks;
	
	for(auto& edge : edges)
	{
		if(edge->type != ir::Edge::Branch) continue;
		
		auto block = edge->head;
		
		if(getBranch(block) == nullptr) continue;

		backwardsBranchBlocks.insert(block);
		
		report("  " << block->label());
	}
	
	return backwardsBranchBlocks;
}
示例#28
0
 // Converts/processes all branchings to a specific target
 void Solipsize(Block *Target, Branch::FlowType Type, Shape *Ancestor, BlockSet &From) {
   PrintDebug("Solipsizing branches into %d\n", Target->Id);
   DebugDump(From, "  relevant to solipsize: ");
   for (BlockSet::iterator iter = Target->BranchesIn.begin(); iter != Target->BranchesIn.end();) {
     Block *Prior = *iter;
     if (From.find(Prior) == From.end()) {
       iter++;
       continue;
     }
     Branch *PriorOut = Prior->BranchesOut[Target];
     PriorOut->Ancestor = Ancestor;
     PriorOut->Type = Type;
     if (MultipleShape *Multiple = Shape::IsMultiple(Ancestor)) {
       Multiple->NeedLoop++; // We are breaking out of this Multiple, so need a loop
     }
     iter++; // carefully increment iter before erasing
     Target->BranchesIn.erase(Prior);
     Target->ProcessedBranchesIn.insert(Prior);
     Prior->BranchesOut.erase(Target);
     Prior->ProcessedBranchesOut[Target] = PriorOut;
     PrintDebug("  eliminated branch from %d\n", Prior->Id);
   }
 }
static bool flagHammocksWithSideEffects(SafeRegion& region,
	const BlockSet& blocksWithSideEffects)
{
	if(region.isLeaf())
	{
		region.doesNotDependOnSideEffects =
			blocksWithSideEffects.count(region.block) == 0;
	}
	else
	{
		region.doesNotDependOnSideEffects = true;
	
		for(auto& child : region.children)
		{
			region.doesNotDependOnSideEffects &=
				flagHammocksWithSideEffects(child, blocksWithSideEffects);
		}
	}
	
	return region.doesNotDependOnSideEffects;
}
static void propagateMoveSourceToUsersInBlock(instruction_iterator move,
	instruction_iterator position, block_iterator block, BlockSet& visited)
{
	// early exit for visited blocks
	if(!visited.insert(block->id()).second) return;

	assert(move->d.size() == 1);
	assert(move->s.size() == 1);

	auto destination = *move->d.front().pointer;
	auto moveSource  = *move->s.front().pointer;
	
	// We can skip PHIs because the use of a PHI would make the removal illegal

	// replace uses in the block
	for(; position != block->instructions().end(); ++position)
	{
		for(auto source = position->s.begin();
			source != position->s.end(); ++source)
		{
			if(*source->pointer == destination)
			{
				*source->pointer = moveSource;
			}
		}
	}
	
	// replace in successors
	for(auto successor = block->successors().begin();
		successor != block->successors().end(); ++successor)
	{
		if((*successor)->aliveIn().count(destination) == 0) continue;
		
		propagateMoveSourceToUsersInBlock(move,
			(*successor)->instructions().begin(), *successor, visited);
	}

}