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(Elt: &MI); |
64 | if (MI.hasProperty(MCFlag: 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 |