diff options
| author | Dan Gohman <dan433584@gmail.com> | 2016-01-26 04:01:11 +0000 |
|---|---|---|
| committer | Dan Gohman <dan433584@gmail.com> | 2016-01-26 04:01:11 +0000 |
| commit | bdf08d5da69fefb674f1ff7c6401e4c7a899ac08 (patch) | |
| tree | 5fd05db5226d90b634ad93c5e9b95ebb48479a75 /llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp | |
| parent | be6f196bff83fc4db016ed793cf48d3fa39c5f5e (diff) | |
| download | bcm5719-llvm-bdf08d5da69fefb674f1ff7c6401e4c7a899ac08.tar.gz bcm5719-llvm-bdf08d5da69fefb674f1ff7c6401e4c7a899ac08.zip | |
[WebAssembly] Optimize memcpy/memmove/memcpy calls.
These calls return their first argument, but because LLVM uses an intrinsic
with a void return type, they can't use the returned attribute. Generalize
the store results pass to optimize these calls too.
llvm-svn: 258781
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp')
| -rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp | 69 |
1 files changed, 57 insertions, 12 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp index 76ef5c061d6..39a4bf9dce5 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp @@ -15,7 +15,10 @@ #include "WebAssembly.h" #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" #include "WebAssemblyMachineFunctionInfo.h" +#include "WebAssemblySubtarget.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" using namespace llvm; #define DEBUG_TYPE "wasm-peephole" @@ -28,6 +31,7 @@ class WebAssemblyPeephole final : public MachineFunctionPass { void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); + AU.addRequired<TargetLibraryInfoWrapperPass>(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -44,11 +48,36 @@ FunctionPass *llvm::createWebAssemblyPeephole() { return new WebAssemblyPeephole(); } -bool WebAssemblyPeephole::runOnMachineFunction(MachineFunction &MF) { +/// If desirable, rewrite NewReg to a discard register. +static bool MaybeRewriteToDiscard(unsigned OldReg, unsigned NewReg, + MachineOperand &MO, + WebAssemblyFunctionInfo &MFI, + MachineRegisterInfo &MRI) { bool Changed = false; + // TODO: Handle SP/physregs + if (OldReg == NewReg && TargetRegisterInfo::isVirtualRegister(NewReg)) { + Changed = true; + unsigned NewReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg)); + MO.setReg(NewReg); + MO.setIsDead(); + MFI.stackifyVReg(NewReg); + MFI.addWAReg(NewReg, WebAssemblyFunctionInfo::UnusedReg); + } + return Changed; +} + +bool WebAssemblyPeephole::runOnMachineFunction(MachineFunction &MF) { + DEBUG({ + dbgs() << "********** Store Results **********\n" + << "********** Function: " << MF.getName() << '\n'; + }); MachineRegisterInfo &MRI = MF.getRegInfo(); WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>(); + const WebAssemblyTargetLowering &TLI = + *MF.getSubtarget<WebAssemblySubtarget>().getTargetLowering(); + auto &LibInfo = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); + bool Changed = false; for (auto &MBB : MF) for (auto &MI : MBB) @@ -69,17 +98,33 @@ bool WebAssemblyPeephole::runOnMachineFunction(MachineFunction &MF) { // can use $discard instead. MachineOperand &MO = MI.getOperand(0); unsigned OldReg = MO.getReg(); - // TODO: Handle SP/physregs - if (OldReg == - MI.getOperand(WebAssembly::StoreValueOperandNo).getReg() && - TargetRegisterInfo::isVirtualRegister( - MI.getOperand(WebAssembly::StoreValueOperandNo).getReg())) { - Changed = true; - unsigned NewReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg)); - MO.setReg(NewReg); - MO.setIsDead(); - MFI.stackifyVReg(NewReg); - MFI.addWAReg(NewReg, WebAssemblyFunctionInfo::UnusedReg); + unsigned NewReg = + MI.getOperand(WebAssembly::StoreValueOperandNo).getReg(); + Changed |= MaybeRewriteToDiscard(OldReg, NewReg, MO, MFI, MRI); + break; + } + case WebAssembly::CALL_I32: + case WebAssembly::CALL_I64: { + 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)) { + LibFunc::Func Func; + if (LibInfo.getLibFunc(Name, Func)) { + if (!MI.getOperand(2).isReg()) + report_fatal_error( + "Call to builtin function with wrong signature"); + MachineOperand &MO = MI.getOperand(0); + unsigned OldReg = MO.getReg(); + unsigned NewReg = MI.getOperand(2).getReg(); + if (MRI.getRegClass(NewReg) != MRI.getRegClass(OldReg)) + report_fatal_error( + "Call to builtin function with wrong signature"); + Changed |= MaybeRewriteToDiscard(OldReg, NewReg, MO, MFI, MRI); + } + } } } } |

