EH and C++ intergation

I was going through documentation and source lately, and I decided how to
make llvm bytecode more compatible to C++:
1) thiscall sould be introduced, which would take N arguments and the
first argument would always be the C++ "this" argument. This would
abstract llvm compiler dependant C++ code emittion.

2) the ret instruction should be able to return structs (as Chris has
already written on his page).

3) the EH could be done at code emission and would leave bytecodes
portable. Each backend would emit code compatible (if possible) with the
compiler it is compiled with; if llvm is compiled with VC8, it would emit
code compatible with VC8.

I will probably soon begin with development. Please let me know if there
is any thing more I need to consider/know, or if there is someting wrong
with the design. Also, any help (especially the thing with struct returns)
would be very welcomed. In my opinion this is a big feature required by llvm.

Regards,
®iga

I was going through documentation and source lately, and I decided how to
make llvm bytecode more compatible to C++:
1) thiscall sould be introduced, which would take N arguments and the
first argument would always be the C++ "this" argument. This would
abstract llvm compiler dependant C++ code emittion.

Sure. Anton can give you ideas for this.

2) the ret instruction should be able to return structs (as Chris has
already written on his page).

This won't help C++ or C.

3) the EH could be done at code emission and would leave bytecodes
portable. Each backend would emit code compatible (if possible) with the
compiler it is compiled with; if llvm is compiled with VC8, it would emit
code compatible with VC8.

I agree for unwind tables, this is what the invoke/unwind abstraction are for. For RTTI, there is nothing the compiler can do to shield you from front-end dependencies.

-Chris

Chris Lattner pravi:

I was going through documentation and source lately, and I decided how to
make llvm bytecode more compatible to C++:
1) thiscall sould be introduced, which would take N arguments and the
first argument would always be the C++ "this" argument. This would
abstract llvm compiler dependant C++ code emittion.

Sure. Anton can give you ideas for this.

I think it should not be too difficult because you allow custom call conversions and this is quite easy to add, we only have to garantee that the backend will emit it.

2) the ret instruction should be able to return structs (as Chris has
already written on his page).

This won't help C++ or C.

I don't agree. For example:

struct SmartPtr { void* px; shared* py; }

Now, if I write the following method signature in C++:
SmartPtr foo(int whatever);

When I return, the llvm cannot return value in registers what is required by Visual C++ (or at least I think it is). I am posing
this issue because I really need this feature in llvm for my project.

Sure. Anton can give you ideas for this.

I think it should not be too difficult because you allow custom call
conversions and this is quite easy to add, we only have to garantee that
the backend will emit it.

Right.

2) the ret instruction should be able to return structs (as Chris has
already written on his page).

This won't help C++ or C.

I don't agree. For example:

struct SmartPtr { void* px; shared* py; }

Now, if I write the following method signature in C++:
SmartPtr foo(int whatever);

When I return, the llvm cannot return value in registers what is
required by Visual C++ (or at least I think it is). I am posing
this issue because I really need this feature in llvm for my project.

You're missing one piece: LLVM types are not C/C++ types, they have to be lowered. This lowering discards some information, which can affect the ABI (e.g. some ABIs treat a 'complex double' differently than a struct with two doubles). LLVM types are not sufficient for making ABI decisions, at least some part of the abi decision currently needs to be made by the front-end.

-Chris

Chris Lattner pravi:

Sure. Anton can give you ideas for this.

I think it should not be too difficult because you allow custom call
conversions and this is quite easy to add, we only have to garantee that
the backend will emit it.

Right.

2) the ret instruction should be able to return structs (as Chris has
already written on his page).

This won't help C++ or C.

I don't agree. For example:

struct SmartPtr { void* px; shared* py; }

Now, if I write the following method signature in C++:
SmartPtr foo(int whatever);

When I return, the llvm cannot return value in registers what is
required by Visual C++ (or at least I think it is). I am posing
this issue because I really need this feature in llvm for my project.

You're missing one piece: LLVM types are not C/C++ types, they have to be lowered. This lowering discards some information, which can affect the ABI (e.g. some ABIs treat a 'complex double' differently than a struct with two doubles). LLVM types are not sufficient for making ABI decisions, at least some part of the abi decision currently needs to be made by the front-end.

But you can (as I am aware) define struct in llvm, such as struct smart_ptr { void* px; void* py; } and if you want to return such struct in the llvm, you must pass it as a pointer to the struct in order to return in correctly. You could actually return such struct as:
ret void* px, void* py
and enable the backend to either return it by struct (if not enough registers) or return it in registers. This is requered in order to call methods that return non-native types. I need this because we use boost smart pointers (which are basically struct of 2 pointers) and we must be able to return them.

Otherwise, we have no problem with modifying frontend, because we will actually write our own (BSF scripts) but we need JIT / C++ engine code compatibility (in all ways; EH, calls etc.).

®iga

That is what csretcc does. At the LLVM level, the retval is passed by pointer, but when code generated, the target can choose to return the struct in registers.

-Chris