Did you have issues with the Verifier complaining about function-local metadata after moving blocks? Did you find a good solution for this?
It looks like you are moving blocks or instructions with attached metadata to another function. Some metadata is function-specific, so the verifier complains because the instruction/BB and the metadata don't belong to the same function. Try creating a new metadata node (MDNode) as a copy of the old one (retrieving the old MDNode operands with getOperand()). Then link it to the instruction/BB, and unlink the old MDNode. For this, you have to lookup the MDNode kind ID in the instruction's MDNode list, and use setMetadata(kind, newMDNode). I'm saying this by heart, try googling "replace MDNode" or something like that.
I also seem to be having issues with the Verifier's DominatorTree analysis claiming that some of the instructions in the new function don’t dominate their uses in the new function, though they look like they do to me. This is probably a bug in my implementation, but if you remember specifically having to deal with regenerating Dominance information, that would be good to know.
I didn't have to regenerate dominance info. As far as I recall, this is a matter of 1) fixing the branch instructions, 2) fixing the Phi nodes, 3) not adding BBs in the wrong place. If you send me an IR file and the dominance-related error message, I might spot the mistake.
If you get that error, it's because there is at least a path down the CFG where a virtual register "use" is not preceded by its "def". Are you sure that you don't see anything suspicious? You can see what your passes are doing to the code at any compilation stage with dump() (all "Value"s can be dumped), or viewCFG() in the case of functions. For me, this is like the printf() of LLVM debugging
I’m also interested in playing with branching between the original code or one of a few variations of the extracted RPC based on some runtime info (such as where global addresses resolve to). Just out of curiosity, have you played with dynamically choosing between different HW mappings based on runtime info?
Yes, this is possible. Essentially, you replicate the outlined function. You then add a block that evaluates the branching condition, and branches to as many "caller" blocks as outlined replicas. Each caller block contains a call to one of the replicas. Of course, you have to know at compile time the condition upon which you'll base the branching decision.