How to get optimization level (O0,O1,O2 etc) from a llvm pass? - llvm

I am writing a llvm pass. I want to bail out my pass if optimization level is O0 or O1. I am not able to find the right API to query the optimization level from a function pass. I tried to search this option in codebase and doc, but could not locate one.

Related

Is there a backend optimizer in LLVM?

I can get the optimization level from the command llc -help
-O=<char> - Optimization level. [-O0, -O1, -O2, or -O3] (default = '-O2')
I want to know what the optimization does exactly.
So, I'm searching the source code of the backend optimizer.
I google it by "llvm backend optimizer", but there is no information about it, only some target-independent pass source code.
I want to know what does the optimization do for div-rem-pars.
It can combine two instructions of llvm IR to one instruction for assembly code.
Apparently there are backend optimizers options in llvm. They are however not well documented [1,2]. The TargetMachine [3] class has functions getOptLevel and setOptLevel to set an optimization level from 0-3 for a specific target machine, so starting from there you can try to track where it is used.
[1] https://llvm.org/docs/CodeGenerator.html#ssa-based-machine-code-optimizations
[2] https://llvm.org/docs/CodeGenerator.html#late-machine-code-optimizations
[3] https://llvm.org/doxygen/classllvm_1_1TargetMachine.html

What is transformations in LLVM? How is is it related to passes in LLVM?

I'm just starting to learn about llvm and a bit confused with transformations and Passes.
An LLVM pass is something that goes through either by you or by an LLVM backend generated LLVM IR. From the structure of said IR, we can do two things.
Analysis in which we from the IR provides some sort of information about the program for static analysis. The clang static analyzer is an example of such a tool.
Transformation:
Another option is that we change the IR as we pass through it. We make a transformation. Usually, we do this to make the resulting executable better. We optimize the code. This last part is what is called a transformation, or Transform Passes to quote the LLVM documentation. Simply stated, transformations are operations conducted by some transform pass, and that relates to changing the IR into some other form when executing the pass.
More information about this can be found here LLVM passes.

Force reduced width of comparison instructions

I want to force LLVM to generate CMPx-, TEST- and alike instructions on x86-64 to be up to 8 bit width only, forcing e.g. 32bit-int comparisons into four separate cmp+branch pairs. This obviously requires some bit-masking and increased instruction count.
Can I achieve this by simply "disabling" certain instructions for x86-64 so LLVM auto-generates the required glue code? Do I have to write a pass and work on the IR myself?
No, there is no way of disabling certain instructions like this from a vanilla build of LLVM. Anything you do to achieve this will require modifying LLVM.
You have several options for modifying LLVM:
You can add an x86-specific pass to the LLVM backend (does not work on the IR) which directly expands the cmp and test instructions into chains of instructions on sub-registers. You would have to do this after instruction selection to preclude some target-independent pass from undoing the transformation. This is called an "MI" pass in LLVM parlance. As an example you can look in X86FixupSetCC.cpp (mirror here). This has a huge advantage in that you can put it behind a flag and otherwise control whether it occurs once you add the core functionality.
You can modify LLVM's instruction tables for LLVM in the X86 .td files to only define these instructions for 8-bit registers, and then add the def Pat<...>; patterns to the .td files that allow programs with wider comparisons to still have their instructions selected (much as Colin suggested above). This has the disadvantage of not only have you modified your LLVM but you can't easily turn those modifications on and off behind some flag.
You can't do anything to LLVM's IR that will really help here because the code generator will just optimize things back into instruction patterns you're trying to avoid.
Hope this helps!
What you're probably looking to do is redefine the lowering pattern in the x86 .td files. There's code that looks like "def Pat<...>;" that defines a translation from one graph of instructions to another. There should be a pattern for going from IR comparison instructions to the x86 32bit compare instructions. You'll want to edit this pattern and instead output your sequence of comparisons.

What is LLVM CodeGen optimization?

The ExecutionEngine class in LLVM library has a option to set the CodeGen optimization level (CodeGenOpt::Level). Do I understand it right that CodeGen optimizations are applied during machine code generation and they are not related to IR? If I want to optimize IR I need to do it with other tools?
The optimizations that happen in the JIT when CodeGenOpt is set are a) which instruction selector is chose (fast isel vs selection dag), and b) whether any optimizations are run during the MC level passes.
If you want optimization on the IR level you'll need to create your own PassManager and add the passes you want to run.

Pin Like Tool for compile time injection of instrumentation code

As you might know, PIN is a dynamic binary instrumentation tool. By using Pin for example, I can instrument every load and store in my application. I was wondering If there is a similar tool which injects code at compile time (Using a higher level of information, not requiring us to write the LLVM pass), rather than at runtime like Pin. I am especially interested for such kind of tool for LLVM.
You could write LLVM passes of your own and apply them on your code to "instrument" it during compile time. These work on LLVM IR and produce LLVM IR, so for some tasks this will be a very natural thing to do and for other tasks it might be cumbersome or difficult (because of the differences between LLVM and IR and the source language). It depends.