27 #if defined(BUILDER_DEAD_CODE_ELIMINATION) || \
28 defined(BUILDER_DEAD_CODE_ELIMINATION_WITH_OUT_REGIONS)
31 #include "pips_config.h"
76 static set the_useful_statements;
82 static hash_table statements_use_def_dependence;
93 static list keeped_functions = 0;
98 static list keeped_functions_prefix = 0;
101 static void dead_code_elimination_error_handler(
void)
103 error_reset_current_statement_stack();
112 add_statement_to_the_statement_to_statement_father_mapping(
statement s)
115 current_statement_rewrite(s);
117 pips_debug(4,
"add_statement_to_the_statement_to_statement_father_mapping statement %p (%#zx), father %p\n",
124 store_statement_father(s, current_statement_head());
135 set_control_statement_father(
control c)
142 build_statement_to_statement_father_mapping(
statement s)
146 make_current_statement_stack();
152 current_statement_filter,
153 add_statement_to_the_statement_to_statement_father_mapping,
158 free_current_statement_stack();
173 pips_debug(7,
"build_statement_to_statement_dependence_mapping"
174 "\tSuccessor list: %p for statement ordering %p\n",
183 pips_debug(7,
"\t%p (%#zx) --> %p (%#zx) with conflicts\n",
210 (
set)
hash_get(statements_use_def_dependence, (
void *) use);
215 hash_put(statements_use_def_dependence,
216 (
void *) use, (
void *) statements_set);
224 "Def: statement %p (%#zx).\n",
225 use, statement_ordering(use),
226 def, statement_ordering(def));
227 // One use-def is enough for this variable couple:
237 free_statement_to_statement_dependence_mapping()
241 set_free((set) value);
243 statements_use_def_dependence);
249 mark_this_node_and_its_predecessors_in_the_dg_as_useful(set s,
252 if (set_belong_p(s, (char *) v))
253 /* We have already seen this node: */
256 /* Mark the current vertex as useful: */
257 set_add_element(s, s, (char *) v);
259 pips_debug(6, "mark_this_node_and_its_predecessors_in_the_dg_as_useful: vertex %p marked, statement ordering (%#x).\n",
261 dg_vertex_label_statement(vertex_vertex_label(v)));
263 MAP(SUCCESSOR, a_successor,
265 dg_arc_label label = successor_arc_label(a_successor);
266 /* Try to find at least one use-def chain: */
267 MAP(CONFLICT, a_conflict,
269 /* Something is useful for the current statement if
270 it writes something that is used in the current
272 if (effect_read_p(conflict_source(a_conflict))
273 && effect_write_p(conflict_sink(a_conflict))) {
274 /* Mark the node that generate something useful
275 for the current statement as useful: */
276 mark_this_node_and_its_predecessors_in_the_dg_as_useful(s,
277 successor_vertex(a_successor));
278 /* Only needed to mark once: */
282 dg_arc_label_conflicts(label));
284 vertex_successors(v));
290 iterate_through_the_predecessor_graph(statement s,
291 set elements_to_visit)
293 pips_debug(6, "iterate_through_the_predecessor_graph, statement %p (%#zx).\n",
294 s, statement_ordering(s));
296 /* Mark the current statement as useful: */
297 set_add_element(the_useful_statements, the_useful_statements, (char *) s);
299 /* First mark the dependence graph predecessors: */
301 set statements_set = (set) hash_get(statements_use_def_dependence,
303 if (statements_set != (set) HASH_UNDEFINED_VALUE) {
304 /* There is at least one statement that generates something
308 statement s2 = (statement) element;
310 /* Mark that we will visit the node that defined a
311 source for this statement, if not already
313 set_add_element(elements_to_visit,
316 pips_debug(6, "\tstatement %p (%#zx) useful by use-def.\n",
317 s2, statement_ordering(s2));
323 /* Mark the father too for control dependences: */
324 if (bound_statement_father_p(s)) {
325 statement father = load_statement_father(s);
326 set_add_element(elements_to_visit, elements_to_visit, (char *) father);
327 pips_debug(6, "\tstatement %p (%#zx) useful as the statement owner.\n",
328 father, statement_ordering(father));
332 /* And if the statement is in an unstructured, mark all the
333 controlling unstructured nodes predecessors as useful, that
334 is all the unstructured IF back-reachable. */
335 if (bound_control_father_p(s)) {
337 control control_father = load_control_father(s);
338 BACKWARD_CONTROL_MAP(pred, {
339 if (gen_length(control_successors(pred)) == 2) {
340 /* pred is an unstructured IF that control control_father: */
341 set_add_element(elements_to_visit,
343 (char *) control_statement(pred));
344 pips_debug(6, "\tstatement unstructed IF %p (%#zx) useful by control dependence.\n",
345 control_statement(pred), statement_ordering(control_statement(pred)));
347 }, control_father, blocks);
348 gen_free_list(blocks);
355 propagate_the_usefulness_through_the_predecessor_graph()
357 pips_debug(5, "Entering propagate_the_usefulness_through_the_predecessor_graph\n");
359 gen_set_closure((void (*)(void *, set)) iterate_through_the_predecessor_graph,
360 the_useful_statements);
362 pips_debug(5, "Exiting propagate_the_usefulness_through_the_predecessor_graph\n");
368 static bool match_call_to_user_function(call c, bool *user_function_found) {
369 const char* match_name = entity_local_name(call_function(c));
371 FOREACH(STRING, func, keeped_functions) {
372 if(strcmp(match_name,func)==0) {
373 *user_function_found = true;
377 FOREACH(STRING, func_prefix, keeped_functions_prefix) {
378 if(strncmp(match_name,func_prefix,strlen(func_prefix))==0) {
379 *user_function_found = true;
384 return !user_function_found;
387 static bool statement_call_a_keep_function_p( statement s ) {
388 bool user_function_found = false;
389 if(statement_call_p(s) || statement_expression_p(s)) {
390 gen_context_recurse(s,&user_function_found, call_domain, match_call_to_user_function, gen_null2);
393 /* FIXME : LOOP header && so one... */
395 return user_function_found;
398 /* FI: not only if it is useful, but if it is legal... */
399 static void use_def_deal_if_useful(statement s) {
400 bool this_statement_has_an_io_effect;
401 /* When a call by reference is used... */
402 bool this_statement_writes_a_procedure_argument;
403 bool this_statement_is_a_format;
404 bool this_statement_is_an_unstructured_test = false;
405 /* FI: any statement that does not have a must/exact continuation
406 * should be preserved. For the time being, only exact
407 * non-continuing calls are checked: return, exit and abort. Since
408 * exceptions are not taken into account, the semantics of the code
411 * Exact non-continuation can be checked with the statement
412 * transformer. beatrice Creusillet has also developped a
413 * continuation analysis.
415 bool this_statement_is_a_c_return;
416 bool outside_effect_p = false;
417 bool this_statement_call_a_user_function;
420 int debugLevel = get_debug_level();
422 fprintf(stderr, "statement %p (%#zx)\n",
423 s, statement_ordering(s));
424 print_text(stderr, Text_Statement(get_current_module_entity(), 0, s));
425 set_debug_level(debugLevel);
428 if (statement_ordering(s) == STATEMENT_ORDERING_UNDEFINED) {
429 pips_user_warning("exited since it found a statement without ordering: statement %p (%#x)\n", s, statement_ordering(s));
433 /* The possible reasons to have useful code: */
434 /* - the statement does an I/O: */
435 this_statement_has_an_io_effect = statement_io_effect_p(s);
437 /* - the statement writes a procedure argument or the return
438 variable of the function, so the value may be used by another
440 /* Regions out should be more precise: */
441 this_statement_writes_a_procedure_argument =
442 statement_has_a_formal_argument_write_effect_p(s);
444 /* Avoid to remove formats in a first approach: */
445 this_statement_is_a_format = instruction_format_p(statement_instruction(s));
447 /* Unstructured tests are very hard to deal with since they can
448 have major control effects, such as leading to an infinite loop,
449 etc. and it is very hard to cope with... Thus, keep all
450 unstructured tests in this approach since I cannot prove the
451 termination of the program and so on. */
452 if (bound_control_father_p(s)) {
453 control control_father = load_control_father(s);
454 if (gen_length(control_successors(control_father)) == 2)
455 /* It is an unstructured test: keep it: */
456 this_statement_is_an_unstructured_test = true;
459 /* All statements with control effects such as exit() or abort()
460 should be preserved. Continuations should be checked for
461 user-defined functions. Exceptions are also a problem. */
462 this_statement_is_a_c_return = return_statement_p(s)
463 || exit_statement_p(s) || abort_statement_p(s);
465 /* Check if this statement write some other things than a local variable */
466 list effects_list = load_proper_rw_effects_list(s);
467 entity current_func = get_current_module_entity();
468 FOREACH(EFFECT, eff,effects_list) {
469 reference a_reference = effect_any_reference(eff);
470 entity touched = reference_variable(a_reference);
471 if(effect_write_p(eff)
472 && (!entity_local_variable_p(touched,current_func)
473 /* FI: we should also check that the static effect is
474 leaked by the function but this is hard to check and is
475 usually not intended by the programmer. See
476 Transformations/Dead_code_elimination.sub/use_def_elim07/08. */
477 || entity_static_variable_p(touched))) {
478 outside_effect_p = true;
479 pips_debug(7, "Statement %p, outside effect on %s (module %s)\n",
481 entity_name(touched),
482 entity_local_name(current_func));
487 this_statement_call_a_user_function = statement_call_a_keep_function_p(s);
490 pips_debug(6, "Statement %p:\n%s\n Statement number: %" _intFMT "\n", s,
491 text_to_string(statement_to_text(s)), statement_number(s));
492 if (outside_effect_p)
493 pips_debug(6, "Statement %p has an outside effect.\n", s);
494 if (this_statement_has_an_io_effect)
495 pips_debug(6, "Statement %p has an io effect.\n", s);
496 if (this_statement_writes_a_procedure_argument)
497 pips_debug(6,"Statement %p writes an argument of its procedure.\n", s);
498 if (this_statement_is_a_format)
499 pips_debug(6, "Statement %p is a FORMAT.\n", s);
500 if (this_statement_is_an_unstructured_test)
501 pips_debug(6, "Statement %p is an unstructured test.\n", s);
502 if (this_statement_is_a_c_return)
503 pips_debug(6, "Statement %p is a C return.\n", s);
508 if (this_statement_has_an_io_effect
510 || this_statement_writes_a_procedure_argument
511 || this_statement_is_a_format
512 || this_statement_is_an_unstructured_test
513 || this_statement_is_a_c_return
514 || this_statement_call_a_user_function
516 /* Mark this statement as useful: */
517 set_add_element(the_useful_statements, the_useful_statements, (char *) s);
519 pips_debug(5, "end\n");
523 static void remove_this_statement_if_useless(statement s, set entities_to_remove) {
524 if (! set_belong_p(the_useful_statements, (char *) s)) {
525 pips_debug(6, "remove_this_statement_if_useless removes statement %p (%#zx).\n", s, statement_ordering(s));
529 // If this is a "declaration statement" keep track of removed declarations
530 if(empty_statement_or_continue_p(s)) {
531 FOREACH(ENTITY,e, statement_declarations(s)) {
532 set_add_element(entities_to_remove,entities_to_remove,e);
536 // Get rid of declarations
537 gen_free_list(statement_declarations(s));
538 statement_declarations(s) = NIL;
540 // Free old instruction
541 free_instruction(statement_instruction(s));
543 // Replace statement with a continue, so that we keep label && comments
544 statement_instruction(s) = make_continue_instruction();
546 // Get rid of removed entity in declarations
547 if(statement_declarations(s) != NIL) {
548 SET_FOREACH(entity,e,entities_to_remove) {
549 pips_debug(5,"Declaration removed for %s\n",entity_name(e));
550 gen_remove(&statement_declarations(s),e);
554 * Let dive into sequence and really remove the statement, it's a lot
555 * cleaner than keeping empty statement when there's not label or comment
557 if(statement_block_p(s)) {
558 pips_debug(6,"Checking sequence\n");
559 list statement_to_remove = NIL;
560 FOREACH(statement,st,statement_block(s)) {
561 if (! set_belong_p(the_useful_statements, (char *) st)
562 && empty_statement_or_continue_without_comment_p(st) ) {
563 pips_debug(4,"Register %p to be removed\n",st);
564 statement_to_remove = CONS(STATEMENT,st,statement_to_remove);
567 FOREACH(statement,st,statement_to_remove) {
568 gen_remove_once(&sequence_statements(statement_sequence(s)),st);
570 gen_free_list(statement_to_remove);
572 // If the sequence is empty now, mark as removable :-)
573 if(empty_statement_or_continue_without_comment_p(s)) {
574 set_add_element(the_useful_statements,the_useful_statements,s);
578 pips_debug(6, "end\n");
586 remove_all_the_non_marked_statements(statement s)
588 pips_debug(5, "Entering remove_all_the_non_marked_statements\n");
590 // Keep track of removed entities
591 set entities_to_remove = set_make(set_pointer);
593 gen_context_recurse(s, entities_to_remove,
594 /* Since statements can be nested, only remove in a
596 statement_domain, gen_true2, remove_this_statement_if_useless);
599 SET_FOREACH(entity,e,entities_to_remove) {
600 pips_debug(6,"Entity '%s' has been totaly removed\n",entity_name(e));
604 set_free(entities_to_remove);
606 pips_debug(5, "Exiting remove_all_the_non_marked_statements\n");
615 dead_code_elimination_on_a_statement(statement s)
617 the_useful_statements = set_make(set_pointer);
618 init_control_father();
619 init_statement_father();
621 ordering_to_dg_mapping = compute_ordering_to_dg_mapping(dependence_graph);
623 build_statement_to_statement_father_mapping(s);
624 build_statement_to_statement_dependence_mapping(dependence_graph);
626 /* Mark as useful the seed statements: */
627 gen_recurse(s, statement_domain,
629 use_def_deal_if_useful);
631 /* Propagate the usefulness through all the predecessor graph: */
632 propagate_the_usefulness_through_the_predecessor_graph();
634 remove_all_the_non_marked_statements(s);
636 hash_table_free(ordering_to_dg_mapping);
637 free_statement_to_statement_dependence_mapping();
638 close_statement_father();
639 close_control_father();
640 set_free(the_useful_statements);
643 static bool non_empty_out_regions_p(statement s)
645 list l_out = load_statement_out_regions(s);
646 list l_out_global = load_statement_out_regions(get_current_module_statement());
647 bool main_p = entity_main_module_p(get_current_module_entity());
649 if(s==get_current_module_statement()) {
650 if(entity_main_module_p(get_current_module_entity())) {
651 // FI: IO's have no impact on the out regions of a main...
652 // The OUT regions of a main function are always empty
653 set_add_element(the_useful_statements, the_useful_statements, (char *) s);
656 /* We can remove all statements but must preserve at least one
657 * return statement, although it is useless, so as not to
658 * generate inconsistent C or Fortran code. So, this cannot be
661 set_add_element(the_useful_statements, the_useful_statements, (char *) s);
664 else if(declaration_statement_p(s)) {
665 // FI: the OUT regions do not take into account all effects
666 // all declaration statements are preserved to be conservative
667 // Other passes might be able to deal witht them, maybe after a
668 // split_initializations pass
669 set_add_element(the_useful_statements, the_useful_statements, (char *) s);
671 else if(ENDP(l_out)) {
674 else if((ENDP(l_out_global) && !main_p)) {
675 /* FI: this does not work because OUT regions do not let
676 distinguish between functions whose returned value is used and
677 functions whose returned value is not used; somehow, the return
678 value should be taken into account by the region analysis. */
680 set_add_element(the_useful_statements, the_useful_statements, (char *) s);
683 /* Mark statement as useful */
684 set_add_element(the_useful_statements, the_useful_statements, (char *) s);
694 dead_code_elimination_on_a_statement_with_out_regions(statement s)
696 the_useful_statements = set_make(set_pointer);
697 init_control_father();
698 init_statement_father();
700 //ordering_to_dg_mapping = compute_ordering_to_dg_mapping(dependence_graph);
702 build_statement_to_statement_father_mapping(s);
703 //build_statement_to_statement_dependence_mapping(dependence_graph);
705 /* Mark as useful the seed statements: */
706 gen_recurse(s, statement_domain,
708 use_def_deal_if_useful);
710 /* Propagate the usefulness through all the predecessor graph: */
711 // propagate_the_usefulness_through_the_predecessor_graph();
712 // all statements with a non empty out region are useful
713 gen_recurse(s, statement_domain, non_empty_out_regions_p, gen_null);
715 remove_all_the_non_marked_statements(s);
717 //hash_table_free(ordering_to_dg_mapping);
718 //free_statement_to_statement_dependence_mapping();
719 close_statement_father();
720 close_control_father();
721 set_free(the_useful_statements);
725 bool dead_code_elimination_on_module(char * module_name, bool use_out_regions)
727 statement module_statement;
728 entity module = module_name_to_entity(module_name);
731 * For C code, this pass requires that effects are calculated with property
732 * MEMORY_EFFECTS_ONLY set to false because we need that the chains include
733 * arcs for declarations as these latter are separate statements now.
735 bool memory_effects_only_p = get_bool_property("MEMORY_EFFECTS_ONLY");
736 if(c_module_p(module) && memory_effects_only_p && !use_out_regions) {
737 pips_user_error("For C code, Dead code elimination should be run with property "
738 "MEMORY_EFFECTS_ONLY set to FALSE.\n"
739 "For C code, this pass requires that effects are calculated with property"
740 " MEMORY_EFFECTS_ONLY set to false because we need that the chains include"
741 " arcs for declarations as these latter are separate statements now.\n");
742 return false; // return to pass manager with a failure code
745 /* Get the true ressource, not a copy. */
747 (statement) db_get_memory_resource(DBR_CODE, module_name, true);
749 /* Get the data dependence graph: */
750 /* The dg is more precise than the chains, so I (RK) guess I should
751 remove more code with the dg, specially with array sections and
753 /* FI: it's much too expensive; and how can you gain something
754 * with scalar variables?
758 (graph) db_get_memory_resource(DBR_DG, module_name, true);
761 if(!use_out_regions) {
763 (graph) db_get_memory_resource(DBR_CHAINS, module_name, true);
766 /* The proper effect to detect the I/O operations: */
767 set_proper_rw_effects((statement_effects)
768 db_get_memory_resource(DBR_PROPER_EFFECTS,
771 if(use_out_regions) {
772 set_out_effects( (statement_effects)
773 db_get_memory_resource(DBR_OUT_REGIONS, module_name, true) );
774 set_precondition_map( (statement_mapping)
775 db_get_memory_resource(DBR_PRECONDITIONS, module_name, true) );
778 set_current_module_statement(module_statement);
779 set_current_module_entity(module);
781 set_ordering_to_statement(module_statement);
783 debug_on("DEAD_CODE_ELIMINATION_DEBUG_LEVEL");
784 pips_debug(1, "begin dead_code_elimination\n");
785 reset_hooks_register(dead_code_elimination_error_handler);
787 /* DEAD_CODE_ELIMINATION_KEEP_FUNCTIONS is a property that can be defined
788 * by the user for telling that a space separated list of functions has to
789 * be considered as important and we have to keep them
790 * Note: it doesn't work with out_regions
792 keeped_functions = strsplit(get_string_property("DEAD_CODE_ELIMINATION_KEEP_FUNCTIONS")," ");
793 keeped_functions_prefix = strsplit(get_string_property("DEAD_CODE_ELIMINATION_KEEP_FUNCTIONS_PREFIX")," ");
795 if(use_out_regions) {
796 dead_code_elimination_on_a_statement_with_out_regions(module_statement);
799 dead_code_elimination_on_a_statement(module_statement);
801 gen_map(free,keeped_functions);gen_free_list(keeped_functions);
802 keeped_functions = 0;
803 gen_map(free,keeped_functions_prefix);gen_free_list(keeped_functions_prefix);
804 keeped_functions_prefix = 0;
807 /* Reorder the module, because some statements have been deleted.
808 Well, the order on the remaining statements should be the same,
809 but by reordering the statements, the number are consecutive. Just
810 for pretty print... :-) */
811 module_reorder(module_statement);
813 pips_debug(2, "done for %s\n", module_name);
816 /* Apply clean declarations ! */
818 * NL: This code are usefull to eliminate:
819 * - when an useless variable is declare with some usefull variable (int usefull, useless;)
820 * - in C, when an useless variable is initialize in the declaration (int useless=0;)
821 * - useless declaration when we use out region for dead_code_elimination
822 * (Transformations/Dead_code_declaratios.sub/use_def_elim10)
825 debug_on("CLEAN_DECLARATIONS_DEBUG_LEVEL");
826 pips_debug(1, "begin clean_declarations\n");
828 set_cumulated_rw_effects(
829 (statement_effects)db_get_memory_resource(DBR_CUMULATED_EFFECTS,
833 module_clean_declarations(get_current_module_entity(),
834 get_current_module_statement());
836 pips_debug(1, "end clean_declarations\n");
840 * If out_regions available
841 * also reduce loop bound iteration
843 if(use_out_regions) {
844 debug_on("LOOP_BOUND_MINIMIZATION_DEBUG_LEVEL");
845 pips_debug(1, "begin loop_bound_minimization\n");
847 loop_bound_minimization_with_out_regions_on_statement(get_current_module_statement());
849 pips_debug(1, "end loop_bound_minimization\n");
854 DB_PUT_MEMORY_RESOURCE(DBR_CODE, module_name, module_statement);
856 // We may have removed some function call, thus recompute the callees
857 DB_PUT_MEMORY_RESOURCE(DBR_CALLEES, module_name,
858 compute_callees(get_current_module_statement()));
861 reset_cumulated_rw_effects();
862 reset_proper_rw_effects();
863 if(use_out_regions) {
865 reset_precondition_map();
867 reset_current_module_statement();
868 reset_current_module_entity();
869 reset_ordering_to_statement();
871 reset_hooks_unregister(dead_code_elimination_error_handler);
873 /* Should have worked: */
877 bool dead_code_elimination(char * module_name)
879 debug_on("DEAD_CODE_ELIMINATION_DEBUG_LEVEL");
880 bool success = dead_code_elimination_on_module(module_name, false);
885 bool dead_code_elimination_with_out_regions(char * module_name)
887 debug_on("DEAD_CODE_ELIMINATION_DEBUG_LEVEL");
888 bool success = dead_code_elimination_on_module(module_name, true);
893 /* Obsolete name: it should be called dead_code_elimination()
895 * Maintained for backward compatibility.
897 bool use_def_elimination(char * module_name)
899 debug_on("USE_DEF_ELIMINATION_DEBUG_LEVEL");
900 pips_user_warning("This phase has been renamed, please use "
901 "'dead_code_elimination' from now.\n" );
902 bool success = dead_code_elimination_on_module(module_name, false);
911 #endif // BUILDER_DEAD_CODE_ELIMINATION*
dg_vertex_label vertex_label
static graph dependence_graph
#define dg_vertex_label_statement(x)
#define dg_arc_label_conflicts(x)
#define conflict_source(x)
list words_effect(effect)
#define action_write_p(x)
#define successor_vertex(x)
#define successor_arc_label(x)
#define vertex_vertex_label(x)
#define vertex_successors(x)
#define graph_vertices(x)
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
hash_table hash_table_make(hash_key_type key_type, size_t size)
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
statement vertex_to_statement(vertex v)
Vertex_to_statement looks for the statement that is pointed to by vertex v.
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
#define DEFINE_LOCAL_STACK(name, type)
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
set set_make(set_type)
Create an empty set of any type but hash_private.
set set_add_element(set, const set, const void *)
#define statement_ordering(x)
#define statement_domain
newgen_sizeofexpression_domain_defined
#define control_domain
newgen_controlmap_domain_defined
#define control_statement(x)
#define statement_undefined
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
static statement current_statement
GENERIC_LOCAL_FUNCTION(directives, step_directives)
Copyright 2007, 2008, 2009 Alain Muller, Frederique Silber-Chaussumier.
FI: I do not understand why the type is duplicated at the set level.
The structure used to build lists in NewGen.
void print_words(FILE *fd, cons *lw)