3 * ./sparse-llvm hello.c | llc | as -o hello.o
6 #include <llvm-c/Core.h>
7 #include <llvm-c/BitWriter.h>
8 #include <llvm-c/Analysis.h>
17 #include "expression.h"
18 #include "linearize.h"
22 LLVMBuilderRef builder
;
28 static inline bool symbol_is_fp_type(struct symbol
*sym
)
33 return sym
->ctype
.base_type
== &fp_type
;
36 static LLVMTypeRef
symbol_type(LLVMModuleRef module
, struct symbol
*sym
);
38 static LLVMTypeRef
func_return_type(LLVMModuleRef module
, struct symbol
*sym
)
40 return symbol_type(module
, sym
->ctype
.base_type
);
43 static LLVMTypeRef
sym_func_type(LLVMModuleRef module
, struct symbol
*sym
)
45 LLVMTypeRef
*arg_type
;
46 LLVMTypeRef func_type
;
51 /* to avoid strangeness with varargs [for now], we build
52 * the function and type anew, for each call. This
53 * is probably wrong. We should look up the
54 * symbol declaration info.
57 ret_type
= func_return_type(module
, sym
);
59 /* count args, build argument type information */
60 FOR_EACH_PTR(sym
->arguments
, arg
) {
62 } END_FOR_EACH_PTR(arg
);
64 arg_type
= calloc(n_arg
, sizeof(LLVMTypeRef
));
67 FOR_EACH_PTR(sym
->arguments
, arg
) {
68 struct symbol
*arg_sym
= arg
->ctype
.base_type
;
70 arg_type
[idx
++] = symbol_type(module
, arg_sym
);
71 } END_FOR_EACH_PTR(arg
);
72 func_type
= LLVMFunctionType(ret_type
, arg_type
, n_arg
,
78 static LLVMTypeRef
sym_array_type(LLVMModuleRef module
, struct symbol
*sym
)
80 LLVMTypeRef elem_type
;
81 struct symbol
*base_type
;
83 base_type
= sym
->ctype
.base_type
;
85 elem_type
= symbol_type(module
, base_type
);
89 return LLVMArrayType(elem_type
, sym
->bit_size
/ 8);
92 #define MAX_STRUCT_MEMBERS 64
94 static LLVMTypeRef
sym_struct_type(LLVMModuleRef module
, struct symbol
*sym
)
96 LLVMTypeRef elem_types
[MAX_STRUCT_MEMBERS
];
97 struct symbol
*member
;
102 sprintf(buffer
, "%.*s", sym
->ident
->len
, sym
->ident
->name
);
104 ret
= LLVMGetTypeByName(module
, buffer
);
108 ret
= LLVMStructCreateNamed(LLVMGetGlobalContext(), buffer
);
110 FOR_EACH_PTR(sym
->symbol_list
, member
) {
111 LLVMTypeRef member_type
;
113 assert(nr
< MAX_STRUCT_MEMBERS
);
115 member_type
= symbol_type(module
, member
);
117 elem_types
[nr
++] = member_type
;
118 } END_FOR_EACH_PTR(member
);
120 LLVMStructSetBody(ret
, elem_types
, nr
, 0 /* packed? */);
124 static LLVMTypeRef
sym_union_type(LLVMModuleRef module
, struct symbol
*sym
)
126 LLVMTypeRef elements
;
130 * There's no union support in the LLVM API so we treat unions as
131 * opaque structs. The downside is that we lose type information on the
132 * members but as LLVM doesn't care, neither do we.
134 union_size
= sym
->bit_size
/ 8;
136 elements
= LLVMArrayType(LLVMInt8Type(), union_size
);
138 return LLVMStructType(&elements
, 1, 0 /* packed? */);
141 static LLVMTypeRef
sym_ptr_type(LLVMModuleRef module
, struct symbol
*sym
)
145 /* 'void *' is treated like 'char *' */
146 if (is_void_type(sym
->ctype
.base_type
))
147 type
= LLVMInt8Type();
149 type
= symbol_type(module
, sym
->ctype
.base_type
);
151 return LLVMPointerType(type
, 0);
154 static LLVMTypeRef
sym_basetype_type(struct symbol
*sym
)
156 LLVMTypeRef ret
= NULL
;
158 if (symbol_is_fp_type(sym
)) {
159 switch (sym
->bit_size
) {
161 ret
= LLVMFloatType();
164 ret
= LLVMDoubleType();
167 ret
= LLVMX86FP80Type();
170 die("invalid bit size %d for type %d", sym
->bit_size
, sym
->type
);
174 switch (sym
->bit_size
) {
176 ret
= LLVMVoidType();
179 ret
= LLVMInt1Type();
182 ret
= LLVMInt8Type();
185 ret
= LLVMInt16Type();
188 ret
= LLVMInt32Type();
191 ret
= LLVMInt64Type();
194 die("invalid bit size %d for type %d", sym
->bit_size
, sym
->type
);
202 static LLVMTypeRef
symbol_type(LLVMModuleRef module
, struct symbol
*sym
)
204 LLVMTypeRef ret
= NULL
;
210 ret
= symbol_type(module
, sym
->ctype
.base_type
);
213 ret
= sym_basetype_type(sym
);
216 ret
= sym_ptr_type(module
, sym
);
219 ret
= sym_union_type(module
, sym
);
222 ret
= sym_struct_type(module
, sym
);
225 ret
= sym_array_type(module
, sym
);
228 ret
= sym_func_type(module
, sym
);
236 static LLVMTypeRef
insn_symbol_type(LLVMModuleRef module
, struct instruction
*insn
)
239 return symbol_type(module
, insn
->type
);
241 switch (insn
->size
) {
242 case 8: return LLVMInt8Type();
243 case 16: return LLVMInt16Type();
244 case 32: return LLVMInt32Type();
245 case 64: return LLVMInt64Type();
248 die("invalid bit size %d", insn
->size
);
252 return NULL
; /* not reached */
255 static LLVMLinkage
data_linkage(struct symbol
*sym
)
257 if (sym
->ctype
.modifiers
& MOD_STATIC
)
258 return LLVMPrivateLinkage
;
260 return LLVMExternalLinkage
;
263 static LLVMLinkage
function_linkage(struct symbol
*sym
)
265 if (sym
->ctype
.modifiers
& MOD_STATIC
)
266 return LLVMInternalLinkage
;
268 return LLVMExternalLinkage
;
271 #define MAX_PSEUDO_NAME 64
273 static void pseudo_name(pseudo_t pseudo
, char *buf
)
275 switch (pseudo
->type
) {
277 snprintf(buf
, MAX_PSEUDO_NAME
, "R%d", pseudo
->nr
);
290 snprintf(buf
, MAX_PSEUDO_NAME
, "PHI%d", pseudo
->nr
);
297 static LLVMValueRef
pseudo_to_value(struct function
*fn
, struct instruction
*insn
, pseudo_t pseudo
)
299 LLVMValueRef result
= NULL
;
301 switch (pseudo
->type
) {
303 result
= pseudo
->priv
;
306 struct symbol
*sym
= pseudo
->sym
;
307 struct expression
*expr
;
309 assert(sym
->bb_target
== NULL
);
311 expr
= sym
->initializer
;
313 switch (expr
->type
) {
315 const char *s
= expr
->string
->data
;
316 LLVMValueRef indices
[] = { LLVMConstInt(LLVMInt64Type(), 0, 0), LLVMConstInt(LLVMInt64Type(), 0, 0) };
319 data
= LLVMAddGlobal(fn
->module
, LLVMArrayType(LLVMInt8Type(), strlen(s
) + 1), ".str");
320 LLVMSetLinkage(data
, LLVMPrivateLinkage
);
321 LLVMSetGlobalConstant(data
, 1);
322 LLVMSetInitializer(data
, LLVMConstString(strdup(s
), strlen(s
) + 1, true));
324 result
= LLVMConstGEP(data
, indices
, ARRAY_SIZE(indices
));
328 struct symbol
*sym
= expr
->symbol
;
330 result
= LLVMGetNamedGlobal(fn
->module
, show_ident(sym
->ident
));
331 assert(result
!= NULL
);
338 const char *name
= show_ident(sym
->ident
);
339 LLVMTypeRef type
= symbol_type(fn
->module
, sym
);
341 if (LLVMGetTypeKind(type
) == LLVMFunctionTypeKind
) {
342 result
= LLVMGetNamedFunction(fn
->module
, name
);
344 result
= LLVMAddFunction(fn
->module
, name
, type
);
346 result
= LLVMGetNamedGlobal(fn
->module
, name
);
348 result
= LLVMAddGlobal(fn
->module
, type
, name
);
354 result
= LLVMConstInt(insn_symbol_type(fn
->module
, insn
), pseudo
->value
, 1);
357 result
= LLVMGetParam(fn
->fn
, pseudo
->nr
- 1);
361 result
= pseudo
->priv
;
373 static LLVMRealPredicate
translate_fop(int opcode
)
375 static const LLVMRealPredicate trans_tbl
[] = {
376 [OP_SET_EQ
] = LLVMRealOEQ
,
377 [OP_SET_NE
] = LLVMRealUNE
,
378 [OP_SET_LE
] = LLVMRealOLE
,
379 [OP_SET_GE
] = LLVMRealOGE
,
380 [OP_SET_LT
] = LLVMRealOLT
,
381 [OP_SET_GT
] = LLVMRealOGT
,
382 /* Are these used with FP? */
383 [OP_SET_B
] = LLVMRealOLT
,
384 [OP_SET_A
] = LLVMRealOGT
,
385 [OP_SET_BE
] = LLVMRealOLE
,
386 [OP_SET_AE
] = LLVMRealOGE
,
389 return trans_tbl
[opcode
];
392 static LLVMIntPredicate
translate_op(int opcode
)
394 static const LLVMIntPredicate trans_tbl
[] = {
395 [OP_SET_EQ
] = LLVMIntEQ
,
396 [OP_SET_NE
] = LLVMIntNE
,
397 [OP_SET_LE
] = LLVMIntSLE
,
398 [OP_SET_GE
] = LLVMIntSGE
,
399 [OP_SET_LT
] = LLVMIntSLT
,
400 [OP_SET_GT
] = LLVMIntSGT
,
401 [OP_SET_B
] = LLVMIntULT
,
402 [OP_SET_A
] = LLVMIntUGT
,
403 [OP_SET_BE
] = LLVMIntULE
,
404 [OP_SET_AE
] = LLVMIntUGE
,
407 return trans_tbl
[opcode
];
410 static void output_op_binary(struct function
*fn
, struct instruction
*insn
)
412 LLVMValueRef lhs
, rhs
, target
;
413 char target_name
[64];
415 lhs
= pseudo_to_value(fn
, insn
, insn
->src1
);
417 rhs
= pseudo_to_value(fn
, insn
, insn
->src2
);
419 pseudo_name(insn
->target
, target_name
);
421 switch (insn
->opcode
) {
424 if (symbol_is_fp_type(insn
->type
))
425 target
= LLVMBuildFAdd(fn
->builder
, lhs
, rhs
, target_name
);
427 target
= LLVMBuildAdd(fn
->builder
, lhs
, rhs
, target_name
);
430 if (symbol_is_fp_type(insn
->type
))
431 target
= LLVMBuildFSub(fn
->builder
, lhs
, rhs
, target_name
);
433 target
= LLVMBuildSub(fn
->builder
, lhs
, rhs
, target_name
);
436 if (symbol_is_fp_type(insn
->type
))
437 target
= LLVMBuildFMul(fn
->builder
, lhs
, rhs
, target_name
);
439 target
= LLVMBuildMul(fn
->builder
, lhs
, rhs
, target_name
);
442 assert(!symbol_is_fp_type(insn
->type
));
443 target
= LLVMBuildMul(fn
->builder
, lhs
, rhs
, target_name
);
446 if (symbol_is_fp_type(insn
->type
))
447 target
= LLVMBuildFDiv(fn
->builder
, lhs
, rhs
, target_name
);
449 target
= LLVMBuildUDiv(fn
->builder
, lhs
, rhs
, target_name
);
452 assert(!symbol_is_fp_type(insn
->type
));
453 target
= LLVMBuildSDiv(fn
->builder
, lhs
, rhs
, target_name
);
456 assert(!symbol_is_fp_type(insn
->type
));
457 target
= LLVMBuildURem(fn
->builder
, lhs
, rhs
, target_name
);
460 assert(!symbol_is_fp_type(insn
->type
));
461 target
= LLVMBuildSRem(fn
->builder
, lhs
, rhs
, target_name
);
464 assert(!symbol_is_fp_type(insn
->type
));
465 target
= LLVMBuildShl(fn
->builder
, lhs
, rhs
, target_name
);
468 assert(!symbol_is_fp_type(insn
->type
));
469 target
= LLVMBuildLShr(fn
->builder
, lhs
, rhs
, target_name
);
472 assert(!symbol_is_fp_type(insn
->type
));
473 target
= LLVMBuildAShr(fn
->builder
, lhs
, rhs
, target_name
);
478 assert(!symbol_is_fp_type(insn
->type
));
479 target
= LLVMBuildAnd(fn
->builder
, lhs
, rhs
, target_name
);
482 assert(!symbol_is_fp_type(insn
->type
));
483 target
= LLVMBuildOr(fn
->builder
, lhs
, rhs
, target_name
);
486 assert(!symbol_is_fp_type(insn
->type
));
487 target
= LLVMBuildXor(fn
->builder
, lhs
, rhs
, target_name
);
492 assert(!symbol_is_fp_type(insn
->type
));
494 y
= LLVMBuildICmp(fn
->builder
, LLVMIntNE
, lhs
, LLVMConstInt(LLVMTypeOf(lhs
), 0, 0), "y");
495 x
= LLVMBuildICmp(fn
->builder
, LLVMIntNE
, rhs
, LLVMConstInt(LLVMTypeOf(rhs
), 0, 0), "x");
497 target
= LLVMBuildAnd(fn
->builder
, y
, x
, target_name
);
503 assert(!symbol_is_fp_type(insn
->type
));
505 tmp
= LLVMBuildOr(fn
->builder
, rhs
, lhs
, "tmp");
507 target
= LLVMBuildICmp(fn
->builder
, LLVMIntNE
, tmp
, LLVMConstInt(LLVMTypeOf(tmp
), 0, 0), target_name
);
511 /* Binary comparison */
512 case OP_BINCMP
... OP_BINCMP_END
: {
513 if (LLVMGetTypeKind(LLVMTypeOf(lhs
)) == LLVMIntegerTypeKind
) {
514 LLVMIntPredicate op
= translate_op(insn
->opcode
);
516 target
= LLVMBuildICmp(fn
->builder
, op
, lhs
, rhs
, target_name
);
518 LLVMRealPredicate op
= translate_fop(insn
->opcode
);
520 target
= LLVMBuildFCmp(fn
->builder
, op
, lhs
, rhs
, target_name
);
529 insn
->target
->priv
= target
;
532 static void output_op_ret(struct function
*fn
, struct instruction
*insn
)
534 pseudo_t pseudo
= insn
->src
;
536 if (pseudo
&& pseudo
!= VOID
) {
537 LLVMValueRef result
= pseudo_to_value(fn
, insn
, pseudo
);
539 LLVMBuildRet(fn
->builder
, result
);
541 LLVMBuildRetVoid(fn
->builder
);
544 static void output_op_load(struct function
*fn
, struct instruction
*insn
)
546 LLVMTypeRef int_type
;
547 LLVMValueRef src_p
, src_i
, ofs_i
, addr_i
, addr
, target
;
549 /* int type large enough to hold a pointer */
550 int_type
= LLVMIntType(bits_in_pointer
);
552 /* convert to integer, add src + offset */
553 src_p
= pseudo_to_value(fn
, insn
, insn
->src
);
554 src_i
= LLVMBuildPtrToInt(fn
->builder
, src_p
, int_type
, "src_i");
556 ofs_i
= LLVMConstInt(int_type
, insn
->offset
, 0);
557 addr_i
= LLVMBuildAdd(fn
->builder
, src_i
, ofs_i
, "addr_i");
559 /* convert address back to pointer */
560 addr
= LLVMBuildIntToPtr(fn
->builder
, addr_i
,
561 LLVMTypeOf(src_p
), "addr");
564 target
= LLVMBuildLoad(fn
->builder
, addr
, "load_target");
566 insn
->target
->priv
= target
;
569 static void output_op_store(struct function
*fn
, struct instruction
*insn
)
571 LLVMTypeRef int_type
;
572 LLVMValueRef src_p
, src_i
, ofs_i
, addr_i
, addr
, target
, target_in
;
574 /* int type large enough to hold a pointer */
575 int_type
= LLVMIntType(bits_in_pointer
);
577 /* convert to integer, add src + offset */
578 src_p
= pseudo_to_value(fn
, insn
, insn
->src
);
579 src_i
= LLVMBuildPtrToInt(fn
->builder
, src_p
, int_type
, "src_i");
581 ofs_i
= LLVMConstInt(int_type
, insn
->offset
, 0);
582 addr_i
= LLVMBuildAdd(fn
->builder
, src_i
, ofs_i
, "addr_i");
584 /* convert address back to pointer */
585 addr
= LLVMBuildIntToPtr(fn
->builder
, addr_i
,
586 LLVMPointerType(int_type
, 0), "addr");
588 target_in
= pseudo_to_value(fn
, insn
, insn
->target
);
591 target
= LLVMBuildStore(fn
->builder
, target_in
, addr
);
593 insn
->target
->priv
= target
;
596 static LLVMValueRef
bool_value(struct function
*fn
, LLVMValueRef value
)
598 if (LLVMTypeOf(value
) != LLVMInt1Type())
599 value
= LLVMBuildIsNotNull(fn
->builder
, value
, "cond");
604 static void output_op_br(struct function
*fn
, struct instruction
*br
)
607 LLVMValueRef cond
= bool_value(fn
,
608 pseudo_to_value(fn
, br
, br
->cond
));
610 LLVMBuildCondBr(fn
->builder
, cond
,
614 LLVMBuildBr(fn
->builder
,
615 br
->bb_true
? br
->bb_true
->priv
:
619 static void output_op_sel(struct function
*fn
, struct instruction
*insn
)
621 LLVMValueRef target
, src1
, src2
, src3
;
623 src1
= bool_value(fn
, pseudo_to_value(fn
, insn
, insn
->src1
));
624 src2
= pseudo_to_value(fn
, insn
, insn
->src2
);
625 src3
= pseudo_to_value(fn
, insn
, insn
->src3
);
627 target
= LLVMBuildSelect(fn
->builder
, src1
, src2
, src3
, "select");
629 insn
->target
->priv
= target
;
632 static void output_op_switch(struct function
*fn
, struct instruction
*insn
)
634 LLVMValueRef sw_val
, target
;
635 struct basic_block
*def
= NULL
;
636 struct multijmp
*jmp
;
639 FOR_EACH_PTR(insn
->multijmp_list
, jmp
) {
640 if (jmp
->begin
== jmp
->end
) { /* case N */
642 } else if (jmp
->begin
< jmp
->end
) { /* case M..N */
644 } else /* default case */
646 } END_FOR_EACH_PTR(jmp
);
648 sw_val
= pseudo_to_value(fn
, insn
, insn
->target
);
649 target
= LLVMBuildSwitch(fn
->builder
, sw_val
,
650 def
? def
->priv
: NULL
, n_jmp
);
652 FOR_EACH_PTR(insn
->multijmp_list
, jmp
) {
653 if (jmp
->begin
== jmp
->end
) { /* case N */
655 LLVMConstInt(LLVMInt32Type(), jmp
->begin
, 0),
657 } else if (jmp
->begin
< jmp
->end
) { /* case M..N */
660 } END_FOR_EACH_PTR(jmp
);
662 insn
->target
->priv
= target
;
665 static void output_op_call(struct function
*fn
, struct instruction
*insn
)
667 LLVMValueRef target
, func
;
672 FOR_EACH_PTR(insn
->arguments
, arg
) {
674 } END_FOR_EACH_PTR(arg
);
676 args
= calloc(n_arg
, sizeof(LLVMValueRef
));
679 FOR_EACH_PTR(insn
->arguments
, arg
) {
680 args
[i
++] = pseudo_to_value(fn
, insn
, arg
);
681 } END_FOR_EACH_PTR(arg
);
683 func
= pseudo_to_value(fn
, insn
, insn
->func
);
684 target
= LLVMBuildCall(fn
->builder
, func
, args
, n_arg
, "");
686 insn
->target
->priv
= target
;
689 static void output_op_phisrc(struct function
*fn
, struct instruction
*insn
)
692 struct instruction
*phi
;
694 assert(insn
->target
->priv
== NULL
);
697 v
= pseudo_to_value(fn
, insn
, insn
->phi_src
);
699 FOR_EACH_PTR(insn
->phi_users
, phi
) {
700 LLVMValueRef load
, ptr
;
702 assert(phi
->opcode
== OP_PHI
);
703 /* phi must be load from alloca */
704 load
= phi
->target
->priv
;
705 assert(LLVMGetInstructionOpcode(load
) == LLVMLoad
);
706 ptr
= LLVMGetOperand(load
, 0);
707 /* store v to alloca */
708 LLVMBuildStore(fn
->builder
, v
, ptr
);
709 } END_FOR_EACH_PTR(phi
);
712 static void output_op_phi(struct function
*fn
, struct instruction
*insn
)
714 LLVMValueRef load
= insn
->target
->priv
;
717 assert(LLVMGetInstructionOpcode(load
) == LLVMLoad
);
718 /* forward load has no parent block */
719 assert(!LLVMGetInstructionParent(load
));
720 /* finalize load in current block */
721 LLVMInsertIntoBuilder(fn
->builder
, load
);
724 static void output_op_ptrcast(struct function
*fn
, struct instruction
*insn
)
726 LLVMValueRef src
, target
;
727 char target_name
[64];
729 src
= insn
->src
->priv
;
731 src
= pseudo_to_value(fn
, insn
, insn
->src
);
733 pseudo_name(insn
->target
, target_name
);
735 assert(!symbol_is_fp_type(insn
->type
));
737 target
= LLVMBuildBitCast(fn
->builder
, src
, insn_symbol_type(fn
->module
, insn
), target_name
);
739 insn
->target
->priv
= target
;
742 static void output_op_cast(struct function
*fn
, struct instruction
*insn
, LLVMOpcode op
)
744 LLVMValueRef src
, target
;
745 char target_name
[64];
747 src
= insn
->src
->priv
;
749 src
= pseudo_to_value(fn
, insn
, insn
->src
);
751 pseudo_name(insn
->target
, target_name
);
753 assert(!symbol_is_fp_type(insn
->type
));
755 if (insn
->size
< LLVMGetIntTypeWidth(LLVMTypeOf(src
)))
756 target
= LLVMBuildTrunc(fn
->builder
, src
, insn_symbol_type(fn
->module
, insn
), target_name
);
758 target
= LLVMBuildCast(fn
->builder
, op
, src
, insn_symbol_type(fn
->module
, insn
), target_name
);
760 insn
->target
->priv
= target
;
763 static void output_op_copy(struct function
*fn
, struct instruction
*insn
,
766 LLVMValueRef src
, target
;
767 LLVMTypeRef const_type
;
768 char target_name
[64];
770 pseudo_name(insn
->target
, target_name
);
771 src
= pseudo_to_value(fn
, insn
, pseudo
);
772 const_type
= insn_symbol_type(fn
->module
, insn
);
775 * This is nothing more than 'target = src'
777 * TODO: find a better way to provide an identity function,
778 * than using "X + 0" simply to produce a new LLVM pseudo
781 if (symbol_is_fp_type(insn
->type
))
782 target
= LLVMBuildFAdd(fn
->builder
, src
,
783 LLVMConstReal(const_type
, 0.0), target_name
);
785 target
= LLVMBuildAdd(fn
->builder
, src
,
786 LLVMConstInt(const_type
, 0, 0), target_name
);
788 insn
->target
->priv
= target
;
791 static void output_insn(struct function
*fn
, struct instruction
*insn
)
793 switch (insn
->opcode
) {
795 output_op_ret(fn
, insn
);
798 output_op_br(fn
, insn
);
807 output_op_switch(fn
, insn
);
809 case OP_COMPUTEDGOTO
:
813 output_op_phisrc(fn
, insn
);
816 output_op_phi(fn
, insn
);
819 output_op_load(fn
, insn
);
825 output_op_store(fn
, insn
);
830 case OP_INLINED_CALL
:
834 output_op_call(fn
, insn
);
837 output_op_cast(fn
, insn
, LLVMZExt
);
840 output_op_cast(fn
, insn
, LLVMSExt
);
846 output_op_ptrcast(fn
, insn
);
848 case OP_BINARY
... OP_BINARY_END
:
849 case OP_BINCMP
... OP_BINCMP_END
:
850 output_op_binary(fn
, insn
);
853 output_op_sel(fn
, insn
);
859 LLVMValueRef src
, target
;
860 char target_name
[64];
862 src
= pseudo_to_value(fn
, insn
, insn
->src
);
864 pseudo_name(insn
->target
, target_name
);
866 target
= LLVMBuildNot(fn
->builder
, src
, target_name
);
868 insn
->target
->priv
= target
;
889 output_op_copy(fn
, insn
, insn
->src
);
896 static void output_bb(struct function
*fn
, struct basic_block
*bb
, unsigned long generation
)
898 struct instruction
*insn
;
900 bb
->generation
= generation
;
902 FOR_EACH_PTR(bb
->insns
, insn
) {
906 output_insn(fn
, insn
);
908 END_FOR_EACH_PTR(insn
);
913 static void output_fn(LLVMModuleRef module
, struct entrypoint
*ep
)
915 unsigned long generation
= ++bb_generation
;
916 struct symbol
*sym
= ep
->name
;
917 struct symbol
*base_type
= sym
->ctype
.base_type
;
918 struct symbol
*ret_type
= sym
->ctype
.base_type
->ctype
.base_type
;
919 LLVMTypeRef arg_types
[MAX_ARGS
];
920 LLVMTypeRef return_type
;
921 struct function function
= { .module
= module
};
922 struct basic_block
*bb
;
927 FOR_EACH_PTR(base_type
->arguments
, arg
) {
928 struct symbol
*arg_base_type
= arg
->ctype
.base_type
;
930 arg_types
[nr_args
++] = symbol_type(module
, arg_base_type
);
931 } END_FOR_EACH_PTR(arg
);
933 name
= show_ident(sym
->ident
);
935 return_type
= symbol_type(module
, ret_type
);
937 function
.type
= LLVMFunctionType(return_type
, arg_types
, nr_args
, 0);
939 function
.fn
= LLVMAddFunction(module
, name
, function
.type
);
940 LLVMSetFunctionCallConv(function
.fn
, LLVMCCallConv
);
942 LLVMSetLinkage(function
.fn
, function_linkage(sym
));
944 function
.builder
= LLVMCreateBuilder();
948 FOR_EACH_PTR(ep
->bbs
, bb
) {
949 if (bb
->generation
== generation
)
952 LLVMBasicBlockRef bbr
;
954 struct instruction
*insn
;
956 sprintf(bbname
, "L%d", nr_bb
++);
957 bbr
= LLVMAppendBasicBlock(function
.fn
, bbname
);
961 /* allocate alloca for each phi */
962 FOR_EACH_PTR(bb
->insns
, insn
) {
963 LLVMBasicBlockRef entrybbr
;
964 LLVMTypeRef phi_type
;
967 if (!insn
->bb
|| insn
->opcode
!= OP_PHI
)
969 /* insert alloca into entry block */
970 entrybbr
= LLVMGetEntryBasicBlock(function
.fn
);
971 LLVMPositionBuilderAtEnd(function
.builder
, entrybbr
);
972 phi_type
= insn_symbol_type(module
, insn
);
973 ptr
= LLVMBuildAlloca(function
.builder
, phi_type
, "");
974 /* emit forward load for phi */
975 LLVMClearInsertionPosition(function
.builder
);
976 insn
->target
->priv
= LLVMBuildLoad(function
.builder
, ptr
, "phi");
977 } END_FOR_EACH_PTR(insn
);
979 END_FOR_EACH_PTR(bb
);
981 FOR_EACH_PTR(ep
->bbs
, bb
) {
982 if (bb
->generation
== generation
)
985 LLVMPositionBuilderAtEnd(function
.builder
, bb
->priv
);
987 output_bb(&function
, bb
, generation
);
989 END_FOR_EACH_PTR(bb
);
992 static LLVMValueRef
output_data(LLVMModuleRef module
, struct symbol
*sym
)
994 struct expression
*initializer
= sym
->initializer
;
995 LLVMValueRef initial_value
;
1000 switch (initializer
->type
) {
1002 initial_value
= LLVMConstInt(symbol_type(module
, sym
), initializer
->value
, 1);
1005 struct symbol
*sym
= initializer
->symbol
;
1007 initial_value
= LLVMGetNamedGlobal(module
, show_ident(sym
->ident
));
1009 initial_value
= output_data(module
, sym
);
1013 const char *s
= initializer
->string
->data
;
1015 initial_value
= LLVMConstString(strdup(s
), strlen(s
) + 1, true);
1022 LLVMTypeRef type
= symbol_type(module
, sym
);
1024 initial_value
= LLVMConstNull(type
);
1027 name
= show_ident(sym
->ident
);
1029 data
= LLVMAddGlobal(module
, LLVMTypeOf(initial_value
), name
);
1031 LLVMSetLinkage(data
, data_linkage(sym
));
1033 if (!(sym
->ctype
.modifiers
& MOD_EXTERN
))
1034 LLVMSetInitializer(data
, initial_value
);
1039 static int compile(LLVMModuleRef module
, struct symbol_list
*list
)
1043 FOR_EACH_PTR(list
, sym
) {
1044 struct entrypoint
*ep
;
1046 ep
= linearize_symbol(sym
);
1048 output_fn(module
, ep
);
1050 output_data(module
, sym
);
1052 END_FOR_EACH_PTR(sym
);
1057 int main(int argc
, char **argv
)
1059 struct string_list
* filelist
= NULL
;
1062 LLVMModuleRef module
= LLVMModuleCreateWithName("sparse");
1064 compile(module
, sparse_initialize(argc
, argv
, &filelist
));
1066 /* need ->phi_users */
1068 FOR_EACH_PTR_NOTAG(filelist
, file
) {
1069 compile(module
, sparse(file
));
1070 } END_FOR_EACH_PTR_NOTAG(file
);
1072 LLVMVerifyModule(module
, LLVMPrintMessageAction
, NULL
);
1074 LLVMWriteBitcodeToFD(module
, STDOUT_FILENO
, 0, 0);
1076 LLVMDisposeModule(module
);