Esempio n. 1
0
static void
traverse (relation_node i)
{
  relation_node j;
  relation_node height;

  VERTICES[++top] = i;
  INDEX[i] = height = top;

  if (R[i])
    for (j = 0; R[i][j] != END_NODE; ++j)
      {
        if (INDEX[R[i][j]] == 0)
          traverse (R[i][j]);

        if (INDEX[i] > INDEX[R[i][j]])
          INDEX[i] = INDEX[R[i][j]];

        bitset_or (F[i], F[i], F[R[i][j]]);
      }

  if (INDEX[i] == height)
    for (;;)
      {
        j = VERTICES[top--];
        INDEX[j] = infinity;

        if (i == j)
          break;

        bitset_copy (F[j], F[i]);
      }
}
Esempio n. 2
0
static int apply_alternating_path(bipartite_t const *const gr,
                                  int *const matching,
                                  bitset_t *const matched_left,
                                  bitset_t *const matched_right)
{
	bool done_something = false;
	bitset_t *const tmp = bitset_alloca(gr->n_right);

	for (unsigned left = 0; left < gr->n_left; ++left) {
		bitset_t *left_adj = gr->adj[left];
		bitset_copy(tmp, left_adj);

		if (matching[left] >= 0) {
			int old_right = matching[left];

			/* Check of all neighbors of the left node are already matched.
			 * We cannot improve this edge then. */
			if (bitset_contains(left_adj, matched_right))
				continue;

			bitset_andnot(tmp, matched_right);
			unsigned right = bitset_next_set(tmp, 0);
			assert(right != ~0u);

			/* We have to find another left node which has the old right one as
			 * a neighbor. This node must not be part of a matching */
			unsigned i;
			for (i = 0; i < gr->n_left; ++i)
				if (i != left && bitset_is_set(gr->adj[i], old_right) && !bitset_is_set(matched_left, i))
					break;

			/* If no such node can be found, exit. */
			if (i >= gr->n_left)
				continue;

			/* Else, we can improve this edge. */
			matching[left] = right;
			matching[i] = old_right;
			bitset_set(matched_left, i);
			bitset_set(matched_right, right);
			done_something = true;
		} else {
			/* We have to create a new single edge */
			assert(!bitset_is_set(matched_left, left));

			bitset_andnot(tmp, matched_right);
			if (bitset_is_empty(tmp))
				continue;

			unsigned right = bitset_next_set(tmp, 0);
			assert(!bitset_is_set(matched_right, right));
			matching[left] = right;
			bitset_set(matched_left, left);
			bitset_set(matched_right, right);
			done_something = true;
		}
	}

	return done_something;
}
Esempio n. 3
0
void networkReadCallbackPerRead(NetworkAddress networkAddr, ADDRINT start, size_t length, void *v)
{
    int tag;
    bitset *s = bitset_init(NUMBER_OF_TAINT_MARKS);
    assert(taintGen);
    tag = taintGen->nextTaintMark();
    //taint entire buffer with 1 mark
    bitset_set_bit(s, tag);

    ADDRINT end = start + length;
    for(ADDRINT addr = start; addr < end; addr++) {
        memTaintMap[addr] = bitset_copy(s);
    }
    bitset_free(s);

    taintAssignmentLog << tag << " - [" << networkAddr.strAddress << "] -> " << std::hex << start << "-" << std::hex << end - 1<< "\n";
    taintAssignmentLog.flush();

#ifdef TRACE
    if(tracing) {
        log << "\t" << std::hex << start << "-" << std::hex << end - 1 << " <- read(" << tag << ")\n";
        log.flush();
    }
#endif
}
Esempio n. 4
0
void networkReadCallbackPerByte(NetworkAddress networkAddr, ADDRINT start, size_t length, void *v)
{
    int tag;

    assert(taintGen);
    bitset *s = bitset_init(NUMBER_OF_TAINT_MARKS);

    ADDRINT end = start + length;
    for(ADDRINT addr = start; addr < end; addr++) {
        tag = taintGen->nextTaintMark();
        bitset_set_bit(s, tag);
        memTaintMap[addr] = bitset_copy(s);
        bitset_reset(s);
    }
    bitset_free(s);

    ADDRINT currAddress = start;
    while (currAddress < end) {
        taintAssignmentLog << tag << " - [" << networkAddr.strAddress << "] -> " << std::hex << currAddress++ << "\n";
    }
    taintAssignmentLog.flush();

#ifdef TRACE
    if(tracing) {
        log << "\t" << std::hex << start << "-" << std::hex << end - 1 << " <- read\n";
        log.flush();
    }
#endif
}
Esempio n. 5
0
bitset *bitset_dup(bitset *b)
{
	bitset *nb = bitset_new(b->bs_nbits);

	bitset_copy(nb, b);

	return nb;
}
Esempio n. 6
0
File: bitset.c Progetto: o11c/nicate
BitSet *bitset_unique(BitSet *b)
{
    if (bitset_refcount(b))
    {
        b[-2].word--;
        return bitset_copy(b);
    }
    return b;
}
Esempio n. 7
0
static int snd_pcm_plugin_dst_channels_mask(snd_pcm_plugin_t *plugin,
					    bitset_t *src_vmask,
					    bitset_t **dst_vmask)
{
	bitset_t *vmask = plugin->dst_vmask;
	bitset_copy(vmask, src_vmask, plugin->dst_format.channels);
	*dst_vmask = vmask;
	return 0;
}
Esempio n. 8
0
/**
 * @brief Creates a copy of a bitset data structure.
 * @details Initializes `set` with the same size of `source` and copies all values of `source` to `set`.
 * @param set Pointer to an unitialized bitset data structure.
 * @param source Pointer to an itialized bitset data structure that is to be copied.
 */
void bitset_init_copy(bitset_t *set, const bitset_t const *source)
{
#ifdef BITSET_ASSERTIONS
    assert(set);
    assert(source);
#endif

    bitset_init(set, source->max);
    bitset_copy(set, source);
}
Esempio n. 9
0
void build(flow_graph * graph){
	flow_node * node = graph->end;
	bitset * live;
	rga_move * move;
	rd_instr * ins;
	unsigned int def_pos = 0, live_pos = 0;
	unsigned int p1_id = 0, p2_id = 0;
	while(node != 0){
		ins = node->data;
		live = bitset_copy(node->liveout);
		if(ins->type == RD_SET && (ins->p1->type == RD_VAR || ins->p1->type == RD_REG) && (ins->p2->type == RD_VAR || ins->p2->type == RD_REG)){			
			if(ins->p1->type == RD_VAR){
				p1_id = ins->p1->id;
			}else{
				p1_id = num_nodes - num_registers + ins->p1->id;
			}
			if(ins->p2->type == RD_VAR){
				p2_id = ins->p2->id;
			}else{
				p2_id = num_nodes - num_registers + ins->p2->id;
			}

			bitset_sub(live, node->use);
			if(!rga_move_list_exists(worklistMoves, nodes[p1_id], nodes[p2_id])){
				move = rga_move_new(nodes[p1_id], nodes[p2_id]);
				moveList[p1_id] = rga_move_map_add(moveList[p1_id], move);
				moveList[p2_id] = rga_move_map_add(moveList[p2_id], move);
				#ifdef DEBUG_MODE
				printf("Added move from v%u to v%u\n", p1_id, p2_id);
				#endif
				rga_move_list_push(worklistMoves, move);
				move->set = RGA_WORKLIST_MOVES;
			}
		}else if(ins->type == RD_INTERFERE){
			add_edge(nodes[ins->p1->id], nodes[num_nodes - num_registers + ins->p2->id]);
		}
		bitset_or(live, node->def);
		#ifdef DEBUG_MODE
		printf("Live out:");
		bitset_show(live);
		#endif
		while((def_pos = bitset_first_on(node->def, def_pos)) != ~0){
			while((live_pos = bitset_first_on(live, live_pos)) != ~0){
				add_edge(nodes[live_pos], nodes[def_pos]);
				live_pos++;
			}
			live_pos = 0;
			def_pos++;
		}
		def_pos = live_pos = 0;
		node = node->prev;
	}
}
Esempio n. 10
0
t_gol				*bitset_gol_create(int32_t x, int32_t y, int32_t state)
{
	register t_gol					*const gol = malloc(sizeof(t_gol));

	if (!gol)
		perror_exit("bitset_gol_create()", 1);
	gol->bt1 = create_bitset(state);
	gol->bt2 = create_bitset(0);
	gol->x = x;
	gol->y = y;
	bitset_copy(gol->bt2, gol->bt1);
	return (gol);
}
Esempio n. 11
0
static void
useless_nonterminals (void)
{
  bitset Np, Ns;
  rule_number r;

  /* N is set as built.  Np is set being built this iteration. P is
     set of all productions which have a RHS all in N.  */

  Np = bitset_create (nvars, BITSET_FIXED);


  /* The set being computed is a set of nonterminals which can derive
     the empty string or strings consisting of all terminals. At each
     iteration a nonterminal is added to the set if there is a
     production with that nonterminal as its LHS for which all the
     nonterminals in its RHS are already in the set.  Iterate until
     the set being computed remains unchanged.  Any nonterminals not
     in the set at that point are useless in that they will never be
     used in deriving a sentence of the language.

     This iteration doesn't use any special traversal over the
     productions.  A set is kept of all productions for which all the
     nonterminals in the RHS are in useful.  Only productions not in
     this set are scanned on each iteration.  At the end, this set is
     saved to be used when finding useful productions: only
     productions in this set will appear in the final grammar.  */

  while (1)
    {
      bitset_copy (Np, N);
      for (r = 0; r < nrules; r++)
        if (!bitset_test (P, r)
            && useful_production (r, N))
          {
            bitset_set (Np, rules[r].lhs->number - ntokens);
            bitset_set (P, r);
          }
      if (bitset_equal_p (N, Np))
        break;
      Ns = Np;
      Np = N;
      N = Ns;
    }
  bitset_free (N);
  N = Np;
}
Esempio n. 12
0
// WARNING: This is not re-entrant; should only be called from one thread.
static int translate_button_Ev( ev_t* dest, const union SDL_Event* ev ) {

	int  which;
	bool pressed;
	switch( ev->type ) {

	case SDL_MOUSEBUTTONDOWN:
	case SDL_MOUSEBUTTONUP: {
		const SDL_MouseButtonEvent* button = &ev->button;

		which = buttonsets[0].base + ev->button.button;
		pressed = SDL_PRESSED == button->state;
		break;
	}

	case SDL_JOYBUTTONDOWN:
	case SDL_JOYBUTTONUP: {
		const SDL_JoyButtonEvent* button = &ev->jbutton;
		struct buttonset_s* buttonset = &buttonsets[ 1+button->which ];
		
		which = buttonset->base + button->button;
		pressed = SDL_PRESSED == button->state;
		break;
	}
	default:
		fatal("Bad button event: 0x%x", ev->type);
		return -1;
	}

	// Update our local state
	if( pressed )
		bitset_set( button_state, which );
	else
		bitset_clear( button_state, which );

	// Copy into dest event
	dest->button.which = which;
	dest->button.pressed = pressed;
	bitset_copy( dest->button.state, maxButtonCount, button_state );

	return 0;

}
Esempio n. 13
0
static void
inaccessable_symbols (void)
{
  bitset Vp, Vs, Pp;

  /* Find out which productions are reachable and which symbols are
     used.  Starting with an empty set of productions and a set of
     symbols which only has the start symbol in it, iterate over all
     productions until the set of productions remains unchanged for an
     iteration.  For each production which has a LHS in the set of
     reachable symbols, add the production to the set of reachable
     productions, and add all of the nonterminals in the RHS of the
     production to the set of reachable symbols.

     Consider only the (partially) reduced grammar which has only
     nonterminals in N and productions in P.

     The result is the set P of productions in the reduced grammar,
     and the set V of symbols in the reduced grammar.

     Although this algorithm also computes the set of terminals which
     are reachable, no terminal will be deleted from the grammar. Some
     terminals might not be in the grammar but might be generated by
     semantic routines, and so the user might want them available with
     specified numbers.  (Is this true?)  However, the nonreachable
     terminals are printed (if running in verbose mode) so that the
     user can know.  */

  Vp = bitset_create (nsyms, BITSET_FIXED);
  Pp = bitset_create (nrules, BITSET_FIXED);

  /* If the start symbol isn't useful, then nothing will be useful. */
  if (bitset_test (N, accept->number - ntokens))
    {
      bitset_set (V, accept->number);

      while (1)
        {
          rule_number r;
          bitset_copy (Vp, V);
          for (r = 0; r < nrules; r++)
            {
              if (!bitset_test (Pp, r)
                  && bitset_test (P, r)
                  && bitset_test (V, rules[r].lhs->number))
                {
                  item_number *rhsp;
                  for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
                    if (ISTOKEN (*rhsp) || bitset_test (N, *rhsp - ntokens))
                      bitset_set (Vp, *rhsp);
                  bitset_set (Pp, r);
                }
            }
          if (bitset_equal_p (V, Vp))
            break;
          Vs = Vp;
          Vp = V;
          V = Vs;
        }
    }

  bitset_free (V);
  V = Vp;

  /* Tokens 0, 1, and 2 are internal to Bison.  Consider them useful. */
  bitset_set (V, endtoken->number);             /* end-of-input token */
  bitset_set (V, errtoken->number);             /* error token */
  bitset_set (V, undeftoken->number);           /* some undefined token */

  bitset_free (P);
  P = Pp;

  nuseful_productions = bitset_count (P);
  nuseless_productions = nrules - nuseful_productions;

  nuseful_nonterminals = 0;
  {
    symbol_number i;
    for (i = ntokens; i < nsyms; i++)
      if (bitset_test (V, i))
        nuseful_nonterminals++;
  }
  nuseless_nonterminals = nvars - nuseful_nonterminals;

  /* A token that was used in %prec should not be warned about.  */
  {
    rule_number r;
    for (r = 0; r < nrules; ++r)
      if (rules[r].precsym != 0)
        bitset_set (V1, rules[r].precsym->number);
  }
}
Esempio n. 14
0
rd_vlist * mem_alloc(rd_instr * code,
	rd_vlist * vlist,
	unsigned int match_types,
	unsigned int ret_type,
	unsigned int type_size){

	//start local variables
	flow_graph * graph;
	flow_node * node;

	rga_node * x, * y;
	rga_node_map * list;
	rga_move * move;

	rd_vlist * new_list;
	rd_instr * ins;
	rd_var * v;

	bitset * live;

	unsigned int def_pos, live_pos, set_size, last_id, i;

	bitset * used_colours;
	//end local variables
	
	//perform flow analysis
	graph = flow_generate_graph(code, vlist, 0, 0, match_types);

	//allocate space for node and move information
	initial          = rga_node_list_new();
	coalescedNodes   = rga_node_list_new();
	colouredNodes    = rga_node_list_new();

	coalescedMoves   = rga_move_list_new();
	constrainedMoves = rga_move_list_new();
	worklistMoves    = rga_move_list_new();
	
	nodes = new rga_node *[vlist->num_vars];
	adjSet = new bitset *[vlist->num_vars];
	adjList = new rga_node_map *[vlist->num_vars];
	alias = new rga_node *[vlist->num_vars];
	colour = new unsigned char[vlist->num_vars];

	//initialise memory variables
	for(i = 0; i < vlist->num_vars; i++){
		nodes[i] = rga_node_new(0);
		rga_node_list_push(initial, nodes[i]);
		nodes[i]->set = RGA_INITIAL;
		colour[i] = 0;
		adjList[i] = 0;
		adjSet[i] = bitset_new(vlist->num_vars);
		alias[i] = 0;
	}

	//build the graph
	node = graph->end;
	def_pos = live_pos = 0;
	while(node != 0){
		ins = node->data;
		live = bitset_copy(node->liveout);
		if(ins->type == RD_SET && ins->p1->type & match_types && ins->p2->type & match_types){
			bitset_sub(live, node->use);
			if(!rga_move_list_exists(worklistMoves, nodes[ins->p1->id], nodes[ins->p2->id])){
				move = rga_move_new(nodes[ins->p1->id], nodes[ins->p2->id]);
				rga_move_list_push(worklistMoves, move);
				move->set = RGA_WORKLIST_MOVES;
			}
		}
		bitset_or(live, node->def);
		while((def_pos = bitset_first_on(node->def, def_pos)) != ~0){
			while((live_pos = bitset_first_on(live, live_pos)) != ~0){
				mem_add_edge(nodes[live_pos], nodes[def_pos]);
				live_pos++;
			}
			live_pos = 0;
			def_pos++;
		}
		def_pos = 0;
		node = node->prev;
	}

	//coalesce phase
	while(!rga_move_list_isempty(worklistMoves)){
		move = rga_move_list_pop(worklistMoves);
		x = get_alias(move->a);
		y = get_alias(move->b);
		if(x == y){
			rga_move_list_push(coalescedMoves, move);
			move->set = RGA_COALESCED_MOVES;
		}else if(bitset_check(adjSet[x->id], y->id) || bitset_check(adjSet[x->id], y->id)){
			rga_move_list_push(constrainedMoves, move);
			move->set = RGA_CONSTRAINED_MOVES;
		}else{
			rga_move_list_push(coalescedMoves, move);
			move->set = RGA_COALESCED_MOVES;
			list = adjList[y->id];
			rga_node_list_remove(initial, y);
			rga_node_list_push(coalescedNodes, y);
			y->set = RGA_COALESCED_NODES;
			alias[y->id] = x;
			while(list != 0){
				if(list->node->set != RGA_COALESCED_NODES){
					mem_add_edge(list->node, x);
				}
				list = list->prev;
			}
		}
	}

	//simplify and select phase
	new_list = rd_varlist(0);
	set_size = 0;
	last_id = 0;
	used_colours = bitset_new(vlist->num_vars);
	while(x = rga_node_list_pop(initial)){
		bitset_reset(used_colours);
		list = adjList[x->id];
		while(list != 0){
			y = get_alias(list->node);
			if(y->set == RGA_COLOURED_NODES){
				bitset_set(used_colours, colour[y->id]);
			}
			list = list->prev;
		}
		rga_node_list_push(colouredNodes, x);
		x->set = RGA_COLOURED_NODES;
		colour[x->id] = bitset_first_off(used_colours, 0);
		if(rd_vlist_find(new_list, colour[x->id]) == 0){
			rd_vlist_add(new_list, colour[x->id], ret_type, 0, 0, type_size);
		}
		if(colour[x->id] > last_id){
			last_id = colour[x->id];
		}
		#ifdef DEBUG_MODE
		printf("mem%u gets %u\n", x->id, colour[x->id]);
		#endif
	}
	bitset_delete(used_colours);

	new_list->num_vars = last_id + 1;

	//set the colour of coalesced nodes
	x = coalescedNodes->end;
	while(x != 0){
		colour[x->id] = colour[get_alias(x)->id];
		//rd_vlist_add(new_list, colour[x->id], ret_type, 0, 0, type_size);
		#ifdef DEBUG_MODE		
		printf("mem%u gets %u\n", x->id, colour[x->id]);
		#endif
		x = x->prev;
	}

	node = graph->end;
	while(node != 0){
		if(node->data->p1 != 0){
			if(node->data->p1->type & match_types){
				v = rd_vlist_find(new_list, colour[node->data->p1->id]);
				if(v != 0){
					node->data->p1 = v;
				}
			}
		}
		if(node->data->p2 != 0){
			if(node->data->p2->type & match_types){
				v = rd_vlist_find(new_list, colour[node->data->p2->id]);
				if(v != 0){
					node->data->p2 = v;
				}
			}
		}
		if(node->data->p3 != 0){
			if(node->data->p3->type & match_types){
				v = rd_vlist_find(new_list, colour[node->data->p3->id]);
				if(v != 0){
					node->data->p3 = v;
				}
			}
		}
		node = node->prev;
	}

	//clean up
	delete initial;
	delete coalescedNodes;
	delete colouredNodes;

	delete coalescedMoves;
	delete constrainedMoves;
	delete worklistMoves;

	for(i = 0; i < vlist->num_vars; i++){
		delete nodes[i];
		if(adjList[i] != 0){
			delete adjList[i];
		}
		bitset_delete(adjSet[i]);
	}

	delete[] nodes;
	delete[] adjSet;
	delete[] adjList;
	delete[] alias;
	delete[] colour;

	rga_reset();

	return new_list;
}
Esempio n. 15
0
/* This is a complex, recursive function to determine the cost for
 * calculating a condition after any still-needed variables have been
 * generated.  Cost is measured in terms of the anticipated number of
 * generated new variable sets, as provided by "*float" annotations
 * on generator and condition lines.
 *
 * Call this with a condition and varsneeded.  The soln_xxx fields will
 * be filled with the requested information, namely the total cost
 * and the generators needed to get there.  The soln_generators bitset
 * is assumed to already exist.
 *
 * This function may not always be able to determine a solution; this
 * can be the case if variables are mentioned in conditions but not in
 * generators, for instance.  In such situations, the function returns
 * false.  It is considered a success if all variables that are needed
 * for a condition are resolved by at least one generator.
 *
 * This is an important function when determining the "path of least
 * resistence" from any generator activity; the least costly condition
 * will always be calculated first, then the calculations are redone,
 * and what is then the least will be selected, and so on.  The
 * generators required will be inserted into the path before their
 * dependent conditions, in the order of least-costly ones first.
 *
 * This is a rather heavy form of analysis, but it is executed only
 * once, at startup of the environment.  After that, the SyncRepl
 * updates can ripple through in great speed.  Note that the complexity
 * and time delays of these procedures rise with the (usually modest)
 * degree of interrelationships between generators and conditions.
 */
bool cnd_get_min_total_cost (struct condition *cc, bitset_t *varsneeded,
				float *soln_mincost,
				bitset_t *soln_generators) {
	bool have_soln = false;
	float soln_mincost;
	varnum_t v, v_max;
	gennum_t g, g_max;
	//
	// Allocate bitsets that will be used while cycling, but not
	// across recursive uses.  To that and, a pile or pool of
	// bitsets could come in handy...  TODO: Optimisation
	//
	bitset_t *cand_varsneeded = bitset_new (varsneeded->type);
	bitset_t *cand_generators = bitset_new (soln_generators->type);
	//
	// If there is no need for further variables to calculate this
	// condition, then terminate recursion on this function.  There
	// will be no requirement to include a generator, and so there
	// will be no generator-incurred expenses.  There will only be
	// the cost of the condition itself, which must still compare
	// with other conditions that might be tighter.
	//
	if (bitset_isempty (varsneeded)) {
		/* Recursion ends, so neither generators nor their cost */
		bitset_empty (out_generators);
		return cc->cost;
	}
	//
	// Iterate over the variables that will need to be generated.
	// For each, iterate over the generators producing it.
	// See how this reduces the variable need, and recurse.
	//
	v_max = bitset_max (varsneeded);
	for (v=0; v<v_max; v++) {
		//
		// Skip this loop iteration if v is not actually needed.
		//
		if (!bitset_test (varsneeded, v)) {
			continue;
		}
		//
		// Iterate over generators for this variable.
		// Note that there may be none left?
		//
		bitset_t *vargenerators;
		vargenerators = var_share_generators (cc->vartab, v);
		g_max = bitset_max (vargenerators);
		if (g_max = BITNUM_BAD) {
			// Apparently, there are no generators for v
			// Skip for-loop (and trouble looping to BITNUM_BAD).
			continue;
		}
		for (g=0; g<g_max; g++) {
			bitset_t *cand_generators = NULL;
			bitset_t *generatorvars;
			float cand_cost;
			//
			// Reduce the variable need.
			//
			cand_varsneeded = bitset_copy (varsneeded);
			generatorvars = gen_share_variables (v);
			bitset_subtract (cand_varsneeded, generatorvars);
			//
			// Determine the cost for generating the remainder.
			//
			if (!cnd_get_cost_total (
					cc, cand_varsneeded,
					&cand_cost, cand_generators)) {
				continue;
			}
			cand_mincost *= generator_cost (g);
			if (have_soln && (cand_cost > soln_mincost)) {
				continue;
			}
			tmp_generators = soln_generators;
			soln_generators = cand_generators;
			cand_generators = tmp_generators; // Reuse in loops
			bitset_set (soln_generators, g);
			soln_mincost = cand_mincost;
			have_soln = true;
		}
	}
	//
	// Cleanup temporary allocations.
	//
	bitset_destroy (cand_varsneeded);
	bitset_destroy (cand_generators);
	//
	// Collect results.  Return success only if we do indeed have
	// found a solution.
	//
	return have_soln;
}