src/CodeGen_LLVM.cpp
// Make a wrapper to call the function with an array of pointer
// args. This is easier for the JIT to call than a function with an
// unknown (at compile time) argument list.
Make a wrapper to call the function with an array of pointer
args. This is easier for the JIT to call than a function with an
unknown (at compile time) argument list.
Make a wrapper to call the function with an array of pointer args . This is easier for the JIT to call than a function with an unknown ( at compile time ) argument list .
llvm::Function *CodeGen_LLVM::add_argv_wrapper(const std::string &name) {
    llvm::Type *args_t[] = {i8_t->getPointerTo()->getPointerTo()};
    llvm::FunctionType *func_t = llvm::FunctionType::get(i32_t, args_t, false);
    llvm::Function *wrapper = llvm::Function::Create(func_t, llvm::GlobalValue::ExternalLinkage, name, module.get());
    llvm::BasicBlock *block = llvm::BasicBlock::Create(module->getContext(), "entry", wrapper);
    builder->SetInsertPoint(block);
    llvm::Value *arg_array = iterator_to_pointer(wrapper->arg_begin());
    std::vector<llvm::Value *> wrapper_args;
    for (llvm::Function::arg_iterator i = function->arg_begin(); i != function->arg_end(); i++) {
        llvm::Value *ptr = builder->CreateConstGEP1_32(arg_array, wrapper_args.size());
        ptr = builder->CreateLoad(ptr);
        if (i->getType() == buffer_t_type->getPointerTo()) {
            wrapper_args.push_back(builder->CreatePointerCast(ptr, buffer_t_type->getPointerTo()));
        } else {
            ptr = builder->CreatePointerCast(ptr, i->getType()->getPointerTo());
            wrapper_args.push_back(builder->CreateLoad(ptr));
        }
    }
    debug(4) << "Creating call from wrapper to actual function\n";
    llvm::CallInst *result = builder->CreateCall(function, wrapper_args);
    result->setIsNoInline();
    builder->CreateRet(result);
    internal_assert(!verifyFunction(*wrapper, &llvm::errs()));
    return wrapper;
}
llvm :: Function * CodeGen_LLVM :: add_argv_wrapper ( const std :: string & name ) { llvm :: Type * args_t [ ] = { i8_t -> getPointerTo ( ) -> getPointerTo ( ) } ; llvm :: FunctionType * func_t = llvm :: FunctionType :: get ( i32_t , args_t , false ) ; llvm :: Function * wrapper = llvm :: Function :: Create ( func_t , llvm :: GlobalValue :: ExternalLinkage , name , module . get ( ) ) ; llvm :: BasicBlock * block = llvm :: BasicBlock :: Create ( module -> getContext ( ) , " " , wrapper ) ; builder -> SetInsertPoint ( block ) ; llvm :: Value * arg_array = iterator_to_pointer ( wrapper -> arg_begin ( ) ) ; std :: vector < llvm :: Value * > wrapper_args ; for ( llvm :: Function :: arg_iterator i = function -> arg_begin ( ) ; i != function -> arg_end ( ) ; i ++ ) { llvm :: Value * ptr = builder -> CreateConstGEP1_32 ( arg_array , wrapper_args . size ( ) ) ; ptr = builder -> CreateLoad ( ptr ) ; if ( i -> getType ( ) == buffer_t_type -> getPointerTo ( ) ) { wrapper_args . push_back ( builder -> CreatePointerCast ( ptr , buffer_t_type -> getPointerTo ( ) ) ) ; } else { ptr = builder -> CreatePointerCast ( ptr , i -> getType ( ) -> getPointerTo ( ) ) ; wrapper_args . push_back ( builder -> CreateLoad ( ptr ) ) ; } } debug ( 4 ) << " \n " ; llvm :: CallInst * result = builder -> CreateCall ( function , wrapper_args ) ; result -> setIsNoInline ( ) ; builder -> CreateRet ( result ) ; internal_assert ( ! verifyFunction ( * wrapper , & llvm :: errs ( ) ) ) ; return wrapper ; }
Make a wrapper to call the function with an array of pointer
args.
Make a wrapper to call the function with an array of pointer args .
// Get the address of the nth argument // Cast the argument to a buffer_t * // Cast to the appropriate type and load // This call should never inline