├── .Rbuildignore ├── .gitignore ├── AnalyzeCCode ├── AST.xml ├── ExplorIR.Rmd ├── FindingArrayExtent.xml ├── GNUmakefile ├── Loops.xml ├── Makevars ├── Notes.xml ├── README.md ├── TODO.md ├── arima.ir ├── asortCFG.tex ├── ast.R ├── callGraph.R ├── check.R ├── class.R ├── coerceVector_have_config.ir ├── colSums.xml ├── eg.R ├── eg.c ├── eg2.R ├── eg3.R ├── error.c ├── error.xml ├── findGlobalUse.R ├── findLength.R ├── findRpVcostUse.R ├── foo.c ├── foo.xml ├── getInputTypes.R ├── getType.R ├── greplFig.tex ├── greplTypes.md ├── greplTypes.xml ├── icmp.tex ├── icmp2.tex ├── icmp2CFG.tex ├── influence.ir ├── influence.xml ├── inputs.xml ├── lengths.R ├── lengths.c ├── lengths.xml ├── loop02BlockGraph.png ├── matrixLoop.c ├── mod.c ├── multiRet.c ├── rcpp.cc ├── recursive.c ├── recursive.xml ├── rnormTypes.xml ├── round.xml ├── rpart.ir ├── rpart_inputs.xml ├── simple.c ├── simpleLen.c ├── sortCFG.tex ├── sortTypes.xml ├── tmp.c ├── tmp.ir └── try.cc ├── BuildingLLVM.md ├── Changelog ├── CompilerNotes ├── DESCRIPTION ├── DebugInfo ├── GNUmakefile ├── TODO.md ├── URLs ├── enums.c ├── fnptr.R ├── fnptr.c ├── genCode.R ├── paramNames.R ├── simple.R ├── simple.c ├── simple2.R ├── simple2.c ├── simpleEx.R ├── simplest.c ├── sql.R └── sqle.c ├── FAQ.xml ├── FAQ └── CodeGenFAQ.xml ├── INSTALL.md ├── Misc ├── DebuggingRuntimeProblems.Rdb ├── FIX_dylib ├── IRNotes ├── Notes ├── R │ ├── callGraph.R │ ├── checkSEXP.R │ ├── funcGroups.R │ ├── mkBlockDiag.R │ ├── runEgs.R │ ├── test.R │ └── testPTX.R ├── ThingsToRemember.md └── VinceQues ├── NAMESPACE ├── Paper ├── GNUmakefile ├── OtherFuncs ├── Outline ├── Rllvm.tex ├── content.tex ├── jssMacros.tex ├── rllvm.bib └── types.tex ├── R ├── Argument.R ├── CallInst.R ├── CallingConvEnum.R ├── DIBuilder.R ├── ExecutionEngine.R ├── Function.R ├── ICmpEnums.R ├── IRBuilder.R ├── IntrinsicEnums.R ├── InvokeInst.R ├── LoadStore.R ├── LoadStore_generics.R ├── ModuleODSigs.R ├── PassManager.R ├── RAPIRoutineSignatures.R ├── TypeID.R ├── allPredecessors.R ├── asEnumValue.R ├── asMethods.R ├── ascii.R ├── assembler.R ├── block.R ├── bool_methods.R ├── byVal.R ├── callGraph.R ├── cfg.R ├── classDefs.R ├── classDefs2.R ├── classof.R ├── constants.R ├── context.R ├── createAccessors.R ├── datalayout.R ├── debugInfo.R ├── declareFunction.R ├── dominates.R ├── drawCFG.R ├── dso.R ├── externalLinkage.R ├── ffi.R ├── findCalledFunctions.R ├── generics.R ├── generics_bools.R ├── gep.R ├── getArray.R ├── getCondition.R ├── globalVar.R ├── guessFile.R ├── inferPointerElType.R ├── initialize.R ├── instruction.R ├── intrinsic.R ├── lljit.R ├── llvm.R ├── llvmMDNodeClasses.R ├── llvmPTXUtils.R ├── llvmTypeClasses.R ├── llvmValueClasses.R ├── llvmVersion.R.in ├── loop.R ├── manual_generics.R ├── manual_instruction.R ├── metadata.R ├── methods.R ├── mkCallProxy.R ├── mkFun.R ├── module.R ├── needSymbol.R ├── oldClasses.R ├── onLoad.R ├── opCodeClassMap.R ├── ostream.R ├── otherClasses.R ├── passConstructors.R ├── phi.R ├── procEnumValues.R ├── sexpTypes.R ├── showBlocks.R ├── simpleFunction.R ├── streams.R ├── targetMachine.R ├── targets.R ├── targets.R.in ├── typeDefs.R ├── typeName.R ├── types.R ├── user.R ├── utils.R ├── value.R ├── version.R ├── z_enumDefs_10.0.R ├── z_enumDefs_11.0.R ├── z_enumDefs_12.0.R ├── z_enumDefs_13.0.R ├── z_enumDefs_14.0.R ├── z_enumDefs_15.0.R ├── z_enumDefs_16.0.R ├── z_enumDefs_17.0.R ├── z_enumDefs_18.1.R ├── z_enumDefs_3.4.R ├── z_enumDefs_3.5.R ├── z_enumDefs_3.6.R ├── z_enumDefs_3.7.R ├── z_enumDefs_3.8.R ├── z_enumDefs_3.9.R ├── z_enumDefs_4.0.R ├── z_enumDefs_5.0.R ├── z_enumDefs_6.0.R ├── z_enumDefs_7.0.R ├── z_enumDefs_8.0.R └── z_enumDefs_9.0.R ├── README.md ├── Rscripts ├── AttributeValues.R ├── CoveredClassesMethods.R ├── opt.R ├── pointerPrint.R └── seg.R ├── TU.old ├── GNUmakefile ├── Questions ├── clang.R ├── classNames ├── funs.R ├── llvm.cpp ├── tu.R └── utils.R ├── TU ├── FIX ├── Functions.md ├── GNUmakefile ├── MemTransfer.md ├── Missing.md ├── Questions.md ├── RAPI.c ├── README.md ├── R_createRef.R ├── Rinstructions.R ├── ValueMethods.R ├── checkClasses.R ├── clang_new.R ├── classHierarchyNames.R ├── classMatrix.R ├── classof.R ├── compareEnums.R ├── cxcursor.R ├── dbg.R ├── enums.R ├── exploreClasses.R ├── exploreMethods.R ├── findClassesInRllvmSrc.R ├── foo.c ├── getBaseClasses.R ├── getCppIncludes.R ├── includeDirs.R ├── inst.R ├── instructions.cc ├── linkPasses.cc ├── llvm.cpp ├── makePassCode.R ├── mergeFuns.R ├── missing.R ├── missingMethods.R ├── mkLLVM_isA.R ├── mkSetClass.R ├── passes.R ├── passes.cc ├── procFindResults.R ├── rapi.R ├── rclasses.R ├── sizeof.c ├── typeClasses.R └── utils.R ├── Todo.xml ├── Updating ├── LLVM14.md ├── LLVM15.md ├── UpdateLLVMVersion ├── UpdatingVersion.md ├── V16.md ├── V17.md └── V18Issues.md ├── Web ├── FAQ.html ├── GNUmakefile ├── autom4te.cache │ ├── output.0 │ ├── requests │ └── traces.0 ├── config.log ├── config.status ├── configure ├── configure.in ├── index.html └── index.html.in ├── attribMechanism.cc ├── cleanup ├── configurations └── Makefile ├── configure ├── configure.ac ├── ctests ├── GNUmakefile ├── globalStringAccess.c └── parms.cc ├── experiments ├── DIBuilder.R ├── GNUmakefile ├── README.md ├── add.c ├── add.cpp ├── add.s ├── add1.c ├── add1.llcpp ├── and.c ├── array.R ├── array.c ├── catchError.R ├── charType.c ├── conditions.c ├── constFold.c ├── constFold.llcpp ├── constFolding.R ├── createLoop.R ├── emptyStruct.c ├── fgets.c ├── fib.c ├── funcPointer.c ├── functionPointer.R ├── functionPointer.c ├── functionPointer_show.c ├── global.c ├── neg.c ├── not.bc ├── not.c ├── not.llcpp ├── nullInit.c ├── nullInit.cpp ├── opaque.c ├── optimization.R ├── optimize.R ├── pointerArith.c ├── shapeClasses.cpp ├── simpleIf.c ├── simpleSet.c ├── simpleStruct.c ├── strcmp.c ├── stress.ll ├── struct.c ├── struct.llcpp ├── struct2.R ├── struct2.c ├── struct2.ll ├── structCall.c ├── structCall.cpp ├── structPtr.c ├── threadStruct.c ├── varArgFun.c ├── varargs.R ├── varargs.c ├── void.c ├── voidPtr.c ├── whileReturn.bc ├── whileReturn.c └── whileReturn.llcpp ├── explorations ├── EXAMPLES ├── Fgets.c ├── GNUmakefile ├── HowToUseLLJIT │ ├── GNUmakefile │ ├── HowToUseLLJIT.cpp │ ├── HowToUseLLJIT2.cpp │ ├── Makevars │ ├── README.md │ ├── bar.c │ ├── bar.ir │ ├── fib.c │ ├── fib.ir │ ├── foo.c │ ├── foo.ir │ ├── objectFiles.R │ ├── rlljit.R │ ├── run.R │ ├── run2.R │ ├── twoModules.cpp │ ├── twoModules2.R │ ├── twoModules2.cpp │ ├── twoModules3.R │ └── twoModules3.cpp ├── MapReduce.R ├── MapReduce.Rdb ├── OpaquePointers │ ├── GNUmakefile │ ├── OpaqueReasoning.md │ ├── README.md │ ├── opaqueExplore.R │ └── opaqueTests.c ├── README.md ├── STATUS ├── ScalarRealCast.R ├── WASMTest.html ├── backend.R ├── castUp.c ├── class.cpp ├── const.c ├── constArg.R ├── constArray.c ├── copyCrash.R ├── cpp.R ├── debugBreakpoint.R ├── distance.R ├── distance.Rdb ├── distance.tm.8000:1000:40_Darwin.rda ├── distance.tm.8000:1000:40_jasper_Linux.rda ├── distance.tm.8000:1000:40_lipschitz_Linux.rda ├── distance.tm.8000:1000:40_lipschitz_Linux_gcc.rda ├── distance.tm.8000:3000:40_Darwin.rda ├── dnorm.R ├── dnorm.Rdb ├── dnorm.c ├── dnormLoop.R ├── dnormLoop.c ├── doubleArray.c ├── execEng.R ├── expandGrid.R ├── fgets.Rdb ├── fib.R ├── fib.c ├── fib.tm.30_Darwin.rda ├── fib.tm.30_jasper_Linux.rda ├── fib.tm.30_lipschitz_Linux.rda ├── fib.tm.30_lipschitz_Linux_gcc.rda ├── foo.c ├── fopen.R ├── fopen.c ├── fuseLoop.R ├── fuseLoop.Rdb ├── fuseLoop.tm.1e+06_Darwin.rda ├── fuseLoop.tm.1e+07_Darwin.rda ├── fuseLoop.tm.1e+07_jasper_Linux.rda ├── fuseLoop.tm.1e+07_lipschitz_Linux.rda ├── fuseLoop.tm.1e+07_lipschitz_Linux_gcc.rda ├── fuseLoop.tm.1e+08_Darwin.rda ├── fuseLoop_osx.rda ├── gfgets.c ├── globalString.R ├── globalString.c ├── globalString.ll ├── globalStringVar.Rdb ├── globalStringVar.c ├── indirectWriteParam.c ├── inferOpaqueTypes.R ├── insertArray.c ├── insertPointOddity.R ├── iterators.R ├── iterators.Rdb ├── lazyCompile.R ├── lljit.R ├── lljit2.R ├── localStringVar.c ├── logLik.c ├── loop.R ├── loop.c ├── manualFib.R ├── manualFib2.R ├── moduleSharingReference.R ├── multiConditions.c ├── neg.c ├── nestedStruct.c ├── nestedStruct.xml ├── nvptrx.Rdb ├── nvvmUtils.R ├── phi.c ├── proxyEg.c ├── proxyFuncs.Rdb ├── ptx.R ├── ptxKernel.cu ├── ptxNVVMExample.Rdb ├── ptx_direct.R ├── ptx_direct_grid.R ├── ptx_direct_simple.R ├── ptx_nvvm.R ├── ptx_nvvm1.R ├── ptx_nvvm_add.R ├── ptx_nvvm_conditional.R ├── ptx_test.R ├── readUpTo.c ├── regexp.Rdb ├── regexp.c ├── sample1.csv ├── sampleCSV.R ├── sampleCSV.Rdb ├── sampleCSV.tm_1e+05_Duncan-Temple-Langs-MacBook-Pro.local_Darwin.rda ├── sampleCSV.tm_1e+05_jasper.ucdavis.edu_Linux.rda ├── sampleCSV.tm_1e+05_lipschitz_Linux.rda ├── sampleCSV.tm_1e+05_lipschitz_Linux_gcc.rda ├── sampleCSV1.Rdb ├── sampleCSVTimes.png ├── sapply.R ├── scalarCast.R ├── select.c ├── simpleGlobalString.R ├── simpleGlobalString.c ├── simpleKernel.cu ├── static.c ├── struct.c ├── switch.c ├── symbolsFrom2Modules.R ├── ternary.c ├── testDist.R ├── testDoubleSet.R ├── testFgets.c ├── testSEXP.R ├── tmp ├── tmp.R ├── twoMods.R ├── twoMods_lljit.R ├── typedefStruct.R ├── typedefStruct.c ├── undefinedSymbols.R ├── void.c ├── void.cpp └── wasm.Rdb ├── inst ├── IR │ ├── GNUmakefile │ ├── README.md │ ├── add.ll │ ├── auxInductionVars.R │ ├── distance.c │ ├── distance.ll │ ├── enums.c │ ├── enums.ir │ ├── fib.c │ ├── fib.ll │ ├── fib.ll-unoptimized │ ├── fib_debug.ir │ ├── lengths.c │ ├── loop.c │ ├── names.ir │ ├── rapiEg.c │ ├── rapiEg.ir │ └── rtypes.c ├── Make │ └── IRMakefile ├── README.md └── doc │ ├── AccessingArrays.R │ ├── FAQ.xml │ ├── README.md │ ├── basics │ ├── check2.R │ └── staticCodeAnalysis.md ├── man ├── Argument.Rd ├── Block.Rd ├── ConstantExpr.Rd ├── DINodeType.Rd ├── ExecutionEngine.Rd ├── Function.Rd ├── IRBuilder.Rd ├── InitializeNativeTarget.Rd ├── InstructionFuns.Rd ├── Intrinsic.Rd ├── LoadStoreInst.Rd ├── Loop.Rd ├── Module.Rd ├── ModuleODSigs.Rd ├── Passes.Rd ├── RC++Reference-class.Rd ├── Rllvm.Rd ├── TargetFuns.Rd ├── Value.Rd ├── VoidType.Rd ├── addCases.Rd ├── binOp.Rd ├── blocks.Rd ├── clone.Rd ├── createGlobalVariable.Rd ├── createICmp.Rd ├── createIsNotNull.Rd ├── declareFunction.Rd ├── demangle.Rd ├── dlsym.Rd ├── dominates.Rd ├── dot.llvm.Rd ├── drawCFG.Rd ├── formattedRawOstream.Rd ├── generatePTX.Rd ├── getAllUsers.Rd ├── getAsCString.Rd ├── getCallingConv.Rd ├── getClassName.Rd ├── getDefinedRoutines.Rd ├── getGetElementPtr.Rd ├── getGlobalContext.Rd ├── getHostCPUName.Rd ├── getIntSize.Rd ├── getLine.Rd ├── getLinkage.Rd ├── getLogicalConstant.Rd ├── getLoops.Rd ├── getMetadata.Rd ├── getModuleFunctions.Rd ├── getOpcode.Rd ├── getPassManager.Rd ├── getSuccessor.Rd ├── getValue.Rd ├── inferParamTypes.Rd ├── isInBounds.Rd ├── isType.Rd ├── isZeroValue.Rd ├── isa.Rd ├── lapplyDebugInfo.Rd ├── lljit.Rd ├── llvmAddSymbol.Rd ├── llvmDump.Rd ├── llvmISA.Rd ├── loopAnalysis.Rd ├── mkCallProxy.Rd ├── mkCallsGraph.Rd ├── newDebugBasicType.Rd ├── offsets.Rd ├── onlyReadsMemory.Rd ├── parseIR.Rd ├── parseIRError.Rd ├── raw_svector_ostream.Rd ├── setAlignment.Rd ├── setArgByVal.Rd ├── setInitializer.Rd ├── setMetadata.Rd ├── setOpaquePointers.Rd ├── simpleFunction.Rd ├── string.Rd ├── stripDebugInfo.Rd ├── typeFuns.Rd └── writeBitcode.Rd ├── purgeWrongArch.sh ├── src ├── ASCII.c ├── AttributeValues.cpp ├── Block.cpp ├── CallInst.cpp ├── Constants.cpp ├── DIBuilder.cpp ├── DataLayout.cpp ├── DebugInfoMeta.cpp ├── ExecEngine.cpp ├── Failed.R ├── Function.cpp ├── IRBuilder.cpp ├── Inst.cpp ├── Instruction.cpp ├── Intrinsics.cpp ├── InvokeInst.cpp ├── JITEventListener.cpp ├── JITEventListener.h ├── LLJIT.cpp ├── LLVM_isA.h ├── LoadStore.cpp ├── LoopInfo.cpp ├── Makevars.in ├── Module.cpp ├── MyMake ├── Old │ └── myGlobal.cpp ├── Pass.cpp ├── RLLVMClassName.cpp ├── Rcast.cpp ├── Rllvm.h ├── Target.cpp ├── Triple.cpp ├── Twine.cpp ├── User.cpp ├── Utils.cpp ├── Value.cpp ├── autoCastCode.h ├── auto_classof.h ├── callGraph.cpp ├── classof.cpp ├── converters.cpp ├── demangle.cpp ├── dlsym.cpp ├── dynamicLib.cpp ├── eg_from_llvm.cpp ├── getOpcodeNames.cpp ├── globalVar.cpp ├── llvm_classof_name.cpp ├── llvm_type_classof_name.cpp ├── mangle.cpp ├── mcjit.cpp ├── memory.c ├── metadata.cpp ├── optimize.cpp ├── ostream.cpp ├── runif.cpp ├── stream.cpp ├── test.cpp └── types.cpp ├── tests ├── 1bit.cc ├── GNUmakefile ├── GNUmakefile.docs ├── PROBLEMS ├── addOne.R ├── bitWidth.R ├── blockSubset.R ├── bob.c ├── branchAccessOrder.c ├── byVal.R ├── call.R ├── cfg.c ├── cifVoidPtr.R ├── cifVoidPtr.c ├── clang.c ├── clang.ir ├── clone.R ├── clone2.R ├── cloneFunction.R ├── cloneFunction2.R ├── cloneFunction3.R ├── coerceArgs.R ├── coerceArgs.c ├── coerceArgs.ir ├── context.R ├── createGlobal.R ├── cumsum.Rdb ├── cumsum.c ├── datalayout.R ├── dist.c ├── dlsym.R ├── emitCode.R ├── enums.R ├── extCall.Rdb ├── ffi.R ├── ffi2.R ├── ffi_1bit.R ├── findCalledFunctions.R ├── findCalledFuns.c ├── findIRFiles.r ├── findInductionVariables.R ├── foo.c ├── fooBlocks.c ├── fpConstant.R ├── funcAttributes.R ├── gc.R ├── gep.R ├── getUses.R ├── global.R ├── globalAccessors.R ├── globalArrays.R ├── globalGet.R ├── globalSet.R ├── globalStruct.c ├── globalVarInit.R ├── globalVariable.R ├── globalVars.Rdb ├── globals.R ├── insertElement.R ├── jitevents.R ├── loop2.R ├── loop3.R ├── loop4.R ├── loop5.R ├── looptest.ir ├── looptest_info.R ├── ls_module.c ├── mangle.R ├── mcjit.R ├── meta.R ├── meta0.R ├── meta1.R ├── metadata.R ├── metadataRaw.R ├── mkCallProxy.R ├── mkRFun.R ├── moveInstructions.R ├── noSymbol.R ├── optimize.R ├── optimize2.R ├── paramAttributes.R ├── parseAssembler.R ├── postdominates.R ├── readBitcode.R ├── real.c ├── rffiCall.Rdb ├── run.r ├── rw1.R ├── rw2d.Rdb ├── rw2d.tm.1e7_Darwin.rda ├── rw2d.tm.1e7_Linux.rda ├── rw2d.tm.1e7_lipschitz_Linux.rda ├── rw2d.tm.1e7_lipschitz_Linux_gcc.rda ├── sameType.R ├── sequentialCFG.c ├── setAttrs.R ├── setGlobal.R ├── simpleFun.R ├── simplest.R ├── store.R ├── store1.R ├── store2.R ├── stringPointer.R ├── stringPointer2.R ├── strings.Rdb ├── struct.R ├── switch.R ├── ternary.R ├── testFooBlocks.R ├── tryCatch.R ├── tryCatch.cpp ├── tut1.R ├── tut2.R ├── types.R ├── verify.R ├── verifyRTypes.R ├── void.R ├── walkBlocks.R ├── writeBitcode.R └── xPlus1.Rdb └── tools └── getIntrinsicEnums.R /.Rbuildignore: -------------------------------------------------------------------------------- 1 | config.log 2 | config.status 3 | .*Web 4 | GNUmakefile 5 | inst/doc/old.xml 6 | .*Rllvm.Rcheck 7 | .*autom4te.cache 8 | \.\.Rcheck.* 9 | Rplots.ps 10 | tests/.*.o 11 | Experiments 12 | TAGS 13 | sample.csv 14 | tests/.*\.rda 15 | explorations/.*\.rda 16 | explorations/.*\.[s]?o 17 | inst/TU/.*\.tu 18 | VinceQues 19 | XSL 20 | CSS 21 | ctests 22 | \.git.* 23 | a.out.dSYM/.* 24 | \.dSYM.* 25 | \.tu$ 26 | explorations/.*\.png 27 | explorations/globalString 28 | src/Rllc.cpp 29 | src/llc.cpp 30 | src/Makevars$ 31 | Paper 32 | IRNotes 33 | CompilerNotes 34 | \./Classes$ 35 | AttributeValues$ 36 | test.R 37 | testPTX.R 38 | funs.Rds 39 | fun.Rds 40 | \.o$ 41 | distance.*.rda 42 | twoModules[23]$ 43 | syms.so 44 | llvmClasses_10.0.rds 45 | TU.old/.* 46 | src/IRMakefile 47 | IRMakefile- 48 | src/*.ir 49 | src/*.bc 50 | 51 | 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | explorations/sample.csv 2 | src/Makevars 3 | *.ll 4 | *.bc 5 | *.llcpp 6 | a.out.dSYM 7 | R/llvmVersion.R 8 | R/targets.R 9 | TAGS 10 | ToFix 11 | XSL 12 | *.s 13 | *.tu 14 | AnalyzeCCode/*.html 15 | src/IRMakefile 16 | -------------------------------------------------------------------------------- /AnalyzeCCode/GNUmakefile: -------------------------------------------------------------------------------- 1 | #CLANG=$(HOME)/LLVM/LLVM5.0.1/llvm-5.0.1.src/build/bin/clang 2 | 3 | ifndef CLANG 4 | CLANG=clang 5 | endif 6 | 7 | CFLAGS=-I$(R_HOME)/include 8 | OPT_LEVEL=-O3 9 | 10 | XDYNDOCS=$(HOME)/GitWorkingArea/XDynDocs/inst 11 | 12 | 13 | include ../inst/IR/GNUmakefile 14 | 15 | IR_FLAGS=-fno-discard-value-names 16 | 17 | %_optimized.ll: %.c GNUmakefile 18 | $(CLANG) $(OPT_LEVEL) $(CFLAGS) -S -emit-llvm -o $@ $< -fno-discard-value-names 19 | 20 | 21 | # -DNDEBUG -I/usr/local/include -fPIC -O2 -g -Wall -S -emit-llvm foo.c -o foo.ir 22 | 23 | 24 | %.html: %.xml 25 | $(MAKE) -f $(XDYNDOCS)/Make/Makefile $@ 26 | 27 | 28 | 29 | -include $(XDYNDOCS)/Make/Makefile 30 | -------------------------------------------------------------------------------- /AnalyzeCCode/Makevars: -------------------------------------------------------------------------------- 1 | PKG_CXXFLAGS=-I$(HOME)/Rpackages/Rcpp/include 2 | -------------------------------------------------------------------------------- /AnalyzeCCode/callGraph.R: -------------------------------------------------------------------------------- 1 | # See callGraph in NativeCodeAnalysis 2 | funCalls = 3 | function(fun) 4 | { 5 | #XXX Fix getInstructions and the cast which fails on MemSetInst to CallInst?? 6 | b = getBlocks(fun) 7 | i = lapply(b, getBlockInstructions, cast = FALSE) 8 | i = unlist(i) 9 | w = sapply(i, is, "CallInst") 10 | ans = unique(lapply(i[w], function(x) x[[length(x)]])) 11 | names(ans) = sapply(ans, getName) 12 | ans 13 | } 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /AnalyzeCCode/check.R: -------------------------------------------------------------------------------- 1 | setClass("Foo", representation(bob = "integer")) 2 | 3 | .Call("rklass") 4 | -------------------------------------------------------------------------------- /AnalyzeCCode/class.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | source("getType.R") 3 | m = parseIR("foo.ir") 4 | setMethod("show", "Value", function(x) print(as(x,'character'))) 5 | 6 | o = compReturnType(m$rklass) 7 | 8 | if(FALSE) { 9 | ii = as(nm, "Instruction") 10 | v = .Call("R_GlobalVariable_getInitializer", ii[[1]]) 11 | getClassName(v) 12 | .Call("R_ConstantDataSequential_getAsCString", v) 13 | } 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /AnalyzeCCode/eg.c: -------------------------------------------------------------------------------- 1 | foo = 2 | function(x) 3 | x[2] 4 | 5 | 6 | cfoo(SEXP x) 7 | { 8 | return(INTEGER(x)[1]); 9 | } 10 | 11 | 12 | 13 | r = 14 | function(x) 15 | { 16 | x = as.character(x) 17 | y = numeric(length(x)) 18 | ans = .C("foo", x, y)[[2]] 19 | y = "abc" 20 | sum(ans) 21 | } 22 | -------------------------------------------------------------------------------- /AnalyzeCCode/error.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | SEXP 4 | r_routine(SEXP x, SEXP y) 5 | { 6 | 7 | if(LENGTH(x) != LENGTH(y)) 8 | PROBLEM "x and y must have the same length" 9 | ERROR; 10 | 11 | return(R_NilValue); 12 | } 13 | -------------------------------------------------------------------------------- /AnalyzeCCode/findGlobalUse.R: -------------------------------------------------------------------------------- 1 | findRoutinesUsingGlobal = 2 | function(gvar) 3 | { 4 | # Not all uses may be in a Function, e.g. being used as a global initializer 5 | # So we handle those by finding out where they are being used. 6 | if(is(gvar, "GlobalVariable") || is(gvar, "ConstantExpr")) 7 | return(unlist(lapply(getAllUsers(gvar), findRoutinesUsingGlobal))) 8 | 9 | as(gvar, "Function") 10 | } 11 | -------------------------------------------------------------------------------- /AnalyzeCCode/findRpVcostUse.R: -------------------------------------------------------------------------------- 1 | accessesRpVcost = 2 | function(i) 3 | { 4 | any(sapply(i[], function(i) { 5 | if(is(i, "ConstantExpr")) 6 | i = as(i, "Instruction") 7 | is(i, "GetElementPtrInst") && identical(i[[1]], m[["rp"]]) && getValue(i[[3]]) == 11L 8 | })) 9 | } 10 | -------------------------------------------------------------------------------- /AnalyzeCCode/icmp2.tex: -------------------------------------------------------------------------------- 1 | \documentclass[tikz]{standalone} 2 | \usetikzlibrary{chains,shadows.blur} 3 | % For decorating a path with text. 4 | \begin{document} 5 | 6 | \input{icmp2CFG} 7 | 8 | \end{document} 9 | -------------------------------------------------------------------------------- /AnalyzeCCode/lengths.xml: -------------------------------------------------------------------------------- 1 |
5 | 6 | 7 | 8 | Consider the simple loop over the elements of two vectors. 9 | 10 | 11 | 12 | We want to programatically determine that the loop 13 | is a) over the length of one of the objects, 14 | b) we are accessing elements within the vectors, 15 | and b) that vectors must have the same length. 16 | 17 | 18 | 19 | We start by find all the uses of each parameter: 20 | 21 | m = parseIR("lengths.ir") 22 | p = getParameters(m$two) 23 | u = lapply(p, getAllUsers) 24 | 25 | 26 | 27 |
28 | 29 | -------------------------------------------------------------------------------- /AnalyzeCCode/loop02BlockGraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/AnalyzeCCode/loop02BlockGraph.png -------------------------------------------------------------------------------- /AnalyzeCCode/matrixLoop.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | SEXP 4 | mloop(SEXP m) 5 | { 6 | int i, j; 7 | double ans = 0.0; 8 | 9 | int nrow = Rf_nrows(m), ncol = Rf_ncols(m); 10 | for(i = 0; i < nrow; i++) { 11 | for(j = 0; j < ncol ; j++) { 12 | ans += REAL(m)[i*nrow + j]; 13 | } 14 | } 15 | 16 | return(ScalarReal(ans)); 17 | } 18 | -------------------------------------------------------------------------------- /AnalyzeCCode/mod.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | int64_t x = 4294967288; 7 | 8 | int 9 | main(int argc, char *argv[]) 10 | { 11 | 12 | int i = atoi(argv[1]); 13 | int ans = (i & x); 14 | fprintf(stderr, "%d -> %d\n", i, ans); 15 | return(0); 16 | } 17 | -------------------------------------------------------------------------------- /AnalyzeCCode/multiRet.c: -------------------------------------------------------------------------------- 1 | int 2 | ret(int x) 3 | { 4 | if(x < 0) 5 | return(-1); 6 | else if(x == 0) 7 | return(0); 8 | else if(x < 10) 9 | return(1); 10 | 11 | return(10); 12 | } 13 | -------------------------------------------------------------------------------- /AnalyzeCCode/rcpp.cc: -------------------------------------------------------------------------------- 1 | // clang -O3 -S -emit-llvm -I$R_HOME/include -I$HOME/Rpackages/Rcpp/include rcpp.cc -o rcpp.ir 2 | 3 | #include 4 | 5 | using namespace Rcpp; 6 | 7 | NumericVector timesTwo(NumericVector x) 8 | { 9 | return(x * 2); 10 | } 11 | 12 | 13 | NumericVector init(int n) 14 | { 15 | NumericVector ans(n); 16 | for(int i = 0; i < n; i++) 17 | ans[i] = i*2*sin(i); 18 | 19 | return(ans); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /AnalyzeCCode/recursive.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | SEXP 4 | getResult(SEXP a, int val) 5 | { 6 | SEXP ans; 7 | int i; 8 | PROTECT(ans = allocMatrix(REALSXP, 2*val, val)); 9 | 10 | for(i = 0; i < 3*val; i++) 11 | REAL(ans)[i] = 2*i*i + .5; 12 | 13 | UNPROTECT(1); 14 | return(ans); 15 | 16 | } 17 | 18 | SEXP 19 | r_start(SEXP rx) 20 | { 21 | return(getResult(rx, 1)); 22 | } 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /AnalyzeCCode/recursive.xml: -------------------------------------------------------------------------------- 1 |
3 | 4 |
5 | 6 | 7 | 8 | This is not about recursive functions but chained calls. 9 | 10 | 11 | 12 | 13 | 14 | m = parseIR("recursive.ir") 15 | b = getBlocks(m$r_start) 16 | 17 | 18 |
19 |
20 | -------------------------------------------------------------------------------- /AnalyzeCCode/simpleLen.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | SEXP 4 | foo(SEXP rn) 5 | { 6 | int n = asInteger(rn); 7 | return(Rf_allocVector(REALSXP, n)); 8 | } 9 | -------------------------------------------------------------------------------- /AnalyzeCCode/sortTypes.xml: -------------------------------------------------------------------------------- 1 |
4 | 5 | 6 | 7 | sort calls do_sort. 8 | 9 | 10 | 11 | 12 | 13 | mm = parseIR("~/R-devel/build/src/main/sort.ll") 14 | ret = getReturnValues(mm$do_sort)[[1]] 15 | ret[] 16 | 23 | 24 | 25 | 26 | 27 |
28 | -------------------------------------------------------------------------------- /AnalyzeCCode/tmp.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | SEXP 4 | foo(SEXP n, SEXP prob) 5 | { 6 | int k; 7 | prob = coerceVector(prob, REALSXP); 8 | k = length(prob); 9 | return(allocMatrix(INTSXP, k, asInteger(n))); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /AnalyzeCCode/try.cc: -------------------------------------------------------------------------------- 1 | // clang -O2 -emit-llvm -S -o try.ir try.cc -I$R_HOME/include -fno-discard-value-names 2 | 3 | int 4 | bob(int x) 5 | { 6 | if(x < 0) 7 | throw "my error message"; 8 | 9 | return(x + 1); 10 | } 11 | 12 | 13 | int 14 | jane(int val) 15 | { 16 | int ans; 17 | try { 18 | ans = bob(val); 19 | } catch(const char *msg) { 20 | return(-1); 21 | } 22 | 23 | return(ans); 24 | } 25 | 26 | #include 27 | SEXP 28 | foo(SEXP r_val) 29 | { 30 | int ans = -1; 31 | try { 32 | ans = bob(INTEGER(r_val)[0]); 33 | } 34 | catch(char *msg) { 35 | PROBLEM "error calling bob: %s", msg 36 | ERROR; 37 | } 38 | 39 | return(ScalarInteger(ans)); 40 | } 41 | -------------------------------------------------------------------------------- /CompilerNotes: -------------------------------------------------------------------------------- 1 | strength reduction 2 | changing multiplications to additions where possible 3 | or other operations to cheaper ones 4 | 5 | 6 | loop fusion 7 | 8 | 9 | loop unrolling 10 | 11 | -------------------------------------------------------------------------------- /DebugInfo/GNUmakefile: -------------------------------------------------------------------------------- 1 | 2 | include ../inst/IR/GNUmakefile 3 | 4 | CFLAGS=-O0 -g -fno-discard-value-names 5 | 6 | #%.ir: %.c 7 | # $(CC) -O0 -S -emit-llvm $^ -o $@ -g -fno-discard-value-names 8 | -------------------------------------------------------------------------------- /DebugInfo/TODO.md: -------------------------------------------------------------------------------- 1 | + get the parameter names for a routine from the debug information in a Module. 2 | + write about in UsefulLLVMTips/llvmUsefulTricks.xml 3 | + -fno-discard-value-names. 4 | 5 | + add R function for getDebugLoc() method for an instruction. 6 | 7 | + How do we get the specific metadata we want 8 | 9 | + Return the DIType nodes from the iterator. 10 | + Do we need to clone 11 | 12 | + Implement methods for DIType 13 | 14 | + Add the other DIType classes 15 | 16 | -------------------------------------------------------------------------------- /DebugInfo/URLs: -------------------------------------------------------------------------------- 1 | http://llvm.org/docs/SourceLevelDebugging.html 2 | https://stackoverflow.com/questions/19946743/how-to-get-the-field-name-from-llvms-metadata 3 | http://www.cs.cornell.edu/~asampson/blog/llvm.html -------------------------------------------------------------------------------- /DebugInfo/enums.c: -------------------------------------------------------------------------------- 1 | typedef enum { RED, GREEN, BLUE} Color; 2 | 3 | int 4 | foo(Color a) 5 | { 6 | if(a == RED) 7 | return(1); 8 | 9 | return(3); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /DebugInfo/fnptr.c: -------------------------------------------------------------------------------- 1 | 2 | int (*f)(int x); 3 | 4 | int 5 | a(int z) 6 | { 7 | return(z*2); 8 | } 9 | 10 | int 11 | b(int z) 12 | { 13 | return(z + 2); 14 | } 15 | 16 | void 17 | init() 18 | { 19 | f = b; 20 | } 21 | 22 | int 23 | k() 24 | { 25 | return(f(10)); 26 | } 27 | -------------------------------------------------------------------------------- /DebugInfo/paramNames.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = parseIR("simplest.ir") 3 | 4 | # get the debug information identified for a function so can go directly to that. 5 | # 6 | # Or can read all of the debug information and get the DISubprogram one and get the name 7 | # For subprogram, we have the id (!34) 8 | # For parameters, we can match their scope attribute/flag to the subprogram 9 | # 10 | 11 | k = lapplyDebugInfo(m, class) 12 | 13 | -------------------------------------------------------------------------------- /DebugInfo/simple.c: -------------------------------------------------------------------------------- 1 | struct A { 2 | int i; 3 | double d; 4 | void *(*f)(int i, double d); 5 | }; 6 | 7 | struct A var; 8 | 9 | -------------------------------------------------------------------------------- /DebugInfo/simple2.c: -------------------------------------------------------------------------------- 1 | struct A { 2 | int i; 3 | double d; 4 | int (*f)(int i, double d); 5 | int (*v)(); 6 | }; 7 | 8 | struct A var, *pvar; 9 | 10 | #include 11 | 12 | int foo(); 13 | 14 | int 15 | doit(int i, double d) 16 | { 17 | printf("i = %d, d = %lf\n", i, d); 18 | return(2*i); 19 | } 20 | 21 | 22 | void 23 | init() 24 | { 25 | pvar = &var; 26 | var.i = 2; 27 | var.d = 3.1415; 28 | var.f = doit; 29 | var.v = foo; 30 | } 31 | 32 | int 33 | foo() 34 | { 35 | return( pvar->f(3, 10.5) ); 36 | } 37 | 38 | void 39 | foov() 40 | { 41 | pvar->v(); 42 | } 43 | 44 | void 45 | foov1() 46 | { 47 | var.v(); 48 | } 49 | 50 | 51 | void 52 | init2() 53 | { 54 | void (*p)(); 55 | p = &init; 56 | p(); 57 | } 58 | 59 | 60 | void 61 | init3() 62 | { 63 | void (*p)(); 64 | p = init; 65 | p(); 66 | } 67 | 68 | 69 | int 70 | xyz(int x) 71 | { 72 | return(x + 1); 73 | } 74 | 75 | int (*fun)(int x1) = xyz; 76 | 77 | void 78 | init4() 79 | { 80 | int (*f)(int); 81 | f = xyz; 82 | f(10); 83 | } 84 | 85 | -------------------------------------------------------------------------------- /DebugInfo/simplest.c: -------------------------------------------------------------------------------- 1 | int 2 | foo(int x, double d) 3 | { 4 | int i = x + 2*d; 5 | return( i ); 6 | } 7 | -------------------------------------------------------------------------------- /DebugInfo/sql.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = parseIR("sqle.ir") 3 | types = .Call("R_Module_debugInfoTypes", m) 4 | 5 | 6 | #setClass("DINode", contains = "RC++Reference") 7 | 8 | # Check the types of the DINodes. 9 | 10 | a = function(x) { if(is(x, "DICompositeType")) names(getElements(x)) else TRUE } 11 | i = lapplyDebugInfoTypes(m, a) 12 | -------------------------------------------------------------------------------- /DebugInfo/sqle.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | 6 | /usr/bin/clang -E sqle.c -o sqle.e -I/usr/local/include 7 | 8 | /usr/bin/clang -S -emit-llvm sqle.c -o sqle.ir -I/usr/local/include 9 | */ 10 | SQLITE_EXTENSION_INIT1 11 | 12 | -------------------------------------------------------------------------------- /FAQ/CodeGenFAQ.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Misc/FIX_dylib: -------------------------------------------------------------------------------- 1 | install_name_tool -change @rpath/libc++.1.dylib /usr/lib/libc++.1.dylib src/Rllvm.so 2 | 3 | -------------------------------------------------------------------------------- /Misc/IRNotes: -------------------------------------------------------------------------------- 1 | names/identifiers have a prefix @ (global), % (local) 2 | 3 | comments character - ; 4 | 5 | -------------------------------------------------------------------------------- /Misc/R/callGraph.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m = parseIR("tests/findCalledFuns.ir") 4 | g1 = mkCallsGraph(m) 5 | 6 | m = parseIR("~/R-4.1/build3/src/main/arithmetic.ir") 7 | g2 = mkCallsGraph(m) 8 | 9 | m = readBitcode("~/R-4.1/build3/src/main/all.bc") 10 | g3 = mkCallsGraph(m) 11 | 12 | 13 | if(FALSE) { 14 | source("R/callGraph.R") 15 | g = mkCallsGraph(m) 16 | 17 | funs = names(getModuleFunctions(m)) 18 | 19 | node = .Call("R_CallGraph_FunctionNode", g, m$foo) 20 | .Call("R_CallGraphNode_getNodeNames", node) 21 | 22 | 23 | node = .Call("R_CallGraph_FunctionNode", g, m$either) 24 | .Call("R_CallGraphNode_getNodeNames", node) 25 | } 26 | -------------------------------------------------------------------------------- /Misc/R/checkSEXP.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | rm = parseIR("../RLLVMCompile/inst/IR/Rmain.bc") 3 | 4 | if(FALSE) { 5 | # Changing the name of the SEXPREC type is not sufficient . 6 | # verifyModule() still says they are different. 7 | # The name does not actually get set verbatim to what we specify 8 | # as LLVM adds a number to it since it would conflict with our SEXPPREC 9 | # in Rllvm. So we need to replace the SEXPREC in rm with getElementType(SEXPType) 10 | sexp = getTypes(rm)$SEXPREC 11 | getName(sexp) 12 | id = getName(getElementType(SEXPType)) 13 | .Call("R_StructType_setName", sexp, id) 14 | } 15 | 16 | m = Module() 17 | f = Function("f", SEXPType, module = m) 18 | ir = IRBuilder(f) 19 | 20 | copyFunction(rm$Rf_allocVector, m, changeSEXPTypes = FALSE) 21 | ir$createReturn(ir$createCall(m$Rf_allocVector, 14, 2L)) 22 | 23 | verifyModule(m) 24 | 25 | 26 | -------------------------------------------------------------------------------- /Misc/R/funcGroups.R: -------------------------------------------------------------------------------- 1 | group = 2 | function(els, prefix = c("get", "set", "is", "may", "llvm", "create")) 3 | { 4 | ans = vector("list", length(prefix) + 1) 5 | names(ans) = c(prefix, "Other") 6 | for(p in prefix) { 7 | w = grepl(paste0("^", p), els) 8 | ans[[p]] = els[w] 9 | els = els[!w] 10 | } 11 | ans$Other = els 12 | ans 13 | } 14 | -------------------------------------------------------------------------------- /Misc/R/runEgs.R: -------------------------------------------------------------------------------- 1 | runEg = 2 | function(rd, env = globalenv()) 3 | { 4 | z = parse_Rd(rd) 5 | eg.idx = grep("\\\\examples", sapply(z, attr, "Rd_tag")) 6 | if(length(eg.idx) == 0) 7 | return(NULL) 8 | 9 | txt = trimws(unlist(z[[eg.idx]])) 10 | e = parse(text = txt) 11 | eval(e, env) 12 | } 13 | -------------------------------------------------------------------------------- /Misc/R/test.R: -------------------------------------------------------------------------------- 1 | # This uses code in src/test.cpp to populate a module with a global variable. 2 | # 3 | # Have to compile the code in src/test.cpp 4 | library(Rllvm) 5 | m = Module("bob") 6 | ctx = as(m, "LLVMContext") 7 | 8 | ity = .Call("R_IntegerType_get", ctx, 8L) 9 | lineType = arrayType(ity, 11) 10 | 11 | .Call("R_standaloneTest2", m, lineType) 12 | 13 | ee = ExecutionEngine(m) 14 | getGlobalValue(m[["str2_a"]], ee) 15 | -------------------------------------------------------------------------------- /Misc/R/testPTX.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | .C("R_llc", 1L, "R", c(path.expand("~/Projects/GPUs/Rnvvm/inst/sampleCode/simple-gpu64.ll"), "/tmp/bob.ptx")) 3 | print(file.exists("/tmp/bob.ptx")) 4 | 5 | -------------------------------------------------------------------------------- /Paper/GNUmakefile: -------------------------------------------------------------------------------- 1 | Rllvm.pdf: ../explorations/dnorm.tex 2 | 3 | JSS_DIR=$(HOME)/Projects/JSS/JSSstyle 4 | 5 | Rllvm.pdf: Rllvm.tex rllvm.bib GNUmakefile jssMacros.tex 6 | -$(run-tex) 7 | -$(run-tex) 8 | # -pdflatex $(", "@", LETTERS, "[", "\\", "]", "^", "_", "?", letters, "{", "|", "}", "~")) 3 | function(x) 4 | { 5 | x = as.character(x) 6 | .C("R_asciiCode", x, length(x), ans = integer(length(x)))$ans 7 | } 8 | -------------------------------------------------------------------------------- /R/assembler.R: -------------------------------------------------------------------------------- 1 | 2 | getAssemblyCode = 3 | function(module) 4 | { 5 | module = as(module, "Module") 6 | 7 | if(getDataLayout(module) == "") 8 | stop("the Module needs a datalayout specification") 9 | 10 | pm = passManager(module) # Regular pass manager, not FunctionPassManager 11 | 12 | machine = createTargetMachine() 13 | fstream = raw_svector_ostream() 14 | status = addPassesToEmitFile(machine, pm, fstream) # , CGFT_AssemblyFile) 15 | 16 | run(pm, module) 17 | 18 | new("AssemblerCode", as(fstream, "character")) 19 | } 20 | 21 | 22 | setClass("AssemblerCode", contains = "character") 23 | setMethod("show", "AssemblerCode", function(object) cat(object, sep = "\n")) 24 | -------------------------------------------------------------------------------- /R/classDefs2.R: -------------------------------------------------------------------------------- 1 | # source()'d after llvmValueClasses.R which is programmatically generated. 2 | # Eventually compute these in that code. 3 | 4 | # Compute these from TU/enums.R and the class hierarchy. 5 | # These are intrinsics and under 6 | setClass("MemIntrinsic", contains = "MemIntrinsicBase") 7 | setClass("MemSetBase", contains = "MemIntrinsic") # Not quite same as LLVM but taking a short cut. 8 | setClass("MemTransferBase", contains = "MemIntrinsic") # Not quite same as LLVM but taking a short cut. 9 | setClass("MemTransferInst", contains = "MemTransferBase") 10 | 11 | setClass("MemSetInst", contains = "MemSetBase") 12 | setClass("MemCpyInst", contains = "MemTransferInst") 13 | 14 | -------------------------------------------------------------------------------- /R/classof.R: -------------------------------------------------------------------------------- 1 | isa = 2 | function(obj, classname = class(obj)) 3 | { 4 | .Call("R_Instruction_classof", as(obj, "Instruction"), as.character(classname)) 5 | } 6 | 7 | 8 | getClassName = 9 | function(value) 10 | { 11 | .Call("R_Value_getClassName", value) 12 | } 13 | -------------------------------------------------------------------------------- /R/datalayout.R: -------------------------------------------------------------------------------- 1 | 2 | setMethod("isLittleEndian", "DataLayout", 3 | function(x) 4 | { 5 | .Call("R_DataLayout_isLittleEndian", as(x, "DataLayout")) 6 | }) 7 | 8 | getPointerSize = 9 | function(dataLayout) 10 | { 11 | .Call("R_DataLayout_getPointerSize", as(dataLayout, "DataLayout")) 12 | } 13 | 14 | getPointerTypeSize = 15 | function(dataLayout, type) 16 | { 17 | .Call("R_DataLayout_getPointerTypeSize", as(dataLayout, "DataLayout"), as(type, "Type")) 18 | } 19 | 20 | getTypeAllocSize = 21 | function(dataLayout, type) 22 | { 23 | .Call("R_DataLayout_getTypeAllocSize", as(dataLayout, "DataLayout"), as(type, "Type")) 24 | } 25 | 26 | getStackAlignment = 27 | function(dataLayout) 28 | { 29 | .Call("R_DataLayout_getStackAlignment", as(dataLayout, "DataLayout")) 30 | } 31 | 32 | 33 | 34 | getABITypeAlignment = 35 | function(dataLayout, type) 36 | { 37 | .Call("R_DataLayout_getABITypeAlignment", as(dataLayout, "DataLayout"), as(type, "Type")) 38 | } 39 | -------------------------------------------------------------------------------- /R/externalLinkage.R: -------------------------------------------------------------------------------- 1 | ExternalLinkage = 0 2 | AvailableExternallyLinkage = 1 3 | LinkOnceAnyLinkage = 2 4 | LinkOnceODRLinkage = 3 5 | WeakAnyLinkage = 4 6 | WeakODRLinkage = 5 7 | AppendingLinkage = 6 8 | InternalLinkage = 7 9 | PrivateLinkage = 8 10 | LinkerPrivateLinkage = 9 11 | DLLImportLinkage = 10 12 | DLLExportLinkage = 11 13 | ExternalWeakLinkage = 12 14 | CommonLinkage = 13 15 | 16 | LinkageTypes = c( 17 | ExternalLinkage = 0, 18 | AvailableExternallyLinkage = 1, 19 | LinkOnceAnyLinkage = 2, 20 | LinkOnceODRLinkage = 3, 21 | WeakAnyLinkage = 4, 22 | WeakODRLinkage = 5, 23 | AppendingLinkage = 6, 24 | InternalLinkage = 7, 25 | PrivateLinkage = 8, 26 | LinkerPrivateLinkage = 9, 27 | DLLImportLinkage = 10, 28 | DLLExportLinkage = 11, 29 | ExternalWeakLinkage = 12, 30 | CommonLinkage = 13) 31 | 32 | -------------------------------------------------------------------------------- /R/gep.R: -------------------------------------------------------------------------------- 1 | # methods for GetElementPtrInst & GEPOperator 2 | # But we don't include GEPOperator in our list of LLVM classes - no super class and not of interest to us. 3 | # 4 | 5 | getSourceElementType = 6 | function(x) 7 | { 8 | if(!is(x, "GetElementPtrInst")) 9 | stop("Must be a GEP") 10 | 11 | .Call("R_GetElementPtrInst_getSourceElementType", x) 12 | } 13 | 14 | -------------------------------------------------------------------------------- /R/getCondition.R: -------------------------------------------------------------------------------- 1 | getCondition = 2 | function(x) 3 | { 4 | .Call("R_BranchInst_getCondition", as(x, "BranchInst")) 5 | } 6 | 7 | getNumSuccessors = 8 | function(x) 9 | { 10 | if(isa(x, "ReturnInst")) 11 | return(0L) 12 | 13 | .Call("R_BranchInst_getNumSuccessors", as(x, "BranchInst")) 14 | } 15 | 16 | 17 | 18 | setMethod("getSuccessor", "ReturnInst", function(x, i = 1L) return(NULL)) 19 | 20 | setMethod("getSuccessor", "BranchInst", 21 | function(x, i = 1L) { 22 | .Call("R_BranchInst_getSuccessor", as(x, "BranchInst"), as.integer(i - 1L)) 23 | }) 24 | 25 | 26 | 27 | setMethod("getSuccessors", "BranchInst", 28 | function(x, ...) 29 | { 30 | x = as(x, "BranchInst") 31 | sapply(seq_len(getNumSuccessors(x)), function(i) getSuccessor(x, i)) 32 | }) 33 | 34 | 35 | isConditional = 36 | function(x) 37 | .Call("R_BranchInst_isConditional", as(x, "BranchInst")) 38 | -------------------------------------------------------------------------------- /R/guessFile.R: -------------------------------------------------------------------------------- 1 | guessFile = 2 | function(file, max.dist = 3) 3 | { 4 | dir = dirname(file) 5 | files = list.files(dir, full.names = TRUE) 6 | w = !grepl("(\\.[oacfRrs]$|~$|\\.(cc|cpp))", files) # , invert = TRUE, value = TRUE) 7 | # i = agrep(file, files[w]) 8 | d = adist(file, files[w]) 9 | i = which(d <= max.dist) 10 | 11 | if(length(i)) 12 | return(files[w][i]) 13 | 14 | # Check the chain of directories to see if they exist. 15 | 16 | 17 | return(character()) 18 | } 19 | -------------------------------------------------------------------------------- /R/initialize.R: -------------------------------------------------------------------------------- 1 | InitializeAllTargets = 2 | function() 3 | .Call("R_InitializeAllTargets") 4 | 5 | InitializeAllTargetMCs = 6 | function() 7 | .Call("R_InitializeAllTargetMCs") 8 | 9 | InitializeAllAsmPrinters = 10 | function() 11 | .Call("R_InitializeAllAsmPrinters") 12 | 13 | InitializeAllAsmParsers = 14 | function() 15 | .Call("R_InitializeAllAsmParsers") 16 | 17 | -------------------------------------------------------------------------------- /R/lljit.R: -------------------------------------------------------------------------------- 1 | # ORC - on-request compilation 2 | lljit = 3 | function(lazy = FALSE, ..., .modules = list(...)) 4 | { 5 | jit = .Call("R_LLJIT_create", as.logical(lazy)) 6 | if(length(modules)) 7 | addModule(jit, .modules = .modules) 8 | 9 | jit 10 | } 11 | 12 | 13 | setMethod("addModule", "LLJIT", 14 | function(engine, ..., .modules = list(...)) { 15 | mods = lapply(.modules, as, "Module") 16 | .Call("R_LLJIT_addModules", engine, mods) 17 | }) 18 | 19 | 20 | jitLookup = 21 | function(jit, sym) 22 | { 23 | .Call("R_LLJIT_lookup", as(jit, "LLJIT"), as.character(sym)) 24 | } 25 | 26 | setMethod("$", "LLJIT", 27 | function(x, name) 28 | jitLookup(x, name)) 29 | -------------------------------------------------------------------------------- /R/llvm.R: -------------------------------------------------------------------------------- 1 | llvmShutdown = 2 | function() 3 | { 4 | # stop("not implemented") 5 | .C("R_llvm_shutdown") 6 | } 7 | 8 | llvmStartMultiThreaded = 9 | function() 10 | .Call("R_llvm_start_multithreaded") 11 | 12 | llvmStopMultiThreaded = 13 | function() 14 | .Call("R_llvm_stop_multithreaded") 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /R/llvmPTXUtils.R: -------------------------------------------------------------------------------- 1 | generatePTX = convertModuleToPTX = 2 | function(m) 3 | { 4 | InitializeNVPTXTarget() 5 | arch = "nvptx64" 6 | 7 | tri <- getDefaultTargetTriple() 8 | setTargetTriple(m, tri) 9 | 10 | trgt = lookupTarget(tri, arch) 11 | machine = createTargetMachine(trgt, tri, "sm_30") 12 | 13 | # Now add the passes to generate the code. 14 | 15 | pm = passManager(m, FALSE) 16 | 17 | trgtLibInfo = targetLibraryInfo(tri) 18 | addPass(pm, trgtLibInfo) 19 | 20 | addAnalysisPasses(machine, pm) 21 | 22 | dataLayout = getDataLayout(machine) 23 | addPass(pm, dataLayout) 24 | 25 | 26 | # We'll write the code to a string stream rather than a file 27 | stream = rawStringOstream() 28 | out = formattedRawOstream(stream) 29 | 30 | if(addPassesToEmitFile(machine, pm, out, 0L)) 31 | stop("failed in addPassesToEmitFile. Is this type of file supported by the manager?") 32 | 33 | run(pm, m) 34 | 35 | flush(out) 36 | as(stream, "character") 37 | } 38 | -------------------------------------------------------------------------------- /R/llvmTypeClasses.R: -------------------------------------------------------------------------------- 1 | setClass('VectorType', contains = 'Type') 2 | setClass('IntegerType', contains = 'Type') 3 | setClass('FunctionType', contains = 'Type') 4 | setClass('StructType', contains = 'Type') 5 | setClass('ArrayType', contains = 'Type') 6 | setClass('PointerType', contains = 'Type') 7 | setClass('FixedVectorType', contains = 'VectorType') 8 | setClass('ScalableVectorType', contains = 'VectorType') 9 | -------------------------------------------------------------------------------- /R/llvmVersion.R.in: -------------------------------------------------------------------------------- 1 | LLVMVersion = .llvmVersion = c(major = @LLVM_VERSION@, minor = @LLVM_MINOR_VERSION@) 2 | 3 | llvmVersion = 4 | function() 5 | { 6 | LLVMVersion 7 | } 8 | 9 | 10 | -------------------------------------------------------------------------------- /R/otherClasses.R: -------------------------------------------------------------------------------- 1 | setClass("StructTypeWithNames", representation(names = "character"), contains = "StructType") 2 | 3 | setClass("DoubleType", contains = "Type") #XXX Not in LLVM 4 | 5 | 6 | # A separate class so we can identify a StringType from a generic pointer since now they both use i8* 7 | setClass("StringType", contains = "Type") 8 | 9 | 10 | # R specific types 11 | setClass("SEXPType", contains = "PointerType") 12 | setClass("LGLSXPType", contains = "SEXPType") 13 | setClass("INTSXPType", contains = "SEXPType") 14 | setClass("REALSXPType", contains = "SEXPType") 15 | setClass("STRSXPType", contains = "SEXPType") 16 | setClass("VECSXPType", contains = "SEXPType") 17 | setClass("CHARSXPType", contains = "SEXPType") 18 | 19 | 20 | setClass("StructTypeWithNames", representation(names = "character"), contains = "StructType") 21 | -------------------------------------------------------------------------------- /R/procEnumValues.R: -------------------------------------------------------------------------------- 1 | getEnumValue = 2 | function(val, values, prefix = "", class = NA) 3 | { 4 | sym = deparse(substitute(val)) 5 | 6 | if(!is.na(i <- match(val, values))) 7 | return(values[i]) # make instance of class if !is.na(class) 8 | 9 | if(val %in% names(values)) 10 | return(values[val]) 11 | 12 | if(prefix != "") { 13 | tmp = paste0(prefix, val) 14 | if(tmp %in% names(values)) 15 | return(values[tmp]) 16 | } 17 | 18 | stop("don't recognize ", val, " as an enumerated value. Possible values are ", paste(names(values), collapse = ", ")) 19 | } 20 | -------------------------------------------------------------------------------- /R/simpleFunction.R: -------------------------------------------------------------------------------- 1 | simpleFunction = 2 | function(.name, retType = VoidType, ..., .types = list(...), module = Module(), 3 | .createLocalVars = FALSE) 4 | { 5 | if(length(names(.types)) == 0) 6 | names(.types) = letters[seq(along = .types)] 7 | fun = Function(.name, retType, .types, module = module) 8 | 9 | ir = IRBuilder(b <- Block(fun)) 10 | vars = NULL 11 | 12 | parms = getParameters(fun) 13 | 14 | if(length(.types)) { 15 | if(.createLocalVars) 16 | vars = mapply(function(ty, id, param) { 17 | var = ir$createLocalVariable(ty, id) 18 | ir$createStore(param, var) 19 | var 20 | }, .types, names(.types), parms) 21 | } 22 | 23 | list(ir = ir, params = parms, vars = vars, module = module, fun = fun, block = b) 24 | } 25 | -------------------------------------------------------------------------------- /R/streams.R: -------------------------------------------------------------------------------- 1 | setAs("raw_svector_ostream", "character", 2 | function(from) { 3 | .Call("R_raw_svector_ostream_as_character", from) 4 | }) 5 | 6 | 7 | raw_svector_ostream = 8 | function(len = 1000L) 9 | { 10 | .Call("R_raw_svector_ostream") 11 | } 12 | 13 | -------------------------------------------------------------------------------- /R/typeDefs.R: -------------------------------------------------------------------------------- 1 | VoidType = 1 2 | LabelType = 1 3 | FloatType = 1 4 | DoubleType = 1 5 | Int1Type = 1 6 | Int8Type = 1 7 | Int16Type = 1 8 | Int32Type = 1 9 | Int64Type = 1 10 | FloatPtrType = 1 11 | DoublePtrType = 1 12 | Int32PtrType = 1 13 | StringType = 1 14 | -------------------------------------------------------------------------------- /R/user.R: -------------------------------------------------------------------------------- 1 | #??? Is this working?? 2 | xgetAllUsers = 3 | function(obj, ...) 4 | .Call("R_User_getAllUsers", as(obj, "User")) 5 | 6 | setMethod("length", "User", 7 | function(x) 8 | .Call("R_getNumOperands", x)) 9 | 10 | 11 | setMethod("[[", "User", 12 | function(x, i, ..., value = TRUE) { 13 | if(value) { 14 | .Call("R_getOperand", x, as.integer(i - 1)) 15 | } else 16 | .Call("R_getOperandUse", x, as.integer(i - 1)) 17 | }) 18 | 19 | 20 | replaceUsesOfWith = 21 | function(user, to, from) 22 | { 23 | .Call("R_User_replaceUsesOfWith", as(user, "User"), as(from, "Value"), as(to, "Value")) 24 | } 25 | 26 | 27 | getUser = 28 | function(u, ...) 29 | { 30 | ans = .Call("R_Use_getUser", u) 31 | as(ans, getClassName(ans)) 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /R/version.R: -------------------------------------------------------------------------------- 1 | llvmCheckVersion = 2 | function(ver, cur = llvmVersion()) 3 | { 4 | ver[1] == cur[1] 5 | } 6 | -------------------------------------------------------------------------------- /Rscripts/AttributeValues.R: -------------------------------------------------------------------------------- 1 | # See Function.R - already done. 2 | AttributeValues = structure(0:28, names = c("None", "AddressSafety", 3 | "Alignment", 4 | "AlwaysInline", 5 | "ByVal", 6 | "InlineHint", 7 | "InReg", 8 | "MinSize", 9 | "Naked", 10 | "Nest", 11 | "NoAlias", 12 | "NoCapture", 13 | "NoImplicitFloat", 14 | "NoInline", 15 | "NonLazyBind", 16 | "NoRedZone", 17 | "NoReturn", 18 | "NoUnwind", 19 | "OptimizeForSize", 20 | "ReadNone", 21 | "ReadOnly", 22 | "ReturnsTwice", 23 | "SExt", 24 | "StackAlignment", 25 | "StackProtect", 26 | "StackProtectReq", 27 | "StructRet", 28 | "UWTable", 29 | "ZExt")) 30 | -------------------------------------------------------------------------------- /Rscripts/opt.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = parseIR("~/GitWorkingArea/NativeCodeAnalysis/examples/convolve/convolve.ll") 3 | mgr = passManager(m, TRUE) 4 | p = .Call("R_createPostOrderFunctionAttrsLegacyPass") 5 | addPass(mgr, p) 6 | 7 | run(mgr, m) 8 | 9 | -------------------------------------------------------------------------------- /Rscripts/pointerPrint.R: -------------------------------------------------------------------------------- 1 | 2 | print.PointerType = 3 | function(x, ...) 4 | print(sprintf("Type PointerType(%s)", as(getElementType(x), "character"))) 5 | 6 | setMethod("show", "PointerType", 7 | function(object) 8 | print.PointerType(object)) 9 | 10 | -------------------------------------------------------------------------------- /Rscripts/seg.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = parseIR("tests/loop.ll") 3 | 4 | b = getBlocks(m$loop) 5 | tt = lapply(b, getTerminator) 6 | br = lapply(tt, function(x) if(is(x, "BranchInst")) { if(isConditional(x)) x[-1] else x[1]}) 7 | 8 | br = lapply(tt, function(x) if(is(x, "BranchInst")) { lapply(seq_len(getNumSuccessors(x)), function(i) getSuccessor(x, i))}) 9 | 10 | #br = lapply(tt, function(x) x[-1]) 11 | 12 | i = lapply(br, function(x) if(is.null(x)) NA else match(x, b)) 13 | e = cbind(rep(seq(along = b), sapply(i, length)), unlist(i)) 14 | # Drop the NA for the return. 15 | e = e[ !is.na(e[,2]), ] 16 | 17 | g = graph_from_edgelist(e) 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /TU.old/GNUmakefile: -------------------------------------------------------------------------------- 1 | # 2 | # This is no longer used. See clang.R 3 | # 4 | # 5 | 6 | LLVM_CONFIG=llvm-config # $(HOME)/Downloads/llvm-2.8/Release/bin/llvm-config 7 | LLVM_CFLAGS=`$(LLVM_CONFIG) --cflags` 8 | 9 | tu: llvm.tu 10 | 11 | llvm.tu: llvm.c 12 | $(CXX) -c -fdump-translation-unit -o /dev/null $^ $(LLVM_CFLAGS) -------------------------------------------------------------------------------- /TU.old/Questions: -------------------------------------------------------------------------------- 1 | Q Why does 2 | sapply(llvm, getFileName) 3 | include files from LLVM3.8 when we were focusing on LLVM3.9 4 | 5 | Answer: Because RCIndex is installed against LLVM3.8 and so it looks for the 6 | standard C++ files in that location. 7 | 8 | Q Why duplicate class names in `llvm`, e.g. LoopBase? 9 | Anwer: Templates and then specific instantiation of the template. 10 | How many templates do we have? 11 | table(sapply(llvm, function(x) names(x$kind))) 12 | 13 | CXCursor_ClassDecl CXCursor_ClassTemplate 14 | 354 279 15 | -------------------------------------------------------------------------------- /TU.old/utils.R: -------------------------------------------------------------------------------- 1 | getAllDescendantClasses = 2 | # 3 | # Given a class, find all classes that are derived from it 4 | # i.e. have this as an ancestor 5 | # 6 | function(classes, top = "llvm::Instruction", 7 | baseClass = sapply(classes, function(x) gsub("class ", "", sapply(x@superClasses, getName))), 8 | namespace = "") 9 | { 10 | 11 | if(namespace != "") 12 | names(baseClass) = paste0(namespace, "::", names(baseClass)) 13 | 14 | i = names(baseClass) == top 15 | classes = classes[!i] 16 | baseClass = baseClass[!i] 17 | 18 | # names(gsub("class ", "", sapply(classes, getName)) 19 | left = baseClass 20 | target = top 21 | while(TRUE) { 22 | matches = sapply(left, function(x) any(!is.na(match(x, target)))) 23 | if(any(matches)) 24 | target = c(target, names(left)[matches]) 25 | else 26 | break 27 | left = left[!matches] 28 | } 29 | target 30 | } 31 | -------------------------------------------------------------------------------- /TU/FIX: -------------------------------------------------------------------------------- 1 | + √ includeDirs.R:mkTU() 2 | + Write a function to create the TU with all the arguments that are currently in clang_new.R 3 | or else move these variables (inc, version, args) to a separate script that each script 4 | 5 | + Combine all the functions into a single file or make a package? 6 | + or keep in a sub-directory and have a script that sources() them all. 7 | + or add some to CodeAnalysis or NativeCodeAnalysis 8 | 9 | 10 | -------------------------------------------------------------------------------- /TU/GNUmakefile: -------------------------------------------------------------------------------- 1 | 2 | LLVM_CFLAGS=$(shell llvm-config --cflags) 3 | SYS_CFLAGS=-I$(shell xcrun --show-sdk-path)/usr/include 4 | 5 | # From ../inst/IR/GNUmakefile 6 | LIB_INCLUDE_DIRS=-I/Library/Developer/CommandLineTools/usr/include -I/Library/Developer/CommandLineTools/usr/include/c++/v1 $(SYS_CFLAGS) 7 | 8 | #-I/Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk/usr/include 9 | 10 | linkPasses.ir: linkPasses.cc 11 | clang++ -S -emit-llvm -o linkPasses.ir linkPasses.cc $(LLVM_CFLAGS) $(IR_FLAGS) $(LIB_INCLUDE_DIRS) 12 | 13 | #$(SYS_CFLAGS) 14 | 15 | sizeof: sizeof.c 16 | $(CC) -o $@ $< -I$(R_HOME)/include 17 | 18 | 19 | llvm.E: llvm.cpp 20 | clang++ -E $(LLVM_CFLAGS) $(SYS_CFLAGS) -o $@ $< -------------------------------------------------------------------------------- /TU/Missing.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Missing Classes. 4 | 5 | GlobalValue 6 | GlobalVariable 7 | 8 | 9 | 10 | # Missing Methods 11 | 12 | See missingMethods.R 13 | 14 | -------------------------------------------------------------------------------- /TU/Questions.md: -------------------------------------------------------------------------------- 1 | 2 | + What LLVM classes do we need to add to Rllvm? 3 | 4 | + What methods do we need to add? 5 | 6 | + 7 | -------------------------------------------------------------------------------- /TU/RAPI.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | -------------------------------------------------------------------------------- /TU/ValueMethods.R: -------------------------------------------------------------------------------- 1 | # 2 | # Find all the public (or @access = NA) methods for all the subclasses of Value. 3 | # 4 | # With k from 5 | # source("includeDirs.R") 6 | # getCppClasses(mkTU(), "include/llvm") 7 | # 8 | 9 | getAllSubclassMethods = 10 | function(k, rootClass = "llvm::Value") 11 | { 12 | value = NativeCodeAnalysis::getSubclasses(rootClass, k) 13 | valSubclasses = rmPrefix(unique(unlist(value))) 14 | valPubMethods = lapply(k[valSubclasses], function(x) { tmp = sapply(x@methods, slot, "access"); names(x@methods)[is.na(tmp) | tmp == "public"]}) 15 | data.frame(method = unlist(valPubMethods), class = rep(valSubclasses, sapply(valPubMethods, length))) 16 | } 17 | 18 | if(FALSE) { 19 | valPubMethods.df = getAllSubclassMethods(k) 20 | 21 | # instPubMethods.df = getAllSubclassMethods(k, "llvm::Instruction") 22 | } 23 | 24 | -------------------------------------------------------------------------------- /TU/compareEnums.R: -------------------------------------------------------------------------------- 1 | evalEnums = 2 | function(file, e = new.env()) 3 | { 4 | code = parse(file) 5 | eval(code[[1]][[3]], e) 6 | as.list.environment(e, TRUE) 7 | } 8 | 9 | if(FALSE) { 10 | e14 = evalEnums("z_enumDefs_14.0.R") 11 | e15 = evalEnums("z_enumDefs_15.0.R") 12 | 13 | prev = setdiff(names(e14), names(e15)) 14 | new = setdiff(names(e15), names(e14)) 15 | 16 | both = intersect(names(e15), names(e14)) 17 | same = mapply(identical, e14[both], e15[both]) 18 | 19 | diffs = both[!same] 20 | d = mapply(all.equal, e14[diffs], e15[diffs], SIMPLIFY = FALSE) 21 | } 22 | 23 | -------------------------------------------------------------------------------- /TU/dbg.R: -------------------------------------------------------------------------------- 1 | # Code to debug the native C & C++ code of libclang 2 | # to see if we can find the invisible CXXBaseSpecifier Cursor nodes 3 | # in the AST. 4 | source("includeDirs.R") 5 | source("cxcursor.R") 6 | tu = mkTU(options = 8192L) 7 | k2 = getCppClasses(tu, "include/llvm", nodesOnly = TRUE) 8 | m = k2$MemTransferInst 9 | sapply(as(m, "list"), getCursorKind) 10 | -------------------------------------------------------------------------------- /TU/exploreMethods.R: -------------------------------------------------------------------------------- 1 | if(FALSE) { 2 | value = NativeCodeAnalysis::getSubclasses("llvm::Value", k) 3 | } 4 | 5 | getMethodNames = 6 | function(classNames, k) 7 | { 8 | rclasses = gsub("llvm::", "", unique(unlist(classNames))) 9 | 10 | rClassMethods = lapply(rclasses, function(x) 11 | unique(names(k[[x]]@methods)[sapply(k[[x]]@methods, isPublicMethod)])) 12 | 13 | #length(unique(unlist(rvalueClassMethods))) 14 | 15 | sort(table(unlist(rClassMethods)), decreasing = TRUE) 16 | } 17 | 18 | isPublicMethod = 19 | function(x) 20 | is.na(x@access) || x@access == 'public' 21 | 22 | 23 | -------------------------------------------------------------------------------- /TU/foo.c: -------------------------------------------------------------------------------- 1 | enum Foo { 2 | 3 | A = 1, 4 | B = 2, 5 | BAD = B + 1 6 | }; 7 | 8 | -------------------------------------------------------------------------------- /TU/instructions.cc: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /TU/linkPasses.cc: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /TU/mkLLVM_isA.R: -------------------------------------------------------------------------------- 1 | # Assumes tu from clang_new or 2 | # 3 | source("includeDirs.R") 4 | tu = mkTU() 5 | 6 | # Getting the class hierarchy takes about 100 seconds. 7 | k = getCppClasses(tu, "include/llvm", numClasses = 1200) 8 | 9 | # getClassHierarchy in NativeCodeAnalysis 10 | #library(NativeCodeAnalysis) 11 | #source("../fun.R") # move this. 12 | 13 | h = NativeCodeAnalysis::getSubclasses("llvm::Value", k) 14 | h2 = unique(unlist(h)) 15 | 16 | # MemIntrinsicBase is a templated class. 17 | h3 = setdiff(h2, "llvm::MemIntrinsicBase") 18 | 19 | cat("/* See Rllvm/TU/mkLLVM_isA.R for programmatically generating this */ ", 20 | sprintf("LLVM_isA(%s)", substring(h3, 7)), sep = "\n", file = "../src/LLVM_isA.h") 21 | -------------------------------------------------------------------------------- /TU/passes.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | -------------------------------------------------------------------------------- /TU/procFindResults.R: -------------------------------------------------------------------------------- 1 | procFindResults = 2 | function(file, ll = readLines(file), rmRCheck = TRUE) 3 | { 4 | if(missing(ll) && !file.exists(file)) { 5 | # probably the wrong directory. 6 | ll = system(sprintf("find . -name '*.R' -exec grep -l '%s' {} \\;", file), intern = TRUE) 7 | } 8 | 9 | ll = grep("^grep:", ll, invert = TRUE, value = TRUE) 10 | 11 | if(rmRCheck) 12 | ll = grep("\\.Rcheck/", ll, invert = TRUE, value = TRUE) 13 | 14 | ll = gsub("^\\./", "", ll) 15 | 16 | els = strsplit(ll, "/") 17 | tdirs = sapply(els, `[`, 1) 18 | 19 | split(sapply(els, function(x) paste(x[-1], collapse = "/")), tdirs) 20 | } 21 | -------------------------------------------------------------------------------- /TU/utils.R: -------------------------------------------------------------------------------- 1 | outputEnum = 2 | function(def, file = character(), name = def@name) 3 | { 4 | if(length(file) && !is.na(file)) { 5 | sink(file) 6 | on.exit(sink()) 7 | } 8 | vals = paste0(def@values, "L") 9 | vals[is.na(def@values)] = NA 10 | cat(paste(paste0("`", names(def@values), "`"), vals, sep = ' = '), sep = "\n") 11 | cat("\n\n\n", paste0("`", name, "`"), " = ") 12 | dput(def@values) 13 | cat("\n\n##########################\n\n") 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Updating/UpdateLLVMVersion: -------------------------------------------------------------------------------- 1 | When updating to a new version of LLVM, you should verify that the enumerated constants 2 | in the R code still correspond correctly to those in the LLVM header files. 3 | AttrKind is the one that has changed most often. 4 | Update the definition of LLVMAttributes (and FuncAttributes) in Function.R. 5 | Use the R commands in TU/enums.R (not in inst/TU/) 6 | 7 | 8 | 9 | converters.cpp 10 | metadata.cpp - activate getting names again! 11 | 12 | [Test] Target.cpp - ifdef'ed out the R_TargetMachine_getDataLayout() routine. Can get it from the Module, but not the target machine anymore. 13 | [Test] IRBuilder.cpp 14 | [Test] Module.cpp 15 | [Test] ostream.cpp 16 | [Test] ExecEngine.cpp - can we create a correct std::unique_ptr from R reference? 17 | 18 | Test the handling of .get() for the std::unique_ptr<>. Do we still own it at the end or is it released?????? 19 | Test the error in ostream - treating as bool - do we get use !err or err? 20 | -------------------------------------------------------------------------------- /Web/GNUmakefile: -------------------------------------------------------------------------------- 1 | PKG=Rllvm 2 | WEB_DIR=www.omegahat.org:~/OmegaWeb/$(PKG) 3 | 4 | 5 | shipIndex: index.html extra 6 | # $(MAKE) -C ../inst/doc ship 7 | scp index.html $(WEB_DIR)/index.html 8 | 9 | extra: 10 | -scp ../Changes.html ../FAQ.html $(WEB_DIR) 11 | 12 | indexInstall indexOnly: index.html 13 | scp index.html $(WEB_DIR)/ 14 | 15 | 16 | html: 17 | if ! test -d Temp ; then mkdir Temp ; fi 18 | R CMD INSTALL -l Temp .. 19 | cp -r Temp/$(PKG)/html . 20 | rm -fr Temp 21 | 22 | index.html: index.html.in configure ../DESCRIPTION 23 | @echo "Running configure to create index.html" 24 | ./configure 25 | 26 | configure: configure.in 27 | autoconf 28 | 29 | 30 | %.html: %.xml 31 | $(MAKE) -C $(@D) $(@F) 32 | 33 | -------------------------------------------------------------------------------- /Web/configure.in: -------------------------------------------------------------------------------- 1 | AC_INIT(index.html.in) 2 | 3 | DESC=../DESCRIPTION 4 | 5 | PKG_NAME=`cat $DESC | grep Package | sed -e 's/.*: //'` 6 | VERSION=`cat $DESC | grep Version | sed -e 's/.*: //'` 7 | 8 | TAR_FILE="${PKG_NAME}_${VERSION}.tar.gz" 9 | 10 | AC_SUBST(PKG_NAME) 11 | AC_SUBST(VERSION) 12 | AC_SUBST(TAR_FILE) 13 | 14 | 15 | DATE=`date "+%d %b %Y"` 16 | AC_SUBST(DATE) 17 | 18 | AC_OUTPUT(index.html) -------------------------------------------------------------------------------- /attribMechanism.cc: -------------------------------------------------------------------------------- 1 | #define GET_ATTR_NAMES 2 | #define ATTRIBUTE_ENUM(A, B) n++; 3 | 4 | int main(int argc, char *argv[]) { 5 | int n = 0; 6 | #include 7 | return(n); 8 | } 9 | -------------------------------------------------------------------------------- /cleanup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | rm src/Makevars 4 | rm R/targets.R R/llvmVersion.R 5 | -------------------------------------------------------------------------------- /configurations/Makefile: -------------------------------------------------------------------------------- 1 | v%: 2 | (export PATH=$(HOME)/LLVM/local_$@/bin:$(PATH); cd ..; R CMD configure > configurations/$@) -------------------------------------------------------------------------------- /ctests/GNUmakefile: -------------------------------------------------------------------------------- 1 | 2 | parms: 3 | $(CXX) -g parms.cc `llvm-config --cxxflags --ldflags --libs core` -o $@ 4 | 5 | 6 | include ../inst/IR/GNUmakefile 7 | -------------------------------------------------------------------------------- /ctests/globalStringAccess.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char *str = "This is the string"; 4 | 5 | 6 | const char * 7 | foo() 8 | { 9 | const char *p = str; 10 | return(p); 11 | } 12 | 13 | int 14 | main(int argc, char *argv[]) 15 | { 16 | printf("str = %s\n", str); 17 | printf("foo() = %s\n", foo()); 18 | return(0); 19 | } 20 | -------------------------------------------------------------------------------- /experiments/GNUmakefile: -------------------------------------------------------------------------------- 1 | ifndef CLANG 2 | CLANG=clang 3 | endif 4 | 5 | CC=llvm-gcc 6 | CC=$(CLANG) 7 | 8 | %.bc: %.c 9 | $(CC) $(OPT_LEVEL) -emit-llvm $< -c -o $@ 10 | 11 | %.llcpp: %.bc 12 | llc -march=cpp $< -o $@ 13 | 14 | %.llcpp: %.ll 15 | llc -march=cpp $< -o $@ 16 | 17 | %.ll: %.c GNUmakefile 18 | $(CLANG) $(OPT_LEVEL) $(CFLAGS) -S -emit-llvm -o $@ $< 19 | 20 | %.bc: %.ll 21 | llvm-as $< 22 | 23 | stress.ll: 24 | llvm-stress > $@ 25 | 26 | 27 | 28 | %.tu: %.c 29 | gcc $(CFLAGS) -fdump-translation-unit -c -o /dev/null $< 30 | 31 | 32 | RDB_TARGETS=$(wildcard *.Rdb) 33 | HTML_TARGETS=$(patsubst %.Rdb,%.html,$(RDB_TARGETS)) 34 | html: $(HTML_TARGETS) 35 | 36 | ifndef XDYN_DOCS 37 | XDYN_DOCS=$(HOME)/Classes/StatComputing/XDynDocs/inst 38 | endif 39 | 40 | %.html: %.Rdb 41 | $(MAKE) -f $(XDYN_DOCS)/Make/Makefile $@ 42 | 43 | cleanHTML: 44 | -rm $(HTML_TARGETS) 45 | -------------------------------------------------------------------------------- /experiments/add.c: -------------------------------------------------------------------------------- 1 | int 2 | foo(int x, int y) 3 | { 4 | int tmp = x + y; 5 | return(tmp); 6 | } 7 | 8 | 9 | double 10 | bar(double w, int x, int y, double z) 11 | { 12 | return( w + x + y + z); 13 | } 14 | -------------------------------------------------------------------------------- /experiments/add.s: -------------------------------------------------------------------------------- 1 | .section __TEXT,__text,regular,pure_instructions 2 | .globl _foo 3 | .align 4, 0x90 4 | _foo: ## @foo 5 | ## BB#0: ## %entry 6 | movl %edi, %eax 7 | addl %esi, %eax 8 | ret 9 | 10 | 11 | .subsections_via_symbols 12 | -------------------------------------------------------------------------------- /experiments/add1.c: -------------------------------------------------------------------------------- 1 | int 2 | foo(int x, int y) 3 | { 4 | int tmp = x + y; 5 | // int a = 1; 6 | // tmp = x + 1; 7 | return(tmp); 8 | } 9 | -------------------------------------------------------------------------------- /experiments/and.c: -------------------------------------------------------------------------------- 1 | int 2 | foo(int x, int y) 3 | { 4 | return(x < y && x > y/2); 5 | } 6 | -------------------------------------------------------------------------------- /experiments/array.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m = parseIR("array.ll") 4 | ee = ExecutionEngine(m) 5 | 6 | .llvm(m$foo, .ee = ee) 7 | 8 | m[["g", ee = ee]] 9 | 10 | .llvm(m$get, .ee = ee) 11 | -------------------------------------------------------------------------------- /experiments/array.c: -------------------------------------------------------------------------------- 1 | int g[100]; 2 | int ctr = 0; 3 | 4 | int 5 | get() 6 | { 7 | return(g[2]); 8 | } 9 | 10 | void 11 | bar() 12 | { 13 | g[ctr] = ctr; 14 | } 15 | 16 | void 17 | foo() 18 | { 19 | for(int i = 0; i < 100; i++) 20 | g[i] = i; 21 | } 22 | -------------------------------------------------------------------------------- /experiments/charType.c: -------------------------------------------------------------------------------- 1 | int getLevel(char *token) 2 | { 3 | if(token[0] == 'z') 4 | return(5L); 5 | 6 | if(token[0] == 'b') { 7 | if(token[2] == 'b') 8 | return(1L); 9 | else 10 | return(2L); 11 | } else if(token[0] == 'a') { 12 | return(3L); 13 | } else 14 | return(4L); 15 | } 16 | -------------------------------------------------------------------------------- /experiments/conditions.c: -------------------------------------------------------------------------------- 1 | int foo(int x, int y) 2 | { 3 | if(x < -9 || y > 5 || x + y == 3) 4 | return(101L); 5 | else 6 | return(201L); 7 | } 8 | -------------------------------------------------------------------------------- /experiments/constFold.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const double pi = 3.14145; 4 | void 5 | foo(double *x, int len, double *ans) 6 | { 7 | int i; 8 | for(i = 0; i < len; i++) 9 | ans[i] = sin(2 * pi * x[i]); 10 | } 11 | -------------------------------------------------------------------------------- /experiments/createLoop.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | createLoop = 4 | # 5 | # This takes a variable, a length variable and builds a loop. 6 | # 7 | # 8 | function(var, len, body, fun, ir = IRBuilder(), module = NULL) 9 | { 10 | entry = Block(fun, "entry") 11 | cond = Block(fun, "cond") 12 | body = Block(fun, "body") 13 | 14 | ir$setEntryPoint(entry) 15 | iv = ir$createLocalVariable(Int32Type, "i") 16 | len = ir$createLocalVariable(Int32Type, "len") 17 | ir$createStore(0L, iv) 18 | 19 | #XX where does len come from 20 | len.ref = params$len 21 | 22 | a = ir$createLoad(iv) 23 | b = ir$createLoad(len.ref) 24 | ok = ir$createICmp(ICMP_SLT, a, b) 25 | ir$createCondBr(ok, body, ret) 26 | 27 | } 28 | -------------------------------------------------------------------------------- /experiments/emptyStruct.c: -------------------------------------------------------------------------------- 1 | typedef struct _Foo {} Foo; 2 | 3 | void 4 | bar() 5 | { 6 | Foo a[3]; 7 | a[0]; 8 | } 9 | -------------------------------------------------------------------------------- /experiments/fgets.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | char p[1000]; 5 | 6 | char * 7 | Fgets(FILE *f) 8 | { 9 | fgets(p, 1000, f); 10 | return(p); 11 | } 12 | 13 | 14 | int 15 | main(int argc, char *argv[]) 16 | { 17 | FILE *f = fopen(argv[1], "r"); 18 | if(!f) 19 | return(1); 20 | 21 | int i; 22 | for(i = 0 ; i < 5; i++) 23 | fprintf(stderr, "%s", Fgets(f)); 24 | 25 | return(0); 26 | } 27 | -------------------------------------------------------------------------------- /experiments/fib.c: -------------------------------------------------------------------------------- 1 | //int fib(int); 2 | 3 | int fib(int n) { 4 | return n < 2 ? n : fib(n-1) + fib(n-2); 5 | } 6 | 7 | int fib1(int n) { 8 | if(n == 0 || n == 1) 9 | return n; 10 | 11 | return fib1(n-1) + fib1(n-2); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /experiments/funcPointer.c: -------------------------------------------------------------------------------- 1 | typedef double (*Metric)(double *x, double *y, int p, int stride); 2 | 3 | double 4 | foo(Metric func) 5 | { 6 | double x[10*20]; 7 | return(func(x, x + 1, 10, 20)); 8 | } 9 | -------------------------------------------------------------------------------- /experiments/functionPointer.c: -------------------------------------------------------------------------------- 1 | typedef int (*Foo)(double x); 2 | 3 | double 4 | bar(double *x, int n, Foo fun) 5 | { 6 | double total = 0; 7 | for(int i = 0; i < n; i++) 8 | total += fun(x[i]); 9 | return(total); 10 | } 11 | -------------------------------------------------------------------------------- /experiments/functionPointer_show.c: -------------------------------------------------------------------------------- 1 | 2 | double 3 | test(double x) 4 | { 5 | return(3.0 * x); 6 | } 7 | -------------------------------------------------------------------------------- /experiments/global.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | SEXP ans; 5 | 6 | void 7 | init(int n) 8 | { 9 | ans = NEW_CHARACTER(n); 10 | R_PreserveObject(ans); 11 | } 12 | -------------------------------------------------------------------------------- /experiments/neg.c: -------------------------------------------------------------------------------- 1 | int 2 | foo() 3 | { 4 | int x = -1; 5 | return(x); 6 | } 7 | -------------------------------------------------------------------------------- /experiments/not.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/experiments/not.bc -------------------------------------------------------------------------------- /experiments/not.c: -------------------------------------------------------------------------------- 1 | int 2 | foo(int z) 3 | { 4 | return(!z); 5 | } 6 | -------------------------------------------------------------------------------- /experiments/nullInit.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int *x = NULL; 4 | 5 | -------------------------------------------------------------------------------- /experiments/opaque.c: -------------------------------------------------------------------------------- 1 | typedef struct _Foo Foo; 2 | 3 | int bar(Foo *x); 4 | 5 | int 6 | foobar(Foo *x) 7 | { 8 | return(bar(x)); 9 | } 10 | 11 | 12 | Foo mkFoo(); 13 | 14 | void 15 | zzz() 16 | { 17 | Foo a[3]; 18 | 19 | a[0] = mkFoo(); 20 | } 21 | -------------------------------------------------------------------------------- /experiments/optimization.R: -------------------------------------------------------------------------------- 1 | # 2 | # The idea here is to see if the llvm optimization step 3 | # will do constand folding, avoid unnecessary assignments 4 | # etc. 5 | 6 | # We'll compile Vince's example of 7 | # 8 | function(x, y) 9 | { 10 | tmp = x + y 11 | return(tmp) 12 | } 13 | 14 | # So we will compile this ourselves and then look at the resulting 15 | # code. 16 | 17 | library(Rllvm) 18 | InitializeNativeTarget() 19 | 20 | mod = Module("opt") 21 | fun = Function("iadd", Int32Type, c(x = Int32Type, y = Int32Type), mod) 22 | params = getParameters(fun) 23 | entry = Block(fun, "entry") 24 | body = Block(fun, "body") 25 | 26 | ir = IRBuilder(entry) 27 | iv = ir$createLocalVariable(Int32Type, "tmp") 28 | ir$createBr(body) 29 | 30 | ir$setInsertPoint(body) 31 | # BinaryOps["Add"] 32 | val = ir$binOp(Add, params$x, params$y) 33 | ir$createReturn(val) 34 | 35 | showModule(mod, FALSE) 36 | 37 | verifyModule(mod) 38 | 39 | 40 | ee = ExecutionEngine(mod) 41 | Optimize(mod, ee) 42 | run(fun, x = 4L, y = 10L, .ee = ee) 43 | 44 | cat("After optimization\n") 45 | showModule(mod, FALSE) 46 | 47 | 48 | -------------------------------------------------------------------------------- /experiments/pointerArith.c: -------------------------------------------------------------------------------- 1 | 2 | int * 3 | foo(int *x, int i) 4 | { 5 | return(x + i); 6 | } 7 | 8 | -------------------------------------------------------------------------------- /experiments/simpleIf.c: -------------------------------------------------------------------------------- 1 | unsigned int getThreadID(); 2 | 3 | void 4 | foo(unsigned int N, int *x) 5 | { 6 | unsigned int i = getThreadID(); 7 | if(i < N) 8 | x[i] = i; 9 | } 10 | -------------------------------------------------------------------------------- /experiments/simpleSet.c: -------------------------------------------------------------------------------- 1 | void 2 | foo(int *out) 3 | { 4 | int i = 0; 5 | out[i] = 1; 6 | } 7 | -------------------------------------------------------------------------------- /experiments/simpleStruct.c: -------------------------------------------------------------------------------- 1 | struct Foo { 2 | int i; 3 | double d; 4 | }; 5 | 6 | int foo(struct Foo f) 7 | { 8 | return(f.i); 9 | } 10 | 11 | int bar(struct Foo f, struct Foo g) 12 | { 13 | return(f.i + g.i); 14 | } 15 | 16 | int x(struct Foo *f) 17 | { 18 | return(f->i); 19 | } 20 | 21 | int y(struct Foo f) 22 | { 23 | struct Foo *p; 24 | p = &f; 25 | return(p->i); 26 | } 27 | -------------------------------------------------------------------------------- /experiments/strcmp.c: -------------------------------------------------------------------------------- 1 | #include 2 | int 3 | foo(char *str) 4 | { 5 | return( strcmp(str, "bob") == 0 ); 6 | } 7 | -------------------------------------------------------------------------------- /experiments/struct.c: -------------------------------------------------------------------------------- 1 | 2 | typedef struct { 3 | char c; 4 | int i; 5 | double d; 6 | double vals[10]; 7 | } Foo; 8 | 9 | Foo g; 10 | 11 | Foo 12 | foo(int i, double d) 13 | { 14 | Foo f; 15 | f.i = i; 16 | f.d = d; 17 | f.vals[0] = d; 18 | return(f); 19 | } 20 | 21 | void 22 | global() 23 | { 24 | g.i = 7; 25 | } 26 | -------------------------------------------------------------------------------- /experiments/struct2.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = parseIR("struct2.ll") 3 | foo = getParameters(m$foo)[[1]] 4 | 5 | ty = getType(foo) 6 | 7 | stopifnot(class(ty) == "PointerType") 8 | 9 | fs = getElementType(ty) 10 | stopifnot(class(fs) == "StructType") 11 | 12 | fields = getFields(fs) 13 | 14 | stopifnot(all(sapply(fields, class) != "Type")) 15 | 16 | class(getElementType(fields[[3]])) 17 | 18 | 19 | p = getParameters(getElementType(fields[[4]])) 20 | sapply(p, class) 21 | 22 | 23 | 24 | stopifnot(class(getReturnType(m$mkFoo2)) != "Type") 25 | -------------------------------------------------------------------------------- /experiments/struct2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct Foo { 4 | 5 | int i; 6 | double d; 7 | int (*fi)(int, int); 8 | double (*fd)(double, double (*f)(double, double )); 9 | } Foo; 10 | 11 | 12 | int 13 | foo(Foo *x) 14 | { 15 | x->fd(3, NULL); 16 | return(0); 17 | } 18 | 19 | 20 | int 21 | p(int x, int y) 22 | { 23 | return(x + y); 24 | } 25 | 26 | Foo 27 | mkFoo() 28 | { 29 | Foo f ; 30 | f.i = 2; 31 | f.d = 3.1415; 32 | f.fi = p; 33 | 34 | return(f); 35 | } 36 | 37 | Foo * 38 | mkFoo2() 39 | { 40 | Foo *f = (Foo *) calloc(1, sizeof(Foo)); 41 | f->i = 2; 42 | f->d = 3.1415; 43 | f->fi = p; 44 | 45 | return(f); 46 | } 47 | -------------------------------------------------------------------------------- /experiments/structCall.c: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | int i; 3 | double d; 4 | } CXCursor; 5 | 6 | typedef struct { 7 | int i[10]; 8 | CXCursor cur; 9 | double d; 10 | } Tmp; 11 | 12 | typedef struct { 13 | char c1; 14 | char c2; 15 | short s; 16 | int i; 17 | double d; 18 | } Bar; 19 | 20 | 21 | 22 | void 23 | foo(Tmp t) 24 | { 25 | t.i[7] = 1; 26 | } 27 | 28 | Bar 29 | setBar(Bar b) 30 | { 31 | b.c1 = 0; 32 | return(b); 33 | } 34 | 35 | 36 | int bar(CXCursor b) 37 | { 38 | return(b.i); 39 | } 40 | 41 | int kind; 42 | 43 | int g(CXCursor *b) 44 | { 45 | kind = b->i; 46 | return(kind); 47 | } 48 | 49 | double f(CXCursor *b) 50 | { 51 | double k; 52 | k = b->d; 53 | return(2 * k); 54 | } 55 | 56 | 57 | int Main() 58 | { 59 | CXCursor a; 60 | a.i = 0; 61 | a.d = 3.141539; 62 | a.d = f(&a); 63 | return(bar(a)); 64 | } 65 | 66 | 67 | int visitor(CXCursor cur, CXCursor parent) 68 | { 69 | bar(cur); 70 | return(0); 71 | } 72 | -------------------------------------------------------------------------------- /experiments/structPtr.c: -------------------------------------------------------------------------------- 1 | 2 | typedef struct { 3 | int i; 4 | double r; 5 | } DataStruct; 6 | 7 | int 8 | foo(DataStruct *s) 9 | { 10 | int i; 11 | i = s->i; 12 | return(i + 10); 13 | } 14 | 15 | int 16 | bar(void *p) 17 | { 18 | DataStruct *s = (DataStruct *) p; 19 | return(foo(s)); 20 | } 21 | -------------------------------------------------------------------------------- /experiments/threadStruct.c: -------------------------------------------------------------------------------- 1 | typedef double (*MetricFun)(double *x, double *y, int ncol, int stride); 2 | 3 | typedef struct { 4 | int start; 5 | int end; 6 | double *d; 7 | int d_nrow; 8 | int d_ncol; 9 | int N; 10 | double *ans; 11 | int ans_nrow; 12 | int ans_ncol; 13 | MetricFun metric; 14 | } ThreadInputs; 15 | 16 | void * 17 | threadFun(void *arg) 18 | { 19 | ThreadInputs *info = (ThreadInputs *) arg; 20 | 21 | int start = info->start; 22 | int end = info->end; 23 | 24 | double *d = info->d; 25 | int d_nrow = info->d_nrow; 26 | int d_ncol = info->d_ncol; 27 | int N = info->N; 28 | double *ans = info->ans; 29 | int ans_nrow = info->ans_nrow; 30 | int ans_col = info->ans_ncol; 31 | MetricFun metric = info->metric; 32 | 33 | int i, j; 34 | 35 | for(i = start; i < end; i++) 36 | for(j = 0 ; j < N; j++) 37 | ans[i + j * ans_nrow] = metric(d + i, d + j, d_ncol, d_nrow); 38 | 39 | return(0); 40 | } 41 | -------------------------------------------------------------------------------- /experiments/varArgFun.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void 5 | foo(int num, ...) 6 | { 7 | va_list ap; 8 | int val; 9 | printf("# arguments %d\n", num); 10 | 11 | va_start(ap, num); 12 | for(int i = 0; i < num; i++) { 13 | val = va_arg(ap, int); 14 | printf("%d) %d\n", i, val); 15 | } 16 | va_end(ap); 17 | } 18 | 19 | int 20 | main(int argc, char **argv) 21 | { 22 | foo(3, 1, 4, 19); 23 | return(0); 24 | } 25 | 26 | 27 | int 28 | bar(int x) 29 | { 30 | return(2*x); 31 | } 32 | -------------------------------------------------------------------------------- /experiments/varargs.R: -------------------------------------------------------------------------------- 1 | library(RLLVMCompile) 2 | mod = Module() 3 | 4 | f = function(i, real) 5 | printf("value: %d %lf %s\n", i, real, " 'a string'") 6 | 7 | pf = Function("printf", Int32Type, list(StringType), mod, varArgs = TRUE) 8 | 9 | fc = compileFunction(f, VoidType, list(Int32Type, DoubleType), module = mod) 10 | 11 | .llvm(fc, 42, pi) 12 | -------------------------------------------------------------------------------- /experiments/varargs.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void 4 | printInt(int i) 5 | { 6 | fprintf(stderr, "%d\n", i); 7 | } 8 | -------------------------------------------------------------------------------- /experiments/void.c: -------------------------------------------------------------------------------- 1 | void foo() 2 | { 3 | 4 | } 5 | 6 | -------------------------------------------------------------------------------- /experiments/voidPtr.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char s[1000]; 4 | void 5 | foo(char *x, int len) 6 | { 7 | memcpy(s, x, len); 8 | } 9 | -------------------------------------------------------------------------------- /experiments/whileReturn.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/experiments/whileReturn.bc -------------------------------------------------------------------------------- /experiments/whileReturn.c: -------------------------------------------------------------------------------- 1 | int 2 | foo(int len) 3 | { 4 | int a; 5 | while(len < 10) { 6 | a = a + 1; 7 | if(a > 5) 8 | return(a); 9 | } 10 | return(0); 11 | } 12 | -------------------------------------------------------------------------------- /explorations/EXAMPLES: -------------------------------------------------------------------------------- 1 | nsdistance 2 | iterators 3 | sampleCSV 4 | 5 | 6 | loop fusion/ReduceMap -------------------------------------------------------------------------------- /explorations/Fgets.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char * 4 | Fgets(FILE *src) 5 | { 6 | const int MAX_SIZE = 10000; 7 | char line[MAX_SIZE]; 8 | return(fgets(line, MAX_SIZE, src)); 9 | } 10 | -------------------------------------------------------------------------------- /explorations/GNUmakefile: -------------------------------------------------------------------------------- 1 | 2 | %.ir: %.c 3 | $(CC) $(CFLAGS) -S -emit-llvm $^ -o $@ -fno-discard-value-names 4 | 5 | %.ir: %.cpp 6 | $(CXX) $(CXXFLAGS) -S -emit-llvm $^ -o $@ -fno-discard-value-names -------------------------------------------------------------------------------- /explorations/HowToUseLLJIT/GNUmakefile: -------------------------------------------------------------------------------- 1 | foo: HowToUseLLJIT2.cpp 2 | clang++ -UUSE_R -o foo $^ `llvm-config --cflags --ldflags --libs Core OrcJIT Support nativecodegen --system-libs ` -lz 3 | 4 | foobar: twoModules.cpp 5 | clang++ -UUSE_R -o $@ $^ `llvm-config --cflags --ldflags --libs Core OrcJIT Support nativecodegen --system-libs ` -lz 6 | 7 | %: %.cpp 8 | clang++ -UUSE_R -o $@ $^ `llvm-config --cflags --ldflags --libs Core OrcJIT Support nativecodegen --system-libs ` -lz 9 | 10 | %.ir: %.c 11 | clang -S -emit-llvm -o $@ $< 12 | -------------------------------------------------------------------------------- /explorations/HowToUseLLJIT/Makevars: -------------------------------------------------------------------------------- 1 | PKG_CPPFLAGS=`llvm-config --cppflags` -DUSE_R=1 2 | PKG_CXXFLAGS=`llvm-config --cxxflags` 3 | PKG_LIBS=`llvm-config --ldflags --libs Core OrcJIT Support nativecodegen --system-libs ` -lz -------------------------------------------------------------------------------- /explorations/HowToUseLLJIT/README.md: -------------------------------------------------------------------------------- 1 | This is an exploration of how to get LLJIT working with two modules where one calls a routine in the 2 | other. We start with the example code in the LLVM source in llvm/examples/HowToUseLLJIT. 3 | This starts by building a simple Module in memory. 4 | We then adapt it incrementally to 5 | + load an IR file and call a routine 6 | + load two IR files and call a routine 7 | + separate the loading from calling the routine 8 | + separate creating the JIT, loading each file, and invoking the routine. 9 | 10 | The .cpp files are can basically be compiled as both stand-alone executables and R shared libraries 11 | that can be loaded into R. 12 | 13 | 14 | + `make name` to create the stand-alone named `name` 15 | + `R CMD SHLIB filename.cpp` to create the shared library for R. 16 | 17 | 18 | ``` 19 | make twoModules3 20 | ./twoModules3 foo.ir bar.ir 21 | ``` 22 | 23 | ``` 24 | R CMD SHLIB twoModules3.cpp 25 | R 26 | source("twoModules3.R") 27 | ``` 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /explorations/HowToUseLLJIT/bar.c: -------------------------------------------------------------------------------- 1 | int foo(); 2 | 3 | int 4 | bar() 5 | { 6 | return(foo()); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /explorations/HowToUseLLJIT/fib.c: -------------------------------------------------------------------------------- 1 | int 2 | fib(int n) 3 | { 4 | if(n < 2) 5 | return(n); 6 | 7 | return(fib(n - 1 ) + fib(n - 2)); 8 | } 9 | -------------------------------------------------------------------------------- /explorations/HowToUseLLJIT/foo.c: -------------------------------------------------------------------------------- 1 | int 2 | foo() 3 | { 4 | return(42); 5 | } 6 | -------------------------------------------------------------------------------- /explorations/HowToUseLLJIT/foo.ir: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'foo.c' 2 | source_filename = "foo.c" 3 | target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 4 | target triple = "x86_64-apple-macosx10.15.0" 5 | 6 | ; Function Attrs: noinline nounwind optnone ssp uwtable 7 | define i32 @foo() #0 { 8 | ret i32 42 9 | } 10 | 11 | attributes #0 = { noinline nounwind optnone ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } 12 | 13 | !llvm.module.flags = !{!0, !1} 14 | !llvm.ident = !{!2} 15 | 16 | !0 = !{i32 1, !"wchar_size", i32 4} 17 | !1 = !{i32 7, !"PIC Level", i32 2} 18 | !2 = !{!"clang version 11.0.0"} 19 | -------------------------------------------------------------------------------- /explorations/HowToUseLLJIT/objectFiles.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | jit = lljit() 4 | 5 | # clang -c foo.c 6 | # clang -c bar.c 7 | .Call("R_LLJIT_addObjectFile", jit, "foo.o") 8 | .Call("R_LLJIT_addObjectFile", jit, "bar.o") 9 | 10 | bar = jitLookup(jit, "bar") 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /explorations/HowToUseLLJIT/rlljit.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | setClass("LLJIT", contains = "RC++Reference") 4 | jit = .Call("R_LLJIT_create") 5 | 6 | mfoo = parseIR("foo.ir") 7 | .Call("R_LLJIT_addModule", jit, mfoo, NULL) 8 | 9 | 10 | .Call("R_LLJIT_addModule", jit, parseIR("fib.ir"), NULL) 11 | 12 | fib = .Call("R_LLJIT_lookup", jit, "fib") 13 | foo = .Call("R_LLJIT_lookup", jit, "foo") 14 | 15 | library(Rffi) 16 | fib.ans = callCIF(CIF(sint32Type, list(sint32Type)), fib@ref, 12L) 17 | 18 | foo.ans = callCIF(CIF(sint32Type, list()), foo@ref) 19 | 20 | 21 | if(FALSE) { 22 | mbar = parseIR("bar.ir") 23 | .Call("R_LLJIT_addModule", jit, mbar, NULL) 24 | 25 | bar1 = .Call("R_LLJIT_lookup", jit, "bar") 26 | 27 | bar.ans = callCIF(CIF(sint32Type, list()), bar1@ref) 28 | } 29 | -------------------------------------------------------------------------------- /explorations/HowToUseLLJIT/run.R: -------------------------------------------------------------------------------- 1 | # No need for library(Rllvm) 2 | dyn.load("HowToUseLLJIT2.so") 3 | .Call("R_loadAndCall", "fib.ir", 12L) 4 | 5 | -------------------------------------------------------------------------------- /explorations/HowToUseLLJIT/run2.R: -------------------------------------------------------------------------------- 1 | dyn.load("twoModules.so") 2 | .Call("R_loadAndCall", "foo.ir", "bar.ir") 3 | -------------------------------------------------------------------------------- /explorations/HowToUseLLJIT/twoModules2.R: -------------------------------------------------------------------------------- 1 | dyn.load("twoModules2.so") 2 | ans = .Call("R_loadAndCall", c("foo.ir", "bar.ir")) 3 | 4 | -------------------------------------------------------------------------------- /explorations/HowToUseLLJIT/twoModules3.R: -------------------------------------------------------------------------------- 1 | dyn.load("twoModules3.so") 2 | 3 | .C("setup") 4 | 5 | jit = .Call("R_mkJIT") 6 | .Call("R_loadModule", jit, "foo.ir") 7 | .Call("R_loadModule", jit, "bar.ir") 8 | 9 | bar = .Call("R_lookupSym", jit, "bar") 10 | 11 | library(Rffi) 12 | cif = CIF(sint32Type, list()) 13 | ans = callCIF(cif, bar) 14 | stopifnot(identical(ans, 42L)) 15 | 16 | -------------------------------------------------------------------------------- /explorations/MapReduce.R: -------------------------------------------------------------------------------- 1 | # Consider the likelihood calculation 2 | # prod(dnorm(x, mu, sigma)) 3 | # In theory, R might end up with 2 copies of x. 4 | # It doesn't, because prod is .Primtive and dnorm is an .External 5 | -------------------------------------------------------------------------------- /explorations/OpaquePointers/GNUmakefile: -------------------------------------------------------------------------------- 1 | opaqueTests.ir: opaqueTests.c 2 | R CMD make -f ../../inst/Make/IRMakefile opaqueTests.ir 3 | -------------------------------------------------------------------------------- /explorations/OpaquePointers/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | To create the IR code on my machine, I can use 4 | ``` 5 | make CC=/Users/duncan/LLVM/local_v18/bin/clang 6 | ``` 7 | 8 | If we don't set CC, we may get the system version of clang which may be 9 | sufficiently old that it supports typed pointers. 10 | 11 | 12 | -------------------------------------------------------------------------------- /explorations/OpaquePointers/opaqueExplore.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | ctxt = getGlobalContext(TRUE) 3 | m = parseIR("dnormLoop.ir", context = ctxt) 4 | p = getParameters(m$v_dnorm)[[1]] 5 | u = getAllUsers(p) 6 | 7 | # Seg fault if u[[1]][[1]] 8 | #ty = .Call("R_Value_getLoadStoreType", u[[1]][[2]]) # HalfTyID ?? 9 | 10 | gep = getAllUsers(getAllUsers(u[[1]][[2]])[[2]])[[1]] 11 | 12 | ty = .Call("R_GetElementPtrInst_getSourceElementType", gep) 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /explorations/ScalarRealCast.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | # Debugging scalar real and casting from i64 4 | ff = Function("dbl", REALSXPType, module = m) 5 | ir = IRBuilder(ff) 6 | # From getrusage. But not in the module yet 7 | v = ir$createCall(m$ru_maxrss) 8 | d = ir$createCast("SIToFP", v, DoubleType) 9 | ans = ir$createCall(m$Rf_ScalarReal, d) 10 | ir$createReturn(ans) 11 | -------------------------------------------------------------------------------- /explorations/WASMTest.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Look in the console for the result of the computation. 8 | 9 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /explorations/backend.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m = parseIR("fib.ll") 4 | 5 | showModule(m) 6 | 7 | -------------------------------------------------------------------------------- /explorations/castUp.c: -------------------------------------------------------------------------------- 1 | long 2 | foo(int x) 3 | { 4 | return( (long) x ); 5 | } 6 | -------------------------------------------------------------------------------- /explorations/class.cpp: -------------------------------------------------------------------------------- 1 | const double pi = 3.14159; 2 | 3 | class Shape { 4 | protected: 5 | int x, y; 6 | public: 7 | // virtual void draw(); 8 | void move(int nx, int ny) { x = nx; y = ny;}; 9 | virtual double area(); 10 | Shape(int x, int y) : x(x), y(y) {}; 11 | }; 12 | 13 | class Circle: public Shape { 14 | protected: 15 | int radius; 16 | public: 17 | 18 | Circle(int x, int y, int r) : Shape(x, y), radius(r) {} 19 | 20 | double area() { 21 | return(pi * radius * radius); 22 | } 23 | }; 24 | 25 | 26 | class Rectangle: public Shape { 27 | protected: 28 | int w, h; 29 | public: 30 | 31 | Rectangle(int x, int y, int w, int h) : Shape(x, y), w(w), h(h) {} 32 | 33 | double area() { 34 | return(w * h); 35 | } 36 | }; 37 | 38 | double 39 | doit() 40 | { 41 | Rectangle r(1, 2, 4, 8); 42 | Circle c(10, 20, 10); 43 | 44 | double a; 45 | a = c.area(); 46 | a = r.area(); 47 | 48 | return(a); 49 | } 50 | -------------------------------------------------------------------------------- /explorations/const.c: -------------------------------------------------------------------------------- 1 | 2 | const char * 3 | foo(const double *x, int n) 4 | { 5 | double total = 0.; 6 | for(int i = 0; i < n; i++) 7 | total += x[i]; 8 | 9 | return("foo"); 10 | } 11 | -------------------------------------------------------------------------------- /explorations/constArg.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m = Module() 4 | f = Function("foo", Int32Type, list(pointerType(DoubleType), Int32Type), module = m) 5 | f[[1]] 6 | 7 | onlyReadsMemory(f[[1]]) 8 | setParamAttributes(f[[1]], LLVMAttributes["ReadOnly"]) 9 | onlyReadsMemory(f[[1]]) 10 | 11 | b = Block(f) 12 | ir = IRBuilder(b) 13 | #createRet(ir, createLoad(ir, f[[2]])) 14 | createRet(ir, createConstant(ir, 10L)) 15 | 16 | ir = showModule(m, TRUE) 17 | mm = parseIR(ir) 18 | onlyReadsMemory(mm$foo[[1]]) 19 | 20 | 21 | -------------------------------------------------------------------------------- /explorations/constArray.c: -------------------------------------------------------------------------------- 1 | 2 | int Ints[] = {1, 2, 3}; 3 | 4 | long Longs[] = {1, 2, 3}; 5 | 6 | double Reals[] = {1.5, 2.6, 3.7}; 7 | 8 | const double cReals[] = {10.5, 22.6, 23.7}; 9 | 10 | const char * const Strings[] = { "abc", "def", "xyz", "final"}; 11 | 12 | struct A { 13 | int i; 14 | double d; 15 | char *str; 16 | }; 17 | 18 | const struct A a[] = { 19 | {1, 1.5, "A"}, 20 | {2, 2.6, "BCD"} 21 | }; 22 | 23 | 24 | struct A b[] = { 25 | {11, 11.5, "xA"}, 26 | {21, 12.6, "xBCD"} 27 | }; 28 | 29 | const void *ptrs[] = {&a, &b, &Ints}; 30 | 31 | -------------------------------------------------------------------------------- /explorations/copyCrash.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | # Okay with -g or not 4 | irfile = "struct.ir" 5 | m = parseIR(irfile) 6 | m$declared2 = m$declared 7 | m$R_foo = m$foo 8 | 9 | # use a second module? 10 | m2 = Module() 11 | m2$R_foo = m$foo 12 | -------------------------------------------------------------------------------- /explorations/debugBreakpoint.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m = parseIR(system.file("IR", "fib.ll", package = "Rllvm")) 4 | 5 | ee = ExecutionEngine(m) 6 | ptr = getPointerToFunction(m$fib, ee) 7 | 8 | # Set break point. 9 | # Can we do it programmaticall !?? 10 | 11 | ptr@ref 12 | 13 | # break set -a 0x1008f6000 14 | 15 | .llvm(m$fib, 2, .ee = ee) 16 | # This will stop in the routine 3 times. 17 | 18 | .llvm(m$fib, 3, .ee = ee) 19 | # This will stop in the routine 5 times. 20 | -------------------------------------------------------------------------------- /explorations/distance.R: -------------------------------------------------------------------------------- 1 | Dist <- 2 | # 3 | # Compute the distance between two sets of observations 4 | # 5 | # Compile for numeric and integer inputs. 6 | # (Combinations of both?) 7 | # 8 | # We would like to use apply() so that we can parallelize 9 | # or outer(1:nrow(g1), 1:nrow(g2), f) to avoid building the 10 | # grid first but fusing the loops. 11 | # 12 | function(g1, g2, op = euclidean, ...) 13 | { 14 | ans <- matrix(0, nrow(g1), nrow(g2)) 15 | 16 | for(i in seq(length = nrow(g1))) 17 | for(j in seq(length = nrow(g2))) 18 | ans[i,j] <- op(g1[i,], g2[j,], ...) 19 | 20 | ans 21 | } 22 | 23 | 24 | 25 | euclidean <- 26 | function(x, y) 27 | sum((x - y)^2) 28 | -------------------------------------------------------------------------------- /explorations/distance.tm.8000:1000:40_Darwin.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/distance.tm.8000:1000:40_Darwin.rda -------------------------------------------------------------------------------- /explorations/distance.tm.8000:1000:40_jasper_Linux.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/distance.tm.8000:1000:40_jasper_Linux.rda -------------------------------------------------------------------------------- /explorations/distance.tm.8000:1000:40_lipschitz_Linux.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/distance.tm.8000:1000:40_lipschitz_Linux.rda -------------------------------------------------------------------------------- /explorations/distance.tm.8000:1000:40_lipschitz_Linux_gcc.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/distance.tm.8000:1000:40_lipschitz_Linux_gcc.rda -------------------------------------------------------------------------------- /explorations/distance.tm.8000:3000:40_Darwin.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/distance.tm.8000:3000:40_Darwin.rda -------------------------------------------------------------------------------- /explorations/dnorm.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | mod = Module() 4 | f = Function("dnorm", DoubleType, list(x = DoubleType, mean = DoubleType, sd = DoubleType), module = mod) 5 | b = Block(f) 6 | ir = IRBuilder(b) 7 | 8 | params = getParameters(f) 9 | x = ir$createLoad(params[["x"]]) 10 | mean = ir$createLoad(params$mean) 11 | 12 | 13 | -------------------------------------------------------------------------------- /explorations/dnorm.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | double 4 | dnorm(double x, double mean, double sd) 5 | { 6 | double tmp = (x - mean)/sd; 7 | tmp = tmp * tmp; 8 | return(1.0/(sd * 2.506628274631) * exp( - .5 * tmp)); 9 | } 10 | -------------------------------------------------------------------------------- /explorations/dnormLoop.c: -------------------------------------------------------------------------------- 1 | #include "dnorm.c" 2 | 3 | void 4 | v_dnorm(double *x, int n, double mu, double sd) 5 | { 6 | int i; 7 | for(i = 0; i < n; i++) { 8 | x[i] = dnorm(x[i], mu, sd); 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /explorations/doubleArray.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void 4 | foo(double *x, double y) 5 | { 6 | int ctr = 0; 7 | x[ctr] = sqrt(y); 8 | } 9 | -------------------------------------------------------------------------------- /explorations/execEng.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = parseIR(system.file("IR", "fib.ll", package = 'Rllvm')) 3 | 4 | ee = ExecutionEngine(m) 5 | 6 | addr = getFunctionAddress("fib", ee) 7 | x = getGlobalValueAtAddress(ee, addr) 8 | 9 | -------------------------------------------------------------------------------- /explorations/expandGrid.R: -------------------------------------------------------------------------------- 1 | # The idea here is to merge 2 | # apply(expand.grid(), 1, f) 3 | # so that we don't build the actual grid in memory and then apply 4 | # the function but fuse the two and avoid the overhead of memory 5 | -------------------------------------------------------------------------------- /explorations/fib.c: -------------------------------------------------------------------------------- 1 | int 2 | fib(int n) 3 | { 4 | if(n == 0 || n == 1) 5 | return(n); 6 | 7 | return(fib(n - 1) + fib(n - 2)); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /explorations/fib.tm.30_Darwin.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/fib.tm.30_Darwin.rda -------------------------------------------------------------------------------- /explorations/fib.tm.30_jasper_Linux.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/fib.tm.30_jasper_Linux.rda -------------------------------------------------------------------------------- /explorations/fib.tm.30_lipschitz_Linux.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/fib.tm.30_lipschitz_Linux.rda -------------------------------------------------------------------------------- /explorations/fib.tm.30_lipschitz_Linux_gcc.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/fib.tm.30_lipschitz_Linux_gcc.rda -------------------------------------------------------------------------------- /explorations/foo.c: -------------------------------------------------------------------------------- 1 | 2 | int 3 | foo() 4 | { 5 | return(20); 6 | } 7 | 8 | 9 | int 10 | bar(int x) 11 | { 12 | int a = 2*x; 13 | return(a); 14 | } 15 | -------------------------------------------------------------------------------- /explorations/fopen.R: -------------------------------------------------------------------------------- 1 | library(RLLVMCompile) 2 | 3 | mod = Module() 4 | FILEType = pointerType(structType(list(o=Int32Type))) # an opaque struct type? 5 | 6 | fopen = Function("fopen", FILEType, list(StringType, StringType), module = mod) 7 | Fopen = function(file, mode) 8 | return(fopen(file, mode)) 9 | 10 | fc = compileFunction(Fopen, FILEType, list(StringType, StringType), module = mod) 11 | 12 | o = .llvm(fc, "tmp", "r") 13 | 14 | 15 | mod = Module() 16 | fopen = Function("fopen", FILEType, list(StringType, StringType), module = mod) 17 | fun = Function("Fopen", FILEType, list(file = StringType, mode = StringType), module = mod) 18 | b = Block(fun, "entry") 19 | ir = IRBuilder(b) 20 | #ans = ir$createLocalVariable(FILEType, "tmp") 21 | params = getParameters(fun) 22 | tmp = ir$createCall(fopen, params[[1]], params[[2]]) 23 | #ir$createStore(tmp, ans) 24 | #ans = ir$createLoad(ans) 25 | #ir$createRet(ans) 26 | ir$createRet(tmp) 27 | -------------------------------------------------------------------------------- /explorations/fopen.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | FILE * 4 | Fopen(const char *f, const char *mode) 5 | { 6 | FILE *tmp; 7 | tmp = fopen(f, mode); 8 | return(tmp); 9 | } 10 | -------------------------------------------------------------------------------- /explorations/fuseLoop.tm.1e+06_Darwin.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/fuseLoop.tm.1e+06_Darwin.rda -------------------------------------------------------------------------------- /explorations/fuseLoop.tm.1e+07_Darwin.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/fuseLoop.tm.1e+07_Darwin.rda -------------------------------------------------------------------------------- /explorations/fuseLoop.tm.1e+07_jasper_Linux.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/fuseLoop.tm.1e+07_jasper_Linux.rda -------------------------------------------------------------------------------- /explorations/fuseLoop.tm.1e+07_lipschitz_Linux.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/fuseLoop.tm.1e+07_lipschitz_Linux.rda -------------------------------------------------------------------------------- /explorations/fuseLoop.tm.1e+07_lipschitz_Linux_gcc.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/fuseLoop.tm.1e+07_lipschitz_Linux_gcc.rda -------------------------------------------------------------------------------- /explorations/fuseLoop.tm.1e+08_Darwin.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/fuseLoop.tm.1e+08_Darwin.rda -------------------------------------------------------------------------------- /explorations/fuseLoop_osx.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/fuseLoop_osx.rda -------------------------------------------------------------------------------- /explorations/gfgets.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char *p; 4 | void 5 | Fgets(FILE *f) 6 | { 7 | fgets(p, 100, f); 8 | } 9 | -------------------------------------------------------------------------------- /explorations/globalString.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m = parseIR("globalString.ll") 4 | ee = ExecutionEngine(m) 5 | 6 | .llvm(m[["getStr2"]], .ee = ee) 7 | .llvm(m[["getStr1"]], .ee = ee) 8 | 9 | .llvm(m[["setStr1"]], .ee = ee) 10 | .llvm(m[["getStr1"]], .ee = ee) 11 | 12 | getGlobalValue(m[["str2_a"]], ee) # works commit: af18e6119 13 | getGlobalValue(m[["str1_p"]], ee) # works now 14 | 15 | names(m) 16 | m[["str1"]] 17 | # works. 18 | getGlobalValue(m[["pi"]], ee) 19 | getGlobalValue(m[["i"]], ee) 20 | getGlobalValue(m[["f"]], ee) 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /explorations/globalString.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char *str1_p = "This is a string"; 4 | char str2_a[] = "So is this"; 5 | char str3_a_noinit[99]; 6 | 7 | double pi = 3.141593; 8 | int i = 97; 9 | float f = 34.5; 10 | 11 | 12 | int 13 | getLen1() 14 | { 15 | return(strlen(str1_p)); 16 | } 17 | 18 | int 19 | getLen2() 20 | { 21 | return(strlen(str2_a)); 22 | } 23 | 24 | const char * const 25 | getStr2() 26 | { 27 | return(str2_a); 28 | } 29 | 30 | const char * const 31 | getStr1() 32 | { 33 | return(str1_p); 34 | } 35 | 36 | void 37 | setStr1() 38 | { 39 | str1_p = strdup("A replacement string"); 40 | } 41 | -------------------------------------------------------------------------------- /explorations/globalStringVar.c: -------------------------------------------------------------------------------- 1 | 2 | char *str = "this is a string"; 3 | char **ptr = &str; 4 | 5 | char * 6 | getStr() 7 | { 8 | return(str); 9 | } 10 | 11 | #include 12 | 13 | char * 14 | Fgets(FILE *f) 15 | { 16 | return(fgets(str, 10, f)); 17 | } 18 | -------------------------------------------------------------------------------- /explorations/indirectWriteParam.c: -------------------------------------------------------------------------------- 1 | 2 | int 3 | bar(int *x, int *y, int len) 4 | { 5 | int total = 0; 6 | for(int i = 0; i < len; i++) { 7 | x[i] = (x[i]* y[i]); 8 | total += x[i]; 9 | } 10 | return(total); 11 | } 12 | 13 | int 14 | foo(int *x, int *y, int len) 15 | { 16 | int val = bar(x, y, len); 17 | return(x[0] + y[0] + val); 18 | } 19 | 20 | int 21 | foo2(int *x, int *y, int len) 22 | { 23 | int val = bar(y, x, len); 24 | return(x[0] + y[0] + val); 25 | } 26 | 27 | int 28 | foo3(int *x, int *y, int len) 29 | { 30 | int val; 31 | if(len < 10) 32 | val = bar(y, x, len); 33 | else 34 | val = bar(x, y, len); 35 | 36 | return(x[0] + y[0] + val); 37 | } 38 | -------------------------------------------------------------------------------- /explorations/insertArray.c: -------------------------------------------------------------------------------- 1 | void 2 | foo(double *x, double y) 3 | { 4 | int ctr = 0; 5 | x[ctr] = y; 6 | } 7 | -------------------------------------------------------------------------------- /explorations/insertPointOddity.R: -------------------------------------------------------------------------------- 1 | # clang -O2 -S -emit-llvm -o foo.ir foo.c 2 | library(Rllvm) 3 | 4 | m = parseIR("foo.ir") 5 | b = getBlocks(m$foo)[[1]] 6 | trm = getTerminator(b) 7 | removeFromParent(trm) 8 | 9 | ir = IRBuilder(m$foo) 10 | ir$createReturn(ir$createConstant(10L)) 11 | llvmDump(m$foo) 12 | #### 13 | 14 | m = parseIR("foo.ir") 15 | b = getBlocks(m$bar)[[1]] 16 | trm = getTerminator(b) 17 | removeFromParent(trm) 18 | 19 | ir = IRBuilder(m$bar) 20 | ir$createReturn(ir$createConstant(10L)) 21 | llvmDump(m$bar) 22 | 23 | -------------------------------------------------------------------------------- /explorations/iterators.R: -------------------------------------------------------------------------------- 1 | # When we do not want to create an entire vector but still want 2 | # to iterate over it, we have difficulties in R. 3 | # We could partition it into blocks stored as elements in a list. 4 | # 5 | # Like AltRep example or Haskell's lazy sequence. 6 | # 7 | # We would like to have the efficiency of iterators where we can loop 8 | # over the elements readily. 9 | # sum(seq(1, n)) 10 | # 11 | # Similarly, mean(rnorm(n)) 12 | # 13 | 14 | -------------------------------------------------------------------------------- /explorations/lazyCompile.R: -------------------------------------------------------------------------------- 1 | # Exploring lazy compilation. 2 | # The MCJIT doesn't do lazy compilation of Functions. So this won't work. 3 | library(Rllvm) 4 | 5 | source("undefinedSymbols.R") 6 | 7 | ee = ExecutionEngine(m) 8 | isCompilingLazily(ee) 9 | DisableLazyCompilation(ee, FALSE) 10 | isCompilingLazily(ee) 11 | 12 | # Still crashes. 13 | debug(finalizeEngine) 14 | if(FALSE) { 15 | fun = getPointerToFunction(m$foo, ee, TRUE) 16 | cif = Rllvm:::genCIF(m$foo, REALSXPType) 17 | Rllvm:::.llvmFFI(fun@ref, list(), .ee = ee, cif = cif) 18 | } 19 | #.llvm(fun, .ee = ee) 20 | #.llvm(m$foo, .ee = ee) 21 | 22 | -------------------------------------------------------------------------------- /explorations/lljit.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | f = system.file("IR/fib.ll", package = "Rllvm") 3 | f = "fib.ir" 4 | m = parseIR(f) 5 | 6 | setClass("LLJIT", contains = "RC++Reference") 7 | jit = .Call("R_LLJIT_create") 8 | .Call("R_LLJIT_addModule", jit, m, NULL) 9 | 10 | fptr = .Call("R_LLJIT_lookup", jit, "fib") 11 | 12 | library(Rffi) 13 | cif = CIF(sint32Type, list(sint32Type)) 14 | ans = callCIF(cif, fptr@ref, 10L) 15 | stopifnot(identical(ans , 55L)) 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /explorations/lljit2.R: -------------------------------------------------------------------------------- 1 | 2 | # Testing a Module we create directly in the R session, 3 | # not a pre-made Module with clang -S -emit-llvm that we tested in lljit.R 4 | 5 | library(Rllvm) 6 | 7 | m1 = Module() 8 | foo = Function("foo", Int32Type, module = m1) 9 | ir = IRBuilder(foo) 10 | ir$createReturn(ir$createConstant(42L, Int32Type)) 11 | 12 | setClass("LLJIT", contains = "RC++Reference") 13 | jit = .Call("R_LLJIT_create") 14 | .Call("R_LLJIT_addModule", jit, m1, NULL) 15 | 16 | foo1 = .Call("R_LLJIT_lookup", jit, "foo") 17 | 18 | library(Rffi) 19 | cif = CIF(sint32Type, list()) 20 | ans = callCIF(cif, foo1@ref) 21 | stopifnot(identical(ans , 42L)) 22 | -------------------------------------------------------------------------------- /explorations/localStringVar.c: -------------------------------------------------------------------------------- 1 | #include 2 | int 3 | foo() 4 | { 5 | char *tmp = ""; 6 | return(strlen(tmp)); 7 | } 8 | -------------------------------------------------------------------------------- /explorations/loop.c: -------------------------------------------------------------------------------- 1 | 2 | void 3 | foo() 4 | { 5 | double x = 0; 6 | while(1) { 7 | x++; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /explorations/manualFib.R: -------------------------------------------------------------------------------- 1 | # This will segfault as it will recurse infinitely. 2 | # There is no if statement to return when we get to n = 1 or 2. 3 | 4 | library(Rllvm) 5 | #library(RLLVMCompile) 6 | 7 | mod = Module() 8 | f = Function("fib", Int32Type, list(n = Int32Type), mod) 9 | start = Block(f) 10 | ir = IRBuilder(start) 11 | parms = getParameters(f) 12 | n.sub.1 = binOp(ir, "Sub", parms$n, createConstant(ir, 1L)) 13 | createCall(ir, f, n.sub.1) 14 | createReturn(ir, parms$n) 15 | 16 | showModule(f) 17 | 18 | .llvm(f, 5) 19 | 20 | -------------------------------------------------------------------------------- /explorations/moduleSharingReference.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m2 = Module("A") 4 | sc = Function("Rf_ScalarReal", SEXPType, list(DoubleType), module = m2) 5 | 6 | m = Module() 7 | f = Function("foo", REALSXPType, module = m) 8 | ir = IRBuilder(f) 9 | 10 | obj = ir$createCall(sc, ir$createConstant(3.1415)) 11 | ir$createReturn(obj) 12 | 13 | verifyModule(m) 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /explorations/multiConditions.c: -------------------------------------------------------------------------------- 1 | int 2 | foo(int x, int y) 3 | { 4 | if( x < 0 && y > 0) 5 | return(1); 6 | else if(x < 0 && y == 0) 7 | return(0); 8 | else if(x > 0 && y < 0) 9 | return(3); 10 | else 11 | return(7); 12 | } 13 | 14 | int 15 | bar(int x) 16 | { 17 | if(x > 4 && x < 10) 18 | x = 3; 19 | 20 | return(x); 21 | } 22 | -------------------------------------------------------------------------------- /explorations/neg.c: -------------------------------------------------------------------------------- 1 | int 2 | foo(int n) 3 | { 4 | return( - n); 5 | } 6 | -------------------------------------------------------------------------------- /explorations/nestedStruct.c: -------------------------------------------------------------------------------- 1 | 2 | typedef struct A { 3 | int *vals; 4 | int len; 5 | } A; 6 | 7 | 8 | typedef struct LinkedListEl { 9 | double val; 10 | struct LinkedListEl *next; 11 | } LinkedListEl; 12 | 13 | typedef struct B { 14 | LinkedListEl *els; 15 | int numEls; 16 | #ifdef B_STATS 17 | double *statistics; // adding this to get 3 elements 18 | #endif 19 | } B; 20 | 21 | 22 | typedef struct C { 23 | double **buckets; 24 | int (*hash)(double x); 25 | #ifdef C_STATS 26 | double *statistics; 27 | #endif 28 | } C; 29 | 30 | 31 | 32 | typedef struct Container { 33 | int type; 34 | union { 35 | A a; 36 | B b; 37 | C c; 38 | } u; 39 | unsigned long count; 40 | } Container; 41 | 42 | 43 | 44 | double 45 | foo(Container z) 46 | { 47 | if(z.type == 0) 48 | return(z.u.a.vals[0]); 49 | else if(z.type == 1) 50 | return(z.u.b.els[0].val); 51 | 52 | int i = z.u.c.hash(10); 53 | return(z.u.c.buckets[ i ][0]); 54 | } 55 | -------------------------------------------------------------------------------- /explorations/phi.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void bar(int *x, double *y, double constant, int len) 4 | { 5 | for(int i = 0; i < len; i++) 6 | y[i] = y[i] + x[i]; 7 | } 8 | 9 | void 10 | foo(SEXP x, SEXP y, SEXP constant) 11 | { 12 | if(TYPEOF(x) == INTSXP) 13 | x = Rf_duplicate(x); 14 | else 15 | x = Rf_coerceVector(x, INTSXP); 16 | 17 | if(TYPEOF(y) == REALSXP) 18 | y = Rf_duplicate(y); 19 | else 20 | y = Rf_coerceVector(y, REALSXP); 21 | 22 | bar(INTEGER(x), REAL(y), asReal(constant), Rf_length(x)); 23 | } 24 | -------------------------------------------------------------------------------- /explorations/proxyEg.c: -------------------------------------------------------------------------------- 1 | //#include 2 | 3 | double 4 | foo(int *x, double *y, int len) 5 | { 6 | double total = 0.; 7 | 8 | for(int i = 0; i < len; i++) { 9 | total += (((double) x[i]) * y[i]); 10 | // fprintf(stderr, "%d %d %lf %lf\n", i, x[i], y[i], total); 11 | } 12 | return(total); 13 | } 14 | 15 | 16 | /* 17 | return value and mutated argument. 18 | Need to duplicate x but not y. 19 | */ 20 | double 21 | bar(int *x, double *y, int len) 22 | { 23 | double total = 0.; 24 | 25 | for(int i = 0; i < len; i++) { 26 | y[i] = ((double) x[i]) * y[i]; 27 | total += y[i]; 28 | } 29 | return(total); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /explorations/ptxKernel.cu: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern "C" 4 | __global__ void kern(int *out) 5 | { 6 | out[0] = 1; 7 | } 8 | -------------------------------------------------------------------------------- /explorations/ptx_nvvm1.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m = Module("simple ptx kernel") 4 | setDataLayout(m, "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64") 5 | 6 | fun = Function("kern", VoidType, list(out = Int32PtrType), mod = m) 7 | setMetadata(m, "nvvm.annotations", list(fun, "kernel", 1L)) 8 | block = Block(fun) 9 | ir = IRBuilder(block) 10 | 11 | out = getParameters(fun)[[1]] 12 | gep = ir$createGEP(out, ir$createSExt(ir$createIntegerConstant(0L), 64L)) 13 | s = ir$createStore(ir$createIntegerConstant(10L), gep) 14 | ir$createReturn() 15 | 16 | verifyModule(m) 17 | 18 | library(Rnvvm) 19 | code = showModule(m, TRUE) 20 | ptx = generatePTX(code, isFile = FALSE) 21 | 22 | 23 | library(RCUDA) 24 | cuda.mod = cuModuleLoadDataEx(ptx) 25 | out = .gpu(cuda.mod$kern, integer(32), gridDim = 1, blockDim = 1) -------------------------------------------------------------------------------- /explorations/ptx_test.R: -------------------------------------------------------------------------------- 1 | library(Rnvvm) 2 | ptx = generatePTX("/tmp/k.ll") 3 | 4 | library(RCUDA) 5 | cuda.mod = cuModuleLoadDataEx(ptx) 6 | out = .gpu(cuda.mod$simple, integer(32), gridDim = 1, blockDim = 1) -------------------------------------------------------------------------------- /explorations/readUpTo.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char line[1000] = "a simple string"; 4 | 5 | char * 6 | readUpTo(FILE *con, int to) 7 | { 8 | int ctr = 0; 9 | int size = 1000; 10 | while(ctr <= to) { 11 | fgets(line, size, con); 12 | ctr = ctr + 1; 13 | } 14 | return(line); 15 | } 16 | -------------------------------------------------------------------------------- /explorations/regexp.c: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /explorations/sample1.csv: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 6 | 6 7 | 7 8 | 8 9 | 9 10 | 10 11 | 11 12 | 12 13 | 13 14 | 14 15 | 15 16 | 16 17 | 17 18 | 18 19 | 19 20 | 20 21 | 21 22 | 22 23 | 23 24 | 24 25 | 25 26 | 26 27 | 27 28 | 28 29 | 29 30 | 30 31 | 31 32 | 32 33 | 33 34 | 34 35 | 35 36 | 36 37 | 37 38 | 38 39 | 39 40 | 40 41 | 41 42 | 42 43 | 43 44 | 44 45 | 45 46 | 46 47 | 47 48 | 48 49 | 49 50 | 50 51 | 51 52 | 52 53 | 53 54 | 54 55 | 55 56 | 56 57 | 57 58 | 58 59 | 59 60 | 60 61 | 61 62 | 62 63 | 63 64 | 64 65 | 65 66 | 66 67 | 67 68 | 68 69 | 69 70 | 70 71 | 71 72 | 72 73 | 73 74 | 74 75 | 75 76 | 76 77 | 77 78 | 78 79 | 79 80 | 80 81 | 81 82 | 82 83 | 83 84 | 84 85 | 85 86 | 86 87 | 87 88 | 88 89 | 89 90 | 90 91 | 91 92 | 92 93 | 93 94 | 94 95 | 95 96 | 96 97 | 97 98 | 98 99 | 99 100 | 100 101 | -------------------------------------------------------------------------------- /explorations/sampleCSV.tm_1e+05_Duncan-Temple-Langs-MacBook-Pro.local_Darwin.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/sampleCSV.tm_1e+05_Duncan-Temple-Langs-MacBook-Pro.local_Darwin.rda -------------------------------------------------------------------------------- /explorations/sampleCSV.tm_1e+05_jasper.ucdavis.edu_Linux.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/sampleCSV.tm_1e+05_jasper.ucdavis.edu_Linux.rda -------------------------------------------------------------------------------- /explorations/sampleCSV.tm_1e+05_lipschitz_Linux.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/sampleCSV.tm_1e+05_lipschitz_Linux.rda -------------------------------------------------------------------------------- /explorations/sampleCSV.tm_1e+05_lipschitz_Linux_gcc.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/sampleCSV.tm_1e+05_lipschitz_Linux_gcc.rda -------------------------------------------------------------------------------- /explorations/sampleCSVTimes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/explorations/sampleCSVTimes.png -------------------------------------------------------------------------------- /explorations/sapply.R: -------------------------------------------------------------------------------- 1 | library(RLLVMCompile) 2 | f = function(x) x + 10L 3 | g = function(x) sapply(x, f) 4 | 5 | mod = Module() 6 | fc = compileFunction(f, Int32Type, Int32Type, mod = mod) 7 | INTSXPType = getSEXPType("INT") 8 | gc = compileFunction(g, INTSXPType, INTSXPType, .globals = NULL, mod = mod) 9 | 10 | .llvm(fc, 1043) 11 | .llvm(gc, 1:4) # last element is wrong - initially some strange number, then 0 or 1 on other calls. 12 | 13 | 14 | ######## Why 15 | 16 | h = function(x) x + counter 17 | createGlobalVariable("counter", mod, Int32Type) 18 | hc = compileFunction(h, Int32Type, Int32Type, mod = mod) 19 | g2 = function(x) sapply(x, h) 20 | gc = compileFunction(g2, INTSXPType, INTSXPType, .globals = NULL, mod = mod) 21 | 22 | 23 | -------------------------------------------------------------------------------- /explorations/scalarCast.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m = Module() 4 | sc = Function("Rf_ScalarReal", SEXPType, list(DoubleType), module = m) 5 | 6 | t = Function("t", SEXPType, module = m) 7 | ir = IRBuilder(t) 8 | if(FALSE) { 9 | val = ir$createConstant(3.1415) 10 | } else { 11 | val = ir$createConstant(3, Int64Type) 12 | val = ir$createCast("SIToFP", val, DoubleType) 13 | } 14 | ans = ir$createCall(sc, val) 15 | ir$createReturn(ans) 16 | 17 | verifyModule(m) 18 | 19 | 20 | .llvm(t) 21 | -------------------------------------------------------------------------------- /explorations/select.c: -------------------------------------------------------------------------------- 1 | int bar1(int x) 2 | { 3 | return(x + 3); 4 | } 5 | 6 | int bar2(int x) 7 | { 8 | return(x * 10 + 13); 9 | } 10 | 11 | int 12 | foo(int x) 13 | { 14 | int ans = x > 1 ? bar1(x) : bar2(x); 15 | return(ans); 16 | } 17 | -------------------------------------------------------------------------------- /explorations/simpleGlobalString.R: -------------------------------------------------------------------------------- 1 | library(RLLVMCompile) 2 | mod = Module("str") 3 | ee = ExecutionEngine(mod) 4 | 5 | stringType = pointerType(getIntegerType(8L, Rllvm:::getContext(mod))) 6 | FILEType = pointerType(Int32Type) # an opaque struct type? 7 | 8 | .str = createGlobalVariable(".str", mod, val = "This is a string", linkage = PrivateLinkage) 9 | p = getGetElementPtr(.str) 10 | .ptr = createGlobalVariable("ptr", mod, stringType, p) 11 | 12 | foo = 13 | function() 14 | return(ptr) 15 | 16 | fun = compileFunction(foo, stringType, list(), mod, name = "foo") 17 | x = .llvm(fun, .ee = ee) 18 | 19 | 20 | -------------------------------------------------------------------------------- /explorations/simpleGlobalString.c: -------------------------------------------------------------------------------- 1 | char *g = "this is a string"; 2 | 3 | -------------------------------------------------------------------------------- /explorations/simpleKernel.cu: -------------------------------------------------------------------------------- 1 | extern "C" 2 | __global__ void 3 | getIndex(int *out, int N) 4 | { 5 | int myblock = blockIdx.x + blockIdx.y * gridDim.x; 6 | int blocksize = blockDim.x * blockDim.y * blockDim.z; 7 | int subthread = threadIdx.z*(blockDim.x * blockDim.y) + threadIdx.y*blockDim.x + threadIdx.x; 8 | 9 | int idx = myblock * blocksize + subthread; 10 | 11 | if(idx < N) { 12 | out[idx] = idx; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /explorations/static.c: -------------------------------------------------------------------------------- 1 | static int 2 | foo(int x) 3 | { 4 | return(x + 1); 5 | } 6 | 7 | 8 | 9 | int 10 | bar(int x) 11 | { 12 | return(foo(x)); 13 | } 14 | -------------------------------------------------------------------------------- /explorations/struct.c: -------------------------------------------------------------------------------- 1 | typedef struct A { 2 | int i; 3 | double d; 4 | } A; 5 | 6 | int declared(int, A *a); 7 | 8 | 9 | void *_[] ={(void*) &declared}; 10 | 11 | double 12 | foo(A a) 13 | { 14 | return(a.i + a.d); 15 | } 16 | 17 | int 18 | bar(int x, A *a) 19 | { 20 | return(x + 2 + a->i); 21 | } 22 | -------------------------------------------------------------------------------- /explorations/switch.c: -------------------------------------------------------------------------------- 1 | int 2 | foo(int i) 3 | { 4 | int a; 5 | switch(i) { 6 | case 2: 7 | a = 4; 8 | break; 9 | case 3: 10 | a = 8; 11 | break; 12 | case 19: 13 | a = 4; 14 | break; 15 | default: 16 | a = -1; 17 | break; 18 | } 19 | return(a); 20 | } 21 | -------------------------------------------------------------------------------- /explorations/ternary.c: -------------------------------------------------------------------------------- 1 | int 2 | foo(int x) 3 | { 4 | return( x ? 2 : 1); 5 | } 6 | -------------------------------------------------------------------------------- /explorations/testDist.R: -------------------------------------------------------------------------------- 1 | 2 | source("distance.R") 3 | 4 | p = 10 5 | n1 = 1000 6 | n2 = 999 7 | 8 | A = matrix(rnorm(n1*p), n1, p) 9 | B = matrix(rnorm(n2*p), n2, p) 10 | 11 | system.time(Dist(A, B)) 12 | 13 | -------------------------------------------------------------------------------- /explorations/testDoubleSet.R: -------------------------------------------------------------------------------- 1 | library(RLLVMCompile) 2 | f = function(x) { x.els = REAL(x); x.els[1] = 3.141539 ; x} 3 | f = function(x) { x[1L] = 3.141539 ; x} 4 | fc = compileFunction(f, REALSXPType, REALSXPType) 5 | .llvm(fc, numeric(3)) 6 | ee = ExecutionEngine(fc) 7 | .llvm(fc, numeric(3), .ee = ee) 8 | z = replicate(100, .llvm(fc, numeric(3), .ee = ee)) 9 | # This seems to work with the additions to SEXP.R to handle subset assignment. 10 | 11 | -------------------------------------------------------------------------------- /explorations/testFgets.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char * 4 | t_fgets(char *ptr, int size, FILE *f) 5 | { 6 | fprintf(stderr, "ptr = %p, f = %p, size = %d\n", ptr, f, size); 7 | // return(ptr); 8 | return(fgets(ptr, size, f)); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /explorations/testSEXP.R: -------------------------------------------------------------------------------- 1 | library(RLLVMCompile) 2 | f = function(n) { ans = numeric(n) ; ans} 3 | fc = compileFunction(f, REALSXPType, Int32Type) 4 | .llvm(fc, 10L) 5 | -------------------------------------------------------------------------------- /explorations/tmp: -------------------------------------------------------------------------------- 1 | abc 2 | def ghi jk 3 | lmn 4 | open 5 | -------------------------------------------------------------------------------- /explorations/tmp.R: -------------------------------------------------------------------------------- 1 | writeMapCall = 2 | function(info) 3 | { 4 | cur = NULL 5 | for(i in 1:length(info)) { 6 | el = info[[i]] 7 | k = makeCall(el$func, quote(x[i]), el$args) 8 | if(!is.null(cur)) 9 | cur[[2]] = k 10 | else 11 | cur = k 12 | } 13 | 14 | cur 15 | } 16 | 17 | makeCall = 18 | function(func, val = NULL, args = list()) 19 | { 20 | ans = substitute(f(), list(f = func)) 21 | if(length(val)) 22 | ans[[2]] = val 23 | if(length(args)) 24 | ans[seq(along = args) + length(ans)] = args 25 | 26 | ans 27 | } 28 | -------------------------------------------------------------------------------- /explorations/typedefStruct.R: -------------------------------------------------------------------------------- 1 | # clang -g -S -emit-llvm -o typedefStruct.ir typedefStruct.c -fno-discard-value-names 2 | library(Rllvm) 3 | m = parseIR("typedefStruct.ir") 4 | getTypes(m) 5 | elTypes = getTypes(m, TRUE) 6 | names(elTypes$A) 7 | 8 | if(FALSE) { 9 | # The above now works and returns i and d 10 | # But this is how we found out what to do. 11 | getElementTypes(z$A) 12 | k = lapplyDebugInfoTypes(m, class) 13 | 14 | 15 | ids = lapplyDebugInfoTypes(m, function(x) 16 | if(is(x, "DIDerivedType") && is(ty <- getBaseType(x), "DICompositeType")) 17 | names(getElements(ty)) 18 | else 19 | character()) 20 | } 21 | -------------------------------------------------------------------------------- /explorations/typedefStruct.c: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | int i; 3 | double d; 4 | } A; 5 | 6 | int 7 | foo(A a) 8 | { 9 | return(a.i); 10 | } 11 | -------------------------------------------------------------------------------- /explorations/undefinedSymbols.R: -------------------------------------------------------------------------------- 1 | # If we have 2 routines and one references an external routine that is not available 2 | # can we call the routine that is okay. 3 | # Here foo is fine. But we have bar that calls other() which is not available. 4 | # If we call foo with .llvm(m$foo) we crash. 5 | library(Rllvm) 6 | 7 | m = Module() 8 | 9 | foo = Function("foo", REALSXPType, module = m) 10 | ir = IRBuilder(foo) 11 | rmain = readBitcode("~/R-4.1/build3/src/main/Rmain.bc") 12 | 13 | # createCall will copy the declaration of Rf_ScalarReal into m. 14 | obj = ir$createCall(rmain$Rf_ScalarReal, ir$createConstant(3.1415)) 15 | ir$createReturn(obj) 16 | #verifyModule(m) 17 | 18 | #.llvm(m$foo) 19 | 20 | bar = Function("bar", Int32Type, module = m) 21 | o = Function("other", Int32Type, module =m) 22 | ir = IRBuilder(bar) 23 | ir$createReturn(ir$createCall(o)) 24 | 25 | 26 | #verifyModule(m) 27 | -------------------------------------------------------------------------------- /explorations/void.c: -------------------------------------------------------------------------------- 1 | void 2 | foo() 3 | { 4 | 5 | } 6 | 7 | -------------------------------------------------------------------------------- /inst/IR/README.md: -------------------------------------------------------------------------------- 1 | add.ll - foo() and bar() routines. Both add their arguments and return the result. 2 | 3 | distance - compute the distance between observations in two matrices, specifying the distance 4 | routine to use. 5 | 6 | fib.ll - Fibonacci sequence computations. 2 slightly different versions, but same computational approach. 7 | 8 | 9 | names.ir is created from names.c in the R source code. 10 | from svn version September, 2020 11 | 12 | -------------------------------------------------------------------------------- /inst/IR/auxInductionVars.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = parseIR("loop.ir") 3 | runLoopPass(m) 4 | fun = m$loopMat 5 | 6 | la = loopAnalysis(fun) # was nestedLoop 7 | loops = getLoops(la) 8 | length(loops) 9 | 10 | getInductionVariables = 11 | function(loop, la, fun) 12 | { 13 | ins = getInstructions(fun) 14 | w = sapply(ins, is, "PHINode") 15 | isAux = sapply(ins[w], function(phi) isAuxInductionVariable(loop, phi, la$scalar)) 16 | ins[w][isAux] 17 | } 18 | 19 | ivs = getInductionVariables(loops[[1]], la, fun) 20 | iv = getInductionVariable(loops[[1]]) 21 | ivs[ ! sapply(ivs, identical, iv) ] 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /inst/IR/distance.c: -------------------------------------------------------------------------------- 1 | typedef double (*dist_func)(double *x, double *y, int len, double p); 2 | 3 | double * 4 | distance(double *x, double *y, int nrow, int ncol_x, int ncol_y, dist_func dist, int p, double *dists) 5 | /* Compute the distance between each pair of columns in two matrices. 6 | * 7 | * Args: 8 | * x matrix 9 | * y matrix 10 | * nrow number of rows in x and y (should be the same) 11 | * ncol_x number of columns in x 12 | * ncol_y number of columns in y 13 | * dist distance function 14 | */ 15 | { 16 | /* Distances are arranged as in the diagram below. 17 | * y1 y2 y3 18 | * x1 _ _ _ 19 | * x2 _ _ _ 20 | */ 21 | 22 | int i, j; 23 | for (i = 0; i < ncol_y; i++) { 24 | for (j = 0; j < ncol_x; j++) { 25 | dists[i * ncol_x + j] = dist(&x[j * nrow], &y[i * nrow], nrow, p); 26 | } 27 | } 28 | 29 | return dists; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /inst/IR/enums.c: -------------------------------------------------------------------------------- 1 | typedef enum { RED, GREEN, BLUE} PrimaryColor; 2 | 3 | 4 | int 5 | foo(PrimaryColor k) 6 | { 7 | if(k == RED) 8 | return(0); 9 | else if(k == GREEN) 10 | return(1); 11 | else if(k == BLUE) 12 | return(2); 13 | 14 | return(-1); 15 | } 16 | -------------------------------------------------------------------------------- /inst/IR/fib.c: -------------------------------------------------------------------------------- 1 | int 2 | fib(int n) 3 | { 4 | if(n < 2) 5 | return(n); 6 | 7 | return(fib(n - 1 ) + fib(n - 2)); 8 | } 9 | 10 | 11 | 12 | #include 13 | 14 | int 15 | fib2(int n) 16 | { 17 | double root5 = 2.2360679774998; 18 | 19 | double phi = (1. + root5)/2.; 20 | double psi = 1. - phi; 21 | 22 | double ans = (pow(phi, n) - pow(psi, n))/root5; 23 | 24 | return(ans); 25 | } 26 | -------------------------------------------------------------------------------- /inst/IR/rapiEg.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void *_[] = { 4 | (void*) Rf_allocVector, 5 | (void*) Rf_setAttrib, 6 | (void*) SET_VECTOR_ELT, 7 | (void*) SET_STRING_ELT, 8 | (void*) REAL, 9 | (void*) INTEGER, 10 | }; 11 | -------------------------------------------------------------------------------- /inst/IR/rtypes.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | SEXP rglobal; 4 | 5 | -------------------------------------------------------------------------------- /inst/doc/AccessingArrays.R: -------------------------------------------------------------------------------- 1 | nms = parseIR(system.file("IR/names.ir", package = "Rllvm")) 2 | ft = nms[["R_FunTab"]] 3 | els = ft[[1]][] 4 | length(els) 5 | 6 | # To expand/unlist the elements within each of the 741 struct elements 7 | els2 = lapply(els, `[`) 8 | 9 | # Instead, if we want to customize how we extract the infomation 10 | # lapply(els, myFun) 11 | # but you have to handle the final ConstantAggregateZero, e.g., with isZeroValue or test the class, or 12 | # check the number of operands. For example, to get the name of the routine in the second element of each struct, 13 | 14 | sapply(els, function(el) if(length(el) > 1) getName(el[[2]]) else NA) 15 | -------------------------------------------------------------------------------- /inst/doc/basics: -------------------------------------------------------------------------------- 1 | * Loading the library, by default, calls the InitializeNativeTarget. 2 | You can avoid this by setting the R option Rllvm.autoInitialize to FALSE. 3 | 4 | * To start creating code, you create a module (Module). 5 | 6 | * Then call Function() to declare a function. 7 | You specify the return type and the types of the parameters. 8 | 9 | * Create one or more Block() objects. 10 | These are used to house the instructions that are related to each 11 | other. The different blocks allow us to jump between them and avoid 12 | other instructions. 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /inst/doc/check2.R: -------------------------------------------------------------------------------- 1 | # 2nd approach in staticCodeAnalysis for finding calls of the form 2 | # Rf_eval(*, R_GlobalEnv) 3 | # 4 | # The first approach is much better - finding uses of R_GlobalEnv and then finding which 5 | # of these are calls to Rf_eval(). 6 | # 7 | 8 | v2 = 9 | function(mod) 10 | { 11 | if(is.character(mod)) 12 | mod = parseIR(mod) 13 | 14 | if(is.null(getGlobalVariable(mod, "R_GlobalEnv"))) 15 | return(NULL) 16 | 17 | i = getInstructions(mod) 18 | i = unlist(i) 19 | w = sapply(i, isEvalCall) 20 | i2 = i[w] 21 | if(length(i2)) 22 | i2[ sapply(i2, usesGlobalEnv) ] 23 | else 24 | list() 25 | } 26 | -------------------------------------------------------------------------------- /man/ConstantExpr.Rd: -------------------------------------------------------------------------------- 1 | \alias{ConstantExpr} 2 | \name{ConstantExpr} 3 | 4 | \alias{isGEPWithNoNotionalOverIndexing} 5 | 6 | 7 | \title{Constant Expression} 8 | \description{ 9 | These are functions for working \code{\link{ConstantExpr-class}} objects. 10 | } 11 | \usage{ 12 | isGEPWithNoNotionalOverIndexing(x) 13 | } 14 | \arguments{ 15 | \item{x}{a \code{\link{ConstantExpr-class}} object} 16 | } 17 | 18 | \author{DTL} 19 | -------------------------------------------------------------------------------- /man/Intrinsic.Rd: -------------------------------------------------------------------------------- 1 | \name{getIntrinsic} 2 | \alias{getIntrinsic} 3 | \alias{getIntrinsic} 4 | \alias{getIntrinsicID} 5 | \alias{getIntrinsicName} 6 | \alias{isIntrinsic} 7 | \alias{isIntrinsicOverloaded} 8 | \alias{coerce,character,IntrinsicID-method} 9 | \title{Functions for working with LLVM Intrinsic routines} 10 | \description{ 11 | These are functions that work with LLVM's intrinsic functions. 12 | } 13 | \usage{ 14 | getIntrinsic(module, id, types = list()) 15 | } 16 | \arguments{ 17 | \item{module}{the \code{Module} object} 18 | \item{id}{the name of the intrinsic} 19 | \item{types}{parameter types} 20 | } 21 | %\value{} 22 | \references{ 23 | LLVM Manual 24 | } 25 | \author{ 26 | Duncan Temple Lang 27 | } 28 | 29 | %\seealso{} 30 | %\examples{} 31 | \keyword{programming} 32 | -------------------------------------------------------------------------------- /man/addCases.Rd: -------------------------------------------------------------------------------- 1 | \name{addCases} 2 | \alias{addCases} 3 | \title{Add cases to a switch instruction} 4 | \description{ 5 | This function allows us to populate a switch-like 6 | instructionw with the different cases. 7 | } 8 | \usage{ 9 | addCases(sw, ..., .cases = list(...), .values = integer(), .ctx = getGlobalContext()) 10 | } 11 | %- maybe also 'usage' for other objects documented here. 12 | \arguments{ 13 | \item{sw}{the switch instruction} 14 | \item{\dots}{code for the individual cases} 15 | \item{.cases}{the cases given as a collection} 16 | \item{.values}{the values corresponding to the cases} 17 | \item{.ctx}{the context for creating the values if necessary} 18 | } 19 | %\details{} 20 | %\value{} 21 | \references{ 22 | LLVM Documentation \url{http://llvm.org/docs/} 23 | } 24 | \author{ 25 | DTL 26 | } 27 | 28 | 29 | %\seealso{} 30 | %\examples{} 31 | \keyword{programming} 32 | -------------------------------------------------------------------------------- /man/blocks.Rd: -------------------------------------------------------------------------------- 1 | \name{blocks} 2 | \alias{blocks} 3 | 4 | \alias{incoming_values} 5 | \alias{setIncomingBlock} 6 | \alias{getIncomingValueForBlock} 7 | \alias{getBasicBlockIndex} 8 | \alias{addIncoming} 9 | 10 | \alias{hasConstantValue} 11 | 12 | \title{Incoming blocks of a PHI node} 13 | \description{ 14 | } 15 | \usage{ 16 | blocks(phi) 17 | } 18 | \arguments{ 19 | \item{phi}{a PHI node} 20 | } 21 | \details{ 22 | %% ~~ If necessary, more details than the description above ~~ 23 | } 24 | \value{ 25 | A list of 0 or more elements each of which is of 26 | class \code{\link{BasicBlock-class}}. 27 | } 28 | \references{ 29 | \url{https://llvm.org/doxygen/classllvm_1_1PHINode.html} 30 | } 31 | \author{ 32 | DTL 33 | } 34 | \seealso{ 35 | 36 | } 37 | \examples{ 38 | } 39 | \keyword{programming} 40 | 41 | -------------------------------------------------------------------------------- /man/createIsNotNull.Rd: -------------------------------------------------------------------------------- 1 | \name{createIsNotNull} 2 | \alias{createIsNotNull} 3 | \alias{createIsNull} 4 | %\alias{createSelect} 5 | %\alias{createUnreachable} 6 | \title{Create LLVM operations} 7 | \description{ 8 | Functions to create LLVM instructions, all typically taking 9 | the IRBuilder as the first argument. 10 | } 11 | \usage{ 12 | createIsNotNull(builder, val, id = character()) 13 | } 14 | \arguments{ 15 | \item{builder}{the \code{IRBuilder} object} 16 | \item{val}{the value/variable to test if is not NULL or is NULL} 17 | \item{id}{a label/identifier for the code/instruction to appear in the byte code} 18 | } 19 | %\value{} 20 | \references{ 21 | The LLVM API documentation 22 | } 23 | \author{ 24 | Duncan Temple Lang 25 | } 26 | 27 | %\seealso{} 28 | %\examples{} 29 | \keyword{progamming} 30 | \keyword{interface} 31 | 32 | -------------------------------------------------------------------------------- /man/generatePTX.Rd: -------------------------------------------------------------------------------- 1 | \name{generatePTX} 2 | \alias{generatePTX} 3 | \title{Generate PTX code to run on a NVIDIA GPU} 4 | \description{ 5 | This function uses LLVM's ability to generate code for 6 | a NVIDIA GPU rather than the local CPU. 7 | } 8 | \usage{ 9 | generatePTX(m) 10 | } 11 | \arguments{ 12 | \item{m}{the \code{Module} to be compiled} 13 | } 14 | \value{ 15 | a character vector containing the PTX code. 16 | This can be written to a file or used directly with the RCUDA 17 | package. See \url{http://www.omegahat.org/RCUDA}. 18 | } 19 | \references{LLVM documentation. NVIDIA and CUDA SDK documentation} 20 | \author{ 21 | Duncan Temple Lang 22 | } 23 | %\seealso{} 24 | %\examples{} 25 | \keyword{programming} 26 | 27 | -------------------------------------------------------------------------------- /man/getAllUsers.Rd: -------------------------------------------------------------------------------- 1 | \name{getAllUsers} 2 | \alias{getAllUsers} 3 | \alias{getAllUses} 4 | \alias{getUser} 5 | 6 | 7 | \alias{replaceUsesOfWith} 8 | \alias{replaceAllUsesWith} 9 | 10 | 11 | \title{Get Uses and Users of a Value} 12 | \description{ 13 | } 14 | \usage{ 15 | getAllUsers(obj, uses = getAllUses(obj)) 16 | } 17 | \arguments{ 18 | \item{obj}{the Value object} 19 | \item{uses}{a list of ....} %XXX 20 | } 21 | \details{ 22 | } 23 | \value{ 24 | } 25 | \references{ 26 | } 27 | \author{ 28 | DTL 29 | } 30 | 31 | \seealso{ 32 | } 33 | \examples{ 34 | } 35 | \keyword{programming} 36 | -------------------------------------------------------------------------------- /man/getAsCString.Rd: -------------------------------------------------------------------------------- 1 | \name{getAsCString} 2 | \alias{getAsCString} 3 | \alias{getAsCString,ConstantDataSequential-method} 4 | \alias{coerce,ConstantDataSequential,character-method} 5 | 6 | \title{Convert Strings to R} 7 | \description{ 8 | %% ~~ A concise (1-5 lines) description of what the function does. ~~ 9 | } 10 | \usage{ 11 | getAsCString(x, ...) 12 | } 13 | %- maybe also 'usage' for other objects documented here. 14 | \arguments{ 15 | \item{x}{ 16 | %% ~~Describe \code{x} here~~ 17 | } 18 | \item{\dots}{ 19 | %% ~~Describe \code{\dots} here~~ 20 | } 21 | } 22 | \details{ 23 | %% ~~ If necessary, more details than the description above ~~ 24 | } 25 | \value{ 26 | %% ~Describe the value returned 27 | %% If it is a LIST, use 28 | %% \item{comp1 }{Description of 'comp1'} 29 | %% \item{comp2 }{Description of 'comp2'} 30 | %% ... 31 | } 32 | \references{ 33 | %% ~put references to the literature/web site here ~ 34 | } 35 | \author{DTL} 36 | 37 | 38 | 39 | \seealso{ 40 | } 41 | \examples{ 42 | } 43 | \keyword{programming} 44 | 45 | -------------------------------------------------------------------------------- /man/getClassName.Rd: -------------------------------------------------------------------------------- 1 | \name{getClassName} 2 | \alias{getClassName} 3 | \title{Get the name of a Value's class} 4 | \description{ 5 | } 6 | \usage{ 7 | getClassName(value) 8 | } 9 | \arguments{ 10 | \item{value}{an LLVM Value object} 11 | } 12 | 13 | \value{ 14 | A character string, i.e., a character vector of length 1. 15 | } 16 | \author{ 17 | DTL 18 | } 19 | \seealso{ 20 | } 21 | \examples{ 22 | } 23 | \keyword{programming} 24 | -------------------------------------------------------------------------------- /man/getGetElementPtr.Rd: -------------------------------------------------------------------------------- 1 | \name{getGetElementPtr} 2 | \alias{getGetElementPtr} 3 | %- Also NEED an '\alias' for EACH other topic documented here. 4 | \title{Create LLVM instruction to access an element in an array or via pointer} 5 | \description{ 6 | This is a function that allows us to create an instruction 7 | to access an element of an array or index a pointer. 8 | } 9 | \usage{ 10 | getGetElementPtr(cons, index = c(0L, 0L), inBounds = FALSE, ctx = getContext(cons)) 11 | } 12 | \arguments{ 13 | \item{cons}{the object whose element we want} 14 | \item{index}{the indices, as a vector of integers or explicitly 15 | created LLVM constant objects} 16 | \item{inBounds}{whether the index is known to be in-bounds} 17 | \item{ctx}{the context which may be needed to create the LLVM 18 | constants, i.e. if \code{index} are numbers.} 19 | } 20 | 21 | %\value{} 22 | \references{ 23 | LLVM Documentation \url{http://llvm.org/docs/} 24 | } 25 | \author{ 26 | DTL 27 | } 28 | 29 | 30 | %\seealso{} 31 | %\examples{} 32 | \keyword{programming} 33 | -------------------------------------------------------------------------------- /man/getIntSize.Rd: -------------------------------------------------------------------------------- 1 | \name{getIntSize} 2 | \alias{getIntSize} 3 | % These are different from getIntSize as they take a DataLayout. Move? 4 | \alias{getPointerSize} 5 | \alias{getPointerTypeSize} 6 | \alias{getTypeAllocSize} 7 | 8 | \title{Get sizes of various data types} 9 | \description{ 10 | } 11 | \usage{ 12 | getIntSize(x, ...) 13 | getPointerTypeSize(x) 14 | getPointerSize(datalayout) 15 | getTypeAllocSize(datalayout) 16 | } 17 | 18 | \arguments{ 19 | \item{x}{the LLVM \code{Value} or \code{Type} to query} 20 | \item{datalayout}{a DataLayout instance or something that can be coerced to DataLayout.} 21 | \item{\dots}{additional parameters for methods or future developments} 22 | } 23 | \details{ 24 | } 25 | \value{ 26 | An integer value (scalar). 27 | } 28 | \references{ 29 | } 30 | \author{DTL} 31 | 32 | 33 | \seealso{ 34 | } 35 | \examples{ 36 | getIntSize(Int32Type) 37 | getIntSize(Int64Type) 38 | getIntSize(Int8Type) 39 | getIntSize(Int1Type) 40 | 41 | ir = IRBuilder() 42 | v = ir$createConstant(3L, Int64Type) 43 | getIntSize(v) 44 | } 45 | 46 | \keyword{programming} 47 | -------------------------------------------------------------------------------- /man/getMetadata.Rd: -------------------------------------------------------------------------------- 1 | \name{getMetadata} 2 | \alias{getMetadata} 3 | \alias{getMetadata,Function,character-method} 4 | \alias{getMetadata,Function,numeric-method} 5 | \alias{getMetadata,Instruction,character-method} 6 | \alias{getMetadata,Instruction,numeric-method} 7 | %XX For global variables 8 | 9 | \alias{coerce,Metadata,character-method} 10 | 11 | \alias{getName,NamedMDNode-method} 12 | \alias{getMetadata,Module,character-method} 13 | 14 | 15 | \alias{Metadata-class} 16 | 17 | \title{Get Meta-data from Functions, Instructions, Global Variables} 18 | 19 | \description{ 20 | } 21 | \usage{ 22 | getMetadata(obj, id, ...) 23 | } 24 | \arguments{ 25 | \item{obj}{} 26 | \item{id}{} 27 | \item{\dots}{additional parameters for methods} 28 | } 29 | \value{ 30 | } 31 | \references{ 32 | } 33 | \author{ 34 | DTL 35 | } 36 | \seealso{ 37 | } 38 | \examples{ 39 | } 40 | \keyword{programming} 41 | -------------------------------------------------------------------------------- /man/getModuleFunctions.Rd: -------------------------------------------------------------------------------- 1 | \name{getModuleFunctions} 2 | \alias{getModuleFunctions} 3 | \title{Get a list of the functions in an LLVM module} 4 | \description{ 5 | This function returns a named list of the 6 | functions that exist in an LLVM module. 7 | } 8 | \usage{ 9 | getModuleFunctions(mod) 10 | } 11 | %- maybe also 'usage' for other objects documented here. 12 | \arguments{ 13 | \item{mod}{the \code{Module} object.} 14 | } 15 | \value{ 16 | A named list. 17 | } 18 | \references{ 19 | The LLVM API documentation. 20 | } 21 | \author{ 22 | Duncan Temple Lang 23 | } 24 | 25 | \seealso{ 26 | \code{\link{Module}}, 27 | \code{\link{Function}} 28 | } 29 | \examples{ 30 | library(Rllvm) 31 | InitializeNativeTarget() 32 | 33 | mod = Module("opt") 34 | fun = Function("iadd", Int32Type, c(x = Int32Type, y = Int32Type), mod) 35 | # Now build the code for the function 36 | # ......... 37 | 38 | getModuleFunctions(mod) 39 | } 40 | \keyword{progamming} 41 | \keyword{interface} 42 | -------------------------------------------------------------------------------- /man/getOpcode.Rd: -------------------------------------------------------------------------------- 1 | \name{getOpcode} 2 | \alias{getOpcode} 3 | \title{Get the operation code/identifier for an LLVM instruction} 4 | \description{ 5 | This function allows us to retrieve the identifier or type of the 6 | instruction. 7 | } 8 | \usage{ 9 | getOpcode(x, ...) 10 | } 11 | \arguments{ 12 | \item{x}{the instruction} 13 | \item{\dots}{additional arguments for methods} 14 | } 15 | 16 | %\value{} 17 | \references{ 18 | LLVM Documentation \url{http://llvm.org/docs/} 19 | } 20 | \author{Duncan Temple Lang} 21 | 22 | %\seealso{} 23 | %\examples{} 24 | \keyword{programming} 25 | -------------------------------------------------------------------------------- /man/getValue.Rd: -------------------------------------------------------------------------------- 1 | \name{getValue} 2 | \alias{getValue} 3 | \alias{getValue,-method} 4 | \alias{getValue,ConstantFP-method} 5 | \alias{getValue,ConstantInt-method} 6 | \alias{getValue,MDNode-method} 7 | \alias{getValue,NamedMDNode-method} 8 | \alias{getValue,Value-method} 9 | \alias{getValue,Metadata-method} 10 | \alias{getValue,Use-method} 11 | 12 | \alias{coerce,ConstantInt,integer-method} 13 | 14 | \title{Get the value from an LLVM entity} 15 | 16 | \description{ 17 | This generic function and its methods allow us to get 18 | the value associated with an LLVM object, e.g., 19 | a meta-data node. 20 | } 21 | \usage{ 22 | getValue(x, ...) 23 | } 24 | %- maybe also 'usage' for other objects documented here. 25 | \arguments{ 26 | \item{x}{the object whose value is being requested} 27 | \item{\dots}{additional arguments for methods} 28 | } 29 | %\details{} 30 | \value{ 31 | An R object! 32 | } 33 | %\references{} 34 | \author{Duncan Temple Lang} 35 | 36 | %\seealso{} 37 | %\examples{} 38 | \keyword{programming} 39 | -------------------------------------------------------------------------------- /man/isInBounds.Rd: -------------------------------------------------------------------------------- 1 | \name{isInBounds} 2 | \alias{isInBounds} 3 | \alias{isInBounds<-} 4 | \alias{isInBounds,Value-method} 5 | \alias{isInBounds<-,Value-method} 6 | 7 | \title{Query or set bounds checking flag} 8 | \description{ 9 | 10 | } 11 | \usage{ 12 | isInBounds(x, ...) 13 | } 14 | 15 | \arguments{ 16 | \item{x}{the LLVM \code{Value} object} 17 | \item{\dots}{additional arguments for methods} 18 | } 19 | \value{ 20 | } 21 | %\references{} 22 | \author{ 23 | 24 | } 25 | \seealso{} 26 | \examples{ 27 | } 28 | \keyword{programming} 29 | 30 | -------------------------------------------------------------------------------- /man/isZeroValue.Rd: -------------------------------------------------------------------------------- 1 | \name{isZeroValue} 2 | \alias{isZeroValue} 3 | \alias{isZeroValue.Constant} 4 | \alias{isZeroValue,Constant-method} 5 | 6 | \title{Check if a Value is a Zero-initializer} 7 | \description{ 8 | } 9 | \usage{ 10 | isZeroValue(x, ...) 11 | } 12 | \arguments{ 13 | \item{x}{the LLVM Value object} 14 | \item{\dots}{arguments for methods} 15 | } 16 | 17 | \value{ 18 | A logical scalar value. 19 | } 20 | \references{ 21 | } 22 | \author{DTL} 23 | 24 | 25 | \seealso{ 26 | } 27 | \examples{ 28 | } 29 | \keyword{programming} 30 | -------------------------------------------------------------------------------- /man/isa.Rd: -------------------------------------------------------------------------------- 1 | \name{isa} 2 | \alias{isa} 3 | \title{Queries if an LLVM Instruction is a particular sub-type} 4 | \description{ 5 | This is a convenience function for querying the particular sub-type 6 | of an LLVM Instruction type. 7 | } 8 | \usage{ 9 | isa(obj, classname = class(obj)) 10 | } 11 | \arguments{ 12 | \item{obj}{the Instruction type} 13 | \item{classname}{the name of the sub-class we are testing} 14 | } 15 | %\details{} 16 | \value{ 17 | a logical scalar value, i.e. \code{TRUE} or \code{FALSE}. 18 | } 19 | \references{ 20 | LLVM Documentation for the \code{Instruction} classes. 21 | } 22 | \author{ 23 | Duncan Temple Lang 24 | } 25 | 26 | \seealso{\code{\link{createGEP}} and all of the create instruction 27 | functions related to the IRBuilder.} 28 | %\examples{} 29 | \keyword{programming} 30 | \keyword{interface} 31 | -------------------------------------------------------------------------------- /man/lljit.Rd: -------------------------------------------------------------------------------- 1 | \name{lljit} 2 | \alias{lljit} 3 | \alias{LLJIT-class} 4 | \alias{LazyLLJIT-class} 5 | 6 | \alias{addModule,LLJIT-method} 7 | \alias{$,LLJIT-method} 8 | 9 | \alias{jitLookup} 10 | 11 | \title{Create an On-Request JIT Execution Engine} 12 | \description{} 13 | \usage{ 14 | lljit(lazy = FALSE, ..., .modules = list(...)) 15 | } 16 | \arguments{ 17 | \item{lazy}{a logical value controlling whether each routine is 18 | compiled only when it is needed, or if all routines are eagerly 19 | compiled (\code{FALSE}) when the first routine in the module(s) is 20 | needed.} 21 | \item{\dots}{individual \code{\link{Module}} objects} 22 | \item{.modules}{a list of \code{\link{Module}} objects} 23 | } 24 | \details{ 25 | %% ~~ If necessary, more details than the description above ~~ 26 | } 27 | \value{ 28 | An object of class \code{LLJIT}. 29 | } 30 | \references{ 31 | \url{https://llvm.org/docs/ORCv2.html} 32 | } 33 | \author{DTL} 34 | \seealso{ 35 | } 36 | \examples{ 37 | 38 | } 39 | 40 | -------------------------------------------------------------------------------- /man/llvmDump.Rd: -------------------------------------------------------------------------------- 1 | \name{llvmDump} 2 | \alias{llvmDump} 3 | \alias{llvmDump,Value-method} 4 | \alias{llvmDump,Type-method} 5 | 6 | \title{Create a text representation of an LLVM object} 7 | \description{ 8 | This generic function and its methods allow us to generate a 9 | text representation of different LLVM data types so that we can 10 | better understand what they contain. 11 | These methods currently display the results on the console! 12 | } 13 | \usage{ 14 | llvmDump(x, ...) 15 | } 16 | \arguments{ 17 | \item{x}{the LLVM object to be displayed} 18 | \item{\dots}{any additional arguments for the methods} 19 | } 20 | \value{ 21 | \code{NULL} 22 | } 23 | \references{ 24 | LLVM documentation. 25 | } 26 | \author{Duncan Temple Lang} 27 | 28 | 29 | %\seealso{} 30 | %\examples{} 31 | % Add one or more standard keywords, see file 'KEYWORDS' in the 32 | % R documentation directory. 33 | \keyword{programming} 34 | \keyword{interface} 35 | -------------------------------------------------------------------------------- /man/llvmISA.Rd: -------------------------------------------------------------------------------- 1 | \name{llvmISA} 2 | \alias{llvmISA} 3 | \title{Query class of LLVM type} 4 | \description{ 5 | This function determines whether 6 | } 7 | \usage{ 8 | llvmISA(obj, type, noChecks = FALSE) 9 | } 10 | 11 | \arguments{ 12 | \item{obj}{the LLVM object, an external reference} 13 | \item{type}{the name of the type we are queryiing whether \code{obj} 14 | is an instance of.ffff} 15 | \item{noChecks}{a logical value controlling whether we check for the 16 | different types before we make the query.} 17 | } 18 | 19 | \value{ 20 | A logical value. 21 | } 22 | \author{DTL} 23 | 24 | -------------------------------------------------------------------------------- /man/mkCallProxy.Rd: -------------------------------------------------------------------------------- 1 | \name{mkCallProxy} 2 | \alias{mkCallProxy} 3 | \title{Create an R Function to call an LLVM Routine} 4 | \description{ 5 | This creates a wrapper/proxy R function to call an LLVM routine. 6 | This creates an LLVM routine that accepts R objects and 7 | marshalls these as arguments to the native routine. 8 | } 9 | \usage{ 10 | mkCallProxy(fun, name = paste0("R_", getName(fun)), mod = as(fun, "Module")) 11 | } 12 | \arguments{ 13 | \item{fun}{the LLVM \code{\link{Function-class}} object for which we are creating a proxy} 14 | \item{name}{the name of the } 15 | \item{mod}{} 16 | } 17 | \value{ 18 | An R function 19 | } 20 | \author{ 21 | Duncan Temple Lang 22 | } 23 | \seealso{ 24 | \code{\link{simpleFunction}} 25 | \code{\link{Function-class}} 26 | \code{\link{.llvm}} 27 | } 28 | \examples{ 29 | f = system.file("IR/fib.ir", package = "Rllvm") 30 | m = parseIR(f) 31 | rf = mkCallProxy(m$fib) 32 | } 33 | \keyword{programming} 34 | \concept{metaprogramming} 35 | -------------------------------------------------------------------------------- /man/offsets.Rd: -------------------------------------------------------------------------------- 1 | \name{offsets} 2 | \alias{offsets} 3 | \alias{structOffsets} 4 | \title{Compute Element Offsets for a Structure} 5 | \description{ 6 | This function provides the offset for each field 7 | in a structure. 8 | This assumes we can get the names of the fields from the debugging information. 9 | } 10 | \usage{ 11 | offsets(ty, varNames = names(ty)) 12 | } 13 | %- maybe also 'usage' for other objects documented here. 14 | \arguments{ 15 | \item{ty}{the description of the structure type} 16 | \item{varNames}{the names of the fields} 17 | } 18 | \value{ 19 | An integer vector. 20 | } 21 | \author{DTL} 22 | \seealso{ 23 | \code{\link{lapplyDebugInfoTypes}} 24 | } 25 | % \examples{} 26 | -------------------------------------------------------------------------------- /man/onlyReadsMemory.Rd: -------------------------------------------------------------------------------- 1 | \name{onlyReadsMemory} 2 | \alias{onlyReadsMemory} 3 | \alias{onlyReadsMemory,Argument-method} 4 | \alias{onlyReadsMemory,Function-method} 5 | 6 | \title{Determines if the LLVM does not write to memory} 7 | \description{ 8 | } 9 | \usage{ 10 | onlyReadsMemory(x, ...) 11 | } 12 | \arguments{ 13 | \item{x}{the LLVM object, currently a \code{Function} or \code{Argument} object} 14 | \item{\dots}{additional arguments for methods} 15 | } 16 | \value{ 17 | } 18 | \references{} 19 | \author{ 20 | } 21 | 22 | \seealso{} 23 | \examples{ 24 | } 25 | 26 | \keyword{programming} 27 | 28 | -------------------------------------------------------------------------------- /man/raw_svector_ostream.Rd: -------------------------------------------------------------------------------- 1 | \name{raw_svector_ostream} 2 | \alias{raw_svector_ostream} 3 | \alias{raw_svector_ostream-class} 4 | \alias{coerce,raw_svector_ostream,character-method} 5 | 6 | %- Also NEED an '\alias' for EACH other topic documented here. 7 | \title{C++ stream as a character buffer} 8 | \description{ 9 | } 10 | \usage{ 11 | raw_svector_ostream(len = 1000L) 12 | } 13 | %- maybe also 'usage' for other objects documented here. 14 | \arguments{ 15 | \item{len}{ 16 | %% ~~Describe \code{len} here~~ 17 | } 18 | } 19 | \details{ 20 | %% ~~ If necessary, more details than the description above ~~ 21 | } 22 | \value{ 23 | } 24 | \references{ 25 | } 26 | \author{ 27 | DTL 28 | } 29 | \seealso{ 30 | } 31 | \examples{ 32 | } 33 | \keyword{programming} 34 | 35 | -------------------------------------------------------------------------------- /man/setInitializer.Rd: -------------------------------------------------------------------------------- 1 | \name{setInitializer} 2 | \alias{setInitializer} 3 | %- Also NEED an '\alias' for EACH other topic documented here. 4 | \title{Set the initializer for an LLVM Value} 5 | \description{ 6 | This function sets the initial value for an LLVM variable or Value object. 7 | } 8 | \usage{ 9 | setInitializer(var, value) 10 | } 11 | \arguments{ 12 | \item{var}{the variable whose value is to be set} 13 | \item{value}{the value with which to initialize the variable} 14 | } 15 | %\value{} 16 | \references{ 17 | LLVM Documentation \url{http://llvm.org/docs/} 18 | } 19 | \author{ 20 | DTL 21 | } 22 | 23 | 24 | %\seealso{} 25 | %\examples{} 26 | \keyword{programming} 27 | -------------------------------------------------------------------------------- /man/setOpaquePointers.Rd: -------------------------------------------------------------------------------- 1 | \name{setOpaquePointers} 2 | \alias{setOpaquePointers} 3 | \title{Enable non-opaque pointers in an LLVM Context} 4 | \description{ 5 | This allows a user to set whether an LLVM context allows non-opaque pointers, 6 | i.e., so we can query the element type of a pointer type. 7 | By default, recent versions of LLVM use only opaque pointers, by default, 8 | but some versions allow one to allow non-opaque pointers. 9 | 10 | As of LLVM version 17, this option doesn't work and only opaque pointers are possible. 11 | 12 | } 13 | \usage{ 14 | setOpaquePointers(val = FALSE, ctxt = getGlobalContext()) 15 | } 16 | \arguments{ 17 | \item{val}{a logical value with \code{FALSE} allowing non-opaque pointer types 18 | if this version of LLVM allows it.} 19 | \item{ctxt}{the \code{LLVMContext} object in which to set this option} 20 | } 21 | \value{ 22 | A logical value. 23 | } 24 | \author{ 25 | Duncan Temple Lang 26 | } 27 | %\seealso{} 28 | %\examples{} 29 | \keyword{programming} 30 | -------------------------------------------------------------------------------- /man/string.Rd: -------------------------------------------------------------------------------- 1 | \name{string} 2 | \alias{string} 3 | \title{Initialize a string object} 4 | \description{ 5 | This is introduced to provide a function 6 | analogous to \code{numeric} and \code{integer} 7 | for creating a string with a specific length, populated with space 8 | characters. 9 | This is used for specifying the type of a string with a fixed maximum length. 10 | } 11 | \usage{ 12 | string(length) 13 | } 14 | \arguments{ 15 | \item{length}{number of characters for the string} 16 | } 17 | \value{ 18 | a character vector with one element 19 | with \code{length} characters. 20 | } 21 | \references{ 22 | LLVM Documentation \url{http://llvm.org/docs/} 23 | } 24 | \author{DTL} 25 | 26 | 27 | %\seealso{} 28 | \examples{ 29 | string(10) 30 | } 31 | \keyword{programming} 32 | 33 | -------------------------------------------------------------------------------- /man/stripDebugInfo.Rd: -------------------------------------------------------------------------------- 1 | \name{stripDebugInfo} 2 | \alias{stripDebugInfo} 3 | \alias{stripDebugInfo,Function-method} 4 | \alias{stripDebugInfo,Module-method} 5 | \title{Remove the debugging meta-data from a Module or Function} 6 | \description{ 7 | This removes the debugging meta-data from an LLVM Module or just for a single Function. 8 | } 9 | \usage{ 10 | stripDebugInfo(x, ...) 11 | } 12 | \arguments{ 13 | \item{x}{the Module or Function object} 14 | \item{\dots}{additional arguments for methods} 15 | } 16 | \value{ 17 | The returned value is typically of no interest 18 | as it is the side effect of modifying the Module or Function 19 | that is important. 20 | } 21 | %\references{} 22 | \author{DTL} 23 | 24 | \seealso{ 25 | \code{\link{parseIR}} and \code{llvm-strip} 26 | } 27 | \examples{ 28 | irFile = system.file("IR/fib_debug.ir", package = "Rllvm") 29 | m = parseIR(irFile) 30 | showModule(m) 31 | stripDebugInfo(m$fib) 32 | showModule(m) 33 | stripDebugInfo(m) 34 | showModule(m) 35 | } 36 | \keyword{programming} 37 | 38 | -------------------------------------------------------------------------------- /purgeWrongArch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # https://unix.stackexchange.com/questions/187088/if-command-in-find-exec 3 | #find -E . -regex '\\.s?o$' -exec sh -c 'if test `lipo -archs $0` = "x86_64" ; then echo "bad $0"; else echo "good $0" ; fi' {} \; 4 | /usr/bin/find . \( -name '*.o' -o -name '*.so' \) -exec sh -c 'TMP=`lipo -archs $0`; if [ $? -eq 1 ] || [ "$TMP" = "x86_64" ] ; then echo "removing $0"; rm "$0" ; fi' {} \; 5 | 6 | # -name '*.o' -o -name '*.so' -o -name '*.a' 7 | -------------------------------------------------------------------------------- /src/ASCII.c: -------------------------------------------------------------------------------- 1 | 2 | void 3 | R_asciiCode(char **x, int *len, int *val) 4 | { 5 | for(int i = 0; i < *len; i++) 6 | val[i] = (int) x[i][0]; 7 | } 8 | -------------------------------------------------------------------------------- /src/Failed.R: -------------------------------------------------------------------------------- 1 | cpp = list.files(pattern = "cpp") 2 | o = gsub("\\.cpp$", ".o", cpp) 3 | fail = cpp[ !file.exists(o) ] 4 | print(fail) 5 | 6 | 7 | cat(paste("##", fail), sep = "\n\n") 8 | 9 | 10 | # "Pass.cpp" "RLLVMClassName.cpp" 11 | # Fixed for 7.0: "Module.cpp" "Target.cpp" 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Inst.cpp: -------------------------------------------------------------------------------- 1 | #include "Rllvm.h" 2 | 3 | extern "C" 4 | SEXP 5 | R_SwitchInst_addCases(SEXP r_inst, SEXP r_vals, SEXP r_block) 6 | { 7 | llvm::SwitchInst *sw = GET_REF(r_inst, SwitchInst); 8 | for(int i = 0 ; i < Rf_length(r_vals) ; i++) { 9 | llvm::ConstantInt *val = GET_REF(VECTOR_ELT(r_vals, i), ConstantInt); 10 | llvm::BasicBlock *block = GET_REF(VECTOR_ELT(r_block, i), BasicBlock); 11 | sw->addCase(val, block); 12 | } 13 | return(ScalarLogical(TRUE)); 14 | } 15 | -------------------------------------------------------------------------------- /src/JITEventListener.h: -------------------------------------------------------------------------------- 1 | #include "Rllvm.h" 2 | 3 | #include 4 | 5 | class RFunctionJITEventListener : public llvm::JITEventListener { 6 | 7 | protected: 8 | SEXP expr; 9 | 10 | public: 11 | 12 | RFunctionJITEventListener(SEXP fun); 13 | 14 | #if LLVM_VERSION == 3 && LLVM_MINOR_VERSION > 5 15 | virtual void NotifyObjectEmitted(const llvm::object::ObjectFile &Obj, 16 | const llvm::RuntimeDyld::LoadedObjectInfo &L); 17 | 18 | /// NotifyFreeingObject - Called just before the memory associated with 19 | /// a previously emitted object is released. 20 | // virtual void NotifyFreeingObject(const llvm::object::ObjectFile &Obj); 21 | #else 22 | 23 | #if LLVM_VERSION < 8 24 | virtual void NotifyFunctionEmitted(const llvm::Function &, 25 | void *, size_t, 26 | const EmittedFunctionDetails &); 27 | #endif 28 | 29 | #endif 30 | }; 31 | -------------------------------------------------------------------------------- /src/Makevars.in: -------------------------------------------------------------------------------- 1 | LLVM_CONFIG=@LLVM_CONFIG@ 2 | 3 | # -fexceptions 4 | LLVM_CFLAGS=@LLVM_CFLAGS@ 5 | PKG_CPPFLAGS= -DLLVM_VERSION=@LLVM_VERSION@ -DLLVM_MINOR_VERSION=@LLVM_MINOR_VERSION@ -DLLVM_VERSION_NUMBER=@LLVM_VERSION_NUMBER@ @NEW_LLVM_ATTRIBUTES_SETUP@ @LLVM_DATALAYOUT_H_IN_IR@ $(LLVM_CFLAGS) 6 | PKG_CXXFLAGS= $(shell $(LLVM_CONFIG) --cxxflags | sed -e 's/-O[0-9]//g') 7 | ALL_LIBS:= $(shell $(LLVM_CONFIG) --ldflags) $(ALL_LIBS) 8 | PKG_LIBS=$(shell $(LLVM_CONFIG) --ldflags --libs @LLVM_SYS_LIBS@) @FFI_LIB@ 9 | 10 | # /usr/lib 11 | # -lstdc++ 12 | SHLIB_CXXLDFLAGS:=$(shell $(LLVM_CONFIG) --ldflags) $(SHLIB_CXXLDFLAGS) 13 | 14 | # -lLLVMSystem 15 | 16 | #Rllvm@SHLIB_EXT@: 17 | #Rllvm.so: 18 | 19 | #RLLVMClassName.o: llvm_classof_name.h 20 | #types.o: llvm_type_classof_name.h 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/MyMake: -------------------------------------------------------------------------------- 1 | SRC=$(shell ls *.cpp) 2 | OBJ=$(patsubst %.cpp,%.o,$(SRC)) 3 | 4 | all: $(OBJ) 5 | 6 | %.o: %.cpp Makevars 7 | -R CMD COMPILE $< 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Rcast.cpp: -------------------------------------------------------------------------------- 1 | #include "Rllvm.h" 2 | 3 | extern "C" 4 | SEXP 5 | R_castGenericInstruction(SEXP r_ptr, SEXP r_targetClass) 6 | { 7 | const char *targetClass = CHAR(STRING_ELT(r_targetClass, 0)); 8 | void *ans = NULL; 9 | void *ptr = getRReference(r_ptr); 10 | 11 | //Use isa or llvm's classof() ? 12 | #include "autoCastCode.h" 13 | 14 | return(ans ? R_createRef(ans, targetClass) : R_NilValue); 15 | } 16 | -------------------------------------------------------------------------------- /src/Triple.cpp: -------------------------------------------------------------------------------- 1 | #include "Rllvm.h" 2 | 3 | #ifdef LLVM_TRIPLE_H_IN_TARGET_PARSER 4 | #include 5 | #else 6 | #include 7 | #endif 8 | 9 | SEXP R_Triple_setTriple(SEXP r_obj, SEXP r_Str) 10 | { 11 | llvm::Triple *obj = GET_REF(r_obj, Triple); 12 | // llvm::Twine Str; 13 | // Str = makeTwine(r_Str); 14 | obj->setTriple(makeTwine(r_Str)); 15 | return(R_NilValue); 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/Twine.cpp: -------------------------------------------------------------------------------- 1 | #include "Rllvm.h" 2 | 3 | llvm::Twine 4 | makeTwine(SEXP val) 5 | { 6 | return(llvm::Twine(CHAR(STRING_ELT(val, 0)))); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /src/classof.cpp: -------------------------------------------------------------------------------- 1 | #include "Rllvm.h" 2 | 3 | extern "C" 4 | SEXP 5 | R_Instruction_classof(SEXP r_val, SEXP r_targetClass) 6 | { 7 | const llvm::Value *val = GET_REF(r_val, Value); 8 | const char *targetClass = CHAR(STRING_ELT(r_targetClass, 0)); 9 | int ans = 0; 10 | 11 | #include "auto_classof.h" 12 | else 13 | return(ScalarLogical(NA_LOGICAL)); 14 | 15 | return(ScalarLogical(ans)); 16 | } 17 | -------------------------------------------------------------------------------- /src/getOpcodeNames.cpp: -------------------------------------------------------------------------------- 1 | #include "Rllvm.h" 2 | 3 | extern "C" 4 | SEXP 5 | R_getOpcodeNames(SEXP r_opcodes) 6 | { 7 | int len = Rf_length(r_opcodes); 8 | SEXP names; 9 | PROTECT(names = NEW_CHARACTER(len)); 10 | for(int i = 0; i < len; i++) { 11 | const char *id = llvm::Instruction::getOpcodeName(INTEGER(r_opcodes)[i]); 12 | SET_STRING_ELT(names, i, id ? mkChar(id) : R_NaString); 13 | } 14 | SET_NAMES(r_opcodes, names); 15 | UNPROTECT(1); 16 | return(r_opcodes); 17 | } 18 | -------------------------------------------------------------------------------- /src/memory.c: -------------------------------------------------------------------------------- 1 | #if 0 2 | static int zero = 0; 3 | #else 4 | #include 5 | 6 | /* 7 | We'll do this for Module for now. 8 | Each time we return the module, a function or global variable, we increment the count. 9 | */ 10 | typedef struct MemContainerStatus { 11 | const void *id; 12 | unsigned int count; 13 | struct TUStatus *next; 14 | struct TUStatus *prev; 15 | } MemContainerStatus; 16 | 17 | MemContainerStatus *memTable = NULL; 18 | #endif 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/runif.cpp: -------------------------------------------------------------------------------- 1 | #if 0 2 | 3 | #include 4 | 5 | extern "C" 6 | double 7 | runif() 8 | { 9 | double val = (double) random(); 10 | return(val/2147483647.); 11 | } 12 | #else 13 | static int noop = 0; 14 | #endif 15 | -------------------------------------------------------------------------------- /src/stream.cpp: -------------------------------------------------------------------------------- 1 | #include "Rllvm.h" 2 | #include 3 | 4 | /* 5 | buffer_ostream is a subclass of raw_svector_ostrea 6 | */ 7 | 8 | extern "C" 9 | SEXP 10 | R_raw_svector_ostream() 11 | { 12 | llvm::SmallString<10000> *Str = new llvm::SmallString<10000>; 13 | llvm::raw_svector_ostream *stream = new llvm::raw_svector_ostream(*Str); 14 | return(R_createRef(stream, "raw_svector_ostream", "native symbol")); // XXX need finalizer. Need to free Str also. 15 | } 16 | 17 | extern "C" 18 | SEXP 19 | R_raw_svector_ostream_as_character(SEXP r_obj) 20 | { 21 | llvm::raw_svector_ostream *stream = GET_REF(r_obj, raw_svector_ostream); 22 | return(ScalarString( mkCharLen( stream->str().data(), stream->str().size() ))); 23 | } 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /tests/1bit.cc: -------------------------------------------------------------------------------- 1 | 2 | extern "C" 3 | bool 4 | h(bool x) 5 | { 6 | return( !x ); 7 | } 8 | -------------------------------------------------------------------------------- /tests/GNUmakefile.docs: -------------------------------------------------------------------------------- 1 | ifndef DYN_DOCS 2 | DYN_DOCS=$(HOME)/GitWorkingArea/XDynDocs/inst 3 | endif 4 | 5 | include $(DYN_DOCS)/Make/Makefile 6 | -------------------------------------------------------------------------------- /tests/addOne.R: -------------------------------------------------------------------------------- 1 | # This shows the assembler code for a very simple routine we generate 2 | # addOne(int n) { 3 | # return(n + 1) 4 | # } 5 | 6 | library(Rllvm) 7 | 8 | m = Module() 9 | f = Function("addOne", Int32Type, list(x = Int32Type), module = m) 10 | 11 | x = getParameters(f)[[1]] 12 | b = Block(f) 13 | ir = IRBuilder(b) 14 | ir$createReturn(ir$binOp(BinaryOps["Add"], x, createConstant(ir, 1L, Int32Type))) 15 | 16 | print(showModule(m)) 17 | 18 | # Check the code does what we think 19 | #sapply(c(1, 10, 12), function(x) .llvm(f, x)) 20 | 21 | 22 | # We need to specify the data layout string 23 | str = getDataLayoutString() 24 | setDataLayout(m, str) 25 | getDataLayout(m) 26 | 27 | showModule(m) 28 | 29 | print(getAssemblyCode(m)) 30 | 31 | # Check the code does what we think 32 | i = c(1, 10, 12) 33 | ans = sapply(i, function(x) .llvm(f, x)) 34 | stopifnot(all(ans == i + 1L)) 35 | 36 | # Add the triple identifying the platform. 37 | setTargetTriple(m, getDefaultTargetTriple()) 38 | showModule(m) 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/bitWidth.R: -------------------------------------------------------------------------------- 1 | 2 | library(Rllvm) 3 | InitializeNativeTarget() 4 | mod = Module("global") 5 | 6 | mod[["l"]] = TRUE 7 | mod[["i"]] = 101L 8 | 9 | stopifnot( getIntegerBitWidth(getElementType(getType(mod[["l"]]))) == 1 ) 10 | stopifnot( getIntegerBitWidth(getElementType(getType(mod[["i"]]))) == 32L ) 11 | 12 | # 1 and 32 13 | 14 | -------------------------------------------------------------------------------- /tests/blockSubset.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | # See clang.c in this tests/ directory. This needs the clang-c include files from libclang. 3 | m = parseIR("clang.ir") 4 | b = getBlocks(m$foo)$entry 5 | b[["val"]] 6 | b[["%val"]] 7 | b[ c("data.addr", "%val")] # gets both, fixing the % in val. 8 | try(b[[ I("%val")]]) # Fails. Now gives NULL 9 | b[ I(c("data.addr", "%val"))] # gets first one 10 | 11 | -------------------------------------------------------------------------------- /tests/bob.c: -------------------------------------------------------------------------------- 1 | double 2 | foo(double x, double y, double z) 3 | { 4 | double tmp = x * y; 5 | return(tmp + z); 6 | } 7 | -------------------------------------------------------------------------------- /tests/branchAccessOrder.c: -------------------------------------------------------------------------------- 1 | int 2 | foo(int x, int y) 3 | { 4 | if((x + y) < 0 & y > 10) { 5 | return(x + 2*y); 6 | } else { 7 | return(10*x + 3*y); 8 | } 9 | } 10 | 11 | 12 | int 13 | bar(int x, int y) 14 | { 15 | if(x < 0) { 16 | return(x + 2*y); 17 | } else { 18 | return(10*x + 3*y); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/byVal.R: -------------------------------------------------------------------------------- 1 | # This illustrates creating a routine that is called with 2 structures passed by value not as pointers to a struct instance. 2 | 3 | library(Rllvm) 4 | 5 | mod = Module() 6 | CXCursorType = structType(list(kind = Int32Type, xdata = Int32Type, data = arrayType(pointerType(Int8Type), 3L)), "CXCursor") 7 | 8 | gn = Function("clang_CXCursor_getKind", StringType, list(CXCursorType, Int32Type, pointerType(Int32Type), pointerType(CXCursorType)), module = mod) 9 | gn[[1]] 10 | 11 | byVal(gn[[1]]) # TRUE 12 | byVal(gn[[4]]) # FALSE 13 | 14 | a = gn[[4]] 15 | byVal(a) = TRUE 16 | 17 | # The following causes problems as there is no method for [[<-(gn, 4) 18 | #XXX Fix. 19 | # byVal(gn[[4]]) = TRUE 20 | 21 | # These two are FALSE. 22 | byVal(gn[[2]]) 23 | byVal(gn[[3]]) 24 | 25 | -------------------------------------------------------------------------------- /tests/cfg.c: -------------------------------------------------------------------------------- 1 | 2 | int 3 | Switch(int x, int y) 4 | { 5 | int ans = -1; 6 | switch(x) { 7 | case 1: 8 | ans = 10; 9 | y += 1; 10 | break; 11 | case 2: 12 | ans = 3; 13 | y += 2; 14 | break; 15 | case 3: 16 | ans = 101; 17 | y += 10; 18 | break; 19 | } 20 | 21 | ans += y; 22 | 23 | return(ans); 24 | } 25 | -------------------------------------------------------------------------------- /tests/cifVoidPtr.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = parseIR("cifVoidPtr.ir") 3 | ee = ExecutionEngine(m) 4 | 5 | str = .llvm(m$getX, .ee = ee) 6 | stopifnot(class(str) == "character") 7 | 8 | ptr = .llvm(m$getX, .ee = ee, .asPointer = TRUE) 9 | 10 | stopifnot(class(ptr) == "externalptr") 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/cifVoidPtr.c: -------------------------------------------------------------------------------- 1 | int abc = 1; 2 | void *x = &abc; 3 | 4 | void * 5 | getX() 6 | { 7 | return(x); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /tests/clang.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int 4 | foo(CXCursor cur, CXCursor parent, void *data) 5 | { 6 | enum CXCursorKind val = clang_getCursorKind(cur); 7 | 8 | return(2); 9 | } 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/clone.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | source('createGlobal.R') 4 | 5 | # Each time we create a new ExecutionEngine, we effectively reinitialize the 6 | # value of the global variable gv to -101 7 | 8 | # Note there is foo and get. foo() increments. get just retrieves the current value. 9 | ee = ExecutionEngine(mod) 10 | #finalizeEngine(ee) 11 | start = run(mod$get, .ee = ee) 12 | replicate(3, run(mod$foo, .ee = ee)) 13 | end = run(mod$get, .ee = ee) 14 | 15 | m2 = clone(mod) 16 | message("*** cloned module **") 17 | showModule(m2) 18 | 19 | cur = run(mod$get, .ee = ee) 20 | 21 | 22 | ee2 = ExecutionEngine(m2) 23 | #finalizeEngine(ee2) 24 | start = run(m2$get, .ee = ee2) # Note that this is -101 25 | replicate(20, run(m2$foo, .ee = ee2)) 26 | end = run(m2$get, .ee = ee2) 27 | 28 | # original module 29 | orig = run(mod$get, .ee = ee) 30 | 31 | stopifnot(end != orig) 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /tests/clone2.R: -------------------------------------------------------------------------------- 1 | # Not clear we need this test as it certainly does nothing with clone(). 2 | 3 | library(XML) 4 | # invisible(xmlSource("../explorations/fgets.Rdb", xpath = "//r:code[@thread='manual']")) 5 | 6 | doc = xmlParse("../explorations/fgets.Rdb") 7 | ans = xpathSApply(doc, "//r:code[@thread = 'manual']", XML:::evalNode) 8 | 9 | 10 | # library(RCurl) 11 | # Using RCurl::CFILE() as that is a simple way to get a FILE * 12 | f = RCurl::CFILE("clone2.R") 13 | .llvm(mod$Fgets, f@ref)# , .ee = ee) 14 | .llvm(mod$Fgets, f@ref) #, .ee = ee) 15 | 16 | getGlobalValue(mod[[".str"]], ee) 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/cloneFunction2.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m1 = parseIR(system.file("IR", "fib.ll", package = "Rllvm")) 4 | #stopifnot(.llvm(m1$fib, 10) == 55) 5 | 6 | m2 = Module("other") 7 | f2 = Function("fib2", getReturnType(m1$fib), lapply(getParameters(m1$fib), getType), module = m2) 8 | .Call("R_CloneFunctionInto", m1$fib, f2, FALSE) 9 | 10 | stopifnot(verifyModule(m2)) 11 | stopifnot(.llvm(f2, 10) == 55) 12 | 13 | -------------------------------------------------------------------------------- /tests/cloneFunction3.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m1 = parseIR(system.file("IR", "fib.ll", package = "Rllvm")) 4 | stopifnot(.llvm(m1$fib, 10) == 55) 5 | 6 | m2 = Module("other") 7 | copyFunction(m1$fib, m2, "f", body = TRUE) 8 | #m2$f = m1$fib would not copy the body, only the declaration. 9 | 10 | stopifnot(verifyModule(m2)) 11 | stopifnot(.llvm(m2$f, 10) == 55) 12 | -------------------------------------------------------------------------------- /tests/coerceArgs.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = parseIR("coerceArgs.ir") 3 | 4 | .llvm(m$f, 3) 5 | # 3L is being passed to the routine as 0.0000 6 | # We can add a puts() to see this. 7 | # or identical(.llvm(m$f, 3L), 1) is TRUE 8 | stopifnot(identical(.llvm(m$f, 3L), .llvm(m$f, 3))) 9 | 10 | 11 | # Now coercing a numeric to a int 12 | stopifnot(identical(.llvm(m$i, 3L), .llvm(m$i, 3))) 13 | 14 | 15 | stopifnot(identical(.llvm(m$b, TRUE), .llvm(m$b, 1))) 16 | 17 | stopifnot(identical(.llvm(m$b2, TRUE), .llvm(m$b2, 1))) 18 | 19 | stopifnot(identical(.llvm(m$b0, 0), FALSE)) 20 | stopifnot(identical(.llvm(m$b0, 1), TRUE)) 21 | stopifnot(identical(.llvm(m$b0, 10L), TRUE)) 22 | stopifnot(identical(.llvm(m$b0, 2L), TRUE)) 23 | stopifnot(identical(.llvm(m$b0, 11L), TRUE)) 24 | 25 | 26 | 27 | stopifnot(identical(.llvm(m$b2, 10L) , 1L)) 28 | 29 | -------------------------------------------------------------------------------- /tests/coerceArgs.c: -------------------------------------------------------------------------------- 1 | 2 | double f(double x) 3 | { 4 | return(x + 1); 5 | } 6 | 7 | 8 | int i(int x) 9 | { 10 | return(x + 1); 11 | } 12 | 13 | 14 | #include 15 | 16 | bool b(bool x) 17 | { 18 | return(!x); 19 | } 20 | 21 | bool b0(bool x) 22 | { 23 | return(x); 24 | } 25 | 26 | int b2(bool x) 27 | { 28 | return((int) x); 29 | } 30 | -------------------------------------------------------------------------------- /tests/context.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | 4 | m = Module("foo") 5 | foo = Function("foo", Int32Type, module = m) 6 | b = Block(foo, "bob") 7 | 8 | ir = IRBuilder(b) 9 | 10 | #ir$createRet(1L) # Doesn't work. Need to create the constant. 11 | ir$createRet(createConstant(ir, 1L)) 12 | -------------------------------------------------------------------------------- /tests/cumsum.c: -------------------------------------------------------------------------------- 1 | void 2 | Cumsum(double *x, double *ans, int *len) 3 | { 4 | int i; 5 | ans[0] = x[0]; 6 | for(i = 1; i < *len; i++) 7 | ans[i] = ans[i-1] + x[i]; 8 | } 9 | -------------------------------------------------------------------------------- /tests/datalayout.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = Module() 3 | dl = getDataLayout(m, TRUE) 4 | 5 | isLittleEndian(dl) 6 | 7 | getPointerSize(dl) 8 | 9 | getStackAlignment(dl) 10 | 11 | getTypeAllocSize(dl, Int32Type) 12 | getTypeAllocSize(dl, DoubleType) 13 | 14 | 15 | getABITypeAlignment(dl, Int32Type) 16 | getABITypeAlignment(dl, DoubleType) 17 | 18 | ty = structType(list(a = Int32Type, b = DoubleType, c = getIntegerType(2)), "bob") 19 | 20 | # Fail - seq fault. Okay for LLVM 11.0 (Dec 25, 2020) 21 | getABITypeAlignment(dl, ty) 22 | 23 | # Fail. Okay for LLVM 11.0 (Dec 25, 2020) 24 | getTypeAllocSize(dl, ty) 25 | 26 | # Fail - Okay for LLVM 11.0 (Dec 25, 2020) 27 | getPointerTypeSize(dl, pointerType(Int32Type)) 28 | -------------------------------------------------------------------------------- /tests/dist.c: -------------------------------------------------------------------------------- 1 | 2 | #define EL(a, i, j) a[ n1 * i + j] 3 | void 4 | dist(double *g1, double *g2, int n1, int n2, int p, int *ans, 5 | double (*f)(double *, double *, int , int , int )) 6 | { 7 | int i, j; 8 | for(i = 0; i < n1; i++) 9 | for(j = 0; j < i; j++) 10 | EL(ans, i, j) = EL(ans, j, i) = f(g1, g2, p, n1, n2); 11 | } 12 | -------------------------------------------------------------------------------- /tests/dlsym.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | a = dlsym("Rf_allocVector") 3 | 4 | stopifnot(!is.null(a) && !Rllvm:::isNativeNull(a)) 5 | 6 | e = try(dlsym("R_real", NULL), silent = TRUE) # fails because not in executable 7 | stopifnot(is(e, 'try-error')) 8 | 9 | if(!file.exists("real.so")) { 10 | # May need to clean real.o 11 | system("R CMD SHLIB real.c") 12 | } 13 | 14 | 15 | if(file.exists("real.so")) { 16 | 17 | a = dlsym("R_real", "real.so") 18 | 19 | stopifnot(!is.null(a)) 20 | 21 | dll = dyn.load("real.so") 22 | 23 | b = dlsym("R_real", dll[["handle"]]) 24 | 25 | stopifnot(identical(a, b)) 26 | } 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/emitCode.R: -------------------------------------------------------------------------------- 1 | # Show the assembler code generated from the fibonacci module. 2 | 3 | # Now in getAssemblyCode() function 4 | # 5 | 6 | library(Rllvm) 7 | 8 | mod = parseIR(system.file("IR", "fib.ll", package = "Rllvm")) 9 | pm = passManager(mod) # Regular pass manager, not FunctionPassManager 10 | 11 | 12 | machine = createTargetMachine() 13 | fstream = raw_svector_ostream() 14 | status = addPassesToEmitFile(machine, pm, fstream) #, Rllvm:::CGFT_AssemblyFile) 15 | 16 | run(pm, mod) 17 | 18 | txt = as(fstream, "character") 19 | cat(txt) 20 | 21 | 22 | # Function to do these steps. 23 | txt2 = getAssemblyCode(mod) 24 | 25 | 26 | # Sometimes there are strange characters at the end. 27 | # We are probably not ensuring C++ objects stay around. 28 | # This was done quickly as an experiment. Look at the R_raw_svector_otream 29 | # ?? Or do we need to put the \0 at the end of the string in the SmallVectorImpl.?? 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /tests/enums.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = parseIR(system.file("IR/enums.ir", package = "Rllvm")) 3 | pc = lapplyDebugInfoTypes(m, getElements)$PrimaryColor 4 | structure( sapply(pc, getValue) , names = sapply(pc, getName)) 5 | -------------------------------------------------------------------------------- /tests/ffi2.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | # This creates a simple function that takes an R object and returns it. 4 | 5 | f = Function("foo", SEXPType, list(x = SEXPType)) 6 | b = Block(f) 7 | ir = IRBuilder(b) 8 | ir$createRet(getParameters(f)$x) 9 | showModule(f) 10 | 11 | #debug(Rllvm:::.llvmFFI) 12 | .llvm(f, 1:3) 13 | .llvm(f, as.numeric(1:3)) 14 | .llvm(f, letters) 15 | 16 | -------------------------------------------------------------------------------- /tests/ffi_1bit.R: -------------------------------------------------------------------------------- 1 | # clang -O2 -S -emit-llvm -o 1bit.ir 1bit.cc 2 | library(Rllvm) 3 | 4 | m = parseIR("1bit.ir") 5 | verifyModule(m) 6 | 7 | # By changing the parameter and return type 8 | # the problem is in the parameter. 9 | # We are passing an INTSXP as a 1 bit integer. 10 | # Remember Rffi doesn't have a 1 bit integer. 11 | 12 | #debug(Rllvm:::.llvmFFI) 13 | #debug(Rffi::callCIF) 14 | .llvm(m$h, 1L) 15 | .llvm(m$h, 0L) 16 | -------------------------------------------------------------------------------- /tests/findCalledFunctions.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = parseIR("findCalledFuns.ir") 3 | funs = findCalledFunctions(m) 4 | 5 | if(FALSE) { 6 | mem = parseIR("~/R-4.1/build3/src/main/memory.ir") 7 | ari = parseIR("~/R-4.1/build3/src/main/arithmetic.ir") 8 | 9 | 10 | # in the debug 11 | # a = i[[1]] # from R_RunWeakRefFinalizerzlier 12 | # u = getAllUsers(a[[1]]) 13 | } 14 | -------------------------------------------------------------------------------- /tests/findCalledFuns.c: -------------------------------------------------------------------------------- 1 | 2 | int 3 | foo(int x) 4 | { 5 | return(x + 1); 6 | } 7 | 8 | int 9 | bar(int x) 10 | { 11 | return(x*2); 12 | } 13 | 14 | int 15 | other(int x) 16 | { 17 | return(x*3); 18 | } 19 | 20 | int 21 | opt(int n, int *x, int (*f)(int)) 22 | { 23 | int i; 24 | int ans; 25 | for(i = 0; i < n ; i++) { 26 | ans += f(x[i]); 27 | } 28 | return(ans); 29 | } 30 | 31 | 32 | int 33 | xdo(int n, int *data, int s) 34 | { 35 | 36 | int (*f)(int); 37 | 38 | f = s == 0 ? foo : bar; 39 | 40 | opt(n, data, other); 41 | 42 | return(opt(n, data, f)); 43 | } 44 | 45 | int 46 | either(int x, int s) 47 | { 48 | int ans; 49 | if(s < 1) 50 | ans = foo(x); 51 | else 52 | ans = bar(x); 53 | 54 | return(ans); 55 | } 56 | 57 | 58 | -------------------------------------------------------------------------------- /tests/foo.c: -------------------------------------------------------------------------------- 1 | int 2 | foo() 3 | { 4 | return(20); 5 | } 6 | -------------------------------------------------------------------------------- /tests/fooBlocks.c: -------------------------------------------------------------------------------- 1 | 2 | int 3 | foo(int n, int *y) 4 | { 5 | if(n < 0) 6 | n = -n; 7 | for(int i = 0; i < n; i++) 8 | y[i] = y[i]*2; 9 | 10 | return(n); 11 | } 12 | 13 | 14 | int 15 | bar(int n, int *x) 16 | { 17 | int y; 18 | for(int i = 0; i < n; i++) { 19 | if(*x < 0) 20 | y = -1; 21 | else if(*x == 0) 22 | y = 0; 23 | else { 24 | y = 1; 25 | i++; 26 | } 27 | } 28 | y = y*2; 29 | return(y); 30 | } 31 | -------------------------------------------------------------------------------- /tests/fpConstant.R: -------------------------------------------------------------------------------- 1 | # test the creation of floating point constants. 2 | library(Rllvm) 3 | InitializeNativeTarget() 4 | mod = Module("dotC") 5 | 6 | fun = Function("foo", DoubleType, module = mod) 7 | 8 | b = Block(fun, "entry") 9 | ir = IRBuilder(b) 10 | 11 | k = createDoubleConstant(.5) 12 | ir$createRet(k) 13 | 14 | showModule(mod) 15 | .llvm(fun) 16 | -------------------------------------------------------------------------------- /tests/funcAttributes.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | # Note that reading ll/ir or bitcode generated with llvm 3.3 4 | # into Rllvm using 3.2 will probably cause an assertion and termination 5 | 6 | 7 | # Works with 3.3 8 | m = parseIR(system.file("IR", "add.ll", package = "Rllvm")) 9 | getFuncAttributes(m[["foo"]]) 10 | setFuncAttributes(m[["foo"]], Rllvm:::NoCapture) 11 | getFuncAttributes(m[["foo"]]) 12 | 13 | 14 | m = Module() 15 | f = Function('foo', Int32Type, Int32Type, m) 16 | getFuncAttributes(m[["foo"]]) 17 | setFuncAttributes(m[["foo"]], "NoCapture") 18 | getFuncAttributes(m[["foo"]]) 19 | 20 | 21 | # distance.ir is from an old version of LLVM. 22 | # Need to recreate via RLLVMCompile (or write the C code ourselves). 23 | m = parseIR(system.file("IR", "distance.ll", package = "Rllvm")) 24 | getFuncAttributes(m[["distance"]]) 25 | setFuncAttributes(m[["distance"]], "NoUnwind", "Alignment", "NoCapture") 26 | getFuncAttributes(m[["distance"]]) 27 | showModule(m) 28 | 29 | -------------------------------------------------------------------------------- /tests/gc.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | mod = parseIR(system.file("IR", "fib.ll", package = "Rllvm")) 4 | f = mod$fib 5 | 6 | gctorture(TRUE) 7 | rm(mod) 8 | rm(f) 9 | 10 | gctorture(FALSE) 11 | -------------------------------------------------------------------------------- /tests/gep.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | module = Module() 4 | fun = Function("fun", VoidType, list(), module = module) 5 | entry = Block(fun, "entry") 6 | builder = IRBuilder(entry) 7 | 8 | data_struct = Rllvm::structType(list(), "data", withNames = FALSE) 9 | 10 | x = createAlloc(builder, Rllvm::arrayType(data_struct, 3L), id = "x") 11 | 12 | #x_id = createGEP(builder, x, createIntegerConstant(0L), "xxx") 13 | -------------------------------------------------------------------------------- /tests/getUses.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m = parseIR(system.file("IR", "fib.ll", package = "Rllvm")) 4 | b = getBlocks(m$fib) 5 | length(b) 6 | sapply(b, getName) 7 | 8 | 9 | m1 = parseIR(system.file("IR", "add.ll", package = "Rllvm")) 10 | names(getBlocks(m1$foo)) 11 | b = getBlocks(m1$foo)[[ 1 ]] 12 | 13 | getAllUses( b[[2]] ) 14 | 15 | getAllUsers( b[[2]] ) 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/global.R: -------------------------------------------------------------------------------- 1 | # This comes from globalVars.Rdb during a debugging session. 2 | 3 | library(Rllvm) 4 | InitializeNativeTarget() 5 | 6 | source('createGlobal.R') 7 | 8 | # we need to use the same ExecEngine 9 | # or else we will end up with independent 10 | # instances of the global variable! 11 | ee = ExecutionEngine(mod) 12 | run(getGV, .ee = ee) 13 | run(fun, .ee = ee) 14 | print(replicate(3, run(fun, .ee = ee))) 15 | 16 | -------------------------------------------------------------------------------- /tests/globalAccessors.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m = Module() 4 | g = createGlobalVariable("x", m, val = 2L) 5 | 6 | source("../R/createAccessors.R") 7 | funs = createAccessors(m[['x']]) 8 | 9 | ee = ExecutionEngine(m) 10 | .llvm(m$getx, .ee = ee) 11 | .llvm(m$setx, 11, .ee = ee) 12 | .llvm(m$getx, .ee = ee) 13 | 14 | funs$get(ee) 15 | funs$set(ee, 20) 16 | funs$get(ee) 17 | 18 | # how do we make 19 | # ee[["x"]] or ee$x 20 | # use these accessors 21 | # And can we use getGlobalValueAddress and LoadValueFromMemory 22 | # methods in ExecutionEngine to do this generically. 23 | 24 | # Note ee$x goes to some very odd method! 25 | 26 | -------------------------------------------------------------------------------- /tests/globalArrays.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = Module() 3 | ty = arrayType(Int32Type, 100) 4 | m[["i"]] = ty 5 | setInitializer(m[["i"]], constantAggregateZero(ty)) 6 | 7 | ty = arrayType(DoubleType, 99) 8 | m[["d"]] = ty 9 | setInitializer(m[["d"]], constantAggregateZero(ty)) 10 | 11 | ee = ExecutionEngine(m) 12 | i = m[["i", ee = ee]] 13 | d = m[["d", ee = ee]] 14 | 15 | print(length(i)) 16 | print(length(d)) 17 | 18 | # Use a different initializer 19 | 20 | ty = arrayType(DoubleType, 10) 21 | m[["o"]] = ty 22 | 23 | 24 | #XXX 25 | # setInitializer(m[["dd"]], createConstant(3.1415)) 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/globalGet.R: -------------------------------------------------------------------------------- 1 | # This comes from globalVars.Rdb during a debugging session. 2 | 3 | library(Rllvm) 4 | InitializeNativeTarget() 5 | mod = Module("global") 6 | 7 | id = "gv" 8 | 9 | one = createIntegerConstant(-101L) 10 | # The object structure is getting removed and only the externalptr is being seen by createGlobalVariable 11 | gvar = createGlobalVariable(id, val = one, mod = mod, type = Int32Type) 12 | 13 | mod[["l"]] = TRUE 14 | mod[["r"]] = pi 15 | mod[["i"]] = 101L 16 | 17 | ee = ExecutionEngine(mod) 18 | getGlobalValue(mod[[id]], ee) 19 | mod[[id, value = TRUE]] 20 | 21 | mod[["i", value = TRUE]] 22 | mod[["l", value = TRUE]] 23 | mod[["r", value = TRUE]] 24 | 25 | lapply(c("l", "r", "i"), 26 | function(id) 27 | getGlobalValue(mod[[id]], ee)) 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/globalSet.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | InitializeNativeTarget() 3 | mod = Module("global") 4 | 5 | mod[["r"]] = pi 6 | mod[["r", value = TRUE]] 7 | 8 | showModule(mod) 9 | 10 | mod[["r"]] = 2 * pi 11 | mod[["r", value = TRUE]] 12 | 13 | showModule(mod) 14 | -------------------------------------------------------------------------------- /tests/globalStruct.c: -------------------------------------------------------------------------------- 1 | struct S { 2 | int i; 3 | double d; 4 | }; 5 | 6 | struct S s; 7 | 8 | void seti(int i) 9 | { 10 | s.i = i; 11 | } 12 | 13 | int geti() 14 | { 15 | return(s.i); 16 | } 17 | -------------------------------------------------------------------------------- /tests/globalVarInit.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | InitializeNativeTarget() 3 | mod = Module("global") 4 | mod[["status"]] = TRUE 5 | cat("Initial value\n") 6 | showModule(mod) 7 | setInitializer(mod[["status"]], createLogicalConstant(FALSE)) 8 | cat("Second value\n") 9 | showModule(mod) 10 | mod[["status"]] = TRUE 11 | 12 | cat("Third value\n") 13 | showModule(mod) 14 | -------------------------------------------------------------------------------- /tests/globalVariable.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = parseIR("../AnalyzeCCode/simple.ll") 3 | a = getValue(m[[".str.2"]]) 4 | stopifnot(a == "xyz") 5 | b = getValue(m[[".str.1"]]) 6 | stopifnot(b == "bcde and fgh") 7 | 8 | names(m) 9 | ans = sapply(grep("^\\.str", names(m), value = TRUE), function(id) getValue(m[[id]])) 10 | stopifnot(identical(ans , c(".str" = "a", ".str.1" = "bcde and fgh", ".str.2" = "xyz"))) 11 | 12 | -------------------------------------------------------------------------------- /tests/globals.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | mod = Module("globalTest") 3 | 4 | mod[["l"]] = TRUE 5 | mod[["r"]] = pi 6 | mod[["i"]] = 101L 7 | 8 | names(mod) 9 | mod[["l"]] 10 | mod[["r"]] 11 | mod[["i"]] 12 | 13 | ee = ExecutionEngine(mod) 14 | mod[["l", ee = ee]] 15 | 16 | mod[c("r", "i")] 17 | 18 | if(FALSE && require(RLLVMCompile)) { 19 | # Adding a function to the module and then the same function 20 | # but with a different name. 21 | f = function() { return(10.4) } 22 | fc = compileFunction(f, DoubleType, mod = mod) 23 | fc = compileFunction(f, DoubleType, mod = mod, name = "g") 24 | 25 | print(names(mod)) 26 | } 27 | -------------------------------------------------------------------------------- /tests/insertElement.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = Module() 3 | f = Function("foo", DoubleType, list(i = Int32Type, arr = pointerType(DoubleType)), module = m) 4 | b = Block(f) 5 | ir = IRBuilder(b) 6 | 7 | # just checking ir$createReturn(makeConstant(ir, 2.3)) 8 | 9 | p = getParameters(f) 10 | v2 = ir$createGEP(p$arr, 0L) 11 | ir$createReturn(ir$createLoad(v2)) 12 | 13 | 14 | if(FALSE) { 15 | # Skip the last two lines above - createGEP & createReturn(createLoad()) 16 | v = ir$createLoad(p$arr) 17 | #v2 = ir$createExtractElement(v, 1L) 18 | #v2 = ir$createExtractElement(v, makeConstant(ir, 1L)) 19 | v2 = ir$createGEP(p$arr, c(0L, 1L)) 20 | ir$createReturn(ir$createLoad(v2)) 21 | } 22 | -------------------------------------------------------------------------------- /tests/jitevents.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = parseIR(system.file("IR", "fib.ll", package = "Rllvm")) 3 | ee = ExecutionEngine(m) 4 | 5 | evHandler = function(obj, info) { cat("In event handler for JIT Events\n")} 6 | 7 | .Call("R_ExecutionEngine_RegisterJITEventListener", ee, evHandler) 8 | 9 | finalizeEngine(ee) 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/loop2.R: -------------------------------------------------------------------------------- 1 | if(FALSE) { 2 | 3 | # See LoopInfoTest.cpp in llvm/unittests/Analysis. 4 | library(Rllvm) 5 | m2 = parseIR("looptest.ir") 6 | 7 | h = .Call("R_getLoopAnalysis", m2$bar) 8 | 9 | lbar = getLoops(m2$bar)[[1]] 10 | 11 | # Canonical IV. 12 | getInductionVariable(lbar) 13 | 14 | blocks = getBlocks(m2$bar) 15 | lpInfo = getLoopInfo(m2$bar) 16 | lp = getLoopFor(lpInfo, blocks[[3]]) 17 | 18 | isGuarded(lbar) 19 | guard = getGuardBranch(lp) 20 | getGuardBranch(lbar) 21 | 22 | stopifnot(identical(guard, getTerminator(blocks[[1]]))) 23 | 24 | isRotatedForm(lp) 25 | 26 | 27 | # Returning NULL 28 | dtree = as(m2$bar, "DominatorTree") 29 | .Call("R_Loop_getInductionVariable2", lbar, dtree, m2$bar) 30 | 31 | 32 | se = .Call("R_mkScalarEvolution", m2$bar, as(dtree, "LoopInfo"), dtree) 33 | .Call("R_Loop_getBounds", lbar, se) 34 | 35 | 36 | .Call("R_Loop_getBounds2", lbar, m2$bar) 37 | 38 | } 39 | -------------------------------------------------------------------------------- /tests/loop3.R: -------------------------------------------------------------------------------- 1 | if(FALSE) { 2 | 3 | library(Rllvm) 4 | setClass("LoopBounds", contains = "RC++Reference") 5 | m2 = parseIR("looptest.ir") 6 | 7 | h = .Call("R_getLoopAnalysis", m2$bar) 8 | 9 | lbar = getLoops(h[[2]])[[1]] 10 | 11 | b = .Call("R_Loop_getBounds_copy", lbar, h[[3]]) 12 | 13 | z = replicate(100, .Call("R_Loop_getBounds_copy", lbar, h[[3]])) 14 | 15 | 16 | if(FALSE) { 17 | b = .Call("R_Loop_getBounds", lbar, h[[3]]) 18 | 19 | .Call("R_LoopBounds_getInitialIVValue", b) 20 | .Call("R_LoopBounds_getFinalIVValue", b) 21 | 22 | 23 | .Call("R_LoopBounds_getCanonicalPredicate", b) 24 | } 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /tests/loop4.R: -------------------------------------------------------------------------------- 1 | if(FALSE) { 2 | 3 | library(Rllvm) 4 | #setClass("LoopBounds", contains = "RC++Reference") 5 | m2 = parseIR("looptest.ir") 6 | 7 | lp = getLoops(m2$bar)[[1]] 8 | 9 | dtree = as(m2$bar, "DominatorTree") 10 | se = .Call("R_mkScalarEvolution", m2$bar, as(dtree, "LoopInfo"), dtree) 11 | 12 | #NULL !!! 13 | b = .Call("R_Loop_getBounds_copy", lp, se) 14 | 15 | 16 | h = .Call("R_getLoopAnalysis", m2$bar) 17 | 18 | lbar = getLoops(h[[2]])[[1]] 19 | 20 | b = .Call("R_Loop_getBounds_copy", lbar, h[[3]]) 21 | 22 | z = replicate(100, .Call("R_Loop_getBounds_copy", lbar, h[[3]])) 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /tests/ls_module.c: -------------------------------------------------------------------------------- 1 | 2 | extern int foo; 3 | 4 | int bar; 5 | 6 | double pi = 3.1415; 7 | 8 | void fun1(); 9 | 10 | 11 | int 12 | fun2() 13 | { 14 | return(10); 15 | } 16 | 17 | 18 | double 19 | fun3() 20 | { 21 | return(2.0); 22 | } 23 | -------------------------------------------------------------------------------- /tests/mangle.R: -------------------------------------------------------------------------------- 1 | if(FALSE) { 2 | 3 | library(Rllvm) 4 | 5 | mod = Module() 6 | f = Function("foo", VoidType, list(Int32Type, Int32Type, DoubleType), mod) 7 | 8 | if(FALSE) { 9 | # Not needed anymore. 10 | # tri = getDefaultTargetTriple() 11 | # trgt = lookupTarget(tri) 12 | tm = createTargetMachine() # trgt, "", "") 13 | #!!! Deprecated as of 3.7. 14 | dl = getDataLayout(tm) 15 | } 16 | 17 | 18 | mangler = .Call("R_new_Mangler", NULL) 19 | nm1 = .Call("R_Mangler_getNameWithPrefix_GV", mangler, f, TRUE, TRUE) 20 | print(nm1) 21 | 22 | g = Function("bar", VoidType, list(DoubleType), mod) 23 | nm2 = .Call("R_Mangler_getNameWithPrefix_GV", mangler, g, TRUE, TRUE) 24 | print(c(nm1, nm2)) # pretty boring as these are the same, and the same as the names we gave them. 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /tests/mcjit.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = parseIR(system.file("IR", "fib.ll", package = "Rllvm")) 3 | ee = ExecutionEngine(m) # , Rllvm:::Aggressive) 4 | finalizeEngine(ee) 5 | 6 | .llvm(m$fib, 10L, .ee = ee) 7 | 8 | 9 | funptr = getPointerToFunction(m$fib, ee) 10 | 11 | n = 3:20 # the values 12 | N = 1e2L # number of repetitions of calling the routine. 13 | 14 | # Using the generated routine from our LLVM module. But R_test_mcjit_fib is 15 | # in the Rllvm package. 16 | tm1 = system.time(a <- .Call("R_test_mcjit_fib", n, funptr@ref, N)) 17 | # The pure C version from the Rllvm package. 18 | tm2 = system.time(b <- .Call("R_fib", n, N)) 19 | # This has the overhead of creating the ExecutionEngine and generating the code. 20 | tm3 = system.time(c <- .Call("R_runModule", m, n, N)) 21 | 22 | stopifnot(identical(a, b)) 23 | stopifnot(identical(a, c)) 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /tests/meta0.R: -------------------------------------------------------------------------------- 1 | # Seg faults. 2 | library(Rllvm) 3 | m = Module() 4 | 5 | setMetadata(m, "foo", "1L") 6 | md = getMetadata(m, "foo") 7 | getName(md) 8 | 9 | ops = getOperands(md) 10 | sapply(ops, class) # MDNode 11 | ops2 = getOperands(ops[[1]]) 12 | sapply(ops2, class) # Metadata 13 | ops2[[1]] 14 | 15 | 16 | z = getValue(md) 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/mkRFun.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | # f = "fib_basic.ll" 4 | f = system.file("IR", "fib.ll", package = "Rllvm") 5 | m1 = parseIR(f) 6 | 7 | f1 = makeRFunction(m1$fib) 8 | f1(10) 9 | 10 | saveRDS(f1, "fun.Rds") 11 | 12 | f2 = readRDS("fun.Rds") 13 | # If we call the function, this will recreate/instantiate the module. 14 | # If we don't, we'll get a segfault in all.equal() 15 | # f2(10) 16 | 17 | 18 | e1 = as.list(environment(f1), TRUE) 19 | e2 = as.list(environment(f2), TRUE) 20 | all(w <- mapply(identical, e1, e2)) 21 | 22 | all.equal(f1,f2) # Fixed now - seg faults! 23 | 24 | identical(f1, f2) # FALSE - different environments. 25 | 26 | f2(10) 27 | stopifnot(all.equal(f1, f2)) 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/moveInstructions.R: -------------------------------------------------------------------------------- 1 | # This is an example of moving instructions around. 2 | library(Rllvm) 3 | m = Module() 4 | f = Function("foo", VoidType, list(x = DoubleType), module = m) 5 | 6 | b = Block(f) 7 | ir = IRBuilder(b) 8 | 9 | i = ir$createLocalVariable(Int32Type, "i") 10 | j = ir$createLocalVariable(Int32Type, "j") 11 | ir$createStore(ir$createConstant(0L), i) 12 | ir$createStore(ir$createConstant(0L, Int32Type), j) 13 | l1 = ir$createLoad(i) 14 | l2 = ir$createLoad(j) 15 | 16 | 17 | ir$createReturn() 18 | print(showModule(m)) 19 | 20 | moveBefore(l1, j) 21 | print(showModule(m)) 22 | 23 | insertBefore(j, i) 24 | print(showModule(m)) 25 | 26 | insertAfter(j, i) 27 | print(showModule(m)) 28 | 29 | 30 | 31 | #ir$createLocalVariable 32 | 33 | 34 | -------------------------------------------------------------------------------- /tests/optimize.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | if(!file.exists("bob.ll")) 4 | system("make bob.ll") 5 | 6 | m = parseIR("bob.ll") 7 | 8 | fun = m$foo 9 | 10 | N = 10 11 | tm1 = system.time(replicate(N, .llvm(fun, 3, 12, 4))) 12 | 13 | ee = ExecutionEngine(m) 14 | tm2 = system.time(replicate(N, .llvm(fun, 3, 12, 4, .ee = ee))) 15 | 16 | Optimize(m, ee) 17 | fun = m$foo 18 | tm3 = system.time(replicate(N, .llvm(fun, 3, 12, 4, .ee = ee))) 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /tests/optimize2.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m = parseIR("bob.ll") 4 | 5 | #fun = m$foo 6 | 7 | showModule(m) 8 | 9 | ee = ExecutionEngine(m) 10 | mgr = getPassManager(m, ee, 3L) 11 | # addPass(mgr, .Call("R_createInstructionCombiningPass")) 12 | ## Eliminate Common SubExpressions. 13 | # addPass(mgr, .Call("R_createGVNPass")) 14 | # Reassociate expressions. 15 | addPass(mgr, .Call("R_createReassociatePass")) 16 | # Simplify the control flow graph (deleting unreachable blocks, etc). 17 | 18 | addPass(mgr, .Call("R_createDeadCodeEliminationPass")) 19 | addPass(mgr, .Call("R_createDeadStoreEliminationPass")) 20 | #createAggressiveDCEPass 21 | 22 | Optimize(m$foo, ee) 23 | Optimize(m$foo, passManager = mgr) 24 | 25 | showModule(m) 26 | 27 | 28 | Optimize(m, ee) 29 | fun = m$foo 30 | N = 1000 31 | tm3 = system.time(replicate(N, .llvm(fun, 3, 12, 4, .ee = ee))) 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /tests/paramAttributes.R: -------------------------------------------------------------------------------- 1 | # Note that reading ll/ir or bitcode generated with llvm 3.3 2 | # into Rllvm using 3.2 will probably cause an assertion and termination 3 | 4 | library(Rllvm) 5 | m = parseIR(system.file("IR", "distance.ll", package = "Rllvm")) 6 | showModule(m) 7 | 8 | # define double* @distance(double* %x, double* %y, i32 %nrow, i32 %ncol_x, i32 %ncol_y, double (double*, double*, i32, double)* %dist, i32 %p, double* %dists) #0 { 9 | 10 | setParamAttributes(m$distance[[1]], Rllvm:::FuncAttributes["NoCapture"]) 11 | setParamAttributes(m$distance[[1]], c("NoCapture", "NoAlias")) 12 | # define double* @distance(double* noalias nocapture %x, double* %y, i32 %nrow, i32 %ncol_x, i32 %ncol_y, double (double*, double*, i32, double)* %dist, i32 %p, double* %dists) #0 { 13 | 14 | showModule(m) 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tests/parseAssembler.R: -------------------------------------------------------------------------------- 1 | # parse content in IR format. 2 | library(Rllvm) 3 | 4 | # Code taken from llvmpy test/operands.py for convenience. 5 | tt = " 6 | define i32 @prod(i32, i32) { 7 | entry: 8 | %2 = mul i32 %0, %1 9 | ret i32 %2 10 | } 11 | 12 | define i32 @test_func(i32, i32, i32) { 13 | entry: 14 | %tmp1 = call i32 @prod(i32 %0, i32 %1) 15 | %tmp2 = add i32 %tmp1, %2 16 | %tmp3 = add i32 %tmp2, 1 17 | ret i32 %tmp3 18 | } 19 | " 20 | 21 | m = parseAssembly(tt, asText = TRUE) 22 | showModule(m) 23 | 24 | names(m) 25 | .llvm(m[["test_func"]], 2, 3, 7) # 14 = 2 * 3 + 7 + 1 26 | 27 | 28 | # 29 | # read into an existing module 30 | 31 | mod = Module("bob") 32 | mod = parseAssembly(tt, mod, asText = TRUE) 33 | showModule(mod) 34 | stopifnot(length(names(mod)) > 0) 35 | 36 | -------------------------------------------------------------------------------- /tests/postdominates.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | if(FALSE) { 4 | m = parseIR("fooBlocks.ll") 5 | ptree = PostDominatorTree(m$bar) 6 | b = getBlocks(m$bar) 7 | dominates(ptree, b[[length(b)]], b[[1]]) 8 | dominates(ptree, b[[length(b)]], b[[3]]) 9 | dominates(ptree, b[[2]], b[[3]]) 10 | postDominates(b[[2]], b[[3]]) 11 | } 12 | 13 | 14 | 15 | m = parseIR("sequentialCFG.ir") 16 | b = getBlocks(m$foo)[[1]] 17 | 18 | stopifnot(postDominates(b[[ length(b) - 1 ]], b[[ 10 ]] )) 19 | stopifnot(! postDominates( b[[4 ]], b[[ 10 ]] ) ) 20 | 21 | 22 | ptree = PostDominatorTree(m$foo) 23 | stopifnot(dominates(ptree, b[[ length(b) - 1 ]], b[[ 10 ]] )) 24 | stopifnot(!dominates(ptree, b[[4 ]], b[[ 10 ]] ) ) 25 | -------------------------------------------------------------------------------- /tests/readBitcode.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | source("tut1.R") # create a module 3 | cat(as(mod, "character"), file = "bob.ll") 4 | # now create the bitcode. 5 | # 6 | system("make bob.bc") 7 | m = readBitcode("bob.bc") 8 | print(names(m)) 9 | run(m$foo, 2, 10, 3) # 2*10 + 3 = 23 10 | unlink(c("bob.ll", "bob.bc")) 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/real.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | SEXP 4 | R_real() 5 | { 6 | return(Rf_allocVector(REALSXP, 2)); 7 | } 8 | 9 | SEXP 10 | R_real2() 11 | { 12 | return(NEW_NUMERIC(2)); 13 | } 14 | -------------------------------------------------------------------------------- /tests/run.r: -------------------------------------------------------------------------------- 1 | f = commandArgs(TRUE) 2 | e = new.env() 3 | source(f[1], e) 4 | 5 | f = commandArgs(TRUE) 6 | cat(f, "ok\n", file = "status.out", append = TRUE) 7 | q("no", status = 0) 8 | 9 | -------------------------------------------------------------------------------- /tests/rw1.R: -------------------------------------------------------------------------------- 1 | rw2d1 = 2 | function(n = 100) { 3 | xpos = ypos = numeric(n) 4 | truefalse = c(TRUE, FALSE) 5 | plusminus1 = c(1, -1) 6 | for(i in 2:n) { 7 | # Decide whether we are moving horizontally 8 | # or vertically. 9 | if (sample(truefalse, 1)) { 10 | xpos[i] = xpos[i-1] + sample(plusminus1, 1) 11 | ypos[i] = ypos[i-1] 12 | } 13 | else { 14 | xpos[i] = xpos[i-1] 15 | ypos[i] = ypos[i-1] + sample(plusminus1, 1) 16 | } 17 | } 18 | list(x = xpos, y = ypos) 19 | } 20 | 21 | rw2d5 = 22 | # Sample from 4 directions, not horizontally and verticallly 23 | # separately. 24 | function(n = 100000) { 25 | xsteps = c(-1, 1, 0, 0) 26 | ysteps = c( 0, 0, -1, 1) 27 | dir = sample(1:4, n - 1, replace = TRUE) 28 | xpos = c(0, cumsum(xsteps[dir])) 29 | ypos = c(0, cumsum(ysteps[dir])) 30 | list(x = xpos, y = ypos) 31 | } 32 | 33 | -------------------------------------------------------------------------------- /tests/rw2d.tm.1e7_Darwin.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/tests/rw2d.tm.1e7_Darwin.rda -------------------------------------------------------------------------------- /tests/rw2d.tm.1e7_Linux.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/tests/rw2d.tm.1e7_Linux.rda -------------------------------------------------------------------------------- /tests/rw2d.tm.1e7_lipschitz_Linux.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/tests/rw2d.tm.1e7_lipschitz_Linux.rda -------------------------------------------------------------------------------- /tests/rw2d.tm.1e7_lipschitz_Linux_gcc.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncantl/Rllvm/683177c5330dd161d9afb5b1f277d6fc008aa815/tests/rw2d.tm.1e7_lipschitz_Linux_gcc.rda -------------------------------------------------------------------------------- /tests/sameType.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | intPtrTypes = lapply(list(Int1Type, Int8Type, Int16Type, Int32Type, Int64Type), pointerType) 4 | names(intPtrTypes) = c(1, 8, 16, 32, 64) 5 | 6 | g = expand.grid(1:5, 1:5) 7 | ans = apply(g, 1, function(i) { 8 | a = intPtrTypes[[ i[1] ]] 9 | b = intPtrTypes[[ i[2] ]] 10 | sameType(a, b) 11 | }) 12 | 13 | w = g[,1] == g[,2] 14 | 15 | stopifnot(all(w == ans)) 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/sequentialCFG.c: -------------------------------------------------------------------------------- 1 | 2 | int 3 | foo(int x, int y) 4 | { 5 | int z = 2*x; 6 | int w = 2*y + z; 7 | int ans = z*10 + 6 + w * 100; 8 | return(ans); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /tests/setAttrs.R: -------------------------------------------------------------------------------- 1 | source("parseAssembler.R") 2 | f = m[['test_func']] 3 | a = getFuncAttributes(f) 4 | 5 | setFuncAttributes(f, "NoUnwind", "NoInline", "NoCapture") 6 | 7 | b = getFuncAttributes(f) 8 | a 9 | b 10 | 11 | -------------------------------------------------------------------------------- /tests/setGlobal.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | InitializeNativeTarget() 3 | mod = Module("global") 4 | 5 | 6 | mod[["gvpi"]] = pi 7 | mod[["gvint"]] = 13L 8 | 9 | mod[["status"]] = FALSE 10 | showModule(mod) 11 | getElementType(getType(mod[["gvpi"]])) 12 | mod[["gvpi", value = TRUE]] 13 | 14 | mod[["status", value = TRUE]] 15 | setInitializer(mod[["status"]], TRUE) # better approach. 16 | 17 | mod[["status"]] = TRUE 18 | showModule(mod) 19 | mod[["status", value = TRUE]] 20 | 21 | 22 | # creating status is equivalent to 23 | #createGlobalVariable("ll", mod, , as(FALSE, "Value")) 24 | -------------------------------------------------------------------------------- /tests/simpleFun.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | f = Function("foo", Int32Type) 3 | b = Block(f) 4 | ir = IRBuilder(b) 5 | ir$createReturn(createIntegerConstant(3)) 6 | showModule(f) 7 | verifyModule(f) 8 | ans = .llvm(f) 9 | stopifnot( ans == 3L ) 10 | 11 | 12 | library(Rllvm) 13 | m = Module() 14 | setTargetTriple(m, getDefaultTargetTriple()) 15 | f = Function("foo", Int32Type, list(Int32Type), module = m) 16 | b = Block(f) 17 | ir = IRBuilder(b) 18 | ir$createReturn(createIntegerConstant(3)) 19 | ans = .llvm(f, 1L) 20 | stopifnot( ans == 3L ) 21 | 22 | ee = ExecutionEngine(m) 23 | ptr = getPointerToFunction(f, ee) 24 | 25 | library(Rffi) 26 | cif = CIF(sint32Type, list(sint32Type)) 27 | 28 | ans = callCIF(cif, ptr@ref, 10L) 29 | stopifnot( ans == 3L ) 30 | -------------------------------------------------------------------------------- /tests/simplest.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m = Module("testing integer") 4 | foo = Function("foo", Int32Type, list(), module = m) 5 | entry = Block(foo, "entry") 6 | builder = IRBuilder(entry) 7 | createReturn(builder, createConstant(builder, 10L)) 8 | 9 | showModule(m) 10 | 11 | .llvm(foo) 12 | -------------------------------------------------------------------------------- /tests/store.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | #InitializeNativeTarget() 3 | 4 | mod = Module("tmp") 5 | 6 | fun = Function("foo", VoidType, list(a = DoubleType), module = mod) 7 | entry = Block(fun) 8 | ir = IRBuilder(entry) 9 | iv = ir$createLocalVariable(Int32Type, "i") 10 | 11 | one = createIntegerConstant(1L) 12 | ir$createStore( one, iv) 13 | 14 | ir$createReturn() 15 | 16 | showModule(mod, FALSE) 17 | 18 | -------------------------------------------------------------------------------- /tests/store1.R: -------------------------------------------------------------------------------- 1 | # compile a simple routine that returns an integer 2 | # and takes no arguments. It returns the value 3 | # we specify here in the code to generate the routine. 4 | 5 | library(Rllvm) 6 | InitializeNativeTarget() 7 | 8 | mod = Module("tmp") 9 | 10 | fun = Function("foo", Int32Type, module = mod) 11 | entry = Block(fun) 12 | ir = IRBuilder(entry) 13 | iv = ir$createLocalVariable(Int32Type, "i") 14 | 15 | one = createIntegerConstant(101L) 16 | ir$createStore( one, iv) 17 | 18 | r = ir$createLoad(iv) 19 | ir$createReturn(r) 20 | 21 | showModule(mod) 22 | 23 | print(run(fun)) 24 | 25 | -------------------------------------------------------------------------------- /tests/store2.R: -------------------------------------------------------------------------------- 1 | # compile a simple routine that returns an double 2 | # and takes no arguments. It returns the value 3 | # we specify here in the code to generate the routine. 4 | 5 | library(Rllvm) 6 | InitializeNativeTarget() 7 | 8 | mod = Module("tmp") 9 | 10 | fun = Function("foo", DoubleType, module = mod) 11 | entry = Block(fun) 12 | ir = IRBuilder(entry) 13 | iv = ir$createLocalVariable(DoubleType, "i") 14 | 15 | one = makeConstant(ir, 3.1415) 16 | ir$createStore( one, iv) 17 | 18 | r = ir$createLoad(iv) 19 | ir$createReturn(r) 20 | 21 | showModule(mod) 22 | 23 | print(run(fun)) 24 | 25 | -------------------------------------------------------------------------------- /tests/stringPointer2.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m = Module("test") 4 | ctx = as(m, "LLVMContext") 5 | ee = ExecutionEngine(m) 6 | 7 | # Create the global variable 8 | ty = pointerType(getIntegerType(8L, ctx)) 9 | gvar = createGlobalVariable("ptr", m, ty) 10 | 11 | # Create a constant 12 | txt = "Initial value of string" 13 | tmp = createGlobalVariable(".str", m, val = txt, constant = TRUE, linkage = PrivateLinkage) 14 | 15 | idx = createIntegerConstant(0L, ctx) 16 | p = getGetElementPtr(tmp, list(idx, idx), FALSE, ctx) 17 | setInitializer(gvar, p) 18 | 19 | x = getGlobalValue(m[["ptr"]], ee) 20 | 21 | print(x) 22 | 23 | -------------------------------------------------------------------------------- /tests/ternary.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | m = Module("bob") 3 | fun = Function("foo", Int32Type, list(n = Int32Type), module = m) 4 | ir = IRBuilder(Block(fun)) 5 | 6 | # 7 | # Return 1 if n < 3, otherwise 100 8 | # 9 | 10 | 11 | len = ir$createLocalVariable(Int32Type, "len") 12 | ir$createStore(getParameters(fun)$n, len) 13 | 14 | # Was ICMP_ULT for unsigned, but since we are accepting signed integers, use ICMP_SLT 15 | s = ir$createSelect( ir$createICmp(ICMP_SLT, ir$createLoad(len), createIntegerConstant(3)), createIntegerConstant(1L), createIntegerConstant(100L)) 16 | 17 | ir$createRet(s) 18 | showModule(m) 19 | 20 | # if we want to return the value, use 21 | # ir$createRet(s) 22 | # but that rewrites the code and removes the select. 23 | 24 | 25 | .llvm(fun, 1L) 26 | .llvm(fun, 4L) 27 | 28 | 29 | # Now works with use of ICMP_SLT. 30 | .llvm(fun, -13L) 31 | -------------------------------------------------------------------------------- /tests/testFooBlocks.R: -------------------------------------------------------------------------------- 1 | # Put this in Rllvm/tests/ 2 | # clang -emit-llvm -S -O0 -o fooBlocks.ll fooBlocks.c -fno-discard-value-names 3 | library(Rllvm) 4 | m = parseIR("fooBlocks.ir") 5 | b = getBlocks(m$foo) 6 | names(b) 7 | 8 | getPredecessor(b$for.end) 9 | getPredecessors(b$for.end) 10 | getSuccessor(b$for.inc) 11 | getSuccessors(b$for.inc) 12 | 13 | stopifnot(is.null(getSuccessor(b$for.end))) 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/tryCatch.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m = parseIR("tryCatch.ll") 4 | names(m) 5 | demangle(names(m)) #XX 6 | bb = getBlocks(m[["main"]]) 7 | bb[[7]] 8 | class(bb[[7]][[1]]) 9 | 10 | isEHPad(bb[[4]]) 11 | isEHPad(bb[[3]]) # FALSE 12 | 13 | isEHPad(bb[[4]][[1]]) # TRUE 14 | isEHPad(bb[[4]][[2]]) # FALSE 15 | -------------------------------------------------------------------------------- /tests/tryCatch.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | double division(int a, int b) { 4 | if( b == 0 ) { 5 | throw "Division by zero condition!"; 6 | } 7 | return (a/b); 8 | } 9 | 10 | 11 | int 12 | main(int argc, char *argv[]) 13 | { 14 | int a = atoi(argv[1]); 15 | int b = atoi(argv[2]); 16 | 17 | try { 18 | division(a, b); 19 | return(0); 20 | } catch (const char *message) { 21 | return(-1); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/types.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | # Need Rllvm:: prefix as structType and arrayType are also functions in Rffi. 4 | 5 | foo = Rllvm::structType(list(i = Int32Type, d = DoubleType), "foo") 6 | getName(foo) 7 | elTypes = getElementTypes(foo) 8 | 9 | 10 | ty = Rllvm::arrayType(Int32Type, 10000) 11 | getNumElements(ty) 12 | 13 | ty = vectorType(Int32Type, 101) 14 | getNumElements(ty) 15 | 16 | -------------------------------------------------------------------------------- /tests/verify.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | # The code we generate is intentionally broken so that we will fail the verifyModule call. 4 | # However, a Debug+Assert build of LLVM will fail in the createCall(ir, bar, ...) 5 | # as the call does not match the signature. 6 | 7 | mod = Module('example.ll') 8 | 9 | foo = Function('foo', Int32Type, list(), mod) 10 | bar = Function('bar', Int32Type, paramTypes = list( SEXPType ), mod) 11 | 12 | block = Block(foo, 'entry') 13 | ir = IRBuilder(block) 14 | 15 | # Passing the wrong type to bar() 16 | createCall(ir, bar, createDoubleConstant(3.14)) 17 | createRet(ir, createIntegerConstant(0)) 18 | 19 | showModule(mod) 20 | 21 | # WARNING: this line will abort R. 22 | # Now gives an error in LLVM 11.0 with a RelWithDebInfo build type. 23 | # (Release with Debug Info) 24 | err = tryCatch(verifyModule(mod), ModuleVerificationError = function(e) e) 25 | 26 | -------------------------------------------------------------------------------- /tests/verifyRTypes.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | sameType(REALSXPType, INTSXPType) 4 | # Currently TRUE! 5 | 6 | #env = parseIR("~/R-4.1/build3/src/main/envir.ir") 7 | env = parseIR(system.file("IR", "times.ir", package = "Rllvm")) 8 | 9 | a = SEXPType 10 | b = getTypes(env)$SEXPREC 11 | 12 | stopifnot( sameType(a, pointerType(b)) ) 13 | 14 | stopifnot( sameType(a, getReturnType(env$Rf_ScalarReal)) ) 15 | 16 | 17 | # Should be FALSE 18 | stopifnot( !sameType(a, b)) 19 | 20 | 21 | ref = structType(list(type = Int32Type), getName(b), withNames = FALSE) 22 | stopifnot( !sameType(ref, b)) 23 | 24 | stopifnot( !.Call("R_StructType_isLayoutIdentical", ref, b) ) 25 | 26 | -------------------------------------------------------------------------------- /tests/void.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | m = Module("testing void") 4 | foo = Function("foo", VoidType, list(), module = m) 5 | entry = Block(foo, "entry") 6 | builder = IRBuilder(entry) 7 | #createRet(builder) 8 | createReturnVoid(builder) 9 | 10 | showModule(m) 11 | 12 | .llvm(foo) 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/walkBlocks.R: -------------------------------------------------------------------------------- 1 | library(Rllvm) 2 | 3 | if(TRUE) { 4 | 5 | library(RLLVMCompile) 6 | fib1 = 7 | function(n) 8 | { 9 | ans = 1L 10 | if(n == 0L || n == 1L) 11 | ans = n 12 | else 13 | ans = fib1(n - 1L) + fib1(n - 2L) 14 | 15 | return(ans) 16 | } 17 | 18 | fc = compileFunction(fib1, Int32Type, Int32Type) 19 | } else { 20 | 21 | m = parseIR(system.file("IR", "fib.ll", package = "Rllvm")) 22 | fc = m$fib 23 | } 24 | 25 | 26 | bb = getBlocks(fc) 27 | length(bb) 28 | names(bb) 29 | 30 | getParent(bb[[1]]) # same as fc. 31 | stopifnot(identical(getParent(bb[[1]]), fc)) 32 | 33 | ins = getBlockInstructions(bb[[1]]) 34 | getParent(ins[[1]]) 35 | 36 | llvmDump(bb[[1]]) 37 | 38 | -------------------------------------------------------------------------------- /tests/writeBitcode.R: -------------------------------------------------------------------------------- 1 | source("tut1.R") 2 | writeBitcode(mod, "mod.bc") 3 | 4 | m = readBitcode("mod.bc") 5 | names(m) 6 | 7 | run(m$foo, 2, 10, 3, .ee = ExecutionEngine(m)) 8 | 9 | -------------------------------------------------------------------------------- /tools/getIntrinsicEnums.R: -------------------------------------------------------------------------------- 1 | # Build an R table of the enum values for the llvm::Intrinsic values. 2 | 3 | # Could do this with RCIndex (or RGCCTranslationUnit) 4 | 5 | getIntrinsicEnum = 6 | function(header = "/usr/local/include/llvm/Intrinsics.gen") 7 | { 8 | if(!file.exists(header)) 9 | stop("header file ", header, " doesn't exist") 10 | 11 | txt = readLines(header) 12 | i = grep("#ifdef GET_INTRINSIC_ENUM_VALUES", txt) 13 | txt = txt[ -(1:i) ] 14 | i = grep("#endif", txt)[1] 15 | txt = txt[ 1 : (i-1)] 16 | vals = gsub(",?[[:space:]]*//.*", "", txt) 17 | # Don't subtract 1 as the not_intrinsic is the first and in the .h file and not in the .gen file that is #include'd 18 | structure(1:length(vals), names = sub("^[[:space:]]+", "", vals)) 19 | } 20 | 21 | if(FALSE) { 22 | # write the results to a R file. 23 | con = file("../R/IntrinsicEnums.R", "w") 24 | cat("IntrinsicIDs <- \n", file = con) 25 | dput(getIntrinsicEnum(), file = con) 26 | close(con) 27 | } 28 | --------------------------------------------------------------------------------