From f65a638d942b87413a7181acb965e4c2fc4c0c6f Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Mon, 19 Nov 2012 21:06:26 +0000 Subject: [PATCH] Factor out type info emission into separate routine. It turned out that ARM wants different layout of type infos. This is yet another patch in attempt to fix PR7187 llvm-svn: 168325 --- llvm/lib/CodeGen/AsmPrinter/ARMException.cpp | 49 ++++++++++++++++ llvm/lib/CodeGen/AsmPrinter/DwarfException.cpp | 14 ++++- llvm/lib/CodeGen/AsmPrinter/DwarfException.h | 3 + llvm/test/CodeGen/ARM/ehabi-filters.ll | 77 ++++++++++++++++++++++++++ 4 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/ARM/ehabi-filters.ll diff --git a/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp b/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp index 8eea802..bbbdfd3 100644 --- a/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp @@ -93,3 +93,52 @@ void ARMException::EndFunction() { Asm->OutStreamer.EmitFnEnd(); } + +void ARMException::EmitTypeInfos(unsigned TTypeEncoding) { + const std::vector &TypeInfos = MMI->getTypeInfos(); + const std::vector &FilterIds = MMI->getFilterIds(); + + bool VerboseAsm = Asm->OutStreamer.isVerboseAsm(); + + int Entry = 0; + // Emit the Catch TypeInfos. + if (VerboseAsm && !TypeInfos.empty()) { + Asm->OutStreamer.AddComment(">> Catch TypeInfos <<"); + Asm->OutStreamer.AddBlankLine(); + Entry = TypeInfos.size(); + } + + for (std::vector::const_reverse_iterator + I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) { + const GlobalVariable *GV = *I; + if (VerboseAsm) + Asm->OutStreamer.AddComment("TypeInfo " + Twine(Entry--)); + if (GV) + Asm->EmitTTypeReference(GV, TTypeEncoding); + else + Asm->OutStreamer.EmitIntValue(0,Asm->GetSizeOfEncodedValue(TTypeEncoding), + 0); + } + + // Emit the Exception Specifications. + if (VerboseAsm && !FilterIds.empty()) { + Asm->OutStreamer.AddComment(">> Filter TypeInfos <<"); + Asm->OutStreamer.AddBlankLine(); + Entry = 0; + } + for (std::vector::const_iterator + I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { + unsigned TypeID = *I; + if (VerboseAsm) { + --Entry; + if (TypeID != 0) + Asm->OutStreamer.AddComment("FilterInfo " + Twine(Entry)); + } + + if (TypeID == 0) + Asm->OutStreamer.EmitIntValue(0,Asm->GetSizeOfEncodedValue(TTypeEncoding), + 0); + else + Asm->EmitTTypeReference(TypeInfos[TypeID - 1], TTypeEncoding); + } +} diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfException.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfException.cpp index 0fab389..4ebb75b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfException.cpp @@ -672,6 +672,18 @@ void DwarfException::EmitExceptionTable() { Asm->EmitSLEB128(Action.NextAction); } + EmitTypeInfos(TTypeEncoding); + + Asm->EmitAlignment(2); +} + +void DwarfException::EmitTypeInfos(unsigned TTypeEncoding) { + const std::vector &TypeInfos = MMI->getTypeInfos(); + const std::vector &FilterIds = MMI->getFilterIds(); + + bool VerboseAsm = Asm->OutStreamer.isVerboseAsm(); + + int Entry = 0; // Emit the Catch TypeInfos. if (VerboseAsm && !TypeInfos.empty()) { Asm->OutStreamer.AddComment(">> Catch TypeInfos <<"); @@ -708,8 +720,6 @@ void DwarfException::EmitExceptionTable() { Asm->EmitULEB128(TypeID); } - - Asm->EmitAlignment(2); } /// EndModule - Emit all exception information that should come after the diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfException.h b/llvm/lib/CodeGen/AsmPrinter/DwarfException.h index fe9e493..74b1b13 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfException.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfException.h @@ -121,6 +121,8 @@ protected: /// catches in the function. This tables is reversed indexed base 1. void EmitExceptionTable(); + virtual void EmitTypeInfos(unsigned TTypeEncoding); + public: //===--------------------------------------------------------------------===// // Main entry points. @@ -175,6 +177,7 @@ public: }; class ARMException : public DwarfException { + void EmitTypeInfos(unsigned TTypeEncoding); public: //===--------------------------------------------------------------------===// // Main entry points. diff --git a/llvm/test/CodeGen/ARM/ehabi-filters.ll b/llvm/test/CodeGen/ARM/ehabi-filters.ll new file mode 100644 index 0000000..d15aa7b3 --- /dev/null +++ b/llvm/test/CodeGen/ARM/ehabi-filters.ll @@ -0,0 +1,77 @@ +; RUN: llc -arm-enable-ehabi -arm-enable-ehabi-descriptors < %s | FileCheck %s +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:64-n32-S64" +target triple = "armv7-none-linux-gnueabi" + +@_ZTIi = external constant i8* + +declare void @_Z3foov() noreturn; + +declare i8* @__cxa_allocate_exception(i32) + +declare i32 @__gxx_personality_v0(...) + +declare void @__cxa_throw(i8*, i8*, i8*) + +declare void @__cxa_call_unexpected(i8*) + +define i32 @main() { +; CHECK main: +entry: + %exception.i = tail call i8* @__cxa_allocate_exception(i32 4) nounwind + %0 = bitcast i8* %exception.i to i32* + store i32 42, i32* %0, align 4, !tbaa !0 + invoke void @__cxa_throw(i8* %exception.i, i8* bitcast (i8** @_ZTIi to i8*), i8* null) noreturn + to label %unreachable.i unwind label %lpad.i + +lpad.i: ; preds = %entry + %1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + filter [1 x i8*] [i8* bitcast (i8** @_ZTIi to i8*)] + catch i8* bitcast (i8** @_ZTIi to i8*) +; CHECK: .long _ZTIi(target2) @ TypeInfo 1 +; CHECK: .long _ZTIi(target2) @ FilterInfo -1 + %2 = extractvalue { i8*, i32 } %1, 1 + %ehspec.fails.i = icmp slt i32 %2, 0 + br i1 %ehspec.fails.i, label %ehspec.unexpected.i, label %lpad.body + +ehspec.unexpected.i: ; preds = %lpad.i + %3 = extractvalue { i8*, i32 } %1, 0 + invoke void @__cxa_call_unexpected(i8* %3) noreturn + to label %.noexc unwind label %lpad + +.noexc: ; preds = %ehspec.unexpected.i + unreachable + +unreachable.i: ; preds = %entry + unreachable + +lpad: ; preds = %ehspec.unexpected.i + %4 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* bitcast (i8** @_ZTIi to i8*) + br label %lpad.body + +lpad.body: ; preds = %lpad.i, %lpad + %eh.lpad-body = phi { i8*, i32 } [ %4, %lpad ], [ %1, %lpad.i ] + %5 = extractvalue { i8*, i32 } %eh.lpad-body, 1 + %6 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) nounwind + %matches = icmp eq i32 %5, %6 + br i1 %matches, label %try.cont, label %eh.resume + +try.cont: ; preds = %lpad.body + %7 = extractvalue { i8*, i32 } %eh.lpad-body, 0 + %8 = tail call i8* @__cxa_begin_catch(i8* %7) nounwind + tail call void @__cxa_end_catch() nounwind + ret i32 0 + +eh.resume: ; preds = %lpad.body + resume { i8*, i32 } %eh.lpad-body +} + +declare i32 @llvm.eh.typeid.for(i8*) nounwind readnone + +declare i8* @__cxa_begin_catch(i8*) + +declare void @__cxa_end_catch() + +!0 = metadata !{metadata !"int", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA"} -- 2.7.4