expression * isl_cond_to_expr (isl_ast_expr * expr) { expression * result; enum isl_ast_op_type t = isl_ast_expr_get_op_type (expr); result = isl_expr_to_noclock_expr (isl_ast_expr_get_op_arg (expr, 1)); if (t == isl_ast_op_lt) { expression * minus_one = expression_alloc (); minus_one->type = EXPR_NUMBER; minus_one->content.number = 1; expression * new_result = expression_sub (result, minus_one); result = new_result; } return result; }
expression * isl_expr_to_noclock_expr (isl_ast_expr * expr) { expression * e = NULL; enum isl_ast_expr_type expr_t = isl_ast_expr_get_type (expr); if (expr_t == isl_ast_expr_id) { e = expression_from_identifier (isl_id_get_name ( isl_ast_expr_get_id (expr))); return e; } else if (expr_t == isl_ast_expr_int) { e = expression_from_number ( isl_val_get_num_si (isl_ast_expr_get_val (expr))); return e; } bool binary = false; enum isl_ast_op_type t = isl_ast_expr_get_op_type (expr); switch (t) { case isl_ast_op_max: e = expression_alloc (); expression_set_type (e, EXPR_MAX); binary = true; break; case isl_ast_op_min: e = expression_alloc (); expression_set_type (e, EXPR_MIN); binary = true; break; case isl_ast_op_minus: e = expression_alloc (); expression_set_type (e, EXPR_NEG); break; case isl_ast_op_add: e = expression_alloc (); expression_set_type (e, EXPR_ADD); binary = true; break; case isl_ast_op_sub: e = expression_alloc (); expression_set_type (e, EXPR_SUB); binary = true; break; case isl_ast_op_mul: e = expression_alloc (); expression_set_type (e, EXPR_MULT); binary = true; break; case isl_ast_op_div: case isl_ast_op_fdiv_q: case isl_ast_op_pdiv_q: case isl_ast_op_pdiv_r: e = expression_alloc (); expression_set_type (e, EXPR_DIV); binary = true; break; case isl_ast_op_member: case isl_ast_op_cond: case isl_ast_op_select: return e; break; case isl_ast_op_eq: e = expression_alloc (); expression_set_type (e, EXPR_EQ); binary = true; break; case isl_ast_op_le: e = expression_alloc (); expression_set_type (e, EXPR_LE); binary = true; break; case isl_ast_op_lt: e = expression_alloc (); expression_set_type (e, EXPR_LT); binary = true; break; case isl_ast_op_ge: e = expression_alloc (); expression_set_type (e, EXPR_GE); binary = true; break; case isl_ast_op_gt: e = expression_alloc (); expression_set_type (e, EXPR_GT); binary = true; break; case isl_ast_op_and: case isl_ast_op_and_then: e = expression_alloc (); expression_set_type (e, EXPR_AND); binary = true; break; case isl_ast_op_or: case isl_ast_op_or_else: e = expression_alloc (); expression_set_type (e, EXPR_OR); binary = true; break; case isl_ast_op_call: case isl_ast_op_access: case isl_ast_op_address_of: default: return e; break; } if (binary) { expression_set_left_operand (e, isl_expr_to_noclock_expr (isl_ast_expr_get_op_arg (expr, 0))); expression_set_right_operand (e, isl_expr_to_noclock_expr (isl_ast_expr_get_op_arg (expr, 1))); } else { expression_set_left_operand (e, isl_expr_to_noclock_expr (isl_ast_expr_get_op_arg (expr, 0))); } return e; }
expression_ptr cpp_from_isl::process_op(isl_ast_expr * ast_op) { int arg_count = isl_ast_expr_get_op_n_arg(ast_op); vector<expression_ptr> args; args.reserve(arg_count); for(int i = 0; i < arg_count; ++i) { auto ast_arg = isl_ast_expr_get_op_arg(ast_op, i); auto arg = process_expr(ast_arg); isl_ast_expr_free(ast_arg); args.push_back(arg); } expression_ptr expr; auto type = isl_ast_expr_get_op_type(ast_op); switch(type) { case isl_ast_op_and: expr = binop(op::logic_and, args[0], args[1]); break; case isl_ast_op_or: expr = binop(op::logic_or, args[0], args[1]); break; case isl_ast_op_max: expr = make_shared<call_expression>("max", args[0], args[1]); break; case isl_ast_op_min: expr = make_shared<call_expression>("min", args[0], args[1]); break; case isl_ast_op_minus: expr = unop(op::u_minus, args[0]); break; case isl_ast_op_add: expr = binop(op::add, args[0], args[1]); break; case isl_ast_op_sub: expr = binop(op::sub, args[0], args[1]); break; case isl_ast_op_mul: expr = binop(op::mult, args[0], args[1]); break; case isl_ast_op_div: expr = binop(op::div, args[0], args[1]); break; case isl_ast_op_eq: expr = binop(op::equal, args[0], args[1]); break; case isl_ast_op_le: expr = binop(op::lesser_or_equal, args[0], args[1]); break; case isl_ast_op_lt: expr = binop(op::lesser, args[0], args[1]); break; case isl_ast_op_ge: expr = binop(op::greater_or_equal, args[0], args[1]); break; case isl_ast_op_gt: expr = binop(op::greater, args[0], args[1]); break; case isl_ast_op_call: { auto id = dynamic_pointer_cast<id_expression>(args[0]); if (!id) throw error("Function identifier expression is not an identifier."); vector<expression_ptr> func_args(++args.begin(), args.end()); if (m_is_user_stmt && m_stmt_func) m_stmt_func(id->name, func_args, m_ctx); else expr = make_shared<call_expression>(id->name, func_args); break; } case isl_ast_op_zdiv_r: { // "Equal to zero iff the remainder on integer division is zero." expr = binop(op::rem, args[0], args[1]); break; } case isl_ast_op_pdiv_r: { //Remainder of integer division, where dividend is known to be non-negative. expr = binop(op::rem, args[0], args[1]); break; } case isl_ast_op_pdiv_q: { // Result of integer division, where dividend is known to be non-negative. expr = binop(op::div, args[0], args[1]); break; } case isl_ast_op_or_else: // not implemented case isl_ast_op_and_then: // not implemented case isl_ast_op_fdiv_q: // Not implemented // Result of integer division, rounded towards negative infinity. case isl_ast_op_cond: // Not implemented. case isl_ast_op_select: // Not implemented. case isl_ast_op_access: // Not implemented case isl_ast_op_member: // Not implemented default: throw error("Unsupported AST expression type."); } return expr; }