static void linkAllBlocks() { auto e = gBlockMap.end(); auto i = gBlockMap.begin(); while(i!=e) { Block *block = (i++)->second; linkBlock(block); } }
static void findBlockParent( Block *b ) { auto where = lseek64( b->chunk->getMap()->fd, b->chunk->getOffset(), SEEK_SET ); if(where!=(signed)b->chunk->getOffset()) { sysErrFatal( "failed to seek into block chain file %s", b->chunk->getMap()->name.c_str() ); } uint8_t buf[gHeaderSize]; auto nbRead = read( b->chunk->getMap()->fd, buf, gHeaderSize ); if(nbRead<(signed)gHeaderSize) { sysErrFatal( "failed to read from block chain file %s", b->chunk->getMap()->name.c_str() ); } auto i = gBlockMap.find(4 + buf); if(unlikely(gBlockMap.end()==i)) { uint8_t bHash[2*kSHA256ByteSize + 1]; toHex(bHash, b->hash); uint8_t pHash[2*kSHA256ByteSize + 1]; toHex(pHash, 4 + buf); warning( "in block %s failed to locate parent block %s", bHash, pHash ); return; } b->prev = i->second; }
static void getBlockHeader( size_t &size, Block *&prev, uint8_t *&hash, size_t &earlyMissCnt, const uint8_t *p ) { LOAD(uint32_t, magic, p); if(unlikely(gExpectedMagic!=magic)) { hash = 0; return; } LOAD(uint32_t, sz, p); size = sz; prev = 0; hash = allocHash256(); #if defined(DARKCOIN) h9(hash, p, gHeaderSize); #elif defined(PAYCON) h13(hash, p, gHeaderSize); #elif defined(MARTEXCOIN) h13(hash, p, gHeaderSize); #elif defined(CLAM) auto pBis = p; LOAD(uint32_t, nVersion, pBis); if(6<nVersion) { sha256Twice(hash, p, gHeaderSize); } else { scrypt(hash, p, gHeaderSize); } #elif defined(JUMBUCKS) scrypt(hash, p, gHeaderSize); #else sha256Twice(hash, p, gHeaderSize); #endif auto i = gBlockMap.find(p + 4); if(likely(gBlockMap.end()!=i)) { prev = i->second; } else { ++earlyMissCnt; } }
static void linkBlock( Block *block ) { if(unlikely(0==block->data)) { block->height = 0; block->prev = 0; block->next = 0; return; } int depth = 0; Block *b = block; while(b->height<0) { auto i = gBlockMap.find(4 + b->data); if(unlikely(gBlockMap.end()==i)) { uint8_t buf[2*kSHA256ByteSize + 1]; toHex(buf, 4 + b->data); warning("at depth %d in chain, failed to locate parent block %s", depth, buf); return; } Block *prev = i->second; prev->next = b; b->prev = prev; b = prev; ++depth; } uint64_t h = b->height; while(block!=b) { Block *next = b->next; b->height = h; b->next = 0; if(likely(gMaxHeight<h)) { gMaxHeight = h; gMaxBlock = b; } b = next; ++h; } }
IloInt getBlock(IloNumVar x) const { BlockMap::const_iterator const it = blockMap.find(x); return (it == blockMap.end()) ? -1 : it->second; }
bool SimplifyControlFlowGraphPass::_mergeExitBlocks(ir::IRKernel& k) { typedef std::unordered_map<ir::ControlFlowGraph::iterator, ir::ControlFlowGraph::instruction_iterator> BlockMap; report(" Merging exit blocks..."); BlockMap exitBlocks; // Find all blocks with exit instructions for(ir::ControlFlowGraph::iterator block = k.cfg()->begin(); block != k.cfg()->end(); ++block) { for(ir::ControlFlowGraph::instruction_iterator instruction = block->instructions.begin(); instruction != block->instructions.end(); ++instruction) { ir::PTXInstruction& ptx = static_cast<ir::PTXInstruction&>(**instruction); if(ptx.isExit() && ptx.opcode != ir::PTXInstruction::Trap) { // There should be an edge to the exit block assertM(block->find_out_edge(k.cfg()->get_exit_block()) != block->out_edges.end(), "No edge from " << block->label() << " to exit node."); exitBlocks.insert(std::make_pair(block, instruction)); break; } } } // If there is only one/zero blocks, then don't change anything if(exitBlocks.size() < 2) { if(exitBlocks.size() == 1) { ir::PTXInstruction& ptx = static_cast<ir::PTXInstruction&>(**exitBlocks.begin()->second); if(k.function()) { ptx.opcode = ir::PTXInstruction::Ret; } else { ptx.opcode = ir::PTXInstruction::Exit; } } return false; } // Otherwise... // 1) create a new exit block ir::ControlFlowGraph::iterator newExit = k.cfg()->insert_block( ir::BasicBlock(k.cfg()->newId())); ir::BasicBlock::EdgePointerVector deletedEdges = k.cfg()->get_exit_block()->in_edges; // 1a) Create edges targetting the new block for(ir::ControlFlowGraph::edge_pointer_iterator edge = deletedEdges.begin(); edge != deletedEdges.end(); ++edge) { k.cfg()->insert_edge(ir::Edge((*edge)->head, newExit, (*edge)->type)); k.cfg()->remove_edge(*edge); } k.cfg()->insert_edge(ir::Edge(newExit, k.cfg()->get_exit_block(), ir::Edge::FallThrough)); // 2) Delete the instructions from their blocks for(BlockMap::iterator block = exitBlocks.begin(); block != exitBlocks.end(); ++block) { report(" merging block " << block->first->label()); // 2a) Insert a branch from blocks with branch edges ir::ControlFlowGraph::edge_pointer_iterator edge = newExit->find_in_edge(block->first); if((*edge)->type == ir::Edge::Branch) { ir::PTXInstruction* newBranch = new ir::PTXInstruction( ir::PTXInstruction::Bra, ir::PTXOperand(newExit->label())); newBranch->uni = true; block->first->instructions.push_back(newBranch); } delete *block->second; block->first->instructions.erase(block->second); } // 3 Add an appropriate exit instruction to the new exit block if(k.function()) { newExit->instructions.push_back( new ir::PTXInstruction(ir::PTXInstruction::Ret)); } else { newExit->instructions.push_back( new ir::PTXInstruction(ir::PTXInstruction::Exit)); } return true; }