grame-cncm / faust

Functional programming language for signal processing and sound synthesis
http://faust.grame.fr
Other
2.53k stars 319 forks source link

Windows 10 - Broken function found, compilation aborted! #180

Closed pierreguillot closed 6 years ago

pierreguillot commented 6 years ago

(created from #158)

Calling the function createCDSPFactoryFromFile() generates the exception "Broken function found, compilation aborted!", (I catch the runtime exception (faustexception)).

When I debug, the stack is:

libcode.cpp l.1379
gGlobal->gDSPFactory = container->produceFactory()

llvm_code_container.cpp l.868
generateCompute()

llvm_code_container.cpp l.953
generateComputeBlock() 

And it generates 2 times this:

Assertion failed 
Program: ..\faust~.dll
llvm-5.0...\Instruction.cpp l. 1400
Expression: getOperand(0)->getType() == cast<PointerType>(getOperand(1)-getType())-getElementType() && "Ptr must be to Val type"

and then 2 times this:

Debug Error
HEAP CORRUPTION DETECTED: pd.exe after Normal block (#29734) at 0x02870888
CRT detected that the application wrote the memory after end of heap buffer

I'm still debugging it...

Also I tried faust -lang llvm foo.dsp (with foo process = _;) and it gives ERROR: -lang llvm/cllvm not supported since llvm backend is not built So I think that is the problem...

I compiled using Visual Studio 14 2015 for Win32 in Debug: cmake .. -G "Visual Studio 14 2015" -DINCLUDE_STATIC=on -DINCLUDE_OSC=off -DINCLUDE_HTTP=off -DUSE_LLVM_CONFIG=off -DLLVM_DIR=./../../llvm/lib/cmake/llvm -C..\backends\backends.cmake then msbuild faust.sln /p:config=Debug /p:plateform=Win32 /target:ALL_BUILD /p:OutDir=../libs

sletz commented 6 years ago

When backends.cmake is used, LLVM backend is added in static and dynamic libfaust.

You can use -C..\backends\all.cmake to add the LLVM backend in the compiler executable.

pierreguillot commented 6 years ago

Yes, I just fixed this so it gives

faust -lang llvm foo.dsp
; ModuleID = 'llvm, -scal -ftz 0, v2.5.34'
source_filename = "llvm, -scal -ftz 0, v2.5.34"
target triple = "i686-pc-windows-msvc"

%struct.dspmydsp = type { i32 }
%struct.UIGlue = type { i8*, void (i8*, i8*)*, void (i8*, i8*)*, void (i8*, i8*)*, void (i8*)*, void (i8*, i8*, float*)*, void (i8*, i8*, float*)*, void (i8*, i8*, float*, float, float, float, float)*, void (i8*, i8*, float*, float, float, float, float)*, void (i8*, i8*, float*, float, float, float, float)*, void (i8*, i8*, float*, float, float)*, void (i8*, i8*, float*, float, float)*, void (i8*, i8*, i8*, %struct.dspSoundfile**)*, void (i8*, float*, i8*, i8*)* }
%struct.dspSoundfile = type { i32, i32, i32, float** }
%struct.MetaGlue = type { i8*, void (i8*, i8*, i8*)* }

@filename = internal constant [9 x i8] c"filename\00"
@foo = internal constant [4 x i8] c"foo\00"
@name = internal constant [5 x i8] c"name\00"

declare void @free(i8*) align 2

define void @destroymydsp(%struct.dspmydsp* %dsp) align 2 {
entry_block:
  br label %return_block

return_block:                                     ; preds = %entry_block
  ret void
}

define void @deletemydsp(%struct.dspmydsp* %dsp) {
entry:
  %0 = bitcast %struct.dspmydsp* %dsp to i8*
  call void @destroymydsp(%struct.dspmydsp* %dsp)
  call void @free(i8* %0)
  ret void
}

declare i8* @malloc(i64)

define void @allocatemydsp(%struct.dspmydsp* %dsp) align 2 {
entry_block:
  br label %return_block

return_block:                                     ; preds = %entry_block
  ret void
}

define %struct.dspmydsp* @newmydsp() {
entry:
  %0 = call i8* @malloc(i64 32)
  %1 = bitcast i8* %0 to %struct.dspmydsp*
  call void @allocatemydsp(%struct.dspmydsp* %1)
  ret %struct.dspmydsp* %1
}

define void @buildUserInterfacemydsp(%struct.dspmydsp* %dsp, %struct.UIGlue* %interface) align 2 {
init:
  %0 = getelementptr inbounds %struct.UIGlue, %struct.UIGlue* %interface, i64 0, i32 0
  %1 = load i8*, i8** %0
  br label %code_block

code_block:                                       ; preds = %init
  %2 = getelementptr inbounds %struct.UIGlue, %struct.UIGlue* %interface, i64 0, i32 3
  %3 = load void (i8*, i8*)*, void (i8*, i8*)** %2
  call void %3(i8* %1, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @foo, i32 0, i32 0))
  %4 = getelementptr inbounds %struct.UIGlue, %struct.UIGlue* %interface, i64 0, i32 4
  %5 = load void (i8*)*, void (i8*)** %4
  call void %5(i8* %1)
  br label %return_block

return_block:                                     ; preds = %code_block
  ret void
}

define i32 @getSampleRatemydsp(%struct.dspmydsp* %dsp) {
entry_block:
  %0 = getelementptr inbounds %struct.dspmydsp, %struct.dspmydsp* %dsp, i32 0, i32 0
  %1 = load i32, i32* %0
  ret i32 %1
}

; Function Attrs: nounwind
define i32 @getNumInputsmydsp(%struct.dspmydsp* %dsp) #0 {
entry_block:
  br label %code_block

code_block:                                       ; preds = %entry_block
  ret i32 1
}

; Function Attrs: nounwind
define i32 @getNumOutputsmydsp(%struct.dspmydsp* %dsp) #0 {
entry_block:
  br label %code_block

code_block:                                       ; preds = %entry_block
  ret i32 1
}

; Function Attrs: nounwind
define i32 @getInputRatemydsp(%struct.dspmydsp* %dsp, i32 %channel) #0 {
entry_block:
  %rate = alloca i32
  br label %code_block

code_block:                                       ; preds = %entry_block
  br label %init_block

init_block:                                       ; preds = %code_block
  switch i32 %channel, label %default [
    i32 0, label %case
  ]

exit_block:                                       ; preds = %code_block2, %code_block1
  %0 = load i32, i32* %rate
  ret i32 %0

default:                                          ; preds = %init_block
  br label %code_block2

case:                                             ; preds = %init_block
  br label %code_block1

code_block1:                                      ; preds = %case
  store i32 1, i32* %rate
  br label %exit_block

code_block2:                                      ; preds = %default
  store i32 -1, i32* %rate
  br label %exit_block
}

; Function Attrs: nounwind
define i32 @getOutputRatemydsp(%struct.dspmydsp* %dsp, i32 %channel) #0 {
entry_block:
  %rate = alloca i32
  br label %code_block

code_block:                                       ; preds = %entry_block
  br label %init_block

init_block:                                       ; preds = %code_block
  switch i32 %channel, label %default [
    i32 0, label %case
  ]

exit_block:                                       ; preds = %code_block2, %code_block1
  %0 = load i32, i32* %rate
  ret i32 %0

default:                                          ; preds = %init_block
  br label %code_block2

case:                                             ; preds = %init_block
  br label %code_block1

code_block1:                                      ; preds = %case
  store i32 1, i32* %rate
  br label %exit_block

code_block2:                                      ; preds = %default
  store i32 -1, i32* %rate
  br label %exit_block
}

define void @classInitmydsp(i32 %samplingFreq) {
entry_block:
  br label %return_block

return_block:                                     ; preds = %entry_block
  ret void
}

define void @instanceResetUserInterfacemydsp(%struct.dspmydsp* %dsp) {
entry_block:
  br label %return_block

return_block:                                     ; preds = %entry_block
  ret void
}

define void @instanceClearmydsp(%struct.dspmydsp* %dsp) {
entry_block:
  br label %return_block

return_block:                                     ; preds = %entry_block
  ret void
}

define void @instanceConstantsmydsp(%struct.dspmydsp* %dsp, i32 %samplingFreq) {
entry_block:
  br label %code_block

code_block:                                       ; preds = %entry_block
  %0 = getelementptr inbounds %struct.dspmydsp, %struct.dspmydsp* %dsp, i32 0, i32 0
  store i32 %samplingFreq, i32* %0
  br label %return_block

return_block:                                     ; preds = %code_block
  ret void
}

define void @metadatamydsp(%struct.MetaGlue* %m) {
entry_block:
  %0 = getelementptr %struct.MetaGlue, %struct.MetaGlue* %m, i64 0, i32 0
  %1 = load i8*, i8** %0
  %2 = getelementptr %struct.MetaGlue, %struct.MetaGlue* %m, i64 0, i32 1
  %3 = load void (i8*, i8*, i8*)*, void (i8*, i8*, i8*)** %2
  call void %3(i8* %1, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @filename, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @foo, i32 0, i32 0))
  call void %3(i8* %1, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @name, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @foo, i32 0, i32 0))
  br label %return_block

return_block:                                     ; preds = %entry_block
  ret void
}

define i32 @getSizemydsp() {
return_block:
  ret i32 32
}

; Function Attrs: nounwind
define i32 @getSampleSizemydsp() #0 {
entry_block:
  br label %code_block

code_block:                                       ; preds = %entry_block
  ret i32 4
}

define void @computemydsp(%struct.dspmydsp* %dsp, i32 %count, float** %inputs, float** %outputs) {
entry_block:
  %i = alloca i32
  %output0 = alloca float*
  %input0 = alloca float*
  br label %code_block

code_block:                                       ; preds = %entry_block
  %0 = getelementptr inbounds float*, float** %inputs, i32 0
  %1 = load float*, float** %0
  store float* %1, float** %input0
  %2 = getelementptr inbounds float*, float** %outputs, i32 0
  %3 = load float*, float** %2
  store float* %3, float** %output0
  br label %init_block

init_block:                                       ; preds = %code_block
  store i32 0, i32* %i
  br label %exec_block

exec_block:                                       ; preds = %code_block2, %init_block
  %i1 = phi i32 [ 0, %init_block ], [ %next_index, %code_block2 ]
  %4 = load i32, i32* %i
  %5 = icmp slt i32 %4, %count
  %6 = select i1 %5, i32 1, i32 0
  %7 = trunc i32 %6 to i1
  br i1 %7, label %loop_body_block, label %exit_block

loop_body_block:                                  ; preds = %exec_block
  br label %code_block2

exit_block:                                       ; preds = %exec_block
  br label %return_block

code_block2:                                      ; preds = %loop_body_block
  %8 = load i32, i32* %i
  %9 = load float*, float** %output0
  %10 = getelementptr inbounds float, float* %9, i32 %8
  %11 = load i32, i32* %i
  %12 = load float*, float** %input0
  %13 = getelementptr inbounds float, float* %12, i32 %11
  %14 = load float, float* %13
  store float %14, float* %10
  %15 = load i32, i32* %i
  %next_index = add i32 %15, 1
  store i32 %next_index, i32* %i
  br label %exec_block

return_block:                                     ; preds = %exit_block
  ret void
}

define void @instanceInitmydsp(%struct.dspmydsp* %dsp, i32 %samplingFreq) {
entry_block:
  call void @instanceConstantsmydsp(%struct.dspmydsp* %dsp, i32 %samplingFreq)
  call void @instanceResetUserInterfacemydsp(%struct.dspmydsp* %dsp)
  call void @instanceClearmydsp(%struct.dspmydsp* %dsp)
  ret void
}

define void @initmydsp(%struct.dspmydsp* %dsp, i32 %samplingFreq) {
entry_block:
  call void @classInitmydsp(i32 %samplingFreq)
  call void @instanceInitmydsp(%struct.dspmydsp* %dsp, i32 %samplingFreq)
  ret void
}

attributes #0 = { nounwind }
sletz commented 6 years ago

So LLVM IR code generation works, but you still get the "Broken function found, compilation aborted!", when using libfaust? Any precise line where this Expression: getOperand(0)->getType() == cast<PointerType>(getOperand(1)-getType())-getElementType() && "Ptr must be to Val type" occurs?

pierreguillot commented 6 years ago

Yes, l. 1400 of Instruction.cpp (in the llvm folder - I don't have the full path)

pierreguillot commented 6 years ago

And if I use createCDSPFactoryFromString("score", "process = _;", 0, NULL, "", errors, -1); I have 2 times:

Debug Error
HEAP CORRUPTION DETECTED: pd.exe after Normal block (#29734) at 0x02870888
CRT detected that the application wrote the memory after end of heap buffer

and then I catch:

Program used external function '_free' which could not be resolved!
sletz commented 6 years ago

Very strange errors... some people were able to compile a functioning libfaust version now Windows, buy I don't know on which exact OS version. Could be Windows 10 specific issue? I suggest to ask on faust-developer mailing list.

pierreguillot commented 6 years ago

I'm not a Windows expert but since Windows 10 the applications use by default runtime libraries (/MD) instead of the static libraries (/MT) perhaps this is the reason why some of the function are not found... I recompile LLVM with MT and I will test that. If it doesn't work and I don't find any other possibility I'll ask on the mailing list, thanks!

pierreguillot commented 6 years ago

I managed to solve the problem on Windows x64. Further information on the dev mailing list.

You can also have a look at the project faustgen~ for Pd and on the faust implementation branch of the application Kiwi.