First implementation of lowering for calls with compound return values
[libfirm] / testprograms / array-stack_example.c
1
2 /*
3  * Project:     libFIRM
4  * File name:   testprograms/array-stack_example.c
5  * Purpose:     Show representation of array on stack.
6  * Author:      Goetz Lindenmaier
7  * Modified by:
8  * Created:
9  * CVS-ID:      $Id$
10  * Copyright:   (c) 1999-2003 Universität Karlsruhe
11  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
12  */
13
14
15 # include <string.h>
16 # include <stdio.h>
17
18 # include "irvrfy.h"
19 # include "irdump.h"
20 # include "firm.h"
21
22 /**
23 *  imperative programs.
24 *  It constructs the IR for the following program:
25 *
26 *
27 *  main(): int
28 *    int a[10];
29 *
30 *    return (a[3]);
31 *  end;
32 *
33 *  The array is placed on the stack, i.e., a pointer to the array
34 *  is obtained by selecting the entity "a" from the stack.  The variables
35 *  on the stack are considered to be entities of the method, as locals
36 *  of a method are only visible within the method.  (An alternative to
37 *  make the method owner of the stack variables is to give the ownership
38 *  to the class representing the C-file.  This would extend the visibility
39 *  of the locals, though.)
40 **/
41
42
43 #define OPTIMIZE_NODE 0
44
45 int
46 main(void)
47 {
48   /* describes the general structure of a C-file */
49   type           *owner;        /* the class standing for everything in this file */
50   type           *proc_main;    /* Typeinformation for method main. */
51   entity         *proc_main_e;  /* The entity describing that method main is an
52                                    entity of the fake class representing the file. */
53
54   /* describes types defined by the language */
55   type           *prim_t_int;
56
57   /* describes the array and its fields. */
58   entity         *array_ent;    /* the entity representing the array as member
59                                    of the stack/method */
60   type           *array_type;   /* the type information for the array */
61   entity         *field_ent;    /* the entity representing a field of the
62                                    array */
63
64   /* holds the graph and nodes. */
65   ir_graph       *main_irg;
66   ir_node        *array_ptr, *c3, *elt, *val, *x;
67
68   init_firm (NULL);
69
70   printf("\nCreating an IR graph: ARRAY-STACK_EXAMPLE...\n");
71
72   /* make basic type information for primitive type int.
73      In Sather primitive types are represented by a class.
74      This is the modeling appropriate for other languages.
75      Mode_i says that all language-integers shall be implemented
76      as a 32 bit processor-integer value.  */
77   prim_t_int = new_type_primitive(new_id_from_chars ("int", 3), mode_Is);
78
79   /* build typeinformation of procedure main */
80   owner = new_type_class (new_id_from_chars ("ARRAY-STACK_EXAMPLE", 19));
81   proc_main = new_type_method(new_id_from_chars("main_tp", 7), 0, 1);
82   set_method_res_type(proc_main, 0, prim_t_int);
83   proc_main_e = new_entity (owner, new_id_from_chars ("main", 4), proc_main);
84   get_entity_ld_name(proc_main_e); /* force name mangling */
85
86   /* make type information for the array and set the bounds */
87 # define N_DIMS 1
88 # define L_BOUND 0
89 # define U_BOUND 9
90   array_type = new_type_array(new_id_from_chars("a_tp", 4), N_DIMS, prim_t_int);
91   current_ir_graph = get_const_code_irg();
92   set_array_bounds(array_type, 0,
93                    new_Const(mode_Iu, new_tarval_from_long (L_BOUND, mode_Iu)),
94                    new_Const(mode_Iu, new_tarval_from_long (U_BOUND, mode_Iu)));
95
96   main_irg = new_ir_graph (proc_main_e, 4);
97
98   /* The array is an entity of the method, placed on the mehtod's own memory,
99      the stack frame. */
100   array_ent = new_entity(get_cur_frame_type(), new_id_from_chars("a", 1), array_type);
101   /* As the array is accessed by Sel nodes, we need information about
102      the entity the node selects.  Entities of an array are it's elements
103      which are, in this case, integers. */
104   /* change entity owner types.   */
105   field_ent = get_array_element_entity(array_type);
106
107
108
109   /* Now the "real" program: */
110   /* Select the array from the stack frame.  */
111   array_ptr = new_simpleSel(get_store(), get_irg_frame(main_irg), array_ent);
112   /* Load element 3 of the array. For this first generate the pointer
113      to this the element by a select node.  (Alternative: increase
114      array pointer by (three * elt_size), but this complicates some
115      optimizations.) The type information accessible via the entity
116      allows to generate the pointer increment later. */
117   c3 = new_Const (mode_Iu, new_tarval_from_long (3, mode_Iu));
118   {
119      ir_node *in[1];
120      in[0] = c3;
121      elt = new_Sel(get_store(), array_ptr, 1, in, field_ent);
122   }
123   val = new_Load(get_store(), elt, mode_Is);
124   set_store(new_Proj(val, mode_M, 0));
125   val = new_Proj(val, mode_Is, 2);
126
127   /* return the result of procedure main */
128   {
129      ir_node *in[1];
130      in[0] = val;
131
132      x = new_Return (get_store (), 1, in);
133   }
134   mature_immBlock (get_irg_current_block(main_irg));
135
136   /* complete the end_block */
137   add_immBlock_pred (get_irg_end_block(main_irg), x);
138   mature_immBlock (get_irg_end_block(main_irg));
139
140   irg_finalize_cons (main_irg);
141
142   printf("Optimizing ...\n");
143   dead_node_elimination(main_irg);
144
145   /* verify the graph */
146   irg_vrfy(main_irg);
147   char *dump_file_suffix = "";
148   printf("Dumping the graph and a type graph.\n");
149   dump_ir_block_graph (main_irg, dump_file_suffix);
150   dump_type_graph(main_irg, dump_file_suffix);
151   dump_ir_block_graph_w_types(main_irg, dump_file_suffix);
152   dump_all_types(dump_file_suffix);
153   printf("Use xvcg to view these graphs:\n");
154   printf("/ben/goetz/bin/xvcg GRAPHNAME\n\n");
155
156   return (0);
157 }