Add custom llvm optimization command (opt) after compilation within CMake projects - c++

I created my own LLVM optimization pass in LLVM 3.7.0 .
I want to use this pass within a cmake project.
I need to run the pass as last, after all optimization passes of -O2 (or -O3) are executed by clang (or clang++).
Unfortunately, I did not find a mechanism to invoke the pass by passing the flag directly from the clang (if you point me out a way to do that, this would already be helpful).
Assuming there is no way to run the pass by giving a flag to clang, I need an extra optimization pass in my toolchain to be placed between the compilation and the linking phase. I need it throughout the whole cmake project.
The commands I would need to generate a binary from a two source files are:
clang -c -g -emit-llvm -O3 mySource0.c -o mySource0.bc
clang -c -g -emit-llvm -O3 mySource1.c -o mySource.bc
llvm-link mySource0.bc mySource1.bc -o main.bc
opt -load myAnalysis.so -myAnalysis main.bc -o main.analysis.bc
clang <libraryRelatedFlags> main.analysis.bc -o myExecutable
My pass is registered as:
static RegisterPass<myAnalysis> X("myAnalysis", "Implement my analysis", false, false);
as in:
http://llvm.org/docs/WritingAnLLVMPass.html#basic-code-required

If I understand your question correctly, you are simply aiming to add your pass so that it is run under the -O3.
You'll need to edit $(llvm-dir)/tools/opt/opt.cpp to get your pass to run -O3. You'll need to find where the OptLevelO3 bool is used to add passes and make sure to add your pass there as well.
If instead you just want your pass to be run on it's own flag you'll need to initialize your pass properly on top of registering it. We can look at DependenceAnalysis.cpp as a good example of how to do this:
INITIALIZE_PASS_BEGIN(DependenceAnalysis, "da", "Dependence Analysis", true, true)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
INITIALIZE_PASS_END(DependenceAnalysis, "da", "Dependence Analysis", true, true)
You also mentioned that you want your pass to run after some other passes. Simply mark them as DA did it with:
INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
to make sure that your pass is run AFTER the pass that you want to depend on.

Related

How can I tell GCC to use custom library for -l instead of the system one?

I have a custom build of SQLite3 at /somepath, so /somepath/.libs contains libsqlite3.so.0.8.6 and the symbolic links to it. I wanted to link a program against it and assumed
g++ -O3 -g -fPIC -I /somepath -I /somepath/src -L /somepath/.libs -lsqlite3 -o myfile.so myfile.cpp
would work. It compiles, but I get a segmentation fault due to some problem in my code, and when trying to debug I run into the issues which look like LD_PRELOAD not working with my program and Setting my lib for LD_PRELOAD makes some processes produce loader errors: I can run LD_PRELOAD=myfile.so /somepath/sqlite3 ..., but under GDB I get symbol lookup error and LD_DEBUG=all LD_PRELOAD=myfile.so gdc -c core /somepath/sqlite3 ... reveals symbols are getting looked up in /usr/lib/x86_64-linux-gnu/libsqlite3.so.0 instead of /somepath/libsqlite3.so.0, and unsurprisingly missing the symbols for functions added in the custom build. How can I fix this and debug my code?
The -lsqlite3 argument should be last. Order of arguments to g++ matters a lot. You should read more about runpath and perhaps pass -Wl,-rpath,/somepath/.libs
You may want to pass -v once to g++ to understand what is happening (what programs are actually running). You might also pass -Wl,--verbose to ask a more verbose link.
Then you can use ldd on your executable (and also readelf) to find out more what are its link time dependencies.
With suitable arguments to g++ you should not need additional options to gdb
From http://visualgdb.com/gdbreference/commands/set_solib-search-path
Inside gdb use the commands below.
set solib-search-path [Directories]
show solib-search-path

Object code generation for new RISCV instruction emitted by LLVM backend

From https://github.com/riscv/riscv-llvm,
Using the llvm-riscv is fairly simple to build a full executable
however you need riscv64-unknown-*-gcc to do the assembling and
linking. An example of compiling hello world:
$ clang -target riscv64 -mriscv=RV64IAMFD -S hello.c -o hello.S
$ riscv64-unknown-elf-gcc -o hello.riscv hello.S
My question is: if I change the LLVM backend and get it to emit a new instruction in the hello.S file, how will riscv64-unknown-elf-gcc know how to convert it into object code? Do I also need to make changes in riscv64-unknown-elf-gcc so that it knows the format of the new instruction?
riscv64-unknown-elf-gcc calls as, i.e. usually GNU as from the binutils to assemble assembly code (i.e. hello.S in your snippet) into executable machine code. Thus you would have to modify the binutils if you want to assemble a new instruction.

Why does a 2-stage command-line build with clang not generate a dSYM directory?

I have a simple project I want to debug want to produce dSYM folder with debugging symbols.
Running:
clang++ -std=c++14 -stdlib=libc++ -g -o Lazy Lazy.cpp
Creates Lazy.dSYM as I expect.
However:
clang++ -std=c++14 -stdlib=libc++ -g -c Lazy.cpp
clang++ -stdlib=libc++ -g -o Lazy Lazy.o
Does not create Lazy.dSYM (It seems that the symbols are embedded in the binary).
Sadly the 2-step build is what my modified makefile does. How can I generate Lazy.dSYM from a 2-stage compile-and-link build?
I don't need a dSYM directory, just debugging symbols, but would like to understand when and why it is created.
The creation of the .dSYM bundle is done by a tool called dsymutil. When Apple added support for DWARF debugging information, they decided to separate "executable linking" from "debug information linking". As such, the debug information linking is not done by the normal linker, it's done by dsymutil.
As a convenience, when you build a program all in one step, the compiler invokes dsymutil on your behalf. That's because it knows it has all of the inputs. If you add the -v (a.k.a. --verbose) option to the compile command, you will see the invocation of dsymutil as the last step it does.
In other cases, though, it doesn't do that. It leaves the debug information linking step for the user to do manually. You can do it by simply issuing the command:
dsymutil <your_program>
Here's an article by an Apple engineer who helped design and implement Apple's support for DWARF explaining their thinking. He also answered a question here on Stack Overflow about this stuff.

Makefile configuration for entire system

As we know, in the appliance when we use the command
make [file-name]
It automatically compiles with some flags:
-ggdb -O0 -std=c99 -Wall - Werror
I need to know in which directory the CS50 edited Makefile is located, because I want to configure my own Makefile for the entire system by which I can make any .cpp file.
When I compile c++ file with make it automatically compiles with g++ but I want to compile .cpp file with clang++ compiler, adding some essential flag such for -g for debugging -O0 for assembly code.
I'm asking how to create a Makefile for that specific reasons, if possible.
Make uses Makefiles in the current directory and Implicit-Rules. You can modify the behavior of implicit rules by changing the variables that those explicit rules use.
For example, to change the compiler for .cpp files, you could set your own CXX variable, either
in the environment (Make uses it):
CXX=clang++ make [file-name]
#OR
export CXX=clang++; make [file-name]
in a local Makefile:
CXX:=clang++
#The implicit rule, which you'll find in the link, takes care of the rest

Configuring g++ from Code::Blocks doesn't take affect on command line

I'm trying to change the settings of g++ from the Code::Blocks IDE. I went to the Settings tab, clicked Compiler... and checked various options for the compiler to use, like
Enable all warnings (-Wall)
Have g++ follow the C++11 ISO C++ language standard (-std=c++11)
......
These are just two of many others; when I compile on the command line, here is what comes up:
g++ -o example example.cpp
# warning: initializer lists only available with -std=c++11 ...
Notice how there's no warning either - I have an unused variable in my program. It only works if I give the options manually:
g++ -Wall -std=c++11 -o example example.cpp
Do you think I might have done something wrong when setting up the compiler? Why aren't the options taking affect?
Invoking the compiler from the ide is completely independent from doing it in a command line shell. There's no reason for the setting and usage of one to have any effect on the other.