3 * ./sparse-llvm hello.c | llc | as -o hello.o
6 #include <llvm-c/Core.h>
7 #include <llvm-c/BitWriter.h>
16 #include "expression.h"
17 #include "linearize.h"
21 LLVMBuilderRef builder
;
27 static inline bool symbol_is_fp_type(struct symbol
*sym
)
32 return sym
->ctype
.base_type
== &fp_type
;
35 static LLVMTypeRef
symbol_type(LLVMModuleRef module
, struct symbol
*sym
);
37 static LLVMTypeRef
func_return_type(LLVMModuleRef module
, struct symbol
*sym
)
39 return symbol_type(module
, sym
->ctype
.base_type
);
42 static LLVMTypeRef
sym_func_type(LLVMModuleRef module
, struct symbol
*sym
)
44 LLVMTypeRef
*arg_type
;
45 LLVMTypeRef func_type
;
50 /* to avoid strangeness with varargs [for now], we build
51 * the function and type anew, for each call. This
52 * is probably wrong. We should look up the
53 * symbol declaration info.
56 ret_type
= func_return_type(module
, sym
);
58 /* count args, build argument type information */
59 FOR_EACH_PTR(sym
->arguments
, arg
) {
61 } END_FOR_EACH_PTR(arg
);
63 arg_type
= calloc(n_arg
, sizeof(LLVMTypeRef
));
66 FOR_EACH_PTR(sym
->arguments
, arg
) {
67 struct symbol
*arg_sym
= arg
->ctype
.base_type
;
69 arg_type
[idx
++] = symbol_type(module
, arg_sym
);
70 } END_FOR_EACH_PTR(arg
);
71 func_type
= LLVMFunctionType(ret_type
, arg_type
, n_arg
,
77 static LLVMTypeRef
sym_array_type(LLVMModuleRef module
, struct symbol
*sym
)
79 LLVMTypeRef elem_type
;
80 struct symbol
*base_type
;
82 base_type
= sym
->ctype
.base_type
;
84 elem_type
= symbol_type(module
, base_type
);
88 return LLVMArrayType(elem_type
, sym
->bit_size
/ 8);
91 #define MAX_STRUCT_MEMBERS 64
93 static LLVMTypeRef
sym_struct_type(LLVMModuleRef module
, struct symbol
*sym
)
95 LLVMTypeRef elem_types
[MAX_STRUCT_MEMBERS
];
96 struct symbol
*member
;
101 sprintf(buffer
, "%.*s", sym
->ident
->len
, sym
->ident
->name
);
103 ret
= LLVMGetTypeByName(module
, buffer
);
107 ret
= LLVMStructCreateNamed(LLVMGetGlobalContext(), buffer
);
109 FOR_EACH_PTR(sym
->symbol_list
, member
) {
110 LLVMTypeRef member_type
;
112 assert(nr
< MAX_STRUCT_MEMBERS
);
114 member_type
= symbol_type(module
, member
);
116 elem_types
[nr
++] = member_type
;
117 } END_FOR_EACH_PTR(member
);
119 LLVMStructSetBody(ret
, elem_types
, nr
, 0 /* packed? */);
123 static LLVMTypeRef
sym_union_type(LLVMModuleRef module
, struct symbol
*sym
)
125 LLVMTypeRef elements
;
129 * There's no union support in the LLVM API so we treat unions as
130 * opaque structs. The downside is that we lose type information on the
131 * members but as LLVM doesn't care, neither do we.
133 union_size
= sym
->bit_size
/ 8;
135 elements
= LLVMArrayType(LLVMInt8Type(), union_size
);
137 return LLVMStructType(&elements
, 1, 0 /* packed? */);
140 static LLVMTypeRef
sym_ptr_type(LLVMModuleRef module
, struct symbol
*sym
)
142 LLVMTypeRef type
= symbol_type(module
, sym
->ctype
.base_type
);
144 return LLVMPointerType(type
, 0);
147 static LLVMTypeRef
sym_basetype_type(struct symbol
*sym
)
149 LLVMTypeRef ret
= NULL
;
151 if (symbol_is_fp_type(sym
)) {
152 switch (sym
->bit_size
) {
154 ret
= LLVMFloatType();
157 ret
= LLVMDoubleType();
160 ret
= LLVMX86FP80Type();
163 die("invalid bit size %d for type %d", sym
->bit_size
, sym
->type
);
167 switch (sym
->bit_size
) {
168 case -1: /* 'void *' is treated like 'char *' */
170 ret
= LLVMInt8Type();
173 ret
= LLVMInt16Type();
176 ret
= LLVMInt32Type();
179 ret
= LLVMInt64Type();
182 die("invalid bit size %d for type %d", sym
->bit_size
, sym
->type
);
190 static LLVMTypeRef
symbol_type(LLVMModuleRef module
, struct symbol
*sym
)
192 LLVMTypeRef ret
= NULL
;
198 ret
= symbol_type(module
, sym
->ctype
.base_type
);
201 ret
= sym_basetype_type(sym
);
204 ret
= sym_ptr_type(module
, sym
);
207 ret
= sym_union_type(module
, sym
);
210 ret
= sym_struct_type(module
, sym
);
213 ret
= sym_array_type(module
, sym
);
216 ret
= sym_func_type(module
, sym
);
224 static LLVMTypeRef
insn_symbol_type(LLVMModuleRef module
, struct instruction
*insn
)
227 return symbol_type(module
, insn
->type
);
229 switch (insn
->size
) {
230 case 8: return LLVMInt8Type();
231 case 16: return LLVMInt16Type();
232 case 32: return LLVMInt32Type();
233 case 64: return LLVMInt64Type();
236 die("invalid bit size %d", insn
->size
);
240 return NULL
; /* not reached */
243 static LLVMLinkage
data_linkage(struct symbol
*sym
)
245 if (sym
->ctype
.modifiers
& MOD_STATIC
)
246 return LLVMPrivateLinkage
;
248 return LLVMExternalLinkage
;
251 static LLVMLinkage
function_linkage(struct symbol
*sym
)
253 if (sym
->ctype
.modifiers
& MOD_STATIC
)
254 return LLVMInternalLinkage
;
256 return LLVMExternalLinkage
;
259 #define MAX_PSEUDO_NAME 64
261 static void pseudo_name(pseudo_t pseudo
, char *buf
)
263 switch (pseudo
->type
) {
265 snprintf(buf
, MAX_PSEUDO_NAME
, "R%d", pseudo
->nr
);
278 snprintf(buf
, MAX_PSEUDO_NAME
, "PHI%d", pseudo
->nr
);
285 static LLVMValueRef
pseudo_to_value(struct function
*fn
, struct instruction
*insn
, pseudo_t pseudo
)
287 LLVMValueRef result
= NULL
;
289 switch (pseudo
->type
) {
291 result
= pseudo
->priv
;
294 struct symbol
*sym
= pseudo
->sym
;
295 struct expression
*expr
;
297 assert(sym
->bb_target
== NULL
);
298 assert(sym
->ident
== NULL
);
300 expr
= sym
->initializer
;
302 switch (expr
->type
) {
304 const char *s
= expr
->string
->data
;
305 LLVMValueRef indices
[] = { LLVMConstInt(LLVMInt64Type(), 0, 0), LLVMConstInt(LLVMInt64Type(), 0, 0) };
308 data
= LLVMAddGlobal(fn
->module
, LLVMArrayType(LLVMInt8Type(), strlen(s
) + 1), ".str");
309 LLVMSetLinkage(data
, LLVMPrivateLinkage
);
310 LLVMSetGlobalConstant(data
, 1);
311 LLVMSetInitializer(data
, LLVMConstString(strdup(s
), strlen(s
) + 1, true));
313 result
= LLVMConstGEP(data
, indices
, ARRAY_SIZE(indices
));
323 result
= LLVMConstInt(insn_symbol_type(fn
->module
, insn
), pseudo
->value
, 1);
326 result
= LLVMGetParam(fn
->fn
, pseudo
->nr
- 1);
330 result
= pseudo
->priv
;
342 static LLVMTypeRef
pseudo_type(struct function
*fn
, struct instruction
*insn
, pseudo_t pseudo
)
345 LLVMTypeRef result
= NULL
;
349 return LLVMTypeOf(v
);
352 switch (pseudo
->type
) {
354 result
= symbol_type(fn
->module
, pseudo
->def
->type
);
357 struct symbol
*sym
= pseudo
->sym
;
358 struct expression
*expr
;
360 assert(sym
->bb_target
== NULL
);
361 assert(sym
->ident
== NULL
);
363 expr
= sym
->initializer
;
365 switch (expr
->type
) {
367 result
= LLVMPointerType(LLVMInt8Type(), 0);
376 result
= insn_symbol_type(fn
->module
, insn
);
379 result
= LLVMTypeOf(LLVMGetParam(fn
->fn
, pseudo
->nr
- 1));
385 result
= LLVMVoidType();
394 static void output_op_binary(struct function
*fn
, struct instruction
*insn
)
396 LLVMValueRef lhs
, rhs
, target
;
397 char target_name
[64];
399 lhs
= pseudo_to_value(fn
, insn
, insn
->src1
);
401 rhs
= pseudo_to_value(fn
, insn
, insn
->src2
);
403 pseudo_name(insn
->target
, target_name
);
405 switch (insn
->opcode
) {
408 if (symbol_is_fp_type(insn
->type
))
409 target
= LLVMBuildFAdd(fn
->builder
, lhs
, rhs
, target_name
);
411 target
= LLVMBuildAdd(fn
->builder
, lhs
, rhs
, target_name
);
414 if (symbol_is_fp_type(insn
->type
))
415 target
= LLVMBuildFSub(fn
->builder
, lhs
, rhs
, target_name
);
417 target
= LLVMBuildSub(fn
->builder
, lhs
, rhs
, target_name
);
420 if (symbol_is_fp_type(insn
->type
))
421 target
= LLVMBuildFMul(fn
->builder
, lhs
, rhs
, target_name
);
423 target
= LLVMBuildMul(fn
->builder
, lhs
, rhs
, target_name
);
426 assert(!symbol_is_fp_type(insn
->type
));
427 target
= LLVMBuildMul(fn
->builder
, lhs
, rhs
, target_name
);
430 if (symbol_is_fp_type(insn
->type
))
431 target
= LLVMBuildFDiv(fn
->builder
, lhs
, rhs
, target_name
);
433 target
= LLVMBuildUDiv(fn
->builder
, lhs
, rhs
, target_name
);
436 assert(!symbol_is_fp_type(insn
->type
));
437 target
= LLVMBuildSDiv(fn
->builder
, lhs
, rhs
, target_name
);
440 assert(!symbol_is_fp_type(insn
->type
));
441 target
= LLVMBuildURem(fn
->builder
, lhs
, rhs
, target_name
);
444 assert(!symbol_is_fp_type(insn
->type
));
445 target
= LLVMBuildSRem(fn
->builder
, lhs
, rhs
, target_name
);
448 assert(!symbol_is_fp_type(insn
->type
));
449 target
= LLVMBuildShl(fn
->builder
, lhs
, rhs
, target_name
);
452 assert(!symbol_is_fp_type(insn
->type
));
453 target
= LLVMBuildLShr(fn
->builder
, lhs
, rhs
, target_name
);
456 assert(!symbol_is_fp_type(insn
->type
));
457 target
= LLVMBuildAShr(fn
->builder
, lhs
, rhs
, target_name
);
462 assert(!symbol_is_fp_type(insn
->type
));
463 target
= LLVMBuildAnd(fn
->builder
, lhs
, rhs
, target_name
);
466 assert(!symbol_is_fp_type(insn
->type
));
467 target
= LLVMBuildOr(fn
->builder
, lhs
, rhs
, target_name
);
470 assert(!symbol_is_fp_type(insn
->type
));
471 target
= LLVMBuildXor(fn
->builder
, lhs
, rhs
, target_name
);
476 assert(!symbol_is_fp_type(insn
->type
));
478 y
= LLVMBuildICmp(fn
->builder
, LLVMIntNE
, lhs
, LLVMConstInt(LLVMTypeOf(lhs
), 0, 0), "y");
479 x
= LLVMBuildICmp(fn
->builder
, LLVMIntNE
, rhs
, LLVMConstInt(LLVMTypeOf(rhs
), 0, 0), "x");
481 target
= LLVMBuildAnd(fn
->builder
, y
, x
, target_name
);
487 assert(!symbol_is_fp_type(insn
->type
));
489 tmp
= LLVMBuildOr(fn
->builder
, rhs
, lhs
, "tmp");
491 target
= LLVMBuildICmp(fn
->builder
, LLVMIntNE
, tmp
, LLVMConstInt(LLVMTypeOf(tmp
), 0, 0), target_name
);
495 /* Binary comparison */
497 assert(!symbol_is_fp_type(insn
->type
));
498 target
= LLVMBuildICmp(fn
->builder
, LLVMIntEQ
, lhs
, rhs
, target_name
);
501 assert(!symbol_is_fp_type(insn
->type
));
502 target
= LLVMBuildICmp(fn
->builder
, LLVMIntNE
, lhs
, rhs
, target_name
);
511 assert(!symbol_is_fp_type(insn
->type
));
512 target
= LLVMBuildICmp(fn
->builder
, LLVMIntSLT
, lhs
, rhs
, target_name
);
515 assert(!symbol_is_fp_type(insn
->type
));
516 target
= LLVMBuildICmp(fn
->builder
, LLVMIntSGT
, lhs
, rhs
, target_name
);
519 target
= LLVMBuildICmp(fn
->builder
, LLVMIntULT
, lhs
, rhs
, target_name
);
522 target
= LLVMBuildICmp(fn
->builder
, LLVMIntUGT
, lhs
, rhs
, target_name
);
535 insn
->target
->priv
= target
;
538 static void output_op_ret(struct function
*fn
, struct instruction
*insn
)
540 pseudo_t pseudo
= insn
->src
;
542 if (pseudo
&& pseudo
!= VOID
) {
543 LLVMValueRef result
= pseudo_to_value(fn
, insn
, pseudo
);
545 LLVMBuildRet(fn
->builder
, result
);
547 LLVMBuildRetVoid(fn
->builder
);
550 static void output_op_load(struct function
*fn
, struct instruction
*insn
)
552 LLVMTypeRef int_type
;
553 LLVMValueRef src_p
, src_i
, ofs_i
, addr_i
, addr
, target
;
555 /* int type large enough to hold a pointer */
556 int_type
= LLVMIntType(bits_in_pointer
);
558 /* convert to integer, add src + offset */
559 src_p
= pseudo_to_value(fn
, insn
, insn
->src
);
560 src_i
= LLVMBuildPtrToInt(fn
->builder
, src_p
, int_type
, "src_i");
562 ofs_i
= LLVMConstInt(int_type
, insn
->offset
, 0);
563 addr_i
= LLVMBuildAdd(fn
->builder
, src_i
, ofs_i
, "addr_i");
565 /* convert address back to pointer */
566 addr
= LLVMBuildIntToPtr(fn
->builder
, addr_i
,
567 LLVMPointerType(int_type
, 0), "addr");
570 target
= LLVMBuildLoad(fn
->builder
, addr
, "load_target");
572 insn
->target
->priv
= target
;
575 static void output_op_store(struct function
*fn
, struct instruction
*insn
)
577 LLVMTypeRef int_type
;
578 LLVMValueRef src_p
, src_i
, ofs_i
, addr_i
, addr
, target
, target_in
;
580 /* int type large enough to hold a pointer */
581 int_type
= LLVMIntType(bits_in_pointer
);
583 /* convert to integer, add src + offset */
584 src_p
= pseudo_to_value(fn
, insn
, insn
->src
);
585 src_i
= LLVMBuildPtrToInt(fn
->builder
, src_p
, int_type
, "src_i");
587 ofs_i
= LLVMConstInt(int_type
, insn
->offset
, 0);
588 addr_i
= LLVMBuildAdd(fn
->builder
, src_i
, ofs_i
, "addr_i");
590 /* convert address back to pointer */
591 addr
= LLVMBuildIntToPtr(fn
->builder
, addr_i
,
592 LLVMPointerType(int_type
, 0), "addr");
594 target_in
= pseudo_to_value(fn
, insn
, insn
->target
);
597 target
= LLVMBuildStore(fn
->builder
, target_in
, addr
);
599 insn
->target
->priv
= target
;
602 static void output_op_br(struct function
*fn
, struct instruction
*br
)
605 LLVMValueRef cond
= pseudo_to_value(fn
, br
, br
->cond
);
607 LLVMBuildCondBr(fn
->builder
, cond
,
611 LLVMBuildBr(fn
->builder
,
612 br
->bb_true
? br
->bb_true
->priv
:
616 static void output_op_sel(struct function
*fn
, struct instruction
*insn
)
618 LLVMValueRef target
, src1
, src2
, src3
;
620 src1
= pseudo_to_value(fn
, insn
, insn
->src1
);
621 src2
= pseudo_to_value(fn
, insn
, insn
->src2
);
622 src3
= pseudo_to_value(fn
, insn
, insn
->src3
);
624 target
= LLVMBuildSelect(fn
->builder
, src1
, src2
, src3
, "select");
626 insn
->target
->priv
= target
;
629 static void output_op_switch(struct function
*fn
, struct instruction
*insn
)
631 LLVMValueRef sw_val
, target
;
632 struct basic_block
*def
= NULL
;
633 struct multijmp
*jmp
;
636 FOR_EACH_PTR(insn
->multijmp_list
, jmp
) {
637 if (jmp
->begin
== jmp
->end
) { /* case N */
639 } else if (jmp
->begin
< jmp
->end
) { /* case M..N */
641 } else /* default case */
643 } END_FOR_EACH_PTR(jmp
);
645 sw_val
= pseudo_to_value(fn
, insn
, insn
->target
);
646 target
= LLVMBuildSwitch(fn
->builder
, sw_val
,
647 def
? def
->priv
: NULL
, n_jmp
);
649 FOR_EACH_PTR(insn
->multijmp_list
, jmp
) {
650 if (jmp
->begin
== jmp
->end
) { /* case N */
652 LLVMConstInt(LLVMInt32Type(), jmp
->begin
, 0),
654 } else if (jmp
->begin
< jmp
->end
) { /* case M..N */
657 } END_FOR_EACH_PTR(jmp
);
659 insn
->target
->priv
= target
;
663 char name
[256]; /* wasteful */
667 DECLARE_ALLOCATOR(llfunc
);
668 DECLARE_PTR_LIST(llfunc_list
, struct llfunc
);
669 ALLOCATOR(llfunc
, "llfuncs");
671 static struct local_module
{
672 struct llfunc_list
*llfunc_list
;
675 static LLVMTypeRef
get_func_type(struct function
*fn
, struct instruction
*insn
)
677 struct symbol
*sym
= insn
->func
->sym
;
679 LLVMTypeRef func_type
, ret_type
;
682 LLVMTypeRef
*arg_type
;
685 sprintf(buffer
, "%.*s", sym
->ident
->len
, sym
->ident
->name
);
687 sprintf(buffer
, "<anon sym %p>", sym
);
689 /* VERIFY: is this correct, for functions? */
690 func_type
= LLVMGetTypeByName(fn
->module
, buffer
);
694 /* to avoid strangeness with varargs [for now], we build
695 * the function and type anew, for each call. This
696 * is probably wrong. We should look up the
697 * symbol declaration info.
700 /* build return type */
701 if (insn
->target
&& insn
->target
!= VOID
)
702 ret_type
= pseudo_type(fn
, insn
, insn
->target
);
704 ret_type
= LLVMVoidType();
706 /* count args, build argument type information */
707 FOR_EACH_PTR(insn
->arguments
, arg
) {
709 } END_FOR_EACH_PTR(arg
);
711 arg_type
= calloc(n_arg
, sizeof(LLVMTypeRef
));
714 FOR_EACH_PTR(insn
->arguments
, arg
) {
715 arg_type
[idx
++] = pseudo_type(fn
, insn
, arg
);
716 } END_FOR_EACH_PTR(arg
);
718 func_type
= LLVMFunctionType(ret_type
, arg_type
, n_arg
,
724 static LLVMValueRef
get_function(struct function
*fn
, struct instruction
*insn
)
726 struct symbol
*sym
= insn
->func
->sym
;
732 sprintf(buffer
, "%.*s", sym
->ident
->len
, sym
->ident
->name
);
734 sprintf(buffer
, "<anon sym %p>", sym
);
737 /* search for pre-built function type definition */
738 FOR_EACH_PTR(mi
.llfunc_list
, f
) {
739 if (!strcmp(f
->name
, buffer
))
740 return f
->func
; /* found match; return */
741 } END_FOR_EACH_PTR(f
);
743 /* build function type definition */
744 LLVMTypeRef func_type
= get_func_type(fn
, insn
);
746 func
= LLVMAddFunction(fn
->module
, buffer
, func_type
);
748 /* store built function on list, for later referencing */
749 f
= calloc(1, sizeof(*f
));
750 strncpy(f
->name
, buffer
, sizeof(f
->name
) - 1);
753 add_ptr_list(&mi
.llfunc_list
, f
);
758 static void output_op_call(struct function
*fn
, struct instruction
*insn
)
760 LLVMValueRef target
, func
;
765 FOR_EACH_PTR(insn
->arguments
, arg
) {
767 } END_FOR_EACH_PTR(arg
);
769 args
= calloc(n_arg
, sizeof(LLVMValueRef
));
772 FOR_EACH_PTR(insn
->arguments
, arg
) {
773 args
[i
++] = pseudo_to_value(fn
, insn
, arg
);
774 } END_FOR_EACH_PTR(arg
);
776 func
= get_function(fn
, insn
);
777 target
= LLVMBuildCall(fn
->builder
, func
, args
, n_arg
, "");
779 insn
->target
->priv
= target
;
782 static void output_op_phi(struct function
*fn
, struct instruction
*insn
)
787 target
= LLVMBuildPhi(fn
->builder
, insn_symbol_type(fn
->module
, insn
),
790 FOR_EACH_PTR(insn
->phi_list
, phi
) {
791 if (pseudo_to_value(fn
, insn
, phi
)) /* skip VOID */
793 } END_FOR_EACH_PTR(phi
);
795 LLVMValueRef
*phi_vals
= calloc(pll
, sizeof(LLVMValueRef
));
796 LLVMBasicBlockRef
*phi_blks
= calloc(pll
, sizeof(LLVMBasicBlockRef
));
799 FOR_EACH_PTR(insn
->phi_list
, phi
) {
802 v
= pseudo_to_value(fn
, insn
, phi
);
803 if (v
) { /* skip VOID */
805 phi_blks
[idx
] = phi
->def
->bb
->priv
;
808 } END_FOR_EACH_PTR(phi
);
810 LLVMAddIncoming(target
, phi_vals
, phi_blks
, pll
);
812 insn
->target
->priv
= target
;
815 static void output_op_ptrcast(struct function
*fn
, struct instruction
*insn
)
817 LLVMValueRef src
, target
;
818 char target_name
[64];
820 src
= insn
->src
->priv
;
822 src
= pseudo_to_value(fn
, insn
, insn
->src
);
824 pseudo_name(insn
->target
, target_name
);
826 assert(!symbol_is_fp_type(insn
->type
));
828 target
= LLVMBuildBitCast(fn
->builder
, src
, insn_symbol_type(fn
->module
, insn
), target_name
);
830 insn
->target
->priv
= target
;
833 static void output_op_cast(struct function
*fn
, struct instruction
*insn
, LLVMOpcode op
)
835 LLVMValueRef src
, target
;
836 char target_name
[64];
838 src
= insn
->src
->priv
;
840 src
= pseudo_to_value(fn
, insn
, insn
->src
);
842 pseudo_name(insn
->target
, target_name
);
844 assert(!symbol_is_fp_type(insn
->type
));
846 if (insn
->size
< LLVMGetIntTypeWidth(LLVMTypeOf(src
)))
847 target
= LLVMBuildTrunc(fn
->builder
, src
, insn_symbol_type(fn
->module
, insn
), target_name
);
849 target
= LLVMBuildCast(fn
->builder
, op
, src
, insn_symbol_type(fn
->module
, insn
), target_name
);
851 insn
->target
->priv
= target
;
854 static void output_op_copy(struct function
*fn
, struct instruction
*insn
,
857 LLVMValueRef src
, target
;
858 LLVMTypeRef const_type
;
859 char target_name
[64];
861 pseudo_name(insn
->target
, target_name
);
862 src
= pseudo_to_value(fn
, insn
, pseudo
);
863 const_type
= insn_symbol_type(fn
->module
, insn
);
866 * This is nothing more than 'target = src'
868 * TODO: find a better way to provide an identity function,
869 * than using "X + 0" simply to produce a new LLVM pseudo
872 if (symbol_is_fp_type(insn
->type
))
873 target
= LLVMBuildFAdd(fn
->builder
, src
,
874 LLVMConstReal(const_type
, 0.0), target_name
);
876 target
= LLVMBuildAdd(fn
->builder
, src
,
877 LLVMConstInt(const_type
, 0, 0), target_name
);
879 insn
->target
->priv
= target
;
882 static void output_insn(struct function
*fn
, struct instruction
*insn
)
884 switch (insn
->opcode
) {
886 output_op_ret(fn
, insn
);
889 output_op_br(fn
, insn
);
898 output_op_switch(fn
, insn
);
900 case OP_COMPUTEDGOTO
:
905 insn
->target
->priv
= pseudo_to_value(fn
, insn
, insn
->phi_src
);
908 output_op_phi(fn
, insn
);
911 output_op_load(fn
, insn
);
917 output_op_store(fn
, insn
);
922 case OP_INLINED_CALL
:
926 output_op_call(fn
, insn
);
929 output_op_cast(fn
, insn
, LLVMZExt
);
932 output_op_cast(fn
, insn
, LLVMSExt
);
938 output_op_ptrcast(fn
, insn
);
940 case OP_BINARY
... OP_BINARY_END
:
941 case OP_BINCMP
... OP_BINCMP_END
:
942 output_op_binary(fn
, insn
);
945 output_op_sel(fn
, insn
);
951 LLVMValueRef src
, target
;
952 char target_name
[64];
954 src
= pseudo_to_value(fn
, insn
, insn
->src
);
956 pseudo_name(insn
->target
, target_name
);
958 target
= LLVMBuildNot(fn
->builder
, src
, target_name
);
960 insn
->target
->priv
= target
;
982 output_op_copy(fn
, insn
, insn
->src
);
989 static void output_bb(struct function
*fn
, struct basic_block
*bb
, unsigned long generation
)
991 struct instruction
*insn
;
993 bb
->generation
= generation
;
995 FOR_EACH_PTR(bb
->insns
, insn
) {
999 output_insn(fn
, insn
);
1001 END_FOR_EACH_PTR(insn
);
1006 static void output_fn(LLVMModuleRef module
, struct entrypoint
*ep
)
1008 unsigned long generation
= ++bb_generation
;
1009 struct symbol
*sym
= ep
->name
;
1010 struct symbol
*base_type
= sym
->ctype
.base_type
;
1011 struct symbol
*ret_type
= sym
->ctype
.base_type
->ctype
.base_type
;
1012 LLVMTypeRef arg_types
[MAX_ARGS
];
1013 LLVMTypeRef return_type
;
1014 struct function function
;
1015 struct basic_block
*bb
;
1021 FOR_EACH_PTR(base_type
->arguments
, arg
) {
1022 struct symbol
*arg_base_type
= arg
->ctype
.base_type
;
1024 arg_types
[nr_args
++] = symbol_type(module
, arg_base_type
);
1025 } END_FOR_EACH_PTR(arg
);
1027 name
= show_ident(sym
->ident
);
1029 return_type
= symbol_type(module
, ret_type
);
1031 function
.module
= module
;
1033 function
.type
= LLVMFunctionType(return_type
, arg_types
, nr_args
, 0);
1035 function
.fn
= LLVMAddFunction(module
, name
, function
.type
);
1036 LLVMSetFunctionCallConv(function
.fn
, LLVMCCallConv
);
1038 LLVMSetLinkage(function
.fn
, function_linkage(sym
));
1040 /* store built function on list, for later referencing */
1041 f
= calloc(1, sizeof(*f
));
1042 strncpy(f
->name
, name
, sizeof(f
->name
) - 1);
1043 f
->func
= function
.fn
;
1045 add_ptr_list(&mi
.llfunc_list
, f
);
1047 function
.builder
= LLVMCreateBuilder();
1051 FOR_EACH_PTR(ep
->bbs
, bb
) {
1052 if (bb
->generation
== generation
)
1055 LLVMBasicBlockRef bbr
;
1058 sprintf(bbname
, "L%d", nr_bb
++);
1059 bbr
= LLVMAppendBasicBlock(function
.fn
, bbname
);
1063 END_FOR_EACH_PTR(bb
);
1065 FOR_EACH_PTR(ep
->bbs
, bb
) {
1066 if (bb
->generation
== generation
)
1069 LLVMPositionBuilderAtEnd(function
.builder
, bb
->priv
);
1071 output_bb(&function
, bb
, generation
);
1073 END_FOR_EACH_PTR(bb
);
1076 static LLVMValueRef
output_data(LLVMModuleRef module
, struct symbol
*sym
)
1078 struct expression
*initializer
= sym
->initializer
;
1079 LLVMValueRef initial_value
;
1084 switch (initializer
->type
) {
1086 initial_value
= LLVMConstInt(symbol_type(module
, sym
), initializer
->value
, 1);
1089 struct symbol
*sym
= initializer
->symbol
;
1091 initial_value
= LLVMGetNamedGlobal(module
, show_ident(sym
->ident
));
1093 initial_value
= output_data(module
, sym
);
1100 LLVMTypeRef type
= symbol_type(module
, sym
);
1102 initial_value
= LLVMConstNull(type
);
1105 name
= show_ident(sym
->ident
);
1107 data
= LLVMAddGlobal(module
, symbol_type(module
, sym
->ctype
.base_type
), name
);
1109 LLVMSetLinkage(data
, data_linkage(sym
));
1111 if (!(sym
->ctype
.modifiers
& MOD_EXTERN
))
1112 LLVMSetInitializer(data
, initial_value
);
1117 static int compile(LLVMModuleRef module
, struct symbol_list
*list
)
1121 FOR_EACH_PTR(list
, sym
) {
1122 struct entrypoint
*ep
;
1124 ep
= linearize_symbol(sym
);
1126 output_fn(module
, ep
);
1128 output_data(module
, sym
);
1130 END_FOR_EACH_PTR(sym
);
1135 int main(int argc
, char **argv
)
1137 struct string_list
* filelist
= NULL
;
1140 LLVMModuleRef module
= LLVMModuleCreateWithName("sparse");
1142 compile(module
, sparse_initialize(argc
, argv
, &filelist
));
1144 FOR_EACH_PTR_NOTAG(filelist
, file
) {
1145 compile(module
, sparse(file
));
1146 } END_FOR_EACH_PTR_NOTAG(file
);
1148 LLVMWriteBitcodeToFD(module
, STDOUT_FILENO
, 0, 0);
1150 LLVMDisposeModule(module
);