irargs.c 7.74 KB
Newer Older
1
2
3
4
5
6
7
8
/*
 * Project:     libFIRM
 * File name:   ir/ir/irargs.c
 * Purpose:     Support for libcore IR object output.
 * Author:      Sebastian Hack
 * Modified by:
 * Created:
 * CVS-ID:      $Id$
9
 * Copyright:   (c) 1998-2005 Universitaet Karlsruhe
10
11
12
13
14
15
16
 * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

17
18
#ifdef WITH_LIBCORE

19
20
#include "bitset.h"

21
#include <ctype.h>
Sebastian Hack's avatar
Sebastian Hack committed
22
#include <libcore/lc_printf.h>
23
24

#include "firm_common.h"
25
26
27
28
#include "irnode_t.h"
#include "entity_t.h"
#include "irloop_t.h"
#include "tv_t.h"
29
#include "dbginfo_t.h"
30
31
32
33

/**
 * identify a firm object type
 */
Sebastian Hack's avatar
Sebastian Hack committed
34
static int firm_get_arg_type(const lc_arg_occ_t *occ) {
35
  /* Firm objects are always pointer */
Sebastian Hack's avatar
Sebastian Hack committed
36
  return lc_arg_type_ptr;
37
38
}

Sebastian Hack's avatar
Sebastian Hack committed
39
static int firm_get_arg_type_int(const lc_arg_occ_t *occ) {
Sebastian Hack's avatar
Sebastian Hack committed
40
  return lc_arg_type_int;
41
42
}

43

Sebastian Hack's avatar
Sebastian Hack committed
44
static int bitset_get_arg_type(const lc_arg_occ_t *occ) {
Sebastian Hack's avatar
Sebastian Hack committed
45
  return lc_arg_type_ptr;
46
47
}

Sebastian Hack's avatar
Sebastian Hack committed
48
49
static int bitset_emit(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
50
51
52
53
54
55
56
{
  int res = 2;
  bitset_t *b = arg->v_ptr;
  bitset_pos_t p;
  char buf[32];
  const char *prefix = "";

Sebastian Hack's avatar
Sebastian Hack committed
57
  lc_arg_append(app, occ, "[", 1);
Sebastian Hack's avatar
Sebastian Hack committed
58
  bitset_foreach(b, p) {
59
60
61
    int n;

    n = snprintf(buf, sizeof(buf), "%s%d", prefix, (int) p);
Sebastian Hack's avatar
Sebastian Hack committed
62
    lc_arg_append(app, occ, buf, n);
63
64
65
    prefix = ", ";
    res += n;
  }
Sebastian Hack's avatar
Sebastian Hack committed
66
  lc_arg_append(app, occ, "]", 1);
67
68
69
70

  return res;
}

71
72
73
/**
 * emit an opaque Firm dbg_info object
 */
Sebastian Hack's avatar
Sebastian Hack committed
74
75
static int firm_emit_dbg(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
76
77
78
79
80
81
82
83
84
85
{
  char buf[1024];
  ir_node *irn = arg->v_ptr;
  dbg_info *dbg = get_irn_dbg_info(irn);

  buf[0] = '\0';
  if (dbg && __dbg_info_snprint) {
    if (__dbg_info_snprint(buf, sizeof(buf), dbg) <= 0)
      buf[0] = '\0';
  }
Sebastian Hack's avatar
Sebastian Hack committed
86
  return lc_arg_append(app, occ, buf, strlen(buf));
87
88
}

89
90
91
92
93
94
95
96
97
/**
 * Beware: do not set the entity ld_name
 */
static const char *get_entity_ld_name_ex(entity *ent) {
  if (ent->ld_name)
    return get_entity_ld_name(ent);
  return get_entity_name(ent);
}

98
99
100
/**
 * emit a Firm object
 */
Sebastian Hack's avatar
Sebastian Hack committed
101
102
static int firm_emit(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
103
{
104
#define A(s)    occ->flag_hash ? s " ": ""
105
106
107
108
109

  void *X = arg->v_ptr;
  firm_kind *obj = X;
  int i, n;
  ir_node *block;
110
  char add[64];
111
  char buf[256];
112
  char tv_buf[256];
113
  entity *ent;
114
115

  buf[0] = '\0';
116
  add[0] = '\0';
117
118
119
120
121
122

  if (! X)
    strncpy(buf, "(null)", sizeof(buf));
  else {
    switch (*obj) {
    case k_BAD:
123
124
      snprintf(buf, sizeof(buf), "BAD");
      snprintf(add, sizeof(add), "[%p]", X);
125
126
      break;
    case k_entity:
127
      snprintf(buf, sizeof(buf), "%s%s", A("ent"),
128
          isupper(occ->conversion) ? get_entity_ld_name_ex(X): get_entity_name(X));
129
      snprintf(add, sizeof(add), "[%ld]", get_entity_nr(X));
130
131
      break;
    case k_type:
132
133
      snprintf(buf, sizeof(buf), "%s%s:%s", A("type"), get_type_tpop_name(X), get_type_name(X));
      snprintf(add, sizeof(add), "[%ld]", get_type_nr(X));
134
135
      break;
    case k_ir_graph:
136
137
      snprintf(buf, sizeof(buf), "%s%s", A("irg"), get_entity_name(get_irg_entity(X)));
      snprintf(add, sizeof(add), "[%ld]", get_irg_graph_nr(X));
138
139
140
141
142
      break;
    case k_ir_node:
      switch (occ->conversion) {
      case 'B':
        block = is_no_Block(X) ? get_nodes_block(X) : X;
143
144
145
        snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(block),
            get_mode_name(get_irn_mode(block)));
        snprintf(add, sizeof(add), "[%ld]", get_irn_node_nr(block));
146
147
148
149
150
        break;
      case 'N':
        snprintf(buf, sizeof(buf), "%ld", get_irn_node_nr(X));
        break;
      default:
Rubino Geiß's avatar
Rubino Geiß committed
151
        if (is_Const(X)) {
152
153
154
155
156
          tarval *tv = get_Const_tarval(X);
          if (tv)
            tarval_snprintf(tv_buf, sizeof(tv_buf), tv);
          else
            strncpy(tv_buf, "(NULL)", sizeof(tv_buf));
157
          snprintf(buf, sizeof(buf), "%s%s%s<%s>", A("irn"), get_irn_opname(X),
158
            get_mode_name(get_irn_mode(X)), tv_buf);
159
160
161
        }
        else
          snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(X),
162
            get_mode_name(get_irn_mode(X)));
Sebastian Hack's avatar
Sebastian Hack committed
163
        snprintf(add, sizeof(add), "[%ld:%d]", get_irn_node_nr(X), get_irn_idx(X));
164
165
166
167
168
169
      }
      break;
    case k_ir_mode:
      snprintf(buf, sizeof(buf), "%s%s", A("mode"), get_mode_name(X));
      break;
    case k_tarval:
170
171
      tarval_snprintf(tv_buf, sizeof(tv_buf), X);
      snprintf(buf, sizeof(buf), "%s%s", A("tv"), tv_buf);
172
173
174
175
176
177
178
179
180
      break;
    case k_ir_loop:
      snprintf(buf, sizeof(buf), "ldepth[%d]", get_loop_depth(X));
      break;
    case k_ir_op:
      snprintf(buf, sizeof(buf), "%s%s", A("op"), get_op_name(X));
      break;
    case k_ir_compound_graph_path:
      n = get_compound_graph_path_length(X);
181

182
      for (i = 0; i < n; ++i) {
183
184
185
        ent = get_compound_graph_path_node(X, i);

        strncat(buf, ".", sizeof(buf));
186
        strncat(buf, get_entity_name(ent), sizeof(buf));
187
188
189
190
191
        if (is_Array_type(get_entity_owner(ent))) {
          snprintf(add, sizeof(add), "[%d]",
            get_compound_graph_path_array_index(X, i));
          strncat(buf, add, sizeof(buf));
        }
192
      }
193
      add[0] = '\0';
194
      break;
195
196
197
198
    case k_ir_extblk:
      snprintf(buf, sizeof(buf), "ExtBlock");
      snprintf(add, sizeof(add), "[%ld]", get_irn_node_nr(get_extbb_leader(X)));
      break;
199

200
    default:
201
202
      snprintf(buf, sizeof(buf), "UNKWN");
      snprintf(add, sizeof(add), "[%p]", X);
203
204
    }
  }
205

206
  if (occ->flag_plus)
207
208
  	strncat(buf, add, sizeof(buf));

Sebastian Hack's avatar
Sebastian Hack committed
209
  return lc_arg_append(app, occ, buf, strlen(buf));
210
211
212
213
214
215
216

#undef A
}

/**
 * emit an ident
 */
Sebastian Hack's avatar
Sebastian Hack committed
217
218
static int firm_emit_ident(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
219
220
221
222
{
  ident *id = (ident *)arg->v_ptr;
  const char *p = id ? get_id_str(id) : "(null)";

Sebastian Hack's avatar
Sebastian Hack committed
223
  return lc_arg_append(app, occ, p, strlen(p));
224
225
}

226
227
228
/**
 * Emit indent.
 */
Sebastian Hack's avatar
Sebastian Hack committed
229
230
static int firm_emit_indent(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
231
232
{
	int i;
233
	int amount = arg->v_int * (occ->width > 0 ? occ->width : 1);
234
235

	for(i = 0; i < amount; ++i)
Sebastian Hack's avatar
Sebastian Hack committed
236
		lc_appendable_chadd(app, ' ');
237
238
239
240

	return amount;
}

241
242
243
/**
 * Emit pnc.
 */
Sebastian Hack's avatar
Sebastian Hack committed
244
245
static int firm_emit_pnc(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
246
247
248
249
{
  int value = arg->v_int;
  const char *p = get_pnc_string(value);

Sebastian Hack's avatar
Sebastian Hack committed
250
  return lc_arg_append(app, occ, p, strlen(p));
251
252
}

Sebastian Hack's avatar
Sebastian Hack committed
253
lc_arg_env_t *firm_get_arg_env(void)
254
255
256
{
#define X(name, letter) {"firm:" name, letter}

Sebastian Hack's avatar
Sebastian Hack committed
257
  static lc_arg_env_t *env = NULL;
258

Sebastian Hack's avatar
Sebastian Hack committed
259
260
261
262
263
264
  static lc_arg_handler_t firm_handler   = { firm_get_arg_type, firm_emit };
  static lc_arg_handler_t ident_handler  = { firm_get_arg_type, firm_emit_ident };
  static lc_arg_handler_t indent_handler = { firm_get_arg_type_int, firm_emit_indent };
  static lc_arg_handler_t pnc_handler    = { firm_get_arg_type_int, firm_emit_pnc };
  static lc_arg_handler_t bitset_handler = { bitset_get_arg_type, bitset_emit };
  static lc_arg_handler_t debug_handler  = { firm_get_arg_type, firm_emit_dbg };
265
266
267
268
269
270
271
272
273
274
275
276
277
278

  static struct {
    const char *name;
    char letter;
  } args[] = {
    X("type",      't'),
    X("entity",    'e'),
    X("entity_ld", 'E'),
    X("tarval",    'T'),
    X("irn",       'n'),
    X("op",        'O'),
    X("irn_nr",    'N'),
    X("mode",      'm'),
    X("block",     'B'),
279
    X("pnc",       '='),
280
    X("cg_path",   'P'),
281
282
283
284
285
  };

  int i;

  if(env == NULL) {
Sebastian Hack's avatar
Sebastian Hack committed
286
287
    env = lc_arg_new_env();
    lc_arg_add_std(env);
288

Sebastian Hack's avatar
Sebastian Hack committed
289
    lc_arg_register(env, "firm", 'F', &firm_handler);
290
    for (i = 0; i < sizeof(args)/sizeof(args[0]); ++i)
Sebastian Hack's avatar
Sebastian Hack committed
291
      lc_arg_register(env, args[i].name, args[i].letter, &firm_handler);
292

Sebastian Hack's avatar
Sebastian Hack committed
293
294
    lc_arg_register(env, "firm:ident",    'I', &ident_handler);
    lc_arg_register(env, "firm:indent",   '>', &indent_handler);
295
    lc_arg_register(env, "firm:dbg_info", 'G', &debug_handler);
Sebastian Hack's avatar
Sebastian Hack committed
296
    lc_arg_register(env, "firm:bitset",   'B', &bitset_handler);
297
298
299
300
  }

  return env;
}
301
302

#endif /* WITH_LIBCORE */