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; }
void abstract_expression( const predicatest &predicates, exprt &expr, const namespacet &ns) { if(expr.type().id()!=ID_bool) throw "abstract_expression expects expression of type Boolean"; simplify(expr, ns); if(is_valid(expr, ns)) { // If expr is valid, we can abstract it as 'true' expr.make_true(); } else if(is_unsatisfiable(expr, ns)) { // If expr is unsatisfiable, we can abstract it as 'false' expr.make_false(); } else if(expr.id()==ID_and || expr.id()==ID_or || expr.id()==ID_implies || expr.id()==ID_xor) { Forall_operands(it, expr) abstract_expression(predicates, *it, ns); } else if(expr.id()==ID_not) { assert(expr.operands().size()==1); abstract_expression(predicates, expr.op0(), ns); // remove double negation if(expr.op0().id()==ID_not && expr.op0().operands().size()==1) { exprt tmp; tmp.swap(expr.op0().op0()); expr.swap(tmp); } } else if(expr.id()==ID_if) { assert(expr.operands().size()==3); Forall_operands(it, expr) abstract_expression(predicates, *it, ns); exprt true_expr(ID_and, bool_typet()); true_expr.copy_to_operands(expr.op0(), expr.op1()); exprt false_expr(ID_and, bool_typet()); false_expr.copy_to_operands(gen_not(expr.op0()), expr.op2()); exprt or_expr(ID_or, bool_typet()); or_expr.move_to_operands(true_expr, false_expr); expr.swap(or_expr); } else if(expr.id()==ID_equal || expr.id()==ID_notequal) { if(expr.operands().size()!=2) throw expr.id_string()+" takes two operands"; // Is it equality on Booleans? if(expr.op0().type().id()==ID_bool && expr.op1().type().id()==ID_bool) { // leave it in Forall_operands(it, expr) abstract_expression(predicates, *it, ns); } else // other types, make it a predicate { if(has_non_boolean_if(expr)) { lift_if(expr); abstract_expression(predicates, expr, ns); } else make_it_a_predicate(predicates, expr, ns); } } else if(expr.is_constant()) { // leave it as is } else if(has_non_boolean_if(expr)) { lift_if(expr); abstract_expression(predicates, expr, ns); } else { make_it_a_predicate(predicates, expr, ns); } }
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; }
void rw_sett::read_write_rec( const exprt &expr, bool r, bool w, const std::string &suffix, const guardt &guard) { if(expr.id()=="symbol" && !expr.has_operands()) { const symbol_exprt &symbol_expr=to_symbol_expr(expr); const symbolt *symbol; if(!ns.lookup(symbol_expr.get_identifier(), symbol)) { if(!symbol->static_lifetime /*&& expr.type().id()=="pointer"*/) { return; // ignore for now } if(symbol->name=="c::__ESBMC_alloc" || symbol->name=="c::__ESBMC_alloc_size" || symbol->name=="c::stdin" || symbol->name=="c::stdout" || symbol->name=="c::stderr" || symbol->name=="c::sys_nerr") { return; // ignore for now } } irep_idt object=id2string(symbol_expr.get_identifier())+suffix; entryt &entry=entries[object]; entry.object=object; entry.r=entry.r || r; entry.w=entry.w || w; entry.guard = migrate_expr_back(guard.as_expr()); } else if(expr.id()=="member") { assert(expr.operands().size()==1); const std::string &component_name=expr.component_name().as_string(); read_write_rec(expr.op0(), r, w, "."+component_name+suffix, guard); } else if(expr.id()=="index") { // we don't distinguish the array elements for now assert(expr.operands().size()==2); std::string tmp; tmp = integer2string(binary2integer(expr.op1().value().as_string(), true),10); read_write_rec(expr.op0(), r, w, "["+suffix+tmp+"]", guard); read(expr.op1(), guard); } else if(expr.id()=="dereference") { assert(expr.operands().size()==1); read(expr.op0(), guard); exprt tmp(expr.op0()); expr2tc tmp_expr; migrate_expr(tmp, tmp_expr); dereference(target, tmp_expr, ns, value_sets); tmp = migrate_expr_back(tmp_expr); read_write_rec(tmp, r, w, suffix, guard); } else if(expr.is_address_of() || expr.id()=="implicit_address_of") { assert(expr.operands().size()==1); } else if(expr.id()=="if") { assert(expr.operands().size()==3); read(expr.op0(), guard); guardt true_guard(guard); expr2tc tmp_expr; migrate_expr(expr.op0(), tmp_expr); true_guard.add(tmp_expr); read_write_rec(expr.op1(), r, w, suffix, true_guard); guardt false_guard(guard); migrate_expr(gen_not(expr.op0()), tmp_expr); false_guard.add(tmp_expr); read_write_rec(expr.op2(), r, w, suffix, false_guard); } else { forall_operands(it, expr) read_write_rec(*it, r, w, suffix, guard); } }