Win32 JIT issue + bug in ScheduleDAGSNodes.h?

Hi all,

While testing my compiler on win32 in JIT mode, I ran into a couple of issues:

1. I linked the compiler with the lib files resulting from the cmake created VS.NET build. While everything built just fine, the ExecutionEngine::create call always returned NULL. The fix was to also link with JIT.obj (thanks aKor for pointing me in the right direction). I would have thought that linking with LLVMJIT.lib should suffice... a VC++ linker issue?

2. There seems to be an issue in ScheduleDAGSDNodes.h when in debug mode. The problem is the evaluation of "&SUnits[0];" which ASSERT's in VC++'s vector[] implementation (when _HAS_ITERATOR_DEBUGGING is on).

As a work-around, I commented out the debug code (see "patch" below.)

What would the proper solution be? The idiom appears to be allowed by the C++03 standard, but at least VC++ 2008 Express Edition with _HAS_ITERATOR_DEBUGGING fails.

Best regards,
Stein Roger

Index: include/llvm/CodeGen/ScheduleDAGSDNodes.h

srs <skaflotten@gmail.com> writes:

While testing my compiler on win32 in JIT mode, I ran into a couple of
issues:

1. I linked the compiler with the lib files resulting from the cmake
created VS.NET build. While everything built just fine, the
ExecutionEngine::create call always returned NULL. The fix was to also
link with JIT.obj (thanks aKor for pointing me in the right direction).
I would have thought that linking with LLVMJIT.lib should suffice... a
VC++ linker issue?

Try adding this to the link command of your executable:

/INCLUDE:_X86TargetMachineModule

I should document this somehow.

[snip]

While testing my compiler on win32 in JIT mode, I ran into a couple of issues:

1. I linked the compiler with the lib files resulting from the cmake created VS.NET build. While everything built just fine, the ExecutionEngine::create call always returned NULL. The fix was to also link with JIT.obj (thanks aKor for pointing me in the right direction). I would have thought that linking with LLVMJIT.lib should suffice... a VC++ linker issue?
    
Try adding this to the link command of your executable:

/INCLUDE:_X86TargetMachineModule

I should document this somehow.
  
Yeah, this is necessary, but not sufficient. I also had to link with ExecutionEngineBindings.obj (not JIT.obj as first stated)

/Stein Roger

srs <skaflotten@gmail.com> writes:

While testing my compiler on win32 in JIT mode, I ran into a couple of
issues:

1. I linked the compiler with the lib files resulting from the cmake
created VS.NET build. While everything built just fine, the
ExecutionEngine::create call always returned NULL. The fix was to also
link with JIT.obj (thanks aKor for pointing me in the right direction).
I would have thought that linking with LLVMJIT.lib should suffice... a
VC++ linker issue?
    
Try adding this to the link command of your executable:

/INCLUDE:_X86TargetMachineModule

I should document this somehow.

Yeah, this is necessary, but not sufficient. I also had to link with
ExecutionEngineBindings.obj (not JIT.obj as first stated)

So you are using the C bindings. Okay, could someone advise what to do
here? Something like the _X86TargetMachineModule trick on
lib/Target/X86/X86TargetMachine.cpp line 26, but on
lib/ExecutionEngine/ExecutionEngineBindings.cpp?

Why is not the linker automatically pulling that code? If you are using
the C bindings, I suppose that your executable refers to the functions
defined on ExecutionEngineBindings.cpp. It is not the same case as
X86TargetMachine.cpp, which has a self-registering static C++ object and
nothing refers to it from the user's code.

Óscar Fuentes wrote:

srs <skaflotten@gmail.com> writes:

While testing my compiler on win32 in JIT mode, I ran into a couple of issues:

1. I linked the compiler with the lib files resulting from the cmake created VS.NET build. While everything built just fine, the ExecutionEngine::create call always returned NULL. The fix was to also link with JIT.obj (thanks aKor for pointing me in the right direction). I would have thought that linking with LLVMJIT.lib should suffice... a VC++ linker issue?
    

Try adding this to the link command of your executable:

/INCLUDE:_X86TargetMachineModule

I should document this somehow.
      

Yeah, this is necessary, but not sufficient. I also had to link with ExecutionEngineBindings.obj (not JIT.obj as first stated)
    
So you are using the C bindings. Okay, could someone advise what to do
here? Something like the _X86TargetMachineModule trick on
lib/Target/X86/X86TargetMachine.cpp line 26, but on
lib/ExecutionEngine/ExecutionEngineBindings.cpp?

Why is not the linker automatically pulling that code? If you are using
the C bindings, I suppose that your executable refers to the functions
defined on ExecutionEngineBindings.cpp. It is not the same case as
X86TargetMachine.cpp, which has a self-registering static C++ object and
nothing refers to it from the user's code

I'm actually not using C bindings; I'm using the C++ API directly. I have no idea why I have to link that object file.

/Stein Roger

2008/12/30 srs <skaflotten@gmail.com>

Óscar Fuentes wrote:

srs <skaflotten@gmail.com> writes:

While testing my compiler on win32 in JIT mode, I ran into a couple of
issues:

  1. I linked the compiler with the lib files resulting from the cmake
    created VS.NET build. While everything built just fine, the
    ExecutionEngine::create call always returned NULL. The fix was to also
    link with JIT.obj (thanks aKor for pointing me in the right direction).
    I would have thought that linking with LLVMJIT.lib should suffice… a
    VC++ linker issue?

Try adding this to the link command of your executable:

/INCLUDE:_X86TargetMachineModule

I should document this somehow.

Yeah, this is necessary, but not sufficient. I also had to link with
ExecutionEngineBindings.obj (not JIT.obj as first stated)

So you are using the C bindings. Okay, could someone advise what to do
here? Something like the _X86TargetMachineModule trick on
lib/Target/X86/X86TargetMachine.cpp line 26, but on
lib/ExecutionEngine/ExecutionEngineBindings.cpp?

Why is not the linker automatically pulling that code? If you are using
the C bindings, I suppose that your executable refers to the functions
defined on ExecutionEngineBindings.cpp. It is not the same case as
X86TargetMachine.cpp, which has a self-registering static C++ object and
nothing refers to it from the user’s code

I’m actually not using C bindings; I’m using the C++ API directly. I
have no idea why I have to link that object file.

Would either of you be willing to prepare a patch for this document once you’ve settled on the proper way to get JIT to work on Visual Studio?

http://llvm.org/docs/GettingStartedVS.html

srs <skaflotten@gmail.com> writes:

Try adding this to the link command of your executable:

/INCLUDE:_X86TargetMachineModule

I should document this somehow.
      

Yeah, this is necessary, but not sufficient. I also had to link with
ExecutionEngineBindings.obj (not JIT.obj as first stated)
    
So you are using the C bindings. Okay, could someone advise what to do
here? Something like the _X86TargetMachineModule trick on
lib/Target/X86/X86TargetMachine.cpp line 26, but on
lib/ExecutionEngine/ExecutionEngineBindings.cpp?

Why is not the linker automatically pulling that code? If you are using
the C bindings, I suppose that your executable refers to the functions
defined on ExecutionEngineBindings.cpp. It is not the same case as
X86TargetMachine.cpp, which has a self-registering static C++ object and
nothing refers to it from the user's code

I'm actually not using C bindings; I'm using the C++ API directly. I
have no idea why I have to link that object file.

This is very strange. Can you test if the Fibonacci.exe example runs
quick? (It should show the result almost instantaneously. Discard the
first run: most of that time is the OS loading the executable from disk)

If the Fibonacci example works, please compare its link command options
with your compiler's.

"Misha Brukman" <brukman@gmail.com> writes:

>>> Try adding this to the link command of your executable:
>>>
>>> /INCLUDE:_X86TargetMachineModule
>>>
>>> I should document this somehow.

Would either of you be willing to prepare a patch for this document once
you've settled on the proper way to get JIT to work on Visual Studio?

http://llvm.org/docs/GettingStartedVS.html

I'm documenting it on http://llvm.org/docs/CMake.html. I'll commit the
changes once this issue is settled. IMO, the document you mention
shouldn't mention build instructions, just refer to the CMake doc.

I plan to make this and other cmake-related changes to the LLVM docs
ASAP (read: after a few weeks from now).

Óscar Fuentes wrote:

srs  writes:

  
Try adding this to the link command of your executable:

/INCLUDE:_X86TargetMachineModule

I should document this somehow.
      
          
Yeah, this is necessary, but not sufficient. I also had to link with 
ExecutionEngineBindings.obj (not JIT.obj as first stated)
    
        
So you are using the C bindings. Okay, could someone advise what to do
here? Something like the _X86TargetMachineModule trick on
lib/Target/X86/X86TargetMachine.cpp line 26, but on
lib/ExecutionEngine/ExecutionEngineBindings.cpp?

Why is not the linker automatically pulling that code? If you are using
the C bindings, I suppose that your executable refers to the functions
defined on ExecutionEngineBindings.cpp. It is not the same case as
X86TargetMachine.cpp, which has a self-registering static C++ object and
nothing refers to it from the user's code
      
I'm actually not using C bindings; I'm using the C++ API directly. I 
have no idea why I have to link that object file.
    

This is very strange. Can you test if the Fibonacci.exe example runs
quick? (It should show the result almost instantaneously. Discard the
first run: most of that time is the OS loading the executable from disk)

If the Fibonacci example works, please compare its link command options
with your compiler's

The Fibonacci example works just fine; results appear quickly. The link options are the same AFAICT (except for the addition of ExecutionEngineBindings.obj…)

/Stein Roger

Óscar Fuentes wrote:

srs <skaflotten@gmail.com> writes:

Try adding this to the link command of your executable:

/INCLUDE:_X86TargetMachineModule

I should document this somehow.
      

Yeah, this is necessary, but not sufficient. I also had to link with ExecutionEngineBindings.obj (not JIT.obj as first stated)
    

So you are using the C bindings. Okay, could someone advise what to do
here? Something like the _X86TargetMachineModule trick on
lib/Target/X86/X86TargetMachine.cpp line 26, but on
lib/ExecutionEngine/ExecutionEngineBindings.cpp?

Why is not the linker automatically pulling that code? If you are using
the C bindings, I suppose that your executable refers to the functions
defined on ExecutionEngineBindings.cpp. It is not the same case as
X86TargetMachine.cpp, which has a self-registering static C++ object and
nothing refers to it from the user's code
      

I'm actually not using C bindings; I'm using the C++ API directly. I have no idea why I have to link that object file.
    
This is very strange. Can you test if the Fibonacci.exe example runs
quick? (It should show the result almost instantaneously. Discard the
first run: most of that time is the OS loading the executable from disk)

If the Fibonacci example works, please compare its link command options
with your compiler's.
  
(Resending... was scrubbed due to html)

The Fibonacci example works just fine; results appear quickly. The link options are the same AFAICT (except for the addition of ExecutionEngineBindings.obj...)

/Stein Roger

srs <skaflotten@gmail.com> writes:

This is very strange. Can you test if the Fibonacci.exe example runs
quick? (It should show the result almost instantaneously. Discard the
first run: most of that time is the OS loading the executable from disk)

If the Fibonacci example works, please compare its link command options
with your compiler's.
  
(Resending... was scrubbed due to html)

The Fibonacci example works just fine; results appear quickly. The link
options are the same AFAICT (except for the addition of
ExecutionEngineBindings.obj...)

Then we have a mystery, as examples/Fibonacci/fibonacci.cpp contains

  ExecutionEngine *EE = ExecutionEngine::create(MP, false);

which works just fine.

2. There seems to be an issue in ScheduleDAGSDNodes.h when in debug
mode. The problem is the evaluation of "&SUnits[0];" which ASSERT's in
VC++'s vector[] implementation (when _HAS_ITERATOR_DEBUGGING is on).

As a work-around, I commented out the debug code (see "patch" below.)

What would the proper solution be? The idiom appears to be allowed by
the C++03 standard, but at least VC++ 2008 Express Edition with
_HAS_ITERATOR_DEBUGGING fails.

What is the assertion message?

-bw

Bill Wendling wrote:

2. There seems to be an issue in ScheduleDAGSDNodes.h when in debug
mode. The problem is the evaluation of "&SUnits[0];" which ASSERT's in
VC++'s vector[] implementation (when _HAS_ITERATOR_DEBUGGING is on).

As a work-around, I commented out the debug code (see "patch" below.)

What would the proper solution be? The idiom appears to be allowed by
the C++03 standard, but at least VC++ 2008 Express Edition with
_HAS_ITERATOR_DEBUGGING fails.

What is the assertion message?

-bw
  
"vector subscript out of range"

This is the asserting code from <vector> :

    const_reference operator[](size_type _Pos) const
        { // subscript nonmutable sequence

#if _HAS_ITERATOR_DEBUGGING
        if (size() <= _Pos)
            {
            _DEBUG_ERROR("vector subscript out of range");
            _SCL_SECURE_OUT_OF_RANGE;
            }
#endif /* _HAS_ITERATOR_DEBUGGING */
        _SCL_SECURE_VALIDATE_RANGE(_Pos < size());

        return (*(_Myfirst + _Pos));
        }

/Stein Roger

Okay. I wonder if we can modify it to check that the vector has elements in it. Could you try this patch and let me know if it works for you?

-bw

Index: include/llvm/CodeGen/ScheduleDAGSDNodes.h

Bill Wendling wrote:

Cool! I'll submit it.

-bw