3 * ./sparse-llvm hello.c | llc | as -o hello.o
6 #include <llvm-c/Core.h>
7 #include <llvm-c/BitWriter.h>
14 #include "expression.h"
15 #include "linearize.h"
19 LLVMBuilderRef builder
;
24 static LLVMTypeRef
symbol_type(struct symbol
*sym
)
26 LLVMTypeRef ret
= NULL
;
28 switch (sym
->bit_size
) {
36 ret
= LLVMInt16Type();
39 ret
= LLVMInt32Type();
42 ret
= LLVMInt64Type();
45 die("invalid bit size %d for type %d", sym
->bit_size
, sym
->type
);
52 static LLVMLinkage
data_linkage(struct symbol
*sym
)
54 if (sym
->ctype
.modifiers
& MOD_STATIC
)
55 return LLVMPrivateLinkage
;
57 return LLVMExternalLinkage
;
60 static LLVMLinkage
function_linkage(struct symbol
*sym
)
62 if (sym
->ctype
.modifiers
& MOD_STATIC
)
63 return LLVMInternalLinkage
;
65 return LLVMExternalLinkage
;
68 static void output_op_ret(struct function
*fn
, struct instruction
*insn
)
70 pseudo_t pseudo
= insn
->src
;
72 if (pseudo
&& pseudo
!= VOID
) {
73 switch (pseudo
->type
) {
81 LLVMBuildRet(fn
->builder
, LLVMConstInt(LLVMGetReturnType(fn
->type
), pseudo
->value
, 1));
84 LLVMValueRef param
= LLVMGetParam(fn
->fn
, pseudo
->nr
- 1);
85 LLVMBuildRet(fn
->builder
, param
);
95 LLVMBuildRetVoid(fn
->builder
);
98 static void output_insn(struct function
*fn
, struct instruction
*insn
)
100 switch (insn
->opcode
) {
102 output_op_ret(fn
, insn
);
112 case OP_COMPUTEDGOTO
:
118 case OP_LOAD
: case OP_LNOP
:
120 case OP_STORE
: case OP_SNOP
:
122 case OP_INLINED_CALL
:
130 case OP_BINARY
... OP_BINARY_END
:
131 case OP_BINCMP
... OP_BINCMP_END
:
137 case OP_NOT
: case OP_NEG
:
156 static void output_bb(struct function
*fn
, struct basic_block
*bb
, unsigned long generation
)
158 struct instruction
*insn
;
160 bb
->generation
= generation
;
162 FOR_EACH_PTR(bb
->insns
, insn
) {
166 output_insn(fn
, insn
);
168 END_FOR_EACH_PTR(insn
);
173 static void output_fn(LLVMModuleRef module
, struct entrypoint
*ep
)
175 unsigned long generation
= ++bb_generation
;
176 struct symbol
*sym
= ep
->name
;
177 struct symbol
*base_type
= sym
->ctype
.base_type
;
178 struct symbol
*ret_type
= sym
->ctype
.base_type
->ctype
.base_type
;
179 LLVMTypeRef arg_types
[MAX_ARGS
];
180 LLVMTypeRef return_type
;
181 struct function function
;
182 struct basic_block
*bb
;
187 FOR_EACH_PTR(base_type
->arguments
, arg
) {
188 struct symbol
*arg_base_type
= arg
->ctype
.base_type
;
190 arg_types
[nr_args
++] = symbol_type(arg_base_type
);
191 } END_FOR_EACH_PTR(arg
);
193 name
= show_ident(sym
->ident
);
195 return_type
= symbol_type(ret_type
);
197 function
.type
= LLVMFunctionType(return_type
, arg_types
, nr_args
, 0);
199 function
.fn
= LLVMAddFunction(module
, name
, function
.type
);
201 LLVMSetLinkage(function
.fn
, function_linkage(sym
));
205 function
.builder
= LLVMCreateBuilder();
207 LLVMBasicBlockRef entry
= LLVMAppendBasicBlock(function
.fn
, "entry");
209 LLVMPositionBuilderAtEnd(function
.builder
, entry
);
211 FOR_EACH_PTR(ep
->bbs
, bb
) {
212 if (bb
->generation
== generation
)
215 output_bb(&function
, bb
, generation
);
217 END_FOR_EACH_PTR(bb
);
220 static int output_data(LLVMModuleRef module
, struct symbol
*sym
)
222 struct expression
*initializer
= sym
->initializer
;
223 unsigned long long initial_value
= 0;
228 if (initializer
->type
== EXPR_VALUE
)
229 initial_value
= initializer
->value
;
234 name
= show_ident(sym
->ident
);
236 data
= LLVMAddGlobal(module
, symbol_type(sym
->ctype
.base_type
), name
);
238 LLVMSetLinkage(data
, data_linkage(sym
));
240 LLVMSetInitializer(data
, LLVMConstInt(symbol_type(sym
), initial_value
, 1));
245 static int compile(LLVMModuleRef module
, struct symbol_list
*list
)
249 FOR_EACH_PTR(list
, sym
) {
250 struct entrypoint
*ep
;
252 ep
= linearize_symbol(sym
);
254 output_fn(module
, ep
);
256 output_data(module
, sym
);
258 END_FOR_EACH_PTR(sym
);
263 int main(int argc
, char **argv
)
265 struct string_list
* filelist
= NULL
;
268 LLVMModuleRef module
= LLVMModuleCreateWithName("sparse");
270 compile(module
, sparse_initialize(argc
, argv
, &filelist
));
272 FOR_EACH_PTR_NOTAG(filelist
, file
) {
273 compile(module
, sparse(file
));
274 } END_FOR_EACH_PTR_NOTAG(file
);
277 LLVMWriteBitcodeToFD(module
, STDOUT_FILENO
, 0, 0);
279 LLVMDumpModule(module
);
282 LLVMDisposeModule(module
);