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 WebAssemblyCleanCodeAfterTrap()32 WebAssemblyCleanCodeAfterTrap() : MachineFunctionPass(ID) {} 33 getPassName() const34 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 createWebAssemblyCleanCodeAfterTrap()46FunctionPass *llvm::createWebAssemblyCleanCodeAfterTrap() { 47 return new WebAssemblyCleanCodeAfterTrap(); 48 } 49 runOnMachineFunction(MachineFunction & MF)50bool 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