Test phis in nested loops
[libfirm] / testprograms / irr_loop_example.c
1 /*
2  * Project:     libFIRM
3  * File name:   testprograms/irr_loop_example.c
4  * Purpose:     Test Phi construction with irregular control flow.
5  * Author:      Christian Schaefer, Goetz Lindenmaier
6  * Modified by:
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1999-2003 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 "irdump.h"
18 # include "firm.h"
19
20 /**
21  *  This file constructs a control flow of following shape:
22  *
23  *
24  *         firstBlock
25  *          /      \
26  *         /        \
27  *       |/_        _\|
28  *            ---->
29  * LoopBlock1       LoopBlock2
30  *            <----
31  *        \              /
32  *         \            /
33  *         _\|        |/_
34  *           nextBlock
35  *
36  *
37  **/
38
39 int main(int argc, char **argv)
40 {
41   ir_graph *irg;        /* this variable contains the irgraph */
42   type     *owner;      /* the class in which this method is defined */
43   type     *proc_main;  /* typeinformation for the method main */
44   entity   *ent;        /* represents this method as entity of owner */
45   ir_node  *expr, *c1, *c2, *c3, *cond, *f, *t, *loopBlock1, *f_l1, *t_l1,
46            *loopBlock2, *f_l2, *t_l2, *x;
47
48
49   /* init library */
50   init_firm (NULL);
51   set_opt_constant_folding (0);  /* so that the stupid tests are not optimized. */
52   set_opt_cse(1);
53   set_opt_dead_node_elimination(1);
54
55   /* FIRM was designed for oo languages where all methods belong to a class.
56    * For imperative languages like C we view a file as a large class containing
57    * all functions as methods in this file.
58    * Therefore we define a class "empty" according to the file name
59    * with a method main as an entity.
60    */
61 #define CLASSNAME "IRR_LOOP"
62 #define METHODNAME "main"
63 #define NRARGS 0
64 #define NRES 0
65   printf("\nCreating an IR graph: %s...\n", CLASSNAME);
66
67   owner = new_type_class (id_from_str (CLASSNAME, strlen(CLASSNAME)));
68   proc_main = new_type_method(id_from_str(METHODNAME, strlen(METHODNAME)),
69                               NRARGS, NRES);
70   ent = new_entity (owner,
71                     id_from_str (METHODNAME, strlen(METHODNAME)),
72                     proc_main);
73   get_entity_ld_name(ent); /* To enforce name mangling for vcg graph name */
74
75 #define NUM_OF_LOCAL_VARS 0
76
77   irg = new_ir_graph (ent, NUM_OF_LOCAL_VARS);
78
79   /* to make three conditionals  */
80   expr = new_Const (mode_Is, new_tarval_from_long (0, mode_Is));
81   c1 = new_Const (mode_Is, new_tarval_from_long (1, mode_Is));
82   c2 = new_Const (mode_Is, new_tarval_from_long (2, mode_Is));
83   c3 = new_Const (mode_Is, new_tarval_from_long (2, mode_Is));
84
85   cond = new_Cond(new_Proj(new_Cmp(expr, c1), mode_b, Eq));
86   f = new_Proj(cond, mode_X, 0);
87   t = new_Proj(cond, mode_X, 1);
88   mature_block(get_irg_current_block(irg));
89
90   loopBlock1 = new_immBlock();
91   add_in_edge(loopBlock1, t);
92   cond = new_Cond(new_Proj(new_Cmp(expr, c2), mode_b, Eq));
93   f_l1 = new_Proj(cond, mode_X, 0);
94   t_l1 = new_Proj(cond, mode_X, 1);
95
96   loopBlock2 = new_immBlock();
97   add_in_edge(loopBlock2, f);
98   cond = new_Cond(new_Proj(new_Cmp(expr, c3), mode_b, Eq));
99   f_l2 = new_Proj(cond, mode_X, 0);
100   t_l2 = new_Proj(cond, mode_X, 1);
101
102   add_in_edge(loopBlock1, t_l2);
103   add_in_edge(loopBlock2, t_l1);
104   mature_block(loopBlock1);
105   mature_block(loopBlock2);
106
107   new_immBlock();
108   add_in_edge(get_irg_current_block(irg), f_l2);
109   add_in_edge(get_irg_current_block(irg), f_l1);
110   x = new_Return (get_store(), 0, NULL);
111   mature_block (get_irg_current_block(irg));
112
113   add_in_edge (get_irg_end_block(irg), x);
114   mature_block (get_irg_end_block(irg));
115
116   finalize_cons (irg);
117
118   printf("Optimizing ...\n");
119   dead_node_elimination(irg);
120
121   /* verify the graph */
122   irg_vrfy(irg);
123
124   printf("Dumping the graph and a control flow graph.\n");
125   dump_ir_block_graph (irg);
126   dump_cfg (irg);
127   printf("Use xvcg to view these graphs:\n");
128   printf("/ben/goetz/bin/xvcg GRAPHNAME\n\n");
129
130   return (0);
131 }