belive_t.h 2.98 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

20
/**
Christian Würdig's avatar
Christian Würdig committed
21
22
23
24
 * @file
 * @brief       Internal headers for liveness analysis.
 * @author      Sebastian Hack
 * @date        06.12.2004
25
 */
Christian Würdig's avatar
Christian Würdig committed
26
27
#ifndef FIRM_BE_BELIVE_T_H
#define FIRM_BE_BELIVE_T_H
28

29
#include <stdbool.h>
30
#include "irnodehashmap.h"
Sebastian Hack's avatar
Sebastian Hack committed
31
#include "irhooks.h"
32
#include "irlivechk.h"
Sebastian Hack's avatar
Sebastian Hack committed
33
#include "belive.h"
34

35
36
37
38
#define be_is_live_in(lv, bl, irn)    _be_is_live_xxx(lv, bl, irn, be_lv_state_in)
#define be_is_live_end(lv, bl, irn)   _be_is_live_xxx(lv, bl, irn, be_lv_state_end)
#define be_is_live_out(lv, bl, irn)   _be_is_live_xxx(lv, bl, irn, be_lv_state_out)

39
struct be_lv_t {
40
41
	ir_nodehashmap_t map;
	struct obstack   obst;
42
	bool             sets_valid;
43
44
	ir_graph        *irg;
	lv_chk_t        *lvc;
Sebastian Hack's avatar
Sebastian Hack committed
45
46
};

47
48
typedef struct be_lv_info_node_t be_lv_info_node_t;
struct be_lv_info_node_t {
49
	ir_node *node;
Sebastian Hack's avatar
Sebastian Hack committed
50
51
52
	unsigned flags;
};

53
struct be_lv_info_head_t {
Sebastian Hack's avatar
Sebastian Hack committed
54
55
56
57
	unsigned n_members;
	unsigned n_size;
};

58
59
60
union be_lv_info_t {
	struct be_lv_info_head_t head;
	struct be_lv_info_node_t node;
Sebastian Hack's avatar
Sebastian Hack committed
61
62
};

63
64
be_lv_info_node_t *be_lv_get(const be_lv_t *li, const ir_node *block,
                             const ir_node *irn);
65

66
67
static inline unsigned _be_is_live_xxx(const be_lv_t *li, const ir_node *block,
                                       const ir_node *irn, unsigned flags)
Sebastian Hack's avatar
Sebastian Hack committed
68
{
69
	unsigned res;
Sebastian Hack's avatar
Sebastian Hack committed
70

71
	if (li->sets_valid) {
72
		be_lv_info_node_t *info = be_lv_get(li, block, irn);
73
		res = info != NULL ? (info->flags & flags) != 0 : 0;
74
	} else {
Sebastian Hack's avatar
Sebastian Hack committed
75
		res = (lv_chk_bl_xxx(li->lvc, block, irn) & flags) != 0;
76
	}
Sebastian Hack's avatar
Sebastian Hack committed
77
78

	return res;
79
80
}

81
82
83
84
85
86
87
typedef struct lv_iterator_t
{
	be_lv_info_t *info;
	size_t        i;
} lv_iterator_t;

static inline lv_iterator_t be_lv_iteration_begin(const be_lv_t *lv,
88
	const ir_node *block)
89
90
91
92
93
94
95
{
	lv_iterator_t res;
	res.info  = ir_nodehashmap_get(be_lv_info_t, &lv->map, block);
	res.i     = res.info != NULL ? res.info[0].head.n_members : 0;
	return res;
}

96
static inline ir_node *be_lv_iteration_next(lv_iterator_t *iterator, be_lv_state_t flags)
97
98
99
{
	while (iterator->i != 0) {
		const be_lv_info_t *info = iterator->info + iterator->i--;
100
101
		if (info->node.flags & flags)
			return info->node.node;
102
103
104
	}
	return NULL;
}
Sebastian Hack's avatar
Sebastian Hack committed
105

106
107
#define be_lv_foreach(lv, block, flags, node) \
	for (bool once = true; once;) \
108
109
		for (lv_iterator_t iter = be_lv_iteration_begin((lv), (block)); once; once = false) \
			for (ir_node *node; (node = be_lv_iteration_next(&iter, (flags))) != NULL;)
Sebastian Hack's avatar
Sebastian Hack committed
110

111
#endif