Skip to content

Instantly share code, notes, and snippets.

@HurricanKai
Created February 2, 2019 17:36
Show Gist options
  • Save HurricanKai/bcf74045775414f68beff841c73915fe to your computer and use it in GitHub Desktop.
Save HurricanKai/bcf74045775414f68beff841c73915fe to your computer and use it in GitHub Desktop.
// define Targets
LLVM.InitializeX86TargetMC();
LLVM.InitializeX86Target();
LLVM.InitializeX86TargetInfo();
LLVM.InitializeX86AsmParser();
LLVM.InitializeX86AsmPrinter();
const int length = 1000;
// create a module
var module = LLVM.ModuleCreateWithName("Example");
// signature
var funcType = LLVM.FunctionType(LLVM.PointerType(LLVM.Int64Type(), 0), new LLVMTypeRef[] { LLVM.ArrayType(LLVM.Int32Type(), length), LLVM.Int32Type() }, false);
// actual definition
var funcDef = LLVM.AddFunction(module, "Add", funcType);
// builder
var builder = LLVM.CreateBuilder();
var basicBlock = LLVM.AppendBasicBlock(funcDef, "init");
var cond = LLVM.AppendBasicBlock(funcDef, "for.cond");
var body = LLVM.AppendBasicBlock(funcDef, "for.body");
var inc = LLVM.AppendBasicBlock(funcDef, "for.inc");
var end = LLVM.AppendBasicBlock(funcDef, "for.end");
// at end of init
LLVM.PositionBuilderAtEnd(builder, basicBlock);
// get result array
var arptr = LLVM.BuildAlloca(builder, LLVM.VectorType(LLVM.Int64Type(), length), "arrayPtr");
// left arg
var lval = LLVM.GetParam(funcDef, 0);
// right arg
var rval = LLVM.BuildZExt(builder, LLVM.GetParam(funcDef, 1), LLVM.Int64Type(), "b");
// i
var i = LLVM.BuildAlloca(builder, LLVM.Int32Type(), "i");
LLVM.BuildStore(builder, LLVM.ConstInt(LLVM.Int32Type(), 0, new LLVMBool()), i);
LLVM.BuildBr(builder, cond);
// loop.cond
LLVM.PositionBuilderAtEnd(builder, cond);
var v = LLVM.BuildLoad(builder, i, "");
var cmp = LLVM.BuildICmp(builder, LLVMIntPredicate.LLVMIntSLT, v, LLVM.ConstInt(LLVM.Int32Type(), length, new LLVMBool(0)), "");
LLVM.BuildCondBr(builder, cmp, body, end);
// loop.body
LLVM.PositionBuilderAtEnd(builder, body);
var index = LLVM.BuildLoad(builder, i, "");
var element = LLVM.BuildExtractElement(builder, lval, index, "");
element = LLVM.BuildZExt(builder, element, LLVM.Int64Type(), "");
var addRes = LLVM.BuildAdd(builder, element, rval, "");
LLVM.BuildInsertElement(builder, LLVM.BuildLoad(builder, arptr, ""), addRes, index, "");
LLVM.BuildBr(builder, inc);
// loop.inc
LLVM.PositionBuilderAtEnd(builder, inc);
var l = LLVM.BuildLoad(builder, i, "");
var r = LLVM.BuildAdd(builder, l, LLVM.ConstInt(LLVM.Int32Type(), 1, new LLVMBool(0)), "");
LLVM.BuildStore(builder, r, i);
LLVM.BuildBr(builder, cond);
// loop.end
LLVM.PositionBuilderAtEnd(builder, end);
LLVM.BuildRet(builder, arptr);
// get bytecode
var bitcode = Marshal.PtrToStringAnsi(LLVM.PrintModuleToString(module));
Console.WriteLine(bitcode);
LLVM.VerifyModule(module, LLVMVerifierFailureAction.LLVMPrintMessageAction, out var error);
Console.WriteLine(error);
Console.ReadLine();
LLVM.LinkInMCJIT();
// make compiler & compile
var options = new LLVMMCJITCompilerOptions { NoFramePointerElim = 1 };
LLVM.InitializeMCJITCompilerOptions(options);
LLVM.CreateMCJITCompilerForModule(out var engine, module, options, out var error1);
var ptr = LLVM.GetPointerToGlobal(engine, funcDef);
var add = Marshal.GetDelegateForFunctionPointer<Add_dt>(ptr);
// output
Console.WriteLine(ptr);
// Console.WriteLine("{0} + {1} = {2}", int.MaxValue, int.MaxValue, add(int.MaxValue, int.MaxValue));
Console.ReadLine();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment