Hey everyone. I’m building a new backend for Glow called NMP (from NeuroMorphic Processor). It is an embedded device to make inferences from convolutional neural networks. So far I’ve used stubs functions (libjit_nmp) to develop the code generator, similar to LLVMIRGen. When I replace the stubs functions with function declarations, the getFunction() called inside the NMPIRGen module always returns nullptr. Note that the definitions of the functions are external (libobj_nmp) as they need to be compiled with GCC because of the device-specific toolchain that was only developed for GCC. Basically what I have in libjit folder now is a header file containing the function declarations and a few variables and constants defined in the source file. What I need is for the clang to keep the declarations in libjit_nmp.bc so that the NMPIRGen module can generate code in the main function to perform their calls. These references would then be resolved at link time with the lib_nmp.o library. Any ideas how to solve this?
Yeah, the problem with the bitcode file generation is that Clang does not store LLVM IR function declarations if they are not really used, i.e. if these functions are not invoked inside the library.
Here are a couple possible work-arounds:
You could add some empty bodies to your function declarations just to make Clang emit them into the BC file. Then, you can add some code at the very beginning of the your LLVMIRGen to remove the bodies from such functions (maybe based on their names or naming convention). This way they become declarations of external functions. Your code will compile just fine and you’ll be able to link them against the actual implementations from your GCC-compiled libraries.
Alternatively, you could at the very beginning of the your LLVMIRGen add the code to create declarations of your external functions using LLVM APIs for creating functions. The rest should just work.
Please let me know if these solutions would work for you.
Thanks, Roman L for your feedback. I worked around this issue by creating wrappers for the external functions. This adds indirection but with clang optimization, it doesn’t affect performance.