yann@251: Hi, yann@251: yann@251: The attached patch makes sure that we create smaller object code for yann@251: simple switch statements. We just make sure to flatten the switch yann@251: statement into an if-else chain, basically. yann@251: yann@251: This fixes a size-regression as compared to gcc-3.4, as can be seen yann@251: below. yann@251: yann@251: 2007-04-15 Bernhard Fischer <..> yann@251: yann@251: * stmt.c (expand_case): Do not create a complex binary tree when yann@251: optimizing for size but rather use the simple ordered list. yann@251: (emit_case_nodes): do not emit jumps to the default_label when yann@251: optimizing for size. yann@251: yann@251: Not regtested so far. yann@251: Comments? yann@251: yann@251: Attached is the test switch.c mentioned below. yann@251: yann@251: $ for i in 2.95 3.3 3.4 4.0 4.1 4.2.orig-HEAD 4.3.orig-HEAD 4.3-HEAD;do yann@251: gcc-$i -DCHAIN -Os -o switch-CHAIN-$i.o -c switch.c ;done yann@251: $ for i in 2.95 3.3 3.4 4.0 4.1 4.2.orig-HEAD 4.3.orig-HEAD 4.3-HEAD;do yann@251: gcc-$i -UCHAIN -Os -o switch-$i.o -c switch.c ;done yann@251: yann@251: $ size switch-*.o yann@251: text data bss dec hex filename yann@251: 169 0 0 169 a9 switch-2.95.o yann@251: 115 0 0 115 73 switch-3.3.o yann@251: 103 0 0 103 67 switch-3.4.o yann@251: 124 0 0 124 7c switch-4.0.o yann@251: 124 0 0 124 7c switch-4.1.o yann@251: 124 0 0 124 7c switch-4.2.orig-HEAD.o yann@251: 95 0 0 95 5f switch-4.3-HEAD.o yann@251: 124 0 0 124 7c switch-4.3.orig-HEAD.o yann@251: 166 0 0 166 a6 switch-CHAIN-2.95.o yann@251: 111 0 0 111 6f switch-CHAIN-3.3.o yann@251: 95 0 0 95 5f switch-CHAIN-3.4.o yann@251: 95 0 0 95 5f switch-CHAIN-4.0.o yann@251: 95 0 0 95 5f switch-CHAIN-4.1.o yann@251: 95 0 0 95 5f switch-CHAIN-4.2.orig-HEAD.o yann@251: 95 0 0 95 5f switch-CHAIN-4.3-HEAD.o yann@251: 95 0 0 95 5f switch-CHAIN-4.3.orig-HEAD.o yann@251: yann@251: yann@251: Content-Type: text/x-diff; charset=us-ascii yann@251: Content-Disposition: attachment; filename="gcc-4.3.gcc-flatten-switch-stmt.00.diff" yann@251: yann@251: Index: gcc-4.2.0/gcc/stmt.c yann@251: =================================================================== yann@251: --- gcc-4.2.0.orig/gcc/stmt.c (revision 123843) yann@251: +++ gcc-4.2.0/gcc/stmt.c (working copy) yann@251: @@ -2517,7 +2517,11 @@ expand_case (tree exp) yann@251: use_cost_table yann@251: = (TREE_CODE (orig_type) != ENUMERAL_TYPE yann@251: && estimate_case_costs (case_list)); yann@251: - balance_case_nodes (&case_list, NULL); yann@251: + /* When optimizing for size, we want a straight list to avoid yann@251: + jumps as much as possible. This basically creates an if-else yann@251: + chain. */ yann@251: + if (!optimize_size) yann@251: + balance_case_nodes (&case_list, NULL); yann@251: emit_case_nodes (index, case_list, default_label, index_type); yann@251: emit_jump (default_label); yann@251: } yann@251: @@ -3075,6 +3079,7 @@ emit_case_nodes (rtx index, case_node_pt yann@251: { yann@251: if (!node_has_low_bound (node, index_type)) yann@251: { yann@251: + if (!optimize_size) /* don't jl to the .default_label. */ yann@251: emit_cmp_and_jump_insns (index, yann@251: convert_modes yann@251: (mode, imode, yann@251: yann@251: yann@251: Content-Type: text/x-csrc; charset=us-ascii yann@251: Content-Disposition: attachment; filename="switch.c" yann@251: yann@251: int yann@251: commutative_tree_code (int code) yann@251: { yann@251: #define CASE(val, ret) case val:/* __asm__("# val="#val ",ret="#ret);*/ return ret; yann@251: #ifndef CHAIN yann@251: switch (code) yann@251: { yann@251: # if 1 yann@251: CASE(1,3) yann@251: CASE(3,2) yann@251: CASE(5,8) yann@251: CASE(7,1) yann@251: CASE(33,4) yann@251: CASE(44,9) yann@251: CASE(55,10) yann@251: CASE(66,-1) yann@251: CASE(77,99) yann@251: CASE(666,0) yann@251: # else yann@251: case 1: yann@251: return 3; yann@251: case 3: yann@251: return 2; yann@251: case 5: yann@251: return 8; yann@251: case 7: yann@251: return 1; yann@251: case 33: yann@251: return 4; yann@251: case 44: yann@251: return 9; yann@251: case 55: yann@251: return 10; yann@251: case 66: yann@251: return -1; yann@251: case 77: yann@251: return 99; yann@251: case 666: yann@251: return 0; yann@251: # endif yann@251: default: yann@251: break; yann@251: } yann@251: return 4711; yann@251: yann@251: #else yann@251: if (code == 1) yann@251: return 3; yann@251: else if (code == 3) yann@251: return 2; yann@251: else if (code == 5) yann@251: return 8; yann@251: else if (code == 7) yann@251: return 1; yann@251: else if (code == 33) yann@251: return 4; yann@251: else if (code == 44) yann@251: return 9; yann@251: else if (code == 55) yann@251: return 10; yann@251: else if (code == 66) yann@251: return -1; yann@251: else if (code == 77) yann@251: return 99; yann@251: else if (code == 666) yann@251: return 0; yann@251: else yann@251: return 4711; yann@251: #endif yann@251: } yann@251: yann@251: yann@251: --AhhlLboLdkugWU4S-- yann@251: