diff --git a/DESCRIPTION b/DESCRIPTION index 835d95b0..23016f98 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -46,4 +46,5 @@ Collate: llvmVersion.R classDefs.R manual_generics.R BinaryOpEnums.R z_enumDefs_3.4.R z_enumDefs_3.5.R z_enumDefs_3.6.R - Function.R \ No newline at end of file + Function.R + DIBuilder.R \ No newline at end of file diff --git a/NAMESPACE b/NAMESPACE index c0244e82..fb6a7539 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -35,7 +35,6 @@ exportClasses( SExtInst, StoreInst, StructType, - functionType, TerminatorInst, Type, UnaryInstruction, @@ -114,6 +113,7 @@ FCMP_ULT, FCMP_UNE, FCMP_UNO, FDiv, +finalizeEngine, FIRST_FCMP_PREDICATE, FIRST_ICMP_PREDICATE, FloatPtrType, @@ -186,7 +186,8 @@ exportMethods(Optimize) export(setLinkage) -export(findFunction, getPointerToFunction) +export(findFunction, getPointerToFunction, + getNativePointerToFunction) export(createDoubleConstant) @@ -303,7 +304,7 @@ export(getIntegerType) export(setAlignment) exportMethods(setAlignment) -#export(getFunctionType) +export(functionType) export(addModule) @@ -470,3 +471,15 @@ export(insertAtEnd) export(isLandingPad, getLandingPadInst) export(createPHI,createPhi) + +export(PHIAddIncoming) + +export(DIBuilder, + finalizeDIBuilder, + newDebugCU, + newDebugFunction, + newDebugLocalVariable, + newDebugBasicType, + newDebugFunctionType, + newDebugPointerType, + debugSetLocation) diff --git a/R/DIBuilder.R b/R/DIBuilder.R new file mode 100644 index 00000000..c5d0ba2f --- /dev/null +++ b/R/DIBuilder.R @@ -0,0 +1,54 @@ +DIBuilder = +function(module) +{ + .Call("R_new_DIBuilder", module) +} + +finalizeDIBuilder = +function(builder) +{ + invisible(.Call("R_finalize_DIBuilder", builder)) +} + +newDebugCU = +function(builder, filename, path) +{ + .Call("R_new_DIBuilder_CU",builder, filename, path) +} + +newDebugFunction = +function(builder, cu, func, type, line) +{ + .Call("R_new_DIBuilder_Function",builder, cu, func, type, line) +} + +newDebugLocalVariable = +function(builder, ir_builder, sp, var, lineNo, cu, di_type, idx) +{ + .Call("R_DIBuilder_CreateLocalVariable",builder, ir_builder, sp, var, lineNo, cu, di_type, idx) +} + +newDebugBasicType = +function(builder, name, size, align, dwarf_type) { + .Call("R_IRBuilder_CreateBasicType", builder, name, as.integer(size), as.integer(align), as.integer(dwarf_type)) +} + +newDebugFunctionType = +function(builder, args, cu) +{ + .Call("R_IRBuilder_CreateFunctionType", builder, as.vector(args), cu) +} + +newDebugPointerType = +function(builder,baseType, name) { + .Call("R_IRBuilder_CreatePointerType", builder, baseType, name) +} + +debugSetLocation = +function(builder, func, lineNo, colNo) +{ + .Call("R_IRBuilder_SetLocation", builder, func, as.integer(lineNo), as.integer(colNo)) +} + + + diff --git a/R/ExecutionEngine.R b/R/ExecutionEngine.R index 6e2ae54c..de430d8e 100644 --- a/R/ExecutionEngine.R +++ b/R/ExecutionEngine.R @@ -27,13 +27,42 @@ function(val, values) } ExecutionEngine = -function(module, optimizationLevel = CodeGenOpt_Default) +function(module, optimizationLevel = CodeGenOpt_Default, useMCJIT) { optimizationLevel = matchEnum(optimizationLevel, CodeGenOptEnum) + + if (missing(useMCJIT)) { + if(all(llvmVersion() >= c(3, 6))) { + #defaulting to mc jit on llvm 3.6 + useMCJIT=TRUE + } else { + useMCJIT=FALSE + } + } - .Call("R_create_ExecutionEngine", as(module, "Module"), as.integer(optimizationLevel)) + res=.Call("R_create_ExecutionEngine", as(module, "Module"), as.integer(optimizationLevel),as.logical(useMCJIT)) + + res@useMCJIT=useMCJIT + res@finalized=FALSE + + res +} + +#finalize must be called before invoking code that has been +#compiled using MC Jit +finalizeEngine = +function(engine) +{ + if(!is(engine, "ExecutionEngine")) + stop("can only finalize an ExecutionEngine") + + if(engine@finalized) + stop("engine has already been finalized") + + invisible(.Call("R_ExecutionEngine_finalize", engine)) } + addModule = function(engine, ...) { @@ -71,15 +100,20 @@ function(.x, ..., .args = list(...), .ee = ExecutionEngine(as(.x, "Module")), .a if(!is(.x, "Function")) stop("argument to .llvm must be a Function") -# If an argument is a Function, we probably want to treat it as a function pointer and so want -# its address which can be obtained via getPointerToFunction() with the exec engine also. -# .args = lapply(.args, function(x) if(is(x, "Function")) getPointerToFunction(x, .ee)@ref else x) + if (.ee@useMCJIT) { + stop("calling .llvm/runFunction is not supported with MC-JIT") + } else { - if(length(.duplicate)) - .args[.duplicate] = lapply(.args[.duplicate], function(x) .Call('Rf_duplicate', x)) + # If an argument is a Function, we probably want to treat it as a function pointer and so want + # its address which can be obtained via getPointerToFunction() with the exec engine also. + # .args = lapply(.args, function(x) if(is(x, "Function")) getPointerToFunction(x, .ee)@ref else x) - - ans = .Call("R_callFunction", .x, .args, .ee) + if(length(.duplicate)) + .args[.duplicate] = lapply(.args[.duplicate], function(x) .Call('Rf_duplicate', x)) + + + ans = .Call("R_callFunction", .x, .args, .ee) + } if(.all) append(ans, structure(.args, names = names(.args))) @@ -123,6 +157,12 @@ function(fun, execEngine) .Call("R_ExecutionEngine_getPointerToFunction", execEngine, fun) } +getNativePointerToFunction = +function(fun, execEngine) +{ + .Call("R_ExecutionEngine_getNativePointerToFunction", execEngine, fun) +} + getPointerToGlobal = function(var, execEngine) { diff --git a/R/IRBuilder.R b/R/IRBuilder.R index f290b7f4..644b41c9 100644 --- a/R/IRBuilder.R +++ b/R/IRBuilder.R @@ -439,15 +439,13 @@ function(builder, vec, elt, idx) .Call("R_IRBuilder_CreateInsertElement", builder, vec, elt, idx) } - -createPHI = -function(builder, type, numReservedVals) +PHIAddIncoming = +function(phiNode, value, block) { - .Call("R_IRBuilder_CreatePHI", builder, type, as.integer(numReservedVals)) + .Call("R_PHINode_addIncoming", phiNode, value, block) } - if(FALSE) { # Old version < 3.4 CastOps = structure(33:44, .Names = c("Trunc", "ZExt", "SExt", "FPToUI", @@ -511,7 +509,7 @@ function(builder, value, type, id = "") createPhi = createPHI = -function(build, type, numReservedValues, id = character()) +function(builder, type, numReservedValues, id = character()) { .Call("R_IRBuilder_CreatePHI", as(builder, "IRBuilder"), as(type, "Type"), as.integer(numReservedValues), as.character(id)) } diff --git a/R/classDefs.R b/R/classDefs.R index 9ae5afb7..772a30a4 100644 --- a/R/classDefs.R +++ b/R/classDefs.R @@ -14,7 +14,7 @@ setClass("formatted_raw_ostream", contains = "raw_ostream") setClass("Module", contains = "RC++Reference") setClass("IRBuilder", contains = "RC++Reference") setClass("LLVMContext", contains = "RC++Reference") -setClass("ExecutionEngine", contains = "RC++Reference") +setClass("ExecutionEngine", representation(useMCJIT = "logical", finalized = "logical"), contains = "RC++Reference") setClass("Value", contains = "RC++Reference") setClass("BasicBlock", contains = "Value") @@ -92,6 +92,13 @@ setClass("NamedMDNode", contains = "RC++Reference") setClass("MDNode", contains = "Value") setClass("MDString", contains = "Value") +#Classes for DIBuilder +setClass("DIBuilder", contains = "RC++Reference") +setClass("DICompileUnit", contains = "RC++Reference") +setClass("DIDescriptor", contains = "RC++Reference") +setClass("DISubprogram", contains = "RC++Reference") +setClass("DIType", contains = "RC++Reference") +setClass("DICompositeType", contains = "DIType") setClass("Type", contains = "RC++Reference") diff --git a/R/onLoad.R b/R/onLoad.R index 494a204c..8ef534a6 100644 --- a/R/onLoad.R +++ b/R/onLoad.R @@ -1,7 +1,9 @@ getTypeDefs = -function() +function(namespace) { - types = .Call("R_getTypeDefinitions") + typeClass= getClass("Type", .Force=TRUE, where=namespace) + types = .Call("R_getTypeDefinitions", typeClass) + names(types) = c("Void", "Label", "Float", "Double", "Int1", "Int8", "Int16", "Int32", "Int64", "FloatPtr", "DoublePtr", "Int32Ptr", "String") types @@ -10,8 +12,11 @@ function() .onLoad = function(...) { - types = getTypeDefs() + e = getNamespace("Rllvm") + + types = getTypeDefs(e) + mapply(utils::assignInNamespace, paste(names(types), "Type", sep = ""), types, diff --git a/experiments/DIBuilder.R b/experiments/DIBuilder.R new file mode 100644 index 00000000..75f5b9b6 --- /dev/null +++ b/experiments/DIBuilder.R @@ -0,0 +1,102 @@ +# The following script illuminates how to add Debug Information to LLVM Code +# the following function is used to show linenumbers in gdb + +fun2 = function(x) { + res=x*2 + return(res) +} + +# dont move the uper function in the file, because the line numbers are encoded in the debug data!! +#set the path to the script here, otherwise gdb cant display source lines + +absPath="/home/chris/dev/llvm/Rllvm/experiments/DIBuilder.R" + +#if gdb doesnt stop in the function, check if you can set a breakpoint in __jit_debug_register_code +#see https://sourceware.org/gdb/onlinedocs/gdb/JIT-Interface.html and http://llvm.org/docs/DebuggingJITedCode.html + + +#end of preambel, start of code + +library(Rllvm) + +cat (paste("Is this script really saved in: ", absPath)) +cat (paste("attach gdb to process ", Sys.getpid(), " and set breakpoint on fun2")) +cat("then come back here, enter a character and press return!") +line <- scan("stdin", character(), n=1) + +m = Module() + +# Create a simple routines that takes a double value and returns that value multiplied by 2. + +f2 = Function("fun2", VoidType, list(x = pointerType(DoubleType)), module = m) +b = Block(f2) +ir = IRBuilder(b) +param_x = getParameters(f2)$x +var_res=createLocalVariable(ir,DoubleType, "res") + +#creating the Debug Builder and tools +debugBuilder = DIBuilder(m) + + + + +#generate CompilationUnit +debugCompUnit = newDebugCU(debugBuilder, basename(absPath), dirname(absPath)) + +#Type +debugDouble=newDebugBasicType(debugBuilder, "double", 64, 64, 4 ) #4 = dwarf::DW_ATE_float +debugVoid=newDebugBasicType(debugBuilder, "void", 64, 64, 5 ) #5 = dwarf::DW_ATE_signed +debugDoublePtr=newDebugPointerType(debugBuilder, debugDouble, "double*") + + +#Function for Debug +debugSignature=c(debugVoid,list(x=debugDoublePtr)) +debugFunSignature=newDebugFunctionType(debugBuilder, debugSignature, debugCompUnit) +debugFun=newDebugFunction(debugBuilder, debugCompUnit, f2, debugFunSignature, absPath) + +#adding function parameters +newDebugLocalVariable(debugBuilder, ir, debugFun, param_x, absPath, debugCompUnit, debugDoublePtr, 1) + +#adding local variable res +newDebugLocalVariable(debugBuilder, ir, debugFun, var_res, absPath, debugCompUnit, debugDouble, 0) + + + +# +# START emitting IR +# +#emit first source location +debugSetLocation(ir, debugFun, 5, 1) + +x2= ir$createLoad(param_x) +two = createConstant(, 2, context = getContext(m)) +res=ir$binOp(FMul, x2, two) +ir$createStore(res,var_res) + +#emit second source location +debugSetLocation(ir, debugFun, 6, 1) +ir$createStore(res,param_x) +ir$createReturn() + + + + +# +# FINISH Emitting IR +# now cleaning up and executing +# + +finalizeDIBuilder(debugBuilder) + + +# Now we create the EEs +eeNew = ExecutionEngine(m, useMCJIT=TRUE) + + +# getNativePointerToFunction returns a pointer that can be used by .C et al +fnPtr = getNativePointerToFunction(f2, eeNew) + +# the MC JIT must be finalized before callin into the code +finalizeEngine(eeNew) +print(.C(fnPtr,10.4)) + diff --git a/experiments/mcjit.R b/experiments/mcjit.R new file mode 100644 index 00000000..a27369fc --- /dev/null +++ b/experiments/mcjit.R @@ -0,0 +1,54 @@ +# The following script illuminates how to call function under the old JIT +# and using MC JIT + +library(Rllvm) + +m = Module() + +# Create two simple routines that do the same : +# taking a double value and returns that value multiplied by 2. + +# The first function will be run under the old JIT +f = Function("fun", DoubleType, list(x = DoubleType), module = m) +b = Block(f) +ir = IRBuilder(b) +x = getParameters(f)$x +two = createConstant(, 2, context = getContext(m)) +ir$createReturn(ir$binOp(FMul, x, two)) + +# the second function uses mc jit and will be called using .C +# Hence it takes a pointer to a double as argument +f2 = Function("fun2", VoidType, list(x = pointerType(DoubleType)), module = m) +b = Block(f2) +ir = IRBuilder(b) +x = getParameters(f2)$x +x2= ir$createLoad(x) +two = createConstant(, 2, context = getContext(m)) +res=ir$binOp(FMul, x2, two) +ir$createStore(res,x) +ir$createReturn() + +# Now we create two EEs +eeNew = ExecutionEngine(m, useMCJIT=TRUE) +eeOld = ExecutionEngine(m, useMCJIT=FALSE) + + +# getNativePointerToFunction returns a pointer that can be used by .C et al +fnPtr = getNativePointerToFunction(f2, eeNew) + +# the MC JIT must be finalized before callin into the code +finalizeEngine(eeNew) +print(.C(fnPtr,10.4)) + +# call using the old JIT +print(.llvm(f, 10.4,.ee = eeOld)) + +# using pointers works with the old JIT, too +fnPtr = getNativePointerToFunction(f2, eeOld) +print(.C(fnPtr,10.4)) + + + + + + diff --git a/src/DIBuilder.cpp b/src/DIBuilder.cpp new file mode 100644 index 00000000..bf2768ff --- /dev/null +++ b/src/DIBuilder.cpp @@ -0,0 +1,218 @@ +#include "Rllvm.h" +#if LLVM_VERSION <= 3 && LLVM_MINOR_VERSION < 2 +#include +#else +#if LLVM_VERSION >= 3 && LLVM_MINOR_VERSION >= 3 +#include +#include +#include +#include +#else +#include +#include +#endif +#endif + +#include "llvm/IR/DIBuilder.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/IR/Metadata.h" + +//FIXME: this code leaks memory. the interface changes with llvm 3.6. writing non leaking code should be easier with llvm 3.6 + +extern "C" +SEXP +R_new_DIBuilder(SEXP r_module) +{ + llvm::Module *module; + module = llvm::cast (GET_REF(r_module, Module)); + llvm::DIBuilder *ans; + ans = new llvm::DIBuilder(*module); + return(R_createRef(ans, "DIBuilder")); +} + +extern "C" +SEXP +R_new_DIBuilder_CU(SEXP r_dibuilder, SEXP filename, SEXP path) +{ + llvm::DIBuilder *builder; + builder = (GET_REF(r_dibuilder, DIBuilder)); + llvm::DICompileUnit ans; + ans = builder->createCompileUnit( + llvm::dwarf::DW_LANG_C, llvm::StringRef(CHAR(STRING_ELT(filename, 0))), + llvm::StringRef(CHAR(STRING_ELT(path, 0))), "Rllvm", 0, "", 0); + + llvm::DICompileUnit* ptr = new llvm::DICompileUnit(); + *ptr=ans; + + return(R_createRef(ptr, "DICompileUnit")); +} + +extern "C" +SEXP +R_finalize_DIBuilder(SEXP r_dibuilder) +{ + llvm::DIBuilder *builder; + builder = (GET_REF(r_dibuilder, DIBuilder)); + builder->finalize(); + + return(R_NilValue); +} + + +extern "C" +SEXP +R_new_DIBuilder_Function(SEXP r_dibuilder, SEXP r_cu, SEXP r_func, SEXP r_type, SEXP r_lineno) +{ + llvm::DIBuilder *builder; + builder = (GET_REF(r_dibuilder, DIBuilder)); + + llvm::Function *func; + func = (GET_REF(r_func, Function)); + + llvm::DICompileUnit *cu; + cu = (GET_REF(r_cu, DICompileUnit)); + llvm::DIFile Unit = builder->createFile(cu->getFilename(), cu->getDirectory()); + llvm::DIDescriptor FContext(Unit); + + llvm::DICompositeType *type; + type = (GET_REF(r_type, DICompositeType)); + + int lineNo=asInteger(r_lineno); + + llvm::DISubprogram SP = builder->createFunction( + FContext, func->getName(), llvm::StringRef(), Unit, lineNo, + *type, false /* internal linkage */, + true /* definition */, lineNo, llvm::DIDescriptor::FlagPrototyped, false, func); + + llvm::DISubprogram* ptr = new llvm::DISubprogram(); + *ptr=SP; + + return(R_createRef(ptr, "DISubprogram")); +} + + + +extern "C" +SEXP +R_DIBuilder_CreateLocalVariable(SEXP r_builder, SEXP r_ir_builder, SEXP r_sp, SEXP r_var, SEXP r_lineNo, + SEXP r_cu, SEXP r_di_type, SEXP r_idx) +{ + llvm::DIBuilder *builder; + builder = GET_REF(r_builder, DIBuilder); + + llvm::DISubprogram *SP; + SP = GET_REF(r_sp, DISubprogram); + + llvm::DICompileUnit *cu; + cu = (GET_REF(r_cu, DICompileUnit)); + llvm::DIFile Unit = builder->createFile(cu->getFilename(), cu->getDirectory()); + + llvm::DIType* di_type; + di_type = (GET_REF(r_di_type, DIType)); + + llvm::AllocaInst *var; + var = (GET_REF(r_var, AllocaInst)); + + llvm::StringRef varName=var->getName(); + + llvm::IRBuilder<> *ir_builder; + ir_builder = GET_REF(r_ir_builder, IRBuilder<>); + + int idx=asInteger(r_idx); + + llvm::DIVariable D = builder->createLocalVariable( + (idx == 0) ? llvm::dwarf::DW_TAG_auto_variable : llvm::dwarf::DW_TAG_arg_variable, + *SP, varName, Unit, asInteger(r_lineNo), + *di_type, false, 0, idx); + + llvm::Instruction *Call = builder->insertDeclare( + var, D, ir_builder->GetInsertBlock()); + + Call->setDebugLoc(llvm::DebugLoc::get(asInteger(r_lineNo), 0, *SP)); + + return(R_NilValue); +} + +extern "C" +SEXP +R_IRBuilder_CreateBasicType(SEXP r_builder,SEXP r_name, SEXP r_size, SEXP r_align, SEXP r_dwarf_type) { + + llvm::DIBuilder *builder; + builder = GET_REF(r_builder, DIBuilder); + + const char * name=CHAR(STRING_ELT(r_name, 0)); + int size=asInteger(r_size); + int align=asInteger(r_align); + int dwarf_type=asInteger(r_dwarf_type); + + llvm::DIType ans = builder->createBasicType(llvm::StringRef(name), size, align, dwarf_type); + llvm::DIType* ptr = new llvm::DIType(); + *ptr=ans; + return(R_createRef(ptr,"DIType")); +} + +extern "C" +SEXP +R_IRBuilder_CreatePointerType(SEXP r_builder, SEXP r_type, SEXP r_name) { + + llvm::DIBuilder *builder; + builder = GET_REF(r_builder, DIBuilder); + + llvm::DIType *baseType=GET_REF(r_type, DIType); + + const char * name=CHAR(STRING_ELT(r_name, 0)); + + llvm::DIType ans = builder->createPointerType(*baseType,sizeof(void*),0,llvm::StringRef(name)); + llvm::DIType* ptr = new llvm::DIType(); + *ptr=ans; + return(R_createRef(ptr,"DIType")); +} + + + +extern "C" +SEXP +R_IRBuilder_CreateFunctionType(SEXP r_builder, SEXP args, SEXP r_cu) { + llvm::SmallVector EltTys; + + llvm::DIBuilder *builder; + builder = GET_REF(r_builder, DIBuilder); + + llvm::DICompileUnit* cu; + cu = (GET_REF(r_cu, DICompileUnit)); + + llvm::DIFile file = builder->createFile(cu->getFilename(), cu->getDirectory()); + + for (unsigned i = 0; i < Rf_length(args); ++i) { + llvm::DIType *element=GET_REF(VECTOR_ELT(args,i), DIType); + EltTys.push_back(*element); + } + + llvm::DIArray EltTypeArray = builder->getOrCreateArray(EltTys); + + llvm::DICompositeType ans=builder->createSubroutineType(file, EltTypeArray); + + llvm::DICompositeType* ptr = new llvm::DICompositeType(); + *ptr=ans; + return R_createRef(ptr,"DICompositeType"); +} + + +extern "C" +SEXP +R_IRBuilder_SetLocation(SEXP r_builder, SEXP r_func, SEXP r_lineNo, SEXP r_colNo) +{ + llvm::IRBuilder<> *builder; + builder = GET_REF(r_builder, IRBuilder<>); + + llvm::DISubprogram *SP; + SP = GET_REF(r_func, DISubprogram); + + int lineNo=asInteger(r_lineNo); + int colNo=asInteger(r_colNo); + + builder->SetCurrentDebugLocation( + llvm::DebugLoc::get(lineNo, colNo, *SP)); + + return(R_NilValue); +} diff --git a/src/ExecEngine.cpp b/src/ExecEngine.cpp index 8fbe23a9..18bf9822 100644 --- a/src/ExecEngine.cpp +++ b/src/ExecEngine.cpp @@ -83,20 +83,34 @@ R_InitializeCppBackendTarget() extern "C" SEXP -R_create_ExecutionEngine(SEXP r_module, SEXP r_optLevel) +R_create_ExecutionEngine(SEXP r_module, SEXP r_optLevel, + SEXP r_usemcjit) { /* Do we want to use some of the create() methods in the ExecutionEngine class. */ std::string errStr; llvm::Module *module = GET_REF(r_module, Module); - llvm::ExecutionEngine *EE = llvm::EngineBuilder( + llvm::EngineBuilder builder( #if LLVM_VERSION == 3 && LLVM_MINOR_VERSION > 5 std::unique_ptr(module) #else module #endif - ).setErrorStr(&errStr).setEngineKind(llvm::EngineKind::JIT).setOptLevel((enum llvm::CodeGenOpt::Level) INTEGER(r_optLevel)[0]).create(); + ); + + builder.setErrorStr(&errStr); + builder.setEngineKind(llvm::EngineKind::JIT); + builder.setUseMCJIT(*LOGICAL(r_usemcjit)); + builder.setOptLevel((enum llvm::CodeGenOpt::Level) INTEGER(r_optLevel)[0]); + + llvm::TargetOptions Options; + Options.JITEmitDebugInfo = *LOGICAL(r_usemcjit); + + builder.setTargetOptions(Options); + + + llvm::ExecutionEngine *EE = builder.create(); if(!EE) { PROBLEM "failed to create execution engine: %s", errStr.c_str() ERROR; @@ -105,6 +119,20 @@ R_create_ExecutionEngine(SEXP r_module, SEXP r_optLevel) return(R_createRef(EE, "ExecutionEngine")); } +/* finalize engine must be called before invoking code +compiled with MC Jit */ +extern "C" +SEXP +R_ExecutionEngine_finalize(SEXP r_ee) +{ + + /* Do we want to use some of the create() methods in the ExecutionEngine class. */ + + llvm::ExecutionEngine *EE = GET_REF(r_ee, ExecutionEngine); + EE->finalizeObject(); + return(R_NilValue); +} + extern "C" SEXP R_callFunction(SEXP r_fun, SEXP r_args, SEXP r_execEngine) @@ -165,6 +193,21 @@ R_ExecutionEngine_getPointerToFunction(SEXP r_execEngine, SEXP r_func) return(R_createRef(ans, "NativeFunctionPointer", "native symbol")); } +extern "C" +SEXP +R_ExecutionEngine_getNativePointerToFunction(SEXP r_execEngine, SEXP r_func) +{ + llvm::ExecutionEngine *ee = GET_REF(r_execEngine, ExecutionEngine); + llvm::Function *fun = GET_REF(r_func, Function); + void *ans = ee->getPointerToFunction(fun); + + SEXP ans2; + PROTECT(ans2=R_MakeExternalPtr(ans, install("native symbol"), + R_NilValue)); + UNPROTECT(1); + return(ans2); +} + extern "C" SEXP R_ExecutionEngine_getPointerToGlobal(SEXP r_execEngine, SEXP r_var) diff --git a/src/IRBuilder.cpp b/src/IRBuilder.cpp index 526a8c46..d063bb17 100644 --- a/src/IRBuilder.cpp +++ b/src/IRBuilder.cpp @@ -1003,3 +1003,24 @@ R_IRBuilder_CreatePHI(SEXP r_builder, SEXP r_type, SEXP r_numReservedValues, SEX return(R_createRef(ret, "PHINode")); } + +extern "C" +SEXP +R_PHINode_addIncoming(SEXP r_phiNode, SEXP r_value, SEXP r_block) +{ + llvm::PHINode* phiNode; + phiNode = GET_REF(r_phiNode, PHINode); + + + llvm::Value *value; + value = GET_REF(r_value, Value); + + llvm::BasicBlock *block; + block = GET_REF(r_block, BasicBlock); + + + phiNode->addIncoming(value, block); + + return(R_NilValue); + +} \ No newline at end of file diff --git a/src/types.cpp b/src/types.cpp index 5e446b94..7bc9af35 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -10,9 +10,20 @@ struct TypeName { const char * const name; } ; + +SEXP +R_createRefTypes(const void *ptr, SEXP klass, const char * tag) +{ + SEXP ans; + PROTECT(ans = NEW_OBJECT(klass)); + SET_SLOT(ans, Rf_install("ref"), R_MakeExternalPtr((void*)ptr, Rf_install(tag), R_NilValue)); + UNPROTECT(1); + return(ans); +} + extern "C" SEXP -R_getTypeDefinitions() +R_getTypeDefinitions(SEXP r_TypeClass) { llvm::LLVMContext &ctxt = llvm::getGlobalContext(); @@ -37,10 +48,15 @@ R_getTypeDefinitions() SEXP ans; PROTECT(ans = NEW_LIST(n)); + + Rf_install("Type"); + for(int i = 0; i < n; i++) { SEXP tmp; - SET_VECTOR_ELT(ans, i, tmp = R_MakeExternalPtr((void *) types[i].type, Rf_install("Type"), R_NilValue)); // R_createRef((void *) types[i], "Type") + //SET_VECTOR_ELT(ans, i, tmp = R_MakeExternalPtr((void *) types[i].type, Rf_install("Type"), R_NilValue)); // R_createRef((void *) types[i], "Type") // Rf_setAttrib(tmp, Rf_install("typeName"), mkString(types[i].name)); + + SET_VECTOR_ELT(ans, i, R_createRefTypes(types[i].type, r_TypeClass, "Type")); } UNPROTECT(1);