How can I pass flags to a LLVM pass? - llvm

I'm implementing a LLVM pass, and would like to turn some options on or off via the command line, especially I'd like to have a -v verbose mode for my pass.
I couldn't find a mechanism for passing command line flags mentioned in any of the docs, does one exist?

The solution I found is to use LLVM's general CommandLine API: http://llvm.org/docs/CommandLine.html
Works as expected in opt when loading the pass dynamically.

Another useful trick is:
#define DEBUG_TYPE "my-special-name"
...
#include "llvm/Support/Debug.h"
...
Sprinkle a bunch of debug output around:
DEBUG(dbgs() << "Original Frame Size: " << FrameSize << "\n" );
...
DEBUG(Node->dump(CurDAG));
Then, on the command line:
... -debug-only my-special-name ...
will get your output.
If your pass is run with the clang front end, you can use:
... -mllvm -debug-only my-special-name ...

If there is only one option with two possible values, the easiest thing to do is to register the same pass twice under two different names. I don't know of any general solution, especially something that will work with opt.

Related

Fastest way to make console output "verbose" or not

I am making a small system and I want to be able to toggle "verbose" text output in the whole system.
I have made a file called globals.h:
namespace REBr{
extern bool console_verbose = false;
}
If this is true I want all my classes to print a message to the console when they are constructing, destructing, copying or doing pretty much anything.
For example:
window(string title="",int width=1280,int height=720):
Width(width),Height(height),title(title)
{
if(console_verbose){
std::cout<<"Generating window #"<<this->instanceCounter;
std::cout<<"-";
}
this->window=SDL_CreateWindow(title.c_str(),0,0,width,height,SDL_WINDOW_OPENGL);
if(console_verbose)
std::cout<<"-";
if(this->window)
{
this->glcontext = SDL_GL_CreateContext(window);
if(console_verbose)
std::cout<<".";
if(this->glcontext==NULL)
{
std::cout<<"FATAL ERROR IN REBr::WINDOW::CONSTR_OPENGLCONTEXT: "<<SDL_GetError()<<std::endl;
}
}
else std::cout<<"FATAL ERROR IN REBr::WINDOW::CONSTR_WINDOW: "<<SDL_GetError()<<std::endl;
if(console_verbose)
std::cout<<">done!"<<endl;
}
Now as you can see I have a lot of ifs in that constructor. And I REALLY dont want that since that will slow down my application. I need this to be as fast as possible without removing the "loading bar" (this helps me determine at which function the program stopped functioning).
What is the best/fastest way to accomplish this?
Everying in my system is under the namespace REBr
Some variants to achieve that:
Use some logger library. It is the best option as it gives you maximum flexibility and some useful experience ;) And you haven't to devise something. For example, look at Google GLOG.
Define some macro, allowing you to turn on/off all these logs by changing only the macro. But it isn't so easy to write such marco correctly.
Mark your conditional flag as constexpr. That way you may switch the flag and, depending on its value, compiler will optimise ifs in compiled program. But ifs will still be in code, so it looks kinda bulky.
Anyway, all these options require program recompilation. W/o recompilation it is impossible to achieve the maximum speed.
I often use a Logger class that supports debug levels. A call might look like:
logger->Log(debugLevel, "%s %s %d %d", timestamp, msg, value1, value2);
The Logger class supports multiple debug levels so that I can fine tune the debug output. This can be set at any time through the command line or with a debugger. The Log statement uses a variable length argument list much like printf.
Google's logging module is widely used in the industry and supports logging levels that you can set from the command line. For example (taken from their documentation)
VLOG(1) << "I'm printed when you run the program with --v=1 or higher";
VLOG(2) << "I'm printed when you run the program with --v=2 or higher";
You can find the code here https://github.com/google/glog and the documentation in the doc/ folder.

boost::program_options: option recognizes following option as an argument when no argument is provided

I have a program that takes a few options and I want to recognize when no argument is provided.
This is what happen when I call my program without one option arg
program -lib
cout: the required argument for option '-lib' is missing
That's ok, but when I call my program with additional options, e.g
program -lib -out number
The variable assigned to lib gets the value "-out", although -out was declared as an option. I expect to get the same warning as in the first example.
I can solve this problem by adding a custom notifier to all the options, code below:
void validate_string(const std::string& r)
{
if (*r.begin() == '-') {
throw Something
}
}
...
("lib", po::value<std::string>(&lib)->notifier(validate_string), "Library")
There's any way of doing this with a build-in mechanism of boost::program_options? I don't like my current solution, the options declaration look messy and is hard to read. Besides -out is not getting assigned.
BTW: I'm using allow_long_disguise, so single - is allowed for long options

Is it possible to see which lines were executed after a command-line app was run?

I am using MinGW (GCC) as a C++ compiler within my application. I have set it to redirect the output of its command line process to my app. Now, suppose I have the following simple C++ code:
int n = 5;
if (n == 6) cout << "YES";
else cout << "NO";
Is there a way to tell what line(s) of code were actually hit during execution of the application? Is there a command I can send to MinGW (GCC) process which, for the given example, would output 1 and 3, as those were the lines hit. And also, in case of a line inside a "for" loop, to tell how many times that statement was actually hit?
And, if not possible, what would be the best approach to having this information? Developing my own compiler or...? Thanks in advance
EDIT: Can someone provide a snippet of commands (in Windows) to be used in order to create a coverage-enabled GCC exe file?
"Is there a way to tell what line(s) of code were actually hit during execution of the application?"
Yes. It's an intrinsic GCC feature. You'll need to compile and link your code with the --coverage, -lgcov or -fprofile-arcs options set.
The gcov tool can be used to consolidate and interpret the actual informations gathered during program runs, that were instrumented with --coverage.
A very good tool to produce browsable consolidated and fairly visualized covearage information from gcov outputs is lcov.
Since you're using mingw you should be able to use gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html

Run LLVM pass with opt

I have just started to work with LLVM. I have wrote my own Hello pass, which worked fine.
Now I want to run opt with the stack protector pass, from StackProtector.cpp, but I am having trouble with that. When I look at the source code, it looks like I should use the flag -stack-protector:
INITIALIZE_PASS(StackProtector, "stack-protector", "Insert stack protectors", false, false)
But this flag is not recognized by opt.
I am not sure which file to "load", as it is not as simple as loading my own LLVMHello.so file and I could not find a StackProtector.so file; I believe this might be the problem.
Edit:
I finally got an answer from LLVMDev. Actually, the pass I wanted to run is performed by llc, not opt. I could not find the option -stack-protector, though, with
llc --help
because this option is hidden. If instead I do
llc --help-hidden
it is shown that the pass is there, and I just need to run
llc -print-before=stack-protector <input>
First you add in your pass :
static RegisterPass<StackProtector> X("StackProtector", "Insert stack protectors", false, false);
Second, in the terminal when you run the pass on a target file, after you run make, you have something like:
//home/YOURNAME/llvm/Release+Asserts/bin/opt -load //home/YOURNAME/llvm/Release+Asserts/lib/StackProtector.so -StackProtector //home/YOURNAME/llvm/tools/clang/woRKSPACE/Test.bc
where Test.bc is your target code. Also, be aware: in your Makefile, don't forget to add LIBRARYNAME = StackProtector.
Also, be aware if the pass in not already registered (if so, you will get a segfault error)

Memory section handling error

I'm getting a link time error:
WARNING: /home/gulevich/development/camac-fedorov/camac/linux/k0607-lsi6/camac-k0607-lsi6.o (.ctors): unexpected non-allocatable section.
Did you forget to use "ax"/"aw" in a .S file?
Note that for example <linux/init.h> contains
section definitions for use in .S files.
The code causing the error (assembly in C source):
# if defined(__ELF__)
# define __SECTION_FLAGS ", \"aw\" , #progbits"
/* writable flag needed for ld ".[cd]tors" sections bug workaround) */
# elif defined(__COFF__)
# define __SECTION_FLAGS ", \"dr\""
/* untested, may be writable flag needed */
# endif
asm
(
".section .ctors" __SECTION_FLAGS "\n"
".globl __ctors_begin__\n"
"__ctors_begin__:\n"
".previous\n"
);
Is there any way to fix this? The idea is to put a varaible __ctors_begin__ at the beginning of a certain memory section. This code is a legacy that worked fine using a different build system and older compiler.
Meaning of this assembly code explained in an answer to my previous question.
very long shot but is the section .ctors is defined like you want in the linker script? ld iirc has a verbose option to show the linker script.
A long shot:
Perhaps your linker is expecting ELF format (instead of COFF), and for some reason __ELF__ is not defined? Have you checked the preprocessor output for this particular build?
I would dobule check the value of __SECTION_FLAGS just to be sure that it indeed contains ax or aw. I'd also be sure that __COFF__ is not defined and that __ELF__ is. Failing that, it might be time to grab (is possible) a previous or future version of the compiler/linker and see if that fixes your problem. Perhaps you could compile your code as C++ and somehow let the compiler/linker/link scritps do what they are supposed to do? Dunno completely, but this is where I would start.
Sections work fine. So I'll ignore this warning.