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.
Related
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
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.
I need to do heavy instrumentation using a LLVM pass. I want to avoid the IR Builder because it is somehow complicated and the code looks really messy. Isn't there a more convenient way to create LLVM IR? I think of a way where I can use for example C/C++ to create the instrumented code.
I do not use the IR Builder for my instrumentation. Most of the instrumentation is accomplished with two steps:
The LLVM pass identifies the instructions of interest and inserts function calls to the requisite instrumentation routine.
The instrumentation routines are written in C files and compiled and linked into the final program. Using link-time optimization (LTO), this approach achieves good performance by removing the function calls and directly inserting the machine code for the library instrumentation routines.
Therefore, most of the instrumentation is C code that clang compiles down to necessary IR.
Other pieces of instrumentation have to be crafted dynamically, so the IR is constructed by invoking the appropriate XYZInst::Create calls, where XYZ is the specific instruction.
The first approach is closer to what you desire; however, it required writing a separate script to act as the compiler driver and managing Makefiles, libraries, et cetera.
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.
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.