Commit 06d5d63d by Roman Zhuykov

modulo-sched: fix bootstrap compare-debug issue

This patch removes all debug insns from DDG analysis.  It fixes bootstrap
comparison failure on powerpc64le when running with -fmodulo-sched enabled.

	* ddg.c (create_ddg_dep_from_intra_loop_link): Remove assertions.
	(create_ddg_dep_no_link): Likewise.
	(add_cross_iteration_register_deps): Move debug instruction check.
	Other minor refactoring.
	(add_intra_loop_mem_dep): Do not check for debug instructions.
	(add_inter_loop_mem_dep): Likewise.
	(build_intra_loop_deps): Likewise.
	(create_ddg): Do not include debug insns into the graph.
	* ddg.h (struct ddg): Remove num_debug field.
	* modulo-sched.c (doloop_register_get): Adjust condition.
	(res_MII): Remove DDG num_debug field usage.
	(sms_schedule_by_order): Use assertion against debug insns.
	(ps_has_conflicts): Drop debug insn check.

testsuite:

    	* gcc.c-torture/execute/pr70127-debug-sms.c: New test.
    	* gcc.dg/torture/pr87197-debug-sms.c: New test.
parent 71d69548
2020-03-27 Roman Zhuykov <zhroma@ispras.ru>
* ddg.c (create_ddg_dep_from_intra_loop_link): Remove assertions.
(create_ddg_dep_no_link): Likewise.
(add_cross_iteration_register_deps): Move debug instruction check.
Other minor refactoring.
(add_intra_loop_mem_dep): Do not check for debug instructions.
(add_inter_loop_mem_dep): Likewise.
(build_intra_loop_deps): Likewise.
(create_ddg): Do not include debug insns into the graph.
* ddg.h (struct ddg): Remove num_debug field.
* modulo-sched.c (doloop_register_get): Adjust condition.
(res_MII): Remove DDG num_debug field usage.
(sms_schedule_by_order): Use assertion against debug insns.
(ps_has_conflicts): Drop debug insn check.
2020-03-26 Richard Earnshaw <rearnsha@arm.com> 2020-03-26 Richard Earnshaw <rearnsha@arm.com>
PR target/94220 PR target/94220
......
...@@ -185,9 +185,6 @@ create_ddg_dep_from_intra_loop_link (ddg_ptr g, ddg_node_ptr src_node, ...@@ -185,9 +185,6 @@ create_ddg_dep_from_intra_loop_link (ddg_ptr g, ddg_node_ptr src_node,
else if (DEP_TYPE (link) == REG_DEP_OUTPUT) else if (DEP_TYPE (link) == REG_DEP_OUTPUT)
t = OUTPUT_DEP; t = OUTPUT_DEP;
gcc_assert (!DEBUG_INSN_P (dest_node->insn) || t == ANTI_DEP);
gcc_assert (!DEBUG_INSN_P (src_node->insn) || t == ANTI_DEP);
/* We currently choose not to create certain anti-deps edges and /* We currently choose not to create certain anti-deps edges and
compensate for that by generating reg-moves based on the life-range compensate for that by generating reg-moves based on the life-range
analysis. The anti-deps that will be deleted are the ones which analysis. The anti-deps that will be deleted are the ones which
...@@ -222,9 +219,9 @@ create_ddg_dep_from_intra_loop_link (ddg_ptr g, ddg_node_ptr src_node, ...@@ -222,9 +219,9 @@ create_ddg_dep_from_intra_loop_link (ddg_ptr g, ddg_node_ptr src_node,
} }
} }
latency = dep_cost (link); latency = dep_cost (link);
e = create_ddg_edge (src_node, dest_node, t, dt, latency, distance); e = create_ddg_edge (src_node, dest_node, t, dt, latency, distance);
add_edge_to_ddg (g, e); add_edge_to_ddg (g, e);
} }
/* The same as the above function, but it doesn't require a link parameter. */ /* The same as the above function, but it doesn't require a link parameter. */
...@@ -237,9 +234,6 @@ create_ddg_dep_no_link (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to, ...@@ -237,9 +234,6 @@ create_ddg_dep_no_link (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to,
enum reg_note dep_kind; enum reg_note dep_kind;
struct _dep _dep, *dep = &_dep; struct _dep _dep, *dep = &_dep;
gcc_assert (!DEBUG_INSN_P (to->insn) || d_t == ANTI_DEP);
gcc_assert (!DEBUG_INSN_P (from->insn) || d_t == ANTI_DEP);
if (d_t == ANTI_DEP) if (d_t == ANTI_DEP)
dep_kind = REG_DEP_ANTI; dep_kind = REG_DEP_ANTI;
else if (d_t == OUTPUT_DEP) else if (d_t == OUTPUT_DEP)
...@@ -272,16 +266,15 @@ create_ddg_dep_no_link (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to, ...@@ -272,16 +266,15 @@ create_ddg_dep_no_link (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to,
static void static void
add_cross_iteration_register_deps (ddg_ptr g, df_ref last_def) add_cross_iteration_register_deps (ddg_ptr g, df_ref last_def)
{ {
int regno = DF_REF_REGNO (last_def);
struct df_link *r_use; struct df_link *r_use;
int has_use_in_bb_p = false; int has_use_in_bb_p = false;
rtx_insn *def_insn = DF_REF_INSN (last_def); int regno = DF_REF_REGNO (last_def);
ddg_node_ptr last_def_node = get_node_of_insn (g, def_insn); ddg_node_ptr last_def_node = get_node_of_insn (g, DF_REF_INSN (last_def));
ddg_node_ptr use_node;
df_ref first_def = df_bb_regno_first_def_find (g->bb, regno); df_ref first_def = df_bb_regno_first_def_find (g->bb, regno);
ddg_node_ptr first_def_node = get_node_of_insn (g, DF_REF_INSN (first_def));
ddg_node_ptr use_node;
gcc_assert (last_def_node); gcc_assert (last_def_node && first_def && first_def_node);
gcc_assert (first_def);
if (flag_checking && DF_REF_ID (last_def) != DF_REF_ID (first_def)) if (flag_checking && DF_REF_ID (last_def) != DF_REF_ID (first_def))
{ {
...@@ -300,6 +293,9 @@ add_cross_iteration_register_deps (ddg_ptr g, df_ref last_def) ...@@ -300,6 +293,9 @@ add_cross_iteration_register_deps (ddg_ptr g, df_ref last_def)
rtx_insn *use_insn = DF_REF_INSN (r_use->ref); rtx_insn *use_insn = DF_REF_INSN (r_use->ref);
if (DEBUG_INSN_P (use_insn))
continue;
/* ??? Do not handle uses with DF_REF_IN_NOTE notes. */ /* ??? Do not handle uses with DF_REF_IN_NOTE notes. */
use_node = get_node_of_insn (g, use_insn); use_node = get_node_of_insn (g, use_insn);
gcc_assert (use_node); gcc_assert (use_node);
...@@ -310,35 +306,28 @@ add_cross_iteration_register_deps (ddg_ptr g, df_ref last_def) ...@@ -310,35 +306,28 @@ add_cross_iteration_register_deps (ddg_ptr g, df_ref last_def)
iteration. Any such upwards exposed use appears before iteration. Any such upwards exposed use appears before
the last_def def. */ the last_def def. */
create_ddg_dep_no_link (g, last_def_node, use_node, create_ddg_dep_no_link (g, last_def_node, use_node,
DEBUG_INSN_P (use_insn) ? ANTI_DEP : TRUE_DEP, TRUE_DEP, REG_DEP, 1);
REG_DEP, 1);
} }
else if (!DEBUG_INSN_P (use_insn)) else
{ {
/* Add anti deps from last_def's uses in the current iteration /* Add anti deps from last_def's uses in the current iteration
to the first def in the next iteration. We do not add ANTI to the first def in the next iteration. We do not add ANTI
dep when there is an intra-loop TRUE dep in the opposite dep when there is an intra-loop TRUE dep in the opposite
direction, but use regmoves to fix such disregarded ANTI direction, but use regmoves to fix such disregarded ANTI
deps when broken. If the first_def reaches the USE then deps when broken. If the first_def reaches the USE then
there is such a dep. */ there is such a dep.
ddg_node_ptr first_def_node = get_node_of_insn (g, Always create the edge if the use node is a branch in
DF_REF_INSN (first_def)); order to prevent the creation of reg-moves.
If the address that is being auto-inc or auto-dec in LAST_DEF
gcc_assert (first_def_node); is used in USE_INSN then do not remove the edge to make sure
reg-moves will not be created for that address. */
/* Always create the edge if the use node is a branch in if (DF_REF_ID (last_def) != DF_REF_ID (first_def)
order to prevent the creation of reg-moves. || !flag_modulo_sched_allow_regmoves
If the address that is being auto-inc or auto-dec in LAST_DEF
is used in USE_INSN then do not remove the edge to make sure
reg-moves will not be created for that address. */
if (DF_REF_ID (last_def) != DF_REF_ID (first_def)
|| !flag_modulo_sched_allow_regmoves
|| JUMP_P (use_node->insn) || JUMP_P (use_node->insn)
|| autoinc_var_is_used_p (DF_REF_INSN (last_def), use_insn) || autoinc_var_is_used_p (DF_REF_INSN (last_def), use_insn)
|| def_has_ccmode_p (DF_REF_INSN (last_def))) || def_has_ccmode_p (DF_REF_INSN (last_def)))
create_ddg_dep_no_link (g, use_node, first_def_node, ANTI_DEP, create_ddg_dep_no_link (g, use_node, first_def_node, ANTI_DEP,
REG_DEP, 1); REG_DEP, 1);
} }
} }
/* Create an inter-loop output dependence between LAST_DEF (which is the /* Create an inter-loop output dependence between LAST_DEF (which is the
...@@ -348,19 +337,11 @@ add_cross_iteration_register_deps (ddg_ptr g, df_ref last_def) ...@@ -348,19 +337,11 @@ add_cross_iteration_register_deps (ddg_ptr g, df_ref last_def)
defs starting with a true dependence to a use which can be in the defs starting with a true dependence to a use which can be in the
next iteration; followed by an anti dependence of that use to the next iteration; followed by an anti dependence of that use to the
first def (i.e. if there is a use between the two defs.) */ first def (i.e. if there is a use between the two defs.) */
if (!has_use_in_bb_p) if (!has_use_in_bb_p && DF_REF_ID (last_def) != DF_REF_ID (first_def))
{ create_ddg_dep_no_link (g, last_def_node, first_def_node,
ddg_node_ptr dest_node; OUTPUT_DEP, REG_DEP, 1);
if (DF_REF_ID (last_def) == DF_REF_ID (first_def))
return;
dest_node = get_node_of_insn (g, DF_REF_INSN (first_def));
gcc_assert (dest_node);
create_ddg_dep_no_link (g, last_def_node, dest_node,
OUTPUT_DEP, REG_DEP, 1);
}
} }
/* Build inter-loop dependencies, by looking at DF analysis backwards. */ /* Build inter-loop dependencies, by looking at DF analysis backwards. */
static void static void
build_inter_loop_deps (ddg_ptr g) build_inter_loop_deps (ddg_ptr g)
...@@ -417,13 +398,9 @@ add_intra_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to) ...@@ -417,13 +398,9 @@ add_intra_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to)
if (mem_write_insn_p (from->insn)) if (mem_write_insn_p (from->insn))
{ {
if (mem_read_insn_p (to->insn)) if (mem_read_insn_p (to->insn))
create_ddg_dep_no_link (g, from, to, create_ddg_dep_no_link (g, from, to, TRUE_DEP, MEM_DEP, 0);
DEBUG_INSN_P (to->insn)
? ANTI_DEP : TRUE_DEP, MEM_DEP, 0);
else else
create_ddg_dep_no_link (g, from, to, create_ddg_dep_no_link (g, from, to, OUTPUT_DEP, MEM_DEP, 0);
DEBUG_INSN_P (to->insn)
? ANTI_DEP : OUTPUT_DEP, MEM_DEP, 0);
} }
else if (!mem_read_insn_p (to->insn)) else if (!mem_read_insn_p (to->insn))
create_ddg_dep_no_link (g, from, to, ANTI_DEP, MEM_DEP, 0); create_ddg_dep_no_link (g, from, to, ANTI_DEP, MEM_DEP, 0);
...@@ -441,13 +418,9 @@ add_inter_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to) ...@@ -441,13 +418,9 @@ add_inter_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to)
if (mem_write_insn_p (from->insn)) if (mem_write_insn_p (from->insn))
{ {
if (mem_read_insn_p (to->insn)) if (mem_read_insn_p (to->insn))
create_ddg_dep_no_link (g, from, to, create_ddg_dep_no_link (g, from, to, TRUE_DEP, MEM_DEP, 1);
DEBUG_INSN_P (to->insn)
? ANTI_DEP : TRUE_DEP, MEM_DEP, 1);
else if (from->cuid != to->cuid) else if (from->cuid != to->cuid)
create_ddg_dep_no_link (g, from, to, create_ddg_dep_no_link (g, from, to, OUTPUT_DEP, MEM_DEP, 1);
DEBUG_INSN_P (to->insn)
? ANTI_DEP : OUTPUT_DEP, MEM_DEP, 1);
} }
else else
{ {
...@@ -456,13 +429,9 @@ add_inter_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to) ...@@ -456,13 +429,9 @@ add_inter_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to)
else if (from->cuid != to->cuid) else if (from->cuid != to->cuid)
{ {
create_ddg_dep_no_link (g, from, to, ANTI_DEP, MEM_DEP, 1); create_ddg_dep_no_link (g, from, to, ANTI_DEP, MEM_DEP, 1);
if (DEBUG_INSN_P (from->insn) || DEBUG_INSN_P (to->insn)) create_ddg_dep_no_link (g, to, from, TRUE_DEP, MEM_DEP, 1);
create_ddg_dep_no_link (g, to, from, ANTI_DEP, MEM_DEP, 1);
else
create_ddg_dep_no_link (g, to, from, TRUE_DEP, MEM_DEP, 1);
} }
} }
} }
/* Perform intra-block Data Dependency analysis and connect the nodes in /* Perform intra-block Data Dependency analysis and connect the nodes in
...@@ -491,20 +460,10 @@ build_intra_loop_deps (ddg_ptr g) ...@@ -491,20 +460,10 @@ build_intra_loop_deps (ddg_ptr g)
sd_iterator_def sd_it; sd_iterator_def sd_it;
dep_t dep; dep_t dep;
if (! INSN_P (dest_node->insn))
continue;
FOR_EACH_DEP (dest_node->insn, SD_LIST_BACK, sd_it, dep) FOR_EACH_DEP (dest_node->insn, SD_LIST_BACK, sd_it, dep)
{ {
rtx_insn *src_insn = DEP_PRO (dep); rtx_insn *src_insn = DEP_PRO (dep);
ddg_node_ptr src_node; ddg_node_ptr src_node = get_node_of_insn (g, src_insn);
/* Don't add dependencies on debug insns to non-debug insns
to avoid codegen differences between -g and -g0. */
if (DEBUG_INSN_P (src_insn) && !DEBUG_INSN_P (dest_node->insn))
continue;
src_node = get_node_of_insn (g, src_insn);
if (!src_node) if (!src_node)
continue; continue;
...@@ -521,8 +480,7 @@ build_intra_loop_deps (ddg_ptr g) ...@@ -521,8 +480,7 @@ build_intra_loop_deps (ddg_ptr g)
for (j = 0; j <= i; j++) for (j = 0; j <= i; j++)
{ {
ddg_node_ptr j_node = &g->nodes[j]; ddg_node_ptr j_node = &g->nodes[j];
if (DEBUG_INSN_P (j_node->insn))
continue;
if (mem_access_insn_p (j_node->insn)) if (mem_access_insn_p (j_node->insn))
{ {
/* Don't bother calculating inter-loop dep if an intra-loop dep /* Don't bother calculating inter-loop dep if an intra-loop dep
...@@ -573,23 +531,21 @@ create_ddg (basic_block bb, int closing_branch_deps) ...@@ -573,23 +531,21 @@ create_ddg (basic_block bb, int closing_branch_deps)
for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb)); for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn)) insn = NEXT_INSN (insn))
{ {
if (! INSN_P (insn) || GET_CODE (PATTERN (insn)) == USE) if (!INSN_P (insn) || GET_CODE (PATTERN (insn)) == USE)
continue; continue;
if (DEBUG_INSN_P (insn)) if (NONDEBUG_INSN_P (insn))
g->num_debug++;
else
{ {
if (mem_read_insn_p (insn)) if (mem_read_insn_p (insn))
g->num_loads++; g->num_loads++;
if (mem_write_insn_p (insn)) if (mem_write_insn_p (insn))
g->num_stores++; g->num_stores++;
num_nodes++;
} }
num_nodes++;
} }
/* There is nothing to do for this BB. */ /* There is nothing to do for this BB. */
if ((num_nodes - g->num_debug) <= 1) if (num_nodes <= 1)
{ {
free (g); free (g);
return NULL; return NULL;
...@@ -604,38 +560,39 @@ create_ddg (basic_block bb, int closing_branch_deps) ...@@ -604,38 +560,39 @@ create_ddg (basic_block bb, int closing_branch_deps)
for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb)); for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn)) insn = NEXT_INSN (insn))
{ {
if (! INSN_P (insn)) if (LABEL_P (insn) || NOTE_INSN_BASIC_BLOCK_P (insn))
{ continue;
if (! first_note && NOTE_P (insn)
&& NOTE_KIND (insn) != NOTE_INSN_BASIC_BLOCK) if (!first_note && (INSN_P (insn) || NOTE_P (insn)))
first_note = insn; first_note = insn;
continue;
} if (!INSN_P (insn) || GET_CODE (PATTERN (insn)) == USE)
continue;
if (JUMP_P (insn)) if (JUMP_P (insn))
{ {
gcc_assert (!g->closing_branch); gcc_assert (!g->closing_branch);
g->closing_branch = &g->nodes[i]; g->closing_branch = &g->nodes[i];
} }
else if (GET_CODE (PATTERN (insn)) == USE)
if (NONDEBUG_INSN_P (insn))
{ {
if (! first_note) g->nodes[i].cuid = i;
first_note = insn; g->nodes[i].successors = sbitmap_alloc (num_nodes);
continue; bitmap_clear (g->nodes[i].successors);
} g->nodes[i].predecessors = sbitmap_alloc (num_nodes);
bitmap_clear (g->nodes[i].predecessors);
g->nodes[i].cuid = i; gcc_checking_assert (first_note);
g->nodes[i].successors = sbitmap_alloc (num_nodes); g->nodes[i].first_note = first_note;
bitmap_clear (g->nodes[i].successors);
g->nodes[i].predecessors = sbitmap_alloc (num_nodes);
bitmap_clear (g->nodes[i].predecessors);
g->nodes[i].first_note = (first_note ? first_note : insn);
g->nodes[i].aux.count = -1; g->nodes[i].aux.count = -1;
g->nodes[i].max_dist = XCNEWVEC (int, num_nodes); g->nodes[i].max_dist = XCNEWVEC (int, num_nodes);
for (j = 0; j < num_nodes; j++) for (j = 0; j < num_nodes; j++)
g->nodes[i].max_dist[j] = -1; g->nodes[i].max_dist[j] = -1;
g->nodes[i++].insn = insn; g->nodes[i++].insn = insn;
}
first_note = NULL; first_note = NULL;
} }
......
...@@ -116,9 +116,6 @@ struct ddg ...@@ -116,9 +116,6 @@ struct ddg
int num_loads; int num_loads;
int num_stores; int num_stores;
/* Number of debug instructions in the BB. */
int num_debug;
/* This array holds the nodes in the graph; it is indexed by the node /* This array holds the nodes in the graph; it is indexed by the node
cuid, which follows the order of the instructions in the BB. */ cuid, which follows the order of the instructions in the BB. */
ddg_node_ptr nodes; ddg_node_ptr nodes;
......
...@@ -369,7 +369,7 @@ doloop_register_get (rtx_insn *head, rtx_insn *tail) ...@@ -369,7 +369,7 @@ doloop_register_get (rtx_insn *head, rtx_insn *tail)
: prev_nondebug_insn (tail)); : prev_nondebug_insn (tail));
for (insn = head; insn != first_insn_not_to_check; insn = NEXT_INSN (insn)) for (insn = head; insn != first_insn_not_to_check; insn = NEXT_INSN (insn))
if (!DEBUG_INSN_P (insn) && reg_mentioned_p (reg, insn)) if (NONDEBUG_INSN_P (insn) && reg_mentioned_p (reg, insn))
{ {
if (dump_file) if (dump_file)
{ {
...@@ -428,7 +428,7 @@ res_MII (ddg_ptr g) ...@@ -428,7 +428,7 @@ res_MII (ddg_ptr g)
if (targetm.sched.sms_res_mii) if (targetm.sched.sms_res_mii)
return targetm.sched.sms_res_mii (g); return targetm.sched.sms_res_mii (g);
return ((g->num_nodes - g->num_debug) / issue_rate); return g->num_nodes / issue_rate;
} }
...@@ -2152,11 +2152,7 @@ sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order) ...@@ -2152,11 +2152,7 @@ sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order)
ddg_node_ptr u_node = &ps->g->nodes[u]; ddg_node_ptr u_node = &ps->g->nodes[u];
rtx_insn *insn = u_node->insn; rtx_insn *insn = u_node->insn;
if (!NONDEBUG_INSN_P (insn)) gcc_checking_assert (NONDEBUG_INSN_P (insn));
{
bitmap_clear_bit (tobe_scheduled, u);
continue;
}
if (bitmap_bit_p (sched_nodes, u)) if (bitmap_bit_p (sched_nodes, u))
continue; continue;
...@@ -3158,9 +3154,6 @@ ps_has_conflicts (partial_schedule_ptr ps, int from, int to) ...@@ -3158,9 +3154,6 @@ ps_has_conflicts (partial_schedule_ptr ps, int from, int to)
{ {
rtx_insn *insn = ps_rtl_insn (ps, crr_insn->id); rtx_insn *insn = ps_rtl_insn (ps, crr_insn->id);
if (!NONDEBUG_INSN_P (insn))
continue;
/* Check if there is room for the current insn. */ /* Check if there is room for the current insn. */
if (!can_issue_more || state_dead_lock_p (curr_state)) if (!can_issue_more || state_dead_lock_p (curr_state))
return true; return true;
......
2020-03-26 Marek Polacek <polacek@redhat.com> 2020-03-27 Roman Zhuykov <zhroma@ispras.ru>
* gcc.c-torture/execute/pr70127-debug-sms.c: New test.
* gcc.dg/torture/pr87197-debug-sms.c: New test.
2020-03-27 Marek Polacek <polacek@redhat.com>
PR c++/94336 - template keyword accepted before destructor names. PR c++/94336 - template keyword accepted before destructor names.
* g++.dg/template/template-keyword2.C: New test. * g++.dg/template/template-keyword2.C: New test.
......
/* { dg-additional-options "-fcompare-debug -fmodulo-sched" } */
struct S { int f; signed int g : 2; } a[1], c = {5, 1}, d;
short b;
__attribute__((noinline, noclone)) void
foo (int x)
{
if (x != 1)
__builtin_abort ();
}
int
main ()
{
while (b++ <= 0)
{
struct S e = {1, 1};
d = e = a[0] = c;
}
foo (a[0].g);
return 0;
}
/* { dg-do compile } */
/* { dg-additional-options "-fcompare-debug -fmodulo-sched --param sms-min-sc=1" } */
int a, c, e, f, g;
void
h (int i)
{
a = i;
}
void
j (char *i, long k)
{
while (k--)
c = *i++;
}
void
l (unsigned char *i, long k)
{
unsigned char *b = i + k;
while (i < b)
{
h (*i);
i++;
}
}
void
m ()
{
while (e)
{
float d = g;
l ((char *) &d, sizeof (g));
if (f)
j ((char *) &d, sizeof (g));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment