1 /** This code is public domain, and taken from
2  * https://github.com/paulsmith/getting-started-llvm-c-api/blob/master/sum.c
3  */
4 /**
5  * LLVM equivalent of:
6  *
7  * int sum(int a, int b) {
8  *     return a + b;
9  * }
10  */
11 
12 #include <llvm-c/Core.h>
13 #include <llvm-c/ExecutionEngine.h>
14 #include <llvm-c/Target.h>
15 #include <llvm-c/Analysis.h>
16 #include <llvm-c/BitWriter.h>
17 
18 #include <inttypes.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 
main(int argc,char const * argv[])22 int main(int argc, char const *argv[]) {
23     LLVMModuleRef mod = LLVMModuleCreateWithName("my_module");
24 
25     LLVMTypeRef param_types[] = { LLVMInt32Type(), LLVMInt32Type() };
26     LLVMTypeRef ret_type = LLVMFunctionType(LLVMInt32Type(), param_types, 2, 0);
27     LLVMValueRef sum = LLVMAddFunction(mod, "sum", ret_type);
28 
29     LLVMBasicBlockRef entry = LLVMAppendBasicBlock(sum, "entry");
30 
31     LLVMBuilderRef builder = LLVMCreateBuilder();
32     LLVMPositionBuilderAtEnd(builder, entry);
33     LLVMValueRef tmp = LLVMBuildAdd(builder, LLVMGetParam(sum, 0), LLVMGetParam(sum, 1), "tmp");
34     LLVMBuildRet(builder, tmp);
35 
36     char *error = NULL;
37     LLVMVerifyModule(mod, LLVMAbortProcessAction, &error);
38     LLVMDisposeMessage(error);
39 
40     LLVMExecutionEngineRef engine;
41     error = NULL;
42     LLVMLinkInMCJIT();
43     LLVMInitializeNativeAsmPrinter();
44     LLVMInitializeNativeTarget();
45     if (LLVMCreateExecutionEngineForModule(&engine, mod, &error) != 0) {
46         fprintf(stderr, "failed to create execution engine\n");
47         abort();
48     }
49     if (error) {
50         fprintf(stderr, "error: %s\n", error);
51         LLVMDisposeMessage(error);
52         exit(EXIT_FAILURE);
53     }
54 
55     if (argc < 3) {
56         fprintf(stderr, "usage: %s x y\n", argv[0]);
57         exit(EXIT_FAILURE);
58     }
59     long long x = strtoll(argv[1], NULL, 10);
60     long long y = strtoll(argv[2], NULL, 10);
61 
62     LLVMGenericValueRef args[] = {
63         LLVMCreateGenericValueOfInt(LLVMInt32Type(), x, 0),
64         LLVMCreateGenericValueOfInt(LLVMInt32Type(), y, 0)
65     };
66     LLVMGenericValueRef res = LLVMRunFunction(engine, sum, 2, args);
67     printf("%d\n", (int)LLVMGenericValueToInt(res, 0));
68 
69     // Write out bitcode to file
70     if (LLVMWriteBitcodeToFile(mod, "sum.bc") != 0) {
71         fprintf(stderr, "error writing bitcode to file, skipping\n");
72     }
73 
74     LLVMDisposeBuilder(builder);
75     LLVMDisposeExecutionEngine(engine);
76 }
77