[LLVMdev] Constant function pointers and inlining

Joonas Govenius joonas.govenius at gmail.com
Thu Jun 19 06:38:01 PDT 2008


I've been working on turning PHP scripts into LLVM IR and I've gotten
to the stage where I'm able to construct LLVM code that calls the PHP
opcode handlers that I've pre-compiled to LLVM IR in the correct
order. However, the PHP API is designed so that the handlers are not
globally accessible (qualified by "static" in the C source). Instead
they're supposed to be accessed like this (in C):

  zend_op op;
  op.opcode = ... // set the opcode number etc.
  zend_vm_set_opcode_handler(&op); // let the engine figure out which
handler should be used
  op->handler(...);  // execute it

Now, the compiler can't know that zend_vm_set_opcode_handler() always
sets the handler to be the same but I do so I'm trying to do this at
compile time (of the PHP function). However, once I get the
GenericValue that points to the handler, I don't really know how to
turn that to a constant function pointer in LLVM. What I do is rather

  Value* handler = ConstantExpr::getIntToPtr(
      (unsigned int) engine->runFunction(get_handler, args).PointerVal),
    PointerType::get(handler_type, 0));

  /* ^^^^^ Is there a better way to do the conversion?  ^^^^^^ */

  Value* result = builder.CreateCall2(handler,

And as a result I get handler calls like this:

  %execute_result9 = tail call i32 inttoptr (i32 54000728 to i32
(%struct.zend_execute_data*, i8***)*)( %struct.zend_execute_data*
%execute_data, i8*** %1 )

However, I haven't able to make LLVM inline these calls. Is there some
reason why that's impossible or have I just not found the right
optimization passes to apply?


More information about the llvm-dev mailing list