Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why empty functions aren't removed as dead code in LLVM IR?

Starting with this simple C program:

void nothing(void) {}
int main() {
  int i;
  for (i = 0; i < 10; ++i) {
    nothing();
  }
  return 0;
}

My passes output as follows:
Note: IR statements are in Green.

; Function Attrs: nounwind readnone ssp uwtable
define void @nothing() #0 {
entry:
  ret void
}

; Function Attrs: nounwind readnone ssp uwtable
define i32 @main() #0 {
entry:
  ret i32 0
}

IR

Question: Using O3 which considered the highest level optimization, Why did nothing function hasn't been eliminated as a dead-code?

like image 333
Ahmed Ghoneim Avatar asked May 28 '16 03:05

Ahmed Ghoneim


People also ask

What is pass in LLVM?

The “Hello” pass is designed to simply print out the name of non-external functions that exist in the program being compiled. It does not modify the program at all, it just inspects it. The source code and files for this pass are available in the LLVM source tree in the lib/Transforms/Hello directory.

What is mem2reg?

-mem2reg : Promote Memory to Register This file promotes memory references to be register references. It promotes alloca instructions which only have loads and stores as uses.

What is i32 in LLVM?

i32 (i32*) * A pointer to a function that takes an i32*, returning an i32. Vectors. <4 x i32> Vector of 4 32-bit integer values. <8 x float> Vector of 8 32-bit floating-point values. <2 x i64> Vector of 2 64-bit integer values.

What is LLVM optimization?

LLVM divides the entire compilation process into three steps: Frontend: Convert the high-level language to IR. Middle-End: Perform optimization in the IR layer. Backend: Convert the IR into the assembly language of the corresponding hardware platform.


1 Answers

The compiler has to consider the possibility, that there is another translation unit that wants to call nothing(). Therefore it can't be removed. The most it can do is to optimize its call out, but the function itself has to stay and its symbol exported for possible external usage.

By defining nothing as static, you give it internal linkage, meaning that the compiler can assume nothing to be inaccessible outside the code it sees at the moment. This allows for optimizations, like choosing a different more performant calling convention, or in your case, eliminate the function altogether.

like image 135
a3f Avatar answered Sep 19 '22 08:09

a3f