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