6

I have found myself with a reasonably large number of useful functions and constants written in LLVM's IR. I can use this pseudo-library by combining it with hand written IR, provided said hand written IR starts with a potentially lengthy list of declarations. I'm aware that IR isn't necessarily designed as a general purpose programming language to write stuff in.

This is much like writing a lot of C functions in one file then redeclaring them wherever they are used. In C this is worked around using #include and header files. That's not perfect, but it beats writing out the prototypes repeatedly.

What's the least nasty way to achieve something similar in IR? It only has to beat typing the stuff out over and over again (which I currently do in copy & paste fashion) and using cat as a custom build step.

Thanks!

Jon Chesterfield
  • 2,251
  • 1
  • 20
  • 30
  • I doubt there is a way. You could've used `cpp` to preprocess LLVM IR sources, but I'm afraid its syntax may clash with preprocessor stuff. – arrowd Sep 12 '17 at 14:05

2 Answers2

3

Sadly there is no such thing in LLVM IR.

LLVM IR isn't designed to have large amounts of it written by hand. Therefore it doesn't have a #include mechanism. The job of handling that kind of stuff falls onto the compiler using the LLVM API.

One thing you could do however if you want to achieve the same effect is either to try to see if someone else's preprocessor will work for what you're trying to do or write a custom preprocessor yourself.

caa515
  • 328
  • 2
  • 8
  • This appears to be the case. I wonder how painful it would be to implement. The use case is testing LLVM itself - lots of unit tests get written in IR and I'd like to factor out some of the boilerplate. – Jon Chesterfield Sep 27 '17 at 11:27
  • I'd say your best bet is just to write a mini preprocessor. You could probably build one in just like an hour or two (Or maybe even less). – caa515 Sep 27 '17 at 21:11
2

You can use llvm-link for combining different IRs together.

For example, you have the following sequence.

// file : f1.ll
; Function Attrs: nounwind readnone
define i32 @f1(i32 %a) #0 {
entry:
  ret i32 %a
}

// file : f2.ll
; Function Attrs: nounwind
define i32 @f2(i32 %a) #0 {
entry:
%call = tail call i32 @f1(i32 %a) #2
 ret i32 %call
}

Then you can call

llvm-link f1.ll f2.ll -S -o ffinal.ll

ffinal.ll would contain both IR codes.

ConsistentProgrammer
  • 1,294
  • 10
  • 14
  • llvm-link means I don't have to reimplement the library in every source file but doesn't seem to provide a way to avoid redeclaring the interface in every source file. Can you show an example of using llvm-link to avoid writing all the declarations? – Jon Chesterfield Sep 27 '17 at 11:26
  • You need to have that `declare` keyword. I think there is not other way possible – ConsistentProgrammer Sep 27 '17 at 11:52