Revision c6e113f5 tcg/tcg.c

b/tcg/tcg.c
946 946
        def = &tcg_op_defs[op];
947 947
        switch(op) {
948 948
        case INDEX_op_call:
949
            nb_args = args[-1];
950
            args -= nb_args;
951
            nb_iargs = args[0] & 0xffff;
952
            nb_oargs = args[0] >> 16;
953
            args++;
949
            {
950
                int call_flags;
954 951

  
955
            /* output args are dead */
956
            for(i = 0; i < nb_oargs; i++) {
957
                arg = args[i];
958
                dead_temps[arg] = 1;
959
            }
960
            
961
            /* globals are live (they may be used by the call) */
962
            memset(dead_temps, 0, s->nb_globals);
952
                nb_args = args[-1];
953
                args -= nb_args;
954
                nb_iargs = args[0] & 0xffff;
955
                nb_oargs = args[0] >> 16;
956
                args++;
957
                call_flags = args[nb_oargs + nb_iargs];
958

  
959
                /* pure functions can be removed if their result is not
960
                   used */
961
                if (call_flags & TCG_CALL_PURE) {
962
                    for(i = 0; i < nb_oargs; i++) {
963
                        arg = args[i];
964
                        if (!dead_temps[arg])
965
                            goto do_not_remove_call;
966
                    }
967
                    tcg_set_nop(s, gen_opc_buf + op_index, 
968
                                args - 1, nb_args);
969
                } else {
970
                do_not_remove_call:
963 971

  
964
            /* input args are live */
965
            dead_iargs = 0;
966
            for(i = 0; i < nb_iargs; i++) {
967
                arg = args[i + nb_oargs];
968
                if (dead_temps[arg]) {
969
                    dead_iargs |= (1 << i);
972
                    /* output args are dead */
973
                    for(i = 0; i < nb_oargs; i++) {
974
                        arg = args[i];
975
                        dead_temps[arg] = 1;
976
                    }
977
                    
978
                    /* globals are live (they may be used by the call) */
979
                    memset(dead_temps, 0, s->nb_globals);
980
                    
981
                    /* input args are live */
982
                    dead_iargs = 0;
983
                    for(i = 0; i < nb_iargs; i++) {
984
                        arg = args[i + nb_oargs];
985
                        if (dead_temps[arg]) {
986
                            dead_iargs |= (1 << i);
987
                        }
988
                        dead_temps[arg] = 0;
989
                    }
990
                    s->op_dead_iargs[op_index] = dead_iargs;
970 991
                }
971
                dead_temps[arg] = 0;
992
                args--;
972 993
            }
973
            s->op_dead_iargs[op_index] = dead_iargs;
974
            args--;
975 994
            break;
976 995
        case INDEX_op_set_label:
977 996
            args--;
......
1640 1659
    }
1641 1660
    
1642 1661
    /* mark dead temporaries and free the associated registers */
1643
    for(i = 0; i < nb_params; i++) {
1662
    for(i = 0; i < nb_iargs; i++) {
1644 1663
        arg = args[nb_oargs + i];
1645 1664
        if (IS_DEAD_IARG(i)) {
1646 1665
            ts = &s->temps[arg];

Also available in: Unified diff