Skip to content

Instantly share code, notes, and snippets.

@HurricanKai
Created February 2, 2019 19:27
Show Gist options
  • Save HurricanKai/438f4c630471744168504b18f62e9b2e to your computer and use it in GitHub Desktop.
Save HurricanKai/438f4c630471744168504b18f62e9b2e to your computer and use it in GitHub Desktop.
// define Targets
LLVM.InitializeX86TargetMC();
LLVM.InitializeX86Target();
LLVM.InitializeX86TargetInfo();
LLVM.InitializeX86AsmParser();
LLVM.InitializeX86AsmPrinter();
// create a module
var module = LLVM.ModuleCreateWithName("Example");
// signature
var funcType = LLVM.FunctionType(LLVM.PointerType(LLVM.VectorType(LLVM.Int64Type(), length), 0),
new[] { LLVM.PointerType(LLVM.VectorType(LLVM.Int32Type(), length), 0), 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.BuildMalloc(builder, LLVM.VectorType(LLVM.Int64Type(), length), "arrayPtr");
LLVM.BuildRet(builder, arptr);
/*// 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, LLVM.BuildLoad(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);
var random = new Random();
fixed (int* data = new int[length])
{
for (int j = 0; j < length; j++)
{
data[j] = random.Next();
}
var addVal = random.Next();
var resDataPtr = add(data, addVal);
for (int j = 0; j < length; j++)
{
Console.WriteLine($"{resDataPtr[j]} + {addVal} = {resDataPtr[j]}");
}
}
Console.ReadLine();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment