How to write a interprocedural optimization in LLVM backend?


I’m wondering how can I write a global optimization pass in the LLVM backend.
What I’m going to do is to merge constant pool entries that are shared
between different machine functions and emit these shared entries
in proper places between the functions.

For example, if foo and bar use the same global variable var, I’d like to
generate something like the following:


code of foo

load r0, .LCPI_0
load r0, r0 # load var

other code of foo

.long var # address of var


code of bar

load r0, .LCPI_0
load r0, r0 # load var

other code of bar

The reason doing this is to reduce the code size as much as possible.
Our backend has a very limited PC-relative displacement for load/store instructions.
I’ve tried the way that ARM and MIPS backend do (ConstantIslandPass),
but it does not share constant pool entries between functions and
increases code size in general.

It is possible to write a moudle pass in machine instruction level? If possible,
how to do it? Any help is welcome. Thanks.