Search code examples
c++llvminstrumentation

What does CallInst::Create() return in LLVM?


Considering

static CallInst *Create(Value *Func,
                      ArrayRef<Value *> Args,
                      const Twine &NameStr = "",
                      Instruction *InsertBefore = 0)

this function, I wonder what the return value of this function means.

For example, in following code,

int foo(int a);
...
Function *foo_ptr = ~~;//say, foo is refered through getOrInsertFunction()
CallInst *ptr = CallInst::Create(foo_ptr, .../* properly set */);

the CallInst *ptr is the return value. Abstractly, does ptr mean

  1. an integer value returned by int foo(int);
  2. or CALL instruction

I thought number 2 was the answer, but started to get confused looking at some codes.


Solution

  • Both 1 and 2 are "true". It returns the call instruction, whose "value", when we execute the code, will be the return value of the function.

    To illustrate, take this little Pascal program:

    program p;
    
    function f: integer;
    begin
       f := 42;
    end; { f }
    
    begin
       writeln(f);
    end.
    

    Which translates to this LLVM-IR:

    ; ModuleID = 'TheModule'
    target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
    target triple = "x86_64-unknown-linux-gnu"
    
    %text = type { i32, i8*, i32, i32 }
    
    @input = global %text zeroinitializer, align 8
    @output = global %text zeroinitializer, align 8
    @UnitIniList = constant [1 x i8*] zeroinitializer
    
    define i32 @P.f() #0 {
    entry:
      %f = alloca i32, align 4
      store i32 42, i32* %f
      %0 = load i32, i32* %f
      ret i32 %0
    }
    
    define void @__PascalMain() #0 {
    entry:
      %calltmp = call i32 @P.f()
      call void @__write_int(%text* @output, i32 %calltmp, i32 0)
      call void @__write_nl(%text* @output)
      ret void
    }
    
    declare void @__write_int(%text*, i32, i32)
    
    declare void @__write_nl(%text*)
    
    attributes #0 = { "no-frame-pointer-elim"="true" }
    

    The call i32 @P.f() is generated by:

    inst = builder.CreateCall(calleF, argsV, "calltmp");
    

    The contents of inst is %calltmp = call i32 @P.f() - and that is a CallInst 'value'.

    and inst is returned to the evaluation of the expression for the argument to writeln.