1 //===-- WebAssemblyPeephole.cpp - WebAssembly Peephole Optimiztions -------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// \brief Late peephole optimizations for WebAssembly. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #include "WebAssembly.h" 16 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 17 #include "WebAssemblyMachineFunctionInfo.h" 18 #include "llvm/CodeGen/MachineFunctionPass.h" 19 using namespace llvm; 20 21 #define DEBUG_TYPE "wasm-peephole" 22 23 namespace { 24 class WebAssemblyPeephole final : public MachineFunctionPass { getPassName() const25 const char *getPassName() const override { 26 return "WebAssembly late peephole optimizer"; 27 } 28 getAnalysisUsage(AnalysisUsage & AU) const29 void getAnalysisUsage(AnalysisUsage &AU) const override { 30 AU.setPreservesCFG(); 31 MachineFunctionPass::getAnalysisUsage(AU); 32 } 33 34 bool runOnMachineFunction(MachineFunction &MF) override; 35 36 public: 37 static char ID; WebAssemblyPeephole()38 WebAssemblyPeephole() : MachineFunctionPass(ID) {} 39 }; 40 } // end anonymous namespace 41 42 char WebAssemblyPeephole::ID = 0; createWebAssemblyPeephole()43FunctionPass *llvm::createWebAssemblyPeephole() { 44 return new WebAssemblyPeephole(); 45 } 46 runOnMachineFunction(MachineFunction & MF)47bool WebAssemblyPeephole::runOnMachineFunction(MachineFunction &MF) { 48 bool Changed = false; 49 50 MachineRegisterInfo &MRI = MF.getRegInfo(); 51 WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>(); 52 53 for (auto &MBB : MF) 54 for (auto &MI : MBB) 55 switch (MI.getOpcode()) { 56 default: 57 break; 58 case WebAssembly::STORE8_I32: 59 case WebAssembly::STORE16_I32: 60 case WebAssembly::STORE8_I64: 61 case WebAssembly::STORE16_I64: 62 case WebAssembly::STORE32_I64: 63 case WebAssembly::STORE_F32: 64 case WebAssembly::STORE_F64: 65 case WebAssembly::STORE_I32: 66 case WebAssembly::STORE_I64: { 67 // Store instructions return their value operand. If we ended up using 68 // the same register for both, replace it with a dead def so that it 69 // can use $discard instead. 70 MachineOperand &MO = MI.getOperand(0); 71 unsigned OldReg = MO.getReg(); 72 // TODO: Handle SP/physregs 73 if (OldReg == MI.getOperand(3).getReg() 74 && TargetRegisterInfo::isVirtualRegister(MI.getOperand(3).getReg())) { 75 Changed = true; 76 unsigned NewReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg)); 77 MO.setReg(NewReg); 78 MO.setIsDead(); 79 MFI.stackifyVReg(NewReg); 80 MFI.addWAReg(NewReg, WebAssemblyFunctionInfo::UnusedReg); 81 } 82 } 83 } 84 85 return Changed; 86 } 87