[WebAssembly] Implement a new algorithm for placing BLOCK markers
[oota-llvm.git] / lib / Target / WebAssembly / WebAssemblyPeephole.cpp
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 }