Home | History | Annotate | Download | only in WebAssembly
      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 {
     25   const char *getPassName() const override {
     26     return "WebAssembly late peephole optimizer";
     27   }
     28 
     29   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;
     38   WebAssemblyPeephole() : MachineFunctionPass(ID) {}
     39 };
     40 } // end anonymous namespace
     41 
     42 char WebAssemblyPeephole::ID = 0;
     43 FunctionPass *llvm::createWebAssemblyPeephole() {
     44   return new WebAssemblyPeephole();
     45 }
     46 
     47 bool 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