llvm.org GIT mirror llvm / 048d7e5
[WinEH] Add a funclet layout pass Windows EH funclets need to be contiguous. The FuncletLayout pass will ensure that the funclets are together and begin with a funclet entry MBB. Differential Revision: http://reviews.llvm.org/D12943 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247937 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 4 years ago
7 changed file(s) with 150 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
581581 /// StackSlotColoring - This pass performs stack slot coloring.
582582 extern char &StackSlotColoringID;
583583
584 /// \brief This pass lays out funclets contiguously.
585 extern char &FuncletLayoutID;
586
584587 /// createStackProtectorPass - This pass adds stack protectors to functions.
585588 ///
586589 FunctionPass *createStackProtectorPass(const TargetMachine *TM);
298298 void initializeLoopDistributePass(PassRegistry&);
299299 void initializeSjLjEHPreparePass(PassRegistry&);
300300 void initializeDemandedBitsPass(PassRegistry&);
301 void initializeFuncletLayoutPass(PassRegistry &);
301302 }
302303
303304 #endif
2525 ExpandISelPseudos.cpp
2626 ExpandPostRAPseudos.cpp
2727 FaultMaps.cpp
28 FuncletLayout.cpp
2829 GCMetadata.cpp
2930 GCMetadataPrinter.cpp
3031 GCRootLowering.cpp
2828 initializeExpandISelPseudosPass(Registry);
2929 initializeExpandPostRAPass(Registry);
3030 initializeFinalizeMachineBundlesPass(Registry);
31 initializeFuncletLayoutPass(Registry);
3132 initializeGCMachineCodeAnalysisPass(Registry);
3233 initializeGCModuleInfoPass(Registry);
3334 initializeIfConverterPass(Registry);
0 //===-- FuncletLayout.cpp - Contiguously lay out funclets -----------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements basic block placement transformations which result in
10 // funclets being contiguous.
11 //
12 //===----------------------------------------------------------------------===//
13 #include "llvm/CodeGen/Passes.h"
14 #include "llvm/ADT/MapVector.h"
15 #include "llvm/CodeGen/MachineBasicBlock.h"
16 #include "llvm/CodeGen/MachineFunction.h"
17 #include "llvm/CodeGen/MachineFunctionPass.h"
18 #include "llvm/CodeGen/MachineModuleInfo.h"
19 using namespace llvm;
20
21 #define DEBUG_TYPE "funclet-layout"
22
23 namespace {
24 class FuncletLayout : public MachineFunctionPass {
25 public:
26 static char ID; // Pass identification, replacement for typeid
27 FuncletLayout() : MachineFunctionPass(ID) {
28 initializeFuncletLayoutPass(*PassRegistry::getPassRegistry());
29 }
30
31 bool runOnMachineFunction(MachineFunction &F) override;
32 };
33 }
34
35 static void
36 collectFuncletMembers(MapVector &FuncletMembership,
37 int Funclet, MachineBasicBlock *MBB) {
38 // Don't revisit blocks.
39 if (FuncletMembership.count(MBB) > 0)
40 return;
41
42 // Add this MBB to our funclet.
43 FuncletMembership[MBB] = Funclet;
44
45 bool IsReturn = false;
46 int NumTerminators = 0;
47 for (MachineInstr &MI : MBB->terminators()) {
48 IsReturn |= MI.isReturn();
49 ++NumTerminators;
50 }
51 assert((!IsReturn || NumTerminators == 1) &&
52 "Expected only one terminator when a return is present!");
53
54 // Returns are boundaries where funclet transfer can occur, don't follow
55 // successors.
56 if (IsReturn)
57 return;
58
59 for (MachineBasicBlock *SMBB : MBB->successors())
60 if (!SMBB->isEHPad())
61 collectFuncletMembers(FuncletMembership, Funclet, SMBB);
62 }
63
64 char FuncletLayout::ID = 0;
65 char &llvm::FuncletLayoutID = FuncletLayout::ID;
66 INITIALIZE_PASS(FuncletLayout, "funclet-layout",
67 "Contiguously Lay Out Funclets", false, false)
68
69 bool FuncletLayout::runOnMachineFunction(MachineFunction &F) {
70 // We don't have anything to do if there aren't any EH pads.
71 if (!F.getMMI().hasEHFunclets())
72 return false;
73
74 SmallVector FuncletBlocks;
75 for (MachineBasicBlock &MBB : F)
76 if (MBB.isEHFuncletEntry())
77 FuncletBlocks.push_back(&MBB);
78
79 // We don't have anything to do if there aren't any EH pads.
80 if (FuncletBlocks.empty())
81 return false;
82
83 MapVector FuncletMembership;
84 for (MachineBasicBlock *MBB : FuncletBlocks)
85 collectFuncletMembers(FuncletMembership, MBB->getNumber(), MBB);
86
87 for (std::pair &FuncletMember :
88 FuncletMembership) {
89 // Move this block to the end of the function.
90 MachineBasicBlock *MBB = FuncletMember.first;
91 MBB->moveAfter(--F.end());
92 }
93
94 // Conservatively assume we changed something.
95 return true;
96 }
581581
582582 addPreEmitPass();
583583
584 addPass(&FuncletLayoutID, false);
585
584586 addPass(&StackMapLivenessID, false);
585587
586588 AddingMachinePasses = false;
0 ; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s
1
2 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
3 target triple = "x86_64-pc-windows-msvc"
4
5 define void @f(i1 %B) personality i32 (...)* @__CxxFrameHandler3 {
6 entry:
7 invoke void @g()
8 to label %unreachable unwind label %catch.dispatch
9
10 catch.dispatch:
11 %cp = catchpad [i8* null, i32 64, i8* null]
12 to label %catch unwind label %catchendblock
13
14 catch:
15 br i1 %B, label %catchret, label %catch
16
17 catchret:
18 catchret %cp to label %try.cont
19
20 try.cont:
21 ret void
22
23 catchendblock:
24 catchendpad unwind to caller
25
26 unreachable:
27 unreachable
28 }
29
30 ; CHECK-LABEL: f:
31
32 ; The entry funclet contains %entry and %try.cont
33 ; CHECK: # %entry
34 ; CHECK: # %try.cont
35 ; CHECK: retq
36
37 ; The catch funclet contains %catch and %catchret
38 ; CHECK: # %catch
39 ; CHECK: # %catchret
40 ; CHECK: retq
41
42 declare void @g()
43
44 declare i32 @__CxxFrameHandler3(...)