First implementation of lowering for calls with compound return values
[libfirm] / testprograms / place_with_dead_block_example.c
1 /*
2  * Project:     libFIRM
3  * File name:   testprograms/
4  * Purpose:
5  * Author:      Goetz Lindenmaier
6  * Modified by:
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 2004 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13 # include <stdio.h>
14 # include <string.h>
15
16 # include "irvrfy.h"
17 # include "firm.h"
18 # include "irdump.h"
19
20
21 /** This file constructs the ir to test a problem with code placement.
22  *
23  * Global cse and removal of dead code can produce nodes, that depend
24  * on live nodes, but originally were placed in dead code.  The
25  * dominator analyses can not compute dominator information for
26  * them, or their block is the Bad node.
27  *
28  * We must place this nodes in the code, as they could be reached
29  * through a live node.
30  *
31  * This program constructs a graph that can result from the program below
32  * by dead node elimination and global cse.
33  *
34  *  class SomeClass {}
35  *  long main() {
36  *    long a = 0;
37  *    int  b = sizeof(SomeClass);
38  *
39  *    if (a > 2)
40  *      { a = (long) b; }
41  *    else
42  *      { a = (long) b; }
43  *
44  *    return a;
45  *  }
46  *
47  *  The Conv node for the cast to long is constructed twice, in each
48  *  if case once.  Global cse visits the Conv in the block that will
49  *  turn dead first, i.e., it adds this node in the hash table.  The
50  *  assignment in the alive block is replaced by this node.  In a next
51  *  step the dead code is removed, only straight control flow remains.
52  *  This results in a Conv node that is not placed in an existing node,
53  *  but needed by the program.
54  *
55  *  Code placememnt (place early) tries to place the node in the Start
56  *  block, which is illegal.  Actually, place late should move the block
57  *  out of the Start block.
58  */
59
60 #define PROGNAME "PLACE_WITH_DEAD"
61
62 int main(int argc, char **argv)
63 {
64   type     *prim_t_int;
65   ir_graph *irg;       /* this variable contains the irgraph */
66   type     *owner;     /* the class in which this method is defined */
67   type     *method;    /* the type of this method */
68   entity   *ent;       /* represents this method as entity of owner */
69   ir_node  *a, *b, *x;
70   symconst_symbol sym;
71
72   printf("\nCreating an IR graph: " PROGNAME "...\n");
73
74   /* init library */
75   init_firm (NULL);
76
77   /* Make basic type information for primitive type int. */
78   prim_t_int = new_type_primitive(new_id_from_chars ("int", 3), mode_Ls);
79
80   /* Make the method type and entity */
81   owner = get_glob_type();
82   method = new_type_method (new_id_from_str(PROGNAME"_main_tp"), 0, 1);
83   set_method_res_type(method, 0, prim_t_int);
84   ent = new_entity (owner, new_id_from_str (PROGNAME"_main"), method);
85
86   /* The ir graph */
87 #define NUM_OF_LOCAL_VARS 2
88   irg = new_ir_graph (ent, NUM_OF_LOCAL_VARS);
89
90   /* Generate the two constants. A SymConst can not be constant evaluated. */
91   sym.type_p = new_type_class(new_id_from_str("SomeClass"));
92   a = new_Const (mode_Is, new_tarval_from_long (0, mode_Is));
93   b = new_SymConst (sym, symconst_size);
94
95   /* Generate the Conv with Bad as block */
96   a = new_Conv(b, mode_Ls);
97   set_nodes_block(a, new_Bad());
98
99   /* Generate the return. */
100   x = new_Return (get_store(), 1, &a);
101
102   /* Finish the graph. */
103   mature_immBlock (get_irg_current_block(irg));
104   add_immBlock_pred (get_irg_end_block(irg), x);
105   mature_immBlock (get_irg_end_block(irg));
106   irg_finalize_cons (irg);
107   irg_vrfy(irg);
108
109   printf("Done building the graph.  Dumping it.\n");
110   dump_ir_block_graph (irg, 0);
111   dump_ir_graph (irg, 0);
112
113   printf("Code placement ...\n");
114   set_opt_global_cse(1);        /* need this option for code placement */
115   place_code(irg);
116
117   dump_ir_block_graph (irg, "-placed");
118   dump_ir_graph (irg, "-placed");
119   irg_vrfy(irg);
120
121   printf("use xvcg to view this graph:\n");
122   printf("/ben/goetz/bin/xvcg GRAPHNAME\n\n");
123
124   return (0);
125 }