Last active
December 7, 2023 17:52
-
-
Save jmorse/2749e0654f7a06d86f10f0601954abc3 to your computer and use it in GitHub Desktop.
Example script for reducing problems with RemoveDIs.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### This is a script of me (jmorse) building and testing the "RemoveDIs" | |
### non-instruction based debug-info compiler, doing a stage2 clang build | |
### and comparing the object files to make sure they're identical. This | |
### includes a demo of how to reduce the differences if you find one. | |
### Comments all start with '###'. | |
### | |
### Note that to assure equivalence, you need to apply the series of patches | |
### at https://github.com/jmorse/llvm-project/tree/removedis-comparison-patches | |
### to match what dbg.value mode does bug-for-bug, and turn off three or four | |
### transformations that are too fiddly to get correct right now. | |
### | |
### To begin, build a compiler with the LLVM_EXPERIMENTAL_DEBUGINFO_ITERATORS | |
### cmake flag set to "ON". | |
% pwd | |
/fast/fs/llvm-stage | |
% mkdir build | |
% cd build | |
% /fast/fs/CMake/build/bin/cmake ../llvm -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=clang -DLLVM_EXPERIMENTAL_DEBUGINFO_ITERATORS=On | |
### Many lines of configuration removed. | |
% ninja clang | |
### Many lines of building removed. | |
### You now have a compiler and tooling with the extra debug-info bit built in. | |
### We'll use this compiler to do two stage2 RelWithDebInfo builds and compare them. | |
### First, we'll do one with the new debug-info mode turned off. Both builds | |
### with also have assignment tracking turned off as that's still being worked | |
### on. | |
% mkdir stage2-build | |
% cd stage2-build | |
% /fast/fs/CMake/build/bin/cmake ../llvm -G Ninja -DCMAKE_CXX_COMPILER=/fast/fs/llvm-stage/build/bin/clang++ -DCMAKE_C_COMPILER=/fast/fs/llvm-stage/build/bin/clang -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_CXX_FLAGS="-fno-ident -Xclang -fexperimental-assignment-tracking=disabled -mllvm -experimental-debuginfo-iterators=false" -DCMAKE_C_FLAGS="-fno-ident -Xclang -fexperimental-assignment-tracking=disabled -mllvm -experimental-debuginfo-iterators=false" | |
-- The CXX compiler identification is Clang 18.0.0 | |
-- The ASM compiler identification is Clang | |
-- Found assembler: /fast/fs/llvm-stage/build/bin/clang | |
-- Detecting C compiler ABI info | |
-- Detecting C compiler ABI info - done | |
-- Check for working C compiler: /fast/fs/llvm-stage/build/bin/clang - skipped | |
-- Detecting C compile features | |
-- Detecting C compile features - done | |
-- Detecting CXX compiler ABI info | |
-- Detecting CXX compiler ABI info - done | |
-- Check for working CXX compiler: /fast/fs/llvm-stage/build/bin/clang++ - skipped | |
-- Detecting CXX compile features | |
-- Detecting CXX compile features - done | |
-- bolt project is disabled | |
-- clang project is enabled | |
### lots of configurating removed from here | |
-- Registering ExampleIRTransforms as a pass plugin (static build: OFF) | |
-- Registering Bye as a pass plugin (static build: OFF) | |
-- Configuring done | |
-- Generating done | |
-- Build files have been written to: /fast/fs/llvm-stage/stage2-build | |
% ninja clang | |
### removed lots of build lines... | |
[3879/3880] Linking CXX executable bin/clang-18 | |
[3879/3880] Creating executable symlink bin/clang | |
[3880/3880] Creating executable symlink bin/clang | |
### We've successfully built a stage2 clang in normal dbg.value mode. Let's save | |
### a copy and then do it again in RemoveDIs mode, by setting the command line | |
### flag to true. | |
% cd .. | |
% cp -r stage2-build REF-stage2-build | |
% cd stage2-build | |
% ninja clean | |
[0/1] Cleaning all built files... | |
[1/1] Cleaning all built files... | |
Cleaning... 4214 files. | |
### Re-configure the build to be in RemoveDIs mode by setting the command line | |
### flag, -experimental-debuginfo-iterators, to true. | |
% /fast/fs/CMake/build/bin/cmake ../llvm -G Ninja -DCMAKE_CXX_COMPILER=/fast/fs/llvm-stage/build/bin/clang++ -DCMAKE_C_COMPILER=/fast/fs/llvm-stage/build/bin/clang -DTEST_SUITE_RUN_BENCHMARKS=0 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_CXX_FLAGS="-fno-ident -Xclang -fexperimental-assignment-tracking=disabled -mllvm -experimental-debuginfo-iterators=true" -DCMAKE_C_FLAGS="-fno-ident -Xclang -fexperimental-assignment-tracking=disabled -mllvm -experimental-debuginfo-iterators=true" | |
-- clang project is enabled | |
-- clang-tools-extra project is disabled | |
-- compiler-rt project is disabled | |
-- cross-project-tests project is disabled | |
-- libc project is disabled | |
-- libclc project is disabled | |
-- lld project is disabled | |
-- lldb project is disabled | |
-- mlir project is disabled | |
-- openmp project is disabled | |
-- polly project is disabled | |
-- pstl project is disabled | |
-- flang project is disabled | |
### removed lots of configurating | |
-- Targeting X86 | |
-- Targeting XCore | |
-- Clang version: 18.0.0git | |
-- Registering ExampleIRTransforms as a pass plugin (static build: OFF) | |
-- Registering Bye as a pass plugin (static build: OFF) | |
-- Configuring done | |
-- Generating done | |
-- Build files have been written to: /fast/fs/llvm-stage/stage2-build | |
% ninja clang | |
### removed many build lines | |
[3879/3880] Creating executable symlink bin/clang | |
[3880/3880] Creating executable symlink bin/clang | |
### We now have two builds -- let's compare whether or not they have identical | |
### object files. We're going to list all the files in one build dir, filter for | |
### object files, pick out the common name component. Then for each object file | |
### compare the copy in REF-stage2-build (which we built in dbg.value mode) with | |
### the copy in stage2-build, which we just built in RemoveDIs mode. | |
% cd .. | |
% find stage2-build | grep \\.cpp\.o$ | sed s_stage2-build/__g | while read x; do cmp stage2-build/$x REF-stage2-build/$x; done | |
stage2-build/lib/Target/Hexagon/CMakeFiles/LLVMHexagonCodeGen.dir/HexagonISelDAGToDAG.cpp.o REF-stage2-build/lib/Target/Hexagon/CMakeFiles/LLVMHexagonCodeGen.dir/HexagonISelDAGToDAG.cpp.o differ: byte 41, line 1 | |
stage2-build/lib/CodeGen/CMakeFiles/LLVMCodeGen.dir/CFIInstrInserter.cpp.o REF-stage2-build/lib/CodeGen/CMakeFiles/LLVMCodeGen.dir/CFIInstrInserter.cpp.o differ: byte 41, line 1 | |
### There are two files that are different unfortunately. Let's examine one, | |
### first by rebuilding it to collect it's build command line: | |
% cd stage2-build | |
% rm lib/CodeGen/CMakeFiles/LLVMCodeGen.dir/CFIInstrInserter.cpp.o | |
% ninja -v lib/CodeGen/CMakeFiles/LLVMCodeGen.dir/CFIInstrInserter.cpp.o | |
ninja[1/1] /fast/fs/llvm-stage/build/bin/clang++ -DEXPERIMENTAL_DEBUGINFO_ITERATORS -DGTEST_HAS_RTTI=0 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Ilib/CodeGen -I/fast/fs/llvm-stage/llvm/lib/CodeGen -Iinclude -I/fast/fs/llvm-stage/llvm/include -fno-ident -Xclang -fexperimental-assignment-tracking=disabled -mllvm -experimental-debuginfo-iterators=true -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O2 -g -DNDEBUG -fno-exceptions -funwind-tables -fno-rtti -std=c++17 -MD -MT lib/CodeGen/CMakeFiles/LLVMCodeGen.dir/CFIInstrInserter.cpp.o -MF lib/CodeGen/CMakeFiles/LLVMCodeGen.dir/CFIInstrInserter.cpp.o.d -o lib/CodeGen/CMakeFiles/LLVMCodeGen.dir/CFIInstrInserter.cpp.o -c /fast/fs/llvm-stage/llvm/lib/CodeGen/CFIInstrInserter.cpp | |
### Now, we'll remove the normal output object file, and instead emit LLVM | |
### bitcode. We'll also turn off the LLVM optimisation passes (don't use -O0!) | |
### so that we get the untransformed output of clang (disable-llvm-passes). | |
% /fast/fs/llvm-stage/build/bin/clang++ -DEXPERIMENTAL_DEBUGINFO_ITERATORS -DGTEST_HAS_RTTI=0 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Ilib/CodeGen -I/fast/fs/llvm-stage/llvm/lib/CodeGen -Iinclude -I/fast/fs/llvm-stage/llvm/include -fno-ident -Xclang -fexperimental-assignment-tracking=disabled -mllvm -experimental-debuginfo-iterators=true -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O2 -g -DNDEBUG -fno-exceptions -funwind-tables -fno-rtti -std=c++17 -MD -MT lib/CodeGen/CMakeFiles/LLVMCodeGen.dir/CFIInstrInserter.cpp.o -MF lib/CodeGen/CMakeFiles/LLVMCodeGen.dir/CFIInstrInserter.cpp.o.d -c /fast/fs/llvm-stage/llvm/lib/CodeGen/CFIInstrInserter.cpp -o out.bc -emit-llvm -Xclang -disable-llvm-passes | |
### We'll use llvm-reduce to narrow down what the problem is. An example test | |
### script is below: it uses opt on the bitcode file, with the O2 optimisation | |
### pipeline, and compares whether the output in dbg.value mode is different | |
### to the output in RemoveDIs mode. | |
% cat diff.sh | |
#!/bin/sh | |
/fast/fs/llvm-stage/build/bin/opt --experimental-debuginfo-iterators=false $1 -O2 -o optgood.ll -S $2 | |
if test $? != 0; then | |
exit 1; | |
fi | |
/fast/fs/llvm-stage/build/bin/opt --experimental-debuginfo-iterators=true $1 -O2 -o optbad.ll -S $2 | |
if test $? != 0; then | |
exit 1; | |
fi | |
cmp optgood.ll optbad.ll | |
if test $? = 0; then | |
exit 1; | |
fi | |
exit 0 | |
% /fast/fs/llvm-stage/build/bin/llvm-reduce --test ./diff.sh out.bc --write-tmp-files-as-bitcode | |
*** Stripping Debug Info... | |
optgood.ll optbad.ll differ: byte 34961, line 332 | |
---------------------------- | |
*** Reducing Functions... | |
optgood.ll optbad.ll differ: byte 34961, line 332 | |
optgood.ll optbad.ll differ: byte 23368, line 222 | |
optgood.ll optbad.ll differ: byte 15573, line 148 | |
optgood.ll optbad.ll differ: byte 6904, line 72 | |
optgood.ll optbad.ll differ: byte 5775, line 59 | |
optgood.ll optbad.ll differ: byte 5610, line 58 | |
optgood.ll optbad.ll differ: byte 4549, line 51 | |
optgood.ll optbad.ll differ: byte 4549, line 51 | |
optgood.ll optbad.ll differ: byte 4549, line 51 | |
optgood.ll optbad.ll differ: byte 4549, line 51 | |
optgood.ll optbad.ll differ: byte 4350, line 48 | |
optgood.ll optbad.ll differ: byte 2353, line 34 | |
**** SUCCESS | Saved new best reduction to reduced.bc | |
### lots of reducing removed | |
**** SUCCESS | Saved new best reduction to reduced.bc | |
---------------------------- | |
done reducing! reduced testcase: reduced.bc | |
### Now that we've reduced down to a small bitcode file, we can use bisect and | |
### opt-bisect-limit to narrow down which optimisation pass the problem is in. | |
% cat diff-bisect.sh | |
#!/bin/sh | |
count=$1 | |
file=reduced.bc | |
/fast/fs/llvm-stage/build/bin/opt --experimental-debuginfo-iterators=false $file -o2 -o optgood.ll -s --opt-bisect-limit=$count | |
if test $? != 0; then | |
exit 1; | |
fi | |
/fast/fs/llvm-stage/build/bin/opt --experimental-debuginfo-iterators=true $file -o2 -o optbad.ll -s --opt-bisect-limit=$count | |
if test $? != 0; then | |
exit 1; | |
fi | |
cmp optgood.ll optbad.ll | |
if test $? = 0; then | |
exit 0; | |
fi | |
exit 1 | |
% python3 /fast/fs/llvm-stage/llvm/utils/bisect --start 0 --end 1000 ./diff-bisect.sh "%(count)s" | |
bisect starting! | |
start: 0 | |
end: 1000 | |
visiting count: 500 with (start, end) = (0,1000) | |
['./diff-bisect.sh', '500'] | |
bisect: running pass (1) annotation2metadatapass on [module] | |
bisect: running pass (2) forcefunctionattrspass on [module] | |
bisect: running pass (3) inferfunctionattrspass on [module] | |
bisect: running pass (4) lowerexpectintrinsicpass on _zn12_global__n_116cfiinstrinserterc2ev | |
bisect: running pass (5) simplifycfgpass on _zn12_global__n_116cfiinstrinserterc2ev | |
bisect: running pass (6) sroapass on _zn12_global__n_116cfiinstrinserterc2ev | |
bisect: running pass (7) earlycsepass on _zn12_global__n_116cfiinstrinserterc2ev | |
bisect: running pass (8) openmpoptpass on [module] | |
bisect: running pass (9) ipsccppass on [module] | |
bisect: running pass (10) calledvaluepropagationpass on [module] | |
bisect: running pass (11) globaloptpass on [module] | |
### skipped a load of bisection messages | |
last good count: 10 | |
% | |
### We now have reduced.bc that contains the reduced LLVM-IR reproducer for the | |
### difference, and we know it's pass 10 that's causing the difference. Now to | |
### file an issue and CC the relevant people on it (not shown!) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment