/* PR rtl-optimization/23454 */ /* Submitted by Matthias Klose */ /* { dg-do compile } */ /* { dg-options "-O3" } */ typedef unsigned long long int ulonglong; typedef long long int longlong; typedef unsigned int uint32; typedef unsigned int uint; typedef unsigned long int ulong; class Item { public: bool null_value; virtual longlong val_int()=0; }; typedef struct st_tree_element { struct st_tree_element *left,*right; uint32 count; } TREE_ELEMENT; typedef struct st_tree { uint offset_to_key,elements_in_tree,size_of_element,memory_limit,allocated; void *custom_arg; bool with_delete; uint flag; } TREE; class field_info { public: ulong treemem, tree_elements, empty, nulls, min_length, max_length; uint room_in_tree; bool found; TREE tree; Item *item; }; class field_ulonglong: public field_info { ulonglong min_arg, max_arg; ulonglong sum, sum_sqr; void add(); }; extern char *longlong10_to_str(longlong val,char *dst,int radix); extern void delete_tree(TREE*); extern TREE_ELEMENT *tree_insert(TREE *tree,void *custom_arg); static int compare_ulonglong(const ulonglong *s, const ulonglong *t) { return ((*s < *t) ? -1 : *s > *t ? 1 : 0); } void field_ulonglong::add() { char buff[(255*3 +1)]; longlong num = item->val_int(); uint length = (uint) (longlong10_to_str(num, buff, 10) - buff); TREE_ELEMENT *element; if (item->null_value) { nulls++; return; } if (num == 0) empty++; if (room_in_tree) { if (!(element = tree_insert(&tree, tree.custom_arg))) { room_in_tree = 0; delete_tree(&tree); } else if (element->count == 1) { room_in_tree = 0; delete_tree(&tree); } } if (!found) { found = 1; min_arg = max_arg = sum = num; sum_sqr = num * num; min_length = max_length = length; } else if (num != 0) { sum += num; sum_sqr += num * num; if (length < min_length) min_length = length; if (length > max_length) max_length = length; if (compare_ulonglong((ulonglong*) &num, &min_arg) < 0) min_arg = num; if (compare_ulonglong((ulonglong*) &num, &max_arg) > 0) max_arg = num; } }