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