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"
29 LLVMBuilderRef builder
;
34 struct phi_fwd
*fwd_list
;
37 static inline bool symbol_is_fp_type(struct symbol
*sym
)
42 return sym
->ctype
.base_type
== &fp_type
;
45 static LLVMTypeRef
symbol_type(LLVMModuleRef module
, struct symbol
*sym
);
47 static LLVMTypeRef
func_return_type(LLVMModuleRef module
, struct symbol
*sym
)
49 return symbol_type(module
, sym
->ctype
.base_type
);
52 static LLVMTypeRef
sym_func_type(LLVMModuleRef module
, struct symbol
*sym
)
54 LLVMTypeRef
*arg_type
;
55 LLVMTypeRef func_type
;
60 /* to avoid strangeness with varargs [for now], we build
61 * the function and type anew, for each call. This
62 * is probably wrong. We should look up the
63 * symbol declaration info.
66 ret_type
= func_return_type(module
, sym
);
68 /* count args, build argument type information */
69 FOR_EACH_PTR(sym
->arguments
, arg
) {
71 } END_FOR_EACH_PTR(arg
);
73 arg_type
= calloc(n_arg
, sizeof(LLVMTypeRef
));
76 FOR_EACH_PTR(sym
->arguments
, arg
) {
77 struct symbol
*arg_sym
= arg
->ctype
.base_type
;
79 arg_type
[idx
++] = symbol_type(module
, arg_sym
);
80 } END_FOR_EACH_PTR(arg
);
81 func_type
= LLVMFunctionType(ret_type
, arg_type
, n_arg
,
82 sym
->ctype
.base_type
->variadic
);
87 static LLVMTypeRef
sym_array_type(LLVMModuleRef module
, struct symbol
*sym
)
89 LLVMTypeRef elem_type
;
90 struct symbol
*base_type
;
92 base_type
= sym
->ctype
.base_type
;
94 elem_type
= symbol_type(module
, base_type
);
98 return LLVMArrayType(elem_type
, sym
->bit_size
/ 8);
101 #define MAX_STRUCT_MEMBERS 64
103 static LLVMTypeRef
sym_struct_type(LLVMModuleRef module
, struct symbol
*sym
)
105 LLVMTypeRef elem_types
[MAX_STRUCT_MEMBERS
];
106 struct symbol
*member
;
111 sprintf(buffer
, "%.*s", sym
->ident
->len
, sym
->ident
->name
);
113 ret
= LLVMGetTypeByName(module
, buffer
);
117 ret
= LLVMStructCreateNamed(LLVMGetGlobalContext(), buffer
);
119 FOR_EACH_PTR(sym
->symbol_list
, member
) {
120 LLVMTypeRef member_type
;
122 assert(nr
< MAX_STRUCT_MEMBERS
);
124 member_type
= symbol_type(module
, member
);
126 elem_types
[nr
++] = member_type
;
127 } END_FOR_EACH_PTR(member
);
129 LLVMStructSetBody(ret
, elem_types
, nr
, 0 /* packed? */);
133 static LLVMTypeRef
sym_union_type(LLVMModuleRef module
, struct symbol
*sym
)
135 LLVMTypeRef elements
;
139 * There's no union support in the LLVM API so we treat unions as
140 * opaque structs. The downside is that we lose type information on the
141 * members but as LLVM doesn't care, neither do we.
143 union_size
= sym
->bit_size
/ 8;
145 elements
= LLVMArrayType(LLVMInt8Type(), union_size
);
147 return LLVMStructType(&elements
, 1, 0 /* packed? */);
150 static LLVMTypeRef
sym_ptr_type(LLVMModuleRef module
, struct symbol
*sym
)
152 LLVMTypeRef type
= symbol_type(module
, sym
->ctype
.base_type
);
154 return LLVMPointerType(type
, 0);
157 static LLVMTypeRef
sym_basetype_type(struct symbol
*sym
)
159 LLVMTypeRef ret
= NULL
;
161 if (symbol_is_fp_type(sym
)) {
162 switch (sym
->bit_size
) {
164 ret
= LLVMFloatType();
167 ret
= LLVMDoubleType();
170 ret
= LLVMX86FP80Type();
173 die("invalid bit size %d for type %d", sym
->bit_size
, sym
->type
);
177 switch (sym
->bit_size
) {
179 ret
= LLVMInt1Type();
181 case -1: /* 'void *' is treated like 'char *' */
183 ret
= LLVMInt8Type();
186 ret
= LLVMInt16Type();
189 ret
= LLVMInt32Type();
192 ret
= LLVMInt64Type();
195 die("invalid bit size %d for type %d", sym
->bit_size
, sym
->type
);
203 static LLVMTypeRef
symbol_type(LLVMModuleRef module
, struct symbol
*sym
)
205 LLVMTypeRef ret
= NULL
;
211 ret
= symbol_type(module
, sym
->ctype
.base_type
);
214 ret
= sym_basetype_type(sym
);
217 ret
= sym_ptr_type(module
, sym
);
220 ret
= sym_union_type(module
, sym
);
223 ret
= sym_struct_type(module
, sym
);
226 ret
= sym_array_type(module
, sym
);
229 ret
= sym_func_type(module
, sym
);
237 static LLVMTypeRef
insn_symbol_type(LLVMModuleRef module
, struct instruction
*insn
)
240 return symbol_type(module
, insn
->type
);
242 switch (insn
->size
) {
243 case 8: return LLVMInt8Type();
244 case 16: return LLVMInt16Type();
245 case 32: return LLVMInt32Type();
246 case 64: return LLVMInt64Type();
249 die("invalid bit size %d", insn
->size
);
253 return NULL
; /* not reached */
256 static LLVMLinkage
data_linkage(struct symbol
*sym
)
258 if (sym
->ctype
.modifiers
& MOD_STATIC
)
259 return LLVMPrivateLinkage
;
261 return LLVMExternalLinkage
;
264 static LLVMLinkage
function_linkage(struct symbol
*sym
)
266 if (sym
->ctype
.modifiers
& MOD_STATIC
)
267 return LLVMInternalLinkage
;
269 return LLVMExternalLinkage
;
272 #define MAX_PSEUDO_NAME 64
274 static void pseudo_name(pseudo_t pseudo
, char *buf
)
276 switch (pseudo
->type
) {
278 snprintf(buf
, MAX_PSEUDO_NAME
, "R%d", pseudo
->nr
);
291 snprintf(buf
, MAX_PSEUDO_NAME
, "PHI%d", pseudo
->nr
);
298 static LLVMValueRef
pseudo_to_value(struct function
*fn
, struct instruction
*insn
, pseudo_t pseudo
)
300 LLVMValueRef result
= NULL
;
302 switch (pseudo
->type
) {
304 result
= pseudo
->priv
;
307 struct symbol
*sym
= pseudo
->sym
;
308 struct expression
*expr
;
310 assert(sym
->bb_target
== NULL
);
311 assert(sym
->ident
== NULL
);
313 expr
= sym
->initializer
;
315 switch (expr
->type
) {
317 const char *s
= expr
->string
->data
;
318 LLVMValueRef indices
[] = { LLVMConstInt(LLVMInt64Type(), 0, 0), LLVMConstInt(LLVMInt64Type(), 0, 0) };
321 data
= LLVMAddGlobal(fn
->module
, LLVMArrayType(LLVMInt8Type(), strlen(s
) + 1), ".str");
322 LLVMSetLinkage(data
, LLVMPrivateLinkage
);
323 LLVMSetGlobalConstant(data
, 1);
324 LLVMSetInitializer(data
, LLVMConstString(strdup(s
), strlen(s
) + 1, true));
326 result
= LLVMConstGEP(data
, indices
, ARRAY_SIZE(indices
));
336 result
= LLVMConstInt(insn_symbol_type(fn
->module
, insn
), pseudo
->value
, 1);
339 result
= LLVMGetParam(fn
->fn
, pseudo
->nr
- 1);
343 result
= pseudo
->priv
;
355 static LLVMTypeRef
pseudo_type(struct function
*fn
, struct instruction
*insn
, pseudo_t pseudo
)
358 LLVMTypeRef result
= NULL
;
362 return LLVMTypeOf(v
);
365 switch (pseudo
->type
) {
367 result
= symbol_type(fn
->module
, pseudo
->def
->type
);
370 struct symbol
*sym
= pseudo
->sym
;
371 struct expression
*expr
;
373 assert(sym
->bb_target
== NULL
);
374 assert(sym
->ident
== NULL
);
376 expr
= sym
->initializer
;
378 switch (expr
->type
) {
380 result
= LLVMPointerType(LLVMInt8Type(), 0);
389 result
= insn_symbol_type(fn
->module
, insn
);
392 result
= LLVMTypeOf(LLVMGetParam(fn
->fn
, pseudo
->nr
- 1));
398 result
= LLVMVoidType();
407 static LLVMRealPredicate
translate_fop(int opcode
)
409 static const LLVMRealPredicate trans_tbl
[] = {
410 [OP_SET_EQ
] = LLVMRealOEQ
,
411 [OP_SET_NE
] = LLVMRealUNE
,
412 [OP_SET_LE
] = LLVMRealOLE
,
413 [OP_SET_GE
] = LLVMRealOGE
,
414 [OP_SET_LT
] = LLVMRealOLT
,
415 [OP_SET_GT
] = LLVMRealOGT
,
416 /* Are these used with FP? */
417 [OP_SET_B
] = LLVMRealOLT
,
418 [OP_SET_A
] = LLVMRealOGT
,
419 [OP_SET_BE
] = LLVMRealOLE
,
420 [OP_SET_AE
] = LLVMRealOGE
,
423 return trans_tbl
[opcode
];
426 static LLVMIntPredicate
translate_op(int opcode
)
428 static const LLVMIntPredicate trans_tbl
[] = {
429 [OP_SET_EQ
] = LLVMIntEQ
,
430 [OP_SET_NE
] = LLVMIntNE
,
431 [OP_SET_LE
] = LLVMIntSLE
,
432 [OP_SET_GE
] = LLVMIntSGE
,
433 [OP_SET_LT
] = LLVMIntSLT
,
434 [OP_SET_GT
] = LLVMIntSGT
,
435 [OP_SET_B
] = LLVMIntULT
,
436 [OP_SET_A
] = LLVMIntUGT
,
437 [OP_SET_BE
] = LLVMIntULE
,
438 [OP_SET_AE
] = LLVMIntUGE
,
441 return trans_tbl
[opcode
];
444 static void output_op_binary(struct function
*fn
, struct instruction
*insn
)
446 LLVMValueRef lhs
, rhs
, target
;
447 char target_name
[64];
449 lhs
= pseudo_to_value(fn
, insn
, insn
->src1
);
451 rhs
= pseudo_to_value(fn
, insn
, insn
->src2
);
453 pseudo_name(insn
->target
, target_name
);
455 switch (insn
->opcode
) {
458 if (symbol_is_fp_type(insn
->type
))
459 target
= LLVMBuildFAdd(fn
->builder
, lhs
, rhs
, target_name
);
461 target
= LLVMBuildAdd(fn
->builder
, lhs
, rhs
, target_name
);
464 if (symbol_is_fp_type(insn
->type
))
465 target
= LLVMBuildFSub(fn
->builder
, lhs
, rhs
, target_name
);
467 target
= LLVMBuildSub(fn
->builder
, lhs
, rhs
, target_name
);
470 if (symbol_is_fp_type(insn
->type
))
471 target
= LLVMBuildFMul(fn
->builder
, lhs
, rhs
, target_name
);
473 target
= LLVMBuildMul(fn
->builder
, lhs
, rhs
, target_name
);
476 assert(!symbol_is_fp_type(insn
->type
));
477 target
= LLVMBuildMul(fn
->builder
, lhs
, rhs
, target_name
);
480 if (symbol_is_fp_type(insn
->type
))
481 target
= LLVMBuildFDiv(fn
->builder
, lhs
, rhs
, target_name
);
483 target
= LLVMBuildUDiv(fn
->builder
, lhs
, rhs
, target_name
);
486 assert(!symbol_is_fp_type(insn
->type
));
487 target
= LLVMBuildSDiv(fn
->builder
, lhs
, rhs
, target_name
);
490 assert(!symbol_is_fp_type(insn
->type
));
491 target
= LLVMBuildURem(fn
->builder
, lhs
, rhs
, target_name
);
494 assert(!symbol_is_fp_type(insn
->type
));
495 target
= LLVMBuildSRem(fn
->builder
, lhs
, rhs
, target_name
);
498 assert(!symbol_is_fp_type(insn
->type
));
499 target
= LLVMBuildShl(fn
->builder
, lhs
, rhs
, target_name
);
502 assert(!symbol_is_fp_type(insn
->type
));
503 target
= LLVMBuildLShr(fn
->builder
, lhs
, rhs
, target_name
);
506 assert(!symbol_is_fp_type(insn
->type
));
507 target
= LLVMBuildAShr(fn
->builder
, lhs
, rhs
, target_name
);
512 assert(!symbol_is_fp_type(insn
->type
));
513 target
= LLVMBuildAnd(fn
->builder
, lhs
, rhs
, target_name
);
516 assert(!symbol_is_fp_type(insn
->type
));
517 target
= LLVMBuildOr(fn
->builder
, lhs
, rhs
, target_name
);
520 assert(!symbol_is_fp_type(insn
->type
));
521 target
= LLVMBuildXor(fn
->builder
, lhs
, rhs
, target_name
);
526 assert(!symbol_is_fp_type(insn
->type
));
528 y
= LLVMBuildICmp(fn
->builder
, LLVMIntNE
, lhs
, LLVMConstInt(LLVMTypeOf(lhs
), 0, 0), "y");
529 x
= LLVMBuildICmp(fn
->builder
, LLVMIntNE
, rhs
, LLVMConstInt(LLVMTypeOf(rhs
), 0, 0), "x");
531 target
= LLVMBuildAnd(fn
->builder
, y
, x
, target_name
);
537 assert(!symbol_is_fp_type(insn
->type
));
539 tmp
= LLVMBuildOr(fn
->builder
, rhs
, lhs
, "tmp");
541 target
= LLVMBuildICmp(fn
->builder
, LLVMIntNE
, tmp
, LLVMConstInt(LLVMTypeOf(tmp
), 0, 0), target_name
);
545 /* Binary comparison */
546 case OP_BINCMP
... OP_BINCMP_END
: {
547 if (LLVMGetTypeKind(LLVMTypeOf(lhs
)) == LLVMIntegerTypeKind
) {
548 LLVMIntPredicate op
= translate_op(insn
->opcode
);
550 target
= LLVMBuildICmp(fn
->builder
, op
, lhs
, rhs
, target_name
);
552 LLVMRealPredicate op
= translate_fop(insn
->opcode
);
554 target
= LLVMBuildFCmp(fn
->builder
, op
, lhs
, rhs
, target_name
);
563 insn
->target
->priv
= target
;
566 static void output_op_ret(struct function
*fn
, struct instruction
*insn
)
568 pseudo_t pseudo
= insn
->src
;
570 if (pseudo
&& pseudo
!= VOID
) {
571 LLVMValueRef result
= pseudo_to_value(fn
, insn
, pseudo
);
573 LLVMBuildRet(fn
->builder
, result
);
575 LLVMBuildRetVoid(fn
->builder
);
578 static void output_op_load(struct function
*fn
, struct instruction
*insn
)
580 LLVMTypeRef int_type
;
581 LLVMValueRef src_p
, src_i
, ofs_i
, addr_i
, addr
, target
;
583 /* int type large enough to hold a pointer */
584 int_type
= LLVMIntType(bits_in_pointer
);
586 /* convert to integer, add src + offset */
587 src_p
= pseudo_to_value(fn
, insn
, insn
->src
);
588 src_i
= LLVMBuildPtrToInt(fn
->builder
, src_p
, int_type
, "src_i");
590 ofs_i
= LLVMConstInt(int_type
, insn
->offset
, 0);
591 addr_i
= LLVMBuildAdd(fn
->builder
, src_i
, ofs_i
, "addr_i");
593 /* convert address back to pointer */
594 addr
= LLVMBuildIntToPtr(fn
->builder
, addr_i
,
595 LLVMPointerType(int_type
, 0), "addr");
598 target
= LLVMBuildLoad(fn
->builder
, addr
, "load_target");
600 insn
->target
->priv
= target
;
603 static void output_op_store(struct function
*fn
, struct instruction
*insn
)
605 LLVMTypeRef int_type
;
606 LLVMValueRef src_p
, src_i
, ofs_i
, addr_i
, addr
, target
, target_in
;
608 /* int type large enough to hold a pointer */
609 int_type
= LLVMIntType(bits_in_pointer
);
611 /* convert to integer, add src + offset */
612 src_p
= pseudo_to_value(fn
, insn
, insn
->src
);
613 src_i
= LLVMBuildPtrToInt(fn
->builder
, src_p
, int_type
, "src_i");
615 ofs_i
= LLVMConstInt(int_type
, insn
->offset
, 0);
616 addr_i
= LLVMBuildAdd(fn
->builder
, src_i
, ofs_i
, "addr_i");
618 /* convert address back to pointer */
619 addr
= LLVMBuildIntToPtr(fn
->builder
, addr_i
,
620 LLVMPointerType(int_type
, 0), "addr");
622 target_in
= pseudo_to_value(fn
, insn
, insn
->target
);
625 target
= LLVMBuildStore(fn
->builder
, target_in
, addr
);
627 insn
->target
->priv
= target
;
630 static void output_op_br(struct function
*fn
, struct instruction
*br
)
633 LLVMValueRef cond
= pseudo_to_value(fn
, br
, br
->cond
);
635 LLVMBuildCondBr(fn
->builder
, cond
,
639 LLVMBuildBr(fn
->builder
,
640 br
->bb_true
? br
->bb_true
->priv
:
644 static void output_op_sel(struct function
*fn
, struct instruction
*insn
)
646 LLVMValueRef target
, src1
, src2
, src3
;
648 src1
= pseudo_to_value(fn
, insn
, insn
->src1
);
649 src2
= pseudo_to_value(fn
, insn
, insn
->src2
);
650 src3
= pseudo_to_value(fn
, insn
, insn
->src3
);
652 target
= LLVMBuildSelect(fn
->builder
, src1
, src2
, src3
, "select");
654 insn
->target
->priv
= target
;
657 static void output_op_switch(struct function
*fn
, struct instruction
*insn
)
659 LLVMValueRef sw_val
, target
;
660 struct basic_block
*def
= NULL
;
661 struct multijmp
*jmp
;
664 FOR_EACH_PTR(insn
->multijmp_list
, jmp
) {
665 if (jmp
->begin
== jmp
->end
) { /* case N */
667 } else if (jmp
->begin
< jmp
->end
) { /* case M..N */
669 } else /* default case */
671 } END_FOR_EACH_PTR(jmp
);
673 sw_val
= pseudo_to_value(fn
, insn
, insn
->target
);
674 target
= LLVMBuildSwitch(fn
->builder
, sw_val
,
675 def
? def
->priv
: NULL
, n_jmp
);
677 FOR_EACH_PTR(insn
->multijmp_list
, jmp
) {
678 if (jmp
->begin
== jmp
->end
) { /* case N */
680 LLVMConstInt(LLVMInt32Type(), jmp
->begin
, 0),
682 } else if (jmp
->begin
< jmp
->end
) { /* case M..N */
685 } END_FOR_EACH_PTR(jmp
);
687 insn
->target
->priv
= target
;
691 char name
[256]; /* wasteful */
695 DECLARE_ALLOCATOR(llfunc
);
696 DECLARE_PTR_LIST(llfunc_list
, struct llfunc
);
697 ALLOCATOR(llfunc
, "llfuncs");
699 static struct local_module
{
700 struct llfunc_list
*llfunc_list
;
703 static LLVMTypeRef
get_func_type(struct function
*fn
, struct instruction
*insn
)
705 struct symbol
*sym
= insn
->func
->sym
;
707 LLVMTypeRef func_type
, ret_type
;
710 LLVMTypeRef
*arg_type
;
713 sprintf(buffer
, "%.*s", sym
->ident
->len
, sym
->ident
->name
);
715 sprintf(buffer
, "<anon sym %p>", sym
);
717 /* VERIFY: is this correct, for functions? */
718 func_type
= LLVMGetTypeByName(fn
->module
, buffer
);
722 /* to avoid strangeness with varargs [for now], we build
723 * the function and type anew, for each call. This
724 * is probably wrong. We should look up the
725 * symbol declaration info.
728 /* build return type */
729 if (insn
->target
&& insn
->target
!= VOID
)
730 ret_type
= pseudo_type(fn
, insn
, insn
->target
);
732 ret_type
= LLVMVoidType();
734 /* count args, build argument type information */
735 FOR_EACH_PTR(insn
->arguments
, arg
) {
737 } END_FOR_EACH_PTR(arg
);
739 arg_type
= calloc(n_arg
, sizeof(LLVMTypeRef
));
742 FOR_EACH_PTR(insn
->arguments
, arg
) {
743 arg_type
[idx
++] = pseudo_type(fn
, insn
, arg
);
744 } END_FOR_EACH_PTR(arg
);
746 func_type
= LLVMFunctionType(ret_type
, arg_type
, n_arg
,
747 insn
->fntype
->variadic
);
752 static LLVMValueRef
get_function(struct function
*fn
, struct instruction
*insn
)
754 struct symbol
*sym
= insn
->func
->sym
;
760 sprintf(buffer
, "%.*s", sym
->ident
->len
, sym
->ident
->name
);
762 sprintf(buffer
, "<anon sym %p>", sym
);
765 /* search for pre-built function type definition */
766 FOR_EACH_PTR(mi
.llfunc_list
, f
) {
767 if (!strcmp(f
->name
, buffer
))
768 return f
->func
; /* found match; return */
769 } END_FOR_EACH_PTR(f
);
771 /* build function type definition */
772 LLVMTypeRef func_type
= get_func_type(fn
, insn
);
774 func
= LLVMAddFunction(fn
->module
, buffer
, func_type
);
776 /* store built function on list, for later referencing */
777 f
= calloc(1, sizeof(*f
));
778 strncpy(f
->name
, buffer
, sizeof(f
->name
) - 1);
781 add_ptr_list(&mi
.llfunc_list
, f
);
786 static void output_op_call(struct function
*fn
, struct instruction
*insn
)
788 LLVMValueRef target
, func
;
793 FOR_EACH_PTR(insn
->arguments
, arg
) {
795 } END_FOR_EACH_PTR(arg
);
797 args
= calloc(n_arg
, sizeof(LLVMValueRef
));
800 FOR_EACH_PTR(insn
->arguments
, arg
) {
801 args
[i
++] = pseudo_to_value(fn
, insn
, arg
);
802 } END_FOR_EACH_PTR(arg
);
804 func
= get_function(fn
, insn
);
805 target
= LLVMBuildCall(fn
->builder
, func
, args
, n_arg
, "");
807 insn
->target
->priv
= target
;
810 static void store_phi_fwd(struct function
*fn
, LLVMValueRef phi
,
815 fwd
= calloc(1, sizeof(*fwd
));
817 fwd
->pseudo
= pseudo
;
819 /* append fwd ref to function-wide list */
823 struct phi_fwd
*last
= fn
->fwd_list
;
831 static void output_phi_fwd(struct function
*fn
, pseudo_t pseudo
, LLVMValueRef v
)
833 struct phi_fwd
*fwd
= fn
->fwd_list
;
841 if (tmp
->pseudo
== pseudo
&& !tmp
->resolved
) {
842 LLVMValueRef phi_vals
[1];
843 LLVMBasicBlockRef phi_blks
[1];
846 phi_blks
[0] = pseudo
->def
->bb
->priv
;
848 LLVMAddIncoming(tmp
->phi
, phi_vals
, phi_blks
, 1);
850 tmp
->resolved
= true;
855 static void output_op_phisrc(struct function
*fn
, struct instruction
*insn
)
859 assert(insn
->target
->priv
== NULL
);
862 v
= pseudo_to_value(fn
, insn
, insn
->phi_src
);
863 insn
->target
->priv
= v
;
865 assert(insn
->target
->priv
!= NULL
);
867 /* resolve forward references to this phi source, if present */
868 output_phi_fwd(fn
, insn
->target
, v
);
871 static void output_op_phi(struct function
*fn
, struct instruction
*insn
)
876 target
= LLVMBuildPhi(fn
->builder
, insn_symbol_type(fn
->module
, insn
),
879 FOR_EACH_PTR(insn
->phi_list
, phi
) {
880 if (pseudo_to_value(fn
, insn
, phi
)) /* skip VOID, fwd refs*/
882 } END_FOR_EACH_PTR(phi
);
884 LLVMValueRef
*phi_vals
= calloc(pll
, sizeof(LLVMValueRef
));
885 LLVMBasicBlockRef
*phi_blks
= calloc(pll
, sizeof(LLVMBasicBlockRef
));
888 FOR_EACH_PTR(insn
->phi_list
, phi
) {
891 v
= pseudo_to_value(fn
, insn
, phi
);
892 if (v
) { /* skip VOID, fwd refs */
894 phi_blks
[idx
] = phi
->def
->bb
->priv
;
897 else if (phi
->type
== PSEUDO_PHI
) /* fwd ref */
898 store_phi_fwd(fn
, target
, phi
);
899 } END_FOR_EACH_PTR(phi
);
901 LLVMAddIncoming(target
, phi_vals
, phi_blks
, pll
);
903 insn
->target
->priv
= target
;
906 static void output_op_ptrcast(struct function
*fn
, struct instruction
*insn
)
908 LLVMValueRef src
, target
;
909 char target_name
[64];
911 src
= insn
->src
->priv
;
913 src
= pseudo_to_value(fn
, insn
, insn
->src
);
915 pseudo_name(insn
->target
, target_name
);
917 assert(!symbol_is_fp_type(insn
->type
));
919 target
= LLVMBuildBitCast(fn
->builder
, src
, insn_symbol_type(fn
->module
, insn
), target_name
);
921 insn
->target
->priv
= target
;
924 static void output_op_cast(struct function
*fn
, struct instruction
*insn
, LLVMOpcode op
)
926 LLVMValueRef src
, target
;
927 char target_name
[64];
929 src
= insn
->src
->priv
;
931 src
= pseudo_to_value(fn
, insn
, insn
->src
);
933 pseudo_name(insn
->target
, target_name
);
935 assert(!symbol_is_fp_type(insn
->type
));
937 if (insn
->size
< LLVMGetIntTypeWidth(LLVMTypeOf(src
)))
938 target
= LLVMBuildTrunc(fn
->builder
, src
, insn_symbol_type(fn
->module
, insn
), target_name
);
940 target
= LLVMBuildCast(fn
->builder
, op
, src
, insn_symbol_type(fn
->module
, insn
), target_name
);
942 insn
->target
->priv
= target
;
945 static void output_op_copy(struct function
*fn
, struct instruction
*insn
,
948 LLVMValueRef src
, target
;
949 LLVMTypeRef const_type
;
950 char target_name
[64];
952 pseudo_name(insn
->target
, target_name
);
953 src
= pseudo_to_value(fn
, insn
, pseudo
);
954 const_type
= insn_symbol_type(fn
->module
, insn
);
957 * This is nothing more than 'target = src'
959 * TODO: find a better way to provide an identity function,
960 * than using "X + 0" simply to produce a new LLVM pseudo
963 if (symbol_is_fp_type(insn
->type
))
964 target
= LLVMBuildFAdd(fn
->builder
, src
,
965 LLVMConstReal(const_type
, 0.0), target_name
);
967 target
= LLVMBuildAdd(fn
->builder
, src
,
968 LLVMConstInt(const_type
, 0, 0), target_name
);
970 insn
->target
->priv
= target
;
973 static void output_insn(struct function
*fn
, struct instruction
*insn
)
975 switch (insn
->opcode
) {
977 output_op_ret(fn
, insn
);
980 output_op_br(fn
, insn
);
989 output_op_switch(fn
, insn
);
991 case OP_COMPUTEDGOTO
:
995 output_op_phisrc(fn
, insn
);
998 output_op_phi(fn
, insn
);
1001 output_op_load(fn
, insn
);
1007 output_op_store(fn
, insn
);
1012 case OP_INLINED_CALL
:
1016 output_op_call(fn
, insn
);
1019 output_op_cast(fn
, insn
, LLVMZExt
);
1022 output_op_cast(fn
, insn
, LLVMSExt
);
1028 output_op_ptrcast(fn
, insn
);
1030 case OP_BINARY
... OP_BINARY_END
:
1031 case OP_BINCMP
... OP_BINCMP_END
:
1032 output_op_binary(fn
, insn
);
1035 output_op_sel(fn
, insn
);
1041 LLVMValueRef src
, target
;
1042 char target_name
[64];
1044 src
= pseudo_to_value(fn
, insn
, insn
->src
);
1046 pseudo_name(insn
->target
, target_name
);
1048 target
= LLVMBuildNot(fn
->builder
, src
, target_name
);
1050 insn
->target
->priv
= target
;
1072 output_op_copy(fn
, insn
, insn
->src
);
1079 static void output_bb(struct function
*fn
, struct basic_block
*bb
, unsigned long generation
)
1081 struct instruction
*insn
;
1083 bb
->generation
= generation
;
1085 FOR_EACH_PTR(bb
->insns
, insn
) {
1089 output_insn(fn
, insn
);
1091 END_FOR_EACH_PTR(insn
);
1096 static void output_fn(LLVMModuleRef module
, struct entrypoint
*ep
)
1098 unsigned long generation
= ++bb_generation
;
1099 struct symbol
*sym
= ep
->name
;
1100 struct symbol
*base_type
= sym
->ctype
.base_type
;
1101 struct symbol
*ret_type
= sym
->ctype
.base_type
->ctype
.base_type
;
1102 LLVMTypeRef arg_types
[MAX_ARGS
];
1103 LLVMTypeRef return_type
;
1104 struct function function
= { .module
= module
};
1105 struct basic_block
*bb
;
1111 FOR_EACH_PTR(base_type
->arguments
, arg
) {
1112 struct symbol
*arg_base_type
= arg
->ctype
.base_type
;
1114 arg_types
[nr_args
++] = symbol_type(module
, arg_base_type
);
1115 } END_FOR_EACH_PTR(arg
);
1117 name
= show_ident(sym
->ident
);
1119 return_type
= symbol_type(module
, ret_type
);
1121 function
.type
= LLVMFunctionType(return_type
, arg_types
, nr_args
, 0);
1123 function
.fn
= LLVMAddFunction(module
, name
, function
.type
);
1124 LLVMSetFunctionCallConv(function
.fn
, LLVMCCallConv
);
1126 LLVMSetLinkage(function
.fn
, function_linkage(sym
));
1128 /* store built function on list, for later referencing */
1129 f
= calloc(1, sizeof(*f
));
1130 strncpy(f
->name
, name
, sizeof(f
->name
) - 1);
1131 f
->func
= function
.fn
;
1133 add_ptr_list(&mi
.llfunc_list
, f
);
1135 function
.builder
= LLVMCreateBuilder();
1139 FOR_EACH_PTR(ep
->bbs
, bb
) {
1140 if (bb
->generation
== generation
)
1143 LLVMBasicBlockRef bbr
;
1146 sprintf(bbname
, "L%d", nr_bb
++);
1147 bbr
= LLVMAppendBasicBlock(function
.fn
, bbname
);
1151 END_FOR_EACH_PTR(bb
);
1153 FOR_EACH_PTR(ep
->bbs
, bb
) {
1154 if (bb
->generation
== generation
)
1157 LLVMPositionBuilderAtEnd(function
.builder
, bb
->priv
);
1159 output_bb(&function
, bb
, generation
);
1161 END_FOR_EACH_PTR(bb
);
1164 static LLVMValueRef
output_data(LLVMModuleRef module
, struct symbol
*sym
)
1166 struct expression
*initializer
= sym
->initializer
;
1167 LLVMValueRef initial_value
;
1172 switch (initializer
->type
) {
1174 initial_value
= LLVMConstInt(symbol_type(module
, sym
), initializer
->value
, 1);
1177 struct symbol
*sym
= initializer
->symbol
;
1179 initial_value
= LLVMGetNamedGlobal(module
, show_ident(sym
->ident
));
1181 initial_value
= output_data(module
, sym
);
1188 LLVMTypeRef type
= symbol_type(module
, sym
);
1190 initial_value
= LLVMConstNull(type
);
1193 name
= show_ident(sym
->ident
);
1195 data
= LLVMAddGlobal(module
, symbol_type(module
, sym
->ctype
.base_type
), name
);
1197 LLVMSetLinkage(data
, data_linkage(sym
));
1199 if (!(sym
->ctype
.modifiers
& MOD_EXTERN
))
1200 LLVMSetInitializer(data
, initial_value
);
1205 static int compile(LLVMModuleRef module
, struct symbol_list
*list
)
1209 FOR_EACH_PTR(list
, sym
) {
1210 struct entrypoint
*ep
;
1212 ep
= linearize_symbol(sym
);
1214 output_fn(module
, ep
);
1216 output_data(module
, sym
);
1218 END_FOR_EACH_PTR(sym
);
1223 int main(int argc
, char **argv
)
1225 struct string_list
* filelist
= NULL
;
1228 LLVMModuleRef module
= LLVMModuleCreateWithName("sparse");
1230 compile(module
, sparse_initialize(argc
, argv
, &filelist
));
1232 FOR_EACH_PTR_NOTAG(filelist
, file
) {
1233 compile(module
, sparse(file
));
1234 } END_FOR_EACH_PTR_NOTAG(file
);
1236 LLVMWriteBitcodeToFD(module
, STDOUT_FILENO
, 0, 0);
1238 LLVMDisposeModule(module
);