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/MachineFunctionAnalysisManager.h"
21#include "llvm/CodeGen/MachinePassManager.h"
22#include "llvm/CodeGen/Passes.h"
23#include "llvm/IR/Analysis.h"
24#include "llvm/MC/MCInstrDesc.h"
25#include "llvm/Support/Debug.h"
26#include "llvm/Support/raw_ostream.h"
27using namespace llvm;
28
29#define DEBUG_TYPE "wasm-clean-code-after-trap"
30
31namespace {
32class WebAssemblyCleanCodeAfterTrapLegacy final : public MachineFunctionPass {
33public:
34 static char ID; // Pass identification, replacement for typeid
35 WebAssemblyCleanCodeAfterTrapLegacy() : MachineFunctionPass(ID) {}
36
37 StringRef getPassName() const override {
38 return "WebAssembly Clean Code After Trap";
39 }
40
41 bool runOnMachineFunction(MachineFunction &MF) override;
42};
43} // end anonymous namespace
44
45char WebAssemblyCleanCodeAfterTrapLegacy::ID = 0;
46INITIALIZE_PASS(WebAssemblyCleanCodeAfterTrapLegacy, DEBUG_TYPE,
47 "WebAssembly Clean Code After Trap", false, false)
48
49FunctionPass *llvm::createWebAssemblyCleanCodeAfterTrapLegacyPass() {
50 return new WebAssemblyCleanCodeAfterTrapLegacy();
51}
52
53static bool cleanCodeAfterTrap(MachineFunction &MF) {
54 LLVM_DEBUG({
55 dbgs() << "********** CleanCodeAfterTrap **********\n"
56 << "********** Function: " << MF.getName() << '\n';
57 });
58
59 bool Changed = false;
60
61 for (MachineBasicBlock &BB : MF) {
62 bool HasTerminator = false;
63 llvm::SmallVector<MachineInstr *> RemoveMI{};
64 for (MachineInstr &MI : BB) {
65 if (HasTerminator)
66 RemoveMI.push_back(Elt: &MI);
67 if (MI.hasProperty(MCFlag: MCID::Trap) && MI.isTerminator())
68 HasTerminator = true;
69 }
70 if (!RemoveMI.empty()) {
71 Changed = true;
72 LLVM_DEBUG({
73 for (MachineInstr *MI : RemoveMI) {
74 llvm::dbgs() << "* remove ";
75 MI->print(llvm::dbgs());
76 }
77 });
78 for (MachineInstr *MI : RemoveMI)
79 MI->eraseFromParent();
80 }
81 }
82 return Changed;
83}
84
85bool WebAssemblyCleanCodeAfterTrapLegacy::runOnMachineFunction(
86 MachineFunction &MF) {
87 return cleanCodeAfterTrap(MF);
88}
89
90PreservedAnalyses
91WebAssemblyCleanCodeAfterTrapPass::run(MachineFunction &MF,
92 MachineFunctionAnalysisManager &MFAM) {
93 return cleanCodeAfterTrap(MF) ? getMachineFunctionPassPreservedAnalyses()
94 .preserveSet<CFGAnalyses>()
95 : PreservedAnalyses::all();
96}
97