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
);
312 expr
= sym
->initializer
;
314 switch (expr
->type
) {
316 const char *s
= expr
->string
->data
;
317 LLVMValueRef indices
[] = { LLVMConstInt(LLVMInt64Type(), 0, 0), LLVMConstInt(LLVMInt64Type(), 0, 0) };
320 data
= LLVMAddGlobal(fn
->module
, LLVMArrayType(LLVMInt8Type(), strlen(s
) + 1), ".str");
321 LLVMSetLinkage(data
, LLVMPrivateLinkage
);
322 LLVMSetGlobalConstant(data
, 1);
323 LLVMSetInitializer(data
, LLVMConstString(strdup(s
), strlen(s
) + 1, true));
325 result
= LLVMConstGEP(data
, indices
, ARRAY_SIZE(indices
));
329 struct symbol
*sym
= expr
->symbol
;
331 result
= LLVMGetNamedGlobal(fn
->module
, show_ident(sym
->ident
));
332 assert(result
!= NULL
);
342 result
= LLVMConstInt(insn_symbol_type(fn
->module
, insn
), pseudo
->value
, 1);
345 result
= LLVMGetParam(fn
->fn
, pseudo
->nr
- 1);
349 result
= pseudo
->priv
;
361 static LLVMTypeRef
pseudo_type(struct function
*fn
, struct instruction
*insn
, pseudo_t pseudo
)
364 LLVMTypeRef result
= NULL
;
368 return LLVMTypeOf(v
);
371 switch (pseudo
->type
) {
373 result
= symbol_type(fn
->module
, pseudo
->def
->type
);
376 struct symbol
*sym
= pseudo
->sym
;
377 struct expression
*expr
;
379 assert(sym
->bb_target
== NULL
);
380 assert(sym
->ident
== NULL
);
382 expr
= sym
->initializer
;
384 switch (expr
->type
) {
386 result
= LLVMPointerType(LLVMInt8Type(), 0);
395 result
= insn_symbol_type(fn
->module
, insn
);
398 result
= LLVMTypeOf(LLVMGetParam(fn
->fn
, pseudo
->nr
- 1));
404 result
= LLVMVoidType();
413 static LLVMRealPredicate
translate_fop(int opcode
)
415 static const LLVMRealPredicate trans_tbl
[] = {
416 [OP_SET_EQ
] = LLVMRealOEQ
,
417 [OP_SET_NE
] = LLVMRealUNE
,
418 [OP_SET_LE
] = LLVMRealOLE
,
419 [OP_SET_GE
] = LLVMRealOGE
,
420 [OP_SET_LT
] = LLVMRealOLT
,
421 [OP_SET_GT
] = LLVMRealOGT
,
422 /* Are these used with FP? */
423 [OP_SET_B
] = LLVMRealOLT
,
424 [OP_SET_A
] = LLVMRealOGT
,
425 [OP_SET_BE
] = LLVMRealOLE
,
426 [OP_SET_AE
] = LLVMRealOGE
,
429 return trans_tbl
[opcode
];
432 static LLVMIntPredicate
translate_op(int opcode
)
434 static const LLVMIntPredicate trans_tbl
[] = {
435 [OP_SET_EQ
] = LLVMIntEQ
,
436 [OP_SET_NE
] = LLVMIntNE
,
437 [OP_SET_LE
] = LLVMIntSLE
,
438 [OP_SET_GE
] = LLVMIntSGE
,
439 [OP_SET_LT
] = LLVMIntSLT
,
440 [OP_SET_GT
] = LLVMIntSGT
,
441 [OP_SET_B
] = LLVMIntULT
,
442 [OP_SET_A
] = LLVMIntUGT
,
443 [OP_SET_BE
] = LLVMIntULE
,
444 [OP_SET_AE
] = LLVMIntUGE
,
447 return trans_tbl
[opcode
];
450 static void output_op_binary(struct function
*fn
, struct instruction
*insn
)
452 LLVMValueRef lhs
, rhs
, target
;
453 char target_name
[64];
455 lhs
= pseudo_to_value(fn
, insn
, insn
->src1
);
457 rhs
= pseudo_to_value(fn
, insn
, insn
->src2
);
459 pseudo_name(insn
->target
, target_name
);
461 switch (insn
->opcode
) {
464 if (symbol_is_fp_type(insn
->type
))
465 target
= LLVMBuildFAdd(fn
->builder
, lhs
, rhs
, target_name
);
467 target
= LLVMBuildAdd(fn
->builder
, lhs
, rhs
, target_name
);
470 if (symbol_is_fp_type(insn
->type
))
471 target
= LLVMBuildFSub(fn
->builder
, lhs
, rhs
, target_name
);
473 target
= LLVMBuildSub(fn
->builder
, lhs
, rhs
, target_name
);
476 if (symbol_is_fp_type(insn
->type
))
477 target
= LLVMBuildFMul(fn
->builder
, lhs
, rhs
, target_name
);
479 target
= LLVMBuildMul(fn
->builder
, lhs
, rhs
, target_name
);
482 assert(!symbol_is_fp_type(insn
->type
));
483 target
= LLVMBuildMul(fn
->builder
, lhs
, rhs
, target_name
);
486 if (symbol_is_fp_type(insn
->type
))
487 target
= LLVMBuildFDiv(fn
->builder
, lhs
, rhs
, target_name
);
489 target
= LLVMBuildUDiv(fn
->builder
, lhs
, rhs
, target_name
);
492 assert(!symbol_is_fp_type(insn
->type
));
493 target
= LLVMBuildSDiv(fn
->builder
, lhs
, rhs
, target_name
);
496 assert(!symbol_is_fp_type(insn
->type
));
497 target
= LLVMBuildURem(fn
->builder
, lhs
, rhs
, target_name
);
500 assert(!symbol_is_fp_type(insn
->type
));
501 target
= LLVMBuildSRem(fn
->builder
, lhs
, rhs
, target_name
);
504 assert(!symbol_is_fp_type(insn
->type
));
505 target
= LLVMBuildShl(fn
->builder
, lhs
, rhs
, target_name
);
508 assert(!symbol_is_fp_type(insn
->type
));
509 target
= LLVMBuildLShr(fn
->builder
, lhs
, rhs
, target_name
);
512 assert(!symbol_is_fp_type(insn
->type
));
513 target
= LLVMBuildAShr(fn
->builder
, lhs
, rhs
, target_name
);
518 assert(!symbol_is_fp_type(insn
->type
));
519 target
= LLVMBuildAnd(fn
->builder
, lhs
, rhs
, target_name
);
522 assert(!symbol_is_fp_type(insn
->type
));
523 target
= LLVMBuildOr(fn
->builder
, lhs
, rhs
, target_name
);
526 assert(!symbol_is_fp_type(insn
->type
));
527 target
= LLVMBuildXor(fn
->builder
, lhs
, rhs
, target_name
);
532 assert(!symbol_is_fp_type(insn
->type
));
534 y
= LLVMBuildICmp(fn
->builder
, LLVMIntNE
, lhs
, LLVMConstInt(LLVMTypeOf(lhs
), 0, 0), "y");
535 x
= LLVMBuildICmp(fn
->builder
, LLVMIntNE
, rhs
, LLVMConstInt(LLVMTypeOf(rhs
), 0, 0), "x");
537 target
= LLVMBuildAnd(fn
->builder
, y
, x
, target_name
);
543 assert(!symbol_is_fp_type(insn
->type
));
545 tmp
= LLVMBuildOr(fn
->builder
, rhs
, lhs
, "tmp");
547 target
= LLVMBuildICmp(fn
->builder
, LLVMIntNE
, tmp
, LLVMConstInt(LLVMTypeOf(tmp
), 0, 0), target_name
);
551 /* Binary comparison */
552 case OP_BINCMP
... OP_BINCMP_END
: {
553 if (LLVMGetTypeKind(LLVMTypeOf(lhs
)) == LLVMIntegerTypeKind
) {
554 LLVMIntPredicate op
= translate_op(insn
->opcode
);
556 target
= LLVMBuildICmp(fn
->builder
, op
, lhs
, rhs
, target_name
);
558 LLVMRealPredicate op
= translate_fop(insn
->opcode
);
560 target
= LLVMBuildFCmp(fn
->builder
, op
, lhs
, rhs
, target_name
);
569 insn
->target
->priv
= target
;
572 static void output_op_ret(struct function
*fn
, struct instruction
*insn
)
574 pseudo_t pseudo
= insn
->src
;
576 if (pseudo
&& pseudo
!= VOID
) {
577 LLVMValueRef result
= pseudo_to_value(fn
, insn
, pseudo
);
579 LLVMBuildRet(fn
->builder
, result
);
581 LLVMBuildRetVoid(fn
->builder
);
584 static void output_op_load(struct function
*fn
, struct instruction
*insn
)
586 LLVMTypeRef int_type
;
587 LLVMValueRef src_p
, src_i
, ofs_i
, addr_i
, addr
, target
;
589 /* int type large enough to hold a pointer */
590 int_type
= LLVMIntType(bits_in_pointer
);
592 /* convert to integer, add src + offset */
593 src_p
= pseudo_to_value(fn
, insn
, insn
->src
);
594 src_i
= LLVMBuildPtrToInt(fn
->builder
, src_p
, int_type
, "src_i");
596 ofs_i
= LLVMConstInt(int_type
, insn
->offset
, 0);
597 addr_i
= LLVMBuildAdd(fn
->builder
, src_i
, ofs_i
, "addr_i");
599 /* convert address back to pointer */
600 addr
= LLVMBuildIntToPtr(fn
->builder
, addr_i
,
601 LLVMPointerType(int_type
, 0), "addr");
604 target
= LLVMBuildLoad(fn
->builder
, addr
, "load_target");
606 insn
->target
->priv
= target
;
609 static void output_op_store(struct function
*fn
, struct instruction
*insn
)
611 LLVMTypeRef int_type
;
612 LLVMValueRef src_p
, src_i
, ofs_i
, addr_i
, addr
, target
, target_in
;
614 /* int type large enough to hold a pointer */
615 int_type
= LLVMIntType(bits_in_pointer
);
617 /* convert to integer, add src + offset */
618 src_p
= pseudo_to_value(fn
, insn
, insn
->src
);
619 src_i
= LLVMBuildPtrToInt(fn
->builder
, src_p
, int_type
, "src_i");
621 ofs_i
= LLVMConstInt(int_type
, insn
->offset
, 0);
622 addr_i
= LLVMBuildAdd(fn
->builder
, src_i
, ofs_i
, "addr_i");
624 /* convert address back to pointer */
625 addr
= LLVMBuildIntToPtr(fn
->builder
, addr_i
,
626 LLVMPointerType(int_type
, 0), "addr");
628 target_in
= pseudo_to_value(fn
, insn
, insn
->target
);
631 target
= LLVMBuildStore(fn
->builder
, target_in
, addr
);
633 insn
->target
->priv
= target
;
636 static void output_op_br(struct function
*fn
, struct instruction
*br
)
639 LLVMValueRef cond
= pseudo_to_value(fn
, br
, br
->cond
);
641 LLVMBuildCondBr(fn
->builder
, cond
,
645 LLVMBuildBr(fn
->builder
,
646 br
->bb_true
? br
->bb_true
->priv
:
650 static void output_op_sel(struct function
*fn
, struct instruction
*insn
)
652 LLVMValueRef target
, src1
, src2
, src3
;
654 src1
= pseudo_to_value(fn
, insn
, insn
->src1
);
655 src2
= pseudo_to_value(fn
, insn
, insn
->src2
);
656 src3
= pseudo_to_value(fn
, insn
, insn
->src3
);
658 target
= LLVMBuildSelect(fn
->builder
, src1
, src2
, src3
, "select");
660 insn
->target
->priv
= target
;
663 static void output_op_switch(struct function
*fn
, struct instruction
*insn
)
665 LLVMValueRef sw_val
, target
;
666 struct basic_block
*def
= NULL
;
667 struct multijmp
*jmp
;
670 FOR_EACH_PTR(insn
->multijmp_list
, jmp
) {
671 if (jmp
->begin
== jmp
->end
) { /* case N */
673 } else if (jmp
->begin
< jmp
->end
) { /* case M..N */
675 } else /* default case */
677 } END_FOR_EACH_PTR(jmp
);
679 sw_val
= pseudo_to_value(fn
, insn
, insn
->target
);
680 target
= LLVMBuildSwitch(fn
->builder
, sw_val
,
681 def
? def
->priv
: NULL
, n_jmp
);
683 FOR_EACH_PTR(insn
->multijmp_list
, jmp
) {
684 if (jmp
->begin
== jmp
->end
) { /* case N */
686 LLVMConstInt(LLVMInt32Type(), jmp
->begin
, 0),
688 } else if (jmp
->begin
< jmp
->end
) { /* case M..N */
691 } END_FOR_EACH_PTR(jmp
);
693 insn
->target
->priv
= target
;
697 char name
[256]; /* wasteful */
701 DECLARE_ALLOCATOR(llfunc
);
702 DECLARE_PTR_LIST(llfunc_list
, struct llfunc
);
703 ALLOCATOR(llfunc
, "llfuncs");
705 static struct local_module
{
706 struct llfunc_list
*llfunc_list
;
709 static LLVMTypeRef
get_func_type(struct function
*fn
, struct instruction
*insn
)
711 struct symbol
*sym
= insn
->func
->sym
;
713 LLVMTypeRef func_type
, ret_type
;
716 LLVMTypeRef
*arg_type
;
719 sprintf(buffer
, "%.*s", sym
->ident
->len
, sym
->ident
->name
);
721 sprintf(buffer
, "<anon sym %p>", sym
);
723 /* VERIFY: is this correct, for functions? */
724 func_type
= LLVMGetTypeByName(fn
->module
, buffer
);
728 /* to avoid strangeness with varargs [for now], we build
729 * the function and type anew, for each call. This
730 * is probably wrong. We should look up the
731 * symbol declaration info.
734 /* build return type */
735 if (insn
->target
&& insn
->target
!= VOID
)
736 ret_type
= pseudo_type(fn
, insn
, insn
->target
);
738 ret_type
= LLVMVoidType();
740 /* count args, build argument type information */
741 FOR_EACH_PTR(insn
->arguments
, arg
) {
743 } END_FOR_EACH_PTR(arg
);
745 arg_type
= calloc(n_arg
, sizeof(LLVMTypeRef
));
748 FOR_EACH_PTR(insn
->arguments
, arg
) {
749 arg_type
[idx
++] = pseudo_type(fn
, insn
, arg
);
750 } END_FOR_EACH_PTR(arg
);
752 func_type
= LLVMFunctionType(ret_type
, arg_type
, n_arg
,
753 insn
->fntype
->variadic
);
758 static LLVMValueRef
get_function(struct function
*fn
, struct instruction
*insn
)
760 struct symbol
*sym
= insn
->func
->sym
;
766 sprintf(buffer
, "%.*s", sym
->ident
->len
, sym
->ident
->name
);
768 sprintf(buffer
, "<anon sym %p>", sym
);
771 /* search for pre-built function type definition */
772 FOR_EACH_PTR(mi
.llfunc_list
, f
) {
773 if (!strcmp(f
->name
, buffer
))
774 return f
->func
; /* found match; return */
775 } END_FOR_EACH_PTR(f
);
777 /* build function type definition */
778 LLVMTypeRef func_type
= get_func_type(fn
, insn
);
780 func
= LLVMAddFunction(fn
->module
, buffer
, func_type
);
782 /* store built function on list, for later referencing */
783 f
= calloc(1, sizeof(*f
));
784 strncpy(f
->name
, buffer
, sizeof(f
->name
) - 1);
787 add_ptr_list(&mi
.llfunc_list
, f
);
792 static void output_op_call(struct function
*fn
, struct instruction
*insn
)
794 LLVMValueRef target
, func
;
799 FOR_EACH_PTR(insn
->arguments
, arg
) {
801 } END_FOR_EACH_PTR(arg
);
803 args
= calloc(n_arg
, sizeof(LLVMValueRef
));
806 FOR_EACH_PTR(insn
->arguments
, arg
) {
807 args
[i
++] = pseudo_to_value(fn
, insn
, arg
);
808 } END_FOR_EACH_PTR(arg
);
810 func
= get_function(fn
, insn
);
811 target
= LLVMBuildCall(fn
->builder
, func
, args
, n_arg
, "");
813 insn
->target
->priv
= target
;
816 static void store_phi_fwd(struct function
*fn
, LLVMValueRef phi
,
821 fwd
= calloc(1, sizeof(*fwd
));
823 fwd
->pseudo
= pseudo
;
825 /* append fwd ref to function-wide list */
829 struct phi_fwd
*last
= fn
->fwd_list
;
837 static void output_phi_fwd(struct function
*fn
, pseudo_t pseudo
, LLVMValueRef v
)
839 struct phi_fwd
*fwd
= fn
->fwd_list
;
847 if (tmp
->pseudo
== pseudo
&& !tmp
->resolved
) {
848 LLVMValueRef phi_vals
[1];
849 LLVMBasicBlockRef phi_blks
[1];
852 phi_blks
[0] = pseudo
->def
->bb
->priv
;
854 LLVMAddIncoming(tmp
->phi
, phi_vals
, phi_blks
, 1);
856 tmp
->resolved
= true;
861 static void output_op_phisrc(struct function
*fn
, struct instruction
*insn
)
865 assert(insn
->target
->priv
== NULL
);
868 v
= pseudo_to_value(fn
, insn
, insn
->phi_src
);
869 insn
->target
->priv
= v
;
871 assert(insn
->target
->priv
!= NULL
);
873 /* resolve forward references to this phi source, if present */
874 output_phi_fwd(fn
, insn
->target
, v
);
877 static void output_op_phi(struct function
*fn
, struct instruction
*insn
)
882 target
= LLVMBuildPhi(fn
->builder
, insn_symbol_type(fn
->module
, insn
),
885 FOR_EACH_PTR(insn
->phi_list
, phi
) {
886 if (pseudo_to_value(fn
, insn
, phi
)) /* skip VOID, fwd refs*/
888 } END_FOR_EACH_PTR(phi
);
890 LLVMValueRef
*phi_vals
= calloc(pll
, sizeof(LLVMValueRef
));
891 LLVMBasicBlockRef
*phi_blks
= calloc(pll
, sizeof(LLVMBasicBlockRef
));
894 FOR_EACH_PTR(insn
->phi_list
, phi
) {
897 v
= pseudo_to_value(fn
, insn
, phi
);
898 if (v
) { /* skip VOID, fwd refs */
900 phi_blks
[idx
] = phi
->def
->bb
->priv
;
903 else if (phi
->type
== PSEUDO_PHI
) /* fwd ref */
904 store_phi_fwd(fn
, target
, phi
);
905 } END_FOR_EACH_PTR(phi
);
907 LLVMAddIncoming(target
, phi_vals
, phi_blks
, pll
);
909 insn
->target
->priv
= target
;
912 static void output_op_ptrcast(struct function
*fn
, struct instruction
*insn
)
914 LLVMValueRef src
, target
;
915 char target_name
[64];
917 src
= insn
->src
->priv
;
919 src
= pseudo_to_value(fn
, insn
, insn
->src
);
921 pseudo_name(insn
->target
, target_name
);
923 assert(!symbol_is_fp_type(insn
->type
));
925 target
= LLVMBuildBitCast(fn
->builder
, src
, insn_symbol_type(fn
->module
, insn
), target_name
);
927 insn
->target
->priv
= target
;
930 static void output_op_cast(struct function
*fn
, struct instruction
*insn
, LLVMOpcode op
)
932 LLVMValueRef src
, target
;
933 char target_name
[64];
935 src
= insn
->src
->priv
;
937 src
= pseudo_to_value(fn
, insn
, insn
->src
);
939 pseudo_name(insn
->target
, target_name
);
941 assert(!symbol_is_fp_type(insn
->type
));
943 if (insn
->size
< LLVMGetIntTypeWidth(LLVMTypeOf(src
)))
944 target
= LLVMBuildTrunc(fn
->builder
, src
, insn_symbol_type(fn
->module
, insn
), target_name
);
946 target
= LLVMBuildCast(fn
->builder
, op
, src
, insn_symbol_type(fn
->module
, insn
), target_name
);
948 insn
->target
->priv
= target
;
951 static void output_op_copy(struct function
*fn
, struct instruction
*insn
,
954 LLVMValueRef src
, target
;
955 LLVMTypeRef const_type
;
956 char target_name
[64];
958 pseudo_name(insn
->target
, target_name
);
959 src
= pseudo_to_value(fn
, insn
, pseudo
);
960 const_type
= insn_symbol_type(fn
->module
, insn
);
963 * This is nothing more than 'target = src'
965 * TODO: find a better way to provide an identity function,
966 * than using "X + 0" simply to produce a new LLVM pseudo
969 if (symbol_is_fp_type(insn
->type
))
970 target
= LLVMBuildFAdd(fn
->builder
, src
,
971 LLVMConstReal(const_type
, 0.0), target_name
);
973 target
= LLVMBuildAdd(fn
->builder
, src
,
974 LLVMConstInt(const_type
, 0, 0), target_name
);
976 insn
->target
->priv
= target
;
979 static void output_insn(struct function
*fn
, struct instruction
*insn
)
981 switch (insn
->opcode
) {
983 output_op_ret(fn
, insn
);
986 output_op_br(fn
, insn
);
995 output_op_switch(fn
, insn
);
997 case OP_COMPUTEDGOTO
:
1001 output_op_phisrc(fn
, insn
);
1004 output_op_phi(fn
, insn
);
1007 output_op_load(fn
, insn
);
1013 output_op_store(fn
, insn
);
1018 case OP_INLINED_CALL
:
1022 output_op_call(fn
, insn
);
1025 output_op_cast(fn
, insn
, LLVMZExt
);
1028 output_op_cast(fn
, insn
, LLVMSExt
);
1034 output_op_ptrcast(fn
, insn
);
1036 case OP_BINARY
... OP_BINARY_END
:
1037 case OP_BINCMP
... OP_BINCMP_END
:
1038 output_op_binary(fn
, insn
);
1041 output_op_sel(fn
, insn
);
1047 LLVMValueRef src
, target
;
1048 char target_name
[64];
1050 src
= pseudo_to_value(fn
, insn
, insn
->src
);
1052 pseudo_name(insn
->target
, target_name
);
1054 target
= LLVMBuildNot(fn
->builder
, src
, target_name
);
1056 insn
->target
->priv
= target
;
1078 output_op_copy(fn
, insn
, insn
->src
);
1085 static void output_bb(struct function
*fn
, struct basic_block
*bb
, unsigned long generation
)
1087 struct instruction
*insn
;
1089 bb
->generation
= generation
;
1091 FOR_EACH_PTR(bb
->insns
, insn
) {
1095 output_insn(fn
, insn
);
1097 END_FOR_EACH_PTR(insn
);
1102 static void output_fn(LLVMModuleRef module
, struct entrypoint
*ep
)
1104 unsigned long generation
= ++bb_generation
;
1105 struct symbol
*sym
= ep
->name
;
1106 struct symbol
*base_type
= sym
->ctype
.base_type
;
1107 struct symbol
*ret_type
= sym
->ctype
.base_type
->ctype
.base_type
;
1108 LLVMTypeRef arg_types
[MAX_ARGS
];
1109 LLVMTypeRef return_type
;
1110 struct function function
= { .module
= module
};
1111 struct basic_block
*bb
;
1117 FOR_EACH_PTR(base_type
->arguments
, arg
) {
1118 struct symbol
*arg_base_type
= arg
->ctype
.base_type
;
1120 arg_types
[nr_args
++] = symbol_type(module
, arg_base_type
);
1121 } END_FOR_EACH_PTR(arg
);
1123 name
= show_ident(sym
->ident
);
1125 return_type
= symbol_type(module
, ret_type
);
1127 function
.type
= LLVMFunctionType(return_type
, arg_types
, nr_args
, 0);
1129 function
.fn
= LLVMAddFunction(module
, name
, function
.type
);
1130 LLVMSetFunctionCallConv(function
.fn
, LLVMCCallConv
);
1132 LLVMSetLinkage(function
.fn
, function_linkage(sym
));
1134 /* store built function on list, for later referencing */
1135 f
= calloc(1, sizeof(*f
));
1136 strncpy(f
->name
, name
, sizeof(f
->name
) - 1);
1137 f
->func
= function
.fn
;
1139 add_ptr_list(&mi
.llfunc_list
, f
);
1141 function
.builder
= LLVMCreateBuilder();
1145 FOR_EACH_PTR(ep
->bbs
, bb
) {
1146 if (bb
->generation
== generation
)
1149 LLVMBasicBlockRef bbr
;
1152 sprintf(bbname
, "L%d", nr_bb
++);
1153 bbr
= LLVMAppendBasicBlock(function
.fn
, bbname
);
1157 END_FOR_EACH_PTR(bb
);
1159 FOR_EACH_PTR(ep
->bbs
, bb
) {
1160 if (bb
->generation
== generation
)
1163 LLVMPositionBuilderAtEnd(function
.builder
, bb
->priv
);
1165 output_bb(&function
, bb
, generation
);
1167 END_FOR_EACH_PTR(bb
);
1170 static LLVMValueRef
output_data(LLVMModuleRef module
, struct symbol
*sym
)
1172 struct expression
*initializer
= sym
->initializer
;
1173 LLVMValueRef initial_value
;
1178 switch (initializer
->type
) {
1180 initial_value
= LLVMConstInt(symbol_type(module
, sym
), initializer
->value
, 1);
1183 struct symbol
*sym
= initializer
->symbol
;
1185 initial_value
= LLVMGetNamedGlobal(module
, show_ident(sym
->ident
));
1187 initial_value
= output_data(module
, sym
);
1191 const char *s
= initializer
->string
->data
;
1193 initial_value
= LLVMConstString(strdup(s
), strlen(s
) + 1, true);
1200 LLVMTypeRef type
= symbol_type(module
, sym
);
1202 initial_value
= LLVMConstNull(type
);
1205 name
= show_ident(sym
->ident
);
1207 data
= LLVMAddGlobal(module
, LLVMTypeOf(initial_value
), name
);
1209 LLVMSetLinkage(data
, data_linkage(sym
));
1211 if (!(sym
->ctype
.modifiers
& MOD_EXTERN
))
1212 LLVMSetInitializer(data
, initial_value
);
1217 static int compile(LLVMModuleRef module
, struct symbol_list
*list
)
1221 FOR_EACH_PTR(list
, sym
) {
1222 struct entrypoint
*ep
;
1224 ep
= linearize_symbol(sym
);
1226 output_fn(module
, ep
);
1228 output_data(module
, sym
);
1230 END_FOR_EACH_PTR(sym
);
1235 int main(int argc
, char **argv
)
1237 struct string_list
* filelist
= NULL
;
1240 LLVMModuleRef module
= LLVMModuleCreateWithName("sparse");
1242 compile(module
, sparse_initialize(argc
, argv
, &filelist
));
1244 FOR_EACH_PTR_NOTAG(filelist
, file
) {
1245 compile(module
, sparse(file
));
1246 } END_FOR_EACH_PTR_NOTAG(file
);
1248 LLVMWriteBitcodeToFD(module
, STDOUT_FILENO
, 0, 0);
1250 LLVMDisposeModule(module
);