• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nickg / nvc / 13887457702

16 Mar 2025 09:12PM UTC coverage: 92.285% (-0.04%) from 92.324%
13887457702

push

github

nickg
Tag Docker images on releases. Fixes #1165

68273 of 73981 relevant lines covered (92.28%)

423265.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.86
/src/mir/mir-unit.c
1
//
2
//  Copyright (C) 2024-2025  Nick Gasson
3
//
4
//  This program is free software: you can redistribute it and/or modify
5
//  it under the terms of the GNU General Public License as published by
6
//  the Free Software Foundation, either version 3 of the License, or
7
//  (at your option) any later version.
8
//
9
//  This program is distributed in the hope that it will be useful,
10
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
//  GNU General Public License for more details.
13
//
14
//  You should have received a copy of the GNU General Public License
15
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
//
17

18
#include "util.h"
19
#include "hash.h"
20
#include "ident.h"
21
#include "lib.h"
22
#include "object.h"
23
#include "mir/mir-unit.h"
24
#include "mir/mir-node.h"
25
#include "mir/mir-priv.h"
26
#include "mir/mir-structs.h"
27
#include "thread.h"
28

29
#include <assert.h>
30
#include <stdlib.h>
31

32
#define TYPE_TAB_SIZE 256
33

34
mir_context_t *mir_context_new(void)
8,782✔
35
{
36
   mir_context_t *mc = xcalloc(sizeof(mir_context_t));
8,782✔
37
   mc->map  = chash_new(32);
8,782✔
38
   mc->pool = pool_new();
8,782✔
39

40
   type_tab_t *tab =
8,782✔
41
      xcalloc_flex(sizeof(type_tab_t), TYPE_TAB_SIZE, sizeof(type_data_t));
8,782✔
42
   tab->max_types = TYPE_TAB_SIZE;
8,782✔
43
   tab->hashtab = xcalloc_array(TYPE_TAB_SIZE, sizeof(uint32_t));
8,782✔
44

45
   store_release(&mc->resizing, tab);
8,782✔
46
   store_release(&mc->typetab, tab);
8,782✔
47

48
   return mc;
8,782✔
49
}
50

51
static void mir_unit_free_memory(mir_unit_t *mu)
42,818✔
52
{
53
#ifdef DEBUG
54
   if (mu->comments != NULL)
42,818✔
55
      tb_free(mu->comments);
5✔
56
#endif
57

58
   for (int i = 0; i < mu->blocks.count; i++)
177,801✔
59
      free(mu->blocks.items[i].nodes);
134,983✔
60

61
   ACLEAR(mu->blocks);
42,818✔
62
   ACLEAR(mu->params);
42,818✔
63
   ACLEAR(mu->vars);
42,818✔
64
   ACLEAR(mu->stamps);
42,818✔
65
   ACLEAR(mu->linkage);
42,818✔
66
   ACLEAR(mu->extvars);
42,818✔
67

68
   free(mu->nodes);
42,818✔
69
   free(mu->argspill);
42,818✔
70
   free(mu);
42,818✔
71
}
42,818✔
72

73
static void mir_free_unit_cb(const void *key, void *value)
31,515✔
74
{
75
   switch (pointer_tag(value)) {
31,515✔
76
   case UNIT_GENERATED:
31,514✔
77
      mir_unit_free_memory(untag_pointer(value, mir_unit_t));
31,514✔
78
      break;
31,514✔
79
   }
80
}
31,515✔
81

82
void mir_context_free(mir_context_t *mc)
8,765✔
83
{
84
   chash_iter(mc->map, mir_free_unit_cb);
8,765✔
85
   mir_free_types(mc->typetab);
8,765✔
86
   pool_free(mc->pool);
8,765✔
87
   chash_free(mc->map);
8,765✔
88
   free(mc);
8,765✔
89
}
8,765✔
90

91
mir_unit_t *mir_unit_new(mir_context_t *mc, ident_t name, object_t *object,
42,823✔
92
                         mir_unit_kind_t kind, mir_shape_t *parent)
93
{
94
   mir_unit_t *mu = xcalloc(sizeof(mir_unit_t));
42,823✔
95
   mu->context = mc;
42,823✔
96
   mu->name    = name;
42,823✔
97
   mu->object  = object;
42,823✔
98
   mu->kind    = kind;
42,823✔
99
   mu->parent  = parent;
42,823✔
100
   mu->result  = MIR_NULL_TYPE;
42,823✔
101

102
   mir_block_t entry = mir_add_block(mu);
42,823✔
103
   mir_set_cursor(mu, entry, MIR_APPEND);
42,823✔
104

105
   return mu;
42,823✔
106
}
107

108
mir_unit_kind_t mir_get_kind(mir_unit_t *mu)
251,003✔
109
{
110
   return mu->kind;
251,003✔
111
}
112

113
object_t *mir_get_object(mir_unit_t *mu)
42,770✔
114
{
115
   return mu->object;
42,770✔
116
}
117

118
ident_t mir_get_parent(mir_unit_t *mu)
×
119
{
120
   if (mu->parent != NULL)
×
121
      return mu->parent->name;
×
122
   else
123
      return NULL;
124
}
125

126
void *mir_malloc(mir_context_t *mc, size_t fixed, size_t nelems, size_t size)
11,832✔
127
{
128
   SCOPED_LOCK(mc->pool_mtx);
23,664✔
129
   return pool_malloc_flex(mc->pool, fixed, nelems, size);
11,832✔
130
}
131

132
static mir_shape_t *mir_build_shape(mir_unit_t *mu)
10,083✔
133
{
134
   mir_shape_t *sh = mir_malloc(mu->context, sizeof(mir_shape_t),
20,166✔
135
                                mu->vars.count, sizeof(shape_slot_t));
10,083✔
136
   sh->name      = mu->name;
10,083✔
137
   sh->kind      = mu->kind;
10,083✔
138
   sh->type      = mir_self_type(mu);
10,083✔
139
   sh->num_slots = mu->vars.count;
10,083✔
140
   sh->parent    = mu->parent;
10,083✔
141

142
   for (int i = 0; i < mu->vars.count; i++) {
36,039✔
143
      const var_data_t *vd = &(mu->vars.items[i]);
25,956✔
144
      sh->slots[i].name    = vd->name;
25,956✔
145
      sh->slots[i].type    = vd->type;
25,956✔
146
      sh->slots[i].pointer = vd->pointer;
25,956✔
147
   }
148

149
   return sh;
10,083✔
150
}
151

152
void mir_unit_free(mir_unit_t *mu)
11,304✔
153
{
154
   if (mu->name != NULL) {
11,304✔
155
      void *ptr = chash_get(mu->context->map, mu->name);
18✔
156
      switch (pointer_tag(ptr)) {
18✔
157
      case UNIT_GENERATED:
1✔
158
         {
159
            mir_shape_t *sh = mu->shape ?: mir_build_shape(mu);
1✔
160
            chash_put(mu->context->map, mu->name, tag_pointer(sh, UNIT_FREED));
1✔
161
         }
162
         break;
1✔
163
      case UNIT_FREED:
×
164
      case UNIT_DEFERRED:
165
         should_not_reach_here();
166
      default:
167
         break;
168
      }
169
   }
170

171
   mir_unit_free_memory(mu);
11,304✔
172
}
11,304✔
173

174
void mir_put_unit(mir_context_t *mc, mir_unit_t *mu)
31,519✔
175
{
176
   assert(mu->context == mc);
31,519✔
177

178
#ifdef DEBUG
179
   void *ptr = chash_get(mc->map, mu->name);
31,519✔
180
   if (ptr != NULL)
31,519✔
181
      fatal_trace("%s already registered", istr(mu->name));
182
#endif
183

184
   chash_put(mc->map, mu->name, tag_pointer(mu, UNIT_GENERATED));
31,519✔
185
}
31,519✔
186

187
mir_unit_t *mir_get_unit(mir_context_t *mc, ident_t name)
45,939✔
188
{
189
   void *ptr = chash_get(mc->map, name);
45,939✔
190
   if (ptr == NULL)
45,939✔
191
      return NULL;
192

193
   switch (pointer_tag(ptr)) {
14,534✔
194
   case UNIT_DEFERRED:
1✔
195
      {
196
         deferred_unit_t *du = untag_pointer(ptr, deferred_unit_t);
1✔
197

198
         mir_unit_t *mu =
1✔
199
            mir_unit_new(mc, name, du->object, du->kind, du->parent);
1✔
200
         (*du->fn)(mu, du->object);
1✔
201

202
         chash_put(mc->map, name, tag_pointer(mu, UNIT_GENERATED));
1✔
203
         return mu;
1✔
204
      }
205
   case UNIT_GENERATED:
14,533✔
206
      return untag_pointer(ptr, mir_unit_t);
14,533✔
207
   case UNIT_FREED:
×
208
      fatal_trace("unit %s has already been freed", istr(name));
209
   default:
×
210
      should_not_reach_here();
211
   }
212
}
213

214
mir_shape_t *mir_get_shape(mir_context_t *mc, ident_t name)
27,369✔
215
{
216
   void *ptr = chash_get(mc->map, name);
27,369✔
217
   if (ptr == NULL)
27,369✔
218
      return NULL;
219

220
   switch (pointer_tag(ptr)) {
27,255✔
221
   case UNIT_DEFERRED:
×
222
      {
223
         deferred_unit_t *du = untag_pointer(ptr, deferred_unit_t);
×
224

225
         mir_unit_t *mu =
×
226
            mir_unit_new(mc, name, du->object, du->kind, du->parent);
×
227
         (*du->fn)(mu, du->object);
×
228

229
         chash_put(mc->map, name, tag_pointer(mu, UNIT_GENERATED));
×
230

231
         return (mu->shape = mir_build_shape(mu));
×
232
      }
233
   case UNIT_GENERATED:
27,254✔
234
      {
235
         mir_unit_t *mu = untag_pointer(ptr, mir_unit_t);
27,254✔
236
         if (mu->shape != NULL)
27,254✔
237
            return mu->shape;
238

239
         return (mu->shape = mir_build_shape(mu));
10,083✔
240
      }
241
   case UNIT_FREED:
1✔
242
      return untag_pointer(ptr, mir_shape_t);
1✔
243
   default:
×
244
      should_not_reach_here();
245
   }
246
}
247

248
void mir_defer(mir_context_t *mc, ident_t name, mir_shape_t *parent,
1✔
249
               mir_unit_kind_t kind, mir_lower_fn_t fn, object_t *object)
250
{
251
#ifdef DEBUG
252
   void *ptr = chash_get(mc->map, name);
1✔
253
   if (ptr != NULL)
1✔
254
      fatal_trace("%s already registered", istr(name));
255
#endif
256

257
   deferred_unit_t *du = mir_malloc(mc, sizeof(deferred_unit_t), 0, 0);
1✔
258
   du->fn     = fn;
1✔
259
   du->parent = parent;
1✔
260
   du->kind   = kind;
1✔
261
   du->object = object;
1✔
262

263
   chash_put(mc->map, name, tag_pointer(du, UNIT_DEFERRED));
1✔
264
}
1✔
265

266
unsigned mir_count_linkage(mir_unit_t *mu)
14,454✔
267
{
268
   return mu->linkage.count;
14,454✔
269
}
270

271
ident_t mir_get_linkage(mir_unit_t *mu, unsigned nth)
28,345✔
272
{
273
   return AGET(mu->linkage, nth);
28,345✔
274
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc