Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
630c79be
Commit
630c79be
authored
Sep 06, 2000
by
Bernd Schmidt
Committed by
Bernd Schmidt
Sep 06, 2000
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Changes in cse.c/loop.c cost calculations
From-SVN: r36192
parent
39a10a29
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
261 additions
and
98 deletions
+261
-98
gcc/ChangeLog
+35
-0
gcc/Makefile.in
+2
-1
gcc/config/i386/i386.h
+2
-10
gcc/config/sh/sh-protos.h
+1
-0
gcc/config/sh/sh.c
+19
-0
gcc/config/sh/sh.h
+8
-20
gcc/cse.c
+129
-48
gcc/loop.c
+65
-19
No files found.
gcc/ChangeLog
View file @
630c79be
2000-09-06 Bernd Schmidt <bernds@redhat.co.uk>
* Makefile.in (cse.o): Depend on $(BASIC_BLOCK_H).
* cse.c: Include "basic-block.h".
(struct table_elt): New field REGCOST.
(CHEAP_REG): Delete macro.
(COST): Return 0 for REGs.
(approx_reg_cost_1, approx_reg_cost, preferrable): New functions.
(notreg_cost): Return 0 for appropriate SUBREGs.
(COSTS_N_INSNS): Return N * 2.
(rtx_cost): Return 0 for REGs, and use cost of nested rtx for cheap
SUBREGs.
(CHEAPER): Use new function preferrable.
(insert): Initialize REGCOST member.
(find_best_addr): Use approx_reg_cost for estimation of register
usage.
(cse_insn): Likewise.
* loop.c (iv_add_mult_cost): New function.
(add_cost, shift_cost, mult_cost): Delete variables.
(init_loop): Don't initialize add_cost; reduce copy_cost by half.
(strength_reduce): Use iv_add_mult_cost instead of fixed add_cost.
Make code that detects autoinc opportunities slightly less optimistic.
(simplify_giv_expr): If expression contains other reg that is also a
giv, only increment benefit if this is the only use of that reg.
(consec_sets_giv): Take that change into account.
(combine_givs): Slightly more verbose output.
* i386.h (RTX_COSTS): For MULT, return true cost of multiplication,
not the cost of an equivalent shift.
* sh-protos.h (addsubcosts): Declare.
* sh.c (addsubcosts): New function.
* sh.h (CONST_COSTS): If CONST_OK_FOR_I, then return 0.
(RTX_COSTS): Tweak. Use addsubcosts.
(ADDRESS_COST): Return higher cost for reg+reg addressing.
2000-09-06 Geoff Keating <geoffk@cygnus.com>
2000-09-06 Geoff Keating <geoffk@cygnus.com>
* config/rs6000/rs6000.c (validate_condition_mode): New function.
* config/rs6000/rs6000.c (validate_condition_mode): New function.
...
...
gcc/Makefile.in
View file @
630c79be
...
@@ -1322,7 +1322,8 @@ simplify-rtx.o : simplify-rtx.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) \
...
@@ -1322,7 +1322,8 @@ simplify-rtx.o : simplify-rtx.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) \
hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h
\
hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h
\
output.h function.h cselib.h ggc.h $(OBSTACK_H)
output.h function.h cselib.h ggc.h $(OBSTACK_H)
cse.o
:
cse.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h flags.h
\
cse.o
:
cse.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h flags.h
\
real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h output.h function.h $(GGC_H)
real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h output.h function.h
\
$(BASIC_BLOCK_H) $(GGC_H)
gcse.o
:
gcse.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h
\
gcse.o
:
gcse.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h
\
flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H)
\
flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H)
\
function.h output.h toplev.h
function.h output.h toplev.h
...
...
gcc/config/i386/i386.h
View file @
630c79be
...
@@ -1978,22 +1978,14 @@ while (0)
...
@@ -1978,22 +1978,14 @@ while (0)
unsigned HOST_WIDE_INT value = INTVAL (XEXP (X, 1)); \
unsigned HOST_WIDE_INT value = INTVAL (XEXP (X, 1)); \
int nbits = 0; \
int nbits = 0; \
\
\
if (value == 2) \
TOPLEVEL_COSTS_N_INSNS (ix86_cost->add); \
if (value == 4 || value == 8) \
TOPLEVEL_COSTS_N_INSNS (ix86_cost->lea); \
\
while (value != 0) \
while (value != 0) \
{ \
{ \
nbits++; \
nbits++; \
value >>= 1; \
value >>= 1; \
} \
} \
\
\
if (nbits == 1) \
TOPLEVEL_COSTS_N_INSNS (ix86_cost->mult_init \
TOPLEVEL_COSTS_N_INSNS (ix86_cost->shift_const); \
+ nbits * ix86_cost->mult_bit); \
else \
TOPLEVEL_COSTS_N_INSNS (ix86_cost->mult_init \
+ nbits * ix86_cost->mult_bit); \
} \
} \
else
/* This is arbitrary */
\
else
/* This is arbitrary */
\
TOPLEVEL_COSTS_N_INSNS (ix86_cost->mult_init \
TOPLEVEL_COSTS_N_INSNS (ix86_cost->mult_init \
...
...
gcc/config/sh/sh-protos.h
View file @
630c79be
...
@@ -54,6 +54,7 @@ extern int prepare_move_operands PARAMS ((rtx[], enum machine_mode mode));
...
@@ -54,6 +54,7 @@ extern int prepare_move_operands PARAMS ((rtx[], enum machine_mode mode));
extern
void
from_compare
PARAMS
((
rtx
*
,
int
));
extern
void
from_compare
PARAMS
((
rtx
*
,
int
));
extern
int
shift_insns_rtx
PARAMS
((
rtx
));
extern
int
shift_insns_rtx
PARAMS
((
rtx
));
extern
int
shiftcosts
PARAMS
((
rtx
));
extern
int
shiftcosts
PARAMS
((
rtx
));
extern
int
addsubcosts
PARAMS
((
rtx
));
extern
int
andcosts
PARAMS
((
rtx
));
extern
int
andcosts
PARAMS
((
rtx
));
extern
int
multcosts
PARAMS
((
rtx
));
extern
int
multcosts
PARAMS
((
rtx
));
extern
void
gen_ashift
PARAMS
((
int
,
int
,
rtx
));
extern
void
gen_ashift
PARAMS
((
int
,
int
,
rtx
));
...
...
gcc/config/sh/sh.c
View file @
630c79be
...
@@ -1012,6 +1012,25 @@ andcosts (x)
...
@@ -1012,6 +1012,25 @@ andcosts (x)
return
3
;
return
3
;
}
}
/* Return the cost of an addition or a subtraction. */
int
addsubcosts
(
x
)
rtx
x
;
{
/* Adding a register is a single cycle insn. */
if
(
GET_CODE
(
XEXP
(
x
,
1
))
!=
CONST_INT
)
return
1
;
/* Likewise for small constants. */
if
(
CONST_OK_FOR_I
(
INTVAL
(
XEXP
(
x
,
1
))))
return
1
;
/* Any other constant requires a 2 cycle pc-relative load plus an
addition. */
return
3
;
}
/* Return the cost of a multiply. */
/* Return the cost of a multiply. */
int
int
multcosts
(
x
)
multcosts
(
x
)
...
...
gcc/config/sh/sh.h
View file @
630c79be
...
@@ -1651,15 +1651,12 @@ extern int current_function_anonymous_args;
...
@@ -1651,15 +1651,12 @@ extern int current_function_anonymous_args;
#define Pmode SImode
#define Pmode SImode
#define FUNCTION_MODE Pmode
#define FUNCTION_MODE Pmode
/* The relative costs of various types of constants. Note that cse.c defines
/* The relative costs of various types of constants. */
REG = 1, SUBREG = 2, any node = (2 + sum of subnodes). */
#define CONST_COSTS(RTX, CODE, OUTER_CODE) \
#define CONST_COSTS(RTX, CODE, OUTER_CODE) \
case CONST_INT: \
case CONST_INT: \
if (
INTVAL (RTX) == 0)
\
if (
CONST_OK_FOR_I (INTVAL (RTX)))
\
return 0; \
return 0; \
else if (CONST_OK_FOR_I (INTVAL (RTX))) \
return 1; \
else if (((OUTER_CODE) == AND || (OUTER_CODE) == IOR || (OUTER_CODE) == XOR) \
else if (((OUTER_CODE) == AND || (OUTER_CODE) == IOR || (OUTER_CODE) == XOR) \
&& CONST_OK_FOR_L (INTVAL (RTX))) \
&& CONST_OK_FOR_L (INTVAL (RTX))) \
return 1; \
return 1; \
...
@@ -1674,10 +1671,7 @@ extern int current_function_anonymous_args;
...
@@ -1674,10 +1671,7 @@ extern int current_function_anonymous_args;
#define RTX_COSTS(X, CODE, OUTER_CODE) \
#define RTX_COSTS(X, CODE, OUTER_CODE) \
case PLUS: \
case PLUS: \
return (COSTS_N_INSNS (1) \
return COSTS_N_INSNS (addsubcosts (X)); \
+ rtx_cost (XEXP ((X), 0), PLUS) \
+ (rtx_equal_p (XEXP ((X), 0), XEXP ((X), 1))\
? 0 : rtx_cost (XEXP ((X), 1), PLUS)));\
case AND: \
case AND: \
return COSTS_N_INSNS (andcosts (X)); \
return COSTS_N_INSNS (andcosts (X)); \
case MULT: \
case MULT: \
...
@@ -1685,13 +1679,7 @@ extern int current_function_anonymous_args;
...
@@ -1685,13 +1679,7 @@ extern int current_function_anonymous_args;
case ASHIFT: \
case ASHIFT: \
case ASHIFTRT: \
case ASHIFTRT: \
case LSHIFTRT: \
case LSHIFTRT: \
/* Add one extra unit for the matching constraint. \
return COSTS_N_INSNS (shiftcosts (X)); \
Otherwise loop strength reduction would think that\
a shift with different sourc and destination is \
as cheap as adding a constant to a register. */
\
return (COSTS_N_INSNS (shiftcosts (X)) \
+ rtx_cost (XEXP ((X), 0), (CODE)) \
+ 1); \
case DIV: \
case DIV: \
case UDIV: \
case UDIV: \
case MOD: \
case MOD: \
...
@@ -1768,11 +1756,11 @@ while (0)
...
@@ -1768,11 +1756,11 @@ while (0)
&& nonpic_symbol_mentioned_p (X))
&& nonpic_symbol_mentioned_p (X))
/* Compute the cost of an address. For the SH, all valid addresses are
/* Compute the cost of an address. For the SH, all valid addresses are
the same cost. */
the same cost. Use a slightly higher cost for reg + reg addressing,
/* ??? Perhaps we should make reg+reg addresses have higher cost because
since it increases pressure on r0. */
they add to register pressure on r0. */
#define ADDRESS_COST(RTX) 1
#define ADDRESS_COST(X) (GET_CODE (X) == PLUS && ! CONSTANT_P (XEXP (X, 1)) \
? 1 : 0)
/* Compute extra cost of moving data between one register class
/* Compute extra cost of moving data between one register class
and another. */
and another. */
...
...
gcc/cse.c
View file @
630c79be
This diff is collapsed.
Click to expand it.
gcc/loop.c
View file @
630c79be
...
@@ -312,6 +312,7 @@ static void try_swap_copy_prop PARAMS ((const struct loop *, rtx,
...
@@ -312,6 +312,7 @@ static void try_swap_copy_prop PARAMS ((const struct loop *, rtx,
static
int
replace_label
PARAMS
((
rtx
*
,
void
*
));
static
int
replace_label
PARAMS
((
rtx
*
,
void
*
));
static
rtx
check_insn_for_givs
PARAMS
((
struct
loop
*
,
rtx
,
int
,
int
));
static
rtx
check_insn_for_givs
PARAMS
((
struct
loop
*
,
rtx
,
int
,
int
));
static
rtx
check_insn_for_bivs
PARAMS
((
struct
loop
*
,
rtx
,
int
,
int
));
static
rtx
check_insn_for_bivs
PARAMS
((
struct
loop
*
,
rtx
,
int
,
int
));
static
int
iv_add_mult_cost
PARAMS
((
rtx
,
rtx
,
rtx
,
rtx
));
static
void
loop_dump_aux
PARAMS
((
const
struct
loop
*
,
FILE
*
,
int
));
static
void
loop_dump_aux
PARAMS
((
const
struct
loop
*
,
FILE
*
,
int
));
void
debug_loop
PARAMS
((
const
struct
loop
*
));
void
debug_loop
PARAMS
((
const
struct
loop
*
));
...
@@ -341,13 +342,6 @@ static int compute_luids PARAMS ((rtx, rtx, int));
...
@@ -341,13 +342,6 @@ static int compute_luids PARAMS ((rtx, rtx, int));
static
int
biv_elimination_giv_has_0_offset
PARAMS
((
struct
induction
*
,
static
int
biv_elimination_giv_has_0_offset
PARAMS
((
struct
induction
*
,
struct
induction
*
,
rtx
));
struct
induction
*
,
rtx
));
/* Relative gain of eliminating various kinds of operations. */
static
int
add_cost
;
#if 0
static int shift_cost;
static int mult_cost;
#endif
/* Benefit penalty, if a giv is not replaceable, i.e. must emit an insn to
/* Benefit penalty, if a giv is not replaceable, i.e. must emit an insn to
copy the value of the strength reduced giv to its original register. */
copy the value of the strength reduced giv to its original register. */
static
int
copy_cost
;
static
int
copy_cost
;
...
@@ -361,15 +355,9 @@ init_loop ()
...
@@ -361,15 +355,9 @@ init_loop ()
char
*
free_point
=
(
char
*
)
oballoc
(
1
);
char
*
free_point
=
(
char
*
)
oballoc
(
1
);
rtx
reg
=
gen_rtx_REG
(
word_mode
,
LAST_VIRTUAL_REGISTER
+
1
);
rtx
reg
=
gen_rtx_REG
(
word_mode
,
LAST_VIRTUAL_REGISTER
+
1
);
add_cost
=
rtx_cost
(
gen_rtx_PLUS
(
word_mode
,
reg
,
reg
),
SET
);
reg_address_cost
=
address_cost
(
reg
,
SImode
);
reg_address_cost
=
address_cost
(
reg
,
SImode
);
/* We multiply by 2 to reconcile the difference in scale between
copy_cost
=
2
;
these two ways of computing costs. Otherwise the cost of a copy
will be far less than the cost of an add. */
copy_cost
=
2
*
2
;
/* Free the objects we just allocated. */
/* Free the objects we just allocated. */
obfree
(
free_point
);
obfree
(
free_point
);
...
@@ -3825,6 +3813,7 @@ strength_reduce (loop, insn_count, flags)
...
@@ -3825,6 +3813,7 @@ strength_reduce (loop, insn_count, flags)
rtx
loop_start
=
loop
->
start
;
rtx
loop_start
=
loop
->
start
;
rtx
loop_end
=
loop
->
end
;
rtx
loop_end
=
loop
->
end
;
rtx
loop_scan_start
=
loop
->
scan_start
;
rtx
loop_scan_start
=
loop
->
scan_start
;
rtx
test_reg
=
gen_rtx_REG
(
word_mode
,
LAST_VIRTUAL_REGISTER
+
1
);
VARRAY_INT_INIT
(
reg_iv_type
,
max_reg_before_loop
,
"reg_iv_type"
);
VARRAY_INT_INIT
(
reg_iv_type
,
max_reg_before_loop
,
"reg_iv_type"
);
VARRAY_GENERIC_PTR_INIT
(
reg_iv_info
,
max_reg_before_loop
,
"reg_iv_info"
);
VARRAY_GENERIC_PTR_INIT
(
reg_iv_info
,
max_reg_before_loop
,
"reg_iv_info"
);
...
@@ -4436,11 +4425,15 @@ strength_reduce (loop, insn_count, flags)
...
@@ -4436,11 +4425,15 @@ strength_reduce (loop, insn_count, flags)
for
(
v
=
bl
->
giv
;
v
;
v
=
v
->
next_iv
)
for
(
v
=
bl
->
giv
;
v
;
v
=
v
->
next_iv
)
{
{
struct
induction
*
tv
;
struct
induction
*
tv
;
int
add_cost
;
if
(
v
->
ignore
||
v
->
same
)
if
(
v
->
ignore
||
v
->
same
)
continue
;
continue
;
benefit
=
v
->
benefit
;
benefit
=
v
->
benefit
;
PUT_MODE
(
test_reg
,
v
->
mode
);
add_cost
=
iv_add_mult_cost
(
bl
->
biv
->
add_val
,
v
->
mult_val
,
test_reg
,
test_reg
);
/* Reduce benefit if not replaceable, since we will insert
/* Reduce benefit if not replaceable, since we will insert
a move-insn to replace the insn that calculates this giv.
a move-insn to replace the insn that calculates this giv.
...
@@ -4457,7 +4450,14 @@ strength_reduce (loop, insn_count, flags)
...
@@ -4457,7 +4450,14 @@ strength_reduce (loop, insn_count, flags)
benefit
-=
copy_cost
;
benefit
-=
copy_cost
;
/* Decrease the benefit to count the add-insns that we will
/* Decrease the benefit to count the add-insns that we will
insert to increment the reduced reg for the giv. */
insert to increment the reduced reg for the giv.
??? This can overestimate the run-time cost of the additional
insns, e.g. if there are multiple basic blocks that increment
the biv, but only one of these blocks is executed during each
iteration. There is no good way to detect cases like this with
the current structure of the loop optimizer.
This code is more accurate for determining code size than
run-time benefits. */
benefit
-=
add_cost
*
bl
->
biv_count
;
benefit
-=
add_cost
*
bl
->
biv_count
;
/* Decide whether to strength-reduce this giv or to leave the code
/* Decide whether to strength-reduce this giv or to leave the code
...
@@ -4469,6 +4469,10 @@ strength_reduce (loop, insn_count, flags)
...
@@ -4469,6 +4469,10 @@ strength_reduce (loop, insn_count, flags)
new add insns; if so, increase BENEFIT (undo the subtraction of
new add insns; if so, increase BENEFIT (undo the subtraction of
add_cost that was done above). */
add_cost that was done above). */
if
(
v
->
giv_type
==
DEST_ADDR
if
(
v
->
giv_type
==
DEST_ADDR
/* Increasing the benefit is risky, since this is only a guess.
Avoid increasing register pressure in cases where there would
be no other benefit from reducing this giv. */
&&
benefit
>
0
&&
GET_CODE
(
v
->
mult_val
)
==
CONST_INT
)
&&
GET_CODE
(
v
->
mult_val
)
==
CONST_INT
)
{
{
if
(
HAVE_POST_INCREMENT
if
(
HAVE_POST_INCREMENT
...
@@ -6439,7 +6443,20 @@ simplify_giv_expr (loop, x, benefit)
...
@@ -6439,7 +6443,20 @@ simplify_giv_expr (loop, x, benefit)
/* Form expression from giv and add benefit. Ensure this giv
/* Form expression from giv and add benefit. Ensure this giv
can derive another and subtract any needed adjustment if so. */
can derive another and subtract any needed adjustment if so. */
*
benefit
+=
v
->
benefit
;
/* Increasing the benefit here is risky. The only case in which it
is arguably correct is if this is the only use of V. In other
cases, this will artificially inflate the benefit of the current
giv, and lead to suboptimal code. Thus, it is disabled, since
potentially not reducing an only marginally beneficial giv is
less harmful than reducing many givs that are not really
beneficial. */
{
rtx
single_use
=
VARRAY_RTX
(
reg_single_usage
,
REGNO
(
x
));
if
(
single_use
&&
single_use
!=
const0_rtx
)
*
benefit
+=
v
->
benefit
;
}
if
(
v
->
cant_derive
)
if
(
v
->
cant_derive
)
return
0
;
return
0
;
...
@@ -6683,7 +6700,7 @@ consec_sets_giv (loop, first_benefit, p, src_reg, dest_reg,
...
@@ -6683,7 +6700,7 @@ consec_sets_giv (loop, first_benefit, p, src_reg, dest_reg,
count
--
;
count
--
;
v
->
mult_val
=
*
mult_val
;
v
->
mult_val
=
*
mult_val
;
v
->
add_val
=
*
add_val
;
v
->
add_val
=
*
add_val
;
v
->
benefit
=
benefit
;
v
->
benefit
+
=
benefit
;
}
}
else
if
(
code
!=
NOTE
)
else
if
(
code
!=
NOTE
)
{
{
...
@@ -7098,8 +7115,9 @@ restart:
...
@@ -7098,8 +7115,9 @@ restart:
if
(
loop_dump_stream
)
if
(
loop_dump_stream
)
fprintf
(
loop_dump_stream
,
fprintf
(
loop_dump_stream
,
"giv at %d combined with giv at %d
\n
"
,
"giv at %d combined with giv at %d; new benefit %d + %d, lifetime %d
\n
"
,
INSN_UID
(
g2
->
insn
),
INSN_UID
(
g1
->
insn
));
INSN_UID
(
g2
->
insn
),
INSN_UID
(
g1
->
insn
),
g1
->
benefit
,
g1_add_benefit
,
g1
->
lifetime
);
}
}
}
}
...
@@ -7613,6 +7631,34 @@ emit_iv_add_mult (b, m, a, reg, insert_before)
...
@@ -7613,6 +7631,34 @@ emit_iv_add_mult (b, m, a, reg, insert_before)
&&
GET_CODE
(
SET_DEST
(
seq
))
==
REG
)
&&
GET_CODE
(
SET_DEST
(
seq
))
==
REG
)
record_base_value
(
REGNO
(
SET_DEST
(
seq
)),
SET_SRC
(
seq
),
0
);
record_base_value
(
REGNO
(
SET_DEST
(
seq
)),
SET_SRC
(
seq
),
0
);
}
}
/* Similar to emit_iv_add_mult, but compute cost rather than emitting
insns. */
static
int
iv_add_mult_cost
(
b
,
m
,
a
,
reg
)
rtx
b
;
/* initial value of basic induction variable */
rtx
m
;
/* multiplicative constant */
rtx
a
;
/* additive constant */
rtx
reg
;
/* destination register */
{
int
cost
=
0
;
rtx
last
,
result
;
start_sequence
();
result
=
expand_mult_add
(
b
,
reg
,
m
,
a
,
GET_MODE
(
reg
),
0
);
if
(
reg
!=
result
)
emit_move_insn
(
reg
,
result
);
last
=
get_last_insn
();
while
(
last
)
{
rtx
t
=
single_set
(
last
);
if
(
t
)
cost
+=
rtx_cost
(
SET_SRC
(
t
),
SET
);
last
=
PREV_INSN
(
last
);
}
end_sequence
();
return
cost
;
}
/* Test whether A * B can be computed without
/* Test whether A * B can be computed without
an actual multiply insn. Value is 1 if so. */
an actual multiply insn. Value is 1 if so. */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment