Ever wanted to use LLVM from C? Can't find any documentation? Welcome.
Since I'm considering retargeting CLISP'S JIT Compiler I've been experimenting with LLVM. LLVM is an optimizing compiler for a virtual instruction set. Technically, it is very interesting. And this year, with Apple and CLANG in the game, it seems to be here to stay.
A Factorial in C with LLVM
Let's make a factorial function using the C bindings of LLVM 2.3+.
The function we will describe in LLVM instructions is illustrated below.
I inserted the phi instruction manually to make things more interesting.
Paste this in your favorite editor and save it as "fac.c":
// Headers required by LLVM
#include <llvm-c/Core.h>
#include <llvm-c/Analysis.h>
#include <llvm-c/ExecutionEngine.h>
#include <llvm-c/Target.h>
#include <llvm-c/Transforms/Scalar.h>
// General stuff
#include <stdlib.h>
#include <stdio.h>
int main (int argc, char const *argv[])
{
char *error = NULL; // Used to retrieve messages from functions
LLVMModuleRef mod = LLVMModuleCreateWithName("fac_module");
LLVMTypeRef fac_args[] = { LLVMInt32Type() };
LLVMValueRef fac = LLVMAddFunction(mod, "fac", LLVMFunctionType(LLVMInt32Type(), fac_args, 1, 0));
LLVMSetFunctionCallConv(fac, LLVMCCallConv);
LLVMValueRef n = LLVMGetParam(fac, 0);
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(fac, "entry");
LLVMBasicBlockRef iftrue = LLVMAppendBasicBlock(fac, "iftrue");
LLVMBasicBlockRef iffalse = LLVMAppendBasicBlock(fac, "iffalse");
LLVMBasicBlockRef end = LLVMAppendBasicBlock(fac, "end");
LLVMBuilderRef builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, entry);
LLVMValueRef If = LLVMBuildICmp(builder, LLVMIntEQ, n, LLVMConstInt(LLVMInt32Type(), 0, 0), "n == 0");
LLVMBuildCondBr(builder, If, iftrue, iffalse);
LLVMPositionBuilderAtEnd(builder, iftrue);
LLVMValueRef res_iftrue = LLVMConstInt(LLVMInt32Type(), 1, 0);
LLVMBuildBr(builder, end);
LLVMPositionBuilderAtEnd(builder, iffalse);
LLVMValueRef n_minus = LLVMBuildSub(builder, n, LLVMConstInt(LLVMInt32Type(), 1, 0), "n - 1");
LLVMValueRef call_fac_args[] = {n_minus};
LLVMValueRef call_fac = LLVMBuildCall(builder, fac, call_fac_args, 1, "fac(n - 1)");
LLVMValueRef res_iffalse = LLVMBuildMul(builder, n, call_fac, "n * fac(n - 1)");
LLVMBuildBr(builder, end);
LLVMPositionBuilderAtEnd(builder, end);
LLVMValueRef res = LLVMBuildPhi(builder, LLVMInt32Type(), "result");
LLVMValueRef phi_vals[] = {res_iftrue, res_iffalse};
LLVMBasicBlockRef phi_blocks[] = {iftrue, iffalse};
LLVMAddIncoming(res, phi_vals, phi_blocks, 2);
LLVMBuildRet(builder, res);
LLVMVerifyModule(mod, LLVMAbortProcessAction, &error);
LLVMDisposeMessage(error); // Handler == LLVMAbortProcessAction -> No need to check errors
LLVMExecutionEngineRef engine;
LLVMModuleProviderRef provider = LLVMCreateModuleProviderForExistingModule(mod);
error = NULL;
LLVMCreateJITCompiler(&engine, provider, &error);
if(error) {
fprintf(stderr, "%s\n", error);
LLVMDisposeMessage(error);
abort();
}
LLVMPassManagerRef pass = LLVMCreatePassManager();
LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
LLVMAddConstantPropagationPass(pass);
LLVMAddInstructionCombiningPass(pass);
LLVMAddPromoteMemoryToRegisterPass(pass);
// LLVMAddDemoteMemoryToRegisterPass(pass); // Demotes every possible value to memory
LLVMAddGVNPass(pass);
LLVMAddCFGSimplificationPass(pass);
LLVMRunPassManager(pass, mod);
LLVMDumpModule(mod);
LLVMGenericValueRef exec_args[] = {LLVMCreateGenericValueOfInt(LLVMInt32Type(), 10, 0)};
LLVMGenericValueRef exec_res = LLVMRunFunction(engine, fac, 1, exec_args);
fprintf(stderr, "\n");
fprintf(stderr, "; Running fac(10) with JIT...\n");
fprintf(stderr, "; Result: %d\n", LLVMGenericValueToInt(exec_res, 0));
LLVMDisposePassManager(pass);
LLVMDisposeBuilder(builder);
LLVMDisposeExecutionEngine(engine);
return 0;
}
Compiling the code
Generating the object file is a no-brainer:
Linking is a little trickier. Even though you are writing C code, you have to use a C++ linker.
gcc `llvm-config --cflags` -c fac.c
All set!
g++ `llvm-config --libs --cflags --ldflags core analysis executionengine jit interpreter native` fac.o -o fac
20 comments:
You might need to call "LLVMLinkInJIT" nowadays.
thanks for this introduction to LLVM
For LLVM 2.6, I needed to make a couple changes:
1)
At the start of main, add:
LLVMLinkInJIT();
LLVMInitializeNativeTarget();
2) LLVMCreateJITCompiler has an extra argument (Optimization level), and has a return value of whether an error occurred. So replace lines 58-59 with:
if(LLVMCreateJITCompiler(&engine, provider, 2, &error) != 0) {
Not sure why, but on Ubuntu 10.04, this only compiles for me if I put fac.o *before* the `llvm-config`. It's weird; this is the only time I can think of that the linker's behaviour has been influenced by the order of the object/library files.
g++ fac.o `llvm-config --libs --cflags --ldflags core analysis executionengine jit interpreter native` -o fac
Misbah Digital Marketing is an excellent online marketing agency in Bangalore.Misbah Digital Marketing!
Misbah Digital Marketing! having certified professionals in Google Ads, Google Analytics and Bing Ads.
Misbah Digital Marketing!
Teacher Vacancy 2020: Check out latest vacancy for teachers online. Find latest teaching vacancies 2020 jobs and apply online. Exclusive job portal
Teacher Job Sites
Join our online group classes live from the Academic Delivery Center. Entire schedule is published before hand with clear guidelines
Online Tuition Classes
best site to visit
Click Hare
click hare
click hare
Click hare
Click hare
Click hare
Click hare
Click hare
Thank you for sharing this extremely useful information. You made some well-considered points.
This essay has a lot of information that I would never have considered on my own.
digital marketing training in hyderabad
digital marketing course in ameerpet
digital marketing course training in hyderabad ameerpet
digital marketing online training in hyderabad
informative blog post. Thanks for sharing
Best Web development company in Hyderabad
Quality Content. Thanks for Sharing
Best Interior Designers
I read your post. It is very informative and helpful to me. I admire the message valuable information you provided in your article.
online bus ticket booking
I really liked the content which is very helpful for me. Thanks for sharing.
tourist places in hyderabad
Hope it will certainly be valuable for all. All the facts are given out in a quite easy and also reasonable form.
december umrah packages 2022
The server-side code of the framework depends on C#. The front end side is written in DHTML with JavaScript and HTML. It likewise can be founded on ASP.NET. The substances and data sets are put away in Microsoft SQL Administration. MS SQL Server Perspectives are utilized widely for areas of strength for giving to Job Based survey of the undertaking information in MS CRM 4.0 and later variants. The association administration is worked with the utilization of the WCF, and the synchronization with disconnected information in Standpoint is based on the Sync Structure. In Microsoft Elements cost of execution relies upon the range of abilities of the developers and size of work. Adding one basic element is less expensive than the formation of the framework without any preparation>> Microsoft Dynamics CRM development company
Even if you have years of experience writing in English, you are bound to make mistakes. Errors in your paper can be as subtle as creating confusion and mistrust. Be sure to get professional proofreading help to make sure your writing is impeccable sentence breakdown tool Our Correct My Sentences Online allows you to write like a native English speaker
Nice Blog, Thanks for providing this wonderful information. If you are looking for a reliable and affordable way to help your child pass the CBSE exams, then CBSE home tutoring is the perfect solution for you.
For more info contact +91-9654271931 | UAE +971- 505593798 or visit Best CBSE Online Tuition Classes
Excellent information on your blog, thank you for taking the time to share with us. Looking for top-notch CBSE tuition classes? Ziyyara’s online tuition classes are designed to help students excel in their CBSE board exams.
For more info contact +91-9654271931 or visit CBSE Online Tuition Classes
This is good information and really helpful for the people who need information about this. Join Ziyyara Edutech’s online private tuition classes designed exclusively for 7th standard students, right in the comfort of your own home.
Book A Free Demo Today visit Private tuition classes for class 7 student
This blog https://attractgroup.com/blog/how-to-create-custom-delivery-software-solutions-for-small-business/ provides valuable insights into creating custom delivery software solutions for small businesses. The detailed step-by-step guide showcases the importance of tailoring software to meet specific business needs, highlighting the benefits of increased efficiency and customer satisfaction. The clear and concise explanations make it a great resource for small business owners looking to streamline their delivery processes. Overall, a must-read for those seeking to enhance their operations through customized software solutions.
Before a workout, fuelling up with the right foods is essential to optimize energy, focus, and endurance. The best pre-workout food often includes complex carbs and moderate protein for sustained energy. Options like oatmeal with a few slices of banana, whole-grain toast with peanut butter, or a small smoothie with fruits and a scoop of protein powder can keep you going strong. These foods digest easily, helping to avoid sluggishness during exercise. For those with limited time, a handful of nuts or a banana alone can still provide a good energy boost without being too heavy.
Post a Comment