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