sparse, llvm: Cleanup output_data()
[smatch.git] / sparse-llvm.c
blobf89f7a73a8f9c8d3600a8503c7ee4e2a29859171
1 /*
2 * Example usage:
3 * ./sparse-llvm hello.c | llc | as -o hello.o
4 */
6 #include <llvm-c/Core.h>
7 #include <llvm-c/BitWriter.h>
9 #include <stdbool.h>
10 #include <stdio.h>
11 #include <unistd.h>
12 #include <string.h>
13 #include <assert.h>
15 #include "symbol.h"
16 #include "expression.h"
17 #include "linearize.h"
18 #include "flow.h"
20 struct function {
21 LLVMBuilderRef builder;
22 LLVMTypeRef type;
23 LLVMValueRef fn;
24 LLVMModuleRef module;
27 static inline bool symbol_is_fp_type(struct symbol *sym)
29 return sym->ctype.base_type == &fp_type;
32 static LLVMTypeRef symbol_type(struct symbol *sym)
34 LLVMTypeRef ret = NULL;
36 if (symbol_is_fp_type(sym)) {
37 switch (sym->bit_size) {
38 case 32:
39 ret = LLVMFloatType();
40 break;
41 case 64:
42 ret = LLVMDoubleType();
43 break;
44 default:
45 die("invalid bit size %d for type %d", sym->bit_size, sym->type);
46 break;
48 } else {
49 switch (sym->bit_size) {
50 case -1:
51 ret = LLVMVoidType();
52 break;
53 case 8:
54 ret = LLVMInt8Type();
55 break;
56 case 16:
57 ret = LLVMInt16Type();
58 break;
59 case 32:
60 ret = LLVMInt32Type();
61 break;
62 case 64:
63 ret = LLVMInt64Type();
64 break;
65 default:
66 die("invalid bit size %d for type %d", sym->bit_size, sym->type);
67 break;
71 return ret;
74 static LLVMLinkage data_linkage(struct symbol *sym)
76 if (sym->ctype.modifiers & MOD_STATIC)
77 return LLVMPrivateLinkage;
79 return LLVMExternalLinkage;
82 static LLVMLinkage function_linkage(struct symbol *sym)
84 if (sym->ctype.modifiers & MOD_STATIC)
85 return LLVMInternalLinkage;
87 return LLVMExternalLinkage;
90 #define MAX_PSEUDO_NAME 64
92 static void pseudo_name(pseudo_t pseudo, char *buf)
94 switch (pseudo->type) {
95 case PSEUDO_REG:
96 snprintf(buf, MAX_PSEUDO_NAME, "R%d", pseudo->nr);
97 break;
98 case PSEUDO_SYM:
99 assert(0);
100 break;
101 case PSEUDO_VAL:
102 assert(0);
103 break;
104 case PSEUDO_ARG: {
105 assert(0);
106 break;
108 case PSEUDO_PHI:
109 snprintf(buf, MAX_PSEUDO_NAME, "PHI%d", pseudo->nr);
110 break;
111 default:
112 assert(0);
116 static LLVMValueRef pseudo_to_value(struct function *fn, pseudo_t pseudo)
118 LLVMValueRef result = NULL;
120 switch (pseudo->type) {
121 case PSEUDO_REG:
122 result = pseudo->priv;
123 break;
124 case PSEUDO_SYM: {
125 struct symbol *sym = pseudo->sym;
126 struct expression *expr;
128 assert(sym->bb_target == NULL);
129 assert(sym->ident == NULL);
131 expr = sym->initializer;
132 if (expr) {
133 switch (expr->type) {
134 case EXPR_STRING: {
135 const char *s = expr->string->data;
136 LLVMValueRef indices[] = { LLVMConstInt(LLVMInt64Type(), 0, 0), LLVMConstInt(LLVMInt64Type(), 0, 0) };
137 LLVMValueRef data;
139 data = LLVMAddGlobal(fn->module, LLVMArrayType(LLVMInt8Type(), strlen(s) + 1), ".str");
140 LLVMSetLinkage(data, LLVMPrivateLinkage);
141 LLVMSetGlobalConstant(data, 1);
142 LLVMSetInitializer(data, LLVMConstString(strdup(s), strlen(s) + 1, true));
144 result = LLVMConstGEP(data, indices, ARRAY_SIZE(indices));
145 break;
147 default:
148 assert(0);
151 break;
153 case PSEUDO_VAL:
154 result = LLVMConstInt(LLVMGetReturnType(fn->type), pseudo->value, 1);
155 break;
156 case PSEUDO_ARG: {
157 result = LLVMGetParam(fn->fn, pseudo->nr - 1);
158 break;
160 case PSEUDO_PHI:
161 result = pseudo->priv;
162 break;
163 case PSEUDO_VOID:
164 result = NULL;
165 break;
166 default:
167 assert(0);
170 return result;
173 static LLVMTypeRef pseudo_type(struct function *fn, pseudo_t pseudo)
175 LLVMValueRef v;
176 LLVMTypeRef result = NULL;
178 if (pseudo->priv) {
179 v = pseudo->priv;
180 return LLVMTypeOf(v);
183 switch (pseudo->type) {
184 case PSEUDO_REG:
185 result = symbol_type(pseudo->def->type);
186 break;
187 case PSEUDO_SYM: {
188 struct symbol *sym = pseudo->sym;
189 struct expression *expr;
191 assert(sym->bb_target == NULL);
192 assert(sym->ident == NULL);
194 expr = sym->initializer;
195 if (expr) {
196 switch (expr->type) {
197 case EXPR_STRING:
198 result = LLVMPointerType(LLVMInt8Type(), 0);
199 break;
200 default:
201 assert(0);
204 break;
206 case PSEUDO_VAL:
207 assert(0);
208 break;
209 case PSEUDO_ARG: {
210 assert(0);
211 break;
213 case PSEUDO_PHI:
214 assert(0);
215 break;
216 case PSEUDO_VOID:
217 result = LLVMVoidType();
218 break;
219 default:
220 assert(0);
223 return result;
226 static void output_op_binary(struct function *fn, struct instruction *insn)
228 LLVMValueRef lhs, rhs, target;
229 char target_name[64];
231 lhs = pseudo_to_value(fn, insn->src1);
233 rhs = pseudo_to_value(fn, insn->src2);
235 pseudo_name(insn->target, target_name);
237 switch (insn->opcode) {
238 /* Binary */
239 case OP_ADD:
240 if (symbol_is_fp_type(insn->type))
241 target = LLVMBuildFAdd(fn->builder, lhs, rhs, target_name);
242 else
243 target = LLVMBuildAdd(fn->builder, lhs, rhs, target_name);
244 break;
245 case OP_SUB:
246 if (symbol_is_fp_type(insn->type))
247 target = LLVMBuildFSub(fn->builder, lhs, rhs, target_name);
248 else
249 target = LLVMBuildSub(fn->builder, lhs, rhs, target_name);
250 break;
251 case OP_MULU:
252 if (symbol_is_fp_type(insn->type))
253 target = LLVMBuildFMul(fn->builder, lhs, rhs, target_name);
254 else
255 target = LLVMBuildMul(fn->builder, lhs, rhs, target_name);
256 break;
257 case OP_MULS:
258 assert(!symbol_is_fp_type(insn->type));
259 target = LLVMBuildMul(fn->builder, lhs, rhs, target_name);
260 break;
261 case OP_DIVU:
262 if (symbol_is_fp_type(insn->type))
263 target = LLVMBuildFDiv(fn->builder, lhs, rhs, target_name);
264 else
265 target = LLVMBuildUDiv(fn->builder, lhs, rhs, target_name);
266 break;
267 case OP_DIVS:
268 assert(!symbol_is_fp_type(insn->type));
269 target = LLVMBuildSDiv(fn->builder, lhs, rhs, target_name);
270 break;
271 case OP_MODU:
272 assert(!symbol_is_fp_type(insn->type));
273 target = LLVMBuildURem(fn->builder, lhs, rhs, target_name);
274 break;
275 case OP_MODS:
276 assert(!symbol_is_fp_type(insn->type));
277 target = LLVMBuildSRem(fn->builder, lhs, rhs, target_name);
278 break;
279 case OP_SHL:
280 assert(!symbol_is_fp_type(insn->type));
281 target = LLVMBuildShl(fn->builder, lhs, rhs, target_name);
282 break;
283 case OP_LSR:
284 assert(!symbol_is_fp_type(insn->type));
285 target = LLVMBuildLShr(fn->builder, lhs, rhs, target_name);
286 break;
287 case OP_ASR:
288 assert(!symbol_is_fp_type(insn->type));
289 target = LLVMBuildAShr(fn->builder, lhs, rhs, target_name);
290 break;
292 /* Logical */
293 case OP_AND:
294 assert(!symbol_is_fp_type(insn->type));
295 target = LLVMBuildAnd(fn->builder, lhs, rhs, target_name);
296 break;
297 case OP_OR:
298 assert(!symbol_is_fp_type(insn->type));
299 target = LLVMBuildOr(fn->builder, lhs, rhs, target_name);
300 break;
301 case OP_XOR:
302 assert(!symbol_is_fp_type(insn->type));
303 target = LLVMBuildXor(fn->builder, lhs, rhs, target_name);
304 break;
305 case OP_AND_BOOL:
306 assert(0);
307 break;
308 case OP_OR_BOOL:
309 assert(0);
310 break;
312 /* Binary comparison */
313 case OP_SET_EQ:
314 assert(!symbol_is_fp_type(insn->type));
315 target = LLVMBuildICmp(fn->builder, LLVMIntEQ, lhs, rhs, target_name);
316 break;
317 case OP_SET_NE:
318 assert(!symbol_is_fp_type(insn->type));
319 target = LLVMBuildICmp(fn->builder, LLVMIntNE, lhs, rhs, target_name);
320 break;
321 case OP_SET_LE:
322 assert(0);
323 break;
324 case OP_SET_GE:
325 assert(0);
326 break;
327 case OP_SET_LT:
328 assert(!symbol_is_fp_type(insn->type));
329 target = LLVMBuildICmp(fn->builder, LLVMIntSLT, lhs, rhs, target_name);
330 break;
331 case OP_SET_GT:
332 assert(!symbol_is_fp_type(insn->type));
333 target = LLVMBuildICmp(fn->builder, LLVMIntSGT, lhs, rhs, target_name);
334 break;
335 case OP_SET_B:
336 assert(0);
337 break;
338 case OP_SET_A:
339 assert(0);
340 break;
341 case OP_SET_BE:
342 assert(0);
343 break;
344 case OP_SET_AE:
345 assert(0);
346 break;
347 default:
348 assert(0);
349 break;
352 insn->target->priv = target;
355 static void output_op_ret(struct function *fn, struct instruction *insn)
357 pseudo_t pseudo = insn->src;
359 if (pseudo && pseudo != VOID) {
360 LLVMValueRef result = pseudo_to_value(fn, pseudo);
362 LLVMBuildRet(fn->builder, result);
363 } else
364 LLVMBuildRetVoid(fn->builder);
367 static void output_op_load(struct function *fn, struct instruction *insn)
369 LLVMTypeRef int_type;
370 LLVMValueRef src_p, src_i, ofs_i, addr_i, addr, target;
372 /* int type large enough to hold a pointer */
373 int_type = LLVMIntType(bits_in_pointer);
375 /* convert to integer, add src + offset */
376 src_p = pseudo_to_value(fn, insn->src);
377 src_i = LLVMBuildPtrToInt(fn->builder, src_p, int_type, "src_i");
379 ofs_i = LLVMConstInt(int_type, insn->offset, 0);
380 addr_i = LLVMBuildAdd(fn->builder, src_i, ofs_i, "addr_i");
382 /* convert address back to pointer */
383 addr = LLVMBuildIntToPtr(fn->builder, addr_i,
384 LLVMPointerType(int_type, 0), "addr");
386 /* perform load */
387 target = LLVMBuildLoad(fn->builder, addr, "load_target");
389 insn->target->priv = target;
392 static void output_op_br(struct function *fn, struct instruction *br)
394 if (br->cond) {
395 LLVMValueRef cond = pseudo_to_value(fn, br->cond);
397 LLVMBuildCondBr(fn->builder, cond,
398 br->bb_true->priv,
399 br->bb_false->priv);
400 } else
401 LLVMBuildBr(fn->builder,
402 br->bb_true ? br->bb_true->priv :
403 br->bb_false->priv);
406 static void output_op_sel(struct function *fn, struct instruction *insn)
408 LLVMValueRef target, src1, src2, src3;
410 src1 = pseudo_to_value(fn, insn->src1);
411 src2 = pseudo_to_value(fn, insn->src2);
412 src3 = pseudo_to_value(fn, insn->src3);
414 target = LLVMBuildSelect(fn->builder, src1, src2, src3, "select");
416 insn->target->priv = target;
419 static void output_op_switch(struct function *fn, struct instruction *insn)
421 LLVMValueRef sw_val, target;
422 struct basic_block *def = NULL;
423 struct multijmp *jmp;
424 int n_jmp = 0;
426 FOR_EACH_PTR(insn->multijmp_list, jmp) {
427 if (jmp->begin == jmp->end) { /* case N */
428 n_jmp++;
429 } else if (jmp->begin < jmp->end) { /* case M..N */
430 assert(0);
431 } else /* default case */
432 def = jmp->target;
433 } END_FOR_EACH_PTR(jmp);
435 sw_val = pseudo_to_value(fn, insn->target);
436 target = LLVMBuildSwitch(fn->builder, sw_val,
437 def ? def->priv : NULL, n_jmp);
439 FOR_EACH_PTR(insn->multijmp_list, jmp) {
440 if (jmp->begin == jmp->end) { /* case N */
441 LLVMAddCase(target,
442 LLVMConstInt(LLVMInt32Type(), jmp->begin, 0),
443 jmp->target->priv);
444 } else if (jmp->begin < jmp->end) { /* case M..N */
445 assert(0);
447 } END_FOR_EACH_PTR(jmp);
449 insn->target->priv = target;
452 struct llfunc {
453 char name[256]; /* wasteful */
454 LLVMValueRef func;
457 DECLARE_ALLOCATOR(llfunc);
458 DECLARE_PTR_LIST(llfunc_list, struct llfunc);
459 ALLOCATOR(llfunc, "llfuncs");
461 static struct local_module {
462 struct llfunc_list *llfunc_list;
463 } mi;
465 static LLVMTypeRef get_func_type(struct function *fn, struct instruction *insn)
467 struct symbol *sym = insn->func->sym;
468 char buffer[256];
469 LLVMTypeRef func_type, ret_type;
470 struct pseudo *arg;
471 int n_arg = 0;
472 LLVMTypeRef *arg_type;
474 sprintf(buffer, "%.*s", sym->ident->len, sym->ident->name);
476 /* VERIFY: is this correct, for functions? */
477 func_type = LLVMGetTypeByName(fn->module, buffer);
478 if (func_type)
479 return func_type;
481 /* to avoid strangeness with varargs [for now], we build
482 * the function and type anew, for each call. This
483 * is probably wrong. We should look up the
484 * symbol declaration info.
487 /* build return type */
488 if (insn->target && insn->target != VOID)
489 ret_type = pseudo_type(fn, insn->target);
490 else
491 ret_type = LLVMVoidType();
493 /* count args, build argument type information */
494 FOR_EACH_PTR(insn->arguments, arg) {
495 n_arg++;
496 } END_FOR_EACH_PTR(arg);
498 arg_type = calloc(n_arg, sizeof(LLVMTypeRef));
500 int idx = 0;
501 FOR_EACH_PTR(insn->arguments, arg) {
502 arg_type[idx++] = pseudo_type(fn, arg);
503 } END_FOR_EACH_PTR(arg);
505 func_type = LLVMFunctionType(ret_type, arg_type, n_arg,
506 /* varargs? */ 0);
508 return func_type;
511 static LLVMValueRef get_function(struct function *fn, struct instruction *insn)
513 struct symbol *sym = insn->func->sym;
514 char buffer[256];
515 LLVMValueRef func;
516 struct llfunc *f;
518 sprintf(buffer, "%.*s", sym->ident->len, sym->ident->name);
520 /* search for pre-built function type definition */
521 FOR_EACH_PTR(mi.llfunc_list, f) {
522 if (!strcmp(f->name, buffer))
523 return f->func; /* found match; return */
524 } END_FOR_EACH_PTR(f);
526 /* build function type definition */
527 LLVMTypeRef func_type = get_func_type(fn, insn);
529 func = LLVMAddFunction(fn->module, buffer, func_type);
531 /* store built function on list, for later */
532 f = calloc(1, sizeof(*f));
533 strncpy(f->name, buffer, sizeof(f->name) - 1);
534 f->func = func;
536 add_ptr_list(&mi.llfunc_list, f);
538 return func;
541 static void output_op_call(struct function *fn, struct instruction *insn)
543 LLVMValueRef target, func;
544 int n_arg = 0, i;
545 struct pseudo *arg;
546 LLVMValueRef *args;
548 FOR_EACH_PTR(insn->arguments, arg) {
549 n_arg++;
550 } END_FOR_EACH_PTR(arg);
552 args = calloc(n_arg, sizeof(LLVMValueRef));
554 i = 0;
555 FOR_EACH_PTR(insn->arguments, arg) {
556 args[i++] = pseudo_to_value(fn, arg);
557 } END_FOR_EACH_PTR(arg);
559 func = get_function(fn, insn);
560 target = LLVMBuildCall(fn->builder, func, args, n_arg, "");
562 insn->target->priv = target;
565 static void output_op_phi(struct function *fn, struct instruction *insn)
567 pseudo_t phi;
568 LLVMValueRef target;
570 target = LLVMBuildPhi(fn->builder, symbol_type(insn->type),
571 "phi");
572 int pll = 0;
573 FOR_EACH_PTR(insn->phi_list, phi) {
574 if (pseudo_to_value(fn, phi)) /* skip VOID */
575 pll++;
576 } END_FOR_EACH_PTR(phi);
578 LLVMValueRef *phi_vals = calloc(pll, sizeof(LLVMValueRef));
579 LLVMBasicBlockRef *phi_blks = calloc(pll, sizeof(LLVMBasicBlockRef));
581 int idx = 0;
582 FOR_EACH_PTR(insn->phi_list, phi) {
583 LLVMValueRef v;
585 v = pseudo_to_value(fn, phi);
586 if (v) { /* skip VOID */
587 phi_vals[idx] = v;
588 phi_blks[idx] = phi->def->bb->priv;
589 idx++;
591 } END_FOR_EACH_PTR(phi);
593 LLVMAddIncoming(target, phi_vals, phi_blks, pll);
595 insn->target->priv = target;
598 static void output_op_cast(struct function *fn, struct instruction *insn)
600 LLVMValueRef src, target;
601 char target_name[64];
603 src = insn->src->priv;
605 pseudo_name(insn->target, target_name);
607 if (symbol_is_fp_type(insn->type))
608 target = LLVMBuildFPCast(fn->builder, src, symbol_type(insn->type), target_name);
609 else
610 target = LLVMBuildIntCast(fn->builder, src, symbol_type(insn->type), target_name);
612 insn->target->priv = target;
615 static void output_insn(struct function *fn, struct instruction *insn)
617 switch (insn->opcode) {
618 case OP_RET:
619 output_op_ret(fn, insn);
620 break;
621 case OP_BR:
622 output_op_br(fn, insn);
623 break;
624 case OP_SYMADDR:
625 assert(0);
626 break;
627 case OP_SETVAL:
628 assert(0);
629 break;
630 case OP_SWITCH:
631 output_op_switch(fn, insn);
632 break;
633 case OP_COMPUTEDGOTO:
634 assert(0);
635 break;
636 case OP_PHISOURCE:
637 /* target = src */
638 insn->target->priv = pseudo_to_value(fn, insn->phi_src);
639 break;
640 case OP_PHI:
641 output_op_phi(fn, insn);
642 break;
643 case OP_LOAD:
644 output_op_load(fn, insn);
645 break;
646 case OP_LNOP:
647 assert(0);
648 break;
649 case OP_STORE: case OP_SNOP:
650 assert(0);
651 break;
652 case OP_INLINED_CALL:
653 assert(0);
654 break;
655 case OP_CALL:
656 output_op_call(fn, insn);
657 break;
658 case OP_CAST:
659 output_op_cast(fn, insn);
660 break;
661 case OP_SCAST:
662 assert(0);
663 break;
664 case OP_FPCAST:
665 assert(0);
666 break;
667 case OP_PTRCAST:
668 assert(0);
669 break;
670 case OP_BINARY ... OP_BINARY_END:
671 case OP_BINCMP ... OP_BINCMP_END:
672 output_op_binary(fn, insn);
673 break;
674 case OP_SEL:
675 output_op_sel(fn, insn);
676 break;
677 case OP_SLICE:
678 assert(0);
679 break;
680 case OP_NOT: {
681 LLVMValueRef src, target;
682 char target_name[64];
684 src = pseudo_to_value(fn, insn->src);
686 pseudo_name(insn->target, target_name);
688 target = LLVMBuildNot(fn->builder, src, target_name);
690 insn->target->priv = target;
691 break;
693 case OP_NEG:
694 assert(0);
695 break;
696 case OP_CONTEXT:
697 assert(0);
698 break;
699 case OP_RANGE:
700 assert(0);
701 break;
702 case OP_NOP:
703 assert(0);
704 break;
705 case OP_DEATHNOTE:
706 assert(0);
707 break;
708 case OP_ASM:
709 assert(0);
710 break;
711 case OP_COPY: {
712 LLVMValueRef src, target;
713 char target_name[64];
715 pseudo_name(insn->target, target_name);
716 src = pseudo_to_value(fn, insn->src);
718 target = LLVMBuildAdd(fn->builder, src,
719 LLVMConstInt(LLVMInt32Type(), 0, 0), target_name);
721 insn->target->priv = target;
722 break;
724 default:
725 break;
729 static void output_bb(struct function *fn, struct basic_block *bb, unsigned long generation)
731 struct instruction *insn;
733 bb->generation = generation;
735 FOR_EACH_PTR(bb->insns, insn) {
736 if (!insn->bb)
737 continue;
739 output_insn(fn, insn);
741 END_FOR_EACH_PTR(insn);
744 #define MAX_ARGS 64
746 static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
748 unsigned long generation = ++bb_generation;
749 struct symbol *sym = ep->name;
750 struct symbol *base_type = sym->ctype.base_type;
751 struct symbol *ret_type = sym->ctype.base_type->ctype.base_type;
752 LLVMTypeRef arg_types[MAX_ARGS];
753 LLVMTypeRef return_type;
754 struct function function;
755 struct basic_block *bb;
756 struct symbol *arg;
757 const char *name;
758 int nr_args = 0;
760 FOR_EACH_PTR(base_type->arguments, arg) {
761 struct symbol *arg_base_type = arg->ctype.base_type;
763 arg_types[nr_args++] = symbol_type(arg_base_type);
764 } END_FOR_EACH_PTR(arg);
766 name = show_ident(sym->ident);
768 return_type = symbol_type(ret_type);
770 function.module = module;
772 function.type = LLVMFunctionType(return_type, arg_types, nr_args, 0);
774 function.fn = LLVMAddFunction(module, name, function.type);
775 LLVMSetFunctionCallConv(function.fn, LLVMCCallConv);
777 LLVMSetLinkage(function.fn, function_linkage(sym));
779 function.builder = LLVMCreateBuilder();
781 static int nr_bb;
783 FOR_EACH_PTR(ep->bbs, bb) {
784 if (bb->generation == generation)
785 continue;
787 LLVMBasicBlockRef bbr;
788 char bbname[32];
790 sprintf(bbname, "L%d", nr_bb++);
791 bbr = LLVMAppendBasicBlock(function.fn, bbname);
793 bb->priv = bbr;
795 END_FOR_EACH_PTR(bb);
797 FOR_EACH_PTR(ep->bbs, bb) {
798 if (bb->generation == generation)
799 continue;
801 LLVMPositionBuilderAtEnd(function.builder, bb->priv);
803 output_bb(&function, bb, generation);
805 END_FOR_EACH_PTR(bb);
808 static int output_data(LLVMModuleRef module, struct symbol *sym)
810 struct expression *initializer = sym->initializer;
811 LLVMValueRef initial_value;
812 LLVMValueRef data;
813 const char *name;
815 if (initializer) {
816 if (initializer->type == EXPR_VALUE)
817 initial_value = LLVMConstInt(symbol_type(sym), initializer->value, 1);
818 else
819 assert(0);
820 } else {
821 initial_value = LLVMConstInt(symbol_type(sym), 0, 1);
824 name = show_ident(sym->ident);
826 data = LLVMAddGlobal(module, symbol_type(sym->ctype.base_type), name);
828 LLVMSetLinkage(data, data_linkage(sym));
830 LLVMSetInitializer(data, initial_value);
832 return 0;
835 static int compile(LLVMModuleRef module, struct symbol_list *list)
837 struct symbol *sym;
839 FOR_EACH_PTR(list, sym) {
840 struct entrypoint *ep;
841 expand_symbol(sym);
842 ep = linearize_symbol(sym);
843 if (ep)
844 output_fn(module, ep);
845 else
846 output_data(module, sym);
848 END_FOR_EACH_PTR(sym);
850 return 0;
853 int main(int argc, char **argv)
855 struct string_list * filelist = NULL;
856 char *file;
858 LLVMModuleRef module = LLVMModuleCreateWithName("sparse");
860 compile(module, sparse_initialize(argc, argv, &filelist));
862 FOR_EACH_PTR_NOTAG(filelist, file) {
863 compile(module, sparse(file));
864 } END_FOR_EACH_PTR_NOTAG(file);
866 LLVMWriteBitcodeToFD(module, STDOUT_FILENO, 0, 0);
868 LLVMDisposeModule(module);
870 return 0;