Skip to content

Instantly share code, notes, and snippets.

@astarasikov
Created May 2, 2014 23:09
Show Gist options
  • Save astarasikov/9086c8fdd1ad1c0c45b0 to your computer and use it in GitHub Desktop.
Save astarasikov/9086c8fdd1ad1c0c45b0 to your computer and use it in GitHub Desktop.
/*
Use the Makefile listed below and build with the PATH to your LLVM binaries
PATH=~/Documents/workspace/builds/llvm/build/bin/:$PATH make
#####
APPNAME=jit_tut1
LLFLAGS=$(shell llvm-config --cxxflags --ldflags --libs core jit interpreter x86) -lcurses
all:
c++ -g ./$(APPNAME).cpp $(LLFLAGS) -o ./$(APPNAME)
clean:
rm *.o
rm ./$(APPNAME)
#####
*/
#include <llvm/PassManager.h>
#include <llvm/IR/CallingConv.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/IRPrintingPasses.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/PassManager.h>
#include <llvm/IR/Verifier.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/ExecutionEngine/Interpreter.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <vector>
#define FUNC_NAME "mul_add_pair"
#define INT_WIDTH 32
using namespace llvm;
Module *makeLLVMModule() {
Module *mod = new Module("test", getGlobalContext());
Constant *c = mod->getOrInsertFunction(FUNC_NAME,
IntegerType::get(getGlobalContext(), INT_WIDTH),
IntegerType::get(getGlobalContext(), INT_WIDTH),
IntegerType::get(getGlobalContext(), INT_WIDTH),
IntegerType::get(getGlobalContext(), INT_WIDTH),
IntegerType::get(getGlobalContext(), INT_WIDTH),
NULL);
Function *mul_add = cast<Function>(c);
mul_add->setCallingConv(CallingConv::C);
Function::arg_iterator args = mul_add->arg_begin();
Value* x = args++;
x->setName("x");
Value* y = args++;
y->setName("y");
Value* z = args++;
z->setName("z");
Value* w = args++;
w->setName("w");
BasicBlock *block = BasicBlock::Create(getGlobalContext(), "entry", mul_add);
IRBuilder<> builder(block);
Value *tmp = builder.CreateBinOp(Instruction::Mul, x, y, "tmp");
Value *tmp2 = builder.CreateBinOp(Instruction::Mul, z, w, "tmp2");
Value *ret = builder.CreateBinOp(Instruction::Add, tmp, tmp2, "ret");
builder.CreateRet(ret);
return mod;
}
int main(int argc, char **argv) {
Module *mod = makeLLVMModule();
verifyModule(*mod);
PassManager PM;
PM.add(createPrintModulePass(outs()));
PM.run(*mod);
/* Now, create JIT and run */
InitializeNativeTarget();
std::string errStr;
ExecutionEngine *EE =
EngineBuilder(mod)
.setErrorStr(&errStr)
.setEngineKind(EngineKind::JIT)
.create();
if (!EE) {
errs() << argv[0] << " Failed to create ExecutionEngine: " << errStr << "\n";
return -1;
}
Function *func = mod->getFunction(FUNC_NAME);
std::vector<GenericValue> Args(4);
Args[0].IntVal = APInt(INT_WIDTH, 66);
Args[1].IntVal = APInt(INT_WIDTH, 11);
Args[2].IntVal = APInt(INT_WIDTH, 200);
Args[3].IntVal = APInt(INT_WIDTH, 300);
GenericValue GV = EE->runFunction(func, Args);
outs() << "Result: " << GV.IntVal << "\n";
delete mod;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment