diff options
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; } |