Commit 7290d709 by Andrew MacLeod Committed by Andrew Macleod

New out of ssa Coalescer.

2006-12-10  Andrew MacLeod  <amacleod@redhat.com>

	* common.opt (-ftree-lrs): Remove live range splitting option.
	* makefile.in: Add tree-ssa-coalesce.o and reduce header dependancies.
	* opts.c (decode_options): Remove flag_tree_live_range_split.
	* tree-flow.h (struct var_ann_d): Rename fields from root_ to base_.
	* tree-flow-inline.h (single_imm_use_p): New.  Check for single use.
	* tree-outof-ssa.c: Remove header files which aren't needed.
	(SSANORM_*): Remove flags.
	(print_exprs_edge, coalesce_abnormal_edges, coalesce_phi_operands, 
	coalesce_result_decls_and_copies, coalesce_asm_operands): Remove.
	(coalesce_ssa_name): Move to tree-ssa-coalesce.c.
	(assign_vars): Use Basevar instead of root_var structure.
	(replace_def_variable): Dont do anything if def is replaceable.
	(remove_ssa_form): Integrate functional changes.
	(rewrite_out_of_ssa): Remove live-range_split option.
	* tree-ssa-coalesce.c: New File for ssa-name coalescing.
	(coalesce_cost): Calculate the cost of a coalesce.
	(coalesce_cost_bb): Calculate the coalesce cost within a BB.
	(coalesce_cost_edge): Calculate the coalesce cost on an edge.
	(pop_cost_one_pair): Remove the best coalesce with cost 1 from the list.
	(pop_best_coalesce): Remove the best coalesce from the list.
	(coalesce_pair_map_hash): Calculate coalesce pair hash.
	(coalesce_pair_map_eq): Compare 2 coalesce pairs for hash function.
	(create_coalesce_list): Create a coalesce list object.
	(delete_coalesce_list): Free a coalesce list object.
	(find_coalesce_pair): Find matching pair in the coalesce list.
	(add_cost_one_coalesce): Add a coalesce to the "cost one" list.
	(add_coalesce): Add a coalesce to the coalesce list.
	(compare_pairs): Comparision function to determine pair sorted order.
	(num_coalesce_pairs): Number of coalesced pairs.
	(first_coalesce_pair, end_coalesce_pair_p, next_coalesce_pair):
	Coalesce pair iterator functions.
	(sort_coalesce_list): Sort coalesce pairs in order of expense.
	(dump_coalesce_list): Show coalesce list.
	(ssa_conflicts_new): Create an SSA conflict graph.
	(ssa_conflicts_delete): Delete an SSA conflict graph.
	(ssa_conflicts_test_p): Test for conflicts.
	(ssa_conflicts_add_one): Add a single conflict.
	(ssa_conflicts_add): Add a conflict pair.
	(ssa_conflicts_merge): Merge conflicts.
	(struct live_track_d): Struct for tracking live partitions.
	(new_live_track): Create new live_track object.
	(delete_live_track): Delete a live_track object.
	(live_track_remove_partition): Remove a partition from the live list.
	(live_track_add_partition): Add a partition from the live list.
	(live_track_clear_var): Take VAR from the live list.
	(live_track_live_p): Is var live?
	(live_track_process_use): Make var come alive.
	(live_track_process_def): Make var go dead, add conflicts.
	(live_track_init): Initialize to a live on exit set.
	(live_track_clear_base_vars): Clear live partitions.
	(build_ssa_conflict_graph): Build a conflict graph.
	(print_exprs): Common debug output routine.
	(abnormal_corrupt): Output info about a failed coalesce across an
	abnormal edge.
	(fail_abnormal_edge_coalesce): Output info about a failed MUST_COALESCE.
	(create_outofssa_var_map): Create a var map and coalesce list.
	(attempt_coalesce): Coalesce a pair.
	(coalesce_partitions): Coalesce all pairs in a coalesce list.
	(coalesce_ssa_name): Entry point.  Determine what ssa_names to coalesce.
	* tree-ssa-live.c: Remove header files which aren't needed.
	(var_map_base_init): New.  Initialize a basevar list.
	(var_map_base_fini): New.  Finish a basevar list.
	(init_var_map): Initialize new fields.
	(delete_var_map): Free new fields.
	(var_union): Use renamed fields.
	(compact_var_map): Remove.
	(partition_to_view_init): Use renamed fields, change order of an if.
	(partition_view_fini): Use renamed fields.
	(partition_view_normal): Create basevar list if requested.
	(partition_view_bitmap): Create a view based on a bitmap of partitions.
	(change_partition_var): Use renamed fields.
	(create_ssa_var_map): Remove.
	(tpa_init, tpa_remove_partition, tpa_delete, tpa_compact,
	root_var_init): Remove.
	(partition_pair_map_hash, partition_pair_map_eq, create_coalesce_list,
	delete_coalesce_list, find_partition_pair, coalesce_cost, add_coalesce,
	compare_pairs, num_coalesce_pairs, first_partition_pair,
	end_partition_pair_p, next_partition_pair, sort_coalesce_list,
	pop_best_coalesce, add_conflicts_if_valid, set_if_valid,
	build_tree_conflict_graph, coalesce_tpa_members, dump_coalesce_list,
	tpa_dump): Moved to tree-ssa-coalesce.c and/or renamed there.
	(dump_var_map): Use renamed fields.
	* tree-ssa-live.h (struct  _var_map): Modify fields.
	(partition_to_var, version_to_var, var_to_partition): Use renamed 
	fields.
	(basevar_index): New.  Index of the base variable of a partition.
	(num_basevars): New.  Number of unique base variables in partition map.
	(register_ssa_partition): Use renamed fields.
	(struct tree_partition_associator_d): Remove.
	(tpa_num_trees, tpa_tree, tpa_first_partition, tpa_next_partition,
	tpa_find_tree, tpa_decompact, root_var_init, root_var_num,
	root_var, root_var_first_partition, root_var_next_partition,
	root_var_dump, root_var_delete, root_var_remove_partition, 
	root_var_find, root_var_compact, root_var_decompact): Remove.
	(struct partition_pair, struct coalesce_list_d): Moved to 
	tree-ssa-coalesce.c
	* tree-ssa-ter.c: Remove header files which aren't needed.

From-SVN: r119711
parent 669353d5
2006-12-10 Andrew MacLeod <amacleod@redhat.com>
* common.opt (-ftree-lrs): Remove live range splitting option.
* makefile.in: Add tree-ssa-coalesce.o and reduce header dependancies.
* opts.c (decode_options): Remove flag_tree_live_range_split.
* tree-flow.h (struct var_ann_d): Rename fields from root_ to base_.
* tree-flow-inline.h (single_imm_use_p): New. Check for single use.
* tree-outof-ssa.c: Remove header files which aren't needed.
(SSANORM_*): Remove flags.
(print_exprs_edge, coalesce_abnormal_edges, coalesce_phi_operands,
coalesce_result_decls_and_copies, coalesce_asm_operands): Remove.
(coalesce_ssa_name): Move to tree-ssa-coalesce.c.
(assign_vars): Use Basevar instead of root_var structure.
(replace_def_variable): Dont do anything if def is replaceable.
(remove_ssa_form): Integrate functional changes.
(rewrite_out_of_ssa): Remove live-range_split option.
* tree-ssa-coalesce.c: New File for ssa-name coalescing.
(coalesce_cost): Calculate the cost of a coalesce.
(coalesce_cost_bb): Calculate the coalesce cost within a BB.
(coalesce_cost_edge): Calculate the coalesce cost on an edge.
(pop_cost_one_pair): Remove the best coalesce with cost 1 from the list.
(pop_best_coalesce): Remove the best coalesce from the list.
(coalesce_pair_map_hash): Calculate coalesce pair hash.
(coalesce_pair_map_eq): Compare 2 coalesce pairs for hash function.
(create_coalesce_list): Create a coalesce list object.
(delete_coalesce_list): Free a coalesce list object.
(find_coalesce_pair): Find matching pair in the coalesce list.
(add_cost_one_coalesce): Add a coalesce to the "cost one" list.
(add_coalesce): Add a coalesce to the coalesce list.
(compare_pairs): Comparision function to determine pair sorted order.
(num_coalesce_pairs): Number of coalesced pairs.
(first_coalesce_pair, end_coalesce_pair_p, next_coalesce_pair):
Coalesce pair iterator functions.
(sort_coalesce_list): Sort coalesce pairs in order of expense.
(dump_coalesce_list): Show coalesce list.
(ssa_conflicts_new): Create an SSA conflict graph.
(ssa_conflicts_delete): Delete an SSA conflict graph.
(ssa_conflicts_test_p): Test for conflicts.
(ssa_conflicts_add_one): Add a single conflict.
(ssa_conflicts_add): Add a conflict pair.
(ssa_conflicts_merge): Merge conflicts.
(struct live_track_d): Struct for tracking live partitions.
(new_live_track): Create new live_track object.
(delete_live_track): Delete a live_track object.
(live_track_remove_partition): Remove a partition from the live list.
(live_track_add_partition): Add a partition from the live list.
(live_track_clear_var): Take VAR from the live list.
(live_track_live_p): Is var live?
(live_track_process_use): Make var come alive.
(live_track_process_def): Make var go dead, add conflicts.
(live_track_init): Initialize to a live on exit set.
(live_track_clear_base_vars): Clear live partitions.
(build_ssa_conflict_graph): Build a conflict graph.
(print_exprs): Common debug output routine.
(abnormal_corrupt): Output info about a failed coalesce across an
abnormal edge.
(fail_abnormal_edge_coalesce): Output info about a failed MUST_COALESCE.
(create_outofssa_var_map): Create a var map and coalesce list.
(attempt_coalesce): Coalesce a pair.
(coalesce_partitions): Coalesce all pairs in a coalesce list.
(coalesce_ssa_name): Entry point. Determine what ssa_names to coalesce.
* tree-ssa-live.c: Remove header files which aren't needed.
(var_map_base_init): New. Initialize a basevar list.
(var_map_base_fini): New. Finish a basevar list.
(init_var_map): Initialize new fields.
(delete_var_map): Free new fields.
(var_union): Use renamed fields.
(compact_var_map): Remove.
(partition_to_view_init): Use renamed fields, change order of an if.
(partition_view_fini): Use renamed fields.
(partition_view_normal): Create basevar list if requested.
(partition_view_bitmap): Create a view based on a bitmap of partitions.
(change_partition_var): Use renamed fields.
(create_ssa_var_map): Remove.
(tpa_init, tpa_remove_partition, tpa_delete, tpa_compact,
root_var_init): Remove.
(partition_pair_map_hash, partition_pair_map_eq, create_coalesce_list,
delete_coalesce_list, find_partition_pair, coalesce_cost, add_coalesce,
compare_pairs, num_coalesce_pairs, first_partition_pair,
end_partition_pair_p, next_partition_pair, sort_coalesce_list,
pop_best_coalesce, add_conflicts_if_valid, set_if_valid,
build_tree_conflict_graph, coalesce_tpa_members, dump_coalesce_list,
tpa_dump): Moved to tree-ssa-coalesce.c and/or renamed there.
(dump_var_map): Use renamed fields.
* tree-ssa-live.h (struct _var_map): Modify fields.
(partition_to_var, version_to_var, var_to_partition): Use renamed
fields.
(basevar_index): New. Index of the base variable of a partition.
(num_basevars): New. Number of unique base variables in partition map.
(register_ssa_partition): Use renamed fields.
(struct tree_partition_associator_d): Remove.
(tpa_num_trees, tpa_tree, tpa_first_partition, tpa_next_partition,
tpa_find_tree, tpa_decompact, root_var_init, root_var_num,
root_var, root_var_first_partition, root_var_next_partition,
root_var_dump, root_var_delete, root_var_remove_partition,
root_var_find, root_var_compact, root_var_decompact): Remove.
(struct partition_pair, struct coalesce_list_d): Moved to
tree-ssa-coalesce.c
* tree-ssa-ter.c: Remove header files which aren't needed.
2006-12-10 Steven Bosscher <steven@gcc.gnu.org> 2006-12-10 Steven Bosscher <steven@gcc.gnu.org>
* cse.c: (struct cse_basic_block_data): Remove LAST field. * cse.c: (struct cse_basic_block_data): Remove LAST field.
......
...@@ -985,7 +985,7 @@ OBJS-common = \ ...@@ -985,7 +985,7 @@ OBJS-common = \
tree-vect-generic.o tree-ssa-loop.o tree-ssa-loop-niter.o \ tree-vect-generic.o tree-ssa-loop.o tree-ssa-loop-niter.o \
tree-ssa-loop-manip.o tree-ssa-threadupdate.o tree-ssa-threadedge.o \ tree-ssa-loop-manip.o tree-ssa-threadupdate.o tree-ssa-threadedge.o \
tree-vectorizer.o tree-vect-analyze.o tree-vect-transform.o \ tree-vectorizer.o tree-vect-analyze.o tree-vect-transform.o \
tree-vect-patterns.o tree-ssa-loop-prefetch.o \ tree-vect-patterns.o tree-ssa-loop-prefetch.o tree-ssa-coalesce.o \
tree-ssa-loop-ivcanon.o tree-ssa-propagate.o tree-ssa-address.o \ tree-ssa-loop-ivcanon.o tree-ssa-propagate.o tree-ssa-address.o \
tree-ssa-math-opts.o \ tree-ssa-math-opts.o \
tree-ssa-loop-ivopts.o tree-if-conv.o tree-ssa-loop-unswitch.o \ tree-ssa-loop-ivopts.o tree-if-conv.o tree-ssa-loop-unswitch.o \
...@@ -1851,17 +1851,14 @@ tree-into-ssa.o : tree-into-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ ...@@ -1851,17 +1851,14 @@ tree-into-ssa.o : tree-into-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
bitmap.h $(CFGLOOP_H) $(FLAGS_H) hard-reg-set.h $(HASHTAB_H) \ bitmap.h $(CFGLOOP_H) $(FLAGS_H) hard-reg-set.h $(HASHTAB_H) \
$(TREE_GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) vecprim.h $(TREE_GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) vecprim.h
tree-ssa-ter.o : tree-ssa-ter.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ tree-ssa-ter.o : tree-ssa-ter.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \ $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
$(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ $(TREE_SSA_LIVE_H) bitmap.h
langhooks.h tree-pass.h $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) bitmap.h \ tree-ssa-coalesce.o : tree-ssa-coalesce.c $(TREE_FLOW_H) $(CONFIG_H) \
$(FLAGS_H) $(GGC_H) hard-reg-set.h $(HASHTAB_H) $(TREE_GIMPLE_H) \ $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
$(TREE_INLINE_H) $(VARRAY_H) toplev.h vecprim.h $(TREE_SSA_LIVE_H) bitmap.h $(FLAGS_H) $(HASHTAB_H) toplev.h
tree-outof-ssa.o : tree-outof-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ tree-outof-ssa.o : tree-outof-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \ $(TREE_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
$(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ tree-pass.h $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) bitmap.h $(GGC_H) toplev.h
langhooks.h tree-pass.h $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) bitmap.h \
$(FLAGS_H) $(GGC_H) hard-reg-set.h $(HASHTAB_H) $(TREE_GIMPLE_H) \
$(TREE_INLINE_H) $(VARRAY_H) toplev.h vecprim.h
tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \ $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
$(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) domwalk.h $(FLAGS_H) \ $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) domwalk.h $(FLAGS_H) \
...@@ -1913,10 +1910,8 @@ tree-phinodes.o : tree-phinodes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ ...@@ -1913,10 +1910,8 @@ tree-phinodes.o : tree-phinodes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
domwalk.o : domwalk.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ domwalk.o : domwalk.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) domwalk.h $(GGC_H) $(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) domwalk.h $(GGC_H)
tree-ssa-live.o : tree-ssa-live.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ tree-ssa-live.o : tree-ssa-live.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) \ $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
$(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) \ $(TREE_SSA_LIVE_H) bitmap.h toplev.h
bitmap.h $(FLAGS_H) $(HASHTAB_H) $(TREE_GIMPLE_H) $(TREE_INLINE_H) \
$(VARRAY_H) toplev.h vecprim.h
tree-ssa-copyrename.o : tree-ssa-copyrename.c $(TREE_FLOW_H) $(CONFIG_H) \ tree-ssa-copyrename.o : tree-ssa-copyrename.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) tree-pass.h \ $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) tree-pass.h \
$(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) \ $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) \
......
...@@ -1003,10 +1003,6 @@ ftree-ter ...@@ -1003,10 +1003,6 @@ ftree-ter
Common Report Var(flag_tree_ter) Common Report Var(flag_tree_ter)
Replace temporary expressions in the SSA->normal pass Replace temporary expressions in the SSA->normal pass
ftree-lrs
Common Report Var(flag_tree_live_range_split)
Perform live range splitting during the SSA->normal pass
ftree-vrp ftree-vrp
Common Report Var(flag_tree_vrp) Init(0) Common Report Var(flag_tree_vrp) Init(0)
Perform Value Range Propagation on trees Perform Value Range Propagation on trees
......
...@@ -449,7 +449,6 @@ decode_options (unsigned int argc, const char **argv) ...@@ -449,7 +449,6 @@ decode_options (unsigned int argc, const char **argv)
flag_tree_dom = 1; flag_tree_dom = 1;
flag_tree_dse = 1; flag_tree_dse = 1;
flag_tree_ter = 1; flag_tree_ter = 1;
flag_tree_live_range_split = 1;
flag_tree_sra = 1; flag_tree_sra = 1;
flag_tree_copyrename = 1; flag_tree_copyrename = 1;
flag_tree_fre = 1; flag_tree_fre = 1;
......
...@@ -541,6 +541,18 @@ has_single_use (tree var) ...@@ -541,6 +541,18 @@ has_single_use (tree var)
return (ptr != ptr->next && ptr == ptr->next->next); return (ptr != ptr->next && ptr == ptr->next->next);
} }
/* If VAR has only a single immediate use, return true. */
static inline bool
single_imm_use_p (tree var)
{
ssa_use_operand_t *ptr;
ptr = &(SSA_NAME_IMM_USE_NODE (var));
return (ptr != ptr->next && ptr == ptr->next->next);
}
/* If VAR has only a single immediate use, return true, and set USE_P and STMT /* If VAR has only a single immediate use, return true, and set USE_P and STMT
to the use pointer and stmt of occurrence. */ to the use pointer and stmt of occurrence. */
static inline bool static inline bool
......
...@@ -218,8 +218,8 @@ struct var_ann_d GTY(()) ...@@ -218,8 +218,8 @@ struct var_ann_d GTY(())
been seen yet or not. */ been seen yet or not. */
unsigned out_of_ssa_tag : 1; unsigned out_of_ssa_tag : 1;
/* Used when building root_var structures in tree_ssa_live.[ch]. */ /* Used when building base variable structures in a var_map. */
unsigned root_var_processed : 1; unsigned base_var_processed : 1;
/* Nonzero if this variable is in the alias set of another variable. */ /* Nonzero if this variable is in the alias set of another variable. */
unsigned is_aliased : 1; unsigned is_aliased : 1;
...@@ -257,8 +257,8 @@ struct var_ann_d GTY(()) ...@@ -257,8 +257,8 @@ struct var_ann_d GTY(())
variable represents storage for. */ variable represents storage for. */
unsigned partition; unsigned partition;
/* Used by the root-var object in tree-ssa-live.[ch]. */ /* Used by var_map for the base index of ssa base variables. */
unsigned root_index; unsigned base_index;
/* During into-ssa and the dominator optimizer, this field holds the /* During into-ssa and the dominator optimizer, this field holds the
current version of this variable (an SSA_NAME). */ current version of this variable (an SSA_NAME). */
......
...@@ -25,29 +25,11 @@ Boston, MA 02110-1301, USA. */ ...@@ -25,29 +25,11 @@ Boston, MA 02110-1301, USA. */
#include "coretypes.h" #include "coretypes.h"
#include "tm.h" #include "tm.h"
#include "tree.h" #include "tree.h"
#include "flags.h"
#include "rtl.h"
#include "tm_p.h"
#include "ggc.h"
#include "langhooks.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "output.h"
#include "expr.h"
#include "function.h"
#include "diagnostic.h" #include "diagnostic.h"
#include "bitmap.h" #include "bitmap.h"
#include "tree-flow.h" #include "tree-flow.h"
#include "tree-gimple.h"
#include "tree-inline.h"
#include "varray.h"
#include "timevar.h"
#include "hashtab.h"
#include "tree-dump.h" #include "tree-dump.h"
#include "tree-ssa-live.h" #include "tree-ssa-live.h"
#include "tree-pass.h"
#include "toplev.h"
#include "vecprim.h"
/* Temporary Expression Replacement (TER) /* Temporary Expression Replacement (TER)
......
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