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 AndricFunctionPass *llvm::createWebAssemblyCleanCodeAfterTrap() { 47ac9a064cSDimitry Andric return new WebAssemblyCleanCodeAfterTrap(); 48ac9a064cSDimitry Andric } 49ac9a064cSDimitry Andric runOnMachineFunction(MachineFunction & MF)50ac9a064cSDimitry Andricbool 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