Optimizing Internal Representation And Algorithmic Differentiation

I am considering using llvm to optimize the computational graph recorded by an Algorithmic Differentiation (AD) package. These graphs can have a huge number of floating point operations.

I plan to convert the graph to LLVM, optimize it, and then have two options:
One option would be to convert it to a JIT function that can be linked from C++.
The other is to convert it back to a computation graph for other operations by the AD package.

One approach is to create an ll file and have clang optimize it. Bitcode would be an improvement if this works.
Perhaps there is an in memory representation that would be even more efficient ?
How would I convert the optimized ll file to a JIT function ?
How would I parse the optimized ll file in-order to generate the computational graph expected by the AD package ?

Another approach is to generate an IR representation of the function using a technique similar to the HowToUseLLJT.cpp example. Optimize this representation, and then convert that back to the computational graph expected by the AD package.
In this approach I plan to use the inst_iterator to iterate through the instructions corresponding to the optimized function to generate the AD computational graph.
Would this approach be more efficient ?