What to pass for the vmap argument of CloneFunction in llvm? - llvm

I am trying to clone the exact copy of another function. I have not been able to find any examples of CloneFunction usage on the internets.

It turns at the you can just create a ValueToValueMapTy variable and pass it without initialization.

The following code segment is enough for cloning the function called Func
ValueToValueMapTy VMap;
auto *Clone = CloneFunction(Func, VMap);
rahib bob

Related

How to insert a function in LLVM module

I am writing an LLVM pass, where I clone some functions by calling llvm::CloneFunction. Now I also want to insert those functions in the module. How can I do that?
Create a new function with Function::Create or by other means. A Function's constructors accept a module into which to insert the new function.
Clone a function into that new function with CloneFunctionInto, or just copy over the BBs you need.
CloneFunction will automatically insert the new Function into the old Function's module. From the doxygen:
Return a copy of the specified function and add it to that function's module.
You can use CloneFunction and insert it into the module afterwards like so
Function* duplicateFunction = CloneFunction(F, VMap,
/*ModuleLevelChanges=*/false);
F->getParent()->getFunctionList().push_back(duplicateFunction);
Example stolen from PartialInlining.cpp in the llvm source.

move function body, avoiding full cloning

This is a follow up question from this one.
I am using llvm::CloneFunctionInto defined in llvm/Transforms/Utils/Cloning.h in order to create a new function after code generation with the right signature inferred from the type of the return values. This works nicely but it is slow
I am trying to optimize this a little bit by some way to move or transfer the function body from the old function to the new one, is there a utility for that?
I am trying to hack a way to do the transfer by looking at the code in CloneFunctionInto, but wanted to see if an existing function exists
Shamelessly stolen from the Arg Promotion pass (search for splice):
// Since we have now created the new function, splice the body of the old
// function right into the new function, leaving the old rotting hulk of the
// function empty.
NF->getBasicBlockList().splice(NF->begin(), F->getBasicBlockList());
Where NF is the new function you're cloning into and F is the old function that you have just cloned.

Custom bindings with boost::python [duplicate]

I am trying to achieve call Python functions from C++. I thought it could be achieved through function pointers, but it does not seem to be possible. I have been using boost.python to accomplish this.
Say there is a function defined in Python:
def callback(arg1, arg2):
#do something
return something
Now I need to pass this function to C++, so that it can be called from there. How do I write the code on C++ side using boost.python to achieve this?
If it might have any name:
Pass it to a function that takes a boost::python::object.
bp::object pycb; //global variable. could also store it in a map, etc
void register_callback(bp::object cb)
{
pycb = cb;
}
If it is in a single known namespace with a consistent name:
bp::object pycb = bp::scope("namespace").attr("callback");
bp::object has operator() defined, so you call it just like any function
ret = pycb()
Not a clue. But you can use PyObject_Call() to call it once you have the function object.
I've not used it before, but the reference manual has a section called Calling Python Functions and Methods which seems to show how to do this.
I used PyRun_SimpleString("myFunction()") as quick hack, as my function's name was known, took no args and lived in the __main__ namespace. Note you additionally need to get lock GIL if you are multi-threaded.

changing llvm::Function signature after code generation, before last CreateRet

I'm trying to implement the following functionality;
a function with no explicit return will by default return the last evaluation in the last executed block
So, currently the process i'm doing is
1) create a Function
llvm::Function* result = llvm::Function::Create(Compiler::Detail::getAnonymousFunctionSignature(llvmContext),
llvm::GlobalValue::ExternalLinkage,
name,
module());
result->setCallingConv( llvm::CallingConv::C );
2) add blocks and evaluations to the blocks
builder.createFoo.....
However, only in the second phase i have the llvm::Value* (and compile-time type) that i want to use by default as return value. The problem is that i need to use this type to determine the signature of the created function
Question:
how do i solve the problem?
is possible to change the signature after the function is created? is it legal?
do i need to create a new function with the updated signature and copy/assign the entry block of the first function to it and thats it? or do i need to reevaluate all the expressions?
is possible to not create the function before code generation? if it is so, at what point should i create the function?
a code example of how to achieve this would be awesome. thanks!
You cannot change function signature, because this will mean that it will have different Type (and thus you will need to update all the users, etc.; this procedure in most cases cannot be done automagically).
There are multiple possible solutions, for example, you can create the function with the updated signature, then use the functions from lib/Transforms/Utils/CloneFunction.cpp to copy the function body and then hack on the return type.
A better solution exists than CloneFunctionInto(), according to https://stackoverflow.com/a/18751365/2024042:
NF->getBasicBlockList().splice(NF->begin(), F->getBasicBlockList());
Where NF is the new function you're cloning into and F is the old function that you have just cloned.

How did I break inheritance?

Refactored from bug_report_view.cc and bug_report_view.h, I extracted send_report(), report_phishing(), a few other smaller functions and BugReport::Cleanup into bug_report.cc and bug_report.h (my versions). Compiling now, I get:
[...]bug_report.cc:196: error: no matching function for call to ‘URLFetcher::URLFetcher(std::wstring&, URLFetcher::RequestType, BugReport::PostCleanup*)’
../chrome/browser/net/url_fetcher.h:136:
note: candidates are: URLFetcher::URLFetcher(const URLFetcher&)
../chrome/browser/net/url_fetcher.h:82:
note: URLFetcher::URLFetcher(const GURL&, URLFetcher::RequestType, URLFetcher::Delegate*)
For some reason, BugReport::PostCleanup (in my version) isn't recognized as a subclass of URLFetcher::Delegate, but BugReportView::PostCleanup (in the first links) is. So where did I mess up? Thanks.
The problem is not the type of the PostCleanup class. The problem is the type of the first parameter to the URLFetcher class constructor. The constructor expects a GURL &, you are passing a std::wstring called post_url. You will need to perform some kind of conversion between the two. Possibly something like this would be appropriate:
GURL post_url(l10n_util::GetString(IDS_BUGREPORT_POST_URL));
URLFetcher* fetcher = new URLFetcher(post_url, URLFetcher::POST,
new BugReport::PostCleanup);
In the code you have modified, the class has a GURL member which is initialised in the constructor, you have changed it to a variable referenced only in that one function, but changed the type.
At:
URLFetcher* fetcher = new URLFetcher(post_url, URLFetcher::POST,
new BugReport::PostCleanup);
it can't find an URLFetcher constructor thzat takes the parameters youn give it - the problem is presumably in url_fetcher.h, which you haven't shown.
BTW, there are a lot of other problems and bad practices exhibited in your code - it would be a good idea to instigate a full code review ASAP.
First version used member variable post_url_ second just local variable post_url.
Please describe what is GURL type - it is typedef on std::wstring or something other.