llvm-project/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h
Adrian Prantl 941fa7588b [DIExpression] Introduce a dedicated DW_OP_LLVM_fragment operation
so we can stop using DW_OP_bit_piece with the wrong semantics.

The entire back story can be found here:
http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20161114/405934.html

The gist is that in LLVM we've been misinterpreting DW_OP_bit_piece's
offset field to mean the offset into the source variable rather than
the offset into the location at the top the DWARF expression stack. In
order to be able to fix this in a subsequent patch, this patch
introduces a dedicated DW_OP_LLVM_fragment operation with the
semantics that we used to apply to DW_OP_bit_piece, which is what we
actually need while inside of LLVM. This patch is complete with a
bitcode upgrade for expressions using the old format. It does not yet
fix the DWARF backend to use DW_OP_bit_piece correctly.

Implementation note: We discussed several options for implementing
this, including reserving a dedicated field in DIExpression for the
fragment size and offset, but using an custom operator at the end of
the expression works just fine and is more efficient because we then
only pay for it when we need it.

Differential Revision: https://reviews.llvm.org/D27361
rdar://problem/29335809

llvm-svn: 288683
2016-12-05 18:04:47 +00:00

110 lines
3.6 KiB
C++

//===-- llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h --------*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Common functionality for different debug information format backends.
// LLVM currently supports DWARF and CodeView.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGHANDLERBASE_H
#define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGHANDLERBASE_H
#include "AsmPrinterHandler.h"
#include "DbgValueHistoryCalculator.h"
#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/CodeGen/MachineInstr.h"
namespace llvm {
class AsmPrinter;
class MachineModuleInfo;
/// Base class for debug information backends. Common functionality related to
/// tracking which variables and scopes are alive at a given PC live here.
class DebugHandlerBase : public AsmPrinterHandler {
protected:
DebugHandlerBase(AsmPrinter *A);
/// Target of debug info emission.
AsmPrinter *Asm;
/// Collected machine module information.
MachineModuleInfo *MMI;
/// Previous instruction's location information. This is used to
/// determine label location to indicate scope boundries in dwarf
/// debug info.
DebugLoc PrevInstLoc;
MCSymbol *PrevLabel = nullptr;
/// This location indicates end of function prologue and beginning of
/// function body.
DebugLoc PrologEndLoc;
/// If nonnull, stores the current machine instruction we're processing.
const MachineInstr *CurMI = nullptr;
LexicalScopes LScopes;
/// History of DBG_VALUE and clobber instructions for each user
/// variable. Variables are listed in order of appearance.
DbgValueHistoryMap DbgValues;
/// Maps instruction with label emitted before instruction.
/// FIXME: Make this private from DwarfDebug, we have the necessary accessors
/// for it.
DenseMap<const MachineInstr *, MCSymbol *> LabelsBeforeInsn;
/// Maps instruction with label emitted after instruction.
DenseMap<const MachineInstr *, MCSymbol *> LabelsAfterInsn;
/// Indentify instructions that are marking the beginning of or
/// ending of a scope.
void identifyScopeMarkers();
/// Ensure that a label will be emitted before MI.
void requestLabelBeforeInsn(const MachineInstr *MI) {
LabelsBeforeInsn.insert(std::make_pair(MI, nullptr));
}
/// Ensure that a label will be emitted after MI.
void requestLabelAfterInsn(const MachineInstr *MI) {
LabelsAfterInsn.insert(std::make_pair(MI, nullptr));
}
// AsmPrinterHandler overrides.
public:
void beginInstruction(const MachineInstr *MI) override;
void endInstruction() override;
void beginFunction(const MachineFunction *MF) override;
void endFunction(const MachineFunction *MF) override;
/// Return Label preceding the instruction.
MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
/// Return Label immediately following the instruction.
MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
/// Determine the relative position of the fragments described by P1 and P2.
/// Returns -1 if P1 is entirely before P2, 0 if P1 and P2 overlap, 1 if P1 is
/// entirely after P2.
static int fragmentCmp(const DIExpression *P1, const DIExpression *P2);
/// Determine whether two variable fragments overlap.
static bool fragmentsOverlap(const DIExpression *P1, const DIExpression *P2);
/// If this type is derived from a base type then return base type size.
static uint64_t getBaseTypeSize(const DITypeRef TyRef);
};
}
#endif