blob: 77514bbde7ef49e08b0e8986bbcd65f334eb32fe [file] [log] [blame]
Dan Gohman81719f82015-11-25 16:55:01 +00001//===-- 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"
19using namespace llvm;
20
21#define DEBUG_TYPE "wasm-peephole"
22
23namespace {
24class WebAssemblyPeephole final : public MachineFunctionPass {
25 const char *getPassName() const override {
26 return "WebAssembly late peephole optimizer";
27 }
28
Dan Gohmanacc09412015-12-10 14:12:04 +000029 void getAnalysisUsage(AnalysisUsage &AU) const override {
30 AU.setPreservesCFG();
31 MachineFunctionPass::getAnalysisUsage(AU);
32 }
33
Dan Gohman81719f82015-11-25 16:55:01 +000034 bool runOnMachineFunction(MachineFunction &MF) override;
35
36public:
37 static char ID;
38 WebAssemblyPeephole() : MachineFunctionPass(ID) {}
39};
40} // end anonymous namespace
41
42char WebAssemblyPeephole::ID = 0;
43FunctionPass *llvm::createWebAssemblyPeephole() {
44 return new WebAssemblyPeephole();
45}
46
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();
Dan Gohmanf0b165a2015-12-05 03:03:35 +000072 if (OldReg == MI.getOperand(3).getReg()) {
Dan Gohman81719f82015-11-25 16:55:01 +000073 unsigned NewReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg));
74 MO.setReg(NewReg);
75 MO.setIsDead();
76 MFI.stackifyVReg(NewReg);
Dan Gohman80e34e02015-11-25 21:13:02 +000077 MFI.addWAReg(NewReg, WebAssemblyFunctionInfo::UnusedReg);
Dan Gohman81719f82015-11-25 16:55:01 +000078 }
79 }
80 }
81
82 return Changed;
83}