Example #1
0
LLVMValueRef gen_or_assign(struct node *ast)
{
	LLVMValueRef result;

	result = gen_or(ast);
	check_store(result, lvalue(ast->one));

	return result;
}
Example #2
0
static bool special_case_operator(compile_t* c, ast_t* ast,
  LLVMValueRef *value, bool short_circuit, bool native128)
{
  AST_GET_CHILDREN(ast, positional, named, postfix);
  AST_GET_CHILDREN(postfix, left, method);

  ast_t* right = ast_child(positional);
  const char* name = ast_name(method);
  *value = NULL;

  if(name == c->str_add)
    *value = gen_add(c, left, right);
  else if(name == c->str_sub)
    *value = gen_sub(c, left, right);
  else if((name == c->str_mul) && native128)
    *value = gen_mul(c, left, right);
  else if((name == c->str_div) && native128)
    *value = gen_div(c, left, right);
  else if((name == c->str_mod) && native128)
    *value = gen_mod(c, left, right);
  else if(name == c->str_neg)
    *value = gen_neg(c, left);
  else if((name == c->str_and) && short_circuit)
    *value = gen_and_sc(c, left, right);
  else if((name == c->str_or) && short_circuit)
    *value = gen_or_sc(c, left, right);
  else if((name == c->str_and) && !short_circuit)
    *value = gen_and(c, left, right);
  else if((name == c->str_or) && !short_circuit)
    *value = gen_or(c, left, right);
  else if(name == c->str_xor)
    *value = gen_xor(c, left, right);
  else if(name == c->str_not)
    *value = gen_not(c, left);
  else if(name == c->str_shl)
    *value = gen_shl(c, left, right);
  else if(name == c->str_shr)
    *value = gen_shr(c, left, right);
  else if(name == c->str_eq)
    *value = gen_eq(c, left, right);
  else if(name == c->str_ne)
    *value = gen_ne(c, left, right);
  else if(name == c->str_lt)
    *value = gen_lt(c, left, right);
  else if(name == c->str_le)
    *value = gen_le(c, left, right);
  else if(name == c->str_ge)
    *value = gen_ge(c, left, right);
  else if(name == c->str_gt)
    *value = gen_gt(c, left, right);
  else
    return false;

  return true;
}
Example #3
0
void predicate_image_satqe(
    message_handlert &message_handler,
    const std::vector<exprt> &deref_curr_predicates,
    const std::vector<exprt> &deref_next_predicates,
    const std::list<exprt> &constraints,
    symex_target_equationt &equation,
    const namespacet &ns,
    abstract_transition_relationt &
    abstract_transition_relation)
{
  const std::set<unsigned> &from_predicates=
    abstract_transition_relation.from_predicates;

  const std::set<unsigned> &to_predicates=
    abstract_transition_relation.to_predicates;

  assert(to_predicates.size()!=0);

  // create SAT solver object
  satqe_satcheckt satqe;
  bv_pointerst solver(satqe);

  solver.unbounded_array=boolbvt::U_ALL;
  solver.set_message_handler(message_handler);

  // turn equation into CNF
  equation.convert(solver);

  for(std::set<unsigned>::const_iterator
      it=from_predicates.begin();
      it!=from_predicates.end();
      it++)
  {
    unsigned i=*it;

    literalt li=make_pos(ns, solver, deref_curr_predicates[i]);
    satqe.quantify(li);
  }

  for(std::set<unsigned>::const_iterator
      it=to_predicates.begin();
      it!=to_predicates.end();
      it++)
  {
    unsigned i=*it;

    literalt lo=make_pos(ns, solver, deref_next_predicates[i]);
    satqe.quantify(lo);
  }

  // we want cubes
  cube_sett cube_set;
  satqe.set_cube_set(cube_set);

  // solve it
  switch(solver.dec_solve())
  {
    case decision_proceduret::D_UNSATISFIABLE:
      // OK, this is what we expect
      break;

    default:
      throw "unexpected result from satqe.solve()";
  }

  message_handler.print(9, "Generated "+
      i2string(cube_set.no_insertions())+" cube(s)");

#if 0
  std::cout << cube_set;
#endif

  exprt constraint_cubes_disj = true_exprt();

  // convert the cubes into constraints
  for(cubest::star_mapt::const_iterator
      it=cube_set.star_map.begin();
      it!=cube_set.star_map.end();
      it++)
  {
    for(cubest::bitssett::const_iterator
        it2=it->second.begin();
        it2!=it->second.end();
        it2++)
    {
      exprt constraint_cube_conj;

      unsigned bit=0;
      unsigned i=0;

      /* Assume it->first[i] is true iff the i-th predicate is in the
         cube. Assume predicates are stored in it->first in the order of
         from_predicates followed by to_predicates. Scan it->first and
         from/to_predicates in parallel to get the cube. */

      for(std::set<unsigned>::const_iterator
          it3=from_predicates.begin();
          it3!=from_predicates.end();
          it3++)
      {
        unsigned id=*it3;

        if(!it->first[i])
        {
          constraint_cube_conj.operands().push_back(exprt());
          exprt &e=constraint_cube_conj.operands().back();
          e=exprt(ID_predicate_symbol, typet(ID_bool));
          e.set(ID_identifier, id);

          if(!(*it2)[bit]) 
            e.make_not();

          bit++;
#if 0
          std::cout << "C: " << from_expr(ns, "", e) << std::endl;
#endif
        }

        i++;
      }

      for(std::set<unsigned>::const_iterator
          it3=to_predicates.begin();
          it3!=to_predicates.end();
          it3++)
      {
        unsigned id=*it3;

        if(!it->first[i])
        {
          constraint_cube_conj.operands().push_back(exprt());
          exprt &e=constraint_cube_conj.operands().back();
          e=exprt(ID_predicate_next_symbol, typet(ID_bool));
          e.set(ID_identifier, id);

          if(!(*it2)[bit]) 
            e.make_not();

          bit++;
#if 0
          std::cout << "C: " << from_expr(ns, "", e) << std::endl;
#endif
        }

        i++;
      }

      assert(i==it->first.size());

      /* Convert the cube into a conjunct. */
      gen_and(constraint_cube_conj);

      /* Add the conjunct in disjunction to previous cubes. */
      if(constraint_cubes_disj.is_true())
        constraint_cubes_disj=constraint_cube_conj;
      else
        constraint_cubes_disj=gen_or(
            constraint_cubes_disj,
            constraint_cube_conj);      
    }
  }

  /* Add the cubes to the contraints of the abstract transition
     relation. Warning: we may want to remove old constrains. */

  abstract_transition_relation.constraints.push_back(constraint_cubes_disj);
}
Example #4
0
bool transition_refinert::check_assignment_transition(
  const predicatest &predicates,
  const abstract_stept &abstract_state_from,
  const abstract_stept &abstract_state_to,
  unsigned passive_id)
{
  // Note that we take "thread_nr" from "abstract_state_from", not from "abstract_state_to", as the "from" state determines which thread is executing
  const unsigned active_id=abstract_state_from.thread_nr;
  const unsigned num_threads=abstract_state_from.thread_states.size();

  std::vector<predicatest> active_passive_preds(num_threads, predicatest());
  std::vector<std::vector<exprt> > predicates_wp(num_threads,
      std::vector<exprt>());
  std::list<exprt> constraints;

  for(unsigned int t=0; t < num_threads; ++t)
  {
    if(active_id!=t &&
        passive_id < num_threads &&
        t!=passive_id)
      continue;

    for(unsigned int i = 0; i < predicates.size(); i++)
    {
      active_passive_preds[t].lookup(active_id==t?
          predicates[i] :
          predicatest::make_expr_passive(predicates[i], concrete_model.ns, t));
    }
    assert(active_passive_preds[t].size() == predicates.size());

    std::list<exprt> constraints_t;
    build_equation(
      concrete_model.ns,
      active_passive_preds[t],
      abstract_state_from.pc->code.concrete_pc,
      constraints_t,
      predicates_wp[t]);

    constraints.splice(constraints.end(), constraints_t);
  }

  // create SAT solver object
  satcheckt satcheck;
  bv_pointerst solver(concrete_model.ns, satcheck);
  solver.unbounded_array=boolbvt::U_NONE;
  
  // convert constraints
  for(std::list<exprt>::const_iterator
      it=constraints.begin();
      it!=constraints.end();
      it++)
  {
    exprt tmp(*it);
    solver.set_to_true(tmp);
  }

  abstract_transition_relationt &abstract_transition_relation=
    abstract_state_from.pc->code.get_transition_relation();

  std::vector<std::vector<literalt> >
    predicate_variables_from(num_threads, std::vector<literalt>(predicates.size(), literalt())),
    predicate_variables_to(num_threads, std::vector<literalt>(predicates.size(), literalt()));
    
  bvt assumptions;

  std::vector<abstract_stept::thread_to_predicate_valuest::const_iterator>
    from_predicates(num_threads, abstract_state_from.thread_states.end()),
    to_predicates(num_threads, abstract_state_to.thread_states.end());
  for(unsigned int t=0; t < num_threads; ++t)
  {
    from_predicates[t]=abstract_state_from.thread_states.find(t);
    assert(abstract_state_from.thread_states.end() != from_predicates[t]);
    to_predicates[t]=abstract_state_to.thread_states.find(t);
    assert(abstract_state_to.thread_states.end() != to_predicates[t]);
  }

  // we use all predicates in order to also find constraints over invalid
  // from/to states
  for(unsigned i=0; i < predicates.size(); ++i)
  {
    assert(abstract_transition_relation.to_predicates.find(i) !=
        abstract_transition_relation.to_predicates.end() ||
        abstract_transition_relation.from_predicates.find(i) !=
        abstract_transition_relation.from_predicates.end() ||
        (from_predicates[active_id]->second[i] ==
         to_predicates[active_id]->second[i] &&
         (passive_id >= num_threads ||
          from_predicates[passive_id]->second[i] ==
          to_predicates[passive_id]->second[i])));

    for(unsigned int t=0; t < num_threads; ++t)
    {
      if(active_id!=t &&
          passive_id < num_threads &&
          t!=passive_id)
        continue;
      // not sure whether we really want the following check
      if(active_id!=t &&
        active_passive_preds[t][i]==predicates[i])
        continue;

      literalt li=make_pos(concrete_model.ns, solver, active_passive_preds[t][i]);
      predicate_variables_from[t][i]=li;

      assumptions.push_back(li.cond_negation(
            !from_predicates[t]->second[i]));

      #ifdef DEBUG
      const std::string predname=
        (active_id==t?"P#":"PP"+i2string(t)+"#")+i2string(i);
      std::cerr
        << "F: " << predname << ": "
        << (from_predicates[t]->second[i]?"":"!") << "("
        << from_expr(concrete_model.ns, "", active_passive_preds[t][i]) << ")" << std::endl;
      #endif

      literalt lo=make_pos(concrete_model.ns, solver, predicates_wp[t][i]);
      predicate_variables_to[t][i]=lo;

      assumptions.push_back(lo.cond_negation(
            !to_predicates[t]->second[i]));

      #ifdef DEBUG
      std::cerr
        << "T: " << predname << ": "
        << (to_predicates[t]->second[i]?"":"!") << "("
        << from_expr(concrete_model.ns, "", predicates_wp[t][i]) << ")" << std::endl;
      #endif
    }
  }
  
  satcheck.set_assumptions(assumptions);

  // solve it
  if(is_satisfiable(solver))
  {
    print(9, "Transition is OK");
    #ifdef DEBUG
    std::cout << "********\n";
    solver.print_assignment(std::cout);
    std::cout << "********\n";
    #endif
    return false; // ok
  }
  
  if(passive_id >= num_threads)
  {
    const std::string opt="Spurious assignment transitions requiring more than 1 passive thread";
    assert(stats.find(opt)!=stats.end());
    ++(stats[opt].val);
    return false; // can't do anything
  }

  print(9, "Assignment transition is spurious, refining");

  exprt constraint;

  for(unsigned i=0; i < predicates.size(); ++i)
  {
    if(satcheck.is_in_conflict(predicate_variables_from[active_id][i]))
    {
      constraint.operands().push_back(exprt());
      exprt &e=constraint.operands().back();
      e=exprt(ID_predicate_symbol, bool_typet());
      e.set(ID_identifier, i);
      if(from_predicates[active_id]->second[i]) e.make_not();
#ifdef DEBUG
      std::cout << "C-F: " << from_expr(concrete_model.ns, "", e) << std::endl;
#endif
    }

    if(passive_id!=active_id &&
        satcheck.is_in_conflict(predicate_variables_from[passive_id][i]))
    {
      constraint.operands().push_back(exprt());
      exprt &e=constraint.operands().back();
      e=exprt(ID_predicate_passive_symbol, bool_typet());
      e.set(ID_identifier, i);
      if(from_predicates[passive_id]->second[i]) e.make_not();
#ifdef DEBUG
      std::cout << "C-F: " << from_expr(concrete_model.ns, "", e) << std::endl;
#endif
    }

    if(satcheck.is_in_conflict(predicate_variables_to[active_id][i]))
    {
      constraint.operands().push_back(exprt());
      exprt &e=constraint.operands().back();
      e=exprt(ID_predicate_next_symbol, bool_typet());
      e.set(ID_identifier, i);
      if(to_predicates[active_id]->second[i]) e.make_not();
#ifdef DEBUG
      std::cout << "C-T: " << from_expr(concrete_model.ns, "", e) << std::endl;
#endif
    }

    if(passive_id!=active_id &&
        satcheck.is_in_conflict(predicate_variables_to[passive_id][i]))
    {
      constraint.operands().push_back(exprt());
      exprt &e=constraint.operands().back();
      e=exprt(ID_next_symbol, bool_typet());
      e.operands().resize(1);
      e.op0()=exprt(ID_predicate_passive_symbol, bool_typet());
      e.op0().set(ID_identifier, i);
      if(to_predicates[passive_id]->second[i]) e.make_not();
#ifdef DEBUG
      std::cout << "C-T: " << from_expr(concrete_model.ns, "", e) << std::endl;
#endif
    }
  }
#ifdef DEBUG
  ::std::cerr << "Spurious in thread " << passive_id << " (active: " << abstract_state_from.thread_nr << "): " << ::std::endl;
  ::std::cerr << abstract_state_from << ::std::endl;
  goto_programt tmp;
  tmp.output_instruction(concrete_model.ns, "", std::cerr, abstract_state_from.pc->code.concrete_pc);
  ::std::cerr << abstract_state_to << ::std::endl;
#endif

  if(constraint.operands().empty())
    constraint.make_false(); // this can happen if
  else                       // the invariants are inconsistent
    gen_or(constraint);
  
  abstract_transition_relation.constraints.push_back(constraint);

  // spurious!
  return true;
}
Example #5
0
static bool special_case_operator(compile_t* c, ast_t* ast,
  LLVMValueRef *value, bool short_circuit, bool native128)
{
  AST_GET_CHILDREN(ast, postfix, positional, named, question);
  AST_GET_CHILDREN(postfix, left, method);

  ast_t* right = ast_child(positional);
  const char* name = ast_name(method);
  bool special_case = true;
  *value = NULL;

  codegen_debugloc(c, ast);

  if(name == c->str_add)
    *value = gen_add(c, left, right, true);
  else if(name == c->str_sub)
    *value = gen_sub(c, left, right, true);
  else if((name == c->str_mul) && native128)
    *value = gen_mul(c, left, right, true);
  else if((name == c->str_div) && native128)
    *value = gen_div(c, left, right, true);
  else if((name == c->str_rem) && native128)
    *value = gen_rem(c, left, right, true);
  else if(name == c->str_neg)
    *value = gen_neg(c, left, true);
  else if(name == c->str_add_unsafe)
    *value = gen_add(c, left, right, false);
  else if(name == c->str_sub_unsafe)
    *value = gen_sub(c, left, right, false);
  else if((name == c->str_mul_unsafe) && native128)
    *value = gen_mul(c, left, right, false);
  else if((name == c->str_div_unsafe) && native128)
    *value = gen_div(c, left, right, false);
  else if((name == c->str_rem_unsafe) && native128)
    *value = gen_rem(c, left, right, false);
  else if(name == c->str_neg_unsafe)
    *value = gen_neg(c, left, false);
  else if((name == c->str_and) && short_circuit)
    *value = gen_and_sc(c, left, right);
  else if((name == c->str_or) && short_circuit)
    *value = gen_or_sc(c, left, right);
  else if((name == c->str_and) && !short_circuit)
    *value = gen_and(c, left, right);
  else if((name == c->str_or) && !short_circuit)
    *value = gen_or(c, left, right);
  else if(name == c->str_xor)
    *value = gen_xor(c, left, right);
  else if(name == c->str_not)
    *value = gen_not(c, left);
  else if(name == c->str_shl)
    *value = gen_shl(c, left, right, true);
  else if(name == c->str_shr)
    *value = gen_shr(c, left, right, true);
  else if(name == c->str_shl_unsafe)
    *value = gen_shl(c, left, right, false);
  else if(name == c->str_shr_unsafe)
    *value = gen_shr(c, left, right, false);
  else if(name == c->str_eq)
    *value = gen_eq(c, left, right, true);
  else if(name == c->str_ne)
    *value = gen_ne(c, left, right, true);
  else if(name == c->str_lt)
    *value = gen_lt(c, left, right, true);
  else if(name == c->str_le)
    *value = gen_le(c, left, right, true);
  else if(name == c->str_ge)
    *value = gen_ge(c, left, right, true);
  else if(name == c->str_gt)
    *value = gen_gt(c, left, right, true);
  else if(name == c->str_eq_unsafe)
    *value = gen_eq(c, left, right, false);
  else if(name == c->str_ne_unsafe)
    *value = gen_ne(c, left, right, false);
  else if(name == c->str_lt_unsafe)
    *value = gen_lt(c, left, right, false);
  else if(name == c->str_le_unsafe)
    *value = gen_le(c, left, right, false);
  else if(name == c->str_ge_unsafe)
    *value = gen_ge(c, left, right, false);
  else if(name == c->str_gt_unsafe)
    *value = gen_gt(c, left, right, false);
  else
    special_case = false;

  codegen_debugloc(c, NULL);
  return special_case;
}