[LLVMdev] Fwd: error while linking modules with exception handling demo code
charles quarra
charllsnotieneningunputocorreo at gmail.com
Thu Dec 13 08:57:00 PST 2012
---------- Forwarded message ----------
From: charles quarra <charllsnotieneningunputocorreo at gmail.com>
Date: 2012/12/13
Subject: error while linking modules with exception handling demo code
To: llvmdev at cs.uiuc.edu
Hi,
I am building a module X with an arithmetic function foo, a module Y
with an arithmetic function foo2 that invokes foo. For the invocation
be a proper one (being able to handle exceptions correctly) i
incorporated a third module that has defined exception-handling code
that i've taken from the ExceptionDemo sample. First i'll post the
module dump, the failed assertion and then i'll explain a bit about
how do i generate the code:
this is the module ExecutableCodeModule dump, which is the module that
is used by the ExecutionEngine (not using new MCJIT, but it is not
relevant for this question, since the error happens during linkage).
It contains definitions from the ExceptionDemo sample AND the foo
function of module X already linked
(modules are being linked with
linker()->LinkModules(ExecutableCodeModule , moduleToLink,
llvm::Linker::PreserveSource, &errorMsg);
Exception Demo is from
https://llvm.org/svn/llvm-project/llvm/trunk/examples/ExceptionDemo/ExceptionDemo.cpp
; ModuleID = 'ExecutableCodeModule'
@typeInfo0 = constant { i32 } zeroinitializer
@typeInfo1 = constant { i32 } { i32 1 }
@typeInfo2 = constant { i32 } { i32 2 }
@typeInfo3 = constant { i32 } { i32 3 }
@typeInfo4 = constant { i32 } { i32 4 }
@typeInfo5 = constant { i32 } { i32 5 }
@typeInfo6 = constant { i32 } { i32 6 }
declare void @print32Int(i32, i8*)
declare void @print64Int(i64, i8*)
declare void @printStr(i8*)
declare void @throwCppException(i32)
declare void @deleteOurException(i8*)
declare i8* @createOurException(i32)
declare i32 @_Unwind_RaiseException(i8*) noreturn
declare i32 @_Unwind_Resume(i8*) noreturn
declare i32 @ourPersonality(i32, i32, i64, i8*, i8*)
declare i32 @llvm.eh.typeid.for(i8*) nounwind readnone
define i32 @foo(i32) {
%g = alloca i32
%bar = alloca i32
store i32 %0, i32* %bar
%"argument read" = load i32* %bar
%addtmp = add i32 %"argument read", 2
store i32 %addtmp, i32* %g
%"argument read1" = load i32* %bar
%read = load i32* %g
%"Code::Op::Mul" = mul i32 %"argument read1", %read
ret i32 %"Code::Op::Mul"
}
this is module Y, which is where foo2 is generated. When it is
supposed to invoke foo, i've placed
createCatchWrappedInvokeFunction(*module, *excptModule,
buildParameters.builder,
*buildParameters.getFunctionPassManager(),
*result, //result
is llvm::Function pointing to foo in module X
"invoke foo",
numExceptionTypesToCatch,
innerExceptionTypesToCatch);
(at the end i put the code for createCatchWrappedInvokeFunction, which
is slightly modified to allow for things like printStr and
createOurException that exists in the separate exception handling
module to be used in the module Y)
; ModuleID = 'Y'
@0 = linker_private constant [52 x i8] c"Gen: Executing finally block
finally in invoke foo\0A\00"
@1 = linker_private constant [52 x i8] c"Gen: Executing catch block
typeInfo6 in invoke foo\0A\00"
@2 = linker_private constant [52 x i8] c"Gen: Executing catch block
typeInfo2 in invoke foo\0A\00"
@3 = linker_private constant [52 x i8] c"Gen: Executing catch block
typeInfo4 in invoke foo\0A\00"
@4 = linker_private constant [43 x i8] c"Gen: In end block: exiting in
invoke foo.\0A\00"
@5 = linker_private constant [34 x i8] c"Gen: No exception in invoke foo!\0A\00"
@6 = linker_private constant [34 x i8] c"Gen: Foreign exception received.\0A\00"
@7 = linker_private constant [67 x i8] c"Gen: Exception type <%d>
received (stack unwound) in invoke foo.\0A\00"
define i32 @foo2(i32) {
%h = alloca i32
%g = alloca i32
%bar = alloca i32
store i32 %0, i32* %bar
%"argument read" = load i32* %bar
%"Code::Op::Mul" = mul i32 %"argument read", 5
store i32 %"Code::Op::Mul", i32* %g
%read = load i32* %g
}
define void @"invoke foo"(i32 %exceptTypeToThrow) {
entry:
%caughtResultStorage = alloca { i8*, i32 }
store { i8*, i32 } zeroinitializer, { i8*, i32 }* %caughtResultStorage
%exceptionStorage = alloca i8*
store i8* null, i8** %exceptionStorage
%exceptionCaught = alloca i8
store i8 0, i8* %exceptionCaught
%0 = invoke i32 @foo(i32 %exceptTypeToThrow)
to label %normal unwind label %exception
normal: ; preds = %entry
call void @printStr(i8* getelementptr inbounds ([34 x i8]* @5, i32 0, i32 0))
br label %finally
exception: ; preds = %entry
%1 = landingpad { i8*, i32 } personality i32 (i32, i32, i64, i8*,
i8*)* @ourPersonality
cleanup
catch { i32 }* @typeInfo6
catch { i32 }* @typeInfo2
catch { i32 }* @typeInfo4
%2 = extractvalue { i8*, i32 } %1, 0
%3 = extractvalue { i8*, i32 } %1, 1
store { i8*, i32 } %1, { i8*, i32 }* %caughtResultStorage
store i8* %2, i8** %exceptionStorage
store i8 1, i8* %exceptionCaught
%4 = bitcast i8* %2 to { i64 }*
%5 = getelementptr inbounds { i64 }* %4, i32 0, i32 0
%6 = load i64* %5
%7 = icmp eq i64 %6, 8026094035810743040
br i1 %7, label %exceptionRoute, label %externalException
exceptionRoute: ; preds = %exception
%8 = getelementptr i8* %2, i64 4294967280
%9 = bitcast i8* %8 to { { i32 } }*
%10 = getelementptr inbounds { { i32 } }* %9, i32 0, i32 0
%11 = getelementptr inbounds { i32 }* %10, i32 0, i32 0
%12 = load i32* %11
call void @print32Int(i32 %12, i8* getelementptr inbounds ([67 x
i8]* @7, i32 0, i32 0))
switch i32 %3, label %finally [
i32 1, label %typeInfo6
i32 2, label %typeInfo2
i32 3, label %typeInfo4
]
store i32 %0, i32* %h
%"argument read" = load i32* %bar
%read = load i32* %h
%addtmp = add i32 %"argument read", %read
ret i32 %addtmp
externalException: ; preds = %exception
call void @printStr(i8* getelementptr inbounds ([34 x i8]* @6, i32 0, i32 0))
br label %finally
unwindResume: ; preds = %finally
%13 = load { i8*, i32 }* %caughtResultStorage
resume { i8*, i32 } %13
end: ; preds = %finally, %finally
call void @printStr(i8* getelementptr inbounds ([43 x i8]* @4, i32 0, i32 0))
%14 = load i8** %exceptionStorage
call void @deleteOurException(i8* %14)
ret void
finally: ; preds =
%exceptionRoute, %externalException, %normal, %typeInfo4, %typeInfo2,
%typeInfo6
call void @printStr(i8* getelementptr inbounds ([52 x i8]* @0, i32 0, i32 0))
%15 = load i8* %exceptionCaught
switch i8 %15, label %end [
i8 2, label %end
i8 1, label %unwindResume
]
typeInfo6: ; preds = %exceptionRoute
call void @printStr(i8* getelementptr inbounds ([52 x i8]* @1, i32 0, i32 0))
store i8 2, i8* %exceptionCaught
br label %finally
typeInfo2: ; preds = %exceptionRoute
call void @printStr(i8* getelementptr inbounds ([52 x i8]* @2, i32 0, i32 0))
store i8 2, i8* %exceptionCaught
br label %finally
typeInfo4: ; preds = %exceptionRoute
call void @printStr(i8* getelementptr inbounds ([52 x i8]* @3, i32 0, i32 0))
store i8 2, i8* %exceptionCaught
br label %finally
}
this is the failed assertion i get during the call to Linker::LinkModules
While deleting: i32 (i32)* %foo
Use still stuck around after Def is destroyed: %0 = invoke i32
@foo(i32 %exceptTypeToThrow)
to label %normal unwind label %exception
hivecompilerlibtests: Value.cpp:75: virtual llvm::Value::~Value():
Assertion `use_empty() && "Uses remain when a value is destroyed!"'
failed.
As a separate but probably related detail, the function 'invoke foo'
is not being inserted in the foo2 IR. The foo2 invoke generation looks
like this:
llvm::Module* module =
Compiler::Services::SymbolResolver::getInstance()->resolveOrCreateModule(
buildParameters.getLLVMContext() ,
buildParameters.getModuleDefinition() );
HAssertMsg( 0 != module , " null module ");
llvm::Module* excptModule =
Compiler::Services::SymbolResolver::getInstance()->resolveOrCreateNativeExceptionHandlingModule(
buildParameters.getLLVMContext() ); //,
buildParameters.getModuleDefinition() );
HAssertMsg( 0 != excptModule , " null
exception module ");
HDebugLogLevel("inside BuildIRExpression:, "
<< dynSym.getSymbolName() << " module resolved? " << excptModule, 0);
Exceptions::InvokeFunctionResult invokeResult
= Exceptions::createCatchWrappedInvokeFunction(*module, *excptModule,
buildParameters.builder,
*buildParameters.getFunctionPassManager(),
*result,
std::string("invoke ")+ fnDecl->functionName.get(),
numExceptionTypesToCatch,
innerExceptionTypesToCatch);
the exceptionModule is being generated as:
Compiler::Detail::Exceptions::initialiseExceptionHandlingStaticStuff(ctx);
llvm::Module* excptModule = new
llvm::Module("NativeExceptionHandlingModule" ,
ctx);Compiler::Detail::Exceptions::createStandardUtilityFunctions(6, *
excptModule);
my slightly modified version of ExceptionDemo is appended as an attachment
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ExceptionHandling.tar.bz2
Type: application/x-bzip2
Size: 5450 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20121213/704edf0c/attachment.bin>
More information about the llvm-dev
mailing list