├── .clang-format ├── .git-blame-ignore-revs ├── .github └── workflows │ ├── build.yml │ └── clang-format.yml ├── .gitignore ├── .gitmodules ├── AddClang.cmake ├── CMakeLists.txt ├── LICENSE ├── README.md ├── cmake └── modules │ └── sanitizers.cmake ├── include ├── CMakeLists.txt └── polygeist │ ├── BarrierUtils.h │ ├── CMakeLists.txt │ ├── Dialect.h │ ├── Dialect.td │ ├── Ops.h │ ├── Passes │ ├── CMakeLists.txt │ ├── Passes.h │ ├── Passes.td │ └── Utils.h │ └── PolygeistOps.td ├── lib ├── CMakeLists.txt └── polygeist │ ├── CMakeLists.txt │ ├── Dialect.cpp │ ├── ExecutionEngine │ ├── CMakeLists.txt │ ├── CudaRuntimeWrappers.cpp │ ├── PGORuntime.h │ └── RocmRuntimeWrappers.cpp │ ├── Ops.cpp │ └── Passes │ ├── AffineCFG.cpp │ ├── AffineReduction.cpp │ ├── AlwaysInliner.h │ ├── BarrierRemovalContinuation.cpp │ ├── CMakeLists.txt │ ├── CanonicalizeFor.cpp │ ├── CollectKernelStatistics.cpp │ ├── ConvertParallelToGPU.cpp │ ├── ConvertPolygeistToLLVM.cpp │ ├── ConvertToOpaquePtr.cpp │ ├── ForBreakToWhile.cpp │ ├── InnerSerialization.cpp │ ├── LoopRestructure.cpp │ ├── LowerAlternatives.cpp │ ├── OpenMPOpt.cpp │ ├── ParallelLICM.cpp │ ├── ParallelLoopDistribute.cpp │ ├── ParallelLoopUnroll.cpp │ ├── ParallelLoopUnroll.h │ ├── ParallelLower.cpp │ ├── PassDetails.h │ ├── PolygeistCanonicalize.cpp │ ├── PolygeistMem2Reg.cpp │ ├── PolyhedralOpt.cpp │ ├── RaiseToAffine.cpp │ ├── RuntimeWrapperUtils.h │ ├── SerializeToCubin.cpp │ ├── SerializeToHsaco.cpp │ └── TrivialUse.cpp ├── test ├── CMakeLists.txt ├── lit.cfg.py ├── lit.site.cfg.py.in └── polygeist-opt │ ├── affbufcopy.mlir │ ├── affifcombine.mlir │ ├── affiflower.mlir │ ├── affine-opt.mlir │ ├── affine-opt2.mlir │ ├── affinecfg.mlir │ ├── affparmerge.mlir │ ├── affraise.mlir │ ├── affraise2.mlir │ ├── affraise3.mlir │ ├── allocdist.mlir │ ├── asynclower.mlir │ ├── barrierelim.mlir │ ├── betterbreak.mlir │ ├── betterbreak2.mlir │ ├── bufcopy.mlir │ ├── canonicalization.mlir │ ├── canonicalize-select-of-ext.mlir │ ├── canonicalizefor.mlir │ ├── cconv-func.mlir │ ├── cconv-memref.mlir │ ├── converttollvm.mlir │ ├── copy2.mlir │ ├── copyopt.mlir │ ├── cpuifybackprop.mlir │ ├── cpuifyhotspot.mlir │ ├── cpuifyifsplit.mlir │ ├── cpuifyloopdistribute.mlir │ ├── cudalower.mlir │ ├── execmem2reg.mlir │ ├── fath.mlir │ ├── fath2.mlir │ ├── forbreak.mlir │ ├── forlicm.mlir │ ├── ifcomb.mlir │ ├── ifsink.mlir │ ├── induction.mlir │ ├── infmem2ref.mlir │ ├── isl │ ├── const_for_if_then_else.mlir │ ├── for_if_then_else.mlir │ ├── for_if_then_else_store.mlir │ ├── for_step.mlir │ ├── matmul.mlir │ ├── matmul_if.mlir │ ├── matmul_par.mlir │ ├── multi_scop.mlir │ ├── onlyconst.mlir │ ├── reg2mem.mlir │ ├── test1.mlir │ ├── test2.mlir │ ├── veccopy.mlir │ └── vecinit.mlir │ ├── llvmmem2reg.mlir │ ├── looprecur.mlir │ ├── mem2regIf2.mlir │ ├── mem2regRedundantArg.mlir │ ├── mem2regaff.mlir │ ├── mem2regelse.mlir │ ├── mem2regnest.mlir │ ├── mem2regshmembarrier.mlir │ ├── mem2regswitchmemerr.mlir │ ├── memfwd.mlir │ ├── multibuf.mlir │ ├── openmpopt.mlir │ ├── paralleldistribute.mlir │ ├── paralleldistributefor.mlir │ ├── parallellicm.mlir │ ├── parallelloopunroll.mlir │ ├── paralleltogpu.mlir │ ├── paralleltogpu2.mlir │ ├── paralleltogpu3.mlir │ ├── paralleltogpu4.mlir │ ├── parifmerge.mlir │ ├── pathfinder.mlir │ ├── pgo.mlir │ ├── plicm.mlir │ ├── promoteonscan.mlir │ ├── raisescffor.mlir │ ├── restructure.mlir │ ├── scanbuf.mlir │ ├── shiftloop.mlir │ ├── shmemfwd.mlir │ ├── subindexbitcast.mlir │ ├── subindexlowering.mlir │ ├── undeflower.mlir │ ├── whiletofor.mlir │ ├── whiletofor2.mlir │ ├── whiletofor3.mlir │ └── wrapperifparallel.mlir └── tools ├── CMakeLists.txt ├── cgeist ├── .clang-format ├── .gitignore ├── ArgumentList.h ├── CMakeLists.txt ├── Lib │ ├── AffineUtils.cc │ ├── AffineUtils.h │ ├── CGCall.cc │ ├── CGStmt.cc │ ├── IfScope.cc │ ├── IfScope.h │ ├── TypeUtils.cc │ ├── TypeUtils.h │ ├── ValueCategory.cc │ ├── ValueCategory.h │ ├── clang-mlir.cc │ ├── clang-mlir.h │ ├── pragmaHandler.cc │ ├── pragmaHandler.h │ ├── utils.cc │ └── utils.h ├── Test │ ├── CMakeLists.txt │ ├── CUDA │ │ └── polybench-cuda │ │ │ ├── 2mm │ │ │ └── 2mm.cu │ │ │ ├── 3mm │ │ │ └── 3mm.cu │ │ │ ├── AUTHORS │ │ │ ├── README │ │ │ ├── adi │ │ │ └── adi.cu │ │ │ ├── atax │ │ │ └── atax.cu │ │ │ ├── bicg │ │ │ └── bicg.cu │ │ │ ├── cholesky │ │ │ └── cholesky.cu │ │ │ ├── correlation │ │ │ └── correlation.cu │ │ │ ├── covariance │ │ │ └── covariance.cu │ │ │ ├── doitgen │ │ │ └── doitgen.cu │ │ │ ├── fdtd-2d │ │ │ └── fdtd-2d.cu │ │ │ ├── gemm │ │ │ └── gemm.cu │ │ │ ├── gemver │ │ │ └── gemver.cu │ │ │ ├── gesummv │ │ │ └── gesummv.cu │ │ │ ├── heat-3d │ │ │ └── heat-3d.cu │ │ │ ├── jacobi-1d-imper │ │ │ └── jacobi-1d-imper.cu │ │ │ ├── jacobi-2d-imper │ │ │ └── jacobi-2d-imper.cu │ │ │ ├── lu │ │ │ └── lu.cu │ │ │ ├── mvt │ │ │ └── mvt.cu │ │ │ ├── nussinov │ │ │ └── nussinov.cu │ │ │ ├── reduction │ │ │ └── reduction.cu │ │ │ ├── seidel-2d │ │ │ └── seidel-2d.cu │ │ │ ├── symm │ │ │ └── symm.cu │ │ │ ├── syr2k │ │ │ └── syr2k.cu │ │ │ ├── syrk │ │ │ └── syrk.cu │ │ │ └── trmm │ │ │ └── trmm.cu │ ├── Verification │ │ ├── CUDA │ │ │ └── cudasymbols.cu │ │ ├── Inputs │ │ │ └── cuda.h │ │ ├── addressof.cpp │ │ ├── affine_loop.c │ │ ├── affun.c │ │ ├── alignof.cpp │ │ ├── arrayconsllvm.cpp │ │ ├── arrayconsmemref.cpp │ │ ├── arrayconsmemrefinner.cpp │ │ ├── arrayinit.cpp │ │ ├── atomicld.c │ │ ├── base_cast.cpp │ │ ├── base_nostructabi.cpp │ │ ├── base_with_virt.cpp │ │ ├── base_with_virt2.cpp │ │ ├── caff.cpp │ │ ├── call.c │ │ ├── calloc.c │ │ ├── canonicalization.c │ │ ├── capture.cpp │ │ ├── charswitch.cpp │ │ ├── clangbuiltin.cpp │ │ ├── classrefmem.cpp │ │ ├── combif.c │ │ ├── cond.c │ │ ├── cond2.c │ │ ├── consabi.cpp │ │ ├── constexpr.cpp │ │ ├── continue.c │ │ ├── cout.cpp │ │ ├── ctz.c │ │ ├── cudaglobalcodegen.cu │ │ ├── cudashmem2reg.cu │ │ ├── cugen.cu │ │ ├── cugen2.cu │ │ ├── decrement.c │ │ ├── defines.c │ │ ├── der.c │ │ ├── deref.c │ │ ├── derived.cpp │ │ ├── dynalloc.c │ │ ├── ext.c │ │ ├── ext_vector_type.cpp │ │ ├── float_real_to_complex.c │ │ ├── free.c │ │ ├── freecst.c │ │ ├── fscanf.c │ │ ├── fw.c │ │ ├── fwfree.c │ │ ├── gcd.c │ │ ├── gettimeofday.c │ │ ├── global.c │ │ ├── globals.c │ │ ├── hist.c │ │ ├── ident.cpp │ │ ├── ident2.cpp │ │ ├── if_decl.cpp │ │ ├── indirect.c │ │ ├── invalid │ │ │ ├── basic.cpp │ │ │ └── invalid_include.cpp │ │ ├── ker.c │ │ ├── label.c │ │ ├── ler.c │ │ ├── loop.cpp │ │ ├── loopinc.c │ │ ├── lower-to-linalg-op.c │ │ ├── lower_to.c │ │ ├── lowerrecur.c │ │ ├── lum.c │ │ ├── malloc.c │ │ ├── memcpystruct.c │ │ ├── memref-fullrank.c │ │ ├── memrefaddassign.cpp │ │ ├── memrefcast.c │ │ ├── memrefsubstract.c │ │ ├── mer.c │ │ ├── min.c │ │ ├── multidim_init.c │ │ ├── nestloop.c │ │ ├── new.cpp │ │ ├── no_inline.c │ │ ├── nocond.c │ │ ├── nulretstruct.c │ │ ├── nus.c │ │ ├── omp.c │ │ ├── omp2.c │ │ ├── omp3.c │ │ ├── omp4.c │ │ ├── omp5.c │ │ ├── ompParallelNumThreads.c │ │ ├── opaquestr.cpp │ │ ├── packedstruct.c │ │ ├── pair.c │ │ ├── pairinit.c │ │ ├── pairptr.c │ │ ├── palloc.c │ │ ├── ptraddsub.c │ │ ├── raiseToAffine.c │ │ ├── raiseToAffineUnsignedCmp.c │ │ ├── recurstruct.c │ │ ├── red.mlir │ │ ├── redstore.c │ │ ├── redstore2.c │ │ ├── reduction.c │ │ ├── ref.cpp │ │ ├── refpair.cpp │ │ ├── refptrabi.cpp │ │ ├── reverseRaise.c │ │ ├── scor.c │ │ ├── scor2.c │ │ ├── scor3.c │ │ ├── scor4.c │ │ ├── sec.c │ │ ├── setter.c │ │ ├── sgesv.c │ │ ├── signcmp.c │ │ ├── simpcomplex.cpp │ │ ├── size.c │ │ ├── sizeof.c │ │ ├── sizeofpack.cpp │ │ ├── snus.c │ │ ├── static.c │ │ ├── staticint.c │ │ ├── str.c │ │ ├── stream.cu │ │ ├── struct.cpp │ │ ├── switcherr.c │ │ ├── switchnone.c │ │ ├── templatemember.cpp │ │ ├── threeInt.c │ │ ├── tobits.c │ │ ├── triple.cu │ │ ├── twotemplatevardecls.cpp │ │ ├── unioncopy.cpp │ │ ├── unlinked.c │ │ ├── vector.cpp │ │ ├── virt.cpp │ │ ├── virt2.cpp │ │ ├── while_decl.cpp │ │ ├── whileset.c │ │ ├── whiletofor.c │ │ ├── x.c │ │ └── xor.c │ ├── addressoff_call.cpp │ ├── elaborated-init.cpp │ ├── lit.cfg │ ├── lit.site.cfg.in │ └── polybench │ │ ├── AUTHORS │ │ ├── CHANGELOG │ │ ├── LICENSE.txt │ │ ├── README │ │ ├── THANKS │ │ ├── datamining │ │ ├── correlation │ │ │ ├── correlation.c │ │ │ └── correlation.h │ │ └── covariance │ │ │ ├── covariance.c │ │ │ └── covariance.h │ │ ├── linear-algebra │ │ ├── blas │ │ │ ├── gemm │ │ │ │ ├── gemm.c │ │ │ │ └── gemm.h │ │ │ ├── gemver │ │ │ │ ├── gemver.c │ │ │ │ └── gemver.h │ │ │ ├── gesummv │ │ │ │ ├── gesummv.c │ │ │ │ └── gesummv.h │ │ │ ├── symm │ │ │ │ ├── symm.c │ │ │ │ └── symm.h │ │ │ ├── syr2k │ │ │ │ ├── syr2k.c │ │ │ │ └── syr2k.h │ │ │ ├── syrk │ │ │ │ ├── syrk.c │ │ │ │ └── syrk.h │ │ │ └── trmm │ │ │ │ ├── trmm.c │ │ │ │ └── trmm.h │ │ ├── kernels │ │ │ ├── 2mm │ │ │ │ ├── 2mm.c │ │ │ │ └── 2mm.h │ │ │ ├── 3mm │ │ │ │ ├── 3mm.c │ │ │ │ └── 3mm.h │ │ │ ├── atax │ │ │ │ ├── atax.c │ │ │ │ └── atax.h │ │ │ ├── bicg │ │ │ │ ├── bicg.c │ │ │ │ └── bicg.h │ │ │ ├── doitgen │ │ │ │ ├── doitgen.c │ │ │ │ └── doitgen.h │ │ │ └── mvt │ │ │ │ ├── mvt.c │ │ │ │ └── mvt.h │ │ └── solvers │ │ │ ├── cholesky │ │ │ ├── cholesky.c │ │ │ └── cholesky.h │ │ │ ├── durbin │ │ │ ├── durbin.c │ │ │ └── durbin.h │ │ │ ├── gramschmidt │ │ │ ├── gramschmidt.c │ │ │ └── gramschmidt.h │ │ │ ├── lu │ │ │ ├── lu.c │ │ │ └── lu.h │ │ │ ├── ludcmp │ │ │ ├── ludcmp.c │ │ │ └── ludcmp.h │ │ │ └── trisolv │ │ │ ├── trisolv.c │ │ │ └── trisolv.h │ │ ├── medley │ │ ├── deriche │ │ │ ├── deriche.c │ │ │ └── deriche.h │ │ ├── floyd-warshall │ │ │ ├── floyd-warshall.c │ │ │ └── floyd-warshall.h │ │ └── nussinov │ │ │ ├── Nussinov.orig.c │ │ │ ├── nussinov.c │ │ │ └── nussinov.h │ │ ├── polybench.pdf │ │ ├── stencils │ │ ├── adi │ │ │ ├── adi.c │ │ │ └── adi.h │ │ ├── fdtd-2d │ │ │ ├── fdtd-2d.c │ │ │ └── fdtd-2d.h │ │ ├── heat-3d │ │ │ ├── heat-3d.c │ │ │ └── heat-3d.h │ │ ├── jacobi-1d │ │ │ ├── jacobi-1d.c │ │ │ └── jacobi-1d.h │ │ ├── jacobi-2d │ │ │ ├── jacobi-2d.c │ │ │ └── jacobi-2d.h │ │ └── seidel-2d │ │ │ ├── seidel-2d.c │ │ │ └── seidel-2d.h │ │ └── utilities │ │ ├── benchmark_list │ │ ├── clean.pl │ │ ├── create_cpped_version.pl │ │ ├── header-gen.pl │ │ ├── makefile-gen.pl │ │ ├── papi_counters.list │ │ ├── polybench.R │ │ ├── polybench.c │ │ ├── polybench.h │ │ ├── polybench.spec │ │ ├── run-all.pl │ │ └── time_benchmark.sh └── driver.cc ├── polygeist-opt ├── CMakeLists.txt └── polygeist-opt.cpp └── polymer ├── .clang-format ├── .gitattributes ├── .github └── workflows │ └── buildAndTest.yml ├── .gitignore ├── CMakeLists.txt ├── Docker └── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── build_polymer_deps.sh ├── cmake ├── AddPluto.cmake ├── CLooG.cmake ├── FindGMP.cmake └── OpenScop.cmake ├── docs ├── INSTALL_INDIVIDUALLY.md ├── INSTALL_WITHIN_POLYGEIST.md ├── LEGACY_INSTALL_METHOD.md ├── PREREQUISITES.md └── WHY_NOT_SUBMODULE_LLVM.md ├── example ├── flow ├── handwritten │ ├── README.md │ ├── gemm.mlir │ ├── gemm.pluto-par.c │ ├── gemm.pluto-par.mlir │ ├── gemm.pluto-par_llvm.mlir │ ├── gemm.pluto.c │ ├── gemm.pluto.mlir │ ├── gemm.pluto_llvm.mlir │ ├── gemver-gen.mlir │ ├── gemver-gen.pluto.c │ ├── gemver-gen.pluto.mlir │ ├── gemver-gen.pluto_llvm.mlir │ ├── gemver-gen.scop │ ├── gemver.mlir │ ├── gemver.pluto-par.c │ ├── gemver.pluto-par.mlir │ ├── gemver.pluto-par_llvm.mlir │ ├── gemver.pluto.c │ ├── gemver.pluto.mlir │ ├── gemver.pluto_llvm.mlir │ ├── gemver.scop │ ├── jacobi-1d.mlir │ ├── lu.mlir │ ├── lu.pluto.c │ ├── lu.pluto.mlir │ ├── lu.pluto_llvm.mlir │ ├── nussinov.mlir │ ├── nussinov.pluto-par.c │ ├── nussinov.pluto-par.mlir │ ├── nussinov.pluto-par_llvm.mlir │ ├── nussinov.pluto.c │ ├── nussinov.pluto.mlir │ ├── nussinov.pluto_llvm.mlir │ ├── run-par.sh │ ├── run.sh │ └── simple.mlir ├── phism │ ├── simple.c │ └── simple.mlir └── polybench │ ├── EXTRALARGE │ ├── 2mm │ │ ├── 2mm.c │ │ ├── 2mm.h │ │ └── 2mm.mlir │ ├── 3mm │ │ ├── 3mm.c │ │ ├── 3mm.h │ │ ├── 3mm.mlir │ │ └── polybench.i │ ├── adi │ │ ├── adi.c │ │ ├── adi.h │ │ └── adi.mlir │ ├── atax │ │ ├── atax.c │ │ ├── atax.h │ │ └── atax.mlir │ ├── bicg │ │ ├── bicg.c │ │ ├── bicg.h │ │ └── bicg.mlir │ ├── cholesky │ │ ├── cholesky.c │ │ ├── cholesky.h │ │ └── cholesky.mlir │ ├── correlation │ │ ├── correlation.c │ │ ├── correlation.h │ │ └── correlation.mlir │ ├── covariance │ │ ├── covariance.c │ │ ├── covariance.h │ │ └── covariance.mlir │ ├── deriche │ │ ├── deriche.c │ │ ├── deriche.h │ │ └── deriche.mlir │ ├── doitgen │ │ ├── doitgen.c │ │ ├── doitgen.h │ │ └── doitgen.mlir │ ├── durbin │ │ ├── durbin.c │ │ ├── durbin.h │ │ └── durbin.mlir │ ├── fdtd-2d │ │ ├── fdtd-2d.c │ │ ├── fdtd-2d.h │ │ └── fdtd-2d.mlir │ ├── floyd-warshall │ │ ├── floyd-warshall.c │ │ ├── floyd-warshall.h │ │ └── floyd-warshall.mlir │ ├── gemm │ │ ├── gemm.c │ │ ├── gemm.h │ │ └── gemm.mlir │ ├── gemver │ │ ├── gemver.c │ │ ├── gemver.h │ │ └── gemver.mlir │ ├── gesummv │ │ ├── gesummv.c │ │ ├── gesummv.h │ │ └── gesummv.mlir │ ├── gramschmidt │ │ ├── gramschmidt.c │ │ ├── gramschmidt.h │ │ └── gramschmidt.mlir │ ├── heat-3d │ │ ├── heat-3d.c │ │ ├── heat-3d.h │ │ └── heat-3d.mlir │ ├── jacobi-1d │ │ ├── jacobi-1d.c │ │ ├── jacobi-1d.h │ │ └── jacobi-1d.mlir │ ├── jacobi-2d │ │ ├── jacobi-2d.c │ │ ├── jacobi-2d.h │ │ └── jacobi-2d.mlir │ ├── lu │ │ ├── lu.c │ │ ├── lu.h │ │ └── lu.mlir │ ├── ludcmp │ │ ├── ludcmp.c │ │ ├── ludcmp.h │ │ └── ludcmp.mlir │ ├── mvt │ │ ├── mvt.c │ │ ├── mvt.h │ │ └── mvt.mlir │ ├── nussinov │ │ ├── nussinov.c │ │ ├── nussinov.h │ │ └── nussinov.mlir │ ├── seidel-2d │ │ ├── seidel-2d.c │ │ ├── seidel-2d.h │ │ └── seidel-2d.mlir │ ├── symm │ │ ├── symm.c │ │ ├── symm.h │ │ └── symm.mlir │ ├── syr2k │ │ ├── syr2k.c │ │ ├── syr2k.h │ │ └── syr2k.mlir │ ├── syrk │ │ ├── syrk.c │ │ ├── syrk.h │ │ └── syrk.mlir │ ├── trisolv │ │ ├── trisolv.c │ │ ├── trisolv.h │ │ └── trisolv.mlir │ └── trmm │ │ ├── trmm.c │ │ ├── trmm.h │ │ └── trmm.mlir │ ├── README.md │ ├── SMALL │ ├── 2mm.mlir │ ├── 3mm.mlir │ ├── adi.mlir │ ├── atax.mlir │ ├── bicg.mlir │ ├── cholesky.mlir │ ├── correlation.mlir │ ├── covariance.mlir │ ├── deriche.mlir │ ├── doitgen.mlir │ ├── durbin.mlir │ ├── fdtd-2d.mlir │ ├── floyd-warshall.mlir │ ├── gemm.mlir │ ├── gemver.mlir │ ├── gesummv.mlir │ ├── gramschmidt.mlir │ ├── heat-3d.mlir │ ├── jacobi-1d.mlir │ ├── jacobi-2d.mlir │ ├── lu.mlir │ ├── ludcmp.mlir │ ├── mvt.mlir │ ├── nussinov.mlir │ ├── seidel-2d.mlir │ ├── symm.mlir │ ├── syr2k.mlir │ ├── syrk.mlir │ ├── trisolv.mlir │ └── trmm.mlir │ ├── benchmark-polly │ ├── check-split │ ├── compare_sched.py │ ├── compile │ ├── eval-perf │ ├── execute │ ├── extract │ ├── find-splittable │ ├── list_num_polyhedral_stmts │ ├── opt │ ├── sanity-check-data │ ├── sanity-check-sched │ ├── search-split │ ├── search │ ├── 2mm.mlir │ ├── 3mm.mlir │ ├── atax.mlir │ ├── bicg.mlir │ ├── cholesky.mlir │ ├── correlation.mlir │ ├── covariance.mlir │ ├── deriche.mlir │ ├── doitgen.mlir │ ├── durbin.mlir │ ├── fdtd-2d.mlir │ ├── floyd-warshall.mlir │ ├── gemm.mlir │ ├── gemver.mlir │ ├── gesummv.mlir │ ├── gramschmidt.mlir │ ├── heat-3d.mlir │ ├── jacobi-1d.mlir │ ├── jacobi-2d.mlir │ ├── lu.mlir │ ├── ludcmp.mlir │ ├── mvt.mlir │ ├── nussinov.mlir │ ├── seidel-2d.mlir │ ├── symm.mlir │ ├── syr2k.mlir │ ├── syrk.mlir │ ├── trisolv.mlir │ └── trmm.mlir │ ├── split-and-merge │ ├── .gitignore │ ├── 2mm │ │ ├── 2mm.c │ │ ├── 2mm.h │ │ ├── 2mm.heuristic.polymer.par.log │ │ ├── 2mm.heuristic.polymer.par.mlir │ │ ├── 2mm.heuristic.polymer.seq.log │ │ ├── 2mm.heuristic.polymer.seq.mlir │ │ ├── 2mm.mlir │ │ ├── 2mm.nosplit.polymer.par.log │ │ ├── 2mm.nosplit.polymer.par.mlir │ │ ├── 2mm.nosplit.polymer.seq.log │ │ ├── 2mm.nosplit.polymer.seq.mlir │ │ ├── 2mm.origin.c │ │ ├── 2mm.origin.pluto.c │ │ ├── 2mm.origin.pluto.cloog │ │ ├── 2mm.pluto.origin.par.log │ │ ├── 2mm.pluto.origin.seq.log │ │ ├── 2mm.pluto.split.par.log │ │ ├── 2mm.pluto.split.seq.log │ │ ├── 2mm.split.c │ │ ├── 2mm.split.pluto.c │ │ └── 2mm.split.pluto.cloog │ ├── 3mm │ │ ├── 3mm.c │ │ ├── 3mm.h │ │ ├── 3mm.heuristic.polymer.par.log │ │ ├── 3mm.heuristic.polymer.par.mlir │ │ ├── 3mm.heuristic.polymer.seq.log │ │ ├── 3mm.heuristic.polymer.seq.mlir │ │ ├── 3mm.mlir │ │ ├── 3mm.nosplit.polymer.par.log │ │ ├── 3mm.nosplit.polymer.par.mlir │ │ ├── 3mm.nosplit.polymer.seq.log │ │ ├── 3mm.nosplit.polymer.seq.mlir │ │ ├── 3mm.origin.c │ │ ├── 3mm.origin.pluto.c │ │ ├── 3mm.origin.pluto.cloog │ │ ├── 3mm.pluto.origin.par.log │ │ ├── 3mm.pluto.origin.seq.log │ │ ├── 3mm.pluto.split.par.log │ │ ├── 3mm.pluto.split.seq.log │ │ ├── 3mm.split.c │ │ ├── 3mm.split.pluto.c │ │ └── 3mm.split.pluto.cloog │ ├── README.md │ ├── correlation │ │ ├── correlation.c │ │ ├── correlation.h │ │ ├── correlation.heuristic.polymer.par.log │ │ ├── correlation.heuristic.polymer.par.mlir │ │ ├── correlation.heuristic.polymer.seq.log │ │ ├── correlation.heuristic.polymer.seq.mlir │ │ ├── correlation.mlir │ │ ├── correlation.nosplit.polymer.par.log │ │ ├── correlation.nosplit.polymer.par.mlir │ │ ├── correlation.nosplit.polymer.seq.log │ │ ├── correlation.nosplit.polymer.seq.mlir │ │ ├── correlation.origin.c │ │ ├── correlation.origin.pluto.c │ │ ├── correlation.origin.pluto.cloog │ │ ├── correlation.pluto.origin.par.log │ │ ├── correlation.pluto.origin.seq.log │ │ ├── correlation.pluto.split.par.log │ │ ├── correlation.pluto.split.seq.log │ │ ├── correlation.split.c │ │ ├── correlation.split.pluto.c │ │ └── correlation.split.pluto.cloog │ ├── covariance │ │ ├── covariance.c │ │ ├── covariance.h │ │ ├── covariance.heuristic.polymer.par.log │ │ ├── covariance.heuristic.polymer.par.mlir │ │ ├── covariance.heuristic.polymer.seq.log │ │ ├── covariance.heuristic.polymer.seq.mlir │ │ ├── covariance.mlir │ │ ├── covariance.nosplit.polymer.par.log │ │ ├── covariance.nosplit.polymer.par.mlir │ │ ├── covariance.nosplit.polymer.seq.log │ │ ├── covariance.nosplit.polymer.seq.mlir │ │ ├── covariance.origin.c │ │ ├── covariance.origin.pluto.c │ │ ├── covariance.origin.pluto.cloog │ │ ├── covariance.pluto.origin.par.log │ │ ├── covariance.pluto.origin.seq.log │ │ ├── covariance.pluto.split.par.log │ │ ├── covariance.pluto.split.seq.log │ │ ├── covariance.split.c │ │ ├── covariance.split.pluto.c │ │ └── covariance.split.pluto.cloog │ ├── eval-split-c │ ├── eval-split-c-batch │ ├── eval-split-mlir │ ├── eval-split-mlir-batch │ ├── eval-split-mlir-heuristic │ ├── eval-split-mlir-heuristic-batch │ ├── eval-split-mlir-perf │ ├── perf_count.txt │ ├── report-timing.py │ └── trmm │ │ ├── trmm.c │ │ ├── trmm.h │ │ ├── trmm.heuristic.polymer.par.log │ │ ├── trmm.heuristic.polymer.par.mlir │ │ ├── trmm.heuristic.polymer.seq.log │ │ ├── trmm.heuristic.polymer.seq.mlir │ │ ├── trmm.mlir │ │ ├── trmm.nosplit.polymer.par.log │ │ ├── trmm.nosplit.polymer.par.mlir │ │ ├── trmm.nosplit.polymer.seq.log │ │ ├── trmm.nosplit.polymer.seq.mlir │ │ ├── trmm.origin.c │ │ ├── trmm.origin.pluto.c │ │ ├── trmm.origin.pluto.cloog │ │ ├── trmm.pluto.origin.par.log │ │ ├── trmm.pluto.origin.seq.log │ │ ├── trmm.pluto.split.par.log │ │ ├── trmm.pluto.split.seq.log │ │ ├── trmm.split.c │ │ ├── trmm.split.pluto.c │ │ └── trmm.split.pluto.cloog │ └── utilities │ ├── polybench.c │ └── polybench.h ├── include └── polymer │ ├── CMakeLists.txt │ ├── Support │ ├── IslScop.h │ ├── OslScop.h │ ├── OslScopStmtOpSet.h │ ├── OslSymbolTable.h │ ├── PolymerUtils.h │ ├── ScatteringUtils.h │ ├── ScopStmt.h │ └── Utils.h │ ├── Target │ ├── ISL.h │ └── OpenScop.h │ └── Transforms │ ├── CMakeLists.txt │ ├── ExtractScopStmt.h │ ├── FoldSCFIf.h │ ├── LoopAnnotate.h │ ├── LoopExtract.h │ ├── Passes.h │ ├── Passes.td │ ├── PlutoTransform.h │ ├── Reg2Mem.h │ └── ScopStmtOpt.h ├── lib ├── CMakeLists.txt ├── Support │ ├── CMakeLists.txt │ ├── IslScop.cc │ ├── OslScop.cc │ ├── OslScopStmtOpSet.cc │ ├── OslSymbolTable.cc │ ├── ScatteringUtils.cc │ ├── ScopStmt.cc │ └── Utils.cc ├── Target │ ├── CMakeLists.txt │ ├── ISL │ │ └── ConvertToISL.cc │ └── OpenScop │ │ ├── ConvertFromOpenScop.cc │ │ └── ConvertToOpenScop.cc └── Transforms │ ├── AnnotateScop.cc │ ├── CMakeLists.txt │ ├── ExtractScopStmt.cc │ ├── FoldSCFIf.cc │ ├── IslExternalTransform.cc │ ├── LoopAnnotate.cc │ ├── LoopExtract.cc │ ├── PassDetail.h │ ├── PlutoTransform.cc │ ├── Reg2Mem.cc │ └── ScopStmtOpt.cc ├── polygeist-version.txt ├── resources └── polymer.bib ├── scripts ├── build-with-polygeist.sh └── update-pluto.sh ├── test ├── CMakeLists.txt ├── archive │ ├── ExtractScopStmt │ │ └── load-store.mlir │ ├── PlutoTransform │ │ ├── arith.mlir │ │ ├── empty.mlir │ │ ├── load-store-dep-tiling.mlir │ │ ├── load-store-nested-tiling.mlir │ │ ├── load-store.mlir │ │ └── matmul.mlir │ ├── array-expansion.mlir │ └── polymer-translate │ │ ├── export-and-import │ │ └── matmul.mlir │ │ ├── export-scop │ │ ├── load-store-if.mlir │ │ ├── load-store-local-vars.mlir │ │ ├── load-store-param-imperfect.mlir │ │ ├── load-store-param.mlir │ │ ├── load-store.mlir │ │ ├── matmul.mlir │ │ └── transpose.mlir │ │ └── import-scop │ │ ├── empty.scop │ │ ├── load-store-if.scop │ │ ├── load-store-local-vars.scop │ │ ├── load-store-no-ctx.scop │ │ ├── load-store-param.scop │ │ ├── matmul.scop │ │ └── transpose.scop ├── lit.cfg.py ├── lit.site.cfg.py.in └── polymer-opt │ ├── AnnotateScop │ └── annotate-single.mlir │ ├── Application │ └── aes.mlir │ ├── ExtractScopStmt │ ├── internal-index-cast.mlir │ ├── no-loop-blockarg.mlir │ ├── no-loop-non-affine.mlir │ ├── no-loop.mlir │ ├── scratchpad-dom-store-diff-mem.mlir │ ├── scratchpad-dom-store-same-mem.mlir │ └── scratchpad-dom-store.mlir │ ├── FoldSCFIf │ ├── match-store-addr.mlir │ ├── match-store-diff-mem.mlir │ ├── match-store-no-else.mlir │ ├── match-store.mlir │ ├── no-result-no-else.mlir │ ├── no-result.mlir │ ├── pure-arith-multi-if.mlir │ └── pure-arith-single-if.mlir │ ├── PlutoTransforms │ ├── const-loop-bounds.mlir │ ├── jacobi-diamond.mlir │ ├── jacobi.mlir │ ├── subindex.mlir │ └── swapped-bounds.mlir │ └── Reg2Mem │ ├── ignored.mlir │ ├── load-store-dep-general.mlir │ ├── load-store-dep.mlir │ └── reduce.mlir └── tools ├── CMakeLists.txt ├── polymer-opt ├── CMakeLists.txt └── polymer-opt.cc └── polymer-translate ├── CMakeLists.txt └── polymer-translate.cc /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | -------------------------------------------------------------------------------- /.github/workflows/clang-format.yml: -------------------------------------------------------------------------------- 1 | name: run-clang-format 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | with: 16 | fetch-depth: 1 17 | - uses: DoozyX/clang-format-lint-action@v0.11 18 | with: 19 | exclude: './tools/cgeist/Test ./test ./tools/polymer/example' 20 | clangFormatVersion: 11 21 | style: llvm 22 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "llvm-project"] 2 | path = llvm-project 3 | url = https://github.com/llvm/llvm-project.git 4 | -------------------------------------------------------------------------------- /AddClang.cmake: -------------------------------------------------------------------------------- 1 | 2 | macro(set_clang_windows_version_resource_properties name) 3 | if(DEFINED windows_resource_file) 4 | set_windows_version_resource_properties(${name} ${windows_resource_file} 5 | VERSION_MAJOR ${CLANG_VERSION_MAJOR} 6 | VERSION_MINOR ${CLANG_VERSION_MINOR} 7 | VERSION_PATCHLEVEL ${CLANG_VERSION_PATCHLEVEL} 8 | VERSION_STRING "${CLANG_VERSION} (${BACKEND_PACKAGE_STRING})" 9 | PRODUCT_NAME "clang") 10 | endif() 11 | endmacro() 12 | 13 | macro(add_clang_executable name) 14 | add_llvm_executable( ${name} ${ARGN} ) 15 | set_target_properties(${name} PROPERTIES FOLDER "Clang executables") 16 | set_clang_windows_version_resource_properties(${name}) 17 | endmacro(add_clang_executable) 18 | 19 | macro(add_clang_tool name) 20 | if (NOT CLANG_BUILD_TOOLS) 21 | set(EXCLUDE_FROM_ALL ON) 22 | endif() 23 | 24 | add_clang_executable(${name} ${ARGN}) 25 | # add_dependencies(${name} clang-resource-headers) 26 | 27 | if (CLANG_BUILD_TOOLS) 28 | get_target_export_arg(${name} Clang export_to_clangtargets) 29 | install(TARGETS ${name} 30 | ${export_to_clangtargets} 31 | RUNTIME DESTINATION bin 32 | COMPONENT ${name}) 33 | 34 | if(NOT LLVM_ENABLE_IDE) 35 | add_llvm_install_targets(install-${name} 36 | DEPENDS ${name} 37 | COMPONENT ${name}) 38 | endif() 39 | set_property(GLOBAL APPEND PROPERTY CLANG_EXPORTS ${name}) 40 | endif() 41 | endmacro() 42 | 43 | -------------------------------------------------------------------------------- /include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(polygeist) 2 | -------------------------------------------------------------------------------- /include/polygeist/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_mlir_dialect(PolygeistOps polygeist) 2 | add_mlir_doc(PolygeistDialect -gen-dialect-doc PolygeistDialect Polygeist/) 3 | add_mlir_doc(PolygeistOps -gen-op-doc PolygeistOps Polygeist/) 4 | 5 | add_subdirectory(Passes) -------------------------------------------------------------------------------- /include/polygeist/Dialect.h: -------------------------------------------------------------------------------- 1 | //===- BFVDialect.h - BFV dialect -----------------*- C++ -*-===// 2 | // 3 | // This file is licensed under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #ifndef BFV_BFVDIALECT_H 10 | #define BFV_BFVDIALECT_H 11 | 12 | #include "mlir/IR/Dialect.h" 13 | 14 | #include "polygeist/PolygeistOpsDialect.h.inc" 15 | 16 | #endif // BFV_BFVDIALECT_H 17 | -------------------------------------------------------------------------------- /include/polygeist/Dialect.td: -------------------------------------------------------------------------------- 1 | //===- BFVDialect.td - BFV dialect -----------*- tablegen -*-===// 2 | // 3 | // This file is licensed under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #ifndef POLYGEIST_DIALECT 10 | #define POLYGEIST_DIALECT 11 | 12 | include "mlir/IR/OpBase.td" 13 | 14 | //===----------------------------------------------------------------------===// 15 | // BFV dialect definition. 16 | //===----------------------------------------------------------------------===// 17 | 18 | def Polygeist_Dialect : Dialect { 19 | let name = "polygeist"; 20 | let description = [{}]; 21 | let cppNamespace = "::mlir::polygeist"; 22 | } 23 | 24 | //===----------------------------------------------------------------------===// 25 | // Base BFV operation definition. 26 | //===----------------------------------------------------------------------===// 27 | 28 | class Polygeist_Op traits = []> 29 | : Op; 30 | 31 | #endif // POLYGEIST_DIALECT 32 | -------------------------------------------------------------------------------- /include/polygeist/Passes/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_TARGET_DEFINITIONS Passes.td) 2 | mlir_tablegen(Passes.h.inc -gen-pass-decls -name polygeist) 3 | add_public_tablegen_target(MLIRPolygeistPassIncGen) 4 | 5 | add_mlir_doc(Passes PolygeistPasses ./ -gen-pass-doc) 6 | -------------------------------------------------------------------------------- /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(polygeist) 2 | -------------------------------------------------------------------------------- /lib/polygeist/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_mlir_dialect_library(MLIRPolygeist 2 | Dialect.cpp 3 | Ops.cpp 4 | 5 | ADDITIONAL_HEADER_DIRS 6 | ${PROJECT_SOURCE_DIR}/include/polygeist 7 | 8 | DEPENDS 9 | MLIRPolygeistOpsIncGen 10 | 11 | LINK_LIBS PUBLIC 12 | MLIRIR 13 | MLIRMemRefDialect 14 | MLIRLLVMDialect 15 | MLIROpenMPDialect 16 | MLIRAffineDialect 17 | MLIRSupport 18 | MLIRSCFTransforms 19 | ) 20 | add_subdirectory(Passes) 21 | add_subdirectory(ExecutionEngine) 22 | -------------------------------------------------------------------------------- /lib/polygeist/Dialect.cpp: -------------------------------------------------------------------------------- 1 | //===- PolygeistDialect.cpp - Polygeist dialect ---------------*- C++ -*-===// 2 | // 3 | // This file is licensed under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #include "polygeist/Dialect.h" 10 | #include "mlir/IR/DialectImplementation.h" 11 | #include "polygeist/Ops.h" 12 | 13 | using namespace mlir; 14 | using namespace mlir::polygeist; 15 | 16 | //===----------------------------------------------------------------------===// 17 | // Polygeist dialect. 18 | //===----------------------------------------------------------------------===// 19 | 20 | void PolygeistDialect::initialize() { 21 | addOperations< 22 | #define GET_OP_LIST 23 | #include "polygeist/PolygeistOps.cpp.inc" 24 | >(); 25 | } 26 | 27 | #include "polygeist/PolygeistOpsDialect.cpp.inc" 28 | -------------------------------------------------------------------------------- /lib/polygeist/Passes/ParallelLoopUnroll.h: -------------------------------------------------------------------------------- 1 | #include "mlir/Dialect/SCF/IR/SCF.h" 2 | #include 3 | 4 | namespace mlir::polygeist { 5 | LogicalResult scfParallelUnrollByFactor( 6 | scf::ParallelOp &pop, uint64_t unrollFactor, unsigned dim, 7 | bool generateEpilogueLoop, bool coalescingFriendlyIndexing, 8 | function_ref annotateFn); 9 | static LogicalResult scfParallelUnrollByFactors( 10 | scf::ParallelOp &pop, ArrayRef unrollFactors, 11 | bool generateEpilogueLoop, bool coalescingFriendlyIndexing, 12 | function_ref annotateFn) { 13 | unsigned dims = pop.getUpperBound().size(); 14 | assert(dims == unrollFactors.size()); 15 | bool succeeded = true; 16 | for (unsigned dim = 0; dim < dims; dim++) { 17 | succeeded = 18 | succeeded && polygeist::scfParallelUnrollByFactor( 19 | pop, unrollFactors[dim], dim, generateEpilogueLoop, 20 | coalescingFriendlyIndexing, annotateFn) 21 | .succeeded(); 22 | } 23 | return success(succeeded); 24 | } 25 | } // namespace mlir::polygeist 26 | -------------------------------------------------------------------------------- /lib/polygeist/Passes/PassDetails.h: -------------------------------------------------------------------------------- 1 | //===- PassDetails.h - polygeist pass class details ----------------*- C++ 2 | //-*-===// 3 | // 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 | // See https://llvm.org/LICENSE.txt for license information. 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // Stuff shared between the different polygeist passes. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | // clang-tidy seems to expect the absolute path in the header guard on some 15 | // systems, so just disable it. 16 | // NOLINTNEXTLINE(llvm-header-guard) 17 | #ifndef DIALECT_POLYGEIST_TRANSFORMS_PASSDETAILS_H 18 | #define DIALECT_POLYGEIST_TRANSFORMS_PASSDETAILS_H 19 | 20 | #include "mlir/Pass/Pass.h" 21 | #include "polygeist/Ops.h" 22 | #include "polygeist/Passes/Passes.h" 23 | 24 | namespace mlir { 25 | class FunctionOpInterface; 26 | // Forward declaration from Dialect.h 27 | template 28 | void registerDialect(DialectRegistry ®istry); 29 | namespace polygeist { 30 | 31 | class PolygeistDialect; 32 | 33 | #define GEN_PASS_CLASSES 34 | #include "polygeist/Passes/Passes.h.inc" 35 | 36 | } // namespace polygeist 37 | } // namespace mlir 38 | 39 | #endif // DIALECT_POLYGEIST_TRANSFORMS_PASSDETAILS_H 40 | -------------------------------------------------------------------------------- /lib/polygeist/Passes/TrivialUse.cpp: -------------------------------------------------------------------------------- 1 | //===- TrivialUse.cpp - Remove trivial use instruction ---------------- -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file implements a pass to lower gpu kernels in NVVM/gpu dialects into 10 | // a generic parallel for representation 11 | //===----------------------------------------------------------------------===// 12 | #include "PassDetails.h" 13 | 14 | #include "polygeist/Ops.h" 15 | #include "polygeist/Passes/Passes.h" 16 | 17 | #define DEBUG_TYPE "trivial-use" 18 | 19 | using namespace mlir; 20 | using namespace polygeist; 21 | 22 | namespace { 23 | struct RemoveTrivialUse : public RemoveTrivialUseBase { 24 | void runOnOperation() override; 25 | }; 26 | 27 | } // end anonymous namespace 28 | 29 | namespace mlir { 30 | namespace polygeist { 31 | std::unique_ptr createRemoveTrivialUsePass() { 32 | return std::make_unique(); 33 | } 34 | } // namespace polygeist 35 | } // namespace mlir 36 | 37 | void RemoveTrivialUse::runOnOperation() { 38 | getOperation()->walk([&](polygeist::TrivialUseOp bidx) { bidx.erase(); }); 39 | } 40 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | configure_lit_site_cfg( 2 | ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in 3 | ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py 4 | MAIN_CONFIG 5 | ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py 6 | ) 7 | 8 | add_lit_testsuite(check-polygeist-opt "Verify Polygeist passes perform correctly" 9 | ${CMAKE_CURRENT_BINARY_DIR} 10 | DEPENDS polygeist-opt FileCheck not 11 | ARGS -v 12 | ) 13 | 14 | set_target_properties(check-polygeist-opt PROPERTIES FOLDER "Tests") 15 | -------------------------------------------------------------------------------- /test/polygeist-opt/affiflower.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt --canonicalize-polygeist --split-input-file %s | FileCheck %s 2 | 3 | #set0 = affine_set<(d0, d1) : (d0 + d1 * 512 == 0)> 4 | 5 | module { 6 | func.func @f(%636: index, %603: memref) { 7 | %c512_i32 = arith.constant 512 : i32 8 | 9 | affine.parallel (%arg7) = (0) to (symbol(%636)) { 10 | %706 = arith.index_cast %arg7 : index to i32 11 | %707 = arith.muli %706, %c512_i32 : i32 12 | affine.parallel (%arg8) = (0) to (512) { 13 | %708 = arith.index_cast %arg8 : index to i32 14 | %709 = arith.addi %707, %708 : i32 15 | affine.if #set0(%arg8, %arg7) { 16 | %712 = arith.sitofp %709 : i32 to f64 17 | affine.store %712, %603[0] : memref 18 | } 19 | } 20 | } 21 | return 22 | } 23 | 24 | } 25 | 26 | // CHECK: #[[$ATTR_0:.+]] = affine_set<()[s0] : (s0 * 512 - 1 >= 0)> 27 | 28 | // CHECK-LABEL: func.func @f( 29 | // CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: index, 30 | // CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: memref) { 31 | // CHECK: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]] = arith.constant 0.000000e+00 : f64 32 | // CHECK: affine.if #[[$ATTR_0]](){{\[}}%[[VAL_0]]] { 33 | // CHECK: affine.store %[[VAL_2]], %[[VAL_1]][0] : memref 34 | // CHECK: } 35 | // CHECK: return 36 | // CHECK: } 37 | 38 | -------------------------------------------------------------------------------- /test/polygeist-opt/affine-opt.mlir: -------------------------------------------------------------------------------- 1 | // RUN: if [ %polymer_pluto_enabled == 1 ]; then polygeist-opt --polyhedral-opt %s 2>&1 | FileCheck %s; fi 2 | 3 | // CHECK: 4 | // CHECK: 5 | // CHECK-NOT: __polygeist_outlined 6 | // CHECK-NOT: S[0-9]+ 7 | #map = affine_map<()[s0] -> (s0)> 8 | module { 9 | func.func @gemm(%alpha: f32, %beta: f32, 10 | %C: memref, 11 | %A: memref, 12 | %B: memref) { 13 | %c0 = arith.constant 0 : index 14 | %c1 = arith.constant 1 : index 15 | %NI = memref.dim %C, %c0 : memref 16 | %NJ = memref.dim %C, %c1 : memref 17 | %NK = memref.dim %A, %c1 : memref 18 | 19 | affine.for %i = 0 to #map()[%NI] { 20 | affine.for %j = 0 to #map()[%NJ] { 21 | %0 = affine.load %C[%i, %j] : memref 22 | %1 = arith.mulf %0, %beta : f32 23 | affine.store %1, %C[%i, %j] : memref 24 | } 25 | 26 | affine.for %j = 0 to #map()[%NJ] { 27 | affine.for %k = 0 to #map()[%NK] { 28 | %2 = affine.load %A[%i, %k] : memref 29 | %3 = arith.mulf %alpha, %2 : f32 30 | %4 = affine.load %B[%k, %j] : memref 31 | %5 = arith.mulf %3, %4 : f32 32 | %6 = affine.load %C[%i, %j] : memref 33 | %7 = arith.addf %6, %5 : f32 34 | affine.store %7, %C[%i, %j] : memref 35 | } 36 | } 37 | } 38 | return 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/polygeist-opt/affparmerge.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt --canonicalize-polygeist --split-input-file %s | FileCheck %s 2 | 3 | module { 4 | func.func @f(%636: index, %603: memref) { 5 | %c512_i32 = arith.constant 512 : i32 6 | affine.parallel (%arg7, %arg8) = (0, 0) to (symbol(%636), 512) { 7 | %706 = arith.index_cast %arg7 : index to i32 8 | %707 = arith.muli %706, %c512_i32 : i32 9 | %708 = arith.index_cast %arg8 : index to i32 10 | %709 = arith.addi %707, %708 : i32 11 | %712 = arith.sitofp %709 : i32 to f64 12 | affine.store %712, %603[%arg8 + %arg7 * 512] : memref 13 | } 14 | return 15 | } 16 | 17 | } 18 | 19 | // CHECK: func.func @f(%[[arg0:.+]]: index, %[[arg1:.+]]: memref) { 20 | // CHECK-NEXT: affine.parallel (%[[arg2:.+]]) = (0) to (symbol(%[[arg0]]) * 512) { 21 | // CHECK-NEXT: %[[V0:.+]] = arith.index_cast %[[arg2]] : index to i32 22 | // CHECK-NEXT: %[[V1:.+]] = arith.sitofp %[[V0]] : i32 to f64 23 | // CHECK-NEXT: affine.store %[[V1]], %arg1[%[[arg2]]] : memref 24 | // CHECK-NEXT: } 25 | // CHECK-NEXT: return 26 | // CHECK-NEXT: } 27 | -------------------------------------------------------------------------------- /test/polygeist-opt/affraise2.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt --raise-scf-to-affine --split-input-file %s | FileCheck %s 2 | 3 | module { 4 | func.func @main(%12 : i1, %14 : i32, %18 : memref, %19 : memref ) { 5 | %c0 = arith.constant 0 : index 6 | %c4 = arith.constant 4 : index 7 | %c1 = arith.constant 1 : index 8 | scf.if %12 { 9 | %15 = arith.index_cast %14 : i32 to index 10 | %16 = arith.muli %15, %c4 : index 11 | %17 = arith.divui %16, %c4 : index 12 | scf.for %arg2 = %c0 to %17 step %c1 { 13 | %20 = memref.load %19[%arg2] : memref 14 | memref.store %20, %18[%arg2] : memref 15 | } 16 | } 17 | return 18 | } 19 | } 20 | 21 | // CHECK: func.func @main(%[[arg0:.+]]: i1, %[[arg1:.+]]: i32, %[[arg2:.+]]: memref, %[[arg3:.+]]: memref) { 22 | // CHECK-NEXT: %[[c4:.+]] = arith.constant 4 : index 23 | // CHECK-NEXT: %[[V0:.+]] = arith.index_cast %[[arg1]] : i32 to index 24 | // CHECK-NEXT: %[[V1:.+]] = arith.muli %[[V0]], %[[c4]] : index 25 | // CHECK-NEXT: %[[V2:.+]] = arith.divui %[[V1]], %[[c4]] : index 26 | // CHECK-NEXT: scf.if %[[arg0]] { 27 | // CHECK-NEXT: affine.for %[[arg4:.+]] = 0 to %[[V2]] { 28 | // CHECK-NEXT: %[[a:.+]] = memref.load %[[arg3]][%[[arg4]]] : memref 29 | // CHECK-NEXT: memref.store %[[a]], %[[arg2]][%[[arg4]]] : memref 30 | // CHECK-NEXT: } 31 | // CHECK-NEXT: } 32 | -------------------------------------------------------------------------------- /test/polygeist-opt/ifcomb.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt --canonicalize-polygeist --split-input-file %s | FileCheck %s 2 | 3 | module { 4 | func.func @_Z17compute_tran_tempPfPS_iiiiiiii(%arg0: memref, %arg1: i32, %arg2: i32, %arg3: i32) -> i8 { 5 | %c1_i8 = arith.constant 1 : i8 6 | %c0_i8 = arith.constant 0 : i8 7 | %cst = arith.constant 0.000000e+00 : f32 8 | %0 = arith.cmpi sge, %arg3, %arg1 : i32 9 | %1 = scf.if %0 -> (i8) { 10 | %2 = arith.cmpi sle, %arg3, %arg2 : i32 11 | %3 = scf.if %2 -> (i8) { 12 | affine.store %cst, %arg0[] : memref 13 | scf.yield %c1_i8 : i8 14 | } else { 15 | scf.yield %c0_i8 : i8 16 | } 17 | scf.yield %3 : i8 18 | } else { 19 | scf.yield %c0_i8 : i8 20 | } 21 | return %1 : i8 22 | } 23 | } 24 | 25 | // CHECK: func.func @_Z17compute_tran_tempPfPS_iiiiiiii(%[[arg0:.+]]: memref, %[[arg1:.+]]: i32, %[[arg2:.+]]: i32, %[[arg3:.+]]: i32) -> i8 { 26 | // CHECK-NEXT: %[[cst:.+]] = arith.constant 0.000000e+00 : f32 27 | // CHECK-NEXT: %[[V0:.+]] = arith.cmpi sge, %[[arg3]], %[[arg1]] : i32 28 | // CHECK-NEXT: %[[V1:.+]] = arith.cmpi sle, %[[arg3]], %[[arg2]] : i32 29 | // CHECK-NEXT: %[[V2:.+]] = arith.andi %[[V0]], %[[V1]] : i1 30 | // CHECK-NEXT: %[[V4:.+]] = arith.extui %[[V2]] : i1 to i8 31 | // CHECK-NEXT: scf.if %[[V2]] { 32 | // CHECK-NEXT: affine.store %[[cst]], %[[arg0]][] : memref 33 | // CHECK-NEXT: } 34 | // CHECK-NEXT: return %[[V4]] : i8 35 | // CHECK-NEXT: } 36 | -------------------------------------------------------------------------------- /test/polygeist-opt/isl/for_step.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt --polyhedral-opt --use-polyhedral-optimizer=islexternal $ISL_OPT_PLACEHOLDER %s 2>&1 | FileCheck %s 2 | // CHECK-NOT: isl_ctx not freed 3 | 4 | #map = affine_map<()[s0] -> (s0)> 5 | #set1 = affine_set<(d0)[s0] : (-d0 + s0 -1 >= 0)> 6 | module { 7 | func.func @gemm(%alpha: f32, %beta: f32, 8 | %C: memref, 9 | %A: memref, 10 | %B: memref, 11 | %S: index, 12 | %N: index) { 13 | affine.for %i = 0 to #map()[%N] step 2 { 14 | affine.store %beta, %C[%i] : memref 15 | } 16 | return 17 | } 18 | } 19 | // RUN: mkdir -p %t/schedules 20 | // RUN: mkdir -p %t/accesses 21 | // RUN: polygeist-opt --polyhedral-opt --use-polyhedral-optimizer=islexternal --islexternal-dump-schedules=%t/schedules --islexternal-dump-accesses=%t/accesses $ISL_OPT_PLACEHOLDER %s && find %t/schedules/ %t/accesses/ -type f -print0 | sort -z | xargs -0r cat | FileCheck --check-prefix=ISL_OUT %s 22 | // ISL_OUT: domain: "[P0] -> { S0[i0] : (i0) mod 2 = 0 and 0 <= i0 < P0 }" 23 | // ISL_OUT: accesses: 24 | // ISL_OUT: - S0: 25 | // ISL_OUT: reads: 26 | // ISL_OUT: writes: 27 | // ISL_OUT: - "[P0] -> { [i0] -> A1[o0] : o0 = i0 }" 28 | // ISL_OUT: { domain: "[P0] -> { S0[i0] : (i0) mod 2 = 0 and 0 <= i0 < P0 }", child: { schedule: "[P0] -> L0[{ S0[i0] -> [(i0)] }]" } } 29 | -------------------------------------------------------------------------------- /test/polygeist-opt/isl/onlyconst.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt --polyhedral-opt --use-polyhedral-optimizer=islexternal $ISL_OPT_PLACEHOLDER %s 2>&1 | FileCheck %s 2 | // CHECK-NOT: isl_ctx not freed 3 | 4 | #map = affine_map<()[s0] -> (s0)> 5 | #set1 = affine_set<(d0)[s0] : (-d0 + s0 -1 >= 0)> 6 | module { 7 | func.func @gemm(%alpha: f32, %beta: f32, 8 | %C: memref, 9 | %A: memref, 10 | %B: memref, 11 | %S: index, 12 | %N: index) { 13 | affine.for %i = 0 to 10 { 14 | affine.for %j = 0 to 20 { 15 | affine.store %beta, %C[0] : memref 16 | } 17 | } 18 | return 19 | } 20 | } 21 | // RUN: mkdir -p %t/schedules 22 | // RUN: mkdir -p %t/accesses 23 | // RUN: polygeist-opt --polyhedral-opt --use-polyhedral-optimizer=islexternal --islexternal-dump-schedules=%t/schedules --islexternal-dump-accesses=%t/accesses $ISL_OPT_PLACEHOLDER %s && find %t/schedules/ %t/accesses/ -type f -print0 | sort -z | xargs -0r cat | FileCheck --check-prefix=ISL_OUT %s 24 | // ISL_OUT: domain: "{ S0[i0, i1] : 0 <= i0 <= 9 and 0 <= i1 <= 19 }" 25 | // ISL_OUT: accesses: 26 | // ISL_OUT: - S0: 27 | // ISL_OUT: reads: 28 | // ISL_OUT: writes: 29 | // ISL_OUT: - "{ [i0, i1] -> A1[o0] : o0 = 0 }" 30 | // ISL_OUT: { domain: "{ S0[i0, i1] : 0 <= i0 <= 9 and 0 <= i1 <= 19 }", child: { schedule: "L1[{ S0[i0, i1] -> [(i0)] }]", child: { schedule: "L0[{ S0[i0, i1] -> [(i1)] }]" } } } 31 | -------------------------------------------------------------------------------- /test/polygeist-opt/isl/veccopy.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt --polyhedral-opt --use-polyhedral-optimizer=islexternal $ISL_OPT_PLACEHOLDER %s 2>&1 | FileCheck %s 2 | // CHECK-NOT: isl_ctx not freed 3 | 4 | #map = affine_map<()[s0] -> (s0)> 5 | #set1 = affine_set<(d0)[s0] : (-d0 + s0 -1 >= 0)> 6 | module { 7 | func.func @gemm(%alpha: f32, %beta: f32, 8 | %C: memref, 9 | %A: memref, 10 | %B: memref, 11 | %S: index, 12 | %N: index) { 13 | affine.for %i = 0 to #map()[%N] { 14 | affine.store %beta, %C[%i] : memref 15 | } 16 | return 17 | } 18 | } 19 | // RUN: mkdir -p %t/schedules 20 | // RUN: mkdir -p %t/accesses 21 | // RUN: polygeist-opt --polyhedral-opt --use-polyhedral-optimizer=islexternal --islexternal-dump-schedules=%t/schedules --islexternal-dump-accesses=%t/accesses $ISL_OPT_PLACEHOLDER %s && find %t/schedules/ %t/accesses/ -type f -print0 | sort -z | xargs -0r cat | FileCheck --check-prefix=ISL_OUT %s 22 | // ISL_OUT: domain: "[P0] -> { S0[i0] : 0 <= i0 < P0 }" 23 | // ISL_OUT: accesses: 24 | // ISL_OUT: - S0: 25 | // ISL_OUT: reads: 26 | // ISL_OUT: writes: 27 | // ISL_OUT: - "[P0] -> { [i0] -> A1[o0] : o0 = i0 }" 28 | // ISL_OUT: { domain: "[P0] -> { S0[i0] : 0 <= i0 < P0 }", child: { schedule: "[P0] -> L0[{ S0[i0] -> [(i0)] }]" } } 29 | -------------------------------------------------------------------------------- /test/polygeist-opt/llvmmem2reg.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt --polygeist-mem2reg --split-input-file %s | FileCheck %s 2 | 3 | // TODO: Fix mem2reg using opaque llvm pointers 4 | // XFAIL: * 5 | 6 | module { 7 | func.func @ll(%arg0: !llvm.ptr) -> !llvm.ptr { 8 | %c1_i64 = arith.constant 1 : i64 9 | %2 = llvm.alloca %c1_i64 x !llvm.ptr : (i64) -> !llvm.ptr 10 | llvm.store %arg0, %2 : !llvm.ptr, !llvm.ptr 11 | %3 = llvm.load %2 : !llvm.ptr -> !llvm.ptr 12 | return %3 : !llvm.ptr 13 | } 14 | } 15 | 16 | // TODO Stopped working after opaque pointer update 17 | 18 | // CHECK: func.func @ll(%[[arg0:.+]]: !llvm.ptr) -> !llvm.ptr { 19 | // CHECK-NEXT: %[[c1_i64:.+]] = arith.constant 1 : i64 20 | // CHECK-NEXT: return %[[arg0]] : !llvm.ptr 21 | // CHECK-NEXT: } 22 | 23 | // ----- 24 | 25 | module { 26 | func.func @mixed(%mr : !llvm.ptr) { 27 | %2 = memref.alloc() : memref<2xf32> 28 | llvm.store %2, %mr : memref<2xf32>, !llvm.ptr 29 | return 30 | } 31 | } 32 | 33 | // CHECK-LABEL: func.func @mixed( 34 | // CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !llvm.ptr) { 35 | // CHECK: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]] = memref.alloc() : memref<2xf32> 36 | // CHECK: llvm.store %[[VAL_1]], %[[VAL_0]] : memref<2xf32>, !llvm.ptr 37 | // CHECK: return 38 | // CHECK: } 39 | -------------------------------------------------------------------------------- /test/polygeist-opt/mem2regaff.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt --polygeist-mem2reg --split-input-file %s | FileCheck %s 2 | 3 | module { 4 | func.func @ll(%arg0: i16) -> i16 { 5 | %1 = memref.alloca() : memref<1x1xi16> 6 | affine.store %arg0, %1[0, 0] : memref<1x1xi16> 7 | %4 = affine.load %1[0, 0] : memref<1x1xi16> 8 | return %4 : i16 9 | } 10 | } 11 | 12 | // CHECK: func.func @ll(%[[arg0:.+]]: i16) -> i16 { 13 | // CHECK-NEXT: return %[[arg0]] : i16 14 | // CHECK-NEXT: } 15 | -------------------------------------------------------------------------------- /test/polygeist-opt/mem2regshmembarrier.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt --polygeist-mem2reg --split-input-file %s | FileCheck %s 2 | 3 | module { 4 | func.func @f() -> f64 { 5 | %cst = arith.constant 3.141592e+00 : f64 6 | %c0 = arith.constant 0 : index 7 | %0 = memref.alloca() : memref 8 | %1 = llvm.mlir.undef : f64 9 | memref.store %1, %0[] : memref 10 | %8 = gpu.thread_id x 11 | %10 = arith.cmpi eq, %8, %c0 : index 12 | scf.if %10 { 13 | memref.store %cst, %0[] : memref 14 | } 15 | nvvm.barrier0 16 | %r11 = memref.load %0[] : memref 17 | return %r11 : f64 18 | } 19 | } 20 | 21 | // CHECK: func.func @f() -> f64 { 22 | // CHECK-DAG: %[[cst:.+]] = arith.constant 3.1415920000000002 : f64 23 | // CHECK-DAG: %[[c0:.+]] = arith.constant 0 : index 24 | // CHECK-NEXT: %[[V0:.+]] = memref.alloca() : memref 25 | // CHECK-NEXT: %[[V1:.+]] = llvm.mlir.undef : f64 26 | // CHECK-NEXT: memref.store %[[V1]], %[[V0]][] : memref 27 | // CHECK-NEXT: %[[V2:.+]] = gpu.thread_id x 28 | // CHECK-NEXT: %[[V3:.+]] = arith.cmpi eq, %[[V2]], %[[c0]] : index 29 | // CHECK-NEXT: scf.if %[[V3]] { 30 | // CHECK-NEXT: memref.store %[[cst]], %[[V0]][] : memref 31 | // CHECK-NEXT: } 32 | // CHECK-NEXT: nvvm.barrier0 33 | // CHECK-NEXT: %[[V4:.+]] = memref.load %[[V0]][] : memref 34 | // CHECK-NEXT: return %[[V4]] : f64 35 | // CHECK-NEXT: } 36 | -------------------------------------------------------------------------------- /test/polygeist-opt/multibuf.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt --canonicalize-polygeist --split-input-file %s --allow-unregistered-dialect | FileCheck %s 2 | 3 | module { 4 | func.func @multi(%arg0: i32, %arg1: memref>, %arg2: index, %arg3: index) -> (i32, i32) { 5 | %c0 = arith.constant 0 : index 6 | %c1 = arith.constant 1 : index 7 | %c8 = arith.constant 8 : index 8 | %c8_i64 = arith.constant 8 : i64 9 | %c2_i32 = arith.constant 2 : i32 10 | %alloca = memref.alloca(%arg3) : memref 11 | scf.for %arg4 = %c0 to %arg3 step %c1 { 12 | %a = arith.index_cast %arg4 : index to i32 13 | memref.store %c2_i32, %alloca[%arg4, %c0] : memref 14 | memref.store %a, %alloca[%arg4, %c1] : memref 15 | } 16 | %a10 = memref.load %alloca[%arg2, %c0] : memref 17 | %a11 = memref.load %alloca[%arg2, %c1] : memref 18 | return %a10, %a11 : i32, i32 19 | } 20 | } 21 | 22 | // CHECK: func.func @multi(%arg0: i32, %arg1: memref>, %arg2: index, %arg3: index) 23 | // CHECK-NEXT: %c2_i32 = arith.constant 2 : i32 24 | // CHECK-NEXT: %[[i0:.+]] = arith.index_cast %arg2 : index to i32 25 | // CHECK-NEXT: return %c2_i32, %[[i0]] : i32, i32 26 | // CHECK-NEXT: } 27 | -------------------------------------------------------------------------------- /test/polygeist-opt/promoteonscan.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt --polygeist-mem2reg --split-input-file %s | FileCheck %s 2 | 3 | module { 4 | llvm.func @scanf(!llvm.ptr, ...) -> i32 5 | llvm.mlir.global internal constant @str4("%d\00") {addr_space = 0 : i32} 6 | func.func @_Z8BFSGraphiPPc(%arg0: i32, %arg1: memref>) -> (i32, i32) { 7 | %c0_i32 = arith.constant 0 : i32 8 | %0 = llvm.mlir.undef : i32 9 | %alloca = memref.alloca() : memref<1xi32> 10 | affine.store %0, %alloca[0] : memref<1xi32> 11 | affine.store %c0_i32, %alloca[0] : memref<1xi32> 12 | %4 = affine.load %arg1[1] : memref> 13 | %8 = llvm.mlir.addressof @str4 : !llvm.ptr 14 | %9 = llvm.getelementptr %8[0, 0] {elem_type = !llvm.array<3 x i8>} : (!llvm.ptr) -> !llvm.ptr 15 | %10 = "polygeist.memref2pointer"(%alloca) : (memref<1xi32>) -> !llvm.ptr 16 | %11 = llvm.call @scanf(%9, %10) vararg(!llvm.func) : (!llvm.ptr, !llvm.ptr) -> i32 17 | %12 = affine.load %alloca[0] : memref<1xi32> 18 | %13 = affine.load %alloca[0] : memref<1xi32> 19 | return %13, %12 : i32, i32 20 | } 21 | // CHECK: %[[i4:.+]] = "polygeist.memref2pointer"(%[[alloca:.+]]) : (memref<1xi32>) -> !llvm.ptr 22 | // CHECK-NEXT: %[[i5:.+]] = llvm.call @scanf(%[[i3:.+]], %[[i4]]) vararg(!llvm.func) : (!llvm.ptr, !llvm.ptr) -> i32 23 | // CHECK-NEXT: %[[i6:.+]] = affine.load %[[alloca]][0] : memref<1xi32> 24 | // CHECK-NEXT: return %[[i6]], %[[i6]] : i32, i32 25 | } 26 | 27 | -------------------------------------------------------------------------------- /test/polygeist-opt/raisescffor.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt --raise-scf-to-affine %s | FileCheck %s 2 | module { 3 | func.func private @_Z12kernel5_initPc(%0: index, %arg0: memref) { 4 | %c10 = arith.constant 10 : index 5 | %c0 = arith.constant 0 : index 6 | scf.for %arg1 = %c0 to %c10 step %0 { 7 | memref.store %c10, %arg0[] : memref 8 | } 9 | return 10 | } 11 | } 12 | 13 | // CHECK-LABEL: func.func private @_Z12kernel5_initPc( 14 | // CHECK-SAME: %[[VAL_0:.*]]: index, 15 | // CHECK-SAME: %[[VAL_1:.*]]: memref) { 16 | // CHECK: %[[VAL_2:.*]] = arith.constant 1 : index 17 | // CHECK: %[[VAL_3:.*]] = arith.constant 10 : index 18 | // CHECK: %[[VAL_4:.*]] = arith.subi %[[VAL_0]], %[[VAL_2]] : index 19 | // CHECK: %[[VAL_5:.*]] = arith.addi %[[VAL_4]], %[[VAL_3]] : index 20 | // CHECK: %[[VAL_6:.*]] = arith.divui %[[VAL_5]], %[[VAL_0]] : index 21 | // CHECK: affine.for %[[VAL_7:.*]] = 0 to %[[VAL_6]] { 22 | // CHECK: memref.store %[[VAL_3]], %[[VAL_1]][] : memref 23 | // CHECK: } 24 | 25 | -------------------------------------------------------------------------------- /test/polygeist-opt/shiftloop.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt --canonicalize-scf-for --split-input-file %s | FileCheck %s 2 | 3 | module { 4 | func.func @foo(%arg0: i32) { 5 | %c1_i32 = arith.constant 1 : i32 6 | %c0_i32 = arith.constant 0 : i32 7 | %0 = scf.while (%arg1 = %arg0) : (i32) -> i32 { 8 | %1 = arith.cmpi ugt, %arg1, %c0_i32 : i32 9 | scf.condition(%1) %arg1 : i32 10 | } do { 11 | ^bb0(%arg1: i32): 12 | func.call @run(%arg1) : (i32) -> () 13 | %1 = arith.shrui %arg1, %c1_i32 : i32 14 | scf.yield %1 : i32 15 | } 16 | return 17 | } 18 | func.func private @run(i32) attributes {llvm.linkage = #llvm.linkage} 19 | } 20 | 21 | // CHECK: func.func @foo(%[[arg0:.+]]: i32) 22 | // CHECK-NEXT: %[[c32:.+]] = arith.constant 32 : index 23 | // CHECK-NEXT: %[[c0:.+]] = arith.constant 0 : index 24 | // CHECK-NEXT: %[[c1:.+]] = arith.constant 1 : index 25 | // CHECK-NEXT: %[[V0:.+]] = math.ctlz %[[arg0]] : i32 26 | // CHECK-NEXT: %[[V1:.+]] = arith.index_cast %[[V0]] : i32 to index 27 | // CHECK-NEXT: %[[V2:.+]] = arith.subi %[[c32]], %[[V1]] : index 28 | // CHECK-NEXT: scf.for %[[arg1:.+]] = %[[c0]] to %[[V2]] step %[[c1]] { 29 | // CHECK-NEXT: %[[V3:.+]] = arith.index_cast %[[arg1]] : index to i32 30 | // CHECK-NEXT: %[[V4:.+]] = arith.shrui %[[arg0]], %[[V3]] : i32 31 | // CHECK-NEXT: func.call @run(%[[V4]]) : (i32) -> () 32 | // CHECK-NEXT: } 33 | // CHECK-NEXT: return 34 | // CHECK-NEXT: } 35 | -------------------------------------------------------------------------------- /test/polygeist-opt/subindexbitcast.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt -convert-polygeist-to-llvm %s | FileCheck %s 2 | module { 3 | func.func @insert_into_leaf(%arg2: memref) -> memref { 4 | %c0 = arith.constant 0 : index 5 | %3 = "polygeist.subindex"(%arg2, %c0) : (memref, index) -> memref 6 | return %3 : memref 7 | } 8 | } 9 | 10 | // CHECK: llvm.func @insert_into_leaf(%arg0: !llvm.ptr) -> !llvm.ptr { 11 | // CHECK=NEXT: %0 = llvm.mlir.constant(0 : index) : i64 12 | // CHECK=NEXT: %1 = llvm.mlir.constant(0 : i64) : i64 13 | // CHECK=NEXT: %2 = llvm.getelementptr %arg0[%0, %1] : (!llvm.ptr, i64, i64) -> !llvm.ptr 14 | // CHECK=NEXT: %3 = llvm.bitcast %2 : !llvm.ptr to !llvm.ptr 15 | // CHECK=NEXT: llvm.return %3 : !llvm.ptr 16 | -------------------------------------------------------------------------------- /test/polygeist-opt/undeflower.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt --convert-polygeist-to-llvm %s | FileCheck %s 2 | 3 | module { 4 | func.func @f() -> index { 5 | %a = "polygeist.undef"() : () -> index 6 | // CHECK: llvm.mlir.undef 7 | func.return %a : index 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/polygeist-opt/whiletofor.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polygeist-opt --canonicalize-scf-for --split-input-file %s | FileCheck %s 2 | 3 | module { 4 | func.func @set(%arg0: memref, %arg1: i64) { 5 | %c1_i32 = arith.constant 1 : i32 6 | %c0_i32 = arith.constant 0 : i32 7 | %0 = scf.while (%arg2 = %c0_i32) : (i32) -> i32 { 8 | %1 = arith.extsi %arg2 : i32 to i64 9 | %2 = arith.cmpi slt, %1, %arg1 : i64 10 | scf.condition(%2) %arg2 : i32 11 | } do { 12 | ^bb0(%arg2: i32): // no predecessors 13 | %1 = arith.index_cast %arg2 : i32 to index 14 | memref.store %c0_i32, %arg0[%1] : memref 15 | %2 = arith.addi %arg2, %c1_i32 : i32 16 | scf.yield %2 : i32 17 | } 18 | return 19 | } 20 | } 21 | 22 | // CHECK: func.func @set(%[[arg0:.+]]: memref, %[[arg1:.+]]: i64) { 23 | // CHECK-DAG: %[[c0_i32:.+]] = arith.constant 0 : i32 24 | // CHECK-DAG: %[[c0:.+]] = arith.constant 0 : index 25 | // CHECK-DAG: %[[c1:.+]] = arith.constant 1 : index 26 | // CHECK-NEXT: %[[V0:.+]] = arith.index_cast %[[arg1]] : i64 to index 27 | // CHECK-NEXT: scf.for %[[arg2:.+]] = %[[c0]] to %[[V0]] step %[[c1]] { 28 | // CHECK-NEXT: %[[V1:.+]] = arith.index_cast %[[arg2]] : index to i32 29 | // CHECK-NEXT: %[[V2:.+]] = arith.index_cast %[[V1]] : i32 to index 30 | // CHECK-NEXT: memref.store %[[c0_i32]], %[[arg0]][%[[V2]]] : memref 31 | // CHECK-NEXT: } 32 | // CHECK-NEXT: return 33 | // CHECK-NEXT: } 34 | -------------------------------------------------------------------------------- /tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(polygeist-opt) 2 | add_subdirectory(cgeist) 3 | 4 | if(POLYGEIST_ENABLE_POLYMER) 5 | add_subdirectory(polymer) 6 | endif() 7 | -------------------------------------------------------------------------------- /tools/cgeist/.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle : LLVM 2 | -------------------------------------------------------------------------------- /tools/cgeist/.gitignore: -------------------------------------------------------------------------------- 1 | *.time *.exec1 *.out1 2 | *.execm 3 | -------------------------------------------------------------------------------- /tools/cgeist/Lib/AffineUtils.h: -------------------------------------------------------------------------------- 1 | //===- AffineUtils.h --------------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #ifndef MLIR_CLANG_AFFINE_UTILS_H 10 | #define MLIR_CLANG_AFFINE_UTILS_H 11 | 12 | #include 13 | 14 | namespace clang { 15 | class VarDecl; 16 | } // end namespace clang 17 | 18 | namespace mlir { 19 | class Value; 20 | class Type; 21 | } // end namespace mlir 22 | 23 | namespace mlirclang { 24 | 25 | struct AffineLoopDescriptorImpl; 26 | 27 | class AffineLoopDescriptor { 28 | private: 29 | std::unique_ptr impl; 30 | 31 | public: 32 | AffineLoopDescriptor(); 33 | ~AffineLoopDescriptor(); 34 | AffineLoopDescriptor(const AffineLoopDescriptor &) = delete; 35 | 36 | mlir::Value getLowerBound() const; 37 | void setLowerBound(mlir::Value value); 38 | 39 | mlir::Value getUpperBound() const; 40 | void setUpperBound(mlir::Value value); 41 | 42 | int getStep() const; 43 | void setStep(int value); 44 | 45 | clang::VarDecl *getName() const; 46 | void setName(clang::VarDecl *value); 47 | 48 | mlir::Type getType() const; 49 | void setType(mlir::Type type); 50 | 51 | bool getForwardMode() const; 52 | void setForwardMode(bool value); 53 | }; 54 | 55 | } // end namespace mlirclang 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /tools/cgeist/Lib/IfScope.h: -------------------------------------------------------------------------------- 1 | //===---- IfScope.h - Create an if statement to guard loop boundaries ----===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | #ifndef IF_SCOPE_H_ 9 | #define IF_SCOPE_H_ 10 | 11 | #include "mlir/IR/Block.h" 12 | 13 | class MLIRScanner; 14 | 15 | class IfScope { 16 | public: 17 | MLIRScanner &scanner; 18 | mlir::Block *prevBlock; 19 | mlir::Block::iterator prevIterator; 20 | IfScope(MLIRScanner &scanner); 21 | ~IfScope(); 22 | }; 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /tools/cgeist/Lib/TypeUtils.h: -------------------------------------------------------------------------------- 1 | //===- type utils.h ---------------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #ifndef MLIR_TOOLS_MLIRCLANG_TYPE_UTILS_H 10 | #define MLIR_TOOLS_MLIRCLANG_TYPE_UTILS_H 11 | 12 | #include "llvm/ADT/SmallPtrSet.h" 13 | 14 | namespace llvm { 15 | class Type; 16 | } 17 | 18 | namespace mlirclang { 19 | 20 | llvm::Type *anonymize(llvm::Type *T); 21 | bool isRecursiveStruct(llvm::Type *T, llvm::Type *Meta, 22 | llvm::SmallPtrSetImpl &seen); 23 | 24 | } // namespace mlirclang 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /tools/cgeist/Lib/ValueCategory.h: -------------------------------------------------------------------------------- 1 | //===- ValueCategory.h -------------------------------------------*- C++-*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #ifndef CLANG_MLIR_VALUE_CATEGORY 10 | #define CLANG_MLIR_VALUE_CATEGORY 11 | 12 | #include "mlir/IR/Builders.h" 13 | #include "mlir/IR/Value.h" 14 | 15 | // Represents a rhs or lhs value. 16 | class ValueCategory { 17 | public: 18 | mlir::Value val; 19 | bool isReference; 20 | 21 | public: 22 | ValueCategory() : val(nullptr), isReference(false){}; 23 | ValueCategory(std::nullptr_t) : val(nullptr), isReference(false){}; 24 | ValueCategory(mlir::Value val, bool isReference); 25 | 26 | // TODO: rename to 'loadVariable'? getValue seems to generic. 27 | mlir::Value getValue(mlir::Location loc, mlir::OpBuilder &builder) const; 28 | void store(mlir::Location loc, mlir::OpBuilder &builder, 29 | ValueCategory toStore, bool isArray) const; 30 | // TODO: rename to storeVariable? 31 | void store(mlir::Location loc, mlir::OpBuilder &builder, 32 | mlir::Value toStore) const; 33 | ValueCategory dereference(mlir::Location loc, mlir::OpBuilder &builder) const; 34 | }; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /tools/cgeist/Test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(MLIR_CLANG_TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}) 2 | set(MLIR_CLANG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) 3 | 4 | configure_lit_site_cfg( 5 | ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in 6 | ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg 7 | MAIN_CONFIG 8 | ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg 9 | ) 10 | 11 | list(APPEND MLIR_CLANG_TEST_DEPS 12 | llvm-config 13 | FileCheck count not 14 | cgeist 15 | split-file 16 | clang 17 | ) 18 | 19 | add_lit_testsuite(check-cgeist "Running the clang-to-mlir regression tests" 20 | ${CMAKE_CURRENT_BINARY_DIR} 21 | DEPENDS ${MLIR_CLANG_TEST_DEPS} 22 | ) 23 | 24 | add_lit_testsuite(check-cgeist-single "Running the clang-to-mlir regression tests" 25 | ${CMAKE_CURRENT_BINARY_DIR} 26 | DEPENDS ${MLIR_CLANG_TEST_DEPS} 27 | ARGS -j 1 28 | ) 29 | 30 | set_target_properties(check-cgeist PROPERTIES FOLDER "clang-to-mlir tests") 31 | -------------------------------------------------------------------------------- /tools/cgeist/Test/CUDA/polybench-cuda/AUTHORS: -------------------------------------------------------------------------------- 1 | * * * * * * * * * * * * * 2 | * Authors of PolyBench * 3 | * * * * * * * * * * * * * 4 | 5 | 6 | * Louis-Noel Pouchet 7 | Who provided packaging and harmonization of all test files, 8 | the PolyBench infrastructure and machinery, and several 9 | reference C files. 10 | 11 | * Uday Bondugula 12 | Who provided many of the original reference C files, including 13 | Fortran to C translation. 14 | 15 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/addressof.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s %stdinclude --function=* -S | FileCheck %s 2 | 3 | #include 4 | 5 | struct Ptr { 6 | }; 7 | 8 | Ptr *foo() 9 | { 10 | Ptr p; 11 | return std::addressof(p); // calls Ptr* overload, (= this) 12 | } 13 | 14 | Ptr *bar() 15 | { 16 | Ptr p; 17 | return __builtin_addressof(p); // calls Ptr* overload, (= this) 18 | } 19 | 20 | // CHECK-LABEL: func.func @_Z3foov() -> memref> 21 | // CHECK: %[[VAL_0:[A-Za-z0-9_]*]] = memref.alloca() : memref<1x!llvm.struct<(i8)>> 22 | // CHECK: %[[VAL_1:[A-Za-z0-9_]*]] = memref.cast %[[VAL_0]] : memref<1x!llvm.struct<(i8)>> to memref> 23 | // CHECK: return %[[VAL_1]] : memref> 24 | // CHECK: } 25 | 26 | // CHECK-LABEL: func.func @_Z3barv() -> memref> 27 | // CHECK: %[[VAL_0:[A-Za-z0-9_]*]] = memref.alloca() : memref<1x!llvm.struct<(i8)>> 28 | // CHECK: %[[VAL_1:[A-Za-z0-9_]*]] = memref.cast %[[VAL_0]] : memref<1x!llvm.struct<(i8)>> to memref> 29 | // CHECK: return %[[VAL_1]] : memref> 30 | // CHECK: } 31 | 32 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/affine_loop.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=kernel_deriche -S | FileCheck %s 2 | 3 | void kernel_deriche(int w, int h, double alpha, double** y2) { 4 | int i,j; 5 | 6 | #pragma scop 7 | for (i=0; i=0; j--) { 9 | y2[i][j] = alpha; 10 | } 11 | } 12 | #pragma endscop 13 | } 14 | // CHECK: func @kernel_deriche(%[[arg0:.+]]: i32, %[[arg1:.+]]: i32, %[[arg2:.+]]: f64, %[[arg3:.+]]: memref>) 15 | // CHECK-NEXT: %[[V0:.+]] = arith.index_cast %[[arg1]] : i32 to index 16 | // CHECK-NEXT: %[[V1:.+]] = arith.index_cast %[[arg0]] : i32 to index 17 | // CHECK-NEXT: affine.for %[[arg4:.+]] = 0 to %[[V1]] { 18 | // CHECK-NEXT: affine.for %[[arg5:.+]] = 0 to %[[V0]] { 19 | // CHECK-NEXT: %[[V2:.+]] = affine.load %[[arg3]][%[[arg4]]] : memref> 20 | // CHECK-NEXT: affine.store %[[arg2]], %[[V2]][-%[[arg5]] + symbol(%[[V0]]) - 1] : memref 21 | // CHECK-NEXT: } 22 | // CHECK-NEXT: } 23 | // CHECK-NEXT: return 24 | // CHECK-NEXT: } 25 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/affun.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=okernel_2mm -S | FileCheck %s 2 | 3 | void okernel_2mm(unsigned int ni, 4 | double *tmp) { 5 | int i, j, k; 6 | 7 | #pragma scop 8 | /* D := alpha*A*B*C + beta*D */ 9 | for (i = 0; i < ni; i++) 10 | { 11 | tmp[i] = 0.0; 12 | } 13 | #pragma endscop 14 | } 15 | 16 | // CHECK: func @okernel_2mm(%[[arg0:.+]]: i32, %[[arg1:.+]]: memref) 17 | // CHECK-NEXT: %[[cst:.+]] = arith.constant 0.000000e+00 : f64 18 | // CHECK-NEXT: %[[V0:.+]] = arith.index_cast %[[arg0]] : i32 to index 19 | // CHECK-NEXT: affine.for %[[arg2:.+]] = 0 to %[[V0]] { 20 | // CHECK-NEXT: affine.store %[[cst]], %[[arg1]][%[[arg2]]] : memref 21 | // CHECK-NEXT: } 22 | // CHECK-NEXT: return 23 | // CHECK-NEXT: } 24 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/alignof.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist -std=c++11 %s --function=* -S | FileCheck %s 2 | 3 | struct Meta { 4 | float* f; 5 | char x; 6 | }; 7 | 8 | unsigned create() { 9 | return alignof(struct Meta); 10 | } 11 | 12 | unsigned create2() { 13 | return alignof(char); 14 | } 15 | 16 | // CHECK: func @_Z6createv() -> i32 17 | // CHECK-NEXT: %[[V0:.+]] = "polygeist.typeAlign"() <{source = !llvm.struct<(memref, i8)>}> : () -> index 18 | // CHECK-NEXT: %[[V1:.+]] = arith.index_cast %[[V0]] : index to i64 19 | // CHECK-NEXT: %[[V2:.+]] = arith.trunci %[[V1]] : i64 to i32 20 | // CHECK-NEXT: return %[[V2]] : i32 21 | // CHECK-NEXT: } 22 | 23 | // CHECK: func @_Z7create2v() -> i32 24 | // CHECK-NEXT: %[[c1_i32:.+]] = arith.constant 1 : i32 25 | // CHECK-NEXT: return %[[c1_i32]] : i32 26 | // CHECK-NEXT: } 27 | 28 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/arrayconsmemref.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | struct AIntDivider { 4 | AIntDivider() : divisor(3) {} 5 | unsigned int divisor; 6 | }; 7 | 8 | void kern() { 9 | AIntDivider sizes_[25]; 10 | } 11 | 12 | // CHECK: func @_Z4kernv() 13 | // CHECK-DAG: %[[c25:.+]] = arith.constant 25 : index 14 | // CHECK-DAG: %[[c1:.+]] = arith.constant 1 : index 15 | // CHECK-DAG: %[[c0:.+]] = arith.constant 0 : index 16 | // CHECK-NEXT: %[[V0:.+]] = memref.alloca() : memref<25x1xi32> 17 | // CHECK-NEXT: scf.for %[[arg0:.+]] = %[[c0]] to %[[c25]] step %[[c1]] { 18 | // CHECK-NEXT: %[[V1:.+]] = "polygeist.subindex"(%[[V0]], %[[arg0]]) : (memref<25x1xi32>, index) -> memref 19 | // CHECK-NEXT: call @_ZN11AIntDividerC1Ev(%[[V1]]) : (memref) -> () 20 | // CHECK-NEXT: } 21 | // CHECK-NEXT: return 22 | // CHECK-NEXT: } 23 | // CHECK: func @_ZN11AIntDividerC1Ev(%[[arg0:.+]]: memref) 24 | // CHECK-NEXT: %[[c3_i32:.+]] = arith.constant 3 : i32 25 | // CHECK-NEXT: affine.store %[[c3_i32]], %[[arg0]][0, 0] : memref 26 | // CHECK-NEXT: return 27 | // CHECK-NEXT: } 28 | 29 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/arrayinit.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function='*' -S | FileCheck %s 2 | // TODO: 3 | // XFAIL: * 4 | 5 | struct Int { 6 | int divisor; 7 | }; 8 | 9 | struct IntArray { 10 | Int sizes_[4]; 11 | }; 12 | 13 | IntArray foo(IntArray &o) { 14 | return o; 15 | } 16 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/atomicld.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s %stdinclude --function=ld -S | FileCheck %s 2 | // RUN: cgeist %s %stdinclude --function=ld -S -emit-llvm | FileCheck %s --check-prefix=LLVM 3 | 4 | int ld(int* x, int i) { 5 | int res; 6 | __atomic_load(&x[i], &res, 0); 7 | return res; 8 | } 9 | 10 | // CHECK: func.func @ld(%arg0: memref, %arg1: i32) -> i32 11 | // CHECK-NEXT: %c0_i32 = arith.constant 0 : i32 12 | // CHECK-NEXT: %0 = arith.index_cast %arg1 : i32 to index 13 | // CHECK-NEXT: %1 = memref.atomic_rmw addi %c0_i32, %arg0[%0] : (i32, memref) -> i32 14 | // CHECK-NEXT: return %1 : i32 15 | // CHECK-NEXT: } 16 | 17 | // LLVM: define i32 @ld(ptr %0, i32 %1) 18 | // LLVM: %[[VAL_0:[A-Za-z0-9_]*]] = sext i32 %1 to i64 19 | // LLVM: %[[VAL_2:[A-Za-z0-9_]*]] = getelementptr i32, ptr %0, i64 %[[VAL_0]] 20 | // LLVM: %[[VAL_4:[A-Za-z0-9_]*]] = atomicrmw add ptr %[[VAL_2]], i32 0 acq_rel, align 4 21 | // LLVM: ret i32 %[[VAL_4]] 22 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/base_with_virt2.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | class M { 4 | }; 5 | 6 | struct _Alloc_hider : M 7 | { 8 | _Alloc_hider() { } 9 | 10 | char* _M_p; // The actual data. 11 | }; 12 | 13 | 14 | class basic_streambuf 15 | { 16 | public: 17 | /// Destructor deallocates no buffer space. 18 | virtual 19 | ~basic_streambuf() 20 | { } 21 | }; 22 | class mbasic_stringbuf : public basic_streambuf 23 | 24 | { 25 | public: 26 | 27 | _Alloc_hider _M_dataplus; 28 | mbasic_stringbuf() 29 | { } 30 | 31 | }; 32 | 33 | void a() { 34 | mbasic_stringbuf a; 35 | } 36 | // CHECK-LABEL: func.func @_Z1av() 37 | // CHECK: return 38 | // CHECK: } 39 | 40 | // CHECK-LABEL: func.func @_ZN16mbasic_stringbufC1Ev( 41 | // CHECK-SAME: %[[VAL_0:[A-Za-z0-9_]*]]: memref, !llvm.struct<(struct<(i8)>, memref)>)>>) 42 | // CHECK: return 43 | // CHECK: } 44 | 45 | // CHECK-LABEL: func.func @_ZN15basic_streambufC1Ev( 46 | // CHECK-SAME: %[[VAL_0:[A-Za-z0-9_]*]]: memref>) 47 | // CHECK: return 48 | // CHECK: } 49 | 50 | // CHECK-LABEL: func.func @_ZN12_Alloc_hiderC1Ev( 51 | // CHECK-SAME: %[[VAL_0:[A-Za-z0-9_]*]]: memref, memref)>>) 52 | // CHECK: return 53 | // CHECK: } 54 | 55 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/call.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | // RUN: cgeist %s --function=* -S -memref-fullrank | FileCheck %s --check-prefix=FULLRANK 3 | 4 | void sub0(int a[2]); 5 | void sub(int a[2]) { a[2]++; } 6 | 7 | void kernel_deriche() { 8 | int a[2]; 9 | sub0(a); 10 | } 11 | 12 | // FULLRANK: @sub(%[[arg0:.+]]: memref<2xi32>) 13 | // CHECK: @sub(%[[arg0:.+]]: memref) 14 | // CHECK-NEXT: %[[c1_i32:.+]] = arith.constant 1 : i32 15 | // CHECK-NEXT: %[[V0:.+]] = affine.load %[[arg0]][2] : memref 16 | // CHECK-NEXT: %[[V1:.+]] = arith.addi %[[V0]], %[[c1_i32]] : i32 17 | // CHECK-NEXT: affine.store %[[V1]], %[[arg0]][2] : memref 18 | // CHECK-NEXT: return 19 | // CHECK-NEXT: } 20 | 21 | // CHECK: func @kernel_deriche() 22 | // CHECK-NEXT: %[[V0:.+]] = memref.alloca() : memref<2xi32> 23 | // CHECK-NEXT: %[[V1:.+]] = memref.cast %[[V0]] : memref<2xi32> to memref 24 | // CHECK-NEXT: call @sub0(%[[V1]]) : (memref) -> () 25 | // CHECK-NEXT: return 26 | // CHECK-NEXT: } 27 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/calloc.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | void* calloc(unsigned long a, unsigned long b); 4 | 5 | float* zmem(int n) { 6 | float* out = (float*)calloc(sizeof(float), n); 7 | return out; 8 | } 9 | 10 | // CHECK: func @zmem(%[[arg0:.+]]: i32) -> memref 11 | // CHECK-DAG: %[[c4:.+]] = arith.constant 4 : index 12 | // CHECK-DAG: %[[cst:.+]] = arith.constant 0.000000e+00 : f32 13 | // CHECK-DAG: %[[c1:.+]] = arith.constant 1 : index 14 | // CHECK-DAG: %[[c0:.+]] = arith.constant 0 : index 15 | // CHECK-NEXT: %[[V0:.+]] = arith.index_cast %[[arg0]] : i32 to index 16 | // CHECK-NEXT: %[[V1:.+]] = arith.muli %[[V0]], %[[c4]] : index 17 | // CHECK-NEXT: %[[V2:.+]] = arith.divui %[[V1]], %[[c4]] : index 18 | // CHECK-NEXT: %[[V3:.+]] = memref.alloc(%[[V2]]) : memref 19 | // CHECK-NEXT: scf.for %[[arg1:.+]] = %[[c0]] to %[[V2]] step %[[c1]] { 20 | // CHECK-NEXT: memref.store %[[cst]], %[[V3]][%[[arg1]]] : memref 21 | // CHECK-NEXT: } 22 | // CHECK-NEXT: return %[[V3]] : memref 23 | // CHECK-NEXT: } 24 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/charswitch.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=foo -S | FileCheck %s 2 | 3 | extern "C" { 4 | int foo(char t) { 5 | int n = 10; 6 | switch (t) { 7 | case 'a': 8 | n = 20; 9 | break; 10 | case 'A': 11 | n = 30; 12 | break; 13 | default: 14 | return -1; 15 | } 16 | return n; 17 | } 18 | } 19 | 20 | // TODO the select should be canonicalized better 21 | // CHECK: func @foo(%[[arg0:.+]]: i8) -> i32 22 | // CHECK-DAG: %[[cm1:.+]] = arith.constant -1 : i32 23 | // CHECK-DAG: %[[c30_i32:.+]] = arith.constant 30 : i32 24 | // CHECK-DAG: %[[false:.+]] = arith.constant false 25 | // CHECK-DAG: %[[c20_i32:.+]] = arith.constant 20 : i32 26 | // CHECK-DAG: %[[c10_i32:.+]] = arith.constant 10 : i32 27 | // CHECK-DAG: %[[true:.+]] = arith.constant true 28 | // CHECK-DAG: %[[V0:.+]] = llvm.mlir.undef : i32 29 | // CHECK-DAG: %[[V1:.+]] = arith.extsi %[[arg0]] : i8 to i32 30 | // CHECK-NEXT: switch %[[V1]] : i32, [ 31 | // CHECK-NEXT: default: ^bb1(%[[c10_i32]], %[[false]], %[[cm1]] : i32, i1, i32), 32 | // CHECK-NEXT: 97: ^bb1(%[[c20_i32]], %[[true]], %[[V0]] : i32, i1, i32), 33 | // CHECK-NEXT: 65: ^bb1(%[[c30_i32]], %[[true]], %[[V0]] : i32, i1, i32) 34 | // CHECK-NEXT: ] 35 | // CHECK-NEXT: ^bb1(%[[V2:.+]]: i32, %[[V3:.+]]: i1, %[[V4:.+]]: i32): // 3 preds: ^bb0, ^bb0, ^bb0 36 | // CHECK-NEXT: %[[V5:.+]] = arith.select %[[V3]], %[[V2]], %[[V4]] : i32 37 | // CHECK-NEXT: return %[[V5]] : i32 38 | // CHECK-NEXT: } 39 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/clangbuiltin.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | #include 4 | 5 | float moo(float &&x) { 6 | return std::move(x); 7 | } 8 | 9 | // CHECK: func.func @_Z3mooOf(%[[arg0:.+]]: memref) 10 | // CHECK-NEXT: %[[V0:.+]] = affine.load %[[arg0]][0] : memref 11 | // CHECK-NEXT: return %[[V0]] : f32 12 | // CHECK-NEXT: } 13 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/cond.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s %stdinclude --function=set -S | FileCheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | /* Array initialization. */ 10 | 11 | int set (int b) 12 | { 13 | int res; 14 | if (b) 15 | res = 1; 16 | else 17 | res = 2; 18 | return res; 19 | //path[0][1] = 2; 20 | } 21 | 22 | // CHECK: func @set(%[[arg0:.+]]: i32) -> i32 23 | // CHCEK-NEXT: %[[c1_i32:.+]] = constant 1 : i32 24 | // CHCEK-NEXT: %[[c2_i32:.+]] = constant 2 : i32 25 | // CHCEK-NEXT: %[[V0:.+]] = arith.trunci %[[arg0]] : i32 to i1 26 | // CHCEK-NEXT: %[[V1:.+]] = arith.select %[[V0]], %[[c1_i32]], %[[c2_i32]] : i32 27 | // CHCEK-NEXT: return %[[V1]] : i32 28 | // CHCEK-NEXT: } 29 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/cond2.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s %stdinclude --function=set -S | FileCheck %s 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | /* Array initialization. */ 10 | 11 | int set (int b) 12 | { 13 | int res = 1; 14 | if (b) 15 | res = 2; 16 | return res; 17 | //path[0][1] = 2; 18 | } 19 | 20 | // CHECK: func @set(%[[arg0:.+]]: i32) -> i32 21 | // CHCEK-NEXT: %[[c1_i32:.+]] = constant 1 : i32 22 | // CHCEK-NEXT: %[[c2_i32:.+]] = constant 2 : i32 23 | // CHCEK-NEXT: %[[V0:.+]] = arith.trunci %[[arg0]] : i32 to i1 24 | // CHCEK-NEXT: %[[V1:.+]] = arith.select %[[V0]], %[[c2_i32]], %[[c1_i32]] : i32 25 | // CHCEK-NEXT: return %[[V1]] : i32 26 | // CHCEK-NEXT: } 27 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/constexpr.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | constexpr int num = 10 + 4; 3 | 4 | int sum(int*); 5 | 6 | int foo() { 7 | int sz[num]; 8 | for(int i=0; i i32 14 | // CHECK-DAG: %[[c1:.+]] = arith.constant 1 : index 15 | // CHECK-DAG: %[[c0:.+]] = arith.constant 0 : index 16 | // CHECK-DAG: %[[c14:.+]] = arith.constant 14 : index 17 | // CHECK-NEXT: %[[V0:.+]] = memref.alloca() : memref<14xi32> 18 | // CHECK-NEXT: scf.for %[[arg0:.+]] = %[[c0]] to %[[c14]] step %[[c1]] { 19 | // CHECK-NEXT: %[[V3:.+]] = arith.index_cast %[[arg0]] : index to i32 20 | // CHECK-NEXT: memref.store %[[V3]], %[[V0]][%[[arg0]]] : memref<14xi32> 21 | // CHECK-NEXT: } 22 | // CHECK-NEXT: %[[V1:.+]] = memref.cast %[[V0]] : memref<14xi32> to memref 23 | // CHECK-NEXT: %[[V2:.+]] = call @_Z3sumPi(%[[V1]]) : (memref) -> i32 24 | // CHECK-NEXT: return %[[V2]] : i32 25 | // CHECK-NEXT: } 26 | 27 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/cout.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | // XFAIL: * 3 | #include 4 | 5 | void moo(int x) { 6 | std::cout << x << std::endl; 7 | } 8 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/ctz.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s %stdinclude --function=* -S | FileCheck %s 2 | 3 | // CHECK: func.func @do_ctzs(%[[ARG:[A-Za-z0-9_]*]]: i16) -> i32 4 | // CHECK-NEXT: %[[VAL_0:[A-Za-z0-9_]*]] = math.cttz %[[ARG]] : i16 5 | // CHECK-NEXT: %[[VAL_1:[A-Za-z0-9_]*]] = arith.extui %[[VAL_0]] : i16 to i32 6 | // CHECK-NEXT: return %[[VAL_1]] : i32 7 | // CHECK-NEXT: } 8 | 9 | int do_ctzs(short int i) { 10 | return __builtin_ctzs(i); 11 | } 12 | 13 | // CHECK: func.func @do_ctz(%[[ARG:[A-Za-z0-9_]*]]: i32) -> i32 14 | // CHECK-NEXT: %[[VAL:[A-Za-z0-9_]*]] = math.cttz %[[ARG]] : i32 15 | // CHECK-NEXT: return %[[VAL]] : i32 16 | // CHECK-NEXT: } 17 | 18 | int do_ctz(int i) { 19 | return __builtin_ctz(i); 20 | } 21 | 22 | // CHECK: func.func @do_ctzl(%[[ARG:[A-Za-z0-9_]*]]: i64) -> i32 23 | // CHECK-NEXT: %[[VAL_0:[A-Za-z0-9_]*]] = math.cttz %[[ARG]] : i64 24 | // CHECK-NEXT: %[[VAL_1:[A-Za-z0-9_]*]] = arith.trunci %[[VAL_0]] : i64 to i32 25 | // CHECK-NEXT: return %[[VAL_1]] : i32 26 | // CHECK-NEXT: } 27 | 28 | int do_ctzl(unsigned long i) { 29 | return __builtin_ctzl(i); 30 | } 31 | 32 | // CHECK: func.func @do_ctzll(%[[ARG:[A-Za-z0-9_]*]]: i64) -> i32 33 | // CHECK-NEXT: %[[VAL_0:[A-Za-z0-9_]*]] = math.cttz %[[ARG]] : i64 34 | // CHECK-NEXT: %[[VAL_1:[A-Za-z0-9_]*]] = arith.trunci %[[VAL_0]] : i64 to i32 35 | // CHECK-NEXT: return %[[VAL_1]] : i32 36 | // CHECK-NEXT: } 37 | 38 | int do_ctzll(unsigned long long i) { 39 | return __builtin_ctzl(i); 40 | } 41 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/cudaglobalcodegen.cu: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --cuda-gpu-arch=sm_60 -nocudalib -nocudainc %resourcedir --function=* -S | FileCheck %s 2 | 3 | #include "Inputs/cuda.h" 4 | 5 | __global__ void bar(int * a) 6 | { 7 | #ifdef __CUDA_ARCH__ 8 | *a = 1; 9 | #else 10 | *a = 2; 11 | #endif 12 | } 13 | 14 | void baz(int * a){ 15 | bar<<>>(a); 16 | } 17 | // CHECK: func private @_Z18__device_stub__barPi(%[[arg0:.+]]: memref) 18 | // CHECK-NEXT: %[[c1_i32:.+]] = arith.constant 1 : i32 19 | // CHECK-NEXT: affine.store %[[c1_i32]], %[[arg0]][0] : memref 20 | // CHECK-NEXT: return 21 | // CHECK-NEXT: } 22 | // CHECK: func @_Z3bazPi(%[[arg0:.+]]: memref) 23 | // CHECK-NEXT: %[[c1:.+]] = arith.constant 1 : index 24 | // CHECK-NEXT: gpu.launch blocks(%[[arg1:.+]], %[[arg2:.+]], %[[arg3:.+]]) in (%[[arg7:.+]] = %[[c1]], %[[arg8:.+]] = %[[c1]], %[[arg9:.+]] = %[[c1]]) threads(%[[arg4:.+]], %[[arg5:.+]], %[[arg6:.+]]) in (%[[arg10:.+]] = %[[c1]], %[[arg11:.+]] = %[[c1]], %[[arg12:.+]] = %[[c1]]) { 25 | // CHECK-NEXT: call @_Z18__device_stub__barPi(%[[arg0]]) : (memref) -> () 26 | // CHECK-NEXT: gpu.terminator 27 | // CHECK-NEXT: } 28 | // CHECK-NEXT: return 29 | // CHECK-NEXT: } 30 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/cugen.cu: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --cuda-gpu-arch=sm_60 -nocudalib -nocudainc %resourcedir --function=* --cuda-lower --cpuify="distribute" -S | FileCheck %s 2 | 3 | #include "Inputs/cuda.h" 4 | #include "__clang_cuda_builtin_vars.h" 5 | 6 | #define N 20 7 | 8 | __device__ void bar(double* w) { 9 | w[threadIdx.x] = 2.0; 10 | } 11 | 12 | __global__ void foo(double * w) { 13 | bar(w); 14 | } 15 | 16 | template 17 | void templ(T fn, double *w) { 18 | fn<<< 1, N >>>(w); 19 | } 20 | 21 | void start(double* w) { 22 | templ(foo, w); 23 | } 24 | 25 | // CHECK: func.func @_Z5startPd(%arg0: memref) 26 | // CHECK-NEXT: %cst = arith.constant 2.000000e+00 : f64 27 | // CHECK-NEXT: %c0 = arith.constant 0 : index 28 | // CHECK-NEXT: %c20 = arith.constant 20 : index 29 | // CHECK-NEXT: %c1 = arith.constant 1 : index 30 | // CHECK-NEXT: scf.parallel (%arg1) = (%c0) to (%c20) step (%c1) { 31 | // CHECK-NEXT: memref.store %cst, %arg0[%arg1] : memref 32 | // CHECK-NEXT: scf.yield 33 | // CHECK-NEXT: } 34 | // CHECK-NEXT: return 35 | // CHECK-NEXT: } 36 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/cugen2.cu: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --cuda-gpu-arch=sm_60 -nocudalib -nocudainc %resourcedir --function=* --cuda-lower --cpuify="distribute" -S | FileCheck %s 2 | 3 | #include "Inputs/cuda.h" 4 | #include "__clang_cuda_builtin_vars.h" 5 | 6 | #define N 20 7 | 8 | __device__ void bar(double* w) { 9 | w[threadIdx.x] = 2.0; 10 | } 11 | 12 | __global__ void foo(double * w) { 13 | bar(w); 14 | } 15 | 16 | void something(double*); 17 | 18 | template 19 | void templ(T fn, double *w) { 20 | something(w); 21 | } 22 | 23 | void start(double* w) { 24 | templ(foo, w); 25 | } 26 | 27 | // CHECK: func.func @_Z5startPd(%arg0: memref) 28 | // CHECK-NEXT: call @_Z9somethingPd(%arg0) : (memref) -> () 29 | // CHECK-NEXT: return 30 | // CHECK-NEXT: } 31 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/decrement.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | int prefix_decrement(int x) 4 | { 5 | return --x; 6 | } 7 | 8 | int postfix_decrement(int x) 9 | { 10 | return x--; 11 | } 12 | 13 | // CHECK: func.func @prefix_decrement(%[[arg0:.+]]: i32) -> i32 attributes {llvm.linkage = #llvm.linkage} { 14 | // CHECK-NEXT: %[[c1_i32:.+]] = arith.constant -1 : i32 15 | // CHECK-NEXT: %[[V0:.+]] = arith.addi %[[arg0]], %[[c1_i32]] : i32 16 | // CHECK-NEXT: return %[[V0]] : i32 17 | // CHECK-NEXT: } 18 | 19 | // CHECK: func.func @postfix_decrement(%[[arg0:.+]]: i32) -> i32 attributes {llvm.linkage = #llvm.linkage} { 20 | // CHECK-NEXT: return %[[arg0]] : i32 21 | // CHECK-NEXT: } 22 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/defines.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist -DOUTPUT -DTEST -c %s -S | FileCheck %s 2 | 3 | int main(int argc, char **argv) 4 | { 5 | #ifdef OUTPUT 6 | return 1; 7 | #else 8 | return 2; 9 | #endif 10 | } 11 | 12 | // CHECK: func.func @main(%arg0: i32, %arg1: memref>) -> i32 13 | // CHECK-NEXT: %c1_i32 = arith.constant 1 : i32 14 | // CHECK-NEXT: return %c1_i32 : i32 15 | // CHECK-NEXT: } 16 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/der.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=kernel_deriche -S | FileCheck %s 2 | 3 | float kernel_deriche() { 4 | float a2, a6; 5 | a2 = a6 = 2.0;//EXP_FUN(-alpha); 6 | return a2; 7 | } 8 | 9 | // CHECK: func @kernel_deriche() -> f32 10 | // CHECK-NEXT: %[[cst:.+]] = arith.constant 2.000000e+00 : f32 11 | // CHECK-NEXT: return %[[cst]] : f32 12 | // CHECK-NEXT: } 13 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/deref.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=kernel_deriche -S | FileCheck %s 2 | 3 | int deref(int a); 4 | 5 | void kernel_deriche(int *a) { 6 | deref(*a); 7 | } 8 | 9 | // CHECK: func @kernel_deriche(%[[arg0:.+]]: memref) 10 | // CHECK-NEXT: %[[V0:.+]] = affine.load %[[arg0]][0] : memref 11 | // CHECK-NEXT: %[[V1:.+]] = call @deref(%[[V0]]) : (i32) -> i32 12 | // CHECK-NEXT: return 13 | // CHECK-NEXT: } 14 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/derived.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | struct A { 4 | int x; 5 | double y; 6 | }; 7 | 8 | struct B : public A { 9 | void* z; 10 | }; 11 | 12 | int ref(struct B& v) { 13 | return v.x; 14 | } 15 | 16 | int ptr(struct B* v) { 17 | return v->x; 18 | } 19 | // CHECK-LABEL: func.func @_Z3refR1B( 20 | // CHECK-SAME: %[[VAL_0:[A-Za-z0-9_]*]]: memref, memref)>>) -> i32 21 | // CHECK: %[[VAL_1:[A-Za-z0-9_]*]] = "polygeist.memref2pointer"(%[[VAL_0]]) : (memref, memref)>>) -> !llvm.ptr 22 | // CHECK: %[[VAL_2:[A-Za-z0-9_]*]] = llvm.load %[[VAL_1]] : !llvm.ptr -> i32 23 | // CHECK: return %[[VAL_2]] : i32 24 | // CHECK: } 25 | 26 | // CHECK-LABEL: func.func @_Z3ptrP1B( 27 | // CHECK-SAME: %[[VAL_0:[A-Za-z0-9_]*]]: memref, memref)>>) -> i32 28 | // CHECK: %[[VAL_1:[A-Za-z0-9_]*]] = "polygeist.memref2pointer"(%[[VAL_0]]) : (memref, memref)>>) -> !llvm.ptr 29 | // CHECK: %[[VAL_2:[A-Za-z0-9_]*]] = llvm.load %[[VAL_1]] : !llvm.ptr -> i32 30 | // CHECK: return %[[VAL_2]] : i32 31 | // CHECK: } 32 | 33 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/dynalloc.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=create_matrix -S | FileCheck %s 2 | 3 | void create_matrix(float *m, int size) { 4 | float coe[2 * size + 1]; 5 | coe[size] = 1.0; 6 | m[size] = coe[size] + coe[0]; 7 | } 8 | 9 | // CHECK: func @create_matrix(%[[arg0:.+]]: memref, %[[arg1:.+]]: i32) 10 | // CHECK-DAG: %[[c0:.+]] = arith.constant 0 : index 11 | // CHECK-DAG: %[[cst:.+]] = arith.constant 1.000000e+00 : f32 12 | // CHECK-NEXT: %[[i3:.+]] = memref.alloca() : memref 13 | // CHECK-NEXT: %[[i4:.+]] = arith.index_cast %[[arg1]] : i32 to index 14 | // CHECK-NEXT: %[[V2:.+]] = arith.cmpi eq, %{{.*}}, %[[c0]] : index 15 | // CHECK-NEXT: scf.if %[[V2]] { 16 | // CHECK-NEXT: affine.store %[[cst]], %[[i3]][] : memref 17 | // CHECK-NEXT: } 18 | // CHECK-NEXT: %[[i5:.+]] = affine.load %[[i3]][] : memref 19 | // CHECK-NEXT: %[[i6:.+]] = arith.addf %[[i5]], %[[cst]] : f32 20 | // CHECK-NEXT: affine.store %[[i6]], %[[arg0]][symbol(%[[i4]])] : memref 21 | // CHECK-NEXT: return 22 | // CHECK-NEXT: } 23 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/ext.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | int c2i(char x) { 4 | return x; 5 | } 6 | 7 | unsigned int c2ui(char x) { 8 | return x; 9 | } 10 | 11 | int uc2i(unsigned char x) { 12 | return x; 13 | } 14 | 15 | unsigned int uc2ui(unsigned char x) { 16 | return x; 17 | } 18 | 19 | // CHECK: func @c2i(%arg0: i8) -> i32 20 | // CHECK-NEXT: %0 = arith.extsi %arg0 : i8 to i32 21 | // CHECK-NEXT: return %0 : i32 22 | // CHECK-NEXT: } 23 | // CHECK: func @c2ui(%arg0: i8) -> i32 24 | // CHECK-NEXT: %0 = arith.extsi %arg0 : i8 to i32 25 | // CHECK-NEXT: return %0 : i32 26 | // CHECK-NEXT: } 27 | // CHECK: func @uc2i(%arg0: i8) -> i32 28 | // CHECK-NEXT: %0 = arith.extui %arg0 : i8 to i32 29 | // CHECK-NEXT: return %0 : i32 30 | // CHECK-NEXT: } 31 | // CHECK: func @uc2ui(%arg0: i8) -> i32 32 | // CHECK-NEXT: %0 = arith.extui %arg0 : i8 to i32 33 | // CHECK-NEXT: return %0 : i32 34 | // CHECK-NEXT: } 35 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/float_real_to_complex.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --struct-abi=0 --function='*' -S | FileCheck %s --check-prefix=STRUCT 2 | // COM: we dont support this yet: cgeist %s --function='*' -S | FileCheck %s 3 | 4 | __complex__ float complextest() 5 | { 6 | __complex__ float z=8.0; 7 | return z; 8 | 9 | } 10 | 11 | // STRUCT-LABEL: func.func @complextest() -> !llvm.struct<(f32, f32)> attributes {llvm.linkage = #llvm.linkage} { 12 | // STRUCT: %[[VAL_0:.*]] = arith.constant 0.000000e+00 : f32 13 | // STRUCT: %[[VAL_1:.*]] = arith.constant 8.000000e+00 : f32 14 | // STRUCT: %[[VAL_2:.*]] = llvm.mlir.undef : !llvm.struct<(f32, f32)> 15 | // STRUCT: %[[VAL_3:.*]] = llvm.insertvalue %[[VAL_1]], %[[VAL_2]][0] : !llvm.struct<(f32, f32)> 16 | // STRUCT: %[[VAL_4:.*]] = llvm.insertvalue %[[VAL_0]], %[[VAL_3]][1] : !llvm.struct<(f32, f32)> 17 | // STRUCT: return %[[VAL_4]] : !llvm.struct<(f32, f32)> -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/freecst.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s %stdinclude --function=* -S | FileCheck %s 2 | 3 | #include 4 | struct band { 5 | int dimX; 6 | }; 7 | struct dimensions { 8 | struct band LL; 9 | }; 10 | void writeNStage2DDWT(struct dimensions* bandDims) 11 | { 12 | free(bandDims); 13 | } 14 | 15 | // CHECK: func @writeNStage2DDWT(%[[arg0:.+]]: memref)>>) 16 | // CHECK-NEXT: memref.dealloc %[[arg0]] : memref)>> 17 | // CHECK-NEXT: return 18 | // CHECK-NEXT: } 19 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/fw.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s %stdinclude -S | FileCheck %s 2 | // RUN: cgeist %s %stdinclude -S -memref-fullrank | FileCheck %s --check-prefix=FULLRANK 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | /* Include polybench common header. */ 10 | #include 11 | 12 | # define N 2800 13 | 14 | /* Array initialization. */ 15 | void init_array (int path[N]); 16 | 17 | int main() 18 | { 19 | /* Retrieve problem size. */ 20 | 21 | /* Variable declaration/allocation. */ 22 | //POLYBENCH_1D_ARRAY_DECL(path, int, N, n); 23 | int (*path)[N]; 24 | //int path[POLYBENCH_C99_SELECT(N,n) + POLYBENCH_PADDING_FACTOR]; 25 | path = (int(*)[N])polybench_alloc_data (N, sizeof(int)) ; 26 | 27 | /* Initialize array(s). */ 28 | init_array (*path); 29 | 30 | 31 | return 0; 32 | } 33 | 34 | // CHECK: func @main() -> i32 35 | // CHECK-NEXT: %[[c0_i32:.+]] = arith.constant 0 : i32 36 | // CHECK-NEXT: %[[V0:.+]] = memref.alloc() : memref<2800xi32> 37 | // CHECK-NEXT: %[[V1:.+]] = memref.cast %[[V0]] : memref<2800xi32> to memref 38 | // CHECK-NEXT: call @init_array(%[[V1]]) : (memref) -> () 39 | // CHECK-NEXT: return %[[c0_i32]] : i32 40 | // CHECK-NEXT: } 41 | 42 | // FULLRANK: %[[MEM:.*]] = memref.alloc() : memref<2800xi32> 43 | // FULLRANK: call @init_array(%[[MEM]]) : (memref<2800xi32>) -> () 44 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/fwfree.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s %stdinclude -S | FileCheck %s 2 | // RUN: cgeist %s %stdinclude -S -memref-fullrank | FileCheck %s --check-prefix=FULLRANK 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | /* Include polybench common header. */ 10 | #include 11 | 12 | # define N 2800 13 | 14 | /* Array initialization. */ 15 | void init_array (int path[N]); 16 | 17 | int main() 18 | { 19 | /* Retrieve problem size. */ 20 | 21 | /* Variable declaration/allocation. */ 22 | //POLYBENCH_1D_ARRAY_DECL(path, int, N, n); 23 | int (*path)[N]; 24 | //int path[POLYBENCH_C99_SELECT(N,n) + POLYBENCH_PADDING_FACTOR]; 25 | path = (int(*)[N])polybench_alloc_data (N, sizeof(int)) ; 26 | 27 | /* Initialize array(s). */ 28 | init_array (*path); 29 | 30 | POLYBENCH_FREE_ARRAY(path); 31 | return 0; 32 | } 33 | 34 | // CHECK: func @main() -> i32 35 | // CHECK-NEXT: %[[c0_i32:.+]] = arith.constant 0 : i32 36 | // CHECK-NEXT: %[[V0:.+]] = memref.alloc() : memref<2800xi32> 37 | // CHECK-NEXT: %[[V1:.+]] = memref.cast %[[V0]] : memref<2800xi32> to memref 38 | // CHECK-NEXT: call @init_array(%[[V1]]) : (memref) -> () 39 | // CHECK-NEXT: memref.dealloc %[[V0]] : memref<2800xi32> 40 | // CHECK-NEXT: return %[[c0_i32]] : i32 41 | // CHECK-NEXT: } 42 | 43 | // FULLRANK: %[[MEM:.*]] = memref.alloc() : memref<2800xi32> 44 | // FULLRANK: call @init_array(%[[MEM]]) : (memref<2800xi32>) -> () 45 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/gcd.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=gcd -S | FileCheck %s 2 | 3 | int gcd(int m, int n) { 4 | while (n > 0) { 5 | int r = m % n; 6 | m = n; 7 | n = r; 8 | } 9 | return m; 10 | } 11 | 12 | // CHECK: func @gcd(%[[arg0:.+]]: i32, %[[arg1:.+]]: i32) -> i32 13 | // CHECK-NEXT: %[[c0_i32:.+]] = arith.constant 0 : i32 14 | // CHECK-NEXT: %[[V0:.+]]:2 = scf.while (%[[arg2:.+]] = %[[arg1]], %[[arg3:.+]] = %[[arg0]]) : (i32, i32) -> (i32, i32) { 15 | // CHECK-NEXT: %[[V1:.+]] = arith.cmpi sgt, %[[arg2]], %[[c0_i32]] : i32 16 | // CHECK-NEXT: scf.condition(%[[V1]]) %[[arg3]], %[[arg2]] : i32, i32 17 | // CHECK-NEXT: } do { 18 | // CHECK-NEXT: ^bb0(%[[arg2:.+]]: i32, %[[arg3:.+]]: i32): 19 | // CHECK-NEXT: %[[V1:.+]] = arith.remsi %[[arg2]], %[[arg3]] : i32 20 | // CHECK-NEXT: scf.yield %[[V1]], %[[arg3]] : i32, i32 21 | // CHECK-NEXT: } 22 | // CHECK-NEXT: return %[[V0]]#0 : i32 23 | // CHECK-NEXT: } 24 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/global.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s %stdinclude -S | FileCheck %s 2 | 3 | float A[64][32]; 4 | 5 | int main() { 6 | #pragma scop 7 | for (int i = 0; i < 64; i++) 8 | for (int j = 0; j < 32; j++) 9 | A[i][j] = 3.0; 10 | #pragma endscop 11 | return 0; 12 | } 13 | 14 | // CHECK: memref.global @A : memref<64x32xf32> 15 | // CHECK: func @main() -> i32 16 | // CHECK-DAG: %[[cst:.+]] = arith.constant 3.000000e+00 : f32 17 | // CHECK-DAG: %[[c0_i32:.+]] = arith.constant 0 : i32 18 | // CHECK-DAG: %[[V0:.+]] = memref.get_global @A : memref<64x32xf32> 19 | // CHECK-NEXT: affine.for %[[arg0:.+]] = 0 to 64 { 20 | // CHECK-NEXT: affine.for %[[arg1:.+]] = 0 to 32 { 21 | // CHECK-NEXT: affine.store %[[cst]], %[[V0]][%[[arg0]], %[[arg1]]] : memref<64x32xf32> 22 | // CHECK-NEXT: } 23 | // CHECK-NEXT: } 24 | // CHECK-NEXT: return %[[c0_i32]] : i32 25 | // CHECK-NEXT: } 26 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/hist.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | void histo_kernel(int i); 4 | 5 | int runHisto(int totalNum, int partialNum) { 6 | for(int i = 0; i < totalNum; i+=partialNum*2) 7 | { 8 | histo_kernel(i); 9 | } 10 | return 0; 11 | } 12 | 13 | // CHECK: func @runHisto(%[[arg0:.+]]: i32, %[[arg1:.+]]: i32) -> i32 14 | // CHECK-DAG: %[[c2_i32:.+]] = arith.constant 2 : i32 15 | // CHECK-DAG: %[[c0_i32:.+]] = arith.constant 0 : i32 16 | // CHECK-DAG: %[[c0:.+]] = arith.constant 0 : index 17 | // CHECK-NEXT: %[[V0:.+]] = arith.muli %[[arg1]], %[[c2_i32]] : i32 18 | // CHECK-NEXT: %[[V1:.+]] = arith.index_cast %[[arg0]] : i32 to index 19 | // CHECK-NEXT: %[[V2:.+]] = arith.index_cast %[[V0]] : i32 to index 20 | // CHECK-NEXT: scf.for %[[arg2:.+]] = %[[c0]] to %[[V1]] step %[[V2]] { 21 | // CHECK-NEXT: %[[V3:.+]] = arith.divui %[[arg2]], %[[V2]] : index 22 | // CHECK-NEXT: %[[V4:.+]] = arith.muli %[[V3]], %[[V2]] : index 23 | // CHECK-NEXT: %[[V5:.+]] = arith.index_cast %[[V4]] : index to i32 24 | // CHECK-NEXT: call @histo_kernel(%[[V5]]) : (i32) -> () 25 | // CHECK-NEXT: } 26 | // CHECK-NEXT: return %[[c0_i32]] : i32 27 | // CHECK-NEXT: } 28 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/ident2.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | struct MOperandInfo { 4 | char device; 5 | char dtype; 6 | }; 7 | 8 | struct MOperandInfo* begin(); 9 | 10 | struct MOperandInfo& inner() { 11 | return begin()[0]; 12 | } 13 | 14 | // CHECK: func @_Z5innerv() -> memref 15 | // CHECK-NEXT: %[[V0:.+]] = call @_Z5beginv() : () -> memref 16 | // CHECK-NEXT: return %[[V0]] : memref 17 | // CHECK-NEXT: } 18 | // CHECK-NEXT: func private @_Z5beginv() -> memref 19 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/if_decl.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | struct A { 4 | int value; 5 | 6 | int* getPointer() { 7 | if (int* tmp = &this->value) { 8 | return tmp; 9 | } 10 | return nullptr; 11 | } 12 | }; 13 | 14 | int main() { 15 | return *A().getPointer(); 16 | } 17 | 18 | // CHECK: func.func @_ZN1A10getPointerEv( 19 | // CHECK: "polygeist.memref2pointer" 20 | // CHECK: llvm.mlir.zero 21 | // CHECK: llvm.icmp "ne" 22 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/invalid/basic.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S 2 | // XFAIL: * 3 | 4 | int main() { 5 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/invalid/invalid_include.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S 2 | // XFAIL: * 3 | 4 | #include "non-existing-header.h" 5 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/ker.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=kernel_deriche -S | FileCheck %s 2 | // RUN: cgeist %s --function=kernel_deriche -S -memref-fullrank | FileCheck %s --check-prefix=FULLRANK 3 | 4 | int kernel_deriche(int a[30][40]) { 5 | a[3][5]++; 6 | return a[1][2]; 7 | } 8 | 9 | // CHECK: func @kernel_deriche(%[[arg0:.+]]: memref) -> i32 10 | // CHECK-NEXT: %[[c1_i32:.+]] = arith.constant 1 : i32 11 | // CHECK-NEXT: %[[V0:.+]] = affine.load %[[arg0]][3, 5] : memref 12 | // CHECK-NEXT: %[[V1:.+]] = arith.addi %[[V0]], %[[c1_i32]] : i32 13 | // CHECK-NEXT: affine.store %[[V1]], %[[arg0]][3, 5] : memref 14 | // CHECK-NEXT: %[[V2:.+]] = affine.load %[[arg0]][1, 2] : memref 15 | // CHECK-NEXT: return %[[V2]] : i32 16 | // CHECK-NEXT: } 17 | 18 | // FULLRANK: func @kernel_deriche(%[[arg0:.+]]: memref<30x40xi32>) -> i32 19 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/label.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | int fir (int d_i[1000], int idx[1000] ) { 4 | int i; 5 | int tmp=0; 6 | 7 | for_loop: 8 | for (i=0;i<1000;i++) { 9 | tmp += idx [i] * d_i[999-i]; 10 | 11 | } 12 | return tmp; 13 | } 14 | 15 | // CHECK: func @fir(%[[arg0:.+]]: memref, %[[arg1:.+]]: memref) -> i32 16 | // CHECK-DAG: %[[c1:.+]] = arith.constant 1 : index 17 | // CHECK-DAG: %[[c0:.+]] = arith.constant 0 : index 18 | // CHECK-DAG: %[[c1000:.+]] = arith.constant 1000 : index 19 | // CHECK-DAG: %[[c999_i32:.+]] = arith.constant 999 : i32 20 | // CHECK-DAG: %[[c0_i32:.+]] = arith.constant 0 : i32 21 | // CHECK-NEXT: %[[V0:.+]] = scf.for %[[arg2:.+]] = %[[c0]] to %[[c1000]] step %[[c1:.+]] iter_args(%[[arg3:.+]] = %[[c0_i32]]) -> (i32) { 22 | // CHECK-NEXT: %[[V1:.+]] = arith.index_cast %[[arg2]] : index to i32 23 | // CHECK-NEXT: %[[V2:.+]] = memref.load %[[arg1]][%[[arg2]]] : memref 24 | // CHECK-NEXT: %[[V3:.+]] = arith.subi %[[c999_i32]], %[[V1]] : i32 25 | // CHECK-NEXT: %[[V4:.+]] = arith.index_cast %[[V3]] : i32 to index 26 | // CHECK-NEXT: %[[V5:.+]] = memref.load %[[arg0]][%[[V4]]] : memref 27 | // CHECK-NEXT: %[[V6:.+]] = arith.muli %[[V2]], %[[V5]] : i32 28 | // CHECK-NEXT: %[[V7:.+]] = arith.addi %[[arg3]], %[[V6]] : i32 29 | // CHECK-NEXT: scf.yield %[[V7]] : i32 30 | // CHECK-NEXT: } 31 | // CHECK-NEXT: return %[[V0]] : i32 32 | // CHECK-NEXT: } 33 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/ler.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=kernel_deriche -S | FileCheck %s 2 | 3 | int kernel_deriche(int *a) { 4 | a[3]++; 5 | return a[1]; 6 | } 7 | 8 | // CHECK: func @kernel_deriche(%[[arg0:.+]]: memref) -> i32 9 | // CHECK-NEXT: %[[c1_i32:.+]] = arith.constant 1 : i32 10 | // CHECK-NEXT: %[[V0:.+]] = affine.load %[[arg0]][3] : memref 11 | // CHECK-NEXT: %[[V1:.+]] = arith.addi %[[V0]], %[[c1_i32]] : i32 12 | // CHECK-NEXT: affine.store %[[V1]], %[[arg0]][3] : memref 13 | // CHECK-NEXT: %[[V2:.+]] = affine.load %[[arg0]][1] : memref 14 | // CHECK-NEXT: return %[[V2]] : i32 15 | // CHECK-NEXT: } 16 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/loopinc.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=test -S | FileCheck %s 2 | 3 | // TODO 4 | // XFAIL: * 5 | 6 | unsigned int test() { 7 | int divisor = 1; 8 | unsigned int shift; // Shift amounts. 9 | 10 | for (shift = 0; 1; shift++) if ((1U << shift) >= divisor) break; 11 | 12 | // should always return 0 13 | return shift; 14 | } 15 | 16 | // CHECK: func @test() -> i32 17 | // CHECK-DAG: %[[c0_i32:.+]] = arith.constant 0 : i32 18 | // CHECK-DAG: %[[c1_i32:.+]] = arith.constant 1 : i32 19 | // CHECK-NEXT: %[[V0:.+]] = scf.while (%[[arg0:.+]] = %[[c0_i32]]) : (i32) -> i32 { 20 | // CHECK-NEXT: %[[V1:.+]] = arith.shli %[[c1_i32]], %[[arg0]] : i32 21 | // CHECK-NEXT: %[[V2:.+]] = arith.cmpi ult, %[[V1]], %[[c1_i32]] : i32 22 | // CHECK-NEXT: scf.condition(%[[V2]]) %[[arg0]] : i32 23 | // CHECK-NEXT: } do { 24 | // CHECK-NEXT: ^bb0(%[[arg0:.+]]: i32): 25 | // CHECK-NEXT: %[[V1:.+]] = arith.addi %[[arg0]], %[[c1_i32]] : i32 26 | // CHECK-NEXT: scf.yield %[[V1]] : i32 27 | // CHECK-NEXT: } 28 | // CHECK-NEXT: return %[[V0]] : i32 29 | // CHECK-NEXT: } 30 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/lower-to-linalg-op.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s -S | FileCheck %s 2 | 3 | #pragma lower_to(copy_op, "memref.copy") "input"(a), "output"(b) 4 | void copy_op(int b[3][3], int a[3][3]) { 5 | for (int i = 0; i < 3; i++) 6 | for (int j = 0; j < 3; j++) 7 | b[i][j] = a[i][j]; 8 | } 9 | 10 | int main() { 11 | int a[3][3]; 12 | int b[3][3]; 13 | // CHECK: memref.copy {{.*}}, {{.*}} : memref<3x3xi32> to memref<3x3xi32> 14 | copy_op(a, b); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/lower_to.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=foo -S | FileCheck %s 2 | 3 | #pragma lower_to(bar, "arith.addf") 4 | extern float bar(float a, float b); 5 | float foo(float a, float b) { return bar(a, b); } 6 | 7 | // CHECK: func @foo(%[[ARG0:.*]]: f32, %[[ARG1:.*]]: f32) 8 | // CHECK-NEXT: %[[VAL0:.*]] = arith.addf %[[ARG0]], %[[ARG1]] 9 | // CHECK-NEXT: return %[[VAL0]] 10 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/lowerrecur.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -emit-llvm -S | FileCheck %s 2 | 3 | struct X{ 4 | double* a; 5 | double* b; 6 | int c; 7 | }; 8 | 9 | void perm(struct X* v) { 10 | v->a = v->b; 11 | } 12 | 13 | // CHECK: define void @perm 14 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/lum.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=test -S | FileCheck %s 2 | 3 | int test() { 4 | return -3; 5 | } 6 | 7 | // CHECK: func @test() -> i32 8 | // CHECK-NEXT: %c-3_i32 = arith.constant -3 : i32 9 | // CHECK-NEXT: return %c-3_i32 : i32 10 | // CHECK-NEXT: } 11 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/malloc.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=caller %stdinclude -S | FileCheck %s 2 | 3 | #include 4 | 5 | void sum(double *result); 6 | 7 | void caller(int size) { 8 | double* array = (double*)malloc(sizeof(double) * size); 9 | sum(array); 10 | free(array); 11 | } 12 | 13 | // CHECK: func @caller(%[[arg0:.+]]: i32) 14 | // CHECK-DAG: %[[c8_i64:.+]] = arith.constant 8 : i64 15 | // CHECK-DAG: %[[c8:.+]] = arith.constant 8 : index 16 | // CHECK-NEXT: %[[V0:.+]] = arith.extsi %[[arg0]] : i32 to i64 17 | // CHECK-NEXT: %[[V1:.+]] = arith.muli %[[V0]], %[[c8_i64]] : i64 18 | // CHECK-NEXT: %[[V2:.+]] = arith.index_cast %[[V1]] : i64 to index 19 | // CHECK-NEXT: %[[V3:.+]] = arith.divui %[[V2]], %[[c8]] : index 20 | // CHECK-NEXT: %[[a:.+]] = memref.alloc(%[[V3]]) : memref 21 | // CHECK-NEXT: call @sum(%[[a]]) : (memref) -> () 22 | // CHECK-NEXT: memref.dealloc %[[a]] : memref 23 | // CHECK-NEXT: return 24 | // CHECK-NEXT: } 25 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/memcpystruct.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | struct N { 4 | int a; 5 | int b; 6 | }; 7 | 8 | void copy(struct N* dst, void* src) { 9 | __builtin_memcpy(dst, src, sizeof(struct N)); 10 | } 11 | 12 | // CHECK-LABEL: func.func @copy( 13 | // CHECK-SAME: %[[VAL_0:[A-Za-z0-9_]*]]: memref, 14 | // CHECK-SAME: %[[VAL_1:[A-Za-z0-9_]*]]: memref) 15 | // CHECK: %[[VAL_2:[A-Za-z0-9_]*]] = arith.constant 8 : index 16 | // CHECK: %[[VAL_3:[A-Za-z0-9_]*]] = arith.constant 1 : index 17 | // CHECK: %[[VAL_4:[A-Za-z0-9_]*]] = arith.constant 0 : index 18 | // CHECK: %[[VAL_5:[A-Za-z0-9_]*]] = "polygeist.memref2pointer"(%[[VAL_0]]) : (memref) -> !llvm.ptr 19 | // CHECK: scf.for %[[VAL_6:[A-Za-z0-9_]*]] = %[[VAL_4]] to %[[VAL_2]] step %[[VAL_3]] { 20 | // CHECK: %[[VAL_7:[A-Za-z0-9_]*]] = memref.load %[[VAL_1]]{{\[}}%[[VAL_6]]] : memref 21 | // CHECK: %[[VAL_8:[A-Za-z0-9_]*]] = arith.index_cast %[[VAL_6]] : index to i32 22 | // CHECK: %[[VAL_9:[A-Za-z0-9_]*]] = llvm.getelementptr %[[VAL_5]]{{\[}}%[[VAL_8]]] : (!llvm.ptr, i32) -> !llvm.ptr, i8 23 | // CHECK: llvm.store %[[VAL_7]], %[[VAL_9]] : i8, !llvm.ptr 24 | // CHECK: } 25 | // CHECK: return 26 | // CHECK: } 27 | 28 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/memref-fullrank.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s -S %stdinclude --function=main -memref-fullrank -O0 | FileCheck %s 2 | 3 | #include 4 | 5 | int f(int A[10][20]) { 6 | int i, j, sum = 0; 7 | #pragma scop 8 | for (i = 0; i < 10; i++) 9 | for (j = 0; j < 20; j++) 10 | sum += A[i][j]; 11 | #pragma endscop 12 | return sum; 13 | } 14 | 15 | int g(int A[10][20]) { 16 | int c = f(A); 17 | printf("%d\n", c); 18 | 19 | return 0; 20 | } 21 | 22 | int main() { 23 | int A[10][20]; 24 | return g(A); 25 | } 26 | 27 | // CHECK: func @main() 28 | // CHECK: %[[VAL0:.*]] = memref.alloca() : memref<10x20xi32> 29 | // CHECK: %{{.*}} = call @g(%[[VAL0]]) : (memref<10x20xi32>) -> i32 30 | 31 | // CHECK: func @g(%[[arg0:.+]]: memref<10x20xi32>) -> i32 32 | 33 | // CHECK: func @f(%[[arg0:.+]]: memref<10x20xi32>) -> i32 34 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/memrefaddassign.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -c -S | FileCheck %s 2 | 3 | float *foo(float *a) { 4 | a += 32; 5 | return a; 6 | } 7 | float *foo1(float *a) { 8 | return a + 32; 9 | } 10 | float *foo2(float *a) { 11 | return 32 + a; 12 | } 13 | // CHECK: func @_Z3fooPf(%[[arg0:.+]]: memref) 14 | // CHECK-NEXT %[[c32:.+]] = arith.constant 32 : index 15 | // CHECK-NEXT %[[V0:.+]] = "polygeist.subindex"(%[[arg0]], %[[c32]]) : (memref, index) -> memref 16 | // CHECK-NEXT return %[[V0]] : memref 17 | // CHECK-NEXT } 18 | 19 | // CHECK: func @_Z4foo1Pf(%[[arg0:.+]]: memref) 20 | // CHECK-NEXT %[[c32:.+]] = arith.constant 32 : index 21 | // CHECK-NEXT %[[V0:.+]] = "polygeist.subindex"(%[[arg0]], %[[c32]]) : (memref, index) -> memref 22 | // CHECK-NEXT return %[[V0]] : memref 23 | // CHECK-NEXT } 24 | 25 | // CHECK: func @_Z4foo2Pf(%[[arg0:.+]]: memref) 26 | // CHECK-NEXT %[[c32:.+]] = arith.constant 32 : index 27 | // CHECK-NEXT %[[V0:.+]] = "polygeist.subindex"(%[[arg0]], %[[c32]]) : (memref, index) -> memref 28 | // CHECK-NEXT return %[[V0]] : memref 29 | // CHECK-NEXT } 30 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/memrefcast.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=foo -S | FileCheck %s 2 | 3 | char* foo(float *dvalue) { 4 | return (char *)(dvalue); 5 | } 6 | 7 | // CHECK-LABEL: func.func @foo( 8 | // CHECK-SAME: %[[VAL_0:[A-Za-z0-9_]*]]: memref) -> memref 9 | // CHECK: %[[VAL_1:[A-Za-z0-9_]*]] = "polygeist.memref2pointer"(%[[VAL_0]]) : (memref) -> !llvm.ptr 10 | // CHECK: %[[VAL_2:[A-Za-z0-9_]*]] = "polygeist.pointer2memref"(%[[VAL_1]]) : (!llvm.ptr) -> memref 11 | // CHECK: return %[[VAL_2]] : memref 12 | // CHECK: } 13 | 14 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/mer.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=kernel_deriche -S | FileCheck %s 2 | // RUN: cgeist %s --function=kernel_deriche -S -memref-fullrank | FileCheck %s --check-prefix=FULLRANK 3 | 4 | int kernel_deriche(int a[30]) { 5 | a[0]++; 6 | return a[1]; 7 | } 8 | 9 | // CHECK: func @kernel_deriche(%[[arg0:.+]]: memref) -> i32 10 | // CHECK-NEXT: %[[c1_i32:.+]] = arith.constant 1 : i32 11 | // CHECK-NEXT: %[[V0:.+]] = affine.load %[[arg0]][0] : memref 12 | // CHECK-NEXT: %[[V1:.+]] = arith.addi %[[V0]], %[[c1_i32]] : i32 13 | // CHECK-NEXT: affine.store %[[V1]], %[[arg0]][0] : memref 14 | // CHECK-NEXT: %[[V2:.+]] = affine.load %[[arg0]][1] : memref 15 | // CHECK-NEXT: return %[[V2]] : i32 16 | // CHECK-NEXT: } 17 | 18 | // FULLRANK: func @kernel_deriche(%[[arg0:.+]]: memref<30xi32>) -> i32 19 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/min.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=min -S | FileCheck %s 2 | 3 | // TODO combine selects 4 | 5 | int min(int a, int b) { 6 | if (a < b) return a; 7 | return b; 8 | } 9 | 10 | // CHECK: func @min(%[[arg0:.+]]: i32, %[[arg1:.+]]: i32) -> i32 11 | // CHECK-NEXT: %[[V0:.+]] = llvm.mlir.undef : i32 12 | // CHECK-NEXT: %[[V1:.+]] = arith.cmpi slt, %[[arg0]], %[[arg1]] : i32 13 | // CHECK-NEXT: %[[V2:.+]] = arith.cmpi sge, %[[arg0]], %[[arg1]] : i32 14 | // CHECK-NEXT: %[[V3:.+]] = arith.select %[[V1]], %[[arg0]], %[[V0]] : i32 15 | // CHECK-NEXT: %[[V4:.+]] = arith.select %[[V2]], %[[arg1]], %[[V3]] : i32 16 | // CHECK-NEXT: return %[[V4]] : i32 17 | // CHECK-NEXT: } 18 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/no_inline.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist -S -O0 %s | FileCheck %s 2 | // RUN: cgeist -S -O1 %s | FileCheck %s --check-prefix=OPT1 3 | 4 | void foo(int A[10]) { 5 | #pragma scop 6 | for (int i = 0; i < 10; ++i) 7 | A[i] = A[i] * 2; 8 | #pragma endscop 9 | } 10 | 11 | // CHECK-LABEL: func @main() 12 | // CHECK: call @foo 13 | // OPT1-LABEL: func @main() 14 | // OPT1-NOT: call @foo 15 | int main() { 16 | int A[10]; 17 | foo(A); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/nocond.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | int run(); 4 | 5 | void what() { 6 | for (;;) { 7 | if (run()) break; 8 | } 9 | } 10 | 11 | // CHECK: func.func @what() 12 | // CHECK-DAG: %[[true:.+]] = arith.constant true 13 | // CHECK-DAG: %[[c0_i32:.+]] = arith.constant 0 : i32 14 | // CHECK-NEXT: scf.while (%[[arg0:.+]] = %[[true]]) : (i1) -> () { 15 | // CHECK-NEXT: scf.condition(%[[arg0]]) 16 | // CHECK-NEXT: } do { 17 | // CHECK-NEXT: %[[V0:.+]] = func.call @run() : () -> i32 18 | // CHECK-NEXT: %[[V1:.+]] = arith.cmpi eq, %[[V0]], %[[c0_i32]] : i32 19 | // CHECK-NEXT: scf.yield %[[V1]] : i1 20 | // CHECK-NEXT: } 21 | // CHECK-NEXT: return 22 | // CHECK-NEXT: } 23 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/nulretstruct.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist -S --function=* %s | FileCheck %s 2 | 3 | struct C { 4 | int a; 5 | double* b; 6 | }; 7 | 8 | struct C* make() { 9 | return (struct C*)0; 10 | } 11 | 12 | float* makeF() { 13 | return (float*)0; 14 | } 15 | 16 | 17 | 18 | // CHECK-LABEL: func.func @make() -> memref)>> 19 | // CHECK: %[[VAL_0:[A-Za-z0-9_]*]] = llvm.mlir.zero : !llvm.ptr 20 | // CHECK: %[[VAL_1:[A-Za-z0-9_]*]] = "polygeist.pointer2memref"(%[[VAL_0]]) : (!llvm.ptr) -> memref)>> 21 | // CHECK: return %[[VAL_1]] : memref)>> 22 | // CHECK: } 23 | 24 | // CHECK-LABEL: func.func @makeF() -> memref 25 | // CHECK: %[[VAL_0:[A-Za-z0-9_]*]] = llvm.mlir.zero : !llvm.ptr 26 | // CHECK: %[[VAL_1:[A-Za-z0-9_]*]] = "polygeist.pointer2memref"(%[[VAL_0]]) : (!llvm.ptr) -> memref 27 | // CHECK: return %[[VAL_1]] : memref 28 | // CHECK: } 29 | 30 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/nus.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=kernel_nussinov -S | FileCheck %s 2 | // RUN: cgeist %s --function=kernel_nussinov -S --memref-fullrank | FileCheck %s --check-prefix=FULLRANK 3 | 4 | #define N 5500 5 | #define max_score(s1, s2) ((s1 >= s2) ? s1 : s2) 6 | 7 | // CHECK: @kernel_nussinov(%[[arg0:.+]]: i32, %[[arg1:.+]]: memref) 8 | // CHECK-NEXT: affine.for %[[arg2:.+]] = 1 to 5500 { 9 | // CHECK-NEXT: affine.if #set(%[[arg2]]) { 10 | // CHECK-NEXT: %[[V0:.+]] = affine.load %[[arg1]][%[[arg2]]] : memref 11 | // CHECK-NEXT: %[[V1:.+]] = affine.load %[[arg1]][%[[arg2]] - 1] : memref 12 | // CHECK-NEXT: %[[V2:.+]] = arith.cmpi sge, %[[V0]], %[[V1]] : i32 13 | // CHECK-NEXT: %[[V3:.+]] = arith.select %[[V2]], %[[V0]], %[[V1]] : i32 14 | // CHECK-NEXT: affine.store %[[V3]], %[[arg1]][%[[arg2]]] : memref 15 | // CHECK-NEXT: } 16 | // CHECK-NEXT: } 17 | // CHECK-NEXT: return 18 | // CHECK-NEXT: } 19 | 20 | // FULLRANK: @kernel_nussinov(%{{.*}}: i32, %{{.*}}: memref<5500xi32>) 21 | 22 | void kernel_nussinov(int n, int table[N]) 23 | { 24 | int j; 25 | 26 | #pragma scop 27 | for (j=1; j=0) 30 | table[j] = max_score(table[j], table[j-1]); 31 | 32 | } 33 | #pragma endscop 34 | 35 | } 36 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/omp.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -fopenmp -S | FileCheck %s 2 | 3 | void square(double* x, int sstart, int send, int sinc) { 4 | #pragma omp parallel for 5 | for(int i=sstart; i < send; i+= sinc) { 6 | x[i] = i; 7 | } 8 | } 9 | 10 | // CHECK: func @square(%[[arg0:.+]]: memref, %[[arg1:.+]]: i32, %[[arg2:.+]]: i32, %[[arg3:.+]]: i32) 11 | // CHECK-NEXT: %c-1_i32 = arith.constant -1 : i32 12 | // CHECK-NEXT: %[[V0:.+]] = arith.index_cast %[[arg1]] : i32 to index 13 | // CHECK-NEXT: %[[V1:.+]] = arith.subi %[[arg2]], %[[arg1]] : i32 14 | // CHECK-NEXT: %[[V2:.+]] = arith.addi %[[V1]], %c-1_i32 : i32 15 | // CHECK-NEXT: %[[V3:.+]] = arith.addi %[[V2]], %[[arg3]] : i32 16 | // CHECK-NEXT: %[[V4:.+]] = arith.divui %[[V3]], %[[arg3]] : i32 17 | // CHECK-NEXT: %[[V5:.+]] = arith.muli %[[V4]], %[[arg3]] : i32 18 | // CHECK-NEXT: %[[V6:.+]] = arith.addi %[[arg1]], %[[V5]] : i32 19 | // CHECK-NEXT: %[[V7:.+]] = arith.index_cast %[[V6]] : i32 to index 20 | // CHECK-NEXT: %[[V8:.+]] = arith.index_cast %[[arg3]] : i32 to index 21 | // CHECK-NEXT: scf.parallel (%[[arg4:.+]]) = (%[[V0]]) to (%[[V7]]) step (%[[V8]]) { 22 | // CHECK-NEXT: %[[V9:.+]] = arith.index_cast %[[arg4]] : index to i32 23 | // CHECK-NEXT: %[[V10:.+]] = arith.sitofp %[[V9]] : i32 to f64 24 | // CHECK-NEXT: memref.store %[[V10]], %[[arg0]][%[[arg4]]] : memref 25 | // CHECK-NEXT: scf.yield 26 | // CHECK-NEXT: } 27 | // CHECK-NEXT: return 28 | // CHECK-NEXT: } 29 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/omp3.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -fopenmp -S | FileCheck %s 2 | 3 | void square(double* x) { 4 | int i; 5 | #pragma omp parallel for private(i) 6 | for(i=3; i < 10; i+= 2) { 7 | x[i] = i; 8 | i++; 9 | x[i] = i; 10 | } 11 | } 12 | 13 | // CHECK: func @square(%[[arg0:.+]]: memref) 14 | // CHECK-DAG: %[[c2:.+]] = arith.constant 2 : index 15 | // CHECK-DAG: %[[c11:.+]] = arith.constant 11 : index 16 | // CHECK-DAG: %[[c1_i32:.+]] = arith.constant 1 : i32 17 | // CHECK-DAG: %[[c3:.+]] = arith.constant 3 : index 18 | // CHECK-NEXT: scf.parallel (%[[arg1:.+]]) = (%[[c3]]) to (%[[c11]]) step (%[[c2]]) { 19 | // CHECK-NEXT: %[[V0:.+]] = arith.index_cast %[[arg1]] : index to i32 20 | // CHECK-NEXT: %[[V1:.+]] = arith.sitofp %[[V0]] : i32 to f64 21 | // CHECK-NEXT: memref.store %[[V1]], %[[arg0]][%[[arg1]]] : memref 22 | // CHECK-NEXT: %[[V2:.+]] = arith.addi %[[V0]], %[[c1_i32]] : i32 23 | // CHECK-NEXT: %[[V3:.+]] = arith.index_cast %[[V2]] : i32 to index 24 | // CHECK-NEXT: %[[V4:.+]] = arith.sitofp %[[V2]] : i32 to f64 25 | // CHECK-NEXT: memref.store %[[V4]], %[[arg0]][%[[V3]]] : memref 26 | // CHECK-NEXT: scf.yield 27 | // CHECK-NEXT: } 28 | // CHECK-NEXT: return 29 | // CHECK-NEXT: } 30 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/omp5.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -fopenmp -S | FileCheck %s 2 | 3 | void square(double* x, int sstart, int send, int sinc) { 4 | #pragma omp parallel for 5 | for(int i=sstart; i < send; i++) { 6 | x[i] = i; 7 | } 8 | } 9 | 10 | // CHECK: func @square(%[[arg0:.+]]: memref, %[[arg1:.+]]: i32, %[[arg2:.+]]: i32, %[[arg3:.+]]: i32) 11 | // CHECK-NEXT: %[[c1:.+]] = arith.constant 1 : index 12 | // CHECK-DAG: %[[i0:.+]] = arith.index_cast %[[arg1]] : i32 to index 13 | // CHECK-DAG: %[[i1:.+]] = arith.index_cast %[[arg2]] : i32 to index 14 | // CHECK-NEXT: scf.parallel (%[[arg4:.+]]) = (%[[i0]]) to (%[[i1]]) step (%[[c1]]) { 15 | // CHECK-NEXT: %[[V2:.+]] = arith.index_cast %[[arg4]] : index to i32 16 | // CHECK-NEXT: %[[V3:.+]] = arith.sitofp %[[V2]] : i32 to f64 17 | // CHECK-NEXT: memref.store %[[V3]], %[[arg0]][%[[arg4]]] : memref 18 | // CHECK-NEXT: scf.yield 19 | // CHECK-NEXT: } 20 | // CHECK-NEXT: return 21 | // CHECK-NEXT: } 22 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/ompParallelNumThreads.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -fopenmp -S | FileCheck %s 2 | 3 | int omp_get_thread_num(); 4 | 5 | void test_parallel_num_threads(double* x, int sinc) { 6 | // CHECK: %[[c32:.+]] = arith.constant 32 : i32 7 | // CHECK: omp.parallel num_threads(%[[c32]] : i32) { 8 | #pragma omp parallel num_threads(32) 9 | { 10 | int tid = omp_get_thread_num(); 11 | x[tid] = 1; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/opaquestr.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s %stdinclude -S | FileCheck %s 2 | 3 | struct Str { 4 | int a; 5 | float b; 6 | }; 7 | 8 | struct OperandInfo { 9 | OperandInfo *info; 10 | struct { 11 | int a; 12 | float b; 13 | } intfloat; 14 | Str a; 15 | Str *b; 16 | int c; 17 | }; 18 | 19 | void *foo(OperandInfo *info) { 20 | return info; 21 | } 22 | 23 | // CHECK: memref>, struct<(i32, f32)>, struct<(i32, f32)>, memref>, i32)>> 24 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/packedstruct.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | struct meta { 4 | long long a; 5 | char dtype; 6 | }; 7 | 8 | struct fin { 9 | struct meta f; 10 | char dtype; 11 | } __attribute__((packed)) ; 12 | 13 | long long run(struct meta m, char c); 14 | 15 | void compute(struct fin f) { 16 | run(f.f, f.dtype); 17 | } 18 | // CHECK-LABEL: func.func @compute( 19 | // CHECK-SAME: %[[VAL_0:[A-Za-z0-9_]*]]: !llvm.struct<(struct<(i64, i8)>, i8)>) 20 | // CHECK: %[[VAL_1:[A-Za-z0-9_]*]] = memref.alloca() : memref<1x!llvm.struct<(struct<(i64, i8)>, i8)>> 21 | // CHECK: affine.store %[[VAL_0]], %[[VAL_1]][0] : memref<1x!llvm.struct<(struct<(i64, i8)>, i8)>> 22 | // CHECK: %[[VAL_2:[A-Za-z0-9_]*]] = "polygeist.memref2pointer"(%[[VAL_1]]) : (memref<1x!llvm.struct<(struct<(i64, i8)>, i8)>>) -> !llvm.ptr 23 | // CHECK: %[[VAL_3:[A-Za-z0-9_]*]] = llvm.load %[[VAL_2]] : !llvm.ptr -> !llvm.struct<(i64, i8)> 24 | // CHECK: %[[VAL_4:[A-Za-z0-9_]*]] = llvm.getelementptr %[[VAL_2]][0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(struct<(i64, i8)>, i8)> 25 | // CHECK: %[[VAL_5:[A-Za-z0-9_]*]] = llvm.load %[[VAL_4]] : !llvm.ptr -> i8 26 | // CHECK: %[[VAL_6:[A-Za-z0-9_]*]] = call @run(%[[VAL_3]], %[[VAL_5]]) : (!llvm.struct<(i64, i8)>, i8) -> i64 27 | // CHECK: return 28 | // CHECK: } 29 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/pairinit.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=func -S | FileCheck %s 2 | 3 | struct pair { 4 | int x, y; 5 | }; 6 | 7 | struct pair func() { 8 | struct pair tmp = {2, 3}; 9 | return tmp; 10 | } 11 | 12 | // CHECK: func @func(%[[arg0:.+]]: memref) 13 | // CHECK-DAG: %[[c3_i32:.+]] = arith.constant 3 : i32 14 | // CHECK-DAG: %[[c2_i32:.+]] = arith.constant 2 : i32 15 | // CHECK-NEXT: affine.store %[[c2_i32]], %[[arg0]][0, 0] : memref 16 | // CHECK-NEXT: affine.store %[[c3_i32]], %[[arg0]][0, 1] : memref 17 | // CHECK-NEXT: return 18 | // CHECK-NEXT: } 19 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/palloc.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s %stdinclude --function=init_array -S | FileCheck %s 2 | // RUN: cgeist %s %stdinclude --function=init_array -S --memref-fullrank | FileCheck %s --check-prefix=FULLRANK 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /* Include polybench common header. */ 9 | #include 10 | 11 | void use(double A[20]); 12 | /* Array initialization. */ 13 | 14 | void init_array (int n) 15 | { 16 | double (*B)[20] = (double(*)[20])polybench_alloc_data (20, sizeof(double)) ; 17 | (*B)[2] = 3.0; 18 | use(*B); 19 | } 20 | 21 | 22 | // CHECK: func @init_array(%[[arg0:.+]]: i32) 23 | // CHECK-NEXT: %[[cst:.+]] = arith.constant 3.000000e+00 : f64 24 | // CHECK-NEXT: %[[V0:.+]] = memref.alloc() : memref<20xf64> 25 | // CHECK-NEXT: affine.store %[[cst]], %[[V0]][2] : memref<20xf64> 26 | // CHECK-NEXT: %[[V1:.+]] = memref.cast %[[V0]] : memref<20xf64> to memref 27 | // CHECK-NEXT: call @use(%[[V1]]) : (memref) -> () 28 | // CHECK-NEXT: return 29 | // CHECK-NEXT: } 30 | 31 | // FULLRANK: %[[VAL0:.*]] = memref.alloc() : memref<20xf64> 32 | // FULLRANK: call @use(%[[VAL0]]) : (memref<20xf64>) -> () 33 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/raiseToAffineUnsignedCmp.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s %stdinclude --function=matmul --raise-scf-to-affine -S | FileCheck %s 2 | 3 | void matmul(float A[100][200], float B[200][300], float C[100][300]) { 4 | int i, j, k; 5 | 6 | // CHECK: affine.for 7 | for (i = 0; i < 100; i++) { 8 | // CHECK: affine.for 9 | for (j = 0; j < 300; j++) { 10 | // CHECK: affine.store %{{.*}}, %{{.*}}[%{{.*}}, %{{.*}}] : memref 11 | C[i][j] = 0; 12 | // CHECK: affine.for 13 | for (k = 0; k < 200; k++) { 14 | // CHECK: {{.*}} = affine.load %{{.*}}[%{{.*}}, %{{.*}}] : memref 15 | // CHECK: {{.*}} = affine.load %{{.*}}[%{{.*}}, %{{.*}}] : memref 16 | // CHECK: {{.*}} = arith.mulf 17 | // CHECK: {{.*}} = affine.load %{{.*}}[%{{.*}}, %{{.*}}] : memref 18 | // CHECK: {{.*}} = arith.addf 19 | // CHECK: affine.store {{.*}}, %{{.*}}[%{{.*}}, %{{.*}}] : memref 20 | C[i][j] += A[i][k] * B[k][j]; 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/red.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt --detect-reduction %s | FileCheck %s 2 | // XFAIL: * 3 | 4 | module { 5 | func @reduce_with_iter_args(%arg0: memref) -> f32 { 6 | %c0 = constant 0 : index 7 | %0 = memref.dim %arg0, %c0 : memref 8 | %cst = constant 0.000000e+00 : f32 9 | %cst_0 = constant 1.000000e+00 : f32 10 | %1 = memref.alloca() : memref<1xf32> 11 | affine.store %cst, %1[0] : memref<1xf32> 12 | %2 = memref.alloca() : memref<1xf32> 13 | affine.store %cst_0, %2[0] : memref<1xf32> 14 | affine.for %arg1 = 0 to %0 { 15 | %6 = affine.load %2[0] : memref<1xf32> 16 | %7 = affine.load %1[0] : memref<1xf32> 17 | %8 = affine.load %arg0[%arg1] : memref 18 | %9 = addf %7, %8 : f32 19 | %10 = mulf %6, %8 : f32 20 | affine.store %9, %1[0] : memref<1xf32> 21 | affine.store %10, %2[0] : memref<1xf32> 22 | } 23 | %3 = affine.load %2[0] : memref<1xf32> 24 | %4 = affine.load %1[0] : memref<1xf32> 25 | %5 = addf %4, %3 : f32 26 | return %5 : f32 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/redstore.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* --detect-reduction -S | FileCheck %s 2 | 3 | extern int print(double); 4 | 5 | void sum(double *result, double* array, int N) { 6 | #pragma scop 7 | for (int j=0; j, %[[arg1:.+]]: memref, %[[arg2:.+]]: i32) 18 | // CHECK-NEXT: %[[cst:.+]] = arith.constant 0.000000e+00 : f64 19 | // CHECK-NEXT: %[[V0:.+]] = arith.index_cast %[[arg2]] : i32 to index 20 | // CHECK-NEXT: affine.for %[[arg3:.+]] = 0 to %[[V0]] { 21 | // CHECK-NEXT: affine.store %[[cst]], %[[arg0]][0] : memref 22 | // CHECK-NEXT: %[[i2:.+]] = affine.load %[[arg0]][0] : memref 23 | // CHECK-NEXT: %[[i3:.+]] = affine.for %[[arg4:.+]] = 0 to 10 iter_args(%[[arg5:.+]] = %[[i2]]) -> (f64) { 24 | // CHECK-NEXT: %[[i6:.+]] = affine.load %[[arg1]][%[[arg4]]] : memref 25 | // CHECK-NEXT: %[[i7:.+]] = arith.addf %[[arg5]], %[[i6]] : f64 26 | // CHECK-NEXT: affine.yield %[[i7]] : f64 27 | // CHECK-NEXT: } 28 | // CHECK-NEXT: affine.store %[[i3]], %[[arg0]][0] : memref 29 | // CHECK-NEXT: %[[i4:.+]] = affine.load %[[arg0]][0] : memref 30 | // CHECK-NEXT: %{{.*}} = func.call @print(%[[i4:.+]]) : (f64) -> i32 31 | // CHECK-NEXT: } 32 | // CHECK-NEXT: return 33 | // CHECK-NEXT: } 34 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/redstore2.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* --detect-reduction -S | FileCheck %s 2 | 3 | void sum(double *result, double* array) { 4 | result[0] = 0; 5 | #pragma scop 6 | for (int i=0; i<10; i++) { 7 | result[0] += array[i]; 8 | } 9 | #pragma endscop 10 | } 11 | 12 | // CHECK: func @sum(%[[arg0:.+]]: memref, %[[arg1:.+]]: memref) 13 | // CHECK-NEXT: %[[cst:.+]] = arith.constant 0.000000e+00 : f64 14 | // CHECK-NEXT: affine.store %[[cst]], %[[arg0]][0] : memref 15 | // CHECK-NEXT: %[[i1:.+]] = affine.load %[[arg0]][0] : memref 16 | // CHECK-NEXT: %[[i2:.+]] = affine.for %[[arg2:.+]] = 0 to 10 iter_args(%[[arg3:.+]] = %[[i1]]) -> (f64) { 17 | // CHECK-NEXT: %[[i3:.+]] = affine.load %[[arg1]][%[[arg2]]] : memref 18 | // CHECK-NEXT: %[[i4:.+]] = arith.addf %[[arg3]], %[[i3]] : f64 19 | // CHECK-NEXT: affine.yield %[[i4]] : f64 20 | // CHECK-NEXT: } 21 | // CHECK-NEXT: affine.store %[[i2]], %[[arg0]][0] : memref 22 | // CHECK-NEXT: return 23 | // CHECK-NEXT: } 24 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/reduction.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=reduction_gemm | FileCheck %s 2 | // XFAIL: * 3 | void reduction_gemm() { 4 | int i, j, k; 5 | int A[1024][1024]; 6 | int B[1024][1024]; 7 | int C[1024][1024]; 8 | 9 | #pragma scop 10 | for (i = 0; i < 1024; i++) 11 | for (j = 0; j < 1024; j++) 12 | for (k = 0; k < 1024; k++) 13 | C[i][j] += A[i][k] * B[k][j]; 14 | #pragma endscop 15 | } 16 | 17 | // RUN: cgeist %s --function=reduction_bicg | FileCheck %s 18 | // XFAIL: * 19 | void reduction_bicg() { 20 | int i, j; 21 | int A[100][200]; 22 | int r[100]; 23 | int s[200]; 24 | int p[200]; 25 | int q[100]; 26 | 27 | #pragma scop 28 | for (i = 0; i < 100; i++) { 29 | for (j = 0; j < 200; j++) { 30 | s[j] = s[j] + r[i] * A[i][j]; 31 | } 32 | } 33 | #pragma endscop 34 | } 35 | 36 | // RUN: cgeist %s --function=reduction_sum | FileCheck %s 37 | // XFAIL: * 38 | void reduction_sum() { 39 | int sum = 0; 40 | int A[100]; 41 | #pragma scop 42 | for (int i = 0; i < 100; i++) 43 | sum += A[i]; 44 | #pragma endscop 45 | } 46 | 47 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/ref.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | extern "C" { 4 | 5 | void sub0(int& a); 6 | void sub(int& a) { 7 | a++; 8 | } 9 | 10 | void kernel_deriche() { 11 | int a = 32;; 12 | int &b = a; 13 | sub0(b); 14 | } 15 | 16 | } 17 | 18 | // CHECK: func @sub(%[[arg0:.+]]: memref) 19 | // CHECK-NEXT: %[[c1_i32:.+]] = arith.constant 1 : i32 20 | // CHECK-NEXT: %[[V0:.+]] = affine.load %[[arg0]][0] : memref 21 | // CHECK-NEXT: %[[V1:.+]] = arith.addi %[[V0]], %[[c1_i32]] : i32 22 | // CHECK-NEXT: affine.store %[[V1]], %[[arg0]][0] : memref 23 | // CHECK-NEXT: return 24 | // CHECK-NEXT: } 25 | // CHECK: func @kernel_deriche() 26 | // CHECK-NEXT: %[[c32_i32:.+]] = arith.constant 32 : i32 27 | // CHECK-NEXT: %[[V0:.+]] = memref.alloca() : memref<1xi32> 28 | // CHECK-NEXT: %[[V1:.+]] = memref.cast %[[V0]] : memref<1xi32> to memref 29 | // CHECK-NEXT: affine.store %[[c32_i32]], %[[V0]][0] : memref<1xi32> 30 | // CHECK-NEXT: call @sub0(%[[V1]]) : (memref) -> () 31 | // CHECK-NEXT: return 32 | // CHECK-NEXT: } 33 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/refpair.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | extern "C" { 4 | 5 | struct pair { 6 | int x, y; 7 | }; 8 | void sub0(pair& a); 9 | void sub(pair& a) { 10 | a.x++; 11 | } 12 | 13 | void kernel_deriche() { 14 | pair a; 15 | a.x = 32;; 16 | pair &b = a; 17 | sub0(b); 18 | } 19 | 20 | } 21 | 22 | // CHECK: func @sub(%[[arg0:.+]]: memref) 23 | // CHECK-NEXT: %[[c1_i32:.+]] = arith.constant 1 : i32 24 | // CHECK-NEXT: %[[V0:.+]] = affine.load %[[arg0]][0, 0] : memref 25 | // CHECK-NEXT: %[[V1:.+]] = arith.addi %[[V0]], %[[c1_i32]] : i32 26 | // CHECK-NEXT: affine.store %[[V1]], %[[arg0]][0, 0] : memref 27 | // CHECK-NEXT: return 28 | // CHECK-NEXT: } 29 | 30 | // CHECK: func @kernel_deriche() 31 | // CHECK-NEXT: %[[c32_i32:.+]] = arith.constant 32 : i32 32 | // CHECK-NEXT: %[[V0:.+]] = memref.alloca() : memref<1x2xi32> 33 | // CHECK-NEXT: %[[V1:.+]] = memref.cast %[[V0]] : memref<1x2xi32> to memref 34 | // CHECK-NEXT: affine.store %[[c32_i32]], %[[V0]][0, 0] : memref<1x2xi32> 35 | // CHECK-NEXT: call @sub0(%[[V1]]) : (memref) -> () 36 | // CHECK-NEXT: return 37 | // CHECK-NEXT: } 38 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/refptrabi.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=ll -S | FileCheck %s 2 | 3 | struct alignas(2) Half { 4 | unsigned short x; 5 | 6 | Half() = default; 7 | }; 8 | 9 | extern "C" { 10 | 11 | float thing(Half); 12 | 13 | float ll(void* data) { 14 | return thing(*(Half*)data); 15 | } 16 | 17 | } 18 | 19 | // CHECK-LABEL: func.func @ll( 20 | // CHECK-SAME: %[[VAL_0:[A-Za-z0-9_]*]]: memref) -> f32 21 | // CHECK: %[[VAL_1:[A-Za-z0-9_]*]] = memref.alloca() : memref<1x1xi16> 22 | // CHECK: %[[VAL_2:[A-Za-z0-9_]*]] = "polygeist.memref2pointer"(%[[VAL_0]]) : (memref) -> !llvm.ptr 23 | // CHECK: %[[VAL_3:[A-Za-z0-9_]*]] = llvm.load %[[VAL_2]] : !llvm.ptr -> i16 24 | // CHECK: affine.store %[[VAL_3]], %[[VAL_1]][0, 0] : memref<1x1xi16> 25 | // CHECK: %[[VAL_4:[A-Za-z0-9_]*]] = memref.cast %[[VAL_1]] : memref<1x1xi16> to memref 26 | // CHECK: %[[VAL_5:[A-Za-z0-9_]*]] = call @thing(%[[VAL_4]]) : (memref) -> f32 27 | // CHECK: return %[[VAL_5]] : f32 28 | // CHECK: } 29 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/reverseRaise.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=kernel_correlation --raise-scf-to-affine -S | FileCheck %s 2 | 3 | #define DATA_TYPE double 4 | 5 | #define SCALAR_VAL(x) ((double)x) 6 | 7 | void use(int i); 8 | 9 | /* Main computational kernel. The whole function will be timed, 10 | including the call and return. */ 11 | void kernel_correlation(int start, int end) { 12 | for (int i = end; i >= start; i--) { 13 | use(i); 14 | } 15 | } 16 | 17 | // CHECK-LABEL: func.func @kernel_correlation( 18 | // CHECK-SAME: %[[VAL_0:[A-Za-z0-9_]*]]: i32, 19 | // CHECK-SAME: %[[VAL_1:[A-Za-z0-9_]*]]: i32) 20 | // CHECK: %[[VAL_2:[A-Za-z0-9_]*]] = arith.index_cast %[[VAL_1]] : i32 to index 21 | // CHECK: %[[VAL_3:[A-Za-z0-9_]*]] = arith.index_cast %[[VAL_0]] : i32 to index 22 | // CHECK: affine.for %[[VAL_4:[A-Za-z0-9_]*]] = %[[VAL_3]] to #map(){{\[}}%[[VAL_2]]] { 23 | // CHECK: %[[VAL_5:[A-Za-z0-9_]*]] = arith.subi %[[VAL_4]], %[[VAL_3]] : index 24 | // CHECK: %[[VAL_6:[A-Za-z0-9_]*]] = arith.subi %[[VAL_2]], %[[VAL_5]] : index 25 | // CHECK: %[[VAL_7:[A-Za-z0-9_]*]] = arith.index_cast %[[VAL_6]] : index to i32 26 | // CHECK: func.call @use(%[[VAL_7]]) : (i32) -> () 27 | // CHECK: } 28 | // CHECK: return 29 | // CHECK: } 30 | // CHECK: func.func private @use(i32) 31 | 32 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/scor2.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=kernel_correlation --raise-scf-to-affine -S | FileCheck %s 2 | // RUN: cgeist %s --function=kernel_correlation --raise-scf-to-affine -S --memref-fullrank | FileCheck %s --check-prefix=FULLRANK 3 | 4 | #define DATA_TYPE double 5 | 6 | #define SCALAR_VAL(x) ((double)x) 7 | 8 | /* Main computational kernel. The whole function will be timed, 9 | including the call and return. */ 10 | void kernel_correlation(int m, double corr[28]) 11 | { 12 | for (int i = 0; i < m-1; i++) { 13 | corr[i] = 0.; 14 | } 15 | } 16 | 17 | // CHECK: #map = affine_map<()[s0] -> (s0 - 1)> 18 | // CHECK: func @kernel_correlation(%[[arg0:.+]]: i32, %[[arg1:.+]]: memref) 19 | // CHECK-DAG: %[[cst:.+]] = arith.constant 0.000000e+00 : f64 20 | // CHECK-NEXT: %[[V0:.+]] = arith.index_cast %[[arg0]] : i32 to index 21 | // CHECK-NEXT: affine.for %[[arg2:.+]] = 0 to #map()[%[[V0]]] { 22 | // CHECK-NEXT: affine.store %[[cst]], %[[arg1]][%[[arg2]]] : memref 23 | // CHECK-NEXT: } 24 | // CHECK-NEXT: return 25 | // CHECK-NEXT: } 26 | 27 | // FULLRANK: func @kernel_correlation(%{{.*}}: i32, %{{.*}}: memref<28xf64>) 28 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/scor3.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=kernel_correlation --raise-scf-to-affine -S | FileCheck %s 2 | // RUN: cgeist %s --function=kernel_correlation --raise-scf-to-affine -S --memref-fullrank | FileCheck %s --check-prefix=FULLRANK 3 | 4 | #define DATA_TYPE double 5 | 6 | #define SCALAR_VAL(x) ((double)x) 7 | 8 | /* Main computational kernel. The whole function will be timed, 9 | including the call and return. */ 10 | void kernel_correlation(int m, double corr[28][28]) 11 | { 12 | int i, j, k; 13 | //i = 0; 14 | for (i = 0; i < 28; i++) 15 | { 16 | for (j = i+1; j < m; j++) 17 | { 18 | corr[i][j] = SCALAR_VAL(0.0); 19 | } 20 | } 21 | } 22 | 23 | // CHECK: func @kernel_correlation(%[[arg0:.+]]: i32, %[[arg1:.+]]: memref) 24 | // CHECK-DAG: %[[cst:.+]] = arith.constant 0.000000e+00 : f64 25 | // CHECK-DAG: %[[V0:.+]] = arith.index_cast %[[arg0]] : i32 to index 26 | // CHECK-NEXT: affine.for %[[arg2:.+]] = 0 to 28 { 27 | // CHECK-NEXT: affine.for %[[arg3:.+]] = #map(%[[arg2]]) to %[[V0]] { 28 | // CHECK-NEXT: affine.store %[[cst]], %[[arg1]][%[[arg2]], %[[arg3]]] : memref 29 | // CHECK-NEXT: } 30 | // CHECK-NEXT: } 31 | // CHECK-NEXT: return 32 | // CHECK-NEXT: } 33 | 34 | // FULLRANK: func @kernel_correlation(%{{.*}}: i32, %{{.*}}: memref<28x28xf64>) 35 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/scor4.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=kernel_correlation --raise-scf-to-affine -S | FileCheck %s 2 | // RUN: cgeist %s --function=kernel_correlation --raise-scf-to-affine -S --memref-fullrank | FileCheck %s --check-prefix=FULLRANK 3 | 4 | #define DATA_TYPE double 5 | 6 | #define SCALAR_VAL(x) ((double)x) 7 | 8 | void use(int i); 9 | 10 | /* Main computational kernel. The whole function will be timed, 11 | including the call and return. */ 12 | void kernel_correlation(double A[28], double B[28]) 13 | { 14 | int i; 15 | for (i = 1; i < 10; i++) { 16 | A[i] = 0.; 17 | } 18 | for (i = 1; i < 10; i++) { 19 | B[i] = 0.; 20 | } 21 | } 22 | 23 | // CHECK: func @kernel_correlation(%[[arg0:.+]]: memref, %[[arg1:.+]]: memref) 24 | // CHECK-NEXT: %[[cst:.+]] = arith.constant 0.000000e+00 : f64 25 | // CHECK-NEXT: affine.for %[[arg2:.+]] = 1 to 10 { 26 | // CHECK-NEXT: affine.store %[[cst]], %[[arg0]][%[[arg2]]] : memref 27 | // CHECK-NEXT: } 28 | // CHECK-NEXT: affine.for %[[arg2:.+]] = 1 to 10 { 29 | // CHECK-NEXT: affine.store %[[cst]], %[[arg1]][%[[arg2]]] : memref 30 | // CHECK-NEXT: } 31 | // CHECK-NEXT: return 32 | // CHECK-NEXT: } 33 | 34 | // FULLRANK: func @kernel_correlation(%{{.*}}: memref<28xf64>, %{{.*}}: memref<28xf64>) 35 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/sec.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | int compute_tran_temp(int total_iterations, int num_iterations) 4 | { 5 | float t; 6 | int src = 1, dst = 0; 7 | for (t = 0; t < total_iterations; t+=num_iterations) { 8 | int temp = src; 9 | src = dst; 10 | dst = temp; 11 | } 12 | return dst; 13 | } 14 | 15 | // CHECK: func @compute_tran_temp(%[[arg0:.+]]: i32, %[[arg1:.+]]: i32) -> i32 16 | // CHECK-DAG: %[[cst:.+]] = arith.constant 0.000000e+00 : f32 17 | // CHECK-DAG: %[[c0_i32:.+]] = arith.constant 0 : i32 18 | // CHECK-DAG: %[[c1_i32:.+]] = arith.constant 1 : i32 19 | // CHECK-NEXT: %[[V0:.+]] = arith.sitofp %[[arg0]] : i32 to f32 20 | // CHECK-NEXT: %[[V1:.+]] = arith.sitofp %[[arg1]] : i32 to f32 21 | // CHECK-NEXT: %[[V2:.+]]:3 = scf.while (%[[arg2:.+]] = %[[c0_i32]], %[[arg3:.+]] = %[[c1_i32]], %[[arg4:.+]] = %[[cst]]) : (i32, i32, f32) -> (i32, i32, f32) { 22 | // CHECK-NEXT: %[[V3:.+]] = arith.cmpf olt, %[[arg4]], %[[V0]] : f32 23 | // CHECK-NEXT: scf.condition(%[[V3]]) %[[arg2]], %[[arg3]], %[[arg4]] : i32, i32, f32 24 | // CHECK-NEXT: } do { 25 | // CHECK-NEXT: ^bb0(%[[arg2:.+]]: i32, %[[arg3:.+]]: i32, %[[arg4:.+]]: f32): 26 | // CHECK-NEXT: %[[V3:.+]] = arith.addf %[[arg4]], %[[V1]] : f32 27 | // CHECK-NEXT: scf.yield %[[arg3]], %[[arg2]], %[[V3]] : i32, i32, f32 28 | // CHECK-NEXT: } 29 | // CHECK-NEXT: return %[[V2]]#0 : i32 30 | // CHECK-NEXT: } 31 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/setter.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | void sub0(int *a); 4 | void sub(int *a) { 5 | *a = 3; 6 | } 7 | 8 | void kernel_deriche() { 9 | int a; 10 | sub0(&a); 11 | } 12 | 13 | // CHECK: func @sub(%[[arg0:.+]]: memref) 14 | // CHECK-NEXT: %[[c3_i32:.+]] = arith.constant 3 : i32 15 | // CHECK-NEXT: affine.store %[[c3_i32]], %[[arg0]][0] : memref 16 | // CHECK-NEXT: return 17 | // CHECK-NEXT: } 18 | 19 | // CHECK: func @kernel_deriche() 20 | // CHECK-NEXT: %[[V0:.+]] = memref.alloca() : memref<1xi32> 21 | // CHECK-NEXT: %[[V1:.+]] = llvm.mlir.undef : i32 22 | // CHECK-NEXT: affine.store %[[V1]], %[[V0]][0] : memref<1xi32> 23 | // CHECK-NEXT: %[[V2:.+]] = memref.cast %[[V0]] : memref<1xi32> to memref 24 | // CHECK-NEXT: call @sub0(%[[V2]]) : (memref) -> () 25 | // CHECK-NEXT: return 26 | // CHECK-NEXT: } 27 | 28 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/signcmp.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | void run(); 4 | unsigned int cmp(int a, int b) { 5 | if (a < b) { 6 | run(); 7 | } 8 | return a < b; 9 | } 10 | unsigned int cmp2() { 11 | if (-2 < 0) { 12 | run(); 13 | } 14 | return -2 < 0; 15 | } 16 | 17 | // CHECK: func @cmp(%[[arg0:.+]]: i32, %[[arg1:.+]]: i32) -> i32 18 | // CHECK-NEXT: %[[V0:.+]] = arith.cmpi slt, %[[arg0]], %[[arg1]] : i32 19 | // CHECK-NEXT: scf.if %[[V0]] { 20 | // CHECK-NEXT: call @run() : () -> () 21 | // CHECK-NEXT: } 22 | // CHECK-NEXT: %[[V1:.+]] = arith.extui %[[V0]] : i1 to i32 23 | // CHECK-NEXT: return %[[V1]] : i32 24 | // CHECK-NEXT: } 25 | // CHECK: func @cmp2() -> i32 26 | // CHECK-NEXT: %c1_i32 = arith.constant 1 : i32 27 | // CHECK-NEXT: call @run() : () -> () 28 | // CHECK-NEXT: return %c1_i32 : i32 29 | // CHECK-NEXT: } 30 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/size.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | struct X { 4 | int a; 5 | long long b; 6 | }; 7 | struct Y { 8 | int c; 9 | struct X x; 10 | }; 11 | unsigned long long size() { 12 | return sizeof(struct Y); 13 | } 14 | 15 | // CHECK: func @size() -> i64 16 | // CHECK-NEXT: %[[c24_i64:.+]] = arith.constant 24 : i64 17 | // CHECK-NEXT: return %[[c24_i64]] : i64 18 | // CHECK-NEXT: } 19 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/sizeof.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | void* malloc(unsigned long); 4 | 5 | struct Meta { 6 | float* f; 7 | char x; 8 | }; 9 | 10 | struct Meta* create() { 11 | return (struct Meta*)malloc(sizeof(struct Meta)); 12 | } 13 | 14 | 15 | // CHECK-LABEL: func.func @create() -> memref, i8)>> 16 | // CHECK: %[[VAL_0:[A-Za-z0-9_]*]] = "polygeist.typeSize"() <{source = !llvm.struct<(memref, i8)>}> : () -> index 17 | // CHECK: %[[VAL_1:[A-Za-z0-9_]*]] = arith.divui %[[VAL_0]], %[[VAL_0]] : index 18 | // CHECK: %[[VAL_2:[A-Za-z0-9_]*]] = memref.alloc(%[[VAL_1]]) : memref, i8)>> 19 | // CHECK: return %[[VAL_2]] : memref, i8)>> 20 | // CHECK: } 21 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/static.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=foo -S | FileCheck %s 2 | 3 | #define N 8 4 | int foo() { 5 | static int bar[N]; 6 | return bar[0]; 7 | } 8 | 9 | // CHECK: memref.global "private" @"foo@static@bar" : memref<8xi32> = uninitialized 10 | // CHECK-NEXT: func @foo() -> i32 11 | // CHECK-NEXT: %[[V0:.+]] = memref.get_global @"foo@static@bar" : memref<8xi32> 12 | // CHECK-NEXT: %[[V1:.+]] = affine.load %[[V0]][0] : memref<8xi32> 13 | // CHECK-NEXT: return %[[V1]] : i32 14 | // CHECK-NEXT: } 15 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/staticint.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | int adder(int x) { 4 | static int cur = 0; 5 | cur += x; 6 | return cur; 7 | } 8 | 9 | // CHECK: memref.global "private" @"adder@static@cur@init" : memref<1xi1> = dense 10 | // CHECK: memref.global "private" @"adder@static@cur" : memref<1xi32> = uninitialized 11 | // CHECK: func @adder(%[[arg0:.+]]: i32) -> i32 12 | // CHECK-DAG: %[[false:.+]] = arith.constant false 13 | // CHECK-DAG: %[[c0_i32:.+]] = arith.constant 0 : i32 14 | // CHECK-DAG: %[[V0:.+]] = memref.get_global @"adder@static@cur" : memref<1xi32> 15 | // CHECK-DAG: %[[V1:.+]] = memref.get_global @"adder@static@cur@init" : memref<1xi1> 16 | // CHECK-NEXT: %[[V2:.+]] = affine.load %[[V1]][0] : memref<1xi1> 17 | // CHECK-NEXT: scf.if %[[V2]] { 18 | // CHECK-NEXT: affine.store %[[false]], %[[V1]][0] : memref<1xi1> 19 | // CHECK-NEXT: affine.store %[[c0_i32]], %[[V0]][0] : memref<1xi32> 20 | // CHECK-NEXT: } 21 | // CHECK-NEXT: %[[V3:.+]] = affine.load %[[V0]][0] : memref<1xi32> 22 | // CHECK-NEXT: %[[V4:.+]] = arith.addi %[[V3]], %[[arg0]] : i32 23 | // CHECK-NEXT: affine.store %[[V4]], %[[V0]][0] : memref<1xi32> 24 | // CHECK-NEXT: return %[[V4]] : i32 25 | // CHECK-NEXT: } 26 | 27 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/str.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=meta -S | FileCheck %s 2 | 3 | int foo(const char*); 4 | 5 | int meta() { 6 | return foo("bar") + foo(__PRETTY_FUNCTION__); 7 | } 8 | 9 | // CHECK: llvm.mlir.global internal constant @str1("int meta()\00") 10 | // CHECK: llvm.mlir.global internal constant @str0("bar\00") 11 | // CHECK: func @meta() -> i32 attributes {llvm.linkage = 12 | // #llvm.linkage} { CHECK-NEXT: %[[V0:.+]] = llvm.mlir.addressof @str0 : 13 | // !llvm.ptr> CHECK-NEXT: %[[V1:.+]] = "polygeist.pointer2memref"(%[[V0]]) 14 | // : (!llvm.ptr>) -> memref CHECK-NEXT: %[[V2:.+]] = call 15 | // @foo(%[[V1]]) : (memref) -> i32 CHECK-NEXT: %[[V3:.+]] = llvm.mlir.addressof 16 | // @str1 : !llvm.ptr> CHECK-NEXT: %[[V4:.+]] = 17 | // "polygeist.pointer2memref"(%[[V3]]) : (!llvm.ptr>) -> memref 18 | // CHECK-NEXT: %[[V5:.+]] = call @foo(%[[V4]]) : (memref) -> i32 19 | // CHECK-NEXT: %[[V6:.+]] = arith.addi %[[V2]], %[[V5]] : i32 20 | // CHECK-NEXT: return %[[V6]] : i32 21 | // CHECK-NEXT: } 22 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/stream.cu: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --cuda-gpu-arch=sm_60 -nocudalib -nocudainc %resourcedir --function=* -S | FileCheck %s 2 | 3 | #include "Inputs/cuda.h" 4 | 5 | __device__ void something(int* array, int n); 6 | 7 | // Type your code here, or load an example. 8 | __global__ void square(int *array, int n) { 9 | something(array, n); 10 | } 11 | 12 | void run(cudaStream_t stream1, int *array, int n) { 13 | square<<< 10, 20, 0, stream1>>> (array, n) ; 14 | } 15 | 16 | // CHECK: func.func @_Z3runP10cudaStreamPii(%[[arg0:.+]]: memref>, %[[arg1:.+]]: memref, %[[arg2:.+]]: i32) 17 | // CHECK-DAG: %[[c10:.+]] = arith.constant 10 : index 18 | // CHECK-DAG: %[[c1:.+]] = arith.constant 1 : index 19 | // CHECK-DAG: %[[c20:.+]] = arith.constant 20 : index 20 | // CHECK-NEXT: %[[V0:.+]] = "polygeist.stream2token"(%[[arg0]]) : (memref>) -> !gpu.async.token 21 | // CHECK-NEXT: %[[V1:.+]] = gpu.launch async [%[[V0:.+]]] blocks(%[[arg3:.+]], %[[arg4:.+]], %[[arg5:.+]]) in (%[[arg9:.+]] = %[[c10]], %[[arg10:.+]] = %[[c1]], %[[arg11:.+]] = %[[c1]]) threads(%[[arg6:.+]], %[[arg7:.+]], %[[arg8:.+]]) in (%[[arg12:.+]] = %[[c20]], %[[arg13:.+]] = %[[c1]], %[[arg14:.+]] = %[[c1]]) { 22 | // CHECK-NEXT: func.call @_Z21__device_stub__squarePii(%[[arg1:.+]], %[[arg2:.+]]) : (memref, i32) -> () 23 | // CHECK-NEXT: gpu.terminator 24 | // CHECK-NEXT: } 25 | // CHECK-NEXT: return 26 | // CHECK-NEXT: } 27 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/struct.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s %stdinclude --function=func -S | FileCheck %s 2 | 3 | float hload(const void* data); 4 | 5 | struct OperandInfo { 6 | char dtype = 'a'; 7 | 8 | void* data; 9 | 10 | bool end; 11 | }; 12 | 13 | extern "C" { 14 | float func(struct OperandInfo* op) { 15 | return hload(op->data); 16 | } 17 | } 18 | 19 | // CHECK-LABEL: func.func @func( 20 | // CHECK-SAME: %[[VAL_0:[A-Za-z0-9_]*]]: memref, i8)>>) -> f32 21 | // CHECK: %[[VAL_1:[A-Za-z0-9_]*]] = "polygeist.memref2pointer"(%[[VAL_0]]) : (memref, i8)>>) -> !llvm.ptr 22 | // CHECK: %[[VAL_2:[A-Za-z0-9_]*]] = llvm.getelementptr %[[VAL_1]][0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i8, memref, i8)> 23 | // CHECK: %[[VAL_3:[A-Za-z0-9_]*]] = llvm.load %[[VAL_2]] : !llvm.ptr -> memref 24 | // CHECK: %[[VAL_4:[A-Za-z0-9_]*]] = call @_Z5hloadPKv(%[[VAL_3]]) : (memref) -> f32 25 | // CHECK: return %[[VAL_4]] : f32 26 | // CHECK: } 27 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/switcherr.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=foo -S | FileCheck %s 2 | 3 | int foo(int t) { 4 | int n = 10; 5 | switch (t) { 6 | case 1: 7 | n = 20; 8 | break; 9 | case 2: 10 | n = 30; 11 | break; 12 | default: 13 | return -1; 14 | } 15 | return n; 16 | } 17 | 18 | // TODO the select should be canonicalized better 19 | // CHECK: func @foo(%[[arg0:.+]]: i32) -> i32 20 | // CHECK-DAG: %[[cm1:.+]] = arith.constant -1 : i32 21 | // CHECK-DAG: %[[c30_i32:.+]] = arith.constant 30 : i32 22 | // CHECK-DAG: %[[false:.+]] = arith.constant false 23 | // CHECK-DAG: %[[c20_i32:.+]] = arith.constant 20 : i32 24 | // CHECK-DAG: %[[c10_i32:.+]] = arith.constant 10 : i32 25 | // CHECK-DAG: %[[true:.+]] = arith.constant true 26 | // CHECK-DAG: %[[V0:.+]] = llvm.mlir.undef : i32 27 | // CHECK-DAG: switch %[[arg0]] : i32, [ 28 | // CHECK-NEXT: default: ^bb1(%[[c10_i32]], %[[false]], %[[cm1:.+]] : i32, i1, i32), 29 | // CHECK-NEXT: 1: ^bb1(%[[c20_i32]], %[[true]], %[[V0]] : i32, i1, i32), 30 | // CHECK-NEXT: 2: ^bb1(%[[c30_i32]], %[[true]], %[[V0]] : i32, i1, i32) 31 | // CHECK-NEXT: ] 32 | // CHECK-NEXT: ^bb1(%[[V1:.+]]: i32, %[[V2:.+]]: i1, %[[V3:.+]]: i32): // 3 preds: ^bb0, ^bb0, ^bb0 33 | // CHECK-NEXT: %[[V4:.+]] = arith.select %[[V2]], %[[V1]], %[[V3]] : i32 34 | // CHECK-NEXT: return %[[V4]] : i32 35 | // CHECK-NEXT: } 36 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/switchnone.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=foo -S | FileCheck %s 2 | 3 | int foo(int t) { 4 | switch (t) { 5 | } 6 | return t; 7 | } 8 | 9 | // CHECK: func @foo(%[[arg0:.+]]: i32) -> i32 10 | // CHECK-NEXT: return %[[arg0]] : i32 11 | // CHECK-NEXT: } 12 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/templatemember.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | class House; 4 | 5 | template 6 | class Info; 7 | 8 | template <> 9 | class Info{ 10 | public: 11 | static constexpr bool has_infinity = true; 12 | }; 13 | 14 | bool add_kernel_cuda() { 15 | return Info::has_infinity; 16 | } 17 | 18 | // CHECK: func @_Z15add_kernel_cudav() -> i8 19 | // CHECK-NEXT: %[[c1_i8:.+]] = arith.constant 1 : i8 20 | // CHECK-NEXT: return %[[c1_i8]] : i8 21 | // CHECK-NEXT: } 22 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/threeInt.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=struct_pass_all_same -S | FileCheck %s 2 | 3 | typedef struct { 4 | int a, b, c; 5 | } threeInt; 6 | 7 | int struct_pass_all_same(threeInt* a) { 8 | return a->b; 9 | } 10 | 11 | // CHECK: func @struct_pass_all_same(%[[arg0:.+]]: memref) -> i32 12 | // CHECK-NEXT: %[[V0:.+]] = affine.load %[[arg0]][0, 1] : memref 13 | // CHECK-NEXT: return %[[V0]] : i32 14 | // CHECK-NEXT: } 15 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/tobits.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=fp32_from_bits -S | FileCheck %s 2 | 3 | #include 4 | float fp32_from_bits(uint32_t w) { 5 | union { 6 | uint32_t as_bits; 7 | float as_value; 8 | } fp32 = {w}; 9 | return fp32.as_value; 10 | } 11 | 12 | 13 | 14 | // CHECK-LABEL: func.func @fp32_from_bits( 15 | // CHECK-SAME: %[[VAL_0:[A-Za-z0-9_]*]]: i32) -> f32 16 | // CHECK: %[[VAL_1:[A-Za-z0-9_]*]] = memref.alloca() : memref<1x!llvm.struct<(i32)>> 17 | // CHECK: %[[VAL_2:[A-Za-z0-9_]*]] = "polygeist.memref2pointer"(%[[VAL_1]]) : (memref<1x!llvm.struct<(i32)>>) -> !llvm.ptr 18 | // CHECK: %[[VAL_3:[A-Za-z0-9_]*]] = llvm.getelementptr %[[VAL_2]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i32)> 19 | // CHECK: llvm.store %[[VAL_0]], %[[VAL_3]] : i32, !llvm.ptr 20 | // CHECK: %[[VAL_4:[A-Za-z0-9_]*]] = llvm.load %[[VAL_2]] : !llvm.ptr -> f32 21 | // CHECK: return %[[VAL_4]] : f32 22 | // CHECK: } 23 | 24 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/triple.cu: -------------------------------------------------------------------------------- 1 | // RUN: cgeist --target aarch64-unknown-linux-gnu %s -nocudalib -nocudainc %stdinclude -S -o - | FileCheck %s -check-prefix=MLIR 2 | // RUN: cgeist --target aarch64-unknown-linux-gnu %s -nocudalib -nocudainc %stdinclude -emit-llvm -S -o - | FileCheck %s -check-prefix=LLVM 3 | 4 | // MLIR: llvm.target_triple = "aarch64-unknown-linux-gnu" 5 | // LLVM: target triple = "aarch64-unknown-linux-gnu" 6 | 7 | int main() { return 0; } 8 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/twotemplatevardecls.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | template 4 | struct integral_constant 5 | { 6 | static constexpr _Tp value = __v; 7 | }; 8 | 9 | template 10 | constexpr _Tp integral_constant<_Tp, __v>::value; 11 | 12 | bool failure() { 13 | return integral_constant::value; 14 | } 15 | 16 | unsigned char conv() { 17 | return integral_constant::value; 18 | } 19 | 20 | 21 | // CHECK: func @_Z7failurev() -> i8 22 | // CHECK-NEXT: %[[c1_i8:.+]] = arith.constant 1 : i8 23 | // CHECK-NEXT: return %[[c1_i8]] : i8 24 | // CHECK-NEXT: } 25 | // CHECK: func @_Z4convv() -> i8 26 | // CHECK-NEXT: %[[c1_i8:.+]] = arith.constant 1 : i8 27 | // CHECK-NEXT: return %[[c1_i8]] : i8 28 | // CHECK-NEXT: } 29 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/vector.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function='*' -S | FileCheck %s 2 | // TODO: 3 | // XFAIL: * 4 | 5 | typedef int v4si __attribute__ ((vector_size (16))); 6 | 7 | int foo() { 8 | v4si a = {1,2,3,4}; 9 | v4si b = {10,20,30,40}; 10 | a = b + 1; /* a = b + {1,1,1,1}; */ 11 | a = 2 * b; /* a = {2,2,2,2} * b; */ 12 | 13 | return a[1]; 14 | } 15 | 16 | int bar() { 17 | v4si a = {1,2,3,4}; 18 | v4si b = {10,20,30,40}; 19 | v4si c; 20 | 21 | c = a > b; /* The result would be {0, 0,-1, 0} */ 22 | c = a == b; /* The result would be {0,-1, 0,-1} */ 23 | return c[3]; 24 | } 25 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/while_decl.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=* -S | FileCheck %s 2 | 3 | struct A { 4 | int value; 5 | 6 | int getValue() { 7 | while (int tmp = this->value) { 8 | tmp++; 9 | } 10 | return value; 11 | } 12 | }; 13 | 14 | int main() { 15 | return A().getValue(); 16 | } 17 | 18 | // CHECK: func.func @_ZN1A8getValueEv( 19 | // CHECK: scf.while 20 | // CHECK: arith.cmpi ne 21 | // CHECK: scf.condition 22 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/x.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=kernel_deriche -S | FileCheck %s 2 | 3 | int kernel_deriche(int x) { 4 | x++; 5 | x+=3; 6 | x*=2; 7 | return x; 8 | } 9 | 10 | // CHECK: func @kernel_deriche(%[[arg0:.+]]: i32) -> i32 11 | // CHECK-DAG: %[[c2_i32:.+]] = arith.constant 2 : i32 12 | // CHECK-DAG: %[[c4_i32:.+]] = arith.constant 4 : i32 13 | // CHECK: %[[V0:.+]] = arith.addi %[[arg0]], %[[c4_i32]] : i32 14 | // CHECK: %[[V1:.+]] = arith.muli %[[V0]], %[[c2_i32]] : i32 15 | // CHECK: return %[[V1]] : i32 16 | // CHECK-NEXT: } 17 | -------------------------------------------------------------------------------- /tools/cgeist/Test/Verification/xor.c: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=foo -S | FileCheck %s 2 | 3 | void foo(int A[10], int a) { 4 | for (int i = 0; i < 10; ++i) 5 | A[i] ^= (a ^ (A[i] + 1)); 6 | } 7 | 8 | // CHECK: func @foo(%[[arg0:.+]]: memref, %[[arg1:.+]]: i32) 9 | // CHECK-DAG: %[[c1_i32:.+]] = arith.constant 1 : i32 10 | // CHECK-DAG: %[[c1:.+]] = arith.constant 1 : index 11 | // CHECK-DAG: %[[c0:.+]] = arith.constant 0 : index 12 | // CHECK-DAG: %[[c10:.+]] = arith.constant 10 : index 13 | // CHECK-NEXT: scf.for %[[arg2:.+]] = %[[c0]] to %[[c10]] step %[[c1]] { 14 | // CHECK-NEXT: %[[V0:.+]] = memref.load %[[arg0]][%[[arg2]]] : memref 15 | // CHECK-NEXT: %[[V1:.+]] = arith.addi %[[V0]], %[[c1_i32]] : i32 16 | // CHECK-NEXT: %[[V2:.+]] = arith.xori %[[arg1]], %[[V1]] : i32 17 | // CHECK-NEXT: %[[V3:.+]] = arith.xori %[[V0]], %[[V2]] : i32 18 | // CHECK-NEXT: memref.store %[[V3]], %[[arg0]][%[[arg2]]] : memref 19 | // CHECK-NEXT: } 20 | -------------------------------------------------------------------------------- /tools/cgeist/Test/addressoff_call.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function=_Z1fv -S | FileCheck %s 2 | unsigned long foo(unsigned); 3 | inline unsigned long inlineFunc(unsigned i) noexcept { 4 | return foo(i); 5 | } 6 | 7 | struct S { 8 | static unsigned long bar() noexcept { 9 | return (&inlineFunc)(0); 10 | } 11 | }; 12 | 13 | void f(){ 14 | auto res = S::bar(); 15 | } 16 | // CHECK: func.func @_Z10inlineFuncj(%arg0: i32) -> i64 17 | // CHECK-NEXT: %0 = call @_Z3fooj(%arg0) : (i32) -> i64 18 | // CHECK-NEXT: return %0 : i64 19 | // CHECK-NEXT: } 20 | -------------------------------------------------------------------------------- /tools/cgeist/Test/elaborated-init.cpp: -------------------------------------------------------------------------------- 1 | // RUN: cgeist %s --function='*' -S | FileCheck %s 2 | struct A { 3 | using TheType = int[4]; 4 | }; 5 | 6 | void testArrayInitExpr() 7 | { 8 | A::TheType a{1,2,3,4}; 9 | auto l = [a]{ 10 | }; 11 | } 12 | 13 | // CHECK-LABEL: func.func @_Z17testArrayInitExprv() 14 | // CHECK: %[[VAL_0:[A-Za-z0-9_]*]] = arith.constant 4 : i32 15 | // CHECK: %[[VAL_1:[A-Za-z0-9_]*]] = arith.constant 3 : i32 16 | // CHECK: %[[VAL_2:[A-Za-z0-9_]*]] = arith.constant 2 : i32 17 | // CHECK: %[[VAL_3:[A-Za-z0-9_]*]] = arith.constant 1 : i32 18 | // CHECK: %[[VAL_4:[A-Za-z0-9_]*]] = memref.alloca() : memref<1x!llvm.struct<(array<4 x i32>)>> 19 | // CHECK: %[[VAL_5:[A-Za-z0-9_]*]] = "polygeist.memref2pointer"(%[[VAL_4]]) : (memref<1x!llvm.struct<(array<4 x i32>)>>) -> !llvm.ptr 20 | // CHECK: llvm.store %[[VAL_3]], %[[VAL_5]] : i32, !llvm.ptr 21 | // CHECK: %[[VAL_6:[A-Za-z0-9_]*]] = llvm.getelementptr %[[VAL_5]][1] : (!llvm.ptr) -> !llvm.ptr, i32 22 | // CHECK: llvm.store %[[VAL_2]], %[[VAL_6]] : i32, !llvm.ptr 23 | // CHECK: %[[VAL_7:[A-Za-z0-9_]*]] = llvm.getelementptr %[[VAL_5]][2] : (!llvm.ptr) -> !llvm.ptr, i32 24 | // CHECK: llvm.store %[[VAL_1]], %[[VAL_7]] : i32, !llvm.ptr 25 | // CHECK: %[[VAL_8:[A-Za-z0-9_]*]] = llvm.getelementptr %[[VAL_5]][3] : (!llvm.ptr) -> !llvm.ptr, i32 26 | // CHECK: llvm.store %[[VAL_0]], %[[VAL_8]] : i32, !llvm.ptr 27 | // CHECK: return 28 | // CHECK: } 29 | 30 | -------------------------------------------------------------------------------- /tools/cgeist/Test/lit.site.cfg.in: -------------------------------------------------------------------------------- 1 | @LIT_SITE_CFG_IN_HEADER@ 2 | 3 | config.llvm_src_root = path(r"@LLVM_SOURCE_DIR@") 4 | config.llvm_obj_root = path(r"@LLVM_BINARY_DIR@") 5 | config.llvm_tools_dir = path(r"@LLVM_TOOLS_DIR@") 6 | config.polygeist_tools_dir = path(r"@POLYGEIST_TOOLS_DIR@") 7 | config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" 8 | config.mlir_clang_obj_root = "@MLIR_CLANG_BINARY_DIR@" 9 | config.target_triple = "@TARGET_TRIPLE@" 10 | config.llvm_obj_root = path(r"@LLVM_BINARY_DIR@") 11 | config.polygeist_enable_cuda = "@POLYGEIST_ENABLE_CUDA@" 12 | config.cudart_static_path = "@CUDA_cudart_static_LIBRARY@" 13 | config.polygeist_enable_rocm = "@POLYGEIST_ENABLE_ROCM@" 14 | config.polymer_enabled = "@POLYGEIST_ENABLE_POLYMER@" 15 | config.polymer_pluto_enabled = "@POLYGEIST_POLYMER_ENABLE_PLUTO@" 16 | 17 | # Support substitution of the tools and build_mode with user parameters. 18 | # This is used when we can't determine the tool dir at configuration time. 19 | try: 20 | config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params 21 | except KeyError as e: 22 | key, = e.args 23 | lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) 24 | 25 | import lit.llvm 26 | lit.llvm.initialize(lit_config, config) 27 | 28 | # Let the main config do the real work. 29 | lit_config.load_config(config, "@MLIR_CLANG_TEST_DIR@/lit.cfg") 30 | -------------------------------------------------------------------------------- /tools/cgeist/Test/polybench/AUTHORS: -------------------------------------------------------------------------------- 1 | * * * * * * * * * * * * * 2 | * Authors of PolyBench * 3 | * * * * * * * * * * * * * 4 | 5 | 6 | * Louis-Noel Pouchet 7 | Who provided packaging and harmonization of all test files, 8 | the PolyBench infrastructure and machinery, and several 9 | reference C files. 10 | 11 | * Uday Bondugula 12 | Who provided many of the original reference C files, including 13 | Fortran to C translation. 14 | 15 | * Tomofumi Yuki 16 | Who provided all the fixes implemented in 4.0, and is now the maintainer 17 | of PolyBench/C. 18 | -------------------------------------------------------------------------------- /tools/cgeist/Test/polybench/THANKS: -------------------------------------------------------------------------------- 1 | We would like to thank the following people for giving reporting bugs and 2 | giving feedback to PolyBench: 3 | * François Gindraud 4 | * Tobias Grosser 5 | * Guillaume Iooss 6 | * Peng Li 7 | * Sanjay Rajopadhye 8 | * Sven Verdoolaege 9 | * Willy Wolff 10 | 11 | and the following for providing reference C implementations: 12 | * Dave Wonnacott, Haverford College 13 | The nussinov implementation was provided by Dave with the help of 14 | - Allison Lake 15 | - Ting Zhou 16 | - Tian Jin 17 | based on algorithm by Nussinov, described in Allison Lake's senior thesis. 18 | 19 | * Gael Deest, University of Rennes 1 20 | The Deriche filter implementation was provided by Gael. 21 | -------------------------------------------------------------------------------- /tools/cgeist/Test/polybench/polybench.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llvm/Polygeist/77c04bb2a7a2406ca9480bcc9e729b07d2c8d077/tools/cgeist/Test/polybench/polybench.pdf -------------------------------------------------------------------------------- /tools/cgeist/Test/polybench/utilities/benchmark_list: -------------------------------------------------------------------------------- 1 | ./datamining/correlation/correlation.c 2 | ./datamining/covariance/covariance.c 3 | ./linear-algebra/kernels/2mm/2mm.c 4 | ./linear-algebra/kernels/3mm/3mm.c 5 | ./linear-algebra/kernels/atax/atax.c 6 | ./linear-algebra/kernels/bicg/bicg.c 7 | ./linear-algebra/kernels/doitgen/doitgen.c 8 | ./linear-algebra/kernels/mvt/mvt.c 9 | ./linear-algebra/blas/gemm/gemm.c 10 | ./linear-algebra/blas/gemver/gemver.c 11 | ./linear-algebra/blas/gesummv/gesummv.c 12 | ./linear-algebra/blas/symm/symm.c 13 | ./linear-algebra/blas/syr2k/syr2k.c 14 | ./linear-algebra/blas/syrk/syrk.c 15 | ./linear-algebra/blas/trmm/trmm.c 16 | ./linear-algebra/solvers/cholesky/cholesky.c 17 | ./linear-algebra/solvers/durbin/durbin.c 18 | ./linear-algebra/solvers/gramschmidt/gramschmidt.c 19 | ./linear-algebra/solvers/lu/lu.c 20 | ./linear-algebra/solvers/ludcmp/ludcmp.c 21 | ./linear-algebra/solvers/trisolv/trisolv.c 22 | ./medley/deriche/deriche.c 23 | ./medley/floyd-warshall/floyd-warshall.c 24 | ./medley/nussinov/nussinov.c 25 | ./stencils/adi/adi.c 26 | ./stencils/fdtd-2d/fdtd-2d.c 27 | ./stencils/heat-3d/heat-3d.c 28 | ./stencils/jacobi-1d/jacobi-1d.c 29 | ./stencils/jacobi-2d/jacobi-2d.c 30 | ./stencils/seidel-2d/seidel-2d.c 31 | -------------------------------------------------------------------------------- /tools/cgeist/Test/polybench/utilities/clean.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # Visits every directory, calls make clean, and then removes the Makefile 4 | # 5 | # Written by Tomofumi Yuki, 11/21 2014 6 | # 7 | 8 | my $TARGET_DIR = "."; 9 | 10 | if ($#ARGV != 0) { 11 | printf("usage perl clean.pl target-dir\n"); 12 | exit(1); 13 | } 14 | 15 | 16 | 17 | if ($#ARGV == 0) { 18 | $TARGET_DIR = $ARGV[0]; 19 | } 20 | 21 | 22 | my @categories = ('linear-algebra/blas', 23 | 'linear-algebra/kernels', 24 | 'linear-algebra/solvers', 25 | 'datamining', 26 | 'stencils', 27 | 'medley'); 28 | 29 | 30 | foreach $cat (@categories) { 31 | my $target = $TARGET_DIR.'/'.$cat; 32 | opendir DIR, $target or die "directory $target not found.\n"; 33 | while (my $dir = readdir DIR) { 34 | next if ($dir=~'^\..*'); 35 | next if (!(-d $target.'/'.$dir)); 36 | 37 | my $targetDir = $target.'/'.$dir; 38 | my $command = "cd $targetDir; make clean; rm -f Makefile"; 39 | print($command."\n"); 40 | system($command); 41 | } 42 | 43 | closedir DIR; 44 | } 45 | 46 | my $cfgFile = $TARGET_DIR.'/'.'config.mk'; 47 | if (-e $cfgFile) { 48 | unlink $cfgFile; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /tools/cgeist/Test/polybench/utilities/papi_counters.list: -------------------------------------------------------------------------------- 1 | // Counters must be delimited with ',' including the last one. 2 | // C/C++ comments are allowed. 3 | // Both native and standard PAPI events are supported. 4 | "PAPI_TOT_CYC", 5 | "L1D:REPL", 6 | -------------------------------------------------------------------------------- /tools/cgeist/Test/polybench/utilities/run-all.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # Visits every directory, calls make, and then executes the benchmark 4 | # (Designed for making sure every kernel compiles/runs after modifications) 5 | # 6 | # Written by Tomofumi Yuki, 01/15 2015 7 | # 8 | 9 | my $TARGET_DIR = "."; 10 | 11 | if ($#ARGV != 0 && $#ARGV != 1) { 12 | printf("usage perl run-all.pl target-dir [output-file]\n"); 13 | exit(1); 14 | } 15 | 16 | 17 | 18 | if ($#ARGV >= 0) { 19 | $TARGET_DIR = $ARGV[0]; 20 | } 21 | 22 | my $OUTFILE = ""; 23 | if ($#ARGV == 1) { 24 | $OUTFILE = $ARGV[1]; 25 | } 26 | 27 | 28 | my @categories = ('linear-algebra/blas', 29 | 'linear-algebra/kernels', 30 | 'linear-algebra/solvers', 31 | 'datamining', 32 | 'stencils', 33 | 'medley'); 34 | 35 | 36 | foreach $cat (@categories) { 37 | my $target = $TARGET_DIR.'/'.$cat; 38 | opendir DIR, $target or die "directory $target not found.\n"; 39 | while (my $dir = readdir DIR) { 40 | next if ($dir=~'^\..*'); 41 | next if (!(-d $target.'/'.$dir)); 42 | 43 | my $kernel = $dir; 44 | my $targetDir = $target.'/'.$dir; 45 | my $command = "cd $targetDir; make clean; make; ./$kernel"; 46 | $command .= " 2>> $OUTFILE" if ($OUTFILE ne ''); 47 | print($command."\n"); 48 | system($command); 49 | } 50 | 51 | closedir DIR; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /tools/polygeist-opt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) 2 | get_property(conversion_libs GLOBAL PROPERTY MLIR_CONVERSION_LIBS) 3 | set(LIBS 4 | ${dialect_libs} 5 | ${conversion_libs} 6 | MLIROptLib 7 | MLIRPolygeist 8 | MLIRPolygeistTransforms 9 | MLIRFuncAllExtensions 10 | ) 11 | if(POLYGEIST_ENABLE_POLYMER) 12 | list(APPEND LIBS 13 | PolymerTransforms 14 | MLIRTranslateLib 15 | MLIRFromLLVMIRTranslationRegistration 16 | ) 17 | endif() 18 | add_llvm_executable(polygeist-opt polygeist-opt.cpp) 19 | 20 | install(TARGETS polygeist-opt 21 | EXPORT PolygeistTargets 22 | RUNTIME DESTINATION ${LLVM_TOOLS_INSTALL_DIR} 23 | COMPONENT polygeist-opt) 24 | 25 | llvm_update_compile_flags(polygeist-opt) 26 | target_link_libraries(polygeist-opt PRIVATE ${LIBS}) 27 | -------------------------------------------------------------------------------- /tools/polymer/.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | -------------------------------------------------------------------------------- /tools/polymer/.gitattributes: -------------------------------------------------------------------------------- 1 | *.mlir linguist-detectable=false 2 | example/**/*.c linguist-detectable=false 3 | -------------------------------------------------------------------------------- /tools/polymer/.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | *.bc 15 | *.ll 16 | *.bin 17 | 18 | # Compiled Dynamic libraries 19 | *.so 20 | *.dylib 21 | *.dll 22 | 23 | # Fortran module files 24 | *.mod 25 | *.smod 26 | 27 | # Compiled Static libraries 28 | *.lai 29 | *.la 30 | *.a 31 | *.lib 32 | 33 | # Executables 34 | *.exe 35 | *.out 36 | *.app 37 | 38 | # CMake 39 | build 40 | build/ 41 | 42 | # Editor 43 | .vscode/ 44 | 45 | # Log files 46 | *.log 47 | 48 | # Temporary output 49 | tmp/ 50 | 51 | # Python 52 | *.pyc 53 | -------------------------------------------------------------------------------- /tools/polymer/Docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | ARG GID 3 | ARG UID 4 | RUN echo "Group ID: $GID" 5 | RUN echo "User ID: $UID" 6 | 7 | USER root 8 | RUN apt-get update 9 | RUN DEBIAN_FRONTEND="noninteractive" apt-get -y install tzdata --assume-yes 10 | 11 | # Install Essential Packages 12 | RUN apt-get install build-essential libtool autoconf pkg-config flex bison libgmp-dev clang-9 libclang-9-dev texinfo cmake vim ninja-build git --assume-yes 13 | 14 | RUN update-alternatives --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-9 100 15 | RUN update-alternatives --install /usr/bin/FileCheck FileCheck /usr/bin/FileCheck-9 100 16 | RUN update-alternatives --install /usr/bin/clang clang /usr/bin/clang-9 100 17 | RUN update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-9 100 18 | 19 | CMD ["bash"] 20 | 21 | RUN apt-get install sudo --assume-yes 22 | 23 | # Add dev-user 24 | RUN groupadd -g $GID dev-user 25 | RUN useradd -r -g $GID -u $UID -m -d /home/dev-user -s /sbin/nologin -c "User" dev-user 26 | RUN echo "dev-user ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers 27 | USER dev-user 28 | 29 | RUN echo 'PATH=$PATH:/workspace/llvm/build/bin:/workspace/build/bin' >> /home/dev-user/.bashrc 30 | RUN echo 'LD_LIBRARY_PATH=/workspace/build/pluto/lib:$LD_LIBRARY_PATH' >> /home/dev-user/.bashrc 31 | WORKDIR workspace 32 | -------------------------------------------------------------------------------- /tools/polymer/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Ruizhe Zhao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tools/polymer/cmake/AddPluto.cmake: -------------------------------------------------------------------------------- 1 | 2 | # execute_process( 3 | # COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/../build_pluto.sh" "${POLYGEIST_PLUTO_DIR}" 4 | # ) 5 | 6 | set(PLUTO_INCLUDE_DIR "${POLYGEIST_PLUTO_DIR}/pluto/install/include") 7 | set(PLUTO_LIB_DIR "${POLYGEIST_PLUTO_DIR}/pluto/install/lib") 8 | 9 | add_library(libpluto SHARED IMPORTED) 10 | set_target_properties(libpluto PROPERTIES IMPORTED_LOCATION "${PLUTO_LIB_DIR}/libpluto.so") 11 | add_library(libplutoosl SHARED IMPORTED) 12 | set_target_properties(libplutoosl PROPERTIES IMPORTED_LOCATION "${PLUTO_LIB_DIR}/libosl.so") 13 | add_library(libplutoisl SHARED IMPORTED) 14 | set_target_properties(libplutoisl PROPERTIES IMPORTED_LOCATION "${PLUTO_LIB_DIR}/libisl.so") 15 | add_library(libplutopip SHARED IMPORTED) 16 | set_target_properties(libplutopip PROPERTIES IMPORTED_LOCATION "${PLUTO_LIB_DIR}/libpiplib_dp.so") 17 | add_library(libplutopolylib SHARED IMPORTED) 18 | set_target_properties(libplutopolylib PROPERTIES IMPORTED_LOCATION "${PLUTO_LIB_DIR}/libpolylib64.so") 19 | add_library(libplutocloog SHARED IMPORTED) 20 | set_target_properties(libplutocloog PROPERTIES IMPORTED_LOCATION "${PLUTO_LIB_DIR}/libcloog-isl.so") 21 | add_library(libplutocandl STATIC IMPORTED) 22 | set_target_properties(libplutocandl PROPERTIES IMPORTED_LOCATION "${PLUTO_LIB_DIR}/libcandl.so") 23 | 24 | add_dependencies(libpluto pluto) 25 | add_dependencies(libplutoisl pluto) 26 | add_dependencies(libplutoosl pluto) 27 | add_dependencies(libplutopip pluto) 28 | add_dependencies(libplutopolylib pluto) 29 | add_dependencies(libplutocloog pluto) 30 | add_dependencies(libplutocandl pluto) 31 | -------------------------------------------------------------------------------- /tools/polymer/cmake/CLooG.cmake: -------------------------------------------------------------------------------- 1 | # Build CLooG from the source tree. 2 | 3 | include(ExternalProject) 4 | 5 | # ExternalProject_Add( 6 | # cloog 7 | # GIT_REPOSITORY https://github.com/kumasento/cloog.git 8 | # GIT_TAG 43CFB85ED1E1BA1C2F27B450498522B35467ACE7 9 | # CONFIGURE_COMMAND "./autogen.sh" && "./configure" --prefix=${CMAKE_CURRENT_BINARY_DIR}/cloog --with-osl-prefix="${CMAKE_CURRENT_BINARY_DIR}/openscop" 10 | # PREFIX ${CMAKE_CURRENT_BINARY_DIR}/cloog 11 | # BUILD_COMMAND make 12 | # INSTALL_COMMAND make install 13 | # BUILD_IN_SOURCE 1 14 | # BUILD_BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/cloog/lib/libcloog-isl.a" "${CMAKE_CURRENT_BINARY_DIR}/cloog/lib/libisl.a" 15 | # ) 16 | 17 | set(CLOOG_INCLUDE_DIR "${POLYGEIST_PLUTO_DIR}/cloog/install/include") 18 | set(CLOOG_LIB_DIR "${POLYGEIST_PLUTO_DIR}/cloog/install/lib") 19 | 20 | add_library(libcloog SHARED IMPORTED) 21 | set_target_properties(libcloog PROPERTIES IMPORTED_LOCATION "${CLOOG_LIB_DIR}/libcloog-isl.a") 22 | add_library(libisl SHARED IMPORTED) 23 | set_target_properties(libisl PROPERTIES IMPORTED_LOCATION "${CLOOG_LIB_DIR}/libisl.a") 24 | 25 | add_dependencies(libcloog cloog) 26 | add_dependencies(libisl cloog) 27 | -------------------------------------------------------------------------------- /tools/polymer/cmake/FindGMP.cmake: -------------------------------------------------------------------------------- 1 | set(GMP_PREFIX "" CACHE PATH "path ") 2 | 3 | find_path(GMP_INCLUDE_DIR gmp.h gmpxx.h 4 | PATHS ${GMP_PREFIX}/include /usr/include /usr/local/include ) 5 | 6 | find_library(GMP_LIBRARY NAMES gmp libgmp 7 | PATHS ${GMP_PREFIX}/lib /usr/lib /usr/local/lib) 8 | 9 | if(GMP_INCLUDE_DIR AND GMP_LIBRARY) 10 | get_filename_component(GMP_LIBRARY_DIR ${GMP_LIBRARY} PATH) 11 | set(GMP_FOUND TRUE) 12 | endif() 13 | 14 | if(GMP_FOUND) 15 | if(NOT GMP_FIND_QUIETLY) 16 | MESSAGE(STATUS "Found GMP: ${GMP_LIBRARY}") 17 | endif() 18 | elseif(GMP_FOUND) 19 | if(GMP_FIND_REQUIRED) 20 | message(FATAL_ERROR "Could not find GMP") 21 | endif() 22 | endif() 23 | -------------------------------------------------------------------------------- /tools/polymer/cmake/OpenScop.cmake: -------------------------------------------------------------------------------- 1 | # Install OpenScop as an external project. 2 | 3 | include(ExternalProject) 4 | 5 | # ExternalProject_Add( 6 | # osl 7 | # GIT_REPOSITORY https://github.com/periscop/openscop.git 8 | # GIT_TAG 37805d8fef38c2d1b8aa8f5c26b40f79100322e7 9 | # CONFIGURE_COMMAND "./autogen.sh" && "./configure" --prefix=${CMAKE_CURRENT_BINARY_DIR}/openscop 10 | # PREFIX ${CMAKE_CURRENT_BINARY_DIR}/openscop 11 | # BUILD_COMMAND make 12 | # INSTALL_COMMAND make install 13 | # BUILD_IN_SOURCE 1 14 | # BUILD_BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/openscop/lib/libosl.a" 15 | # ) 16 | 17 | set(OSL_INCLUDE_DIR "${POLYGEIST_PLUTO_DIR}/openscop/install/include") 18 | set(OSL_LIB_DIR "${POLYGEIST_PLUTO_DIR}/openscop/install/lib") 19 | 20 | add_library(libosl SHARED IMPORTED) 21 | set_target_properties(libosl PROPERTIES IMPORTED_LOCATION "${OSL_LIB_DIR}/libosl.a") 22 | add_dependencies(libosl osl) 23 | -------------------------------------------------------------------------------- /tools/polymer/docs/INSTALL_INDIVIDUALLY.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llvm/Polygeist/77c04bb2a7a2406ca9480bcc9e729b07d2c8d077/tools/polymer/docs/INSTALL_INDIVIDUALLY.md -------------------------------------------------------------------------------- /tools/polymer/docs/INSTALL_WITHIN_POLYGEIST.md: -------------------------------------------------------------------------------- 1 | # Install Polymer within Polygeist 2 | 3 | Polymer is now a part of [Polygeist](https://github.com/wsmoses/Polygeist), and our future work will be built on that basis. 4 | 5 | We have a [handy script](../scripts/build-with-polygeist.sh) that will clone Polygeist with the version given in [polygeist-version.txt](../polygeist-version.txt) to the upper-level directory, and symlink Polymer to its appropriate position in Polygeist (which should be `mlir/tools/polymer`). This will get around with the tedious submodule sync problem. 6 | 7 | To run it: 8 | 9 | ```sh 10 | # At the root directory of Polymer 11 | ./scripts/build-with-polygeist.sh 12 | ``` 13 | 14 | At the end of this script, `check-polymer` will be launched to perform the regression tests. 15 | 16 | Also, the `build` directory in the Polygeist project will be symlinked to the root of Polymer. You can access to all the binaries over there. 17 | -------------------------------------------------------------------------------- /tools/polymer/docs/WHY_NOT_SUBMODULE_LLVM.md: -------------------------------------------------------------------------------- 1 | # Why not have LLVM as a submodule to Polymer 2 | 3 | We used to have a LLVM submodule in Polymer, which kept track of the specific commit of LLVM that Polymer relies on. 4 | 5 | However, we're now moving Polymer as a project within Polygeist, doing so is practically not possible, due to the cyclic dependencies that might be introduced. 6 | 7 | Let's say, you have three git repos: 8 | 9 | * LLVM-1: the parent of Polymer, which keeps Polymer as its submodule. 10 | * POLYMER 11 | * LLVM-2: the llvm project as a submodule of Polymer. 12 | 13 | The directory structure would look like: 14 | 15 | ``` 16 | 17 | | 18 | +----> 19 | | 20 | +-----> 21 | ``` 22 | 23 | In another word, POLYMER is a submodule of LLVM-1, and LLVM-2 is a submodule 24 | of POLYMER. 25 | 26 | Suppose the versions of these repos are: 27 | 28 | * LLVM-1 is llvm@v1 29 | * POLYMER is polymer@v1 30 | * LLVM-2 is llvm@v0 31 | 32 | LLVM-1 and LLVM-2 are of two different versions of the same repo llvm, and normally LLVM-2 is older than LLVM-1. 33 | 34 | When you try to make LLVM-2 of the same version as LLVM-1, i.e., update LLVM-2 from llvm@v0 to llvm@v1, the version of POLYMER is changed as well, from polymer@v1 to polymer@v2, and consequently, LLVM-1 will be updated to llvm@v2. 35 | It unfortunately says that LLVM-2 can never catch up with LLVM-1. 36 | -------------------------------------------------------------------------------- /tools/polymer/example/flow: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # -------- A uniform script for compilation/evaluation/benchmark ------------ 4 | # 5 | # Usage: 6 | # 7 | # - Compilation 8 | # 9 | # ./flow compile polymer 10 | # ./flow compile pluto 11 | # 12 | # 13 | # 14 | 15 | set -o errexit 16 | set -o pipefail 17 | set -o nounset 18 | -------------------------------------------------------------------------------- /tools/polymer/example/handwritten/gemm.mlir: -------------------------------------------------------------------------------- 1 | #map = affine_map<()[s0] -> (s0)> 2 | 3 | func @gemm(%alpha: f32, %beta: f32, 4 | %C: memref, 5 | %A: memref, 6 | %B: memref) { 7 | %c0 = constant 0 : index 8 | %c1 = constant 1 : index 9 | %NI = dim %C, %c0 : memref 10 | %NJ = dim %C, %c1 : memref 11 | %NK = dim %A, %c1 : memref 12 | 13 | affine.for %i = 0 to #map()[%NI] { 14 | affine.for %j = 0 to #map()[%NJ] { 15 | %0 = affine.load %C[%i, %j] : memref 16 | %1 = mulf %0, %beta : f32 17 | affine.store %1, %C[%i, %j] : memref 18 | } 19 | 20 | affine.for %j = 0 to #map()[%NJ] { 21 | affine.for %k = 0 to #map()[%NK] { 22 | %2 = affine.load %A[%i, %k] : memref 23 | %3 = mulf %alpha, %2 : f32 24 | %4 = affine.load %B[%k, %j] : memref 25 | %5 = mulf %3, %4 : f32 26 | %6 = affine.load %C[%i, %j] : memref 27 | %7 = addf %6, %5 : f32 28 | affine.store %7, %C[%i, %j] : memref 29 | } 30 | } 31 | } 32 | return 33 | } 34 | -------------------------------------------------------------------------------- /tools/polymer/example/handwritten/jacobi-1d.mlir: -------------------------------------------------------------------------------- 1 | #map0 = affine_map<()[s0] -> (s0 - 1)> 2 | 3 | func @jacobi_1d(%A: memref, %B: memref, %T: index, %N: index) { 4 | affine.for %t = 0 to %T { 5 | affine.for %i = 2 to #map0()[%N] { 6 | %cst = constant 0.333333 : f32 7 | %0 = affine.load %A[%i - 1] : memref 8 | %1 = affine.load %A[%i] : memref 9 | %2 = affine.load %A[%i + 1] : memref 10 | %3 = addf %0, %1 : f32 11 | %4 = addf %2, %3 : f32 12 | %5 = mulf %cst, %4 : f32 13 | affine.store %5, %B[%i] : memref 14 | } 15 | 16 | affine.for %i = 2 to #map0()[%N] { 17 | %0 = affine.load %B[%i] : memref 18 | affine.store %0, %A[%i] : memref 19 | } 20 | } 21 | return 22 | } 23 | -------------------------------------------------------------------------------- /tools/polymer/example/handwritten/lu.mlir: -------------------------------------------------------------------------------- 1 | #map = affine_map<(d0) -> (d0)> 2 | module { 3 | func @kernel_lu(%arg0: i32, %arg1: memref<2000x2000xf64>) { 4 | %0 = index_cast %arg0 : i32 to index 5 | affine.for %arg2 = 0 to %0 { 6 | affine.for %arg3 = 0 to #map(%arg2) { 7 | %1 = affine.load %arg1[%arg2, %arg3] : memref<2000x2000xf64> 8 | affine.for %arg4 = 0 to #map(%arg3) { 9 | %5 = affine.load %arg1[%arg2, %arg4] : memref<2000x2000xf64> 10 | %6 = affine.load %arg1[%arg4, %arg3] : memref<2000x2000xf64> 11 | %7 = mulf %5, %6 : f64 12 | %8 = subf %1, %7 : f64 13 | affine.store %8, %arg1[%arg2, %arg3] : memref<2000x2000xf64> 14 | } 15 | %2 = affine.load %arg1[%arg3, %arg3] : memref<2000x2000xf64> 16 | %3 = affine.load %arg1[%arg2, %arg3] : memref<2000x2000xf64> 17 | %4 = divf %3, %2 : f64 18 | affine.store %4, %arg1[%arg2, %arg3] : memref<2000x2000xf64> 19 | } 20 | affine.for %arg3 = #map(%arg2) to %0 { 21 | %1 = affine.load %arg1[%arg2, %arg3] : memref<2000x2000xf64> 22 | affine.for %arg4 = 0 to #map(%arg2) { 23 | %2 = affine.load %arg1[%arg2, %arg4] : memref<2000x2000xf64> 24 | %3 = affine.load %arg1[%arg4, %arg3] : memref<2000x2000xf64> 25 | %4 = mulf %2, %3 : f64 26 | %5 = subf %1, %4 : f64 27 | affine.store %5, %arg1[%arg2, %arg3] : memref<2000x2000xf64> 28 | } 29 | } 30 | } 31 | return 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tools/polymer/example/handwritten/nussinov.pluto-par.mlir: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llvm/Polygeist/77c04bb2a7a2406ca9480bcc9e729b07d2c8d077/tools/polymer/example/handwritten/nussinov.pluto-par.mlir -------------------------------------------------------------------------------- /tools/polymer/example/handwritten/nussinov.pluto-par_llvm.mlir: -------------------------------------------------------------------------------- 1 | module attributes {llvm.data_layout = ""} { 2 | } 3 | 4 | -------------------------------------------------------------------------------- /tools/polymer/example/handwritten/nussinov.pluto.mlir: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llvm/Polygeist/77c04bb2a7a2406ca9480bcc9e729b07d2c8d077/tools/polymer/example/handwritten/nussinov.pluto.mlir -------------------------------------------------------------------------------- /tools/polymer/example/handwritten/nussinov.pluto_llvm.mlir: -------------------------------------------------------------------------------- 1 | module attributes {llvm.data_layout = ""} { 2 | } 3 | 4 | -------------------------------------------------------------------------------- /tools/polymer/example/handwritten/simple.mlir: -------------------------------------------------------------------------------- 1 | func @simple(%A: memref) { 2 | %c0 = constant 0 : index 3 | %c1 = constant 1 : index 4 | %N = dim %A, %c0: memref 5 | %M = dim %A, %c1: memref 6 | affine.for %i = 1 to %N { 7 | affine.for %j = 1 to %M { 8 | %0 = affine.load %A[%i - 1, %j] : memref 9 | %1 = affine.load %A[%i, %j - 1] : memref 10 | %2 = addf %0, %1: f32 11 | affine.store %2, %A[%i, %j]: memref 12 | } 13 | } 14 | return 15 | } 16 | -------------------------------------------------------------------------------- /tools/polymer/example/phism/simple.c: -------------------------------------------------------------------------------- 1 | void kernel(float A[64][64], int n) { 2 | int i, j; 3 | #pragma scop 4 | for (i = 1; i < n; i ++) { 5 | for (j = 1; j < n; j ++) { 6 | A[i][j] = A[i-1][j] + A[i][j-1]; 7 | } 8 | } 9 | #pragma endscop 10 | } 11 | 12 | void main() { 13 | int N = 64; 14 | float A[N][N]; 15 | 16 | kernel(A, N); 17 | } -------------------------------------------------------------------------------- /tools/polymer/example/phism/simple.mlir: -------------------------------------------------------------------------------- 1 | func @main() { 2 | %A = alloc() : memref<64x64xf32> 3 | %n = constant 64 : i32 4 | call @kernel(%A, %n): (memref<64x64xf32>, i32) -> () 5 | return 6 | } 7 | 8 | func @kernel(%A : memref<64x64xf32>, %n : i32) { 9 | %N = index_cast %n : i32 to index 10 | 11 | affine.for %i = 1 to %N { 12 | affine.for %j = 1 to %N { 13 | %0 = affine.load %A[%i - 1, %j] : memref<64x64xf32> 14 | %1 = affine.load %A[%i, %j - 1] : memref<64x64xf32> 15 | %2 = addf %0, %1 : f32 16 | affine.store %2, %A[%i, %j] : memref<64x64xf32> 17 | } 18 | } 19 | 20 | return 21 | } 22 | -------------------------------------------------------------------------------- /tools/polymer/example/polybench/compare_sched.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | def get_scheds(file): 4 | scheds = [] 5 | with open(file, 'r') as f: 6 | while True: 7 | line = f.readline() 8 | if not line: 9 | break 10 | if not line.startswith('T'): 11 | continue 12 | line = line.strip() 13 | 14 | # Process the schedule string 15 | sched = line.split(':')[1].strip() 16 | sched = sched[1:-1].split(',') 17 | sched = [s.strip() for s in sched] 18 | scheds.append(sched) 19 | return scheds 20 | 21 | def compare_sched(file1, file2): 22 | scheds1 = get_scheds(file1) 23 | scheds2 = get_scheds(file2) 24 | 25 | for sched1, sched2 in zip(scheds1, scheds2): 26 | if len(sched1) != len(sched2): 27 | return False 28 | 29 | imap = {} 30 | for i in range(len(sched1)): 31 | if sched1[i].isalpha(): 32 | imap[sched1[i]] = sched2[i] 33 | 34 | for i in range(len(sched1)): 35 | s1 = sched1[i] 36 | for k, v in imap.items(): 37 | s1 = s1.replace(k, v) 38 | if s1 != sched2[i]: 39 | return False 40 | 41 | return True 42 | -------------------------------------------------------------------------------- /tools/polymer/example/polybench/execute: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | SRC_FILE="$1" 4 | DST_FILE="$2" 5 | 6 | LLVM_BINDIR="${PWD}/../../llvm/build/bin" 7 | 8 | execute() 9 | { 10 | local MLIR_FILE="$1" 11 | local OUT_FILE="$2" 12 | 13 | # Run the compiled MLIR code by lli. 14 | "${LLVM_BINDIR}/mlir-opt" "${MLIR_FILE}" -lower-affine -convert-scf-to-std -canonicalize -convert-std-to-llvm |\ 15 | "${LLVM_BINDIR}/mlir-translate" -mlir-to-llvmir |\ 16 | "${LLVM_BINDIR}/opt" -O3 -march=native |\ 17 | "${LLVM_BINDIR}/lli" 2>&1 | tee "${OUT_FILE}" >/dev/null 18 | } 19 | 20 | execute "${SRC_FILE}" "src.out" 21 | 22 | if [ ! -z "${DST_FILE} " ]; then 23 | execute "${DST_FILE}" "dst.out" 24 | vimdiff "src.out" "dst.out" 25 | fi 26 | 27 | rm "src.out" "dst.out" 28 | -------------------------------------------------------------------------------- /tools/polymer/example/polybench/extract: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | MLIR_FILE="$1" 4 | BUILD_DIR="${PWD}/../../build" 5 | POLYMER_BINDIR="${BUILD_DIR}/bin" 6 | PLUTO_LIBDIR="${BUILD_DIR}/pluto/lib" 7 | 8 | cd ${BUILD_DIR} && ninja && cd - 9 | 10 | 11 | ${POLYMER_BINDIR}/polymer-opt "${MLIR_FILE}" \ 12 | -reg2mem \ 13 | -extract-scop-stmt \ 14 | -canonicalize \ 15 | -verify-each=1 16 | &> out-extract.log 17 | -------------------------------------------------------------------------------- /tools/polymer/example/polybench/find-splittable: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Get the number of splittable statements for mlir files under a given directory. 4 | 5 | 6 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)" 7 | BIN_DIR="${DIR}/../../build/bin" 8 | TMP_DIR="${DIR}/tmp" 9 | UTILITIES_DIR="${DIR}/utilities" 10 | 11 | export PATH="${BIN_DIR}:${PATH}" 12 | 13 | function annotate_splittable() { 14 | local SRC_FILE="$1" 15 | local TARGET_DIR="$2" 16 | local DST_FILE="${TARGET_DIR}/$(basename "${SRC_FILE}")" 17 | 18 | polymer-opt "${SRC_FILE}" -annotate-splittable | tee "${DST_FILE}" &>/dev/null 19 | 20 | local NUM_SPLITTABLE="$(grep "scop.splittable" "${DST_FILE}" | wc -l)" 21 | echo "$(basename "${SRC_FILE}"),${NUM_SPLITTABLE}" 22 | } 23 | 24 | SRC_FILES="$(find "$1" -type f -name "*.mlir")" 25 | 26 | 27 | WORK_DIR="${TMP_DIR}/splittable.$(date "+%Y%m%d-%H%M%S")" 28 | mkdir -p "${WORK_DIR}" 29 | 30 | for f in ${SRC_FILES}; do 31 | annotate_splittable "$f" "${WORK_DIR}" 32 | done 33 | -------------------------------------------------------------------------------- /tools/polymer/example/polybench/list_num_polyhedral_stmts: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for f in $(find "$1" -name "*.pluto.mlir" -type f); do 4 | file_name=$(basename "$f") 5 | kernel_name="kernel_${file_name/.pluto.mlir/}" 6 | 7 | echo "${kernel_name}","$(grep -o "func private @S" "$f" | wc -l)" 8 | done 9 | -------------------------------------------------------------------------------- /tools/polymer/example/polybench/opt: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | MLIR_FILE="$1" 4 | BUILD_DIR="${PWD}/../../build" 5 | POLYMER_BINDIR="${BUILD_DIR}/bin" 6 | PLUTO_LIBDIR="${BUILD_DIR}/pluto/lib" 7 | 8 | cd ${BUILD_DIR} && ninja && cd - 9 | 10 | 11 | ${POLYMER_BINDIR}/polymer-opt "${MLIR_FILE}" \ 12 | -reg2mem \ 13 | -extract-scop-stmt \ 14 | -canonicalize \ 15 | -pluto-opt \ 16 | -canonicalize \ 17 | -verify-each=1 \ 18 | -debug-only="extract-scop-stmt" \ 19 | 2>&1 | tee out.log >/dev/null 20 | 21 | -------------------------------------------------------------------------------- /tools/polymer/example/polybench/split-and-merge/.gitignore: -------------------------------------------------------------------------------- 1 | .outfilename 2 | .srcfilename 3 | .regtile 4 | 5 | !*.log 6 | -------------------------------------------------------------------------------- /tools/polymer/example/polybench/split-and-merge/README.md: -------------------------------------------------------------------------------- 1 | # Split and Merge Statements 2 | 3 | This directory contains examples that does statement splitting and merging. 4 | 5 | ## How to run? 6 | 7 | > Due to some recent updates, some of the scripts here may not work properly. We will update them later. 8 | 9 | ### Evaluate heuristic splitting 10 | 11 | ```sh 12 | ./eval-split-mlir-heuristic 2mm/2mm.c 13 | ./eval-split-mlir-heuristic 3mm/3mm.c 14 | ./eval-split-mlir-heuristic correlation/correlation.c 15 | ./eval-split-mlir-heuristic covariance/covariance.c 16 | ./eval-split-mlir-heuristic trmm/trmm.c 17 | ``` 18 | 19 | -------------------------------------------------------------------------------- /tools/polymer/example/polybench/split-and-merge/eval-split-c-batch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | for d in */; do 4 | dir="$(basename "${d}")" 5 | cd ${dir} 6 | for mode in "origin" "split"; do 7 | SRC_FILE="${dir}.${mode}.c" 8 | LOG_FILE="${dir}.pluto.${mode}.seq.log" 9 | $HOME/polymer/pluto/polycc --noparallel --nounrolljam --noprevector ${SRC_FILE} &> "$(basename "${LOG_FILE}")" 10 | 11 | LOG_FILE="${dir}.pluto.${mode}.par.log" 12 | $HOME/polymer/pluto/polycc --parallel --nounrolljam --noprevector ${SRC_FILE} &> "$(basename "${LOG_FILE}")" 13 | done 14 | cd - 15 | 16 | done 17 | -------------------------------------------------------------------------------- /tools/polymer/example/polybench/split-and-merge/eval-split-mlir-batch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ./eval-split-mlir 2mm 4 | ./eval-split-mlir 2mm 0 2 5 | ./eval-split-mlir 3mm 6 | ./eval-split-mlir 3mm 0 1 2 7 | ./eval-split-mlir correlation 8 | ./eval-split-mlir correlation 8 9 | ./eval-split-mlir covariance 10 | ./eval-split-mlir covariance 0 11 | ./eval-split-mlir gramschmidt 12 | ./eval-split-mlir gramschmidt 0 13 | -------------------------------------------------------------------------------- /tools/polymer/example/polybench/split-and-merge/eval-split-mlir-heuristic-batch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ./eval-split-mlir-heuristic 2mm/2mm.c 4 | ./eval-split-mlir-heuristic 3mm/3mm.c 5 | ./eval-split-mlir-heuristic correlation/correlation.c 6 | ./eval-split-mlir-heuristic covariance/covariance.c 7 | ./eval-split-mlir-heuristic trmm/trmm.c 8 | -------------------------------------------------------------------------------- /tools/polymer/include/polymer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(Transforms) 2 | -------------------------------------------------------------------------------- /tools/polymer/include/polymer/Support/OslSymbolTable.h: -------------------------------------------------------------------------------- 1 | //===- OslSymbolTable.h -----------------------------------------*- C++ -*-===// 2 | // 3 | // This file declares the OslSymbolTable class that stores the mapping between 4 | // symbols and MLIR values. 5 | // 6 | //===----------------------------------------------------------------------===// 7 | 8 | #include "mlir/Support/LLVM.h" 9 | #include "llvm/ADT/StringMap.h" 10 | 11 | using namespace llvm; 12 | using namespace mlir; 13 | 14 | namespace mlir { 15 | class Operation; 16 | class Value; 17 | } // namespace mlir 18 | 19 | namespace polymer { 20 | 21 | class ScopStmtOpSet; 22 | 23 | class PolymerSymbolTable { 24 | public: 25 | using OpSet = ScopStmtOpSet; 26 | using OpSetPtr = std::unique_ptr; 27 | 28 | enum SymbolType { LoopIV, Memref, StmtOpSet }; 29 | 30 | Value getValue(StringRef key); 31 | 32 | OpSet getOpSet(StringRef key); 33 | 34 | void setValue(StringRef key, Value val, SymbolType type); 35 | 36 | void setOpSet(StringRef key, OpSet val, SymbolType type); 37 | 38 | unsigned getNumValues(SymbolType type); 39 | 40 | unsigned getNumOpSets(SymbolType type); 41 | 42 | void getValueSymbols(SmallVectorImpl &symbols); 43 | 44 | void getOpSetSymbols(SmallVectorImpl &symbols); 45 | 46 | private: 47 | StringMap nameToStmtOpSet; 48 | StringMap nameToLoopIV; 49 | StringMap nameToMemref; 50 | }; 51 | 52 | } // namespace polymer 53 | -------------------------------------------------------------------------------- /tools/polymer/include/polymer/Support/PolymerUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef POLYMER_SUPPORT_POLYMERUTILS_H_ 2 | #define POLYMER_SUPPORT_POLYMERUTILS_H_ 3 | 4 | #include "mlir/Dialect/Affine/IR/AffineOps.h" 5 | #include "mlir/Dialect/Func/IR/FuncOps.h" 6 | 7 | namespace polymer { 8 | mlir::func::FuncOp islexternalTransform(mlir::func::FuncOp f, 9 | mlir::OpBuilder &rewriter); 10 | mlir::func::FuncOp plutoTransform(mlir::func::FuncOp f, 11 | mlir::OpBuilder &rewriter, 12 | std::string dumpClastAfterPluto, 13 | bool parallelize = false, bool debug = false, 14 | int cloogf = -1, int cloogl = -1, 15 | bool diamondTiling = false); 16 | unsigned extractScopStmt(mlir::func::FuncOp f, mlir::OpBuilder &b); 17 | void replaceUsesByStored(mlir::func::FuncOp f, mlir::OpBuilder &b); 18 | void separateAffineIfBlocks(mlir::func::FuncOp f, mlir::OpBuilder &b); 19 | void demoteRegisterToMemory(mlir::func::FuncOp f, mlir::OpBuilder &b); 20 | void dedupIndexCast(mlir::func::FuncOp f); 21 | void plutoParallelize(mlir::func::FuncOp f, mlir::OpBuilder b); 22 | void demoteLoopReduction(mlir::func::FuncOp f, mlir::OpBuilder &b); 23 | void demoteLoopReduction(mlir::func::FuncOp f, mlir::affine::AffineForOp forOp, 24 | mlir::OpBuilder &b); 25 | } // namespace polymer 26 | 27 | #endif // POLYMERUTILS_H_ 28 | -------------------------------------------------------------------------------- /tools/polymer/include/polymer/Support/ScatteringUtils.h: -------------------------------------------------------------------------------- 1 | //===- ScatteringUtils.h ----------------------------------------*- C++ -*-===// 2 | // 3 | // This file declares the C++ wrapper for the Scop scattering. 4 | // 5 | //===----------------------------------------------------------------------===// 6 | #ifndef POLYMER_SUPPORT_SCATTERINGUTILS_H 7 | #define POLYMER_SUPPORT_SCATTERINGUTILS_H 8 | 9 | #include 10 | 11 | #include "llvm/ADT/ArrayRef.h" 12 | #include "llvm/ADT/SmallVector.h" 13 | 14 | namespace mlir { 15 | class Value; 16 | class Operation; 17 | } // namespace mlir 18 | 19 | namespace polymer { 20 | 21 | class ScatTreeNodeImpl; 22 | 23 | /// Tree that holds scattering information. This node can represent an induction 24 | /// variable or a statement. A statement is constructed as a leaf node. 25 | class ScatTreeNode { 26 | public: 27 | ScatTreeNode(); 28 | ScatTreeNode(mlir::Value iv); 29 | 30 | ~ScatTreeNode(); 31 | 32 | ScatTreeNode(ScatTreeNode &&); 33 | ScatTreeNode(const ScatTreeNode &) = delete; 34 | ScatTreeNode &operator=(ScatTreeNode &&); 35 | ScatTreeNode &operator=(const ScatTreeNode &) = delete; 36 | 37 | void insertScopStmt(llvm::ArrayRef ops, 38 | llvm::SmallVectorImpl &scats); 39 | /// Get the depth of the tree starting from this node. 40 | unsigned getDepth() const; 41 | 42 | private: 43 | std::unique_ptr impl; 44 | }; 45 | 46 | } // namespace polymer 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /tools/polymer/include/polymer/Support/Utils.h: -------------------------------------------------------------------------------- 1 | //===- Utils.h --------------------------------------------------*- C++ -*-===// 2 | // 3 | // This file declares some generic utility functions. 4 | // 5 | //===----------------------------------------------------------------------===// 6 | 7 | #ifndef POLYMER_SUPPORT_UTILS_H 8 | #define POLYMER_SUPPORT_UTILS_H 9 | 10 | #include "llvm/ADT/SetVector.h" 11 | 12 | namespace mlir { 13 | class Block; 14 | class Value; 15 | } // namespace mlir 16 | 17 | namespace polymer { 18 | 19 | /// Find all the values that should be the arguments of the given block if it is 20 | /// not nested in the current scope. 21 | void inferBlockArgs(mlir::Block *block, llvm::SetVector &args); 22 | 23 | } // namespace polymer 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /tools/polymer/include/polymer/Target/ISL.h: -------------------------------------------------------------------------------- 1 | //===- OpenScop.h -----------------------------------------------*- C++ -*-===// 2 | // 3 | // This file declares the interfaces for converting OpenScop representation to 4 | // MLIR modules. 5 | // 6 | //===----------------------------------------------------------------------===// 7 | 8 | #ifndef POLYMER_TARGET_ISL_H 9 | #define POLYMER_TARGET_ISL_H 10 | 11 | #include 12 | 13 | #include "mlir/Dialect/Func/IR/FuncOps.h" 14 | #include "mlir/Support/LLVM.h" 15 | #include "llvm/ADT/DenseMap.h" 16 | #include "llvm/ADT/StringMap.h" 17 | 18 | namespace mlir { 19 | template class OwningOpRef; 20 | class MLIRContext; 21 | class ModuleOp; 22 | namespace func { 23 | class FuncOp; 24 | } 25 | struct LogicalResult; 26 | class Operation; 27 | class Value; 28 | } // namespace mlir 29 | 30 | struct isl_schedule; 31 | 32 | #define __isl_give 33 | 34 | namespace polymer { 35 | 36 | class IslScop; 37 | class PolymerSymbolTable; 38 | 39 | std::unique_ptr createIslFromFuncOp(mlir::func::FuncOp funcOp); 40 | 41 | /// Create a function (FuncOp) from the given OpenScop object in the given 42 | /// module (ModuleOp). 43 | mlir::func::FuncOp createFuncOpFromIsl(std::unique_ptr scop, 44 | mlir::func::FuncOp f, 45 | __isl_give isl_schedule *newSchedule); 46 | 47 | } // namespace polymer 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /tools/polymer/include/polymer/Transforms/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_TARGET_DEFINITIONS Passes.td) 2 | mlir_tablegen(Passes.h.inc -gen-pass-decls -name Transforms) 3 | add_public_tablegen_target(PolymerTransformsIncGen) 4 | -------------------------------------------------------------------------------- /tools/polymer/include/polymer/Transforms/ExtractScopStmt.h: -------------------------------------------------------------------------------- 1 | //===- ExtractScopStmt.h - Extract scop stmt to func ------------------C++-===// 2 | // 3 | // This file declares the transformation that extracts scop statements into MLIR 4 | // functions. 5 | // 6 | //===----------------------------------------------------------------------===// 7 | 8 | #ifndef POLYMER_TRANSFORMS_EXTRACTSCOPSTMT_H 9 | #define POLYMER_TRANSFORMS_EXTRACTSCOPSTMT_H 10 | 11 | #include "mlir/Pass/Pass.h" 12 | 13 | /// TODO: place this macro at the right position. 14 | #define SCOP_STMT_ATTR_NAME "scop.stmt" 15 | 16 | namespace polymer { 17 | void registerExtractScopStmtPass(); 18 | std::unique_ptr createExtractScopStmtPass(); 19 | } // namespace polymer 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /tools/polymer/include/polymer/Transforms/FoldSCFIf.h: -------------------------------------------------------------------------------- 1 | //===- FoldSCFIf.h - Fold scf.if into select --------------C++-===// 2 | 3 | #ifndef POLYMER_TRANSFORMS_FOLDSCFIF_H 4 | #define POLYMER_TRANSFORMS_FOLDSCFIF_H 5 | 6 | namespace polymer { 7 | void registerFoldSCFIfPass(); 8 | } 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /tools/polymer/include/polymer/Transforms/LoopAnnotate.h: -------------------------------------------------------------------------------- 1 | //===- LoopAnnotate.h - Annotate loop properties -----------------C++-===// 2 | 3 | #ifndef POLYMER_TRANSFORMS_LOOPANNOTATE_H 4 | #define POLYMER_TRANSFORMS_LOOPANNOTATE_H 5 | 6 | namespace polymer { 7 | 8 | void registerLoopAnnotatePasses(); 9 | 10 | } 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /tools/polymer/include/polymer/Transforms/LoopExtract.h: -------------------------------------------------------------------------------- 1 | //===- LoopExtract.h - Extract loops for partitioning --------------C++-===// 2 | 3 | #ifndef POLYMER_TRANSFORMS_LOOPEXTRACT_H 4 | #define POLYMER_TRANSFORMS_LOOPEXTRACT_H 5 | 6 | namespace polymer { 7 | 8 | void registerLoopExtractPasses(); 9 | 10 | } 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /tools/polymer/include/polymer/Transforms/Passes.h: -------------------------------------------------------------------------------- 1 | //===- Passes.h - Include Tblgen pass defs ------------C++-===// 2 | #ifndef POLYMER_TRANSFORMS_PASSES_H 3 | #define POLYMER_TRANSFORMS_PASSES_H 4 | 5 | #include "mlir/Dialect/Func/IR/FuncOps.h" 6 | #include "mlir/Pass/Pass.h" 7 | 8 | namespace mlir { 9 | class Pass; 10 | } // namespace mlir 11 | 12 | namespace polymer { 13 | 14 | std::unique_ptr createAnnotateScopPass(); 15 | 16 | /// Generate the code for registering passes. 17 | #define GEN_PASS_REGISTRATION 18 | #include "polymer/Transforms/Passes.h.inc" 19 | 20 | } // namespace polymer 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tools/polymer/include/polymer/Transforms/Passes.td: -------------------------------------------------------------------------------- 1 | #ifndef POLYMER_TRANSFORMS_PASSES 2 | #define POLYMER_TRANSFORMS_PASSES 3 | 4 | include "mlir/Pass/PassBase.td" 5 | include "mlir/Dialect/Func/IR/FuncOps.td" 6 | include "mlir/Rewrite/PassUtil.td" 7 | 8 | def AnnotateScop : Pass<"annotate-scop", "mlir::func::FuncOp"> { 9 | let summary = "Annotate scop.ignore to unselected functions."; 10 | let constructor = "polymer::createAnnotateScopPass()"; 11 | 12 | let options = [ 13 | ListOption< 14 | "includedFunctions", 15 | "functions", 16 | "std::string", 17 | "A list of functions to be included.", 18 | "llvm::cl::ZeroOrMore"> 19 | ]; 20 | } 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tools/polymer/include/polymer/Transforms/Reg2Mem.h: -------------------------------------------------------------------------------- 1 | //===- Reg2Mem.cc - reg2mem transformation --------------------------------===// 2 | // 3 | // This file declares the registration for the reg2mem transformation pass. 4 | // 5 | //===----------------------------------------------------------------------===// 6 | 7 | #include "mlir/Pass/Pass.h" 8 | 9 | namespace polymer { 10 | 11 | void registerRegToMemPass(); 12 | std::unique_ptr createRegToMemPass(); 13 | } // namespace polymer 14 | -------------------------------------------------------------------------------- /tools/polymer/include/polymer/Transforms/ScopStmtOpt.h: -------------------------------------------------------------------------------- 1 | //===- ScopStmtOpt.h - Optimise SCoP statement extraction -------------C++-===// 2 | 3 | #ifndef POLYMER_TRANSFORMS_SCOPSTMTOPT_H 4 | #define POLYMER_TRANSFORMS_SCOPSTMTOPT_H 5 | 6 | namespace polymer { 7 | 8 | void registerScopStmtOptPasses(); 9 | 10 | } 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /tools/polymer/lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(Support) 2 | add_subdirectory(Target) 3 | add_subdirectory(Transforms) 4 | -------------------------------------------------------------------------------- /tools/polymer/lib/Support/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(POLYGEIST_POLYMER_ENABLE_PLUTO) 2 | add_mlir_library(PolymerSupport 3 | OslScop.cc 4 | OslScopStmtOpSet.cc 5 | OslSymbolTable.cc 6 | ScopStmt.cc 7 | ScatteringUtils.cc 8 | Utils.cc 9 | 10 | DEPENDS 11 | mlir-headers 12 | 13 | ADDITIONAL_HEADERS 14 | ${POLYMER_MAIN_INCLUDE_DIR}/polymer/Support 15 | 16 | LINK_LIBS PUBLIC 17 | MLIRAnalysis 18 | MLIRAffineAnalysis 19 | 20 | # libosl 21 | libcloog 22 | # libisl 23 | libplutoisl 24 | libplutoosl 25 | libplutopip 26 | libplutopolylib 27 | libplutocloog 28 | libplutocandl 29 | libpluto 30 | ) 31 | elseif(POLYGEIST_POLYMER_ENABLE_ISL) 32 | add_mlir_library(PolymerSupport 33 | IslScop.cc 34 | ScopStmt.cc 35 | Utils.cc 36 | 37 | DEPENDS 38 | mlir-headers 39 | 40 | ADDITIONAL_HEADERS 41 | ${POLYMER_MAIN_INCLUDE_DIR}/polymer/Support 42 | 43 | LINK_LIBS PUBLIC 44 | MLIRAnalysis 45 | MLIRAffineAnalysis 46 | 47 | PollyISL 48 | Polly 49 | ) 50 | endif() 51 | 52 | target_link_libraries(PolymerSupport PUBLIC ${GMP_LIBRARY}) 53 | -------------------------------------------------------------------------------- /tools/polymer/lib/Target/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(POLYGEIST_POLYMER_ENABLE_PLUTO) 2 | add_mlir_translation_library(PolymerTargetOpenScop 3 | OpenScop/ConvertFromOpenScop.cc 4 | OpenScop/ConvertToOpenScop.cc 5 | 6 | ADDITIONAL_HEADER_DIRS 7 | ${POLYMER_MAIN_INCLUDE_DIR}/polymer/Target/OpenScop 8 | 9 | LINK_COMPONENTS 10 | Core 11 | TransformUtils 12 | 13 | LINK_LIBS PUBLIC 14 | MLIRIR 15 | MLIRAffineDialect 16 | MLIRAffineUtils 17 | MLIRSupport 18 | 19 | PolymerSupport 20 | ) 21 | elseif(POLYGEIST_POLYMER_ENABLE_ISL) 22 | add_mlir_translation_library(PolymerTargetISL 23 | ISL/ConvertToISL.cc 24 | 25 | ADDITIONAL_HEADER_DIRS 26 | ${POLYMER_MAIN_INCLUDE_DIR}/polymer/Target/ISL 27 | 28 | LINK_COMPONENTS 29 | Core 30 | TransformUtils 31 | 32 | LINK_LIBS PUBLIC 33 | MLIRIR 34 | MLIRAffineDialect 35 | MLIRAffineUtils 36 | MLIRSupport 37 | 38 | PolymerSupport 39 | ) 40 | endif() 41 | -------------------------------------------------------------------------------- /tools/polymer/lib/Transforms/AnnotateScop.cc: -------------------------------------------------------------------------------- 1 | //===- AnnotateScop.cc --------------------------------------*- C++ -*-===// 2 | 3 | #include "PassDetail.h" 4 | 5 | #include "mlir/Dialect/Affine/IR/AffineOps.h" 6 | #include "mlir/Dialect/Affine/LoopUtils.h" 7 | #include "mlir/Dialect/MemRef/IR/MemRef.h" 8 | #include "mlir/Dialect/SCF/IR/SCF.h" 9 | #include "mlir/Transforms/Passes.h" 10 | #include "mlir/Transforms/RegionUtils.h" 11 | #include "llvm/Support/Debug.h" 12 | 13 | using namespace mlir; 14 | using namespace llvm; 15 | using namespace polymer; 16 | 17 | namespace { 18 | struct AnnotateScop : public polymer::AnnotateScopBase { 19 | void runOnOperation() override { 20 | func::FuncOp f = getOperation(); 21 | OpBuilder b(f.getContext()); 22 | 23 | for (auto &name : includedFunctions) 24 | if (name == f.getName()) 25 | return; 26 | 27 | f->setAttr("scop.ignored", b.getUnitAttr()); 28 | } // namespace 29 | }; 30 | } // namespace 31 | 32 | std::unique_ptr polymer::createAnnotateScopPass() { 33 | return std::make_unique(); 34 | } 35 | -------------------------------------------------------------------------------- /tools/polymer/lib/Transforms/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | if(POLYGEIST_POLYMER_ENABLE_PLUTO) 3 | set(POLYMER_TRANSFORM_SRC 4 | PlutoTransform.cc 5 | ) 6 | elseif(POLYGEIST_POLYMER_ENABLE_ISL) 7 | set(POLYMER_TRANSFORM_SRC 8 | IslExternalTransform.cc 9 | ) 10 | endif() 11 | 12 | add_mlir_conversion_library(PolymerTransforms 13 | Reg2Mem.cc 14 | ExtractScopStmt.cc 15 | ScopStmtOpt.cc 16 | LoopAnnotate.cc 17 | LoopExtract.cc 18 | FoldSCFIf.cc 19 | AnnotateScop.cc 20 | "${POLYMER_TRANSFORM_SRC}" 21 | 22 | ADDITIONAL_HEADER_DIRS 23 | "${POLYMER_MAIN_INCLUDE_DIR}/polymer/Transforms" 24 | 25 | DEPENDS 26 | PolymerTransformsIncGen 27 | 28 | LINK_LIBS PUBLIC 29 | MLIRAffineDialect 30 | MLIRAnalysis 31 | MLIRPass 32 | MLIRTransforms 33 | MLIRTransformUtils 34 | MLIRIR 35 | MLIRFuncDialect 36 | MLIRSupport 37 | MLIRAffineToStandard 38 | MLIRAffineTransforms 39 | 40 | PolymerSupport 41 | "${POLYMER_AVAIL_TARGETS}" 42 | ) 43 | -------------------------------------------------------------------------------- /tools/polymer/lib/Transforms/PassDetail.h: -------------------------------------------------------------------------------- 1 | //===- PassDetail.h - Transforms Pass class details -------------*- C++ -*-===// 2 | 3 | #ifndef POLYMER_TRANSFORMS_PASSDETAIL_H_ 4 | #define POLYMER_TRANSFORMS_PASSDETAIL_H_ 5 | 6 | #include "mlir/Pass/Pass.h" 7 | #include "polymer/Transforms/Passes.h" 8 | 9 | namespace polymer { 10 | #define GEN_PASS_CLASSES 11 | #include "polymer/Transforms/Passes.h.inc" 12 | } // namespace polymer 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /tools/polymer/polygeist-version.txt: -------------------------------------------------------------------------------- 1 | 6ba6b7b8ac07c9d60994eb46b46682a9f76ea34e 2 | -------------------------------------------------------------------------------- /tools/polymer/resources/polymer.bib: -------------------------------------------------------------------------------- 1 | @inproceedings{polygeist, 2 | title={Polygeist: Affine C in MLIR}, 3 | author={Moses, William S and Chelini, Lorenzo and Zhao, Ruizhe and Zinenko, Oleksandr}, 4 | booktitle={{IMPACT}}, 5 | year={2021} 6 | } 7 | @article{phism, 8 | title={Phism: Polyhedral High-Level Synthesis in MLIR}, 9 | author={Zhao, Ruizhe and Cheng, Jianyi}, 10 | journal={arXiv preprint arXiv:2103.15103}, 11 | year={2021} 12 | } 13 | @inproceedings{50565, 14 | title = {Polygeist: Raising C to Polyhedral MLIR}, 15 | author = {William S. Moses and Lorenzo Chelini and Ruizhe Zhao and Oleksandr Zinenko}, 16 | year = {2021}, 17 | booktitle = {{PACT}} 18 | } 19 | 20 | -------------------------------------------------------------------------------- /tools/polymer/scripts/update-pluto.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Sync pluto as a submodule. 3 | 4 | set -o errexit 5 | set -o pipefail 6 | set -o nounset 7 | 8 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)" 9 | POLYMER_ROOT="${DIR}/../" 10 | 11 | cd "${POLYMER_ROOT}" 12 | git submodule sync 13 | git submodule update --init --recursive "${POLYMER_ROOT}/pluto" 14 | cd - &>/dev/null 15 | -------------------------------------------------------------------------------- /tools/polymer/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | configure_lit_site_cfg( 2 | "${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in" 3 | "${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py" 4 | MAIN_CONFIG 5 | "${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py" 6 | ) 7 | 8 | if(POLYGEIST_POLYMER_ENABLE_PLUTO) 9 | set(POLYMER_TEST_DEPENDS 10 | FileCheck count not 11 | polymer-translate 12 | polymer-opt 13 | ) 14 | elseif(POLYGEIST_POLYMER_ENABLE_ISL) 15 | set(POLYMER_TEST_DEPENDS 16 | FileCheck count not 17 | polymer-opt 18 | ) 19 | endif() 20 | 21 | add_lit_testsuite(check-polymer "Running the Polymer regression tests" 22 | ${CMAKE_CURRENT_BINARY_DIR} 23 | DEPENDS ${POLYMER_TEST_DEPENDS} 24 | ) 25 | set_target_properties(check-polymer PROPERTIES FOLDER "Tests") 26 | 27 | add_lit_testsuites(POLYMER ${CMAKE_CURRENT_SOURCE_DIR} 28 | DEPENDS ${POLYMER_TEST_DEPS} 29 | ) 30 | -------------------------------------------------------------------------------- /tools/polymer/test/archive/PlutoTransform/empty.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -pluto-opt | FileCheck %s 2 | 3 | func @empty() { 4 | return 5 | } 6 | 7 | // CHECK: func @empty() { 8 | // CHECK-NEXT: return 9 | // CHECK-NEXT: } 10 | -------------------------------------------------------------------------------- /tools/polymer/test/archive/PlutoTransform/load-store.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -pluto-opt | FileCheck %s 2 | 3 | // Test whether a load-store pair can be optimized. 4 | 5 | func @load_store() -> () { 6 | %A = alloc() : memref<64xf32> 7 | affine.for %i = 0 to 64 { 8 | %0 = affine.load %A[%i] : memref<64xf32> 9 | affine.store %0, %A[%i] : memref<64xf32> 10 | } 11 | return 12 | } 13 | 14 | 15 | // CHECK-DAG: #[[MAP0:.*]] = affine_map<(d0) -> (d0 * 32)> 16 | // CHECK-DAG: #[[MAP1:.*]] = affine_map<(d0) -> (d0 * 32 + 32)> 17 | // 18 | // 19 | // CHECK: func @main(%[[ARG0:.*]]: memref) { 20 | // CHECK-NEXT: affine.for %[[ARG1:.*]] = 0 to 2 { 21 | // CHECK-NEXT: affine.for %[[ARG2:.*]] = #[[MAP0]](%[[ARG1]]) to #[[MAP1]](%[[ARG1]]) { 22 | // CHECK-NEXT: %[[VAL0:.*]] = affine.load %[[ARG0]][%[[ARG2]]] : memref 23 | // CHECK-NEXT: affine.store %[[VAL0]], %[[ARG0]][%[[ARG2]]] : memref 24 | // CHECK-NEXT: } 25 | // CHECK-NEXT: } 26 | // CHECK-NEXT: return 27 | // CHECK-NEXT: } 28 | -------------------------------------------------------------------------------- /tools/polymer/test/archive/polymer-translate/export-and-import/matmul.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-translate %s -export-scop | polymer-translate -import-scop | FileCheck %s 2 | 3 | func @matmul() { 4 | %A = alloc() : memref<64x64xf32> 5 | %B = alloc() : memref<64x64xf32> 6 | %C = alloc() : memref<64x64xf32> 7 | 8 | affine.for %i = 0 to 64 { 9 | affine.for %j = 0 to 64 { 10 | affine.for %k = 0 to 64 { 11 | %0 = affine.load %A[%i, %k] : memref<64x64xf32> 12 | %1 = affine.load %B[%k, %j] : memref<64x64xf32> 13 | %2 = mulf %0, %1 : f32 14 | %3 = affine.load %C[%i, %j] : memref<64x64xf32> 15 | %4 = addf %2, %3 : f32 16 | affine.store %4, %C[%i, %j] : memref<64x64xf32> 17 | } 18 | } 19 | } 20 | 21 | return 22 | } 23 | 24 | // CHECK: func @main(%[[ARG0:.*]]: memref, %[[ARG1:.*]]: memref, %[[ARG2:.*]]: memref) { 25 | // CHECK-NEXT: affine.for %[[ARG3:.*]] = 0 to 64 { 26 | // CHECK-NEXT: affine.for %[[ARG4:.*]] = 0 to 64 { 27 | // CHECK-NEXT: affine.for %[[ARG5:.*]] = 0 to 64 { 28 | // CHECK-NEXT: func.call @S0(%[[ARG0]], %[[ARG1]], %[[ARG2]], %[[ARG0]], %[[ARG3]], %[[ARG4]], %[[ARG5]]) : (memref, memref, memref, memref, index, index, index) -> () 29 | // CHECK-NEXT: } 30 | // CHECK-NEXT: } 31 | // CHECK-NEXT: } 32 | // CHECK-NEXT: return 33 | // CHECK-NEXT: } 34 | // CHECK: func private @S0(memref, memref, memref, memref, index, index, index) 35 | -------------------------------------------------------------------------------- /tools/polymer/test/archive/polymer-translate/import-scop/empty.scop: -------------------------------------------------------------------------------- 1 | // RUN: polymer-translate %s -import-scop | FileCheck %s 2 | 3 | 4 | 5 | # =============================================== Global 6 | # Language 7 | C 8 | 9 | # Context 10 | CONTEXT 11 | 0 2 0 0 0 0 12 | 13 | # Parameter names are not provided 14 | 0 15 | 16 | # One statement 17 | 1 18 | 19 | # =============================================== Statement 1 20 | # Number of relations describing the statement 21 | 0 22 | 23 | # ---------------------------------------------- 1.1 Domain 24 | # NULL Domain 25 | 26 | # ---------------------------------------------- 1.2 Scattering 27 | # NULL Scattering 28 | 29 | # ---------------------------------------------- 1.3 Access 30 | # NULL Access 31 | 32 | # ---------------------------------------------- 1.4 Body 33 | # Statement body is not provided 34 | 0 35 | 36 | 37 | 38 | // CHECK: module { 39 | // CHECK: func @main() { 40 | // CHECK: return 41 | // CHECK: } 42 | // CHECK: } 43 | -------------------------------------------------------------------------------- /tools/polymer/test/lit.site.cfg.py.in: -------------------------------------------------------------------------------- 1 | @LIT_SITE_CFG_IN_HEADER@ 2 | 3 | config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" 4 | config.polymer_obj_root = "@POLYMER_BINARY_DIR@" 5 | config.polymer_tools_dir = "@POLYMER_TOOLS_DIR@" 6 | config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" 7 | config.target_triple = "@TARGET_TRIPLE@" 8 | 9 | # Support substitution of the tools and build_mode with user parameters. 10 | # This is used when we can't determine the tool dir at configuration time. 11 | try: 12 | config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params 13 | config.polymer_tools_dir = config.polymer_tools_dir % lit_config.params 14 | except KeyError as e: 15 | key, = e.args 16 | lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) 17 | 18 | import lit.llvm 19 | lit.llvm.initialize(lit_config, config) 20 | 21 | # Let the main config do the real work. 22 | lit_config.load_config(config, "@POLYMER_SOURCE_DIR@/test/lit.cfg.py") 23 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/AnnotateScop/annotate-single.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -annotate-scop="functions=foo" | FileCheck %s 2 | 3 | func.func @foo() { 4 | return 5 | } 6 | 7 | func.func @bar() { 8 | return 9 | } 10 | 11 | // CHECK: func.func @foo() { 12 | // CHECK: func.func @bar() attributes {scop.ignored} { 13 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/ExtractScopStmt/internal-index-cast.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -extract-scop-stmt | FileCheck %s 2 | 3 | func.func @foo(%A: memref<1024xi32>, %B: memref<1024x16xi32>) { 4 | %c4_i32 = arith.constant 4 : i32 5 | %c15_i32 = arith.constant 15 : i32 6 | 7 | affine.for %i = 1 to 5 { 8 | affine.for %j = 0 to 16 { 9 | %1 = affine.load %A[%j * 4] : memref<1024xi32> 10 | %2 = arith.shrsi %1, %c4_i32 : i32 11 | %3 = arith.index_cast %2 : i32 to index 12 | %4 = arith.andi %1, %c15_i32 : i32 13 | %5 = arith.index_cast %4 : i32 to index 14 | %6 = memref.load %B[%3, %5] : memref<1024x16xi32> 15 | affine.store %6, %A[%j * 4] : memref<1024xi32> 16 | } 17 | } 18 | 19 | return 20 | } 21 | 22 | // CHECK: func.func private @S0 23 | // CHECK: %{{.*}} = affine.load 24 | // CHECK-NEXT: %{{.*}} = arith.shrsi 25 | // CHECK-NEXT: %{{.*}} = arith.index_cast 26 | // CHECK-NEXT: %{{.*}} = arith.andi 27 | // CHECK-NEXT: %{{.*}} = arith.index_cast 28 | // CHECK-NEXT: %{{.*}} = memref.load 29 | // CHECK-NEXT: affine.store 30 | 31 | // CHECK: func.func @foo(%[[ARG0:.*]]: memref<1024xi32>, %[[ARG1:.*]]: memref<1024x16xi32>) 32 | // CHECK-NEXT: affine.for %[[I:.*]] = 1 to 5 33 | // CHECK-NEXT: affine.for %[[J:.*]] = 0 to 16 34 | // CHECK-NEXT: func.call @S0(%[[ARG0]], %[[J]], %[[ARG1]]) 35 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/ExtractScopStmt/no-loop-blockarg.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -extract-scop-stmt | FileCheck %s 2 | 3 | func.func @no_loop_blockarg(%A: memref<1xf32>, %a: f32) { 4 | affine.store %a, %A[0] : memref<1xf32> 5 | return 6 | } 7 | 8 | // CHECK: func.func private @S0(%[[a:.*]]: f32, %[[A:.*]]: memref<1xf32>) attributes {scop.stmt} 9 | // CHECK-NEXT: affine.store %[[a]], %[[A]][0] 10 | 11 | // CHECK: func.func @no_loop_blockarg(%[[A:.*]]: memref<1xf32>, %[[a:.*]]: f32) 12 | // CHECK-NEXT: call @S0(%[[a]], %[[A]]) : (f32, memref<1xf32>) -> () 13 | 14 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/ExtractScopStmt/no-loop-non-affine.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -extract-scop-stmt | FileCheck %s 2 | 3 | func.func @foo(%A: memref<1xf32>) { 4 | %0 = arith.constant 1.23 : f32 5 | %c0 = arith.constant 0 : index 6 | memref.store %0, %A[%c0] : memref<1xf32> 7 | return 8 | } 9 | 10 | // CHECK-LABEL: func.func @foo 11 | // CHECK-NEXT: %{{.*}} = arith.constant 12 | // CHECK-NEXT: %{{.*}} = arith.constant 13 | // CHECK-NEXT: memref.store 14 | // CHECK-NEXT: return 15 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/ExtractScopStmt/no-loop.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -extract-scop-stmt | FileCheck %s 2 | 3 | func.func @no_loop(%A: memref<1xf32>) { 4 | %0 = arith.constant 1.23 : f32 5 | affine.store %0, %A[0] : memref<1xf32> 6 | return 7 | } 8 | 9 | // CHECK: func.func private @S0(%[[A:.*]]: memref<1xf32>) attributes {scop.stmt} 10 | // CHECK-NEXT: %[[CST:.*]] = arith.constant 1.23 11 | // CHECK-NEXT: affine.store %[[CST]], %[[A]][0] 12 | 13 | // CHECK: func.func @no_loop(%[[A:.*]]: memref<1xf32>) 14 | // CHECK-NEXT: call @S0(%[[A]]) : (memref<1xf32>) -> () 15 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/ExtractScopStmt/scratchpad-dom-store-diff-mem.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -extract-scop-stmt | FileCheck %s 2 | 3 | // There should be no scratchpad inserted. 4 | func.func @foo(%A: memref<1xf32>, %B: memref<1xf32>) { 5 | %c0 = arith.constant 0 : index 6 | %0 = affine.load %A[0] : memref<1xf32> 7 | affine.store %0, %B[0] : memref<1xf32> 8 | affine.store %0, %A[0] : memref<1xf32> 9 | return 10 | } 11 | 12 | // CHECK: func.func @foo(%[[A:.*]]: memref<1xf32>, %[[B:.*]]: memref<1xf32>) 13 | // CHECK-NEXT: call @S0(%[[B]], %[[A]]) 14 | // CHECK-NEXT: call @S1(%[[A]]) 15 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/ExtractScopStmt/scratchpad-dom-store-same-mem.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -extract-scop-stmt | FileCheck %s 2 | 3 | func.func @foo(%A: memref<1xf32>) { 4 | %c0 = arith.constant 0 : index 5 | %0 = affine.load %A[0] : memref<1xf32> 6 | affine.store %0, %A[0] : memref<1xf32> 7 | affine.store %0, %A[0] : memref<1xf32> 8 | return 9 | } 10 | 11 | // CHECK: func.func private @S0(%[[A:.*]]: memref<1xf32>, %[[SCRATCHPAD:.*]]: memref<1xf32>) 12 | // CHECK-NEXT: %[[VAL0:.*]] = affine.load %[[A]][0] 13 | // CHECK-NEXT: affine.store %[[VAL0]], %[[SCRATCHPAD]][0] 14 | // CHECK-NEXT: affine.store %[[VAL0]], %[[A]][0] 15 | 16 | // CHECK: func.func private @S1(%[[A:.*]]: memref<1xf32>, %[[SCRATCHPAD:.*]]: memref<1xf32>) 17 | // CHECK-NEXT: %[[VAL0:.*]] = affine.load %[[SCRATCHPAD]][0] 18 | // CHECK-NEXT: affine.store %[[VAL0]], %[[A]][0] 19 | 20 | // CHECK: func.func @foo(%[[A:.*]]: memref<1xf32>) 21 | // CHECK-NEXT: %[[SCRATCHPAD:.*]] = memref.alloca() : memref<1xf32> 22 | // CHECK-NEXT: call @S0(%[[A]], %[[SCRATCHPAD]]) 23 | // CHECK-NEXT: call @S1(%[[A]], %[[SCRATCHPAD]]) 24 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/FoldSCFIf/match-store-addr.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -fold-scf-if | FileCheck %s 2 | 3 | func.func @foo(%A: memref<10xf32>, %i: index, %a: f32, %b: f32, %cond: i1) { 4 | scf.if %cond { 5 | affine.store %a, %A[%i] : memref<10xf32> 6 | } else { 7 | affine.store %b, %A[%i] : memref<10xf32> 8 | } 9 | 10 | return 11 | } 12 | 13 | // CHECK: func.func @foo(%[[A:.*]]: memref<10xf32>, %[[i:.*]]: index, %[[a:.*]]: f32, %[[b:.*]]: f32, %[[cond:.*]]: i1) 14 | // CHECK-NEXT: %[[v0:.*]] = arith.select %[[cond]], %[[a]], %[[b]] : f32 15 | // CHECK-NEXT: affine.store %[[v0]], %[[A]][%[[i]]] : memref<10xf32> 16 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/FoldSCFIf/match-store-diff-mem.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -fold-scf-if | FileCheck %s 2 | 3 | func.func @foo(%A: memref<10xf32>, %B: memref<10xf32>, %a: f32, %b: f32, %cond: i1) { 4 | scf.if %cond { 5 | affine.store %a, %A[0] : memref<10xf32> 6 | } else { 7 | affine.store %b, %B[0] : memref<10xf32> 8 | } 9 | return 10 | } 11 | 12 | // CHECK: func.func @foo(%[[A:.*]]: memref<10xf32>, %[[B:.*]]: memref<10xf32>, %[[a:.*]]: f32, %[[b:.*]]: f32, %[[cond:.*]]: i1) 13 | // CHECK-NEXT: %[[v0:.*]] = affine.load %[[B]][0] : memref<10xf32> 14 | // CHECK-NEXT: %[[v1:.*]] = affine.load %[[A]][0] : memref<10xf32> 15 | // CHECK-NEXT: %[[v2:.*]] = arith.select %[[cond]], %[[a]], %[[v1]] : f32 16 | // CHECK-NEXT: %[[v3:.*]] = arith.select %[[cond]], %[[v0]], %[[b]] : f32 17 | // CHECK-NEXT: affine.store %[[v2]], %[[A]][0] : memref<10xf32> 18 | // CHECK-NEXT: affine.store %[[v3]], %[[B]][0] : memref<10xf32> 19 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/FoldSCFIf/match-store-no-else.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -fold-scf-if | FileCheck %s 2 | 3 | func.func @foo(%A: memref<10xf32>, %a: f32, %cond: i1) { 4 | scf.if %cond { 5 | affine.store %a, %A[0] : memref<10xf32> 6 | } 7 | return 8 | } 9 | 10 | // CHECK: func.func @foo(%[[A:.*]]: memref<10xf32>, %[[a:.*]]: f32, %[[cond:.*]]: i1) 11 | // CHECK-NEXT: %[[v0:.*]] = affine.load %[[A]][0] : memref<10xf32> 12 | // CHECK-NEXT: %[[v1:.*]] = arith.select %[[cond]], %[[a]], %[[v0]] : f32 13 | // CHECK-NEXT: affine.store %[[v1]], %[[A]][0] : memref<10xf32> 14 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/FoldSCFIf/match-store.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -fold-scf-if | FileCheck %s 2 | 3 | func.func @foo(%A: memref<10xf32>, %a: f32, %b: f32, %cond: i1) { 4 | scf.if %cond { 5 | affine.store %a, %A[0] : memref<10xf32> 6 | } else { 7 | affine.store %b, %A[0] : memref<10xf32> 8 | } 9 | return 10 | } 11 | 12 | // CHECK: func.func @foo(%[[A:.*]]: memref<10xf32>, %[[a:.*]]: f32, %[[b:.*]]: f32, %[[cond:.*]]: i1) 13 | // CHECK-NEXT: %[[v0:.*]] = arith.select %[[cond]], %[[a]], %[[b]] : f32 14 | // CHECK-NEXT: affine.store %[[v0]], %[[A]][0] : memref<10xf32> 15 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/FoldSCFIf/no-result-no-else.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -fold-scf-if | FileCheck %s 2 | 3 | func.func @foo(%a: f32, %b: f32, %c: i1) { 4 | scf.if %c { 5 | %0 = arith.addf %a, %b : f32 6 | } 7 | return 8 | } 9 | 10 | // CHECK: func.func @foo 11 | // CHECK-NEXT: arith.addf 12 | // CHECK-NEXT: return 13 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/FoldSCFIf/no-result.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -fold-scf-if | FileCheck %s 2 | func.func @foo(%a: f32, %b: f32, %c: i1) { 3 | scf.if %c { 4 | %0 = arith.addf %a, %b : f32 5 | } else { 6 | %0 = arith.mulf %a, %b : f32 7 | } 8 | 9 | return 10 | } 11 | 12 | // CHECK: func.func @foo 13 | // CHECK-NEXT: arith.addf 14 | // CHECK-NEXT: arith.mulf 15 | // CHECK-NEXT: return 16 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/FoldSCFIf/pure-arith-multi-if.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -fold-scf-if | FileCheck %s 2 | 3 | func.func @foo(%a: f32, %b: f32, %c: i1, %d: i1) -> f32 { 4 | %0 = scf.if %c -> f32 { 5 | %0 = scf.if %d -> f32 { 6 | scf.yield %a : f32 7 | } else { 8 | scf.yield %b : f32 9 | } 10 | %1 = arith.addf %0, %b : f32 11 | scf.yield %1 : f32 12 | } else { 13 | %1 = arith.mulf %a, %b : f32 14 | scf.yield %1 : f32 15 | } 16 | return %0 : f32 17 | } 18 | 19 | // CHECK: func.func @foo(%[[a:.*]]: f32, %[[b:.*]]: f32, %[[c:.*]]: i1, %[[d:.*]]: i1) -> f32 20 | // CHECK-NEXT: %[[v0:.*]] = arith.select %[[d]], %[[a]], %[[b]] : f32 21 | // CHECK-NEXT: %[[v1:.*]] = arith.addf %[[v0]], %[[b]] : f32 22 | // CHECK-NEXT: %[[v2:.*]] = arith.mulf %[[a]], %[[b]] : f32 23 | // CHECK-NEXT: %[[v3:.*]] = arith.select %[[c]], %[[v1]], %[[v2]] : f32 24 | // CHECK-NEXT: return %[[v3]] : f32 25 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/FoldSCFIf/pure-arith-single-if.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -fold-scf-if | FileCheck %s 2 | 3 | func.func @foo(%a: f32, %b: f32, %c: i1) -> f32 { 4 | %0 = scf.if %c -> f32 { 5 | %1 = arith.addf %a, %b : f32 6 | scf.yield %1 : f32 7 | } else { 8 | %1 = arith.mulf %a, %b : f32 9 | scf.yield %1 : f32 10 | } 11 | return %0 : f32 12 | } 13 | 14 | // CHECK: func.func @foo(%[[a:.*]]: f32, %[[b:.*]]: f32, %[[c:.*]]: i1) -> f32 15 | // CHECK-NEXT: %[[v0:.*]] = arith.addf %[[a]], %[[b]] : f32 16 | // CHECK-NEXT: %[[v1:.*]] = arith.mulf %[[a]], %[[b]] : f32 17 | // CHECK-NEXT: %[[v2:.*]] = arith.select %[[c]], %[[v0]], %[[v1]] : f32 18 | // CHECK-NEXT: return %[[v2]] : f32 19 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/PlutoTransforms/const-loop-bounds.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -reg2mem -extract-scop-stmt -pluto-opt | FileCheck %s 2 | 3 | func.func @const_loop_bounds(%A: memref<64xf32>) { 4 | affine.for %i = 0 to 64 { 5 | %0 = affine.load %A[%i] : memref<64xf32> 6 | %1 = arith.addf %0, %0 : f32 7 | affine.store %1, %A[%i] : memref<64xf32> 8 | } 9 | 10 | return 11 | } 12 | 13 | // CHECK-LABEL: @const_loop_bounds 14 | // CHECK: affine.for %[[ARG1:.*]] = 0 to 2 15 | // CHECK: affine.for %[[ARG2:.*]] = #[[MAP0:.*]](%[[ARG1]]) to #[[MAP1:.*]](%[[ARG1]]) 16 | // CHECK: func.call @[[S0:.*]](%[[ARG0:.*]], %[[ARG2]]) 17 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/PlutoTransforms/subindex.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -pluto-opt | FileCheck %s 2 | 3 | 4 | func.func @S0(%A: memref<10x60xf32>, %i: index, %j: index) attributes {scop.stmt} { 5 | %cst = arith.constant 3.14 : f32 6 | affine.store %cst, %A[%i, %j] : memref<10x60xf32> 7 | return 8 | } 9 | 10 | func.func @foo(%A: memref<10x60xf32>, %i: index) { 11 | affine.for %j = 0 to 60 { 12 | func.call @S0(%A, %i, %j): (memref<10x60xf32>, index, index) -> () 13 | } 14 | return 15 | } 16 | 17 | // CHECK: func.func @foo(%[[A:.*]]: memref<{{.*}}>, %[[i:.*]]: index) 18 | // CHECK-NEXT: affine.for 19 | // CHECK-NEXT: affine.for %[[j:.*]] = 20 | // CHECK-NEXT: func.call @S0(%[[A]], %[[i]], %[[j]]) 21 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/PlutoTransforms/swapped-bounds.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -pluto-opt | FileCheck %s 2 | func.func private @S0() attributes {scop.stmt} 3 | func.func private @S1() attributes {scop.stmt} 4 | 5 | func.func @foo(%N: index, %M: index, %L: index) { 6 | affine.for %i = 0 to %N { 7 | affine.for %j = 0 to %L { 8 | func.call @S0() : () -> () 9 | } 10 | affine.for %j = 0 to %M { 11 | affine.for %k = 0 to %L { 12 | func.call @S1() : () -> () 13 | } 14 | } 15 | } 16 | return 17 | } 18 | 19 | 20 | // Just need to check this thing can be transformed. 21 | // CHECK: func.func @foo 22 | -------------------------------------------------------------------------------- /tools/polymer/test/polymer-opt/Reg2Mem/ignored.mlir: -------------------------------------------------------------------------------- 1 | // RUN: polymer-opt %s -reg2mem | FileCheck %s 2 | func.func @foo(%A: memref) attributes {scop.ignored} { 3 | %0 = affine.load %A[0] : memref 4 | affine.for %i = 1 to 30 { 5 | affine.store %0, %A[%i] : memref 6 | } 7 | 8 | return 9 | } 10 | 11 | // CHECK: func.func @foo 12 | // CHECK-NEXT: %[[v0:.*]] = affine.load 13 | // CHECK-NEXT: affine.for %{{.*}} = 1 to 30 14 | // CHECK-NEXT: affine.store %[[v0]] 15 | -------------------------------------------------------------------------------- /tools/polymer/tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # otherwise those tools added by add_llvm_tool won't be installed. 2 | set(LLVM_BUILD_TOOLS ON) 3 | 4 | add_subdirectory(polymer-translate) 5 | add_subdirectory(polymer-opt) 6 | -------------------------------------------------------------------------------- /tools/polymer/tools/polymer-opt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set(LLVM_LINK_COMPONENTS 3 | Support 4 | ) 5 | 6 | add_llvm_tool(polymer-opt 7 | polymer-opt.cc 8 | ) 9 | llvm_update_compile_flags(polymer-opt) 10 | target_link_libraries(polymer-opt 11 | PRIVATE 12 | 13 | PolymerTransforms 14 | ${POLYMER_AVAIL_TARGETS} 15 | 16 | MLIRFuncDialect 17 | MLIRLLVMDialect 18 | MLIRAffineAnalysis 19 | MLIRAnalysis 20 | MLIRDialect 21 | MLIRMathDialect 22 | MLIROptLib 23 | MLIRParser 24 | MLIRPass 25 | MLIRTransforms 26 | MLIRTransformUtils 27 | MLIRSupport 28 | MLIRIR 29 | MLIRAffineTransforms 30 | MLIRTranslateLib 31 | ${translation_libs} 32 | ) 33 | -------------------------------------------------------------------------------- /tools/polymer/tools/polymer-translate/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(POLYGEIST_POLYMER_ENABLE_PLUTO) 2 | set(LLVM_LINK_COMPONENTS 3 | Support 4 | ) 5 | 6 | #get_property(translation_libs GLOBAL PROPERTY MLIR_TRANSLATION_LIBS) 7 | 8 | add_llvm_tool(polymer-translate 9 | polymer-translate.cc 10 | ) 11 | llvm_update_compile_flags(polymer-translate) 12 | target_link_libraries(polymer-translate 13 | PRIVATE 14 | 15 | PolymerTargetOpenScop 16 | 17 | MLIRFuncDialect 18 | MLIRLLVMDialect 19 | MLIRAffineAnalysis 20 | MLIRAnalysis 21 | MLIRDialect 22 | MLIROptLib 23 | MLIRParser 24 | MLIRPass 25 | MLIRTransforms 26 | MLIRTransformUtils 27 | MLIRSupport 28 | MLIRIR 29 | MLIRTranslateLib 30 | MLIRToLLVMIRTranslationRegistration 31 | ) 32 | endif() 33 | --------------------------------------------------------------------------------