clang: call extern function using JIT

hi, im creating a music application(image below).

At the moment im using tcc compiler but im moving across to clang because of
the improved compiler warnings.
Can anyone please explain and show code so I can use clang's JIT to call
functions in my application?

Thanks.

http://old.nabble.com/file/p29449300/51709341.jpeg

You'll probably want to take a look at the Kaleidoscope tutorial[1] on how to get
the JIT up and running inside an application of its own. If you can give me
a little more information as to what you're trying to JIT it'd be helpful.

-eric

[1] http://llvm.org/docs/tutorial/

Can someone pease tell me what I am doing wrong?

Im trying to register an external function with the JIT, so can call
functions in my music

application.

Here my function

int Execute(llvm::Module *Mod, char * const *envp) {
  llvm::InitializeNativeTarget();

  std::string Error;
  llvm::OwningPtr<llvm::ExecutionEngine> EE(
    llvm::ExecutionEngine::createJIT(Mod, &Error));
  if (!EE) {
    llvm::errs() << "unable to make execution engine: " << Error << "\n";
    return 255;
  }

  // code I have added

gafferuk <gafferuk@gmail.com> writes:

Can someone pease tell me what I am doing wrong?

It is hard to say because you don't say what the problem is, but let's
try.

Im trying to register an external function with the JIT, so can call
functions in my music

application.

Here my function

int Execute(llvm::Module *Mod, char * const *envp) {
  llvm::InitializeNativeTarget();

It is not necessary to call InitializeNativeTarget each time. One is
enough.

[snip]

  llvm::FunctionType* ft = llvm::FunctionType::get(llvm::Type::getInt32Ty

(llvm::getGlobalContext()),
    std::vector<const llvm::Type*>(0, llvm::Type::getInt32Ty

_______________________________________________^

You are creating a vector of Type's with *zero* elements, so the effect
of this is a FuntionType that takes zero arguments.

[snip]

Next time please be more explicit on the descripcion of the problem.

Im trying to call fuctions in my music application from c code which will be
used by the JIT.

Here my function, i have made no other changes to the clang interpreter
example. Can you see anything else I have to add to either the fuction below
or to the c code to be JIT at the bottom?

// function I wish to call.
int yipee(int aVar)
{
    aVar = 5;
}

int Execute(llvm::Module *Mod, char * const *envp) {
  llvm::InitializeNativeTarget();

  std::string Error;
  llvm::OwningPtr<llvm::ExecutionEngine> EE(
    llvm::ExecutionEngine::createJIT(Mod, &Error));
  if (!EE) {
    llvm::errs() << "unable to make execution engine: " << Error << "\n";
    return 255;
  }

  // code I have added

ok, i have changed functionType code to:

  llvm::FunctionType* ft =
llvm::FunctionType::get(llvm::Type::getInt32Ty(llvm::getGlobalContext()),
    std::vector<const llvm::Type*>(1,
llvm::Type::getInt32Ty(llvm::getGlobalContext())), false);

when I run my app the compiler says:
E:\Projects\Whistle\Whistle\Release>Whistle file.c
file.c(3) : warning: implicit declaration of function 'yipee' is invalid in
C99

      [-Wimplicit-function-declaration]
    int dd = yipee(1);
             ^
1 warning generated.
LLVM ERROR: Program used external function 'yipee' which could not be
resolved!
Stack dump:
0. Running pass 'X86 Machine Code Emitter' on function '@main'

and if I change the code to be ran on the JIT to this:

extern int yipee;
int main()
{
    int dd = yipee(1);

    return 0;
}

I get this error:

E:\Projects\Whistle\Whistle\Release>Whistle file.c
file.c(5) : error: called object type 'int' is not a function or function
      pointer
    int dd = yipee(1);
             ~~~~~^
1 error generated.

Óscar Fuentes wrote:

Hello

Im trying to call fuctions in my music application from c code which will be
used by the JIT.

Here my function, i have made no other changes to the clang interpreter
example. Can you see anything else I have to add to either the fuction below
or to the c code to be JIT at the bottom?

And still you haven't said which problem you're seeing. Sorry, but
telepathy module
is off due to maintenance :slight_smile:

when I run my app the compiler says:
E:\Projects\Whistle\Whistle\Release>Whistle file.c
file.c(3) : warning: implicit declaration of function 'yipee' is invalid in
C99

 \[\-Wimplicit\-function\-declaration\]

int dd = yipee(1);
^

This way you're creating a call to variadic function. It's of different type
compared to function you're binding to.

Im confused. The function i wish to call is a return type of int.
Im calling it with int dd = yipee(1);

What's wrong?

Anton Korobeynikov-2 wrote:

gafferuk <gafferuk@gmail.com> writes:

Im confused. The function i wish to call is a return type of int.
Im calling it with int dd = yipee(1);

What's wrong?

Declare the function:

int yipee(int);
int main()
{
    int dd = yipee(1);

    return 0;
}

If that still crashes, put a breakpoint on `yipee' and see if the
execution gets there, if the argument is right, if the crash happens
inside the function or after it returns...

Im confused. The function i wish to call is a return type of int.

You're creating the function which returns i32 and have exactly one i32 argument

Im calling it with int dd = yipee(1);

This way you're calling int yipee(...) according to C standard
(because you haven't declared this previously).

What's wrong?

I have not idea, but this is at least one thing which needs to be addressed.

I tried what you said, now I get:

LLVM ERROR: Program used external function 'yipee' which could not be
resolved!
Stack dump:
0. Running pass 'X86 Machine Code Emitter' on function '@main'

did not even get as far as a breakpoint.

Óscar Fuentes wrote:

Heres my full code listing, im totally stuck.

// Whistle.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "clang/CodeGen/CodeGenAction.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Tool.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Support/TypeBuilder.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Config/config.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Config/config.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Host.h"
#include "llvm/System/Path.h"
#include "llvm/Target/TargetSelect.h"
using namespace clang;
using namespace clang::driver;

extern "C"
int yipee(int val)
{
  fprintf(stderr, "yipee!");

  return 1;
}

llvm::sys::Path GetExecutablePath(const char *Argv0) {
  // This just needs to be some symbol in the binary; C++ doesn't
  // allow taking the address of ::main however.
  void *MainAddr = (void*) (intptr_t) GetExecutablePath;
  return llvm::sys::Path::GetMainExecutable(Argv0, MainAddr);
}

int Execute(llvm::Module *Mod, char * const *envp) {
  llvm::InitializeNativeTarget();

  std::string Error;
  llvm::OwningPtr<llvm::ExecutionEngine> EE(
    llvm::ExecutionEngine::createJIT(Mod, &Error));
  if (!EE) {
    llvm::errs() << "unable to make execution engine: " << Error << "\n";
    return 255;
  }

  // code I have added

See my reply to your other post.