aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2012-11-19 21:06:26 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2012-11-19 21:06:26 +0000
commit2386fc8daa682c7b6c2479cd9c9c3113581c41db (patch)
tree2021ae0f1116be36930ed37b6eba37acd69e0795
parent97c3472bf915ce9124f682f6c8ce9e4baff7c284 (diff)
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168325 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/AsmPrinter/ARMException.cpp49
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.cpp14
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.h3
-rw-r--r--test/CodeGen/ARM/ehabi-filters.ll77
4 files changed, 141 insertions, 2 deletions
diff --git a/lib/CodeGen/AsmPrinter/ARMException.cpp b/lib/CodeGen/AsmPrinter/ARMException.cpp
index 8eea802765..bbbdfd3c10 100644
--- a/lib/CodeGen/AsmPrinter/ARMException.cpp
+++ b/lib/CodeGen/AsmPrinter/ARMException.cpp
@@ -93,3 +93,52 @@ void ARMException::EndFunction() {
Asm->OutStreamer.EmitFnEnd();
}
+
+void ARMException::EmitTypeInfos(unsigned TTypeEncoding) {
+ const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
+ const std::vector<unsigned> &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 GlobalVariable *>::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<unsigned>::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/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp
index 0fab389ab7..4ebb75b9b8 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.cpp
+++ b/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<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
+ const std::vector<unsigned> &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/lib/CodeGen/AsmPrinter/DwarfException.h b/lib/CodeGen/AsmPrinter/DwarfException.h
index fe9e493609..74b1b13367 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.h
+++ b/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/test/CodeGen/ARM/ehabi-filters.ll b/test/CodeGen/ARM/ehabi-filters.ll
new file mode 100644
index 0000000000..d15aa7b32c
--- /dev/null
+++ b/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"}