📄 nloop.c
字号:
build1 (INDIRECT_REF, ip->base_type, ip->loc_ptr_temp)); /* FIXME: see stor_layout */ ip->step_temp = size_in_bytes (ip->base_type); temp = TYPE_DOMAIN (array_type); /* pointer to first array entry to look at */ start_ptr = build1 (ADDR_EXPR, ptr_type, ip->start_exp); mark_addressable (ip->start_exp); ip->start_temp = ip->down_flag ? fold (build (PLUS_EXPR, ptr_type, start_ptr, fold (build (MULT_EXPR, integer_type_node, ip->step_temp, fold (build (MINUS_EXPR, integer_type_node, TYPE_MAX_VALUE (temp), TYPE_MIN_VALUE (temp))))))) : start_ptr; } else { tree array_length = convert (integer_type_node, build_component_ref (ip->start_exp, var_length_id)); tree array_type = TREE_TYPE (TREE_CHAIN ( TYPE_FIELDS (TREE_TYPE (ip->start_exp)))); tree array_data_ptr = build_component_ref (ip->start_exp, var_data_id); tree ptr_type; if (TREE_CODE (TREE_TYPE (array_type)) == BOOLEAN_TYPE) { error ("Can't iterate through array of BOOL"); firstp->error_flag = 1; return firstp->error_flag; } /* create pointer temporary */ ip->base_type = TREE_TYPE (array_type); ptr_type = build_pointer_type (ip->base_type); ip->loc_ptr_temp = build_temporary_variable ("loc_ptr_temp", ptr_type); /* declare the user's iteration variable in the loop's scope, as an expression, to be passed to build_component_ref later */ save_expr_under_name (ip->user_var, build1 (INDIRECT_REF, ip->base_type, ip->loc_ptr_temp)); /* FIXME: see stor_layout */ ip->step_temp = size_in_bytes (ip->base_type); /* pointer to first array entry to look at */ start_ptr = build1 (ADDR_EXPR, ptr_type, array_data_ptr); mark_addressable (array_data_ptr); ip->start_temp = ip->down_flag ? fold (build (PLUS_EXPR, ptr_type, start_ptr, fold (build (MULT_EXPR, integer_type_node, ip->step_temp, fold (build (MINUS_EXPR, integer_type_node, array_length, integer_one_node)))))) : start_ptr; } default: ; } } return firstp->error_flag;}/* * Initialize the hidden iteration-control variables, * and the user's explicit loop variable. */static intinitialize_iter_var (){ ITERATOR *firstp = loop_stack->iter_list, *ip; for (ip = firstp; ip != NULL; ip = ip->next) { switch (ip->itype) { case DO_FOREVER: case DO_WHILE: break; case DO_STEP: case DO_RANGE: { tree count = fold (build (PLUS_EXPR, ip->iter_type, integer_one_node, fold (build (TRUNC_DIV_EXPR, ip->iter_type, convert (ip->iter_type, fold (build (MINUS_EXPR, ip->iter_type, ip->down_flag ? ip->start_temp : ip->end_temp, ip->down_flag ? ip->end_temp : ip->start_temp))), ip->step_temp)))); /* initialize the loop's hidden counter variable */ expand_expr_stmt ( build_chill_modify_expr (ip->iter_var, count)); /* initialize user's variable */ expand_expr_stmt ( build_chill_modify_expr (ip->user_var, ip->start_temp)); } break; case DO_POWERSET: break; case DO_LOC: { tree array_type = TREE_TYPE (ip->start_exp); tree array_length = fold (build (TRUNC_DIV_EXPR, integer_type_node, size_in_bytes (array_type), size_in_bytes (TREE_TYPE (array_type)))); expand_expr_stmt ( build_chill_modify_expr (ip->iter_var, array_length)); goto do_loc_common; } case DO_LOC_VARYING: expand_expr_stmt ( build_chill_modify_expr (ip->iter_var, convert (integer_type_node, build_component_ref (ip->start_exp, var_length_id)))); do_loc_common: expand_expr_stmt ( build_chill_modify_expr (ip->loc_ptr_temp, ip->start_temp)); break; default: ; } } return firstp->error_flag;}/* Generate code to skip the whole loop, if start expression not * <= end expression (or >= for DOWN loops). This comparison must * *NOT* be done in unsigned mode, or it will fail. * Also, skip processing an empty VARYING array. */static intmaybe_skip_loop (){ ITERATOR *firstp = loop_stack->iter_list, *ip; for (ip = firstp; ip != NULL; ip = ip->next) { switch (ip->itype) { case DO_STEP: expand_start_cond ( build (ip->down_flag ? GE_EXPR : LE_EXPR, TREE_TYPE (ip->start_exp), ip->start_exp, ip->end_exp), 0); break; case DO_LOC_VARYING: { tree array_length = convert (integer_type_node, build_component_ref (ip->start_exp, var_length_id)); expand_start_cond ( build (NE_EXPR, TREE_TYPE (array_length), array_length, integer_zero_node), 0); break; } default: break; } } return 0;} /* * Check at the top of the loop for a termination */static inttop_loop_end_check (){ ITERATOR *firstp = loop_stack->iter_list, *ip; /* now, exit the loop if the condition isn't TRUE. */ if (firstp->condition) { expand_exit_loop_if_false (0, chill_truthvalue_conversion (firstp->condition)); } for (ip = firstp; ip != NULL; ip = ip->next) { switch (ip->itype) { case DO_FOREVER: case DO_WHILE: case DO_STEP: case DO_RANGE: break; case DO_POWERSET: { tree temp1; char *func_name; if (ip->down_flag) func_name = "__flsetclrpowerset"; else func_name = "__ffsetclrpowerset"; temp1 = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (ip->powerset_temp))); expand_exit_loop_if_false (0, build_chill_function_call (lookup_name (get_identifier (func_name)), tree_cons (NULL_TREE, force_addr_of (ip->powerset_temp), tree_cons (NULL_TREE, powersetlen (ip->powerset_temp), tree_cons (NULL_TREE, force_addr_of (ip->user_var), tree_cons (NULL_TREE, size_in_bytes (TREE_TYPE (ip->user_var)), tree_cons (NULL_TREE, convert (long_integer_type_node, temp1), NULL_TREE))))))); } break; case DO_LOC: case DO_LOC_VARYING: break; default: ; } } return firstp->error_flag;}/* * Check generated temporaries for loop's end */static intbottom_loop_end_check (){ ITERATOR *firstp = loop_stack->iter_list, *ip; emit_line_note (input_filename, lineno); /* now, generate code to check each loop counter for termination */ for (ip = firstp; ip != NULL; ip = ip->next) { switch (ip->itype) { case DO_FOREVER: case DO_WHILE: break; case DO_STEP: case DO_RANGE: case DO_LOC: case DO_LOC_VARYING: /* decrement iteration counter by one */ chill_expand_assignment (ip->iter_var, MINUS_EXPR, integer_one_node); /* exit if it's zero */ expand_exit_loop_if_false (0, build (NE_EXPR, boolean_type_node, ip->iter_var, integer_zero_node)); break; case DO_POWERSET: break; default: ; } } return firstp->error_flag;}/* * increment the loop-control variables. */static intincrement_temps (){ ITERATOR *firstp = loop_stack->iter_list, *ip; for (ip = firstp; ip != NULL; ip = ip->next) { switch (ip->itype) { case DO_FOREVER: case DO_WHILE: break; case DO_STEP: case DO_RANGE: { tree delta = fold (build (ip->down_flag ? MINUS_EXPR : PLUS_EXPR, TREE_TYPE (ip->user_var), ip->user_var, ip->step_temp)); expand_expr_stmt ( build_chill_modify_expr (ip->user_var, delta)); } break; case DO_LOC: case DO_LOC_VARYING: /* This statement uses the C semantics, so that the pointer is actually incremented by the length of the object pointed to. */#if 1 expand_expr_stmt ( build_modify_expr (ip->loc_ptr_temp, ip->down_flag ? MINUS_EXPR : PLUS_EXPR, integer_one_node));#else { enum tree_code op = ip->down_flag ? MINUS_EXPR : PLUS_EXPR; tree el_type = TREE_TYPE (TREE_TYPE (ip->loc_ptr_temp)); chill_expand_assignment (ip->loc_ptr_temp, NOP_EXPR, build (op, TREE_TYPE (ip->loc_ptr_temp), ip->loc_ptr_temp, size_in_bytes (el_type))); }#endif break; case DO_POWERSET: break; default: ; } } return firstp->error_flag;}/* * Generate a (temporary) unique identifier_node of * the form "__tmp_%s_%d" */treeget_unique_identifier (lead) char *lead;{ char idbuf [256]; static int idcount = 0; sprintf (idbuf, "__tmp_%s_%d", lead ? lead : "", idcount++); return get_identifier (idbuf);}/* * build a temporary variable, given its NAME and TYPE. * The name will have a number appended to assure uniqueness. * return its DECL node. */static treebuild_temporary_variable (name, type) char *name; tree type;{ return decl_temp1 (get_unique_identifier (name), type, 0, NULL_TREE, 0, 0);}/* * If the given expression isn't a constant, build a temp for it * and evaluate the expression into the temp. Return the tree * representing either the original constant expression or the * temp which now contains the expression's value. */static treemaybe_make_for_temp (exp, temp_name, exp_type) tree exp; char *temp_name; tree exp_type;{ tree result = exp; if (exp != NULL_TREE) { /* if exp isn't constant, create a temporary for its value */ if (TREE_CONSTANT (exp)) { /* FIXME: assure that TREE_TYPE (result) == ip->exp_type */ result = convert (exp_type, exp); } else { /* build temp, assign the value */ result = decl_temp1 (get_unique_identifier (temp_name), exp_type, 0, exp, 0, 0); } } return result;}/* * Adapt the C unsigned_type function to CHILL - we need to * account for any CHILL-specific integer types here. So far, * the 16-bit integer type is the only one. */static treechill_unsigned_type (type) tree type;{ extern tree chill_unsigned_type_node; tree type1 = TYPE_MAIN_VARIANT (type); if (type1 == chill_integer_type_node) return chill_unsigned_type_node; else return unsigned_type (type);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -