xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/EHContGuardCatchret.cpp (revision ec0ea6efa1ad229d75c394c1a9b9cac33af2b1d3)
1 //===-- EHContGuardCatchret.cpp - Catchret target symbols -------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file contains a machine function pass to insert a symbol before each
11 /// valid catchret target and store this in the MachineFunction's
12 /// CatchRetTargets vector. This will be used to emit the table of valid targets
13 /// used by EHCont Guard.
14 ///
15 //===----------------------------------------------------------------------===//
16 
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/CodeGen/MachineBasicBlock.h"
19 #include "llvm/CodeGen/MachineFunctionPass.h"
20 #include "llvm/CodeGen/MachineInstr.h"
21 #include "llvm/CodeGen/MachineModuleInfo.h"
22 #include "llvm/CodeGen/MachineOperand.h"
23 #include "llvm/CodeGen/Passes.h"
24 #include "llvm/InitializePasses.h"
25 
26 using namespace llvm;
27 
28 #define DEBUG_TYPE "ehcontguard-catchret"
29 
30 STATISTIC(EHContGuardCatchretTargets,
31           "Number of EHCont Guard catchret targets");
32 
33 namespace {
34 
35 /// MachineFunction pass to insert a symbol before each valid catchret target
36 /// and store these in the MachineFunction's CatchRetTargets vector.
37 class EHContGuardCatchret : public MachineFunctionPass {
38 public:
39   static char ID;
40 
41   EHContGuardCatchret() : MachineFunctionPass(ID) {
42     initializeEHContGuardCatchretPass(*PassRegistry::getPassRegistry());
43   }
44 
45   StringRef getPassName() const override {
46     return "EH Cont Guard catchret targets";
47   }
48 
49   bool runOnMachineFunction(MachineFunction &MF) override;
50 };
51 
52 } // end anonymous namespace
53 
54 char EHContGuardCatchret::ID = 0;
55 
56 INITIALIZE_PASS(EHContGuardCatchret, "EHContGuardCatchret",
57                 "Insert symbols at valid catchret targets for /guard:ehcont",
58                 false, false)
59 FunctionPass *llvm::createEHContGuardCatchretPass() {
60   return new EHContGuardCatchret();
61 }
62 
63 bool EHContGuardCatchret::runOnMachineFunction(MachineFunction &MF) {
64 
65   // Skip modules for which the ehcontguard flag is not set.
66   if (!MF.getMMI().getModule()->getModuleFlag("ehcontguard"))
67     return false;
68 
69   // Skip functions that do not have catchret
70   if (!MF.hasEHCatchret())
71     return false;
72 
73   bool Result = false;
74 
75   for (MachineBasicBlock &MBB : MF) {
76     if (MBB.isEHCatchretTarget()) {
77       MF.addCatchretTarget(MBB.getEHCatchretSymbol());
78       EHContGuardCatchretTargets++;
79       Result = true;
80     }
81   }
82 
83   return Result;
84 }
85