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"
18 static LLVMTypeRef
symbol_type(struct symbol
*sym
)
20 LLVMTypeRef ret
= NULL
;
22 switch (sym
->bit_size
) {
30 ret
= LLVMInt16Type();
33 ret
= LLVMInt32Type();
36 ret
= LLVMInt64Type();
39 die("invalid bit size %d for type %d", sym
->bit_size
, sym
->type
);
46 static LLVMLinkage
data_linkage(struct symbol
*sym
)
48 if (sym
->ctype
.modifiers
& MOD_STATIC
)
49 return LLVMPrivateLinkage
;
51 return LLVMCommonLinkage
;
54 static LLVMLinkage
function_linkage(struct symbol
*sym
)
56 if (sym
->ctype
.modifiers
& MOD_STATIC
)
57 return LLVMInternalLinkage
;
59 return LLVMExternalLinkage
;
62 static void output_insn(struct instruction
*insn
)
66 static void output_bb(struct basic_block
*bb
, unsigned long generation
)
68 struct instruction
*insn
;
70 bb
->generation
= generation
;
72 FOR_EACH_PTR(bb
->insns
, insn
) {
78 END_FOR_EACH_PTR(insn
);
83 static void output_fn(LLVMModuleRef module
, struct entrypoint
*ep
)
85 unsigned long generation
= ++bb_generation
;
86 struct symbol
*sym
= ep
->name
;
87 struct symbol
*base_type
= sym
->ctype
.base_type
;
88 struct symbol
*ret_type
= sym
->ctype
.base_type
->ctype
.base_type
;
89 LLVMTypeRef arg_types
[MAX_ARGS
];
90 struct basic_block
*bb
;
91 LLVMValueRef function
;
96 FOR_EACH_PTR(base_type
->arguments
, arg
) {
97 struct symbol
*arg_base_type
= arg
->ctype
.base_type
;
99 arg_types
[nr_args
++] = symbol_type(arg_base_type
);
100 } END_FOR_EACH_PTR(arg
);
102 name
= show_ident(sym
->ident
);
104 function
= LLVMAddFunction(module
, name
, LLVMFunctionType(symbol_type(ret_type
), arg_types
, nr_args
, 0));
106 LLVMSetLinkage(function
, function_linkage(sym
));
110 FOR_EACH_PTR(ep
->bbs
, bb
) {
111 if (bb
->generation
== generation
)
113 output_bb(bb
, generation
);
115 END_FOR_EACH_PTR(bb
);
117 LLVMBasicBlockRef entry
= LLVMAppendBasicBlock(function
, "entry");
119 LLVMBuilderRef builder
= LLVMCreateBuilder();
121 LLVMPositionBuilderAtEnd(builder
, entry
);
123 if (ret_type
== &void_ctype
)
124 LLVMBuildRetVoid(builder
);
126 LLVMBuildRet(builder
, LLVMConstInt(symbol_type(ret_type
), 0, 1));
129 static int output_data(LLVMModuleRef module
, struct symbol
*sym
)
134 name
= show_ident(sym
->ident
);
136 data
= LLVMAddGlobal(module
, symbol_type(sym
->ctype
.base_type
), name
);
138 LLVMSetLinkage(data
, data_linkage(sym
));
140 LLVMSetInitializer(data
, LLVMConstInt(symbol_type(sym
), 0, 1));
145 static int compile(LLVMModuleRef module
, struct symbol_list
*list
)
149 FOR_EACH_PTR(list
, sym
) {
150 struct entrypoint
*ep
;
152 ep
= linearize_symbol(sym
);
154 output_fn(module
, ep
);
156 output_data(module
, sym
);
158 END_FOR_EACH_PTR(sym
);
163 int main(int argc
, char **argv
)
165 struct string_list
* filelist
= NULL
;
168 LLVMModuleRef module
= LLVMModuleCreateWithName("sparse");
170 compile(module
, sparse_initialize(argc
, argv
, &filelist
));
172 FOR_EACH_PTR_NOTAG(filelist
, file
) {
173 compile(module
, sparse(file
));
174 } END_FOR_EACH_PTR_NOTAG(file
);
177 LLVMWriteBitcodeToFD(module
, STDOUT_FILENO
, 0, 0);
179 LLVMDumpModule(module
);
182 LLVMDisposeModule(module
);