I am writing a program optimization, which involves adding new functions, removing lines of code, inserting function calls and changing arguments to functions.
Is all this possible using an LLVM Pass, and if yes how would I write such a code for this?
Having had a look at the how to write an LLVM pass page on the LLVM website, it does not explain anything about altering code.
This is a really good guide to start off writing pass. It also has an example how to change code.
Related
I am working on a project for which I need to "combine" code distributed over multiple C++ files into one file. Due to the nature of the project, I only need one entry function (the function that will be defined as the top function in the Xilinx High-Level-Synthesis software -> see context below). The signature of this function needs to be preserved in the transformation. Whether other functions from other files simply get copied into the file and get called as a subroutine or are inlined does not matter. I think due to variable and function scopes simply concatenating the files will not work.
Since I did not write the C++ code myself and it is quite comprehensive, I am looking for a way to do the transformation automatically. The possibilities I am aware of to do this are the following:
Compile the code to LLVM IR with inlining flags and use a C++/C backend to turn the LLVM code into the source language again. This will result in bad source code and require either an old release of Clang and LLVM or another backend like JuliaComputing. 1
The other option would be developing a tool that relies on using the AST and a library like LibTooling to restructure the code. This option would probably result in better code and put everything into one file without the unnecessary inlining. 2 However, this options seems too complicated to put the all the code into one file.
Hence my question: Are you aware of a better or simply alternative approach to solve this problem?
Context: The project aims to run some of the code on a Xilinx FPGA and the Vitis High-Level-Synthesis tool requires all code that is to be made into a single IP block to be contained in a single file. That is why I need to realise this transformation.
I need to define functions in c++ code to be user defined. Basically that he writes the function in form of a string which is exact c++ code, then use that function in the very next line of code.
I have tried to append output to a file which is imported, but it obviously failed
You simply cannot do it. C++ code can not be interpreted at run-time. You may want to try Qt/QML which will give an opportunity to run a javascript code or an entire QML file from network/string or any other method which can deliver your code to the host application.
I assume you are talking about a pure function such as a mathematical formula.
To my knowledge, what you ask is not possible without
a) writing your own parser, that effectively creates functions from strings or
b) using external libraries - a quick google search brought be to this library that seems to provide the functionality you are looking for. I have no personal experience with it, though.
As #Useless pointed out, "editing" the code after compilation is not intended in a compiled language as c++. This could be tricked by having a second code compiled and executed in the background; this, however, seems rather unelegant and would rely on additional threads, compilers and the operating system.
Generally, I see many people using :
CallSite CS(function->use_back());
to create callsite.
However, use_back() seems not appear in the lately released LLVM. So how can achieve the same goal in the newest LLVM.
How about Value::uses().Remember to take care of ConstantExprs and whatnot because in some cases the functions will go through a BitCastConstantExpr before being called
I do not quite understand the definition of pass in the llvm. Does it mean I can only use opt command to run the program?
My situation is like I want to find loops in a CFG of basic blocks and I want to use LLVM API instead of writing code by myself. I found a file called Loopinfo http://llvm.org/docs/doxygen/html/LoopInfo_8h_source.html which includes pass.h and class passinfo inherited from Functionpass. Does it mean I can only use opt command to call instead of writing a normal project which uses some of class's functions and build and execute? I hope I clarified my question clearly.
You can analyze and manipulate LLVM IR just fine without knowing anything about passes. Just use the LLVM API and you'll be OK.
So what's the deal with passes? Well, if you do write your analysis or transformation in the form of a pass - by following this guide - you can still just use it as any regular C++ class1, but you get some advantages:
You can use the opt tool to run your pass. It will take care of everything else for you (e.g. loading the IR), it makes it very easy to run other passes before or after your pass (including the useful verification pass), makes it easy to enable/disable debug mode, etc.
You can easily combine your pass with other passes using a pass manager, which is very convenient (will take care of pass dependencies for you, for example).
So in general, writing things in the form of passes is recommended but not required.
1 Well if you define requirements on other passes then you'll have to run those yourself if you're not using opt or a pass manager
The easiest way is to add pass executed via opt command. But, you should be able to create dedicated executable which reads LLVM bitcode, performs your pass and writes bitcode back.
See here for an example:
Parsing and Modifying LLVM IR code
Source of opt command might also be useful:
https://llvm.org/svn/llvm-project/llvm/trunk/tools/opt/opt.cpp
learned english as a second lang, sorry for the mistakes & awkwardness
I have given a peculiar project to work on. The company has lost the source code for the app, and I have to make changes to it. Now, reverse engineering the whole thing is impossible for one man, its just too huge, however patching individual functions would be feasible, since the changes are not that monumental.
So, one possible solution would be compiling C code and somehow -after rewriting addresses- patching it into the actual binary, ideally, replacing the code the CALL instruction jumps to, or inserting a JMP to my code.
Is there any way to accomplish this using MingW32? If it is, can you provide a simple example? I'm also interested in books which could help me accomplishing the task.
Thanks for your help
I use OllyDBG for this kind of things. It allows you to see the disassembly and debug it, you can place breakpoints etc, and you can also edit the binary. So, you could edit the PE header of that program adding a code section with your (compiled) code inside, then call it from the original program.
I can't give you any advice since I've never tried, although I thought about it many times. You know, lazyness.. :)
I would disassemble the program with a high-quality disassembler that produces something that can be assembled back into a runnable app, and then replace the parts you need to modify with C code.
Something like this will let you reverse the machine code into source. It won't be pretty but it does work.
http://www.hex-rays.com/idapro/
There are also tools for runtime patching http://www.dyninst.org/ for instance. They really aren't made for patching but they can do the trick.
And of course the last choice is to just use an assembler and write machine code :)