|  | //=== WebAssemblyExceptionInfoTest.cpp - WebAssebmlyExceptionInfo unit tests =// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "WebAssemblyExceptionInfo.h" | 
|  | #include "llvm/CodeGen/MIRParser/MIRParser.h" | 
|  | #include "llvm/CodeGen/MachineDominanceFrontier.h" | 
|  | #include "llvm/CodeGen/MachineDominators.h" | 
|  | #include "llvm/CodeGen/MachineModuleInfo.h" | 
|  | #include "llvm/Support/SourceMgr.h" | 
|  | #include "llvm/Support/TargetRegistry.h" | 
|  | #include "llvm/Support/TargetSelect.h" | 
|  | #include "llvm/Target/TargetMachine.h" | 
|  | #include "gtest/gtest.h" | 
|  |  | 
|  | using namespace llvm; | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | std::unique_ptr<TargetMachine> createTargetMachine() { | 
|  | auto TT(Triple::normalize("wasm32-unknown-unknown")); | 
|  | std::string CPU(""); | 
|  | std::string FS(""); | 
|  |  | 
|  | LLVMInitializeWebAssemblyTargetInfo(); | 
|  | LLVMInitializeWebAssemblyTarget(); | 
|  | LLVMInitializeWebAssemblyTargetMC(); | 
|  |  | 
|  | std::string Error; | 
|  | const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error); | 
|  | assert(TheTarget); | 
|  |  | 
|  | return std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine( | 
|  | TT, CPU, FS, TargetOptions(), None, None, CodeGenOpt::Default)); | 
|  | } | 
|  |  | 
|  | std::unique_ptr<Module> parseMIR(LLVMContext &Context, | 
|  | std::unique_ptr<MIRParser> &MIR, | 
|  | const TargetMachine &TM, StringRef MIRCode, | 
|  | const char *FuncName, MachineModuleInfo &MMI) { | 
|  | SMDiagnostic Diagnostic; | 
|  | std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode); | 
|  | MIR = createMIRParser(std::move(MBuffer), Context); | 
|  | if (!MIR) | 
|  | return nullptr; | 
|  |  | 
|  | std::unique_ptr<Module> M = MIR->parseIRModule(); | 
|  | if (!M) | 
|  | return nullptr; | 
|  |  | 
|  | M->setDataLayout(TM.createDataLayout()); | 
|  |  | 
|  | if (MIR->parseMachineFunctions(*M, MMI)) | 
|  | return nullptr; | 
|  |  | 
|  | return M; | 
|  | } | 
|  |  | 
|  | } // namespace | 
|  |  | 
|  | TEST(WebAssemblyExceptionInfoTest, TEST0) { | 
|  | std::unique_ptr<TargetMachine> TM = createTargetMachine(); | 
|  | ASSERT_TRUE(TM); | 
|  |  | 
|  | StringRef MIRString = R"MIR( | 
|  | --- | | 
|  | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | 
|  | target triple = "wasm32-unknown-unknown" | 
|  |  | 
|  | declare i32 @__gxx_wasm_personality_v0(...) | 
|  |  | 
|  | define hidden void @test0() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { | 
|  | unreachable | 
|  | } | 
|  |  | 
|  | ... | 
|  | --- | 
|  | name: test0 | 
|  | liveins: | 
|  | - { reg: '$arguments' } | 
|  | - { reg: '$value_stack' } | 
|  | body: | | 
|  | bb.0: | 
|  | successors: %bb.1, %bb.2 | 
|  | liveins: $arguments, $value_stack | 
|  | BR %bb.1, implicit-def dead $arguments | 
|  |  | 
|  | bb.1: | 
|  | ; predecessors: %bb.0 | 
|  | successors: %bb.7 | 
|  | liveins: $value_stack | 
|  | BR %bb.7, implicit-def $arguments | 
|  |  | 
|  | bb.2 (landing-pad): | 
|  | ; predecessors: %bb.0 | 
|  | successors: %bb.3, %bb.9 | 
|  | liveins: $value_stack | 
|  | CATCH_ALL implicit-def $arguments | 
|  | CLEANUPRET implicit-def dead $arguments | 
|  |  | 
|  | bb.3 (landing-pad): | 
|  | ; predecessors: %bb.2 | 
|  | successors: %bb.4, %bb.6 | 
|  | liveins: $value_stack | 
|  | CATCH_ALL implicit-def $arguments | 
|  | BR_IF %bb.4, %58:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack | 
|  | BR %bb.6, implicit-def $arguments | 
|  |  | 
|  | bb.4: | 
|  | ; predecessors: %bb.3 | 
|  | successors: %bb.5, %bb.8 | 
|  | liveins: $value_stack | 
|  | BR %bb.5, implicit-def dead $arguments | 
|  |  | 
|  | bb.5: | 
|  | ; predecessors: %bb.4 | 
|  | successors: %bb.7 | 
|  | liveins: $value_stack | 
|  | CATCHRET %bb.7, %bb.0, implicit-def dead $arguments | 
|  |  | 
|  | bb.6: | 
|  | ; predecessors: %bb.3 | 
|  | successors: %bb.10, %bb.9 | 
|  | liveins: $value_stack | 
|  | BR %bb.10, implicit-def dead $arguments | 
|  |  | 
|  | bb.7: | 
|  | ; predecessors: %bb.5, %bb.1 | 
|  | liveins: $value_stack | 
|  | RETURN_VOID implicit-def $arguments | 
|  |  | 
|  | bb.8 (landing-pad): | 
|  | ; predecessors: %bb.4 | 
|  | successors: %bb.9 | 
|  | liveins: $value_stack | 
|  | CATCH_ALL implicit-def $arguments | 
|  | CLEANUPRET implicit-def dead $arguments | 
|  |  | 
|  | bb.9 (landing-pad): | 
|  | ; predecessors: %bb.2, %bb.6, %bb.8 | 
|  | liveins: $value_stack | 
|  | CATCH_ALL implicit-def $arguments | 
|  | CLEANUPRET implicit-def dead $arguments | 
|  |  | 
|  | bb.10: | 
|  | ; predecessors: %bb.6 | 
|  | liveins: $value_stack | 
|  | UNREACHABLE implicit-def $arguments | 
|  | )MIR"; | 
|  |  | 
|  | LLVMContext Context; | 
|  | std::unique_ptr<MIRParser> MIR; | 
|  | MachineModuleInfo MMI(TM.get()); | 
|  | std::unique_ptr<Module> M = | 
|  | parseMIR(Context, MIR, *TM, MIRString, "test0", MMI); | 
|  | ASSERT_TRUE(M); | 
|  |  | 
|  | Function *F = M->getFunction("test0"); | 
|  | auto *MF = MMI.getMachineFunction(*F); | 
|  | ASSERT_TRUE(MF); | 
|  |  | 
|  | WebAssemblyExceptionInfo WEI; | 
|  | MachineDominatorTree MDT; | 
|  | MachineDominanceFrontier MDF; | 
|  | MDT.runOnMachineFunction(*MF); | 
|  | MDF.getBase().analyze(MDT.getBase()); | 
|  | WEI.recalculate(MDT, MDF); | 
|  |  | 
|  | // Exception info structure: | 
|  | // |- bb2 (ehpad), bb3, bb4, bb5, bb6, bb8, bb9, bb10 | 
|  | //   |- bb3 (ehpad), bb4, bb5, bb6, bb8, bb10 | 
|  | //     |- bb8 (ehpad) | 
|  | //   |- bb9 (ehpad) | 
|  |  | 
|  | auto *MBB2 = MF->getBlockNumbered(2); | 
|  | auto *WE0 = WEI.getExceptionFor(MBB2); | 
|  | ASSERT_TRUE(WE0); | 
|  | EXPECT_EQ(WE0->getEHPad(), MBB2); | 
|  | EXPECT_EQ(WE0->getParentException(), nullptr); | 
|  | EXPECT_EQ(WE0->getExceptionDepth(), (unsigned)1); | 
|  |  | 
|  | auto *MBB3 = MF->getBlockNumbered(3); | 
|  | auto *WE0_0 = WEI.getExceptionFor(MBB3); | 
|  | ASSERT_TRUE(WE0_0); | 
|  | EXPECT_EQ(WE0_0->getEHPad(), MBB3); | 
|  | EXPECT_EQ(WE0_0->getParentException(), WE0); | 
|  | EXPECT_EQ(WE0_0->getExceptionDepth(), (unsigned)2); | 
|  |  | 
|  | auto *MBB4 = MF->getBlockNumbered(4); | 
|  | WE0_0 = WEI.getExceptionFor(MBB4); | 
|  | ASSERT_TRUE(WE0_0); | 
|  | EXPECT_EQ(WE0_0->getEHPad(), MBB3); | 
|  |  | 
|  | auto *MBB5 = MF->getBlockNumbered(5); | 
|  | WE0_0 = WEI.getExceptionFor(MBB5); | 
|  | ASSERT_TRUE(WE0_0); | 
|  | EXPECT_EQ(WE0_0->getEHPad(), MBB3); | 
|  |  | 
|  | auto *MBB6 = MF->getBlockNumbered(6); | 
|  | WE0_0 = WEI.getExceptionFor(MBB6); | 
|  | ASSERT_TRUE(WE0_0); | 
|  | EXPECT_EQ(WE0_0->getEHPad(), MBB3); | 
|  |  | 
|  | auto *MBB10 = MF->getBlockNumbered(10); | 
|  | WE0_0 = WEI.getExceptionFor(MBB10); | 
|  | ASSERT_TRUE(WE0_0); | 
|  | EXPECT_EQ(WE0_0->getEHPad(), MBB3); | 
|  |  | 
|  | auto *MBB8 = MF->getBlockNumbered(8); | 
|  | auto *WE0_0_0 = WEI.getExceptionFor(MBB8); | 
|  | ASSERT_TRUE(WE0_0_0); | 
|  | EXPECT_EQ(WE0_0_0->getEHPad(), MBB8); | 
|  | EXPECT_EQ(WE0_0_0->getParentException(), WE0_0); | 
|  | EXPECT_EQ(WE0_0_0->getExceptionDepth(), (unsigned)3); | 
|  |  | 
|  | auto *MBB9 = MF->getBlockNumbered(9); | 
|  | auto *WE0_1 = WEI.getExceptionFor(MBB9); | 
|  | ASSERT_TRUE(WE0_1); | 
|  | EXPECT_EQ(WE0_1->getEHPad(), MBB9); | 
|  | EXPECT_EQ(WE0_1->getParentException(), WE0); | 
|  | EXPECT_EQ(WE0_1->getExceptionDepth(), (unsigned)2); | 
|  | } | 
|  |  | 
|  | TEST(WebAssemblyExceptionInfoTest, TEST1) { | 
|  | std::unique_ptr<TargetMachine> TM = createTargetMachine(); | 
|  | ASSERT_TRUE(TM); | 
|  |  | 
|  | StringRef MIRString = R"MIR( | 
|  | --- | | 
|  | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | 
|  | target triple = "wasm32-unknown-unknown" | 
|  |  | 
|  | declare i32 @__gxx_wasm_personality_v0(...) | 
|  |  | 
|  | define hidden void @test1() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { | 
|  | unreachable | 
|  | } | 
|  |  | 
|  | ... | 
|  | --- | 
|  | name: test1 | 
|  | liveins: | 
|  | - { reg: '$arguments' } | 
|  | - { reg: '$value_stack' } | 
|  | body: | | 
|  | bb.0: | 
|  | successors: %bb.9, %bb.1 | 
|  | liveins: $arguments, $value_stack | 
|  | BR %bb.9, implicit-def dead $arguments | 
|  |  | 
|  | bb.1 (landing-pad): | 
|  | ; predecessors: %bb.0 | 
|  | successors: %bb.2, %bb.8 | 
|  | liveins: $value_stack | 
|  | %52:i32 = CATCH_I32 0, implicit-def dead $arguments | 
|  | BR_IF %bb.2, %32:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack | 
|  | BR %bb.8, implicit-def $arguments | 
|  |  | 
|  | bb.2: | 
|  | ; predecessors: %bb.1 | 
|  | successors: %bb.7, %bb.3, %bb.11 | 
|  | liveins: $value_stack | 
|  | BR %bb.7, implicit-def dead $arguments | 
|  |  | 
|  | bb.3 (landing-pad): | 
|  | ; predecessors: %bb.2 | 
|  | successors: %bb.4, %bb.6 | 
|  | liveins: $value_stack | 
|  | CATCH_ALL implicit-def $arguments | 
|  | BR_IF %bb.4, %43:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack | 
|  | BR %bb.6, implicit-def $arguments | 
|  |  | 
|  | bb.4: | 
|  | ; predecessors: %bb.3 | 
|  | successors: %bb.5, %bb.10 | 
|  | liveins: $value_stack | 
|  | BR %bb.5, implicit-def dead $arguments | 
|  |  | 
|  | bb.5: | 
|  | ; predecessors: %bb.4 | 
|  | successors: %bb.7(0x80000000); %bb.7(200.00%) | 
|  | liveins: $value_stack | 
|  | CATCHRET %bb.7, %bb.1, implicit-def dead $arguments | 
|  |  | 
|  | bb.6: | 
|  | ; predecessors: %bb.3 | 
|  | successors: %bb.12, %bb.11 | 
|  | liveins: $value_stack | 
|  | BR %bb.12, implicit-def dead $arguments | 
|  |  | 
|  | bb.7: | 
|  | ; predecessors: %bb.2, %bb.5 | 
|  | successors: %bb.9(0x80000000); %bb.9(200.00%) | 
|  | liveins: $value_stack | 
|  | CATCHRET %bb.9, %bb.0, implicit-def dead $arguments | 
|  |  | 
|  | bb.8: | 
|  | ; predecessors: %bb.1 | 
|  | liveins: $value_stack | 
|  | UNREACHABLE implicit-def $arguments | 
|  |  | 
|  | bb.9: | 
|  | ; predecessors: %bb.0, %bb.7 | 
|  | liveins: $value_stack | 
|  | RETURN_VOID implicit-def $arguments | 
|  |  | 
|  | bb.10 (landing-pad): | 
|  | ; predecessors: %bb.4 | 
|  | successors: %bb.11 | 
|  | liveins: $value_stack | 
|  | CATCH_ALL implicit-def $arguments | 
|  | CLEANUPRET implicit-def dead $arguments | 
|  |  | 
|  | bb.11 (landing-pad): | 
|  | ; predecessors: %bb.2, %bb.6, %bb.10 | 
|  | liveins: $value_stack | 
|  | CATCH_ALL implicit-def $arguments | 
|  | CLEANUPRET implicit-def dead $arguments | 
|  |  | 
|  | bb.12: | 
|  | ; predecessors: %bb.6 | 
|  | liveins: $value_stack | 
|  | UNREACHABLE implicit-def $arguments | 
|  | )MIR"; | 
|  |  | 
|  | LLVMContext Context; | 
|  | std::unique_ptr<MIRParser> MIR; | 
|  | MachineModuleInfo MMI(TM.get()); | 
|  | std::unique_ptr<Module> M = | 
|  | parseMIR(Context, MIR, *TM, MIRString, "test1", MMI); | 
|  | ASSERT_TRUE(M); | 
|  |  | 
|  | Function *F = M->getFunction("test1"); | 
|  | auto *MF = MMI.getMachineFunction(*F); | 
|  | ASSERT_TRUE(MF); | 
|  |  | 
|  | WebAssemblyExceptionInfo WEI; | 
|  | MachineDominatorTree MDT; | 
|  | MachineDominanceFrontier MDF; | 
|  | MDT.runOnMachineFunction(*MF); | 
|  | MDF.getBase().analyze(MDT.getBase()); | 
|  | WEI.recalculate(MDT, MDF); | 
|  |  | 
|  | // Exception info structure: | 
|  | // |- bb1 (ehpad), bb2, bb3, bb4, bb5, bb6, bb7, bb8, bb10, bb11, bb12 | 
|  | //   |- bb3 (ehpad), bb4, bb5, bb6, bb10, bb12 | 
|  | //     |- bb10 (ehpad) | 
|  | //   |- bb11 (ehpad) | 
|  |  | 
|  | auto *MBB1 = MF->getBlockNumbered(1); | 
|  | auto *WE0 = WEI.getExceptionFor(MBB1); | 
|  | ASSERT_TRUE(WE0); | 
|  | EXPECT_EQ(WE0->getEHPad(), MBB1); | 
|  | EXPECT_EQ(WE0->getParentException(), nullptr); | 
|  | EXPECT_EQ(WE0->getExceptionDepth(), (unsigned)1); | 
|  |  | 
|  | auto *MBB2 = MF->getBlockNumbered(2); | 
|  | WE0 = WEI.getExceptionFor(MBB2); | 
|  | ASSERT_TRUE(WE0); | 
|  | EXPECT_EQ(WE0->getEHPad(), MBB1); | 
|  |  | 
|  | auto *MBB7 = MF->getBlockNumbered(7); | 
|  | WE0 = WEI.getExceptionFor(MBB7); | 
|  | ASSERT_TRUE(WE0); | 
|  | EXPECT_EQ(WE0->getEHPad(), MBB1); | 
|  |  | 
|  | auto *MBB8 = MF->getBlockNumbered(8); | 
|  | WE0 = WEI.getExceptionFor(MBB8); | 
|  | ASSERT_TRUE(WE0); | 
|  | EXPECT_EQ(WE0->getEHPad(), MBB1); | 
|  |  | 
|  | auto *MBB3 = MF->getBlockNumbered(3); | 
|  | auto *WE0_0 = WEI.getExceptionFor(MBB3); | 
|  | ASSERT_TRUE(WE0_0); | 
|  | EXPECT_EQ(WE0_0->getEHPad(), MBB3); | 
|  | EXPECT_EQ(WE0_0->getParentException(), WE0); | 
|  | EXPECT_EQ(WE0_0->getExceptionDepth(), (unsigned)2); | 
|  |  | 
|  | auto *MBB4 = MF->getBlockNumbered(4); | 
|  | WE0_0 = WEI.getExceptionFor(MBB4); | 
|  | ASSERT_TRUE(WE0_0); | 
|  | EXPECT_EQ(WE0_0->getEHPad(), MBB3); | 
|  |  | 
|  | auto *MBB5 = MF->getBlockNumbered(5); | 
|  | WE0_0 = WEI.getExceptionFor(MBB5); | 
|  | ASSERT_TRUE(WE0_0); | 
|  | EXPECT_EQ(WE0_0->getEHPad(), MBB3); | 
|  |  | 
|  | auto *MBB6 = MF->getBlockNumbered(6); | 
|  | WE0_0 = WEI.getExceptionFor(MBB6); | 
|  | ASSERT_TRUE(WE0_0); | 
|  | EXPECT_EQ(WE0_0->getEHPad(), MBB3); | 
|  |  | 
|  | auto *MBB12 = MF->getBlockNumbered(12); | 
|  | WE0_0 = WEI.getExceptionFor(MBB12); | 
|  | ASSERT_TRUE(WE0_0); | 
|  | EXPECT_EQ(WE0_0->getEHPad(), MBB3); | 
|  |  | 
|  | auto *MBB10 = MF->getBlockNumbered(10); | 
|  | auto *WE0_0_0 = WEI.getExceptionFor(MBB10); | 
|  | ASSERT_TRUE(WE0_0_0); | 
|  | EXPECT_EQ(WE0_0_0->getEHPad(), MBB10); | 
|  | EXPECT_EQ(WE0_0_0->getParentException(), WE0_0); | 
|  | EXPECT_EQ(WE0_0_0->getExceptionDepth(), (unsigned)3); | 
|  |  | 
|  | auto *MBB11 = MF->getBlockNumbered(11); | 
|  | auto *WE0_1 = WEI.getExceptionFor(MBB11); | 
|  | ASSERT_TRUE(WE0_1); | 
|  | EXPECT_EQ(WE0_1->getEHPad(), MBB11); | 
|  | EXPECT_EQ(WE0_1->getParentException(), WE0); | 
|  | EXPECT_EQ(WE0_1->getExceptionDepth(), (unsigned)2); | 
|  | } | 
|  |  | 
|  | // Terminate pad test | 
|  | TEST(WebAssemblyExceptionInfoTest, TEST2) { | 
|  | std::unique_ptr<TargetMachine> TM = createTargetMachine(); | 
|  | ASSERT_TRUE(TM); | 
|  |  | 
|  | StringRef MIRString = R"MIR( | 
|  | --- | | 
|  | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | 
|  | target triple = "wasm32-unknown-unknown" | 
|  |  | 
|  | declare i32 @__gxx_wasm_personality_v0(...) | 
|  | declare void @_ZSt9terminatev() | 
|  | declare void @__clang_call_terminate(i8*) | 
|  |  | 
|  | define hidden void @test2() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { | 
|  | unreachable | 
|  | } | 
|  |  | 
|  | ... | 
|  | --- | 
|  | name: test2 | 
|  | liveins: | 
|  | - { reg: '$arguments' } | 
|  | - { reg: '$value_stack' } | 
|  | body: | | 
|  | bb.0: | 
|  | successors: %bb.3, %bb.1 | 
|  | BR %bb.3, implicit-def dead $arguments | 
|  |  | 
|  | bb.1 (landing-pad): | 
|  | ; predecessors: %bb.0 | 
|  | successors: %bb.2, %bb.4 | 
|  | %3:i32 = CATCH_I32 0, implicit-def dead $arguments | 
|  | BR %bb.2, implicit-def dead $arguments | 
|  |  | 
|  | bb.2: | 
|  | ; predecessors: %bb.1 | 
|  | successors: %bb.3(0x80000000); %bb.3(200.00%) | 
|  | CATCHRET %bb.3, %bb.0, implicit-def dead $arguments | 
|  |  | 
|  | bb.3: | 
|  | ; predecessors: %bb.0, %bb.2 | 
|  | RETURN_VOID implicit-def $arguments | 
|  |  | 
|  | bb.4 (landing-pad): | 
|  | ; predecessors: %bb.1 | 
|  | successors: %bb.5, %bb.6 | 
|  | CATCH_ALL implicit-def $arguments | 
|  | BR %bb.5, implicit-def dead $arguments | 
|  |  | 
|  | bb.5: | 
|  | ; predecessors: %bb.4 | 
|  | CLEANUPRET implicit-def dead $arguments | 
|  |  | 
|  | bb.6 (landing-pad): | 
|  | ; predecessors: %bb.4 | 
|  | successors: %bb.7(0x80000000); %bb.7(200.00%) | 
|  | %6:i32 = CATCH_I32 0, implicit-def dead $arguments | 
|  | CALL_VOID @__clang_call_terminate, %7:i32, implicit-def $arguments | 
|  | UNREACHABLE implicit-def $arguments | 
|  |  | 
|  | bb.7 (landing-pad): | 
|  | ; predecessors: %bb.6 | 
|  | CATCH_ALL implicit-def $arguments | 
|  | CALL_VOID @_ZSt9terminatev, implicit-def $arguments | 
|  | UNREACHABLE implicit-def $arguments | 
|  | )MIR"; | 
|  |  | 
|  | LLVMContext Context; | 
|  | std::unique_ptr<MIRParser> MIR; | 
|  | MachineModuleInfo MMI(TM.get()); | 
|  | std::unique_ptr<Module> M = | 
|  | parseMIR(Context, MIR, *TM, MIRString, "test2", MMI); | 
|  | ASSERT_TRUE(M); | 
|  |  | 
|  | Function *F = M->getFunction("test2"); | 
|  | auto *MF = MMI.getMachineFunction(*F); | 
|  | ASSERT_TRUE(MF); | 
|  |  | 
|  | WebAssemblyExceptionInfo WEI; | 
|  | MachineDominatorTree MDT; | 
|  | MachineDominanceFrontier MDF; | 
|  | MDT.runOnMachineFunction(*MF); | 
|  | MDF.getBase().analyze(MDT.getBase()); | 
|  | WEI.recalculate(MDT, MDF); | 
|  |  | 
|  | // Exception info structure: | 
|  | // |- bb1 (ehpad), bb2, bb4, bb5, bb6, bb7 | 
|  | //   |- bb4 (ehpad), bb5, bb6, bb7 | 
|  | //     |- bb6 (ehpad), bb7 | 
|  | // | 
|  | // Here, bb6 is a terminate pad with a 'catch' instruction, and bb7 is a | 
|  | // terminate pad with a 'catch_all' instruction, In this case we put bb6 and | 
|  | // bb7 into one exception. | 
|  |  | 
|  | auto *MBB1 = MF->getBlockNumbered(1); | 
|  | auto *WE0 = WEI.getExceptionFor(MBB1); | 
|  | ASSERT_TRUE(WE0); | 
|  | EXPECT_EQ(WE0->getEHPad(), MBB1); | 
|  | EXPECT_EQ(WE0->getParentException(), nullptr); | 
|  | EXPECT_EQ(WE0->getExceptionDepth(), (unsigned)1); | 
|  |  | 
|  | auto *MBB2 = MF->getBlockNumbered(2); | 
|  | WE0 = WEI.getExceptionFor(MBB2); | 
|  | ASSERT_TRUE(WE0); | 
|  | EXPECT_EQ(WE0->getEHPad(), MBB1); | 
|  |  | 
|  | auto *MBB4 = MF->getBlockNumbered(4); | 
|  | auto *WE0_0 = WEI.getExceptionFor(MBB4); | 
|  | ASSERT_TRUE(WE0_0); | 
|  | EXPECT_EQ(WE0_0->getEHPad(), MBB4); | 
|  | EXPECT_EQ(WE0_0->getParentException(), WE0); | 
|  | EXPECT_EQ(WE0_0->getExceptionDepth(), (unsigned)2); | 
|  |  | 
|  | auto *MBB5 = MF->getBlockNumbered(5); | 
|  | WE0_0 = WEI.getExceptionFor(MBB5); | 
|  | ASSERT_TRUE(WE0_0); | 
|  | EXPECT_EQ(WE0_0->getEHPad(), MBB4); | 
|  |  | 
|  | auto *MBB6 = MF->getBlockNumbered(6); | 
|  | auto *WE0_0_0 = WEI.getExceptionFor(MBB6); | 
|  | ASSERT_TRUE(WE0_0_0); | 
|  | EXPECT_EQ(WE0_0_0->getEHPad(), MBB6); | 
|  | EXPECT_EQ(WE0_0_0->getParentException(), WE0_0); | 
|  | EXPECT_EQ(WE0_0_0->getExceptionDepth(), (unsigned)3); | 
|  |  | 
|  | auto *MBB7 = MF->getBlockNumbered(7); | 
|  | WE0_0_0 = WEI.getExceptionFor(MBB7); | 
|  | ASSERT_TRUE(WE0_0_0); | 
|  | EXPECT_EQ(WE0_0_0->getEHPad(), MBB6); | 
|  | } |