R/ExecutionEngine.R

CodeGenOpt_None = 0L
CodeGenOpt_Less = 1L
CodeGenOpt_Default = 2L
CodeGenOpt_Aggressive = 3L

CodeGenOptEnum = c(None = CodeGenOpt_None, Less = CodeGenOpt_Less,
               Default = CodeGenOpt_Default,
               Aggressive = CodeGenOpt_Aggressive)

matchEnum =
function(val, values)
{
  orig = val
  
  if(is.character(val)) {
    val = pmatch(tolower(val), tolower(names(values)))
    val = values[val]
  }

  if(is.na(val))
    stop("no matching value")

  if(!(val %in% values))
    stop("value is not one of the acceptable values")

  val
}

ExecutionEngine =
function(module, optimizationLevel = CodeGenOpt_Default)
{
  optimizationLevel = matchEnum(optimizationLevel, CodeGenOptEnum)
  
  res=.Call("R_create_ExecutionEngine", as(module, "Module"), as.integer(optimizationLevel))

  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")

   
   invisible(.Call("R_ExecutionEngine_finalize", engine))
}


addModule =
function(engine, ...)
{
   if(!is(engine, "ExecutionEngine"))
     stop("can only add modules to an ExecutionEngine, currently")
   
   mods = lapply(list(...), as, "Module")
   .Call("R_ExecutionEngine_addModule", engine, mods)
}


needsDuplicate =
function(arg)
  !onlyReadsMemory(arg) && isPointerType(getType(arg)) 

.duplicateArgs =
function(fun)
{
  args = getFunctionArgs(fun)
  if(length(args) == 0)
      return(integer())
  which(sapply(args, needsDuplicate))
}

# Use the name .x so that we don't conflict with routines with parameters named x
# which  we want to name in our call, e.g for mutable parameters we want back.
setGeneric("run",
            function(.x, ...)
	       standardGeneric("run"))

.llvmCallFunction =
function(.x, ..., .args = list(...), .ee = ExecutionEngine(as(.x, "Module")), .all = FALSE,
          .duplicate = .duplicateArgs(.x)) 
{
  if(!is(.x, "Function"))
    stop("argument to .llvm must be a Function")

  if (.ee@useMCJIT) {
    stop("calling .llvm/runFunction is not supported with MC-JIT")
  } else {

  # 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(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)))
  else
     ans
}

setMethod("run", "Function", .llvmCallFunction)


.llvm = .llvmCallFunction

llvmShutdow = shutdown =
function()
{
    .C("R_LLVMShutdown")
}    

InitializeNativeTarget =
function()
{
  .C("R_InitializeNativeTarget")
  # Need this in 3.6. For now, do it always.
  .C("R_InitializeNativeTargetAsmPrinter")
  .C("R_InitializeNativeTargetAsmParser")
}

InitializeCppBackendTarget =
function()
  .C("R_InitializeCppBackendTarget")

InitializeNVPTXTarget =
function()
  .C("R_InitializeNVPTXTarget")



getPointerToFunction =
function(fun, execEngine)
{
   .Call("R_ExecutionEngine_getPointerToFunction", execEngine, fun)
}

getNativePointerToFunction =
function(fun, execEngine)
{
   .Call("R_ExecutionEngine_getNativePointerToFunction", execEngine, fun)
}

getPointerToGlobal =
function(var, execEngine)
{
   .Call("R_ExecutionEngine_getPointerToGlobal", execEngine, var)
}

findFunction =
function(funcName, execEngine)
{
   .Call("R_ExecutionEngine_FindFunctionNamed", execEngine, as.character(funcName))
}


getGlobalValue = 
function(var, exec, type = getType(var))
{
   ptr = getPointerToGlobal(var, exec)

   ty = getElementType(type)
   .Call("R_convertNativeValuePtrToR", ptr@ref, ty)
}

addGlobalMapping =
function(execEngine, var, addr)
{
   .Call("R_ExecutionEngine_addGlobalMapping", execEngine, var, addr)
}



getVerifyModules =
function(exeEng)
{
  .Call("R_ExecutionEngine_getVerifyModules", exeEng)
}

setVerifyModules =
function(exeEng, val)
{
  .Call("R_ExecutionEngine_setVerifyModules", exeEng, as.logical(val))
}
doktorschiwago/Rllvm2 documentation built on May 15, 2019, 9:42 a.m.