xref: /freebsd/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyCleanCodeAfterTrap.cpp (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
1 //===-- WebAssemblyCleanCodeAfterTrap.cpp - Clean Code After Trap ---------===//
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 remove instruction after trap.
11 /// ``llvm.trap`` will be convert as ``unreachable`` which is terminator.
12 /// Instruction after terminator will cause validation failed.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #include "WebAssembly.h"
17 #include "WebAssemblyUtilities.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
20 #include "llvm/CodeGen/Passes.h"
21 #include "llvm/MC/MCInstrDesc.h"
22 #include "llvm/Support/Debug.h"
23 #include "llvm/Support/raw_ostream.h"
24 using namespace llvm;
25 
26 #define DEBUG_TYPE "wasm-clean-code-after-trap"
27 
28 namespace {
29 class WebAssemblyCleanCodeAfterTrap final : public MachineFunctionPass {
30 public:
31   static char ID; // Pass identification, replacement for typeid
32   WebAssemblyCleanCodeAfterTrap() : MachineFunctionPass(ID) {}
33 
34   StringRef getPassName() const override {
35     return "WebAssembly Clean Code After Trap";
36   }
37 
38   bool runOnMachineFunction(MachineFunction &MF) override;
39 };
40 } // end anonymous namespace
41 
42 char WebAssemblyCleanCodeAfterTrap::ID = 0;
43 INITIALIZE_PASS(WebAssemblyCleanCodeAfterTrap, DEBUG_TYPE,
44                 "WebAssembly Clean Code After Trap", false, false)
45 
46 FunctionPass *llvm::createWebAssemblyCleanCodeAfterTrap() {
47   return new WebAssemblyCleanCodeAfterTrap();
48 }
49 
50 bool WebAssemblyCleanCodeAfterTrap::runOnMachineFunction(MachineFunction &MF) {
51   LLVM_DEBUG({
52     dbgs() << "********** CleanCodeAfterTrap **********\n"
53            << "********** Function: " << MF.getName() << '\n';
54   });
55 
56   bool Changed = false;
57 
58   for (MachineBasicBlock &BB : MF) {
59     bool HasTerminator = false;
60     llvm::SmallVector<MachineInstr *> RemoveMI{};
61     for (MachineInstr &MI : BB) {
62       if (HasTerminator)
63         RemoveMI.push_back(&MI);
64       if (MI.hasProperty(MCID::Trap) && MI.isTerminator())
65         HasTerminator = true;
66     }
67     if (!RemoveMI.empty()) {
68       Changed = true;
69       LLVM_DEBUG({
70         for (MachineInstr *MI : RemoveMI) {
71           llvm::dbgs() << "* remove ";
72           MI->print(llvm::dbgs());
73         }
74       });
75       for (MachineInstr *MI : RemoveMI)
76         MI->eraseFromParent();
77     }
78   }
79   return Changed;
80 }
81