diff options
author | Thomas Lively <tlively@google.com> | 2020-01-14 14:22:49 -0800 |
---|---|---|
committer | Thomas Lively <tlively@google.com> | 2020-02-18 14:56:09 -0800 |
commit | 52861809994c9199ceb45b98d982ab736a376e67 (patch) | |
tree | b96ce700921b7df80eb394cfd8b2a8b0bd320a90 /llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp | |
parent | b91d9ec0bb8caedcdd1ddf0506fc19d6c55efae3 (diff) | |
download | llvm-52861809994c9199ceb45b98d982ab736a376e67.zip llvm-52861809994c9199ceb45b98d982ab736a376e67.tar.gz llvm-52861809994c9199ceb45b98d982ab736a376e67.tar.bz2 |
[WebAssembly] Fix RegStackify and ExplicitLocals to handle multivalue
Summary:
There is still room for improvement in the handling of multivalue
nodes in both passes, but the current algorithm is at least correct
and optimizes some simpler cases. In order to make future
optimizations of these passes easier and build confidence that the
current algorithms are correct, this CL also adds a script that
automatically and exhaustively generates interesting multivalue test
cases.
Reviewers: aheejin, dschuff
Subscribers: sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D72902
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp')
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp index 6ca71139..4da97b6 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp @@ -178,11 +178,18 @@ static MVT typeForRegClass(const TargetRegisterClass *RC) { /// start of the expression tree. static MachineInstr *findStartOfTree(MachineOperand &MO, MachineRegisterInfo &MRI, - WebAssemblyFunctionInfo &MFI) { + const WebAssemblyFunctionInfo &MFI) { Register Reg = MO.getReg(); assert(MFI.isVRegStackified(Reg)); MachineInstr *Def = MRI.getVRegDef(Reg); + // If this instruction has any non-stackified defs, it is the start + for (auto DefReg : Def->defs()) { + if (!MFI.isVRegStackified(DefReg.getReg())) { + return Def; + } + } + // Find the first stackified use and proceed from there. for (MachineOperand &DefMO : Def->explicit_uses()) { if (!DefMO.isReg()) @@ -243,6 +250,12 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) { if (MI.isDebugInstr() || MI.isLabel()) continue; + if (MI.getOpcode() == WebAssembly::IMPLICIT_DEF) { + MI.eraseFromParent(); + Changed = true; + continue; + } + // Replace tee instructions with local.tee. The difference is that tee // instructions have two defs, while local.tee instructions have one def // and an index of a local to write to. @@ -279,20 +292,13 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) { continue; } - // Insert local.sets for any defs that aren't stackified yet. Currently - // we handle at most one def. - assert(MI.getDesc().getNumDefs() <= 1); - if (MI.getDesc().getNumDefs() == 1) { - Register OldReg = MI.getOperand(0).getReg(); + // Insert local.sets for any defs that aren't stackified yet. + for (auto &Def : MI.defs()) { + Register OldReg = Def.getReg(); if (!MFI.isVRegStackified(OldReg)) { const TargetRegisterClass *RC = MRI.getRegClass(OldReg); Register NewReg = MRI.createVirtualRegister(RC); auto InsertPt = std::next(MI.getIterator()); - if (MI.getOpcode() == WebAssembly::IMPLICIT_DEF) { - MI.eraseFromParent(); - Changed = true; - continue; - } if (UseEmpty[Register::virtReg2Index(OldReg)]) { unsigned Opc = getDropOpcode(RC); MachineInstr *Drop = @@ -310,11 +316,11 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) { .addImm(LocalId) .addReg(NewReg); } - MI.getOperand(0).setReg(NewReg); // This register operand of the original instruction is now being used // by the inserted drop or local.set instruction, so make it not dead // yet. - MI.getOperand(0).setIsDead(false); + Def.setReg(NewReg); + Def.setIsDead(false); MFI.stackifyVReg(NewReg); Changed = true; } |