Summary: When building the selection DAG at ISel all PHI nodes are selected and lowered to Machine Instruction PHI nodes before we start to create any SDNodes. So there are no SDNodes for values produced by the PHI nodes. In the past when selecting a dbg.value intrinsic that uses the value produced by a PHI node we have been handling such dbg.value intrinsics as "dangling debug info". I.e. we have not created a SDDbgValue node directly, because there is no existing SDNode for the PHI result, instead we deferred the creationg of a SDDbgValue until we found the first use of the PHI result. The old solution had a couple of flaws. The position of the selected DBG_VALUE instruction would end up quite late in a basic block, and for example not directly after the PHI node as in the LLVM IR input. And in case there were no use at all in the basic block the dbg.value could be dropped completely. This patch introduces a new VREG kind of SDDbgValue nodes. It is similar to a SDNODE kind of node, but it refers directly to a virtual register and not a SDNode. When we do selection for a dbg.value that is using the result of a PHI node we can do a lookup of the virtual register directly (as it already is determined for the PHI node) and create a SDDbgValue node immediately instead of delaying the selection until we find a use. This should fix a problem with losing debug info at ISel as seen in PR37234 (https://bugs.llvm.org/show_bug.cgi?id=37234). It does not resolve PR37234 completely, because the debug info is dropped later on in the BranchFolder (see D46184). Reviewers: #debug-info, aprantl Reviewed By: #debug-info, aprantl Subscribers: rnk, gbedwell, aprantl, JDevlieghere, llvm-commits Differential Revision: https://reviews.llvm.org/D46129 llvm-svn: 331182
134 lines
4.2 KiB
C++
134 lines
4.2 KiB
C++
//===-- llvm/CodeGen/SDNodeDbgValue.h - SelectionDAG dbg_value --*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file declares the SDDbgValue class.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_CODEGEN_SELECTIONDAG_SDNODEDBGVALUE_H
|
|
#define LLVM_LIB_CODEGEN_SELECTIONDAG_SDNODEDBGVALUE_H
|
|
|
|
#include "llvm/IR/DebugLoc.h"
|
|
#include "llvm/Support/DataTypes.h"
|
|
#include <utility>
|
|
|
|
namespace llvm {
|
|
|
|
class DIVariable;
|
|
class DIExpression;
|
|
class SDNode;
|
|
class Value;
|
|
|
|
/// Holds the information from a dbg_value node through SDISel.
|
|
/// We do not use SDValue here to avoid including its header.
|
|
class SDDbgValue {
|
|
public:
|
|
enum DbgValueKind {
|
|
SDNODE = 0, ///< Value is the result of an expression.
|
|
CONST = 1, ///< Value is a constant.
|
|
FRAMEIX = 2, ///< Value is contents of a stack location.
|
|
VREG = 3 ///< Value is a virtual register.
|
|
};
|
|
private:
|
|
union {
|
|
struct {
|
|
SDNode *Node; ///< Valid for expressions.
|
|
unsigned ResNo; ///< Valid for expressions.
|
|
} s;
|
|
const Value *Const; ///< Valid for constants.
|
|
unsigned FrameIx; ///< Valid for stack objects.
|
|
unsigned VReg; ///< Valid for registers.
|
|
} u;
|
|
DIVariable *Var;
|
|
DIExpression *Expr;
|
|
DebugLoc DL;
|
|
unsigned Order;
|
|
enum DbgValueKind kind;
|
|
bool IsIndirect;
|
|
bool Invalid = false;
|
|
|
|
public:
|
|
/// Constructor for non-constants.
|
|
SDDbgValue(DIVariable *Var, DIExpression *Expr, SDNode *N, unsigned R,
|
|
bool indir, DebugLoc dl, unsigned O)
|
|
: Var(Var), Expr(Expr), DL(std::move(dl)), Order(O), IsIndirect(indir) {
|
|
kind = SDNODE;
|
|
u.s.Node = N;
|
|
u.s.ResNo = R;
|
|
}
|
|
|
|
/// Constructor for constants.
|
|
SDDbgValue(DIVariable *Var, DIExpression *Expr, const Value *C, DebugLoc dl,
|
|
unsigned O)
|
|
: Var(Var), Expr(Expr), DL(std::move(dl)), Order(O), IsIndirect(false) {
|
|
kind = CONST;
|
|
u.Const = C;
|
|
}
|
|
|
|
/// Constructor for frame indices.
|
|
SDDbgValue(DIVariable *Var, DIExpression *Expr, unsigned FI, DebugLoc dl,
|
|
unsigned O)
|
|
: Var(Var), Expr(Expr), DL(std::move(dl)), Order(O), IsIndirect(false) {
|
|
kind = FRAMEIX;
|
|
u.FrameIx = FI;
|
|
}
|
|
|
|
/// Constructor for virtual registers.
|
|
SDDbgValue(DIVariable *Var, DIExpression *Expr, unsigned VReg, bool indir,
|
|
DebugLoc dl, unsigned O)
|
|
: Var(Var), Expr(Expr), DL(std::move(dl)), Order(O), IsIndirect(indir) {
|
|
kind = VREG;
|
|
u.VReg = VReg;
|
|
}
|
|
|
|
/// Returns the kind.
|
|
DbgValueKind getKind() const { return kind; }
|
|
|
|
/// Returns the DIVariable pointer for the variable.
|
|
DIVariable *getVariable() const { return Var; }
|
|
|
|
/// Returns the DIExpression pointer for the expression.
|
|
DIExpression *getExpression() const { return Expr; }
|
|
|
|
/// Returns the SDNode* for a register ref
|
|
SDNode *getSDNode() const { assert (kind==SDNODE); return u.s.Node; }
|
|
|
|
/// Returns the ResNo for a register ref
|
|
unsigned getResNo() const { assert (kind==SDNODE); return u.s.ResNo; }
|
|
|
|
/// Returns the Value* for a constant
|
|
const Value *getConst() const { assert (kind==CONST); return u.Const; }
|
|
|
|
/// Returns the FrameIx for a stack object
|
|
unsigned getFrameIx() const { assert (kind==FRAMEIX); return u.FrameIx; }
|
|
|
|
/// Returns the Virtual Register for a VReg
|
|
unsigned getVReg() const { assert (kind==VREG); return u.VReg; }
|
|
|
|
/// Returns whether this is an indirect value.
|
|
bool isIndirect() const { return IsIndirect; }
|
|
|
|
/// Returns the DebugLoc.
|
|
DebugLoc getDebugLoc() const { return DL; }
|
|
|
|
/// Returns the SDNodeOrder. This is the order of the preceding node in the
|
|
/// input.
|
|
unsigned getOrder() const { return Order; }
|
|
|
|
/// setIsInvalidated / isInvalidated - Setter / getter of the "Invalidated"
|
|
/// property. A SDDbgValue is invalid if the SDNode that produces the value is
|
|
/// deleted.
|
|
void setIsInvalidated() { Invalid = true; }
|
|
bool isInvalidated() const { return Invalid; }
|
|
};
|
|
|
|
} // end llvm namespace
|
|
|
|
#endif
|