-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathworklist.c
136 lines (121 loc) · 2.23 KB
/
worklist.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "worklist.h"
worklist_t
WL_newlist()
{
// always have empty node(t = NULL)
// you'll never delete this node
// so a list can't be NULL
worklist_t wl = checked_malloc(sizeof(*wl));
wl->lid = listcnt++;
wl->prev = wl->next = NULL;
wl->t = NULL;
}
worklist_t
WL_newnode(Temp_temp temp)
{
worklist_t wl = checked_malloc(sizeof(*wl));
wl->lid = -1; // when add, it'll be set
wl->prev = wl->next = NULL;
wl->t = temp;
}
void
WL_delete(worklist_t* head, worklist_t node)
{
assert(*head);
assert( (*head)->t);
assert(!(*head)->prev); // is it really head?
if ((*head)->lid != node->lid) {
// assert(0);
return;
}
node->lid = -1;
if (node == *head) {
// new head
*head = (*head)->next;
(*head)->prev = NULL;
}
else {
node->prev->next = node->next;
node->next->prev = node->prev;
}
}
// void
// WL_add(worklist_t* head, Temp_temp t)
//{
// WL_addn(head, WL_newnode(t));
//}
void
WL_add(worklist_t* head, worklist_t node)
{
// add to new head.
if ((*head)->lid == node->lid) {
// assert(0);
return;
}
(*head)->prev = node;
node->next = *head;
node->prev = NULL;
node->lid = (*head)->lid;
*head = node;
}
inline bool
WL_empty(worklist_t head)
{
// always have empty node(see WL_newlist)
return !head->t;
}
static TAB_table n2wmap;
void
WL_newn2w(G_nodeList nl)
{
n2wmap = TAB_empty();
for (; nl; nl = nl->tail) {
if (nl) {
TAB_enter(n2wmap, nl->head, WL_newnode(G_nodeInfo(nl->head)));
}
}
}
worklist_t
n2w(G_node n)
{
return TAB_look(n2wmap, n);
}
worklist_t
WL_pop(worklist_t* head)
{
if ((*head)->t) {
worklist_t w = *head;
*head = w->next;
(*head)->prev = NULL;
w->next = NULL;
w->lid = -1;
return w;
}
return NULL;
}
bool
WL_in(worklist_t head, worklist_t node)
{
return head->lid == node->lid;
}
inline static worklist_t
t2w(Temp_temp t)
{
return n2w(t2n(t));
}
worklist_t
WL_excepttl(worklist_t w1, Temp_tempList tl)
{
for (; tl; tl = tl->tail) {
if (WL_in(w1, t2w(tl->head))) WL_delete(&w1, t2w(tl->head));
}
return w1;
}
worklist_t
WL_cattl(worklist_t w1, Temp_tempList tl)
{
for (; tl; tl = tl->tail) {
if (!WL_in(w1, t2w(tl->head))) WL_add(&w1, t2w(tl->head));
}
return w1;
}