0

As the title states, my goal is to convert static array (e.g., int[16]) to dynamic array in the LLVM IR level. I have an idea of how to do it (which I will describe below), but I wondered whether there is a nicer alternative approach.

There are various ways in the C source level (Static array vs. dynamic array in C++ and How to convert static array to dynamic array in c?) already explained as shown above.

However, these methods are not applicable for the LLVM IR level at least from what I see.

For a C source code below:

  /* ----- First case; Static array ----- */
  char a[16];
  a[1] = '1';

  /* ----- Second case; Dynamic array ----- */
  unsigned char *a = malloc(16*sizeof(char));
  *a  = '1'; 

Following LLVM IR is generated:

   /* ----- First case; Static array ----- */
   %2 = alloca [16 x i8], align 1
   %3 = getelementptr inbounds [16 x i8], [16 x i8]* %2, i64 0, i64 0
   ...
   %6 = getelementptr inbounds [16 x i8], [16 x i8]* %2, i64 0, i64 1
   store i8 49, i8* %6, align 1

   /* ----- Second case; Dynamic array ----- */
  %2 = alloca i8*, align 8
  %3 = call noalias align 16 i8* @malloc(i64 16) #3
  store i8* %3, i8** %2, align 8
  ...
  %7 = load i8*, i8** %2, align 8
  %8 = getelementptr inbounds i8, i8* %7, i64 1
  store i8 49, i8* %8, align 1

So the approach I was thinking of was to try to convert its respective instructions to the counterparts as follows using IRBuilder (just an example for alloca)

(e.g., %2 = alloca [16 x i8], align 1 -> %2 = alloca i8*, align 8) and then so on...

However, I feel this approach is first terrible in terms of scaling and second, very naive.

Therefore, I have been brainstorming ways to convert static arrays to dynamic arrays at the IR level, but I am a bit at a loss, so I wanted to hear any suggestions other LLVM programmers may have that I missed (maybe useful APIs that I am missing).

I have figured out the approach to find static array and which Value *, so at least those are taken care of.

Please let me know if anything is unclear or I need to expand.

Sincerely,

Ken White
  • 120,522
  • 13
  • 212
  • 426
Jay
  • 147
  • 7
  • 1
    What you're doing is roughly the right way. If you look at other passes you'll see that many of them follow the same pattern: First scan the instructions in a function to find candidates for change. Then do the change. The scanning may have several phases and often one or more is outsourced to a specialised analysis pass, but in this case I don't think an analysis pass will help you very much. – arnt Jan 17 '22 at 09:39

0 Answers0