Re: [sv-cc] C Macros For C++ Virtual Function access

From: Kevin Cameron <kcameron@altera.com>
Date: Thu Oct 07 2004 - 10:36:24 PDT

Stickley, John wrote:

> Kevin,
>
> It seems to me that if we can keep function argument data types
> defined as they are currently in the LRM, where the actual
> representation is a data type that is opaque to the user, then
> we can avoid creating the extra normalized copies of data that you
> mention below altogether. The good thing about the current
> specification is that, in an optimal implementation, it allows
> direct use of in-place data from the originating side of the interface,
> by the consuming side of the interface with no copying at all.

I'm not sure what you mean by "optimal implementation", the most
efficient (performance-wise) implementation of a data structure in SV
may not be anything like the normalized version expected by DPI
routines. In particular a design's wiring is likely to be flattened and
instances will have disjoint references into the structure rather than
the ordered view in the original description.

> This, to me is the ultimate efficiency.
>
> What Ralph's proposal 205 attempts to do is allow this same
> efficiency but achieve full binary compatiblity as well. This is
> the best of both worlds.

BTW, where is that proposal?

> Kevin, I see advantages to your proposal but it does imply
> an additional level of indirection on each call that did not
> exist before because now a number of helper functions have to be
> called through pointers. I don't think this is necessary and it
> complicates the definition of the interface and adds some
> inefficiency, especially if such helpers are called in
> loops which they often can be.

If you don't translate the vendor's view of an object to a normalized
DPI view you will always have some levels of call indirection to operate
on it. If you use C++ type object pointers rather than opaque handles
you can make it only one offset calculation and one level of call from
the user code - the opaque handle approach requires a call into the
simulator where the offsets etc. are calculated and a second level of
call to perform an operation. (probably copying the call arguments again).

Using the C++ approach removes a level of routine call.

E.g.: currently there is a routine -

    void svPutBitVec32 (svBitPackedArrRef d, const svBitVec32* s, int w);

svBitPackedArrRef is of type void *, if it is instead a C++ type object
pointer you could call the function as:

       d->svPutBitVec32 (s, w); // in C++

or something like the following in C (where FN_SVB is a function type
much the same as svPutBitVec32):

       (*((FN_SVB **)d)[SV_PUT_BITVEC32])(d,s,w);

or (if you macro-def it) something like:

       SV_CALL_PUTBITVEC32(d,s,w)

Since the C call svPutBitVec32 is the same for all callers it has to do
the work of determinig which data d refers too before it can perform the
operation. For the virtual function approach the object d points to can
have a set of routines created at compile time to perform the operations
so no extra level of call is required.

The use of C++ style object pointers instead of opaque handles is
backward compatible i.e. you should be able to treat the pointers as
opaque handles.

> The DPI today does not require indirection of function calls
> or copying of data. I would like to request that we keep these
> as requirements, but add a new requirement: full binary
> compatibility for a given platform/compiler across vendors.
> I think this is Ralph's intent.
>
> -- johnS

I think I'd have to dispute your first claim, but agree with your
additional requirement.

Kev.

>
>
> Kevin Cameron wrote:
>
>>
>> The attached file demonstrates C macros for accessing C++ virtual
>> functions for the Sunpro C++ compiler on Solaris, it's basically the
>> same as the GNU version except there appears to be a 2-slot offset
>> before the user functions. The file also compiles and runs with g++ on
>> Solaris and Linux. If most compilers generate vtables which are similar
>> except for an offset, you can export the offset from the simulator to
>> make code binary compatible (if you want to be able to use the same C++
>> compiler as well as C), similarly if the simulator knows which C++
>> compiler the user code was built with it could serve the appropriate
>> type of vtables (attributes on the function import declarations could be
>> used if you want to do it per-call when libraries are from different
>> compilers).
>>
>> Virtual functions solve most of the problems of binary incompatibility
>> between vendors internal data representations, aren't particularly hard
>> to implement
>> and are probably more efficient than creating normalized copies of data
>> to pass to DPI user functions. Using them from C is not hard, and
>> compatibility with most C++ compilers is not difficult to achieve (as a
>> longer term goal).
>>
>> Kev.
>>
>> --
>> Altera Corp, 101 Innovation Drv, San Jose, CA 95134. T# (408) 544 7126
>>
>>
>> ------------------------------------------------------------------------
>>
>> #include <stdio.h>
>>
>> #ifdef __SUNPRO_CC
>> int offset = 2;
>> #else
>> int offset = 0;
>> #endif
>>
>> class test {
>> public:
>> virtual int fn_a(); // creates vtable pointer as first field in class
>> virtual int fn_b();
>> };
>>
>> int test::fn_a() {return 23;}
>> int test::fn_b() {return 42;}
>>
>>
>> class test2 :test { // derived class with different implementation
>> of fn_a/b
>> virtual int fn_a();
>> virtual int fn_b();
>> int n;
>> public:
>> test2() {n = -42;}
>> };
>>
>> int test2::fn_a() {return -23;}
>> int test2::fn_b() {return n;}
>>
>> // C Macros
>> typedef int (*IFN)(...);
>> #define FN_A(h) (*((IFN *)*(void **)h)[offset+0])(h)
>> #define FN_B(h) (*((IFN *)*(void **)h)[offset+1])(h)
>>
>> void DPI(void *h)
>> {
>> printf ("%d\n",FN_A(h)); printf ("%d\n",FN_B(h));
>> }
>>
>> int main(int argc,char **argv)
>> {
>> DPI(new test);
>> DPI(new test2);
>> }
>
>

-- 
Altera Corp, 101 Innovation Drv, San Jose, CA 95134. T# (408) 544 7126
Received on Thu Oct 7 10:36:57 2004

This archive was generated by hypermail 2.1.8 : Thu Oct 07 2004 - 10:37:02 PDT