This is a repo to store notes when learning the llvm.
LLVM installation: https://solarianprogrammer.com/2013/01/17/building-clang-libcpp-ubuntu-linux/
Check notes.
-
Create a new folder at <llvm_src>/lib/Transforms/:
FuncBlockCount
-
Create required files that used to create the library. I just copy the Hello folder and change the name from
Hello
toFuncBlockCount
accordiingly. -
Write the pass flowed by llvm-cookbook. There are several additional work to make the pass work.
-
Error:
Loop is not declared.
-
Solution: add analysis pass header file:
#include "llvm/Analysis/LoopInfo.h"
-
Error:
opt: .../PassAnalysisSupport.h:235: AnalysisType& llvm::Pass::getAnalysisID(llvm::AnalysisID) const [with AnalysisType = llvm::LoopInfoWrapperPass; llvm::AnalysisID = const void*]: Assertion `ResultPass && "getAnalysis*() called on an analysis that was not " "'required' by pass!"' failed.
-
Solution: add
getAnalysisUsage
function afterrunOnFunction
virtual void getAnalysisUsage(AnalysisUsage& AU) const override { AU.addRequired<LoopInfoWrapperPass>(); }
-
-
Modify the CMakelists.txt in this pass folder and the parent folder.
// pass folder if( NOT LLVM_REQUIRES_RTTI ) if( NOT LLVM_REQUIRES_EH ) set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/FuncBlockCount.exports) endif() endif() if(WIN32 OR CYGWIN) set(LLVM_LINK_COMPONENTS Core Support) endif() add_llvm_library( LLVMFuncBlockCount MODULE BUILDTREE_ONLY FuncBlockCount.cpp DEPENDS intrinsics_gen PLUGIN_TOOL opt ) ------------------------------------- // parent folder add_subdirectory(xxx)
-
Compile this pass, run
make
inbuild/
folder. Or only compile this new pass by using llvm-pass-skeleton. -
compile the test source code (I target to arm):
clang -O0 -S -emit-llvm target-program.cpp -o target-program3.ll
-
check our pass:
opt -load build/lib/xx.so -xx -disable-output test.ll
- Add pass in the llvm/lib/Transforms/Scalar/
-
Life of an LLVM IR instruction:
C code to LLVM IR
→ IR optimization
→ LLVM IR to SelectionDAG (visit each IR instruction to create an SDAGNode)
→ SelectionDAG legalization (make it to support target architecture)
→ Conversion from target-independent DAG to machine DAG (MachineSDNode, machine instructions are described in the target description .td file)
→ Scheduling instructions (covert d DAG into a linear set of instructions)
→ Register allocation (SSA has unlimited registers)
→ Code emission (JIT or llc: generate assembly instructions for a target) -
Visualizing LLVM IR CFG using graphviz
$ llc --view-dag-combine-lt-dags test.ll $ dot -Tpng /tmp/dag._Z8additionv-88c78e.dot > test.png
-
Choice 1. LLVM embedded toolchain for arm
- Install the toolchain
- Modify the <repo_root>/sample/src/<proj_name>/Makefile to generate .ll
hello.ll: *.c $(BIN_PATH)/clang --config armv6m_soft_nofp_rdimon_baremetal -g -T ../../ldscripts/microbit.ld -O0 -S -emit-llvm hello.c -o hello.ll
- Gnereate the
.ll
file - Add new pass
# Add the folder in repo-1.0/llvm/lib/Transform/Test $ cp -r Test <root_repo>/repo-1.0/llvm/lib/Transform/Test # Compile the new pass $ cd <root_repo>/build-1.0/llvm $ make -j4
- Run new pass
# run the new pass $ ../../../build-0.1/llvm/bin/opt -load ../../../build-0.1/llvm/lib/LLVMTest.so -test -disable-output hello.ll
- Run samples and Debug (needs qemu version >= 4.0.0)
$ make $ make debug $ arm-none-eabi-gdb hello.elf (gdb) target remote :1234
-
[TODO] Choice 2 . Use flags to specific the target. For example, I install LLVM 9.0.0 and I don't want to reinstall the LLVM.
- Use the
clang
to compile (learn from the previous repo*cfg
files):
clang --target=armv8m.main-non-eabi -mfloat-abi=soft -march=armv8m.main+nofp -fno-exceptions -fno-rtti -O0 -S -emit-llvm target-program.cpp -o target-program4.ll
- Use the
llc
to generate the .s- run
llc -march=arm -mattr=help
to check which cpu it supports - I select the cortex-m33:
llc -mcpu=cortex-m33 target-program4.ll -o target-program4.s
- run
- But this is not convenient to generate the executable
.elf
file since we need to write linker script for the simple tests.
- Use the
-
Install arm gcc toolchain. (Reference)
- Download the arm gcc toolchain from link.
sudo tar xjf gcc-arm-none-eabi-your-version.bz2 -C /usr/share/ sudo ln -s /usr/share/gcc-arm-none-eabi-your-version/bin/* /usr/bin/
- Download the arm gcc toolchain from link.
-
Install qemu 4.0.0. Reference
- Update the python3. Reference.
$ sudo apt update $ sudo apt install software-properties-common $ sudo add-apt-repository ppa:deadsnakes/ppa $ sudo apt update $ sudo apt install python3.8 ---------- Link newly installed python3---- $ which python3.8 /usr/bin/python3.8 $ sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 1 $ which python3.5 /usr/bin/python3.5 $ sudo update-alternatives --config python3 [select 2, and enter]
- Install Ninja:
sudo apt install ninja-build
- Clear previous installation:
sudo apt-get purge "qemu*" sudo apt-get autoremove
- Enable Source Code repositories in Software and Updates (software-properties-gtk) and then:
sudo apt-get build-dep qemu
- Download qemu and compile (I installed qemu 4.0.0 for
microbit
is supported since qemu 4.0.0):
cd ~/Downloads wget https://download.qemu.org/qemu-4.0.0.tar.xz tar -xf qemu-4.0.0.tar.xz cd qemu-4.0.0/
- Decide the target we want.
I only need the x86 and arm, so specifi the confiration (run ./configure --help to get the suppported tareget list.).
./configure --target-list=aarch64-softmmu,aarch64-linux-user,arm-softmmu,arm-linux-user,x86_64-softmmu,x86_64-linux-user make
- Use
checkinstall
, the qemu package will be generated as a .deb file and can be managed by the package manager. Can be easy to remove withdpkg - r qemu
.sudo apt-get install checkinstall sudo checkinstall make install sudo apt-get install ./*.deb
- Check the version:
$ qemu-system-arm --version QEMU emulator version 4.0.0 Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
- Update the python3. Reference.
Refer to FreeRTOS Demo for m3_mps2+
ORTEX_M3_MPS2_QEMU_GCC git:(main) ✗ sudo qemu-system-arm -machine mps2-an385 -monitor null -semihosting \
--semihosting-config enable=on,target=native \
-kernel ./build/RTOSDemo.axf \
-serial stdio -nographic -s -S
blinking
blinking
blinking
blinking