A compilation tool that converts LLVM IR into CIM-executable code.
RCCT is a tool for converting LLVM IR to computing in memory (CIM) recognizable and accelerable target code. Its goal is to use ReRAM and accelerate applications without modifying the source code and without source code. Four accelerable patterns are currently supported: matrix-vector multiplication (MVM), matrix-matrix multiplication (MMM), cblas library functions, and bitmap logic operations.
So far, we have supported many different loop structures, data types and dependencies. The support is shown in the table below.
Item | Form 1 | Form 2 | Form 3 | Form 4 |
---|---|---|---|---|
Vector | float A[6]; | float A[] = {...}; | float *A= malloc(...); | float *A = new float[10]; |
Matrix | float W[6][8]; | float W[] = {...}; | float *W= malloc(...); | float *W = new float[10]; |
Loop mode | for | while | ||
Loop form | for(i = 0; i < 10; i++) | for(i = 0; i <= 9; i++) | while(i < 10) {i++} | while(i >= 0) {i--} |
i = 0; for(; i < 10; i++) |
i = 0; for(; i <= n; i++) |
|||
int n = 10; for(i = 0; i < n; i++) |
int n = 9; for(i = 0; i <= n; i++) |
int n = 10; while(i < n) {i++} |
int n = 9; while(i >= 0) {i--} |
|
Loop form sum | slt (i < 10 / n) | sle (i <= 9 / n) | sgt (i > -1) | sge (i >= 0) |
Dependence | mul = b * c; e = mul + d; (direct) |
mul = b * c; f = mul e = f + d; (indirect) |
||
Date Type | int | float | double | short |
Generic form | c=A * b | C=A * B | cblas_xxxx(alpha=1, beta=0...) | c = a logic b |
git clone --depth 1 --single-branch --branch main https://github.com/leibo-hust/RCCT.git
cd RCCT
Just run the makefile to make.
make
Copy librcct.so to /usr/lib and librcct.h to /usr/local/include/ or set the LD_LIBRARY_PATH variable.
cp librcct.so /usr/lib/ & cp rcct.h /usr/local/include/
OR
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
We've provided a sample file called mvm.ll in the IR directory. You can compile and run the code directly and see the result of the example: a mvm_add.ll file will appear in the IR directory, which is the newly created file. For your own LLVM IR files, you need to follow these steps.
First you need to get the corresponding LLVM IR file.
For compilation, we use clang/clang++ to compile the source code to LLVM IR (.ll).
clang/clang++ source.c/cpp -emit-llvm -S -fno-discard-value-names -o source.ll
For decompilation, we use McSema to lift the binary to LLVM IR (.ll). First, you shoud install the McSema, then use the following commands to lift the binary to IR.
mcsema-dyninst-disass --os linux --arch amd64 --output source.cfg --binary source --entrypoint main --std_defs Docs/linux.txt
mcsema-lift-9.0 --os linux --arch amd64 --cfg source.cfg --output source.bc --abi_libraries Docs/abi.bc --explicit_args --explicit_args_count 8
llvm-dis source.bc -o source.ll
Add the source files (compiled or decompiled LLVM IR (.ll)) you need to convert to the RCCT directory.
Change the filename variable in mian.cpp to your own filename. For example, if your source file is: test.ll, then change the filename variable to test.
string filename = "test";
Specifies whether the IR is compiled or decompiled. In function.h, there is an isDecompile variable. If IR is compiled, then set it to false; if it is decompiled, then set it to true.
bool isDecompile = false;
Now there is no need to set isDecompile manually because the compilation tool can set it automatically. (until the decompilation tool is updated and new decompiled IR occur).
Recompile the code and run.
make
./main
At the end of the run, you'll get a new file - your filename _add.ll (for example: test_add.ll), which is the target file. You can recompile and execute it.
Use the following commands to recompile the target code into an executable program that can run under the CIM architecture.
clang/clang++ source_add.ll -o target.out -lrcct -lopenblas
clang/clang++ -rdynamic -o source_new.out source_add.ll /usr/local/lib/libmcsema_rt64-9.0.a -Wno-unknown-warning-option -Wno-override-module -Wall -Werror -lm -m64 -lrcct -lopenblas