void bind(int x, int y) { x = getset(x); y = getset(y); if (x == y) return; if (rank[x] > rank[y]) { p[y] = x; } else { if (rank[x] == rank[y]) { ++ rank[y]; } p[x] = y; } }
int getset(int x) { if (p[x] == x) { return x; } else { return p[x] = getset(p[x]); } }
void Load(mem_addr_t* addr) { cache_set_t this_set=cache[getset(addr)]; int index; int full = 1; int empty_item = 0; // if not full, keep track of the empty item int last_item = 0; // if full, keep track of the evict item unsigned long long int last_time = this_set[0].lru; for (index = 0; index < E; index++) { // found, update the lru time if ((this_set[index]).valid == '1' && gettag(addr) == (this_set[index]).tag) { (this_set[index]).lru = ++lru_counter; break; } // not valid, then this entry is considered empty which means cache is not full else if ((this_set[index]).valid == '0') { full = 0; empty_item = index; } // valid but tag not equal else { // keep track of the LRU item, ready for eviction if ((this_set[index]).lru < last_time) { last_item = index; last_time = (this_set[index]).lru; } } } if (index == E) // miss { miss_count++; if (full) //evict { (this_set[last_item]).tag=gettag(addr); (this_set[last_item]).lru = ++lru_counter; eviction_count++; } else { (this_set[empty_item]).valid = '1'; (this_set[empty_item]).tag = gettag(addr); (this_set[empty_item]).lru = ++lru_counter; } } else // hit { hit_count++; } }
//------------------------------add_liveout------------------------------------ // Add a live-out value to a given blocks live-out set. If it is new, then // also add it to the delta set and stick the block on the worklist. void PhaseLive::add_liveout( Block *p, uint r, VectorSet &first_pass ) { IndexSet *live = &_live[p->_pre_order-1]; if( live->insert(r) ) { // If actually inserted... // We extended the live-out set. See if the value is generated locally. // If it is not, then we must extend the live-in set. if( !_defs[p->_pre_order-1].member( r ) ) { if( !_deltas[p->_pre_order-1] && // Not on worklist? first_pass.test(p->_pre_order) ) _worklist->push(p); // Actually go on worklist if already 1st pass getset(p)->insert(r); } } }
void getset(int n,int i) { int j; if(n==1) { a[i]=1; for(j=0;j<=i;j++) printf("%d ",a[j]); printf("\n "); return; } if(n==0) { for(j=0;j<i;j++) printf("%d ",a[j]); printf("\n "); return ; } a[i]=1; getset(n-1,i+1); a[i]=2; getset(n-2,i+1); }
void Store(mem_addr_t* addr) { cache_set_t this_set=cache[getset(addr)]; int index; for (index = 0; index < E; index++) { if ((this_set[index]).valid == '1' && gettag(addr) == (this_set[index]).tag) //found { (this_set[index]).lru = ++lru_counter; break; } } if (index == E) // store miss { Load(addr); // if miss, then load } else // store hit { hit_count++; } }
int main() { getset(20,0); return 0; }
void PhaseLive::compute(uint maxlrg) { _maxlrg = maxlrg; _worklist = new (_arena) Block_List(); // Init the sparse live arrays. This data is live on exit from here! // The _live info is the live-out info. _live = (IndexSet*)_arena->Amalloc(sizeof(IndexSet)*_cfg._num_blocks); uint i; for( i=0; i<_cfg._num_blocks; i++ ) { _live[i].initialize(_maxlrg); } // Init the sparse arrays for delta-sets. ResourceMark rm; // Nuke temp storage on exit // Does the memory used by _defs and _deltas get reclaimed? Does it matter? TT // Array of values defined locally in blocks _defs = NEW_RESOURCE_ARRAY(IndexSet,_cfg._num_blocks); for( i=0; i<_cfg._num_blocks; i++ ) { _defs[i].initialize(_maxlrg); } // Array of delta-set pointers, indexed by block pre_order-1. _deltas = NEW_RESOURCE_ARRAY(IndexSet*,_cfg._num_blocks); memset( _deltas, 0, sizeof(IndexSet*)* _cfg._num_blocks); _free_IndexSet = NULL; // Blocks having done pass-1 VectorSet first_pass(Thread::current()->resource_area()); // Outer loop: must compute local live-in sets and push into predecessors. uint iters = _cfg._num_blocks; // stat counters for( uint j=_cfg._num_blocks; j>0; j-- ) { Block *b = _cfg._blocks[j-1]; // Compute the local live-in set. Start with any new live-out bits. IndexSet *use = getset( b ); IndexSet *def = &_defs[b->_pre_order-1]; uint i; for( i=b->_nodes.size(); i>1; i-- ) { Node *n = b->_nodes[i-1]; if( n->is_Phi() ) break; // BoxNodes keep their input alive as long as their uses. If we // see a BoxNode then make its input live to the Root block. // Because we are solving LIVEness, the input now becomes live // over the whole procedure, interferencing with everything else // and getting a private unshared stack slot. YeeeHaw! MachNode *mach = n->is_Mach(); if( mach && mach->ideal_Opcode() == Op_Box ) getset(_cfg._broot)->insert( _names[n->in(1)->_idx] ); uint r = _names[n->_idx]; def->insert( r ); use->remove( r ); uint cnt = n->req(); for( uint k=1; k<cnt; k++ ) { Node *nk = n->in(k); uint nkidx = nk->_idx; if( _cfg._bbs[nkidx] != b ) use->insert( _names[nkidx] ); } } // Remove anything defined by Phis and the block start instruction for( uint k=i; k>0; k-- ) { uint r = _names[b->_nodes[k-1]->_idx]; def->insert( r ); use->remove( r ); } // Push these live-in things to predecessors for( uint l=1; l<b->num_preds(); l++ ) { Block *p = _cfg._bbs[b->pred(l)->_idx]; add_liveout( p, use, first_pass ); // PhiNode uses go in the live-out set of prior blocks. for( uint k=i; k>0; k-- ) add_liveout( p, _names[b->_nodes[k-1]->in(l)->_idx], first_pass ); } freeset( b ); first_pass.set(b->_pre_order); // Inner loop: blocks that picked up new live-out values to be propagated while( _worklist->size() ) { // !!!!! // #ifdef ASSERT iters++; // #endif Block *b = _worklist->pop(); IndexSet *delta = getset(b); assert( delta->count(), "missing delta set" ); // Add new-live-in to predecessors live-out sets for( uint l=1; l<b->num_preds(); l++ ) add_liveout( _cfg._bbs[b->pred(l)->_idx], delta, first_pass ); freeset(b); } // End of while-worklist-not-empty } // End of for-all-blocks-outer-loop // We explicitly clear all of the IndexSets which we are about to release. // This allows us to recycle their internal memory into IndexSet's free list. for( i=0; i<_cfg._num_blocks; i++ ) { _defs[i].clear(); if (_deltas[i]) { // Is this always true? _deltas[i]->clear(); } } IndexSet *free = _free_IndexSet; while (free != NULL) { IndexSet *temp = free; free = free->next(); temp->clear(); } }
void PhaseLive::compute(uint maxlrg) { _maxlrg = maxlrg; _worklist = new (_arena) Block_List(); // Init the sparse live arrays. This data is live on exit from here! // The _live info is the live-out info. _live = (IndexSet*)_arena->Amalloc(sizeof(IndexSet) * _cfg.number_of_blocks()); uint i; for (i = 0; i < _cfg.number_of_blocks(); i++) { _live[i].initialize(_maxlrg); } if (_keep_deltas) { _livein = (IndexSet*)_arena->Amalloc(sizeof(IndexSet) * _cfg.number_of_blocks()); for (i = 0; i < _cfg.number_of_blocks(); i++) { _livein[i].initialize(_maxlrg); } } // Init the sparse arrays for delta-sets. ResourceMark rm; // Nuke temp storage on exit // Does the memory used by _defs and _deltas get reclaimed? Does it matter? TT // Array of values defined locally in blocks _defs = NEW_RESOURCE_ARRAY(IndexSet,_cfg.number_of_blocks()); for (i = 0; i < _cfg.number_of_blocks(); i++) { _defs[i].initialize(_maxlrg); } // Array of delta-set pointers, indexed by block pre_order-1. _deltas = NEW_RESOURCE_ARRAY(IndexSet*,_cfg.number_of_blocks()); memset( _deltas, 0, sizeof(IndexSet*)* _cfg.number_of_blocks()); _free_IndexSet = NULL; // Blocks having done pass-1 VectorSet first_pass(Thread::current()->resource_area()); // Outer loop: must compute local live-in sets and push into predecessors. for (uint j = _cfg.number_of_blocks(); j > 0; j--) { Block* block = _cfg.get_block(j - 1); // Compute the local live-in set. Start with any new live-out bits. IndexSet* use = getset(block); IndexSet* def = &_defs[block->_pre_order-1]; DEBUG_ONLY(IndexSet *def_outside = getfreeset();) uint i; for (i = block->number_of_nodes(); i > 1; i--) { Node* n = block->get_node(i-1); if (n->is_Phi()) { break; } uint r = _names.at(n->_idx); assert(!def_outside->member(r), "Use of external LRG overlaps the same LRG defined in this block"); def->insert( r ); use->remove( r ); uint cnt = n->req(); for (uint k = 1; k < cnt; k++) { Node *nk = n->in(k); uint nkidx = nk->_idx; if (_cfg.get_block_for_node(nk) != block) { uint u = _names.at(nkidx); use->insert(u); DEBUG_ONLY(def_outside->insert(u);) } } }
bool redis_string::getset(const char* key, const char* value, string& buf) { return getset(key, strlen(key), value, strlen(value), buf); }