2015-11-26 00:55:01 +08:00
|
|
|
//===-- WebAssemblyPeephole.cpp - WebAssembly Peephole Optimiztions -------===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2015-11-26 00:55:01 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
///
|
|
|
|
/// \file
|
2018-05-01 23:54:18 +08:00
|
|
|
/// Late peephole optimizations for WebAssembly.
|
2015-11-26 00:55:01 +08:00
|
|
|
///
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
|
2016-05-21 08:21:56 +08:00
|
|
|
#include "WebAssembly.h"
|
2015-11-26 00:55:01 +08:00
|
|
|
#include "WebAssemblyMachineFunctionInfo.h"
|
2016-01-26 12:01:11 +08:00
|
|
|
#include "WebAssemblySubtarget.h"
|
|
|
|
#include "llvm/Analysis/TargetLibraryInfo.h"
|
2015-11-26 00:55:01 +08:00
|
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
2016-05-21 08:21:56 +08:00
|
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
2016-01-26 12:01:11 +08:00
|
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
2015-11-26 00:55:01 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
#define DEBUG_TYPE "wasm-peephole"
|
|
|
|
|
2016-05-21 08:21:56 +08:00
|
|
|
static cl::opt<bool> DisableWebAssemblyFallthroughReturnOpt(
|
|
|
|
"disable-wasm-fallthrough-return-opt", cl::Hidden,
|
|
|
|
cl::desc("WebAssembly: Disable fallthrough-return optimizations."),
|
|
|
|
cl::init(false));
|
|
|
|
|
2015-11-26 00:55:01 +08:00
|
|
|
namespace {
|
|
|
|
class WebAssemblyPeephole final : public MachineFunctionPass {
|
2016-10-01 10:56:57 +08:00
|
|
|
StringRef getPassName() const override {
|
2015-11-26 00:55:01 +08:00
|
|
|
return "WebAssembly late peephole optimizer";
|
|
|
|
}
|
|
|
|
|
2015-12-10 22:12:04 +08:00
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
|
|
|
AU.setPreservesCFG();
|
2016-01-26 12:01:11 +08:00
|
|
|
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
2015-12-10 22:12:04 +08:00
|
|
|
MachineFunctionPass::getAnalysisUsage(AU);
|
|
|
|
}
|
|
|
|
|
2015-11-26 00:55:01 +08:00
|
|
|
bool runOnMachineFunction(MachineFunction &MF) override;
|
|
|
|
|
|
|
|
public:
|
|
|
|
static char ID;
|
|
|
|
WebAssemblyPeephole() : MachineFunctionPass(ID) {}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
char WebAssemblyPeephole::ID = 0;
|
2018-03-31 04:36:58 +08:00
|
|
|
INITIALIZE_PASS(WebAssemblyPeephole, DEBUG_TYPE,
|
|
|
|
"WebAssembly peephole optimizations", false, false)
|
|
|
|
|
2015-11-26 00:55:01 +08:00
|
|
|
FunctionPass *llvm::createWebAssemblyPeephole() {
|
|
|
|
return new WebAssemblyPeephole();
|
|
|
|
}
|
|
|
|
|
2016-05-18 07:19:03 +08:00
|
|
|
/// If desirable, rewrite NewReg to a drop register.
|
[WebAssembly] clang-tidy (NFC)
Summary:
This patch fixes clang-tidy warnings on wasm-only files.
The list of checks used is:
`-*,clang-diagnostic-*,llvm-*,misc-*,-misc-unused-parameters,readability-identifier-naming,modernize-*`
(LLVM's default .clang-tidy list is the same except it does not have
`modernize-*`. But I've seen in multiple CLs in LLVM the modernize style
was recommended and code was fixed based on the style, so I added it as
well.)
The common fixes are:
- Variable names start with an uppercase letter
- Function names start with a lowercase letter
- Use `auto` when you use casts so the type is evident
- Use inline initialization for class member variables
- Use `= default` for empty constructors / destructors
- Use `using` in place of `typedef`
Reviewers: sbc100, tlively, aardappel
Subscribers: dschuff, sunfish, jgravelle-google, yurydelendik, kripken, MatzeB, mgorny, rupprecht, llvm-commits
Differential Revision: https://reviews.llvm.org/D57500
llvm-svn: 353075
2019-02-05 03:13:39 +08:00
|
|
|
static bool maybeRewriteToDrop(unsigned OldReg, unsigned NewReg,
|
2016-05-21 08:21:56 +08:00
|
|
|
MachineOperand &MO, WebAssemblyFunctionInfo &MFI,
|
2016-05-18 07:19:03 +08:00
|
|
|
MachineRegisterInfo &MRI) {
|
2015-11-26 00:55:01 +08:00
|
|
|
bool Changed = false;
|
2016-02-21 11:27:22 +08:00
|
|
|
if (OldReg == NewReg) {
|
2016-01-26 12:01:11 +08:00
|
|
|
Changed = true;
|
[webassembly] Apply llvm-prefer-register-over-unsigned from clang-tidy to LLVM
Summary:
This clang-tidy check is looking for unsigned integer variables whose initializer
starts with an implicit cast from llvm::Register and changes the type of the
variable to llvm::Register (dropping the llvm:: where possible).
Reviewers: aheejin
Subscribers: jholewinski, MatzeB, qcolombet, dschuff, jyknight, dylanmckay, sdardis, nemanjai, jvesely, wdng, nhaehnle, sbc100, jgravelle-google, kristof.beyls, hiraditya, aheejin, kbarton, fedor.sergeev, javed.absar, asb, rbar, johnrusso, simoncook, apazos, sabuasal, niosHD, jrtc27, MaskRay, zzheng, edward-jones, atanasyan, rogfer01, MartinMosbeck, brucehoult, the_o, tpr, PkmX, jocewei, jsji, Petar.Avramovic, asbirlea, Jim, s.egerton, llvm-commits
Tags: #llvm
Differential Revision for whole review: https://reviews.llvm.org/D65962
llvm-svn: 368627
2019-08-13 06:40:45 +08:00
|
|
|
Register NewReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg));
|
2016-01-26 12:01:11 +08:00
|
|
|
MO.setReg(NewReg);
|
|
|
|
MO.setIsDead();
|
|
|
|
MFI.stackifyVReg(NewReg);
|
|
|
|
}
|
|
|
|
return Changed;
|
|
|
|
}
|
|
|
|
|
[WebAssembly] clang-tidy (NFC)
Summary:
This patch fixes clang-tidy warnings on wasm-only files.
The list of checks used is:
`-*,clang-diagnostic-*,llvm-*,misc-*,-misc-unused-parameters,readability-identifier-naming,modernize-*`
(LLVM's default .clang-tidy list is the same except it does not have
`modernize-*`. But I've seen in multiple CLs in LLVM the modernize style
was recommended and code was fixed based on the style, so I added it as
well.)
The common fixes are:
- Variable names start with an uppercase letter
- Function names start with a lowercase letter
- Use `auto` when you use casts so the type is evident
- Use inline initialization for class member variables
- Use `= default` for empty constructors / destructors
- Use `using` in place of `typedef`
Reviewers: sbc100, tlively, aardappel
Subscribers: dschuff, sunfish, jgravelle-google, yurydelendik, kripken, MatzeB, mgorny, rupprecht, llvm-commits
Differential Revision: https://reviews.llvm.org/D57500
llvm-svn: 353075
2019-02-05 03:13:39 +08:00
|
|
|
static bool maybeRewriteToFallthrough(MachineInstr &MI, MachineBasicBlock &MBB,
|
2016-05-21 08:21:56 +08:00
|
|
|
const MachineFunction &MF,
|
|
|
|
WebAssemblyFunctionInfo &MFI,
|
|
|
|
MachineRegisterInfo &MRI,
|
2019-10-10 05:42:08 +08:00
|
|
|
const WebAssemblyInstrInfo &TII) {
|
2016-05-21 08:21:56 +08:00
|
|
|
if (DisableWebAssemblyFallthroughReturnOpt)
|
|
|
|
return false;
|
|
|
|
if (&MBB != &MF.back())
|
|
|
|
return false;
|
2018-07-17 07:09:29 +08:00
|
|
|
|
|
|
|
MachineBasicBlock::iterator End = MBB.end();
|
|
|
|
--End;
|
|
|
|
assert(End->getOpcode() == WebAssembly::END_FUNCTION);
|
|
|
|
--End;
|
|
|
|
if (&MI != &*End)
|
|
|
|
return false;
|
2016-05-21 08:21:56 +08:00
|
|
|
|
2019-10-10 05:42:08 +08:00
|
|
|
for (auto &MO : MI.explicit_operands()) {
|
|
|
|
// If the operand isn't stackified, insert a COPY to read the operands and
|
|
|
|
// stackify them.
|
[webassembly] Apply llvm-prefer-register-over-unsigned from clang-tidy to LLVM
Summary:
This clang-tidy check is looking for unsigned integer variables whose initializer
starts with an implicit cast from llvm::Register and changes the type of the
variable to llvm::Register (dropping the llvm:: where possible).
Reviewers: aheejin
Subscribers: jholewinski, MatzeB, qcolombet, dschuff, jyknight, dylanmckay, sdardis, nemanjai, jvesely, wdng, nhaehnle, sbc100, jgravelle-google, kristof.beyls, hiraditya, aheejin, kbarton, fedor.sergeev, javed.absar, asb, rbar, johnrusso, simoncook, apazos, sabuasal, niosHD, jrtc27, MaskRay, zzheng, edward-jones, atanasyan, rogfer01, MartinMosbeck, brucehoult, the_o, tpr, PkmX, jocewei, jsji, Petar.Avramovic, asbirlea, Jim, s.egerton, llvm-commits
Tags: #llvm
Differential Revision for whole review: https://reviews.llvm.org/D65962
llvm-svn: 368627
2019-08-13 06:40:45 +08:00
|
|
|
Register Reg = MO.getReg();
|
2017-02-10 07:19:03 +08:00
|
|
|
if (!MFI.isVRegStackified(Reg)) {
|
2019-10-10 05:42:08 +08:00
|
|
|
unsigned CopyLocalOpc;
|
|
|
|
const TargetRegisterClass *RegClass = MRI.getRegClass(Reg);
|
|
|
|
switch (RegClass->getID()) {
|
|
|
|
case WebAssembly::I32RegClassID:
|
|
|
|
CopyLocalOpc = WebAssembly::COPY_I32;
|
|
|
|
break;
|
|
|
|
case WebAssembly::I64RegClassID:
|
|
|
|
CopyLocalOpc = WebAssembly::COPY_I64;
|
|
|
|
break;
|
|
|
|
case WebAssembly::F32RegClassID:
|
|
|
|
CopyLocalOpc = WebAssembly::COPY_F32;
|
|
|
|
break;
|
|
|
|
case WebAssembly::F64RegClassID:
|
|
|
|
CopyLocalOpc = WebAssembly::COPY_F64;
|
|
|
|
break;
|
|
|
|
case WebAssembly::V128RegClassID:
|
|
|
|
CopyLocalOpc = WebAssembly::COPY_V128;
|
|
|
|
break;
|
|
|
|
case WebAssembly::EXNREFRegClassID:
|
|
|
|
CopyLocalOpc = WebAssembly::COPY_EXNREF;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Unexpected register class for return operand");
|
|
|
|
}
|
|
|
|
Register NewReg = MRI.createVirtualRegister(RegClass);
|
2017-02-10 07:19:03 +08:00
|
|
|
BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(CopyLocalOpc), NewReg)
|
|
|
|
.addReg(Reg);
|
|
|
|
MO.setReg(NewReg);
|
|
|
|
MFI.stackifyVReg(NewReg);
|
|
|
|
}
|
2016-05-21 08:21:56 +08:00
|
|
|
}
|
|
|
|
|
2019-10-10 05:42:08 +08:00
|
|
|
MI.setDesc(TII.get(WebAssembly::FALLTHROUGH_RETURN));
|
2016-05-21 08:21:56 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-01-26 12:01:11 +08:00
|
|
|
bool WebAssemblyPeephole::runOnMachineFunction(MachineFunction &MF) {
|
2018-05-14 20:53:11 +08:00
|
|
|
LLVM_DEBUG({
|
2016-05-21 08:21:56 +08:00
|
|
|
dbgs() << "********** Peephole **********\n"
|
2016-01-26 12:01:11 +08:00
|
|
|
<< "********** Function: " << MF.getName() << '\n';
|
|
|
|
});
|
2015-11-26 00:55:01 +08:00
|
|
|
|
|
|
|
MachineRegisterInfo &MRI = MF.getRegInfo();
|
|
|
|
WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
|
2016-08-03 07:31:56 +08:00
|
|
|
const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
|
2016-01-26 12:01:11 +08:00
|
|
|
const WebAssemblyTargetLowering &TLI =
|
|
|
|
*MF.getSubtarget<WebAssemblySubtarget>().getTargetLowering();
|
Change TargetLibraryInfo analysis passes to always require Function
Summary:
This is the first change to enable the TLI to be built per-function so
that -fno-builtin* handling can be migrated to use function attributes.
See discussion on D61634 for background. This is an enabler for fixing
handling of these options for LTO, for example.
This change should not affect behavior, as the provided function is not
yet used to build a specifically per-function TLI, but rather enables
that migration.
Most of the changes were very mechanical, e.g. passing a Function to the
legacy analysis pass's getTLI interface, or in Module level cases,
adding a callback. This is similar to the way the per-function TTI
analysis works.
There was one place where we were looking for builtins but not in the
context of a specific function. See FindCXAAtExit in
lib/Transforms/IPO/GlobalOpt.cpp. I'm somewhat concerned my workaround
could provide the wrong behavior in some corner cases. Suggestions
welcome.
Reviewers: chandlerc, hfinkel
Subscribers: arsenm, dschuff, jvesely, nhaehnle, mehdi_amini, javed.absar, sbc100, jgravelle-google, eraman, aheejin, steven_wu, george.burgess.iv, dexonsmith, jfb, asbirlea, gchatelet, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D66428
llvm-svn: 371284
2019-09-07 11:09:36 +08:00
|
|
|
auto &LibInfo =
|
|
|
|
getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(MF.getFunction());
|
2016-01-26 12:01:11 +08:00
|
|
|
bool Changed = false;
|
2015-11-26 00:55:01 +08:00
|
|
|
|
|
|
|
for (auto &MBB : MF)
|
|
|
|
for (auto &MI : MBB)
|
|
|
|
switch (MI.getOpcode()) {
|
|
|
|
default:
|
|
|
|
break;
|
[WebAssembly] Replace all calls with generalized multivalue calls
Summary:
Extends the multivalue call infrastructure to tail calls, removes all
legacy calls specialized for particular result types, and removes the
CallIndirectFixup pass, since all indirect call arguments are now
fixed up directly in the post-insertion hook.
In order to keep supporting pretty-printed defs and uses in test
expectations, MCInstLower now inserts an immediate containing the
number of defs for each call and call_indirect. The InstPrinter is
updated to query this immediate if it is present and determine which
MCOperands are defs and uses accordingly.
Depends on D72902.
Reviewers: aheejin
Subscribers: dschuff, mgorny, sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D74192
2020-02-07 08:29:59 +08:00
|
|
|
case WebAssembly::CALL: {
|
2016-01-26 12:01:11 +08:00
|
|
|
MachineOperand &Op1 = MI.getOperand(1);
|
|
|
|
if (Op1.isSymbol()) {
|
|
|
|
StringRef Name(Op1.getSymbolName());
|
|
|
|
if (Name == TLI.getLibcallName(RTLIB::MEMCPY) ||
|
|
|
|
Name == TLI.getLibcallName(RTLIB::MEMMOVE) ||
|
|
|
|
Name == TLI.getLibcallName(RTLIB::MEMSET)) {
|
2017-01-24 08:01:18 +08:00
|
|
|
LibFunc Func;
|
2016-01-26 12:01:11 +08:00
|
|
|
if (LibInfo.getLibFunc(Name, Func)) {
|
2016-01-27 04:22:42 +08:00
|
|
|
const auto &Op2 = MI.getOperand(2);
|
2016-01-27 05:08:27 +08:00
|
|
|
if (!Op2.isReg())
|
2016-01-27 04:22:42 +08:00
|
|
|
report_fatal_error("Peephole: call to builtin function with "
|
2016-01-27 05:08:27 +08:00
|
|
|
"wrong signature, not consuming reg");
|
|
|
|
MachineOperand &MO = MI.getOperand(0);
|
[webassembly] Apply llvm-prefer-register-over-unsigned from clang-tidy to LLVM
Summary:
This clang-tidy check is looking for unsigned integer variables whose initializer
starts with an implicit cast from llvm::Register and changes the type of the
variable to llvm::Register (dropping the llvm:: where possible).
Reviewers: aheejin
Subscribers: jholewinski, MatzeB, qcolombet, dschuff, jyknight, dylanmckay, sdardis, nemanjai, jvesely, wdng, nhaehnle, sbc100, jgravelle-google, kristof.beyls, hiraditya, aheejin, kbarton, fedor.sergeev, javed.absar, asb, rbar, johnrusso, simoncook, apazos, sabuasal, niosHD, jrtc27, MaskRay, zzheng, edward-jones, atanasyan, rogfer01, MartinMosbeck, brucehoult, the_o, tpr, PkmX, jocewei, jsji, Petar.Avramovic, asbirlea, Jim, s.egerton, llvm-commits
Tags: #llvm
Differential Revision for whole review: https://reviews.llvm.org/D65962
llvm-svn: 368627
2019-08-13 06:40:45 +08:00
|
|
|
Register OldReg = MO.getReg();
|
|
|
|
Register NewReg = Op2.getReg();
|
2016-01-27 06:47:43 +08:00
|
|
|
|
2016-05-20 05:07:20 +08:00
|
|
|
if (MRI.getRegClass(NewReg) != MRI.getRegClass(OldReg))
|
2016-01-27 05:08:27 +08:00
|
|
|
report_fatal_error("Peephole: call to builtin function with "
|
|
|
|
"wrong signature, from/to mismatch");
|
[WebAssembly] clang-tidy (NFC)
Summary:
This patch fixes clang-tidy warnings on wasm-only files.
The list of checks used is:
`-*,clang-diagnostic-*,llvm-*,misc-*,-misc-unused-parameters,readability-identifier-naming,modernize-*`
(LLVM's default .clang-tidy list is the same except it does not have
`modernize-*`. But I've seen in multiple CLs in LLVM the modernize style
was recommended and code was fixed based on the style, so I added it as
well.)
The common fixes are:
- Variable names start with an uppercase letter
- Function names start with a lowercase letter
- Use `auto` when you use casts so the type is evident
- Use inline initialization for class member variables
- Use `= default` for empty constructors / destructors
- Use `using` in place of `typedef`
Reviewers: sbc100, tlively, aardappel
Subscribers: dschuff, sunfish, jgravelle-google, yurydelendik, kripken, MatzeB, mgorny, rupprecht, llvm-commits
Differential Revision: https://reviews.llvm.org/D57500
llvm-svn: 353075
2019-02-05 03:13:39 +08:00
|
|
|
Changed |= maybeRewriteToDrop(OldReg, NewReg, MO, MFI, MRI);
|
2016-01-26 12:01:11 +08:00
|
|
|
}
|
|
|
|
}
|
2015-11-26 00:55:01 +08:00
|
|
|
}
|
2016-05-21 08:21:56 +08:00
|
|
|
break;
|
2015-11-26 00:55:01 +08:00
|
|
|
}
|
2016-05-21 08:21:56 +08:00
|
|
|
// Optimize away an explicit void return at the end of the function.
|
2019-10-10 05:42:08 +08:00
|
|
|
case WebAssembly::RETURN:
|
|
|
|
Changed |= maybeRewriteToFallthrough(MI, MBB, MF, MFI, MRI, TII);
|
2016-05-21 08:21:56 +08:00
|
|
|
break;
|
2015-11-26 00:55:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return Changed;
|
|
|
|
}
|