From 9d48b555e24842c9a180e22511a39bfe62dfd5bd Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Wed, 9 Sep 2009 00:11:02 +0000 Subject: [PATCH] Fix PR4865. This syncs up the JIT's DWARF emitter with what's in the 'DwarfException.cpp' file, which changed how CIEs were emitted, the sizes of some fields, etc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81295 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp | 41 +++--- test/ExecutionEngine/jit-eh-x86-64.ll | 141 ++++++++++++++++++++ 2 files changed, 162 insertions(+), 20 deletions(-) create mode 100644 test/ExecutionEngine/jit-eh-x86-64.ll diff --git a/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp b/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp index f7fb983e1ac..25974cdcde1 100644 --- a/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp @@ -28,7 +28,6 @@ #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegisterInfo.h" - using namespace llvm; JITDwarfEmitter::JITDwarfEmitter(JIT& theJit) : Jit(theJit) {} @@ -56,7 +55,7 @@ unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction& F, Result = EmitEHFrame(Personalities[MMI->getPersonalityIndex()], EHFramePtr, StartFunction, EndFunction, ExceptionTable); - + return Result; } @@ -107,11 +106,9 @@ JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr, JCE->emitULEB128Bytes(RI->getDwarfRegNum(Src.getReg(), true)); } - int Offset = -Src.getOffset(); - - JCE->emitULEB128Bytes(Offset); + JCE->emitULEB128Bytes(-Src.getOffset()); } else { - llvm_unreachable("Machine move no supported yet."); + llvm_unreachable("Machine move not supported yet."); } } else if (Src.isReg() && Src.getReg() == MachineLocation::VirtualFP) { @@ -119,7 +116,7 @@ JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr, JCE->emitByte(dwarf::DW_CFA_def_cfa_register); JCE->emitULEB128Bytes(RI->getDwarfRegNum(Dst.getReg(), true)); } else { - llvm_unreachable("Machine move no supported yet."); + llvm_unreachable("Machine move not supported yet."); } } else { unsigned Reg = RI->getDwarfRegNum(Src.getReg(), true); @@ -466,11 +463,10 @@ unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF, GlobalVariable *GV = TypeInfos[M - 1]; if (GV) { - if (TD->getPointerSize() == sizeof(int32_t)) { + if (TD->getPointerSize() == sizeof(int32_t)) JCE->emitInt32((intptr_t)Jit.getOrEmitGlobalVariable(GV)); - } else { + else JCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV)); - } } else { if (TD->getPointerSize() == sizeof(int32_t)) JCE->emitInt32(0); @@ -508,7 +504,7 @@ JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) const { JCE->emitULEB128Bytes(1); JCE->emitSLEB128Bytes(stackGrowth); JCE->emitByte(RI->getDwarfRegNum(RI->getRARegister(), true)); - + if (Personality) { // Augmentation Size: 3 small ULEBs of one byte each, and the personality // function which size is PointerSize. @@ -524,10 +520,9 @@ JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) const { JCE->emitByte(dwarf::DW_EH_PE_sdata8); JCE->emitInt64(((intptr_t)Jit.getPointerToGlobal(Personality))); } - + JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); - } else { JCE->emitULEB128Bytes(1); JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); @@ -566,13 +561,19 @@ JITDwarfEmitter::EmitEHFrame(const Function* Personality, // If there is a personality and landing pads then point to the language // specific data area in the exception table. - if (MMI->getPersonalityIndex()) { - JCE->emitULEB128Bytes(4); + if (Personality) { + JCE->emitULEB128Bytes(PointerSize == 4 ? 4 : 8); - if (!MMI->getLandingPads().empty()) { - JCE->emitInt32(ExceptionTable - (unsigned char*)JCE->getCurrentPCValue()); + if (PointerSize == 4) { + if (!MMI->getLandingPads().empty()) + JCE->emitInt32(ExceptionTable-(unsigned char*)JCE->getCurrentPCValue()); + else + JCE->emitInt32((int)0); } else { - JCE->emitInt32((int)0); + if (!MMI->getLandingPads().empty()) + JCE->emitInt64(ExceptionTable-(unsigned char*)JCE->getCurrentPCValue()); + else + JCE->emitInt64((int)0); } } else { JCE->emitULEB128Bytes(0); @@ -621,7 +622,7 @@ unsigned JITDwarfEmitter::GetDwarfTableSizeInBytes(MachineFunction& F, FinalSize += GetEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()], StartFunction); - + return FinalSize; } @@ -644,7 +645,7 @@ JITDwarfEmitter::GetEHFrameSizeInBytes(const Function* Personality, FinalSize += 3 * PointerSize; // If there is a personality and landing pads then point to the language // specific data area in the exception table. - if (MMI->getPersonalityIndex()) { + if (Personality) { FinalSize += MCAsmInfo::getULEB128Size(4); FinalSize += PointerSize; } else { diff --git a/test/ExecutionEngine/jit-eh-x86-64.ll b/test/ExecutionEngine/jit-eh-x86-64.ll new file mode 100644 index 00000000000..bd15974e2f6 --- /dev/null +++ b/test/ExecutionEngine/jit-eh-x86-64.ll @@ -0,0 +1,141 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: lli -march=x86-64 %t.bc > /dev/null +; PR4865 + +%struct.__fundamental_type_info_pseudo = type { %struct.__type_info_pseudo } +%struct.__type_info_pseudo = type { i8*, i8* } + +@_ZTIi = external constant %struct.__fundamental_type_info_pseudo ; <%struct.__fundamental_type_info_pseudo*> [#uses=1] +@.str = private constant [3 x i8] c"ok\00", align 1 ; <[3 x i8]*> [#uses=1] + +define i32 @main() ssp { +entry: + %retval = alloca i32 ; [#uses=2] + %save_filt.5 = alloca i32 ; [#uses=2] + %save_eptr.4 = alloca i8* ; [#uses=2] + %0 = alloca i32 ; [#uses=2] + %eh_exception = alloca i8* ; [#uses=10] + %eh_selector = alloca i32 ; [#uses=5] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + invoke void @_ZL3foov() ssp + to label %invcont unwind label %lpad + +invcont: ; preds = %entry + br label %bb6 + +bb: ; preds = %ppad + %eh_value = load i8** %eh_exception ; [#uses=1] + %1 = call i8* @__cxa_begin_catch(i8* %eh_value) nounwind ; [#uses=0] + %2 = invoke i32 @puts(i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0)) + to label %invcont1 unwind label %lpad10 ; [#uses=0] + +invcont1: ; preds = %bb + call void @__cxa_end_catch() + br label %bb6 + +bb2: ; preds = %ppad18 + %eh_select = load i32* %eh_selector ; [#uses=1] + store i32 %eh_select, i32* %save_filt.5, align 4 + %eh_value3 = load i8** %eh_exception ; [#uses=1] + store i8* %eh_value3, i8** %save_eptr.4, align 4 + invoke void @__cxa_end_catch() + to label %invcont4 unwind label %lpad14 + +invcont4: ; preds = %bb2 + %3 = load i8** %save_eptr.4, align 4 ; [#uses=1] + store i8* %3, i8** %eh_exception, align 4 + %4 = load i32* %save_filt.5, align 4 ; [#uses=1] + store i32 %4, i32* %eh_selector, align 4 + br label %Unwind + +bb5: ; preds = %ppad19 + call void @_ZSt9terminatev() noreturn nounwind + unreachable + +bb6: ; preds = %invcont1, %invcont + store i32 0, i32* %0, align 4 + %5 = load i32* %0, align 4 ; [#uses=1] + store i32 %5, i32* %retval, align 4 + br label %return + +return: ; preds = %bb6 + %retval7 = load i32* %retval ; [#uses=1] + ret i32 %retval7 + +lpad: ; preds = %entry + %eh_ptr = call i8* @llvm.eh.exception() ; [#uses=1] + store i8* %eh_ptr, i8** %eh_exception + %eh_ptr8 = load i8** %eh_exception ; [#uses=1] + %eh_select9 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr8, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; [#uses=1] + store i32 %eh_select9, i32* %eh_selector + br label %ppad + +lpad10: ; preds = %bb + %eh_ptr11 = call i8* @llvm.eh.exception() ; [#uses=1] + store i8* %eh_ptr11, i8** %eh_exception + %eh_ptr12 = load i8** %eh_exception ; [#uses=1] + %eh_select13 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr12, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) ; [#uses=1] + store i32 %eh_select13, i32* %eh_selector + br label %ppad18 + +lpad14: ; preds = %bb2 + %eh_ptr15 = call i8* @llvm.eh.exception() ; [#uses=1] + store i8* %eh_ptr15, i8** %eh_exception + %eh_ptr16 = load i8** %eh_exception ; [#uses=1] + %eh_select17 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr16, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; [#uses=1] + store i32 %eh_select17, i32* %eh_selector + br label %ppad19 + +ppad: ; preds = %lpad + br label %bb + +ppad18: ; preds = %lpad10 + br label %bb2 + +ppad19: ; preds = %lpad14 + br label %bb5 + +Unwind: ; preds = %invcont4 + %eh_ptr20 = load i8** %eh_exception ; [#uses=1] + call void @_Unwind_Resume_or_Rethrow(i8* %eh_ptr20) + unreachable +} + +define internal void @_ZL3foov() ssp { +entry: + %0 = alloca i8* ; [#uses=3] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + %1 = call i8* @__cxa_allocate_exception(i32 4) nounwind ; [#uses=1] + store i8* %1, i8** %0, align 4 + %2 = load i8** %0, align 4 ; [#uses=1] + %3 = bitcast i8* %2 to i32* ; [#uses=1] + store i32 42, i32* %3, align 4 + %4 = load i8** %0, align 4 ; [#uses=1] + call void @__cxa_throw(i8* %4, i8* bitcast (%struct.__fundamental_type_info_pseudo* @_ZTIi to i8*), void (i8*)* null) noreturn + unreachable + +return: ; No predecessors! + ret void +} + +declare i8* @__cxa_allocate_exception(i32) nounwind + +declare void @__cxa_throw(i8*, i8*, void (i8*)*) noreturn + +declare i8* @__cxa_begin_catch(i8*) nounwind + +declare i8* @llvm.eh.exception() nounwind + +declare i32 @llvm.eh.selector.i32(i8*, i8*, ...) nounwind + +declare i32 @llvm.eh.typeid.for.i32(i8*) nounwind + +declare i32 @puts(i8*) + +declare void @__cxa_end_catch() + +declare void @_ZSt9terminatev() noreturn nounwind + +declare i32 @__gxx_personality_v0(...) + +declare void @_Unwind_Resume_or_Rethrow(i8*)