aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2020-01-14 14:22:49 -0800
committerThomas Lively <tlively@google.com>2020-02-18 14:56:09 -0800
commit52861809994c9199ceb45b98d982ab736a376e67 (patch)
treeb96ce700921b7df80eb394cfd8b2a8b0bd320a90 /llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
parentb91d9ec0bb8caedcdd1ddf0506fc19d6c55efae3 (diff)
downloadllvm-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.cpp32
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;
}