The current `DebugValueManager`, which is mostly used in `RegStackify`, simply sinks `DBG_VALUE`s along when a def instruction sinks. (`RegStackify` only does sinks; it doesn't do hoists.) But this simple strategy can result in incorrect combinations of variables' values which would have not been possible in the original program. In this case, LLVM's policy is to make the value unavailable, so they will be shown as 'optimized out', rather than showing inaccurate debug info. Especially, when an instruction sinks, its original `DBG_VALUE` should be set to undef. This is well illustrated in the third example in https://llvm.org/docs/SourceLevelDebugging.html#instruction-scheduling. This CL rewrites `DebugValueManager` with this principle in mind. When sinking an instruction, it sinks its eligible `DBG_VALUE`s with it, but also leaves undef `DBG_VALUE`s in the original place to make those variables' values undefined. Also, unlike the current version, we sink only an eligible subset of `DBG_VALUE`s with a def instruction. See comments in the code for details. In case of cloning, because the original def is still there, we don't set its `DBG_VALUE`s to undef. But we clone only an eligible subset of `DBG_VALUE`s here as well. One consequence of this change is that now we do sinking and cloning of the def instruction itself within the `DebugValueManager`'s `sink` and `clone` methods. This is necessary because the `DebugValueManager` needs to know the original def's location before sinking and cloning in order to scan other interfering `DBG_VALUE`s between the original def and the insertion point. If we want to separate these two, we need to call `DebugValueManager`'s `sink` and `clone` methods //before// sinking/cloning the def instruction, which I don't think is a good design alternative either, because the user of this class needs to pay extra attention when using it. Because this change is fixing the existing inaccuracy of the current debug info, this reduces the variable info coverage in debug info, but not by a large margin. In Emscripten core benchmarks compiled with `-O1`, the coverage goes from 56.6% down to 55.2%, which I doubt will be a noticeable drop. The compilation time doesn't have any meaningful difference either with this change. Reviewed By: dschuff Differential Revision: https://reviews.llvm.org/D146744
57 lines
2.0 KiB
C++
57 lines
2.0 KiB
C++
// WebAssemblyDebugValueManager.h - WebAssembly DebugValue Manager -*- C++ -*-//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file
|
|
/// This file contains the declaration of the WebAssembly-specific
|
|
/// manager for DebugValues associated with the specific MachineInstr.
|
|
/// This pass currently does not handle DBG_VALUE_LISTs; they are assumed to
|
|
/// have been set to undef in NullifyDebugValueLists pass.
|
|
/// TODO Handle DBG_VALUE_LIST
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYDEBUGVALUEMANAGER_H
|
|
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYDEBUGVALUEMANAGER_H
|
|
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/CodeGen/Register.h"
|
|
|
|
namespace llvm {
|
|
|
|
class MachineInstr;
|
|
|
|
class WebAssemblyDebugValueManager {
|
|
MachineInstr *Def;
|
|
SmallVector<MachineInstr *, 1> DbgValues;
|
|
Register CurrentReg;
|
|
SmallVector<MachineInstr *>
|
|
getSinkableDebugValues(MachineInstr *Insert) const;
|
|
|
|
public:
|
|
WebAssemblyDebugValueManager(MachineInstr *Def);
|
|
|
|
// Sink 'Def', and also sink its eligible DBG_VALUEs to the place before
|
|
// 'Insert'. Convert the original DBG_VALUEs into undefs.
|
|
void sink(MachineInstr *Insert);
|
|
// Clone 'Def' (optionally), and also clone its eligible DBG_VALUEs to the
|
|
// place before 'Insert'.
|
|
void cloneSink(MachineInstr *Insert, Register NewReg = Register(),
|
|
bool CloneDef = true) const;
|
|
// Update the register for Def and DBG_VALUEs.
|
|
void updateReg(Register Reg);
|
|
// Replace the current register in DBG_VALUEs with the given LocalId target
|
|
// index.
|
|
void replaceWithLocal(unsigned LocalId);
|
|
// Remove Def, and set its DBG_VALUEs to undef.
|
|
void removeDef();
|
|
};
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif
|