forked from OSchip/llvm-project
				
			[WebAssembly] Fix updating/moving DBG_VALUEs in RegStackify
Summary: As described in PR40209, there can be issues in DBG_VALUEs handling when multiple defs present in a BB. This patch adds logic for detection of related to def DBG_VALUEs and localizes register update and movement to found DBG_VALUEs. Reviewers: aheejin Subscribers: mgorny, dschuff, sbc100, jgravelle-google, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D56401 llvm-svn: 351216
This commit is contained in:
		
							parent
							
								
									d8024371a5
								
							
						
					
					
						commit
						be24c02003
					
				| 
						 | 
					@ -19,6 +19,7 @@ add_llvm_target(WebAssemblyCodeGen
 | 
				
			||||||
  WebAssemblyCallIndirectFixup.cpp
 | 
					  WebAssemblyCallIndirectFixup.cpp
 | 
				
			||||||
  WebAssemblyCFGStackify.cpp
 | 
					  WebAssemblyCFGStackify.cpp
 | 
				
			||||||
  WebAssemblyCFGSort.cpp
 | 
					  WebAssemblyCFGSort.cpp
 | 
				
			||||||
 | 
					  WebAssemblyDebugValueManager.cpp
 | 
				
			||||||
  WebAssemblyLateEHPrepare.cpp
 | 
					  WebAssemblyLateEHPrepare.cpp
 | 
				
			||||||
  WebAssemblyEHRestoreStackPointer.cpp
 | 
					  WebAssemblyEHRestoreStackPointer.cpp
 | 
				
			||||||
  WebAssemblyExceptionInfo.cpp
 | 
					  WebAssemblyExceptionInfo.cpp
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,46 @@
 | 
				
			||||||
 | 
					//===-- WebAssemblyDebugValueManager.cpp - WebAssembly DebugValue Manager -===//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//                     The LLVM Compiler Infrastructure
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This file is distributed under the University of Illinois Open Source
 | 
				
			||||||
 | 
					// License. See LICENSE.TXT for details.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// \file
 | 
				
			||||||
 | 
					/// This file implements the manager for MachineInstr DebugValues.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "WebAssemblyDebugValueManager.h"
 | 
				
			||||||
 | 
					#include "WebAssemblyMachineFunctionInfo.h"
 | 
				
			||||||
 | 
					#include "llvm/CodeGen/MachineInstr.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace llvm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WebAssemblyDebugValueManager::WebAssemblyDebugValueManager(
 | 
				
			||||||
 | 
					    MachineInstr *Instr) {
 | 
				
			||||||
 | 
					  Instr->collectDebugValues(DbgValues);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WebAssemblyDebugValueManager::move(MachineInstr *Insert) {
 | 
				
			||||||
 | 
					  MachineBasicBlock *MBB = Insert->getParent();
 | 
				
			||||||
 | 
					  for (MachineInstr *DBI : reverse(DbgValues))
 | 
				
			||||||
 | 
					    MBB->splice(Insert, DBI->getParent(), DBI);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WebAssemblyDebugValueManager::updateReg(unsigned Reg) {
 | 
				
			||||||
 | 
					  for (auto *DBI : DbgValues)
 | 
				
			||||||
 | 
					    DBI->getOperand(0).setReg(Reg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WebAssemblyDebugValueManager::clone(MachineInstr *Insert,
 | 
				
			||||||
 | 
					                                         unsigned NewReg) {
 | 
				
			||||||
 | 
					  MachineBasicBlock *MBB = Insert->getParent();
 | 
				
			||||||
 | 
					  MachineFunction *MF = MBB->getParent();
 | 
				
			||||||
 | 
					  for (MachineInstr *DBI : reverse(DbgValues)) {
 | 
				
			||||||
 | 
					    MachineInstr *Clone = MF->CloneMachineInstr(DBI);
 | 
				
			||||||
 | 
					    Clone->getOperand(0).setReg(NewReg);
 | 
				
			||||||
 | 
					    MBB->insert(Insert, Clone);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					// WebAssemblyDebugValueManager.h - WebAssembly DebugValue Manager -*- C++ -*-//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//                     The LLVM Compiler Infrastructure
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This file is distributed under the University of Illinois Open Source
 | 
				
			||||||
 | 
					// License. See LICENSE.TXT for details.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// \file
 | 
				
			||||||
 | 
					/// This file contains the declaration of the WebAssembly-specific
 | 
				
			||||||
 | 
					/// manager for DebugValues associated with the specific MachineInstr.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYDEBUGVALUEMANAGER_H
 | 
				
			||||||
 | 
					#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYDEBUGVALUEMANAGER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "llvm/ADT/SmallVector.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace llvm {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MachineInstr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class WebAssemblyDebugValueManager {
 | 
				
			||||||
 | 
					  SmallVector<MachineInstr *, 2> DbgValues;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  WebAssemblyDebugValueManager(MachineInstr *Instr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void move(MachineInstr *Insert);
 | 
				
			||||||
 | 
					  void updateReg(unsigned Reg);
 | 
				
			||||||
 | 
					  void clone(MachineInstr *Insert, unsigned NewReg);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // end namespace llvm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -22,6 +22,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" // for WebAssembly::ARGUMENT_*
 | 
					#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" // for WebAssembly::ARGUMENT_*
 | 
				
			||||||
#include "WebAssembly.h"
 | 
					#include "WebAssembly.h"
 | 
				
			||||||
 | 
					#include "WebAssemblyDebugValueManager.h"
 | 
				
			||||||
#include "WebAssemblyMachineFunctionInfo.h"
 | 
					#include "WebAssemblyMachineFunctionInfo.h"
 | 
				
			||||||
#include "WebAssemblySubtarget.h"
 | 
					#include "WebAssemblySubtarget.h"
 | 
				
			||||||
#include "WebAssemblyUtilities.h"
 | 
					#include "WebAssemblyUtilities.h"
 | 
				
			||||||
| 
						 | 
					@ -466,27 +467,6 @@ static void ShrinkToUses(LiveInterval &LI, LiveIntervals &LIS) {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void MoveDebugValues(unsigned Reg, MachineInstr *Insert,
 | 
					 | 
				
			||||||
                            MachineBasicBlock &MBB, MachineRegisterInfo &MRI) {
 | 
					 | 
				
			||||||
  for (auto &Op : MRI.reg_operands(Reg)) {
 | 
					 | 
				
			||||||
    MachineInstr *MI = Op.getParent();
 | 
					 | 
				
			||||||
    assert(MI != nullptr);
 | 
					 | 
				
			||||||
    if (MI->isDebugValue() && MI->getParent() == &MBB)
 | 
					 | 
				
			||||||
      MBB.splice(Insert, &MBB, MI);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void UpdateDebugValuesReg(unsigned Reg, unsigned NewReg,
 | 
					 | 
				
			||||||
                                 MachineBasicBlock &MBB,
 | 
					 | 
				
			||||||
                                 MachineRegisterInfo &MRI) {
 | 
					 | 
				
			||||||
  for (auto &Op : MRI.reg_operands(Reg)) {
 | 
					 | 
				
			||||||
    MachineInstr *MI = Op.getParent();
 | 
					 | 
				
			||||||
    assert(MI != nullptr);
 | 
					 | 
				
			||||||
    if (MI->isDebugValue() && MI->getParent() == &MBB)
 | 
					 | 
				
			||||||
      Op.setReg(NewReg);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// A single-use def in the same block with no intervening memory or register
 | 
					/// A single-use def in the same block with no intervening memory or register
 | 
				
			||||||
/// dependencies; move the def down and nest it with the current instruction.
 | 
					/// dependencies; move the def down and nest it with the current instruction.
 | 
				
			||||||
static MachineInstr *MoveForSingleUse(unsigned Reg, MachineOperand &Op,
 | 
					static MachineInstr *MoveForSingleUse(unsigned Reg, MachineOperand &Op,
 | 
				
			||||||
| 
						 | 
					@ -496,8 +476,9 @@ static MachineInstr *MoveForSingleUse(unsigned Reg, MachineOperand &Op,
 | 
				
			||||||
                                      MachineRegisterInfo &MRI) {
 | 
					                                      MachineRegisterInfo &MRI) {
 | 
				
			||||||
  LLVM_DEBUG(dbgs() << "Move for single use: "; Def->dump());
 | 
					  LLVM_DEBUG(dbgs() << "Move for single use: "; Def->dump());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  WebAssemblyDebugValueManager DefDIs(Def);
 | 
				
			||||||
  MBB.splice(Insert, &MBB, Def);
 | 
					  MBB.splice(Insert, &MBB, Def);
 | 
				
			||||||
  MoveDebugValues(Reg, Insert, MBB, MRI);
 | 
					  DefDIs.move(Insert);
 | 
				
			||||||
  LIS.handleMove(*Def);
 | 
					  LIS.handleMove(*Def);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (MRI.hasOneDef(Reg) && MRI.hasOneUse(Reg)) {
 | 
					  if (MRI.hasOneDef(Reg) && MRI.hasOneUse(Reg)) {
 | 
				
			||||||
| 
						 | 
					@ -522,7 +503,7 @@ static MachineInstr *MoveForSingleUse(unsigned Reg, MachineOperand &Op,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MFI.stackifyVReg(NewReg);
 | 
					    MFI.stackifyVReg(NewReg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    UpdateDebugValuesReg(Reg, NewReg, MBB, MRI);
 | 
					    DefDIs.updateReg(NewReg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
 | 
					    LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -531,29 +512,6 @@ static MachineInstr *MoveForSingleUse(unsigned Reg, MachineOperand &Op,
 | 
				
			||||||
  return Def;
 | 
					  return Def;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void CloneDebugValues(unsigned Reg, MachineInstr *Insert,
 | 
					 | 
				
			||||||
                             unsigned TargetReg, MachineBasicBlock &MBB,
 | 
					 | 
				
			||||||
                             MachineRegisterInfo &MRI,
 | 
					 | 
				
			||||||
                             const WebAssemblyInstrInfo *TII) {
 | 
					 | 
				
			||||||
  SmallPtrSet<MachineInstr *, 4> Instrs;
 | 
					 | 
				
			||||||
  for (auto &Op : MRI.reg_operands(Reg)) {
 | 
					 | 
				
			||||||
    MachineInstr *MI = Op.getParent();
 | 
					 | 
				
			||||||
    assert(MI != nullptr);
 | 
					 | 
				
			||||||
    if (MI->isDebugValue() && MI->getParent() == &MBB &&
 | 
					 | 
				
			||||||
        Instrs.find(MI) == Instrs.end())
 | 
					 | 
				
			||||||
      Instrs.insert(MI);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  for (const auto &MI : Instrs) {
 | 
					 | 
				
			||||||
    MachineInstr &Clone = TII->duplicate(MBB, Insert, *MI);
 | 
					 | 
				
			||||||
    for (unsigned i = 0, e = Clone.getNumOperands(); i != e; ++i) {
 | 
					 | 
				
			||||||
      MachineOperand &MO = Clone.getOperand(i);
 | 
					 | 
				
			||||||
      if (MO.isReg() && MO.getReg() == Reg)
 | 
					 | 
				
			||||||
        MO.setReg(TargetReg);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    LLVM_DEBUG(dbgs() << " - - Cloned DBG_VALUE: "; Clone.dump());
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// A trivially cloneable instruction; clone it and nest the new copy with the
 | 
					/// A trivially cloneable instruction; clone it and nest the new copy with the
 | 
				
			||||||
/// current instruction.
 | 
					/// current instruction.
 | 
				
			||||||
static MachineInstr *RematerializeCheapDef(
 | 
					static MachineInstr *RematerializeCheapDef(
 | 
				
			||||||
| 
						 | 
					@ -564,6 +522,8 @@ static MachineInstr *RematerializeCheapDef(
 | 
				
			||||||
  LLVM_DEBUG(dbgs() << "Rematerializing cheap def: "; Def.dump());
 | 
					  LLVM_DEBUG(dbgs() << "Rematerializing cheap def: "; Def.dump());
 | 
				
			||||||
  LLVM_DEBUG(dbgs() << " - for use in "; Op.getParent()->dump());
 | 
					  LLVM_DEBUG(dbgs() << " - for use in "; Op.getParent()->dump());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  WebAssemblyDebugValueManager DefDIs(&Def);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  unsigned NewReg = MRI.createVirtualRegister(MRI.getRegClass(Reg));
 | 
					  unsigned NewReg = MRI.createVirtualRegister(MRI.getRegClass(Reg));
 | 
				
			||||||
  TII->reMaterialize(MBB, Insert, NewReg, 0, Def, *TRI);
 | 
					  TII->reMaterialize(MBB, Insert, NewReg, 0, Def, *TRI);
 | 
				
			||||||
  Op.setReg(NewReg);
 | 
					  Op.setReg(NewReg);
 | 
				
			||||||
| 
						 | 
					@ -593,10 +553,10 @@ static MachineInstr *RematerializeCheapDef(
 | 
				
			||||||
    LIS.RemoveMachineInstrFromMaps(Def);
 | 
					    LIS.RemoveMachineInstrFromMaps(Def);
 | 
				
			||||||
    Def.eraseFromParent();
 | 
					    Def.eraseFromParent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MoveDebugValues(Reg, &*Insert, MBB, MRI);
 | 
					    DefDIs.move(&*Insert);
 | 
				
			||||||
    UpdateDebugValuesReg(Reg, NewReg, MBB, MRI);
 | 
					    DefDIs.updateReg(NewReg);
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    CloneDebugValues(Reg, &*Insert, NewReg, MBB, MRI, TII);
 | 
					    DefDIs.clone(&*Insert, NewReg);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return Clone;
 | 
					  return Clone;
 | 
				
			||||||
| 
						 | 
					@ -628,6 +588,8 @@ static MachineInstr *MoveAndTeeForMultiUse(
 | 
				
			||||||
    MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII) {
 | 
					    MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII) {
 | 
				
			||||||
  LLVM_DEBUG(dbgs() << "Move and tee for multi-use:"; Def->dump());
 | 
					  LLVM_DEBUG(dbgs() << "Move and tee for multi-use:"; Def->dump());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  WebAssemblyDebugValueManager DefDIs(Def);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Move Def into place.
 | 
					  // Move Def into place.
 | 
				
			||||||
  MBB.splice(Insert, &MBB, Def);
 | 
					  MBB.splice(Insert, &MBB, Def);
 | 
				
			||||||
  LIS.handleMove(*Def);
 | 
					  LIS.handleMove(*Def);
 | 
				
			||||||
| 
						 | 
					@ -646,7 +608,7 @@ static MachineInstr *MoveAndTeeForMultiUse(
 | 
				
			||||||
  SlotIndex TeeIdx = LIS.InsertMachineInstrInMaps(*Tee).getRegSlot();
 | 
					  SlotIndex TeeIdx = LIS.InsertMachineInstrInMaps(*Tee).getRegSlot();
 | 
				
			||||||
  SlotIndex DefIdx = LIS.getInstructionIndex(*Def).getRegSlot();
 | 
					  SlotIndex DefIdx = LIS.getInstructionIndex(*Def).getRegSlot();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  MoveDebugValues(Reg, Insert, MBB, MRI);
 | 
					  DefDIs.move(Insert);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Tell LiveIntervals we moved the original vreg def from Def to Tee.
 | 
					  // Tell LiveIntervals we moved the original vreg def from Def to Tee.
 | 
				
			||||||
  LiveInterval &LI = LIS.getInterval(Reg);
 | 
					  LiveInterval &LI = LIS.getInterval(Reg);
 | 
				
			||||||
| 
						 | 
					@ -664,8 +626,8 @@ static MachineInstr *MoveAndTeeForMultiUse(
 | 
				
			||||||
  ImposeStackOrdering(Def);
 | 
					  ImposeStackOrdering(Def);
 | 
				
			||||||
  ImposeStackOrdering(Tee);
 | 
					  ImposeStackOrdering(Tee);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  CloneDebugValues(Reg, Tee, DefReg, MBB, MRI, TII);
 | 
					  DefDIs.clone(Tee, DefReg);
 | 
				
			||||||
  CloneDebugValues(Reg, Insert, TeeReg, MBB, MRI, TII);
 | 
					  DefDIs.clone(Insert, TeeReg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
 | 
					  LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
 | 
				
			||||||
  LLVM_DEBUG(dbgs() << " - Tee instruction: "; Tee->dump());
 | 
					  LLVM_DEBUG(dbgs() << " - Tee instruction: "; Tee->dump());
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,65 @@
 | 
				
			||||||
 | 
					# RUN: llc < %s -run-pass=wasm-reg-stackify -x=mir 2>&1 | FileCheck %s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# CHECK: body:
 | 
				
			||||||
 | 
					# CHECK: bb.0:
 | 
				
			||||||
 | 
					# CHECK: %[[REG1:[0-9]+]]:i32 = CONST_I32 0,
 | 
				
			||||||
 | 
					# CHECK-NEXT: DBG_VALUE %[[REG1]],
 | 
				
			||||||
 | 
					# CHECK-NEXT: CALL_VOID @foo, %[[REG1]],
 | 
				
			||||||
 | 
					# CHECK: bb.1:
 | 
				
			||||||
 | 
					# CHECK: %[[REG2:[0-9]+]]:i32 = CONST_I32 0,
 | 
				
			||||||
 | 
					# CHECK-NEXT: DBG_VALUE %[[REG2]],
 | 
				
			||||||
 | 
					# CHECK-NEXT: CALL_VOID @foo, %[[REG2]],
 | 
				
			||||||
 | 
					# CHECK: %[[REG3:[0-9]+]]:i32 = CONST_I32 0,
 | 
				
			||||||
 | 
					# CHECK-NEXT: DBG_VALUE %[[REG3]],
 | 
				
			||||||
 | 
					# CHECK-NEXT: CALL_VOID @foo, %[[REG3]],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--- |
 | 
				
			||||||
 | 
					  target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 | 
				
			||||||
 | 
					  target triple = "wasm32-unknown-unknown"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  declare void @foo(i32)
 | 
				
			||||||
 | 
					  declare i32 @bar()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  define void @test(i64 %arg) {
 | 
				
			||||||
 | 
					    unreachable
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  !llvm.dbg.cu = !{!0}
 | 
				
			||||||
 | 
					  !llvm.module.flags = !{!4}
 | 
				
			||||||
 | 
					  !0 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !2, producer: "clang LLVM (rustc version 1.30.0-dev)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !1, globals: !1)
 | 
				
			||||||
 | 
					  !1 = !{}
 | 
				
			||||||
 | 
					  !2 = !DIFile(filename: "<unknown>", directory: "")
 | 
				
			||||||
 | 
					  !3 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "&str", file: !2, size: 64, align: 32, elements: !{}, identifier: "111094d970b097647de579f9c509ef08")
 | 
				
			||||||
 | 
					  !4 = !{i32 2, !"Debug Info Version", i32 3}
 | 
				
			||||||
 | 
					  !5 = distinct !DILexicalBlock(scope: !6, file: !2, line: 357, column: 8)
 | 
				
			||||||
 | 
					  !6 = distinct !DISubprogram(name: "testfoo", linkageName: "_testba", scope: !7, file: !2, line: 353, type: !8, isLocal: true, isDefinition: true, scopeLine: 353, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !1, retainedNodes: !9)
 | 
				
			||||||
 | 
					  !7 = !DINamespace(name: "ptr", scope: null)
 | 
				
			||||||
 | 
					  !8 = !DISubroutineType(types: !1)
 | 
				
			||||||
 | 
					  !9 = !{!10}
 | 
				
			||||||
 | 
					  !10 = !DILocalVariable(name: "val0", scope: !5, file: !2, line: 357, type: !3, align: 4)
 | 
				
			||||||
 | 
					  !11 = !DILocalVariable(name: "val1", scope: !5, file: !2, line: 358, type: !3, align: 4)
 | 
				
			||||||
 | 
					  !12 = !DILocalVariable(name: "val2", scope: !5, file: !2, line: 359, type: !3, align: 4)
 | 
				
			||||||
 | 
					  !13 = !DILocation(line: 357, column: 12, scope: !5)
 | 
				
			||||||
 | 
					  !14 = !DILocation(line: 358, column: 12, scope: !5)
 | 
				
			||||||
 | 
					  !15 = !DILocation(line: 359, column: 12, scope: !5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					name: test
 | 
				
			||||||
 | 
					liveins:
 | 
				
			||||||
 | 
					  - { reg: '$arguments' }
 | 
				
			||||||
 | 
					tracksRegLiveness: true
 | 
				
			||||||
 | 
					body: |
 | 
				
			||||||
 | 
					  bb.0:
 | 
				
			||||||
 | 
					    successors: %bb.1
 | 
				
			||||||
 | 
					    liveins: $arguments
 | 
				
			||||||
 | 
					    %0:i64 = ARGUMENT_i64 0, implicit $arguments
 | 
				
			||||||
 | 
					    %1:i32 = CONST_I32 0, implicit-def dead $arguments
 | 
				
			||||||
 | 
					    DBG_VALUE %1:i32, $noreg, !10, !DIExpression(), debug-location !13; <unknown>:357:12 line no:357
 | 
				
			||||||
 | 
					    CALL_VOID @foo, %1:i32, implicit-def dead $arguments, implicit $sp32, implicit $sp64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bb.1:
 | 
				
			||||||
 | 
					    CALL_VOID @foo, %1:i32, implicit-def dead $arguments, implicit $sp32, implicit $sp64
 | 
				
			||||||
 | 
					    CALL_VOID @foo, %1:i32, implicit-def dead $arguments, implicit $sp32, implicit $sp64
 | 
				
			||||||
 | 
					    RETURN_VOID implicit-def dead $arguments
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					...
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,60 @@
 | 
				
			||||||
 | 
					# RUN: llc < %s -run-pass=wasm-reg-stackify -x=mir 2>&1 | FileCheck %s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# CHECK: body:
 | 
				
			||||||
 | 
					# CHECK: %1:i32 = I32_WRAP_I64 %0,
 | 
				
			||||||
 | 
					# CHECK-NEXT: DBG_VALUE %1,
 | 
				
			||||||
 | 
					# CHECK-NEXT: %1:i32 = CALL_I32 @bar,
 | 
				
			||||||
 | 
					# CHECK-NEXT: DBG_VALUE %1,
 | 
				
			||||||
 | 
					# CHECK-NEXT: %[[NEWREG:.*]]:i32 = CALL_I32 @bar,
 | 
				
			||||||
 | 
					# CHECK-NEXT: DBG_VALUE %[[NEWREG]],
 | 
				
			||||||
 | 
					# CHECK-NEXT: CALL_VOID @foo, %[[NEWREG]],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--- |
 | 
				
			||||||
 | 
					  target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 | 
				
			||||||
 | 
					  target triple = "wasm32-unknown-unknown"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  declare void @foo(i32)
 | 
				
			||||||
 | 
					  declare i32 @bar()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  define void @test(i64 %arg) {
 | 
				
			||||||
 | 
					    unreachable
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  !llvm.dbg.cu = !{!0}
 | 
				
			||||||
 | 
					  !llvm.module.flags = !{!4}
 | 
				
			||||||
 | 
					  !0 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !2, producer: "clang LLVM (rustc version 1.30.0-dev)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !1, globals: !1)
 | 
				
			||||||
 | 
					  !1 = !{}
 | 
				
			||||||
 | 
					  !2 = !DIFile(filename: "<unknown>", directory: "")
 | 
				
			||||||
 | 
					  !3 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "&str", file: !2, size: 64, align: 32, elements: !{}, identifier: "111094d970b097647de579f9c509ef08")
 | 
				
			||||||
 | 
					  !4 = !{i32 2, !"Debug Info Version", i32 3}
 | 
				
			||||||
 | 
					  !5 = distinct !DILexicalBlock(scope: !6, file: !2, line: 357, column: 8)
 | 
				
			||||||
 | 
					  !6 = distinct !DISubprogram(name: "testfoo", linkageName: "_testba", scope: !7, file: !2, line: 353, type: !8, isLocal: true, isDefinition: true, scopeLine: 353, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !1, retainedNodes: !9)
 | 
				
			||||||
 | 
					  !7 = !DINamespace(name: "ptr", scope: null)
 | 
				
			||||||
 | 
					  !8 = !DISubroutineType(types: !1)
 | 
				
			||||||
 | 
					  !9 = !{!10}
 | 
				
			||||||
 | 
					  !10 = !DILocalVariable(name: "val0", scope: !5, file: !2, line: 357, type: !3, align: 4)
 | 
				
			||||||
 | 
					  !11 = !DILocalVariable(name: "val1", scope: !5, file: !2, line: 358, type: !3, align: 4)
 | 
				
			||||||
 | 
					  !12 = !DILocalVariable(name: "val2", scope: !5, file: !2, line: 359, type: !3, align: 4)
 | 
				
			||||||
 | 
					  !13 = !DILocation(line: 357, column: 12, scope: !5)
 | 
				
			||||||
 | 
					  !14 = !DILocation(line: 358, column: 12, scope: !5)
 | 
				
			||||||
 | 
					  !15 = !DILocation(line: 359, column: 12, scope: !5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					name: test
 | 
				
			||||||
 | 
					liveins:
 | 
				
			||||||
 | 
					  - { reg: '$arguments' }
 | 
				
			||||||
 | 
					tracksRegLiveness: true
 | 
				
			||||||
 | 
					body: |
 | 
				
			||||||
 | 
					  bb.0:
 | 
				
			||||||
 | 
					    liveins: $arguments
 | 
				
			||||||
 | 
					    %0:i64 = ARGUMENT_i64 0, implicit $arguments
 | 
				
			||||||
 | 
					    %1:i32 = I32_WRAP_I64 %0:i64, implicit-def dead $arguments
 | 
				
			||||||
 | 
					    DBG_VALUE %1:i32, $noreg, !10, !DIExpression(), debug-location !13; <unknown>:357:12 line no:357
 | 
				
			||||||
 | 
					    %1:i32 = CALL_I32 @bar, implicit-def dead $arguments, implicit $sp32, implicit $sp64
 | 
				
			||||||
 | 
					    DBG_VALUE %1:i32, $noreg, !11, !DIExpression(), debug-location !14; <unknown>:357:12 line no:357
 | 
				
			||||||
 | 
					    %1:i32 = CALL_I32 @bar, implicit-def dead $arguments, implicit $sp32, implicit $sp64
 | 
				
			||||||
 | 
					    DBG_VALUE %1:i32, $noreg, !12, !DIExpression(), debug-location !15; <unknown>:357:12 line no:357
 | 
				
			||||||
 | 
					    CALL_VOID @foo, %1:i32, implicit-def dead $arguments, implicit $sp32, implicit $sp64
 | 
				
			||||||
 | 
					    RETURN_VOID implicit-def dead $arguments
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					...
 | 
				
			||||||
		Loading…
	
		Reference in New Issue